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
|
@@ -5,11 +5,7 @@ import { loadEffectiveGSDPreferences } from "../preferences.js";
|
|
|
5
5
|
import { ensureDbOpen } from "./dynamic-tools.js";
|
|
6
6
|
import { StringEnum } from "@gsd/pi-ai";
|
|
7
7
|
import { logError } from "../workflow-logger.js";
|
|
8
|
-
import {
|
|
9
|
-
const SUPPORTED_SUMMARY_ARTIFACT_TYPES = ["SUMMARY", "RESEARCH", "CONTEXT", "ASSESSMENT", "CONTEXT-DRAFT"];
|
|
10
|
-
export function isSupportedSummaryArtifactType(artifactType) {
|
|
11
|
-
return SUPPORTED_SUMMARY_ARTIFACT_TYPES.includes(artifactType);
|
|
12
|
-
}
|
|
8
|
+
import { executeCompleteMilestone, executePlanMilestone, executePlanSlice, executeReplanSlice, executeReassessRoadmap, executeSaveGateResult, executeSliceComplete, executeSummarySave, executeTaskComplete, executeValidateMilestone, } from "../tools/workflow-tool-executors.js";
|
|
13
9
|
/**
|
|
14
10
|
* Register an alias tool that shares the same execute function as its canonical counterpart.
|
|
15
11
|
* The alias description and promptGuidelines direct the LLM to prefer the canonical name.
|
|
@@ -272,59 +268,7 @@ export function registerDbTools(pi) {
|
|
|
272
268
|
registerAlias(pi, requirementSaveTool, "gsd_save_requirement", "gsd_requirement_save");
|
|
273
269
|
// ─── gsd_summary_save (formerly gsd_save_summary) ──────────────────────
|
|
274
270
|
const summarySaveExecute = async (_toolCallId, params, _signal, _onUpdate, _ctx) => {
|
|
275
|
-
|
|
276
|
-
if (!dbAvailable) {
|
|
277
|
-
return {
|
|
278
|
-
content: [{ type: "text", text: "Error: GSD database is not available. Cannot save artifact." }],
|
|
279
|
-
details: { operation: "save_summary", error: "db_unavailable" },
|
|
280
|
-
};
|
|
281
|
-
}
|
|
282
|
-
if (!isSupportedSummaryArtifactType(params.artifact_type)) {
|
|
283
|
-
return {
|
|
284
|
-
content: [{ type: "text", text: `Error: Invalid artifact_type "${params.artifact_type}". Must be one of: ${SUPPORTED_SUMMARY_ARTIFACT_TYPES.join(", ")}` }],
|
|
285
|
-
details: { operation: "save_summary", error: "invalid_artifact_type" },
|
|
286
|
-
};
|
|
287
|
-
}
|
|
288
|
-
const contextGuard = shouldBlockContextArtifactSave(params.artifact_type, params.milestone_id ?? null, params.slice_id ?? null);
|
|
289
|
-
if (contextGuard.block) {
|
|
290
|
-
return {
|
|
291
|
-
content: [{ type: "text", text: `Error saving artifact: ${contextGuard.reason ?? "context write blocked"}` }],
|
|
292
|
-
details: { operation: "save_summary", error: "context_write_blocked" },
|
|
293
|
-
};
|
|
294
|
-
}
|
|
295
|
-
try {
|
|
296
|
-
let relativePath;
|
|
297
|
-
if (params.task_id && params.slice_id) {
|
|
298
|
-
relativePath = `milestones/${params.milestone_id}/slices/${params.slice_id}/tasks/${params.task_id}-${params.artifact_type}.md`;
|
|
299
|
-
}
|
|
300
|
-
else if (params.slice_id) {
|
|
301
|
-
relativePath = `milestones/${params.milestone_id}/slices/${params.slice_id}/${params.slice_id}-${params.artifact_type}.md`;
|
|
302
|
-
}
|
|
303
|
-
else {
|
|
304
|
-
relativePath = `milestones/${params.milestone_id}/${params.milestone_id}-${params.artifact_type}.md`;
|
|
305
|
-
}
|
|
306
|
-
const { saveArtifactToDb } = await import("../db-writer.js");
|
|
307
|
-
await saveArtifactToDb({
|
|
308
|
-
path: relativePath,
|
|
309
|
-
artifact_type: params.artifact_type,
|
|
310
|
-
content: params.content,
|
|
311
|
-
milestone_id: params.milestone_id,
|
|
312
|
-
slice_id: params.slice_id,
|
|
313
|
-
task_id: params.task_id,
|
|
314
|
-
}, process.cwd());
|
|
315
|
-
return {
|
|
316
|
-
content: [{ type: "text", text: `Saved ${params.artifact_type} artifact to ${relativePath}` }],
|
|
317
|
-
details: { operation: "save_summary", path: relativePath, artifact_type: params.artifact_type },
|
|
318
|
-
};
|
|
319
|
-
}
|
|
320
|
-
catch (err) {
|
|
321
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
322
|
-
logError("tool", `gsd_summary_save tool failed: ${msg}`, { tool: "gsd_summary_save", error: String(err) });
|
|
323
|
-
return {
|
|
324
|
-
content: [{ type: "text", text: `Error saving artifact: ${msg}` }],
|
|
325
|
-
details: { operation: "save_summary", error: msg },
|
|
326
|
-
};
|
|
327
|
-
}
|
|
271
|
+
return executeSummarySave(params, process.cwd());
|
|
328
272
|
};
|
|
329
273
|
const summarySaveTool = {
|
|
330
274
|
name: "gsd_summary_save",
|
|
@@ -452,39 +396,7 @@ export function registerDbTools(pi) {
|
|
|
452
396
|
registerAlias(pi, milestoneGenerateIdTool, "gsd_generate_milestone_id", "gsd_milestone_generate_id");
|
|
453
397
|
// ─── gsd_plan_milestone (gsd_milestone_plan alias) ─────────────────────
|
|
454
398
|
const planMilestoneExecute = async (_toolCallId, params, _signal, _onUpdate, _ctx) => {
|
|
455
|
-
|
|
456
|
-
if (!dbAvailable) {
|
|
457
|
-
return {
|
|
458
|
-
content: [{ type: "text", text: "Error: GSD database is not available. Cannot plan milestone." }],
|
|
459
|
-
details: { operation: "plan_milestone", error: "db_unavailable" },
|
|
460
|
-
};
|
|
461
|
-
}
|
|
462
|
-
try {
|
|
463
|
-
const { handlePlanMilestone } = await import("../tools/plan-milestone.js");
|
|
464
|
-
const result = await handlePlanMilestone(params, process.cwd());
|
|
465
|
-
if ("error" in result) {
|
|
466
|
-
return {
|
|
467
|
-
content: [{ type: "text", text: `Error planning milestone: ${result.error}` }],
|
|
468
|
-
details: { operation: "plan_milestone", error: result.error },
|
|
469
|
-
};
|
|
470
|
-
}
|
|
471
|
-
return {
|
|
472
|
-
content: [{ type: "text", text: `Planned milestone ${result.milestoneId}` }],
|
|
473
|
-
details: {
|
|
474
|
-
operation: "plan_milestone",
|
|
475
|
-
milestoneId: result.milestoneId,
|
|
476
|
-
roadmapPath: result.roadmapPath,
|
|
477
|
-
},
|
|
478
|
-
};
|
|
479
|
-
}
|
|
480
|
-
catch (err) {
|
|
481
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
482
|
-
logError("tool", `plan_milestone tool failed: ${msg}`, { tool: "gsd_plan_milestone", error: String(err) });
|
|
483
|
-
return {
|
|
484
|
-
content: [{ type: "text", text: `Error planning milestone: ${msg}` }],
|
|
485
|
-
details: { operation: "plan_milestone", error: msg },
|
|
486
|
-
};
|
|
487
|
-
}
|
|
399
|
+
return executePlanMilestone(params, process.cwd());
|
|
488
400
|
};
|
|
489
401
|
const planMilestoneTool = {
|
|
490
402
|
name: "gsd_plan_milestone",
|
|
@@ -541,41 +453,7 @@ export function registerDbTools(pi) {
|
|
|
541
453
|
registerAlias(pi, planMilestoneTool, "gsd_milestone_plan", "gsd_plan_milestone");
|
|
542
454
|
// ─── gsd_plan_slice (gsd_slice_plan alias) ─────────────────────────────
|
|
543
455
|
const planSliceExecute = async (_toolCallId, params, _signal, _onUpdate, _ctx) => {
|
|
544
|
-
|
|
545
|
-
if (!dbAvailable) {
|
|
546
|
-
return {
|
|
547
|
-
content: [{ type: "text", text: "Error: GSD database is not available. Cannot plan slice." }],
|
|
548
|
-
details: { operation: "plan_slice", error: "db_unavailable" },
|
|
549
|
-
};
|
|
550
|
-
}
|
|
551
|
-
try {
|
|
552
|
-
const { handlePlanSlice } = await import("../tools/plan-slice.js");
|
|
553
|
-
const result = await handlePlanSlice(params, process.cwd());
|
|
554
|
-
if ("error" in result) {
|
|
555
|
-
return {
|
|
556
|
-
content: [{ type: "text", text: `Error planning slice: ${result.error}` }],
|
|
557
|
-
details: { operation: "plan_slice", error: result.error },
|
|
558
|
-
};
|
|
559
|
-
}
|
|
560
|
-
return {
|
|
561
|
-
content: [{ type: "text", text: `Planned slice ${result.sliceId} (${result.milestoneId})` }],
|
|
562
|
-
details: {
|
|
563
|
-
operation: "plan_slice",
|
|
564
|
-
milestoneId: result.milestoneId,
|
|
565
|
-
sliceId: result.sliceId,
|
|
566
|
-
planPath: result.planPath,
|
|
567
|
-
taskPlanPaths: result.taskPlanPaths,
|
|
568
|
-
},
|
|
569
|
-
};
|
|
570
|
-
}
|
|
571
|
-
catch (err) {
|
|
572
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
573
|
-
logError("tool", `plan_slice tool failed: ${msg}`, { tool: "gsd_plan_slice", error: String(err) });
|
|
574
|
-
return {
|
|
575
|
-
content: [{ type: "text", text: `Error planning slice: ${msg}` }],
|
|
576
|
-
details: { operation: "plan_slice", error: msg },
|
|
577
|
-
};
|
|
578
|
-
}
|
|
456
|
+
return executePlanSlice(params, process.cwd());
|
|
579
457
|
};
|
|
580
458
|
const planSliceTool = {
|
|
581
459
|
name: "gsd_plan_slice",
|
|
@@ -682,44 +560,7 @@ export function registerDbTools(pi) {
|
|
|
682
560
|
registerAlias(pi, planTaskTool, "gsd_task_plan", "gsd_plan_task");
|
|
683
561
|
// ─── gsd_task_complete (gsd_complete_task alias) ────────────────────────
|
|
684
562
|
const taskCompleteExecute = async (_toolCallId, params, _signal, _onUpdate, _ctx) => {
|
|
685
|
-
|
|
686
|
-
if (!dbAvailable) {
|
|
687
|
-
return {
|
|
688
|
-
content: [{ type: "text", text: "Error: GSD database is not available. Cannot complete task." }],
|
|
689
|
-
details: { operation: "complete_task", error: "db_unavailable" },
|
|
690
|
-
};
|
|
691
|
-
}
|
|
692
|
-
try {
|
|
693
|
-
// Coerce string items to objects for verificationEvidence (#3541).
|
|
694
|
-
const coerced = { ...params };
|
|
695
|
-
coerced.verificationEvidence = (params.verificationEvidence ?? []).map((v) => typeof v === "string" ? { command: v, exitCode: -1, verdict: "unknown (coerced from string)", durationMs: 0 } : v);
|
|
696
|
-
const { handleCompleteTask } = await import("../tools/complete-task.js");
|
|
697
|
-
const result = await handleCompleteTask(coerced, process.cwd());
|
|
698
|
-
if ("error" in result) {
|
|
699
|
-
return {
|
|
700
|
-
content: [{ type: "text", text: `Error completing task: ${result.error}` }],
|
|
701
|
-
details: { operation: "complete_task", error: result.error },
|
|
702
|
-
};
|
|
703
|
-
}
|
|
704
|
-
return {
|
|
705
|
-
content: [{ type: "text", text: `Completed task ${result.taskId} (${result.sliceId}/${result.milestoneId})` }],
|
|
706
|
-
details: {
|
|
707
|
-
operation: "complete_task",
|
|
708
|
-
taskId: result.taskId,
|
|
709
|
-
sliceId: result.sliceId,
|
|
710
|
-
milestoneId: result.milestoneId,
|
|
711
|
-
summaryPath: result.summaryPath,
|
|
712
|
-
},
|
|
713
|
-
};
|
|
714
|
-
}
|
|
715
|
-
catch (err) {
|
|
716
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
717
|
-
logError("tool", `complete_task tool failed: ${msg}`, { tool: "gsd_task_complete", error: String(err) });
|
|
718
|
-
return {
|
|
719
|
-
content: [{ type: "text", text: `Error completing task: ${msg}` }],
|
|
720
|
-
details: { operation: "complete_task", error: msg },
|
|
721
|
-
};
|
|
722
|
-
}
|
|
563
|
+
return executeTaskComplete(params, process.cwd());
|
|
723
564
|
};
|
|
724
565
|
const taskCompleteTool = {
|
|
725
566
|
name: "gsd_task_complete",
|
|
@@ -764,90 +605,7 @@ export function registerDbTools(pi) {
|
|
|
764
605
|
registerAlias(pi, taskCompleteTool, "gsd_complete_task", "gsd_task_complete");
|
|
765
606
|
// ─── gsd_slice_complete (gsd_complete_slice alias) ─────────────────────
|
|
766
607
|
const sliceCompleteExecute = async (_toolCallId, params, _signal, _onUpdate, _ctx) => {
|
|
767
|
-
|
|
768
|
-
if (!dbAvailable) {
|
|
769
|
-
return {
|
|
770
|
-
content: [{ type: "text", text: "Error: GSD database is not available. Cannot complete slice." }],
|
|
771
|
-
details: { operation: "complete_slice", error: "db_unavailable" },
|
|
772
|
-
};
|
|
773
|
-
}
|
|
774
|
-
try {
|
|
775
|
-
// Coerce string items to objects for fields where LLMs sometimes pass
|
|
776
|
-
// plain strings instead of the expected { key, value } shape (#3541).
|
|
777
|
-
// Parses "key — value" or "key - value" format when possible.
|
|
778
|
-
const splitPair = (s) => {
|
|
779
|
-
const m = s.match(/^(.+?)\s*(?:—|-)\s+(.+)$/);
|
|
780
|
-
return m ? [m[1].trim(), m[2].trim()] : [s.trim(), ""];
|
|
781
|
-
};
|
|
782
|
-
const coerced = { ...params };
|
|
783
|
-
// Coerce simple string-array fields: LLMs sometimes pass a plain string
|
|
784
|
-
// instead of a single-element array (#3585).
|
|
785
|
-
const wrapArray = (v) => v == null ? [] : Array.isArray(v) ? v : [v];
|
|
786
|
-
coerced.provides = wrapArray(params.provides);
|
|
787
|
-
coerced.keyFiles = wrapArray(params.keyFiles);
|
|
788
|
-
coerced.keyDecisions = wrapArray(params.keyDecisions);
|
|
789
|
-
coerced.patternsEstablished = wrapArray(params.patternsEstablished);
|
|
790
|
-
coerced.observabilitySurfaces = wrapArray(params.observabilitySurfaces);
|
|
791
|
-
coerced.requirementsSurfaced = wrapArray(params.requirementsSurfaced);
|
|
792
|
-
coerced.drillDownPaths = wrapArray(params.drillDownPaths);
|
|
793
|
-
coerced.affects = wrapArray(params.affects);
|
|
794
|
-
coerced.filesModified = wrapArray(params.filesModified).map((f) => {
|
|
795
|
-
if (typeof f !== "string")
|
|
796
|
-
return f;
|
|
797
|
-
const [path, description] = splitPair(f);
|
|
798
|
-
return { path, description };
|
|
799
|
-
});
|
|
800
|
-
coerced.requires = wrapArray(params.requires).map((r) => {
|
|
801
|
-
if (typeof r !== "string")
|
|
802
|
-
return r;
|
|
803
|
-
const [slice, provides] = splitPair(r);
|
|
804
|
-
return { slice, provides };
|
|
805
|
-
});
|
|
806
|
-
coerced.requirementsAdvanced = wrapArray(params.requirementsAdvanced).map((r) => {
|
|
807
|
-
if (typeof r !== "string")
|
|
808
|
-
return r;
|
|
809
|
-
const [id, how] = splitPair(r);
|
|
810
|
-
return { id, how };
|
|
811
|
-
});
|
|
812
|
-
coerced.requirementsValidated = wrapArray(params.requirementsValidated).map((r) => {
|
|
813
|
-
if (typeof r !== "string")
|
|
814
|
-
return r;
|
|
815
|
-
const [id, proof] = splitPair(r);
|
|
816
|
-
return { id, proof };
|
|
817
|
-
});
|
|
818
|
-
coerced.requirementsInvalidated = wrapArray(params.requirementsInvalidated).map((r) => {
|
|
819
|
-
if (typeof r !== "string")
|
|
820
|
-
return r;
|
|
821
|
-
const [id, what] = splitPair(r);
|
|
822
|
-
return { id, what };
|
|
823
|
-
});
|
|
824
|
-
const { handleCompleteSlice } = await import("../tools/complete-slice.js");
|
|
825
|
-
const result = await handleCompleteSlice(coerced, process.cwd());
|
|
826
|
-
if ("error" in result) {
|
|
827
|
-
return {
|
|
828
|
-
content: [{ type: "text", text: `Error completing slice: ${result.error}` }],
|
|
829
|
-
details: { operation: "complete_slice", error: result.error },
|
|
830
|
-
};
|
|
831
|
-
}
|
|
832
|
-
return {
|
|
833
|
-
content: [{ type: "text", text: `Completed slice ${result.sliceId} (${result.milestoneId})` }],
|
|
834
|
-
details: {
|
|
835
|
-
operation: "complete_slice",
|
|
836
|
-
sliceId: result.sliceId,
|
|
837
|
-
milestoneId: result.milestoneId,
|
|
838
|
-
summaryPath: result.summaryPath,
|
|
839
|
-
uatPath: result.uatPath,
|
|
840
|
-
},
|
|
841
|
-
};
|
|
842
|
-
}
|
|
843
|
-
catch (err) {
|
|
844
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
845
|
-
logError("tool", `complete_slice tool failed: ${msg}`, { tool: "gsd_slice_complete", error: String(err) });
|
|
846
|
-
return {
|
|
847
|
-
content: [{ type: "text", text: `Error completing slice: ${msg}` }],
|
|
848
|
-
details: { operation: "complete_slice", error: msg },
|
|
849
|
-
};
|
|
850
|
-
}
|
|
608
|
+
return executeSliceComplete(params, process.cwd());
|
|
851
609
|
};
|
|
852
610
|
const sliceCompleteTool = {
|
|
853
611
|
name: "gsd_slice_complete",
|
|
@@ -1004,42 +762,7 @@ export function registerDbTools(pi) {
|
|
|
1004
762
|
});
|
|
1005
763
|
// ─── gsd_complete_milestone ────────────────────────────────────────────
|
|
1006
764
|
const milestoneCompleteExecute = async (_toolCallId, params, _signal, _onUpdate, _ctx) => {
|
|
1007
|
-
|
|
1008
|
-
if (!dbAvailable) {
|
|
1009
|
-
return {
|
|
1010
|
-
content: [{ type: "text", text: "Error: GSD database is not available. Cannot complete milestone." }],
|
|
1011
|
-
details: { operation: "complete_milestone", error: "db_unavailable" },
|
|
1012
|
-
};
|
|
1013
|
-
}
|
|
1014
|
-
try {
|
|
1015
|
-
// ── Input sanitization: normalize markdown parameters (#3013) ──────
|
|
1016
|
-
const { sanitizeCompleteMilestoneParams } = await import("./sanitize-complete-milestone.js");
|
|
1017
|
-
const sanitized = sanitizeCompleteMilestoneParams(params);
|
|
1018
|
-
const { handleCompleteMilestone } = await import("../tools/complete-milestone.js");
|
|
1019
|
-
const result = await handleCompleteMilestone(sanitized, process.cwd());
|
|
1020
|
-
if ("error" in result) {
|
|
1021
|
-
return {
|
|
1022
|
-
content: [{ type: "text", text: `Error completing milestone: ${result.error}` }],
|
|
1023
|
-
details: { operation: "complete_milestone", error: result.error },
|
|
1024
|
-
};
|
|
1025
|
-
}
|
|
1026
|
-
return {
|
|
1027
|
-
content: [{ type: "text", text: `Completed milestone ${result.milestoneId}. Summary written to ${result.summaryPath}` }],
|
|
1028
|
-
details: {
|
|
1029
|
-
operation: "complete_milestone",
|
|
1030
|
-
milestoneId: result.milestoneId,
|
|
1031
|
-
summaryPath: result.summaryPath,
|
|
1032
|
-
},
|
|
1033
|
-
};
|
|
1034
|
-
}
|
|
1035
|
-
catch (err) {
|
|
1036
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
1037
|
-
logError("tool", `complete_milestone tool failed: ${msg}`, { tool: "gsd_complete_milestone", error: String(err) });
|
|
1038
|
-
return {
|
|
1039
|
-
content: [{ type: "text", text: `Error completing milestone: ${msg}` }],
|
|
1040
|
-
details: { operation: "complete_milestone", error: msg },
|
|
1041
|
-
};
|
|
1042
|
-
}
|
|
765
|
+
return executeCompleteMilestone(params, process.cwd());
|
|
1043
766
|
};
|
|
1044
767
|
const milestoneCompleteTool = {
|
|
1045
768
|
name: "gsd_complete_milestone",
|
|
@@ -1076,40 +799,7 @@ export function registerDbTools(pi) {
|
|
|
1076
799
|
registerAlias(pi, milestoneCompleteTool, "gsd_milestone_complete", "gsd_complete_milestone");
|
|
1077
800
|
// ─── gsd_validate_milestone (gsd_milestone_validate alias) ─────────────
|
|
1078
801
|
const milestoneValidateExecute = async (_toolCallId, params, _signal, _onUpdate, _ctx) => {
|
|
1079
|
-
|
|
1080
|
-
if (!dbAvailable) {
|
|
1081
|
-
return {
|
|
1082
|
-
content: [{ type: "text", text: "Error: GSD database is not available. Cannot validate milestone." }],
|
|
1083
|
-
details: { operation: "validate_milestone", error: "db_unavailable" },
|
|
1084
|
-
};
|
|
1085
|
-
}
|
|
1086
|
-
try {
|
|
1087
|
-
const { handleValidateMilestone } = await import("../tools/validate-milestone.js");
|
|
1088
|
-
const result = await handleValidateMilestone(params, process.cwd());
|
|
1089
|
-
if ("error" in result) {
|
|
1090
|
-
return {
|
|
1091
|
-
content: [{ type: "text", text: `Error validating milestone: ${result.error}` }],
|
|
1092
|
-
details: { operation: "validate_milestone", error: result.error },
|
|
1093
|
-
};
|
|
1094
|
-
}
|
|
1095
|
-
return {
|
|
1096
|
-
content: [{ type: "text", text: `Validated milestone ${result.milestoneId} — verdict: ${result.verdict}. Written to ${result.validationPath}` }],
|
|
1097
|
-
details: {
|
|
1098
|
-
operation: "validate_milestone",
|
|
1099
|
-
milestoneId: result.milestoneId,
|
|
1100
|
-
verdict: result.verdict,
|
|
1101
|
-
validationPath: result.validationPath,
|
|
1102
|
-
},
|
|
1103
|
-
};
|
|
1104
|
-
}
|
|
1105
|
-
catch (err) {
|
|
1106
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
1107
|
-
logError("tool", `validate_milestone tool failed: ${msg}`, { tool: "gsd_validate_milestone", error: String(err) });
|
|
1108
|
-
return {
|
|
1109
|
-
content: [{ type: "text", text: `Error validating milestone: ${msg}` }],
|
|
1110
|
-
details: { operation: "validate_milestone", error: msg },
|
|
1111
|
-
};
|
|
1112
|
-
}
|
|
802
|
+
return executeValidateMilestone(params, process.cwd());
|
|
1113
803
|
};
|
|
1114
804
|
const milestoneValidateTool = {
|
|
1115
805
|
name: "gsd_validate_milestone",
|
|
@@ -1141,41 +831,7 @@ export function registerDbTools(pi) {
|
|
|
1141
831
|
registerAlias(pi, milestoneValidateTool, "gsd_milestone_validate", "gsd_validate_milestone");
|
|
1142
832
|
// ─── gsd_replan_slice (gsd_slice_replan alias) ─────────────────────────
|
|
1143
833
|
const replanSliceExecute = async (_toolCallId, params, _signal, _onUpdate, _ctx) => {
|
|
1144
|
-
|
|
1145
|
-
if (!dbAvailable) {
|
|
1146
|
-
return {
|
|
1147
|
-
content: [{ type: "text", text: "Error: GSD database is not available. Cannot replan slice." }],
|
|
1148
|
-
details: { operation: "replan_slice", error: "db_unavailable" },
|
|
1149
|
-
};
|
|
1150
|
-
}
|
|
1151
|
-
try {
|
|
1152
|
-
const { handleReplanSlice } = await import("../tools/replan-slice.js");
|
|
1153
|
-
const result = await handleReplanSlice(params, process.cwd());
|
|
1154
|
-
if ("error" in result) {
|
|
1155
|
-
return {
|
|
1156
|
-
content: [{ type: "text", text: `Error replanning slice: ${result.error}` }],
|
|
1157
|
-
details: { operation: "replan_slice", error: result.error },
|
|
1158
|
-
};
|
|
1159
|
-
}
|
|
1160
|
-
return {
|
|
1161
|
-
content: [{ type: "text", text: `Replanned slice ${result.sliceId} (${result.milestoneId})` }],
|
|
1162
|
-
details: {
|
|
1163
|
-
operation: "replan_slice",
|
|
1164
|
-
milestoneId: result.milestoneId,
|
|
1165
|
-
sliceId: result.sliceId,
|
|
1166
|
-
replanPath: result.replanPath,
|
|
1167
|
-
planPath: result.planPath,
|
|
1168
|
-
},
|
|
1169
|
-
};
|
|
1170
|
-
}
|
|
1171
|
-
catch (err) {
|
|
1172
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
1173
|
-
logError("tool", `replan_slice tool failed: ${msg}`, { tool: "gsd_replan_slice", error: String(err) });
|
|
1174
|
-
return {
|
|
1175
|
-
content: [{ type: "text", text: `Error replanning slice: ${msg}` }],
|
|
1176
|
-
details: { operation: "replan_slice", error: msg },
|
|
1177
|
-
};
|
|
1178
|
-
}
|
|
834
|
+
return executeReplanSlice(params, process.cwd());
|
|
1179
835
|
};
|
|
1180
836
|
const replanSliceTool = {
|
|
1181
837
|
name: "gsd_replan_slice",
|
|
@@ -1214,41 +870,7 @@ export function registerDbTools(pi) {
|
|
|
1214
870
|
registerAlias(pi, replanSliceTool, "gsd_slice_replan", "gsd_replan_slice");
|
|
1215
871
|
// ─── gsd_reassess_roadmap (gsd_roadmap_reassess alias) ─────────────────
|
|
1216
872
|
const reassessRoadmapExecute = async (_toolCallId, params, _signal, _onUpdate, _ctx) => {
|
|
1217
|
-
|
|
1218
|
-
if (!dbAvailable) {
|
|
1219
|
-
return {
|
|
1220
|
-
content: [{ type: "text", text: "Error: GSD database is not available. Cannot reassess roadmap." }],
|
|
1221
|
-
details: { operation: "reassess_roadmap", error: "db_unavailable" },
|
|
1222
|
-
};
|
|
1223
|
-
}
|
|
1224
|
-
try {
|
|
1225
|
-
const { handleReassessRoadmap } = await import("../tools/reassess-roadmap.js");
|
|
1226
|
-
const result = await handleReassessRoadmap(params, process.cwd());
|
|
1227
|
-
if ("error" in result) {
|
|
1228
|
-
return {
|
|
1229
|
-
content: [{ type: "text", text: `Error reassessing roadmap: ${result.error}` }],
|
|
1230
|
-
details: { operation: "reassess_roadmap", error: result.error },
|
|
1231
|
-
};
|
|
1232
|
-
}
|
|
1233
|
-
return {
|
|
1234
|
-
content: [{ type: "text", text: `Reassessed roadmap for milestone ${result.milestoneId} after ${result.completedSliceId}` }],
|
|
1235
|
-
details: {
|
|
1236
|
-
operation: "reassess_roadmap",
|
|
1237
|
-
milestoneId: result.milestoneId,
|
|
1238
|
-
completedSliceId: result.completedSliceId,
|
|
1239
|
-
assessmentPath: result.assessmentPath,
|
|
1240
|
-
roadmapPath: result.roadmapPath,
|
|
1241
|
-
},
|
|
1242
|
-
};
|
|
1243
|
-
}
|
|
1244
|
-
catch (err) {
|
|
1245
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
1246
|
-
logError("tool", `reassess_roadmap tool failed: ${msg}`, { tool: "gsd_reassess_roadmap", error: String(err) });
|
|
1247
|
-
return {
|
|
1248
|
-
content: [{ type: "text", text: `Error reassessing roadmap: ${msg}` }],
|
|
1249
|
-
details: { operation: "reassess_roadmap", error: msg },
|
|
1250
|
-
};
|
|
1251
|
-
}
|
|
873
|
+
return executeReassessRoadmap(params, process.cwd());
|
|
1252
874
|
};
|
|
1253
875
|
const reassessRoadmapTool = {
|
|
1254
876
|
name: "gsd_reassess_roadmap",
|
|
@@ -1292,53 +914,7 @@ export function registerDbTools(pi) {
|
|
|
1292
914
|
registerAlias(pi, reassessRoadmapTool, "gsd_roadmap_reassess", "gsd_reassess_roadmap");
|
|
1293
915
|
// ─── gsd_save_gate_result ──────────────────────────────────────────────
|
|
1294
916
|
const saveGateResultExecute = async (_toolCallId, params, _signal, _onUpdate, _ctx) => {
|
|
1295
|
-
|
|
1296
|
-
if (!dbAvailable) {
|
|
1297
|
-
return {
|
|
1298
|
-
content: [{ type: "text", text: "Error: GSD database is not available." }],
|
|
1299
|
-
details: { operation: "save_gate_result", error: "db_unavailable" },
|
|
1300
|
-
};
|
|
1301
|
-
}
|
|
1302
|
-
const validGates = ["Q3", "Q4", "Q5", "Q6", "Q7", "Q8"];
|
|
1303
|
-
if (!validGates.includes(params.gateId)) {
|
|
1304
|
-
return {
|
|
1305
|
-
content: [{ type: "text", text: `Error: Invalid gateId "${params.gateId}". Must be one of: ${validGates.join(", ")}` }],
|
|
1306
|
-
details: { operation: "save_gate_result", error: "invalid_gate_id" },
|
|
1307
|
-
};
|
|
1308
|
-
}
|
|
1309
|
-
const validVerdicts = ["pass", "flag", "omitted"];
|
|
1310
|
-
if (!validVerdicts.includes(params.verdict)) {
|
|
1311
|
-
return {
|
|
1312
|
-
content: [{ type: "text", text: `Error: Invalid verdict "${params.verdict}". Must be one of: ${validVerdicts.join(", ")}` }],
|
|
1313
|
-
details: { operation: "save_gate_result", error: "invalid_verdict" },
|
|
1314
|
-
};
|
|
1315
|
-
}
|
|
1316
|
-
try {
|
|
1317
|
-
const { saveGateResult } = await import("../gsd-db.js");
|
|
1318
|
-
const { invalidateStateCache } = await import("../state.js");
|
|
1319
|
-
saveGateResult({
|
|
1320
|
-
milestoneId: params.milestoneId,
|
|
1321
|
-
sliceId: params.sliceId,
|
|
1322
|
-
gateId: params.gateId,
|
|
1323
|
-
taskId: params.taskId ?? "",
|
|
1324
|
-
verdict: params.verdict,
|
|
1325
|
-
rationale: params.rationale,
|
|
1326
|
-
findings: params.findings ?? "",
|
|
1327
|
-
});
|
|
1328
|
-
invalidateStateCache();
|
|
1329
|
-
return {
|
|
1330
|
-
content: [{ type: "text", text: `Gate ${params.gateId} result saved: verdict=${params.verdict}` }],
|
|
1331
|
-
details: { operation: "save_gate_result", gateId: params.gateId, verdict: params.verdict },
|
|
1332
|
-
};
|
|
1333
|
-
}
|
|
1334
|
-
catch (err) {
|
|
1335
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
1336
|
-
logError("tool", `gsd_save_gate_result failed: ${msg}`, { tool: "gsd_save_gate_result", error: String(err) });
|
|
1337
|
-
return {
|
|
1338
|
-
content: [{ type: "text", text: `Error saving gate result: ${msg}` }],
|
|
1339
|
-
details: { operation: "save_gate_result", error: msg },
|
|
1340
|
-
};
|
|
1341
|
-
}
|
|
917
|
+
return executeSaveGateResult(params, process.cwd());
|
|
1342
918
|
};
|
|
1343
919
|
const saveGateResultTool = {
|
|
1344
920
|
name: "gsd_save_gate_result",
|
|
@@ -64,12 +64,9 @@ export function resolveProjectRootDbPath(basePath) {
|
|
|
64
64
|
}
|
|
65
65
|
return join(basePath, ".gsd", "gsd.db");
|
|
66
66
|
}
|
|
67
|
-
export async function ensureDbOpen() {
|
|
67
|
+
export async function ensureDbOpen(basePath = process.cwd()) {
|
|
68
68
|
try {
|
|
69
69
|
const db = await import("../gsd-db.js");
|
|
70
|
-
if (db.isDbAvailable())
|
|
71
|
-
return true;
|
|
72
|
-
const basePath = process.cwd();
|
|
73
70
|
const dbPath = resolveProjectRootDbPath(basePath);
|
|
74
71
|
const gsdDir = join(basePath, ".gsd");
|
|
75
72
|
// Derive the project root from the DB path (strip .gsd/gsd.db)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// GSD2 — Read-only query tools exposing DB state to the LLM via the WAL connection
|
|
2
2
|
import { Type } from "@sinclair/typebox";
|
|
3
|
-
import {
|
|
3
|
+
import { ensureDbOpen } from "./dynamic-tools.js";
|
|
4
|
+
import { executeMilestoneStatus } from "../tools/workflow-tool-executors.js";
|
|
4
5
|
export function registerQueryTools(pi) {
|
|
5
6
|
pi.registerTool({
|
|
6
7
|
name: "gsd_milestone_status",
|
|
@@ -16,72 +17,14 @@ export function registerQueryTools(pi) {
|
|
|
16
17
|
milestoneId: Type.String({ description: "Milestone ID to query (e.g. M001)" }),
|
|
17
18
|
}),
|
|
18
19
|
async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
// ensureDbOpen() only creates/migrates when .gsd/ has content (#3644).
|
|
22
|
-
const { ensureDbOpen } = await import("./dynamic-tools.js");
|
|
23
|
-
const dbAvailable = await ensureDbOpen();
|
|
24
|
-
const { getMilestone, getSliceStatusSummary, getSliceTaskCounts, _getAdapter, } = await import("../gsd-db.js");
|
|
25
|
-
if (!dbAvailable) {
|
|
26
|
-
return {
|
|
27
|
-
content: [{ type: "text", text: "Error: GSD database is not available." }],
|
|
28
|
-
details: { operation: "milestone_status", error: "db_unavailable" },
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
// Wrap all reads in a single transaction for snapshot consistency.
|
|
32
|
-
// SQLite WAL mode guarantees reads within a transaction see a single
|
|
33
|
-
// consistent snapshot, preventing torn reads from concurrent writes.
|
|
34
|
-
const adapter = _getAdapter();
|
|
35
|
-
adapter.exec("BEGIN"); // eslint-disable-line -- SQLite exec, not child_process
|
|
36
|
-
try {
|
|
37
|
-
const milestone = getMilestone(params.milestoneId);
|
|
38
|
-
if (!milestone) {
|
|
39
|
-
adapter.exec("COMMIT"); // eslint-disable-line
|
|
40
|
-
return {
|
|
41
|
-
content: [{ type: "text", text: `Milestone ${params.milestoneId} not found in database.` }],
|
|
42
|
-
details: { operation: "milestone_status", milestoneId: params.milestoneId, found: false },
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
const sliceStatuses = getSliceStatusSummary(params.milestoneId);
|
|
46
|
-
const slices = sliceStatuses.map((s) => {
|
|
47
|
-
const counts = getSliceTaskCounts(params.milestoneId, s.id);
|
|
48
|
-
return {
|
|
49
|
-
id: s.id,
|
|
50
|
-
status: s.status,
|
|
51
|
-
taskCounts: counts,
|
|
52
|
-
};
|
|
53
|
-
});
|
|
54
|
-
adapter.exec("COMMIT"); // eslint-disable-line
|
|
55
|
-
const result = {
|
|
56
|
-
milestoneId: milestone.id,
|
|
57
|
-
title: milestone.title,
|
|
58
|
-
status: milestone.status,
|
|
59
|
-
createdAt: milestone.created_at,
|
|
60
|
-
completedAt: milestone.completed_at,
|
|
61
|
-
sliceCount: slices.length,
|
|
62
|
-
slices,
|
|
63
|
-
};
|
|
64
|
-
return {
|
|
65
|
-
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
66
|
-
details: { operation: "milestone_status", milestoneId: milestone.id, sliceCount: slices.length },
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
catch (txErr) {
|
|
70
|
-
try {
|
|
71
|
-
adapter.exec("ROLLBACK");
|
|
72
|
-
}
|
|
73
|
-
catch { /* swallow */ } // eslint-disable-line
|
|
74
|
-
throw txErr;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
catch (err) {
|
|
78
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
79
|
-
logWarning("tool", `gsd_milestone_status tool failed: ${msg}`);
|
|
20
|
+
const dbAvailable = await ensureDbOpen();
|
|
21
|
+
if (!dbAvailable) {
|
|
80
22
|
return {
|
|
81
|
-
content: [{ type: "text", text:
|
|
82
|
-
details: { operation: "milestone_status", error:
|
|
23
|
+
content: [{ type: "text", text: "Error: GSD database is not available. Cannot read milestone status." }],
|
|
24
|
+
details: { operation: "milestone_status", error: "db_unavailable" },
|
|
83
25
|
};
|
|
84
26
|
}
|
|
27
|
+
return executeMilestoneStatus(params);
|
|
85
28
|
},
|
|
86
29
|
});
|
|
87
30
|
}
|
|
@@ -141,7 +141,7 @@ export async function buildBeforeAgentStartResult(event, ctx) {
|
|
|
141
141
|
warnDeprecatedAgentInstructions();
|
|
142
142
|
const injection = await buildGuidedExecuteContextInjection(event.prompt, process.cwd());
|
|
143
143
|
// Re-inject forensics context on follow-up turns (#2941)
|
|
144
|
-
const forensicsInjection = !injection ? buildForensicsContextInjection(process.cwd()) : null;
|
|
144
|
+
const forensicsInjection = !injection ? buildForensicsContextInjection(process.cwd(), event.prompt) : null;
|
|
145
145
|
const worktreeBlock = buildWorktreeContextBlock();
|
|
146
146
|
const fullSystem = `${event.systemPrompt}\n\n[SYSTEM CONTEXT — GSD]\n\n${systemContent}${preferenceBlock}${knowledgeBlock}${codebaseBlock}${memoryBlock}${newSkillsBlock}${worktreeBlock}`;
|
|
147
147
|
stopContextTimer({
|
|
@@ -425,7 +425,7 @@ function oneLine(text) {
|
|
|
425
425
|
* Check for an active forensics session and return the prompt content
|
|
426
426
|
* so it can be re-injected on follow-up turns.
|
|
427
427
|
*/
|
|
428
|
-
function buildForensicsContextInjection(basePath) {
|
|
428
|
+
export function buildForensicsContextInjection(basePath, prompt) {
|
|
429
429
|
const marker = readForensicsMarker(basePath);
|
|
430
430
|
if (!marker)
|
|
431
431
|
return null;
|
|
@@ -435,6 +435,11 @@ function buildForensicsContextInjection(basePath) {
|
|
|
435
435
|
clearForensicsMarker(basePath);
|
|
436
436
|
return null;
|
|
437
437
|
}
|
|
438
|
+
const trimmed = prompt.trim().toLowerCase().replace(/[.!?,]+$/g, "");
|
|
439
|
+
if (trimmed && !RESUME_INTENT_PATTERNS.test(trimmed)) {
|
|
440
|
+
clearForensicsMarker(basePath);
|
|
441
|
+
return null;
|
|
442
|
+
}
|
|
438
443
|
return marker.promptContent;
|
|
439
444
|
}
|
|
440
445
|
/**
|