Public/Test-CCRepoHealth.ps1

function Test-CCRepoHealth {
    [CmdletBinding()]
    param(
        [string]$Path = '.',
        [ValidateSet('core','active','minimal')][string]$Standard = 'core',
        [string]$Config,
        [switch]$Detailed,
        [ValidateSet('Console','Json','Quiet')][string]$OutputFormat = 'Console',
        [ValidateSet('Error','Warning')][string]$FailOn
    )

    $Path = (Resolve-Path $Path -ErrorAction Stop).Path

    $splat = @{ Path = $Path; Standard = $Standard; Config = $Config }
    $allResults = @()

    $allResults += Test-CCFilePresence @splat
    $allResults += Test-CCFolderStructure @splat
    $allResults += Test-CCDocumentation @splat
    $allResults += Test-CCDependencies @splat
    $allResults += Test-CCCIConfiguration @splat

    # Security checks inline (simple enough to not need a separate file)
    $cfg = Get-CCRepoConfig -Path $Path -Standard $Standard -ConfigFile $Config
    $disabled = $cfg['disabled_checks'] ?? @()

    # SEC-001: .gitignore covers secret patterns
    if ('SEC-001' -notin $disabled -and $cfg['security_forbidden'].Count -gt 0) {
        $gitignorePath = Join-Path $Path '.gitignore'
        if (Test-Path $gitignorePath) {
            $gitignoreContent = Get-Content $gitignorePath -Raw
            $uncovered = @()
            foreach ($pattern in $cfg['security_forbidden']) {
                if ($gitignoreContent -notmatch [regex]::Escape($pattern)) {
                    $uncovered += $pattern
                }
            }
            if ($uncovered.Count -eq 0) {
                $allResults += New-CCRepoCheckResult -CheckId 'SEC-001' -Category 'Security' `
                    -Item '.gitignore secrets' -Status 'Pass' -Severity 'Error' `
                    -Message ".gitignore covers all secret patterns" -Standard $Standard
            }
            else {
                $allResults += New-CCRepoCheckResult -CheckId 'SEC-001' -Category 'Security' `
                    -Item '.gitignore secrets' -Status 'Warning' -Severity 'Warning' `
                    -Message ".gitignore missing patterns: $($uncovered -join ', ')" -Standard $Standard `
                    -FixAvailable $true -FixAction "Add patterns to .gitignore"
            }
        }
        else {
            $allResults += New-CCRepoCheckResult -CheckId 'SEC-001' -Category 'Security' `
                -Item '.gitignore secrets' -Status 'Skipped' -Severity 'Error' `
                -Message ".gitignore not found" -Standard $Standard
        }
    }

    # Output handling
    switch ($OutputFormat) {
        'Json' {
            $allResults | ConvertTo-Json -Depth 5
        }
        'Quiet' {
            # No output, just set exit code
        }
        default {
            # Console output
            $pass = ($allResults | Where-Object Status -eq 'Pass').Count
            $fail = ($allResults | Where-Object Status -eq 'Fail').Count
            $warn = ($allResults | Where-Object Status -eq 'Warning').Count
            $skip = ($allResults | Where-Object Status -eq 'Skipped').Count

            if ($Detailed) {
                $grouped = $allResults | Group-Object Category
                foreach ($group in $grouped) {
                    Write-Host "`n $($group.Name)" -ForegroundColor Cyan
                    foreach ($r in $group.Group) {
                        $icon = switch ($r.Status) {
                            'Pass'    { '[PASS]' }
                            'Fail'    { '[FAIL]' }
                            'Warning' { '[WARN]' }
                            'Skipped' { '[SKIP]' }
                        }
                        $color = switch ($r.Status) {
                            'Pass'    { 'Green' }
                            'Fail'    { 'Red' }
                            'Warning' { 'Yellow' }
                            'Skipped' { 'DarkGray' }
                        }
                        Write-Host " $icon $($r.CheckId): $($r.Message)" -ForegroundColor $color
                    }
                }
            }

            Write-Host "`n Repository Health ($Standard): " -NoNewline
            if ($fail -eq 0) {
                Write-Host "HEALTHY" -ForegroundColor Green
            }
            else {
                Write-Host "$fail ISSUE(S)" -ForegroundColor Red
            }
            Write-Host " Pass: $pass | Fail: $fail | Warning: $warn | Skipped: $skip`n"

            $allResults
        }
    }

    # FailOn exit code
    if ($FailOn) {
        $failCount = switch ($FailOn) {
            'Error'   { ($allResults | Where-Object { $_.Status -eq 'Fail' -and $_.Severity -eq 'Error' }).Count }
            'Warning' { ($allResults | Where-Object { $_.Status -in 'Fail','Warning' }).Count }
        }
        if ($failCount -gt 0) {
            $host.SetShouldExit(1)
            exit 1
        }
    }
}