Initial commit: AVWatch v1.0.0 with .gitignore and CLAUDE.md

This commit is contained in:
2026-09-24 13:07:21 -04:00
commit ea70a9cb5f
38 changed files with 9604 additions and 0 deletions
+79
View File
@@ -0,0 +1,79 @@
<#
.SYNOPSIS
Wrapper that Windows Task Scheduler calls. Runs one avwatch command and
writes a timestamped log.
.DESCRIPTION
Kept deliberately thin: it resolves the project folder, prefers a local
virtual environment if one exists, runs the command, and keeps the last
30 logs. Secrets come from the user's environment variables, which the
scheduled task inherits because it runs as that user.
.EXAMPLE
.\run_avwatch.ps1 -Command scan
.\run_avwatch.ps1 -Command digest
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
[ValidateSet('scan', 'digest')]
[string]$Command,
[string]$ProjectRoot,
[string[]]$ExtraArgs = @()
)
$ErrorActionPreference = 'Stop'
if (-not $ProjectRoot) {
$ProjectRoot = Split-Path -Parent $PSScriptRoot
}
Set-Location $ProjectRoot
$logDir = Join-Path $ProjectRoot 'logs'
if (-not (Test-Path $logDir)) {
New-Item -ItemType Directory -Path $logDir -Force | Out-Null
}
$stamp = Get-Date -Format 'yyyy-MM-dd_HHmm'
$logFile = Join-Path $logDir "$Command`_$stamp.log"
# Prefer a project virtualenv if present, else whatever python is on PATH.
$venvPython = Join-Path $ProjectRoot '.venv\Scripts\python.exe'
if (Test-Path $venvPython) {
$python = $venvPython
} else {
$cmd = Get-Command python -ErrorAction SilentlyContinue
if (-not $cmd) {
"FATAL: no python found on PATH and no .venv present" | Out-File $logFile -Encoding utf8
exit 1
}
$python = $cmd.Source
}
"=== avwatch $Command @ $(Get-Date -Format 'u') ===" | Out-File $logFile -Encoding utf8
"python: $python" | Out-File $logFile -Append -Encoding utf8
"root: $ProjectRoot" | Out-File $logFile -Append -Encoding utf8
# Report which credentials are visible, without ever logging their values.
foreach ($name in 'ANTHROPIC_API_KEY', 'AVWATCH_SMTP_PASSWORD',
'AVWATCH_GITHUB_TOKEN', 'AVWATCH_REDDIT_CLIENT_ID') {
$present = if ([Environment]::GetEnvironmentVariable($name)) { 'set' } else { 'NOT SET' }
"$name`: $present" | Out-File $logFile -Append -Encoding utf8
}
"" | Out-File $logFile -Append -Encoding utf8
$argList = @('-m', 'avwatch', $Command) + $ExtraArgs
& $python $argList *>&1 | Out-File $logFile -Append -Encoding utf8
$code = $LASTEXITCODE
"" | Out-File $logFile -Append -Encoding utf8
"=== exit code $code @ $(Get-Date -Format 'u') ===" | Out-File $logFile -Append -Encoding utf8
# Keep the last 30 logs so this never fills a booth machine's disk.
Get-ChildItem $logDir -Filter '*.log' |
Sort-Object LastWriteTime -Descending |
Select-Object -Skip 30 |
Remove-Item -Force -ErrorAction SilentlyContinue
exit $code