73 lines
2.3 KiB
PowerShell
73 lines
2.3 KiB
PowerShell
$ErrorActionPreference = "Stop"
|
|
|
|
function Get-TaipeiNow {
|
|
try {
|
|
$tz = [TimeZoneInfo]::FindSystemTimeZoneById("Taipei Standard Time")
|
|
return [TimeZoneInfo]::ConvertTime([DateTimeOffset]::Now, $tz)
|
|
} catch {
|
|
return [DateTimeOffset]::Now
|
|
}
|
|
}
|
|
|
|
try {
|
|
$statePath = ".kiro/.audit_state.json"
|
|
if (-not (Test-Path $statePath)) { exit 0 }
|
|
|
|
$state = $null
|
|
try { $state = Get-Content $statePath -Raw | ConvertFrom-Json } catch { exit 0 }
|
|
if (-not $state) { exit 0 }
|
|
|
|
# If no pending audit, do nothing
|
|
if (-not $state.audit_required) { exit 0 }
|
|
|
|
# If working tree is clean (ignoring logs/state), stop reminding
|
|
$null = git rev-parse --is-inside-work-tree 2>$null
|
|
if ($LASTEXITCODE -ne 0) { exit 0 }
|
|
$status = git status --porcelain
|
|
$files = @()
|
|
foreach ($line in $status) {
|
|
if ([string]::IsNullOrWhiteSpace($line)) { continue }
|
|
$pathPart = $line.Substring([Math]::Min(3, $line.Length-1)).Trim()
|
|
if ($pathPart -match " -> ") { $pathPart = ($pathPart -split " -> ")[-1] }
|
|
$p = $pathPart.Replace("\", "/").Trim()
|
|
if ($p -and $p -notmatch "^docs/audit/" -and $p -notmatch "^\.kiro/") { $files += $p }
|
|
}
|
|
if (($files | Sort-Object -Unique).Count -eq 0) {
|
|
$state.audit_required = $false
|
|
$state.reasons = @()
|
|
$state.changed_files = @()
|
|
$state.last_reminded_at = $null
|
|
($state | ConvertTo-Json -Depth 6) | Set-Content -Path $statePath -Encoding UTF8
|
|
exit 0
|
|
}
|
|
|
|
$now = Get-TaipeiNow
|
|
$minInterval = [TimeSpan]::FromMinutes(15)
|
|
|
|
$last = $null
|
|
if ($state.last_reminded_at) {
|
|
try { $last = [DateTimeOffset]::Parse($state.last_reminded_at) } catch { $last = $null }
|
|
}
|
|
|
|
$shouldRemind = $true
|
|
if ($last) {
|
|
$elapsed = $now - $last
|
|
if ($elapsed -lt $minInterval) { $shouldRemind = $false }
|
|
}
|
|
|
|
if (-not $shouldRemind) { exit 0 }
|
|
|
|
# Update last_reminded_at (persist even if user ignores)
|
|
$state.last_reminded_at = $now.ToString("o")
|
|
($state | ConvertTo-Json -Depth 6) | Set-Content -Path $statePath -Encoding UTF8
|
|
|
|
$reasons = @()
|
|
if ($state.reasons) { $reasons = @($state.reasons) }
|
|
$reasonText = if ($reasons.Count -gt 0) { ($reasons -join ", ") } else { "high-risk paths changed" }
|
|
|
|
[Console]::Error.WriteLine("[AUDIT REMINDER] Pending audit detected ($reasonText). Run /audit (Manual: Run /audit hook) to sync docs & write audit artifacts. (rate limit: 15min)")
|
|
exit 1
|
|
} catch {
|
|
exit 0
|
|
}
|