patchwarden 0.4.0 → 0.6.1
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/PatchWarden.cmd +51 -0
- package/README.en.md +1022 -0
- package/README.md +897 -358
- package/dist/assessments/agentAssessor.d.ts +15 -0
- package/dist/assessments/agentAssessor.js +293 -0
- package/dist/assessments/assessmentStore.d.ts +133 -0
- package/dist/assessments/assessmentStore.js +238 -0
- package/dist/assessments/confirmCli.d.ts +9 -0
- package/dist/assessments/confirmCli.js +26 -0
- package/dist/config.d.ts +22 -1
- package/dist/config.js +156 -3
- package/dist/direct/directAudit.d.ts +23 -0
- package/dist/direct/directAudit.js +309 -0
- package/dist/direct/directGuards.d.ts +20 -0
- package/dist/direct/directGuards.js +137 -0
- package/dist/direct/directPatch.d.ts +17 -0
- package/dist/direct/directPatch.js +113 -0
- package/dist/direct/directSessionStore.d.ts +63 -0
- package/dist/direct/directSessionStore.js +192 -0
- package/dist/direct/directVerification.d.ts +12 -0
- package/dist/direct/directVerification.js +96 -0
- package/dist/doctor.js +73 -5
- package/dist/logging.d.ts +52 -0
- package/dist/logging.js +123 -0
- package/dist/runner/agentInvocation.d.ts +23 -0
- package/dist/runner/agentInvocation.js +106 -0
- package/dist/runner/changeCapture.d.ts +70 -0
- package/dist/runner/changeCapture.js +278 -6
- package/dist/runner/runTask.js +271 -65
- package/dist/runner/simpleProcess.d.ts +21 -0
- package/dist/runner/simpleProcess.js +206 -0
- package/dist/runner/watch.js +17 -2
- package/dist/security/commandGuard.d.ts +2 -1
- package/dist/security/commandGuard.js +25 -3
- package/dist/security/riskEngine.d.ts +27 -0
- package/dist/security/riskEngine.js +118 -0
- package/dist/security/runtimeGuard.d.ts +6 -0
- package/dist/security/runtimeGuard.js +28 -0
- package/dist/smoke-test.js +1353 -7
- package/dist/test/unit/android-doctor.test.d.ts +1 -0
- package/dist/test/unit/android-doctor.test.js +118 -0
- package/dist/test/unit/chinese-path.test.d.ts +1 -0
- package/dist/test/unit/chinese-path.test.js +91 -0
- package/dist/test/unit/command-guard.test.d.ts +1 -0
- package/dist/test/unit/command-guard.test.js +160 -0
- package/dist/test/unit/direct-guards.test.d.ts +1 -0
- package/dist/test/unit/direct-guards.test.js +213 -0
- package/dist/test/unit/logging.test.d.ts +1 -0
- package/dist/test/unit/logging.test.js +275 -0
- package/dist/test/unit/path-guard.test.d.ts +1 -0
- package/dist/test/unit/path-guard.test.js +109 -0
- package/dist/test/unit/safe-status.test.d.ts +1 -0
- package/dist/test/unit/safe-status.test.js +165 -0
- package/dist/test/unit/sensitive-guard.test.d.ts +1 -0
- package/dist/test/unit/sensitive-guard.test.js +104 -0
- package/dist/test/unit/sync-file.test.d.ts +1 -0
- package/dist/test/unit/sync-file.test.js +154 -0
- package/dist/test/unit/watcher-status.test.d.ts +1 -0
- package/dist/test/unit/watcher-status.test.js +169 -0
- package/dist/tools/androidDoctor.d.ts +38 -0
- package/dist/tools/androidDoctor.js +391 -0
- package/dist/tools/applyPatch.d.ts +16 -0
- package/dist/tools/applyPatch.js +41 -0
- package/dist/tools/auditSession.d.ts +5 -0
- package/dist/tools/auditSession.js +12 -0
- package/dist/tools/auditTask.d.ts +7 -0
- package/dist/tools/auditTask.js +105 -7
- package/dist/tools/createDirectSession.d.ts +14 -0
- package/dist/tools/createDirectSession.js +54 -0
- package/dist/tools/createTask.d.ts +48 -1
- package/dist/tools/createTask.js +298 -47
- package/dist/tools/finalizeDirectSession.d.ts +19 -0
- package/dist/tools/finalizeDirectSession.js +84 -0
- package/dist/tools/getTaskSummary.d.ts +50 -0
- package/dist/tools/getTaskSummary.js +79 -2
- package/dist/tools/healthCheck.d.ts +27 -12
- package/dist/tools/healthCheck.js +44 -6
- package/dist/tools/readWorkspaceFile.d.ts +7 -1
- package/dist/tools/readWorkspaceFile.js +48 -2
- package/dist/tools/registry.js +270 -19
- package/dist/tools/runVerification.d.ts +16 -0
- package/dist/tools/runVerification.js +32 -0
- package/dist/tools/safeStatus.d.ts +19 -0
- package/dist/tools/safeStatus.js +72 -0
- package/dist/tools/savePlan.d.ts +1 -0
- package/dist/tools/savePlan.js +38 -7
- package/dist/tools/searchWorkspace.d.ts +19 -0
- package/dist/tools/searchWorkspace.js +205 -0
- package/dist/tools/syncFile.d.ts +18 -0
- package/dist/tools/syncFile.js +65 -0
- package/dist/tools/taskOutputs.d.ts +2 -2
- package/dist/tools/taskTemplates.js +2 -1
- package/dist/tools/toolCatalog.d.ts +4 -3
- package/dist/tools/toolCatalog.js +34 -5
- package/dist/tools/waitForTask.d.ts +2 -2
- package/dist/tools/waitForTask.js +1 -1
- package/dist/version.d.ts +2 -2
- package/dist/version.js +2 -2
- package/dist/watcherStatus.d.ts +1 -0
- package/dist/watcherStatus.js +96 -4
- package/docs/chatgpt-usage.md +101 -0
- package/docs/performance-notes.md +55 -0
- package/docs/release-checklist.md +14 -0
- package/docs/release-v0.6.0.md +71 -0
- package/docs/release-v0.6.1.md +75 -0
- package/examples/config.example.json +5 -0
- package/examples/openai-tunnel/README.md +11 -4
- package/examples/openai-tunnel/chatgpt-test-prompt.md +18 -14
- package/examples/openai-tunnel/tunnel-client.example.yaml +8 -0
- package/package.json +13 -8
- package/scripts/brand-check.js +58 -12
- package/scripts/control-smoke.js +206 -0
- package/scripts/http-mcp-smoke.js +10 -2
- package/scripts/launchers/Check-PatchWarden-Health.cmd +6 -0
- package/scripts/launchers/Reset-PatchWarden-Tunnel-Key.cmd +6 -0
- package/scripts/launchers/Restart-PatchWarden.cmd +6 -0
- package/scripts/launchers/Start-PatchWarden-Direct-Tunnel.cmd +7 -0
- package/scripts/launchers/Start-PatchWarden-Tunnel.cmd +7 -0
- package/scripts/lifecycle-smoke.js +402 -8
- package/scripts/manage-patchwarden.ps1 +639 -0
- package/scripts/mcp-manifest-check.js +123 -58
- package/scripts/mcp-smoke.js +160 -2
- package/scripts/pack-clean.js +160 -5
- package/scripts/package-manifest-check.js +78 -0
- package/scripts/patchwarden-mcp-direct.cmd +7 -0
- package/scripts/patchwarden-mcp-stdio.cmd +1 -1
- package/scripts/restart-patchwarden.ps1 +5 -4
- package/scripts/start-patchwarden-tunnel.ps1 +261 -30
- package/scripts/tunnel-supervisor-smoke.js +36 -4
- package/scripts/unit-tests.js +36 -0
- package/scripts/watcher-supervisor-smoke.js +10 -6
- package/src/assessments/agentAssessor.ts +324 -0
- package/src/assessments/assessmentStore.ts +426 -0
- package/src/assessments/confirmCli.ts +29 -0
- package/src/config.ts +178 -4
- package/src/direct/directAudit.ts +400 -0
- package/src/direct/directGuards.ts +279 -0
- package/src/direct/directPatch.ts +258 -0
- package/src/direct/directSessionStore.ts +345 -0
- package/src/direct/directVerification.ts +138 -0
- package/src/doctor.ts +103 -7
- package/src/logging.ts +152 -0
- package/src/runner/agentInvocation.ts +125 -0
- package/src/runner/changeCapture.ts +352 -6
- package/src/runner/runTask.ts +279 -63
- package/src/runner/simpleProcess.ts +223 -0
- package/src/runner/watch.ts +18 -2
- package/src/security/commandGuard.ts +46 -4
- package/src/security/riskEngine.ts +160 -0
- package/src/security/runtimeGuard.ts +41 -0
- package/src/smoke-test.ts +1291 -4
- package/src/test/unit/android-doctor.test.ts +158 -0
- package/src/test/unit/chinese-path.test.ts +106 -0
- package/src/test/unit/command-guard.test.ts +221 -0
- package/src/test/unit/direct-guards.test.ts +297 -0
- package/src/test/unit/logging.test.ts +325 -0
- package/src/test/unit/path-guard.test.ts +150 -0
- package/src/test/unit/safe-status.test.ts +187 -0
- package/src/test/unit/sensitive-guard.test.ts +124 -0
- package/src/test/unit/sync-file.test.ts +231 -0
- package/src/test/unit/watcher-status.test.ts +190 -0
- package/src/tools/androidDoctor.ts +424 -0
- package/src/tools/applyPatch.ts +86 -0
- package/src/tools/auditSession.ts +28 -0
- package/src/tools/auditTask.ts +111 -7
- package/src/tools/createDirectSession.ts +113 -0
- package/src/tools/createTask.ts +405 -55
- package/src/tools/finalizeDirectSession.ts +144 -0
- package/src/tools/getTaskSummary.ts +133 -2
- package/src/tools/healthCheck.ts +45 -6
- package/src/tools/readWorkspaceFile.ts +85 -2
- package/src/tools/registry.ts +305 -19
- package/src/tools/runVerification.ts +58 -0
- package/src/tools/safeStatus.ts +96 -0
- package/src/tools/savePlan.ts +57 -7
- package/src/tools/searchWorkspace.ts +275 -0
- package/src/tools/syncFile.ts +122 -0
- package/src/tools/taskTemplates.ts +2 -1
- package/src/tools/toolCatalog.ts +37 -6
- package/src/tools/waitForTask.ts +3 -3
- package/src/version.ts +2 -2
- package/src/watcherStatus.ts +101 -4
- package/tsconfig.json +18 -17
- package/Check-PatchWarden-Health.cmd +0 -6
- package/Reset-PatchWarden-Tunnel-Key.cmd +0 -6
- package/Restart-PatchWarden.cmd +0 -19
- package/Start-PatchWarden-Tunnel.cmd +0 -7
- package/docs/release-v0.3.0.md +0 -43
- package/docs/release-v0.4.0.md +0 -74
package/README.en.md
ADDED
|
@@ -0,0 +1,1022 @@
|
|
|
1
|
+
# PatchWarden
|
|
2
|
+
|
|
3
|
+
<p align="right">
|
|
4
|
+
<a href="./README.md">简体中文</a> · <strong>English</strong>
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/patchwarden)
|
|
8
|
+
[](https://nodejs.org/)
|
|
9
|
+
[](LICENSE)
|
|
10
|
+
|
|
11
|
+
Current stable release: **v0.6.0**. See the
|
|
12
|
+
[release notes](docs/release-v0.6.0.md),
|
|
13
|
+
[migration guide](docs/migration-from-safe-bifrost.md), and
|
|
14
|
+
[GitHub Release](https://github.com/jiezeng2004-design/PatchWarden/releases/tag/v0.6.0).
|
|
15
|
+
|
|
16
|
+
PatchWarden is a security-focused MCP bridge for local coding agents.
|
|
17
|
+
ChatGPT, Codex, OpenCode, or another MCP client can plan and review work;
|
|
18
|
+
PatchWarden stores that plan as a workspace-scoped task, lets a preconfigured
|
|
19
|
+
local agent execute it, and returns results, diffs, and independent
|
|
20
|
+
verification evidence.
|
|
21
|
+
|
|
22
|
+

|
|
23
|
+
|
|
24
|
+
> [!IMPORTANT]
|
|
25
|
+
> PatchWarden is not a general-purpose remote shell. MCP clients cannot run
|
|
26
|
+
> arbitrary commands: files must remain inside the configured workspace,
|
|
27
|
+
> agents must be registered in advance, verification commands must exactly
|
|
28
|
+
> match the allowlist, and sensitive paths are blocked.
|
|
29
|
+
|
|
30
|
+
## Contents
|
|
31
|
+
|
|
32
|
+
- [What PatchWarden solves](#what-patchwarden-solves)
|
|
33
|
+
- [Runtime architecture](#runtime-architecture)
|
|
34
|
+
- [Requirements](#requirements)
|
|
35
|
+
- [Five-minute quick start](#five-minute-quick-start)
|
|
36
|
+
- [Complete configuration guide](#complete-configuration-guide)
|
|
37
|
+
- [Connect OpenCode](#connect-opencode)
|
|
38
|
+
- [Connect Codex](#connect-codex)
|
|
39
|
+
- [Connect ChatGPT](#connect-chatgpt)
|
|
40
|
+
- [Proxy configuration: read this first](#proxy-configuration-read-this-first)
|
|
41
|
+
- [Recommended task workflow](#recommended-task-workflow)
|
|
42
|
+
- [HTTP MCP mode](#http-mcp-mode)
|
|
43
|
+
- [Diagnostics and health checks](#diagnostics-and-health-checks)
|
|
44
|
+
- [Lessons learned and troubleshooting](#lessons-learned-and-troubleshooting)
|
|
45
|
+
- [Security boundaries and local data](#security-boundaries-and-local-data)
|
|
46
|
+
- [Upgrading and migration](#upgrading-and-migration)
|
|
47
|
+
- [Development and release verification](#development-and-release-verification)
|
|
48
|
+
|
|
49
|
+
## What PatchWarden solves
|
|
50
|
+
|
|
51
|
+
Many local coding bridges expose a broad shell to the upstream model.
|
|
52
|
+
PatchWarden uses a narrower, auditable task channel:
|
|
53
|
+
|
|
54
|
+
- Upstream models call explicit MCP tools instead of assembling arbitrary
|
|
55
|
+
shell commands.
|
|
56
|
+
- Every task must specify a `repo_path` inside `workspaceRoot`.
|
|
57
|
+
- Agent launch commands come from local configuration, not model input.
|
|
58
|
+
- Verification commands must exactly match `allowedTestCommands`.
|
|
59
|
+
- Every completed task records structured results, a full diff, file
|
|
60
|
+
statistics, and independent verification output.
|
|
61
|
+
- Changes outside the requested repository cause a scope violation instead of
|
|
62
|
+
being silently accepted.
|
|
63
|
+
- Sensitive paths such as `.env` files, tokens, SSH keys, cookies, and
|
|
64
|
+
credential stores are blocked by default.
|
|
65
|
+
|
|
66
|
+
Good use cases:
|
|
67
|
+
|
|
68
|
+
- Let ChatGPT plan and review while OpenCode or Codex executes locally.
|
|
69
|
+
- Add an auditable plan → task → verify flow to a local MCP client.
|
|
70
|
+
- Review `result.json`, `diff.patch`, and `verify.json` after execution.
|
|
71
|
+
- Automate tasks that need workspace containment, command allowlists, and
|
|
72
|
+
sensitive-data protection.
|
|
73
|
+
|
|
74
|
+
PatchWarden is not designed for:
|
|
75
|
+
|
|
76
|
+
- Giving an MCP client unrestricted shell access.
|
|
77
|
+
- Managing an entire drive, home directory, or directory full of private data.
|
|
78
|
+
- Unattended commits, pushes, releases, or production changes.
|
|
79
|
+
|
|
80
|
+
## Runtime architecture
|
|
81
|
+
|
|
82
|
+
```text
|
|
83
|
+
ChatGPT / Codex / OpenCode / another MCP client
|
|
84
|
+
|
|
|
85
|
+
v
|
|
86
|
+
PatchWarden MCP Server
|
|
87
|
+
|
|
|
88
|
+
save_plan / create_task
|
|
89
|
+
|
|
|
90
|
+
v
|
|
91
|
+
.patchwarden/tasks/<task_id>/
|
|
92
|
+
|
|
|
93
|
+
Watcher finds task
|
|
94
|
+
|
|
|
95
|
+
v
|
|
96
|
+
Local agent (OpenCode / Codex)
|
|
97
|
+
|
|
|
98
|
+
v
|
|
99
|
+
result.json / diff.patch / verify.json / status.json
|
|
100
|
+
|
|
|
101
|
+
v
|
|
102
|
+
Client reviews and audits
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
A complete setup normally has three distinct roles:
|
|
106
|
+
|
|
107
|
+
1. **MCP Server** — started by Codex, OpenCode, or the tunnel.
|
|
108
|
+
2. **Watcher** — monitors pending tasks and launches the local agent.
|
|
109
|
+
3. **Local agent** — modifies the code and must be registered in advance.
|
|
110
|
+
|
|
111
|
+
> [!WARNING]
|
|
112
|
+
> “MCP connected” does not mean tasks can execute. If the Watcher is not
|
|
113
|
+
> running, `create_task` can still save a task, but the task remains queued and
|
|
114
|
+
> reports `execution_blocked: true`.
|
|
115
|
+
|
|
116
|
+
## Requirements
|
|
117
|
+
|
|
118
|
+
- Node.js 18 or newer
|
|
119
|
+
- npm
|
|
120
|
+
- Git (optional, but reliable `git.diff` evidence requires it)
|
|
121
|
+
- At least one local coding agent, such as OpenCode or the Codex CLI
|
|
122
|
+
- Windows tunnel mode also requires `tunnel-client.exe`, a Tunnel ID, and a
|
|
123
|
+
runtime API key
|
|
124
|
+
|
|
125
|
+
Check the Windows environment in PowerShell:
|
|
126
|
+
|
|
127
|
+
```powershell
|
|
128
|
+
node -v
|
|
129
|
+
npm.cmd -v
|
|
130
|
+
git --version
|
|
131
|
+
where.exe opencode
|
|
132
|
+
where.exe codex
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
If `where.exe codex` only returns the Codex Desktop executable under
|
|
136
|
+
WindowsApps, it may not be a callable Codex CLI. Install or point to the real
|
|
137
|
+
CLI, or configure OpenCode as the execution agent.
|
|
138
|
+
|
|
139
|
+
## Five-minute quick start
|
|
140
|
+
|
|
141
|
+
### Option A: run from source (recommended)
|
|
142
|
+
|
|
143
|
+
Source mode is the easiest way to use the Watcher, Windows launchers, and
|
|
144
|
+
diagnostic scripts together.
|
|
145
|
+
|
|
146
|
+
Windows PowerShell:
|
|
147
|
+
|
|
148
|
+
```powershell
|
|
149
|
+
git clone https://github.com/jiezeng2004-design/PatchWarden.git
|
|
150
|
+
cd .\PatchWarden
|
|
151
|
+
npm.cmd ci
|
|
152
|
+
npm.cmd run build
|
|
153
|
+
Copy-Item .\examples\config.example.json .\patchwarden.config.json
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Edit `patchwarden.config.json` and set at least:
|
|
157
|
+
|
|
158
|
+
- `workspaceRoot`
|
|
159
|
+
- `agents`
|
|
160
|
+
- `allowedTestCommands`
|
|
161
|
+
|
|
162
|
+
Run diagnostics:
|
|
163
|
+
|
|
164
|
+
```powershell
|
|
165
|
+
npm.cmd run doctor
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Start the Watcher:
|
|
169
|
+
|
|
170
|
+
```powershell
|
|
171
|
+
$env:PATCHWARDEN_CONFIG = (Resolve-Path .\patchwarden.config.json)
|
|
172
|
+
npm.cmd run watch
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Keep this window open, then configure OpenCode, Codex, or ChatGPT as described
|
|
176
|
+
below.
|
|
177
|
+
|
|
178
|
+
### Option B: use the npm package
|
|
179
|
+
|
|
180
|
+
The npm package is convenient for launching a pinned MCP server. Task
|
|
181
|
+
execution still requires a separate Watcher.
|
|
182
|
+
|
|
183
|
+
```powershell
|
|
184
|
+
New-Item -ItemType Directory .\patchwarden-runtime
|
|
185
|
+
Set-Location .\patchwarden-runtime
|
|
186
|
+
npm.cmd init -y
|
|
187
|
+
npm.cmd install patchwarden@0.6.0
|
|
188
|
+
Copy-Item .\node_modules\patchwarden\examples\config.example.json .\patchwarden.config.json
|
|
189
|
+
$env:PATCHWARDEN_CONFIG = (Resolve-Path .\patchwarden.config.json)
|
|
190
|
+
node .\node_modules\patchwarden\dist\runner\watch.js
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
An MCP client can launch:
|
|
194
|
+
|
|
195
|
+
```text
|
|
196
|
+
npx.cmd -y patchwarden@0.6.0
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Pin the version in important environments instead of using `latest`
|
|
200
|
+
unconditionally.
|
|
201
|
+
|
|
202
|
+
## Complete configuration guide
|
|
203
|
+
|
|
204
|
+
Create a local configuration from the example:
|
|
205
|
+
|
|
206
|
+
```powershell
|
|
207
|
+
Copy-Item .\examples\config.example.json .\patchwarden.config.json
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Recommended Windows example:
|
|
211
|
+
|
|
212
|
+
```json
|
|
213
|
+
{
|
|
214
|
+
"workspaceRoot": "D:/ai_agent/codex_program",
|
|
215
|
+
"plansDir": ".patchwarden/plans",
|
|
216
|
+
"tasksDir": ".patchwarden/tasks",
|
|
217
|
+
"toolProfile": "full",
|
|
218
|
+
"agents": {
|
|
219
|
+
"opencode": {
|
|
220
|
+
"command": "opencode",
|
|
221
|
+
"args": ["run", "{prompt}"]
|
|
222
|
+
},
|
|
223
|
+
"codex": {
|
|
224
|
+
"command": "codex",
|
|
225
|
+
"args": ["exec", "--cd", "{repo}", "{prompt}"]
|
|
226
|
+
}
|
|
227
|
+
},
|
|
228
|
+
"allowedTestCommands": [
|
|
229
|
+
"npm test",
|
|
230
|
+
"npm run build",
|
|
231
|
+
"npm run lint",
|
|
232
|
+
"pytest"
|
|
233
|
+
],
|
|
234
|
+
"repoAllowedTestCommands": {
|
|
235
|
+
"desktop-app": ["npm run release:check"]
|
|
236
|
+
},
|
|
237
|
+
"maxReadFileBytes": 200000,
|
|
238
|
+
"defaultTaskTimeoutSeconds": 900,
|
|
239
|
+
"maxTaskTimeoutSeconds": 3600,
|
|
240
|
+
"watcherStaleSeconds": 30,
|
|
241
|
+
"httpPort": 7331
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Configuration fields:
|
|
246
|
+
|
|
247
|
+
| Field | Required | Description |
|
|
248
|
+
| --- | --- | --- |
|
|
249
|
+
| `workspaceRoot` | Yes | The only workspace root PatchWarden may access. |
|
|
250
|
+
| `plansDir` | Yes | Plan directory, normally `.patchwarden/plans`. |
|
|
251
|
+
| `tasksDir` | Yes | Task and result directory, normally `.patchwarden/tasks`. |
|
|
252
|
+
| `toolProfile` | No | `full` or `chatgpt_core`; use `full` for local clients. |
|
|
253
|
+
| `agents` | Yes | Execution-agent allowlist; supports `{repo}` and `{prompt}` placeholders. |
|
|
254
|
+
| `allowedTestCommands` | Yes | Exact allowlist for independent verification commands. |
|
|
255
|
+
| `repoAllowedTestCommands` | No | Extra exact commands keyed by workspace-relative repository path; wildcards are unsupported. |
|
|
256
|
+
| `maxReadFileBytes` | Yes | Maximum bytes returned by one MCP file read. |
|
|
257
|
+
| `defaultTaskTimeoutSeconds` | Yes | Default task timeout. |
|
|
258
|
+
| `maxTaskTimeoutSeconds` | Yes | Maximum timeout a client may request. |
|
|
259
|
+
| `watcherStaleSeconds` | Yes | Watcher heartbeat expiry, from 5 to 3600 seconds. |
|
|
260
|
+
| `repoAliases` | No | Short aliases for repositories inside the workspace. |
|
|
261
|
+
| `httpPort` | No | Local HTTP MCP port; default is 7331. |
|
|
262
|
+
| `http.ownerTokenEnv` | No | Environment variable that contains the HTTP owner token. |
|
|
263
|
+
|
|
264
|
+
Important configuration rules:
|
|
265
|
+
|
|
266
|
+
- In Windows JSON, prefer paths such as `D:/path/to/project`.
|
|
267
|
+
- If you use backslashes, escape them as `D:\\path\\to\\project`.
|
|
268
|
+
- Do not set `workspaceRoot` to a drive root, home directory, Desktop,
|
|
269
|
+
Downloads, or Documents.
|
|
270
|
+
- `plansDir` and `tasksDir` are resolved relative to `workspaceRoot`.
|
|
271
|
+
- `repo_path` must stay inside `workspaceRoot` and cannot escape with `..`.
|
|
272
|
+
- `allowedTestCommands` uses exact matching; similar commands are not
|
|
273
|
+
automatically authorized.
|
|
274
|
+
- Repository-specific commands come only from trusted local configuration;
|
|
275
|
+
a target repository cannot authorize itself through `package.json`.
|
|
276
|
+
- Configuration may contain private paths and should not be committed.
|
|
277
|
+
|
|
278
|
+
Set the configuration path:
|
|
279
|
+
|
|
280
|
+
```powershell
|
|
281
|
+
$env:PATCHWARDEN_CONFIG = "D:\path\to\patchwarden.config.json"
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
This environment variable affects only the current PowerShell process and its
|
|
285
|
+
children. Set it again in every separately opened terminal that starts a
|
|
286
|
+
Watcher or MCP Server.
|
|
287
|
+
|
|
288
|
+
## Connect OpenCode
|
|
289
|
+
|
|
290
|
+
Local source mode is recommended so the MCP Server, Watcher, and
|
|
291
|
+
configuration remain on the same version.
|
|
292
|
+
|
|
293
|
+
Edit:
|
|
294
|
+
|
|
295
|
+
```text
|
|
296
|
+
%USERPROFILE%\.config\opencode\opencode.jsonc
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
Example:
|
|
300
|
+
|
|
301
|
+
```jsonc
|
|
302
|
+
{
|
|
303
|
+
"mcp": {
|
|
304
|
+
"patchwarden": {
|
|
305
|
+
"type": "local",
|
|
306
|
+
"command": [
|
|
307
|
+
"node",
|
|
308
|
+
"D:/path/to/PatchWarden/dist/index.js"
|
|
309
|
+
],
|
|
310
|
+
"environment": {
|
|
311
|
+
"PATCHWARDEN_CONFIG": "D:/path/to/PatchWarden/patchwarden.config.json",
|
|
312
|
+
"PATCHWARDEN_TOOL_PROFILE": "full"
|
|
313
|
+
},
|
|
314
|
+
"enabled": true
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
Verify the connection:
|
|
321
|
+
|
|
322
|
+
```powershell
|
|
323
|
+
opencode mcp list
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
Expected result:
|
|
327
|
+
|
|
328
|
+
```text
|
|
329
|
+
patchwarden connected
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
In a separate PowerShell window, start the Watcher:
|
|
333
|
+
|
|
334
|
+
```powershell
|
|
335
|
+
$env:PATCHWARDEN_CONFIG = (Resolve-Path .\patchwarden.config.json)
|
|
336
|
+
npm.cmd run watch
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
If OpenCode sees the MCP tools but tasks remain queued, check the Watcher
|
|
340
|
+
before repeatedly deleting and recreating the MCP entry.
|
|
341
|
+
|
|
342
|
+
## Connect Codex
|
|
343
|
+
|
|
344
|
+
Edit:
|
|
345
|
+
|
|
346
|
+
```text
|
|
347
|
+
%USERPROFILE%\.codex\config.toml
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
Pinned npm configuration:
|
|
351
|
+
|
|
352
|
+
```toml
|
|
353
|
+
[mcp_servers.patchwarden]
|
|
354
|
+
command = "npx.cmd"
|
|
355
|
+
args = ["-y", "patchwarden@0.6.0"]
|
|
356
|
+
|
|
357
|
+
[mcp_servers.patchwarden.env]
|
|
358
|
+
PATCHWARDEN_CONFIG = "D:\\path\\to\\patchwarden.config.json"
|
|
359
|
+
PATCHWARDEN_TOOL_PROFILE = "full"
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
Local source configuration:
|
|
363
|
+
|
|
364
|
+
```toml
|
|
365
|
+
[mcp_servers.patchwarden]
|
|
366
|
+
command = "node"
|
|
367
|
+
args = ["D:\\path\\to\\PatchWarden\\dist\\index.js"]
|
|
368
|
+
|
|
369
|
+
[mcp_servers.patchwarden.env]
|
|
370
|
+
PATCHWARDEN_CONFIG = "D:\\path\\to\\PatchWarden\\patchwarden.config.json"
|
|
371
|
+
PATCHWARDEN_TOOL_PROFILE = "full"
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
Fully exit and reopen Codex Desktop after editing the configuration, then
|
|
375
|
+
start a new conversation. Existing conversations may retain the old MCP tool
|
|
376
|
+
catalog.
|
|
377
|
+
|
|
378
|
+
Codex as an **MCP client** and the Codex CLI as an **execution agent** are
|
|
379
|
+
different roles. A successful MCP connection does not prove that the CLI
|
|
380
|
+
configured under `agents` is available.
|
|
381
|
+
|
|
382
|
+
## Connect ChatGPT
|
|
383
|
+
|
|
384
|
+
Recommended Windows path:
|
|
385
|
+
|
|
386
|
+
```text
|
|
387
|
+
ChatGPT Web
|
|
388
|
+
→ ChatGPT Connector
|
|
389
|
+
→ OpenAI Secure MCP Tunnel
|
|
390
|
+
→ PatchWarden stdio MCP
|
|
391
|
+
→ Watcher
|
|
392
|
+
→ local agent
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
### One-click launcher
|
|
396
|
+
|
|
397
|
+
Prepare:
|
|
398
|
+
|
|
399
|
+
- A built PatchWarden source checkout
|
|
400
|
+
- A valid `patchwarden.config.json`
|
|
401
|
+
- `tunnel-client.exe`
|
|
402
|
+
- A Tunnel ID
|
|
403
|
+
- A tunnel runtime API key
|
|
404
|
+
- A working HTTP proxy with a supported exit region
|
|
405
|
+
|
|
406
|
+
Configure the proxy first, then run:
|
|
407
|
+
|
|
408
|
+
```text
|
|
409
|
+
PatchWarden.cmd start core
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
The launcher:
|
|
413
|
+
|
|
414
|
+
- Builds `dist/index.js` if it is missing.
|
|
415
|
+
- Verifies v0.6.0, the fixed 16-tool `chatgpt_core` catalog, and its schema
|
|
416
|
+
manifest.
|
|
417
|
+
- Reads or prompts for the Tunnel ID.
|
|
418
|
+
- Reads or prompts for the runtime API key.
|
|
419
|
+
- Stores credentials with Windows DPAPI under `%APPDATA%\patchwarden`.
|
|
420
|
+
- Starts and supervises only the Watcher it owns.
|
|
421
|
+
- Runs `tunnel-client doctor` and readiness checks.
|
|
422
|
+
- Applies capped retries to recoverable disconnects.
|
|
423
|
+
|
|
424
|
+
Runtime status is stored under:
|
|
425
|
+
|
|
426
|
+
```text
|
|
427
|
+
%LOCALAPPDATA%\patchwarden\runtime
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
This directory contains PIDs, health state, and redacted diagnostics. It must
|
|
431
|
+
not contain the API key or Tunnel ID.
|
|
432
|
+
|
|
433
|
+
When creating the ChatGPT Connector:
|
|
434
|
+
|
|
435
|
+
- Select the tunnel **Channel**.
|
|
436
|
+
- Choose **None** for authentication unless you implemented OAuth.
|
|
437
|
+
- Do not use the local `127.0.0.1` address as a public Server URL.
|
|
438
|
+
- Reconnect the Connector and open a new ChatGPT conversation after changes.
|
|
439
|
+
- Disable browser translation extensions if the Platform page behaves
|
|
440
|
+
unexpectedly.
|
|
441
|
+
|
|
442
|
+
See [examples/openai-tunnel/README.md](examples/openai-tunnel/README.md) for
|
|
443
|
+
the expanded tunnel examples.
|
|
444
|
+
|
|
445
|
+
## Proxy configuration: read this first
|
|
446
|
+
|
|
447
|
+
### Launcher default
|
|
448
|
+
|
|
449
|
+
`scripts/start-patchwarden-tunnel.ps1` first reads `HTTPS_PROXY` from the
|
|
450
|
+
current process. If it is absent, the launcher defaults to:
|
|
451
|
+
|
|
452
|
+
```text
|
|
453
|
+
http://127.0.0.1:7892
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
**Port 7892 is not universal.** Clash, Mihomo, V2Ray, sing-box, and other proxy
|
|
457
|
+
applications may use 7890, 7897, 10809, or a custom port. Check the actual
|
|
458
|
+
HTTP/Mixed listening port in your proxy application instead of copying the
|
|
459
|
+
example.
|
|
460
|
+
|
|
461
|
+
Test the port:
|
|
462
|
+
|
|
463
|
+
```powershell
|
|
464
|
+
Test-NetConnection 127.0.0.1 -Port 7892
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
If `TcpTestSucceeded` is `False`, no proxy service is listening on that port.
|
|
468
|
+
|
|
469
|
+
### Recommended environment
|
|
470
|
+
|
|
471
|
+
These variables affect only the current PowerShell process and its children.
|
|
472
|
+
They do not modify system-wide environment variables:
|
|
473
|
+
|
|
474
|
+
```powershell
|
|
475
|
+
$env:HTTPS_PROXY = "http://127.0.0.1:YOUR_HTTP_OR_MIXED_PORT"
|
|
476
|
+
$env:HTTP_PROXY = $env:HTTPS_PROXY
|
|
477
|
+
$env:ALL_PROXY = $env:HTTPS_PROXY
|
|
478
|
+
$env:NO_PROXY = "localhost,127.0.0.1,::1"
|
|
479
|
+
.\PatchWarden.cmd start core
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
Example for a Mixed port of 7890:
|
|
483
|
+
|
|
484
|
+
```powershell
|
|
485
|
+
$env:HTTPS_PROXY = "http://127.0.0.1:7890"
|
|
486
|
+
$env:HTTP_PROXY = $env:HTTPS_PROXY
|
|
487
|
+
$env:ALL_PROXY = $env:HTTPS_PROXY
|
|
488
|
+
$env:NO_PROXY = "localhost,127.0.0.1,::1"
|
|
489
|
+
.\PatchWarden.cmd start core
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
Using `HTTPS_PROXY=http://...` is expected: the variable identifies HTTPS
|
|
493
|
+
requests that should use a proxy, while the `http://` scheme describes the
|
|
494
|
+
local HTTP proxy endpoint. Do not enter a SOCKS-only port into the current
|
|
495
|
+
`--http-proxy` setting.
|
|
496
|
+
|
|
497
|
+
### Three separate network paths
|
|
498
|
+
|
|
499
|
+
| Network path | Proxy? | Notes |
|
|
500
|
+
| --- | --- | --- |
|
|
501
|
+
| Tunnel → OpenAI control plane | Usually | The launcher passes `HTTPS_PROXY` to tunnel-client. |
|
|
502
|
+
| PatchWarden → `127.0.0.1` | No | Keep `NO_PROXY=localhost,127.0.0.1,::1`. |
|
|
503
|
+
| Local agent → model provider API | Agent-specific | The Watcher and child agent may inherit terminal proxy variables. |
|
|
504
|
+
| npm / GitHub | Network-specific | Their connectivity is separate from tunnel health. |
|
|
505
|
+
|
|
506
|
+
If you start the Watcher manually and want its child agent to use the same
|
|
507
|
+
proxy, set the proxy variables in the PowerShell window that launches the
|
|
508
|
+
Watcher.
|
|
509
|
+
|
|
510
|
+
### Region errors are not code errors
|
|
511
|
+
|
|
512
|
+
If logs show:
|
|
513
|
+
|
|
514
|
+
```text
|
|
515
|
+
unsupported_country_region_territory
|
|
516
|
+
403 Forbidden
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
the proxy exit region is not accepted by the current OpenAI control plane.
|
|
520
|
+
Reinstalling dependencies, rebuilding `dist`, or repeatedly logging in will
|
|
521
|
+
usually not address this condition. Switch to a supported exit region and
|
|
522
|
+
restart the tunnel. Support can change, so this project does not hard-code a
|
|
523
|
+
country list.
|
|
524
|
+
|
|
525
|
+
### Proxy troubleshooting order
|
|
526
|
+
|
|
527
|
+
1. Confirm the proxy application is running.
|
|
528
|
+
2. Use its actual HTTP/Mixed port, not a copied example.
|
|
529
|
+
3. Confirm `Test-NetConnection` succeeds.
|
|
530
|
+
4. Set `HTTPS_PROXY` in the same terminal that starts the tunnel.
|
|
531
|
+
5. Keep local addresses in `NO_PROXY`.
|
|
532
|
+
6. Check whether the exit region is accepted.
|
|
533
|
+
7. Then run `PatchWarden.cmd health` and tunnel-client doctor.
|
|
534
|
+
|
|
535
|
+
## Recommended task workflow
|
|
536
|
+
|
|
537
|
+
Use this sequence:
|
|
538
|
+
|
|
539
|
+
1. `health_check` — verify version, workspace, Watcher, and tool catalog.
|
|
540
|
+
2. `list_agents` — confirm the local execution agent is available.
|
|
541
|
+
3. `list_workspace` — identify the correct `repo_path`.
|
|
542
|
+
4. `save_plan`, or provide an `inline_plan` when creating the task.
|
|
543
|
+
5. `create_task` — specify the agent, repository, and verification commands.
|
|
544
|
+
6. Use `wait_for_task(timeout_seconds: 25)` for short tasks; poll long tasks with `list_tasks` and `get_task_status`.
|
|
545
|
+
7. `get_task_summary(view: "compact")` — inspect bounded structured evidence first.
|
|
546
|
+
8. `get_result_json`, `get_diff`, and `get_test_log` — inspect detail as needed.
|
|
547
|
+
9. `audit_task` — independently verify the result.
|
|
548
|
+
10. Let a human decide whether to accept, commit, or publish.
|
|
549
|
+
|
|
550
|
+
Example `create_task` payload:
|
|
551
|
+
|
|
552
|
+
```json
|
|
553
|
+
{
|
|
554
|
+
"agent": "opencode",
|
|
555
|
+
"repo_path": "my-project",
|
|
556
|
+
"inline_plan": "Fix form validation on the login page, avoid unrelated files, and add regression coverage.",
|
|
557
|
+
"verify_commands": [
|
|
558
|
+
"npm run build",
|
|
559
|
+
"npm test"
|
|
560
|
+
],
|
|
561
|
+
"timeout_seconds": 900
|
|
562
|
+
}
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
Rules:
|
|
566
|
+
|
|
567
|
+
- `repo_path` must stay inside `workspaceRoot`.
|
|
568
|
+
- Every `verify_commands` entry must exactly match the global or current
|
|
569
|
+
repository's trusted command allowlist.
|
|
570
|
+
- Select exactly one plan source: `plan_id`, `inline_plan`, or `template`.
|
|
571
|
+
- When `wait_for_task` returns `continuation_required: true`, call it again.
|
|
572
|
+
- `terminal: true` means the task reached a terminal state, not that the work
|
|
573
|
+
is correct.
|
|
574
|
+
|
|
575
|
+
Built-in templates:
|
|
576
|
+
|
|
577
|
+
- `inspect_only`
|
|
578
|
+
- `feature_small`
|
|
579
|
+
- `fix_tests`
|
|
580
|
+
- `release_check`
|
|
581
|
+
- `rollback_scope_violation`
|
|
582
|
+
|
|
583
|
+
ChatGPT tasks should prefer the first three guarded templates: use
|
|
584
|
+
`inspect_only` for read-only diagnosis, `feature_small` for a narrowly scoped
|
|
585
|
+
change, and `fix_tests` for a known verification failure. Use `inline_plan` or
|
|
586
|
+
a saved long plan only when these templates cannot express the goal. Prefer an
|
|
587
|
+
`execution_mode: "assess_only"` call followed by the returned `next_tool_call`;
|
|
588
|
+
do not resend the goal, plan, repository, agent, or verification arguments in
|
|
589
|
+
the execute call.
|
|
590
|
+
|
|
591
|
+
`inspect_only` and rollback-review tasks fail with
|
|
592
|
+
`failed_policy_violation` if they modify files. Rollback review only writes a
|
|
593
|
+
plan; it never automatically reverts user changes.
|
|
594
|
+
|
|
595
|
+
`audit_task` places evidence-backed failures in `confirmed_failures` and lists
|
|
596
|
+
heuristic warnings separately in `possible_false_positives` and
|
|
597
|
+
`manual_verification_items`. A `warn` verdict therefore does not automatically
|
|
598
|
+
mean the task is wrong.
|
|
599
|
+
|
|
600
|
+
### Task artifacts
|
|
601
|
+
|
|
602
|
+
| File | Purpose |
|
|
603
|
+
| --- | --- |
|
|
604
|
+
| `status.json` | Current status, phase, heartbeat, and error details. |
|
|
605
|
+
| `progress.md` | Progress reported by the agent. |
|
|
606
|
+
| `result.md` | Human-readable execution report. |
|
|
607
|
+
| `result.json` | Structured result, paths, changes, warnings, and next steps. |
|
|
608
|
+
| `diff.patch` | Complete task change evidence. |
|
|
609
|
+
| `file-stats.json` | Per-file addition and deletion statistics. |
|
|
610
|
+
| `verify.json` | Structured record for every independent verification command. |
|
|
611
|
+
| `verify.log` | Human-readable independent verification output. |
|
|
612
|
+
| `test.log` | Test output captured during agent execution. |
|
|
613
|
+
|
|
614
|
+
An agent saying “published” or “pushed” is not reliable remote evidence.
|
|
615
|
+
Verify GitHub, npm, tags, and releases against the live platform state.
|
|
616
|
+
|
|
617
|
+
## HTTP MCP mode
|
|
618
|
+
|
|
619
|
+
The HTTP server binds only to `127.0.0.1`. The default port is 7331 and it is
|
|
620
|
+
not directly exposed to the LAN.
|
|
621
|
+
|
|
622
|
+
Terminal 1 — start the Watcher:
|
|
623
|
+
|
|
624
|
+
```powershell
|
|
625
|
+
$env:PATCHWARDEN_CONFIG = (Resolve-Path .\patchwarden.config.json)
|
|
626
|
+
npm.cmd run watch
|
|
627
|
+
```
|
|
628
|
+
|
|
629
|
+
Terminal 2 — start HTTP MCP:
|
|
630
|
+
|
|
631
|
+
```powershell
|
|
632
|
+
$env:PATCHWARDEN_CONFIG = (Resolve-Path .\patchwarden.config.json)
|
|
633
|
+
npm.cmd run start:http
|
|
634
|
+
```
|
|
635
|
+
|
|
636
|
+
Health check:
|
|
637
|
+
|
|
638
|
+
```powershell
|
|
639
|
+
Invoke-RestMethod http://127.0.0.1:7331/healthz
|
|
640
|
+
```
|
|
641
|
+
|
|
642
|
+
MCP endpoint:
|
|
643
|
+
|
|
644
|
+
```text
|
|
645
|
+
http://127.0.0.1:7331/mcp
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
Optional token configuration:
|
|
649
|
+
|
|
650
|
+
```json
|
|
651
|
+
{
|
|
652
|
+
"httpPort": 7331,
|
|
653
|
+
"http": {
|
|
654
|
+
"ownerTokenEnv": "PATCHWARDEN_OWNER_TOKEN"
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
```
|
|
658
|
+
|
|
659
|
+
Set the token in the PowerShell process that starts the server:
|
|
660
|
+
|
|
661
|
+
```powershell
|
|
662
|
+
$env:PATCHWARDEN_OWNER_TOKEN = "use-a-random-local-only-value"
|
|
663
|
+
```
|
|
664
|
+
|
|
665
|
+
Clients can send `Authorization: Bearer ...` or `x-patchwarden-token`. Never
|
|
666
|
+
write the token into configuration, documentation, logs, or Git.
|
|
667
|
+
|
|
668
|
+
> [!CAUTION]
|
|
669
|
+
> Do not expose local port 7331 through router port forwarding, a
|
|
670
|
+
> `0.0.0.0` relay, or an ordinary reverse proxy. Use an authenticated secure
|
|
671
|
+
> tunnel for remote access.
|
|
672
|
+
|
|
673
|
+
## Diagnostics and health checks
|
|
674
|
+
|
|
675
|
+
Project diagnostics:
|
|
676
|
+
|
|
677
|
+
```powershell
|
|
678
|
+
npm.cmd run doctor
|
|
679
|
+
```
|
|
680
|
+
|
|
681
|
+
Doctor checks Node, npm, Git, configuration, workspace containment, sensitive
|
|
682
|
+
path protection, agent commands, the tool manifest, HTTP port, task
|
|
683
|
+
directories, and build output.
|
|
684
|
+
|
|
685
|
+
### Unified Windows control entry point
|
|
686
|
+
|
|
687
|
+
Double-click `PatchWarden.cmd` for one menu that starts, stops, restarts, and
|
|
688
|
+
checks Core Agent and Direct independently or together. The same operations are
|
|
689
|
+
available from PowerShell:
|
|
690
|
+
|
|
691
|
+
```powershell
|
|
692
|
+
.\PatchWarden.cmd start core
|
|
693
|
+
.\PatchWarden.cmd start direct
|
|
694
|
+
.\PatchWarden.cmd stop all
|
|
695
|
+
.\PatchWarden.cmd restart all
|
|
696
|
+
.\PatchWarden.cmd status all
|
|
697
|
+
.\PatchWarden.cmd kill all
|
|
698
|
+
```
|
|
699
|
+
|
|
700
|
+
The old single-purpose launchers remain under `scripts/launchers/` as a
|
|
701
|
+
compatibility layer. Personal launchers live under `.local/launchers/` and
|
|
702
|
+
remain excluded from Git and release packages. `stop` and `restart` correlate
|
|
703
|
+
runtime state with the exact Tunnel profile, project launcher, and process tree,
|
|
704
|
+
so they can clean up an orphaned `tunnel-client.exe` for that profile without
|
|
705
|
+
terminating unrelated processes. `kill` is an explicit force-clean command but
|
|
706
|
+
keeps the same profile and project-path restrictions. If an unrelated process
|
|
707
|
+
owns port 8080 or 8081, the operation stops and reports its PID.
|
|
708
|
+
|
|
709
|
+
`status` cross-checks runtime JSON, the health URL file, the fixed `/readyz` and
|
|
710
|
+
`/healthz` endpoints, and the real process list. A ready endpoint therefore wins
|
|
711
|
+
over a stale stopped status file. Supervisor output is written to:
|
|
712
|
+
|
|
713
|
+
```text
|
|
714
|
+
%LOCALAPPDATA%\patchwarden\runtime\tunnel-client.stdout.log
|
|
715
|
+
%LOCALAPPDATA%\patchwarden\runtime\tunnel-client.stderr.log
|
|
716
|
+
%LOCALAPPDATA%\patchwarden\runtime-direct\tunnel-client.stdout.log
|
|
717
|
+
%LOCALAPPDATA%\patchwarden\runtime-direct\tunnel-client.stderr.log
|
|
718
|
+
```
|
|
719
|
+
|
|
720
|
+
On a non-zero exit, the launcher displays the last 30 stderr lines and records
|
|
721
|
+
the exit code, redacted stdout/stderr tails, and log paths in
|
|
722
|
+
`tunnel-status.json`. It never prints the API key value.
|
|
723
|
+
|
|
724
|
+
Detailed Windows tunnel health:
|
|
725
|
+
|
|
726
|
+
```text
|
|
727
|
+
PatchWarden.cmd health
|
|
728
|
+
```
|
|
729
|
+
|
|
730
|
+
It reports:
|
|
731
|
+
|
|
732
|
+
- Source and `dist` versions
|
|
733
|
+
- The real MCP process source
|
|
734
|
+
- Tool profile, count, names, and schema hash
|
|
735
|
+
- Workspace and task-directory access
|
|
736
|
+
- Watcher heartbeat
|
|
737
|
+
- Tunnel readiness
|
|
738
|
+
- Mixed-version process warnings
|
|
739
|
+
|
|
740
|
+
The check is read-only and does not terminate processes.
|
|
741
|
+
|
|
742
|
+
For expanded MCP diagnostics, call `health_check` with:
|
|
743
|
+
|
|
744
|
+
```json
|
|
745
|
+
{
|
|
746
|
+
"detail": "self_diagnostic"
|
|
747
|
+
}
|
|
748
|
+
```
|
|
749
|
+
|
|
750
|
+
This includes configured agents, allowlist counts, recent failures, and tool
|
|
751
|
+
catalog consistency.
|
|
752
|
+
|
|
753
|
+
After a configuration or version change, use:
|
|
754
|
+
|
|
755
|
+
```text
|
|
756
|
+
PatchWarden.cmd restart all
|
|
757
|
+
```
|
|
758
|
+
|
|
759
|
+
It stops only this project's launchers and Watcher plus `tunnel-client.exe`
|
|
760
|
+
processes that exactly match the selected profile. It does not globally
|
|
761
|
+
terminate unrelated PatchWarden, OpenCode, or Codex instances.
|
|
762
|
+
|
|
763
|
+
## Lessons learned and troubleshooting
|
|
764
|
+
|
|
765
|
+
### Quick reference
|
|
766
|
+
|
|
767
|
+
| Symptom | Most likely cause | Fix |
|
|
768
|
+
| --- | --- | --- |
|
|
769
|
+
| Tunnel connection keeps timing out | No proxy is listening on default port 7892 | Find the real HTTP/Mixed port, set `HTTPS_PROXY`, and start from the same terminal. |
|
|
770
|
+
| Logs show 403 and `unsupported_country_region_territory` | Unsupported proxy exit region | Switch exit region and restart the tunnel. |
|
|
771
|
+
| `list_workspace` only shows `tunnel-client.exe` | MCP started in the wrong directory or did not receive the config path | Use `scripts/patchwarden-mcp-stdio.cmd`. |
|
|
772
|
+
| MCP is connected, but tasks do not run | Watcher is missing or stale | Start `npm.cmd run watch` and inspect `health_check`. |
|
|
773
|
+
| `Agent command not found` | Agent is not on PATH, or Codex Desktop was mistaken for the CLI | Run `where.exe` and use the real CLI path in `agents.command`. |
|
|
774
|
+
| Verification command is rejected | It does not exactly match the allowlist | Add the exact command to `allowedTestCommands`. |
|
|
775
|
+
| ChatGPT still shows old tools | Connector or conversation cached the old catalog | Reconnect and open a new ChatGPT conversation. |
|
|
776
|
+
| ChatGPT stops after `create_task` | The same turn did not continue with `wait_for_task` | Loop while `continuation_required` is true. |
|
|
777
|
+
| HTTP reports `EADDRINUSE` | Port 7331 is already in use | Check the existing instance or change `httpPort`. |
|
|
778
|
+
| DPAPI credential cannot be decrypted | Windows user/machine changed or the cache is damaged | Run `PatchWarden.cmd reset-key` and enter it again. |
|
|
779
|
+
| Code changed but runtime behavior did not | Old `dist` or process is still active | Build, compare the manifest, and restart owned processes. |
|
|
780
|
+
| The supervisor shows only exit code 1 | The real tunnel-client failure is in child-process stderr | Read the mode's `tunnel-client.stderr.log` or `tunnel-status.json.stderr_tail`. |
|
|
781
|
+
| Core looks for its profile under `opencode-config\tunnel-client` | An older launcher leaked the Watcher's `XDG_CONFIG_HOME` into tunnel-client | Upgrade to v0.6.0 and run `PatchWarden.cmd restart core`; v0.6.0 isolates Watcher-only environment variables. |
|
|
782
|
+
| npm MCP initializes, but tasks remain queued | npm launched only the MCP Server | Start `dist/runner/watch.js` in the local installation. |
|
|
783
|
+
| Config exists but is not found | Variable was set in another terminal or path escaping is wrong | Use an absolute path and set `PATCHWARDEN_CONFIG` in the launching terminal. |
|
|
784
|
+
| Legacy environment names are ignored | v0.4.0 intentionally broke old names | Use `PATCHWARDEN_*` everywhere. |
|
|
785
|
+
|
|
786
|
+
### Lesson 1: connected is not end-to-end readiness
|
|
787
|
+
|
|
788
|
+
An MCP connection proves only that the client started PatchWarden. Also check:
|
|
789
|
+
|
|
790
|
+
1. `health_check` sees the intended workspace.
|
|
791
|
+
2. `list_agents` finds the execution agent.
|
|
792
|
+
3. The Watcher heartbeat is fresh.
|
|
793
|
+
4. A task moves from queued to running.
|
|
794
|
+
|
|
795
|
+
### Lesson 2: do not copy proxy port 7892 blindly
|
|
796
|
+
|
|
797
|
+
Port 7892 is a launcher default, not a standard shared by all proxy clients.
|
|
798
|
+
Check the proxy application and run `Test-NetConnection` before reinstalling
|
|
799
|
+
Node or PatchWarden.
|
|
800
|
+
|
|
801
|
+
### Lesson 3: do not proxy localhost
|
|
802
|
+
|
|
803
|
+
HTTP MCP, health endpoints, and the tunnel-client UI use loopback addresses.
|
|
804
|
+
Keep:
|
|
805
|
+
|
|
806
|
+
```powershell
|
|
807
|
+
$env:NO_PROXY = "localhost,127.0.0.1,::1"
|
|
808
|
+
```
|
|
809
|
+
|
|
810
|
+
### Lesson 4: old sessions can keep old schemas
|
|
811
|
+
|
|
812
|
+
Connectors and MCP clients may cache tool catalogs when a session opens.
|
|
813
|
+
Compare `server_version`, `schema_epoch`, and
|
|
814
|
+
`tool_manifest_sha256`, then reconnect and create a new session.
|
|
815
|
+
|
|
816
|
+
### Lesson 5: stale Watchers and unsafe process killing
|
|
817
|
+
|
|
818
|
+
PatchWarden uses heartbeat age to determine Watcher health. The launcher
|
|
819
|
+
supervises only the Watcher it created, and restart scripts touch only owned
|
|
820
|
+
processes. Do not use broad commands such as `taskkill /IM node.exe`; they can
|
|
821
|
+
terminate unrelated Node, Codex, or OpenCode work.
|
|
822
|
+
|
|
823
|
+
### Lesson 6: oversized workspace roots
|
|
824
|
+
|
|
825
|
+
Using a drive, home directory, or mixed workspace as `workspaceRoot` expands
|
|
826
|
+
scan scope, privacy risk, and accidental unrelated changes. Use a dedicated
|
|
827
|
+
code directory and point each task at a specific relative `repo_path`.
|
|
828
|
+
|
|
829
|
+
### Lesson 7: execution finished is not acceptance
|
|
830
|
+
|
|
831
|
+
`done` only means the agent process finished. Still verify:
|
|
832
|
+
|
|
833
|
+
- Whether `failed_scope_violation` occurred
|
|
834
|
+
- Whether every record in `verify.json` passed
|
|
835
|
+
- Whether `diff.patch` contains only intended changes
|
|
836
|
+
- Whether `audit_task` found inconsistent claims
|
|
837
|
+
- Whether claimed npm, GitHub, tag, or release state exists remotely
|
|
838
|
+
|
|
839
|
+
### Lesson 8: rename migration does not read old state
|
|
840
|
+
|
|
841
|
+
PatchWarden v0.4.0 does not automatically read legacy CLI names, environment
|
|
842
|
+
variables, headers, task directories, or DPAPI credentials. Preserve old data
|
|
843
|
+
as a backup if needed, but configure all new runs with PatchWarden paths and
|
|
844
|
+
names.
|
|
845
|
+
|
|
846
|
+
## MCP tools and profiles
|
|
847
|
+
|
|
848
|
+
`chatgpt_core` is the fixed 16-tool profile used by the ChatGPT tunnel:
|
|
849
|
+
|
|
850
|
+
`health_check`, `list_agents`, `list_workspace`,
|
|
851
|
+
`read_workspace_file`, `save_plan`, `create_task`,
|
|
852
|
+
`wait_for_task`, `get_task_summary`, `get_diff`, `get_result`,
|
|
853
|
+
`get_result_json`, `get_test_log`, `get_task_status`, `list_tasks`,
|
|
854
|
+
`cancel_task`, and `audit_task`.
|
|
855
|
+
|
|
856
|
+
`get_task_summary` keeps the backward-compatible `standard` view by default.
|
|
857
|
+
ChatGPT should request `view: "compact"` first; terminal `wait_for_task`
|
|
858
|
+
responses also embed compact acceptance evidence only.
|
|
859
|
+
|
|
860
|
+
`full` additionally provides:
|
|
861
|
+
|
|
862
|
+
- `get_plan`
|
|
863
|
+
- `kill_task`
|
|
864
|
+
- `retry_task`
|
|
865
|
+
- `get_task_progress`
|
|
866
|
+
- `get_task_stdout_tail`
|
|
867
|
+
- `get_task_log_tail`
|
|
868
|
+
|
|
869
|
+
The tunnel wrapper forces `chatgpt_core`. Ordinary local development defaults
|
|
870
|
+
to `full`.
|
|
871
|
+
|
|
872
|
+
### ChatGPT Direct mode
|
|
873
|
+
|
|
874
|
+
Direct mode exposes nine guarded tools so ChatGPT can create an editing
|
|
875
|
+
session, read and search source files, apply hash-bound JSON patches, run
|
|
876
|
+
exactly allowlisted verification commands, finalize the evidence, and audit
|
|
877
|
+
the result without a local execution agent.
|
|
878
|
+
|
|
879
|
+
Enable it in the trusted local configuration while keeping the ordinary Core
|
|
880
|
+
profile unchanged:
|
|
881
|
+
|
|
882
|
+
```json
|
|
883
|
+
{
|
|
884
|
+
"enableDirectProfile": true
|
|
885
|
+
}
|
|
886
|
+
```
|
|
887
|
+
|
|
888
|
+
Start the separate Direct tunnel entrypoint:
|
|
889
|
+
|
|
890
|
+
```text
|
|
891
|
+
PatchWarden.cmd start direct
|
|
892
|
+
```
|
|
893
|
+
|
|
894
|
+
On first use, provide the `tunnel-client.exe` path and a Tunnel ID dedicated
|
|
895
|
+
to the Direct Connector. The launcher uses the `patchwarden-direct` profile,
|
|
896
|
+
stores runtime state under `%LOCALAPPDATA%\patchwarden\runtime-direct`, skips
|
|
897
|
+
the Watcher, and retains the existing DPAPI credential handling. In a fresh
|
|
898
|
+
ChatGPT conversation, `health_check` should report `chatgpt_direct`, nine
|
|
899
|
+
tools, and `direct_profile_enabled=true`.
|
|
900
|
+
|
|
901
|
+
## Security boundaries and local data
|
|
902
|
+
|
|
903
|
+
Primary protections:
|
|
904
|
+
|
|
905
|
+
- MCP tools do not expose a general shell.
|
|
906
|
+
- Agent commands and argument templates must be configured in advance.
|
|
907
|
+
- Verification commands must exactly match the allowlist.
|
|
908
|
+
- File access is contained to `workspaceRoot`.
|
|
909
|
+
- Sensitive filenames and obvious credential-read plans are blocked.
|
|
910
|
+
- Secret-like values in task artifacts are redacted.
|
|
911
|
+
- HTTP mode binds only to `127.0.0.1`.
|
|
912
|
+
- The Runner does not automatically commit, push, publish, or reset.
|
|
913
|
+
|
|
914
|
+
Protect these local paths:
|
|
915
|
+
|
|
916
|
+
| Path | Content | Commit? |
|
|
917
|
+
| --- | --- | --- |
|
|
918
|
+
| `patchwarden.config.json` | Private paths, agents, command allowlist | No |
|
|
919
|
+
| `.patchwarden/` | Plans, tasks, diffs, and logs | No |
|
|
920
|
+
| `%APPDATA%\patchwarden` | DPAPI-encrypted tunnel credential | No |
|
|
921
|
+
| `%LOCALAPPDATA%\patchwarden` | Runtime status and isolated configuration | No |
|
|
922
|
+
|
|
923
|
+
Never commit API keys, tokens, Tunnel IDs, ChatGPT Workspace IDs, cookies,
|
|
924
|
+
`.env` files, private project paths, or real task logs.
|
|
925
|
+
|
|
926
|
+
PatchWarden reduces accidental exposure, but it does not replace human review.
|
|
927
|
+
Start with a dedicated test workspace and a repository you can recover.
|
|
928
|
+
|
|
929
|
+
## Upgrading and migration
|
|
930
|
+
|
|
931
|
+
Upgrade a pinned npm installation:
|
|
932
|
+
|
|
933
|
+
```powershell
|
|
934
|
+
npm.cmd install patchwarden@0.6.0
|
|
935
|
+
```
|
|
936
|
+
|
|
937
|
+
Upgrade a source checkout:
|
|
938
|
+
|
|
939
|
+
```powershell
|
|
940
|
+
git pull --ff-only
|
|
941
|
+
npm.cmd ci
|
|
942
|
+
npm.cmd run build
|
|
943
|
+
npm.cmd test
|
|
944
|
+
```
|
|
945
|
+
|
|
946
|
+
After upgrading:
|
|
947
|
+
|
|
948
|
+
1. Run `npm.cmd run doctor`.
|
|
949
|
+
2. Run `PatchWarden.cmd health`.
|
|
950
|
+
3. Compare version, schema epoch, and manifest hash.
|
|
951
|
+
4. Restart owned processes with `PatchWarden.cmd restart all`.
|
|
952
|
+
5. Reconnect the MCP client or Connector.
|
|
953
|
+
6. Validate in a new session instead of relying on an old conversation.
|
|
954
|
+
|
|
955
|
+
When migrating from Safe-Bifrost, manually update:
|
|
956
|
+
|
|
957
|
+
- npm package and CLIs include `patchwarden`, `patchwarden-runner`, and the
|
|
958
|
+
local-only medium-risk ticket confirmation command `patchwarden-confirm`
|
|
959
|
+
- Configuration filename to `patchwarden.config.json`
|
|
960
|
+
- Environment variables to `PATCHWARDEN_*`
|
|
961
|
+
- Task directory to `.patchwarden/`
|
|
962
|
+
- HTTP header to `x-patchwarden-token`
|
|
963
|
+
- AppData directory to `patchwarden`
|
|
964
|
+
|
|
965
|
+
Old data is not deleted and is not read as an automatic fallback. See the
|
|
966
|
+
[migration guide](docs/migration-from-safe-bifrost.md).
|
|
967
|
+
|
|
968
|
+
## Development and release verification
|
|
969
|
+
|
|
970
|
+
Windows PowerShell:
|
|
971
|
+
|
|
972
|
+
```powershell
|
|
973
|
+
npm.cmd run build
|
|
974
|
+
npm.cmd test
|
|
975
|
+
npm.cmd run test:mcp
|
|
976
|
+
npm.cmd run test:http-mcp
|
|
977
|
+
npm.cmd run doctor
|
|
978
|
+
npm.cmd run check:tool-manifest
|
|
979
|
+
npm.cmd run check:brand
|
|
980
|
+
npm.cmd run test:tunnel-supervisor
|
|
981
|
+
npm.cmd run test:watcher-supervisor
|
|
982
|
+
npm.cmd run pack:clean
|
|
983
|
+
npm.cmd run verify:package
|
|
984
|
+
```
|
|
985
|
+
|
|
986
|
+
Package checks exclude:
|
|
987
|
+
|
|
988
|
+
- `node_modules/`
|
|
989
|
+
- `.patchwarden/`
|
|
990
|
+
- `*.log`
|
|
991
|
+
- `.env`
|
|
992
|
+
- `patchwarden.config.json`
|
|
993
|
+
- Local credentials and runtime state
|
|
994
|
+
|
|
995
|
+
Before publishing, verify npm Registry state, remote tags, the GitHub Release,
|
|
996
|
+
and release-asset checksums independently.
|
|
997
|
+
|
|
998
|
+
## Related documentation
|
|
999
|
+
|
|
1000
|
+
- [v0.6.0 release notes](docs/release-v0.6.0.md)
|
|
1001
|
+
- [ChatGPT usage guide](docs/chatgpt-usage.md)
|
|
1002
|
+
- [Migration guide](docs/migration-from-safe-bifrost.md)
|
|
1003
|
+
- [ChatGPT Connector demo](docs/demo.md)
|
|
1004
|
+
- [OpenAI tunnel examples](examples/openai-tunnel/README.md)
|
|
1005
|
+
- [ChatGPT test prompt](examples/openai-tunnel/chatgpt-test-prompt.md)
|
|
1006
|
+
|
|
1007
|
+
## Roadmap
|
|
1008
|
+
|
|
1009
|
+
- [x] stdio MCP Server
|
|
1010
|
+
- [x] Plan and Task lifecycle
|
|
1011
|
+
- [x] Runner and Watcher
|
|
1012
|
+
- [x] HTTP MCP Server
|
|
1013
|
+
- [x] ChatGPT Connector / tunnel
|
|
1014
|
+
- [x] Doctor and runtime health checks
|
|
1015
|
+
- [x] Tool manifest and schema-drift detection
|
|
1016
|
+
- [ ] Worktree isolation
|
|
1017
|
+
- [ ] Multi-agent task queue
|
|
1018
|
+
- [ ] Local dashboard
|
|
1019
|
+
|
|
1020
|
+
## License
|
|
1021
|
+
|
|
1022
|
+
[MIT](LICENSE)
|