Master Alex Audit
Master Alex Audit
Comprehensive project audit with 22 automated checks across security, quality, and health
Overview
Extends: architecture-audit
Master Alex-specific audit procedures that leverage knowledge of:
- Exact folder structure and file locations
- Heir relationships (VS Code extension, M365 agent)
- Safety imperatives and protection mechanisms
- Build/release workflows
- Platform-specific configurations
Total Audit Sections: 22
- Master-Only (1-9): Version alignment, heir sync, safety imperatives, build artifacts
- Inheritable (10-22): UI, dependencies, security, tests, accessibility, localization, assets, config
Triggers
- "master audit", "full audit"
- "heir sync check", "platform alignment"
- "pre-release master check"
- "dependency audit", "security audit", "ui audit"
- "test coverage", "accessibility audit", "bundle size"
- Before publishing heirs to marketplace
Audit Quick Reference
| # | Section | Inheritable | Priority |
|---|---|---|---|
| 1-9 | Master-Specific | ❌ | 🔴 Critical |
| 10 | UI Audit | ✅ | 🟡 Medium |
| 11 | Dependency Health | ✅ | 🔴 High |
| 12 | TypeScript & Lint | ✅ | 🔴 High |
| 13 | Security | ✅ | 🔴 High |
| 14 | Bundle Size | ✅ | 🟡 Medium |
| 15 | Git Hygiene | ✅ | 🟡 Medium |
| 16 | Changelog | ✅ | 🟡 Medium |
| 17 | API Compatibility | ✅ | 🟡 Medium |
| 18 | Test Coverage | ✅ | 🟡 Medium |
| 19 | Accessibility | ✅ | 🟢 Low |
| 20 | Localization | ✅ | 🟢 Low |
| 21 | Asset Integrity | ✅ | 🟢 Low |
| 22 | Configuration Files | ✅ | 🟢 Low |
Master-Specific Audit Points
1. Version Alignment Across Platforms
Master Alex must maintain version consistency across all platforms:
# Canonical version sources
$versionFiles = @{
"Master" = "platforms/vscode-extension/package.json"
"Copilot Instructions" = ".github/copilot-instructions.md"
"M365 Agent" = "platforms/m365-copilot/appPackage/declarativeAgent.json"
"Changelog" = "CHANGELOG.md"
}
# Extract and compare versions
foreach ($source in $versionFiles.GetEnumerator()) {
$content = Get-Content $source.Value -Raw
$version = [regex]::Match($content, '(?:version["\s:]+|Version:\s*|##\s*\[?v?)(\d+\.\d+\.\d+)').Groups[1].Value
Write-Host "$($source.Key): v$version"
}
Expected State: All show same version (currently v3.7.3)
2. Heir Folder Sync Status
Check that heirs have current copies of inheritable content:
# Files that should be synced to heirs
$syncTargets = @(
@{
Source = ".github/copilot-instructions.md"
Heirs = @(
"platforms/vscode-extension/.github/copilot-instructions.md"
)
},
@{
Source = ".github/instructions/"
Heirs = @(
"platforms/vscode-extension/.github/instructions/"
)
},
@{
Source = ".github/prompts/"
Heirs = @(
"platforms/vscode-extension/.github/prompts/"
)
}
)
# Compare file counts and modification dates
foreach ($target in $syncTargets) {
$sourceCount = (Get-ChildItem $target.Source -Recurse -File).Count
foreach ($heir in $target.Heirs) {
if (Test-Path $heir) {
$heirCount = (Get-ChildItem $heir -Recurse -File).Count
$diff = $sourceCount - $heirCount
Write-Host "$($target.Source) -> $heir : $($diff) file difference"
} else {
Write-Host "$heir MISSING"
}
}
}
3. Skill Inheritance Audit
Verify inheritable skills are properly deployed to heirs:
# Get inheritable skills from catalog
$catalog = Get-Content "alex_docs/SKILLS-CATALOG.md" -Raw
$inheritable = [regex]::Matches($catalog, '\|\s*(\w+-\w+(?:-\w+)*)\s*\|[^|]*\|[^|]*\|\s*✅\s*\|') |
ForEach-Object { $_.Groups[1].Value }
Write-Host "Inheritable skills: $($inheritable.Count)"
# Check heir skill folders
$heirSkills = Get-ChildItem "platforms/vscode-extension/.github/skills" -Directory |
Select-Object -ExpandProperty Name
$missing = $inheritable | Where-Object { $_ -notin $heirSkills }
if ($missing) {
Write-Host "⚠️ Missing from heir: $($missing -join ', ')"
}
4. Safety Imperative Validation
Verify protection mechanisms are in place:
# Critical protection files
$protectionChecks = @(
@{
File = ".github/config/MASTER-ALEX-PROTECTED.json"
Check = '"protected": true'
Purpose = "Kill switch marker"
},
@{
File = ".vscode/settings.json"
Check = '"alex.workspace.protectedMode": true'
Purpose = "Workspace protection setting"
},
@{
File = "platforms/vscode-extension/.vscodeignore"
Check = "MASTER-ALEX-PROTECTED.json"
Purpose = "Marker excluded from package"
}
)
foreach ($check in $protectionChecks) {
if (Test-Path $check.File) {
$content = Get-Content $check.File -Raw
$found = $content -match [regex]::Escape($check.Check)
$status = if ($found) { "✅" } else { "❌ MISSING" }
Write-Host "$status $($check.Purpose): $($check.File)"
} else {
Write-Host "❌ FILE MISSING: $($check.File)"
}
}
5. Build Artifact Verification
Ensure extension package is buildable:
cd "platforms/vscode-extension"
# Check TypeScript compiles
npm run compile 2>&1 | Select-Object -Last 5
# Check package.json validity
$pkg = Get-Content "package.json" | ConvertFrom-Json
Write-Host "Extension: $($pkg.name) v$($pkg.version)"
Write-Host "Commands: $($pkg.contributes.commands.Count)"
Write-Host "Tools: $($pkg.contributes.'languageModelTools'.Count)"
# Verify dist exists and is recent
$dist = Get-Item "dist/extension.js" -ErrorAction SilentlyContinue
if ($dist) {
$age = (Get-Date) - $dist.LastWriteTime
Write-Host "dist/extension.js age: $([int]$age.TotalMinutes) minutes"
} else {
Write-Host "⚠️ dist/extension.js not found - run 'npm run compile'"
}
6. Documentation Cross-Reference Check
Validate key documentation references:
# Key cross-references that must exist
$requiredRefs = @(
@{ Doc = "README.md"; MustLink = "alex_docs/USER-MANUAL.md" },
@{ Doc = "README.md"; MustLink = "CHANGELOG.md" },
@{ Doc = ".github/copilot-instructions.md"; MustLink = "RISKS.md" },
@{ Doc = "RISKS.md"; MustLink = "COMEBACK-PLAN.md" }
)
foreach ($ref in $requiredRefs) {
$content = Get-Content $ref.Doc -Raw
$found = $content -match [regex]::Escape($ref.MustLink)
$status = if ($found) { "✅" } else { "⚠️" }
Write-Host "$status $($ref.Doc) -> $($ref.MustLink)"
}
7. Synapse Network Health
Validate cognitive architecture connections:
# Run built-in synapse validation
# In VS Code: "Alex: Dream (Neural Maintenance)"
# Or manual check
$synapseFiles = Get-ChildItem ".github/skills/*/synapses.json" -Recurse
Write-Host "Synapse files found: $($synapseFiles.Count)"
# Check for broken connections
$allSkills = Get-ChildItem ".github/skills" -Directory | Select-Object -ExpandProperty Name
foreach ($file in $synapseFiles) {
$synapses = Get-Content $file | ConvertFrom-Json
foreach ($conn in $synapses.connections) {
if ($conn.target -notin $allSkills) {
Write-Host "⚠️ Broken synapse in $($file.Directory.Name): $($conn.target)"
}
}
}
8. alex_docs Documentation Audit
Comprehensive check of the documentation folder:
# === alex_docs AUDIT ===
$alexDocs = "alex_docs"
$issues = @()
# 8a. Version references - should all match current version
Write-Host "`n--- Version References ---"
$currentVersion = "3.7.3"
$versionRefs = Select-String -Path "$alexDocs/*.md" -Pattern '\d+\.\d+\.\d+' -AllMatches
$wrongVersions = $versionRefs | Where-Object { $_.Matches.Value -ne $currentVersion -and $_.Matches.Value -match '^\d+\.\d+\.\d+$' }
if ($wrongVersions) {
Write-Host "⚠️ Non-current versions found:"
$wrongVersions | ForEach-Object { Write-Host " $($_.Filename):$($_.LineNumber) - $($_.Matches.Value)" }
$issues += "Version drift in alex_docs"
} else {
Write-Host "✅ All version references current"
}
# 8b. Deprecated terminology
Write-Host "`n--- Deprecated Terms ---"
$deprecated = @(
@{ Term = 'DK-\*.md'; Replacement = 'skills/*/SKILL.md' },
@{ Term = 'domain-knowledge/'; Replacement = 'skills/' },
@{ Term = 'domain knowledge'; Replacement = 'skills' }
)
foreach ($dep in $deprecated) {
$found = Select-String -Path "$alexDocs/*.md" -Pattern $dep.Term -SimpleMatch
if ($found) {
Write-Host "⚠️ '$($dep.Term)' found (use '$($dep.Replacement)'):"
$found | ForEach-Object { Write-Host " $($_.Filename):$($_.LineNumber)" }
$issues += "Deprecated term: $($dep.Term)"
}
}
if ($issues.Count -eq 0) { Write-Host "✅ No deprecated terms" }
# 8c. Skill count accuracy in docs
Write-Host "`n--- Skill Count Accuracy ---"
$actualSkillCount = (Get-ChildItem ".github/skills" -Directory).Count
$docSkillCounts = Select-String -Path "$alexDocs/*.md" -Pattern '(\d+)\s*skills?' -AllMatches
$wrongCounts = $docSkillCounts | Where-Object {
$_.Matches | Where-Object { [int]$_.Groups[1].Value -ne $actualSkillCount -and [int]$_.Groups[1].Value -gt 30 }
}
if ($wrongCounts) {
Write-Host "⚠️ Incorrect skill counts (actual: $actualSkillCount):"
$wrongCounts | ForEach-Object { Write-Host " $($_.Filename):$($_.LineNumber) - $($_.Line.Trim())" }
$issues += "Skill count mismatch"
} else {
Write-Host "✅ Skill counts accurate"
}
# 8d. Broken internal links
Write-Host "`n--- Internal Links ---"
$mdFiles = Get-ChildItem "$alexDocs/*.md"
$brokenLinks = @()
foreach ($file in $mdFiles) {
$content = Get-Content $file -Raw
$links = [regex]::Matches($content, '\[([^\]]+)\]\(([^)]+)\)') | Where-Object { $_.Groups[2].Value -notmatch '^https?://' }
foreach ($link in $links) {
$target = $link.Groups[2].Value -replace '#.*$', '' # Remove anchors
if ($target -and -not (Test-Path (Join-Path $alexDocs $target)) -and -not (Test-Path $target)) {
$brokenLinks += "$($file.Name): $($link.Groups[2].Value)"
}
}
}
if ($brokenLinks) {
Write-Host "⚠️ Broken links:"
$brokenLinks | ForEach-Object { Write-Host " $_" }
$issues += "Broken internal links"
} else {
Write-Host "✅ All internal links valid"
}
# 8e. Diagram accuracy (Mermaid node counts)
Write-Host "`n--- Diagram Checks ---"
$catalogDiagram = Select-String -Path "$alexDocs/SKILLS-CATALOG.md" -Pattern '\[[\w-]+\]' -AllMatches
$diagramNodes = ($catalogDiagram.Matches | Select-Object -ExpandProperty Value | Sort-Object -Unique).Count
Write-Host "Skill network diagram nodes: $diagramNodes (actual skills: $actualSkillCount)"
if ([Math]::Abs($diagramNodes - $actualSkillCount) -gt 2) {
Write-Host "⚠️ Diagram may be out of sync"
$issues += "Diagram node count mismatch"
} else {
Write-Host "✅ Diagram appears current"
}
# Summary
Write-Host "`n--- alex_docs SUMMARY ---"
if ($issues.Count -eq 0) {
Write-Host "✅ All checks passed" -ForegroundColor Green
} else {
Write-Host "⚠️ Issues found: $($issues.Count)" -ForegroundColor Yellow
$issues | ForEach-Object { Write-Host " - $_" }
}
9. Skill Network Diagram Audit
Deep validation of the Mermaid skill network diagram in SKILLS-CATALOG.md:
# === SKILL NETWORK DIAGRAM AUDIT ===
$catalogFile = "alex_docs/SKILLS-CATALOG.md"
$catalogContent = Get-Content $catalogFile -Raw
$issues = @()
# 9a. Extract all actual skills
$actualSkills = Get-ChildItem ".github/skills" -Directory | Select-Object -ExpandProperty Name
Write-Host "Actual skills: $($actualSkills.Count)"
# 9b. Extract diagram nodes (format: ABBREV[skill-name])
$nodePattern = '(\w+)\[([\w-]+)\]'
$diagramNodes = [regex]::Matches($catalogContent, $nodePattern)
$nodeMap = @{}
foreach ($match in $diagramNodes) {
$abbrev = $match.Groups[1].Value
$skillName = $match.Groups[2].Value
$nodeMap[$skillName] = $abbrev
}
Write-Host "Diagram nodes: $($nodeMap.Count)"
# 9c. Skills missing from diagram
$missingFromDiagram = $actualSkills | Where-Object { $_ -notin $nodeMap.Keys }
if ($missingFromDiagram) {
Write-Host "`n⚠️ Skills MISSING from diagram:"
$missingFromDiagram | ForEach-Object { Write-Host " - $_" }
$issues += "Missing from diagram: $($missingFromDiagram -join ', ')"
} else {
Write-Host "✅ All skills have diagram nodes"
}
# 9d. Phantom nodes (in diagram but not actual skills)
$phantomNodes = $nodeMap.Keys | Where-Object { $_ -notin $actualSkills }
if ($phantomNodes) {
Write-Host "`n⚠️ PHANTOM nodes (skill doesn't exist):"
$phantomNodes | ForEach-Object { Write-Host " - $_ ($($nodeMap[$_]))" }
$issues += "Phantom nodes: $($phantomNodes -join ', ')"
} else {
Write-Host "✅ No phantom nodes"
}
# 9e. Check class assignments match inheritance
# Extract class definitions
$masterClass = [regex]::Match($catalogContent, 'class\s+([\w,]+)\s+master').Groups[1].Value -split ','
$inheritableClass = [regex]::Match($catalogContent, 'class\s+([\w,]+)\s+inheritable').Groups[1].Value -split ','
$vscodeClass = [regex]::Match($catalogContent, 'class\s+([\w,]+)\s+vscode').Groups[1].Value -split ','
$m365Class = [regex]::Match($catalogContent, 'class\s+([\w,]+)\s+m365').Groups[1].Value -split ','
Write-Host "`nClass assignments:"
Write-Host " Master: $($masterClass.Count) nodes"
Write-Host " Inheritable: $($inheritableClass.Count) nodes"
Write-Host " VS Code: $($vscodeClass.Count) nodes"
Write-Host " M365: $($m365Class.Count) nodes"
# 9f. Verify master-only skills are in master class
$masterOnlySkills = @(
'meditation', 'meditation-facilitation', 'knowledge-synthesis', 'global-knowledge',
'architecture-refinement', 'llm-model-selection', 'self-actualization', 'heir-curation',
'master-alex-audit'
)
$masterAbbrevs = $masterOnlySkills | ForEach-Object { $nodeMap[$_] } | Where-Object { $_ }
$missingMasterClass = $masterAbbrevs | Where-Object { $_ -notin $masterClass }
if ($missingMasterClass) {
Write-Host "`n⚠️ Master-only skills not in master class:"
$missingMasterClass | ForEach-Object { Write-Host " - $_" }
$issues += "Master class mismatch"
}
# 9g. Check for orphan nodes (no connections)
$connectionPattern = '(\w+)\s*(?:-->|<-->|-.->)\s*'
$connectedNodes = [regex]::Matches($catalogContent, $connectionPattern) |
ForEach-Object { $_.Groups[1].Value } | Sort-Object -Unique
$allAbbrevs = $nodeMap.Values | Sort-Object -Unique
$orphans = $allAbbrevs | Where-Object { $_ -notin $connectedNodes -and $_ -ne 'BT' } # BT is temp, may be orphan
if ($orphans) {
Write-Host "`n⚠️ Orphan nodes (no connections):"
$orphans | ForEach-Object {
$skill = ($nodeMap.GetEnumerator() | Where-Object { $_.Value -eq $_ }).Key
Write-Host " - $_ ($skill)"
}
$issues += "Orphan nodes: $($orphans -join ', ')"
} else {
Write-Host "✅ All nodes connected"
}
# Summary
Write-Host "`n--- DIAGRAM AUDIT SUMMARY ---"
if ($issues.Count -eq 0) {
Write-Host "✅ Diagram is accurate" -ForegroundColor Green
} else {
Write-Host "⚠️ Diagram issues: $($issues.Count)" -ForegroundColor Yellow
$issues | ForEach-Object { Write-Host " - $_" }
}
Quick diagram check command:
# One-liner to compare skill count vs diagram nodes
$skills = (Get-ChildItem ".github/skills" -Directory).Count
$nodes = ([regex]::Matches((Get-Content "alex_docs/SKILLS-CATALOG.md" -Raw), '\w+\[[\w-]+\]') | Select-Object -ExpandProperty Value | Sort-Object -Unique).Count
Write-Host "Skills: $skills | Diagram nodes: $nodes | $(if($skills -eq $nodes){'✅ MATCH'}else{'⚠️ MISMATCH'})"
10. Extension UI Audit
Deep inspection of VS Code extension UI elements for dead buttons and non-functional features:
# === EXTENSION UI AUDIT ===
$srcPath = "platforms/vscode-extension/src"
$issues = @()
Write-Host "=== UI AUDIT ===" -ForegroundColor Cyan
# 10a. WebView window.open() calls (don't work in WebViews)
Write-Host "`n--- Dead External Links ---"
$windowOpen = Select-String -Path "$srcPath/**/*.ts" -Pattern 'window\.open\(' -Recurse
if ($windowOpen) {
Write-Host "⚠️ window.open() found (doesn't work in WebViews):"
$windowOpen | ForEach-Object {
Write-Host " $($_.Filename):$($_.LineNumber)"
$issues += "window.open in $($_.Filename)"
}
} else {
Write-Host "✅ No window.open() calls"
}
# 10b. location.reload() calls (don't work in WebViews)
Write-Host "`n--- Dead Reload Buttons ---"
$locationReload = Select-String -Path "$srcPath/**/*.ts" -Pattern 'location\.reload\(\)' -Recurse
if ($locationReload) {
Write-Host "⚠️ location.reload() found (doesn't work in WebViews):"
$locationReload | ForEach-Object {
Write-Host " $($_.Filename):$($_.LineNumber)"
$issues += "location.reload in $($_.Filename)"
}
} else {
Write-Host "✅ No location.reload() calls"
}
# 10c. Duplicate QuickPick items (same handler, different labels)
Write-Host "`n--- Duplicate QuickPick Items ---"
$extensionTs = Get-Content "$srcPath/extension.ts" -Raw
$goalItems = [regex]::Matches($extensionTs, 'label:\s*"[^"]*Goals[^"]*"')
if ($goalItems.Count -gt 1) {
Write-Host "⚠️ Multiple 'Goals' quick pick items:"
$goalItems | ForEach-Object { Write-Host " - $($_.Value)" }
$issues += "Duplicate Goals items"
} else {
Write-Host "✅ No duplicate quick pick items"
}
# 10d. Modal dialogs with buttons that don't do anything unique
Write-Host "`n--- Modal Button Analysis ---"
$modals = Select-String -Path "$srcPath/**/*.ts" -Pattern 'showInformationMessage|showWarningMessage|showErrorMessage' -Recurse
$modalCount = $modals.Count
Write-Host "Found $modalCount modal dialogs to review manually"
# 10e. Message handler coverage check
Write-Host "`n--- WebView Message Handlers ---"
$views = @(
@{ Name = "welcomeView"; Pattern = "cmd\('(\w+)'\)" },
@{ Name = "healthDashboard"; Pattern = "command:\s*'(\w+)'" }
)
foreach ($view in $views) {
$viewFile = Get-ChildItem "$srcPath/views/$($view.Name).ts" -ErrorAction SilentlyContinue
if ($viewFile) {
$content = Get-Content $viewFile -Raw
# Extract onclick commands from HTML
$cmds = [regex]::Matches($content, $view.Pattern) |
ForEach-Object { $_.Groups[1].Value } | Sort-Object -Unique
# Extract handled cases from switch statement
$cases = [regex]::Matches($content, "case ['\"](\w+)['\"]") |
ForEach-Object { $_.Groups[1].Value } | Sort-Object -Unique
$unhandled = $cmds | Where-Object { $_ -notin $cases }
if ($unhandled) {
Write-Host "⚠️ $($view.Name): Unhandled commands: $($unhandled -join ', ')"
$issues += "Unhandled in $($view.Name): $($unhandled -join ', ')"
} else {
Write-Host "✅ $($view.Name): All commands handled"
}
}
}
# 10f. Commands registered but not implemented
Write-Host "`n--- Command Registration Check ---"
$pkgJson = Get-Content "platforms/vscode-extension/package.json" | ConvertFrom-Json
$registeredCmds = $pkgJson.contributes.commands | ForEach-Object { $_.command }
$implementedCmds = Select-String -Path "$srcPath/**/*.ts" -Pattern "registerCommand\(['\"]([^'\"]+)['\"]" -AllMatches -Recurse |
ForEach-Object { $_.Matches } | ForEach-Object { $_.Groups[1].Value }
$notImplemented = $registeredCmds | Where-Object { $_ -notin $implementedCmds }
if ($notImplemented) {
Write-Host "⚠️ Registered but not implemented:"
$notImplemented | ForEach-Object { Write-Host " - $_" }
$issues += "Unimplemented commands: $($notImplemented -join ', ')"
} else {
Write-Host "✅ All registered commands implemented"
}
# Summary
Write-Host "`n--- UI AUDIT SUMMARY ---"
if ($issues.Count -eq 0) {
Write-Host "✅ No UI issues found" -ForegroundColor Green
} else {
Write-Host "⚠️ UI issues: $($issues.Count)" -ForegroundColor Yellow
$issues | ForEach-Object { Write-Host " - $_" }
}
Common UI Anti-Patterns to Check:
| Anti-Pattern | Why It's Dead | Fix |
|---|---|---|
window.open(url) |
WebViews are sandboxed | Use vscode.postMessage({command: 'openExternal', url}) + vscode.env.openExternal() |
location.reload() |
No browser navigation in WebViews | Use vscode.postMessage({command: 'refresh'}) + re-render HTML |
onclick="..." without handler |
Button does nothing | Add case in onDidReceiveMessage switch |
| Duplicate quick pick items | Confusing UX | Remove duplicates, keep most descriptive |
| Modal with single info button | Button does nothing useful | Remove button or use only Cancel |
WebView Button Pattern (Correct):
// In HTML template
<button onclick="vscode.postMessage({command: 'doThing'})">Click Me</button>
// In provider
webview.onDidReceiveMessage(async (message) => {
switch (message.command) {
case 'doThing':
// Actually do something
vscode.commands.executeCommand('myCommand');
break;
case 'openExternal':
vscode.env.openExternal(vscode.Uri.parse(message.url));
break;
}
});
Key files to audit:
| File | Key Checks |
|---|---|
SKILLS-CATALOG.md |
Skill count, network diagram, inheritance table |
COGNITIVE-ARCHITECTURE.md |
Version, component counts |
USER-MANUAL.md |
Command list, feature descriptions |
PROJECT-STRUCTURE.md |
Folder structure accuracy |
MEMORY-SYSTEMS.md |
Memory type descriptions |
Inheritable Audit Checks ✅
These audit sections can be inherited by heirs (VS Code extension, M365 agent, future platforms). They use relative paths and generic patterns that work in any deployment.
11. Dependency Health Audit
Check for outdated packages, security vulnerabilities, and unused dependencies:
# === DEPENDENCY HEALTH AUDIT ===
$extPath = "platforms/vscode-extension"
Push-Location $extPath
Write-Host "=== DEPENDENCY HEALTH ===" -ForegroundColor Cyan
# 11a. Security vulnerabilities
Write-Host "`n--- Security Audit ---"
$auditResult = npm audit --json 2>$null | ConvertFrom-Json
if ($auditResult.metadata) {
$vulns = $auditResult.metadata.vulnerabilities
$total = $vulns.info + $vulns.low + $vulns.moderate + $vulns.high + $vulns.critical
Write-Host "Vulnerabilities: $total total"
Write-Host " Critical: $($vulns.critical) | High: $($vulns.high) | Moderate: $($vulns.moderate)"
if ($vulns.critical -gt 0 -or $vulns.high -gt 0) {
Write-Host "⚠️ ACTION REQUIRED: Run 'npm audit fix'" -ForegroundColor Red
} else {
Write-Host "✅ No critical/high vulnerabilities" -ForegroundColor Green
}
} else {
Write-Host "✅ No vulnerabilities found"
}
# 11b. Outdated packages
Write-Host "`n--- Outdated Packages ---"
$outdated = npm outdated --json 2>$null | ConvertFrom-Json
$outdatedCount = ($outdated.PSObject.Properties | Measure-Object).Count
if ($outdatedCount -gt 0) {
Write-Host "⚠️ $outdatedCount packages outdated:"
$outdated.PSObject.Properties | ForEach-Object {
$pkg = $_.Name
$curr = $_.Value.current
$latest = $_.Value.latest
$type = if ($_.Value.type -eq 'devDependencies') { 'dev' } else { 'prod' }
Write-Host " $pkg : $curr → $latest ($type)"
}
} else {
Write-Host "✅ All packages up to date"
}
# 11c. Unused dependencies (requires depcheck)
Write-Host "`n--- Unused Dependencies ---"
if (Get-Command depcheck -ErrorAction SilentlyContinue) {
$unused = npx depcheck --json 2>$null | ConvertFrom-Json
if ($unused.dependencies.Count -gt 0) {
Write-Host "⚠️ Possibly unused:"
$unused.dependencies | ForEach-Object { Write-Host " - $_" }
} else {
Write-Host "✅ No unused dependencies detected"
}
} else {
Write-Host "ℹ️ Install depcheck for unused dependency detection: npm i -g depcheck"
}
Pop-Location
12. TypeScript & Lint Audit
Check for compile errors, ESLint warnings, and code quality issues:
# === TYPESCRIPT & LINT AUDIT ===
$extPath = "platforms/vscode-extension"
Push-Location $extPath
Write-Host "=== CODE QUALITY ===" -ForegroundColor Cyan
# 12a. TypeScript compilation
Write-Host "`n--- TypeScript Compile Check ---"
$tscOutput = npm run compile 2>&1
$errors = $tscOutput | Select-String -Pattern 'error TS\d+' -AllMatches
if ($errors) {
Write-Host "❌ Compile errors found:" -ForegroundColor Red
$errors | Select-Object -First 10 | ForEach-Object { Write-Host " $_" }
if ($errors.Count -gt 10) { Write-Host " ... and $($errors.Count - 10) more" }
} else {
Write-Host "✅ TypeScript compiles successfully" -ForegroundColor Green
}
# 12b. ESLint (if configured)
Write-Host "`n--- ESLint Check ---"
if (Test-Path ".eslintrc*" -or (Get-Content "package.json" | Select-String '"eslint"')) {
$eslintOutput = npx eslint src --format compact 2>&1
$warnings = ($eslintOutput | Select-String -Pattern 'Warning' -AllMatches).Matches.Count
$errs = ($eslintOutput | Select-String -Pattern 'Error' -AllMatches).Matches.Count
Write-Host "Errors: $errs | Warnings: $warnings"
if ($errs -gt 0) {
Write-Host "❌ ESLint errors need fixing" -ForegroundColor Red
} elseif ($warnings -gt 5) {
Write-Host "⚠️ Consider fixing warnings" -ForegroundColor Yellow
} else {
Write-Host "✅ Code quality good" -ForegroundColor Green
}
} else {
Write-Host "ℹ️ ESLint not configured"
}
# 12c. Unused exports (dead code)
Write-Host "`n--- Unused Exports ---"
$exports = Select-String -Path "src/**/*.ts" -Pattern 'export (function|class|const|interface|type|enum) (\w+)' -Recurse
$exportNames = $exports | ForEach-Object { $_.Matches[0].Groups[2].Value } | Sort-Object -Unique
$unusedExports = @()
foreach ($name in $exportNames) {
$usages = Select-String -Path "src/**/*.ts" -Pattern "\b$name\b" -Recurse
if ($usages.Count -le 1) { # Only the export itself
$unusedExports += $name
}
}
if ($unusedExports.Count -gt 0 -and $unusedExports.Count -lt 20) {
Write-Host "⚠️ Possibly unused exports: $($unusedExports -join ', ')"
} else {
Write-Host "✅ No obviously unused exports"
}
Pop-Location
13. Security Audit
Check for secrets in code, CSP compliance, and input sanitization:
# === SECURITY AUDIT ===
$extPath = "platforms/vscode-extension"
Write-Host "=== SECURITY ===" -ForegroundColor Cyan
# 13a. Secrets in code
Write-Host "`n--- Secret Scanning ---"
$secretPatterns = @(
@{ Name = 'API Key'; Pattern = '(?i)(api[_-]?key|apikey)\s*[:=]\s*["\x27]?[\w-]{20,}' },
@{ Name = 'Password'; Pattern = '(?i)(password|passwd|pwd)\s*[:=]\s*["\x27][^"\x27]{4,}' },
@{ Name = 'Token'; Pattern = '(?i)(token|secret|bearer)\s*[:=]\s*["\x27][\w-]{20,}' },
@{ Name = 'Private Key'; Pattern = '-----BEGIN (RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----' },
@{ Name = 'Connection String'; Pattern = '(?i)(connection[_-]?string|connstr)\s*[:=]' }
)
$secretsFound = @()
foreach ($pattern in $secretPatterns) {
$matches = Select-String -Path "$extPath/src/**/*.ts" -Pattern $pattern.Pattern -Recurse
if ($matches) {
$secretsFound += "$($pattern.Name): $($matches.Count) potential matches"
$matches | Select-Object -First 2 | ForEach-Object {
Write-Host " ⚠️ $($_.Filename):$($_.LineNumber)" -ForegroundColor Yellow
}
}
}
if ($secretsFound.Count -eq 0) {
Write-Host "✅ No secrets detected in code" -ForegroundColor Green
} else {
Write-Host "⚠️ Review potential secrets: $($secretsFound -join '; ')" -ForegroundColor Yellow
}
# 13b. WebView CSP (Content Security Policy)
Write-Host "`n--- WebView CSP Check ---"
$webviews = Get-ChildItem "$extPath/src/**/*.ts" -Recurse |
Select-String -Pattern 'createWebviewPanel|WebviewViewProvider' -List
$cspUsage = Get-ChildItem "$extPath/src/**/*.ts" -Recurse |
Select-String -Pattern 'Content-Security-Policy|cspSource|getNonce' -List
if ($webviews.Count -gt 0) {
Write-Host "WebViews found: $($webviews.Count)"
if ($cspUsage.Count -gt 0) {
Write-Host "✅ CSP implementation detected" -ForegroundColor Green
} else {
Write-Host "⚠️ No CSP found - WebViews may be vulnerable to XSS" -ForegroundColor Yellow
}
} else {
Write-Host "ℹ️ No WebViews detected"
}
# 13c. Input sanitization for user data
Write-Host "`n--- Input Sanitization ---"
$userInputs = Select-String -Path "$extPath/src/**/*.ts" -Pattern 'showInputBox|showQuickPick.*editable' -Recurse
$sanitization = Select-String -Path "$extPath/src/**/*.ts" -Pattern 'sanitize|escape|encode|validate' -Recurse
Write-Host "User input points: $($userInputs.Count)"
Write-Host "Sanitization calls: $($sanitization.Count)"
if ($userInputs.Count -gt $sanitization.Count * 2) {
Write-Host "⚠️ Consider adding input validation" -ForegroundColor Yellow
} else {
Write-Host "✅ Input handling appears reasonable"
}
14. Bundle Size & Performance Audit
Check extension size, activation time, and bundle efficiency:
# === BUNDLE SIZE AUDIT ===
$extPath = "platforms/vscode-extension"
Write-Host "=== BUNDLE & PERFORMANCE ===" -ForegroundColor Cyan
# 14a. Extension bundle size
Write-Host "`n--- Bundle Size ---"
$distFile = Get-Item "$extPath/dist/extension.js" -ErrorAction SilentlyContinue
if ($distFile) {
$sizeKB = [math]::Round($distFile.Length / 1KB, 1)
$sizeMB = [math]::Round($distFile.Length / 1MB, 2)
Write-Host "Bundle: $sizeKB KB ($sizeMB MB)"
if ($sizeKB -gt 500) {
Write-Host "⚠️ Bundle is large - consider code splitting" -ForegroundColor Yellow
} else {
Write-Host "✅ Bundle size acceptable" -ForegroundColor Green
}
} else {
Write-Host "⚠️ No bundle found - run 'npm run compile'"
}
# 14b. Source map size
$mapFile = Get-Item "$extPath/dist/extension.js.map" -ErrorAction SilentlyContinue
if ($mapFile) {
$mapSizeKB = [math]::Round($mapFile.Length / 1KB, 1)
Write-Host "Source map: $mapSizeKB KB"
}
# 14c. node_modules size (dev environment)
Write-Host "`n--- Dependencies Size ---"
$nodeModules = Get-ChildItem "$extPath/node_modules" -Recurse -File -ErrorAction SilentlyContinue |
Measure-Object -Property Length -Sum
$nmSizeMB = [math]::Round($nodeModules.Sum / 1MB, 1)
Write-Host "node_modules: $nmSizeMB MB"
# 14d. Package size estimate (what gets published)
Write-Host "`n--- Published Package Estimate ---"
$vscodeignore = Get-Content "$extPath/.vscodeignore" -ErrorAction SilentlyContinue
$includedPatterns = @('dist/', 'package.json', 'README.md', 'CHANGELOG.md', 'LICENSE.md', '.github/')
$estimatedFiles = Get-ChildItem $extPath -Recurse -File | Where-Object {
$path = $_.FullName.Replace("$extPath\", "").Replace('\', '/')
$included = $false
foreach ($p in $includedPatterns) {
if ($path -like "$p*" -or $path -eq $p.TrimEnd('/')) { $included = $true; break }
}
$included
}
$pkgSizeKB = [math]::Round(($estimatedFiles | Measure-Object Length -Sum).Sum / 1KB, 1)
Write-Host "Estimated package: ~$pkgSizeKB KB"
if ($pkgSizeKB -gt 1000) {
Write-Host "⚠️ Package may be large for marketplace" -ForegroundColor Yellow
}
15. Git Hygiene Audit
Check repository health, uncommitted changes, and branch status:
# === GIT HYGIENE AUDIT ===
Write-Host "=== GIT HYGIENE ===" -ForegroundColor Cyan
# 15a. Uncommitted changes
Write-Host "`n--- Working Directory ---"
$status = git status --porcelain
$staged = ($status | Where-Object { $_ -match '^[MADRCU]' }).Count
$unstaged = ($status | Where-Object { $_ -match '^.[MADRCU?]' }).Count
Write-Host "Staged: $staged | Unstaged: $unstaged"
if ($staged -gt 0 -or $unstaged -gt 0) {
Write-Host "⚠️ Uncommitted changes exist" -ForegroundColor Yellow
$status | Select-Object -First 10 | ForEach-Object { Write-Host " $_" }
} else {
Write-Host "✅ Working directory clean" -ForegroundColor Green
}
# 15b. Branch status
Write-Host "`n--- Branch Status ---"
$branch = git branch --show-current
$ahead = git rev-list --count '@{u}..HEAD' 2>$null
$behind = git rev-list --count 'HEAD..@{u}' 2>$null
Write-Host "Branch: $branch"
if ($ahead -and $behind) {
Write-Host "Ahead: $ahead | Behind: $behind"
if ($behind -gt 0) {
Write-Host "⚠️ Pull recommended" -ForegroundColor Yellow
}
if ($ahead -gt 5) {
Write-Host "⚠️ Consider pushing commits" -ForegroundColor Yellow
}
}
# 15c. Large files
Write-Host "`n--- Large Files Check ---"
$largeFiles = Get-ChildItem -Recurse -File |
Where-Object { $_.Length -gt 1MB -and $_.FullName -notmatch 'node_modules|\.git|dist' } |
Sort-Object Length -Descending | Select-Object -First 5
if ($largeFiles) {
Write-Host "⚠️ Large files (>1MB):"
$largeFiles | ForEach-Object {
$sizeMB = [math]::Round($_.Length / 1MB, 2)
Write-Host " $($_.Name): $sizeMB MB"
}
} else {
Write-Host "✅ No unexpectedly large files"
}
# 15d. .gitignore effectiveness
Write-Host "`n--- Gitignore Check ---"
$trackedGenerated = git ls-files | Where-Object {
$_ -match '(node_modules|dist/|\.vsix$|\.log$)'
}
if ($trackedGenerated) {
Write-Host "⚠️ Generated files tracked in git:"
$trackedGenerated | Select-Object -First 5 | ForEach-Object { Write-Host " $_" }
} else {
Write-Host "✅ .gitignore working correctly"
}
16. Changelog Consistency Audit
Validate changelog format and version alignment:
# === CHANGELOG AUDIT ===
Write-Host "=== CHANGELOG ===" -ForegroundColor Cyan
$changelogPath = "CHANGELOG.md"
if (Test-Path $changelogPath) {
$changelog = Get-Content $changelogPath -Raw
# 16a. Format check (Keep a Changelog format)
Write-Host "`n--- Format Validation ---"
$hasUnreleased = $changelog -match '## \[Unreleased\]'
$hasVersions = [regex]::Matches($changelog, '## \[(\d+\.\d+\.\d+)\]')
$hasDates = $changelog -match '## \[\d+\.\d+\.\d+\] - \d{4}-\d{2}-\d{2}'
Write-Host "Unreleased section: $(if($hasUnreleased){'✅'}else{'⚠️ Missing'})"
Write-Host "Version entries: $($hasVersions.Count)"
Write-Host "Dates format: $(if($hasDates){'✅'}else{'⚠️ Check format'})"
# 16b. Version order (should be descending)
Write-Host "`n--- Version Order ---"
$versions = $hasVersions | ForEach-Object { [version]$_.Groups[1].Value }
$sorted = $versions | Sort-Object -Descending
$isOrdered = ($versions -join ',') -eq ($sorted -join ',')
Write-Host "Chronological order: $(if($isOrdered){'✅'}else{'❌ Out of order'})"
# 16c. Latest version matches package.json
Write-Host "`n--- Version Alignment ---"
$latestChangelog = $hasVersions[0].Groups[1].Value
$pkgVersion = (Get-Content "platforms/vscode-extension/package.json" | ConvertFrom-Json).version
Write-Host "Changelog latest: v$latestChangelog"
Write-Host "Package.json: v$pkgVersion"
if ($latestChangelog -eq $pkgVersion) {
Write-Host "✅ Versions match" -ForegroundColor Green
} else {
Write-Host "⚠️ Version mismatch - update changelog?" -ForegroundColor Yellow
}
# 16d. Change categories (Added, Changed, Fixed, etc.)
Write-Host "`n--- Change Categories ---"
$categories = @('Added', 'Changed', 'Deprecated', 'Removed', 'Fixed', 'Security')
$usedCategories = $categories | Where-Object { $changelog -match "### $_" }
Write-Host "Categories used: $($usedCategories -join ', ')"
} else {
Write-Host "❌ CHANGELOG.md not found!" -ForegroundColor Red
}
17. VS Code API Compatibility Audit
Check for deprecated APIs and engine version alignment:
# === API COMPATIBILITY AUDIT ===
$extPath = "platforms/vscode-extension"
Write-Host "=== API COMPATIBILITY ===" -ForegroundColor Cyan
# 17a. Engine version
Write-Host "`n--- Engine Version ---"
$pkg = Get-Content "$extPath/package.json" | ConvertFrom-Json
$engineVersion = $pkg.engines.vscode -replace '\^', ''
Write-Host "Required VS Code: $engineVersion"
# Current VS Code version (if running in VS Code terminal)
$currentVSCode = code --version 2>$null | Select-Object -First 1
if ($currentVSCode) {
Write-Host "Installed VS Code: $currentVSCode"
}
# 17b. Deprecated API usage
Write-Host "`n--- Deprecated APIs ---"
$deprecatedAPIs = @(
@{ API = 'workspace.rootPath'; Replacement = 'workspace.workspaceFolders' },
@{ API = 'window.showQuickPick.*canPickMany'; Replacement = 'QuickPickOptions.canPickMany' },
@{ API = 'ExtensionContext.storagePath'; Replacement = 'ExtensionContext.globalStorageUri' },
@{ API = 'ExtensionContext.globalStoragePath'; Replacement = 'ExtensionContext.globalStorageUri' },
@{ API = 'TreeItem.resourceUri'; Replacement = 'TreeItem.resourceUri (check usage)' }
)
$deprecatedFound = @()
foreach ($api in $deprecatedAPIs) {
$matches = Select-String -Path "$extPath/src/**/*.ts" -Pattern $api.API -Recurse -SimpleMatch
if ($matches) {
$deprecatedFound += "$($api.API) → $($api.Replacement)"
}
}
if ($deprecatedFound.Count -gt 0) {
Write-Host "⚠️ Deprecated APIs found:"
$deprecatedFound | ForEach-Object { Write-Host " $_" }
} else {
Write-Host "✅ No deprecated APIs detected"
}
# 17c. Proposed API usage (requires enabledApiProposals)
Write-Host "`n--- Proposed APIs ---"
$proposedAPIs = Select-String -Path "$extPath/src/**/*.ts" -Pattern '@proposed|enableProposedApi' -Recurse
if ($proposedAPIs) {
Write-Host "⚠️ Proposed APIs in use - ensure enabledApiProposals in package.json"
} else {
Write-Host "✅ No proposed APIs"
}
# 17d. Activation events
Write-Host "`n--- Activation Events ---"
$activationEvents = $pkg.activationEvents
if ($activationEvents -contains '*') {
Write-Host "⚠️ Using '*' activation - consider more specific events" -ForegroundColor Yellow
} else {
Write-Host "Activation events: $($activationEvents.Count)"
Write-Host "✅ Specific activation events configured"
}
18. Test Coverage Audit
Check for test files, coverage gaps, and test health:
# === TEST COVERAGE AUDIT ===
$extPath = "platforms/vscode-extension"
Write-Host "=== TEST COVERAGE ===" -ForegroundColor Cyan
# 18a. Test file inventory
Write-Host "`n--- Test Files ---"
$testFiles = Get-ChildItem "$extPath" -Recurse -Include "*.test.ts", "*.spec.ts", "*_test.ts" -File
$srcFiles = Get-ChildItem "$extPath/src" -Recurse -Include "*.ts" -File |
Where-Object { $_.Name -notmatch '\.(test|spec)\.ts$' }
Write-Host "Source files: $($srcFiles.Count)"
Write-Host "Test files: $($testFiles.Count)"
if ($testFiles.Count -eq 0) {
Write-Host "⚠️ No test files found" -ForegroundColor Yellow
} else {
$ratio = [math]::Round($testFiles.Count / $srcFiles.Count * 100, 1)
Write-Host "Test ratio: $ratio%"
}
# 18b. Check for test framework
Write-Host "`n--- Test Framework ---"
$pkg = Get-Content "$extPath/package.json" | ConvertFrom-Json
$testFrameworks = @('mocha', 'jest', 'vitest', '@vscode/test-electron')
$foundFramework = $testFrameworks | Where-Object {
$pkg.devDependencies.$_ -or $pkg.dependencies.$_
}
if ($foundFramework) {
Write-Host "✅ Test framework: $($foundFramework -join ', ')"
} else {
Write-Host "⚠️ No test framework detected"
}
# 18c. Files without tests
Write-Host "`n--- Coverage Gaps ---"
$testedModules = $testFiles | ForEach-Object {
$_.BaseName -replace '\.(test|spec)$', ''
}
$untestedFiles = $srcFiles | Where-Object {
$baseName = $_.BaseName
$baseName -notin $testedModules -and
$baseName -notmatch '^(index|types|constants|interfaces)$'
} | Select-Object -First 10
if ($untestedFiles.Count -gt 0) {
Write-Host "Files potentially missing tests:"
$untestedFiles | ForEach-Object { Write-Host " - $($_.Name)" }
} else {
Write-Host "✅ Good test coverage"
}
# 18d. Run tests if available
Write-Host "`n--- Test Execution ---"
if ($pkg.scripts.test) {
Write-Host "Test command available: npm test"
Write-Host "ℹ️ Run 'npm test' to execute tests"
} else {
Write-Host "⚠️ No test script in package.json"
}
19. Accessibility Audit
Check WebViews for accessibility compliance:
# === ACCESSIBILITY AUDIT ===
$extPath = "platforms/vscode-extension"
Write-Host "=== ACCESSIBILITY ===" -ForegroundColor Cyan
# 19a. ARIA labels in WebViews
Write-Host "`n--- ARIA Labels ---"
$webviewFiles = Get-ChildItem "$extPath/src/**/*.ts" -Recurse |
Select-String -Pattern 'html\s*[`=]|getWebviewContent|<button|<input' -List
$ariaUsage = Select-String -Path "$extPath/src/**/*.ts" -Pattern 'aria-|role=' -Recurse
$ariaCount = $ariaUsage.Count
Write-Host "WebView files: $($webviewFiles.Count)"
Write-Host "ARIA attributes: $ariaCount"
if ($webviewFiles.Count -gt 0 -and $ariaCount -lt $webviewFiles.Count * 2) {
Write-Host "⚠️ Consider adding more ARIA labels for screen readers" -ForegroundColor Yellow
} else {
Write-Host "✅ ARIA usage appears adequate"
}
# 19b. Keyboard navigation
Write-Host "`n--- Keyboard Navigation ---"
$tabindex = Select-String -Path "$extPath/src/**/*.ts" -Pattern 'tabindex|tabIndex' -Recurse
$keyHandlers = Select-String -Path "$extPath/src/**/*.ts" -Pattern 'onkeydown|onkeyup|onkeypress|addEventListener.*key' -Recurse
Write-Host "Tabindex usage: $($tabindex.Count)"
Write-Host "Key handlers: $($keyHandlers.Count)"
if ($webviewFiles.Count -gt 0 -and $keyHandlers.Count -eq 0) {
Write-Host "⚠️ No keyboard handlers - buttons may not be keyboard accessible" -ForegroundColor Yellow
}
# 19c. Color contrast (check for hardcoded colors)
Write-Host "`n--- Color Usage ---"
$hardcodedColors = Select-String -Path "$extPath/src/**/*.ts" -Pattern '#[0-9a-fA-F]{3,6}|rgb\(|rgba\(' -Recurse
$cssVariables = Select-String -Path "$extPath/src/**/*.ts" -Pattern 'var\(--vscode-' -Recurse
Write-Host "Hardcoded colors: $($hardcodedColors.Count)"
Write-Host "VS Code CSS variables: $($cssVariables.Count)"
if ($hardcodedColors.Count -gt $cssVariables.Count) {
Write-Host "⚠️ Prefer VS Code CSS variables for theme compatibility" -ForegroundColor Yellow
} else {
Write-Host "✅ Good use of theme-aware colors"
}
# 19d. Alt text for images
Write-Host "`n--- Image Alt Text ---"
$images = Select-String -Path "$extPath/src/**/*.ts" -Pattern '<img' -Recurse
$altText = Select-String -Path "$extPath/src/**/*.ts" -Pattern '<img[^>]*alt=' -Recurse
if ($images.Count -gt 0) {
Write-Host "Images: $($images.Count) | With alt: $($altText.Count)"
if ($altText.Count -lt $images.Count) {
Write-Host "⚠️ Some images missing alt text" -ForegroundColor Yellow
}
} else {
Write-Host "✅ No images requiring alt text"
}
20. Localization Audit
Check for i18n readiness and hardcoded strings:
# === LOCALIZATION AUDIT ===
$extPath = "platforms/vscode-extension"
Write-Host "=== LOCALIZATION ===" -ForegroundColor Cyan
# 20a. Check for l10n setup
Write-Host "`n--- i18n Configuration ---"
$hasL10n = Test-Path "$extPath/l10n" -or Test-Path "$extPath/package.nls.json"
$hasVscodeL10n = Select-String -Path "$extPath/src/**/*.ts" -Pattern 'vscode\.l10n|nls\.' -Recurse
Write-Host "l10n folder/nls file: $(if($hasL10n){'✅ Found'}else{'⚠️ Not configured'})"
Write-Host "l10n API usage: $($hasVscodeL10n.Count) instances"
# 20b. Hardcoded user-facing strings
Write-Host "`n--- Hardcoded Strings ---"
$userFacingPatterns = @(
'showInformationMessage\s*\(\s*[`''"]',
'showWarningMessage\s*\(\s*[`''"]',
'showErrorMessage\s*\(\s*[`''"]',
'label:\s*[''"]',
'title:\s*[''"]',
'description:\s*[''"]',
'placeHolder:\s*[''"]'
)
$hardcodedStrings = @()
foreach ($pattern in $userFacingPatterns) {
$matches = Select-String -Path "$extPath/src/**/*.ts" -Pattern $pattern -Recurse
$hardcodedStrings += $matches
}
Write-Host "Hardcoded UI strings: $($hardcodedStrings.Count)"
if ($hardcodedStrings.Count -gt 50) {
Write-Host "ℹ️ Many hardcoded strings - consider l10n for internationalization"
} else {
Write-Host "✅ Manageable string count"
}
# 20c. Command titles in package.json
Write-Host "`n--- Command Localization ---"
$pkg = Get-Content "$extPath/package.json" | ConvertFrom-Json
$commandCount = $pkg.contributes.commands.Count
$nlsFile = "$extPath/package.nls.json"
if (Test-Path $nlsFile) {
$nls = Get-Content $nlsFile | ConvertFrom-Json
$nlsKeys = ($nls.PSObject.Properties).Count
Write-Host "Commands: $commandCount | NLS keys: $nlsKeys"
Write-Host "✅ Localization file exists"
} else {
Write-Host "Commands: $commandCount (not localized)"
Write-Host "ℹ️ Create package.nls.json for marketplace localization"
}
21. Asset Integrity Audit
Check for unused assets, missing icons, and broken references:
# === ASSET INTEGRITY AUDIT ===
$extPath = "platforms/vscode-extension"
Write-Host "=== ASSET INTEGRITY ===" -ForegroundColor Cyan
# 21a. Icon files
Write-Host "`n--- Extension Icons ---"
$pkg = Get-Content "$extPath/package.json" | ConvertFrom-Json
$iconPath = $pkg.icon
if ($iconPath) {
$iconExists = Test-Path "$extPath/$iconPath"
Write-Host "Icon: $iconPath $(if($iconExists){'✅'}else{'❌ MISSING'})"
if ($iconExists) {
$iconFile = Get-Item "$extPath/$iconPath"
$sizeKB = [math]::Round($iconFile.Length / 1KB, 1)
Write-Host "Size: $sizeKB KB $(if($sizeKB -gt 100){'⚠️ Large'}else{'✅'})"
}
} else {
Write-Host "⚠️ No icon defined in package.json"
}
# 21b. Asset folder inventory
Write-Host "`n--- Asset Files ---"
$assetFolders = @('assets', 'images', 'icons', 'media', 'resources')
foreach ($folder in $assetFolders) {
$path = "$extPath/$folder"
if (Test-Path $path) {
$files = Get-ChildItem $path -Recurse -File
$totalSize = ($files | Measure-Object Length -Sum).Sum / 1KB
Write-Host "$folder/: $($files.Count) files, $([math]::Round($totalSize, 1)) KB"
}
}
# 21c. Referenced but missing assets
Write-Host "`n--- Asset References ---"
$assetRefs = Select-String -Path "$extPath/src/**/*.ts" -Pattern '\.(png|jpg|jpeg|gif|svg|ico)' -Recurse
$referencedAssets = $assetRefs | ForEach-Object {
[regex]::Match($_.Line, '[''"`]([^''"`]*\.(png|jpg|jpeg|gif|svg|ico))[''"`]').Groups[1].Value
} | Where-Object { $_ } | Sort-Object -Unique
$missingAssets = @()
foreach ($asset in $referencedAssets) {
$assetPath = Join-Path $extPath $asset
if (-not (Test-Path $assetPath) -and $asset -notmatch '^https?://') {
$missingAssets += $asset
}
}
if ($missingAssets.Count -gt 0) {
Write-Host "❌ Missing referenced assets:"
$missingAssets | ForEach-Object { Write-Host " - $_" }
} else {
Write-Host "✅ All referenced assets exist"
}
# 21d. Unused assets
Write-Host "`n--- Unused Assets ---"
$allAssets = Get-ChildItem "$extPath" -Recurse -Include "*.png","*.jpg","*.svg","*.ico" -File |
Where-Object { $_.FullName -notmatch 'node_modules' }
$codeContent = Get-ChildItem "$extPath/src" -Recurse -Include "*.ts" -File | Get-Content -Raw
$pkgContent = Get-Content "$extPath/package.json" -Raw
$unusedAssets = $allAssets | Where-Object {
$name = $_.Name
-not ($codeContent -match [regex]::Escape($name)) -and
-not ($pkgContent -match [regex]::Escape($name))
}
if ($unusedAssets.Count -gt 0) {
Write-Host "⚠️ Possibly unused assets:"
$unusedAssets | ForEach-Object { Write-Host " - $($_.Name)" }
} else {
Write-Host "✅ No obviously unused assets"
}
22. Configuration Files Audit
Check launch.json, tasks.json, tsconfig alignment:
# === CONFIGURATION FILES AUDIT ===
$extPath = "platforms/vscode-extension"
Write-Host "=== CONFIGURATION FILES ===" -ForegroundColor Cyan
# 22a. launch.json validation
Write-Host "`n--- launch.json ---"
$launchPath = "$extPath/.vscode/launch.json"
if (Test-Path $launchPath) {
try {
$launch = Get-Content $launchPath -Raw | ConvertFrom-Json
$configs = $launch.configurations.Count
Write-Host "✅ Valid JSON with $configs configuration(s)"
# Check for Extension Development Host config
$extDevHost = $launch.configurations | Where-Object { $_.type -eq 'extensionHost' }
if ($extDevHost) {
Write-Host "✅ Extension Development Host configured"
} else {
Write-Host "⚠️ No extensionHost configuration - F5 won't work"
}
} catch {
Write-Host "❌ Invalid JSON: $_" -ForegroundColor Red
}
} else {
Write-Host "⚠️ No launch.json found"
}
# 22b. tasks.json validation
Write-Host "`n--- tasks.json ---"
$tasksPath = "$extPath/.vscode/tasks.json"
if (Test-Path $tasksPath) {
try {
$tasks = Get-Content $tasksPath -Raw | ConvertFrom-Json
Write-Host "✅ Valid JSON with $($tasks.tasks.Count) task(s)"
# Check for watch task
$watchTask = $tasks.tasks | Where-Object { $_.label -match 'watch' -or $_.script -eq 'watch' }
if ($watchTask) {
Write-Host "✅ Watch task configured"
}
} catch {
Write-Host "❌ Invalid JSON: $_" -ForegroundColor Red
}
} else {
Write-Host "ℹ️ No tasks.json (optional)"
}
# 22c. tsconfig.json validation
Write-Host "`n--- tsconfig.json ---"
$tsconfigPath = "$extPath/tsconfig.json"
if (Test-Path $tsconfigPath) {
try {
# tsconfig may have comments, use a simple check
$content = Get-Content $tsconfigPath -Raw
if ($content -match '"compilerOptions"') {
Write-Host "✅ tsconfig.json exists"
# Check key settings
$strict = $content -match '"strict"\s*:\s*true'
$esModule = $content -match '"esModuleInterop"\s*:\s*true'
$outDir = [regex]::Match($content, '"outDir"\s*:\s*"([^"]+)"').Groups[1].Value
Write-Host "Strict mode: $(if($strict){'✅'}else{'⚠️ Not enabled'})"
Write-Host "ES Module Interop: $(if($esModule){'✅'}else{'⚠️'})"
Write-Host "Output dir: $outDir"
}
} catch {
Write-Host "⚠️ Could not parse tsconfig"
}
} else {
Write-Host "❌ No tsconfig.json found!" -ForegroundColor Red
}
# 22d. .vscodeignore validation
Write-Host "`n--- .vscodeignore ---"
$ignorePath = "$extPath/.vscodeignore"
if (Test-Path $ignorePath) {
$ignoreContent = Get-Content $ignorePath
$requiredIgnores = @('src/', 'node_modules/', '.vscode/', '*.ts', 'tsconfig.json')
$missing = $requiredIgnores | Where-Object {
$pattern = $_
-not ($ignoreContent | Where-Object { $_ -eq $pattern -or $_ -eq "$pattern*" })
}
if ($missing.Count -gt 0) {
Write-Host "⚠️ Consider adding to .vscodeignore: $($missing -join ', ')"
} else {
Write-Host "✅ .vscodeignore properly configured"
}
# Check package size impact
$lines = $ignoreContent.Count
Write-Host "Ignore rules: $lines"
} else {
Write-Host "⚠️ No .vscodeignore - extension may be bloated"
}
# 22e. esbuild/webpack config
Write-Host "`n--- Build Config ---"
$buildConfigs = @('esbuild.js', 'esbuild.config.js', 'webpack.config.js', 'rollup.config.js')
$foundBuild = $buildConfigs | Where-Object { Test-Path "$extPath/$_" }
if ($foundBuild) {
Write-Host "✅ Build config: $($foundBuild -join ', ')"
} else {
Write-Host "ℹ️ No custom build config (using npm scripts)"
}
Inheritable Audit Summary
| # | Audit Area | Checks | Severity |
|---|---|---|---|
| 10 | UI Audit | Dead buttons, window.open, location.reload | 🟡 Medium |
| 11 | Dependency Health | npm audit, outdated, unused | 🔴 High |
| 12 | TypeScript & Lint | Compile errors, ESLint, dead code | 🔴 High |
| 13 | Security | Secrets, CSP, input sanitization | 🔴 High |
| 14 | Bundle Size | Extension size, package estimate | 🟡 Medium |
| 15 | Git Hygiene | Uncommitted, large files, branch | 🟡 Medium |
| 16 | Changelog | Format, versions, categories | 🟡 Medium |
| 17 | API Compatibility | Deprecated APIs, engine version | 🟡 Medium |
| 18 | Test Coverage | Test files, framework, gaps | 🟡 Medium |
| 19 | Accessibility | ARIA, keyboard, colors, alt text | 🟢 Low |
| 20 | Localization | i18n setup, hardcoded strings | 🟢 Low |
| 21 | Asset Integrity | Icons, missing/unused assets | 🟢 Low |
| 22 | Configuration | launch.json, tsconfig, vscodeignore | 🟢 Low |
Consistency Reference (What Must Match)
Version Numbers
These locations must all show the same version:
| Location | File | Pattern |
|---|---|---|
| Package.json | platforms/vscode-extension/package.json |
"version": "X.Y.Z" |
| Copilot Instructions | .github/copilot-instructions.md |
**Version**: X.Y.Z |
| M365 Agent | platforms/m365-copilot/appPackage/declarativeAgent.json |
"version": "X.Y.Z" |
| Changelog | CHANGELOG.md |
## [X.Y.Z] (latest) |
| Quick Reference | alex_docs/QUICK-REFERENCE.md |
Version table |
Note: Historical files (UPGRADE-MIGRATION-PLAN.md, VSCODE-EXTENSIONS-ANALYSIS.md) may have old versions - that's OK if they're documenting history.
Skill Count
These locations must show the actual skill count:
| Location | File | Pattern |
|---|---|---|
| Copilot Instructions | .github/copilot-instructions.md |
In stats section |
| Skills Catalog | alex_docs/SKILLS-CATALOG.md |
## Skill Count: N |
| Cognitive Architecture | alex_docs/COGNITIVE-ARCHITECTURE.md |
Skills mention |
| Quick Reference | alex_docs/QUICK-REFERENCE.md |
Skills summary |
| Network Diagram | alex_docs/SKILLS-CATALOG.md |
Mermaid nodes |
Current: 47 skills (check with (Get-ChildItem ".github/skills" -Directory).Count)
MCP Tool Count
| Location | File | Pattern |
|---|---|---|
| Package.json | platforms/vscode-extension/package.json |
contributes.languageModelTools |
| User Manual | alex_docs/USER-MANUAL.md |
Tools section |
| Copilot Instructions | .github/copilot-instructions.md |
Stats |
Current: 11 tools
Command Count
| Location | File | Pattern |
|---|---|---|
| Package.json | platforms/vscode-extension/package.json |
contributes.commands |
| User Manual | alex_docs/USER-MANUAL.md |
Commands section |
Current: Check with (Get-Content "platforms/vscode-extension/package.json" | ConvertFrom-Json).contributes.commands.Count
Identity/Name Consistency
| Term | Correct Form | Incorrect Forms |
|---|---|---|
| Product name | Alex Cognitive Architecture | Alex Extension, Alex Plugin |
| Short name | Alex | ALEX, alex (in headings) |
| Extension ID | fabioc-aloha.alex-cognitive-architecture |
Any variation |
| Publisher | fabioc-aloha | fabioc, aloha |
Deprecated Terms (Never Use)
| Deprecated | Replacement | Reason |
|---|---|---|
DK-*.md |
skills/*/SKILL.md |
Format migration 2026-01 |
domain-knowledge/ |
skills/ |
Folder rename |
domain knowledge files |
skills |
Terminology update |
Exception: Historical documentation (migration guides, upgrade plans) may reference deprecated terms when explaining the migration.
File Path Consistency
| Logical Location | Actual Path |
|---|---|
| Master copilot instructions | .github/copilot-instructions.md |
| Skills folder | .github/skills/ |
| Instructions folder | .github/instructions/ |
| Prompts folder | .github/prompts/ |
| VS Code extension | platforms/vscode-extension/ |
| M365 agent | platforms/m365-copilot/ |
| Documentation | alex_docs/ |
| Protection marker | .github/config/MASTER-ALEX-PROTECTED.json |
Diagram Node Abbreviations
The skill network diagram uses these abbreviations:
| Abbrev | Skill |
|---|---|
| BL | bootstrap-learning |
| LP | learning-psychology |
| CL | cognitive-load |
| AR | appropriate-reliance |
| AH | architecture-health |
| AAU | architecture-audit |
| MAA | master-alex-audit |
| HC | heir-curation |
| MED | meditation |
| SA | self-actualization |
| ... | (see SKILLS-CATALOG.md for full list) |
Master Audit Report Template
# Master Alex Audit Report
**Date:** {{DATE}}
**Version:** {{VERSION}}
**Auditor:** Alex + {{USER}}
## Summary
| Check | Status | Notes |
|-------|--------|-------|
| Version Alignment | ✅/⚠️/❌ | |
| Heir Sync | ✅/⚠️/❌ | |
| Skill Inheritance | ✅/⚠️/❌ | |
| Safety Imperatives | ✅/⚠️/❌ | |
| Build Artifacts | ✅/⚠️/❌ | |
| Documentation Refs | ✅/⚠️/❌ | |
| Synapse Health | ✅/⚠️/❌ | |
| alex_docs Audit | ✅/⚠️/❌ | |
## Detailed Findings
### Critical Issues (Must Fix)
-
### Warnings (Should Fix)
-
### Observations (Nice to Have)
-
## Actions Taken
1.
2.
## Next Steps
-
Quick Master Audit Commands
Copy-paste ready audit sequence:
# === MASTER ALEX QUICK AUDIT ===
cd "C:\Development\Alex_Plug_In"
# 1. Git status
Write-Host "`n=== GIT STATUS ===" -ForegroundColor Cyan
git status --short
# 2. Version check
Write-Host "`n=== VERSION CHECK ===" -ForegroundColor Cyan
$pkgVersion = (Get-Content "platforms/vscode-extension/package.json" | ConvertFrom-Json).version
$copilotVersion = [regex]::Match((Get-Content ".github/copilot-instructions.md" -Raw), '\*\*Version\*\*:\s*(\d+\.\d+\.\d+)').Groups[1].Value
Write-Host "Package: v$pkgVersion"
Write-Host "Copilot: v$copilotVersion"
if ($pkgVersion -eq $copilotVersion) { Write-Host "✅ Versions match" -ForegroundColor Green }
else { Write-Host "❌ Version mismatch!" -ForegroundColor Red }
# 3. Protection check
Write-Host "`n=== PROTECTION CHECK ===" -ForegroundColor Cyan
$protected = Test-Path ".github/config/MASTER-ALEX-PROTECTED.json"
Write-Host "Kill switch marker: $(if($protected){'✅'}else{'❌'})"
# 4. Skill count
Write-Host "`n=== SKILL COUNT ===" -ForegroundColor Cyan
$skillCount = (Get-ChildItem ".github/skills" -Directory).Count
Write-Host "Skills: $skillCount"
# 5. Build freshness
Write-Host "`n=== BUILD STATUS ===" -ForegroundColor Cyan
$dist = Get-Item "platforms/vscode-extension/dist/extension.js" -ErrorAction SilentlyContinue
if ($dist) {
$age = [int]((Get-Date) - $dist.LastWriteTime).TotalHours
Write-Host "Build age: $age hours"
} else {
Write-Host "⚠️ No build found"
}
Write-Host "`n=== AUDIT COMPLETE ===" -ForegroundColor Green
Synapses
See synapses.json for connections to:
architecture-audit(extends) - Generic audit foundationrelease-preflight- Pre-release verificationheir-curation- Heir managementarchitecture-health- Structural integrityvscode-extension-patterns- Extension-specific knowledge