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.
Files changed (153) hide show
  1. package/Check-PatchWarden-Health.cmd +6 -0
  2. package/LICENSE +21 -0
  3. package/README.md +526 -0
  4. package/Reset-PatchWarden-Tunnel-Key.cmd +6 -0
  5. package/Restart-PatchWarden.cmd +19 -0
  6. package/Start-PatchWarden-Tunnel.cmd +7 -0
  7. package/dist/config.d.ts +24 -0
  8. package/dist/config.js +131 -0
  9. package/dist/doctor.d.ts +10 -0
  10. package/dist/doctor.js +388 -0
  11. package/dist/errors.d.ts +16 -0
  12. package/dist/errors.js +27 -0
  13. package/dist/httpServer.d.ts +17 -0
  14. package/dist/httpServer.js +255 -0
  15. package/dist/index.d.ts +9 -0
  16. package/dist/index.js +24 -0
  17. package/dist/runner/changeCapture.d.ts +43 -0
  18. package/dist/runner/changeCapture.js +245 -0
  19. package/dist/runner/cli.d.ts +9 -0
  20. package/dist/runner/cli.js +26 -0
  21. package/dist/runner/runTask.d.ts +8 -0
  22. package/dist/runner/runTask.js +821 -0
  23. package/dist/runner/watch.d.ts +19 -0
  24. package/dist/runner/watch.js +136 -0
  25. package/dist/security/commandGuard.d.ts +22 -0
  26. package/dist/security/commandGuard.js +56 -0
  27. package/dist/security/contentRedaction.d.ts +12 -0
  28. package/dist/security/contentRedaction.js +65 -0
  29. package/dist/security/pathGuard.d.ts +3 -0
  30. package/dist/security/pathGuard.js +98 -0
  31. package/dist/security/planGuard.d.ts +1 -0
  32. package/dist/security/planGuard.js +65 -0
  33. package/dist/security/sensitiveGuard.d.ts +2 -0
  34. package/dist/security/sensitiveGuard.js +60 -0
  35. package/dist/smoke-test.d.ts +15 -0
  36. package/dist/smoke-test.js +989 -0
  37. package/dist/taskProgress.d.ts +6 -0
  38. package/dist/taskProgress.js +36 -0
  39. package/dist/taskRuntime.d.ts +10 -0
  40. package/dist/taskRuntime.js +25 -0
  41. package/dist/tools/auditTask.d.ts +19 -0
  42. package/dist/tools/auditTask.js +307 -0
  43. package/dist/tools/cancelTask.d.ts +30 -0
  44. package/dist/tools/cancelTask.js +64 -0
  45. package/dist/tools/createTask.d.ts +42 -0
  46. package/dist/tools/createTask.js +188 -0
  47. package/dist/tools/getPlan.d.ts +12 -0
  48. package/dist/tools/getPlan.js +29 -0
  49. package/dist/tools/getTaskFile.d.ts +24 -0
  50. package/dist/tools/getTaskFile.js +84 -0
  51. package/dist/tools/getTaskProgress.d.ts +1 -0
  52. package/dist/tools/getTaskProgress.js +4 -0
  53. package/dist/tools/getTaskStatus.d.ts +46 -0
  54. package/dist/tools/getTaskStatus.js +36 -0
  55. package/dist/tools/getTaskStdoutTail.d.ts +9 -0
  56. package/dist/tools/getTaskStdoutTail.js +56 -0
  57. package/dist/tools/getTaskSummary.d.ts +66 -0
  58. package/dist/tools/getTaskSummary.js +237 -0
  59. package/dist/tools/healthCheck.d.ts +79 -0
  60. package/dist/tools/healthCheck.js +230 -0
  61. package/dist/tools/killTask.d.ts +15 -0
  62. package/dist/tools/killTask.js +4 -0
  63. package/dist/tools/listAgents.d.ts +12 -0
  64. package/dist/tools/listAgents.js +42 -0
  65. package/dist/tools/listTasks.d.ts +36 -0
  66. package/dist/tools/listTasks.js +94 -0
  67. package/dist/tools/listWorkspace.d.ts +10 -0
  68. package/dist/tools/listWorkspace.js +54 -0
  69. package/dist/tools/readWorkspaceFile.d.ts +8 -0
  70. package/dist/tools/readWorkspaceFile.js +26 -0
  71. package/dist/tools/registry.d.ts +24 -0
  72. package/dist/tools/registry.js +566 -0
  73. package/dist/tools/retryTask.d.ts +8 -0
  74. package/dist/tools/retryTask.js +45 -0
  75. package/dist/tools/savePlan.d.ts +10 -0
  76. package/dist/tools/savePlan.js +28 -0
  77. package/dist/tools/taskOutputs.d.ts +49 -0
  78. package/dist/tools/taskOutputs.js +136 -0
  79. package/dist/tools/taskTemplates.d.ts +15 -0
  80. package/dist/tools/taskTemplates.js +116 -0
  81. package/dist/tools/toolCatalog.d.ts +19 -0
  82. package/dist/tools/toolCatalog.js +71 -0
  83. package/dist/tools/waitForTask.d.ts +25 -0
  84. package/dist/tools/waitForTask.js +59 -0
  85. package/dist/version.d.ts +2 -0
  86. package/dist/version.js +2 -0
  87. package/dist/watcherStatus.d.ts +20 -0
  88. package/dist/watcherStatus.js +77 -0
  89. package/docs/assets/patchwarden-chatgpt-demo.svg +30 -0
  90. package/docs/demo.md +58 -0
  91. package/docs/migration-from-safe-bifrost.md +31 -0
  92. package/docs/release-v0.3.0.md +43 -0
  93. package/docs/release-v0.4.0.md +74 -0
  94. package/examples/config.example.json +40 -0
  95. package/examples/openai-tunnel/README.md +48 -0
  96. package/examples/openai-tunnel/chatgpt-test-prompt.md +53 -0
  97. package/examples/openai-tunnel/tunnel-client.example.yaml +39 -0
  98. package/package.json +73 -0
  99. package/scripts/brand-check.js +44 -0
  100. package/scripts/doctor-smoke.js +52 -0
  101. package/scripts/get-patchwarden-health.ps1 +114 -0
  102. package/scripts/http-mcp-smoke.js +351 -0
  103. package/scripts/lifecycle-smoke.js +453 -0
  104. package/scripts/mcp-manifest-check.js +120 -0
  105. package/scripts/mcp-smoke.js +336 -0
  106. package/scripts/pack-clean.js +142 -0
  107. package/scripts/patchwarden-mcp-stdio.cmd +7 -0
  108. package/scripts/restart-patchwarden.ps1 +242 -0
  109. package/scripts/start-patchwarden-tunnel.ps1 +503 -0
  110. package/scripts/tunnel-supervisor-smoke.js +77 -0
  111. package/scripts/watcher-supervisor-smoke.js +195 -0
  112. package/src/config.ts +165 -0
  113. package/src/doctor.ts +438 -0
  114. package/src/errors.ts +26 -0
  115. package/src/httpServer.ts +277 -0
  116. package/src/index.ts +34 -0
  117. package/src/runner/changeCapture.ts +304 -0
  118. package/src/runner/cli.ts +34 -0
  119. package/src/runner/runTask.ts +935 -0
  120. package/src/runner/watch.ts +152 -0
  121. package/src/security/commandGuard.ts +97 -0
  122. package/src/security/contentRedaction.ts +85 -0
  123. package/src/security/pathGuard.ts +175 -0
  124. package/src/security/planGuard.ts +93 -0
  125. package/src/security/sensitiveGuard.ts +72 -0
  126. package/src/smoke-test.ts +1078 -0
  127. package/src/taskProgress.ts +41 -0
  128. package/src/taskRuntime.ts +37 -0
  129. package/src/tools/auditTask.ts +340 -0
  130. package/src/tools/cancelTask.ts +70 -0
  131. package/src/tools/createTask.ts +337 -0
  132. package/src/tools/getPlan.ts +48 -0
  133. package/src/tools/getTaskFile.ts +111 -0
  134. package/src/tools/getTaskProgress.ts +5 -0
  135. package/src/tools/getTaskStatus.ts +85 -0
  136. package/src/tools/getTaskStdoutTail.ts +61 -0
  137. package/src/tools/getTaskSummary.ts +307 -0
  138. package/src/tools/healthCheck.ts +234 -0
  139. package/src/tools/killTask.ts +5 -0
  140. package/src/tools/listAgents.ts +54 -0
  141. package/src/tools/listTasks.ts +139 -0
  142. package/src/tools/listWorkspace.ts +71 -0
  143. package/src/tools/readWorkspaceFile.ts +41 -0
  144. package/src/tools/registry.ts +666 -0
  145. package/src/tools/retryTask.ts +53 -0
  146. package/src/tools/savePlan.ts +46 -0
  147. package/src/tools/taskOutputs.ts +155 -0
  148. package/src/tools/taskTemplates.ts +162 -0
  149. package/src/tools/toolCatalog.ts +92 -0
  150. package/src/tools/waitForTask.ts +90 -0
  151. package/src/version.ts +2 -0
  152. package/src/watcherStatus.ts +102 -0
  153. package/tsconfig.json +17 -0
@@ -0,0 +1,6 @@
1
+ @echo off
2
+ setlocal
3
+ cd /d "%~dp0"
4
+ powershell.exe -NoProfile -ExecutionPolicy Bypass -File "%~dp0scripts\get-patchwarden-health.ps1"
5
+ echo.
6
+ pause
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 PatchWarden contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,526 @@
1
+ # PatchWarden
2
+
3
+ Development version: **v0.4.0** (not yet published). See the
4
+ [v0.4.0 release notes](docs/release-v0.4.0.md).
5
+
6
+ > **Renamed in v0.4.0:** PatchWarden replaces the former Safe-Bifrost package.
7
+ > This is an intentional pre-1.0 breaking rename with new CLI, environment,
8
+ > configuration, and runtime paths. See the
9
+ > [migration guide](docs/migration-from-safe-bifrost.md).
10
+
11
+ PatchWarden is a local Model Context Protocol (MCP) bridge for safe
12
+ plan-and-execute coding workflows.
13
+
14
+ It lets ChatGPT, Codex, Claude, or another MCP client save a plan, create a
15
+ workspace-scoped task, let a local agent execute it, and then read back the
16
+ result, git diff, test log, and task status.
17
+
18
+ ![PatchWarden ChatGPT connector demo](docs/assets/patchwarden-chatgpt-demo.svg)
19
+
20
+ ## Why
21
+
22
+ Many local coding bridges give the upstream model broad shell access.
23
+ PatchWarden takes a narrower route:
24
+
25
+ ```text
26
+ ChatGPT Web or another MCP client
27
+ -> PatchWarden MCP tools
28
+ -> save_plan / create_task
29
+ -> watcher finds pending tasks
30
+ -> local agent executes
31
+ -> result.md / result.json / diff.patch / verify.json / status.json
32
+ -> client reviews the result
33
+ ```
34
+
35
+ The MCP client can plan and review, but it does not receive a general shell
36
+ tool.
37
+
38
+ ## Features
39
+
40
+ - MCP stdio server with workspace-scoped tools.
41
+ - Optional HTTP MCP server bound to `127.0.0.1`.
42
+ - ChatGPT Connector / OpenAI Secure MCP Tunnel workflow.
43
+ - Automatic watcher for pending tasks.
44
+ - Local runner that captures `result.md`, `git.diff`, `test.log`, and
45
+ `status.json`.
46
+ - Task phases, heartbeat timestamps, progress reports, cancellation, forced
47
+ termination, and bounded task timeouts.
48
+ - Server-side `wait_for_task` long polling so ChatGPT can remain in one tool
49
+ loop until the agent reaches a terminal state.
50
+ - `create_task` accepts a saved `plan_id`, an auditable `inline_plan`, or one
51
+ of five guarded task templates.
52
+ - A supervised Windows tunnel launcher retries recoverable disconnects and
53
+ writes local, redacted runtime health state.
54
+ - Structured `result.json`, `verify.json`, `diff.patch`, and
55
+ `get_task_summary` acceptance evidence.
56
+ - Workspace-wide before/after fingerprints that fail a task when changes are
57
+ detected outside its explicit `repo_path`.
58
+ - Before/after file fingerprints for stronger change evidence.
59
+ - File reads contained to one configured `workspaceRoot`.
60
+ - Sensitive file blocking for `.env`, tokens, SSH keys, credentials, cookies,
61
+ and similar paths.
62
+ - Low-risk plan storage: ordinary build/test/release language is accepted;
63
+ explicit credential theft, destructive disk deletion, and backdoor plans are blocked.
64
+ - Task artifacts are returned with secret-like values redacted instead of
65
+ failing the entire read.
66
+ - Pending task artifacts return structured `available: false` evidence with
67
+ task phase, watcher health, pending reason, and the next safe tool call.
68
+ - Structured `result.json`, `verify.json`, and `get_task_summary` values are
69
+ recursively redacted and report `redacted` plus `redaction_categories`.
70
+ - Agent command allowlist through `patchwarden.config.json`.
71
+ - Test command exact-match allowlist.
72
+ - Windows-friendly helper scripts.
73
+ - Read-only `doctor` command for local setup diagnostics.
74
+
75
+ ## MCP Tools and Profiles
76
+
77
+ PatchWarden has two deterministic tool profiles. `full` is the default for
78
+ ordinary local development and exposes all tools listed below. The Windows
79
+ tunnel stdio wrapper explicitly uses `chatgpt_core`, a stable 16-tool profile
80
+ ordered for the create/wait/review loop:
81
+
82
+ `health_check`, `list_agents`, `list_workspace`, `read_workspace_file`,
83
+ `save_plan`, `create_task`, `wait_for_task`, `get_task_summary`, `get_diff`,
84
+ `get_result`, `get_result_json`, `get_test_log`, `get_task_status`, `list_tasks`,
85
+ `cancel_task`, `audit_task`.
86
+
87
+ The full profile exposes:
88
+
89
+ - `list_workspace`
90
+ - `read_workspace_file`
91
+ - `save_plan`
92
+ - `get_plan`
93
+ - `health_check`
94
+ - `list_agents`
95
+ - `create_task`
96
+ - `get_task_status`
97
+ - `get_result`
98
+ - `get_result_json`
99
+ - `get_diff`
100
+ - `get_test_log`
101
+ - `list_tasks`
102
+ - `cancel_task`
103
+ - `kill_task`
104
+ - `retry_task`
105
+ - `get_task_progress`
106
+ - `wait_for_task`
107
+ - `get_task_summary`
108
+ - `get_task_stdout_tail`
109
+ - `get_task_log_tail`
110
+ - `audit_task`
111
+
112
+ ## Install
113
+
114
+ Requirements:
115
+
116
+ - Node.js 18 or newer
117
+ - npm
118
+ - Git, if you want `git.diff`
119
+ - A configured local coding agent such as `opencode` or `codex`
120
+
121
+ Windows PowerShell:
122
+
123
+ ```powershell
124
+ cd path\to\patchwarden
125
+ npm.cmd ci
126
+ npm.cmd run build
127
+ npm.cmd test
128
+ ```
129
+
130
+ Linux, macOS, or WSL:
131
+
132
+ ```bash
133
+ cd patchwarden
134
+ npm ci
135
+ npm run build
136
+ npm test
137
+ ```
138
+
139
+ ## Configure
140
+
141
+ Create `patchwarden.config.json` in the project root. Do not commit this
142
+ file.
143
+
144
+ ```json
145
+ {
146
+ "workspaceRoot": "D:/path/to/test-or-project-workspace",
147
+ "plansDir": ".patchwarden/plans",
148
+ "tasksDir": ".patchwarden/tasks",
149
+ "toolProfile": "full",
150
+ "agents": {
151
+ "opencode": {
152
+ "command": "opencode",
153
+ "args": ["run", "{prompt}"]
154
+ }
155
+ },
156
+ "allowedTestCommands": [
157
+ "npm test",
158
+ "npm run build",
159
+ "npm run doctor",
160
+ "npm run check:tool-manifest"
161
+ ],
162
+ "maxReadFileBytes": 200000,
163
+ "defaultTaskTimeoutSeconds": 900,
164
+ "maxTaskTimeoutSeconds": 3600,
165
+ "watcherStaleSeconds": 30,
166
+ "httpPort": 7331
167
+ }
168
+ ```
169
+
170
+ Important rules:
171
+
172
+ - Use a small project directory for `workspaceRoot`.
173
+ - Do not set `workspaceRoot` to a drive root, home directory, Desktop,
174
+ Downloads, or Documents.
175
+ - Do not place secrets inside the workspace.
176
+ - Keep agent commands and test commands narrow.
177
+
178
+ ## Run Locally
179
+
180
+ Build first:
181
+
182
+ ```powershell
183
+ npm.cmd run build
184
+ ```
185
+
186
+ Run the stdio MCP server:
187
+
188
+ ```powershell
189
+ $env:PATCHWARDEN_CONFIG = "path\to\patchwarden.config.json"
190
+ node dist\index.js
191
+ ```
192
+
193
+ Run the watcher in another terminal:
194
+
195
+ ```powershell
196
+ $env:PATCHWARDEN_CONFIG = "path\to\patchwarden.config.json"
197
+ npm.cmd run watch
198
+ ```
199
+
200
+ Run the HTTP MCP server for local tunnel mode:
201
+
202
+ ```powershell
203
+ $env:PATCHWARDEN_CONFIG = "path\to\patchwarden.config.json"
204
+ npm.cmd run start:http
205
+ ```
206
+
207
+ The HTTP server binds only to `127.0.0.1`.
208
+
209
+ ## ChatGPT Connector
210
+
211
+ The intended ChatGPT flow is:
212
+
213
+ ```text
214
+ ChatGPT Web
215
+ -> ChatGPT Connector
216
+ -> OpenAI Secure MCP Tunnel
217
+ -> PatchWarden MCP server
218
+ -> watcher
219
+ -> local agent
220
+ ```
221
+
222
+ For stdio tunnel mode on Windows, use the launcher:
223
+
224
+ ```text
225
+ scripts/patchwarden-mcp-stdio.cmd
226
+ ```
227
+
228
+ This wrapper sets `PATCHWARDEN_CONFIG`, changes into the PatchWarden project
229
+ root, and starts `node dist/index.js`. It prevents tunnel-client from using
230
+ the tunnel-client directory as the MCP workspace.
231
+
232
+ ### One-Click Windows Launcher
233
+
234
+ For local development, run:
235
+
236
+ ```text
237
+ Start-PatchWarden-Tunnel.cmd
238
+ ```
239
+
240
+ The launcher:
241
+
242
+ - asks for your tunnel runtime API key on first use, then stores it encrypted
243
+ with Windows DPAPI under `%APPDATA%\patchwarden`
244
+ - asks for a tunnel ID if `PATCHWARDEN_TUNNEL_ID` is not already set
245
+ - starts a hidden watcher owned by the launcher when no healthy external watcher exists
246
+ - supervises only its owned watcher and retries stale/exited instances with a
247
+ capped 2/5/10/20/30-second backoff
248
+ - runs machine-readable `tunnel-client doctor` checks
249
+ - performs a real stdio MCP `initialize` plus `tools/list` preflight and stops
250
+ before tunnel startup if the core tools or v0.4.0 schemas are missing
251
+ - supervises `tunnel-client run`, probes readiness, and retries recoverable
252
+ exits with a capped 5/10/20/30-second backoff
253
+ - stops on non-retryable authentication, configuration, region, or control
254
+ plane errors instead of looping blindly
255
+
256
+ Optional environment variables:
257
+
258
+ ```powershell
259
+ $env:PATCHWARDEN_TUNNEL_ID = "tunnel_xxx"
260
+ $env:TUNNEL_CLIENT_EXE = "C:\path\to\tunnel-client.exe"
261
+ $env:OPENCODE_BIN_DIR = "C:\path\to\opencode-ai\bin"
262
+ $env:HTTPS_PROXY = "http://127.0.0.1:7892"
263
+ $env:PATCHWARDEN_CREDENTIAL_PATH = "C:\private\patchwarden-key.dpapi"
264
+ ```
265
+
266
+ The saved key is bound to the current Windows user and computer. It is never
267
+ written to the repository or printed to logs. To remove it, run
268
+ `Reset-PatchWarden-Tunnel-Key.cmd`.
269
+
270
+ Never commit API keys, runtime keys, tunnel IDs, local account names, or
271
+ private workspace IDs.
272
+
273
+ If ChatGPT reports a tunnel 404 or cannot call any MCP tool, run:
274
+
275
+ ```text
276
+ Check-PatchWarden-Health.cmd
277
+ ```
278
+
279
+ This local-only diagnostic reports source/dist version, the actual MCP process
280
+ source, tool profile/count/names/schema hash, workspace/tasks access, watcher
281
+ freshness, configured agents, tunnel readiness, and other detected
282
+ PatchWarden processes. It only warns about mixed versions and never ends a
283
+ process. Runtime status is stored under `%LOCALAPPDATA%\patchwarden\runtime`
284
+ and does not contain the API key or Tunnel ID.
285
+
286
+ For an expanded read-only diagnosis, call
287
+ `health_check({"detail":"self_diagnostic"})`. It adds allowlist counts,
288
+ configured agents, recent task failures, and catalog consistency evidence
289
+ without creating a task that depends on the watcher.
290
+
291
+ If you need to fully restart everything (after a config change, version
292
+ upgrade, or hung process), double-click:
293
+
294
+ ```text
295
+ Restart-PatchWarden.cmd
296
+ ```
297
+
298
+ This stops only the process tree recorded as owned by the current launcher,
299
+ rebuilds the project, clears stale runtime state, and opens a fresh tunnel
300
+ launcher window. It does not stop unrelated or legacy PatchWarden instances.
301
+
302
+ ## Demo
303
+
304
+ See [docs/demo.md](docs/demo.md) for a privacy-safe ChatGPT connector demo and
305
+ expected outputs.
306
+
307
+ ## Troubleshooting
308
+
309
+ ### ChatGPT lists the tunnel-client directory
310
+
311
+ If `list_workspace` returns only `tunnel-client.exe`, the MCP child process did
312
+ not receive `PATCHWARDEN_CONFIG` or started from the wrong working directory.
313
+
314
+ Fix: use `scripts/patchwarden-mcp-stdio.cmd` as the tunnel MCP command, then
315
+ restart tunnel-client.
316
+
317
+ ### ChatGPT tool call times out
318
+
319
+ Check the tunnel-client UI at:
320
+
321
+ ```text
322
+ http://127.0.0.1:8080/ui
323
+ ```
324
+
325
+ If logs show:
326
+
327
+ ```text
328
+ unsupported_country_region_territory
329
+ 403 Forbidden
330
+ ```
331
+
332
+ then the current proxy exit region is not supported by the OpenAI API control
333
+ plane. Change to a supported region and restart tunnel-client.
334
+
335
+ ### ChatGPT stops after `create_task`
336
+
337
+ An MCP server cannot send a new message into ChatGPT after the assistant turn
338
+ has ended. Do not rely on a prompt that says only "wait and check later".
339
+ Immediately call `wait_for_task` after `create_task`. If its response contains
340
+ `continuation_required: true`, call it again in the same assistant turn. When
341
+ `terminal: true`, use the included summary and then call `audit_task` for the
342
+ independent review. Each wait is capped at 30 seconds to stay below common
343
+ connector and tunnel request timeouts.
344
+
345
+ ### ChatGPT still shows an older tool list
346
+
347
+ Tool catalogs can remain attached to a connector session that was opened
348
+ before the tunnel was refreshed. First run `Check-PatchWarden-Health.cmd` and
349
+ confirm `configured_tunnel_manifest.tool_profile` is `chatgpt_core`, its
350
+ `tool_count` is 16, and the next tunnel status reports `core_tools_ready` as
351
+ true. Then refresh or reconnect the Connector and open a
352
+ new ChatGPT conversation. Do not use the old conversation as proof that the
353
+ new schema was loaded. `health_check` exposes `server_version`, `schema_epoch`,
354
+ and `tool_manifest_sha256` so the same tool names with stale schemas can still
355
+ be distinguished.
356
+
357
+ If an old conversation calls a tool that is no longer in the active profile,
358
+ PatchWarden returns `tool_catalog_mismatch` with the current tool manifest and
359
+ refresh instructions instead of a generic unavailable-tool error.
360
+
361
+ ### Task remains queued and watcher is stale
362
+
363
+ `create_task`, `get_task_status`, `list_tasks`, and pending artifact reads all
364
+ return the same watcher evidence. A stale or missing watcher leaves the task
365
+ saved but sets `execution_blocked: true`, `continuation_required: false`, and
366
+ points to `health_check`. The Windows launcher automatically retries only the
367
+ watcher process it created; external and legacy instances are never stopped.
368
+
369
+ If logs show direct connection timeouts to `api.openai.com`, set a proxy:
370
+
371
+ ```powershell
372
+ $env:HTTPS_PROXY = "http://127.0.0.1:7892"
373
+ ```
374
+
375
+ ### ChatGPT Connector creation fails
376
+
377
+ Verify:
378
+
379
+ - tunnel-client is running
380
+ - the tunnel is associated with the correct ChatGPT workspace
381
+ - the connector uses `Channel`, not `Server URL`
382
+ - authentication is set to `None` unless you have implemented OAuth
383
+ - browser translation extensions are disabled on Platform pages
384
+
385
+ ## Recommended Workflow
386
+
387
+ Start with `health_check` and `list_agents`. `create_task` requires an explicit
388
+ `repo_path`; it never silently falls back to the workspace root. Prefer
389
+ `verify_commands` from the exact schema allowlist. Immediately enter the
390
+ `wait_for_task(timeout_seconds: 25)` loop and keep calling it while
391
+ `continuation_required` is true. The legacy `wait_seconds` name remains
392
+ supported; if both aliases are sent, their values must match. Each wait
393
+ defaults to 25 seconds and is capped at 30 seconds.
394
+ Use `cancel_task` for graceful cancellation or `kill_task` for immediate
395
+ termination. Final acceptance starts with `get_task_summary`, followed by
396
+ `audit_task` and any detailed artifacts needed for review.
397
+
398
+ Do not use the entire `workspaceRoot` as the task repository unless that is
399
+ truly the intended repository. Prefer a relative subdirectory such as
400
+ `desktop-pet-wangzai`; absolute paths are also accepted when they resolve
401
+ inside `workspaceRoot`.
402
+
403
+ `create_task` requires exactly one plan source: `plan_id`, `inline_plan`, or
404
+ `template`. The existing `save_plan` flow remains compatible. A shorter inline
405
+ flow looks like:
406
+
407
+ ```json
408
+ {
409
+ "agent": "opencode",
410
+ "repo_path": "desktop-pet-wangzai",
411
+ "inline_plan": "Implement the requested small feature without changing unrelated files.",
412
+ "verify_commands": [
413
+ "npm run build",
414
+ "npm test"
415
+ ]
416
+ }
417
+ ```
418
+
419
+ Guarded templates are `inspect_only`, `feature_small`, `fix_tests`,
420
+ `release_check`, and `rollback_scope_violation`. Template tasks also require a
421
+ `goal`; the rollback review additionally requires `source_task_id` and never
422
+ performs an automatic rollback. `inspect_only` and rollback review tasks fail
423
+ with `failed_policy_violation` if they change repository files.
424
+
425
+ `list_tasks` accepts `status`, `repo_path`, `active_only`, and `limit`. Each
426
+ entry includes its computed `pending_reason` and watcher state.
427
+
428
+ 1. `list_workspace` — explore the project
429
+ 2. `save_plan` — ChatGPT writes the implementation plan
430
+ 3. `create_task` with `repo_path` and `verify_commands`
431
+ 4. `wait_for_task` — repeat in the same turn until `terminal: true`
432
+ 5. `get_task_summary` — inspect scope, verification, files, and artifacts
433
+ 6. `get_result_json` / `get_diff` / `get_test_log` — inspect detailed evidence
434
+ 7. `audit_task` — independent verification (checks claims vs reality)
435
+
436
+ > **Important:**
437
+ > - `task done` means the agent finished executing — it does NOT mean the work is correct or complete.
438
+ > - `failed_scope_violation` takes precedence over acceptance. Review
439
+ > `rollback_scope_violation_plan.md`; PatchWarden never auto-rolls back concurrent/user edits.
440
+ > - `failed_verification` means at least one independent allow-listed command failed;
441
+ > inspect `verify.log` before retrying.
442
+ > - `failed_policy_violation` means a no-changes template unexpectedly changed
443
+ > repository files; inspect the diff and use the backup-first follow-up prompt.
444
+ > - `audit_task` provides an independent review, but still requires human judgment.
445
+ > - Local `result.md` claims about `npm publish`, `git push`, or `GitHub release` are **unverified**.
446
+ > - Publishing, tagging, pushing, and npm publish must be confirmed manually.
447
+ > - Before running `doctor`, create `patchwarden.config.json` from the example template.
448
+
449
+ ### Task artifacts
450
+
451
+ - `result.md`: human-readable execution report and agent output.
452
+ - `result.json`: structured status, paths, changed files, scope evidence,
453
+ verification state, warnings, errors, and next steps for tools.
454
+ - `verify.json`: one structured record per independently executed allow-listed
455
+ verification command, including cwd, exit code, output tails, and timing.
456
+ - `verify.log`: readable form of the same independent verification evidence.
457
+ - `diff.patch`: complete task change evidence. `get_diff.patch_mode` is
458
+ `textual`, `no_changes`, or `hash_only`; hash-only responses include an
459
+ `unavailable_reason`. Large textual responses return a bounded patch head,
460
+ byte counts, truncation evidence, and the complete local `diff_patch_path`.
461
+ - `file-stats.json`: standalone per-file additions/deletions and aggregate counts.
462
+ - `rollback_scope_violation_plan.md`: review-only list of repo-external changes;
463
+ it never includes normal in-repo changes and never performs rollback itself.
464
+
465
+ ## Security Model
466
+
467
+ PatchWarden intentionally avoids general shell execution through MCP tools.
468
+
469
+ - MCP clients cannot pass arbitrary shell commands.
470
+ - Agent commands must be configured ahead of time.
471
+ - Test commands must match `allowedTestCommands` exactly.
472
+ - File reads are contained to `workspaceRoot`.
473
+ - Sensitive file names are blocked even inside the workspace.
474
+ - The runner does not commit, push, delete files, or reset repositories.
475
+ - HTTP mode binds to `127.0.0.1` only.
476
+
477
+ This is still a local automation bridge. Treat connector access as powerful
478
+ and use a dedicated test workspace first.
479
+
480
+ ## Development
481
+
482
+ Windows PowerShell:
483
+
484
+ ```powershell
485
+ npm.cmd run build
486
+ npm.cmd test
487
+ npm.cmd run test:mcp
488
+ npm.cmd run test:http-mcp
489
+ npm.cmd run doctor
490
+ npm.cmd run check:tool-manifest
491
+ npm.cmd run test:tunnel-supervisor
492
+ npm.cmd run test:watcher-supervisor
493
+ npm.cmd run pack:clean
494
+ ```
495
+
496
+ Package checks:
497
+
498
+ ```powershell
499
+ npm.cmd run verify:package
500
+ npm.cmd run pack:clean
501
+ ```
502
+
503
+ The clean archive excludes:
504
+
505
+ - `node_modules/`
506
+ - `.patchwarden/`
507
+ - `*.log`
508
+ - `.env`
509
+ - `patchwarden.config.json`
510
+ - local release artifacts
511
+
512
+ ## Roadmap
513
+
514
+ - [x] stdio MCP server
515
+ - [x] plan and task CRUD
516
+ - [x] runner and watcher
517
+ - [x] HTTP MCP server
518
+ - [x] ChatGPT Connector tunnel docs
519
+ - [x] doctor command
520
+ - [ ] worktree isolation
521
+ - [ ] multi-agent task queue
522
+ - [ ] dashboard
523
+
524
+ ## License
525
+
526
+ MIT
@@ -0,0 +1,6 @@
1
+ @echo off
2
+ setlocal
3
+ cd /d "%~dp0"
4
+ powershell.exe -NoProfile -ExecutionPolicy Bypass -File "%~dp0scripts\start-patchwarden-tunnel.ps1" -ForgetSavedApiKey
5
+ echo.
6
+ pause
@@ -0,0 +1,19 @@
1
+ @echo off
2
+ setlocal
3
+ cd /d "%~dp0"
4
+ echo.
5
+ echo ========================================
6
+ echo PatchWarden One-Click Restart
7
+ echo ========================================
8
+ echo.
9
+ echo This will:
10
+ echo 1. Stop only processes owned by the current PatchWarden launcher
11
+ echo 2. Rebuild the project
12
+ echo 3. Start a fresh tunnel launcher window
13
+ echo.
14
+ echo Close this window to cancel, or
15
+ pause
16
+ powershell.exe -NoProfile -ExecutionPolicy Bypass -File "%~dp0scripts\restart-patchwarden.ps1"
17
+ echo.
18
+ echo Restart script finished.
19
+ pause
@@ -0,0 +1,7 @@
1
+ @echo off
2
+ setlocal
3
+ cd /d "%~dp0"
4
+ powershell.exe -NoProfile -ExecutionPolicy Bypass -File "%~dp0scripts\start-patchwarden-tunnel.ps1"
5
+ echo.
6
+ echo PatchWarden tunnel launcher exited.
7
+ pause
@@ -0,0 +1,24 @@
1
+ export interface AgentConfig {
2
+ command: string;
3
+ args: string[];
4
+ }
5
+ export interface PatchWardenConfig {
6
+ workspaceRoot: string;
7
+ plansDir: string;
8
+ tasksDir: string;
9
+ agents: Record<string, AgentConfig>;
10
+ allowedTestCommands: string[];
11
+ maxReadFileBytes: number;
12
+ defaultTaskTimeoutSeconds: number;
13
+ maxTaskTimeoutSeconds: number;
14
+ watcherStaleSeconds: number;
15
+ toolProfile?: "full" | "chatgpt_core";
16
+ repoAliases?: Record<string, string>;
17
+ }
18
+ export declare function loadConfig(configPath?: string): PatchWardenConfig;
19
+ export declare function getConfig(): PatchWardenConfig;
20
+ /** Resolve workspaceRoot: expand relative paths */
21
+ export declare function resolveWorkspaceRoot(config: PatchWardenConfig): string;
22
+ /** Resolve plans/tasks dirs relative to workspaceRoot */
23
+ export declare function getPlansDir(config: PatchWardenConfig): string;
24
+ export declare function getTasksDir(config: PatchWardenConfig): string;