patchwarden 0.6.4 → 1.5.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/README.en.md +54 -20
- package/README.md +48 -21
- package/dist/agents/agentRouter.d.ts +40 -0
- package/dist/agents/agentRouter.js +95 -0
- package/dist/config.d.ts +1 -1
- package/dist/config.js +6 -2
- package/dist/controlCenter.js +212 -3
- package/dist/direct/directSessionStore.d.ts +2 -0
- package/dist/direct/directVerification.js +7 -0
- package/dist/doctor.js +32 -1
- package/dist/goal/acceptanceEngine.d.ts +62 -0
- package/dist/goal/acceptanceEngine.js +103 -0
- package/dist/goal/acceptanceTemplate.d.ts +10 -0
- package/dist/goal/acceptanceTemplate.js +104 -0
- package/dist/goal/goalGraph.d.ts +58 -0
- package/dist/goal/goalGraph.js +189 -0
- package/dist/goal/goalProgress.d.ts +81 -0
- package/dist/goal/goalProgress.js +216 -0
- package/dist/goal/goalStatus.d.ts +60 -0
- package/dist/goal/goalStatus.js +137 -0
- package/dist/goal/goalStore.d.ts +79 -0
- package/dist/goal/goalStore.js +211 -0
- package/dist/goal/handoffExport.d.ts +34 -0
- package/dist/goal/handoffExport.js +183 -0
- package/dist/goal/subgoalSync.d.ts +40 -0
- package/dist/goal/subgoalSync.js +72 -0
- package/dist/goal/worktreeManager.d.ts +96 -0
- package/dist/goal/worktreeManager.js +292 -0
- package/dist/logging.d.ts +44 -0
- package/dist/logging.js +68 -0
- package/dist/policy/projectPolicy.d.ts +55 -0
- package/dist/policy/projectPolicy.js +286 -0
- package/dist/release/releaseGate.d.ts +99 -0
- package/dist/release/releaseGate.js +475 -0
- package/dist/runner/postTaskCleanup.d.ts +13 -0
- package/dist/runner/postTaskCleanup.js +147 -0
- package/dist/runner/runTask.js +50 -10
- package/dist/security/discoveryTokenStore.d.ts +62 -0
- package/dist/security/discoveryTokenStore.js +100 -0
- package/dist/security/toolInvocationGuard.d.ts +35 -0
- package/dist/security/toolInvocationGuard.js +153 -0
- package/dist/smoke-test.js +18 -10
- package/dist/taskRuntime.d.ts +17 -0
- package/dist/test/unit/acceptance-engine.test.d.ts +1 -0
- package/dist/test/unit/acceptance-engine.test.js +228 -0
- package/dist/test/unit/agent-router.test.d.ts +1 -0
- package/dist/test/unit/agent-router.test.js +287 -0
- package/dist/test/unit/audit-checks.test.d.ts +1 -0
- package/dist/test/unit/audit-checks.test.js +350 -0
- package/dist/test/unit/diagnose-task.test.d.ts +1 -0
- package/dist/test/unit/diagnose-task.test.js +457 -0
- package/dist/test/unit/discovery-token-store.test.d.ts +1 -0
- package/dist/test/unit/discovery-token-store.test.js +139 -0
- package/dist/test/unit/evidence-pack.test.d.ts +1 -0
- package/dist/test/unit/evidence-pack.test.js +130 -0
- package/dist/test/unit/goal-graph.test.d.ts +1 -0
- package/dist/test/unit/goal-graph.test.js +298 -0
- package/dist/test/unit/goal-progress.test.d.ts +1 -0
- package/dist/test/unit/goal-progress.test.js +381 -0
- package/dist/test/unit/goal-status.test.d.ts +1 -0
- package/dist/test/unit/goal-status.test.js +215 -0
- package/dist/test/unit/goal-store.test.d.ts +1 -0
- package/dist/test/unit/goal-store.test.js +253 -0
- package/dist/test/unit/goal-subgoal-task.test.d.ts +1 -0
- package/dist/test/unit/goal-subgoal-task.test.js +55 -0
- package/dist/test/unit/goal-tools-registry.test.d.ts +1 -0
- package/dist/test/unit/goal-tools-registry.test.js +190 -0
- package/dist/test/unit/handoff-export.test.d.ts +1 -0
- package/dist/test/unit/handoff-export.test.js +263 -0
- package/dist/test/unit/invoke-discovered-tool.test.d.ts +1 -0
- package/dist/test/unit/invoke-discovered-tool.test.js +167 -0
- package/dist/test/unit/logging.test.js +127 -5
- package/dist/test/unit/post-task-cleanup.test.d.ts +1 -0
- package/dist/test/unit/post-task-cleanup.test.js +48 -0
- package/dist/test/unit/project-policy-release-mode.test.d.ts +1 -0
- package/dist/test/unit/project-policy-release-mode.test.js +125 -0
- package/dist/test/unit/reconcile-tasks.test.d.ts +1 -0
- package/dist/test/unit/reconcile-tasks.test.js +456 -0
- package/dist/test/unit/release-gate.test.d.ts +1 -0
- package/dist/test/unit/release-gate.test.js +242 -0
- package/dist/test/unit/run-task-loop.test.d.ts +1 -0
- package/dist/test/unit/run-task-loop.test.js +380 -0
- package/dist/test/unit/safe-views.test.d.ts +1 -0
- package/dist/test/unit/safe-views.test.js +171 -0
- package/dist/test/unit/schema-drift-check.test.d.ts +1 -0
- package/dist/test/unit/schema-drift-check.test.js +176 -0
- package/dist/test/unit/subgoal-sync.test.d.ts +1 -0
- package/dist/test/unit/subgoal-sync.test.js +183 -0
- package/dist/test/unit/tool-invocation-guard.test.d.ts +1 -0
- package/dist/test/unit/tool-invocation-guard.test.js +432 -0
- package/dist/test/unit/tool-usage-stats.test.d.ts +1 -0
- package/dist/test/unit/tool-usage-stats.test.js +300 -0
- package/dist/test/unit/toolSearch.test.d.ts +1 -0
- package/dist/test/unit/toolSearch.test.js +571 -0
- package/dist/test/unit/worktree-manager.test.d.ts +1 -0
- package/dist/test/unit/worktree-manager.test.js +176 -0
- package/dist/tools/auditTask.d.ts +103 -1
- package/dist/tools/auditTask.js +461 -8
- package/dist/tools/cancelTask.js +1 -1
- package/dist/tools/checkReleaseGate.d.ts +21 -0
- package/dist/tools/checkReleaseGate.js +22 -0
- package/dist/tools/createTask.d.ts +18 -2
- package/dist/tools/createTask.js +29 -1
- package/dist/tools/diagnoseTask.d.ts +45 -0
- package/dist/tools/diagnoseTask.js +347 -0
- package/dist/tools/discardWorktree.d.ts +24 -0
- package/dist/tools/discardWorktree.js +27 -0
- package/dist/tools/discoverTools.d.ts +11 -0
- package/dist/tools/discoverTools.js +39 -0
- package/dist/tools/evidencePack.d.ts +39 -0
- package/dist/tools/evidencePack.js +168 -0
- package/dist/tools/explainTool.d.ts +11 -0
- package/dist/tools/explainTool.js +21 -0
- package/dist/tools/getTaskSummary.js +2 -1
- package/dist/tools/goalSubgoalTask.d.ts +51 -0
- package/dist/tools/goalSubgoalTask.js +110 -0
- package/dist/tools/healthCheck.d.ts +1 -0
- package/dist/tools/healthCheck.js +5 -1
- package/dist/tools/invokeDiscoveredTool.d.ts +37 -0
- package/dist/tools/invokeDiscoveredTool.js +112 -0
- package/dist/tools/listTasks.d.ts +3 -1
- package/dist/tools/listTasks.js +14 -1
- package/dist/tools/mergeWorktree.d.ts +24 -0
- package/dist/tools/mergeWorktree.js +27 -0
- package/dist/tools/recommendAgentForTask.d.ts +19 -0
- package/dist/tools/recommendAgentForTask.js +56 -0
- package/dist/tools/reconcileTasks.d.ts +41 -0
- package/dist/tools/reconcileTasks.js +352 -0
- package/dist/tools/registry.js +926 -2
- package/dist/tools/releaseMode.d.ts +50 -0
- package/dist/tools/releaseMode.js +370 -0
- package/dist/tools/runDirectVerificationBundle.d.ts +26 -0
- package/dist/tools/runDirectVerificationBundle.js +64 -0
- package/dist/tools/runTaskLoop.d.ts +57 -0
- package/dist/tools/runTaskLoop.js +417 -0
- package/dist/tools/runVerification.d.ts +4 -0
- package/dist/tools/runVerification.js +4 -0
- package/dist/tools/safeStatus.d.ts +31 -1
- package/dist/tools/safeStatus.js +43 -1
- package/dist/tools/safeViews.d.ts +262 -0
- package/dist/tools/safeViews.js +252 -0
- package/dist/tools/schemaDriftCheck.d.ts +46 -0
- package/dist/tools/schemaDriftCheck.js +80 -0
- package/dist/tools/taskLineage.d.ts +91 -0
- package/dist/tools/taskLineage.js +175 -0
- package/dist/tools/toolCatalog.d.ts +4 -3
- package/dist/tools/toolCatalog.js +39 -11
- package/dist/tools/toolRegistry.d.ts +61 -0
- package/dist/tools/toolRegistry.js +834 -0
- package/dist/tools/toolSearch.d.ts +110 -0
- package/dist/tools/toolSearch.js +331 -0
- package/dist/tools/toolUsageStats.d.ts +41 -0
- package/dist/tools/toolUsageStats.js +116 -0
- package/dist/tools/waitForTask.js +1 -0
- package/dist/version.d.ts +2 -2
- package/dist/version.js +2 -2
- package/dist/watcherStatus.d.ts +29 -0
- package/dist/watcherStatus.js +92 -1
- package/docs/chatgpt-usage.md +31 -0
- package/docs/control-center/README.md +9 -0
- package/package.json +3 -2
- package/scripts/checks/control-center-smoke.js +87 -0
- package/scripts/checks/control-smoke.js +2 -2
- package/scripts/checks/doctor-smoke.js +1 -0
- package/scripts/checks/lifecycle-smoke.js +13 -9
- package/scripts/checks/mcp-manifest-check.js +65 -6
- package/scripts/checks/mcp-smoke.js +60 -9
- package/scripts/checks/watcher-supervisor-smoke.js +2 -2
- package/src/agents/agentRouter.ts +149 -0
- package/src/config.ts +9 -3
- package/src/controlCenter.ts +215 -4
- package/src/direct/directSessionStore.ts +2 -0
- package/src/direct/directVerification.ts +7 -0
- package/src/doctor.ts +36 -1
- package/src/goal/acceptanceEngine.ts +160 -0
- package/src/goal/acceptanceTemplate.ts +121 -0
- package/src/goal/goalGraph.ts +225 -0
- package/src/goal/goalProgress.ts +301 -0
- package/src/goal/goalStatus.ts +234 -0
- package/src/goal/goalStore.ts +306 -0
- package/src/goal/handoffExport.ts +211 -0
- package/src/goal/subgoalSync.ts +82 -0
- package/src/goal/worktreeManager.ts +404 -0
- package/src/logging.ts +91 -0
- package/src/policy/projectPolicy.ts +344 -0
- package/src/release/releaseGate.ts +567 -0
- package/src/runner/postTaskCleanup.ts +154 -0
- package/src/runner/runTask.ts +49 -10
- package/src/security/discoveryTokenStore.ts +157 -0
- package/src/security/toolInvocationGuard.ts +251 -0
- package/src/smoke-test.ts +15 -7
- package/src/taskRuntime.ts +17 -0
- package/src/test/unit/acceptance-engine.test.ts +261 -0
- package/src/test/unit/agent-router.test.ts +342 -0
- package/src/test/unit/audit-checks.test.ts +567 -0
- package/src/test/unit/diagnose-task.test.ts +544 -0
- package/src/test/unit/discovery-token-store.test.ts +181 -0
- package/src/test/unit/evidence-pack.test.ts +142 -0
- package/src/test/unit/goal-graph.test.ts +347 -0
- package/src/test/unit/goal-progress.test.ts +538 -0
- package/src/test/unit/goal-status.test.ts +270 -0
- package/src/test/unit/goal-store.test.ts +318 -0
- package/src/test/unit/goal-subgoal-task.test.ts +72 -0
- package/src/test/unit/goal-tools-registry.test.ts +243 -0
- package/src/test/unit/handoff-export.test.ts +295 -0
- package/src/test/unit/invoke-discovered-tool.test.ts +216 -0
- package/src/test/unit/logging.test.ts +177 -5
- package/src/test/unit/post-task-cleanup.test.ts +53 -0
- package/src/test/unit/project-policy-release-mode.test.ts +156 -0
- package/src/test/unit/reconcile-tasks.test.ts +551 -0
- package/src/test/unit/release-gate.test.ts +314 -0
- package/src/test/unit/run-task-loop.test.ts +425 -0
- package/src/test/unit/safe-views.test.ts +184 -0
- package/src/test/unit/schema-drift-check.test.ts +260 -0
- package/src/test/unit/subgoal-sync.test.ts +236 -0
- package/src/test/unit/tool-invocation-guard.test.ts +542 -0
- package/src/test/unit/tool-usage-stats.test.ts +384 -0
- package/src/test/unit/toolSearch.test.ts +756 -0
- package/src/test/unit/worktree-manager.test.ts +247 -0
- package/src/tools/auditTask.ts +831 -402
- package/src/tools/cancelTask.ts +1 -1
- package/src/tools/checkReleaseGate.ts +45 -0
- package/src/tools/createTask.ts +64 -6
- package/src/tools/diagnoseTask.ts +460 -0
- package/src/tools/discardWorktree.ts +42 -0
- package/src/tools/discoverTools.ts +51 -0
- package/src/tools/evidencePack.ts +205 -0
- package/src/tools/explainTool.ts +26 -0
- package/src/tools/getTaskSummary.ts +2 -1
- package/src/tools/goalSubgoalTask.ts +170 -0
- package/src/tools/healthCheck.ts +4 -1
- package/src/tools/invokeDiscoveredTool.ts +163 -0
- package/src/tools/listTasks.ts +16 -2
- package/src/tools/listWorkspace.ts +71 -71
- package/src/tools/mergeWorktree.ts +42 -0
- package/src/tools/recommendAgentForTask.ts +79 -0
- package/src/tools/reconcileTasks.ts +464 -0
- package/src/tools/registry.ts +1093 -73
- package/src/tools/releaseMode.ts +450 -0
- package/src/tools/runDirectVerificationBundle.ts +98 -0
- package/src/tools/runTaskLoop.ts +526 -0
- package/src/tools/runVerification.ts +8 -0
- package/src/tools/safeStatus.ts +73 -2
- package/src/tools/safeViews.ts +273 -0
- package/src/tools/schemaDriftCheck.ts +120 -0
- package/src/tools/taskLineage.ts +300 -0
- package/src/tools/toolCatalog.ts +40 -11
- package/src/tools/toolRegistry.ts +896 -0
- package/src/tools/toolSearch.ts +464 -0
- package/src/tools/toolUsageStats.ts +151 -0
- package/src/tools/waitForTask.ts +1 -0
- package/src/version.ts +2 -2
- package/src/watcherStatus.ts +97 -1
- package/ui/pages/dashboard.html +143 -2
package/dist/tools/registry.js
CHANGED
|
@@ -21,27 +21,49 @@ import { listAgents } from "../tools/listAgents.js";
|
|
|
21
21
|
import { healthCheck } from "../tools/healthCheck.js";
|
|
22
22
|
import { getTaskSummary } from "../tools/getTaskSummary.js";
|
|
23
23
|
import { waitForTask } from "../tools/waitForTask.js";
|
|
24
|
+
import { runTaskLoop } from "./runTaskLoop.js";
|
|
25
|
+
import { getTaskLineage } from "./taskLineage.js";
|
|
26
|
+
import { exportTaskEvidencePack } from "./evidencePack.js";
|
|
27
|
+
import { recommendAgentForTask } from "./recommendAgentForTask.js";
|
|
24
28
|
import { errorPayload, PatchWardenError } from "../errors.js";
|
|
25
29
|
import { auditTask } from "../tools/auditTask.js";
|
|
26
30
|
import { safeStatus } from "../tools/safeStatus.js";
|
|
31
|
+
import { safeAudit, safeAuditDirectSession, safeDiffSummary, safeDirectSummary, safeFinalizeDirectSession, safeResult, safeTestSummary, } from "../tools/safeViews.js";
|
|
32
|
+
import { diagnoseTask } from "../tools/diagnoseTask.js";
|
|
33
|
+
import { reconcileTasks } from "../tools/reconcileTasks.js";
|
|
34
|
+
import { discoverTools } from "../tools/discoverTools.js";
|
|
35
|
+
import { explainTool } from "../tools/explainTool.js";
|
|
36
|
+
import { invokeDiscoveredTool } from "./invokeDiscoveredTool.js";
|
|
27
37
|
import { logger } from "../logging.js";
|
|
28
38
|
import { runTask } from "../runner/runTask.js";
|
|
29
39
|
import { createDirectSession } from "../tools/createDirectSession.js";
|
|
30
40
|
import { searchWorkspace } from "../tools/searchWorkspace.js";
|
|
31
41
|
import { applyPatch } from "../tools/applyPatch.js";
|
|
32
42
|
import { runVerification } from "../tools/runVerification.js";
|
|
43
|
+
import { runDirectVerificationBundle } from "../tools/runDirectVerificationBundle.js";
|
|
33
44
|
import { finalizeDirectSession } from "../tools/finalizeDirectSession.js";
|
|
34
45
|
import { auditSession } from "../tools/auditSession.js";
|
|
35
46
|
import { syncFile } from "../tools/syncFile.js";
|
|
47
|
+
import { createGoal, listGoals, readGoal, readGoalStatus } from "../goal/goalStore.js";
|
|
48
|
+
import { suggestNextSubgoal } from "../goal/goalGraph.js";
|
|
49
|
+
import { exportHandoff } from "../goal/handoffExport.js";
|
|
50
|
+
import { acceptSubgoal, rejectSubgoal, summarizeGoalProgress } from "../goal/goalProgress.js";
|
|
51
|
+
import { createSubgoalTask } from "./goalSubgoalTask.js";
|
|
52
|
+
import { checkReleaseGate } from "./checkReleaseGate.js";
|
|
53
|
+
import { getProjectPolicyTool, releaseCheck, releaseCleanup, releasePrepare, releaseVerify, } from "./releaseMode.js";
|
|
54
|
+
import { mergeWorktreeTool } from "./mergeWorktree.js";
|
|
55
|
+
import { discardWorktreeTool } from "./discardWorktree.js";
|
|
36
56
|
import { TASK_TEMPLATE_NAMES } from "./taskTemplates.js";
|
|
37
57
|
import { buildToolCatalogSnapshot, getLastToolCatalogSnapshot, resolveToolProfile, selectToolsForProfile, } from "./toolCatalog.js";
|
|
38
58
|
export function getToolDefs() {
|
|
39
59
|
const config = getConfig();
|
|
40
60
|
const agentNames = Object.keys(config.agents).sort();
|
|
61
|
+
const routableAgentNames = [...agentNames, "auto"];
|
|
41
62
|
const agentDescription = agentNames.length > 0
|
|
42
|
-
? `Configured local agent name. Available agents: ${agentNames.map((name) => JSON.stringify(name)).join(", ")}
|
|
63
|
+
? `Configured local agent name. Available agents: ${agentNames.map((name) => JSON.stringify(name)).join(", ")}. run_task_loop also accepts "auto" for bounded routing.`
|
|
43
64
|
: "Configured local agent name. No agents are currently configured.";
|
|
44
65
|
const testCommands = getAllConfiguredTestCommands(config).sort();
|
|
66
|
+
const directCommands = getAllConfiguredDirectCommands(config);
|
|
45
67
|
const tools = [
|
|
46
68
|
{
|
|
47
69
|
name: "save_plan",
|
|
@@ -151,6 +173,173 @@ export function getToolDefs() {
|
|
|
151
173
|
required: [],
|
|
152
174
|
},
|
|
153
175
|
},
|
|
176
|
+
{
|
|
177
|
+
name: "run_task_loop",
|
|
178
|
+
description: "Run a guarded PatchWarden task loop by composing create_task, wait_for_task, safe summaries, and audit_task. It does not bypass the watcher, command allow-list, workspace confinement, or confirmation boundaries. Returns only bounded structured lineage and final status.",
|
|
179
|
+
inputSchema: {
|
|
180
|
+
type: "object",
|
|
181
|
+
properties: {
|
|
182
|
+
repo_path: {
|
|
183
|
+
type: "string",
|
|
184
|
+
description: "Required repository path inside workspaceRoot. No implicit workspace-root fallback is allowed.",
|
|
185
|
+
},
|
|
186
|
+
goal: { type: "string", description: "Task goal to execute through the guarded loop." },
|
|
187
|
+
verify_commands: {
|
|
188
|
+
type: "array",
|
|
189
|
+
minItems: 1,
|
|
190
|
+
maxItems: 20,
|
|
191
|
+
items: {
|
|
192
|
+
type: "string",
|
|
193
|
+
...(testCommands.length > 0 ? { enum: testCommands } : {}),
|
|
194
|
+
},
|
|
195
|
+
description: "Exact-match verification commands. The loop reuses create_task validation and will not run commands outside the allow-list.",
|
|
196
|
+
},
|
|
197
|
+
agent: {
|
|
198
|
+
type: "string",
|
|
199
|
+
description: agentDescription,
|
|
200
|
+
...(agentNames.length > 0 ? { enum: routableAgentNames } : {}),
|
|
201
|
+
},
|
|
202
|
+
template: {
|
|
203
|
+
type: "string",
|
|
204
|
+
enum: ["inspect_only", "feature_small", "release_check"],
|
|
205
|
+
default: "feature_small",
|
|
206
|
+
description: "Initial guarded task template. Follow-up repair tasks use fix_tests automatically when verification fails.",
|
|
207
|
+
},
|
|
208
|
+
max_iterations: {
|
|
209
|
+
type: "integer",
|
|
210
|
+
minimum: 1,
|
|
211
|
+
maximum: 5,
|
|
212
|
+
default: 3,
|
|
213
|
+
description: "Maximum total main/fix task attempts.",
|
|
214
|
+
},
|
|
215
|
+
task_timeout_seconds: {
|
|
216
|
+
type: "integer",
|
|
217
|
+
minimum: 1,
|
|
218
|
+
maximum: config.maxTaskTimeoutSeconds,
|
|
219
|
+
default: config.defaultTaskTimeoutSeconds,
|
|
220
|
+
description: `Per-task wait budget in seconds (default ${config.defaultTaskTimeoutSeconds}, max ${config.maxTaskTimeoutSeconds}).`,
|
|
221
|
+
},
|
|
222
|
+
auto_fix_tests: {
|
|
223
|
+
type: "boolean",
|
|
224
|
+
default: true,
|
|
225
|
+
description: "When true, create a fix_tests follow-up task after failed_verification until max_iterations is reached.",
|
|
226
|
+
},
|
|
227
|
+
auto_cleanup_artifacts: {
|
|
228
|
+
type: "boolean",
|
|
229
|
+
default: true,
|
|
230
|
+
description: "Records cleanup intent in lineage. Low-risk cleanup remains handled by runTask post-task cleanup.",
|
|
231
|
+
},
|
|
232
|
+
stop_on_high_risk: {
|
|
233
|
+
type: "boolean",
|
|
234
|
+
default: true,
|
|
235
|
+
description: "When true, stop immediately on non-policy high-risk audit evidence. Scope, policy, sensitive-path, release/publish, and confirmation boundaries always stop regardless of this flag.",
|
|
236
|
+
},
|
|
237
|
+
direct_verify: {
|
|
238
|
+
type: "boolean",
|
|
239
|
+
default: false,
|
|
240
|
+
description: "When true, run an independent Direct verification session after the guarded task/audit succeeds. Direct never patches files in this loop.",
|
|
241
|
+
},
|
|
242
|
+
direct_verify_commands: {
|
|
243
|
+
type: "array",
|
|
244
|
+
minItems: 1,
|
|
245
|
+
maxItems: 20,
|
|
246
|
+
items: {
|
|
247
|
+
type: "string",
|
|
248
|
+
...(directCommands.length > 0 ? { enum: directCommands } : {}),
|
|
249
|
+
},
|
|
250
|
+
description: "Optional Direct verification commands. Defaults to verify_commands and still must pass the Direct command allow-list.",
|
|
251
|
+
},
|
|
252
|
+
direct_verify_timeout_seconds: {
|
|
253
|
+
type: "integer",
|
|
254
|
+
minimum: 1,
|
|
255
|
+
maximum: Math.min(config.maxTaskTimeoutSeconds, config.directSessionTtlSeconds),
|
|
256
|
+
default: 120,
|
|
257
|
+
description: "Per-command timeout for Direct verification.",
|
|
258
|
+
},
|
|
259
|
+
scope_files: {
|
|
260
|
+
type: "array",
|
|
261
|
+
maxItems: 50,
|
|
262
|
+
items: { type: "string" },
|
|
263
|
+
description: "Optional bounded file scope used only for agent routing hints.",
|
|
264
|
+
},
|
|
265
|
+
isolation_mode: {
|
|
266
|
+
type: "string",
|
|
267
|
+
enum: ["current_repo", "worktree"],
|
|
268
|
+
default: "current_repo",
|
|
269
|
+
description: "Use current_repo by default. worktree creates an isolated git worktree for the task but never auto-merges it.",
|
|
270
|
+
},
|
|
271
|
+
worktree_base_branch: {
|
|
272
|
+
type: "string",
|
|
273
|
+
description: "Optional base-branch label recorded in lineage. v1.5 does not auto-checkout or merge this branch.",
|
|
274
|
+
},
|
|
275
|
+
worktree_cleanup: {
|
|
276
|
+
type: "string",
|
|
277
|
+
enum: ["keep", "archive", "delete_ignored_only"],
|
|
278
|
+
default: "keep",
|
|
279
|
+
description: "Cleanup intent recorded in lineage. v1.5 keeps worktrees by default and does not auto-delete them.",
|
|
280
|
+
},
|
|
281
|
+
},
|
|
282
|
+
required: ["repo_path", "goal", "verify_commands"],
|
|
283
|
+
},
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
name: "recommend_agent_for_task",
|
|
287
|
+
description: "Return a bounded read-only agent routing recommendation for a repo-scoped task. Does not start an agent, create a task, or read logs.",
|
|
288
|
+
inputSchema: {
|
|
289
|
+
type: "object",
|
|
290
|
+
properties: {
|
|
291
|
+
repo_path: { type: "string", description: "Repository path inside workspaceRoot." },
|
|
292
|
+
goal: { type: "string", description: "Task goal used for routing hints." },
|
|
293
|
+
scope_files: {
|
|
294
|
+
type: "array",
|
|
295
|
+
maxItems: 50,
|
|
296
|
+
items: { type: "string" },
|
|
297
|
+
description: "Optional bounded list of files or directories expected to be in scope.",
|
|
298
|
+
},
|
|
299
|
+
template: { type: "string", description: "Optional task template hint." },
|
|
300
|
+
risk_hint: { type: "string", description: "Optional compact risk hint text." },
|
|
301
|
+
},
|
|
302
|
+
required: ["repo_path", "goal"],
|
|
303
|
+
},
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
name: "get_task_lineage",
|
|
307
|
+
description: "Read a bounded safe summary for a run_task_loop lineage. Does not return full logs, diffs, stdout, stderr, or markdown artifacts.",
|
|
308
|
+
inputSchema: {
|
|
309
|
+
type: "object",
|
|
310
|
+
properties: {
|
|
311
|
+
lineage_id: { type: "string", description: "Lineage ID returned by run_task_loop." },
|
|
312
|
+
max_items: { type: "integer", minimum: 1, maximum: 50, default: 8, description: "Maximum rounds/tasks/warnings to return." },
|
|
313
|
+
},
|
|
314
|
+
required: ["lineage_id"],
|
|
315
|
+
},
|
|
316
|
+
},
|
|
317
|
+
{
|
|
318
|
+
name: "export_task_evidence_pack",
|
|
319
|
+
description: "Export a bounded evidence pack for a run_task_loop lineage. Writes evidence.json and EVIDENCE.md without stdout, stderr, full logs, full diff, or sensitive file contents.",
|
|
320
|
+
inputSchema: {
|
|
321
|
+
type: "object",
|
|
322
|
+
properties: {
|
|
323
|
+
lineage_id: { type: "string", description: "Lineage ID returned by run_task_loop." },
|
|
324
|
+
max_items: { type: "integer", minimum: 1, maximum: 50, default: 12, description: "Maximum rounds/tasks/warnings to include." },
|
|
325
|
+
},
|
|
326
|
+
required: ["lineage_id"],
|
|
327
|
+
},
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
name: "get_project_policy",
|
|
331
|
+
description: "Read the bounded effective .patchwarden/project-policy.json summary for a repository. Missing policy returns safe defaults. Project policy never expands PatchWarden command allow-lists, workspace confinement, sensitive-path blocking, or watcher/audit boundaries.",
|
|
332
|
+
inputSchema: {
|
|
333
|
+
type: "object",
|
|
334
|
+
properties: {
|
|
335
|
+
repo_path: {
|
|
336
|
+
type: "string",
|
|
337
|
+
description: "Repository path inside workspaceRoot.",
|
|
338
|
+
},
|
|
339
|
+
},
|
|
340
|
+
required: ["repo_path"],
|
|
341
|
+
},
|
|
342
|
+
},
|
|
154
343
|
{
|
|
155
344
|
name: "get_task_status",
|
|
156
345
|
description: "Check task status, execution phase, watcher health, pending reason, current command, timeout, and change evidence.",
|
|
@@ -389,9 +578,431 @@ export function getToolDefs() {
|
|
|
389
578
|
required: ["task_id"],
|
|
390
579
|
},
|
|
391
580
|
},
|
|
581
|
+
{
|
|
582
|
+
name: "safe_result",
|
|
583
|
+
description: "Return a low-noise structured task result summary without full logs, markdown, or diff content.",
|
|
584
|
+
inputSchema: {
|
|
585
|
+
type: "object",
|
|
586
|
+
properties: {
|
|
587
|
+
task_id: { type: "string", description: "Task ID to summarize" },
|
|
588
|
+
max_items: { type: "integer", minimum: 1, maximum: 50, default: 8, description: "Maximum list entries to return per evidence group." },
|
|
589
|
+
},
|
|
590
|
+
required: ["task_id"],
|
|
591
|
+
},
|
|
592
|
+
},
|
|
593
|
+
{
|
|
594
|
+
name: "safe_audit",
|
|
595
|
+
description: "Run audit_task and return only bounded structured audit evidence without full review markdown.",
|
|
596
|
+
inputSchema: {
|
|
597
|
+
type: "object",
|
|
598
|
+
properties: {
|
|
599
|
+
task_id: { type: "string", description: "Task ID to audit" },
|
|
600
|
+
max_items: { type: "integer", minimum: 1, maximum: 50, default: 8, description: "Maximum list entries to return per evidence group." },
|
|
601
|
+
},
|
|
602
|
+
required: ["task_id"],
|
|
603
|
+
},
|
|
604
|
+
},
|
|
605
|
+
{
|
|
606
|
+
name: "safe_test_summary",
|
|
607
|
+
description: "Return a compact verification summary for a task without stdout/stderr or test log content.",
|
|
608
|
+
inputSchema: {
|
|
609
|
+
type: "object",
|
|
610
|
+
properties: {
|
|
611
|
+
task_id: { type: "string", description: "Task ID to summarize" },
|
|
612
|
+
},
|
|
613
|
+
required: ["task_id"],
|
|
614
|
+
},
|
|
615
|
+
},
|
|
616
|
+
{
|
|
617
|
+
name: "safe_diff_summary",
|
|
618
|
+
description: "Return changed-file counts and bounded path metadata without returning diff content.",
|
|
619
|
+
inputSchema: {
|
|
620
|
+
type: "object",
|
|
621
|
+
properties: {
|
|
622
|
+
task_id: { type: "string", description: "Task ID to summarize" },
|
|
623
|
+
max_items: { type: "integer", minimum: 1, maximum: 50, default: 8, description: "Maximum changed files to return." },
|
|
624
|
+
},
|
|
625
|
+
required: ["task_id"],
|
|
626
|
+
},
|
|
627
|
+
}, {
|
|
628
|
+
name: "diagnose_task",
|
|
629
|
+
description: "v0.7.0: Diagnose a running or collecting_artifacts task using multi-signal evidence (heartbeat age, log freshness, child PID liveness, watcher ownership, artifact presence). Returns a conservative diagnosis (active_running, stale_running, possibly_stale_running, orphaned_running, artifact_collection_stuck, done_candidate, unknown, terminal) with confidence level and safe_actions. Never relies on a single signal; refuses to call PID-alive tasks 'active' when other signals are stale (PID reuse protection). Read-only — does not modify task state.",
|
|
630
|
+
inputSchema: {
|
|
631
|
+
type: "object",
|
|
632
|
+
properties: {
|
|
633
|
+
task_id: { type: "string", description: "Task ID to diagnose" },
|
|
634
|
+
include_logs: {
|
|
635
|
+
type: "boolean",
|
|
636
|
+
default: false,
|
|
637
|
+
description: "When true, include redacted stdout/stderr tails in the output. Default false to keep output minimal.",
|
|
638
|
+
},
|
|
639
|
+
},
|
|
640
|
+
required: ["task_id"],
|
|
641
|
+
},
|
|
642
|
+
},
|
|
643
|
+
{
|
|
644
|
+
name: "reconcile_tasks",
|
|
645
|
+
description: "v0.7.0: Scan stale running/collecting_artifacts tasks and either report or safely fix them. report_only (default) returns a diagnosis report without modifying state. safe_fix additionally writes high-confidence status transitions (failed_stale/orphaned/done_by_agent) atomically with backup (status.json.bak), audit fields, and an appended reconcile.log. Never touches tasks still owned by an active watcher; never applies medium/low confidence fixes.",
|
|
646
|
+
inputSchema: {
|
|
647
|
+
type: "object",
|
|
648
|
+
properties: {
|
|
649
|
+
mode: {
|
|
650
|
+
type: "string",
|
|
651
|
+
enum: ["report_only", "safe_fix"],
|
|
652
|
+
default: "report_only",
|
|
653
|
+
description: "report_only: read-only diagnosis report. safe_fix: additionally apply high-confidence status transitions with backup + atomic write + reconcile.log.",
|
|
654
|
+
},
|
|
655
|
+
max_age_minutes: {
|
|
656
|
+
type: "number",
|
|
657
|
+
minimum: 1,
|
|
658
|
+
maximum: 1440,
|
|
659
|
+
default: 30,
|
|
660
|
+
description: "Only consider tasks older than this (based on created_at or status.json mtime). Default 30 minutes.",
|
|
661
|
+
},
|
|
662
|
+
include_done_candidates: {
|
|
663
|
+
type: "boolean",
|
|
664
|
+
default: true,
|
|
665
|
+
description: "Include done_by_agent tasks as candidates (useful for auditing acceptance_status). Default true.",
|
|
666
|
+
},
|
|
667
|
+
},
|
|
668
|
+
},
|
|
669
|
+
},
|
|
670
|
+
{
|
|
671
|
+
name: "discover_tools",
|
|
672
|
+
description: "v0.7.1: Search candidate tools by natural-language query (Chinese or English). Returns compressed summaries with risk level and schema digest. Filters by profile/mode/riskCeiling. High-risk tools (command/release/credential_sensitive) are hidden by default unless includeHighRisk=true. Read-only — never invokes tools.",
|
|
673
|
+
inputSchema: {
|
|
674
|
+
type: "object",
|
|
675
|
+
properties: {
|
|
676
|
+
query: {
|
|
677
|
+
type: "string",
|
|
678
|
+
description: "Natural-language search query. Supports Chinese intent terms (验收/改文件/发布/状态/差异/卡住/旧任务/搜索/工具/诊断 etc.) and English keywords.",
|
|
679
|
+
},
|
|
680
|
+
profile: {
|
|
681
|
+
type: "string",
|
|
682
|
+
enum: ["full", "chatgpt_core", "chatgpt_direct", "chatgpt_search"],
|
|
683
|
+
description: "Filter tools by profile. Default: no filter (all profiles).",
|
|
684
|
+
},
|
|
685
|
+
mode: {
|
|
686
|
+
type: "string",
|
|
687
|
+
enum: ["delegate", "direct", "audit", "release", "diagnostic"],
|
|
688
|
+
description: "Filter tools by mode. Default: no filter.",
|
|
689
|
+
},
|
|
690
|
+
maxResults: {
|
|
691
|
+
type: "number",
|
|
692
|
+
minimum: 1,
|
|
693
|
+
maximum: 50,
|
|
694
|
+
default: 8,
|
|
695
|
+
description: "Maximum number of results. Default 8.",
|
|
696
|
+
},
|
|
697
|
+
riskCeiling: {
|
|
698
|
+
type: "string",
|
|
699
|
+
enum: ["readonly", "workspace_read_sensitive", "workspace_write", "command", "release", "credential_sensitive"],
|
|
700
|
+
description: "Maximum risk level to include. Tools above this level are hidden. Overrides includeHighRisk.",
|
|
701
|
+
},
|
|
702
|
+
includeHighRisk: {
|
|
703
|
+
type: "boolean",
|
|
704
|
+
default: false,
|
|
705
|
+
description: "When true, include high-risk tools (command/release/credential_sensitive) in results. Default false.",
|
|
706
|
+
},
|
|
707
|
+
},
|
|
708
|
+
required: ["query"],
|
|
709
|
+
},
|
|
710
|
+
},
|
|
711
|
+
{
|
|
712
|
+
name: "explain_tool",
|
|
713
|
+
description: "v0.7.1: Expand a single tool's metadata — title, summary, risk level, tags, aliases, profiles, modes, schema digest, and optionally the full inputSchema. Use after discover_tools to understand a specific tool before calling it. Read-only.",
|
|
714
|
+
inputSchema: {
|
|
715
|
+
type: "object",
|
|
716
|
+
properties: {
|
|
717
|
+
name: {
|
|
718
|
+
type: "string",
|
|
719
|
+
description: "Tool name or alias to explain. Accepts both the canonical name (e.g. 'create_task') and aliases (e.g. 'new_task').",
|
|
720
|
+
},
|
|
721
|
+
includeSchema: {
|
|
722
|
+
type: "boolean",
|
|
723
|
+
default: false,
|
|
724
|
+
description: "When true, include the full inputSchema in the response. Default false to keep output minimal.",
|
|
725
|
+
},
|
|
726
|
+
},
|
|
727
|
+
required: ["name"],
|
|
728
|
+
},
|
|
729
|
+
},
|
|
730
|
+
{
|
|
731
|
+
name: "invoke_discovered_tool",
|
|
732
|
+
description: "v0.8.1: Invoke a previously discovered tool using a discoveryToken. The token must be obtained from discover_tools first. Enforces 10 security checks: token validity, toolName match, profile allowance, risk ceiling, sensitive path guard, assessment requirement, command whitelist, release confirmation, credential block, and invocation logging. Cannot call itself recursively.",
|
|
733
|
+
inputSchema: {
|
|
734
|
+
type: "object",
|
|
735
|
+
properties: {
|
|
736
|
+
toolName: { type: "string", description: "Name of the tool to invoke (must match the discoveryToken's toolName)." },
|
|
737
|
+
arguments: {
|
|
738
|
+
type: "object",
|
|
739
|
+
description: "Arguments to pass to the tool. Must match the tool's inputSchema.",
|
|
740
|
+
additionalProperties: true,
|
|
741
|
+
},
|
|
742
|
+
discoveryToken: { type: "string", description: "Token id from discover_tools. Single-use, expires after 10 minutes." },
|
|
743
|
+
assessmentId: { type: "string", description: "Required for workspace_write/release risk tools. Obtained from the assessment flow." },
|
|
744
|
+
},
|
|
745
|
+
required: ["toolName", "arguments", "discoveryToken"],
|
|
746
|
+
},
|
|
747
|
+
},
|
|
748
|
+
{
|
|
749
|
+
name: "create_goal",
|
|
750
|
+
description: "v0.8.0: Create a Goal Session for managing a multi-task objective with subgoal dependencies. Generates a structured directory under .patchwarden/goals/{goal_id}/ with GOAL.md, GOALS.md, and goal_status.json. Use list_goals to enumerate existing goals and read_goal to inspect details.",
|
|
751
|
+
inputSchema: {
|
|
752
|
+
type: "object",
|
|
753
|
+
properties: {
|
|
754
|
+
title: { type: "string", description: "Goal title (human-readable)." },
|
|
755
|
+
goal_description: { type: "string", description: "Markdown description of the goal, success criteria, and context." },
|
|
756
|
+
repo_path: { type: "string", description: "Repository path inside workspaceRoot. Must be inside the configured workspace." },
|
|
757
|
+
},
|
|
758
|
+
required: ["title", "goal_description", "repo_path"],
|
|
759
|
+
},
|
|
760
|
+
},
|
|
761
|
+
{
|
|
762
|
+
name: "list_goals",
|
|
763
|
+
description: "v0.8.0: List all Goal Sessions with completion summaries. Returns goal_id, title, status, subgoal counts, and last update time. Sorted by updated_at descending.",
|
|
764
|
+
inputSchema: {
|
|
765
|
+
type: "object",
|
|
766
|
+
properties: {},
|
|
767
|
+
},
|
|
768
|
+
},
|
|
769
|
+
{
|
|
770
|
+
name: "read_goal",
|
|
771
|
+
description: "v0.8.0: Read full Goal Session details including GOAL.md content, goal_status.json, and all subgoals with dependency info. Use after list_goals to inspect a specific goal.",
|
|
772
|
+
inputSchema: {
|
|
773
|
+
type: "object",
|
|
774
|
+
properties: {
|
|
775
|
+
goal_id: { type: "string", description: "Goal ID from list_goals or create_goal." },
|
|
776
|
+
},
|
|
777
|
+
required: ["goal_id"],
|
|
778
|
+
},
|
|
779
|
+
},
|
|
780
|
+
{
|
|
781
|
+
name: "create_subgoal_task",
|
|
782
|
+
description: "v0.8.0: Create a subgoal within a Goal Session and immediately launch an associated task. Atomically: addSubgoal → create_task → linkTask → mark subgoal running. The subgoal depends_on other subgoals (by id) which must be accepted before suggest_next_subgoal returns it.",
|
|
783
|
+
inputSchema: {
|
|
784
|
+
type: "object",
|
|
785
|
+
properties: {
|
|
786
|
+
goal_id: { type: "string", description: "Goal ID to add the subgoal to." },
|
|
787
|
+
subgoal_title: { type: "string", description: "Title of the new subgoal." },
|
|
788
|
+
depends_on: {
|
|
789
|
+
type: "array",
|
|
790
|
+
items: { type: "string" },
|
|
791
|
+
description: "Subgoal IDs this subgoal depends on. Dependencies must be accepted before this subgoal is suggested.",
|
|
792
|
+
},
|
|
793
|
+
plan_id: { type: "string", description: "Plan ID from save_plan. One of plan_id/inline_plan/template+goal is required." },
|
|
794
|
+
inline_plan: { type: "string", description: "Inline Markdown plan." },
|
|
795
|
+
plan_title: { type: "string", description: "Optional title for inline_plan." },
|
|
796
|
+
template: {
|
|
797
|
+
type: "string",
|
|
798
|
+
enum: [...TASK_TEMPLATE_NAMES],
|
|
799
|
+
description: "Built-in task template. Use with goal.",
|
|
800
|
+
},
|
|
801
|
+
goal: { type: "string", description: "Task goal when template is supplied." },
|
|
802
|
+
agent: { type: "string", description: "Agent name." },
|
|
803
|
+
repo_path: { type: "string", description: "Repository path inside workspaceRoot." },
|
|
804
|
+
test_command: { type: "string", description: "Verification command." },
|
|
805
|
+
verify_commands: {
|
|
806
|
+
type: "array",
|
|
807
|
+
maxItems: 20,
|
|
808
|
+
items: { type: "string" },
|
|
809
|
+
description: "Additional verification commands.",
|
|
810
|
+
},
|
|
811
|
+
timeout_seconds: { type: "integer", minimum: 1, description: "Task timeout in seconds." },
|
|
812
|
+
scope: { type: "array", items: { type: "string" }, description: "Allowed file/directory scope." },
|
|
813
|
+
forbidden: { type: "array", items: { type: "string" }, description: "Forbidden file/directory paths." },
|
|
814
|
+
verification: { type: "array", items: { type: "string" }, description: "Acceptance verification commands." },
|
|
815
|
+
done_evidence: { type: "array", items: { type: "string" }, description: "Required done evidence files." },
|
|
816
|
+
isolate_worktree: { type: "boolean", default: true, description: "v1.0.0: If true (default), create the task in an isolated git worktree under _workspacetrees/. Set false to run in the main workspace (v0.8.0 behavior)." },
|
|
817
|
+
},
|
|
818
|
+
required: ["goal_id", "subgoal_title", "repo_path"],
|
|
819
|
+
},
|
|
820
|
+
},
|
|
821
|
+
{
|
|
822
|
+
name: "accept_subgoal",
|
|
823
|
+
description: "v0.8.0: Accept a subgoal after all its associated tasks are accepted (via audit_task). Validates every task in subgoal.task_ids has status 'accepted'. Throws subgoal_not_ready if any task is not yet accepted.",
|
|
824
|
+
inputSchema: {
|
|
825
|
+
type: "object",
|
|
826
|
+
properties: {
|
|
827
|
+
goal_id: { type: "string", description: "Goal ID." },
|
|
828
|
+
subgoal_id: { type: "string", description: "Subgoal ID to accept." },
|
|
829
|
+
},
|
|
830
|
+
required: ["goal_id", "subgoal_id"],
|
|
831
|
+
},
|
|
832
|
+
},
|
|
833
|
+
{
|
|
834
|
+
name: "reject_subgoal",
|
|
835
|
+
description: "v0.8.0: Reject a subgoal with a reason. Allowed from any non-terminal status (ready/running/done_by_agent/needs_fix). Records rejected_reason in goal_status.json.",
|
|
836
|
+
inputSchema: {
|
|
837
|
+
type: "object",
|
|
838
|
+
properties: {
|
|
839
|
+
goal_id: { type: "string", description: "Goal ID." },
|
|
840
|
+
subgoal_id: { type: "string", description: "Subgoal ID to reject." },
|
|
841
|
+
reason: { type: "string", description: "Rejection reason (required)." },
|
|
842
|
+
},
|
|
843
|
+
required: ["goal_id", "subgoal_id", "reason"],
|
|
844
|
+
},
|
|
845
|
+
},
|
|
846
|
+
{
|
|
847
|
+
name: "suggest_next_subgoal",
|
|
848
|
+
description: "v0.8.0: Suggest the next executable subgoal based on the dependency graph. Returns a ready subgoal whose dependencies are all accepted. If none ready, returns blocked_by list. Use to drive goal-directed task sequencing.",
|
|
849
|
+
inputSchema: {
|
|
850
|
+
type: "object",
|
|
851
|
+
properties: {
|
|
852
|
+
goal_id: { type: "string", description: "Goal ID." },
|
|
853
|
+
},
|
|
854
|
+
required: ["goal_id"],
|
|
855
|
+
},
|
|
856
|
+
},
|
|
857
|
+
{
|
|
858
|
+
name: "summarize_goal_progress",
|
|
859
|
+
description: "v0.8.0: Summarize goal completion: counts by status (accepted/rejected/running/ready/needs_fix/done_by_agent), completion_rate percentage, blocked_subgoals, and risks (needs_fix or running subgoals).",
|
|
860
|
+
inputSchema: {
|
|
861
|
+
type: "object",
|
|
862
|
+
properties: {
|
|
863
|
+
goal_id: { type: "string", description: "Goal ID." },
|
|
864
|
+
},
|
|
865
|
+
required: ["goal_id"],
|
|
866
|
+
},
|
|
867
|
+
},
|
|
868
|
+
{
|
|
869
|
+
name: "export_handoff",
|
|
870
|
+
description: "v0.8.0: Export a handoff.md document for transferring a Goal Session to a new conversation. Includes current goal, completed/pending subgoals, recent diff/test results, blockers, next steps, and risks. Writes to .patchwarden/goals/{goal_id}/handoff.md.",
|
|
871
|
+
inputSchema: {
|
|
872
|
+
type: "object",
|
|
873
|
+
properties: {
|
|
874
|
+
goal_id: { type: "string", description: "Goal ID." },
|
|
875
|
+
},
|
|
876
|
+
required: ["goal_id"],
|
|
877
|
+
},
|
|
878
|
+
},
|
|
879
|
+
{
|
|
880
|
+
name: "check_release_gate",
|
|
881
|
+
description: "v1.0.0: Verify release readiness across five sequential stages: local_ready → packed_ready → published_verified → github_release_verified → ci_verified. Remote stages (published/github/ci) query npm registry and GitHub API via node:https read-only GET; network errors return 'not_checked' (not 'failed'). Never claims release complete before published_verified passes. Does not execute shell commands for remote queries.",
|
|
882
|
+
inputSchema: {
|
|
883
|
+
type: "object",
|
|
884
|
+
properties: {
|
|
885
|
+
repo_path: { type: "string", description: "Repository path inside workspaceRoot." },
|
|
886
|
+
target_stage: {
|
|
887
|
+
type: "string",
|
|
888
|
+
enum: ["local_ready", "packed_ready", "published_verified", "github_release_verified", "ci_verified"],
|
|
889
|
+
description: "Target stage to verify. Stages before target are checked; stages after a failure are 'not_checked'.",
|
|
890
|
+
},
|
|
891
|
+
package_name: { type: "string", description: "npm package name for published_verified (e.g. 'patchwarden'). Required for published_verified stage." },
|
|
892
|
+
version: { type: "string", description: "Version string for published_verified (e.g. '1.0.0'). Required for published_verified stage." },
|
|
893
|
+
github_repo: { type: "string", description: "GitHub repo in 'owner/repo' form for github_release_verified and ci_verified." },
|
|
894
|
+
branch: { type: "string", description: "Git branch for ci_verified (e.g. 'main')." },
|
|
895
|
+
},
|
|
896
|
+
required: ["repo_path", "target_stage"],
|
|
897
|
+
},
|
|
898
|
+
},
|
|
899
|
+
{
|
|
900
|
+
name: "release_check",
|
|
901
|
+
description: "v1.3.0: Run a bounded release readiness check by wrapping the existing release gate. Local stages use existing guarded release-gate commands; remote stages are read-only. Does not publish, push, tag, or create a GitHub Release.",
|
|
902
|
+
inputSchema: {
|
|
903
|
+
type: "object",
|
|
904
|
+
properties: {
|
|
905
|
+
repo_path: { type: "string", description: "Repository path inside workspaceRoot." },
|
|
906
|
+
target_stage: {
|
|
907
|
+
type: "string",
|
|
908
|
+
enum: ["local_ready", "packed_ready", "published_verified", "github_release_verified", "ci_verified"],
|
|
909
|
+
default: "local_ready",
|
|
910
|
+
description: "Release gate stage to check. Defaults to local_ready.",
|
|
911
|
+
},
|
|
912
|
+
package_name: { type: "string", description: "npm package name for remote verification." },
|
|
913
|
+
version: { type: "string", description: "Version to verify. Defaults to project policy/package.json when omitted." },
|
|
914
|
+
github_repo: { type: "string", description: "GitHub repo in owner/repo form for release/CI verification." },
|
|
915
|
+
branch: { type: "string", default: "main", description: "Branch for CI verification." },
|
|
916
|
+
},
|
|
917
|
+
required: ["repo_path"],
|
|
918
|
+
},
|
|
919
|
+
},
|
|
920
|
+
{
|
|
921
|
+
name: "release_prepare",
|
|
922
|
+
description: "v1.3.0: Run project-policy release preparation commands only when each command is already accepted by the existing PatchWarden command guard. Returns command status only, never stdout/stderr. Does not publish, push, tag, or create a GitHub Release.",
|
|
923
|
+
inputSchema: {
|
|
924
|
+
type: "object",
|
|
925
|
+
properties: {
|
|
926
|
+
repo_path: { type: "string", description: "Repository path inside workspaceRoot." },
|
|
927
|
+
required_commands: {
|
|
928
|
+
type: "array",
|
|
929
|
+
maxItems: 10,
|
|
930
|
+
items: {
|
|
931
|
+
type: "string",
|
|
932
|
+
...(testCommands.length > 0 ? { enum: testCommands } : {}),
|
|
933
|
+
},
|
|
934
|
+
description: "Optional exact-match release preparation commands. Defaults to project policy release_mode.required_commands.",
|
|
935
|
+
},
|
|
936
|
+
timeout_seconds: {
|
|
937
|
+
type: "integer",
|
|
938
|
+
minimum: 1,
|
|
939
|
+
maximum: config.maxTaskTimeoutSeconds,
|
|
940
|
+
default: 300,
|
|
941
|
+
description: "Per-command timeout in seconds.",
|
|
942
|
+
},
|
|
943
|
+
},
|
|
944
|
+
required: ["repo_path"],
|
|
945
|
+
},
|
|
946
|
+
},
|
|
947
|
+
{
|
|
948
|
+
name: "release_verify",
|
|
949
|
+
description: "v1.3.0: Verify npm/GitHub/CI release facts with read-only HTTPS requests. Does not run local shell commands and does not publish, push, tag, or create a GitHub Release.",
|
|
950
|
+
inputSchema: {
|
|
951
|
+
type: "object",
|
|
952
|
+
properties: {
|
|
953
|
+
repo_path: { type: "string", description: "Repository path inside workspaceRoot." },
|
|
954
|
+
package_name: { type: "string", description: "npm package name. Defaults to package.json name." },
|
|
955
|
+
version: { type: "string", description: "Version to verify. Defaults to project policy/package.json." },
|
|
956
|
+
github_repo: { type: "string", description: "GitHub repo in owner/repo form. Defaults to package.json repository when available." },
|
|
957
|
+
branch: { type: "string", default: "main", description: "Branch for CI verification." },
|
|
958
|
+
},
|
|
959
|
+
required: ["repo_path"],
|
|
960
|
+
},
|
|
961
|
+
},
|
|
962
|
+
{
|
|
963
|
+
name: "release_cleanup",
|
|
964
|
+
description: "v1.3.0: Clean up release artifacts using project-policy auto_cleanup rules. Defaults to dry_run=true. Non-dry-run cleanup only removes low-risk ignored/untracked artifacts under repo_path and writes an audit summary.",
|
|
965
|
+
inputSchema: {
|
|
966
|
+
type: "object",
|
|
967
|
+
properties: {
|
|
968
|
+
repo_path: { type: "string", description: "Repository path inside workspaceRoot." },
|
|
969
|
+
dry_run: { type: "boolean", default: true, description: "Preview cleanup by default. Set false to remove eligible artifacts." },
|
|
970
|
+
patterns: {
|
|
971
|
+
type: "array",
|
|
972
|
+
maxItems: 20,
|
|
973
|
+
items: { type: "string" },
|
|
974
|
+
description: "Optional cleanup patterns. Defaults to project policy auto_cleanup.patterns.",
|
|
975
|
+
},
|
|
976
|
+
},
|
|
977
|
+
required: ["repo_path"],
|
|
978
|
+
},
|
|
979
|
+
},
|
|
980
|
+
{
|
|
981
|
+
name: "merge_worktree",
|
|
982
|
+
description: "v1.0.0: Merge an isolated git worktree's changes back into the main workspace. Use after a subgoal task (created with isolate_worktree=true) is accepted. Updates worktree_status.json to status='merged'. Merge failures do NOT delete the worktree (preserved for manual inspection).",
|
|
983
|
+
inputSchema: {
|
|
984
|
+
type: "object",
|
|
985
|
+
properties: {
|
|
986
|
+
worktree_id: { type: "string", description: "Worktree ID (wt_...) from create_subgoal_task." },
|
|
987
|
+
repo_path: { type: "string", description: "Main workspace repository path inside workspaceRoot." },
|
|
988
|
+
},
|
|
989
|
+
required: ["worktree_id", "repo_path"],
|
|
990
|
+
},
|
|
991
|
+
},
|
|
992
|
+
{
|
|
993
|
+
name: "discard_worktree",
|
|
994
|
+
description: "v1.0.0: Discard an isolated git worktree safely. Removes the worktree (git worktree remove --force), deletes its branch, and archives status as 'discarded'. Use when a subgoal is rejected or abandoned. All paths pass guardWorkspacePath + sensitiveGuard.",
|
|
995
|
+
inputSchema: {
|
|
996
|
+
type: "object",
|
|
997
|
+
properties: {
|
|
998
|
+
worktree_id: { type: "string", description: "Worktree ID (wt_...) to discard." },
|
|
999
|
+
repo_path: { type: "string", description: "Main workspace repository path inside workspaceRoot." },
|
|
1000
|
+
},
|
|
1001
|
+
required: ["worktree_id", "repo_path"],
|
|
1002
|
+
},
|
|
1003
|
+
},
|
|
392
1004
|
];
|
|
393
1005
|
// Direct session tools
|
|
394
|
-
const directCommands = getAllConfiguredDirectCommands(config);
|
|
395
1006
|
tools.push({
|
|
396
1007
|
name: "create_direct_session",
|
|
397
1008
|
description: "Create a Direct editing session for ChatGPT to apply patches directly. Requires enableDirectProfile: true in config.",
|
|
@@ -473,6 +1084,28 @@ export function getToolDefs() {
|
|
|
473
1084
|
required: ["session_id", "command"],
|
|
474
1085
|
},
|
|
475
1086
|
});
|
|
1087
|
+
tools.push({
|
|
1088
|
+
name: "run_direct_verification_bundle",
|
|
1089
|
+
description: "Run multiple allowlisted Direct verification commands sequentially and return only bounded structured status. Omits stdout/stderr tails and log content.",
|
|
1090
|
+
inputSchema: {
|
|
1091
|
+
type: "object",
|
|
1092
|
+
properties: {
|
|
1093
|
+
session_id: { type: "string", description: "Direct session ID" },
|
|
1094
|
+
commands: {
|
|
1095
|
+
type: "array",
|
|
1096
|
+
minItems: 1,
|
|
1097
|
+
maxItems: 20,
|
|
1098
|
+
items: {
|
|
1099
|
+
type: "string",
|
|
1100
|
+
...(directCommands.length > 0 ? { enum: directCommands } : {}),
|
|
1101
|
+
},
|
|
1102
|
+
description: "Verification commands to run in order. Each command must be accepted by the existing Direct command guard.",
|
|
1103
|
+
},
|
|
1104
|
+
timeout_seconds: { type: "integer", minimum: 1, maximum: Math.min(config.maxTaskTimeoutSeconds, config.directSessionTtlSeconds), default: 120 },
|
|
1105
|
+
},
|
|
1106
|
+
required: ["session_id", "commands"],
|
|
1107
|
+
},
|
|
1108
|
+
});
|
|
476
1109
|
tools.push({
|
|
477
1110
|
name: "finalize_direct_session",
|
|
478
1111
|
description: "Finalize a Direct session: capture after snapshot, generate diff/summary/change artifacts, mark session as finalized. Must be called before audit_session.",
|
|
@@ -495,6 +1128,42 @@ export function getToolDefs() {
|
|
|
495
1128
|
required: ["session_id"],
|
|
496
1129
|
},
|
|
497
1130
|
});
|
|
1131
|
+
tools.push({
|
|
1132
|
+
name: "safe_direct_summary",
|
|
1133
|
+
description: "Return a low-noise Direct session summary without diff content or verification stdout/stderr tails.",
|
|
1134
|
+
inputSchema: {
|
|
1135
|
+
type: "object",
|
|
1136
|
+
properties: {
|
|
1137
|
+
session_id: { type: "string", description: "Direct session ID" },
|
|
1138
|
+
max_items: { type: "integer", minimum: 1, maximum: 50, default: 8, description: "Maximum list entries to return per evidence group." },
|
|
1139
|
+
},
|
|
1140
|
+
required: ["session_id"],
|
|
1141
|
+
},
|
|
1142
|
+
});
|
|
1143
|
+
tools.push({
|
|
1144
|
+
name: "safe_finalize_direct_session",
|
|
1145
|
+
description: "Finalize a Direct session and return only bounded structured evidence, omitting diff and verification log content.",
|
|
1146
|
+
inputSchema: {
|
|
1147
|
+
type: "object",
|
|
1148
|
+
properties: {
|
|
1149
|
+
session_id: { type: "string", description: "Direct session ID to finalize" },
|
|
1150
|
+
max_items: { type: "integer", minimum: 1, maximum: 50, default: 8, description: "Maximum list entries to return per evidence group." },
|
|
1151
|
+
},
|
|
1152
|
+
required: ["session_id"],
|
|
1153
|
+
},
|
|
1154
|
+
});
|
|
1155
|
+
tools.push({
|
|
1156
|
+
name: "safe_audit_direct_session",
|
|
1157
|
+
description: "Audit a Direct session and return only bounded structured evidence without verification stdout/stderr tails.",
|
|
1158
|
+
inputSchema: {
|
|
1159
|
+
type: "object",
|
|
1160
|
+
properties: {
|
|
1161
|
+
session_id: { type: "string", description: "Direct session ID to audit" },
|
|
1162
|
+
max_items: { type: "integer", minimum: 1, maximum: 50, default: 8, description: "Maximum list entries to return per evidence group." },
|
|
1163
|
+
},
|
|
1164
|
+
required: ["session_id"],
|
|
1165
|
+
},
|
|
1166
|
+
});
|
|
498
1167
|
tools.push({
|
|
499
1168
|
name: "sync_file",
|
|
500
1169
|
description: "Copy a file from source to target within the same Direct session repo. Both paths must be inside the session repo_path. Returns before/after sha256 hashes and whether the target changed.",
|
|
@@ -588,6 +1257,60 @@ async function handleToolCallInternal(name, args) {
|
|
|
588
1257
|
assessment_id: args?.assessment_id ? String(args.assessment_id) : undefined,
|
|
589
1258
|
}));
|
|
590
1259
|
}
|
|
1260
|
+
case "run_task_loop": {
|
|
1261
|
+
return toResult(await runTaskLoop({
|
|
1262
|
+
repo_path: String(args?.repo_path ?? ""),
|
|
1263
|
+
goal: String(args?.goal ?? ""),
|
|
1264
|
+
verify_commands: Array.isArray(args?.verify_commands)
|
|
1265
|
+
? args.verify_commands.map((command) => String(command))
|
|
1266
|
+
: [],
|
|
1267
|
+
agent: args?.agent ? String(args.agent) : undefined,
|
|
1268
|
+
template: args?.template === "inspect_only" || args?.template === "release_check"
|
|
1269
|
+
? args.template
|
|
1270
|
+
: "feature_small",
|
|
1271
|
+
max_iterations: args?.max_iterations !== undefined ? Number(args.max_iterations) : undefined,
|
|
1272
|
+
task_timeout_seconds: args?.task_timeout_seconds !== undefined ? Number(args.task_timeout_seconds) : undefined,
|
|
1273
|
+
auto_fix_tests: args?.auto_fix_tests !== undefined ? Boolean(args.auto_fix_tests) : undefined,
|
|
1274
|
+
auto_cleanup_artifacts: args?.auto_cleanup_artifacts !== undefined ? Boolean(args.auto_cleanup_artifacts) : undefined,
|
|
1275
|
+
stop_on_high_risk: args?.stop_on_high_risk !== undefined ? Boolean(args.stop_on_high_risk) : undefined,
|
|
1276
|
+
direct_verify: args?.direct_verify !== undefined ? Boolean(args.direct_verify) : undefined,
|
|
1277
|
+
direct_verify_commands: Array.isArray(args?.direct_verify_commands)
|
|
1278
|
+
? args.direct_verify_commands.map((command) => String(command))
|
|
1279
|
+
: undefined,
|
|
1280
|
+
direct_verify_timeout_seconds: args?.direct_verify_timeout_seconds !== undefined ? Number(args.direct_verify_timeout_seconds) : undefined,
|
|
1281
|
+
scope_files: Array.isArray(args?.scope_files)
|
|
1282
|
+
? args.scope_files.map((entry) => String(entry))
|
|
1283
|
+
: undefined,
|
|
1284
|
+
isolation_mode: args?.isolation_mode === "worktree" ? "worktree" : "current_repo",
|
|
1285
|
+
worktree_base_branch: args?.worktree_base_branch ? String(args.worktree_base_branch) : undefined,
|
|
1286
|
+
worktree_cleanup: args?.worktree_cleanup === "archive" || args?.worktree_cleanup === "delete_ignored_only"
|
|
1287
|
+
? args.worktree_cleanup
|
|
1288
|
+
: "keep",
|
|
1289
|
+
}));
|
|
1290
|
+
}
|
|
1291
|
+
case "recommend_agent_for_task": {
|
|
1292
|
+
return toResult(recommendAgentForTask({
|
|
1293
|
+
repo_path: String(args?.repo_path ?? ""),
|
|
1294
|
+
goal: String(args?.goal ?? ""),
|
|
1295
|
+
scope_files: Array.isArray(args?.scope_files) ? args.scope_files.map((entry) => String(entry)) : undefined,
|
|
1296
|
+
template: args?.template ? String(args.template) : undefined,
|
|
1297
|
+
risk_hint: args?.risk_hint ? String(args.risk_hint) : undefined,
|
|
1298
|
+
}));
|
|
1299
|
+
}
|
|
1300
|
+
case "get_task_lineage": {
|
|
1301
|
+
return toResult(getTaskLineage(String(args?.lineage_id ?? ""), {
|
|
1302
|
+
max_items: args?.max_items !== undefined ? Number(args.max_items) : undefined,
|
|
1303
|
+
}));
|
|
1304
|
+
}
|
|
1305
|
+
case "export_task_evidence_pack": {
|
|
1306
|
+
return toResult(exportTaskEvidencePack({
|
|
1307
|
+
lineage_id: String(args?.lineage_id ?? ""),
|
|
1308
|
+
max_items: args?.max_items !== undefined ? Number(args.max_items) : undefined,
|
|
1309
|
+
}));
|
|
1310
|
+
}
|
|
1311
|
+
case "get_project_policy": {
|
|
1312
|
+
return toResult(getProjectPolicyTool(String(args?.repo_path ?? "")));
|
|
1313
|
+
}
|
|
591
1314
|
case "get_task_status": {
|
|
592
1315
|
return toResult(getTaskStatus(String(args?.task_id ?? "")));
|
|
593
1316
|
}
|
|
@@ -666,6 +1389,75 @@ async function handleToolCallInternal(name, args) {
|
|
|
666
1389
|
case "safe_status": {
|
|
667
1390
|
return toResult(safeStatus(String(args?.task_id ?? "")));
|
|
668
1391
|
}
|
|
1392
|
+
case "safe_result": {
|
|
1393
|
+
return toResult(safeResult(String(args?.task_id ?? ""), {
|
|
1394
|
+
max_items: args?.max_items !== undefined ? Number(args.max_items) : undefined,
|
|
1395
|
+
}));
|
|
1396
|
+
}
|
|
1397
|
+
case "safe_audit": {
|
|
1398
|
+
return toResult(safeAudit(String(args?.task_id ?? ""), {
|
|
1399
|
+
max_items: args?.max_items !== undefined ? Number(args.max_items) : undefined,
|
|
1400
|
+
}));
|
|
1401
|
+
}
|
|
1402
|
+
case "safe_test_summary": {
|
|
1403
|
+
return toResult(safeTestSummary(String(args?.task_id ?? "")));
|
|
1404
|
+
}
|
|
1405
|
+
case "safe_diff_summary": {
|
|
1406
|
+
return toResult(safeDiffSummary(String(args?.task_id ?? ""), {
|
|
1407
|
+
max_items: args?.max_items !== undefined ? Number(args.max_items) : undefined,
|
|
1408
|
+
}));
|
|
1409
|
+
}
|
|
1410
|
+
case "diagnose_task": {
|
|
1411
|
+
return toResult(diagnoseTask({
|
|
1412
|
+
task_id: String(args?.task_id ?? ""),
|
|
1413
|
+
include_logs: args?.include_logs !== undefined ? Boolean(args.include_logs) : undefined,
|
|
1414
|
+
}));
|
|
1415
|
+
}
|
|
1416
|
+
case "reconcile_tasks": {
|
|
1417
|
+
return toResult(reconcileTasks({
|
|
1418
|
+
mode: args?.mode === "safe_fix" ? "safe_fix" : "report_only",
|
|
1419
|
+
max_age_minutes: args?.max_age_minutes !== undefined ? Number(args.max_age_minutes) : undefined,
|
|
1420
|
+
include_done_candidates: args?.include_done_candidates !== undefined ? Boolean(args.include_done_candidates) : undefined,
|
|
1421
|
+
}));
|
|
1422
|
+
}
|
|
1423
|
+
case "discover_tools": {
|
|
1424
|
+
const profile = args?.profile === "full" || args?.profile === "chatgpt_core" || args?.profile === "chatgpt_direct" || args?.profile === "chatgpt_search"
|
|
1425
|
+
? args.profile : undefined;
|
|
1426
|
+
const mode = args?.mode === "delegate" || args?.mode === "direct" || args?.mode === "audit" || args?.mode === "release" || args?.mode === "diagnostic"
|
|
1427
|
+
? args.mode : undefined;
|
|
1428
|
+
const riskCeiling = ["readonly", "workspace_read_sensitive", "workspace_write", "command", "release", "credential_sensitive"]
|
|
1429
|
+
.includes(String(args?.riskCeiling ?? "")) ? String(args?.riskCeiling) : undefined;
|
|
1430
|
+
return toResult(discoverTools({
|
|
1431
|
+
query: String(args?.query ?? ""),
|
|
1432
|
+
profile,
|
|
1433
|
+
mode,
|
|
1434
|
+
maxResults: args?.maxResults !== undefined ? Number(args.maxResults) : undefined,
|
|
1435
|
+
riskCeiling,
|
|
1436
|
+
includeHighRisk: args?.includeHighRisk !== undefined ? Boolean(args.includeHighRisk) : undefined,
|
|
1437
|
+
}, getToolDefs()));
|
|
1438
|
+
}
|
|
1439
|
+
case "explain_tool": {
|
|
1440
|
+
return toResult(explainTool({
|
|
1441
|
+
name: String(args?.name ?? ""),
|
|
1442
|
+
includeSchema: args?.includeSchema !== undefined ? Boolean(args.includeSchema) : undefined,
|
|
1443
|
+
}, getToolDefs()));
|
|
1444
|
+
}
|
|
1445
|
+
case "invoke_discovered_tool": {
|
|
1446
|
+
const profile = resolveToolProfile(getConfig().toolProfile);
|
|
1447
|
+
const result = await invokeDiscoveredTool({
|
|
1448
|
+
toolName: String(args?.toolName ?? ""),
|
|
1449
|
+
arguments: (args?.arguments && typeof args.arguments === "object" ? args.arguments : {}),
|
|
1450
|
+
discoveryToken: String(args?.discoveryToken ?? ""),
|
|
1451
|
+
assessmentId: args?.assessmentId ? String(args.assessmentId) : undefined,
|
|
1452
|
+
}, {
|
|
1453
|
+
tools: getToolDefs(),
|
|
1454
|
+
profile,
|
|
1455
|
+
dispatch: async (name, dispatchArgs) => {
|
|
1456
|
+
return handleToolCall(name, dispatchArgs);
|
|
1457
|
+
},
|
|
1458
|
+
});
|
|
1459
|
+
return toResult(result);
|
|
1460
|
+
}
|
|
669
1461
|
case "run_task": {
|
|
670
1462
|
const config = getConfig();
|
|
671
1463
|
if (config.enableRunTaskTool !== true) {
|
|
@@ -710,6 +1502,14 @@ async function handleToolCallInternal(name, args) {
|
|
|
710
1502
|
timeout_seconds: args?.timeout_seconds ? Number(args.timeout_seconds) : undefined,
|
|
711
1503
|
}));
|
|
712
1504
|
}
|
|
1505
|
+
case "run_direct_verification_bundle": {
|
|
1506
|
+
guardDirectProfileEnabled();
|
|
1507
|
+
return toResult(await runDirectVerificationBundle({
|
|
1508
|
+
session_id: String(args?.session_id ?? ""),
|
|
1509
|
+
commands: Array.isArray(args?.commands) ? args.commands.map((command) => String(command)) : [],
|
|
1510
|
+
timeout_seconds: args?.timeout_seconds ? Number(args.timeout_seconds) : undefined,
|
|
1511
|
+
}));
|
|
1512
|
+
}
|
|
713
1513
|
case "finalize_direct_session": {
|
|
714
1514
|
guardDirectProfileEnabled();
|
|
715
1515
|
return toResult(finalizeDirectSession({
|
|
@@ -722,6 +1522,24 @@ async function handleToolCallInternal(name, args) {
|
|
|
722
1522
|
session_id: String(args?.session_id ?? ""),
|
|
723
1523
|
}));
|
|
724
1524
|
}
|
|
1525
|
+
case "safe_direct_summary": {
|
|
1526
|
+
guardDirectProfileEnabled();
|
|
1527
|
+
return toResult(safeDirectSummary(String(args?.session_id ?? ""), {
|
|
1528
|
+
max_items: args?.max_items !== undefined ? Number(args.max_items) : undefined,
|
|
1529
|
+
}));
|
|
1530
|
+
}
|
|
1531
|
+
case "safe_finalize_direct_session": {
|
|
1532
|
+
guardDirectProfileEnabled();
|
|
1533
|
+
return toResult(safeFinalizeDirectSession(String(args?.session_id ?? ""), {
|
|
1534
|
+
max_items: args?.max_items !== undefined ? Number(args.max_items) : undefined,
|
|
1535
|
+
}));
|
|
1536
|
+
}
|
|
1537
|
+
case "safe_audit_direct_session": {
|
|
1538
|
+
guardDirectProfileEnabled();
|
|
1539
|
+
return toResult(safeAuditDirectSession(String(args?.session_id ?? ""), {
|
|
1540
|
+
max_items: args?.max_items !== undefined ? Number(args.max_items) : undefined,
|
|
1541
|
+
}));
|
|
1542
|
+
}
|
|
725
1543
|
case "sync_file": {
|
|
726
1544
|
guardDirectProfileEnabled();
|
|
727
1545
|
return toResult(syncFile(String(args?.session_id ?? ""), String(args?.source_path ?? ""), String(args?.target_path ?? ""), {
|
|
@@ -729,6 +1547,112 @@ async function handleToolCallInternal(name, args) {
|
|
|
729
1547
|
expected_target_sha256: args?.expected_target_sha256 ? String(args.expected_target_sha256) : undefined,
|
|
730
1548
|
}));
|
|
731
1549
|
}
|
|
1550
|
+
case "create_goal": {
|
|
1551
|
+
return toResult(createGoal(String(args?.repo_path ?? ""), String(args?.title ?? ""), String(args?.goal_description ?? "")));
|
|
1552
|
+
}
|
|
1553
|
+
case "list_goals": {
|
|
1554
|
+
return toResult({ goals: listGoals() });
|
|
1555
|
+
}
|
|
1556
|
+
case "read_goal": {
|
|
1557
|
+
return toResult(readGoal(String(args?.goal_id ?? "")));
|
|
1558
|
+
}
|
|
1559
|
+
case "create_subgoal_task": {
|
|
1560
|
+
return toResult(createSubgoalTask({
|
|
1561
|
+
goal_id: String(args?.goal_id ?? ""),
|
|
1562
|
+
subgoal_title: String(args?.subgoal_title ?? ""),
|
|
1563
|
+
depends_on: Array.isArray(args?.depends_on) ? args.depends_on.map(String) : undefined,
|
|
1564
|
+
plan_id: args?.plan_id ? String(args.plan_id) : undefined,
|
|
1565
|
+
inline_plan: args?.inline_plan ? String(args.inline_plan) : undefined,
|
|
1566
|
+
plan_title: args?.plan_title ? String(args.plan_title) : undefined,
|
|
1567
|
+
template: args?.template ? String(args.template) : undefined,
|
|
1568
|
+
goal: args?.goal ? String(args.goal) : undefined,
|
|
1569
|
+
agent: args?.agent ? String(args.agent) : undefined,
|
|
1570
|
+
repo_path: String(args?.repo_path ?? ""),
|
|
1571
|
+
test_command: args?.test_command ? String(args.test_command) : undefined,
|
|
1572
|
+
verify_commands: Array.isArray(args?.verify_commands) ? args.verify_commands.map(String) : undefined,
|
|
1573
|
+
timeout_seconds: args?.timeout_seconds ? Number(args.timeout_seconds) : undefined,
|
|
1574
|
+
scope: Array.isArray(args?.scope) ? args.scope.map(String) : undefined,
|
|
1575
|
+
forbidden: Array.isArray(args?.forbidden) ? args.forbidden.map(String) : undefined,
|
|
1576
|
+
verification: Array.isArray(args?.verification) ? args.verification.map(String) : undefined,
|
|
1577
|
+
done_evidence: Array.isArray(args?.done_evidence) ? args.done_evidence.map(String) : undefined,
|
|
1578
|
+
isolate_worktree: args?.isolate_worktree === undefined ? undefined : Boolean(args.isolate_worktree),
|
|
1579
|
+
}));
|
|
1580
|
+
}
|
|
1581
|
+
case "accept_subgoal": {
|
|
1582
|
+
return toResult(acceptSubgoal(String(args?.goal_id ?? ""), String(args?.subgoal_id ?? "")));
|
|
1583
|
+
}
|
|
1584
|
+
case "reject_subgoal": {
|
|
1585
|
+
return toResult(rejectSubgoal(String(args?.goal_id ?? ""), String(args?.subgoal_id ?? ""), String(args?.reason ?? "")));
|
|
1586
|
+
}
|
|
1587
|
+
case "suggest_next_subgoal": {
|
|
1588
|
+
const goalStatus = readGoalStatus(String(args?.goal_id ?? ""));
|
|
1589
|
+
return toResult(suggestNextSubgoal(goalStatus));
|
|
1590
|
+
}
|
|
1591
|
+
case "summarize_goal_progress": {
|
|
1592
|
+
return toResult(summarizeGoalProgress(String(args?.goal_id ?? "")));
|
|
1593
|
+
}
|
|
1594
|
+
case "export_handoff": {
|
|
1595
|
+
const goalId = String(args?.goal_id ?? "");
|
|
1596
|
+
const goalStatus = readGoalStatus(goalId);
|
|
1597
|
+
return toResult(exportHandoff(goalId, goalStatus));
|
|
1598
|
+
}
|
|
1599
|
+
case "check_release_gate": {
|
|
1600
|
+
return toResult(await checkReleaseGate({
|
|
1601
|
+
repo_path: String(args?.repo_path ?? ""),
|
|
1602
|
+
target_stage: String(args?.target_stage ?? "local_ready"),
|
|
1603
|
+
package_name: args?.package_name ? String(args.package_name) : undefined,
|
|
1604
|
+
version: args?.version ? String(args.version) : undefined,
|
|
1605
|
+
github_repo: args?.github_repo ? String(args.github_repo) : undefined,
|
|
1606
|
+
branch: args?.branch ? String(args.branch) : undefined,
|
|
1607
|
+
}));
|
|
1608
|
+
}
|
|
1609
|
+
case "release_check": {
|
|
1610
|
+
return toResult(await releaseCheck({
|
|
1611
|
+
repo_path: String(args?.repo_path ?? ""),
|
|
1612
|
+
target_stage: String(args?.target_stage ?? "local_ready"),
|
|
1613
|
+
package_name: args?.package_name ? String(args.package_name) : undefined,
|
|
1614
|
+
version: args?.version ? String(args.version) : undefined,
|
|
1615
|
+
github_repo: args?.github_repo ? String(args.github_repo) : undefined,
|
|
1616
|
+
branch: args?.branch ? String(args.branch) : undefined,
|
|
1617
|
+
}));
|
|
1618
|
+
}
|
|
1619
|
+
case "release_prepare": {
|
|
1620
|
+
return toResult(releasePrepare({
|
|
1621
|
+
repo_path: String(args?.repo_path ?? ""),
|
|
1622
|
+
required_commands: Array.isArray(args?.required_commands)
|
|
1623
|
+
? args.required_commands.map(String)
|
|
1624
|
+
: undefined,
|
|
1625
|
+
timeout_seconds: args?.timeout_seconds !== undefined ? Number(args.timeout_seconds) : undefined,
|
|
1626
|
+
}));
|
|
1627
|
+
}
|
|
1628
|
+
case "release_verify": {
|
|
1629
|
+
return toResult(await releaseVerify({
|
|
1630
|
+
repo_path: String(args?.repo_path ?? ""),
|
|
1631
|
+
package_name: args?.package_name ? String(args.package_name) : undefined,
|
|
1632
|
+
version: args?.version ? String(args.version) : undefined,
|
|
1633
|
+
github_repo: args?.github_repo ? String(args.github_repo) : undefined,
|
|
1634
|
+
branch: args?.branch ? String(args.branch) : undefined,
|
|
1635
|
+
}));
|
|
1636
|
+
}
|
|
1637
|
+
case "release_cleanup": {
|
|
1638
|
+
return toResult(releaseCleanup({
|
|
1639
|
+
repo_path: String(args?.repo_path ?? ""),
|
|
1640
|
+
dry_run: args?.dry_run !== undefined ? Boolean(args.dry_run) : undefined,
|
|
1641
|
+
patterns: Array.isArray(args?.patterns) ? args.patterns.map(String) : undefined,
|
|
1642
|
+
}));
|
|
1643
|
+
}
|
|
1644
|
+
case "merge_worktree": {
|
|
1645
|
+
return toResult(mergeWorktreeTool({
|
|
1646
|
+
worktree_id: String(args?.worktree_id ?? ""),
|
|
1647
|
+
repo_path: String(args?.repo_path ?? ""),
|
|
1648
|
+
}));
|
|
1649
|
+
}
|
|
1650
|
+
case "discard_worktree": {
|
|
1651
|
+
return toResult(discardWorktreeTool({
|
|
1652
|
+
worktree_id: String(args?.worktree_id ?? ""),
|
|
1653
|
+
repo_path: String(args?.repo_path ?? ""),
|
|
1654
|
+
}));
|
|
1655
|
+
}
|
|
732
1656
|
default:
|
|
733
1657
|
throw new Error(`Unknown tool: ${name}`);
|
|
734
1658
|
}
|