Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 49 additions & 13 deletions scripts/powershell/site-audit.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ function Get-FileCategories {
$excludePattern = '(^|[/\\])(' + (($excludeDirs | ForEach-Object { [regex]::Escape($_) }) -join '|') + ')([/\\]|$)'

# Get all files, excluding common directories
$allFiles = Get-ChildItem -Path $RepoRoot -Recurse -File -ErrorAction SilentlyContinue |
$allFiles = Get-ChildItem -Path $RepoRoot -Recurse -File -Force -ErrorAction SilentlyContinue |
Where-Object { $_.FullName -notmatch $excludePattern }

foreach ($file in $allFiles) {
Expand All @@ -164,6 +164,16 @@ function Get-FileCategories {
continue
}

# Check build files by path/name first so that workflow .yml files are not
# claimed by the config extension check below.
if ($relativePath -match '(^|[/\\])\.github[/\\]workflows[/\\]' -or
$name -match '^dockerfile' -or
$name -eq 'makefile' -or
$ext -in @('.gradle', '.maven')) {
$categories.build += $relativePath
continue
}

# Check config by extension or env files
if ($ext -in $configExtensions -or $name -match '^\.env' -or $name -match 'rc$') {
$categories.config += $relativePath
Expand All @@ -181,14 +191,6 @@ function Get-FileCategories {
$categories.scripts += $relativePath
continue
}

# Check build files
if ($relativePath -match '\.github/workflows/' -or
$name -match '^dockerfile' -or
$name -eq 'makefile' -or
$ext -in @('.gradle', '.maven')) {
$categories.build += $relativePath
}
}

return $categories
Expand Down Expand Up @@ -468,6 +470,37 @@ function Get-PatternDetection {
return $patterns
}

function Get-SpeckitVersion {
param([string]$RepoRoot)

$stampPath = Join-Path $RepoRoot '.documentation/SPECKIT_VERSION'
$info = @{
stamp_exists = $false
installed_version = $null
installed_date = $null
agent = $null
}

if (Test-Path $stampPath) {
$info.stamp_exists = $true
try {
$lines = @(Get-Content $stampPath -ErrorAction SilentlyContinue)
if ($lines.Count -gt 0) {
$info.installed_version = $lines[0].Trim()
}
foreach ($line in $lines) {
if ($line -match '^installed:\s*(.+)$') {
$info.installed_date = $matches[1].Trim()
} elseif ($line -match '^agent:\s*(.+)$') {
$info.agent = $matches[1].Trim()
}
}
} catch { }
}

return $info
}

function Get-ConstitutionInfo {
param([string]$RepoRoot)

Expand Down Expand Up @@ -514,13 +547,15 @@ function Get-SampledItems {
# Main execution
$repoRoot = Get-RepoRoot
$constitutionInfo = Get-ConstitutionInfo -RepoRoot $repoRoot
$speckitVersion = Get-SpeckitVersion -RepoRoot $repoRoot

# Build result object
$result = @{
timestamp = (Get-Date -Format 'yyyy-MM-ddTHH:mm:ssZ')
scope = $Scope
repo_root = $repoRoot
constitution = $constitutionInfo
speckit = $speckitVersion
audit_dir = '.documentation/copilot/audit'
}

Expand Down Expand Up @@ -607,6 +642,7 @@ if ($OutputFormat -eq 'json') {
Write-Output "Repository: $repoRoot"
Write-Output "Scope: $Scope"
Write-Output "Constitution: $(if ($constitutionInfo.exists) { 'Found' } else { 'MISSING' })"
Write-Output "Spec Kit Version: $(if ($speckitVersion.stamp_exists) { $speckitVersion.installed_version } else { 'absent' })"
Write-Output ""
Write-Output "File Counts:"
Write-Output " Source files: $($fileCategories.source.Count)"
Expand All @@ -629,14 +665,14 @@ if ($OutputFormat -eq 'json') {
Write-Output "Code Metrics:"
Write-Output " Total lines: $($result.metrics.total_lines)"
Write-Output " Avg lines/file: $($result.metrics.avg_lines_per_file)"
Write-Output " Large files (>500 lines): $($result.metrics.large_files.Count)"
Write-Output " Large files (>500 lines): $($result.metrics.large_files_total)"
}

if ($result.patterns) {
Write-Output ""
Write-Output "Pattern Detection:"
Write-Output " Potential secrets: $($result.patterns.security.hardcoded_secrets.Count)"
Write-Output " Insecure patterns: $($result.patterns.security.insecure_patterns.Count)"
Write-Output " TODO/FIXME comments: $($result.patterns.quality.todo_comments.Count)"
Write-Output " Potential secrets: $($result.patterns.security.hardcoded_secrets_total)"
Write-Output " Insecure patterns: $($result.patterns.security.insecure_patterns_total)"
Write-Output " TODO/FIXME comments: $($result.patterns.quality.todo_comments_total)"
}
}
Loading