gsd-pi 2.67.0-dev.509bd95 → 2.67.0-dev.6fc2289
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 +152 -70
- package/dist/resources/extensions/gsd/auto/session.js +10 -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/system-context.js +7 -2
- package/dist/resources/extensions/gsd/commands/catalog.js +2 -1
- package/dist/resources/extensions/gsd/commands/handlers/core.js +1 -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/guided-flow.js +40 -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/workflow-mcp.js +90 -19
- 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 +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 +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/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/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/workflow-tools.ts +13 -2
- 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 +190 -93
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +89 -116
- package/src/resources/extensions/gsd/auto/session.ts +10 -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/system-context.ts +8 -2
- package/src/resources/extensions/gsd/commands/catalog.ts +2 -1
- package/src/resources/extensions/gsd/commands/handlers/core.ts +1 -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/guided-flow.ts +42 -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/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/crash-recovery.test.ts +380 -2
- package/src/resources/extensions/gsd/tests/forensics-context-persist.test.ts +30 -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-mcp.test.ts +212 -13
- package/src/resources/extensions/gsd/workflow-mcp.ts +106 -19
- 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/{mHJZ3Z8yGRzZ32BmQs-I7 → yh2vT27L1E6PChb_C1N_F}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{mHJZ3Z8yGRzZ32BmQs-I7 → yh2vT27L1E6PChb_C1N_F}/_ssgManifest.js +0 -0
|
@@ -14,7 +14,8 @@ import { buildSkillActivationBlock } from "./auto-prompts.js";
|
|
|
14
14
|
import { deriveState } from "./state.js";
|
|
15
15
|
import { invalidateAllCaches } from "./cache.js";
|
|
16
16
|
import { startAuto } from "./auto.js";
|
|
17
|
-
import {
|
|
17
|
+
import { clearLock } from "./crash-recovery.js";
|
|
18
|
+
import { assessInterruptedSession, formatInterruptedSessionRunningMessage, formatInterruptedSessionSummary, } from "./interrupted-session.js";
|
|
18
19
|
import { listUnitRuntimeRecords, clearUnitRuntimeRecord } from "./unit-runtime.js";
|
|
19
20
|
import { resolveExpectedArtifactPath } from "./auto.js";
|
|
20
21
|
import { gsdRoot, milestonesDir, resolveMilestoneFile, resolveSliceFile, resolveSlicePath, resolveGsdRootFile, relGsdRootFile, relMilestoneFile, relSliceFile, } from "./paths.js";
|
|
@@ -167,14 +168,9 @@ export function checkAutoStartAfterDiscuss() {
|
|
|
167
168
|
}
|
|
168
169
|
// Gate 4: Discussion manifest process verification (multi-milestone only)
|
|
169
170
|
// The LLM writes DISCUSSION-MANIFEST.json after each Phase 3 gate decision.
|
|
170
|
-
//
|
|
171
|
-
//
|
|
171
|
+
// When it exists, validate it before auto-starting. Project history alone is
|
|
172
|
+
// not a reliable signal for the current discussion mode.
|
|
172
173
|
const manifestPath = join(gsdRoot(basePath), "DISCUSSION-MANIFEST.json");
|
|
173
|
-
const requiresManifest = projectIds.length > 1 || findMilestoneIds(basePath).length > 1;
|
|
174
|
-
if (requiresManifest && !existsSync(manifestPath)) {
|
|
175
|
-
ctx.ui.notify("Multi-milestone discussion manifest is missing. Auto-start will remain paused until the manifest is written.", "warning");
|
|
176
|
-
return false;
|
|
177
|
-
}
|
|
178
174
|
if (existsSync(manifestPath)) {
|
|
179
175
|
try {
|
|
180
176
|
const manifest = JSON.parse(readFileSync(manifestPath, "utf-8"));
|
|
@@ -1102,33 +1098,46 @@ export async function showSmartEntry(ctx, pi, basePath, options) {
|
|
|
1102
1098
|
untrackRuntimeFiles(basePath);
|
|
1103
1099
|
// ── Self-heal stale runtime records from crashed auto-mode sessions ──
|
|
1104
1100
|
selfHealRuntimeRecords(basePath, ctx);
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1101
|
+
const interrupted = await assessInterruptedSession(basePath);
|
|
1102
|
+
if (interrupted.classification === "running") {
|
|
1103
|
+
ctx.ui.notify(formatInterruptedSessionRunningMessage(interrupted), "error");
|
|
1104
|
+
return;
|
|
1105
|
+
}
|
|
1106
|
+
if (interrupted.classification === "stale") {
|
|
1110
1107
|
clearLock(basePath);
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
// real auto-mode work begins.
|
|
1115
|
-
const isBootstrapCrash = crashLock.unitType === "starting"
|
|
1116
|
-
&& crashLock.unitId === "bootstrap";
|
|
1117
|
-
if (!isBootstrapCrash) {
|
|
1118
|
-
const resume = await showNextAction(ctx, {
|
|
1119
|
-
title: "GSD — Interrupted Session Detected",
|
|
1120
|
-
summary: [formatCrashInfo(crashLock)],
|
|
1121
|
-
actions: [
|
|
1122
|
-
{ id: "resume", label: "Resume with /gsd auto", description: "Pick up where it left off", recommended: true },
|
|
1123
|
-
{ id: "continue", label: "Continue manually", description: "Open the wizard as normal" },
|
|
1124
|
-
],
|
|
1125
|
-
});
|
|
1126
|
-
if (resume === "resume") {
|
|
1127
|
-
await startAuto(ctx, pi, basePath, false);
|
|
1128
|
-
return;
|
|
1108
|
+
if (interrupted.pausedSession) {
|
|
1109
|
+
try {
|
|
1110
|
+
unlinkSync(join(gsdRoot(basePath), "runtime", "paused-session.json"));
|
|
1129
1111
|
}
|
|
1112
|
+
catch (e) {
|
|
1113
|
+
logWarning("guided", `stale pause file cleanup failed: ${e.message}`, { file: "guided-flow.ts" });
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
else if (interrupted.classification === "recoverable") {
|
|
1118
|
+
if (interrupted.lock)
|
|
1119
|
+
clearLock(basePath);
|
|
1120
|
+
const resumeLabel = interrupted.pausedSession?.stepMode
|
|
1121
|
+
? "Resume with /gsd next"
|
|
1122
|
+
: "Resume with /gsd auto";
|
|
1123
|
+
const resume = await showNextAction(ctx, {
|
|
1124
|
+
title: "GSD — Interrupted Session Detected",
|
|
1125
|
+
summary: formatInterruptedSessionSummary(interrupted),
|
|
1126
|
+
actions: [
|
|
1127
|
+
{ id: "resume", label: resumeLabel, description: "Pick up where it left off", recommended: true },
|
|
1128
|
+
{ id: "continue", label: "Continue manually", description: "Open the wizard as normal" },
|
|
1129
|
+
],
|
|
1130
|
+
});
|
|
1131
|
+
if (resume === "resume") {
|
|
1132
|
+
await startAuto(ctx, pi, basePath, false, {
|
|
1133
|
+
interrupted,
|
|
1134
|
+
step: interrupted.pausedSession?.stepMode ?? false,
|
|
1135
|
+
});
|
|
1136
|
+
return;
|
|
1130
1137
|
}
|
|
1131
1138
|
}
|
|
1139
|
+
// Always derive from the project root — the assessment may have derived
|
|
1140
|
+
// state from a worktree path that was cleaned up in the stale branch above.
|
|
1132
1141
|
const state = await deriveState(basePath);
|
|
1133
1142
|
// Rebuild STATE.md from derived state before any dispatch (#3475).
|
|
1134
1143
|
try {
|
|
@@ -187,6 +187,16 @@ export async function showProjectInit(ctx, pi, basePath, detection) {
|
|
|
187
187
|
}
|
|
188
188
|
// ── Step 9: Bootstrap .gsd/ ────────────────────────────────────────────────
|
|
189
189
|
bootstrapGsdDirectory(basePath, prefs, signals);
|
|
190
|
+
// Initialize SQLite database so GSD starts in full-capability mode (#3880).
|
|
191
|
+
// Without this, isDbAvailable() returns false and GSD enters degraded
|
|
192
|
+
// markdown-only mode until a tool handler happens to call ensureDbOpen().
|
|
193
|
+
try {
|
|
194
|
+
const { ensureDbOpen } = await import("./bootstrap/dynamic-tools.js");
|
|
195
|
+
await ensureDbOpen(basePath);
|
|
196
|
+
}
|
|
197
|
+
catch {
|
|
198
|
+
// Non-fatal — DB creation failure should not block project init
|
|
199
|
+
}
|
|
190
200
|
// Ensure .gitignore
|
|
191
201
|
ensureGitignore(basePath);
|
|
192
202
|
untrackRuntimeFiles(basePath);
|
|
@@ -201,6 +211,32 @@ export async function showProjectInit(ctx, pi, basePath, detection) {
|
|
|
201
211
|
catch {
|
|
202
212
|
// Non-fatal — codebase map generation failure should never block project init
|
|
203
213
|
}
|
|
214
|
+
// Write initial STATE.md so it exists before the first /gsd invocation.
|
|
215
|
+
// The explicit /gsd init path (ops.ts) returns without entering showSmartEntry(),
|
|
216
|
+
// which would otherwise generate STATE.md at guided-flow.ts:1358.
|
|
217
|
+
try {
|
|
218
|
+
const { deriveState } = await import("./state.js");
|
|
219
|
+
const { buildStateMarkdown } = await import("./doctor.js");
|
|
220
|
+
const { saveFile } = await import("./files.js");
|
|
221
|
+
const { resolveGsdRootFile } = await import("./paths.js");
|
|
222
|
+
const state = await deriveState(basePath);
|
|
223
|
+
await saveFile(resolveGsdRootFile(basePath, "STATE"), buildStateMarkdown(state));
|
|
224
|
+
}
|
|
225
|
+
catch {
|
|
226
|
+
// Non-fatal — STATE.md will be regenerated on next /gsd invocation
|
|
227
|
+
}
|
|
228
|
+
if (ctx.model?.provider === "claude-code") {
|
|
229
|
+
try {
|
|
230
|
+
const { ensureProjectWorkflowMcpConfig } = await import("./mcp-project-config.js");
|
|
231
|
+
const result = ensureProjectWorkflowMcpConfig(basePath);
|
|
232
|
+
if (result.status !== "unchanged") {
|
|
233
|
+
ctx.ui.notify(`Claude Code MCP prepared at ${result.configPath}`, "info");
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
catch (err) {
|
|
237
|
+
ctx.ui.notify(`Claude Code MCP prep failed: ${err instanceof Error ? err.message : String(err)}`, "warning");
|
|
238
|
+
}
|
|
239
|
+
}
|
|
204
240
|
ctx.ui.notify("GSD initialized. Starting your first milestone...", "info");
|
|
205
241
|
return { completed: true, bootstrapped: true };
|
|
206
242
|
}
|
|
@@ -348,6 +384,7 @@ function bootstrapGsdDirectory(basePath, prefs, signals) {
|
|
|
348
384
|
assertSafeDirectory(basePath);
|
|
349
385
|
const gsd = gsdRoot(basePath);
|
|
350
386
|
mkdirSync(join(gsd, "milestones"), { recursive: true });
|
|
387
|
+
mkdirSync(join(gsd, "runtime"), { recursive: true });
|
|
351
388
|
// Write PREFERENCES.md from wizard answers
|
|
352
389
|
const preferencesContent = buildPreferencesFile(prefs);
|
|
353
390
|
writeFileSync(join(gsd, "PREFERENCES.md"), preferencesContent, "utf-8");
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { verifyExpectedArtifact } from "./auto-recovery.js";
|
|
4
|
+
import { formatCrashInfo, isLockProcessAlive, readCrashLock, } from "./crash-recovery.js";
|
|
5
|
+
import { gsdRoot } from "./paths.js";
|
|
6
|
+
import { synthesizeCrashRecovery, } from "./session-forensics.js";
|
|
7
|
+
import { deriveState } from "./state.js";
|
|
8
|
+
export function readPausedSessionMetadata(basePath) {
|
|
9
|
+
const pausedPath = join(gsdRoot(basePath), "runtime", "paused-session.json");
|
|
10
|
+
if (!existsSync(pausedPath))
|
|
11
|
+
return null;
|
|
12
|
+
try {
|
|
13
|
+
return JSON.parse(readFileSync(pausedPath, "utf-8"));
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export function isBootstrapCrashLock(lock) {
|
|
20
|
+
return !!(lock &&
|
|
21
|
+
lock.unitType === "starting" &&
|
|
22
|
+
lock.unitId === "bootstrap");
|
|
23
|
+
}
|
|
24
|
+
export function hasResumableDerivedState(state) {
|
|
25
|
+
return !!(state?.activeMilestone && state.phase !== "complete");
|
|
26
|
+
}
|
|
27
|
+
export async function assessInterruptedSession(basePath) {
|
|
28
|
+
const pausedSession = readPausedSessionMetadata(basePath);
|
|
29
|
+
const worktreeExists = pausedSession?.worktreePath
|
|
30
|
+
? existsSync(pausedSession.worktreePath)
|
|
31
|
+
: false;
|
|
32
|
+
const assessmentBasePath = worktreeExists ? pausedSession.worktreePath : basePath;
|
|
33
|
+
const rawLock = readCrashLock(basePath);
|
|
34
|
+
const lock = rawLock && rawLock.pid !== process.pid ? rawLock : null;
|
|
35
|
+
if (!lock && !pausedSession) {
|
|
36
|
+
return {
|
|
37
|
+
classification: "none",
|
|
38
|
+
lock: null,
|
|
39
|
+
pausedSession: null,
|
|
40
|
+
state: null,
|
|
41
|
+
recovery: null,
|
|
42
|
+
recoveryPrompt: null,
|
|
43
|
+
recoveryToolCallCount: 0,
|
|
44
|
+
artifactSatisfied: false,
|
|
45
|
+
hasResumableDiskState: false,
|
|
46
|
+
isBootstrapCrash: false,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
if (lock && isLockProcessAlive(lock)) {
|
|
50
|
+
return {
|
|
51
|
+
classification: "running",
|
|
52
|
+
lock,
|
|
53
|
+
pausedSession,
|
|
54
|
+
state: null,
|
|
55
|
+
recovery: null,
|
|
56
|
+
recoveryPrompt: null,
|
|
57
|
+
recoveryToolCallCount: 0,
|
|
58
|
+
artifactSatisfied: false,
|
|
59
|
+
hasResumableDiskState: false,
|
|
60
|
+
isBootstrapCrash: false,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
const isBootstrapCrash = isBootstrapCrashLock(lock);
|
|
64
|
+
const state = await deriveState(assessmentBasePath);
|
|
65
|
+
const hasResumableDiskState = hasResumableDerivedState(state);
|
|
66
|
+
const artifactSatisfied = !!(lock &&
|
|
67
|
+
!isBootstrapCrash &&
|
|
68
|
+
verifyExpectedArtifact(lock.unitType, lock.unitId, assessmentBasePath));
|
|
69
|
+
let recovery = null;
|
|
70
|
+
if (lock && !isBootstrapCrash && !artifactSatisfied) {
|
|
71
|
+
recovery = synthesizeCrashRecovery(assessmentBasePath, lock.unitType, lock.unitId, lock.sessionFile, join(gsdRoot(assessmentBasePath), "activity"));
|
|
72
|
+
}
|
|
73
|
+
const recoveryToolCallCount = recovery?.trace.toolCallCount ?? 0;
|
|
74
|
+
const recoveryPrompt = recoveryToolCallCount > 0 ? recovery.prompt : null;
|
|
75
|
+
if (isBootstrapCrash) {
|
|
76
|
+
return {
|
|
77
|
+
classification: pausedSession ? "recoverable" : "stale",
|
|
78
|
+
lock,
|
|
79
|
+
pausedSession,
|
|
80
|
+
state,
|
|
81
|
+
recovery,
|
|
82
|
+
recoveryPrompt,
|
|
83
|
+
recoveryToolCallCount,
|
|
84
|
+
artifactSatisfied,
|
|
85
|
+
hasResumableDiskState,
|
|
86
|
+
isBootstrapCrash: true,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
if (!hasResumableDiskState && pausedSession && !lock && recoveryToolCallCount === 0) {
|
|
90
|
+
return {
|
|
91
|
+
classification: "stale",
|
|
92
|
+
lock,
|
|
93
|
+
pausedSession,
|
|
94
|
+
state,
|
|
95
|
+
recovery,
|
|
96
|
+
recoveryPrompt,
|
|
97
|
+
recoveryToolCallCount,
|
|
98
|
+
artifactSatisfied,
|
|
99
|
+
hasResumableDiskState,
|
|
100
|
+
isBootstrapCrash: false,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
if (lock && artifactSatisfied && !hasResumableDiskState && recoveryToolCallCount === 0) {
|
|
104
|
+
return {
|
|
105
|
+
classification: "stale",
|
|
106
|
+
lock,
|
|
107
|
+
pausedSession,
|
|
108
|
+
state,
|
|
109
|
+
recovery,
|
|
110
|
+
recoveryPrompt,
|
|
111
|
+
recoveryToolCallCount,
|
|
112
|
+
artifactSatisfied,
|
|
113
|
+
hasResumableDiskState,
|
|
114
|
+
isBootstrapCrash: false,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
const hasStrongRecoverySignal = hasResumableDiskState || recoveryToolCallCount > 0;
|
|
118
|
+
return {
|
|
119
|
+
classification: hasStrongRecoverySignal ? "recoverable" : "stale",
|
|
120
|
+
lock,
|
|
121
|
+
pausedSession,
|
|
122
|
+
state,
|
|
123
|
+
recovery,
|
|
124
|
+
recoveryPrompt,
|
|
125
|
+
recoveryToolCallCount,
|
|
126
|
+
artifactSatisfied,
|
|
127
|
+
hasResumableDiskState,
|
|
128
|
+
isBootstrapCrash: false,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
export function formatInterruptedSessionSummary(assessment) {
|
|
132
|
+
if (assessment.lock)
|
|
133
|
+
return [formatCrashInfo(assessment.lock)];
|
|
134
|
+
if (assessment.pausedSession?.milestoneId) {
|
|
135
|
+
return [
|
|
136
|
+
`Paused auto-mode session detected for ${assessment.pausedSession.milestoneId}.`,
|
|
137
|
+
];
|
|
138
|
+
}
|
|
139
|
+
return ["Paused auto-mode session detected."];
|
|
140
|
+
}
|
|
141
|
+
export function formatInterruptedSessionRunningMessage(assessment) {
|
|
142
|
+
const pid = assessment.lock?.pid;
|
|
143
|
+
return pid
|
|
144
|
+
? `Another auto-mode session (PID ${pid}) appears to be running.\nStop it with \`kill ${pid}\` before starting a new session.`
|
|
145
|
+
: "Another auto-mode session appears to be running.";
|
|
146
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { assertSafeDirectory } from "./validate-directory.js";
|
|
5
|
+
import { detectWorkflowMcpLaunchConfig } from "./workflow-mcp.js";
|
|
6
|
+
export const GSD_WORKFLOW_MCP_SERVER_NAME = "gsd-workflow";
|
|
7
|
+
export function resolveBundledGsdCliPath(env = process.env) {
|
|
8
|
+
const explicit = env.GSD_CLI_PATH?.trim() || env.GSD_BIN_PATH?.trim();
|
|
9
|
+
if (explicit)
|
|
10
|
+
return explicit;
|
|
11
|
+
const candidates = [
|
|
12
|
+
resolve(fileURLToPath(new URL("../../../../scripts/dev-cli.js", import.meta.url))),
|
|
13
|
+
resolve(fileURLToPath(new URL("../../../../dist/loader.js", import.meta.url))),
|
|
14
|
+
resolve(fileURLToPath(new URL("../../../loader.js", import.meta.url))),
|
|
15
|
+
];
|
|
16
|
+
for (const candidate of candidates) {
|
|
17
|
+
if (existsSync(candidate))
|
|
18
|
+
return candidate;
|
|
19
|
+
}
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
export function buildProjectWorkflowMcpServerConfig(projectRoot, env = process.env) {
|
|
23
|
+
const resolvedProjectRoot = resolve(projectRoot);
|
|
24
|
+
const gsdCliPath = resolveBundledGsdCliPath(env);
|
|
25
|
+
const launch = detectWorkflowMcpLaunchConfig(resolvedProjectRoot, {
|
|
26
|
+
...env,
|
|
27
|
+
...(gsdCliPath ? { GSD_CLI_PATH: gsdCliPath, GSD_BIN_PATH: gsdCliPath } : {}),
|
|
28
|
+
});
|
|
29
|
+
if (!launch) {
|
|
30
|
+
throw new Error("Unable to resolve the GSD workflow MCP server. Build this checkout or install gsd-mcp-server on PATH.");
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
command: launch.command,
|
|
34
|
+
...(launch.args && launch.args.length > 0 ? { args: launch.args } : {}),
|
|
35
|
+
...(launch.cwd ? { cwd: launch.cwd } : {}),
|
|
36
|
+
...(launch.env ? { env: launch.env } : {}),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function readExistingConfig(configPath) {
|
|
40
|
+
if (!existsSync(configPath))
|
|
41
|
+
return {};
|
|
42
|
+
const raw = readFileSync(configPath, "utf-8");
|
|
43
|
+
try {
|
|
44
|
+
const parsed = JSON.parse(raw);
|
|
45
|
+
return parsed && typeof parsed === "object" ? parsed : {};
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
throw new Error(`Failed to parse ${configPath}: ${err instanceof Error ? err.message : String(err)}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
export function ensureProjectWorkflowMcpConfig(projectRoot, env = process.env) {
|
|
52
|
+
const resolvedProjectRoot = resolve(projectRoot);
|
|
53
|
+
assertSafeDirectory(resolvedProjectRoot);
|
|
54
|
+
const configPath = resolve(resolvedProjectRoot, ".mcp.json");
|
|
55
|
+
const existing = readExistingConfig(configPath);
|
|
56
|
+
const desiredServer = buildProjectWorkflowMcpServerConfig(resolvedProjectRoot, env);
|
|
57
|
+
const previousServers = existing.mcpServers ?? {};
|
|
58
|
+
const nextServers = {
|
|
59
|
+
...previousServers,
|
|
60
|
+
[GSD_WORKFLOW_MCP_SERVER_NAME]: desiredServer,
|
|
61
|
+
};
|
|
62
|
+
const alreadyPresent = existsSync(configPath);
|
|
63
|
+
const unchanged = JSON.stringify(previousServers[GSD_WORKFLOW_MCP_SERVER_NAME] ?? null)
|
|
64
|
+
=== JSON.stringify(desiredServer)
|
|
65
|
+
&& existing.mcpServers !== undefined;
|
|
66
|
+
if (unchanged) {
|
|
67
|
+
return {
|
|
68
|
+
configPath,
|
|
69
|
+
serverName: GSD_WORKFLOW_MCP_SERVER_NAME,
|
|
70
|
+
status: "unchanged",
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
const nextConfig = {
|
|
74
|
+
...existing,
|
|
75
|
+
mcpServers: nextServers,
|
|
76
|
+
};
|
|
77
|
+
writeFileSync(configPath, `${JSON.stringify(nextConfig, null, 2)}\n`, "utf-8");
|
|
78
|
+
return {
|
|
79
|
+
configPath,
|
|
80
|
+
serverName: GSD_WORKFLOW_MCP_SERVER_NAME,
|
|
81
|
+
status: alreadyPresent ? "updated" : "created",
|
|
82
|
+
};
|
|
83
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { execSync } from "node:child_process";
|
|
2
2
|
import { existsSync } from "node:fs";
|
|
3
|
-
import { resolve } from "node:path";
|
|
3
|
+
import { dirname, resolve } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
4
5
|
const MCP_WORKFLOW_TOOL_SURFACE = new Set([
|
|
5
6
|
"gsd_complete_milestone",
|
|
6
7
|
"gsd_complete_task",
|
|
@@ -47,23 +48,91 @@ function lookupCommand(command, platform = process.platform) {
|
|
|
47
48
|
return null;
|
|
48
49
|
}
|
|
49
50
|
}
|
|
51
|
+
function findWorkflowCliFromAncestorPath(startPath) {
|
|
52
|
+
let current = resolve(startPath);
|
|
53
|
+
while (true) {
|
|
54
|
+
const candidate = resolve(current, "packages", "mcp-server", "dist", "cli.js");
|
|
55
|
+
if (existsSync(candidate))
|
|
56
|
+
return candidate;
|
|
57
|
+
const parent = dirname(current);
|
|
58
|
+
if (parent === current)
|
|
59
|
+
break;
|
|
60
|
+
current = parent;
|
|
61
|
+
}
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
function getBundledWorkflowMcpCliPath(env) {
|
|
65
|
+
const envAnchors = [
|
|
66
|
+
env.GSD_BIN_PATH?.trim(),
|
|
67
|
+
env.GSD_CLI_PATH?.trim(),
|
|
68
|
+
env.GSD_WORKFLOW_PATH?.trim(),
|
|
69
|
+
].filter((value) => typeof value === "string" && value.length > 0);
|
|
70
|
+
for (const anchor of envAnchors) {
|
|
71
|
+
const candidate = findWorkflowCliFromAncestorPath(anchor);
|
|
72
|
+
if (candidate)
|
|
73
|
+
return candidate;
|
|
74
|
+
}
|
|
75
|
+
const candidates = [
|
|
76
|
+
resolve(fileURLToPath(new URL("../../../../packages/mcp-server/dist/cli.js", import.meta.url))),
|
|
77
|
+
resolve(fileURLToPath(new URL("../../../../../packages/mcp-server/dist/cli.js", import.meta.url))),
|
|
78
|
+
];
|
|
79
|
+
for (const bundledCli of candidates) {
|
|
80
|
+
if (existsSync(bundledCli))
|
|
81
|
+
return bundledCli;
|
|
82
|
+
}
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
function getBundledWorkflowExecutorModulePath() {
|
|
86
|
+
const candidates = [
|
|
87
|
+
resolve(fileURLToPath(new URL("../../../../dist/resources/extensions/gsd/tools/workflow-tool-executors.js", import.meta.url))),
|
|
88
|
+
resolve(fileURLToPath(new URL("./tools/workflow-tool-executors.js", import.meta.url))),
|
|
89
|
+
resolve(fileURLToPath(new URL("./tools/workflow-tool-executors.ts", import.meta.url))),
|
|
90
|
+
];
|
|
91
|
+
for (const candidate of candidates) {
|
|
92
|
+
if (existsSync(candidate))
|
|
93
|
+
return candidate;
|
|
94
|
+
}
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
function getBundledWorkflowWriteGateModulePath() {
|
|
98
|
+
const candidates = [
|
|
99
|
+
resolve(fileURLToPath(new URL("../../../../dist/resources/extensions/gsd/bootstrap/write-gate.js", import.meta.url))),
|
|
100
|
+
resolve(fileURLToPath(new URL("./bootstrap/write-gate.js", import.meta.url))),
|
|
101
|
+
resolve(fileURLToPath(new URL("./bootstrap/write-gate.ts", import.meta.url))),
|
|
102
|
+
];
|
|
103
|
+
for (const candidate of candidates) {
|
|
104
|
+
if (existsSync(candidate))
|
|
105
|
+
return candidate;
|
|
106
|
+
}
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
function buildWorkflowLaunchEnv(projectRoot, gsdCliPath, explicitEnv) {
|
|
110
|
+
const executorModulePath = getBundledWorkflowExecutorModulePath();
|
|
111
|
+
const writeGateModulePath = getBundledWorkflowWriteGateModulePath();
|
|
112
|
+
return {
|
|
113
|
+
...(explicitEnv ?? {}),
|
|
114
|
+
...(gsdCliPath ? { GSD_CLI_PATH: gsdCliPath } : {}),
|
|
115
|
+
...(executorModulePath ? { GSD_WORKFLOW_EXECUTORS_MODULE: executorModulePath } : {}),
|
|
116
|
+
...(writeGateModulePath ? { GSD_WORKFLOW_WRITE_GATE_MODULE: writeGateModulePath } : {}),
|
|
117
|
+
GSD_PERSIST_WRITE_GATE_STATE: "1",
|
|
118
|
+
GSD_WORKFLOW_PROJECT_ROOT: projectRoot,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
50
121
|
export function detectWorkflowMcpLaunchConfig(projectRoot = process.cwd(), env = process.env) {
|
|
51
122
|
const name = env.GSD_WORKFLOW_MCP_NAME?.trim() || "gsd-workflow";
|
|
52
123
|
const explicitCommand = env.GSD_WORKFLOW_MCP_COMMAND?.trim();
|
|
53
124
|
const explicitArgs = parseJsonEnv(env, "GSD_WORKFLOW_MCP_ARGS");
|
|
54
125
|
const explicitEnv = parseJsonEnv(env, "GSD_WORKFLOW_MCP_ENV");
|
|
55
126
|
const explicitCwd = env.GSD_WORKFLOW_MCP_CWD?.trim();
|
|
127
|
+
const gsdCliPath = env.GSD_CLI_PATH?.trim() || env.GSD_BIN_PATH?.trim();
|
|
56
128
|
const workflowProjectRoot = explicitEnv?.GSD_WORKFLOW_PROJECT_ROOT?.trim() ||
|
|
57
129
|
env.GSD_WORKFLOW_PROJECT_ROOT?.trim() ||
|
|
130
|
+
env.GSD_PROJECT_ROOT?.trim() ||
|
|
58
131
|
explicitCwd ||
|
|
59
132
|
projectRoot;
|
|
133
|
+
const resolvedWorkflowProjectRoot = resolve(workflowProjectRoot);
|
|
60
134
|
if (explicitCommand) {
|
|
61
|
-
const launchEnv =
|
|
62
|
-
...(explicitEnv ?? {}),
|
|
63
|
-
...(env.GSD_CLI_PATH ? { GSD_CLI_PATH: env.GSD_CLI_PATH } : {}),
|
|
64
|
-
GSD_PERSIST_WRITE_GATE_STATE: "1",
|
|
65
|
-
GSD_WORKFLOW_PROJECT_ROOT: resolve(workflowProjectRoot),
|
|
66
|
-
};
|
|
135
|
+
const launchEnv = buildWorkflowLaunchEnv(resolve(workflowProjectRoot), gsdCliPath, explicitEnv);
|
|
67
136
|
return {
|
|
68
137
|
name,
|
|
69
138
|
command: explicitCommand,
|
|
@@ -72,18 +141,24 @@ export function detectWorkflowMcpLaunchConfig(projectRoot = process.cwd(), env =
|
|
|
72
141
|
env: Object.keys(launchEnv).length > 0 ? launchEnv : undefined,
|
|
73
142
|
};
|
|
74
143
|
}
|
|
75
|
-
const distCli = resolve(
|
|
144
|
+
const distCli = resolve(resolvedWorkflowProjectRoot, "packages", "mcp-server", "dist", "cli.js");
|
|
76
145
|
if (existsSync(distCli)) {
|
|
77
146
|
return {
|
|
78
147
|
name,
|
|
79
148
|
command: process.execPath,
|
|
80
149
|
args: [distCli],
|
|
81
|
-
cwd:
|
|
82
|
-
env:
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
150
|
+
cwd: resolvedWorkflowProjectRoot,
|
|
151
|
+
env: buildWorkflowLaunchEnv(resolvedWorkflowProjectRoot, gsdCliPath),
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
const bundledCli = getBundledWorkflowMcpCliPath(env);
|
|
155
|
+
if (bundledCli) {
|
|
156
|
+
return {
|
|
157
|
+
name,
|
|
158
|
+
command: process.execPath,
|
|
159
|
+
args: [bundledCli],
|
|
160
|
+
cwd: resolvedWorkflowProjectRoot,
|
|
161
|
+
env: buildWorkflowLaunchEnv(resolvedWorkflowProjectRoot, gsdCliPath),
|
|
87
162
|
};
|
|
88
163
|
}
|
|
89
164
|
const binPath = lookupCommand("gsd-mcp-server");
|
|
@@ -91,11 +166,7 @@ export function detectWorkflowMcpLaunchConfig(projectRoot = process.cwd(), env =
|
|
|
91
166
|
return {
|
|
92
167
|
name,
|
|
93
168
|
command: binPath,
|
|
94
|
-
env:
|
|
95
|
-
...(env.GSD_CLI_PATH ? { GSD_CLI_PATH: env.GSD_CLI_PATH } : {}),
|
|
96
|
-
GSD_PERSIST_WRITE_GATE_STATE: "1",
|
|
97
|
-
GSD_WORKFLOW_PROJECT_ROOT: resolve(projectRoot),
|
|
98
|
-
},
|
|
169
|
+
env: buildWorkflowLaunchEnv(resolvedWorkflowProjectRoot, gsdCliPath),
|
|
99
170
|
};
|
|
100
171
|
}
|
|
101
172
|
return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
yh2vT27L1E6PChb_C1N_F
|
|
@@ -1,47 +1,47 @@
|
|
|
1
1
|
{
|
|
2
2
|
"/_not-found/page": "/_not-found",
|
|
3
3
|
"/_global-error/page": "/_global-error",
|
|
4
|
-
"/api/bridge-terminal/input/route": "/api/bridge-terminal/input",
|
|
5
4
|
"/api/boot/route": "/api/boot",
|
|
5
|
+
"/api/bridge-terminal/input/route": "/api/bridge-terminal/input",
|
|
6
6
|
"/api/bridge-terminal/resize/route": "/api/bridge-terminal/resize",
|
|
7
|
-
"/api/bridge-terminal/stream/route": "/api/bridge-terminal/stream",
|
|
8
|
-
"/api/dev-mode/route": "/api/dev-mode",
|
|
9
7
|
"/api/cleanup/route": "/api/cleanup",
|
|
10
|
-
"/api/doctor/route": "/api/doctor",
|
|
11
8
|
"/api/captures/route": "/api/captures",
|
|
12
|
-
"/api/
|
|
9
|
+
"/api/dev-mode/route": "/api/dev-mode",
|
|
13
10
|
"/api/browse-directories/route": "/api/browse-directories",
|
|
14
|
-
"/api/
|
|
11
|
+
"/api/doctor/route": "/api/doctor",
|
|
12
|
+
"/api/export-data/route": "/api/export-data",
|
|
15
13
|
"/api/forensics/route": "/api/forensics",
|
|
14
|
+
"/api/experimental/route": "/api/experimental",
|
|
16
15
|
"/api/git/route": "/api/git",
|
|
17
16
|
"/api/history/route": "/api/history",
|
|
18
|
-
"/api/inspect/route": "/api/inspect",
|
|
19
17
|
"/api/hooks/route": "/api/hooks",
|
|
18
|
+
"/api/inspect/route": "/api/inspect",
|
|
19
|
+
"/api/bridge-terminal/stream/route": "/api/bridge-terminal/stream",
|
|
20
20
|
"/api/knowledge/route": "/api/knowledge",
|
|
21
21
|
"/api/live-state/route": "/api/live-state",
|
|
22
22
|
"/api/notifications/route": "/api/notifications",
|
|
23
23
|
"/api/preferences/route": "/api/preferences",
|
|
24
|
+
"/api/files/route": "/api/files",
|
|
24
25
|
"/api/onboarding/route": "/api/onboarding",
|
|
25
26
|
"/api/recovery/route": "/api/recovery",
|
|
26
27
|
"/api/projects/route": "/api/projects",
|
|
27
|
-
"/api/files/route": "/api/files",
|
|
28
28
|
"/api/session/browser/route": "/api/session/browser",
|
|
29
|
-
"/api/session/command/route": "/api/session/command",
|
|
30
29
|
"/api/session/events/route": "/api/session/events",
|
|
31
30
|
"/api/settings-data/route": "/api/settings-data",
|
|
31
|
+
"/api/session/command/route": "/api/session/command",
|
|
32
32
|
"/api/shutdown/route": "/api/shutdown",
|
|
33
33
|
"/api/session/manage/route": "/api/session/manage",
|
|
34
34
|
"/api/skill-health/route": "/api/skill-health",
|
|
35
35
|
"/api/steer/route": "/api/steer",
|
|
36
|
-
"/api/terminal/input/route": "/api/terminal/input",
|
|
37
36
|
"/api/switch-root/route": "/api/switch-root",
|
|
38
|
-
"/api/terminal/
|
|
37
|
+
"/api/terminal/input/route": "/api/terminal/input",
|
|
39
38
|
"/api/terminal/sessions/route": "/api/terminal/sessions",
|
|
40
|
-
"/api/terminal/
|
|
41
|
-
"/api/
|
|
39
|
+
"/api/terminal/resize/route": "/api/terminal/resize",
|
|
40
|
+
"/api/remote-questions/route": "/api/remote-questions",
|
|
42
41
|
"/api/terminal/upload/route": "/api/terminal/upload",
|
|
43
|
-
"/api/update/route": "/api/update",
|
|
44
42
|
"/api/visualizer/route": "/api/visualizer",
|
|
45
|
-
"/api/
|
|
43
|
+
"/api/undo/route": "/api/undo",
|
|
44
|
+
"/api/update/route": "/api/update",
|
|
45
|
+
"/api/terminal/stream/route": "/api/terminal/stream",
|
|
46
46
|
"/page": "/"
|
|
47
47
|
}
|
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
],
|
|
5
5
|
"devFiles": [],
|
|
6
6
|
"lowPriorityFiles": [
|
|
7
|
-
"static/
|
|
8
|
-
"static/
|
|
7
|
+
"static/yh2vT27L1E6PChb_C1N_F/_buildManifest.js",
|
|
8
|
+
"static/yh2vT27L1E6PChb_C1N_F/_ssgManifest.js"
|
|
9
9
|
],
|
|
10
10
|
"rootMainFiles": [
|
|
11
|
-
"static/chunks/webpack-
|
|
11
|
+
"static/chunks/webpack-6e4d7e9a4f57bed4.js",
|
|
12
12
|
"static/chunks/4bd1b696-e356ca5ba0218e27.js",
|
|
13
13
|
"static/chunks/3794-42fdce068d44fa4f.js",
|
|
14
14
|
"static/chunks/main-app-fdab67f7802d7832.js"
|
|
@@ -78,8 +78,8 @@
|
|
|
78
78
|
"dynamicRoutes": {},
|
|
79
79
|
"notFoundRoutes": [],
|
|
80
80
|
"preview": {
|
|
81
|
-
"previewModeId": "
|
|
82
|
-
"previewModeSigningKey": "
|
|
83
|
-
"previewModeEncryptionKey": "
|
|
81
|
+
"previewModeId": "2d37a349be50ac937c61a539f8a27f2e",
|
|
82
|
+
"previewModeSigningKey": "7cbe27818262dc45964f3e579507b977175f4587a2991eb4af84d469ca44b520",
|
|
83
|
+
"previewModeEncryptionKey": "bf90146580294c958fc137e154442ee89e64e08c1bc2dc318f88db074f4eca45"
|
|
84
84
|
}
|
|
85
85
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"app/page.tsx -> @/components/gsd/app-shell": {
|
|
3
|
-
"id":
|
|
3
|
+
"id": 62826,
|
|
4
4
|
"files": [
|
|
5
5
|
"static/css/659eccb5db697b76.css",
|
|
6
6
|
"static/chunks/363642f4.cf8b455e0d94b478.js",
|
|
7
7
|
"static/chunks/4986-c2fc8845ce785303.js",
|
|
8
8
|
"static/chunks/2008.71ee9230ad78df21.js",
|
|
9
|
-
"static/chunks/
|
|
9
|
+
"static/chunks/2826.821e01b07d92e948.js"
|
|
10
10
|
]
|
|
11
11
|
},
|
|
12
12
|
"components/gsd/chat-mode.tsx -> react-markdown": {
|