patchwarden 1.5.0 → 1.5.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/README.en.md +43 -2
- package/README.md +43 -2
- package/dist/assessments/agentAssessor.d.ts +1 -1
- package/dist/assessments/agentAssessor.js +3 -3
- package/dist/assessments/assessmentStore.d.ts +1 -1
- package/dist/assessments/assessmentStore.js +2 -2
- package/dist/assessments/confirmCli.js +5 -4
- package/dist/config.d.ts +7 -0
- package/dist/config.js +34 -0
- package/dist/control/middleware/auth.d.ts +10 -0
- package/dist/control/middleware/auth.js +8 -0
- package/dist/control/middleware/static.d.ts +3 -0
- package/dist/control/middleware/static.js +65 -0
- package/dist/control/routes/audit.d.ts +15 -0
- package/dist/control/routes/audit.js +277 -0
- package/dist/control/routes/evidence.d.ts +4 -0
- package/dist/control/routes/evidence.js +96 -0
- package/dist/control/routes/lineage.d.ts +3 -0
- package/dist/control/routes/lineage.js +71 -0
- package/dist/control/routes/policy.d.ts +3 -0
- package/dist/control/routes/policy.js +81 -0
- package/dist/control/routes/process.d.ts +5 -0
- package/dist/control/routes/process.js +200 -0
- package/dist/control/routes/sessions.d.ts +22 -0
- package/dist/control/routes/sessions.js +224 -0
- package/dist/control/routes/status.d.ts +6 -0
- package/dist/control/routes/status.js +250 -0
- package/dist/control/routes/taskActions.d.ts +21 -0
- package/dist/control/routes/taskActions.js +233 -0
- package/dist/control/routes/tasks.d.ts +20 -0
- package/dist/control/routes/tasks.js +310 -0
- package/dist/control/routes/workspace.d.ts +15 -0
- package/dist/control/routes/workspace.js +193 -0
- package/dist/control/runtime.d.ts +91 -0
- package/dist/control/runtime.js +392 -0
- package/dist/control/server.d.ts +13 -0
- package/dist/control/server.js +479 -0
- package/dist/control/shared.d.ts +35 -0
- package/dist/control/shared.js +288 -0
- package/dist/controlCenter.d.ts +6 -0
- package/dist/controlCenter.js +7 -2197
- package/dist/direct/directGuards.js +30 -8
- package/dist/doctor.d.ts +18 -1
- package/dist/doctor.js +579 -348
- package/dist/goal/goalReport.d.ts +54 -0
- package/dist/goal/goalReport.js +204 -0
- package/dist/goal/goalStatus.d.ts +6 -0
- package/dist/goal/specKitImport.d.ts +63 -0
- package/dist/goal/specKitImport.js +220 -0
- package/dist/goal/subgoalSync.js +2 -1
- package/dist/httpServer.js +15 -12
- package/dist/index.js +7 -4
- package/dist/logging.d.ts +7 -1
- package/dist/logging.js +8 -0
- package/dist/runner/changeCapture.d.ts +3 -3
- package/dist/runner/changeCapture.js +63 -39
- package/dist/runner/cli.js +7 -6
- package/dist/runner/postTaskCleanup.js +26 -2
- package/dist/runner/runTask.js +245 -221
- package/dist/runner/simpleProcess.js +4 -4
- package/dist/runner/watch.js +17 -14
- package/dist/security/contentRedaction.d.ts +6 -0
- package/dist/security/contentRedaction.js +22 -0
- package/dist/smoke-test.js +257 -251
- package/dist/test/unit/apply-patch.test.d.ts +1 -0
- package/dist/test/unit/apply-patch.test.js +225 -0
- package/dist/test/unit/create-task.test.d.ts +1 -0
- package/dist/test/unit/create-task.test.js +197 -0
- package/dist/test/unit/direct-guards.test.js +124 -9
- package/dist/test/unit/evidence-pack.test.js +95 -1
- package/dist/test/unit/get-task-status.test.d.ts +1 -0
- package/dist/test/unit/get-task-status.test.js +174 -0
- package/dist/test/unit/get-task-summary.test.d.ts +1 -0
- package/dist/test/unit/get-task-summary.test.js +146 -0
- package/dist/test/unit/goal-report.test.d.ts +1 -0
- package/dist/test/unit/goal-report.test.js +159 -0
- package/dist/test/unit/goal-subgoal-task.test.js +6 -6
- package/dist/test/unit/goal-tools-registry.test.js +6 -4
- package/dist/test/unit/path-guard.test.js +24 -0
- package/dist/test/unit/spec-kit-import.test.d.ts +1 -0
- package/dist/test/unit/spec-kit-import.test.js +341 -0
- package/dist/test/unit/wait-for-task.test.d.ts +1 -0
- package/dist/test/unit/wait-for-task.test.js +144 -0
- package/dist/tools/auditTask.d.ts +8 -63
- package/dist/tools/auditTask.js +12 -8
- package/dist/tools/createDirectSession.d.ts +1 -1
- package/dist/tools/createDirectSession.js +2 -2
- package/dist/tools/createTask.d.ts +2 -2
- package/dist/tools/createTask.js +4 -4
- package/dist/tools/dispatch/coreDispatch.d.ts +9 -0
- package/dist/tools/dispatch/coreDispatch.js +282 -0
- package/dist/tools/dispatch/diagnosticDispatch.d.ts +14 -0
- package/dist/tools/dispatch/diagnosticDispatch.js +78 -0
- package/dist/tools/dispatch/directDispatch.d.ts +8 -0
- package/dist/tools/dispatch/directDispatch.js +115 -0
- package/dist/tools/dispatch/goalDispatch.d.ts +8 -0
- package/dist/tools/dispatch/goalDispatch.js +91 -0
- package/dist/tools/dispatch/releaseDispatch.d.ts +8 -0
- package/dist/tools/dispatch/releaseDispatch.js +45 -0
- package/dist/tools/dispatch/types.d.ts +23 -0
- package/dist/tools/dispatch/types.js +15 -0
- package/dist/tools/evidencePack.d.ts +6 -0
- package/dist/tools/evidencePack.js +213 -6
- package/dist/tools/finalizeDirectSession.d.ts +1 -1
- package/dist/tools/finalizeDirectSession.js +3 -3
- package/dist/tools/goalSubgoalTask.d.ts +1 -1
- package/dist/tools/goalSubgoalTask.js +2 -2
- package/dist/tools/healthCheck.js +3 -3
- package/dist/tools/registry.d.ts +3 -3
- package/dist/tools/registry.js +60 -503
- package/dist/tools/retryTask.d.ts +2 -2
- package/dist/tools/retryTask.js +2 -2
- package/dist/tools/runTaskLoop.js +4 -4
- package/dist/tools/safeViews.d.ts +2 -2
- package/dist/tools/safeViews.js +2 -2
- package/dist/tools/toolRegistry.js +22 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/docs/CODE_WIKI.md +983 -0
- package/docs/agentseal-integration.md +150 -0
- package/docs/architecture.md +63 -0
- package/docs/assets/patchwarden-oss-demo.gif +0 -0
- package/docs/dashboard-overview.md +86 -0
- package/docs/demo.md +8 -0
- package/docs/direct-session-workflow.md +98 -0
- package/docs/evidence-pack-schema.md +215 -0
- package/docs/execution-plan-2026-07-09.md +315 -0
- package/docs/lineage-evidence-pack-workflow.md +127 -0
- package/docs/mcp-inspector-testing.md +200 -0
- package/docs/open-source-application.md +162 -0
- package/docs/opencode-worker.md +151 -0
- package/docs/openhands-worker.md +181 -0
- package/docs/release-evidence.md +72 -0
- package/docs/roadmap-execution-and-acceptance.md +365 -0
- package/docs/spec-kit-integration.md +131 -0
- package/docs/task-safe-review-workflow.md +98 -0
- package/docs/threat-model.md +79 -0
- package/docs/user-feedback.md +40 -0
- package/docs/why-patchwarden.md +110 -0
- package/package.json +2 -2
- package/scripts/checks/control-center-smoke.js +356 -0
- package/scripts/checks/lifecycle-smoke.js +29 -23
- package/scripts/checks/mcp-smoke.js +3 -1
- package/scripts/generate-demo-gif.py +320 -0
- package/src/assessments/agentAssessor.ts +3 -3
- package/src/assessments/assessmentStore.ts +2 -2
- package/src/assessments/confirmCli.ts +5 -4
- package/src/config.ts +37 -0
- package/src/control/middleware/auth.ts +17 -0
- package/src/control/middleware/static.ts +71 -0
- package/src/control/routes/audit.ts +321 -0
- package/src/control/routes/evidence.ts +107 -0
- package/src/control/routes/lineage.ts +92 -0
- package/src/control/routes/policy.ts +81 -0
- package/src/control/routes/process.ts +204 -0
- package/src/control/routes/sessions.ts +251 -0
- package/src/control/routes/status.ts +325 -0
- package/src/control/routes/taskActions.ts +248 -0
- package/src/control/routes/tasks.ts +323 -0
- package/src/control/routes/workspace.ts +203 -0
- package/src/control/runtime.ts +472 -0
- package/src/control/server.ts +471 -0
- package/src/control/shared.ts +294 -0
- package/src/controlCenter.ts +7 -2347
- package/src/direct/directGuards.ts +28 -7
- package/src/doctor.ts +741 -481
- package/src/goal/goalReport.ts +271 -0
- package/src/goal/goalStatus.ts +6 -0
- package/src/goal/specKitImport.ts +355 -0
- package/src/goal/subgoalSync.ts +4 -2
- package/src/httpServer.ts +17 -14
- package/src/index.ts +7 -4
- package/src/logging.ts +10 -1
- package/src/runner/changeCapture.ts +70 -42
- package/src/runner/cli.ts +7 -6
- package/src/runner/postTaskCleanup.ts +26 -2
- package/src/runner/runTask.ts +325 -223
- package/src/runner/simpleProcess.ts +4 -4
- package/src/runner/watch.ts +17 -14
- package/src/security/contentRedaction.ts +29 -0
- package/src/smoke-test.ts +252 -250
- package/src/test/unit/apply-patch.test.ts +293 -0
- package/src/test/unit/create-task.test.ts +255 -0
- package/src/test/unit/direct-guards.test.ts +178 -8
- package/src/test/unit/evidence-pack.test.ts +110 -1
- package/src/test/unit/get-task-status.test.ts +203 -0
- package/src/test/unit/get-task-summary.test.ts +173 -0
- package/src/test/unit/goal-report.test.ts +189 -0
- package/src/test/unit/goal-subgoal-task.test.ts +6 -6
- package/src/test/unit/goal-tools-registry.test.ts +7 -5
- package/src/test/unit/path-guard.test.ts +30 -0
- package/src/test/unit/spec-kit-import.test.ts +429 -0
- package/src/test/unit/wait-for-task.test.ts +176 -0
- package/src/tools/auditTask.ts +99 -59
- package/src/tools/createDirectSession.ts +3 -3
- package/src/tools/createTask.ts +7 -7
- package/src/tools/dispatch/coreDispatch.ts +374 -0
- package/src/tools/dispatch/diagnosticDispatch.ts +101 -0
- package/src/tools/dispatch/directDispatch.ts +167 -0
- package/src/tools/dispatch/goalDispatch.ts +127 -0
- package/src/tools/dispatch/releaseDispatch.ts +65 -0
- package/src/tools/dispatch/types.ts +24 -0
- package/src/tools/evidencePack.ts +291 -6
- package/src/tools/finalizeDirectSession.ts +4 -4
- package/src/tools/goalSubgoalTask.ts +2 -2
- package/src/tools/healthCheck.ts +3 -3
- package/src/tools/registry.ts +68 -628
- package/src/tools/retryTask.ts +2 -2
- package/src/tools/runTaskLoop.ts +4 -4
- package/src/tools/safeViews.ts +2 -2
- package/src/tools/toolRegistry.ts +22 -0
- package/src/version.ts +1 -1
- package/ui/pages/audit.html +192 -3
- package/ui/pages/dashboard.html +959 -44
- package/ui/pages/direct-sessions.html +505 -53
- package/ui/pages/task-detail.html +456 -438
- package/ui/pages/tasks.html +598 -61
package/dist/tools/auditTask.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @ts-nocheck
|
|
2
1
|
import { readFileSync, existsSync, writeFileSync, readdirSync, statSync } from "node:fs";
|
|
3
2
|
import { join, resolve, relative, basename, sep, isAbsolute } from "node:path";
|
|
4
3
|
import { getTasksDir, getConfig } from "../config.js";
|
|
@@ -288,9 +287,10 @@ function readPackageScripts(repoPath) {
|
|
|
288
287
|
try {
|
|
289
288
|
guardSensitivePath(pkgJsonPath);
|
|
290
289
|
const parsed = JSON.parse(readFileSync(pkgJsonPath, "utf-8"));
|
|
291
|
-
|
|
290
|
+
const scripts = parsed.scripts;
|
|
291
|
+
if (!scripts || typeof scripts !== "object" || Array.isArray(scripts))
|
|
292
292
|
return {};
|
|
293
|
-
return Object.fromEntries(Object.entries(
|
|
293
|
+
return Object.fromEntries(Object.entries(scripts).filter(([, value]) => typeof value === "string"));
|
|
294
294
|
}
|
|
295
295
|
catch {
|
|
296
296
|
return {};
|
|
@@ -370,8 +370,8 @@ function findHighRiskCommandEvidence(text) {
|
|
|
370
370
|
return [...new Set(found)];
|
|
371
371
|
}
|
|
372
372
|
export function checkUnrecordedCommandExecution(testLogContent, resultMdContent, verifyCommands, testCommand, repoPath = null) {
|
|
373
|
-
const hasLog = testLogContent && testLogContent.length > 0;
|
|
374
|
-
const hasResult = resultMdContent && resultMdContent.length > 0;
|
|
373
|
+
const hasLog = !!testLogContent && testLogContent.length > 0;
|
|
374
|
+
const hasResult = !!resultMdContent && resultMdContent.length > 0;
|
|
375
375
|
if (!hasLog && !hasResult)
|
|
376
376
|
return null;
|
|
377
377
|
const combined = `${testLogContent || ""}\n${resultMdContent || ""}`;
|
|
@@ -381,9 +381,9 @@ export function checkUnrecordedCommandExecution(testLogContent, resultMdContent,
|
|
|
381
381
|
}
|
|
382
382
|
const whitelist = buildCommandWhitelist(verifyCommands, testCommand, repoPath);
|
|
383
383
|
const discovered = [];
|
|
384
|
-
if (hasLog)
|
|
384
|
+
if (hasLog && testLogContent)
|
|
385
385
|
discovered.push(...extractCommands(testLogContent));
|
|
386
|
-
if (hasResult)
|
|
386
|
+
if (hasResult && resultMdContent)
|
|
387
387
|
discovered.push(...extractCommands(resultMdContent));
|
|
388
388
|
const unrecorded = new Set();
|
|
389
389
|
for (const cmd of discovered) {
|
|
@@ -804,7 +804,11 @@ export function auditTask(taskId) {
|
|
|
804
804
|
return null;
|
|
805
805
|
try {
|
|
806
806
|
const v = JSON.parse(readFileSync(verifyJsonFile, "utf-8"));
|
|
807
|
-
|
|
807
|
+
if (v.status === "passed")
|
|
808
|
+
return "passed";
|
|
809
|
+
if (v.status === "failed")
|
|
810
|
+
return "failed";
|
|
811
|
+
return "skipped";
|
|
808
812
|
}
|
|
809
813
|
catch {
|
|
810
814
|
return null;
|
|
@@ -11,4 +11,4 @@ export interface CreateDirectSessionOutput {
|
|
|
11
11
|
expires_at: string;
|
|
12
12
|
next_action: string;
|
|
13
13
|
}
|
|
14
|
-
export declare function createDirectSession(input: CreateDirectSessionInput): CreateDirectSessionOutput
|
|
14
|
+
export declare function createDirectSession(input: CreateDirectSessionInput): Promise<CreateDirectSessionOutput>;
|
|
@@ -6,7 +6,7 @@ import { guardRuntimeSelfModification } from "../security/runtimeGuard.js";
|
|
|
6
6
|
import { captureRepoSnapshot } from "../runner/changeCapture.js";
|
|
7
7
|
import { createDirectSession as createDirectSessionRecord, } from "../direct/directSessionStore.js";
|
|
8
8
|
// ── Tool implementation ────────────────────────────────────────────
|
|
9
|
-
export function createDirectSession(input) {
|
|
9
|
+
export async function createDirectSession(input) {
|
|
10
10
|
const config = getConfig();
|
|
11
11
|
// ── Validate repo_path ───────────────────────────────────────────
|
|
12
12
|
if (!input.repo_path || input.repo_path.trim() === "") {
|
|
@@ -33,7 +33,7 @@ export function createDirectSession(input) {
|
|
|
33
33
|
// ── Runtime self-modification protection ─────────────────────────
|
|
34
34
|
guardRuntimeSelfModification(resolvedRepoPath);
|
|
35
35
|
// ── Capture repo snapshot ────────────────────────────────────────
|
|
36
|
-
const snapshot = captureRepoSnapshot(resolvedRepoPath);
|
|
36
|
+
const snapshot = await captureRepoSnapshot(resolvedRepoPath);
|
|
37
37
|
// ── Create session record ────────────────────────────────────────
|
|
38
38
|
const session = createDirectSessionRecord({
|
|
39
39
|
repo_path: input.repo_path,
|
|
@@ -101,5 +101,5 @@ export interface CreateTaskOutput {
|
|
|
101
101
|
}
|
|
102
102
|
export declare function createTask(input: CreateTaskInput & {
|
|
103
103
|
execution_mode: "assess_only";
|
|
104
|
-
}): AssessOnlyOutput
|
|
105
|
-
export declare function createTask(input: CreateTaskInput): CreateTaskOutput
|
|
104
|
+
}): Promise<AssessOnlyOutput>;
|
|
105
|
+
export declare function createTask(input: CreateTaskInput): Promise<CreateTaskOutput>;
|
package/dist/tools/createTask.js
CHANGED
|
@@ -18,7 +18,7 @@ import { PATCHWARDEN_VERSION } from "../version.js";
|
|
|
18
18
|
import { getLastToolCatalogSnapshot, resolveToolProfile } from "./toolCatalog.js";
|
|
19
19
|
import { derivePendingReason, readWatcherStatus, } from "../watcherStatus.js";
|
|
20
20
|
import { routeAgent } from "../agents/agentRouter.js";
|
|
21
|
-
export function createTask(input) {
|
|
21
|
+
export async function createTask(input) {
|
|
22
22
|
const config = getConfig();
|
|
23
23
|
const tasksDir = getTasksDir(config);
|
|
24
24
|
const plansDir = getPlansDir(config);
|
|
@@ -151,7 +151,7 @@ export function createTask(input) {
|
|
|
151
151
|
planBlocked = true;
|
|
152
152
|
planBlockReason = e instanceof PatchWardenError ? e.reason : "plan_content_blocked";
|
|
153
153
|
}
|
|
154
|
-
const snapshot = captureRepoSnapshot(safeRepoPath);
|
|
154
|
+
const snapshot = await captureRepoSnapshot(safeRepoPath);
|
|
155
155
|
const snapshotTruncated = snapshot.warnings.some((w) => w.includes("snapshot limited"));
|
|
156
156
|
let riskResult;
|
|
157
157
|
if (planBlocked) {
|
|
@@ -208,7 +208,7 @@ export function createTask(input) {
|
|
|
208
208
|
preGeneratedAssessmentId = generateAssessmentId();
|
|
209
209
|
preGeneratedAssessmentDir = createAssessmentDir(preGeneratedAssessmentId);
|
|
210
210
|
const assessorAgentName = config.agentAssessmentAgentName || effectiveInput.agent;
|
|
211
|
-
agentAssessmentSummary = runAgentAssessment({
|
|
211
|
+
agentAssessmentSummary = await runAgentAssessment({
|
|
212
212
|
assessmentId: preGeneratedAssessmentId,
|
|
213
213
|
assessmentDir: preGeneratedAssessmentDir,
|
|
214
214
|
agentName: assessorAgentName,
|
|
@@ -330,7 +330,7 @@ export function createTask(input) {
|
|
|
330
330
|
}
|
|
331
331
|
// ── execute mode with assessment_id: validate freshness ──
|
|
332
332
|
if (assessmentRecord) {
|
|
333
|
-
const snapshot = captureRepoSnapshot(safeRepoPath);
|
|
333
|
+
const snapshot = await captureRepoSnapshot(safeRepoPath);
|
|
334
334
|
const validation = validateAssessmentFreshness(input.assessment_id, snapshot);
|
|
335
335
|
if (!validation.valid) {
|
|
336
336
|
throw new PatchWardenError(validation.failure_reason || "assessment_validation_failed", `Assessment "${input.assessment_id}" is no longer valid: ${validation.failure_reason}`, "Re-run create_task with execution_mode=assess_only to get a fresh assessment_id.", true, { assessment_id: input.assessment_id, failure_reason: validation.failure_reason });
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dispatch handlers for core task-management tools.
|
|
3
|
+
*
|
|
4
|
+
* Each handler directly calls the existing tool function — no logic is
|
|
5
|
+
* rewritten. Extracted from the original handleToolCallInternal switch.
|
|
6
|
+
*/
|
|
7
|
+
import type { ToolHandlerMap } from "./types.js";
|
|
8
|
+
export declare const coreHandlers: ToolHandlerMap;
|
|
9
|
+
export declare const runTaskHandler: ToolHandlerMap["run_task"];
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dispatch handlers for core task-management tools.
|
|
3
|
+
*
|
|
4
|
+
* Each handler directly calls the existing tool function — no logic is
|
|
5
|
+
* rewritten. Extracted from the original handleToolCallInternal switch.
|
|
6
|
+
*/
|
|
7
|
+
import { savePlan } from "../savePlan.js";
|
|
8
|
+
import { getPlan } from "../getPlan.js";
|
|
9
|
+
import { createTask } from "../createTask.js";
|
|
10
|
+
import { getTaskStatus } from "../getTaskStatus.js";
|
|
11
|
+
import { getResult, getResultJson, getDiff, getTestLog, getTaskLogTail } from "../taskOutputs.js";
|
|
12
|
+
import { listWorkspace } from "../listWorkspace.js";
|
|
13
|
+
import { readWorkspaceFile } from "../readWorkspaceFile.js";
|
|
14
|
+
import { listTasks } from "../listTasks.js";
|
|
15
|
+
import { cancelTask } from "../cancelTask.js";
|
|
16
|
+
import { killTask } from "../killTask.js";
|
|
17
|
+
import { retryTask } from "../retryTask.js";
|
|
18
|
+
import { getTaskStdoutTail } from "../getTaskStdoutTail.js";
|
|
19
|
+
import { getTaskProgress } from "../getTaskProgress.js";
|
|
20
|
+
import { listAgents } from "../listAgents.js";
|
|
21
|
+
import { healthCheck } from "../healthCheck.js";
|
|
22
|
+
import { getTaskSummary } from "../getTaskSummary.js";
|
|
23
|
+
import { waitForTask } from "../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";
|
|
28
|
+
import { auditTask } from "../auditTask.js";
|
|
29
|
+
import { safeStatus } from "../safeStatus.js";
|
|
30
|
+
import { safeAudit, safeDiffSummary, safeResult, safeTestSummary } from "../safeViews.js";
|
|
31
|
+
import { diagnoseTask } from "../diagnoseTask.js";
|
|
32
|
+
import { reconcileTasks } from "../reconcileTasks.js";
|
|
33
|
+
import { checkReleaseGate } from "../checkReleaseGate.js";
|
|
34
|
+
import { getProjectPolicyTool } from "../releaseMode.js";
|
|
35
|
+
import { runTask } from "../../runner/runTask.js";
|
|
36
|
+
import { getConfig } from "../../config.js";
|
|
37
|
+
import { getToolCatalogSnapshot } from "../registry.js";
|
|
38
|
+
import { toResult } from "./types.js";
|
|
39
|
+
// ── Local helpers (moved verbatim from registry.ts) ───────────────
|
|
40
|
+
function normalizeWaitSeconds(args) {
|
|
41
|
+
const legacy = args?.wait_seconds;
|
|
42
|
+
const preferred = args?.timeout_seconds;
|
|
43
|
+
if (legacy !== undefined && preferred !== undefined && Number(legacy) !== Number(preferred)) {
|
|
44
|
+
throw new Error("wait_seconds and timeout_seconds must match when both are supplied.");
|
|
45
|
+
}
|
|
46
|
+
const value = preferred ?? legacy;
|
|
47
|
+
return value === undefined ? undefined : Number(value);
|
|
48
|
+
}
|
|
49
|
+
function normalizeSummaryView(value) {
|
|
50
|
+
if (value === undefined)
|
|
51
|
+
return "standard";
|
|
52
|
+
if (value !== "compact" && value !== "standard") {
|
|
53
|
+
throw new Error('view must be "compact" or "standard".');
|
|
54
|
+
}
|
|
55
|
+
return value;
|
|
56
|
+
}
|
|
57
|
+
// ── Handler map ───────────────────────────────────────────────────
|
|
58
|
+
export const coreHandlers = {
|
|
59
|
+
save_plan: async (args) => {
|
|
60
|
+
return toResult(savePlan({
|
|
61
|
+
title: String(args?.title ?? ""),
|
|
62
|
+
content: args?.content !== undefined ? String(args.content) : "",
|
|
63
|
+
plan_ref: args?.plan_ref ? String(args.plan_ref) : undefined,
|
|
64
|
+
}));
|
|
65
|
+
},
|
|
66
|
+
get_plan: async (args) => {
|
|
67
|
+
return toResult(getPlan({ plan_id: String(args?.plan_id ?? "") }));
|
|
68
|
+
},
|
|
69
|
+
create_task: async (args) => {
|
|
70
|
+
return toResult(await createTask({
|
|
71
|
+
plan_id: args?.plan_id ? String(args.plan_id) : undefined,
|
|
72
|
+
inline_plan: args?.inline_plan ? String(args.inline_plan) : undefined,
|
|
73
|
+
plan_title: args?.plan_title ? String(args.plan_title) : undefined,
|
|
74
|
+
template: args?.template ? String(args.template) : undefined,
|
|
75
|
+
goal: args?.goal ? String(args.goal) : undefined,
|
|
76
|
+
source_task_id: args?.source_task_id ? String(args.source_task_id) : undefined,
|
|
77
|
+
agent: String(args?.agent ?? ""),
|
|
78
|
+
repo_path: args?.repo_path ? String(args.repo_path) : undefined,
|
|
79
|
+
test_command: args?.test_command ? String(args.test_command) : undefined,
|
|
80
|
+
verify_commands: Array.isArray(args?.verify_commands)
|
|
81
|
+
? args.verify_commands.map((command) => String(command))
|
|
82
|
+
: undefined,
|
|
83
|
+
timeout_seconds: args?.timeout_seconds !== undefined ? Number(args.timeout_seconds) : undefined,
|
|
84
|
+
execution_mode: args?.execution_mode === "assess_only" ? "assess_only" : "execute",
|
|
85
|
+
assessment_id: args?.assessment_id ? String(args.assessment_id) : undefined,
|
|
86
|
+
}));
|
|
87
|
+
},
|
|
88
|
+
run_task_loop: async (args) => {
|
|
89
|
+
return toResult(await runTaskLoop({
|
|
90
|
+
repo_path: String(args?.repo_path ?? ""),
|
|
91
|
+
goal: String(args?.goal ?? ""),
|
|
92
|
+
verify_commands: Array.isArray(args?.verify_commands)
|
|
93
|
+
? args.verify_commands.map((command) => String(command))
|
|
94
|
+
: [],
|
|
95
|
+
agent: args?.agent ? String(args.agent) : undefined,
|
|
96
|
+
template: args?.template === "inspect_only" || args?.template === "release_check"
|
|
97
|
+
? args.template
|
|
98
|
+
: "feature_small",
|
|
99
|
+
max_iterations: args?.max_iterations !== undefined ? Number(args.max_iterations) : undefined,
|
|
100
|
+
task_timeout_seconds: args?.task_timeout_seconds !== undefined ? Number(args.task_timeout_seconds) : undefined,
|
|
101
|
+
auto_fix_tests: args?.auto_fix_tests !== undefined ? Boolean(args.auto_fix_tests) : undefined,
|
|
102
|
+
auto_cleanup_artifacts: args?.auto_cleanup_artifacts !== undefined
|
|
103
|
+
? Boolean(args.auto_cleanup_artifacts)
|
|
104
|
+
: undefined,
|
|
105
|
+
stop_on_high_risk: args?.stop_on_high_risk !== undefined ? Boolean(args.stop_on_high_risk) : undefined,
|
|
106
|
+
direct_verify: args?.direct_verify !== undefined ? Boolean(args.direct_verify) : undefined,
|
|
107
|
+
direct_verify_commands: Array.isArray(args?.direct_verify_commands)
|
|
108
|
+
? args.direct_verify_commands.map((command) => String(command))
|
|
109
|
+
: undefined,
|
|
110
|
+
direct_verify_timeout_seconds: args?.direct_verify_timeout_seconds !== undefined
|
|
111
|
+
? Number(args.direct_verify_timeout_seconds)
|
|
112
|
+
: undefined,
|
|
113
|
+
scope_files: Array.isArray(args?.scope_files)
|
|
114
|
+
? args.scope_files.map((entry) => String(entry))
|
|
115
|
+
: undefined,
|
|
116
|
+
isolation_mode: args?.isolation_mode === "worktree" ? "worktree" : "current_repo",
|
|
117
|
+
worktree_base_branch: args?.worktree_base_branch
|
|
118
|
+
? String(args.worktree_base_branch)
|
|
119
|
+
: undefined,
|
|
120
|
+
worktree_cleanup: args?.worktree_cleanup === "archive" || args?.worktree_cleanup === "delete_ignored_only"
|
|
121
|
+
? args.worktree_cleanup
|
|
122
|
+
: "keep",
|
|
123
|
+
}));
|
|
124
|
+
},
|
|
125
|
+
recommend_agent_for_task: async (args) => {
|
|
126
|
+
return toResult(recommendAgentForTask({
|
|
127
|
+
repo_path: String(args?.repo_path ?? ""),
|
|
128
|
+
goal: String(args?.goal ?? ""),
|
|
129
|
+
scope_files: Array.isArray(args?.scope_files)
|
|
130
|
+
? args.scope_files.map((entry) => String(entry))
|
|
131
|
+
: undefined,
|
|
132
|
+
template: args?.template ? String(args.template) : undefined,
|
|
133
|
+
risk_hint: args?.risk_hint ? String(args.risk_hint) : undefined,
|
|
134
|
+
}));
|
|
135
|
+
},
|
|
136
|
+
get_task_lineage: async (args) => {
|
|
137
|
+
return toResult(getTaskLineage(String(args?.lineage_id ?? ""), {
|
|
138
|
+
max_items: args?.max_items !== undefined ? Number(args.max_items) : undefined,
|
|
139
|
+
}));
|
|
140
|
+
},
|
|
141
|
+
export_task_evidence_pack: async (args) => {
|
|
142
|
+
return toResult(exportTaskEvidencePack({
|
|
143
|
+
lineage_id: String(args?.lineage_id ?? ""),
|
|
144
|
+
max_items: args?.max_items !== undefined ? Number(args.max_items) : undefined,
|
|
145
|
+
}));
|
|
146
|
+
},
|
|
147
|
+
get_project_policy: async (args) => {
|
|
148
|
+
return toResult(getProjectPolicyTool(String(args?.repo_path ?? "")));
|
|
149
|
+
},
|
|
150
|
+
get_task_status: async (args) => {
|
|
151
|
+
return toResult(getTaskStatus(String(args?.task_id ?? "")));
|
|
152
|
+
},
|
|
153
|
+
get_result: async (args) => {
|
|
154
|
+
return toResult(getResult(String(args?.task_id ?? "")));
|
|
155
|
+
},
|
|
156
|
+
get_result_json: async (args) => {
|
|
157
|
+
return toResult(getResultJson(String(args?.task_id ?? "")));
|
|
158
|
+
},
|
|
159
|
+
get_diff: async (args) => {
|
|
160
|
+
return toResult(getDiff(String(args?.task_id ?? "")));
|
|
161
|
+
},
|
|
162
|
+
get_test_log: async (args) => {
|
|
163
|
+
return toResult(getTestLog(String(args?.task_id ?? "")));
|
|
164
|
+
},
|
|
165
|
+
list_workspace: async (args) => {
|
|
166
|
+
return toResult(listWorkspace(args?.path ? String(args.path) : undefined));
|
|
167
|
+
},
|
|
168
|
+
read_workspace_file: async (args) => {
|
|
169
|
+
const sessionId = args?.session_id ? String(args.session_id) : undefined;
|
|
170
|
+
return toResult(readWorkspaceFile({
|
|
171
|
+
path: String(args?.path ?? ""),
|
|
172
|
+
session_id: sessionId,
|
|
173
|
+
}));
|
|
174
|
+
},
|
|
175
|
+
list_tasks: async (args) => {
|
|
176
|
+
return toResult(listTasks({
|
|
177
|
+
status: args?.status ? String(args.status) : undefined,
|
|
178
|
+
repo_path: args?.repo_path ? String(args.repo_path) : undefined,
|
|
179
|
+
active_only: args?.active_only !== undefined ? Boolean(args.active_only) : undefined,
|
|
180
|
+
limit: args?.limit ? Number(args.limit) : undefined,
|
|
181
|
+
}));
|
|
182
|
+
},
|
|
183
|
+
list_agents: async () => {
|
|
184
|
+
return toResult(listAgents());
|
|
185
|
+
},
|
|
186
|
+
health_check: async (args) => {
|
|
187
|
+
return toResult(healthCheck(getToolCatalogSnapshot(), {
|
|
188
|
+
detail: args?.detail === "self_diagnostic" ? "self_diagnostic" : "standard",
|
|
189
|
+
}));
|
|
190
|
+
},
|
|
191
|
+
cancel_task: async (args) => {
|
|
192
|
+
return toResult(cancelTask(String(args?.task_id ?? "")));
|
|
193
|
+
},
|
|
194
|
+
kill_task: async (args) => {
|
|
195
|
+
return toResult(killTask(String(args?.task_id ?? "")));
|
|
196
|
+
},
|
|
197
|
+
retry_task: async (args) => {
|
|
198
|
+
return toResult(await retryTask(String(args?.task_id ?? "")));
|
|
199
|
+
},
|
|
200
|
+
get_task_stdout_tail: async (args) => {
|
|
201
|
+
return toResult(getTaskStdoutTail(String(args?.task_id ?? ""), args?.lines ? Number(args.lines) : undefined));
|
|
202
|
+
},
|
|
203
|
+
get_task_log_tail: async (args) => {
|
|
204
|
+
return toResult(getTaskLogTail(String(args?.task_id ?? ""), args?.file || "stdout", {
|
|
205
|
+
lines: args?.lines ? Number(args.lines) : undefined,
|
|
206
|
+
redact: args?.redact !== undefined ? Boolean(args.redact) : undefined,
|
|
207
|
+
}));
|
|
208
|
+
},
|
|
209
|
+
get_task_progress: async (args) => {
|
|
210
|
+
return toResult(getTaskProgress(String(args?.task_id ?? "")));
|
|
211
|
+
},
|
|
212
|
+
wait_for_task: async (args) => {
|
|
213
|
+
const waitSeconds = normalizeWaitSeconds(args);
|
|
214
|
+
return toResult(await waitForTask(String(args?.task_id ?? ""), waitSeconds));
|
|
215
|
+
},
|
|
216
|
+
get_task_summary: async (args) => {
|
|
217
|
+
return toResult(getTaskSummary(String(args?.task_id ?? ""), {
|
|
218
|
+
view: normalizeSummaryView(args?.view),
|
|
219
|
+
max_items: args?.max_items !== undefined ? Number(args.max_items) : undefined,
|
|
220
|
+
}));
|
|
221
|
+
},
|
|
222
|
+
audit_task: async (args) => {
|
|
223
|
+
return toResult(auditTask(String(args?.task_id ?? "")));
|
|
224
|
+
},
|
|
225
|
+
safe_status: async (args) => {
|
|
226
|
+
return toResult(safeStatus(String(args?.task_id ?? "")));
|
|
227
|
+
},
|
|
228
|
+
safe_result: async (args) => {
|
|
229
|
+
return toResult(safeResult(String(args?.task_id ?? ""), {
|
|
230
|
+
max_items: args?.max_items !== undefined ? Number(args.max_items) : undefined,
|
|
231
|
+
}));
|
|
232
|
+
},
|
|
233
|
+
safe_audit: async (args) => {
|
|
234
|
+
return toResult(safeAudit(String(args?.task_id ?? ""), {
|
|
235
|
+
max_items: args?.max_items !== undefined ? Number(args.max_items) : undefined,
|
|
236
|
+
}));
|
|
237
|
+
},
|
|
238
|
+
safe_test_summary: async (args) => {
|
|
239
|
+
return toResult(safeTestSummary(String(args?.task_id ?? "")));
|
|
240
|
+
},
|
|
241
|
+
safe_diff_summary: async (args) => {
|
|
242
|
+
return toResult(safeDiffSummary(String(args?.task_id ?? ""), {
|
|
243
|
+
max_items: args?.max_items !== undefined ? Number(args.max_items) : undefined,
|
|
244
|
+
}));
|
|
245
|
+
},
|
|
246
|
+
diagnose_task: async (args) => {
|
|
247
|
+
return toResult(diagnoseTask({
|
|
248
|
+
task_id: String(args?.task_id ?? ""),
|
|
249
|
+
include_logs: args?.include_logs !== undefined ? Boolean(args.include_logs) : undefined,
|
|
250
|
+
}));
|
|
251
|
+
},
|
|
252
|
+
reconcile_tasks: async (args) => {
|
|
253
|
+
return toResult(reconcileTasks({
|
|
254
|
+
mode: args?.mode === "safe_fix" ? "safe_fix" : "report_only",
|
|
255
|
+
max_age_minutes: args?.max_age_minutes !== undefined ? Number(args.max_age_minutes) : undefined,
|
|
256
|
+
include_done_candidates: args?.include_done_candidates !== undefined
|
|
257
|
+
? Boolean(args.include_done_candidates)
|
|
258
|
+
: undefined,
|
|
259
|
+
}));
|
|
260
|
+
},
|
|
261
|
+
check_release_gate: async (args) => {
|
|
262
|
+
return toResult(await checkReleaseGate({
|
|
263
|
+
repo_path: String(args?.repo_path ?? ""),
|
|
264
|
+
target_stage: String(args?.target_stage ?? "local_ready"),
|
|
265
|
+
package_name: args?.package_name ? String(args.package_name) : undefined,
|
|
266
|
+
version: args?.version ? String(args.version) : undefined,
|
|
267
|
+
github_repo: args?.github_repo ? String(args.github_repo) : undefined,
|
|
268
|
+
branch: args?.branch ? String(args.branch) : undefined,
|
|
269
|
+
}));
|
|
270
|
+
},
|
|
271
|
+
};
|
|
272
|
+
// run_task is conditionally registered (only when enableRunTaskTool === true).
|
|
273
|
+
// Exported separately so registry.ts can add it conditionally to the dispatch map.
|
|
274
|
+
export const runTaskHandler = async (args) => {
|
|
275
|
+
const config = getConfig();
|
|
276
|
+
if (config.enableRunTaskTool !== true) {
|
|
277
|
+
throw new Error("run_task is disabled. Set enableRunTaskTool: true in config to enable. Prefer using the local watcher (npm run watch).");
|
|
278
|
+
}
|
|
279
|
+
const taskId = String(args?.task_id ?? "");
|
|
280
|
+
const result = await runTask(taskId);
|
|
281
|
+
return toResult(result);
|
|
282
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dispatch handlers for diagnostic / discovery tools (v0.7.1+).
|
|
3
|
+
*
|
|
4
|
+
* discover_tools and explain_tool are read-only catalog queries.
|
|
5
|
+
* invoke_discovered_tool consumes a discovery token and dispatches to
|
|
6
|
+
* the target tool via handleToolCall.
|
|
7
|
+
*
|
|
8
|
+
* Note: This module imports getToolDefs and handleToolCall from
|
|
9
|
+
* registry.ts. The import is a live ESM binding resolved at runtime,
|
|
10
|
+
* so the circular dependency (registry → diagnosticDispatch → registry)
|
|
11
|
+
* is safe: neither binding is touched during module evaluation.
|
|
12
|
+
*/
|
|
13
|
+
import type { ToolHandlerMap } from "./types.js";
|
|
14
|
+
export declare const diagnosticHandlers: ToolHandlerMap;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dispatch handlers for diagnostic / discovery tools (v0.7.1+).
|
|
3
|
+
*
|
|
4
|
+
* discover_tools and explain_tool are read-only catalog queries.
|
|
5
|
+
* invoke_discovered_tool consumes a discovery token and dispatches to
|
|
6
|
+
* the target tool via handleToolCall.
|
|
7
|
+
*
|
|
8
|
+
* Note: This module imports getToolDefs and handleToolCall from
|
|
9
|
+
* registry.ts. The import is a live ESM binding resolved at runtime,
|
|
10
|
+
* so the circular dependency (registry → diagnosticDispatch → registry)
|
|
11
|
+
* is safe: neither binding is touched during module evaluation.
|
|
12
|
+
*/
|
|
13
|
+
import { discoverTools } from "../discoverTools.js";
|
|
14
|
+
import { explainTool } from "../explainTool.js";
|
|
15
|
+
import { invokeDiscoveredTool } from "../invokeDiscoveredTool.js";
|
|
16
|
+
import { getConfig } from "../../config.js";
|
|
17
|
+
import { resolveToolProfile } from "../toolCatalog.js";
|
|
18
|
+
import { getToolDefs, handleToolCall } from "../registry.js";
|
|
19
|
+
import { toResult } from "./types.js";
|
|
20
|
+
export const diagnosticHandlers = {
|
|
21
|
+
discover_tools: async (args) => {
|
|
22
|
+
const profile = args?.profile === "full" ||
|
|
23
|
+
args?.profile === "chatgpt_core" ||
|
|
24
|
+
args?.profile === "chatgpt_direct" ||
|
|
25
|
+
args?.profile === "chatgpt_search"
|
|
26
|
+
? args.profile
|
|
27
|
+
: undefined;
|
|
28
|
+
const mode = args?.mode === "delegate" ||
|
|
29
|
+
args?.mode === "direct" ||
|
|
30
|
+
args?.mode === "audit" ||
|
|
31
|
+
args?.mode === "release" ||
|
|
32
|
+
args?.mode === "diagnostic"
|
|
33
|
+
? args.mode
|
|
34
|
+
: undefined;
|
|
35
|
+
const riskCeiling = [
|
|
36
|
+
"readonly",
|
|
37
|
+
"workspace_read_sensitive",
|
|
38
|
+
"workspace_write",
|
|
39
|
+
"command",
|
|
40
|
+
"release",
|
|
41
|
+
"credential_sensitive",
|
|
42
|
+
].includes(String(args?.riskCeiling ?? ""))
|
|
43
|
+
? String(args?.riskCeiling)
|
|
44
|
+
: undefined;
|
|
45
|
+
return toResult(discoverTools({
|
|
46
|
+
query: String(args?.query ?? ""),
|
|
47
|
+
profile,
|
|
48
|
+
mode,
|
|
49
|
+
maxResults: args?.maxResults !== undefined ? Number(args.maxResults) : undefined,
|
|
50
|
+
riskCeiling,
|
|
51
|
+
includeHighRisk: args?.includeHighRisk !== undefined ? Boolean(args.includeHighRisk) : undefined,
|
|
52
|
+
}, getToolDefs()));
|
|
53
|
+
},
|
|
54
|
+
explain_tool: async (args) => {
|
|
55
|
+
return toResult(explainTool({
|
|
56
|
+
name: String(args?.name ?? ""),
|
|
57
|
+
includeSchema: args?.includeSchema !== undefined ? Boolean(args.includeSchema) : undefined,
|
|
58
|
+
}, getToolDefs()));
|
|
59
|
+
},
|
|
60
|
+
invoke_discovered_tool: async (args) => {
|
|
61
|
+
const profile = resolveToolProfile(getConfig().toolProfile);
|
|
62
|
+
const result = await invokeDiscoveredTool({
|
|
63
|
+
toolName: String(args?.toolName ?? ""),
|
|
64
|
+
arguments: args?.arguments && typeof args.arguments === "object"
|
|
65
|
+
? args.arguments
|
|
66
|
+
: {},
|
|
67
|
+
discoveryToken: String(args?.discoveryToken ?? ""),
|
|
68
|
+
assessmentId: args?.assessmentId ? String(args.assessmentId) : undefined,
|
|
69
|
+
}, {
|
|
70
|
+
tools: getToolDefs(),
|
|
71
|
+
profile,
|
|
72
|
+
dispatch: async (name, dispatchArgs) => {
|
|
73
|
+
return handleToolCall(name, dispatchArgs);
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
return toResult(result);
|
|
77
|
+
},
|
|
78
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dispatch handlers for Direct session tools.
|
|
3
|
+
*
|
|
4
|
+
* Direct sessions allow ChatGPT to apply patches directly within a
|
|
5
|
+
* repo-scoped workspace. All handlers guard on enableDirectProfile.
|
|
6
|
+
*/
|
|
7
|
+
import type { ToolHandlerMap } from "./types.js";
|
|
8
|
+
export declare const directHandlers: ToolHandlerMap;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dispatch handlers for Direct session tools.
|
|
3
|
+
*
|
|
4
|
+
* Direct sessions allow ChatGPT to apply patches directly within a
|
|
5
|
+
* repo-scoped workspace. All handlers guard on enableDirectProfile.
|
|
6
|
+
*/
|
|
7
|
+
import { getConfig } from "../../config.js";
|
|
8
|
+
import { PatchWardenError } from "../../errors.js";
|
|
9
|
+
import { createDirectSession } from "../createDirectSession.js";
|
|
10
|
+
import { searchWorkspace } from "../searchWorkspace.js";
|
|
11
|
+
import { applyPatch } from "../applyPatch.js";
|
|
12
|
+
import { runVerification } from "../runVerification.js";
|
|
13
|
+
import { runDirectVerificationBundle } from "../runDirectVerificationBundle.js";
|
|
14
|
+
import { finalizeDirectSession } from "../finalizeDirectSession.js";
|
|
15
|
+
import { auditSession } from "../auditSession.js";
|
|
16
|
+
import { syncFile } from "../syncFile.js";
|
|
17
|
+
import { safeAuditDirectSession, safeDirectSummary, safeFinalizeDirectSession, } from "../safeViews.js";
|
|
18
|
+
import { toResult } from "./types.js";
|
|
19
|
+
/** Mirror of guardDirectProfileEnabled from the original registry.ts. */
|
|
20
|
+
function guardDirectProfileEnabled() {
|
|
21
|
+
const config = getConfig();
|
|
22
|
+
if (!config.enableDirectProfile) {
|
|
23
|
+
throw new PatchWardenError("direct_profile_disabled", "Direct profile is disabled by local config.", "Set enableDirectProfile: true in patchwarden.config.json to use Direct session tools.", true, { operation: "direct_tool_call" });
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export const directHandlers = {
|
|
27
|
+
create_direct_session: async (args) => {
|
|
28
|
+
guardDirectProfileEnabled();
|
|
29
|
+
return toResult(await createDirectSession({
|
|
30
|
+
repo_path: String(args?.repo_path ?? ""),
|
|
31
|
+
title: args?.title ? String(args.title) : undefined,
|
|
32
|
+
}));
|
|
33
|
+
},
|
|
34
|
+
search_workspace: async (args) => {
|
|
35
|
+
guardDirectProfileEnabled();
|
|
36
|
+
return toResult(searchWorkspace({
|
|
37
|
+
session_id: String(args?.session_id ?? ""),
|
|
38
|
+
query: String(args?.query ?? ""),
|
|
39
|
+
max_results: args?.max_results ? Number(args.max_results) : undefined,
|
|
40
|
+
case_sensitive: args?.case_sensitive !== undefined ? Boolean(args.case_sensitive) : undefined,
|
|
41
|
+
max_preview_chars: args?.max_preview_chars ? Number(args.max_preview_chars) : undefined,
|
|
42
|
+
include_globs: Array.isArray(args?.include_globs)
|
|
43
|
+
? args.include_globs.map(String)
|
|
44
|
+
: undefined,
|
|
45
|
+
}));
|
|
46
|
+
},
|
|
47
|
+
apply_patch: async (args) => {
|
|
48
|
+
guardDirectProfileEnabled();
|
|
49
|
+
return toResult(applyPatch({
|
|
50
|
+
session_id: String(args?.session_id ?? ""),
|
|
51
|
+
path: String(args?.path ?? ""),
|
|
52
|
+
expected_sha256: String(args?.expected_sha256 ?? ""),
|
|
53
|
+
operations: Array.isArray(args?.operations) ? args.operations : [],
|
|
54
|
+
}));
|
|
55
|
+
},
|
|
56
|
+
run_verification: async (args) => {
|
|
57
|
+
guardDirectProfileEnabled();
|
|
58
|
+
return toResult(await runVerification({
|
|
59
|
+
session_id: String(args?.session_id ?? ""),
|
|
60
|
+
command: String(args?.command ?? ""),
|
|
61
|
+
timeout_seconds: args?.timeout_seconds ? Number(args.timeout_seconds) : undefined,
|
|
62
|
+
}));
|
|
63
|
+
},
|
|
64
|
+
run_direct_verification_bundle: async (args) => {
|
|
65
|
+
guardDirectProfileEnabled();
|
|
66
|
+
return toResult(await runDirectVerificationBundle({
|
|
67
|
+
session_id: String(args?.session_id ?? ""),
|
|
68
|
+
commands: Array.isArray(args?.commands)
|
|
69
|
+
? args.commands.map((command) => String(command))
|
|
70
|
+
: [],
|
|
71
|
+
timeout_seconds: args?.timeout_seconds ? Number(args.timeout_seconds) : undefined,
|
|
72
|
+
}));
|
|
73
|
+
},
|
|
74
|
+
finalize_direct_session: async (args) => {
|
|
75
|
+
guardDirectProfileEnabled();
|
|
76
|
+
return toResult(await finalizeDirectSession({
|
|
77
|
+
session_id: String(args?.session_id ?? ""),
|
|
78
|
+
}));
|
|
79
|
+
},
|
|
80
|
+
audit_session: async (args) => {
|
|
81
|
+
guardDirectProfileEnabled();
|
|
82
|
+
return toResult(auditSession({
|
|
83
|
+
session_id: String(args?.session_id ?? ""),
|
|
84
|
+
}));
|
|
85
|
+
},
|
|
86
|
+
safe_direct_summary: async (args) => {
|
|
87
|
+
guardDirectProfileEnabled();
|
|
88
|
+
return toResult(safeDirectSummary(String(args?.session_id ?? ""), {
|
|
89
|
+
max_items: args?.max_items !== undefined ? Number(args.max_items) : undefined,
|
|
90
|
+
}));
|
|
91
|
+
},
|
|
92
|
+
safe_finalize_direct_session: async (args) => {
|
|
93
|
+
guardDirectProfileEnabled();
|
|
94
|
+
return toResult(await safeFinalizeDirectSession(String(args?.session_id ?? ""), {
|
|
95
|
+
max_items: args?.max_items !== undefined ? Number(args.max_items) : undefined,
|
|
96
|
+
}));
|
|
97
|
+
},
|
|
98
|
+
safe_audit_direct_session: async (args) => {
|
|
99
|
+
guardDirectProfileEnabled();
|
|
100
|
+
return toResult(safeAuditDirectSession(String(args?.session_id ?? ""), {
|
|
101
|
+
max_items: args?.max_items !== undefined ? Number(args.max_items) : undefined,
|
|
102
|
+
}));
|
|
103
|
+
},
|
|
104
|
+
sync_file: async (args) => {
|
|
105
|
+
guardDirectProfileEnabled();
|
|
106
|
+
return toResult(syncFile(String(args?.session_id ?? ""), String(args?.source_path ?? ""), String(args?.target_path ?? ""), {
|
|
107
|
+
expected_source_sha256: args?.expected_source_sha256
|
|
108
|
+
? String(args.expected_source_sha256)
|
|
109
|
+
: undefined,
|
|
110
|
+
expected_target_sha256: args?.expected_target_sha256
|
|
111
|
+
? String(args.expected_target_sha256)
|
|
112
|
+
: undefined,
|
|
113
|
+
}));
|
|
114
|
+
},
|
|
115
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dispatch handlers for Goal Session tools (v0.8.0+).
|
|
3
|
+
*
|
|
4
|
+
* Covers goal lifecycle, subgoal management, Spec Kit import,
|
|
5
|
+
* worktree merge/discard, and goal reporting.
|
|
6
|
+
*/
|
|
7
|
+
import type { ToolHandlerMap } from "./types.js";
|
|
8
|
+
export declare const goalHandlers: ToolHandlerMap;
|