@opengsd/gsd-pi 1.2.0-dev.84c56d87 → 1.2.0-dev.8e6112e9

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 (631) 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/headless-events.js +7 -5
  5. package/dist/loader.js +6 -4
  6. package/dist/mcp-server.js +2 -1
  7. package/dist/register-agent-bundles.d.ts +11 -2
  8. package/dist/register-agent-bundles.js +18 -4
  9. package/dist/resource-loader.d.ts +10 -5
  10. package/dist/resource-loader.js +121 -6
  11. package/dist/resources/.managed-resources-content-hash +1 -1
  12. package/dist/resources/GSD-WORKFLOW.md +5 -4
  13. package/dist/resources/extensions/ask-user-questions.js +3 -2
  14. package/dist/resources/extensions/async-jobs/async-bash-tool.js +30 -64
  15. package/dist/resources/extensions/async-jobs/await-tool.js +80 -12
  16. package/dist/resources/extensions/async-jobs/index.js +65 -0
  17. package/dist/resources/extensions/async-jobs/job-manager.js +12 -1
  18. package/dist/resources/extensions/bg-shell/bg-shell-command.js +6 -6
  19. package/dist/resources/extensions/bg-shell/bg-shell-tool.js +10 -7
  20. package/dist/resources/extensions/bg-shell/overlay.js +9 -6
  21. package/dist/resources/extensions/bg-shell/process-manager.js +54 -25
  22. package/dist/resources/extensions/bg-shell/readiness-detector.js +11 -0
  23. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +447 -215
  24. package/dist/resources/extensions/claude-code-cli/turn-assembler.js +33 -1
  25. package/dist/resources/extensions/gsd/auto/closeout.js +215 -0
  26. package/dist/resources/extensions/gsd/auto/custom-verify-retry-store.js +17 -2
  27. package/dist/resources/extensions/gsd/auto/detect-stuck.js +33 -13
  28. package/dist/resources/extensions/gsd/auto/dispatch-history.js +120 -0
  29. package/dist/resources/extensions/gsd/auto/dispatch-key.js +37 -0
  30. package/dist/resources/extensions/gsd/auto/dispatch.js +365 -0
  31. package/dist/resources/extensions/gsd/auto/finalize.js +347 -0
  32. package/dist/resources/extensions/gsd/auto/loop.js +7 -1
  33. package/dist/resources/extensions/gsd/auto/milestone-lease-reclaim.js +56 -0
  34. package/dist/resources/extensions/gsd/auto/orchestrator.js +174 -69
  35. package/dist/resources/extensions/gsd/auto/phase-helpers.js +146 -0
  36. package/dist/resources/extensions/gsd/auto/phases.js +17 -2329
  37. package/dist/resources/extensions/gsd/auto/pre-dispatch.js +534 -0
  38. package/dist/resources/extensions/gsd/auto/session.js +3 -0
  39. package/dist/resources/extensions/gsd/auto/unit-phase.js +694 -0
  40. package/dist/resources/extensions/gsd/auto/workflow-unit-dispatch.js +1 -1
  41. package/dist/resources/extensions/gsd/auto/worktree-safety-phase.js +125 -0
  42. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +11 -34
  43. package/dist/resources/extensions/gsd/auto-dispatch.js +50 -58
  44. package/dist/resources/extensions/gsd/auto-model-selection.js +36 -13
  45. package/dist/resources/extensions/gsd/auto-post-unit.js +30 -12
  46. package/dist/resources/extensions/gsd/auto-prompts.js +78 -19
  47. package/dist/resources/extensions/gsd/auto-start.js +35 -15
  48. package/dist/resources/extensions/gsd/auto-unit-closeout.js +45 -21
  49. package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +5 -4
  50. package/dist/resources/extensions/gsd/auto-verification.js +23 -30
  51. package/dist/resources/extensions/gsd/auto-worktree.js +15 -2
  52. package/dist/resources/extensions/gsd/auto.js +52 -2
  53. package/dist/resources/extensions/gsd/blocked-models.js +28 -0
  54. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +26 -6
  55. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +60 -13
  56. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +2 -2
  57. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +145 -50
  58. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +302 -80
  59. package/dist/resources/extensions/gsd/browser-daemon-auto-prep.js +83 -0
  60. package/dist/resources/extensions/gsd/closeout-wizard.js +92 -0
  61. package/dist/resources/extensions/gsd/commands/context.js +16 -2
  62. package/dist/resources/extensions/gsd/commands-handlers.js +46 -3
  63. package/dist/resources/extensions/gsd/commands-mcp-status.js +2 -2
  64. package/dist/resources/extensions/gsd/commands-workflow-templates.js +9 -2
  65. package/dist/resources/extensions/gsd/consent-question.js +353 -0
  66. package/dist/resources/extensions/gsd/consent-verdict.js +63 -0
  67. package/dist/resources/extensions/gsd/constants.js +0 -2
  68. package/dist/resources/extensions/gsd/crash-recovery.js +8 -3
  69. package/dist/resources/extensions/gsd/db/engine.js +5 -3
  70. package/dist/resources/extensions/gsd/db/queries.js +56 -0
  71. package/dist/resources/extensions/gsd/db-writer.js +8 -17
  72. package/dist/resources/extensions/gsd/dispatch-guard.js +10 -35
  73. package/dist/resources/extensions/gsd/doctor-engine-checks.js +5 -5
  74. package/dist/resources/extensions/gsd/doctor-environment.js +256 -125
  75. package/dist/resources/extensions/gsd/doctor-git-checks.js +2 -18
  76. package/dist/resources/extensions/gsd/engine-hook-contract.js +70 -0
  77. package/dist/resources/extensions/gsd/exec-sandbox.js +30 -10
  78. package/dist/resources/extensions/gsd/files.js +33 -19
  79. package/dist/resources/extensions/gsd/gsd-command-home.js +22 -12
  80. package/dist/resources/extensions/gsd/gsd-db.js +11 -8
  81. package/dist/resources/extensions/gsd/guidance.js +60 -0
  82. package/dist/resources/extensions/gsd/guided-flow.js +93 -4
  83. package/dist/resources/extensions/gsd/health-widget.js +87 -28
  84. package/dist/resources/extensions/gsd/markdown-renderer.js +10 -0
  85. package/dist/resources/extensions/gsd/mcp-bridge.js +10 -0
  86. package/dist/resources/extensions/gsd/memory-relations.js +1 -1
  87. package/dist/resources/extensions/gsd/milestone-closeout.js +85 -24
  88. package/dist/resources/extensions/gsd/milestone-planning-persistence.js +2 -2
  89. package/dist/resources/extensions/gsd/milestone-reopen-events.js +3 -5
  90. package/dist/resources/extensions/gsd/milestone-settlement.js +2 -2
  91. package/dist/resources/extensions/gsd/notifications.js +12 -7
  92. package/dist/resources/extensions/gsd/parsers-legacy.js +16 -4
  93. package/dist/resources/extensions/gsd/preferences-models.js +2 -2
  94. package/dist/resources/extensions/gsd/projection-flush.js +7 -0
  95. package/dist/resources/extensions/gsd/prompts/complete-slice.md +4 -4
  96. package/dist/resources/extensions/gsd/prompts/execute-task.md +3 -2
  97. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  98. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  99. package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -1
  100. package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
  101. package/dist/resources/extensions/gsd/prompts/refine-slice.md +1 -1
  102. package/dist/resources/extensions/gsd/prompts/replan-slice.md +1 -1
  103. package/dist/resources/extensions/gsd/prompts/research-milestone.md +1 -1
  104. package/dist/resources/extensions/gsd/prompts/research-slice.md +1 -1
  105. package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  106. package/dist/resources/extensions/gsd/prompts/run-uat.md +9 -5
  107. package/dist/resources/extensions/gsd/prompts/system.md +5 -2
  108. package/dist/resources/extensions/gsd/prompts/triage-captures.md +1 -1
  109. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +1 -1
  110. package/dist/resources/extensions/gsd/prompts/workflow-start.md +2 -1
  111. package/dist/resources/extensions/gsd/reactive-graph.js +8 -1
  112. package/dist/resources/extensions/gsd/roadmap-slices.js +25 -3
  113. package/dist/resources/extensions/gsd/safety/destructive-confirmation.js +108 -0
  114. package/dist/resources/extensions/gsd/session-lock.js +1 -1
  115. package/dist/resources/extensions/gsd/skill-activation.js +3 -6
  116. package/dist/resources/extensions/gsd/state.js +11 -2
  117. package/dist/resources/extensions/gsd/tool-contract.js +14 -3
  118. package/dist/resources/extensions/gsd/tool-presentation-plan.js +4 -4
  119. package/dist/resources/extensions/gsd/tool-surface-readiness.js +83 -31
  120. package/dist/resources/extensions/gsd/tools/complete-milestone.js +3 -2
  121. package/dist/resources/extensions/gsd/tools/complete-slice.js +22 -12
  122. package/dist/resources/extensions/gsd/tools/complete-task.js +65 -2
  123. package/dist/resources/extensions/gsd/tools/exec-tool.js +5 -0
  124. package/dist/resources/extensions/gsd/tools/plan-slice.js +2 -2
  125. package/dist/resources/extensions/gsd/tools/plan-task.js +2 -2
  126. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +2 -2
  127. package/dist/resources/extensions/gsd/tools/reopen-milestone.js +2 -2
  128. package/dist/resources/extensions/gsd/tools/reopen-slice.js +2 -2
  129. package/dist/resources/extensions/gsd/tools/reopen-task.js +2 -2
  130. package/dist/resources/extensions/gsd/tools/replan-slice.js +2 -2
  131. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +67 -2
  132. package/dist/resources/extensions/gsd/uat-policy.js +40 -15
  133. package/dist/resources/extensions/gsd/unit-context-composer.js +65 -0
  134. package/dist/resources/extensions/gsd/unit-registry.js +34 -4
  135. package/dist/resources/extensions/gsd/verdict-parser.js +1 -1
  136. package/dist/resources/extensions/gsd/verification-verdict.js +2 -1
  137. package/dist/resources/extensions/gsd/workflow-event-ledger.js +91 -0
  138. package/dist/resources/extensions/gsd/workflow-event-vocabulary.js +46 -0
  139. package/dist/resources/extensions/gsd/workflow-events.js +6 -18
  140. package/dist/resources/extensions/gsd/workflow-mcp-auto-prep.js +2 -0
  141. package/dist/resources/extensions/gsd/workflow-mcp-readiness-cache.js +105 -0
  142. package/dist/resources/extensions/gsd/workflow-reconcile.js +21 -56
  143. package/dist/resources/extensions/gsd/worktree-lifecycle.js +3 -2
  144. package/dist/resources/extensions/gsd/worktree-manager.js +7 -1
  145. package/dist/resources/extensions/gsd/worktree-safety.js +28 -26
  146. package/dist/resources/extensions/gsd/worktree.js +8 -1
  147. package/dist/resources/extensions/mcp-client/manager.js +6 -1
  148. package/dist/resources/extensions/shared/gsd-browser-cli.js +45 -3
  149. package/dist/resources/shared/gsd-browser-path-sync.js +214 -0
  150. package/dist/resources/shared/package-manager-detection.js +1 -1
  151. package/dist/resources/shared/package.json +3 -0
  152. package/dist/resources/skills/create-skill/SKILL.md +3 -0
  153. package/dist/resources/skills/create-skill/references/skill-structure.md +1 -0
  154. package/dist/runtime-checks.d.ts +10 -0
  155. package/dist/runtime-checks.js +27 -0
  156. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  157. package/dist/update-check.d.ts +2 -0
  158. package/dist/update-check.js +24 -1
  159. package/dist/update-cmd.js +20 -3
  160. package/dist/web/standalone/.next/BUILD_ID +1 -1
  161. package/dist/web/standalone/.next/app-path-routes-manifest.json +6 -6
  162. package/dist/web/standalone/.next/build-manifest.json +3 -3
  163. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  164. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  165. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  166. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  167. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  168. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  169. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  170. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  171. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  172. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  173. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  174. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  175. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  176. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  177. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  178. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  179. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  180. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  181. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/update/route.js.nft.json +1 -1
  183. package/dist/web/standalone/.next/server/app/index.html +1 -1
  184. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  185. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  186. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  187. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  188. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  189. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  190. package/dist/web/standalone/.next/server/app-paths-manifest.json +6 -6
  191. package/dist/web/standalone/.next/server/chunks/8357.js +2 -2
  192. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  194. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  195. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  196. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  197. package/dist/web/standalone/.next/static/chunks/{796.cf859a427a2cb2ac.js → 796.e0bdc932325d7e03.js} +1 -1
  198. package/dist/web/standalone/.next/static/chunks/{webpack-fbea77b5f9953368.js → webpack-f0285ce91d4ec9ef.js} +1 -1
  199. package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
  200. package/dist/web/standalone/node_modules/postcss/lib/container.js +26 -18
  201. package/dist/web/standalone/node_modules/postcss/lib/css-syntax-error.js +47 -14
  202. package/dist/web/standalone/node_modules/postcss/lib/declaration.js +4 -4
  203. package/dist/web/standalone/node_modules/postcss/lib/fromJSON.js +3 -3
  204. package/dist/web/standalone/node_modules/postcss/lib/input.js +54 -29
  205. package/dist/web/standalone/node_modules/postcss/lib/lazy-result.js +47 -37
  206. package/dist/web/standalone/node_modules/postcss/lib/map-generator.js +26 -9
  207. package/dist/web/standalone/node_modules/postcss/lib/no-work-result.js +57 -55
  208. package/dist/web/standalone/node_modules/postcss/lib/node.js +99 -31
  209. package/dist/web/standalone/node_modules/postcss/lib/parse.js +1 -1
  210. package/dist/web/standalone/node_modules/postcss/lib/parser.js +10 -9
  211. package/dist/web/standalone/node_modules/postcss/lib/postcss.js +12 -12
  212. package/dist/web/standalone/node_modules/postcss/lib/previous-map.js +30 -11
  213. package/dist/web/standalone/node_modules/postcss/lib/processor.js +7 -7
  214. package/dist/web/standalone/node_modules/postcss/lib/result.js +5 -5
  215. package/dist/web/standalone/node_modules/postcss/lib/rule.js +6 -6
  216. package/dist/web/standalone/node_modules/postcss/lib/stringifier.js +69 -28
  217. package/dist/web/standalone/node_modules/postcss/lib/tokenize.js +6 -2
  218. package/dist/web/standalone/node_modules/postcss/package.json +48 -48
  219. package/package.json +3 -3
  220. package/packages/cloud-mcp-gateway/package.json +2 -2
  221. package/packages/contracts/dist/rpc.d.ts +1 -0
  222. package/packages/contracts/dist/rpc.d.ts.map +1 -1
  223. package/packages/contracts/dist/rpc.js.map +1 -1
  224. package/packages/contracts/package.json +1 -1
  225. package/packages/daemon/package.json +4 -4
  226. package/packages/gsd-agent-core/dist/sdk.d.ts.map +1 -1
  227. package/packages/gsd-agent-core/dist/sdk.js +6 -4
  228. package/packages/gsd-agent-core/dist/sdk.js.map +1 -1
  229. package/packages/gsd-agent-core/package.json +5 -5
  230. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts +2 -0
  231. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  232. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js +10 -0
  233. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js.map +1 -1
  234. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +13 -0
  235. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  236. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +55 -6
  237. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  238. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts +2 -0
  239. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts.map +1 -1
  240. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js +34 -5
  241. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js.map +1 -1
  242. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  243. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +7 -0
  244. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  245. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
  246. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js +8 -1
  247. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  248. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.d.ts.map +1 -1
  249. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js +11 -1
  250. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js.map +1 -1
  251. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts +1 -0
  252. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  253. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +12 -0
  254. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
  255. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.d.ts.map +1 -1
  256. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js +4 -4
  257. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js.map +1 -1
  258. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.d.ts.map +1 -1
  259. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js +4 -0
  260. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js.map +1 -1
  261. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  262. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +3 -1
  263. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -1
  264. package/packages/gsd-agent-modes/package.json +7 -7
  265. package/packages/mcp-server/README.md +12 -3
  266. package/packages/mcp-server/dist/cli-runner.d.ts +40 -0
  267. package/packages/mcp-server/dist/cli-runner.d.ts.map +1 -0
  268. package/packages/mcp-server/dist/cli-runner.js +137 -0
  269. package/packages/mcp-server/dist/cli-runner.js.map +1 -0
  270. package/packages/mcp-server/dist/cli.js +2 -53
  271. package/packages/mcp-server/dist/cli.js.map +1 -1
  272. package/packages/mcp-server/dist/moonshot-tool-schema.d.ts +29 -0
  273. package/packages/mcp-server/dist/moonshot-tool-schema.d.ts.map +1 -0
  274. package/packages/mcp-server/dist/moonshot-tool-schema.js +50 -0
  275. package/packages/mcp-server/dist/moonshot-tool-schema.js.map +1 -0
  276. package/packages/mcp-server/dist/pid-registry.d.ts +46 -0
  277. package/packages/mcp-server/dist/pid-registry.d.ts.map +1 -0
  278. package/packages/mcp-server/dist/pid-registry.js +452 -0
  279. package/packages/mcp-server/dist/pid-registry.js.map +1 -0
  280. package/packages/mcp-server/dist/probe-mode.d.ts +4 -0
  281. package/packages/mcp-server/dist/probe-mode.d.ts.map +1 -0
  282. package/packages/mcp-server/dist/probe-mode.js +10 -0
  283. package/packages/mcp-server/dist/probe-mode.js.map +1 -0
  284. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  285. package/packages/mcp-server/dist/server.js +4 -0
  286. package/packages/mcp-server/dist/server.js.map +1 -1
  287. package/packages/mcp-server/dist/stdio-watchdog.d.ts +8 -0
  288. package/packages/mcp-server/dist/stdio-watchdog.d.ts.map +1 -0
  289. package/packages/mcp-server/dist/stdio-watchdog.js +40 -0
  290. package/packages/mcp-server/dist/stdio-watchdog.js.map +1 -0
  291. package/packages/mcp-server/dist/workflow-tools.d.ts +18 -18
  292. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  293. package/packages/mcp-server/dist/workflow-tools.js +161 -81
  294. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  295. package/packages/mcp-server/package.json +5 -4
  296. package/packages/native/package.json +1 -1
  297. package/packages/pi-agent-core/dist/agent-loop.js +43 -2
  298. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  299. package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts +1 -0
  300. package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts.map +1 -1
  301. package/packages/pi-agent-core/dist/harness/env/nodejs.js +34 -3
  302. package/packages/pi-agent-core/dist/harness/env/nodejs.js.map +1 -1
  303. package/packages/pi-agent-core/dist/index.d.ts +1 -0
  304. package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
  305. package/packages/pi-agent-core/dist/index.js +3 -0
  306. package/packages/pi-agent-core/dist/index.js.map +1 -1
  307. package/packages/pi-agent-core/package.json +1 -1
  308. package/packages/pi-ai/README.md +1 -0
  309. package/packages/pi-ai/dist/image-models.generated.d.ts +2 -2
  310. package/packages/pi-ai/dist/image-models.generated.js +6 -6
  311. package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
  312. package/packages/pi-ai/dist/index.d.ts +2 -0
  313. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  314. package/packages/pi-ai/dist/index.js +2 -0
  315. package/packages/pi-ai/dist/index.js.map +1 -1
  316. package/packages/pi-ai/dist/models.generated.d.ts +419 -221
  317. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  318. package/packages/pi-ai/dist/models.generated.js +460 -261
  319. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  320. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  321. package/packages/pi-ai/dist/providers/anthropic.js +12 -7
  322. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  323. package/packages/pi-ai/dist/providers/google-shared.d.ts +5 -0
  324. package/packages/pi-ai/dist/providers/google-shared.d.ts.map +1 -1
  325. package/packages/pi-ai/dist/providers/google-shared.js +12 -3
  326. package/packages/pi-ai/dist/providers/google-shared.js.map +1 -1
  327. package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
  328. package/packages/pi-ai/dist/providers/openai-completions.js +7 -3
  329. package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
  330. package/packages/pi-ai/dist/utils/moonshot-tool-schema.d.ts +9 -0
  331. package/packages/pi-ai/dist/utils/moonshot-tool-schema.d.ts.map +1 -0
  332. package/packages/pi-ai/dist/utils/moonshot-tool-schema.js +34 -0
  333. package/packages/pi-ai/dist/utils/moonshot-tool-schema.js.map +1 -0
  334. package/packages/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
  335. package/packages/pi-ai/dist/utils/oauth/github-copilot.js +6 -2
  336. package/packages/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
  337. package/packages/pi-ai/package.json +3 -2
  338. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +2 -2
  339. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  340. package/packages/pi-coding-agent/dist/core/auth-storage.js +19 -13
  341. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  342. package/packages/pi-coding-agent/dist/core/provider-readiness.d.ts.map +1 -1
  343. package/packages/pi-coding-agent/dist/core/provider-readiness.js +13 -6
  344. package/packages/pi-coding-agent/dist/core/provider-readiness.js.map +1 -1
  345. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +3 -0
  346. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  347. package/packages/pi-coding-agent/dist/core/settings-manager.js +11 -0
  348. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  349. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts +11 -0
  350. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
  351. package/packages/pi-coding-agent/dist/core/tools/bash.js +53 -11
  352. package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
  353. package/packages/pi-coding-agent/dist/index.d.ts +1 -1
  354. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  355. package/packages/pi-coding-agent/dist/index.js +1 -1
  356. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  357. package/packages/pi-coding-agent/dist/theme/theme.d.ts.map +1 -1
  358. package/packages/pi-coding-agent/dist/theme/theme.js +45 -17
  359. package/packages/pi-coding-agent/dist/theme/theme.js.map +1 -1
  360. package/packages/pi-coding-agent/dist/utils/shell.d.ts +28 -2
  361. package/packages/pi-coding-agent/dist/utils/shell.d.ts.map +1 -1
  362. package/packages/pi-coding-agent/dist/utils/shell.js +56 -10
  363. package/packages/pi-coding-agent/dist/utils/shell.js.map +1 -1
  364. package/packages/pi-coding-agent/package.json +7 -7
  365. package/packages/pi-tui/dist/index.d.ts +1 -1
  366. package/packages/pi-tui/dist/index.d.ts.map +1 -1
  367. package/packages/pi-tui/dist/index.js +1 -1
  368. package/packages/pi-tui/dist/index.js.map +1 -1
  369. package/packages/pi-tui/dist/terminal-image.d.ts +33 -0
  370. package/packages/pi-tui/dist/terminal-image.d.ts.map +1 -1
  371. package/packages/pi-tui/dist/terminal-image.js +54 -2
  372. package/packages/pi-tui/dist/terminal-image.js.map +1 -1
  373. package/packages/pi-tui/dist/tui.d.ts +8 -0
  374. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  375. package/packages/pi-tui/dist/tui.js +63 -18
  376. package/packages/pi-tui/dist/tui.js.map +1 -1
  377. package/packages/pi-tui/dist/utils.d.ts.map +1 -1
  378. package/packages/pi-tui/dist/utils.js +110 -36
  379. package/packages/pi-tui/dist/utils.js.map +1 -1
  380. package/packages/pi-tui/package.json +2 -2
  381. package/packages/rpc-client/package.json +2 -2
  382. package/pkg/dist/theme/theme.d.ts.map +1 -1
  383. package/pkg/dist/theme/theme.js +45 -17
  384. package/pkg/dist/theme/theme.js.map +1 -1
  385. package/pkg/package.json +1 -1
  386. package/src/resources/GSD-WORKFLOW.md +5 -4
  387. package/src/resources/extensions/ask-user-questions.ts +7 -2
  388. package/src/resources/extensions/async-jobs/async-bash-cancel.test.ts +360 -0
  389. package/src/resources/extensions/async-jobs/async-bash-tool.ts +33 -56
  390. package/src/resources/extensions/async-jobs/await-tool.test.ts +139 -0
  391. package/src/resources/extensions/async-jobs/await-tool.ts +82 -12
  392. package/src/resources/extensions/async-jobs/index.ts +79 -0
  393. package/src/resources/extensions/async-jobs/job-manager.ts +21 -1
  394. package/src/resources/extensions/bg-shell/bg-shell-command.ts +6 -6
  395. package/src/resources/extensions/bg-shell/bg-shell-tool.ts +10 -6
  396. package/src/resources/extensions/bg-shell/overlay.ts +9 -5
  397. package/src/resources/extensions/bg-shell/process-manager.ts +50 -25
  398. package/src/resources/extensions/bg-shell/readiness-detector.ts +12 -0
  399. package/src/resources/extensions/bg-shell/tests/lifecycle-and-utilities.test.ts +48 -1
  400. package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +40 -1
  401. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +531 -226
  402. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +672 -7
  403. package/src/resources/extensions/claude-code-cli/turn-assembler.ts +38 -1
  404. package/src/resources/extensions/gsd/auto/closeout.ts +309 -0
  405. package/src/resources/extensions/gsd/auto/custom-verify-retry-store.ts +21 -3
  406. package/src/resources/extensions/gsd/auto/detect-stuck.ts +32 -9
  407. package/src/resources/extensions/gsd/auto/dispatch-history.ts +168 -0
  408. package/src/resources/extensions/gsd/auto/dispatch-key.ts +39 -0
  409. package/src/resources/extensions/gsd/auto/dispatch.ts +449 -0
  410. package/src/resources/extensions/gsd/auto/finalize.ts +445 -0
  411. package/src/resources/extensions/gsd/auto/loop.ts +7 -1
  412. package/src/resources/extensions/gsd/auto/milestone-lease-reclaim.ts +74 -0
  413. package/src/resources/extensions/gsd/auto/orchestrator.ts +193 -71
  414. package/src/resources/extensions/gsd/auto/phase-helpers.ts +199 -0
  415. package/src/resources/extensions/gsd/auto/phases.ts +58 -3022
  416. package/src/resources/extensions/gsd/auto/pre-dispatch.ts +704 -0
  417. package/src/resources/extensions/gsd/auto/session.ts +3 -0
  418. package/src/resources/extensions/gsd/auto/unit-phase.ts +910 -0
  419. package/src/resources/extensions/gsd/auto/workflow-unit-dispatch.ts +1 -1
  420. package/src/resources/extensions/gsd/auto/worktree-safety-phase.ts +149 -0
  421. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +18 -48
  422. package/src/resources/extensions/gsd/auto-dispatch.ts +48 -61
  423. package/src/resources/extensions/gsd/auto-model-selection.ts +41 -12
  424. package/src/resources/extensions/gsd/auto-post-unit.ts +33 -12
  425. package/src/resources/extensions/gsd/auto-prompts.ts +115 -35
  426. package/src/resources/extensions/gsd/auto-start.ts +36 -18
  427. package/src/resources/extensions/gsd/auto-unit-closeout.ts +83 -28
  428. package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +4 -4
  429. package/src/resources/extensions/gsd/auto-verification.ts +26 -28
  430. package/src/resources/extensions/gsd/auto-worktree.ts +15 -2
  431. package/src/resources/extensions/gsd/auto.ts +64 -2
  432. package/src/resources/extensions/gsd/blocked-models.ts +49 -0
  433. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +34 -5
  434. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +79 -12
  435. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +2 -2
  436. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +163 -55
  437. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +350 -86
  438. package/src/resources/extensions/gsd/browser-daemon-auto-prep.ts +108 -0
  439. package/src/resources/extensions/gsd/closeout-wizard.ts +102 -0
  440. package/src/resources/extensions/gsd/commands/context.ts +16 -2
  441. package/src/resources/extensions/gsd/commands-handlers.ts +46 -3
  442. package/src/resources/extensions/gsd/commands-mcp-status.ts +2 -2
  443. package/src/resources/extensions/gsd/commands-workflow-templates.ts +11 -4
  444. package/src/resources/extensions/gsd/consent-question.ts +431 -0
  445. package/src/resources/extensions/gsd/consent-verdict.ts +86 -0
  446. package/src/resources/extensions/gsd/constants.ts +0 -3
  447. package/src/resources/extensions/gsd/crash-recovery.ts +10 -2
  448. package/src/resources/extensions/gsd/db/engine.ts +5 -3
  449. package/src/resources/extensions/gsd/db/queries.ts +66 -0
  450. package/src/resources/extensions/gsd/db-writer.ts +11 -19
  451. package/src/resources/extensions/gsd/dispatch-guard.ts +8 -31
  452. package/src/resources/extensions/gsd/doctor-engine-checks.ts +5 -4
  453. package/src/resources/extensions/gsd/doctor-environment.ts +267 -142
  454. package/src/resources/extensions/gsd/doctor-git-checks.ts +2 -19
  455. package/src/resources/extensions/gsd/engine-hook-contract.ts +79 -0
  456. package/src/resources/extensions/gsd/exec-sandbox.ts +49 -9
  457. package/src/resources/extensions/gsd/files.ts +33 -12
  458. package/src/resources/extensions/gsd/gsd-command-home.ts +13 -3
  459. package/src/resources/extensions/gsd/gsd-db.ts +13 -10
  460. package/src/resources/extensions/gsd/guidance.ts +78 -0
  461. package/src/resources/extensions/gsd/guided-flow.ts +145 -24
  462. package/src/resources/extensions/gsd/health-widget.ts +91 -27
  463. package/src/resources/extensions/gsd/markdown-renderer.ts +11 -0
  464. package/src/resources/extensions/gsd/mcp-bridge.ts +39 -0
  465. package/src/resources/extensions/gsd/memory-relations.ts +1 -1
  466. package/src/resources/extensions/gsd/milestone-closeout.ts +109 -24
  467. package/src/resources/extensions/gsd/milestone-planning-persistence.ts +2 -2
  468. package/src/resources/extensions/gsd/milestone-reopen-events.ts +3 -6
  469. package/src/resources/extensions/gsd/milestone-settlement.ts +2 -2
  470. package/src/resources/extensions/gsd/notifications.ts +13 -6
  471. package/src/resources/extensions/gsd/parsers-legacy.ts +16 -4
  472. package/src/resources/extensions/gsd/preferences-models.ts +2 -1
  473. package/src/resources/extensions/gsd/projection-flush.ts +20 -0
  474. package/src/resources/extensions/gsd/prompts/complete-slice.md +4 -4
  475. package/src/resources/extensions/gsd/prompts/execute-task.md +3 -2
  476. package/src/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  477. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  478. package/src/resources/extensions/gsd/prompts/quick-task.md +1 -1
  479. package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
  480. package/src/resources/extensions/gsd/prompts/refine-slice.md +1 -1
  481. package/src/resources/extensions/gsd/prompts/replan-slice.md +1 -1
  482. package/src/resources/extensions/gsd/prompts/research-milestone.md +1 -1
  483. package/src/resources/extensions/gsd/prompts/research-slice.md +1 -1
  484. package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  485. package/src/resources/extensions/gsd/prompts/run-uat.md +9 -5
  486. package/src/resources/extensions/gsd/prompts/system.md +5 -2
  487. package/src/resources/extensions/gsd/prompts/triage-captures.md +1 -1
  488. package/src/resources/extensions/gsd/prompts/validate-milestone.md +1 -1
  489. package/src/resources/extensions/gsd/prompts/workflow-start.md +2 -1
  490. package/src/resources/extensions/gsd/reactive-graph.ts +11 -1
  491. package/src/resources/extensions/gsd/roadmap-slices.ts +28 -3
  492. package/src/resources/extensions/gsd/safety/destructive-confirmation.ts +134 -0
  493. package/src/resources/extensions/gsd/session-lock.ts +1 -1
  494. package/src/resources/extensions/gsd/skill-activation.ts +3 -6
  495. package/src/resources/extensions/gsd/state.ts +12 -1
  496. package/src/resources/extensions/gsd/tests/auto-abort-pause-regression.test.ts +1 -1
  497. package/src/resources/extensions/gsd/tests/auto-blocked-remediation-message.test.ts +1 -1
  498. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +206 -22
  499. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +97 -1
  500. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +273 -37
  501. package/src/resources/extensions/gsd/tests/auto-pause-double-entry-guard.test.ts +1 -1
  502. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +77 -1
  503. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +2 -1
  504. package/src/resources/extensions/gsd/tests/auto-remote-session-lock-cleanup.test.ts +65 -3
  505. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +236 -0
  506. package/src/resources/extensions/gsd/tests/auto-unit-closeout.test.ts +169 -1
  507. package/src/resources/extensions/gsd/tests/blocked-models.test.ts +19 -0
  508. package/src/resources/extensions/gsd/tests/browser-daemon-auto-prep.test.ts +144 -0
  509. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +42 -0
  510. package/src/resources/extensions/gsd/tests/complete-task.test.ts +141 -5
  511. package/src/resources/extensions/gsd/tests/consent-question.test.ts +351 -0
  512. package/src/resources/extensions/gsd/tests/custom-verify-retry-store.test.ts +67 -0
  513. package/src/resources/extensions/gsd/tests/db-writer.test.ts +15 -4
  514. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +12 -11
  515. package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +36 -0
  516. package/src/resources/extensions/gsd/tests/destructive-confirmation.test.ts +303 -0
  517. package/src/resources/extensions/gsd/tests/discuss-routing-fixes.test.ts +12 -2
  518. package/src/resources/extensions/gsd/tests/dispatch-history.test.ts +328 -0
  519. package/src/resources/extensions/gsd/tests/dist-redirect.mjs +8 -0
  520. package/src/resources/extensions/gsd/tests/doctor-git-checks-terminal.test.ts +73 -0
  521. package/src/resources/extensions/gsd/tests/dynamic-bash-no-cap.test.ts +132 -0
  522. package/src/resources/extensions/gsd/tests/engine-hook-contract.test.ts +148 -0
  523. package/src/resources/extensions/gsd/tests/engine-interfaces-contract.test.ts +117 -91
  524. package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +113 -0
  525. package/src/resources/extensions/gsd/tests/exec-graceful-kill.test.ts +193 -0
  526. package/src/resources/extensions/gsd/tests/exec-tool.test.ts +29 -1
  527. package/src/resources/extensions/gsd/tests/gsd-command-home.test.ts +120 -0
  528. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +27 -0
  529. package/src/resources/extensions/gsd/tests/guidance.test.ts +23 -0
  530. package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +18 -6
  531. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +15 -0
  532. package/src/resources/extensions/gsd/tests/integration/doctor-environment-async.test.ts +104 -0
  533. package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +217 -0
  534. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +47 -16
  535. package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +3 -1
  536. package/src/resources/extensions/gsd/tests/mcp-readiness-preflight.test.ts +205 -0
  537. package/src/resources/extensions/gsd/tests/mcp-status.test.ts +6 -5
  538. package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +95 -4
  539. package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +1 -1
  540. package/src/resources/extensions/gsd/tests/milestone-report-path.test.ts +1 -1
  541. package/src/resources/extensions/gsd/tests/milestone-settlement.test.ts +92 -0
  542. package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +1 -1
  543. package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +32 -1
  544. package/src/resources/extensions/gsd/tests/notifications.test.ts +64 -9
  545. package/src/resources/extensions/gsd/tests/oauth-api-model-routing.test.ts +167 -0
  546. package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +18 -0
  547. package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +2 -2
  548. package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +143 -0
  549. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +1 -1
  550. package/src/resources/extensions/gsd/tests/phases-terminal-complete-idempotent.test.ts +242 -0
  551. package/src/resources/extensions/gsd/tests/plan-gate-failed-doctor-heal-hint.test.ts +3 -3
  552. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +63 -2
  553. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +10 -2
  554. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +124 -6
  555. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +2 -4
  556. package/src/resources/extensions/gsd/tests/remote-notification-from-desktop.test.ts +31 -81
  557. package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +68 -0
  558. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +26 -2
  559. package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +170 -48
  560. package/src/resources/extensions/gsd/tests/skill-activation.test.ts +20 -17
  561. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +7 -3
  562. package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +1 -1
  563. package/src/resources/extensions/gsd/tests/teardown-chdir-failure-clears-registry.test.ts +17 -0
  564. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +45 -2
  565. package/src/resources/extensions/gsd/tests/tool-surface-readiness.test.ts +184 -10
  566. package/src/resources/extensions/gsd/tests/tool-unavailable-retry.test.ts +33 -0
  567. package/src/resources/extensions/gsd/tests/transport-gate-double-complete.test.ts +139 -0
  568. package/src/resources/extensions/gsd/tests/uat-policy.test.ts +88 -0
  569. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +44 -0
  570. package/src/resources/extensions/gsd/tests/uok-audit-unified.test.ts +8 -0
  571. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +1 -1
  572. package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +2 -0
  573. package/src/resources/extensions/gsd/tests/workflow-events.test.ts +19 -0
  574. package/src/resources/extensions/gsd/tests/workflow-mcp-readiness-cache.test.ts +119 -0
  575. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +65 -2
  576. package/src/resources/extensions/gsd/tests/workflow-phase-contract-matrix.test.ts +332 -0
  577. package/src/resources/extensions/gsd/tests/workflow-reconcile.test.ts +20 -0
  578. package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +92 -0
  579. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +273 -38
  580. package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +1 -1
  581. package/src/resources/extensions/gsd/tests/worktree-project-root-degrade.test.ts +1 -1
  582. package/src/resources/extensions/gsd/tests/worktree-safety-phase.test.ts +100 -0
  583. package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +72 -0
  584. package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +22 -0
  585. package/src/resources/extensions/gsd/tests/worktree.test.ts +18 -0
  586. package/src/resources/extensions/gsd/tests/write-gate-seam.test.ts +358 -0
  587. package/src/resources/extensions/gsd/tests/write-gate.test.ts +67 -1
  588. package/src/resources/extensions/gsd/tool-contract.ts +38 -3
  589. package/src/resources/extensions/gsd/tool-presentation-plan.ts +4 -4
  590. package/src/resources/extensions/gsd/tool-surface-readiness.ts +126 -19
  591. package/src/resources/extensions/gsd/tools/complete-milestone.ts +3 -2
  592. package/src/resources/extensions/gsd/tools/complete-slice.ts +22 -12
  593. package/src/resources/extensions/gsd/tools/complete-task.ts +90 -2
  594. package/src/resources/extensions/gsd/tools/exec-tool.ts +4 -0
  595. package/src/resources/extensions/gsd/tools/plan-slice.ts +2 -2
  596. package/src/resources/extensions/gsd/tools/plan-task.ts +2 -2
  597. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +2 -2
  598. package/src/resources/extensions/gsd/tools/reopen-milestone.ts +2 -2
  599. package/src/resources/extensions/gsd/tools/reopen-slice.ts +2 -2
  600. package/src/resources/extensions/gsd/tools/reopen-task.ts +2 -2
  601. package/src/resources/extensions/gsd/tools/replan-slice.ts +2 -2
  602. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +81 -2
  603. package/src/resources/extensions/gsd/uat-policy.ts +60 -15
  604. package/src/resources/extensions/gsd/unit-context-composer.ts +99 -0
  605. package/src/resources/extensions/gsd/unit-registry.ts +34 -4
  606. package/src/resources/extensions/gsd/verdict-parser.ts +1 -1
  607. package/src/resources/extensions/gsd/verification-verdict.ts +4 -2
  608. package/src/resources/extensions/gsd/workflow-event-ledger.ts +131 -0
  609. package/src/resources/extensions/gsd/workflow-event-vocabulary.ts +59 -0
  610. package/src/resources/extensions/gsd/workflow-events.ts +12 -20
  611. package/src/resources/extensions/gsd/workflow-mcp-auto-prep.ts +2 -0
  612. package/src/resources/extensions/gsd/workflow-mcp-readiness-cache.ts +150 -0
  613. package/src/resources/extensions/gsd/workflow-reconcile.ts +29 -62
  614. package/src/resources/extensions/gsd/worktree-lifecycle.ts +3 -8
  615. package/src/resources/extensions/gsd/worktree-manager.ts +6 -1
  616. package/src/resources/extensions/gsd/worktree-safety.ts +41 -39
  617. package/src/resources/extensions/gsd/worktree.ts +7 -1
  618. package/src/resources/extensions/mcp-client/manager.ts +7 -1
  619. package/src/resources/extensions/shared/gsd-browser-cli.ts +54 -3
  620. package/src/resources/shared/gsd-browser-path-sync.ts +273 -0
  621. package/src/resources/shared/package-manager-detection.ts +1 -1
  622. package/src/resources/shared/package.json +3 -0
  623. package/src/resources/skills/create-skill/SKILL.md +3 -0
  624. package/src/resources/skills/create-skill/references/skill-structure.md +1 -0
  625. package/dist/resources/extensions/gsd/user-input-boundary.js +0 -218
  626. package/dist/resources/skills/gsd-browser/SKILL.md +0 -41
  627. package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +0 -173
  628. package/src/resources/extensions/gsd/user-input-boundary.ts +0 -216
  629. package/src/resources/skills/gsd-browser/SKILL.md +0 -41
  630. /package/dist/web/standalone/.next/static/{AOpDeK_gJHU8OZjRo31gQ → pZbHa49xI-knmKlphIRq0}/_buildManifest.js +0 -0
  631. /package/dist/web/standalone/.next/static/{AOpDeK_gJHU8OZjRo31gQ → pZbHa49xI-knmKlphIRq0}/_ssgManifest.js +0 -0
@@ -317,6 +317,24 @@ test('(k2) run-uat prompt references gsd_uat_result_save, not direct write', ()
317
317
  );
318
318
  });
319
319
 
320
+ test('(k3) run-uat prompt warns that .gsd glob misses can be symlink traversal artifacts', async () => {
321
+ const base = createFixtureBase();
322
+ try {
323
+ const uatRel = '.gsd/milestones/M001/slices/S01/S01-UAT.md';
324
+ const uatContent = makeUatContent('runtime-executable');
325
+ writeSliceFile(base, 'M001', 'S01', 'UAT', uatContent);
326
+
327
+ const prompt = await buildRunUatPrompt('M001', 'S01', uatRel, uatContent, base);
328
+
329
+ assert.match(prompt, /\.gsd\/\*\*/);
330
+ assert.match(prompt, /symlink-backed/i);
331
+ assert.match(prompt, /do not infer that the GSD harness is missing/i);
332
+ assert.match(prompt, /use the preloaded UAT context/i);
333
+ } finally {
334
+ cleanup(base);
335
+ }
336
+ });
337
+
320
338
  test('(l) dispatch preconditions via resolveSliceFile', () => {
321
339
  const base = createFixtureBase();
322
340
  const uatContent = makeUatContent('artifact-driven');
@@ -731,6 +749,75 @@ test('(u) run-uat prompt promotes artifact-driven browser specs to browser-execu
731
749
  }
732
750
  });
733
751
 
752
+ test('(w) run-uat prompt promotes browser-executable harness specs to runtime-executable (M006/S01)', async () => {
753
+ const base = createFixtureBase();
754
+ try {
755
+ const uatRel = '.gsd/milestones/M006/slices/S01/S01-UAT.md';
756
+ const uatContent = [
757
+ '# S01 UAT',
758
+ '',
759
+ '## UAT Type',
760
+ '- UAT mode: browser-executable',
761
+ '',
762
+ '## Preconditions',
763
+ '- Start the local app server with `npm run start`.',
764
+ '- Open the app at `http://127.0.0.1:4173`.',
765
+ '',
766
+ '## Evidence',
767
+ '- Fresh closeout verification command: `npm run test:uat`',
768
+ ].join('\n');
769
+ writeSliceFile(base, 'M006', 'S01', 'UAT', uatContent);
770
+
771
+ const prompt = await buildRunUatPrompt('M006', 'S01', uatRel, uatContent, base);
772
+
773
+ assert.match(prompt, /\*\*Detected UAT mode:\*\*\s*`runtime-executable`/);
774
+ assert.match(prompt, /uatType: "runtime-executable"/);
775
+ assert.match(prompt, /Runtime harness override/i);
776
+ assert.match(prompt, /Do \*\*not\*\* call `uat-service-start`/);
777
+ assert.doesNotMatch(prompt, /uatType: "browser-executable"/);
778
+ } finally {
779
+ cleanup(base);
780
+ }
781
+ });
782
+
783
+ test('(w2) run-uat prompt promotes harness from slice context when UAT only names test:server (M007/S01)', async () => {
784
+ const base = createFixtureBase();
785
+ try {
786
+ const uatRel = '.gsd/milestones/M007/slices/S01/S01-UAT.md';
787
+ const uatContent = [
788
+ '# S01 UAT',
789
+ '',
790
+ '## UAT Type',
791
+ '- UAT mode: browser-executable',
792
+ '',
793
+ '## Preconditions',
794
+ '- Start the dev/local verification server with `npm run test:server`.',
795
+ '- Open the app at the localhost URL printed by the server.',
796
+ ].join('\n');
797
+ writeSliceFile(base, 'M007', 'S01', 'UAT', uatContent);
798
+ writeSliceFile(
799
+ base,
800
+ 'M007',
801
+ 'S01',
802
+ 'SUMMARY',
803
+ [
804
+ '# S01 Summary',
805
+ '',
806
+ 'Verification: `npm run test:uat` passed with clean browser diagnostics.',
807
+ ].join('\n'),
808
+ );
809
+
810
+ const prompt = await buildRunUatPrompt('M007', 'S01', uatRel, uatContent, base);
811
+
812
+ assert.match(prompt, /\*\*Detected UAT mode:\*\*\s*`runtime-executable`/);
813
+ assert.match(prompt, /Runtime harness override/i);
814
+ assert.match(prompt, /npm run test:server/);
815
+ assert.match(prompt, /uatType: "runtime-executable"/);
816
+ } finally {
817
+ cleanup(base);
818
+ }
819
+ });
820
+
734
821
  test('(v) run-uat prompt keeps deferred browser work artifact-driven', async () => {
735
822
  const base = createFixtureBase();
736
823
  try {
@@ -748,4 +835,134 @@ test('(v) run-uat prompt keeps deferred browser work artifact-driven', async ()
748
835
  cleanup(base);
749
836
  }
750
837
  });
838
+
839
+ test('(x) checkNeedsRunUat returns runtime-executable when slice SUMMARY names a self-contained harness (M007/S01)', async () => {
840
+ // Regression: the dispatch gate must surface the same effective UAT mode
841
+ // that buildRunUatPrompt emits. When the UAT file alone declares
842
+ // `browser-executable` but the slice SUMMARY references `npm run test:uat`,
843
+ // the prompt promotes to `runtime-executable` — and so must the gate, or
844
+ // the auto-dispatch path requires browser tools / warms up the browser
845
+ // daemon (and may stop dispatch entirely) for a UAT that never touches
846
+ // the browser. See cursor[bot] review on PR #696.
847
+ const base = createFixtureBase();
848
+ try {
849
+ const roadmapDir = join(base, '.gsd', 'milestones', 'M007');
850
+ mkdirSync(roadmapDir, { recursive: true });
851
+ writeFileSync(
852
+ join(roadmapDir, 'M007-ROADMAP.md'),
853
+ [
854
+ '# M007: Test roadmap',
855
+ '',
856
+ '## Slices',
857
+ '',
858
+ '- [x] **S01: Only slice** `risk:low` `depends:[]`',
859
+ '',
860
+ '## Boundary Map',
861
+ '',
862
+ ].join('\n'),
863
+ );
864
+ writeSliceFile(
865
+ base,
866
+ 'M007',
867
+ 'S01',
868
+ 'UAT',
869
+ [
870
+ '# S01 UAT',
871
+ '',
872
+ '## UAT Type',
873
+ '- UAT mode: browser-executable',
874
+ '',
875
+ '## Preconditions',
876
+ '- Start the dev/local verification server with `npm run test:server`.',
877
+ ].join('\n'),
878
+ );
879
+ writeSliceFile(
880
+ base,
881
+ 'M007',
882
+ 'S01',
883
+ 'SUMMARY',
884
+ [
885
+ '# S01 Summary',
886
+ '',
887
+ 'Verification: `npm run test:uat` passed with clean browser diagnostics.',
888
+ ].join('\n'),
889
+ );
890
+
891
+ const state = {
892
+ activeMilestone: { id: 'M007', title: 'Test roadmap' },
893
+ activeSlice: null,
894
+ activeTask: null,
895
+ phase: 'validating-milestone',
896
+ recentDecisions: [],
897
+ blockers: [],
898
+ nextAction: 'Validate M007',
899
+ registry: [],
900
+ } as const;
901
+
902
+ const result = await checkNeedsRunUat(base, 'M007', state as any, { uat_dispatch: true } as any);
903
+ assert.deepStrictEqual(
904
+ result,
905
+ { sliceId: 'S01', uatType: 'runtime-executable' },
906
+ 'dispatch gate must mirror the prompt`s runtime-executable promotion so it does not require browser tools',
907
+ );
908
+ } finally {
909
+ cleanup(base);
910
+ }
911
+ });
912
+
913
+ test('(x2) checkNeedsRunUat leaves true browser-executable UAT unpromoted when no harness is referenced', async () => {
914
+ // Counter-test for (x): when the slice SUMMARY does NOT name a
915
+ // self-contained harness, the dispatch gate must still require browser
916
+ // tools for a genuinely browser-executable UAT.
917
+ const base = createFixtureBase();
918
+ try {
919
+ const roadmapDir = join(base, '.gsd', 'milestones', 'M008');
920
+ mkdirSync(roadmapDir, { recursive: true });
921
+ writeFileSync(
922
+ join(roadmapDir, 'M008-ROADMAP.md'),
923
+ [
924
+ '# M008: Test roadmap',
925
+ '',
926
+ '## Slices',
927
+ '',
928
+ '- [x] **S01: Only slice** `risk:low` `depends:[]`',
929
+ '',
930
+ '## Boundary Map',
931
+ '',
932
+ ].join('\n'),
933
+ );
934
+ writeSliceFile(base, 'M008', 'S01', 'UAT', makeBrowserObservableUatContent('browser-executable'));
935
+ writeSliceFile(
936
+ base,
937
+ 'M008',
938
+ 'S01',
939
+ 'SUMMARY',
940
+ [
941
+ '# S01 Summary',
942
+ '',
943
+ 'Verification: clicked through the UI and confirmed the search box filters todos.',
944
+ ].join('\n'),
945
+ );
946
+
947
+ const state = {
948
+ activeMilestone: { id: 'M008', title: 'Test roadmap' },
949
+ activeSlice: null,
950
+ activeTask: null,
951
+ phase: 'validating-milestone',
952
+ recentDecisions: [],
953
+ blockers: [],
954
+ nextAction: 'Validate M008',
955
+ registry: [],
956
+ } as const;
957
+
958
+ const result = await checkNeedsRunUat(base, 'M008', state as any, { uat_dispatch: true } as any);
959
+ assert.deepStrictEqual(
960
+ result,
961
+ { sliceId: 'S01', uatType: 'browser-executable' },
962
+ 'a true browser-executable UAT without a harness reference must keep its browser-executable mode',
963
+ );
964
+ } finally {
965
+ cleanup(base);
966
+ }
967
+ });
751
968
  });
@@ -15,12 +15,27 @@ import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
15
15
  import { tmpdir } from "node:os";
16
16
  import { join } from "node:path";
17
17
 
18
+ /** Create a temp project root with a git repo for phase-function tests. */
19
+ function makeTestBase(prefix: string): string {
20
+ const base = mkdtempSync(join(tmpdir(), prefix));
21
+ execFileSync("git", ["init", "--initial-branch=main"], { cwd: base, stdio: "ignore" });
22
+ execFileSync("git", ["config", "user.email", "test@test.com"], { cwd: base, stdio: "ignore" });
23
+ execFileSync("git", ["config", "user.name", "Test"], { cwd: base, stdio: "ignore" });
24
+ writeFileSync(join(base, "README.md"), "# test\n");
25
+ execFileSync("git", ["add", "README.md"], { cwd: base, stdio: "ignore" });
26
+ execFileSync("git", ["commit", "-m", "chore: seed"], { cwd: base, stdio: "ignore" });
27
+ return base;
28
+ }
29
+
18
30
  import type { JournalEntry } from "../journal.js";
19
31
  import type { LoopDeps } from "../auto/loop-deps.js";
20
32
  import { WorktreeStateProjection } from "../worktree-state-projection.js";
21
33
  import type { IterationContext, LoopState, PreDispatchData, IterationData } from "../auto/types.js";
22
34
  import type { SessionLockStatus } from "../session-lock.js";
23
- import { runDispatch, runUnitPhase, runPreDispatch, runFinalize } from "../auto/phases.js";
35
+ import { runDispatch } from "../auto/dispatch.js";
36
+ import { runUnitPhase } from "../auto/unit-phase.js";
37
+ import { runPreDispatch } from "../auto/pre-dispatch.js";
38
+ import { runFinalize } from "../auto/finalize.js";
24
39
  import { readUnitRuntimeRecord } from "../unit-runtime.js";
25
40
  import { ModelPolicyDispatchBlockedError } from "../auto-model-selection.js";
26
41
  import {
@@ -182,7 +197,7 @@ function makeSession() {
182
197
  verbose: false,
183
198
  stepMode: false,
184
199
  paused: false,
185
- basePath: "/tmp/project",
200
+ basePath: makeTestBase("gsd-journal-session-"),
186
201
  originalBasePath: "",
187
202
  currentMilestoneId: "M001",
188
203
  currentUnit: null,
@@ -296,10 +311,18 @@ test("runDispatch emits dispatch-stop when dispatch returns stop action", async
296
311
  assert.equal(stopEvents[0].flowId, ic.flowId);
297
312
  });
298
313
 
299
- test("runDispatch checks prior-slice completion against the project root in worktree mode", async () => {
314
+ test("runDispatch checks prior-slice completion against the project root in worktree mode", async (t) => {
300
315
  const capture = createEventCapture();
301
316
  const guardCalls: Array<{ fn: string; args: unknown[] }> = [];
317
+ const projectRoot = makeTestBase("gsd-wt-prior-slice-");
318
+ const milestoneId = "M029-xoklo9";
319
+ const worktreeRoot = join(projectRoot, ".gsd", "worktrees", milestoneId);
320
+ execFileSync("git", ["worktree", "add", "-b", `auto/${milestoneId}`, worktreeRoot], { cwd: projectRoot, stdio: "ignore" });
321
+ t.after(() => rmSync(projectRoot, { recursive: true, force: true }));
322
+
302
323
  const deps = makeMockDeps(capture, {
324
+ getIsolationMode: () => "worktree",
325
+ autoWorktreeBranch: (mid: string) => `auto/${mid}`,
303
326
  getMainBranch: (basePath: string) => {
304
327
  guardCalls.push({ fn: "getMainBranch", args: [basePath] });
305
328
  return "main";
@@ -320,19 +343,21 @@ test("runDispatch checks prior-slice completion against the project root in work
320
343
  const ic = makeIC(deps, {
321
344
  s: {
322
345
  ...makeSession(),
323
- basePath: "/tmp/project/.gsd/worktrees/M029-xoklo9",
324
- originalBasePath: "/tmp/project",
346
+ basePath: worktreeRoot,
347
+ originalBasePath: projectRoot,
348
+ canonicalProjectRoot: projectRoot,
349
+ currentMilestoneId: milestoneId,
325
350
  } as any,
326
351
  });
327
352
  const preData: PreDispatchData = {
328
353
  state: {
329
354
  phase: "executing",
330
- activeMilestone: { id: "M029-xoklo9", title: "Test", status: "active" },
355
+ activeMilestone: { id: milestoneId, title: "Test", status: "active" },
331
356
  activeSlice: { id: "S01", title: "Slice 1" },
332
- registry: [{ id: "M029-xoklo9", status: "active" }],
357
+ registry: [{ id: milestoneId, status: "active" }],
333
358
  blockers: [],
334
359
  } as any,
335
- mid: "M029-xoklo9",
360
+ mid: milestoneId,
336
361
  midTitle: "Test Milestone",
337
362
  };
338
363
 
@@ -342,12 +367,12 @@ test("runDispatch checks prior-slice completion against the project root in work
342
367
  consecutiveFinalizeTimeouts: 0,
343
368
  });
344
369
 
345
- assert.equal(result.action, "next");
370
+ assert.equal(result.action, "next", "dispatch must proceed under worktree isolation");
346
371
  assert.deepEqual(guardCalls, [
347
- { fn: "getMainBranch", args: ["/tmp/project"] },
372
+ { fn: "getMainBranch", args: [projectRoot] },
348
373
  {
349
374
  fn: "getPriorSliceCompletionBlocker",
350
- args: ["/tmp/project", "main", "execute-task", "M001/S01/T01"],
375
+ args: [projectRoot, "main", "execute-task", "M001/S01/T01"],
351
376
  },
352
377
  ]);
353
378
  });
@@ -434,6 +459,9 @@ test("runDispatch pauses when execute-task artifacts exist but DB status is stil
434
459
  const sliceDir = join(base, ".gsd", "milestones", "M001", "slices", "S01");
435
460
  const tasksDir = join(sliceDir, "tasks");
436
461
  mkdirSync(tasksDir, { recursive: true });
462
+ execFileSync("git", ["init", "--initial-branch=main"], { cwd: base, stdio: "ignore" });
463
+ execFileSync("git", ["config", "user.email", "test@test.com"], { cwd: base, stdio: "ignore" });
464
+ execFileSync("git", ["config", "user.name", "Test"], { cwd: base, stdio: "ignore" });
437
465
  openDatabase(join(base, ".gsd", "gsd.db"));
438
466
  insertMilestone({ id: "M001", title: "Test", status: "active" });
439
467
  insertSlice({ id: "S01", milestoneId: "M001", title: "Slice", status: "in_progress" });
@@ -517,6 +545,9 @@ test("runDispatch pauses at Level 2 when execute-task artifacts exist but DB sta
517
545
  const sliceDir = join(base, ".gsd", "milestones", "M001", "slices", "S01");
518
546
  const tasksDir = join(sliceDir, "tasks");
519
547
  mkdirSync(tasksDir, { recursive: true });
548
+ execFileSync("git", ["init", "--initial-branch=main"], { cwd: base, stdio: "ignore" });
549
+ execFileSync("git", ["config", "user.email", "test@test.com"], { cwd: base, stdio: "ignore" });
550
+ execFileSync("git", ["config", "user.name", "Test"], { cwd: base, stdio: "ignore" });
520
551
  openDatabase(join(base, ".gsd", "gsd.db"));
521
552
  insertMilestone({ id: "M001", title: "Test", status: "active" });
522
553
  insertSlice({ id: "S01", milestoneId: "M001", title: "Slice", status: "in_progress" });
@@ -888,7 +919,7 @@ test("runUnitPhase increments unitDispatchCount for repeated artifact-missing re
888
919
 
889
920
  test("runUnitPhase pre-dispatch model validation failures do not emit unit-start or dispatch runtime state", async (t) => {
890
921
  const capture = createEventCapture();
891
- const base = mkdtempSync(join(tmpdir(), `gsd-pre-dispatch-block-${randomUUID()}`));
922
+ const base = makeTestBase(`gsd-pre-dispatch-block-${randomUUID()}`);
892
923
  t.after(() => rmSync(base, { recursive: true, force: true }));
893
924
 
894
925
  const deps = makeMockDeps(capture, {
@@ -1084,7 +1115,7 @@ test("terminal event is emitted on blocked state", async () => {
1084
1115
  });
1085
1116
 
1086
1117
  test("#4671: plan-v2 missing CONTEXT.md reaches dispatch recovery instead of pausing", async () => {
1087
- const basePath = mkdtempSync(join(tmpdir(), "gsd-4671-predispatch-"));
1118
+ const basePath = makeTestBase("gsd-4671-predispatch-");
1088
1119
  mkdirSync(join(basePath, ".gsd", "milestones", "M001", "slices", "S01", "tasks"), { recursive: true });
1089
1120
  openDatabase(join(basePath, ".gsd", "gsd.db"));
1090
1121
  try {
@@ -1141,7 +1172,7 @@ test("#4671: plan-v2 missing CONTEXT.md reaches dispatch recovery instead of pau
1141
1172
  });
1142
1173
 
1143
1174
  test("plan-v2 empty graph rederives state before pausing", async () => {
1144
- const basePath = mkdtempSync(join(tmpdir(), "gsd-plan-v2-empty-graph-"));
1175
+ const basePath = makeTestBase("gsd-plan-v2-empty-graph-");
1145
1176
  mkdirSync(join(basePath, ".gsd", "milestones", "M001"), { recursive: true });
1146
1177
  writeFileSync(
1147
1178
  join(basePath, ".gsd", "milestones", "M001", "M001-CONTEXT.md"),
@@ -1204,7 +1235,7 @@ test("plan-v2 empty graph rederives state before pausing", async () => {
1204
1235
  });
1205
1236
 
1206
1237
  test("plan-v2 empty graph pauses after one failed rederive", async () => {
1207
- const basePath = mkdtempSync(join(tmpdir(), "gsd-plan-v2-empty-graph-pause-"));
1238
+ const basePath = makeTestBase("gsd-plan-v2-empty-graph-pause-");
1208
1239
  mkdirSync(join(basePath, ".gsd", "milestones", "M001"), { recursive: true });
1209
1240
  writeFileSync(
1210
1241
  join(basePath, ".gsd", "milestones", "M001", "M001-CONTEXT.md"),
@@ -1394,7 +1425,7 @@ test("session-failed cancellations close out and emit unit-end before hard stop"
1394
1425
  test("runFinalize pauses and emits unit-end when pre-verification times out", async () => {
1395
1426
  const capture = createEventCapture();
1396
1427
  let pauseCalls = 0;
1397
- const basePath = mkdtempSync(join(tmpdir(), "gsd-finalize-timeout-"));
1428
+ const basePath = makeTestBase("gsd-finalize-timeout-");
1398
1429
 
1399
1430
  const deps = makeMockDeps(capture, {
1400
1431
  pauseAuto: async () => { pauseCalls++; },
@@ -60,7 +60,9 @@ test("ensureProjectWorkflowMcpConfig creates .mcp.json with workflow and browser
60
60
  assert.equal(typeof browserArgs[mcpArgIndex + 6], "string");
61
61
  assert.ok((browserArgs[mcpArgIndex + 6] ?? "").length > 0, "identity-key must be non-empty");
62
62
  assert.equal(browserArgs[mcpArgIndex + 7], "--identity-project");
63
- assert.equal(browserArgs[mcpArgIndex + 8], projectRoot);
63
+ assert.equal(typeof browserArgs[mcpArgIndex + 8], "string");
64
+ assert.ok((browserArgs[mcpArgIndex + 8] ?? "").length > 0, "identity-project must be non-empty");
65
+ assert.doesNotMatch(browserArgs[mcpArgIndex + 8] ?? "", /[\\/]/, "identity-project must not be a filesystem path");
64
66
  assert.equal((browserServer as { cwd?: string })?.cwd, projectRoot);
65
67
 
66
68
  const settings = JSON.parse(readFileSync(join(projectRoot, ".claude", "settings.local.json"), "utf-8")) as {
@@ -0,0 +1,205 @@
1
+ // Project/App: gsd-pi
2
+ // File Purpose: Tests for the MCP readiness preflight gate in dispatchWorkflow.
3
+
4
+ import { describe, test, mock } from "node:test";
5
+ import assert from "node:assert/strict";
6
+ import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
7
+ import { createRequire } from "node:module";
8
+ import { tmpdir } from "node:os";
9
+ import { join } from "node:path";
10
+ import { pathToFileURL } from "node:url";
11
+
12
+ import { _awaitWorkflowMcpReadinessForTest as awaitWorkflowMcpReadiness } from "../guided-flow.ts";
13
+ import { clearMcpConfigCache } from "../../mcp-client/manager.ts";
14
+ import { clearWorkflowMcpProbeCache } from "../workflow-mcp-readiness-cache.ts";
15
+
16
+ function makeCtx(opts: { authMode?: string; baseUrl?: string; systemPrompt?: string } = {}) {
17
+ const { authMode = "externalCli", baseUrl = "local://pipe", systemPrompt = "" } = opts;
18
+ return {
19
+ model: { provider: "anthropic", baseUrl },
20
+ modelRegistry: {
21
+ getProviderAuthMode: mock.fn(() => authMode),
22
+ },
23
+ getSystemPrompt: mock.fn(() => systemPrompt),
24
+ ui: {
25
+ setStatus: mock.fn(),
26
+ notify: mock.fn(),
27
+ },
28
+ } as any;
29
+ }
30
+
31
+ function makePi(tools: string[] | (() => string[])) {
32
+ const getTools = typeof tools === "function" ? tools : () => tools;
33
+ return {
34
+ getActiveTools: getTools,
35
+ getAllTools: () => getTools().map((name: string) => ({ name })),
36
+ } as any;
37
+ }
38
+
39
+ describe("awaitWorkflowMcpReadiness", () => {
40
+ test("returns null (ready) when not using MCP transport", async () => {
41
+ clearWorkflowMcpProbeCache();
42
+ const ctx = makeCtx({ authMode: "native", baseUrl: "https://api.anthropic.com" });
43
+ const pi = makePi([]);
44
+ assert.equal(await awaitWorkflowMcpReadiness(pi, ctx, "/fake/path"), null);
45
+ });
46
+
47
+ test("returns null (ready) when provider has no auth mode", async () => {
48
+ const ctx = {
49
+ model: undefined,
50
+ modelRegistry: { getProviderAuthMode: mock.fn(() => undefined) },
51
+ ui: { setStatus: mock.fn(), notify: mock.fn() },
52
+ } as any;
53
+ const pi = makePi([]);
54
+ assert.equal(await awaitWorkflowMcpReadiness(pi, ctx, "/fake/path"), null);
55
+ });
56
+
57
+ test("returns null (ready) when MCP tools are already registered", async () => {
58
+ const ctx = makeCtx();
59
+ const pi = makePi(["read", "bash", "mcp__gsd-workflow__ask_user_questions", "mcp__gsd-workflow__gsd_plan_slice"]);
60
+ assert.equal(await awaitWorkflowMcpReadiness(pi, ctx, "/fake/path"), null);
61
+ });
62
+
63
+ test("returns null (ready) when host system prompt advertises workflow MCP tools", async () => {
64
+ const originalCommand = process.env.GSD_WORKFLOW_MCP_COMMAND;
65
+ const ctx = makeCtx({
66
+ systemPrompt: "Available tools: read, bash, mcp__gsd-workflow__ask_user_questions",
67
+ });
68
+ const pi = makePi(["read", "bash"]);
69
+ try {
70
+ process.env.GSD_WORKFLOW_MCP_COMMAND = "node";
71
+ assert.equal(await awaitWorkflowMcpReadiness(pi, ctx, "/fake/path"), null);
72
+ } finally {
73
+ if (originalCommand === undefined) {
74
+ delete process.env.GSD_WORKFLOW_MCP_COMMAND;
75
+ } else {
76
+ process.env.GSD_WORKFLOW_MCP_COMMAND = originalCommand;
77
+ }
78
+ }
79
+ });
80
+
81
+ test("treats a successful direct probe as readiness when session tools are absent", async () => {
82
+ const previousGsdHome = process.env.GSD_HOME;
83
+ const projectDir = mkdtempSync(join(tmpdir(), "gsd-guided-mcp-probe-project-"));
84
+ const gsdHomeDir = mkdtempSync(join(tmpdir(), "gsd-guided-mcp-probe-home-"));
85
+ try {
86
+ process.env.GSD_HOME = gsdHomeDir;
87
+ mkdirSync(join(projectDir, ".gsd"), { recursive: true });
88
+
89
+ const require = createRequire(import.meta.url);
90
+ const mcpModuleUrl = pathToFileURL(require.resolve("@modelcontextprotocol/sdk/server/mcp.js")).href;
91
+ const stdioModuleUrl = pathToFileURL(require.resolve("@modelcontextprotocol/sdk/server/stdio.js")).href;
92
+ const serverPath = join(projectDir, "fake-workflow-mcp-server.mjs");
93
+ writeFileSync(
94
+ serverPath,
95
+ [
96
+ `const { McpServer } = await import(${JSON.stringify(mcpModuleUrl)});`,
97
+ `const { StdioServerTransport } = await import(${JSON.stringify(stdioModuleUrl)});`,
98
+ 'const server = new McpServer({ name: "fake", version: "1.0.0" }, { capabilities: { tools: {} } });',
99
+ 'server.tool("gsd_status", "Probe-visible workflow tool", {}, async () => ({ content: [{ type: "text", text: "ok" }] }));',
100
+ 'await server.connect(new StdioServerTransport());',
101
+ ].join("\n"),
102
+ "utf-8",
103
+ );
104
+ writeFileSync(
105
+ join(projectDir, ".mcp.json"),
106
+ JSON.stringify({ mcpServers: { "gsd-workflow": { command: process.execPath, args: [serverPath] } } }),
107
+ "utf-8",
108
+ );
109
+
110
+ const ctx = makeCtx();
111
+ const pi = makePi(["read", "bash"]);
112
+
113
+ assert.equal(
114
+ await awaitWorkflowMcpReadiness(pi, ctx, projectDir, { timeoutMs: 15_000, pollMs: 100 }),
115
+ null,
116
+ );
117
+ } finally {
118
+ if (previousGsdHome === undefined) {
119
+ delete process.env.GSD_HOME;
120
+ } else {
121
+ process.env.GSD_HOME = previousGsdHome;
122
+ }
123
+ rmSync(projectDir, { recursive: true, force: true });
124
+ rmSync(gsdHomeDir, { recursive: true, force: true });
125
+ clearMcpConfigCache();
126
+ }
127
+ });
128
+
129
+ test("returns server and probe error when workflow MCP never becomes ready", async () => {
130
+ const originalCommand = process.env.GSD_WORKFLOW_MCP_COMMAND;
131
+ const ctx = makeCtx();
132
+ const pi = makePi(["read", "bash"]);
133
+ try {
134
+ process.env.GSD_WORKFLOW_MCP_COMMAND = "node";
135
+ const failure = await awaitWorkflowMcpReadiness(pi, ctx, "/fake/path", {
136
+ timeoutMs: 5,
137
+ pollMs: 1,
138
+ probe: async () => ({
139
+ ok: false,
140
+ tools: [],
141
+ serverName: "gsd-workflow",
142
+ error: "connection refused",
143
+ }),
144
+ });
145
+ assert.deepEqual(failure, { server: "gsd-workflow", error: "connection refused" });
146
+ assert.ok(ctx.ui.setStatus.mock.calls.length >= 2);
147
+ } finally {
148
+ if (originalCommand === undefined) {
149
+ delete process.env.GSD_WORKFLOW_MCP_COMMAND;
150
+ } else {
151
+ process.env.GSD_WORKFLOW_MCP_COMMAND = originalCommand;
152
+ }
153
+ }
154
+ });
155
+
156
+ test("returns null (ready) when MCP tools appear during polling", async () => {
157
+ const ctx = makeCtx();
158
+ let callCount = 0;
159
+ const pi = makePi(() => {
160
+ callCount++;
161
+ if (callCount >= 3) return ["mcp__gsd-workflow__gsd_plan_slice"];
162
+ return ["read", "bash"];
163
+ });
164
+ assert.equal(await awaitWorkflowMcpReadiness(pi, ctx, "/fake/path"), null);
165
+ assert.ok(callCount >= 3, `expected at least 3 tool-check calls, got ${callCount}`);
166
+ assert.ok(ctx.ui.setStatus.mock.calls.length >= 2);
167
+ });
168
+
169
+ test("requires the active unit's workflow tools, not just any MCP workflow tool", async () => {
170
+ const originalCommand = process.env.GSD_WORKFLOW_MCP_COMMAND;
171
+ const ctx = makeCtx();
172
+ const pi = makePi(["read", "bash", "mcp__gsd-workflow__gsd_slice_complete"]);
173
+ try {
174
+ process.env.GSD_WORKFLOW_MCP_COMMAND = "node";
175
+ const failure = await awaitWorkflowMcpReadiness(pi, ctx, "/fake/path", {
176
+ unitType: "complete-slice",
177
+ timeoutMs: 5,
178
+ pollMs: 1,
179
+ probe: async () => ({
180
+ ok: true,
181
+ tools: ["gsd_slice_complete"],
182
+ serverName: "gsd-workflow",
183
+ }),
184
+ });
185
+
186
+ assert.deepEqual(failure, { server: "gsd-workflow" });
187
+ } finally {
188
+ if (originalCommand === undefined) {
189
+ delete process.env.GSD_WORKFLOW_MCP_COMMAND;
190
+ } else {
191
+ process.env.GSD_WORKFLOW_MCP_COMMAND = originalCommand;
192
+ }
193
+ }
194
+ });
195
+
196
+ test("returns null when no launch config is discoverable", async () => {
197
+ const ctx = makeCtx();
198
+ const pi = makePi(["read", "bash"]);
199
+ const launch = (await import("../workflow-mcp.js")).detectWorkflowMcpLaunchConfig(process.cwd());
200
+ if (!launch) {
201
+ assert.equal(await awaitWorkflowMcpReadiness(pi, ctx, process.cwd()), null);
202
+ }
203
+ // When launch config IS found, the function would timeout (15s) — skip that path in tests.
204
+ });
205
+ });
@@ -58,13 +58,14 @@ describe("formatMcpStatusReport", () => {
58
58
  assert.match(result, /disabled/i);
59
59
  });
60
60
 
61
- test("shows available state for servers that pass a status probe", () => {
61
+ test("labels probe-only availability separately from live connections", () => {
62
62
  const servers: McpServerStatus[] = [
63
63
  { name: "gsd-workflow", transport: "stdio", connected: false, available: true, toolCount: 62, error: undefined },
64
64
  ];
65
65
  const result = formatMcpStatusReport(servers);
66
66
  assert.match(result, /gsd-workflow/);
67
- assert.match(result, /available — 62 tools/);
67
+ assert.match(result, /probe available — 62 tools/);
68
+ assert.doesNotMatch(result, /connected — 62 tools/);
68
69
  assert.doesNotMatch(result, /disconnected/);
69
70
  });
70
71
 
@@ -132,7 +133,7 @@ describe("formatMcpServerDetail", () => {
132
133
  assert.match(result, /disconnected/i);
133
134
  });
134
135
 
135
- test("shows available status with tool names", () => {
136
+ test("shows probe-available status with tool names", () => {
136
137
  const result = formatMcpServerDetail({
137
138
  name: "gsd-workflow",
138
139
  transport: "stdio",
@@ -142,7 +143,7 @@ describe("formatMcpServerDetail", () => {
142
143
  tools: ["gsd_milestone_status"],
143
144
  error: undefined,
144
145
  });
145
- assert.match(result, /available/i);
146
+ assert.match(result, /probe available/i);
146
147
  assert.match(result, /gsd_milestone_status/);
147
148
  });
148
149
 
@@ -206,7 +207,7 @@ describe("handleMcpStatus", () => {
206
207
  await handleMcpStatus("status", ctx as unknown as ExtensionCommandContext);
207
208
 
208
209
  assert.match(message, /gsd-workflow/);
209
- assert.match(message, /available — 1 tools/);
210
+ assert.match(message, /probe available — 1 tools/);
210
211
  assert.doesNotMatch(message, /disconnected/);
211
212
  } finally {
212
213
  process.chdir(originalCwd);