@opengsd/gsd-pi 1.2.0-dev.9ad8ae33 → 1.2.0-dev.a6376d75

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.
Files changed (264) hide show
  1. package/dist/cli-model-override.d.ts +15 -0
  2. package/dist/cli-model-override.js +21 -0
  3. package/dist/cli.js +1 -18
  4. package/dist/loader.js +6 -4
  5. package/dist/register-agent-bundles.d.ts +11 -2
  6. package/dist/register-agent-bundles.js +18 -4
  7. package/dist/resources/.managed-resources-content-hash +1 -1
  8. package/dist/resources/extensions/ask-user-questions.js +3 -2
  9. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +447 -215
  10. package/dist/resources/extensions/claude-code-cli/turn-assembler.js +33 -1
  11. package/dist/resources/extensions/gsd/auto/closeout.js +215 -0
  12. package/dist/resources/extensions/gsd/auto/dispatch-history.js +21 -6
  13. package/dist/resources/extensions/gsd/auto/dispatch.js +365 -0
  14. package/dist/resources/extensions/gsd/auto/finalize.js +347 -0
  15. package/dist/resources/extensions/gsd/auto/loop.js +4 -1
  16. package/dist/resources/extensions/gsd/auto/milestone-lease-reclaim.js +56 -0
  17. package/dist/resources/extensions/gsd/auto/orchestrator.js +85 -15
  18. package/dist/resources/extensions/gsd/auto/phase-helpers.js +146 -0
  19. package/dist/resources/extensions/gsd/auto/phases.js +17 -2372
  20. package/dist/resources/extensions/gsd/auto/pre-dispatch.js +534 -0
  21. package/dist/resources/extensions/gsd/auto/unit-phase.js +694 -0
  22. package/dist/resources/extensions/gsd/auto/workflow-unit-dispatch.js +1 -1
  23. package/dist/resources/extensions/gsd/auto/worktree-safety-phase.js +125 -0
  24. package/dist/resources/extensions/gsd/auto-worktree.js +1 -1
  25. package/dist/resources/extensions/gsd/auto.js +15 -1
  26. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +37 -7
  27. package/dist/resources/extensions/gsd/commands-mcp-status.js +2 -2
  28. package/dist/resources/extensions/gsd/commands-workflow-templates.js +9 -2
  29. package/dist/resources/extensions/gsd/db/queries.js +30 -0
  30. package/dist/resources/extensions/gsd/doctor-environment.js +256 -125
  31. package/dist/resources/extensions/gsd/guided-flow.js +88 -2
  32. package/dist/resources/extensions/gsd/health-widget.js +87 -28
  33. package/dist/resources/extensions/gsd/mcp-bridge.js +10 -0
  34. package/dist/resources/extensions/gsd/milestone-settlement.js +2 -2
  35. package/dist/resources/extensions/gsd/notifications.js +12 -7
  36. package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  37. package/dist/resources/extensions/gsd/prompts/execute-task.md +2 -1
  38. package/dist/resources/extensions/gsd/prompts/run-uat.md +2 -0
  39. package/dist/resources/extensions/gsd/prompts/workflow-start.md +2 -1
  40. package/dist/resources/extensions/gsd/skill-activation.js +3 -6
  41. package/dist/resources/extensions/gsd/state.js +6 -2
  42. package/dist/resources/extensions/gsd/tool-surface-readiness.js +83 -31
  43. package/dist/resources/extensions/gsd/tools/complete-task.js +62 -0
  44. package/dist/resources/extensions/gsd/unit-context-composer.js +1 -1
  45. package/dist/resources/extensions/gsd/unit-registry.js +34 -4
  46. package/dist/resources/extensions/gsd/workflow-mcp-auto-prep.js +2 -0
  47. package/dist/resources/extensions/gsd/workflow-mcp-readiness-cache.js +105 -0
  48. package/dist/resources/extensions/gsd/worktree-safety.js +28 -26
  49. package/dist/resources/extensions/mcp-client/manager.js +6 -1
  50. package/dist/runtime-checks.d.ts +10 -0
  51. package/dist/runtime-checks.js +27 -0
  52. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  53. package/dist/web/standalone/.next/BUILD_ID +1 -1
  54. package/dist/web/standalone/.next/app-path-routes-manifest.json +8 -8
  55. package/dist/web/standalone/.next/build-manifest.json +2 -2
  56. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  57. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  58. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  59. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  60. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  61. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  62. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  63. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  64. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  65. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  66. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  67. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  68. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  69. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  70. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  71. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  72. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  73. package/dist/web/standalone/.next/server/app/index.html +1 -1
  74. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  75. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  76. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  77. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  78. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  79. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  80. package/dist/web/standalone/.next/server/app-paths-manifest.json +8 -8
  81. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  82. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  83. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  84. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  85. package/package.json +2 -2
  86. package/packages/cloud-mcp-gateway/package.json +2 -2
  87. package/packages/contracts/package.json +1 -1
  88. package/packages/daemon/package.json +4 -4
  89. package/packages/gsd-agent-core/dist/sdk.d.ts.map +1 -1
  90. package/packages/gsd-agent-core/dist/sdk.js +6 -4
  91. package/packages/gsd-agent-core/dist/sdk.js.map +1 -1
  92. package/packages/gsd-agent-core/package.json +5 -5
  93. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts +2 -0
  94. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  95. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js +10 -0
  96. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js.map +1 -1
  97. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +8 -0
  98. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  99. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +50 -6
  100. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  101. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts +2 -0
  102. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts.map +1 -1
  103. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js +34 -5
  104. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js.map +1 -1
  105. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts +1 -0
  106. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  107. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +12 -0
  108. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
  109. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.d.ts.map +1 -1
  110. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js +4 -0
  111. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js.map +1 -1
  112. package/packages/gsd-agent-modes/package.json +7 -7
  113. package/packages/mcp-server/README.md +12 -3
  114. package/packages/mcp-server/dist/cli-runner.d.ts +40 -0
  115. package/packages/mcp-server/dist/cli-runner.d.ts.map +1 -0
  116. package/packages/mcp-server/dist/cli-runner.js +137 -0
  117. package/packages/mcp-server/dist/cli-runner.js.map +1 -0
  118. package/packages/mcp-server/dist/cli.js +2 -58
  119. package/packages/mcp-server/dist/cli.js.map +1 -1
  120. package/packages/mcp-server/dist/pid-registry.d.ts +46 -0
  121. package/packages/mcp-server/dist/pid-registry.d.ts.map +1 -0
  122. package/packages/mcp-server/dist/pid-registry.js +452 -0
  123. package/packages/mcp-server/dist/pid-registry.js.map +1 -0
  124. package/packages/mcp-server/dist/probe-mode.d.ts +4 -0
  125. package/packages/mcp-server/dist/probe-mode.d.ts.map +1 -0
  126. package/packages/mcp-server/dist/probe-mode.js +10 -0
  127. package/packages/mcp-server/dist/probe-mode.js.map +1 -0
  128. package/packages/mcp-server/dist/stdio-watchdog.d.ts +8 -0
  129. package/packages/mcp-server/dist/stdio-watchdog.d.ts.map +1 -0
  130. package/packages/mcp-server/dist/stdio-watchdog.js +40 -0
  131. package/packages/mcp-server/dist/stdio-watchdog.js.map +1 -0
  132. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  133. package/packages/mcp-server/dist/workflow-tools.js +62 -43
  134. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  135. package/packages/mcp-server/package.json +5 -5
  136. package/packages/native/package.json +1 -1
  137. package/packages/pi-agent-core/dist/agent-loop.js +43 -2
  138. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  139. package/packages/pi-agent-core/package.json +1 -1
  140. package/packages/pi-ai/package.json +1 -1
  141. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +3 -0
  142. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  143. package/packages/pi-coding-agent/dist/core/settings-manager.js +11 -0
  144. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  145. package/packages/pi-coding-agent/dist/theme/theme.d.ts.map +1 -1
  146. package/packages/pi-coding-agent/dist/theme/theme.js +45 -17
  147. package/packages/pi-coding-agent/dist/theme/theme.js.map +1 -1
  148. package/packages/pi-coding-agent/package.json +7 -7
  149. package/packages/pi-tui/dist/index.d.ts +1 -1
  150. package/packages/pi-tui/dist/index.d.ts.map +1 -1
  151. package/packages/pi-tui/dist/index.js +1 -1
  152. package/packages/pi-tui/dist/index.js.map +1 -1
  153. package/packages/pi-tui/dist/terminal-image.d.ts +33 -0
  154. package/packages/pi-tui/dist/terminal-image.d.ts.map +1 -1
  155. package/packages/pi-tui/dist/terminal-image.js +54 -2
  156. package/packages/pi-tui/dist/terminal-image.js.map +1 -1
  157. package/packages/pi-tui/dist/tui.d.ts +8 -0
  158. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  159. package/packages/pi-tui/dist/tui.js +63 -18
  160. package/packages/pi-tui/dist/tui.js.map +1 -1
  161. package/packages/pi-tui/dist/utils.d.ts.map +1 -1
  162. package/packages/pi-tui/dist/utils.js +110 -36
  163. package/packages/pi-tui/dist/utils.js.map +1 -1
  164. package/packages/pi-tui/package.json +2 -2
  165. package/packages/rpc-client/package.json +2 -2
  166. package/pkg/dist/theme/theme.d.ts.map +1 -1
  167. package/pkg/dist/theme/theme.js +45 -17
  168. package/pkg/dist/theme/theme.js.map +1 -1
  169. package/pkg/package.json +1 -1
  170. package/src/resources/extensions/ask-user-questions.ts +7 -2
  171. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +531 -226
  172. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +672 -7
  173. package/src/resources/extensions/claude-code-cli/turn-assembler.ts +38 -1
  174. package/src/resources/extensions/gsd/auto/closeout.ts +309 -0
  175. package/src/resources/extensions/gsd/auto/dispatch-history.ts +22 -6
  176. package/src/resources/extensions/gsd/auto/dispatch.ts +449 -0
  177. package/src/resources/extensions/gsd/auto/finalize.ts +445 -0
  178. package/src/resources/extensions/gsd/auto/loop.ts +4 -1
  179. package/src/resources/extensions/gsd/auto/milestone-lease-reclaim.ts +74 -0
  180. package/src/resources/extensions/gsd/auto/orchestrator.ts +95 -15
  181. package/src/resources/extensions/gsd/auto/phase-helpers.ts +199 -0
  182. package/src/resources/extensions/gsd/auto/phases.ts +58 -3061
  183. package/src/resources/extensions/gsd/auto/pre-dispatch.ts +704 -0
  184. package/src/resources/extensions/gsd/auto/unit-phase.ts +910 -0
  185. package/src/resources/extensions/gsd/auto/workflow-unit-dispatch.ts +1 -1
  186. package/src/resources/extensions/gsd/auto/worktree-safety-phase.ts +149 -0
  187. package/src/resources/extensions/gsd/auto-worktree.ts +1 -1
  188. package/src/resources/extensions/gsd/auto.ts +20 -1
  189. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +56 -6
  190. package/src/resources/extensions/gsd/commands-mcp-status.ts +2 -2
  191. package/src/resources/extensions/gsd/commands-workflow-templates.ts +11 -4
  192. package/src/resources/extensions/gsd/db/queries.ts +29 -0
  193. package/src/resources/extensions/gsd/doctor-environment.ts +267 -142
  194. package/src/resources/extensions/gsd/guided-flow.ts +128 -2
  195. package/src/resources/extensions/gsd/health-widget.ts +91 -27
  196. package/src/resources/extensions/gsd/mcp-bridge.ts +39 -0
  197. package/src/resources/extensions/gsd/milestone-settlement.ts +2 -2
  198. package/src/resources/extensions/gsd/notifications.ts +13 -6
  199. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  200. package/src/resources/extensions/gsd/prompts/execute-task.md +2 -1
  201. package/src/resources/extensions/gsd/prompts/run-uat.md +2 -0
  202. package/src/resources/extensions/gsd/prompts/workflow-start.md +2 -1
  203. package/src/resources/extensions/gsd/skill-activation.ts +3 -6
  204. package/src/resources/extensions/gsd/state.ts +7 -1
  205. package/src/resources/extensions/gsd/tests/auto-abort-pause-regression.test.ts +1 -1
  206. package/src/resources/extensions/gsd/tests/auto-blocked-remediation-message.test.ts +1 -1
  207. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +206 -22
  208. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +76 -12
  209. package/src/resources/extensions/gsd/tests/auto-pause-double-entry-guard.test.ts +1 -1
  210. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +77 -1
  211. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +2 -1
  212. package/src/resources/extensions/gsd/tests/auto-unit-closeout.test.ts +169 -1
  213. package/src/resources/extensions/gsd/tests/complete-task.test.ts +141 -5
  214. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +2 -1
  215. package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +36 -0
  216. package/src/resources/extensions/gsd/tests/dispatch-history.test.ts +55 -0
  217. package/src/resources/extensions/gsd/tests/dist-redirect.mjs +8 -0
  218. package/src/resources/extensions/gsd/tests/engine-interfaces-contract.test.ts +117 -91
  219. package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +113 -0
  220. package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +16 -0
  221. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +15 -0
  222. package/src/resources/extensions/gsd/tests/integration/doctor-environment-async.test.ts +104 -0
  223. package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +18 -0
  224. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +47 -16
  225. package/src/resources/extensions/gsd/tests/mcp-readiness-preflight.test.ts +205 -0
  226. package/src/resources/extensions/gsd/tests/mcp-status.test.ts +6 -5
  227. package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +1 -1
  228. package/src/resources/extensions/gsd/tests/milestone-report-path.test.ts +1 -1
  229. package/src/resources/extensions/gsd/tests/milestone-settlement.test.ts +92 -0
  230. package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +1 -1
  231. package/src/resources/extensions/gsd/tests/notifications.test.ts +64 -9
  232. package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +2 -2
  233. package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +5 -0
  234. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +1 -1
  235. package/src/resources/extensions/gsd/tests/phases-terminal-complete-idempotent.test.ts +1 -1
  236. package/src/resources/extensions/gsd/tests/plan-gate-failed-doctor-heal-hint.test.ts +3 -3
  237. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +10 -2
  238. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +2 -4
  239. package/src/resources/extensions/gsd/tests/remote-notification-from-desktop.test.ts +31 -81
  240. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +7 -1
  241. package/src/resources/extensions/gsd/tests/skill-activation.test.ts +20 -17
  242. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +7 -3
  243. package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +1 -1
  244. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +4 -2
  245. package/src/resources/extensions/gsd/tests/tool-surface-readiness.test.ts +184 -10
  246. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +1 -1
  247. package/src/resources/extensions/gsd/tests/workflow-mcp-readiness-cache.test.ts +119 -0
  248. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +65 -2
  249. package/src/resources/extensions/gsd/tests/workflow-phase-contract-matrix.test.ts +332 -0
  250. package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +92 -0
  251. package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +1 -1
  252. package/src/resources/extensions/gsd/tests/worktree-project-root-degrade.test.ts +1 -1
  253. package/src/resources/extensions/gsd/tests/worktree-safety-phase.test.ts +100 -0
  254. package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +72 -0
  255. package/src/resources/extensions/gsd/tool-surface-readiness.ts +126 -19
  256. package/src/resources/extensions/gsd/tools/complete-task.ts +87 -0
  257. package/src/resources/extensions/gsd/unit-context-composer.ts +1 -1
  258. package/src/resources/extensions/gsd/unit-registry.ts +34 -4
  259. package/src/resources/extensions/gsd/workflow-mcp-auto-prep.ts +2 -0
  260. package/src/resources/extensions/gsd/workflow-mcp-readiness-cache.ts +150 -0
  261. package/src/resources/extensions/gsd/worktree-safety.ts +41 -39
  262. package/src/resources/extensions/mcp-client/manager.ts +7 -1
  263. /package/dist/web/standalone/.next/static/{FBNo5cT_chy7YNoAQsU3o → xyMkEaICFHJoa98VgJyzY}/_buildManifest.js +0 -0
  264. /package/dist/web/standalone/.next/static/{FBNo5cT_chy7YNoAQsU3o → xyMkEaICFHJoa98VgJyzY}/_ssgManifest.js +0 -0
@@ -0,0 +1,150 @@
1
+ // Project/App: gsd-pi
2
+ // File Purpose: Share recent workflow MCP probe results across guided-flow and Claude Code SDK preflight.
3
+
4
+ import { testMcpServerConnection } from "../mcp-client/manager.js";
5
+ import { mcpToolMatchesBaseName } from "./mcp-tool-name.js";
6
+ import {
7
+ detectWorkflowMcpLaunchConfig,
8
+ resolveWorkflowMcpProjectRoot,
9
+ } from "./workflow-mcp.js";
10
+ import { isWorkflowToolSurfaceName } from "./workflow-tool-surface.js";
11
+
12
+ /** Reuse a recent successful probe instead of spawning another stdio server. */
13
+ export const WORKFLOW_MCP_PROBE_CACHE_TTL_MS = 120_000;
14
+ /** Per-probe connect + tools/list budget (server typically ready in ~1–2s). */
15
+ export const WORKFLOW_MCP_PROBE_TIMEOUT_MS = 5_000;
16
+
17
+ export interface WorkflowMcpProbeCacheEntry {
18
+ serverName: string;
19
+ tools: readonly string[];
20
+ probedAt: number;
21
+ }
22
+
23
+ type WorkflowMcpProbeResult = {
24
+ ok: boolean;
25
+ tools: readonly string[];
26
+ serverName?: string;
27
+ error?: string;
28
+ };
29
+
30
+ const cacheByProject = new Map<string, WorkflowMcpProbeCacheEntry>();
31
+ const probeInFlightByProject = new Map<string, Promise<WorkflowMcpProbeResult>>();
32
+ let activeWorkflowMcpSdkSessions = 0;
33
+
34
+ function cacheKey(projectRoot: string): string {
35
+ return resolveWorkflowMcpProjectRoot(projectRoot);
36
+ }
37
+
38
+ export function beginWorkflowMcpSdkSession(): void {
39
+ activeWorkflowMcpSdkSessions++;
40
+ }
41
+
42
+ export function endWorkflowMcpSdkSession(): void {
43
+ activeWorkflowMcpSdkSessions = Math.max(0, activeWorkflowMcpSdkSessions - 1);
44
+ }
45
+
46
+ export function getCachedWorkflowMcpProbe(projectRoot: string): WorkflowMcpProbeCacheEntry | null {
47
+ const entry = cacheByProject.get(cacheKey(projectRoot));
48
+ if (!entry) return null;
49
+ if (Date.now() - entry.probedAt > WORKFLOW_MCP_PROBE_CACHE_TTL_MS) {
50
+ cacheByProject.delete(cacheKey(projectRoot));
51
+ return null;
52
+ }
53
+ return entry;
54
+ }
55
+
56
+ export function recordWorkflowMcpProbe(
57
+ projectRoot: string,
58
+ serverName: string,
59
+ tools: readonly string[],
60
+ ): void {
61
+ cacheByProject.set(cacheKey(projectRoot), {
62
+ serverName,
63
+ tools: [...tools],
64
+ probedAt: Date.now(),
65
+ });
66
+ }
67
+
68
+ export function clearWorkflowMcpProbeCache(projectRoot?: string): void {
69
+ if (projectRoot === undefined) {
70
+ cacheByProject.clear();
71
+ probeInFlightByProject.clear();
72
+ activeWorkflowMcpSdkSessions = 0;
73
+ return;
74
+ }
75
+ const key = cacheKey(projectRoot);
76
+ cacheByProject.delete(key);
77
+ probeInFlightByProject.delete(key);
78
+ }
79
+
80
+ export function workflowMcpProbeAdvertisesSurface(tools: readonly string[]): boolean {
81
+ return tools.some((tool) => isWorkflowToolSurfaceName(tool));
82
+ }
83
+
84
+ export function cachedWorkflowMcpCoversRequired(
85
+ projectRoot: string,
86
+ serverName: string,
87
+ required: readonly string[],
88
+ ): boolean {
89
+ const entry = getCachedWorkflowMcpProbe(projectRoot);
90
+ if (!entry || entry.serverName !== serverName) return false;
91
+ return required.every((tool) =>
92
+ entry.tools.some((name) => name === tool || mcpToolMatchesBaseName(name, tool)),
93
+ );
94
+ }
95
+
96
+ async function runProbeAndCacheWorkflowMcp(
97
+ projectRoot: string,
98
+ options: { timeoutMs?: number } = {},
99
+ ): Promise<WorkflowMcpProbeResult> {
100
+ const root = cacheKey(projectRoot);
101
+ const launch = detectWorkflowMcpLaunchConfig(root);
102
+ const serverName = launch?.name ?? "gsd-workflow";
103
+
104
+ const cached = getCachedWorkflowMcpProbe(projectRoot);
105
+ if (cached && workflowMcpProbeAdvertisesSurface(cached.tools)) {
106
+ return { ok: true, tools: cached.tools, serverName: cached.serverName };
107
+ }
108
+
109
+ const result = await testMcpServerConnection(serverName, {
110
+ projectDir: root,
111
+ timeoutMs: options.timeoutMs ?? WORKFLOW_MCP_PROBE_TIMEOUT_MS,
112
+ });
113
+ if (result.ok && workflowMcpProbeAdvertisesSurface(result.tools)) {
114
+ recordWorkflowMcpProbe(projectRoot, serverName, result.tools);
115
+ }
116
+ return {
117
+ ok: result.ok,
118
+ tools: result.tools,
119
+ serverName,
120
+ error: result.error,
121
+ };
122
+ }
123
+
124
+ export async function probeAndCacheWorkflowMcp(
125
+ projectRoot: string,
126
+ options: { timeoutMs?: number } = {},
127
+ ): Promise<WorkflowMcpProbeResult> {
128
+ const key = cacheKey(projectRoot);
129
+ const inFlight = probeInFlightByProject.get(key);
130
+ if (inFlight) return inFlight;
131
+
132
+ const promise = runProbeAndCacheWorkflowMcp(projectRoot, options).finally(() => {
133
+ probeInFlightByProject.delete(key);
134
+ });
135
+ probeInFlightByProject.set(key, promise);
136
+ return promise;
137
+ }
138
+
139
+ /** Fire-and-forget probe so /gsd dispatch often hits a warm cache. */
140
+ export function warmWorkflowMcpProbeInBackground(projectRoot: string): void {
141
+ if (activeWorkflowMcpSdkSessions > 0) return;
142
+
143
+ const key = cacheKey(projectRoot);
144
+ if (getCachedWorkflowMcpProbe(projectRoot)) return;
145
+ if (probeInFlightByProject.has(key)) return;
146
+
147
+ void probeAndCacheWorkflowMcp(projectRoot).catch(() => {
148
+ // Background warm is best-effort.
149
+ });
150
+ }
@@ -218,52 +218,54 @@ export function createWorktreeSafetyModule(
218
218
  }
219
219
 
220
220
  let registered: readonly RegisteredWorktree[] | undefined;
221
- try {
222
- registered = deps.listRegisteredWorktrees?.(projectRoot);
223
- } catch (error) {
224
- return failure(
225
- "worktree-git-probe-failed",
226
- `Unable to list registered worktrees for project root ${projectRoot}.`,
227
- "Recover or recreate the milestone worktree before dispatching the source-writing Unit.",
228
- { projectRoot, error: errorMessage(error) },
229
- );
230
- }
231
- if (registered && !registered.some((worktree) => samePath(worktree.path, unitRoot))) {
232
- const wasPreviouslyTracked = unregisteredRecoveryFailed.has(unitRoot);
233
- let attemptedPrune = false;
221
+ if (isolationMode === "worktree") {
222
+ try {
223
+ registered = deps.listRegisteredWorktrees?.(projectRoot);
224
+ } catch (error) {
225
+ return failure(
226
+ "worktree-git-probe-failed",
227
+ `Unable to list registered worktrees for project root ${projectRoot}.`,
228
+ "Recover or recreate the milestone worktree before dispatching the source-writing Unit.",
229
+ { projectRoot, error: errorMessage(error) },
230
+ );
231
+ }
232
+ if (registered && !registered.some((worktree) => samePath(worktree.path, unitRoot))) {
233
+ const wasPreviouslyTracked = unregisteredRecoveryFailed.has(unitRoot);
234
+ let attemptedPrune = false;
234
235
 
235
- if (!wasPreviouslyTracked && deps.pruneRegisteredWorktrees) {
236
- attemptedPrune = true;
237
- try {
238
- deps.pruneRegisteredWorktrees(projectRoot);
239
- const rechecked = deps.listRegisteredWorktrees?.(projectRoot);
240
- if (rechecked?.some((worktree) => samePath(worktree.path, unitRoot))) {
241
- unregisteredRecoveryFailed.delete(unitRoot);
242
- registered = rechecked;
243
- } else {
236
+ if (!wasPreviouslyTracked && deps.pruneRegisteredWorktrees) {
237
+ attemptedPrune = true;
238
+ try {
239
+ deps.pruneRegisteredWorktrees(projectRoot);
240
+ const rechecked = deps.listRegisteredWorktrees?.(projectRoot);
241
+ if (rechecked?.some((worktree) => samePath(worktree.path, unitRoot))) {
242
+ unregisteredRecoveryFailed.delete(unitRoot);
243
+ registered = rechecked;
244
+ } else {
245
+ unregisteredRecoveryFailed.add(unitRoot);
246
+ }
247
+ } catch (error) {
244
248
  unregisteredRecoveryFailed.add(unitRoot);
249
+ return failure(
250
+ "worktree-git-probe-failed",
251
+ `Unable to recover unregistered worktree root ${unitRoot}.`,
252
+ "Run 'git worktree prune', then recreate or re-register the milestone worktree before dispatching the source-writing Unit.",
253
+ { projectRoot, unitRoot, error: errorMessage(error) },
254
+ );
245
255
  }
246
- } catch (error) {
247
- unregisteredRecoveryFailed.add(unitRoot);
256
+ }
257
+
258
+ if (!registered?.some((worktree) => samePath(worktree.path, unitRoot))) {
248
259
  return failure(
249
- "worktree-git-probe-failed",
250
- `Unable to recover unregistered worktree root ${unitRoot}.`,
251
- "Run 'git worktree prune', then recreate the milestone worktree before dispatching the source-writing Unit.",
252
- { projectRoot, unitRoot, error: errorMessage(error) },
260
+ "worktree-unregistered",
261
+ `Worktree root ${unitRoot} is not registered with git worktree list.`,
262
+ attemptedPrune || wasPreviouslyTracked
263
+ ? "Worktree recovery was attempted but the root is still unregistered. Recreate or re-register the milestone worktree before dispatching the source-writing Unit."
264
+ : "Run 'git worktree prune'. If still unregistered, recreate or re-register the milestone worktree before dispatching the source-writing Unit.",
265
+ { unitRoot, attemptedPrune, trackedAsFailed: unregisteredRecoveryFailed.has(unitRoot) },
253
266
  );
254
267
  }
255
268
  }
256
-
257
- if (!registered?.some((worktree) => samePath(worktree.path, unitRoot))) {
258
- return failure(
259
- "worktree-unregistered",
260
- `Worktree root ${unitRoot} is not registered with git worktree list.`,
261
- attemptedPrune || wasPreviouslyTracked
262
- ? "Worktree recovery was attempted but the root is still unregistered. Recreate or re-register the milestone worktree before dispatching the source-writing Unit."
263
- : "Run 'git worktree prune'. If still unregistered, recreate or re-register the milestone worktree before dispatching the source-writing Unit.",
264
- { unitRoot, attemptedPrune, trackedAsFailed: unregisteredRecoveryFailed.has(unitRoot) },
265
- );
266
- }
267
269
  }
268
270
 
269
271
  if (input.emptyWorktreeWithProjectContent) {
@@ -105,6 +105,9 @@ const CHILD_ENV_ALLOWLIST = new Set([
105
105
 
106
106
  const MCP_STDERR_MAX_BYTES = 4096;
107
107
 
108
+ /** Short-lived stdio probes must not register/kill production MCP PIDs (see probe-mode.ts). */
109
+ export const GSD_MCP_PROBE_ENV = "GSD_MCP_PROBE";
110
+
108
111
  let cachedStatus: ManagedMcpStatus | null = null;
109
112
  let cachedStatusKey = "";
110
113
 
@@ -385,7 +388,10 @@ export async function testMcpServerConnection(
385
388
  transport = new StdioClientTransport({
386
389
  command: config.command ?? "",
387
390
  args: config.args,
388
- env: buildMcpChildEnv(config.env),
391
+ env: {
392
+ ...buildMcpChildEnv(config.env),
393
+ [GSD_MCP_PROBE_ENV]: "1",
394
+ },
389
395
  cwd: config.cwd,
390
396
  stderr: "pipe",
391
397
  });