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,102 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { getConfig, getTasksDir, type PatchWardenConfig } from "./config.js";
|
|
4
|
+
|
|
5
|
+
export type WatcherState = "healthy" | "stale" | "missing" | "unreadable";
|
|
6
|
+
export type PendingReason =
|
|
7
|
+
| "queued_waiting_for_watcher"
|
|
8
|
+
| "queued_but_watcher_stale"
|
|
9
|
+
| "queued_but_watcher_missing"
|
|
10
|
+
| "queued_but_watcher_unreadable"
|
|
11
|
+
| "agent_running"
|
|
12
|
+
| "verification_running"
|
|
13
|
+
| "preparing"
|
|
14
|
+
| "collecting_artifacts"
|
|
15
|
+
| null;
|
|
16
|
+
|
|
17
|
+
export interface WatcherStatusSnapshot {
|
|
18
|
+
status: WatcherState;
|
|
19
|
+
available: boolean;
|
|
20
|
+
stale_after_seconds: number;
|
|
21
|
+
last_heartbeat_at: string | null;
|
|
22
|
+
heartbeat_age_seconds: number | null;
|
|
23
|
+
heartbeat_pid: number | null;
|
|
24
|
+
instance_id: string | null;
|
|
25
|
+
launcher_pid: number | null;
|
|
26
|
+
reason: string | null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function getWatcherHeartbeatPath(config: PatchWardenConfig = getConfig()): string {
|
|
30
|
+
return join(dirname(getTasksDir(config)), "watcher-heartbeat.json");
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function readWatcherStatus(
|
|
34
|
+
config: PatchWardenConfig = getConfig(),
|
|
35
|
+
nowMs = Date.now()
|
|
36
|
+
): WatcherStatusSnapshot {
|
|
37
|
+
const staleAfterSeconds = config.watcherStaleSeconds;
|
|
38
|
+
const heartbeatPath = getWatcherHeartbeatPath(config);
|
|
39
|
+
if (!existsSync(heartbeatPath)) {
|
|
40
|
+
return {
|
|
41
|
+
status: "missing",
|
|
42
|
+
available: false,
|
|
43
|
+
stale_after_seconds: staleAfterSeconds,
|
|
44
|
+
last_heartbeat_at: null,
|
|
45
|
+
heartbeat_age_seconds: null,
|
|
46
|
+
heartbeat_pid: null,
|
|
47
|
+
instance_id: null,
|
|
48
|
+
launcher_pid: null,
|
|
49
|
+
reason: "Watcher heartbeat has not been observed. Start or restart the PatchWarden watcher.",
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
const raw = readFileSync(heartbeatPath, "utf-8");
|
|
55
|
+
const data = JSON.parse(raw.charCodeAt(0) === 0xfeff ? raw.slice(1) : raw);
|
|
56
|
+
const heartbeatMs = Date.parse(String(data.last_heartbeat_at || ""));
|
|
57
|
+
if (!Number.isFinite(heartbeatMs)) throw new Error("invalid heartbeat timestamp");
|
|
58
|
+
const ageMs = Math.max(0, nowMs - heartbeatMs);
|
|
59
|
+
const ageSeconds = Math.round(ageMs / 1000);
|
|
60
|
+
const healthy = ageMs < staleAfterSeconds * 1000;
|
|
61
|
+
return {
|
|
62
|
+
status: healthy ? "healthy" : "stale",
|
|
63
|
+
available: healthy,
|
|
64
|
+
stale_after_seconds: staleAfterSeconds,
|
|
65
|
+
last_heartbeat_at: String(data.last_heartbeat_at),
|
|
66
|
+
heartbeat_age_seconds: ageSeconds,
|
|
67
|
+
heartbeat_pid: Number.isInteger(Number(data.pid)) ? Number(data.pid) : null,
|
|
68
|
+
instance_id: typeof data.instance_id === "string" ? data.instance_id : null,
|
|
69
|
+
launcher_pid: Number.isInteger(Number(data.launcher_pid)) ? Number(data.launcher_pid) : null,
|
|
70
|
+
reason: healthy ? null : "Watcher heartbeat is stale. Restart the PatchWarden watcher.",
|
|
71
|
+
};
|
|
72
|
+
} catch {
|
|
73
|
+
return {
|
|
74
|
+
status: "unreadable",
|
|
75
|
+
available: false,
|
|
76
|
+
stale_after_seconds: staleAfterSeconds,
|
|
77
|
+
last_heartbeat_at: null,
|
|
78
|
+
heartbeat_age_seconds: null,
|
|
79
|
+
heartbeat_pid: null,
|
|
80
|
+
instance_id: null,
|
|
81
|
+
launcher_pid: null,
|
|
82
|
+
reason: "Watcher heartbeat file is unreadable.",
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function derivePendingReason(
|
|
88
|
+
task: { status?: string; phase?: string },
|
|
89
|
+
watcher: WatcherStatusSnapshot
|
|
90
|
+
): PendingReason {
|
|
91
|
+
if (task.status === "pending") {
|
|
92
|
+
if (watcher.status === "stale") return "queued_but_watcher_stale";
|
|
93
|
+
if (watcher.status === "missing") return "queued_but_watcher_missing";
|
|
94
|
+
if (watcher.status === "unreadable") return "queued_but_watcher_unreadable";
|
|
95
|
+
return "queued_waiting_for_watcher";
|
|
96
|
+
}
|
|
97
|
+
if (task.status !== "running") return null;
|
|
98
|
+
if (task.phase === "executing_agent") return "agent_running";
|
|
99
|
+
if (task.phase === "running_tests") return "verification_running";
|
|
100
|
+
if (task.phase === "collecting_artifacts") return "collecting_artifacts";
|
|
101
|
+
return "preparing";
|
|
102
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ES2022",
|
|
5
|
+
"moduleResolution": "node",
|
|
6
|
+
"outDir": "dist",
|
|
7
|
+
"rootDir": "src",
|
|
8
|
+
"strict": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"forceConsistentCasingInFileNames": true,
|
|
11
|
+
"resolveJsonModule": true,
|
|
12
|
+
"declaration": true,
|
|
13
|
+
"skipLibCheck": true
|
|
14
|
+
},
|
|
15
|
+
"include": ["src/**/*.ts"],
|
|
16
|
+
"exclude": ["node_modules", "dist"]
|
|
17
|
+
}
|