gsd-pi 2.67.0-dev.1cd1e0f → 2.67.0-dev.2367d7e
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.md +1 -1
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +155 -70
- package/dist/resources/extensions/gsd/auto/phases.js +17 -0
- package/dist/resources/extensions/gsd/auto/session.js +10 -0
- package/dist/resources/extensions/gsd/auto-direct-dispatch.js +12 -0
- package/dist/resources/extensions/gsd/auto-dispatch.js +1 -1
- package/dist/resources/extensions/gsd/auto-start.js +16 -30
- package/dist/resources/extensions/gsd/auto-worktree.js +62 -15
- package/dist/resources/extensions/gsd/auto.js +121 -59
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +11 -435
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +1 -4
- package/dist/resources/extensions/gsd/bootstrap/query-tools.js +7 -64
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +7 -2
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +88 -8
- package/dist/resources/extensions/gsd/commands/catalog.js +2 -1
- package/dist/resources/extensions/gsd/commands/handlers/core.js +39 -25
- package/dist/resources/extensions/gsd/commands/index.js +8 -1
- package/dist/resources/extensions/gsd/commands-mcp-status.js +43 -7
- package/dist/resources/extensions/gsd/doctor-git-checks.js +4 -4
- package/dist/resources/extensions/gsd/doctor-proactive.js +3 -3
- package/dist/resources/extensions/gsd/doctor.js +8 -4
- package/dist/resources/extensions/gsd/gsd-db.js +11 -0
- package/dist/resources/extensions/gsd/guided-flow.js +56 -31
- package/dist/resources/extensions/gsd/init-wizard.js +37 -0
- package/dist/resources/extensions/gsd/interrupted-session.js +146 -0
- package/dist/resources/extensions/gsd/mcp-project-config.js +83 -0
- package/dist/resources/extensions/gsd/state.js +7 -2
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +508 -0
- package/dist/resources/extensions/gsd/workflow-logger.js +18 -3
- package/dist/resources/extensions/gsd/workflow-mcp.js +261 -0
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +8 -8
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +2 -2
- package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +8 -8
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/2826.821e01b07d92e948.js +9 -0
- package/dist/web/standalone/.next/static/chunks/app/{page-0c485498795110d6.js → page-f1e30ab6bb269149.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/{webpack-b49b09f97429b5d0.js → webpack-6e4d7e9a4f57bed4.js} +1 -1
- package/package.json +4 -2
- package/packages/mcp-server/README.md +38 -0
- package/packages/mcp-server/dist/cli.d.ts +9 -0
- package/packages/mcp-server/dist/cli.d.ts.map +1 -0
- package/packages/mcp-server/dist/cli.js +58 -0
- package/packages/mcp-server/dist/cli.js.map +1 -0
- package/packages/mcp-server/dist/index.d.ts +20 -0
- package/packages/mcp-server/dist/index.d.ts.map +1 -0
- package/packages/mcp-server/dist/index.js +14 -0
- package/packages/mcp-server/dist/index.js.map +1 -0
- package/packages/mcp-server/dist/readers/captures.d.ts +25 -0
- package/packages/mcp-server/dist/readers/captures.d.ts.map +1 -0
- package/packages/mcp-server/dist/readers/captures.js +67 -0
- package/packages/mcp-server/dist/readers/captures.js.map +1 -0
- package/packages/mcp-server/dist/readers/doctor-lite.d.ts +20 -0
- package/packages/mcp-server/dist/readers/doctor-lite.d.ts.map +1 -0
- package/packages/mcp-server/dist/readers/doctor-lite.js +173 -0
- package/packages/mcp-server/dist/readers/doctor-lite.js.map +1 -0
- package/packages/mcp-server/dist/readers/index.d.ts +14 -0
- package/packages/mcp-server/dist/readers/index.d.ts.map +1 -0
- package/packages/mcp-server/dist/readers/index.js +10 -0
- package/packages/mcp-server/dist/readers/index.js.map +1 -0
- package/packages/mcp-server/dist/readers/knowledge.d.ts +18 -0
- package/packages/mcp-server/dist/readers/knowledge.d.ts.map +1 -0
- package/packages/mcp-server/dist/readers/knowledge.js +82 -0
- package/packages/mcp-server/dist/readers/knowledge.js.map +1 -0
- package/packages/mcp-server/dist/readers/metrics.d.ts +32 -0
- package/packages/mcp-server/dist/readers/metrics.d.ts.map +1 -0
- package/packages/mcp-server/dist/readers/metrics.js +74 -0
- package/packages/mcp-server/dist/readers/metrics.js.map +1 -0
- package/packages/mcp-server/dist/readers/paths.d.ts +42 -0
- package/packages/mcp-server/dist/readers/paths.d.ts.map +1 -0
- package/packages/mcp-server/dist/readers/paths.js +199 -0
- package/packages/mcp-server/dist/readers/paths.js.map +1 -0
- package/packages/mcp-server/dist/readers/roadmap.d.ts +26 -0
- package/packages/mcp-server/dist/readers/roadmap.d.ts.map +1 -0
- package/packages/mcp-server/dist/readers/roadmap.js +194 -0
- package/packages/mcp-server/dist/readers/roadmap.js.map +1 -0
- package/packages/mcp-server/dist/readers/state.d.ts +43 -0
- package/packages/mcp-server/dist/readers/state.d.ts.map +1 -0
- package/packages/mcp-server/dist/readers/state.js +184 -0
- package/packages/mcp-server/dist/readers/state.js.map +1 -0
- package/packages/mcp-server/dist/server.d.ts +28 -0
- package/packages/mcp-server/dist/server.d.ts.map +1 -0
- package/packages/mcp-server/dist/server.js +319 -0
- package/packages/mcp-server/dist/server.js.map +1 -0
- package/packages/mcp-server/dist/session-manager.d.ts +54 -0
- package/packages/mcp-server/dist/session-manager.d.ts.map +1 -0
- package/packages/mcp-server/dist/session-manager.js +284 -0
- package/packages/mcp-server/dist/session-manager.js.map +1 -0
- package/packages/mcp-server/dist/types.d.ts +61 -0
- package/packages/mcp-server/dist/types.d.ts.map +1 -0
- package/packages/mcp-server/dist/types.js +11 -0
- package/packages/mcp-server/dist/types.js.map +1 -0
- package/packages/mcp-server/dist/workflow-tools.d.ts +9 -0
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -0
- package/packages/mcp-server/dist/workflow-tools.js +532 -0
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -0
- package/packages/mcp-server/src/server.ts +6 -2
- package/packages/mcp-server/src/workflow-tools.test.ts +976 -0
- package/packages/mcp-server/src/workflow-tools.ts +997 -0
- package/packages/mcp-server/tsconfig.json +1 -1
- package/packages/pi-agent-core/dist/agent-loop.js +14 -6
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/src/agent-loop.test.ts +53 -0
- package/packages/pi-agent-core/src/agent-loop.ts +20 -6
- package/packages/pi-coding-agent/dist/core/contextual-tips.d.ts +43 -0
- package/packages/pi-coding-agent/dist/core/contextual-tips.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/contextual-tips.js +208 -0
- package/packages/pi-coding-agent/dist/core/contextual-tips.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/contextual-tips.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/contextual-tips.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/contextual-tips.test.js +227 -0
- package/packages/pi-coding-agent/dist/core/contextual-tips.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/index.d.ts +1 -0
- package/packages/pi-coding-agent/dist/core/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/index.js +1 -0
- package/packages/pi-coding-agent/dist/core/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +28 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +17 -12
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +19 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.d.ts +4 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +14 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +3 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +15 -12
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/src/core/contextual-tips.test.ts +259 -0
- package/packages/pi-coding-agent/src/core/contextual-tips.ts +232 -0
- package/packages/pi-coding-agent/src/core/index.ts +2 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +54 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +18 -12
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +21 -0
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +19 -0
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +19 -15
- package/packages/rpc-client/dist/index.d.ts +10 -0
- package/packages/rpc-client/dist/index.d.ts.map +1 -0
- package/packages/rpc-client/dist/index.js +9 -0
- package/packages/rpc-client/dist/index.js.map +1 -0
- package/packages/rpc-client/dist/jsonl.d.ts +17 -0
- package/packages/rpc-client/dist/jsonl.d.ts.map +1 -0
- package/packages/rpc-client/dist/jsonl.js +54 -0
- package/packages/rpc-client/dist/jsonl.js.map +1 -0
- package/packages/rpc-client/dist/rpc-client.d.ts +259 -0
- package/packages/rpc-client/dist/rpc-client.d.ts.map +1 -0
- package/packages/rpc-client/dist/rpc-client.js +541 -0
- package/packages/rpc-client/dist/rpc-client.js.map +1 -0
- package/packages/rpc-client/dist/rpc-client.test.d.ts +2 -0
- package/packages/rpc-client/dist/rpc-client.test.d.ts.map +1 -0
- package/packages/rpc-client/dist/rpc-client.test.js +477 -0
- package/packages/rpc-client/dist/rpc-client.test.js.map +1 -0
- package/packages/rpc-client/dist/rpc-types.d.ts +566 -0
- package/packages/rpc-client/dist/rpc-types.d.ts.map +1 -0
- package/packages/rpc-client/dist/rpc-types.js +12 -0
- package/packages/rpc-client/dist/rpc-types.js.map +1 -0
- package/scripts/ensure-workspace-builds.cjs +2 -0
- package/scripts/link-workspace-packages.cjs +21 -14
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +193 -93
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +173 -79
- package/src/resources/extensions/gsd/auto/phases.ts +25 -0
- package/src/resources/extensions/gsd/auto/session.ts +10 -0
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +20 -0
- package/src/resources/extensions/gsd/auto-dispatch.ts +1 -1
- package/src/resources/extensions/gsd/auto-start.ts +23 -55
- package/src/resources/extensions/gsd/auto-worktree.ts +59 -15
- package/src/resources/extensions/gsd/auto.ts +133 -64
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +22 -435
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +1 -5
- package/src/resources/extensions/gsd/bootstrap/query-tools.ts +7 -72
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +8 -2
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +122 -6
- package/src/resources/extensions/gsd/commands/catalog.ts +2 -1
- package/src/resources/extensions/gsd/commands/handlers/core.ts +53 -26
- package/src/resources/extensions/gsd/commands/index.ts +7 -1
- package/src/resources/extensions/gsd/commands-mcp-status.ts +53 -7
- package/src/resources/extensions/gsd/doctor-git-checks.ts +4 -4
- package/src/resources/extensions/gsd/doctor-proactive.ts +3 -3
- package/src/resources/extensions/gsd/doctor.ts +9 -5
- package/src/resources/extensions/gsd/gsd-db.ts +12 -0
- package/src/resources/extensions/gsd/guided-flow.ts +66 -36
- package/src/resources/extensions/gsd/init-wizard.ts +40 -0
- package/src/resources/extensions/gsd/interrupted-session.ts +224 -0
- package/src/resources/extensions/gsd/mcp-project-config.ts +128 -0
- package/src/resources/extensions/gsd/state.ts +7 -1
- package/src/resources/extensions/gsd/tests/auto-project-root-env.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +668 -2
- package/src/resources/extensions/gsd/tests/cold-resume-db-reopen.test.ts +14 -4
- package/src/resources/extensions/gsd/tests/copy-planning-artifacts-samepath.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/core-overlay-fallback.test.ts +101 -0
- package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +380 -2
- package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +66 -0
- package/src/resources/extensions/gsd/tests/forensics-context-persist.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/integration/doctor-fixlevel.test.ts +52 -1
- package/src/resources/extensions/gsd/tests/integration/doctor-git.test.ts +2 -9
- package/src/resources/extensions/gsd/tests/integration/doctor-proactive.test.ts +0 -33
- package/src/resources/extensions/gsd/tests/integration/merge-cwd-restore.test.ts +169 -0
- package/src/resources/extensions/gsd/tests/interrupted-session-auto.test.ts +146 -0
- package/src/resources/extensions/gsd/tests/interrupted-session-ui.test.ts +136 -0
- package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +85 -0
- package/src/resources/extensions/gsd/tests/mcp-status.test.ts +15 -0
- package/src/resources/extensions/gsd/tests/verification-operational-gate.test.ts +11 -0
- package/src/resources/extensions/gsd/tests/workflow-logger.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +500 -0
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +625 -0
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +629 -0
- package/src/resources/extensions/gsd/workflow-logger.ts +19 -3
- package/src/resources/extensions/gsd/workflow-mcp.ts +320 -0
- package/dist/web/standalone/.next/static/chunks/6502.b804e48b7919f55e.js +0 -9
- package/packages/pi-coding-agent/dist/modes/interactive/provider-auth-setup.d.ts +0 -13
- package/packages/pi-coding-agent/dist/modes/interactive/provider-auth-setup.d.ts.map +0 -1
- package/packages/pi-coding-agent/dist/modes/interactive/provider-auth-setup.js +0 -27
- package/packages/pi-coding-agent/dist/modes/interactive/provider-auth-setup.js.map +0 -1
- package/packages/pi-coding-agent/src/modes/interactive/provider-auth-setup.ts +0 -40
- /package/dist/web/standalone/.next/static/{PHqEommYRR8CRn3i84CGM → WMDT_0C0XDkBKtsAI_AX4}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{PHqEommYRR8CRn3i84CGM → WMDT_0C0XDkBKtsAI_AX4}/_ssgManifest.js +0 -0
|
@@ -8,15 +8,18 @@ import { ensureDbOpen } from "./dynamic-tools.js";
|
|
|
8
8
|
import { StringEnum } from "@gsd/pi-ai";
|
|
9
9
|
import { logError } from "../workflow-logger.js";
|
|
10
10
|
import { getErrorMessage } from "../error-utils.js";
|
|
11
|
-
import {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
11
|
+
import {
|
|
12
|
+
executeCompleteMilestone,
|
|
13
|
+
executePlanMilestone,
|
|
14
|
+
executePlanSlice,
|
|
15
|
+
executeReplanSlice,
|
|
16
|
+
executeReassessRoadmap,
|
|
17
|
+
executeSaveGateResult,
|
|
18
|
+
executeSliceComplete,
|
|
19
|
+
executeSummarySave,
|
|
20
|
+
executeTaskComplete,
|
|
21
|
+
executeValidateMilestone,
|
|
22
|
+
} from "../tools/workflow-tool-executors.js";
|
|
20
23
|
|
|
21
24
|
/**
|
|
22
25
|
* Register an alias tool that shares the same execute function as its canonical counterpart.
|
|
@@ -286,63 +289,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
286
289
|
// ─── gsd_summary_save (formerly gsd_save_summary) ──────────────────────
|
|
287
290
|
|
|
288
291
|
const summarySaveExecute = async (_toolCallId: string, params: any, _signal: AbortSignal | undefined, _onUpdate: unknown, _ctx: unknown) => {
|
|
289
|
-
|
|
290
|
-
if (!dbAvailable) {
|
|
291
|
-
return {
|
|
292
|
-
content: [{ type: "text" as const, text: "Error: GSD database is not available. Cannot save artifact." }],
|
|
293
|
-
details: { operation: "save_summary", error: "db_unavailable" } as any,
|
|
294
|
-
};
|
|
295
|
-
}
|
|
296
|
-
if (!isSupportedSummaryArtifactType(params.artifact_type)) {
|
|
297
|
-
return {
|
|
298
|
-
content: [{ type: "text" as const, text: `Error: Invalid artifact_type "${params.artifact_type}". Must be one of: ${SUPPORTED_SUMMARY_ARTIFACT_TYPES.join(", ")}` }],
|
|
299
|
-
details: { operation: "save_summary", error: "invalid_artifact_type" } as any,
|
|
300
|
-
};
|
|
301
|
-
}
|
|
302
|
-
const contextGuard = shouldBlockContextArtifactSave(
|
|
303
|
-
params.artifact_type,
|
|
304
|
-
params.milestone_id ?? null,
|
|
305
|
-
params.slice_id ?? null,
|
|
306
|
-
);
|
|
307
|
-
if (contextGuard.block) {
|
|
308
|
-
return {
|
|
309
|
-
content: [{ type: "text" as const, text: `Error saving artifact: ${contextGuard.reason ?? "context write blocked"}` }],
|
|
310
|
-
details: { operation: "save_summary", error: "context_write_blocked" } as any,
|
|
311
|
-
};
|
|
312
|
-
}
|
|
313
|
-
try {
|
|
314
|
-
let relativePath: string;
|
|
315
|
-
if (params.task_id && params.slice_id) {
|
|
316
|
-
relativePath = `milestones/${params.milestone_id}/slices/${params.slice_id}/tasks/${params.task_id}-${params.artifact_type}.md`;
|
|
317
|
-
} else if (params.slice_id) {
|
|
318
|
-
relativePath = `milestones/${params.milestone_id}/slices/${params.slice_id}/${params.slice_id}-${params.artifact_type}.md`;
|
|
319
|
-
} else {
|
|
320
|
-
relativePath = `milestones/${params.milestone_id}/${params.milestone_id}-${params.artifact_type}.md`;
|
|
321
|
-
}
|
|
322
|
-
const { saveArtifactToDb } = await import("../db-writer.js");
|
|
323
|
-
await saveArtifactToDb(
|
|
324
|
-
{
|
|
325
|
-
path: relativePath,
|
|
326
|
-
artifact_type: params.artifact_type,
|
|
327
|
-
content: params.content,
|
|
328
|
-
milestone_id: params.milestone_id,
|
|
329
|
-
slice_id: params.slice_id,
|
|
330
|
-
task_id: params.task_id,
|
|
331
|
-
},
|
|
332
|
-
process.cwd(),
|
|
333
|
-
);
|
|
334
|
-
return {
|
|
335
|
-
content: [{ type: "text" as const, text: `Saved ${params.artifact_type} artifact to ${relativePath}` }],
|
|
336
|
-
details: { operation: "save_summary", path: relativePath, artifact_type: params.artifact_type } as any,
|
|
337
|
-
};
|
|
338
|
-
} catch (err) {
|
|
339
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
340
|
-
logError("tool", `gsd_summary_save tool failed: ${msg}`, { tool: "gsd_summary_save", error: String(err) });
|
|
341
|
-
return {
|
|
342
|
-
content: [{ type: "text" as const, text: `Error saving artifact: ${msg}` }],
|
|
343
|
-
details: { operation: "save_summary", error: msg } as any,
|
|
344
|
-
};
|
|
345
|
-
}
|
|
292
|
+
return executeSummarySave(params, process.cwd());
|
|
346
293
|
};
|
|
347
294
|
|
|
348
295
|
const summarySaveTool = {
|
|
@@ -475,38 +422,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
475
422
|
// ─── gsd_plan_milestone (gsd_milestone_plan alias) ─────────────────────
|
|
476
423
|
|
|
477
424
|
const planMilestoneExecute = async (_toolCallId: string, params: any, _signal: AbortSignal | undefined, _onUpdate: unknown, _ctx: unknown) => {
|
|
478
|
-
|
|
479
|
-
if (!dbAvailable) {
|
|
480
|
-
return {
|
|
481
|
-
content: [{ type: "text" as const, text: "Error: GSD database is not available. Cannot plan milestone." }],
|
|
482
|
-
details: { operation: "plan_milestone", error: "db_unavailable" } as any,
|
|
483
|
-
};
|
|
484
|
-
}
|
|
485
|
-
try {
|
|
486
|
-
const { handlePlanMilestone } = await import("../tools/plan-milestone.js");
|
|
487
|
-
const result = await handlePlanMilestone(params, process.cwd());
|
|
488
|
-
if ("error" in result) {
|
|
489
|
-
return {
|
|
490
|
-
content: [{ type: "text" as const, text: `Error planning milestone: ${result.error}` }],
|
|
491
|
-
details: { operation: "plan_milestone", error: result.error } as any,
|
|
492
|
-
};
|
|
493
|
-
}
|
|
494
|
-
return {
|
|
495
|
-
content: [{ type: "text" as const, text: `Planned milestone ${result.milestoneId}` }],
|
|
496
|
-
details: {
|
|
497
|
-
operation: "plan_milestone",
|
|
498
|
-
milestoneId: result.milestoneId,
|
|
499
|
-
roadmapPath: result.roadmapPath,
|
|
500
|
-
} as any,
|
|
501
|
-
};
|
|
502
|
-
} catch (err) {
|
|
503
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
504
|
-
logError("tool", `plan_milestone tool failed: ${msg}`, { tool: "gsd_plan_milestone", error: String(err) });
|
|
505
|
-
return {
|
|
506
|
-
content: [{ type: "text" as const, text: `Error planning milestone: ${msg}` }],
|
|
507
|
-
details: { operation: "plan_milestone", error: msg } as any,
|
|
508
|
-
};
|
|
509
|
-
}
|
|
425
|
+
return executePlanMilestone(params, process.cwd());
|
|
510
426
|
};
|
|
511
427
|
|
|
512
428
|
const planMilestoneTool = {
|
|
@@ -568,40 +484,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
568
484
|
// ─── gsd_plan_slice (gsd_slice_plan alias) ─────────────────────────────
|
|
569
485
|
|
|
570
486
|
const planSliceExecute = async (_toolCallId: string, params: any, _signal: AbortSignal | undefined, _onUpdate: unknown, _ctx: unknown) => {
|
|
571
|
-
|
|
572
|
-
if (!dbAvailable) {
|
|
573
|
-
return {
|
|
574
|
-
content: [{ type: "text" as const, text: "Error: GSD database is not available. Cannot plan slice." }],
|
|
575
|
-
details: { operation: "plan_slice", error: "db_unavailable" } as any,
|
|
576
|
-
};
|
|
577
|
-
}
|
|
578
|
-
try {
|
|
579
|
-
const { handlePlanSlice } = await import("../tools/plan-slice.js");
|
|
580
|
-
const result = await handlePlanSlice(params, process.cwd());
|
|
581
|
-
if ("error" in result) {
|
|
582
|
-
return {
|
|
583
|
-
content: [{ type: "text" as const, text: `Error planning slice: ${result.error}` }],
|
|
584
|
-
details: { operation: "plan_slice", error: result.error } as any,
|
|
585
|
-
};
|
|
586
|
-
}
|
|
587
|
-
return {
|
|
588
|
-
content: [{ type: "text" as const, text: `Planned slice ${result.sliceId} (${result.milestoneId})` }],
|
|
589
|
-
details: {
|
|
590
|
-
operation: "plan_slice",
|
|
591
|
-
milestoneId: result.milestoneId,
|
|
592
|
-
sliceId: result.sliceId,
|
|
593
|
-
planPath: result.planPath,
|
|
594
|
-
taskPlanPaths: result.taskPlanPaths,
|
|
595
|
-
} as any,
|
|
596
|
-
};
|
|
597
|
-
} catch (err) {
|
|
598
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
599
|
-
logError("tool", `plan_slice tool failed: ${msg}`, { tool: "gsd_plan_slice", error: String(err) });
|
|
600
|
-
return {
|
|
601
|
-
content: [{ type: "text" as const, text: `Error planning slice: ${msg}` }],
|
|
602
|
-
details: { operation: "plan_slice", error: msg } as any,
|
|
603
|
-
};
|
|
604
|
-
}
|
|
487
|
+
return executePlanSlice(params, process.cwd());
|
|
605
488
|
};
|
|
606
489
|
|
|
607
490
|
const planSliceTool = {
|
|
@@ -717,46 +600,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
717
600
|
// ─── gsd_task_complete (gsd_complete_task alias) ────────────────────────
|
|
718
601
|
|
|
719
602
|
const taskCompleteExecute = async (_toolCallId: string, params: any, _signal: AbortSignal | undefined, _onUpdate: unknown, _ctx: unknown) => {
|
|
720
|
-
|
|
721
|
-
if (!dbAvailable) {
|
|
722
|
-
return {
|
|
723
|
-
content: [{ type: "text" as const, text: "Error: GSD database is not available. Cannot complete task." }],
|
|
724
|
-
details: { operation: "complete_task", error: "db_unavailable" } as any,
|
|
725
|
-
};
|
|
726
|
-
}
|
|
727
|
-
try {
|
|
728
|
-
// Coerce string items to objects for verificationEvidence (#3541).
|
|
729
|
-
const coerced = { ...params };
|
|
730
|
-
coerced.verificationEvidence = (params.verificationEvidence ?? []).map((v: any) =>
|
|
731
|
-
typeof v === "string" ? { command: v, exitCode: -1, verdict: "unknown (coerced from string)", durationMs: 0 } : v,
|
|
732
|
-
);
|
|
733
|
-
|
|
734
|
-
const { handleCompleteTask } = await import("../tools/complete-task.js");
|
|
735
|
-
const result = await handleCompleteTask(coerced, process.cwd());
|
|
736
|
-
if ("error" in result) {
|
|
737
|
-
return {
|
|
738
|
-
content: [{ type: "text" as const, text: `Error completing task: ${result.error}` }],
|
|
739
|
-
details: { operation: "complete_task", error: result.error } as any,
|
|
740
|
-
};
|
|
741
|
-
}
|
|
742
|
-
return {
|
|
743
|
-
content: [{ type: "text" as const, text: `Completed task ${result.taskId} (${result.sliceId}/${result.milestoneId})` }],
|
|
744
|
-
details: {
|
|
745
|
-
operation: "complete_task",
|
|
746
|
-
taskId: result.taskId,
|
|
747
|
-
sliceId: result.sliceId,
|
|
748
|
-
milestoneId: result.milestoneId,
|
|
749
|
-
summaryPath: result.summaryPath,
|
|
750
|
-
} as any,
|
|
751
|
-
};
|
|
752
|
-
} catch (err) {
|
|
753
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
754
|
-
logError("tool", `complete_task tool failed: ${msg}`, { tool: "gsd_task_complete", error: String(err) });
|
|
755
|
-
return {
|
|
756
|
-
content: [{ type: "text" as const, text: `Error completing task: ${msg}` }],
|
|
757
|
-
details: { operation: "complete_task", error: msg } as any,
|
|
758
|
-
};
|
|
759
|
-
}
|
|
603
|
+
return executeTaskComplete(params, process.cwd());
|
|
760
604
|
};
|
|
761
605
|
|
|
762
606
|
const taskCompleteTool = {
|
|
@@ -809,86 +653,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
809
653
|
// ─── gsd_slice_complete (gsd_complete_slice alias) ─────────────────────
|
|
810
654
|
|
|
811
655
|
const sliceCompleteExecute = async (_toolCallId: string, params: any, _signal: AbortSignal | undefined, _onUpdate: unknown, _ctx: unknown) => {
|
|
812
|
-
|
|
813
|
-
if (!dbAvailable) {
|
|
814
|
-
return {
|
|
815
|
-
content: [{ type: "text" as const, text: "Error: GSD database is not available. Cannot complete slice." }],
|
|
816
|
-
details: { operation: "complete_slice", error: "db_unavailable" } as any,
|
|
817
|
-
};
|
|
818
|
-
}
|
|
819
|
-
try {
|
|
820
|
-
// Coerce string items to objects for fields where LLMs sometimes pass
|
|
821
|
-
// plain strings instead of the expected { key, value } shape (#3541).
|
|
822
|
-
// Parses "key — value" or "key - value" format when possible.
|
|
823
|
-
const splitPair = (s: string): [string, string] => {
|
|
824
|
-
const m = s.match(/^(.+?)\s*(?:—|-)\s+(.+)$/);
|
|
825
|
-
return m ? [m[1].trim(), m[2].trim()] : [s.trim(), ""];
|
|
826
|
-
};
|
|
827
|
-
const coerced = { ...params };
|
|
828
|
-
// Coerce simple string-array fields: LLMs sometimes pass a plain string
|
|
829
|
-
// instead of a single-element array (#3585).
|
|
830
|
-
const wrapArray = (v: any): any[] =>
|
|
831
|
-
v == null ? [] : Array.isArray(v) ? v : [v];
|
|
832
|
-
coerced.provides = wrapArray(params.provides);
|
|
833
|
-
coerced.keyFiles = wrapArray(params.keyFiles);
|
|
834
|
-
coerced.keyDecisions = wrapArray(params.keyDecisions);
|
|
835
|
-
coerced.patternsEstablished = wrapArray(params.patternsEstablished);
|
|
836
|
-
coerced.observabilitySurfaces = wrapArray(params.observabilitySurfaces);
|
|
837
|
-
coerced.requirementsSurfaced = wrapArray(params.requirementsSurfaced);
|
|
838
|
-
coerced.drillDownPaths = wrapArray(params.drillDownPaths);
|
|
839
|
-
coerced.affects = wrapArray(params.affects);
|
|
840
|
-
coerced.filesModified = wrapArray(params.filesModified).map((f: any) => {
|
|
841
|
-
if (typeof f !== "string") return f;
|
|
842
|
-
const [path, description] = splitPair(f);
|
|
843
|
-
return { path, description };
|
|
844
|
-
});
|
|
845
|
-
coerced.requires = wrapArray(params.requires).map((r: any) => {
|
|
846
|
-
if (typeof r !== "string") return r;
|
|
847
|
-
const [slice, provides] = splitPair(r);
|
|
848
|
-
return { slice, provides };
|
|
849
|
-
});
|
|
850
|
-
coerced.requirementsAdvanced = wrapArray(params.requirementsAdvanced).map((r: any) => {
|
|
851
|
-
if (typeof r !== "string") return r;
|
|
852
|
-
const [id, how] = splitPair(r);
|
|
853
|
-
return { id, how };
|
|
854
|
-
});
|
|
855
|
-
coerced.requirementsValidated = wrapArray(params.requirementsValidated).map((r: any) => {
|
|
856
|
-
if (typeof r !== "string") return r;
|
|
857
|
-
const [id, proof] = splitPair(r);
|
|
858
|
-
return { id, proof };
|
|
859
|
-
});
|
|
860
|
-
coerced.requirementsInvalidated = wrapArray(params.requirementsInvalidated).map((r: any) => {
|
|
861
|
-
if (typeof r !== "string") return r;
|
|
862
|
-
const [id, what] = splitPair(r);
|
|
863
|
-
return { id, what };
|
|
864
|
-
});
|
|
865
|
-
|
|
866
|
-
const { handleCompleteSlice } = await import("../tools/complete-slice.js");
|
|
867
|
-
const result = await handleCompleteSlice(coerced, process.cwd());
|
|
868
|
-
if ("error" in result) {
|
|
869
|
-
return {
|
|
870
|
-
content: [{ type: "text" as const, text: `Error completing slice: ${result.error}` }],
|
|
871
|
-
details: { operation: "complete_slice", error: result.error } as any,
|
|
872
|
-
};
|
|
873
|
-
}
|
|
874
|
-
return {
|
|
875
|
-
content: [{ type: "text" as const, text: `Completed slice ${result.sliceId} (${result.milestoneId})` }],
|
|
876
|
-
details: {
|
|
877
|
-
operation: "complete_slice",
|
|
878
|
-
sliceId: result.sliceId,
|
|
879
|
-
milestoneId: result.milestoneId,
|
|
880
|
-
summaryPath: result.summaryPath,
|
|
881
|
-
uatPath: result.uatPath,
|
|
882
|
-
} as any,
|
|
883
|
-
};
|
|
884
|
-
} catch (err) {
|
|
885
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
886
|
-
logError("tool", `complete_slice tool failed: ${msg}`, { tool: "gsd_slice_complete", error: String(err) });
|
|
887
|
-
return {
|
|
888
|
-
content: [{ type: "text" as const, text: `Error completing slice: ${msg}` }],
|
|
889
|
-
details: { operation: "complete_slice", error: msg } as any,
|
|
890
|
-
};
|
|
891
|
-
}
|
|
656
|
+
return executeSliceComplete(params, process.cwd());
|
|
892
657
|
};
|
|
893
658
|
|
|
894
659
|
const sliceCompleteTool = {
|
|
@@ -1073,42 +838,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
1073
838
|
// ─── gsd_complete_milestone ────────────────────────────────────────────
|
|
1074
839
|
|
|
1075
840
|
const milestoneCompleteExecute = async (_toolCallId: string, params: any, _signal: AbortSignal | undefined, _onUpdate: unknown, _ctx: unknown) => {
|
|
1076
|
-
|
|
1077
|
-
if (!dbAvailable) {
|
|
1078
|
-
return {
|
|
1079
|
-
content: [{ type: "text" as const, text: "Error: GSD database is not available. Cannot complete milestone." }],
|
|
1080
|
-
details: { operation: "complete_milestone", error: "db_unavailable" } as any,
|
|
1081
|
-
};
|
|
1082
|
-
}
|
|
1083
|
-
try {
|
|
1084
|
-
// ── Input sanitization: normalize markdown parameters (#3013) ──────
|
|
1085
|
-
const { sanitizeCompleteMilestoneParams } = await import("./sanitize-complete-milestone.js");
|
|
1086
|
-
const sanitized = sanitizeCompleteMilestoneParams(params);
|
|
1087
|
-
|
|
1088
|
-
const { handleCompleteMilestone } = await import("../tools/complete-milestone.js");
|
|
1089
|
-
const result = await handleCompleteMilestone(sanitized, process.cwd());
|
|
1090
|
-
if ("error" in result) {
|
|
1091
|
-
return {
|
|
1092
|
-
content: [{ type: "text" as const, text: `Error completing milestone: ${result.error}` }],
|
|
1093
|
-
details: { operation: "complete_milestone", error: result.error } as any,
|
|
1094
|
-
};
|
|
1095
|
-
}
|
|
1096
|
-
return {
|
|
1097
|
-
content: [{ type: "text" as const, text: `Completed milestone ${result.milestoneId}. Summary written to ${result.summaryPath}` }],
|
|
1098
|
-
details: {
|
|
1099
|
-
operation: "complete_milestone",
|
|
1100
|
-
milestoneId: result.milestoneId,
|
|
1101
|
-
summaryPath: result.summaryPath,
|
|
1102
|
-
} as any,
|
|
1103
|
-
};
|
|
1104
|
-
} catch (err) {
|
|
1105
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
1106
|
-
logError("tool", `complete_milestone tool failed: ${msg}`, { tool: "gsd_complete_milestone", error: String(err) });
|
|
1107
|
-
return {
|
|
1108
|
-
content: [{ type: "text" as const, text: `Error completing milestone: ${msg}` }],
|
|
1109
|
-
details: { operation: "complete_milestone", error: msg } as any,
|
|
1110
|
-
};
|
|
1111
|
-
}
|
|
841
|
+
return executeCompleteMilestone(params, process.cwd());
|
|
1112
842
|
};
|
|
1113
843
|
|
|
1114
844
|
const milestoneCompleteTool = {
|
|
@@ -1150,39 +880,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
1150
880
|
// ─── gsd_validate_milestone (gsd_milestone_validate alias) ─────────────
|
|
1151
881
|
|
|
1152
882
|
const milestoneValidateExecute = async (_toolCallId: string, params: any, _signal: AbortSignal | undefined, _onUpdate: unknown, _ctx: unknown) => {
|
|
1153
|
-
|
|
1154
|
-
if (!dbAvailable) {
|
|
1155
|
-
return {
|
|
1156
|
-
content: [{ type: "text" as const, text: "Error: GSD database is not available. Cannot validate milestone." }],
|
|
1157
|
-
details: { operation: "validate_milestone", error: "db_unavailable" } as any,
|
|
1158
|
-
};
|
|
1159
|
-
}
|
|
1160
|
-
try {
|
|
1161
|
-
const { handleValidateMilestone } = await import("../tools/validate-milestone.js");
|
|
1162
|
-
const result = await handleValidateMilestone(params, process.cwd());
|
|
1163
|
-
if ("error" in result) {
|
|
1164
|
-
return {
|
|
1165
|
-
content: [{ type: "text" as const, text: `Error validating milestone: ${result.error}` }],
|
|
1166
|
-
details: { operation: "validate_milestone", error: result.error } as any,
|
|
1167
|
-
};
|
|
1168
|
-
}
|
|
1169
|
-
return {
|
|
1170
|
-
content: [{ type: "text" as const, text: `Validated milestone ${result.milestoneId} — verdict: ${result.verdict}. Written to ${result.validationPath}` }],
|
|
1171
|
-
details: {
|
|
1172
|
-
operation: "validate_milestone",
|
|
1173
|
-
milestoneId: result.milestoneId,
|
|
1174
|
-
verdict: result.verdict,
|
|
1175
|
-
validationPath: result.validationPath,
|
|
1176
|
-
} as any,
|
|
1177
|
-
};
|
|
1178
|
-
} catch (err) {
|
|
1179
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
1180
|
-
logError("tool", `validate_milestone tool failed: ${msg}`, { tool: "gsd_validate_milestone", error: String(err) });
|
|
1181
|
-
return {
|
|
1182
|
-
content: [{ type: "text" as const, text: `Error validating milestone: ${msg}` }],
|
|
1183
|
-
details: { operation: "validate_milestone", error: msg } as any,
|
|
1184
|
-
};
|
|
1185
|
-
}
|
|
883
|
+
return executeValidateMilestone(params, process.cwd());
|
|
1186
884
|
};
|
|
1187
885
|
|
|
1188
886
|
const milestoneValidateTool = {
|
|
@@ -1219,40 +917,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
1219
917
|
// ─── gsd_replan_slice (gsd_slice_replan alias) ─────────────────────────
|
|
1220
918
|
|
|
1221
919
|
const replanSliceExecute = async (_toolCallId: string, params: any, _signal: AbortSignal | undefined, _onUpdate: unknown, _ctx: unknown) => {
|
|
1222
|
-
|
|
1223
|
-
if (!dbAvailable) {
|
|
1224
|
-
return {
|
|
1225
|
-
content: [{ type: "text" as const, text: "Error: GSD database is not available. Cannot replan slice." }],
|
|
1226
|
-
details: { operation: "replan_slice", error: "db_unavailable" } as any,
|
|
1227
|
-
};
|
|
1228
|
-
}
|
|
1229
|
-
try {
|
|
1230
|
-
const { handleReplanSlice } = await import("../tools/replan-slice.js");
|
|
1231
|
-
const result = await handleReplanSlice(params, process.cwd());
|
|
1232
|
-
if ("error" in result) {
|
|
1233
|
-
return {
|
|
1234
|
-
content: [{ type: "text" as const, text: `Error replanning slice: ${result.error}` }],
|
|
1235
|
-
details: { operation: "replan_slice", error: result.error } as any,
|
|
1236
|
-
};
|
|
1237
|
-
}
|
|
1238
|
-
return {
|
|
1239
|
-
content: [{ type: "text" as const, text: `Replanned slice ${result.sliceId} (${result.milestoneId})` }],
|
|
1240
|
-
details: {
|
|
1241
|
-
operation: "replan_slice",
|
|
1242
|
-
milestoneId: result.milestoneId,
|
|
1243
|
-
sliceId: result.sliceId,
|
|
1244
|
-
replanPath: result.replanPath,
|
|
1245
|
-
planPath: result.planPath,
|
|
1246
|
-
} as any,
|
|
1247
|
-
};
|
|
1248
|
-
} catch (err) {
|
|
1249
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
1250
|
-
logError("tool", `replan_slice tool failed: ${msg}`, { tool: "gsd_replan_slice", error: String(err) });
|
|
1251
|
-
return {
|
|
1252
|
-
content: [{ type: "text" as const, text: `Error replanning slice: ${msg}` }],
|
|
1253
|
-
details: { operation: "replan_slice", error: msg } as any,
|
|
1254
|
-
};
|
|
1255
|
-
}
|
|
920
|
+
return executeReplanSlice(params, process.cwd());
|
|
1256
921
|
};
|
|
1257
922
|
|
|
1258
923
|
const replanSliceTool = {
|
|
@@ -1299,40 +964,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
1299
964
|
// ─── gsd_reassess_roadmap (gsd_roadmap_reassess alias) ─────────────────
|
|
1300
965
|
|
|
1301
966
|
const reassessRoadmapExecute = async (_toolCallId: string, params: any, _signal: AbortSignal | undefined, _onUpdate: unknown, _ctx: unknown) => {
|
|
1302
|
-
|
|
1303
|
-
if (!dbAvailable) {
|
|
1304
|
-
return {
|
|
1305
|
-
content: [{ type: "text" as const, text: "Error: GSD database is not available. Cannot reassess roadmap." }],
|
|
1306
|
-
details: { operation: "reassess_roadmap", error: "db_unavailable" } as any,
|
|
1307
|
-
};
|
|
1308
|
-
}
|
|
1309
|
-
try {
|
|
1310
|
-
const { handleReassessRoadmap } = await import("../tools/reassess-roadmap.js");
|
|
1311
|
-
const result = await handleReassessRoadmap(params, process.cwd());
|
|
1312
|
-
if ("error" in result) {
|
|
1313
|
-
return {
|
|
1314
|
-
content: [{ type: "text" as const, text: `Error reassessing roadmap: ${result.error}` }],
|
|
1315
|
-
details: { operation: "reassess_roadmap", error: result.error } as any,
|
|
1316
|
-
};
|
|
1317
|
-
}
|
|
1318
|
-
return {
|
|
1319
|
-
content: [{ type: "text" as const, text: `Reassessed roadmap for milestone ${result.milestoneId} after ${result.completedSliceId}` }],
|
|
1320
|
-
details: {
|
|
1321
|
-
operation: "reassess_roadmap",
|
|
1322
|
-
milestoneId: result.milestoneId,
|
|
1323
|
-
completedSliceId: result.completedSliceId,
|
|
1324
|
-
assessmentPath: result.assessmentPath,
|
|
1325
|
-
roadmapPath: result.roadmapPath,
|
|
1326
|
-
} as any,
|
|
1327
|
-
};
|
|
1328
|
-
} catch (err) {
|
|
1329
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
1330
|
-
logError("tool", `reassess_roadmap tool failed: ${msg}`, { tool: "gsd_reassess_roadmap", error: String(err) });
|
|
1331
|
-
return {
|
|
1332
|
-
content: [{ type: "text" as const, text: `Error reassessing roadmap: ${msg}` }],
|
|
1333
|
-
details: { operation: "reassess_roadmap", error: msg } as any,
|
|
1334
|
-
};
|
|
1335
|
-
}
|
|
967
|
+
return executeReassessRoadmap(params, process.cwd());
|
|
1336
968
|
};
|
|
1337
969
|
|
|
1338
970
|
const reassessRoadmapTool = {
|
|
@@ -1387,52 +1019,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
1387
1019
|
// ─── gsd_save_gate_result ──────────────────────────────────────────────
|
|
1388
1020
|
|
|
1389
1021
|
const saveGateResultExecute = async (_toolCallId: string, params: any, _signal: AbortSignal | undefined, _onUpdate: unknown, _ctx: unknown) => {
|
|
1390
|
-
|
|
1391
|
-
if (!dbAvailable) {
|
|
1392
|
-
return {
|
|
1393
|
-
content: [{ type: "text" as const, text: "Error: GSD database is not available." }],
|
|
1394
|
-
details: { operation: "save_gate_result", error: "db_unavailable" } as any,
|
|
1395
|
-
};
|
|
1396
|
-
}
|
|
1397
|
-
const validGates = ["Q3", "Q4", "Q5", "Q6", "Q7", "Q8"];
|
|
1398
|
-
if (!validGates.includes(params.gateId)) {
|
|
1399
|
-
return {
|
|
1400
|
-
content: [{ type: "text" as const, text: `Error: Invalid gateId "${params.gateId}". Must be one of: ${validGates.join(", ")}` }],
|
|
1401
|
-
details: { operation: "save_gate_result", error: "invalid_gate_id" } as any,
|
|
1402
|
-
};
|
|
1403
|
-
}
|
|
1404
|
-
const validVerdicts = ["pass", "flag", "omitted"];
|
|
1405
|
-
if (!validVerdicts.includes(params.verdict)) {
|
|
1406
|
-
return {
|
|
1407
|
-
content: [{ type: "text" as const, text: `Error: Invalid verdict "${params.verdict}". Must be one of: ${validVerdicts.join(", ")}` }],
|
|
1408
|
-
details: { operation: "save_gate_result", error: "invalid_verdict" } as any,
|
|
1409
|
-
};
|
|
1410
|
-
}
|
|
1411
|
-
try {
|
|
1412
|
-
const { saveGateResult } = await import("../gsd-db.js");
|
|
1413
|
-
const { invalidateStateCache } = await import("../state.js");
|
|
1414
|
-
saveGateResult({
|
|
1415
|
-
milestoneId: params.milestoneId,
|
|
1416
|
-
sliceId: params.sliceId,
|
|
1417
|
-
gateId: params.gateId,
|
|
1418
|
-
taskId: params.taskId ?? "",
|
|
1419
|
-
verdict: params.verdict,
|
|
1420
|
-
rationale: params.rationale,
|
|
1421
|
-
findings: params.findings ?? "",
|
|
1422
|
-
});
|
|
1423
|
-
invalidateStateCache();
|
|
1424
|
-
return {
|
|
1425
|
-
content: [{ type: "text" as const, text: `Gate ${params.gateId} result saved: verdict=${params.verdict}` }],
|
|
1426
|
-
details: { operation: "save_gate_result", gateId: params.gateId, verdict: params.verdict } as any,
|
|
1427
|
-
};
|
|
1428
|
-
} catch (err) {
|
|
1429
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
1430
|
-
logError("tool", `gsd_save_gate_result failed: ${msg}`, { tool: "gsd_save_gate_result", error: String(err) });
|
|
1431
|
-
return {
|
|
1432
|
-
content: [{ type: "text" as const, text: `Error saving gate result: ${msg}` }],
|
|
1433
|
-
details: { operation: "save_gate_result", error: msg } as any,
|
|
1434
|
-
};
|
|
1435
|
-
}
|
|
1022
|
+
return executeSaveGateResult(params, process.cwd());
|
|
1436
1023
|
};
|
|
1437
1024
|
|
|
1438
1025
|
const saveGateResultTool = {
|
|
@@ -75,12 +75,9 @@ export function resolveProjectRootDbPath(basePath: string): string {
|
|
|
75
75
|
return join(basePath, ".gsd", "gsd.db");
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
export async function ensureDbOpen(): Promise<boolean> {
|
|
78
|
+
export async function ensureDbOpen(basePath: string = process.cwd()): Promise<boolean> {
|
|
79
79
|
try {
|
|
80
80
|
const db = await import("../gsd-db.js");
|
|
81
|
-
if (db.isDbAvailable()) return true;
|
|
82
|
-
|
|
83
|
-
const basePath = process.cwd();
|
|
84
81
|
const dbPath = resolveProjectRootDbPath(basePath);
|
|
85
82
|
const gsdDir = join(basePath, ".gsd");
|
|
86
83
|
|
|
@@ -194,4 +191,3 @@ export function registerDynamicTools(pi: ExtensionAPI): void {
|
|
|
194
191
|
},
|
|
195
192
|
} as any);
|
|
196
193
|
}
|
|
197
|
-
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
import { Type } from "@sinclair/typebox";
|
|
4
4
|
import type { ExtensionAPI } from "@gsd/pi-coding-agent";
|
|
5
|
-
|
|
6
|
-
import {
|
|
5
|
+
import { ensureDbOpen } from "./dynamic-tools.js";
|
|
6
|
+
import { executeMilestoneStatus } from "../tools/workflow-tool-executors.js";
|
|
7
7
|
|
|
8
8
|
export function registerQueryTools(pi: ExtensionAPI): void {
|
|
9
9
|
pi.registerTool({
|
|
@@ -21,79 +21,14 @@ export function registerQueryTools(pi: ExtensionAPI): void {
|
|
|
21
21
|
milestoneId: Type.String({ description: "Milestone ID to query (e.g. M001)" }),
|
|
22
22
|
}),
|
|
23
23
|
async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
// ensureDbOpen() only creates/migrates when .gsd/ has content (#3644).
|
|
27
|
-
const { ensureDbOpen } = await import("./dynamic-tools.js");
|
|
28
|
-
const dbAvailable = await ensureDbOpen();
|
|
29
|
-
const {
|
|
30
|
-
getMilestone,
|
|
31
|
-
getSliceStatusSummary,
|
|
32
|
-
getSliceTaskCounts,
|
|
33
|
-
_getAdapter,
|
|
34
|
-
} = await import("../gsd-db.js");
|
|
35
|
-
|
|
36
|
-
if (!dbAvailable) {
|
|
37
|
-
return {
|
|
38
|
-
content: [{ type: "text" as const, text: "Error: GSD database is not available." }],
|
|
39
|
-
details: { operation: "milestone_status", error: "db_unavailable" } as any,
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// Wrap all reads in a single transaction for snapshot consistency.
|
|
44
|
-
// SQLite WAL mode guarantees reads within a transaction see a single
|
|
45
|
-
// consistent snapshot, preventing torn reads from concurrent writes.
|
|
46
|
-
const adapter = _getAdapter()!;
|
|
47
|
-
adapter.exec("BEGIN"); // eslint-disable-line -- SQLite exec, not child_process
|
|
48
|
-
try {
|
|
49
|
-
const milestone = getMilestone(params.milestoneId);
|
|
50
|
-
if (!milestone) {
|
|
51
|
-
adapter.exec("COMMIT"); // eslint-disable-line
|
|
52
|
-
return {
|
|
53
|
-
content: [{ type: "text" as const, text: `Milestone ${params.milestoneId} not found in database.` }],
|
|
54
|
-
details: { operation: "milestone_status", milestoneId: params.milestoneId, found: false } as any,
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const sliceStatuses = getSliceStatusSummary(params.milestoneId);
|
|
59
|
-
|
|
60
|
-
const slices = sliceStatuses.map((s) => {
|
|
61
|
-
const counts = getSliceTaskCounts(params.milestoneId, s.id);
|
|
62
|
-
return {
|
|
63
|
-
id: s.id,
|
|
64
|
-
status: s.status,
|
|
65
|
-
taskCounts: counts,
|
|
66
|
-
};
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
adapter.exec("COMMIT"); // eslint-disable-line
|
|
70
|
-
|
|
71
|
-
const result = {
|
|
72
|
-
milestoneId: milestone.id,
|
|
73
|
-
title: milestone.title,
|
|
74
|
-
status: milestone.status,
|
|
75
|
-
createdAt: milestone.created_at,
|
|
76
|
-
completedAt: milestone.completed_at,
|
|
77
|
-
sliceCount: slices.length,
|
|
78
|
-
slices,
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
return {
|
|
82
|
-
content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }],
|
|
83
|
-
details: { operation: "milestone_status", milestoneId: milestone.id, sliceCount: slices.length } as any,
|
|
84
|
-
};
|
|
85
|
-
} catch (txErr) {
|
|
86
|
-
try { adapter.exec("ROLLBACK"); } catch { /* swallow */ } // eslint-disable-line
|
|
87
|
-
throw txErr;
|
|
88
|
-
}
|
|
89
|
-
} catch (err) {
|
|
90
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
91
|
-
logWarning("tool", `gsd_milestone_status tool failed: ${msg}`);
|
|
24
|
+
const dbAvailable = await ensureDbOpen();
|
|
25
|
+
if (!dbAvailable) {
|
|
92
26
|
return {
|
|
93
|
-
content: [{ type: "text"
|
|
94
|
-
details: { operation: "milestone_status", error:
|
|
27
|
+
content: [{ type: "text", text: "Error: GSD database is not available. Cannot read milestone status." }],
|
|
28
|
+
details: { operation: "milestone_status", error: "db_unavailable" },
|
|
95
29
|
};
|
|
96
30
|
}
|
|
31
|
+
return executeMilestoneStatus(params);
|
|
97
32
|
},
|
|
98
33
|
});
|
|
99
34
|
}
|
|
@@ -168,7 +168,7 @@ export async function buildBeforeAgentStartResult(
|
|
|
168
168
|
const injection = await buildGuidedExecuteContextInjection(event.prompt, process.cwd());
|
|
169
169
|
|
|
170
170
|
// Re-inject forensics context on follow-up turns (#2941)
|
|
171
|
-
const forensicsInjection = !injection ? buildForensicsContextInjection(process.cwd()) : null;
|
|
171
|
+
const forensicsInjection = !injection ? buildForensicsContextInjection(process.cwd(), event.prompt) : null;
|
|
172
172
|
|
|
173
173
|
const worktreeBlock = buildWorktreeContextBlock();
|
|
174
174
|
const fullSystem = `${event.systemPrompt}\n\n[SYSTEM CONTEXT — GSD]\n\n${systemContent}${preferenceBlock}${knowledgeBlock}${codebaseBlock}${memoryBlock}${newSkillsBlock}${worktreeBlock}`;
|
|
@@ -481,7 +481,7 @@ function oneLine(text: string): string {
|
|
|
481
481
|
* Check for an active forensics session and return the prompt content
|
|
482
482
|
* so it can be re-injected on follow-up turns.
|
|
483
483
|
*/
|
|
484
|
-
function buildForensicsContextInjection(basePath: string): string | null {
|
|
484
|
+
export function buildForensicsContextInjection(basePath: string, prompt: string): string | null {
|
|
485
485
|
const marker = readForensicsMarker(basePath);
|
|
486
486
|
if (!marker) return null;
|
|
487
487
|
|
|
@@ -492,6 +492,12 @@ function buildForensicsContextInjection(basePath: string): string | null {
|
|
|
492
492
|
return null;
|
|
493
493
|
}
|
|
494
494
|
|
|
495
|
+
const trimmed = prompt.trim().toLowerCase().replace(/[.!?,]+$/g, "");
|
|
496
|
+
if (trimmed && !RESUME_INTENT_PATTERNS.test(trimmed)) {
|
|
497
|
+
clearForensicsMarker(basePath);
|
|
498
|
+
return null;
|
|
499
|
+
}
|
|
500
|
+
|
|
495
501
|
return marker.promptContent;
|
|
496
502
|
}
|
|
497
503
|
|