patchwarden 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Check-PatchWarden-Health.cmd +6 -0
- package/LICENSE +21 -0
- package/README.md +526 -0
- package/Reset-PatchWarden-Tunnel-Key.cmd +6 -0
- package/Restart-PatchWarden.cmd +19 -0
- package/Start-PatchWarden-Tunnel.cmd +7 -0
- package/dist/config.d.ts +24 -0
- package/dist/config.js +131 -0
- package/dist/doctor.d.ts +10 -0
- package/dist/doctor.js +388 -0
- package/dist/errors.d.ts +16 -0
- package/dist/errors.js +27 -0
- package/dist/httpServer.d.ts +17 -0
- package/dist/httpServer.js +255 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +24 -0
- package/dist/runner/changeCapture.d.ts +43 -0
- package/dist/runner/changeCapture.js +245 -0
- package/dist/runner/cli.d.ts +9 -0
- package/dist/runner/cli.js +26 -0
- package/dist/runner/runTask.d.ts +8 -0
- package/dist/runner/runTask.js +821 -0
- package/dist/runner/watch.d.ts +19 -0
- package/dist/runner/watch.js +136 -0
- package/dist/security/commandGuard.d.ts +22 -0
- package/dist/security/commandGuard.js +56 -0
- package/dist/security/contentRedaction.d.ts +12 -0
- package/dist/security/contentRedaction.js +65 -0
- package/dist/security/pathGuard.d.ts +3 -0
- package/dist/security/pathGuard.js +98 -0
- package/dist/security/planGuard.d.ts +1 -0
- package/dist/security/planGuard.js +65 -0
- package/dist/security/sensitiveGuard.d.ts +2 -0
- package/dist/security/sensitiveGuard.js +60 -0
- package/dist/smoke-test.d.ts +15 -0
- package/dist/smoke-test.js +989 -0
- package/dist/taskProgress.d.ts +6 -0
- package/dist/taskProgress.js +36 -0
- package/dist/taskRuntime.d.ts +10 -0
- package/dist/taskRuntime.js +25 -0
- package/dist/tools/auditTask.d.ts +19 -0
- package/dist/tools/auditTask.js +307 -0
- package/dist/tools/cancelTask.d.ts +30 -0
- package/dist/tools/cancelTask.js +64 -0
- package/dist/tools/createTask.d.ts +42 -0
- package/dist/tools/createTask.js +188 -0
- package/dist/tools/getPlan.d.ts +12 -0
- package/dist/tools/getPlan.js +29 -0
- package/dist/tools/getTaskFile.d.ts +24 -0
- package/dist/tools/getTaskFile.js +84 -0
- package/dist/tools/getTaskProgress.d.ts +1 -0
- package/dist/tools/getTaskProgress.js +4 -0
- package/dist/tools/getTaskStatus.d.ts +46 -0
- package/dist/tools/getTaskStatus.js +36 -0
- package/dist/tools/getTaskStdoutTail.d.ts +9 -0
- package/dist/tools/getTaskStdoutTail.js +56 -0
- package/dist/tools/getTaskSummary.d.ts +66 -0
- package/dist/tools/getTaskSummary.js +237 -0
- package/dist/tools/healthCheck.d.ts +79 -0
- package/dist/tools/healthCheck.js +230 -0
- package/dist/tools/killTask.d.ts +15 -0
- package/dist/tools/killTask.js +4 -0
- package/dist/tools/listAgents.d.ts +12 -0
- package/dist/tools/listAgents.js +42 -0
- package/dist/tools/listTasks.d.ts +36 -0
- package/dist/tools/listTasks.js +94 -0
- package/dist/tools/listWorkspace.d.ts +10 -0
- package/dist/tools/listWorkspace.js +54 -0
- package/dist/tools/readWorkspaceFile.d.ts +8 -0
- package/dist/tools/readWorkspaceFile.js +26 -0
- package/dist/tools/registry.d.ts +24 -0
- package/dist/tools/registry.js +566 -0
- package/dist/tools/retryTask.d.ts +8 -0
- package/dist/tools/retryTask.js +45 -0
- package/dist/tools/savePlan.d.ts +10 -0
- package/dist/tools/savePlan.js +28 -0
- package/dist/tools/taskOutputs.d.ts +49 -0
- package/dist/tools/taskOutputs.js +136 -0
- package/dist/tools/taskTemplates.d.ts +15 -0
- package/dist/tools/taskTemplates.js +116 -0
- package/dist/tools/toolCatalog.d.ts +19 -0
- package/dist/tools/toolCatalog.js +71 -0
- package/dist/tools/waitForTask.d.ts +25 -0
- package/dist/tools/waitForTask.js +59 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.js +2 -0
- package/dist/watcherStatus.d.ts +20 -0
- package/dist/watcherStatus.js +77 -0
- package/docs/assets/patchwarden-chatgpt-demo.svg +30 -0
- package/docs/demo.md +58 -0
- package/docs/migration-from-safe-bifrost.md +31 -0
- package/docs/release-v0.3.0.md +43 -0
- package/docs/release-v0.4.0.md +74 -0
- package/examples/config.example.json +40 -0
- package/examples/openai-tunnel/README.md +48 -0
- package/examples/openai-tunnel/chatgpt-test-prompt.md +53 -0
- package/examples/openai-tunnel/tunnel-client.example.yaml +39 -0
- package/package.json +73 -0
- package/scripts/brand-check.js +44 -0
- package/scripts/doctor-smoke.js +52 -0
- package/scripts/get-patchwarden-health.ps1 +114 -0
- package/scripts/http-mcp-smoke.js +351 -0
- package/scripts/lifecycle-smoke.js +453 -0
- package/scripts/mcp-manifest-check.js +120 -0
- package/scripts/mcp-smoke.js +336 -0
- package/scripts/pack-clean.js +142 -0
- package/scripts/patchwarden-mcp-stdio.cmd +7 -0
- package/scripts/restart-patchwarden.ps1 +242 -0
- package/scripts/start-patchwarden-tunnel.ps1 +503 -0
- package/scripts/tunnel-supervisor-smoke.js +77 -0
- package/scripts/watcher-supervisor-smoke.js +195 -0
- package/src/config.ts +165 -0
- package/src/doctor.ts +438 -0
- package/src/errors.ts +26 -0
- package/src/httpServer.ts +277 -0
- package/src/index.ts +34 -0
- package/src/runner/changeCapture.ts +304 -0
- package/src/runner/cli.ts +34 -0
- package/src/runner/runTask.ts +935 -0
- package/src/runner/watch.ts +152 -0
- package/src/security/commandGuard.ts +97 -0
- package/src/security/contentRedaction.ts +85 -0
- package/src/security/pathGuard.ts +175 -0
- package/src/security/planGuard.ts +93 -0
- package/src/security/sensitiveGuard.ts +72 -0
- package/src/smoke-test.ts +1078 -0
- package/src/taskProgress.ts +41 -0
- package/src/taskRuntime.ts +37 -0
- package/src/tools/auditTask.ts +340 -0
- package/src/tools/cancelTask.ts +70 -0
- package/src/tools/createTask.ts +337 -0
- package/src/tools/getPlan.ts +48 -0
- package/src/tools/getTaskFile.ts +111 -0
- package/src/tools/getTaskProgress.ts +5 -0
- package/src/tools/getTaskStatus.ts +85 -0
- package/src/tools/getTaskStdoutTail.ts +61 -0
- package/src/tools/getTaskSummary.ts +307 -0
- package/src/tools/healthCheck.ts +234 -0
- package/src/tools/killTask.ts +5 -0
- package/src/tools/listAgents.ts +54 -0
- package/src/tools/listTasks.ts +139 -0
- package/src/tools/listWorkspace.ts +71 -0
- package/src/tools/readWorkspaceFile.ts +41 -0
- package/src/tools/registry.ts +666 -0
- package/src/tools/retryTask.ts +53 -0
- package/src/tools/savePlan.ts +46 -0
- package/src/tools/taskOutputs.ts +155 -0
- package/src/tools/taskTemplates.ts +162 -0
- package/src/tools/toolCatalog.ts +92 -0
- package/src/tools/waitForTask.ts +90 -0
- package/src/version.ts +2 -0
- package/src/watcherStatus.ts +102 -0
- package/tsconfig.json +17 -0
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
param(
|
|
2
|
+
[switch]$SkipBuild,
|
|
3
|
+
[switch]$SkipWatcher,
|
|
4
|
+
[switch]$WhatIf,
|
|
5
|
+
[int]$KillTimeoutSeconds = 10
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
$ErrorActionPreference = "Stop"
|
|
9
|
+
$ProgressPreference = "SilentlyContinue"
|
|
10
|
+
|
|
11
|
+
$ProjectRoot = Split-Path -Parent $PSScriptRoot
|
|
12
|
+
$ConfigPath = Join-Path $ProjectRoot "patchwarden.config.json"
|
|
13
|
+
$RuntimeDirectory = Join-Path $env:LOCALAPPDATA "patchwarden\runtime"
|
|
14
|
+
|
|
15
|
+
Write-Host ""
|
|
16
|
+
Write-Host "========================================" -ForegroundColor Cyan
|
|
17
|
+
Write-Host " PatchWarden One-Click Restart" -ForegroundColor Cyan
|
|
18
|
+
Write-Host "========================================" -ForegroundColor Cyan
|
|
19
|
+
Write-Host ""
|
|
20
|
+
|
|
21
|
+
# -- 1. Find PatchWarden processes ----------------------------------
|
|
22
|
+
|
|
23
|
+
Write-Host "[1/4] Scanning for PatchWarden processes..." -ForegroundColor Yellow
|
|
24
|
+
|
|
25
|
+
$processesToKill = @()
|
|
26
|
+
try {
|
|
27
|
+
$allProcesses = Get-CimInstance Win32_Process
|
|
28
|
+
$byPid = @{}
|
|
29
|
+
foreach ($process in $allProcesses) { $byPid[[int]$process.ProcessId] = $process }
|
|
30
|
+
$seedIds = New-Object System.Collections.Generic.HashSet[int]
|
|
31
|
+
$tunnelStatusPath = Join-Path $RuntimeDirectory "tunnel-status.json"
|
|
32
|
+
$watcherStatusPath = Join-Path $RuntimeDirectory "watcher-status.json"
|
|
33
|
+
if (Test-Path -LiteralPath $tunnelStatusPath) {
|
|
34
|
+
$state = Get-Content -LiteralPath $tunnelStatusPath -Raw | ConvertFrom-Json
|
|
35
|
+
$candidate = $byPid[[int]$state.pid]
|
|
36
|
+
if ($candidate -and [string]$candidate.CommandLine -match '(?i)tunnel-client\.exe.*run.*patchwarden') {
|
|
37
|
+
[void]$seedIds.Add([int]$candidate.ProcessId)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
if (Test-Path -LiteralPath $watcherStatusPath) {
|
|
41
|
+
$state = Get-Content -LiteralPath $watcherStatusPath -Raw | ConvertFrom-Json
|
|
42
|
+
$watcherCandidate = $byPid[[int]$state.pid]
|
|
43
|
+
if ($watcherCandidate -and [string]$watcherCandidate.CommandLine -like "*$ProjectRoot*dist*runner*watch.js*") {
|
|
44
|
+
[void]$seedIds.Add([int]$watcherCandidate.ProcessId)
|
|
45
|
+
}
|
|
46
|
+
$launcherCandidate = $byPid[[int]$state.launcher_pid]
|
|
47
|
+
if ($launcherCandidate -and [string]$launcherCandidate.CommandLine -like "*$ProjectRoot*start-patchwarden-tunnel.ps1*") {
|
|
48
|
+
[void]$seedIds.Add([int]$launcherCandidate.ProcessId)
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
foreach ($seed in @($seedIds)) {
|
|
52
|
+
$current = $byPid[$seed]
|
|
53
|
+
while ($current -and [int]$current.ParentProcessId -gt 0) {
|
|
54
|
+
$parent = $byPid[[int]$current.ParentProcessId]
|
|
55
|
+
if (-not $parent) { break }
|
|
56
|
+
if ([string]$parent.CommandLine -like "*$ProjectRoot*start-patchwarden-tunnel.ps1*") {
|
|
57
|
+
[void]$seedIds.Add([int]$parent.ProcessId)
|
|
58
|
+
}
|
|
59
|
+
$current = $parent
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
$ownedIds = New-Object System.Collections.Generic.HashSet[int]
|
|
63
|
+
foreach ($seed in $seedIds) { [void]$ownedIds.Add($seed) }
|
|
64
|
+
$changed = $true
|
|
65
|
+
while ($changed) {
|
|
66
|
+
$changed = $false
|
|
67
|
+
foreach ($process in $allProcesses) {
|
|
68
|
+
if ($ownedIds.Contains([int]$process.ParentProcessId) -and -not $ownedIds.Contains([int]$process.ProcessId)) {
|
|
69
|
+
[void]$ownedIds.Add([int]$process.ProcessId)
|
|
70
|
+
$changed = $true
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
foreach ($ownedId in $ownedIds) {
|
|
75
|
+
$process = $byPid[$ownedId]
|
|
76
|
+
if (-not $process -or $process.ProcessId -eq $PID) { continue }
|
|
77
|
+
$commandLine = [string]$process.CommandLine
|
|
78
|
+
$processesToKill += [ordered]@{
|
|
79
|
+
pid = $process.ProcessId
|
|
80
|
+
name = $process.Name
|
|
81
|
+
label = if ($seedIds.Contains([int]$process.ProcessId)) { "owned runtime" } else { "owned child" }
|
|
82
|
+
command = $commandLine.Substring(0, [Math]::Min(200, $commandLine.Length))
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
} catch {
|
|
86
|
+
Write-Warning "Could not enumerate processes: $_"
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if ($processesToKill.Count -eq 0) {
|
|
90
|
+
Write-Host " No PatchWarden processes found." -ForegroundColor Green
|
|
91
|
+
} else {
|
|
92
|
+
Write-Host " Found $($processesToKill.Count) PatchWarden process(es):" -ForegroundColor White
|
|
93
|
+
foreach ($proc in $processesToKill) {
|
|
94
|
+
Write-Host " PID $($proc.pid) - $($proc.label) ($($proc.name))" -ForegroundColor Gray
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
# -- 2. Kill processes -----------------------------------------------
|
|
99
|
+
|
|
100
|
+
if ($processesToKill.Count -gt 0) {
|
|
101
|
+
Write-Host ""
|
|
102
|
+
Write-Host "[2/4] Stopping PatchWarden processes..." -ForegroundColor Yellow
|
|
103
|
+
|
|
104
|
+
if ($WhatIf) {
|
|
105
|
+
Write-Host " WHAT-IF: Would stop $($processesToKill.Count) process(es)." -ForegroundColor Magenta
|
|
106
|
+
} else {
|
|
107
|
+
foreach ($proc in $processesToKill) {
|
|
108
|
+
try {
|
|
109
|
+
$process = Get-Process -Id $proc.pid -ErrorAction Stop
|
|
110
|
+
Write-Host " Stopping PID $($proc.pid) ($($proc.label))..." -ForegroundColor Gray
|
|
111
|
+
$process.Kill()
|
|
112
|
+
$exited = $process.WaitForExit($KillTimeoutSeconds * 1000)
|
|
113
|
+
if ($exited) {
|
|
114
|
+
Write-Host " Stopped." -ForegroundColor Green
|
|
115
|
+
} else {
|
|
116
|
+
Write-Host " Kill sent but process did not exit within ${KillTimeoutSeconds}s." -ForegroundColor Yellow
|
|
117
|
+
}
|
|
118
|
+
} catch {
|
|
119
|
+
Write-Host " PID $($proc.pid) already exited or inaccessible - skipped." -ForegroundColor DarkGray
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
# -- 3. Rebuild ------------------------------------------------------
|
|
127
|
+
|
|
128
|
+
Write-Host ""
|
|
129
|
+
if ($SkipBuild) {
|
|
130
|
+
Write-Host "[3/4] Skipping build (--SkipBuild)." -ForegroundColor DarkYellow
|
|
131
|
+
} else {
|
|
132
|
+
Write-Host "[3/4] Rebuilding PatchWarden..." -ForegroundColor Yellow
|
|
133
|
+
|
|
134
|
+
if ($WhatIf) {
|
|
135
|
+
Write-Host " WHAT-IF: Would run npm.cmd run build." -ForegroundColor Magenta
|
|
136
|
+
} else {
|
|
137
|
+
Push-Location $ProjectRoot
|
|
138
|
+
try {
|
|
139
|
+
$buildResult = npm.cmd run build 2>&1
|
|
140
|
+
if ($LASTEXITCODE -ne 0) {
|
|
141
|
+
Write-Warning "Build completed with warnings (exit code $LASTEXITCODE)."
|
|
142
|
+
Write-Host ($buildResult -join "`n") -ForegroundColor DarkGray
|
|
143
|
+
} else {
|
|
144
|
+
Write-Host " Build successful." -ForegroundColor Green
|
|
145
|
+
}
|
|
146
|
+
} catch {
|
|
147
|
+
Write-Warning "Build failed: $_"
|
|
148
|
+
Write-Host " Continuing anyway - dist may be stale." -ForegroundColor DarkRed
|
|
149
|
+
} finally {
|
|
150
|
+
Pop-Location
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
# -- Clear stale runtime state ----------------------------------------
|
|
156
|
+
|
|
157
|
+
if (-not $WhatIf) {
|
|
158
|
+
# LOCALAPPDATA runtime files (launcher-managed supervision state)
|
|
159
|
+
if (Test-Path -LiteralPath $RuntimeDirectory) {
|
|
160
|
+
try {
|
|
161
|
+
$staleFiles = @(
|
|
162
|
+
Join-Path $RuntimeDirectory "tunnel-health-url.txt",
|
|
163
|
+
Join-Path $RuntimeDirectory "tunnel-client.pid",
|
|
164
|
+
Join-Path $RuntimeDirectory "watcher-status.json",
|
|
165
|
+
Join-Path $RuntimeDirectory "tunnel-status.json"
|
|
166
|
+
)
|
|
167
|
+
foreach ($file in $staleFiles) {
|
|
168
|
+
if (Test-Path -LiteralPath $file) {
|
|
169
|
+
Remove-Item -LiteralPath $file -Force -ErrorAction SilentlyContinue
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
} catch {}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
# Workspace watcher heartbeat - CRITICAL: the killed watcher stops
|
|
176
|
+
# writing this file, but the stale record can fool a fresh launcher
|
|
177
|
+
# into treating it as an "external_healthy" watcher (age < stale
|
|
178
|
+
# threshold right after kill), which prevents the launcher from
|
|
179
|
+
# starting its own watcher. Removing it forces a clean start.
|
|
180
|
+
try {
|
|
181
|
+
if (Test-Path -LiteralPath $ConfigPath) {
|
|
182
|
+
$cfg = Get-Content -LiteralPath $ConfigPath -Raw | ConvertFrom-Json
|
|
183
|
+
$tasksDir = Join-Path $cfg.workspaceRoot $cfg.tasksDir
|
|
184
|
+
$heartbeatFile = Join-Path (Split-Path -Parent $tasksDir) "watcher-heartbeat.json"
|
|
185
|
+
if (Test-Path -LiteralPath $heartbeatFile) {
|
|
186
|
+
Remove-Item -LiteralPath $heartbeatFile -Force -ErrorAction SilentlyContinue
|
|
187
|
+
Write-Host " Cleared stale watcher heartbeat." -ForegroundColor Green
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
} catch {}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
# -- 4. Relaunch tunnel ----------------------------------------------
|
|
194
|
+
|
|
195
|
+
Write-Host ""
|
|
196
|
+
Write-Host "[4/4] Launching PatchWarden tunnel..." -ForegroundColor Yellow
|
|
197
|
+
|
|
198
|
+
if ($WhatIf) {
|
|
199
|
+
Write-Host " WHAT-IF: Would launch Start-PatchWarden-Tunnel.cmd." -ForegroundColor Magenta
|
|
200
|
+
Write-Host ""
|
|
201
|
+
Write-Host "========================================" -ForegroundColor Cyan
|
|
202
|
+
Write-Host " Restart plan complete (--WhatIf)." -ForegroundColor Cyan
|
|
203
|
+
Write-Host "========================================" -ForegroundColor Cyan
|
|
204
|
+
Write-Host ""
|
|
205
|
+
exit 0
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
# Relaunch the tunnel in a new PowerShell window.
|
|
209
|
+
# Prefer Start-PatchWarden-Tunnel.local.cmd (your saved config) over the generic launcher.
|
|
210
|
+
$localLauncher = Join-Path $ProjectRoot "Start-PatchWarden-Tunnel.local.cmd"
|
|
211
|
+
$genericLauncher = Join-Path $ProjectRoot "Start-PatchWarden-Tunnel.cmd"
|
|
212
|
+
$launcherPath = if (Test-Path -LiteralPath $localLauncher) { $localLauncher } else { $genericLauncher }
|
|
213
|
+
|
|
214
|
+
if (-not (Test-Path -LiteralPath $launcherPath)) {
|
|
215
|
+
Write-Error "Launcher not found: $launcherPath"
|
|
216
|
+
exit 1
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
$launcherName = Split-Path -Leaf $launcherPath
|
|
220
|
+
Write-Host " Using launcher: $launcherName" -ForegroundColor White
|
|
221
|
+
if ($launcherPath -eq $localLauncher) {
|
|
222
|
+
Write-Host " (local config with pre-set TUNNEL_ID / TUNNEL_CLIENT_EXE)" -ForegroundColor DarkGray
|
|
223
|
+
}
|
|
224
|
+
Write-Host ""
|
|
225
|
+
|
|
226
|
+
$args = @(
|
|
227
|
+
"-NoProfile",
|
|
228
|
+
"-NoExit",
|
|
229
|
+
"-Command",
|
|
230
|
+
"Set-Location '$ProjectRoot'; & '$launcherPath'"
|
|
231
|
+
)
|
|
232
|
+
if ($SkipWatcher) {
|
|
233
|
+
$args[3] = "Set-Location '$ProjectRoot'; `$env:PATCHWARDEN_SKIP_WATCHER='1'; & '$launcherPath'"
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
Start-Process powershell.exe -ArgumentList $args
|
|
237
|
+
|
|
238
|
+
Write-Host "========================================" -ForegroundColor Cyan
|
|
239
|
+
Write-Host " Restart complete. Tunnel launcher window opened." -ForegroundColor Cyan
|
|
240
|
+
Write-Host " Use Check-PatchWarden-Health.cmd to verify." -ForegroundColor Cyan
|
|
241
|
+
Write-Host "========================================" -ForegroundColor Cyan
|
|
242
|
+
Write-Host ""
|