@opengsd/gsd-pi 1.2.0-dev.955e4da0 → 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 (726) 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-style.d.ts +17 -0
  4. package/dist/cli-style.js +28 -0
  5. package/dist/cli.js +2 -19
  6. package/dist/headless-events.d.ts +4 -2
  7. package/dist/headless-events.js +14 -34
  8. package/dist/loader.js +6 -4
  9. package/dist/mcp-server.js +2 -1
  10. package/dist/models-resolver.d.ts +3 -13
  11. package/dist/models-resolver.js +3 -22
  12. package/dist/register-agent-bundles.d.ts +11 -2
  13. package/dist/register-agent-bundles.js +18 -4
  14. package/dist/resource-loader.d.ts +10 -5
  15. package/dist/resource-loader.js +123 -20
  16. package/dist/resources/.managed-resources-content-hash +1 -1
  17. package/dist/resources/GSD-WORKFLOW.md +5 -4
  18. package/dist/resources/extensions/ask-user-questions.js +3 -2
  19. package/dist/resources/extensions/async-jobs/async-bash-tool.js +30 -64
  20. package/dist/resources/extensions/async-jobs/await-tool.js +80 -12
  21. package/dist/resources/extensions/async-jobs/index.js +65 -0
  22. package/dist/resources/extensions/async-jobs/job-manager.js +12 -1
  23. package/dist/resources/extensions/bg-shell/bg-shell-command.js +6 -6
  24. package/dist/resources/extensions/bg-shell/bg-shell-tool.js +10 -7
  25. package/dist/resources/extensions/bg-shell/overlay.js +9 -6
  26. package/dist/resources/extensions/bg-shell/process-manager.js +54 -25
  27. package/dist/resources/extensions/bg-shell/readiness-detector.js +11 -0
  28. package/dist/resources/extensions/bg-shell/utilities.js +3 -0
  29. package/dist/resources/extensions/browser-tools/engine/managed-gsd-browser.js +209 -88
  30. package/dist/resources/extensions/browser-tools/engine/selection.js +73 -5
  31. package/dist/resources/extensions/browser-tools/index.js +69 -12
  32. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +456 -198
  33. package/dist/resources/extensions/claude-code-cli/turn-assembler.js +33 -1
  34. package/dist/resources/extensions/gsd/auto/closeout.js +215 -0
  35. package/dist/resources/extensions/gsd/auto/custom-verify-retry-store.js +17 -2
  36. package/dist/resources/extensions/gsd/auto/detect-stuck.js +33 -13
  37. package/dist/resources/extensions/gsd/auto/dispatch-history.js +120 -0
  38. package/dist/resources/extensions/gsd/auto/dispatch-key.js +37 -0
  39. package/dist/resources/extensions/gsd/auto/dispatch.js +365 -0
  40. package/dist/resources/extensions/gsd/auto/finalize.js +347 -0
  41. package/dist/resources/extensions/gsd/auto/loop.js +7 -1
  42. package/dist/resources/extensions/gsd/auto/milestone-lease-reclaim.js +56 -0
  43. package/dist/resources/extensions/gsd/auto/orchestrator.js +174 -69
  44. package/dist/resources/extensions/gsd/auto/phase-helpers.js +146 -0
  45. package/dist/resources/extensions/gsd/auto/phases.js +17 -2329
  46. package/dist/resources/extensions/gsd/auto/pre-dispatch.js +534 -0
  47. package/dist/resources/extensions/gsd/auto/session.js +3 -0
  48. package/dist/resources/extensions/gsd/auto/unit-phase.js +694 -0
  49. package/dist/resources/extensions/gsd/auto/workflow-unit-dispatch.js +1 -1
  50. package/dist/resources/extensions/gsd/auto/worktree-safety-phase.js +125 -0
  51. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +11 -34
  52. package/dist/resources/extensions/gsd/auto-dispatch.js +50 -58
  53. package/dist/resources/extensions/gsd/auto-model-selection.js +36 -13
  54. package/dist/resources/extensions/gsd/auto-post-unit.js +35 -8
  55. package/dist/resources/extensions/gsd/auto-prompts.js +81 -19
  56. package/dist/resources/extensions/gsd/auto-start.js +41 -18
  57. package/dist/resources/extensions/gsd/auto-tool-tracking.js +18 -0
  58. package/dist/resources/extensions/gsd/auto-unit-closeout.js +45 -21
  59. package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +12 -20
  60. package/dist/resources/extensions/gsd/auto-verification.js +23 -30
  61. package/dist/resources/extensions/gsd/auto-worktree.js +45 -92
  62. package/dist/resources/extensions/gsd/auto.js +56 -15
  63. package/dist/resources/extensions/gsd/blocked-models.js +28 -0
  64. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +29 -8
  65. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +60 -13
  66. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +2 -2
  67. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +19 -0
  68. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +212 -48
  69. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +303 -77
  70. package/dist/resources/extensions/gsd/branch-patterns.js +2 -0
  71. package/dist/resources/extensions/gsd/browser-daemon-auto-prep.js +83 -0
  72. package/dist/resources/extensions/gsd/browser-evidence.js +8 -2
  73. package/dist/resources/extensions/gsd/captures.js +4 -6
  74. package/dist/resources/extensions/gsd/closeout-wizard.js +92 -0
  75. package/dist/resources/extensions/gsd/commands/context.js +16 -2
  76. package/dist/resources/extensions/gsd/commands-handlers.js +46 -3
  77. package/dist/resources/extensions/gsd/commands-mcp-status.js +2 -2
  78. package/dist/resources/extensions/gsd/commands-workflow-templates.js +9 -2
  79. package/dist/resources/extensions/gsd/consent-question.js +353 -0
  80. package/dist/resources/extensions/gsd/consent-verdict.js +63 -0
  81. package/dist/resources/extensions/gsd/constants.js +0 -2
  82. package/dist/resources/extensions/gsd/crash-recovery.js +12 -15
  83. package/dist/resources/extensions/gsd/db/queries.js +56 -0
  84. package/dist/resources/extensions/gsd/db-writer.js +8 -17
  85. package/dist/resources/extensions/gsd/dispatch-guard.js +10 -35
  86. package/dist/resources/extensions/gsd/doctor-engine-checks.js +5 -5
  87. package/dist/resources/extensions/gsd/doctor-environment.js +258 -131
  88. package/dist/resources/extensions/gsd/doctor-format.js +9 -6
  89. package/dist/resources/extensions/gsd/doctor-git-checks.js +2 -18
  90. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +13 -15
  91. package/dist/resources/extensions/gsd/engine-hook-contract.js +70 -0
  92. package/dist/resources/extensions/gsd/error-classifier.js +9 -0
  93. package/dist/resources/extensions/gsd/exec-sandbox.js +30 -10
  94. package/dist/resources/extensions/gsd/files.js +33 -19
  95. package/dist/resources/extensions/gsd/gsd-command-home.js +22 -12
  96. package/dist/resources/extensions/gsd/gsd-db.js +2 -1
  97. package/dist/resources/extensions/gsd/guidance.js +158 -0
  98. package/dist/resources/extensions/gsd/guided-flow.js +110 -6
  99. package/dist/resources/extensions/gsd/health-widget.js +87 -28
  100. package/dist/resources/extensions/gsd/markdown-renderer.js +10 -0
  101. package/dist/resources/extensions/gsd/mcp-bridge.js +10 -0
  102. package/dist/resources/extensions/gsd/mcp-filter.js +2 -19
  103. package/dist/resources/extensions/gsd/mcp-tool-name.js +5 -13
  104. package/dist/resources/extensions/gsd/memory-consolidation-scanner.js +1 -1
  105. package/dist/resources/extensions/gsd/migrate/safety.js +4 -1
  106. package/dist/resources/extensions/gsd/milestone-closeout.js +85 -24
  107. package/dist/resources/extensions/gsd/milestone-planning-persistence.js +2 -2
  108. package/dist/resources/extensions/gsd/milestone-reopen-events.js +3 -5
  109. package/dist/resources/extensions/gsd/milestone-settlement.js +2 -2
  110. package/dist/resources/extensions/gsd/notification-store.js +11 -4
  111. package/dist/resources/extensions/gsd/notifications.js +12 -7
  112. package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +6 -4
  113. package/dist/resources/extensions/gsd/parsers-legacy.js +16 -4
  114. package/dist/resources/extensions/gsd/paths.js +27 -0
  115. package/dist/resources/extensions/gsd/pre-execution-checks.js +91 -3
  116. package/dist/resources/extensions/gsd/preferences-models.js +14 -48
  117. package/dist/resources/extensions/gsd/projection-flush.js +7 -0
  118. package/dist/resources/extensions/gsd/prompts/complete-slice.md +4 -4
  119. package/dist/resources/extensions/gsd/prompts/execute-task.md +3 -2
  120. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  121. package/dist/resources/extensions/gsd/prompts/plan-slice.md +2 -2
  122. package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -1
  123. package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
  124. package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  125. package/dist/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  126. package/dist/resources/extensions/gsd/prompts/research-milestone.md +1 -1
  127. package/dist/resources/extensions/gsd/prompts/research-slice.md +1 -1
  128. package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  129. package/dist/resources/extensions/gsd/prompts/run-uat.md +9 -5
  130. package/dist/resources/extensions/gsd/prompts/system.md +5 -2
  131. package/dist/resources/extensions/gsd/prompts/triage-captures.md +1 -1
  132. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +1 -1
  133. package/dist/resources/extensions/gsd/prompts/workflow-start.md +2 -1
  134. package/dist/resources/extensions/gsd/provider-error-guidance.js +1 -5
  135. package/dist/resources/extensions/gsd/provider-switch-observer.js +1 -1
  136. package/dist/resources/extensions/gsd/publication.js +87 -0
  137. package/dist/resources/extensions/gsd/reactive-graph.js +8 -1
  138. package/dist/resources/extensions/gsd/recovery-classification.js +37 -94
  139. package/dist/resources/extensions/gsd/roadmap-slices.js +25 -3
  140. package/dist/resources/extensions/gsd/safety/destructive-confirmation.js +108 -0
  141. package/dist/resources/extensions/gsd/session-lock.js +1 -1
  142. package/dist/resources/extensions/gsd/skill-activation.js +3 -6
  143. package/dist/resources/extensions/gsd/state.js +12 -22
  144. package/dist/resources/extensions/gsd/stop-notice.js +57 -0
  145. package/dist/resources/extensions/gsd/tool-contract.js +14 -3
  146. package/dist/resources/extensions/gsd/tool-presentation-plan.js +4 -4
  147. package/dist/resources/extensions/gsd/tool-surface-readiness.js +108 -0
  148. package/dist/resources/extensions/gsd/tools/complete-milestone.js +3 -2
  149. package/dist/resources/extensions/gsd/tools/complete-slice.js +22 -12
  150. package/dist/resources/extensions/gsd/tools/complete-task.js +65 -2
  151. package/dist/resources/extensions/gsd/tools/exec-tool.js +9 -7
  152. package/dist/resources/extensions/gsd/tools/plan-slice.js +14 -8
  153. package/dist/resources/extensions/gsd/tools/plan-task.js +2 -2
  154. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +2 -2
  155. package/dist/resources/extensions/gsd/tools/reopen-milestone.js +2 -2
  156. package/dist/resources/extensions/gsd/tools/reopen-slice.js +2 -2
  157. package/dist/resources/extensions/gsd/tools/reopen-task.js +2 -2
  158. package/dist/resources/extensions/gsd/tools/replan-slice.js +2 -2
  159. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +67 -2
  160. package/dist/resources/extensions/gsd/uat-policy.js +42 -16
  161. package/dist/resources/extensions/gsd/unit-closeout.js +138 -0
  162. package/dist/resources/extensions/gsd/unit-context-composer.js +74 -1
  163. package/dist/resources/extensions/gsd/unit-context-manifest.js +4 -27
  164. package/dist/resources/extensions/gsd/unit-registry.js +367 -0
  165. package/dist/resources/extensions/gsd/unit-tool-contracts.js +9 -182
  166. package/dist/resources/extensions/gsd/verdict-parser.js +1 -1
  167. package/dist/resources/extensions/gsd/verification-verdict.js +2 -1
  168. package/dist/resources/extensions/gsd/web-app-uat.js +45 -8
  169. package/dist/resources/extensions/gsd/workflow-event-ledger.js +91 -0
  170. package/dist/resources/extensions/gsd/workflow-event-vocabulary.js +46 -0
  171. package/dist/resources/extensions/gsd/workflow-events.js +6 -18
  172. package/dist/resources/extensions/gsd/workflow-mcp-auto-prep.js +2 -0
  173. package/dist/resources/extensions/gsd/workflow-mcp-readiness-cache.js +105 -0
  174. package/dist/resources/extensions/gsd/workflow-reconcile.js +21 -56
  175. package/dist/resources/extensions/gsd/workflow-tool-surface.js +1 -1
  176. package/dist/resources/extensions/gsd/worktree-git-recovery.js +15 -9
  177. package/dist/resources/extensions/gsd/worktree-lifecycle.js +3 -2
  178. package/dist/resources/extensions/gsd/worktree-manager.js +7 -1
  179. package/dist/resources/extensions/gsd/worktree-root.js +11 -0
  180. package/dist/resources/extensions/gsd/worktree-safety.js +28 -26
  181. package/dist/resources/extensions/gsd/worktree-session-state.js +4 -5
  182. package/dist/resources/extensions/gsd/worktree.js +8 -1
  183. package/dist/resources/extensions/mcp-client/manager.js +6 -1
  184. package/dist/resources/extensions/search-the-web/native-search.js +5 -3
  185. package/dist/resources/extensions/shared/browser-contract.js +59 -0
  186. package/dist/resources/extensions/shared/gsd-browser-cli.js +116 -6
  187. package/dist/resources/shared/gsd-browser-path-sync.js +214 -0
  188. package/dist/resources/shared/package-manager-detection.js +1 -1
  189. package/dist/resources/shared/package.json +3 -0
  190. package/dist/resources/skills/create-skill/SKILL.md +3 -0
  191. package/dist/resources/skills/create-skill/references/executable-code.md +1 -1
  192. package/dist/resources/skills/create-skill/references/skill-structure.md +1 -0
  193. package/dist/resources/skills/create-skill/workflows/add-reference.md +8 -3
  194. package/dist/resources/skills/create-skill/workflows/add-script.md +4 -2
  195. package/dist/resources/skills/create-skill/workflows/add-template.md +3 -1
  196. package/dist/resources/skills/create-skill/workflows/add-workflow.md +8 -3
  197. package/dist/resources/skills/create-skill/workflows/upgrade-to-router.md +10 -5
  198. package/dist/resources/skills/create-skill/workflows/verify-skill.md +9 -4
  199. package/dist/resources/skills/spike-wrap-up/SKILL.md +9 -9
  200. package/dist/runtime-checks.d.ts +10 -0
  201. package/dist/runtime-checks.js +27 -0
  202. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  203. package/dist/update-check.d.ts +2 -0
  204. package/dist/update-check.js +24 -1
  205. package/dist/update-cmd.js +20 -3
  206. package/dist/web/standalone/.next/BUILD_ID +1 -1
  207. package/dist/web/standalone/.next/app-path-routes-manifest.json +13 -13
  208. package/dist/web/standalone/.next/build-manifest.json +3 -3
  209. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  210. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  211. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  212. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  213. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  214. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  215. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  216. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  217. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  218. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  219. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  220. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  221. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  222. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  223. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  224. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  225. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  226. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  227. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  228. package/dist/web/standalone/.next/server/app/api/update/route.js.nft.json +1 -1
  229. package/dist/web/standalone/.next/server/app/index.html +1 -1
  230. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  231. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  232. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  233. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  234. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  235. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  236. package/dist/web/standalone/.next/server/app-paths-manifest.json +13 -13
  237. package/dist/web/standalone/.next/server/chunks/5124.js +1 -1
  238. package/dist/web/standalone/.next/server/chunks/8357.js +2 -2
  239. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  240. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  241. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  242. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  243. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  244. package/dist/web/standalone/.next/static/chunks/{796.cf859a427a2cb2ac.js → 796.e0bdc932325d7e03.js} +1 -1
  245. package/dist/web/standalone/.next/static/chunks/{webpack-fbea77b5f9953368.js → webpack-f0285ce91d4ec9ef.js} +1 -1
  246. package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
  247. package/dist/web/standalone/package.json +1 -1
  248. package/dist/worktree-cli.js +3 -6
  249. package/dist/worktree-status-banner.js +7 -15
  250. package/package.json +3 -3
  251. package/packages/cloud-mcp-gateway/package.json +2 -2
  252. package/packages/contracts/dist/rpc.d.ts +1 -0
  253. package/packages/contracts/dist/rpc.d.ts.map +1 -1
  254. package/packages/contracts/dist/rpc.js.map +1 -1
  255. package/packages/contracts/dist/workflow.d.ts +4 -0
  256. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  257. package/packages/contracts/dist/workflow.js.map +1 -1
  258. package/packages/contracts/package.json +1 -1
  259. package/packages/daemon/package.json +4 -4
  260. package/packages/gsd-agent-core/dist/sdk.d.ts.map +1 -1
  261. package/packages/gsd-agent-core/dist/sdk.js +6 -4
  262. package/packages/gsd-agent-core/dist/sdk.js.map +1 -1
  263. package/packages/gsd-agent-core/package.json +5 -5
  264. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts +2 -0
  265. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  266. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js +10 -0
  267. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js.map +1 -1
  268. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +13 -0
  269. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  270. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +55 -6
  271. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  272. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts +2 -0
  273. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts.map +1 -1
  274. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js +34 -5
  275. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js.map +1 -1
  276. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  277. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +7 -0
  278. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  279. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
  280. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js +8 -1
  281. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  282. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.d.ts.map +1 -1
  283. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js +11 -1
  284. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js.map +1 -1
  285. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts +1 -0
  286. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  287. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +12 -0
  288. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
  289. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.d.ts.map +1 -1
  290. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js +4 -4
  291. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js.map +1 -1
  292. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.d.ts.map +1 -1
  293. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js +4 -0
  294. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js.map +1 -1
  295. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  296. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +3 -1
  297. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -1
  298. package/packages/gsd-agent-modes/package.json +7 -7
  299. package/packages/mcp-server/README.md +12 -3
  300. package/packages/mcp-server/dist/cli-runner.d.ts +40 -0
  301. package/packages/mcp-server/dist/cli-runner.d.ts.map +1 -0
  302. package/packages/mcp-server/dist/cli-runner.js +137 -0
  303. package/packages/mcp-server/dist/cli-runner.js.map +1 -0
  304. package/packages/mcp-server/dist/cli.js +2 -50
  305. package/packages/mcp-server/dist/cli.js.map +1 -1
  306. package/packages/mcp-server/dist/moonshot-tool-schema.d.ts +29 -0
  307. package/packages/mcp-server/dist/moonshot-tool-schema.d.ts.map +1 -0
  308. package/packages/mcp-server/dist/moonshot-tool-schema.js +50 -0
  309. package/packages/mcp-server/dist/moonshot-tool-schema.js.map +1 -0
  310. package/packages/mcp-server/dist/pid-registry.d.ts +46 -0
  311. package/packages/mcp-server/dist/pid-registry.d.ts.map +1 -0
  312. package/packages/mcp-server/dist/pid-registry.js +452 -0
  313. package/packages/mcp-server/dist/pid-registry.js.map +1 -0
  314. package/packages/mcp-server/dist/probe-mode.d.ts +4 -0
  315. package/packages/mcp-server/dist/probe-mode.d.ts.map +1 -0
  316. package/packages/mcp-server/dist/probe-mode.js +10 -0
  317. package/packages/mcp-server/dist/probe-mode.js.map +1 -0
  318. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  319. package/packages/mcp-server/dist/server.js +4 -0
  320. package/packages/mcp-server/dist/server.js.map +1 -1
  321. package/packages/mcp-server/dist/stdio-watchdog.d.ts +8 -0
  322. package/packages/mcp-server/dist/stdio-watchdog.d.ts.map +1 -0
  323. package/packages/mcp-server/dist/stdio-watchdog.js +40 -0
  324. package/packages/mcp-server/dist/stdio-watchdog.js.map +1 -0
  325. package/packages/mcp-server/dist/workflow-tools.d.ts +26 -18
  326. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  327. package/packages/mcp-server/dist/workflow-tools.js +178 -82
  328. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  329. package/packages/mcp-server/package.json +5 -4
  330. package/packages/native/package.json +1 -1
  331. package/packages/pi-agent-core/dist/agent-loop.js +43 -2
  332. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  333. package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts +1 -0
  334. package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts.map +1 -1
  335. package/packages/pi-agent-core/dist/harness/env/nodejs.js +34 -3
  336. package/packages/pi-agent-core/dist/harness/env/nodejs.js.map +1 -1
  337. package/packages/pi-agent-core/dist/index.d.ts +1 -0
  338. package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
  339. package/packages/pi-agent-core/dist/index.js +3 -0
  340. package/packages/pi-agent-core/dist/index.js.map +1 -1
  341. package/packages/pi-agent-core/package.json +1 -1
  342. package/packages/pi-ai/README.md +1 -0
  343. package/packages/pi-ai/dist/image-models.generated.d.ts +2 -2
  344. package/packages/pi-ai/dist/image-models.generated.js +6 -6
  345. package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
  346. package/packages/pi-ai/dist/index.d.ts +2 -0
  347. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  348. package/packages/pi-ai/dist/index.js +2 -0
  349. package/packages/pi-ai/dist/index.js.map +1 -1
  350. package/packages/pi-ai/dist/models.generated.d.ts +35 -125
  351. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  352. package/packages/pi-ai/dist/models.generated.js +46 -120
  353. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  354. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  355. package/packages/pi-ai/dist/providers/anthropic.js +12 -7
  356. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  357. package/packages/pi-ai/dist/providers/google-shared.d.ts +5 -0
  358. package/packages/pi-ai/dist/providers/google-shared.d.ts.map +1 -1
  359. package/packages/pi-ai/dist/providers/google-shared.js +12 -3
  360. package/packages/pi-ai/dist/providers/google-shared.js.map +1 -1
  361. package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
  362. package/packages/pi-ai/dist/providers/openai-completions.js +7 -3
  363. package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
  364. package/packages/pi-ai/dist/utils/moonshot-tool-schema.d.ts +9 -0
  365. package/packages/pi-ai/dist/utils/moonshot-tool-schema.d.ts.map +1 -0
  366. package/packages/pi-ai/dist/utils/moonshot-tool-schema.js +34 -0
  367. package/packages/pi-ai/dist/utils/moonshot-tool-schema.js.map +1 -0
  368. package/packages/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
  369. package/packages/pi-ai/dist/utils/oauth/github-copilot.js +6 -2
  370. package/packages/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
  371. package/packages/pi-ai/package.json +3 -2
  372. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +2 -2
  373. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  374. package/packages/pi-coding-agent/dist/core/auth-storage.js +19 -13
  375. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  376. package/packages/pi-coding-agent/dist/core/provider-readiness.d.ts.map +1 -1
  377. package/packages/pi-coding-agent/dist/core/provider-readiness.js +13 -6
  378. package/packages/pi-coding-agent/dist/core/provider-readiness.js.map +1 -1
  379. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +3 -0
  380. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  381. package/packages/pi-coding-agent/dist/core/settings-manager.js +11 -0
  382. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  383. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts +11 -0
  384. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
  385. package/packages/pi-coding-agent/dist/core/tools/bash.js +53 -11
  386. package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
  387. package/packages/pi-coding-agent/dist/index.d.ts +1 -1
  388. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  389. package/packages/pi-coding-agent/dist/index.js +1 -1
  390. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  391. package/packages/pi-coding-agent/dist/theme/theme.d.ts.map +1 -1
  392. package/packages/pi-coding-agent/dist/theme/theme.js +45 -17
  393. package/packages/pi-coding-agent/dist/theme/theme.js.map +1 -1
  394. package/packages/pi-coding-agent/dist/utils/shell.d.ts +28 -2
  395. package/packages/pi-coding-agent/dist/utils/shell.d.ts.map +1 -1
  396. package/packages/pi-coding-agent/dist/utils/shell.js +56 -10
  397. package/packages/pi-coding-agent/dist/utils/shell.js.map +1 -1
  398. package/packages/pi-coding-agent/package.json +7 -7
  399. package/packages/pi-tui/dist/index.d.ts +1 -1
  400. package/packages/pi-tui/dist/index.d.ts.map +1 -1
  401. package/packages/pi-tui/dist/index.js +1 -1
  402. package/packages/pi-tui/dist/index.js.map +1 -1
  403. package/packages/pi-tui/dist/terminal-image.d.ts +33 -0
  404. package/packages/pi-tui/dist/terminal-image.d.ts.map +1 -1
  405. package/packages/pi-tui/dist/terminal-image.js +54 -2
  406. package/packages/pi-tui/dist/terminal-image.js.map +1 -1
  407. package/packages/pi-tui/dist/tui.d.ts +8 -0
  408. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  409. package/packages/pi-tui/dist/tui.js +72 -18
  410. package/packages/pi-tui/dist/tui.js.map +1 -1
  411. package/packages/pi-tui/dist/utils.d.ts.map +1 -1
  412. package/packages/pi-tui/dist/utils.js +110 -36
  413. package/packages/pi-tui/dist/utils.js.map +1 -1
  414. package/packages/pi-tui/package.json +2 -2
  415. package/packages/rpc-client/package.json +2 -2
  416. package/pkg/dist/theme/theme.d.ts.map +1 -1
  417. package/pkg/dist/theme/theme.js +45 -17
  418. package/pkg/dist/theme/theme.js.map +1 -1
  419. package/pkg/package.json +1 -1
  420. package/src/resources/GSD-WORKFLOW.md +5 -4
  421. package/src/resources/extensions/ask-user-questions.ts +7 -2
  422. package/src/resources/extensions/async-jobs/async-bash-cancel.test.ts +360 -0
  423. package/src/resources/extensions/async-jobs/async-bash-tool.ts +33 -56
  424. package/src/resources/extensions/async-jobs/await-tool.test.ts +139 -0
  425. package/src/resources/extensions/async-jobs/await-tool.ts +82 -12
  426. package/src/resources/extensions/async-jobs/index.ts +79 -0
  427. package/src/resources/extensions/async-jobs/job-manager.ts +21 -1
  428. package/src/resources/extensions/bg-shell/bg-shell-command.ts +6 -6
  429. package/src/resources/extensions/bg-shell/bg-shell-tool.ts +10 -6
  430. package/src/resources/extensions/bg-shell/overlay.ts +9 -5
  431. package/src/resources/extensions/bg-shell/process-manager.ts +50 -25
  432. package/src/resources/extensions/bg-shell/readiness-detector.ts +12 -0
  433. package/src/resources/extensions/bg-shell/tests/lifecycle-and-utilities.test.ts +48 -1
  434. package/src/resources/extensions/bg-shell/utilities.ts +3 -0
  435. package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +265 -98
  436. package/src/resources/extensions/browser-tools/engine/selection.ts +90 -4
  437. package/src/resources/extensions/browser-tools/index.ts +71 -13
  438. package/src/resources/extensions/browser-tools/tests/browser-engine-selection.test.mjs +83 -13
  439. package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +40 -1
  440. package/src/resources/extensions/browser-tools/tests/managed-gsd-browser-tools.test.mjs +136 -0
  441. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +537 -202
  442. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +672 -7
  443. package/src/resources/extensions/claude-code-cli/turn-assembler.ts +38 -1
  444. package/src/resources/extensions/gsd/auto/closeout.ts +309 -0
  445. package/src/resources/extensions/gsd/auto/custom-verify-retry-store.ts +21 -3
  446. package/src/resources/extensions/gsd/auto/detect-stuck.ts +32 -9
  447. package/src/resources/extensions/gsd/auto/dispatch-history.ts +168 -0
  448. package/src/resources/extensions/gsd/auto/dispatch-key.ts +39 -0
  449. package/src/resources/extensions/gsd/auto/dispatch.ts +449 -0
  450. package/src/resources/extensions/gsd/auto/finalize.ts +445 -0
  451. package/src/resources/extensions/gsd/auto/loop.ts +7 -1
  452. package/src/resources/extensions/gsd/auto/milestone-lease-reclaim.ts +74 -0
  453. package/src/resources/extensions/gsd/auto/orchestrator.ts +193 -71
  454. package/src/resources/extensions/gsd/auto/phase-helpers.ts +199 -0
  455. package/src/resources/extensions/gsd/auto/phases.ts +58 -3022
  456. package/src/resources/extensions/gsd/auto/pre-dispatch.ts +704 -0
  457. package/src/resources/extensions/gsd/auto/session.ts +3 -0
  458. package/src/resources/extensions/gsd/auto/unit-phase.ts +910 -0
  459. package/src/resources/extensions/gsd/auto/workflow-unit-dispatch.ts +1 -1
  460. package/src/resources/extensions/gsd/auto/worktree-safety-phase.ts +149 -0
  461. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +18 -48
  462. package/src/resources/extensions/gsd/auto-dispatch.ts +48 -61
  463. package/src/resources/extensions/gsd/auto-model-selection.ts +41 -12
  464. package/src/resources/extensions/gsd/auto-post-unit.ts +40 -8
  465. package/src/resources/extensions/gsd/auto-prompts.ts +118 -35
  466. package/src/resources/extensions/gsd/auto-start.ts +42 -21
  467. package/src/resources/extensions/gsd/auto-tool-tracking.ts +19 -0
  468. package/src/resources/extensions/gsd/auto-unit-closeout.ts +83 -28
  469. package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +14 -21
  470. package/src/resources/extensions/gsd/auto-verification.ts +26 -28
  471. package/src/resources/extensions/gsd/auto-worktree.ts +45 -95
  472. package/src/resources/extensions/gsd/auto.ts +72 -17
  473. package/src/resources/extensions/gsd/blocked-models.ts +49 -0
  474. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +37 -10
  475. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +79 -12
  476. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +2 -2
  477. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +24 -0
  478. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +251 -47
  479. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +352 -84
  480. package/src/resources/extensions/gsd/branch-patterns.ts +3 -0
  481. package/src/resources/extensions/gsd/browser-daemon-auto-prep.ts +108 -0
  482. package/src/resources/extensions/gsd/browser-evidence.ts +18 -2
  483. package/src/resources/extensions/gsd/captures.ts +4 -6
  484. package/src/resources/extensions/gsd/closeout-wizard.ts +102 -0
  485. package/src/resources/extensions/gsd/commands/context.ts +16 -2
  486. package/src/resources/extensions/gsd/commands-handlers.ts +46 -3
  487. package/src/resources/extensions/gsd/commands-mcp-status.ts +2 -2
  488. package/src/resources/extensions/gsd/commands-workflow-templates.ts +11 -4
  489. package/src/resources/extensions/gsd/consent-question.ts +431 -0
  490. package/src/resources/extensions/gsd/consent-verdict.ts +86 -0
  491. package/src/resources/extensions/gsd/constants.ts +0 -3
  492. package/src/resources/extensions/gsd/crash-recovery.ts +13 -11
  493. package/src/resources/extensions/gsd/db/queries.ts +66 -0
  494. package/src/resources/extensions/gsd/db-writer.ts +11 -19
  495. package/src/resources/extensions/gsd/dispatch-guard.ts +8 -31
  496. package/src/resources/extensions/gsd/doctor-engine-checks.ts +5 -4
  497. package/src/resources/extensions/gsd/doctor-environment.ts +269 -149
  498. package/src/resources/extensions/gsd/doctor-format.ts +12 -7
  499. package/src/resources/extensions/gsd/doctor-git-checks.ts +2 -19
  500. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +13 -15
  501. package/src/resources/extensions/gsd/engine-hook-contract.ts +79 -0
  502. package/src/resources/extensions/gsd/error-classifier.ts +11 -0
  503. package/src/resources/extensions/gsd/exec-sandbox.ts +49 -9
  504. package/src/resources/extensions/gsd/files.ts +33 -12
  505. package/src/resources/extensions/gsd/gsd-command-home.ts +13 -3
  506. package/src/resources/extensions/gsd/gsd-db.ts +4 -3
  507. package/src/resources/extensions/gsd/guidance.ts +217 -0
  508. package/src/resources/extensions/gsd/guided-flow.ts +161 -26
  509. package/src/resources/extensions/gsd/health-widget.ts +91 -27
  510. package/src/resources/extensions/gsd/markdown-renderer.ts +11 -0
  511. package/src/resources/extensions/gsd/mcp-bridge.ts +39 -0
  512. package/src/resources/extensions/gsd/mcp-filter.ts +2 -23
  513. package/src/resources/extensions/gsd/mcp-tool-name.ts +6 -11
  514. package/src/resources/extensions/gsd/memory-consolidation-scanner.ts +1 -1
  515. package/src/resources/extensions/gsd/migrate/safety.ts +4 -1
  516. package/src/resources/extensions/gsd/milestone-closeout.ts +109 -24
  517. package/src/resources/extensions/gsd/milestone-planning-persistence.ts +2 -2
  518. package/src/resources/extensions/gsd/milestone-reopen-events.ts +3 -6
  519. package/src/resources/extensions/gsd/milestone-settlement.ts +2 -2
  520. package/src/resources/extensions/gsd/notification-store.ts +26 -3
  521. package/src/resources/extensions/gsd/notifications.ts +13 -6
  522. package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +6 -4
  523. package/src/resources/extensions/gsd/parsers-legacy.ts +16 -4
  524. package/src/resources/extensions/gsd/paths.ts +33 -0
  525. package/src/resources/extensions/gsd/pre-execution-checks.ts +109 -3
  526. package/src/resources/extensions/gsd/preferences-models.ts +12 -47
  527. package/src/resources/extensions/gsd/projection-flush.ts +20 -0
  528. package/src/resources/extensions/gsd/prompts/complete-slice.md +4 -4
  529. package/src/resources/extensions/gsd/prompts/execute-task.md +3 -2
  530. package/src/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  531. package/src/resources/extensions/gsd/prompts/plan-slice.md +2 -2
  532. package/src/resources/extensions/gsd/prompts/quick-task.md +1 -1
  533. package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
  534. package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  535. package/src/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  536. package/src/resources/extensions/gsd/prompts/research-milestone.md +1 -1
  537. package/src/resources/extensions/gsd/prompts/research-slice.md +1 -1
  538. package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  539. package/src/resources/extensions/gsd/prompts/run-uat.md +9 -5
  540. package/src/resources/extensions/gsd/prompts/system.md +5 -2
  541. package/src/resources/extensions/gsd/prompts/triage-captures.md +1 -1
  542. package/src/resources/extensions/gsd/prompts/validate-milestone.md +1 -1
  543. package/src/resources/extensions/gsd/prompts/workflow-start.md +2 -1
  544. package/src/resources/extensions/gsd/provider-error-guidance.ts +4 -9
  545. package/src/resources/extensions/gsd/provider-switch-observer.ts +1 -1
  546. package/src/resources/extensions/gsd/publication.ts +122 -0
  547. package/src/resources/extensions/gsd/reactive-graph.ts +11 -1
  548. package/src/resources/extensions/gsd/recovery-classification.ts +42 -96
  549. package/src/resources/extensions/gsd/roadmap-slices.ts +28 -3
  550. package/src/resources/extensions/gsd/safety/destructive-confirmation.ts +134 -0
  551. package/src/resources/extensions/gsd/session-lock.ts +1 -1
  552. package/src/resources/extensions/gsd/skill-activation.ts +3 -6
  553. package/src/resources/extensions/gsd/state.ts +16 -22
  554. package/src/resources/extensions/gsd/stop-notice.ts +75 -0
  555. package/src/resources/extensions/gsd/tests/auto-abort-pause-regression.test.ts +1 -1
  556. package/src/resources/extensions/gsd/tests/auto-blocked-remediation-message.test.ts +1 -1
  557. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +206 -22
  558. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +97 -1
  559. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +273 -37
  560. package/src/resources/extensions/gsd/tests/auto-pause-double-entry-guard.test.ts +1 -1
  561. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +77 -1
  562. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +2 -1
  563. package/src/resources/extensions/gsd/tests/auto-remote-session-lock-cleanup.test.ts +65 -3
  564. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +236 -0
  565. package/src/resources/extensions/gsd/tests/auto-unit-closeout.test.ts +169 -1
  566. package/src/resources/extensions/gsd/tests/blocked-models.test.ts +19 -0
  567. package/src/resources/extensions/gsd/tests/browser-automation-contract-fixture.ts +39 -0
  568. package/src/resources/extensions/gsd/tests/browser-contract.test.ts +44 -0
  569. package/src/resources/extensions/gsd/tests/browser-daemon-auto-prep.test.ts +144 -0
  570. package/src/resources/extensions/gsd/tests/checkout-branch-stash-guard.test.ts +66 -1
  571. package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +22 -0
  572. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +8 -7
  573. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +42 -0
  574. package/src/resources/extensions/gsd/tests/complete-task.test.ts +141 -5
  575. package/src/resources/extensions/gsd/tests/consent-question.test.ts +351 -0
  576. package/src/resources/extensions/gsd/tests/custom-verify-retry-store.test.ts +67 -0
  577. package/src/resources/extensions/gsd/tests/db-writer.test.ts +15 -4
  578. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +12 -11
  579. package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +36 -0
  580. package/src/resources/extensions/gsd/tests/destructive-confirmation.test.ts +303 -0
  581. package/src/resources/extensions/gsd/tests/discuss-routing-fixes.test.ts +12 -2
  582. package/src/resources/extensions/gsd/tests/dispatch-history.test.ts +328 -0
  583. package/src/resources/extensions/gsd/tests/dispatch-run-uat-browser-tools.test.ts +2 -1
  584. package/src/resources/extensions/gsd/tests/dist-redirect.mjs +8 -0
  585. package/src/resources/extensions/gsd/tests/doctor-git-checks-terminal.test.ts +73 -0
  586. package/src/resources/extensions/gsd/tests/dynamic-bash-no-cap.test.ts +132 -0
  587. package/src/resources/extensions/gsd/tests/engine-hook-contract.test.ts +148 -0
  588. package/src/resources/extensions/gsd/tests/engine-interfaces-contract.test.ts +117 -91
  589. package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +113 -0
  590. package/src/resources/extensions/gsd/tests/exec-graceful-kill.test.ts +193 -0
  591. package/src/resources/extensions/gsd/tests/exec-tool.test.ts +29 -1
  592. package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +35 -1
  593. package/src/resources/extensions/gsd/tests/gsd-command-home.test.ts +120 -0
  594. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +27 -0
  595. package/src/resources/extensions/gsd/tests/guidance.test.ts +148 -0
  596. package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +18 -6
  597. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +53 -11
  598. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +88 -58
  599. package/src/resources/extensions/gsd/tests/integration/doctor-environment-async.test.ts +104 -0
  600. package/src/resources/extensions/gsd/tests/integration/gsd-integration-fixture.ts +80 -0
  601. package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +217 -0
  602. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +47 -16
  603. package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +3 -1
  604. package/src/resources/extensions/gsd/tests/mcp-readiness-preflight.test.ts +205 -0
  605. package/src/resources/extensions/gsd/tests/mcp-status.test.ts +6 -5
  606. package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +95 -4
  607. package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +1 -1
  608. package/src/resources/extensions/gsd/tests/milestone-report-path.test.ts +1 -1
  609. package/src/resources/extensions/gsd/tests/milestone-settlement.test.ts +92 -0
  610. package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +1 -1
  611. package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +32 -1
  612. package/src/resources/extensions/gsd/tests/notification-store.test.ts +32 -0
  613. package/src/resources/extensions/gsd/tests/notifications.test.ts +64 -9
  614. package/src/resources/extensions/gsd/tests/oauth-api-model-routing.test.ts +167 -0
  615. package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +18 -0
  616. package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +2 -2
  617. package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +143 -0
  618. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +1 -1
  619. package/src/resources/extensions/gsd/tests/phases-terminal-complete-idempotent.test.ts +242 -0
  620. package/src/resources/extensions/gsd/tests/plan-gate-failed-doctor-heal-hint.test.ts +3 -3
  621. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +63 -2
  622. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +193 -1
  623. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +10 -2
  624. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +124 -6
  625. package/src/resources/extensions/gsd/tests/provider-error-guidance.test.ts +3 -3
  626. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +2 -4
  627. package/src/resources/extensions/gsd/tests/publication.test.ts +120 -0
  628. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +157 -0
  629. package/src/resources/extensions/gsd/tests/remote-notification-from-desktop.test.ts +31 -81
  630. package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +68 -0
  631. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +27 -2
  632. package/src/resources/extensions/gsd/tests/skill-activation.test.ts +20 -17
  633. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +7 -3
  634. package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +1 -1
  635. package/src/resources/extensions/gsd/tests/stop-notice.test.ts +70 -0
  636. package/src/resources/extensions/gsd/tests/teardown-chdir-failure-clears-registry.test.ts +17 -0
  637. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +80 -2
  638. package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +8 -0
  639. package/src/resources/extensions/gsd/tests/tool-surface-readiness.test.ts +329 -0
  640. package/src/resources/extensions/gsd/tests/tool-unavailable-retry.test.ts +33 -0
  641. package/src/resources/extensions/gsd/tests/transport-gate-double-complete.test.ts +139 -0
  642. package/src/resources/extensions/gsd/tests/uat-policy.test.ts +112 -29
  643. package/src/resources/extensions/gsd/tests/unit-closeout.test.ts +209 -0
  644. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +67 -2
  645. package/src/resources/extensions/gsd/tests/unit-registry.test.ts +163 -0
  646. package/src/resources/extensions/gsd/tests/uok-audit-unified.test.ts +8 -0
  647. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +1 -1
  648. package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +2 -0
  649. package/src/resources/extensions/gsd/tests/web-app-uat.test.ts +44 -1
  650. package/src/resources/extensions/gsd/tests/workflow-events.test.ts +19 -0
  651. package/src/resources/extensions/gsd/tests/workflow-mcp-readiness-cache.test.ts +119 -0
  652. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +67 -4
  653. package/src/resources/extensions/gsd/tests/workflow-phase-contract-matrix.test.ts +332 -0
  654. package/src/resources/extensions/gsd/tests/workflow-reconcile.test.ts +20 -0
  655. package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +92 -0
  656. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +275 -40
  657. package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +1 -1
  658. package/src/resources/extensions/gsd/tests/worktree-project-root-degrade.test.ts +1 -1
  659. package/src/resources/extensions/gsd/tests/worktree-safety-phase.test.ts +100 -0
  660. package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +72 -0
  661. package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +22 -0
  662. package/src/resources/extensions/gsd/tests/worktree.test.ts +18 -0
  663. package/src/resources/extensions/gsd/tests/write-gate-seam.test.ts +358 -0
  664. package/src/resources/extensions/gsd/tests/write-gate.test.ts +67 -1
  665. package/src/resources/extensions/gsd/tool-contract.ts +38 -3
  666. package/src/resources/extensions/gsd/tool-presentation-plan.ts +4 -4
  667. package/src/resources/extensions/gsd/tool-surface-readiness.ts +183 -0
  668. package/src/resources/extensions/gsd/tools/complete-milestone.ts +3 -2
  669. package/src/resources/extensions/gsd/tools/complete-slice.ts +22 -12
  670. package/src/resources/extensions/gsd/tools/complete-task.ts +90 -2
  671. package/src/resources/extensions/gsd/tools/exec-tool.ts +8 -7
  672. package/src/resources/extensions/gsd/tools/plan-slice.ts +14 -8
  673. package/src/resources/extensions/gsd/tools/plan-task.ts +2 -2
  674. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +2 -2
  675. package/src/resources/extensions/gsd/tools/reopen-milestone.ts +2 -2
  676. package/src/resources/extensions/gsd/tools/reopen-slice.ts +2 -2
  677. package/src/resources/extensions/gsd/tools/reopen-task.ts +2 -2
  678. package/src/resources/extensions/gsd/tools/replan-slice.ts +2 -2
  679. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +81 -2
  680. package/src/resources/extensions/gsd/uat-policy.ts +62 -16
  681. package/src/resources/extensions/gsd/unit-closeout.ts +201 -0
  682. package/src/resources/extensions/gsd/unit-context-composer.ts +111 -1
  683. package/src/resources/extensions/gsd/unit-context-manifest.ts +4 -28
  684. package/src/resources/extensions/gsd/unit-registry.ts +442 -0
  685. package/src/resources/extensions/gsd/unit-tool-contracts.ts +27 -192
  686. package/src/resources/extensions/gsd/verdict-parser.ts +1 -1
  687. package/src/resources/extensions/gsd/verification-verdict.ts +4 -2
  688. package/src/resources/extensions/gsd/web-app-uat.ts +51 -8
  689. package/src/resources/extensions/gsd/workflow-event-ledger.ts +131 -0
  690. package/src/resources/extensions/gsd/workflow-event-vocabulary.ts +59 -0
  691. package/src/resources/extensions/gsd/workflow-events.ts +12 -20
  692. package/src/resources/extensions/gsd/workflow-mcp-auto-prep.ts +2 -0
  693. package/src/resources/extensions/gsd/workflow-mcp-readiness-cache.ts +150 -0
  694. package/src/resources/extensions/gsd/workflow-reconcile.ts +29 -62
  695. package/src/resources/extensions/gsd/workflow-tool-surface.ts +4 -1
  696. package/src/resources/extensions/gsd/worktree-git-recovery.ts +15 -9
  697. package/src/resources/extensions/gsd/worktree-lifecycle.ts +3 -8
  698. package/src/resources/extensions/gsd/worktree-manager.ts +6 -1
  699. package/src/resources/extensions/gsd/worktree-root.ts +12 -0
  700. package/src/resources/extensions/gsd/worktree-safety.ts +41 -39
  701. package/src/resources/extensions/gsd/worktree-session-state.ts +3 -5
  702. package/src/resources/extensions/gsd/worktree.ts +7 -1
  703. package/src/resources/extensions/mcp-client/manager.ts +7 -1
  704. package/src/resources/extensions/search-the-web/native-search.ts +5 -3
  705. package/src/resources/extensions/shared/browser-contract.ts +66 -0
  706. package/src/resources/extensions/shared/gsd-browser-cli.ts +141 -6
  707. package/src/resources/shared/gsd-browser-path-sync.ts +273 -0
  708. package/src/resources/shared/package-manager-detection.ts +1 -1
  709. package/src/resources/shared/package.json +3 -0
  710. package/src/resources/skills/create-skill/SKILL.md +3 -0
  711. package/src/resources/skills/create-skill/references/executable-code.md +1 -1
  712. package/src/resources/skills/create-skill/references/skill-structure.md +1 -0
  713. package/src/resources/skills/create-skill/workflows/add-reference.md +8 -3
  714. package/src/resources/skills/create-skill/workflows/add-script.md +4 -2
  715. package/src/resources/skills/create-skill/workflows/add-template.md +3 -1
  716. package/src/resources/skills/create-skill/workflows/add-workflow.md +8 -3
  717. package/src/resources/skills/create-skill/workflows/upgrade-to-router.md +10 -5
  718. package/src/resources/skills/create-skill/workflows/verify-skill.md +9 -4
  719. package/src/resources/skills/spike-wrap-up/SKILL.md +9 -9
  720. package/dist/resources/extensions/gsd/user-input-boundary.js +0 -218
  721. package/dist/resources/skills/gsd-browser/SKILL.md +0 -41
  722. package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +0 -173
  723. package/src/resources/extensions/gsd/user-input-boundary.ts +0 -216
  724. package/src/resources/skills/gsd-browser/SKILL.md +0 -41
  725. /package/dist/web/standalone/.next/static/{C24pqUd-aru-l0Dp0gLZP → xyMkEaICFHJoa98VgJyzY}/_buildManifest.js +0 -0
  726. /package/dist/web/standalone/.next/static/{C24pqUd-aru-l0Dp0gLZP → xyMkEaICFHJoa98VgJyzY}/_ssgManifest.js +0 -0
@@ -32,6 +32,7 @@ import {
32
32
  buildFinalAssistantContent,
33
33
  extractToolResultsFromSdkUserMessage,
34
34
  handleClaudeCodePartialStreamEvent,
35
+ shouldSuppressDuplicateToolUnavailableBlock,
35
36
  } from "./turn-assembler.js";
36
37
  import type {
37
38
  ExternalToolResultPayload,
@@ -59,6 +60,21 @@ import {
59
60
  computeMcpDisallowedTools,
60
61
  } from "../gsd/mcp-filter.js";
61
62
  import { RUN_UAT_CLAUDE_NATIVE_TOOL_NAMES, RUN_UAT_FORBIDDEN_TOOL_NAMES, RUN_UAT_WORKFLOW_TOOL_NAMES, resolveToolPresentationPlan } from "../gsd/tool-presentation-plan.js";
63
+ import { getUnitToolSurfaceContract } from "../gsd/unit-tool-contracts.js";
64
+ import {
65
+ awaitWorkflowMcpToolRegistration,
66
+ getToolSurfaceReadinessError,
67
+ POST_PREFLIGHT_READINESS_RETRY_DELAYS_MS,
68
+ POST_PREFLIGHT_SDK_SETTLE_MS,
69
+ TOOL_SURFACE_NOT_READY,
70
+ type LiveToolSurfaceObservation,
71
+ } from "../gsd/tool-surface-readiness.js";
72
+ import {
73
+ beginWorkflowMcpSdkSession,
74
+ endWorkflowMcpSdkSession,
75
+ } from "../gsd/workflow-mcp-readiness-cache.js";
76
+ import { getGuidedUnitContext } from "../gsd/guided-unit-context.js";
77
+ import { hasBrowserContractPrefix } from "../shared/browser-contract.js";
62
78
  import { showInterviewRound, type Question, type RoundResult } from "../shared/tui.js";
63
79
  import type {
64
80
  SDKAssistantMessage,
@@ -73,6 +89,7 @@ export {
73
89
  extractToolResultsFromSdkUserMessage,
74
90
  handleClaudeCodePartialStreamEvent,
75
91
  mergePendingToolCalls,
92
+ shouldSuppressDuplicateToolUnavailableBlock,
76
93
  } from "./turn-assembler.js";
77
94
  export type {
78
95
  ExternalToolResultContentBlock,
@@ -90,6 +107,11 @@ interface ClaudeCodeStreamOptions extends SimpleStreamOptions {
90
107
  extensionUIContext?: ExtensionUIContext;
91
108
  onExternalToolCall?: (toolCall: ToolCall) => Promise<void> | void;
92
109
  onExternalToolResult?: (event: { toolCall: ToolCall; result: ExternalToolResultPayload }) => Promise<void> | void;
110
+ _sdkQueryForTest?: (args: {
111
+ prompt: string | AsyncIterable<unknown>;
112
+ options?: Record<string, unknown>;
113
+ }) => AsyncIterable<SDKMessage>;
114
+ _skipWorkflowMcpPreflightForTest?: boolean;
93
115
  }
94
116
 
95
117
  export function serverToolUseToToolCallLike(block: {
@@ -350,13 +372,18 @@ const GSD_PHASE_PATTERNS: Array<[string, RegExp]> = [
350
372
  ["reassess-roadmap", /\b(?:UNIT:\s*Reassess Roadmap|reassess-roadmap)\b/i],
351
373
  ["complete-slice", /\b(?:UNIT:\s*Complete Slice|complete-slice)\b/i],
352
374
  ["replan-slice", /\b(?:UNIT:\s*Replan Slice|replan-slice)\b/i],
375
+ ["refine-slice", /\b(?:UNIT:\s*Refine Slice|refine-slice)\b/i],
353
376
  ["plan-slice", /\b(?:UNIT:\s*Plan Slice|plan-slice|gsd_plan_slice)\b/i],
354
377
  ["plan-milestone", /\b(?:UNIT:\s*Plan Milestone|plan-milestone|gsd_plan_milestone)\b/i],
355
378
  ["execute-task", /\b(?:UNIT:\s*Execute Task|execute-task|execute-task-simple|reactive-execute)\b/i],
356
379
  ["gate-evaluate", /\b(?:UNIT:\s*Gate Evaluate|gate-evaluate|gsd_save_gate_result)\b/i],
357
380
  ["research-milestone", /\b(?:UNIT:\s*Research Milestone|research-milestone)\b/i],
358
381
  ["research-slice", /\b(?:UNIT:\s*Research Slice|research-slice)\b/i],
382
+ ["research-decision", /\b(?:research decision|research-decision)\b/i],
359
383
  ["discuss-milestone", /\b(?:Discuss milestone|discuss-milestone)\b/i],
384
+ ["discuss-slice", /\b(?:Discuss slice|discuss-slice)\b/i],
385
+ ["discuss-project", /\b(?:discuss-project|Discuss project)\b/i],
386
+ ["discuss-requirements", /\b(?:discuss-requirements|Discuss requirements)\b/i],
360
387
  ];
361
388
 
362
389
  export function inferGsdPhaseFromContext(context: Context): string | undefined {
@@ -370,6 +397,26 @@ export function inferGsdPhaseFromContext(context: Context): string | undefined {
370
397
  return undefined;
371
398
  }
372
399
 
400
+ /**
401
+ * Resolve the GSD unit phase for Claude Code SDK sessions. Guided-flow
402
+ * dispatch records the authoritative unit type before the turn is queued;
403
+ * prefer that over regex inference from prompt text.
404
+ */
405
+ export function resolveGsdPhaseForSdk(context: Context, projectRoot: string): string | undefined {
406
+ const resolvedRoot = resolveWorkflowMcpProjectRoot(projectRoot);
407
+ const guided =
408
+ getGuidedUnitContext(resolvedRoot)
409
+ ?? getGuidedUnitContext(projectRoot)
410
+ ?? getGuidedUnitContext();
411
+ if (guided?.unitType) {
412
+ const guidedRoot = resolveWorkflowMcpProjectRoot(guided.basePath);
413
+ if (guidedRoot === resolvedRoot) {
414
+ return guided.unitType;
415
+ }
416
+ }
417
+ return inferGsdPhaseFromContext(context);
418
+ }
419
+
373
420
  /**
374
421
  * Build a full conversational prompt from GSD's context messages.
375
422
  *
@@ -395,10 +442,15 @@ export function buildPromptFromContext(context: Context, toolContext: PromptTool
395
442
  const workflowToolLine = toolContext.workflowMcpServerName
396
443
  ? "- GSD workflow tools (gsd_exec, gsd_slice_complete, gsd_task_complete, gsd_plan_slice, gsd_save_gate_result, etc.) " +
397
444
  `are MCP tools — call them as mcp__${toolContext.workflowMcpServerName}__<tool_name> ` +
398
- `(e.g. mcp__${toolContext.workflowMcpServerName}__gsd_exec, mcp__${toolContext.workflowMcpServerName}__gsd_save_gate_result)\n`
445
+ `(e.g. mcp__${toolContext.workflowMcpServerName}__gsd_exec, mcp__${toolContext.workflowMcpServerName}__gsd_save_gate_result)\n` +
446
+ `- Structured user input: call mcp__${toolContext.workflowMcpServerName}__ask_user_questions. ` +
447
+ "Do not call bare ask_user_questions. Do not call native AskUserQuestion.\n"
399
448
  : "- GSD workflow MCP tools are unavailable in this Claude Code run.\n";
400
449
  const toolSearchLine = toolContext.workflowMcpServerName
401
- ? "- ToolSearch is NOT available never use it to discover tools; invoke the MCP tool directly\n"
450
+ ? "- ToolSearch is available only for Claude Code deferred workflow MCP hydration. " +
451
+ `If mcp__${toolContext.workflowMcpServerName}__<tool_name> is missing or Claude Code reports the server is still connecting, ` +
452
+ `use ToolSearch with select:mcp__${toolContext.workflowMcpServerName}__<tool_name> or the base tool name, then call the returned MCP tool directly. ` +
453
+ "Do not use ToolSearch for browser_* tools or general discovery.\n"
402
454
  : "- ToolSearch is NOT available — never use it to discover tools\n";
403
455
  const browserToolLine = toolContext.browserMcpServerName
404
456
  ? "- Browser verification uses gsd-browser MCP by default — call browser tools as " +
@@ -509,9 +561,11 @@ export function buildSdkQueryPrompt(
509
561
  parent_tool_use_id: null,
510
562
  };
511
563
 
512
- return (async function* () {
513
- yield sdkMessage;
514
- })();
564
+ return {
565
+ async *[Symbol.asyncIterator]() {
566
+ yield sdkMessage;
567
+ },
568
+ };
515
569
  }
516
570
 
517
571
  // ---------------------------------------------------------------------------
@@ -533,6 +587,59 @@ function makeErrorMessage(model: string, errorMsg: string): AssistantMessage {
533
587
  };
534
588
  }
535
589
 
590
+ export interface WorkflowMcpReadinessProgressState {
591
+ contentIndex?: number;
592
+ }
593
+
594
+ export function buildWorkflowMcpReadinessProgressMessage(input: {
595
+ unitType: string;
596
+ workflowServerName: string;
597
+ stage: "preflight" | "retry";
598
+ attempt?: number;
599
+ delayMs?: number;
600
+ }): string {
601
+ const { unitType, workflowServerName, stage } = input;
602
+ if (stage === "preflight") {
603
+ return `Starting ${workflowServerName} MCP for ${unitType}; waiting for workflow tools to register...`;
604
+ }
605
+
606
+ const attempt = input.attempt === undefined ? "" : ` attempt ${input.attempt}`;
607
+ const delay = input.delayMs === undefined ? "" : ` Retrying in ${formatReadinessDelay(input.delayMs)}.`;
608
+ return `Still waiting for ${workflowServerName} MCP tools for ${unitType}${attempt}.${delay}`;
609
+ }
610
+
611
+ function formatReadinessDelay(delayMs: number): string {
612
+ if (delayMs < 1_000) return `${delayMs}ms`;
613
+ const seconds = delayMs / 1_000;
614
+ return Number.isInteger(seconds) ? `${seconds}s` : `${seconds.toFixed(1)}s`;
615
+ }
616
+
617
+ export function pushWorkflowMcpReadinessProgressEvent(input: {
618
+ stream: Pick<AssistantMessageEventStream, "push">;
619
+ partial: AssistantMessage;
620
+ state: WorkflowMcpReadinessProgressState;
621
+ message: string;
622
+ }): void {
623
+ const { stream, partial, state, message } = input;
624
+ if (!message) return;
625
+
626
+ let contentIndex = state.contentIndex;
627
+ const existing = contentIndex === undefined ? undefined : partial.content[contentIndex];
628
+ if (contentIndex === undefined || existing?.type !== "text") {
629
+ contentIndex = partial.content.length;
630
+ state.contentIndex = contentIndex;
631
+ partial.content.push({ type: "text", text: "" });
632
+ stream.push({ type: "text_start", contentIndex, partial });
633
+ }
634
+
635
+ const block = partial.content[contentIndex];
636
+ if (block.type !== "text") return;
637
+
638
+ const delta = block.text.length === 0 ? message : `\n${message}`;
639
+ block.text += delta;
640
+ stream.push({ type: "text_delta", contentIndex, delta, partial });
641
+ }
642
+
536
643
  export function isClaudeCodeAbortErrorMessage(message: string | undefined | null): boolean {
537
644
  if (!message) return false;
538
645
  return /\b(?:claude code process aborted by user|request aborted by user|process aborted by user|aborterror)\b/i.test(message);
@@ -1590,7 +1697,7 @@ function browserMcpServerNameFromAllowedTools(allowedTools: unknown): string | u
1590
1697
  if (typeof toolName !== "string") continue;
1591
1698
  const parsed = parseAllowedMcpToolName(toolName);
1592
1699
  if (!parsed) continue;
1593
- if (parsed.server === "gsd-browser" || parsed.tool.startsWith("browser_")) {
1700
+ if (parsed.server === "gsd-browser" || hasBrowserContractPrefix(parsed.tool)) {
1594
1701
  return parsed.server;
1595
1702
  }
1596
1703
  }
@@ -1603,7 +1710,7 @@ function workflowMcpServerNameFromAllowedTools(allowedTools: unknown): string |
1603
1710
  for (const toolName of allowedTools) {
1604
1711
  if (typeof toolName !== "string") continue;
1605
1712
  const parsed = parseAllowedMcpToolName(toolName);
1606
- if (!parsed || parsed.server === browserServerName || parsed.tool.startsWith("browser_")) continue;
1713
+ if (!parsed || parsed.server === browserServerName || hasBrowserContractPrefix(parsed.tool)) continue;
1607
1714
  return parsed.server;
1608
1715
  }
1609
1716
  return undefined;
@@ -1661,11 +1768,15 @@ function resolveExactWorkflowMcpToolsForPhase(
1661
1768
  workflowExplicitlyBlocked: boolean,
1662
1769
  ): string[] {
1663
1770
  if (!gsdPhase || !workflowServerName || workflowExplicitlyBlocked) return [];
1664
- const requiredTools = gsdPhase === "run-uat"
1771
+ const requestedTools = gsdPhase === "run-uat"
1665
1772
  ? [...RUN_UAT_WORKFLOW_TOOL_NAMES]
1666
- : getRequiredWorkflowToolsForAutoUnit(gsdPhase);
1667
- const supportTools = gsdPhase === "run-uat" ? [] : ["gsd_milestone_status"];
1668
- const requestedToolNames = [...new Set([...requiredTools, ...supportTools])];
1773
+ : [
1774
+ ...(getUnitToolSurfaceContract(gsdPhase)?.allowedGsdTools ?? []),
1775
+ ...getRequiredWorkflowToolsForAutoUnit(gsdPhase),
1776
+ ];
1777
+ const requestedToolNames = [...new Set(
1778
+ requestedTools.filter((toolName) => toolName.startsWith("gsd_") || toolName === "ask_user_questions"),
1779
+ )];
1669
1780
  if (requestedToolNames.length === 0) return [];
1670
1781
  return resolveToolPresentationPlan({
1671
1782
  phase: gsdPhase,
@@ -1675,6 +1786,25 @@ function resolveExactWorkflowMcpToolsForPhase(
1675
1786
  }).presentedToolNames;
1676
1787
  }
1677
1788
 
1789
+ function resolveClaudeNativeToolsForPhase(gsdPhase: string | undefined): string[] {
1790
+ const standardClaudeTools = [
1791
+ "Read",
1792
+ "Write",
1793
+ "Edit",
1794
+ "Glob",
1795
+ "Grep",
1796
+ "Bash",
1797
+ "Agent",
1798
+ "WebFetch",
1799
+ "WebSearch",
1800
+ ];
1801
+ if (!gsdPhase) return standardClaudeTools;
1802
+ if (gsdPhase === "run-uat" || gsdPhase === "complete-slice") {
1803
+ return [...RUN_UAT_CLAUDE_NATIVE_TOOL_NAMES];
1804
+ }
1805
+ return standardClaudeTools;
1806
+ }
1807
+
1678
1808
  export function autoInitClaudeCodeWorkflowMcp(cwd: string): void {
1679
1809
  const projectRoot = resolveWorkflowMcpProjectRoot(cwd);
1680
1810
  try {
@@ -1688,6 +1818,70 @@ export function autoInitClaudeCodeWorkflowMcp(cwd: string): void {
1688
1818
  }
1689
1819
  }
1690
1820
 
1821
+ export function resolveClaudeCodeToolSurfaceReadinessError(input: {
1822
+ unitType: string | undefined;
1823
+ workflowServerName: string | undefined;
1824
+ observation: LiveToolSurfaceObservation;
1825
+ projectRoot?: string | undefined;
1826
+ allowPendingToolSearchHydration?: boolean | undefined;
1827
+ }): Promise<string | null> {
1828
+ const error = getToolSurfaceReadinessError(input);
1829
+ if (
1830
+ error
1831
+ && input.allowPendingToolSearchHydration
1832
+ && input.workflowServerName
1833
+ && input.observation.mcpServers.some(
1834
+ (server) => server.name === input.workflowServerName && server.status === "pending",
1835
+ )
1836
+ ) {
1837
+ return Promise.resolve(null);
1838
+ }
1839
+ return Promise.resolve(error);
1840
+ }
1841
+
1842
+ export { awaitWorkflowMcpToolRegistration } from "../gsd/tool-surface-readiness.js";
1843
+
1844
+ const TOOL_SURFACE_READINESS_RETRY_DELAYS_MS = [500, 1_000, 2_000, 4_000, 8_000, 15_000, 15_000, 15_000] as const;
1845
+
1846
+ export function shouldRetryClaudeCodeToolSurfaceReadiness(error: string | null): boolean {
1847
+ if (!error) return false;
1848
+ return error.includes(TOOL_SURFACE_NOT_READY) && !/\bterminal\b/i.test(error);
1849
+ }
1850
+
1851
+ export function resolveClaudeCodeToolSurfaceReadinessRetryDelayMs(
1852
+ error: string | null,
1853
+ attempt: number,
1854
+ preflightVerified = false,
1855
+ ): number | null {
1856
+ if (!shouldRetryClaudeCodeToolSurfaceReadiness(error)) return null;
1857
+ const delays = preflightVerified
1858
+ ? POST_PREFLIGHT_READINESS_RETRY_DELAYS_MS
1859
+ : TOOL_SURFACE_READINESS_RETRY_DELAYS_MS;
1860
+ return delays[attempt] ?? null;
1861
+ }
1862
+
1863
+ function makeAbortError(): Error {
1864
+ const error = new Error("AbortError: The operation was aborted");
1865
+ error.name = "AbortError";
1866
+ return error;
1867
+ }
1868
+
1869
+ function delay(ms: number, signal?: AbortSignal): Promise<void> {
1870
+ if (signal?.aborted) return Promise.reject(makeAbortError());
1871
+
1872
+ return new Promise((resolve, reject) => {
1873
+ const timeout = setTimeout(() => {
1874
+ signal?.removeEventListener("abort", onAbort);
1875
+ resolve();
1876
+ }, ms);
1877
+ const onAbort = (): void => {
1878
+ clearTimeout(timeout);
1879
+ reject(makeAbortError());
1880
+ };
1881
+ signal?.addEventListener("abort", onAbort, { once: true });
1882
+ });
1883
+ }
1884
+
1691
1885
  /**
1692
1886
  * Build the options object passed to the Claude Agent SDK's `query()` call.
1693
1887
  *
@@ -1838,34 +2032,27 @@ export function buildSdkOptions(
1838
2032
  `mcp__${workflowServerName}__gsd_save_gate_result`,
1839
2033
  ]
1840
2034
  : [];
2035
+ const allowToolSearchForWorkflowMcp = workflowMcpTools.length > 0 || exactWorkflowMcpTools.length > 0;
1841
2036
  const disallowedTools: string[] = [...new Set([
1842
- "ToolSearch",
2037
+ ...(allowToolSearchForWorkflowMcp ? [] : ["ToolSearch"]),
2038
+ ...(gsdPhase ? ["Skill"] : []),
1843
2039
  ...(workflowMcpTools.length > 0 || exactWorkflowMcpTools.length > 0 ? ["AskUserQuestion"] : []),
1844
2040
  ...questionToolSurface.disallowedTools,
1845
2041
  ...runUatDisallowedTools,
1846
2042
  ...extraDisallowedTools,
1847
2043
  ])];
1848
- const standardClaudeTools = [
1849
- "Read",
1850
- "Write",
1851
- "Edit",
1852
- "Glob",
1853
- "Grep",
1854
- "Bash",
1855
- "Agent",
1856
- "WebFetch",
1857
- "WebSearch",
1858
- ];
2044
+ const nativeTools = resolveClaudeNativeToolsForPhase(gsdPhase);
1859
2045
  const allowedTools = gsdPhase === "run-uat"
1860
2046
  ? [
1861
- ...RUN_UAT_CLAUDE_NATIVE_TOOL_NAMES,
2047
+ ...nativeTools,
1862
2048
  ...(exactWorkflowMcpTools.length > 0 ? exactWorkflowMcpTools : []),
1863
2049
  ...allowedBrowserMcpTools,
1864
2050
  ]
1865
2051
  : [
1866
- ...standardClaudeTools,
2052
+ ...nativeTools,
1867
2053
  ...exactWorkflowMcpTools,
1868
- ...(workflowMcpTools.length > 0 ? workflowMcpTools : ["AskUserQuestion"]),
2054
+ ...(!gsdPhase && workflowMcpTools.length > 0 ? workflowMcpTools : []),
2055
+ ...(workflowMcpTools.length === 0 && exactWorkflowMcpTools.length === 0 ? ["AskUserQuestion"] : []),
1869
2056
  ...allowedBrowserMcpTools,
1870
2057
  ];
1871
2058
  const supportsAdaptive = modelSupportsAdaptiveThinking(modelId);
@@ -1936,6 +2123,20 @@ export function streamViaClaudeCode(
1936
2123
  return stream;
1937
2124
  }
1938
2125
 
2126
+ interface SdkAttemptMessageState {
2127
+ builder: PartialMessageBuilder | null;
2128
+ intermediateToolBlocks: AssistantMessage["content"];
2129
+ toolResultsById: Map<string, ExternalToolResultPayload>;
2130
+ }
2131
+
2132
+ function createSdkAttemptMessageState(): SdkAttemptMessageState {
2133
+ return {
2134
+ builder: null,
2135
+ intermediateToolBlocks: [],
2136
+ toolResultsById: new Map<string, ExternalToolResultPayload>(),
2137
+ };
2138
+ }
2139
+
1939
2140
  /** Async pump that drives the Claude Agent SDK's async-iterable message stream and pushes events into `stream`. */
1940
2141
  async function pumpSdkMessages(
1941
2142
  model: Model<any>,
@@ -1944,38 +2145,30 @@ async function pumpSdkMessages(
1944
2145
  stream: AssistantMessageEventStream,
1945
2146
  ): Promise<void> {
1946
2147
  const modelId = model.id;
1947
- let builder: PartialMessageBuilder | null = null;
1948
2148
  /** Track the last text content seen across all assistant turns for the final message. */
1949
2149
  let lastTextContent = "";
1950
2150
  let lastThinkingContent = "";
1951
- /** Collect tool blocks from intermediate SDK turns for tool execution rendering. */
1952
- const intermediateToolBlocks: AssistantMessage["content"] = [];
1953
- /** Preserve real external tool results from Claude Code's synthetic user messages. */
1954
- const toolResultsById = new Map<string, ExternalToolResultPayload>();
1955
2151
 
1956
2152
  try {
1957
- // Dynamic import — the SDK is an optional dependency.
1958
- const sdkModule = "@anthropic-ai/claude-agent-sdk";
1959
- const sdk = (await import(/* webpackIgnore: true */ sdkModule)) as {
1960
- query: (args: {
1961
- prompt: string | AsyncIterable<unknown>;
1962
- options?: Record<string, unknown>;
1963
- }) => AsyncIterable<SDKMessage>;
1964
- };
1965
-
1966
- // Bridge GSD's AbortSignal to SDK's AbortController
1967
- const controller = new AbortController();
1968
- if (options?.signal) {
1969
- options.signal.addEventListener("abort", () => controller.abort(), { once: true });
1970
- }
1971
-
1972
2153
  const permissionMode = await resolveClaudePermissionMode();
1973
- const uiContext = (options as ClaudeCodeStreamOptions | undefined)?.extensionUIContext;
1974
- const onExternalToolCall = (options as ClaudeCodeStreamOptions | undefined)?.onExternalToolCall;
1975
- const onExternalToolResult = (options as ClaudeCodeStreamOptions | undefined)?.onExternalToolResult;
2154
+ const claudeOptions = options as ClaudeCodeStreamOptions | undefined;
2155
+ const uiContext = claudeOptions?.extensionUIContext;
2156
+ const onExternalToolCall = claudeOptions?.onExternalToolCall;
2157
+ const onExternalToolResult = claudeOptions?.onExternalToolResult;
2158
+ const sdkQueryForTest = claudeOptions?._sdkQueryForTest;
2159
+ const query = sdkQueryForTest ?? (
2160
+ // Dynamic import — the SDK is an optional dependency.
2161
+ (await import(/* webpackIgnore: true */ "@anthropic-ai/claude-agent-sdk")) as {
2162
+ query: (args: {
2163
+ prompt: string | AsyncIterable<unknown>;
2164
+ options?: Record<string, unknown>;
2165
+ }) => AsyncIterable<SDKMessage>;
2166
+ }
2167
+ ).query;
1976
2168
  const cwd = resolveClaudeCodeCwd(options);
2169
+ const projectRoot = resolveWorkflowMcpProjectRoot(cwd);
1977
2170
  autoInitClaudeCodeWorkflowMcp(cwd);
1978
- const gsdPhase = inferGsdPhaseFromContext(context);
2171
+ const gsdPhase = resolveGsdPhaseForSdk(context, projectRoot);
1979
2172
  const canUseToolHandler = createClaudeCodeCanUseToolHandler(uiContext);
1980
2173
  // When no UI is available (headless / auto-mode), auto-approve all
1981
2174
  // tool requests. This replaces the old bypassPermissions workaround.
@@ -1998,20 +2191,16 @@ async function pumpSdkMessages(
1998
2191
  : {}),
1999
2192
  },
2000
2193
  );
2194
+ const workflowMcpServerName = workflowMcpServerNameFromAllowedTools(sdkOpts.allowedTools);
2195
+ const allowPendingToolSearchHydration =
2196
+ Boolean(workflowMcpServerName && gsdPhase)
2197
+ && !(sdkOpts.disallowedTools as string[] | undefined)?.includes("ToolSearch");
2001
2198
  const prompt = buildPromptFromContext(context, {
2002
- workflowMcpServerName: workflowMcpServerNameFromAllowedTools(sdkOpts.allowedTools),
2199
+ workflowMcpServerName,
2003
2200
  browserMcpServerName: browserMcpServerNameFromAllowedTools(sdkOpts.allowedTools),
2004
2201
  });
2005
2202
  const queryPrompt = buildSdkQueryPrompt(context, prompt);
2006
2203
 
2007
- const queryResult = sdk.query({
2008
- prompt: queryPrompt,
2009
- options: {
2010
- ...sdkOpts,
2011
- abortController: controller,
2012
- },
2013
- });
2014
-
2015
2204
  // Emit start with an empty partial
2016
2205
  const initialPartial: AssistantMessage = {
2017
2206
  role: "assistant",
@@ -2024,174 +2213,320 @@ async function pumpSdkMessages(
2024
2213
  timestamp: Date.now(),
2025
2214
  };
2026
2215
  stream.push({ type: "start", partial: initialPartial });
2216
+ const readinessProgressState: WorkflowMcpReadinessProgressState = {};
2027
2217
 
2028
- for await (const msg of queryResult as AsyncIterable<SDKMessage>) {
2029
- if (options?.signal?.aborted) {
2030
- // User-initiated cancel — emit an aborted error so the agent
2031
- // loop classifies this as a deliberate stop, not a transient
2032
- // provider failure that should be retried.
2033
- stream.push({
2034
- type: "error",
2035
- reason: "aborted",
2036
- error: makeAbortedMessage(modelId, lastTextContent),
2037
- });
2038
- return;
2218
+ const trackWorkflowMcpSdk = Boolean(workflowMcpServerName && gsdPhase);
2219
+ if (trackWorkflowMcpSdk) beginWorkflowMcpSdkSession();
2220
+ try {
2221
+ let workflowMcpPreflightVerified = false;
2222
+ const shouldRunWorkflowMcpPreflight =
2223
+ workflowMcpServerName && gsdPhase && !claudeOptions?._skipWorkflowMcpPreflightForTest;
2224
+ if (shouldRunWorkflowMcpPreflight) {
2225
+ try {
2226
+ const progressMessage = buildWorkflowMcpReadinessProgressMessage({
2227
+ unitType: gsdPhase,
2228
+ workflowServerName: workflowMcpServerName,
2229
+ stage: "preflight",
2230
+ });
2231
+ pushWorkflowMcpReadinessProgressEvent({
2232
+ stream,
2233
+ partial: initialPartial,
2234
+ state: readinessProgressState,
2235
+ message: progressMessage,
2236
+ });
2237
+ uiContext?.setStatus?.("gsd-step", progressMessage);
2238
+ const preflightError = await awaitWorkflowMcpToolRegistration({
2239
+ unitType: gsdPhase,
2240
+ workflowServerName: workflowMcpServerName,
2241
+ projectRoot,
2242
+ signal: options?.signal,
2243
+ });
2244
+ if (preflightError) {
2245
+ stream.push({
2246
+ type: "error",
2247
+ reason: "error",
2248
+ error: makeErrorMessage(modelId, preflightError),
2249
+ });
2250
+ return;
2251
+ }
2252
+ workflowMcpPreflightVerified = true;
2253
+ } finally {
2254
+ uiContext?.setStatus?.("gsd-step", "");
2255
+ }
2256
+ if (workflowMcpPreflightVerified) {
2257
+ await delay(POST_PREFLIGHT_SDK_SETTLE_MS, options?.signal);
2258
+ }
2039
2259
  }
2040
2260
 
2041
- switch (msg.type) {
2042
- // -- Init --
2043
- case "system": {
2044
- // Nothing to emit — the stream is already started.
2045
- break;
2261
+ sdkAttemptLoop:
2262
+ for (let readinessAttempt = 0; ; readinessAttempt++) {
2263
+ let { builder, intermediateToolBlocks, toolResultsById } = createSdkAttemptMessageState();
2264
+ const controller = new AbortController();
2265
+ const forwardAbort = (): void => controller.abort();
2266
+ if (options?.signal) {
2267
+ options.signal.addEventListener("abort", forwardAbort, { once: true });
2046
2268
  }
2047
2269
 
2048
- // -- Streaming partial messages --
2049
- case "stream_event": {
2050
- const partial = msg as SDKPartialAssistantMessage;
2051
-
2052
- const event = partial.event;
2053
-
2054
- const result = handleClaudeCodePartialStreamEvent(builder, event, modelId);
2055
- builder = result.builder;
2056
- const assistantEvent = result.assistantEvent;
2057
- if (assistantEvent) {
2058
- stream.push(assistantEvent);
2059
- if (assistantEvent.type === "toolcall_start") {
2060
- const toolBlock = assistantEvent.partial.content[assistantEvent.contentIndex];
2061
- if (toolBlock?.type === "toolCall") {
2062
- try {
2063
- await onExternalToolCall?.(toolBlock);
2064
- } catch (error) {
2065
- console.warn("[claude-code] onExternalToolCall callback failed:", error);
2270
+ const queryResult = query({
2271
+ prompt: queryPrompt,
2272
+ options: {
2273
+ ...sdkOpts,
2274
+ abortController: controller,
2275
+ },
2276
+ });
2277
+
2278
+ try {
2279
+ for await (const msg of queryResult as AsyncIterable<SDKMessage>) {
2280
+ if (options?.signal?.aborted) {
2281
+ // User-initiated cancel emit an aborted error so the agent
2282
+ // loop classifies this as a deliberate stop, not a transient
2283
+ // provider failure that should be retried.
2284
+ stream.push({
2285
+ type: "error",
2286
+ reason: "aborted",
2287
+ error: makeAbortedMessage(modelId, lastTextContent),
2288
+ });
2289
+ return;
2290
+ }
2291
+
2292
+ switch (msg.type) {
2293
+ // -- Init --
2294
+ case "system": {
2295
+ // Tool Surface Readiness gate: the init message is the first (and
2296
+ // only) point where the session reports its live tool surface and
2297
+ // MCP server statuses. If the workflow server failed or has not
2298
+ // registered this Unit's required tools, abort before the first
2299
+ // model turn with a transient, recovery-classifiable error
2300
+ // (tool-unavailable → retry) instead of letting the model hit
2301
+ // "No such tool available" mid-Unit and improvise around it.
2302
+ const init = msg as unknown as {
2303
+ subtype?: string;
2304
+ tools?: string[];
2305
+ mcp_servers?: { name: string; status: string }[];
2306
+ };
2307
+ if (init.subtype === "init") {
2308
+ const readinessError = await resolveClaudeCodeToolSurfaceReadinessError({
2309
+ unitType: gsdPhase,
2310
+ workflowServerName: workflowMcpServerName,
2311
+ projectRoot,
2312
+ observation: { tools: init.tools ?? [], mcpServers: init.mcp_servers ?? [] },
2313
+ allowPendingToolSearchHydration,
2314
+ });
2315
+ if (readinessError) {
2316
+ const retryDelayMs = resolveClaudeCodeToolSurfaceReadinessRetryDelayMs(
2317
+ readinessError,
2318
+ readinessAttempt,
2319
+ workflowMcpPreflightVerified,
2320
+ );
2321
+ if (retryDelayMs !== null && !options?.signal?.aborted) {
2322
+ controller.abort();
2323
+ const progressMessage = buildWorkflowMcpReadinessProgressMessage({
2324
+ unitType: gsdPhase ?? "workflow unit",
2325
+ workflowServerName: workflowMcpServerName ?? "workflow",
2326
+ stage: "retry",
2327
+ attempt: readinessAttempt + 1,
2328
+ delayMs: retryDelayMs,
2329
+ });
2330
+ pushWorkflowMcpReadinessProgressEvent({
2331
+ stream,
2332
+ partial: initialPartial,
2333
+ state: readinessProgressState,
2334
+ message: progressMessage,
2335
+ });
2336
+ uiContext?.setStatus?.("gsd-step", progressMessage);
2337
+ await delay(retryDelayMs, options?.signal);
2338
+ uiContext?.setStatus?.("gsd-step", "");
2339
+ continue sdkAttemptLoop;
2340
+ }
2341
+ controller.abort();
2342
+ stream.push({
2343
+ type: "error",
2344
+ reason: "error",
2345
+ error: makeErrorMessage(modelId, readinessError),
2346
+ });
2347
+ return;
2066
2348
  }
2067
2349
  }
2350
+ break;
2068
2351
  }
2069
- }
2070
- break;
2071
- }
2072
2352
 
2073
- // -- Complete assistant message (non-streaming fallback) --
2074
- case "assistant": {
2075
- const sdkAssistant = msg as SDKAssistantMessage;
2076
-
2077
- // Capture text content from complete messages
2078
- for (const block of sdkAssistant.message.content) {
2079
- if (block.type === "text") {
2080
- lastTextContent = block.text;
2081
- } else if (block.type === "thinking") {
2082
- lastThinkingContent = block.thinking;
2353
+ // -- Streaming partial messages --
2354
+ case "stream_event": {
2355
+ const partial = msg as SDKPartialAssistantMessage;
2356
+
2357
+ const event = partial.event;
2358
+
2359
+ const result = handleClaudeCodePartialStreamEvent(builder, event, modelId);
2360
+ builder = result.builder;
2361
+ const assistantEvent = result.assistantEvent;
2362
+ if (assistantEvent) {
2363
+ stream.push(assistantEvent);
2364
+ if (assistantEvent.type === "toolcall_start") {
2365
+ const toolBlock = assistantEvent.partial.content[assistantEvent.contentIndex];
2366
+ if (toolBlock?.type === "toolCall") {
2367
+ try {
2368
+ await onExternalToolCall?.(toolBlock);
2369
+ } catch (error) {
2370
+ console.warn("[claude-code] onExternalToolCall callback failed:", error);
2371
+ }
2372
+ }
2373
+ }
2374
+ }
2375
+ break;
2083
2376
  }
2084
- }
2085
- break;
2086
- }
2087
2377
 
2088
- // -- User message (synthetic tool result — signals turn boundary) --
2089
- case "user": {
2090
- // Capture content from the completed turn before resetting
2091
- if (builder) {
2092
- for (const block of builder.message.content) {
2093
- if (block.type === "text" && block.text) {
2094
- lastTextContent = block.text;
2095
- } else if (block.type === "thinking" && block.thinking) {
2096
- lastThinkingContent = block.thinking;
2097
- } else if (block.type === "toolCall" || block.type === "serverToolUse") {
2098
- // Collect tool blocks for externalToolExecution rendering
2099
- intermediateToolBlocks.push(block);
2378
+ // -- Complete assistant message (non-streaming fallback) --
2379
+ case "assistant": {
2380
+ const sdkAssistant = msg as SDKAssistantMessage;
2381
+
2382
+ // Capture text content from complete messages
2383
+ for (const block of sdkAssistant.message.content) {
2384
+ if (block.type === "text") {
2385
+ lastTextContent = block.text;
2386
+ } else if (block.type === "thinking") {
2387
+ lastThinkingContent = block.thinking;
2388
+ }
2100
2389
  }
2390
+ break;
2101
2391
  }
2102
- }
2103
2392
 
2104
- // Extract tool results from the SDK's synthetic user message
2105
- // and attach to corresponding tool call blocks immediately.
2106
- for (const { toolUseId, result } of extractToolResultsFromSdkUserMessage(msg as SDKUserMessage)) {
2107
- toolResultsById.set(toolUseId, result);
2108
- }
2109
- attachExternalResultsToToolBlocks(intermediateToolBlocks, toolResultsById);
2110
-
2111
- // Push a synthetic toolcall_end for each tool call from this turn
2112
- // so the TUI can render tool results in real-time during the SDK
2113
- // session instead of waiting until the entire session completes.
2114
- if (builder) {
2115
- for (const block of builder.message.content) {
2116
- const extResult = (block as ToolCallWithExternalResult).externalResult;
2117
- if (!extResult) continue;
2118
- const contentIndex = builder.message.content.indexOf(block);
2119
- if (contentIndex < 0) continue;
2120
- // Push synthetic completion events with result attached so the
2121
- // chat-controller can update pending ToolExecutionComponents.
2122
- if (block.type === "toolCall") {
2123
- try {
2124
- await onExternalToolResult?.({
2125
- toolCall: block,
2126
- result: extResult,
2127
- });
2128
- } catch (error) {
2129
- console.warn("[claude-code] onExternalToolResult callback failed:", error);
2393
+ // -- User message (synthetic tool result signals turn boundary) --
2394
+ case "user": {
2395
+ // Capture content from the completed turn before resetting
2396
+ if (builder) {
2397
+ for (const block of builder.message.content) {
2398
+ if (block.type === "text" && block.text) {
2399
+ lastTextContent = block.text;
2400
+ } else if (block.type === "thinking" && block.thinking) {
2401
+ lastThinkingContent = block.thinking;
2402
+ } else if (block.type === "toolCall" || block.type === "serverToolUse") {
2403
+ // Collect tool blocks for externalToolExecution rendering
2404
+ intermediateToolBlocks.push(block);
2405
+ }
2130
2406
  }
2131
- stream.push({
2132
- type: "toolcall_end",
2133
- contentIndex,
2134
- toolCall: block,
2135
- partial: builder.message,
2136
- });
2137
- } else if (block.type === "serverToolUse") {
2138
- try {
2139
- await onExternalToolResult?.({
2140
- toolCall: serverToolUseToToolCallLike(block),
2141
- result: extResult,
2142
- });
2143
- } catch (error) {
2144
- console.warn("[claude-code] onExternalToolResult callback failed:", error);
2407
+ }
2408
+
2409
+ // Extract tool results from the SDK's synthetic user message
2410
+ // and attach to corresponding tool call blocks immediately.
2411
+ for (const { toolUseId, result } of extractToolResultsFromSdkUserMessage(msg as SDKUserMessage)) {
2412
+ toolResultsById.set(toolUseId, result);
2413
+ }
2414
+ attachExternalResultsToToolBlocks(intermediateToolBlocks, toolResultsById);
2415
+
2416
+ // Push a synthetic toolcall_end for each tool call from this turn
2417
+ // so the TUI can render tool results in real-time during the SDK
2418
+ // session instead of waiting until the entire session completes.
2419
+ if (builder) {
2420
+ for (const block of builder.message.content) {
2421
+ const extResult = (block as ToolCallWithExternalResult).externalResult;
2422
+ if (!extResult) continue;
2423
+ const contentIndex = builder.message.content.indexOf(block);
2424
+ if (contentIndex < 0) continue;
2425
+ const suppressDuplicateUnavailable = shouldSuppressDuplicateToolUnavailableBlock(
2426
+ block,
2427
+ builder.message.content,
2428
+ );
2429
+ // Push synthetic completion events with result attached so the
2430
+ // chat-controller can update pending ToolExecutionComponents.
2431
+ if (block.type === "toolCall") {
2432
+ if (suppressDuplicateUnavailable) {
2433
+ delete (block as ToolCallWithExternalResult).externalResult;
2434
+ stream.push({
2435
+ type: "toolcall_end",
2436
+ contentIndex,
2437
+ toolCall: block,
2438
+ partial: builder.message,
2439
+ });
2440
+ (block as ToolCallWithExternalResult).externalResult = extResult;
2441
+ continue;
2442
+ }
2443
+ try {
2444
+ await onExternalToolResult?.({
2445
+ toolCall: block,
2446
+ result: extResult,
2447
+ });
2448
+ } catch (error) {
2449
+ console.warn("[claude-code] onExternalToolResult callback failed:", error);
2450
+ }
2451
+ stream.push({
2452
+ type: "toolcall_end",
2453
+ contentIndex,
2454
+ toolCall: block,
2455
+ partial: builder.message,
2456
+ });
2457
+ } else if (block.type === "serverToolUse") {
2458
+ try {
2459
+ await onExternalToolResult?.({
2460
+ toolCall: serverToolUseToToolCallLike(block),
2461
+ result: extResult,
2462
+ });
2463
+ } catch (error) {
2464
+ console.warn("[claude-code] onExternalToolResult callback failed:", error);
2465
+ }
2466
+ stream.push({
2467
+ type: "server_tool_use",
2468
+ contentIndex,
2469
+ partial: builder.message,
2470
+ });
2471
+ }
2145
2472
  }
2146
- stream.push({
2147
- type: "server_tool_use",
2148
- contentIndex,
2149
- partial: builder.message,
2150
- });
2151
2473
  }
2474
+
2475
+ builder = null;
2476
+ break;
2152
2477
  }
2153
- }
2154
2478
 
2155
- builder = null;
2156
- break;
2157
- }
2479
+ // -- Result (terminal) --
2480
+ case "result": {
2481
+ const result = msg as SDKResultMessage;
2482
+ const finalContent = buildFinalAssistantContent({
2483
+ intermediateToolBlocks,
2484
+ pendingContent: builder?.message.content,
2485
+ toolResultsById,
2486
+ lastThinkingContent,
2487
+ lastTextContent,
2488
+ fallbackResultText:
2489
+ result.subtype === "success" && result.result ? result.result : undefined,
2490
+ });
2491
+
2492
+ const finalMessage: AssistantMessage = {
2493
+ role: "assistant",
2494
+ content: finalContent,
2495
+ api: "anthropic-messages",
2496
+ provider: "claude-code",
2497
+ model: modelId,
2498
+ usage: mapUsage(result.usage, result.total_cost_usd),
2499
+ stopReason: result.is_error ? "error" : "stop",
2500
+ timestamp: Date.now(),
2501
+ };
2158
2502
 
2159
- // -- Result (terminal) --
2160
- case "result": {
2161
- const result = msg as SDKResultMessage;
2162
- const finalContent = buildFinalAssistantContent({
2163
- intermediateToolBlocks,
2164
- pendingContent: builder?.message.content,
2165
- toolResultsById,
2166
- lastThinkingContent,
2167
- lastTextContent,
2168
- fallbackResultText:
2169
- result.subtype === "success" && result.result ? result.result : undefined,
2170
- });
2503
+ if (result.is_error) {
2504
+ finalMessage.errorMessage = getResultErrorMessage(result);
2505
+ stream.push({ type: "error", reason: "error", error: finalMessage });
2506
+ } else {
2507
+ stream.push({ type: "done", reason: "stop", message: finalMessage });
2508
+ }
2509
+ return;
2510
+ }
2171
2511
 
2172
- const finalMessage: AssistantMessage = {
2173
- role: "assistant",
2174
- content: finalContent,
2175
- api: "anthropic-messages",
2176
- provider: "claude-code",
2177
- model: modelId,
2178
- usage: mapUsage(result.usage, result.total_cost_usd),
2179
- stopReason: result.is_error ? "error" : "stop",
2180
- timestamp: Date.now(),
2181
- };
2182
-
2183
- if (result.is_error) {
2184
- finalMessage.errorMessage = getResultErrorMessage(result);
2185
- stream.push({ type: "error", reason: "error", error: finalMessage });
2186
- } else {
2187
- stream.push({ type: "done", reason: "stop", message: finalMessage });
2512
+ default:
2513
+ break;
2188
2514
  }
2189
- return;
2515
+ }
2516
+ } finally {
2517
+ options?.signal?.removeEventListener("abort", forwardAbort);
2190
2518
  }
2191
2519
 
2192
- default:
2193
- break;
2520
+ // The SDK stream ended without a terminal `result` message and
2521
+ // without a readiness retry (the only restart path, via
2522
+ // `continue sdkAttemptLoop`). Break out so the post-loop
2523
+ // exhaustion handler emits a transient stream-exhausted error,
2524
+ // instead of silently starting another SDK session and looping
2525
+ // forever.
2526
+ break sdkAttemptLoop;
2194
2527
  }
2528
+ } finally {
2529
+ if (trackWorkflowMcpSdk) endWorkflowMcpSdkSession();
2195
2530
  }
2196
2531
 
2197
2532
  // Generator exhaustion without a terminal result is a stream interruption,