gsd-pi 2.67.0-dev.a5b1d8f → 2.67.0-dev.fe39184
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 +41 -31
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +121 -8
- package/dist/resources/extensions/gsd/auto/phases.js +17 -0
- package/dist/resources/extensions/gsd/auto/session.js +6 -0
- package/dist/resources/extensions/gsd/auto-direct-dispatch.js +12 -0
- package/dist/resources/extensions/gsd/auto-start.js +12 -0
- package/dist/resources/extensions/gsd/auto.js +27 -0
- 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/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/guided-flow.js +16 -0
- package/dist/resources/extensions/gsd/init-wizard.js +37 -0
- package/dist/resources/extensions/gsd/mcp-project-config.js +83 -0
- 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 +15 -15
- 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 +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.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 +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- 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-paths-manifest.json +15 -15
- 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/6502.5dcdcf1e1432e20d.js +9 -0
- package/dist/web/standalone/.next/static/chunks/{webpack-b49b09f97429b5d0.js → webpack-42a66876b763aa26.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/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/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/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 +157 -8
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +182 -0
- package/src/resources/extensions/gsd/auto/phases.ts +25 -0
- package/src/resources/extensions/gsd/auto/session.ts +6 -0
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +20 -0
- package/src/resources/extensions/gsd/auto-start.ts +15 -1
- package/src/resources/extensions/gsd/auto.ts +29 -1
- 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/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/guided-flow.ts +24 -0
- package/src/resources/extensions/gsd/init-wizard.ts +40 -0
- package/src/resources/extensions/gsd/mcp-project-config.ts +128 -0
- package/src/resources/extensions/gsd/tests/auto-project-root-env.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/core-overlay-fallback.test.ts +101 -0
- package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +66 -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/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/dist/web/standalone/.next/static/{NllX5BEOLdTXS9ypf1i3i → gbSATDX4Jt2ufxzUr5nYm}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{NllX5BEOLdTXS9ypf1i3i → gbSATDX4Jt2ufxzUr5nYm}/_ssgManifest.js +0 -0
|
@@ -241,6 +241,29 @@ const s = new AutoSession();
|
|
|
241
241
|
/** Throttle STATE.md rebuilds — at most once per 30 seconds */
|
|
242
242
|
const STATE_REBUILD_MIN_INTERVAL_MS = 30_000;
|
|
243
243
|
|
|
244
|
+
function captureProjectRootEnv(projectRoot: string): void {
|
|
245
|
+
if (!s.projectRootEnvCaptured) {
|
|
246
|
+
s.hadProjectRootEnv = Object.prototype.hasOwnProperty.call(process.env, "GSD_PROJECT_ROOT");
|
|
247
|
+
s.previousProjectRootEnv = process.env.GSD_PROJECT_ROOT ?? null;
|
|
248
|
+
s.projectRootEnvCaptured = true;
|
|
249
|
+
}
|
|
250
|
+
process.env.GSD_PROJECT_ROOT = projectRoot;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
function restoreProjectRootEnv(): void {
|
|
254
|
+
if (!s.projectRootEnvCaptured) return;
|
|
255
|
+
|
|
256
|
+
if (s.hadProjectRootEnv && s.previousProjectRootEnv !== null) {
|
|
257
|
+
process.env.GSD_PROJECT_ROOT = s.previousProjectRootEnv;
|
|
258
|
+
} else {
|
|
259
|
+
delete process.env.GSD_PROJECT_ROOT;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
s.previousProjectRootEnv = null;
|
|
263
|
+
s.hadProjectRootEnv = false;
|
|
264
|
+
s.projectRootEnvCaptured = false;
|
|
265
|
+
}
|
|
266
|
+
|
|
244
267
|
export function shouldUseWorktreeIsolation(): boolean {
|
|
245
268
|
const prefs = loadEffectiveGSDPreferences()?.preferences?.git;
|
|
246
269
|
if (prefs?.isolation === "worktree") return true;
|
|
@@ -542,6 +565,7 @@ function handleLostSessionLock(
|
|
|
542
565
|
s.active = false;
|
|
543
566
|
s.paused = false;
|
|
544
567
|
clearUnitTimeout();
|
|
568
|
+
restoreProjectRootEnv();
|
|
545
569
|
deregisterSigtermHandler();
|
|
546
570
|
clearCmuxSidebar(loadEffectiveGSDPreferences()?.preferences);
|
|
547
571
|
const base = lockBase();
|
|
@@ -577,6 +601,7 @@ function cleanupAfterLoopExit(ctx: ExtensionContext): void {
|
|
|
577
601
|
s.currentUnit = null;
|
|
578
602
|
s.active = false;
|
|
579
603
|
clearUnitTimeout();
|
|
604
|
+
restoreProjectRootEnv();
|
|
580
605
|
|
|
581
606
|
// Clear crash lock and release session lock so the next `/gsd next` does
|
|
582
607
|
// not see a stale lock with the current PID and treat it as a "remote"
|
|
@@ -846,6 +871,7 @@ export async function stopAuto(
|
|
|
846
871
|
ctx?.ui.setStatus("gsd-auto", undefined);
|
|
847
872
|
ctx?.ui.setWidget("gsd-progress", undefined);
|
|
848
873
|
ctx?.ui.setFooter(undefined);
|
|
874
|
+
restoreProjectRootEnv();
|
|
849
875
|
|
|
850
876
|
// Reset all session state in one call
|
|
851
877
|
s.reset();
|
|
@@ -934,6 +960,7 @@ export async function pauseAuto(
|
|
|
934
960
|
|
|
935
961
|
s.active = false;
|
|
936
962
|
s.paused = true;
|
|
963
|
+
restoreProjectRootEnv();
|
|
937
964
|
s.pendingVerificationRetry = null;
|
|
938
965
|
s.verificationRetryCount.clear();
|
|
939
966
|
ctx?.ui.setStatus("gsd-auto", "paused");
|
|
@@ -1305,6 +1332,7 @@ export async function startAuto(
|
|
|
1305
1332
|
);
|
|
1306
1333
|
logCmuxEvent(loadEffectiveGSDPreferences()?.preferences, s.stepMode ? "Step-mode resumed." : "Auto-mode resumed.", "progress");
|
|
1307
1334
|
|
|
1335
|
+
captureProjectRootEnv(s.originalBasePath || s.basePath);
|
|
1308
1336
|
await autoLoop(ctx, pi, s, buildLoopDeps());
|
|
1309
1337
|
cleanupAfterLoopExit(ctx);
|
|
1310
1338
|
return;
|
|
@@ -1329,6 +1357,7 @@ export async function startAuto(
|
|
|
1329
1357
|
);
|
|
1330
1358
|
if (!ready) return;
|
|
1331
1359
|
|
|
1360
|
+
captureProjectRootEnv(s.originalBasePath || s.basePath);
|
|
1332
1361
|
try {
|
|
1333
1362
|
syncCmuxSidebar(loadEffectiveGSDPreferences()?.preferences, await deriveState(s.basePath));
|
|
1334
1363
|
} catch (err) {
|
|
@@ -1569,4 +1598,3 @@ export {
|
|
|
1569
1598
|
buildLoopRemediationSteps,
|
|
1570
1599
|
} from "./auto-recovery.js";
|
|
1571
1600
|
export { resolveExpectedArtifactPath } from "./auto-artifact-paths.js";
|
|
1572
|
-
|
|
@@ -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
|
-
|