@opengsd/gsd-pi 1.2.0-dev.844675c9 → 1.2.0-dev.8e6112e9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1016) 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-web-branch.d.ts +2 -0
  6. package/dist/cli-web-branch.js +9 -2
  7. package/dist/cli.js +2 -19
  8. package/dist/headless-events.d.ts +4 -2
  9. package/dist/headless-events.js +14 -34
  10. package/dist/help-text.js +5 -0
  11. package/dist/loader.js +6 -4
  12. package/dist/mcp-server.js +2 -1
  13. package/dist/models-resolver.d.ts +3 -13
  14. package/dist/models-resolver.js +3 -22
  15. package/dist/register-agent-bundles.d.ts +11 -2
  16. package/dist/register-agent-bundles.js +18 -4
  17. package/dist/resource-loader.d.ts +10 -5
  18. package/dist/resource-loader.js +123 -20
  19. package/dist/resources/.managed-resources-content-hash +1 -1
  20. package/dist/resources/GSD-WORKFLOW.md +5 -4
  21. package/dist/resources/extensions/ask-user-questions.js +81 -25
  22. package/dist/resources/extensions/async-jobs/async-bash-tool.js +30 -64
  23. package/dist/resources/extensions/async-jobs/await-tool.js +80 -12
  24. package/dist/resources/extensions/async-jobs/index.js +65 -0
  25. package/dist/resources/extensions/async-jobs/job-manager.js +12 -1
  26. package/dist/resources/extensions/bg-shell/bg-shell-command.js +6 -6
  27. package/dist/resources/extensions/bg-shell/bg-shell-tool.js +10 -7
  28. package/dist/resources/extensions/bg-shell/overlay.js +9 -6
  29. package/dist/resources/extensions/bg-shell/process-manager.js +54 -25
  30. package/dist/resources/extensions/bg-shell/readiness-detector.js +11 -0
  31. package/dist/resources/extensions/bg-shell/utilities.js +5 -2
  32. package/dist/resources/extensions/browser-tools/engine/managed-gsd-browser.js +209 -88
  33. package/dist/resources/extensions/browser-tools/engine/selection.js +73 -5
  34. package/dist/resources/extensions/browser-tools/index.js +69 -12
  35. package/dist/resources/extensions/claude-code-cli/models.js +9 -0
  36. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +546 -426
  37. package/dist/resources/extensions/claude-code-cli/turn-assembler.js +256 -0
  38. package/dist/resources/extensions/github-sync/templates.js +3 -3
  39. package/dist/resources/extensions/gsd/artifact-projection.js +14 -0
  40. package/dist/resources/extensions/gsd/auto/closeout.js +215 -0
  41. package/dist/resources/extensions/gsd/auto/custom-verify-retry-store.js +17 -2
  42. package/dist/resources/extensions/gsd/auto/detect-stuck.js +33 -13
  43. package/dist/resources/extensions/gsd/auto/dispatch-history.js +120 -0
  44. package/dist/resources/extensions/gsd/auto/dispatch-key.js +37 -0
  45. package/dist/resources/extensions/gsd/auto/dispatch.js +365 -0
  46. package/dist/resources/extensions/gsd/auto/finalize.js +347 -0
  47. package/dist/resources/extensions/gsd/auto/loop.js +80 -56
  48. package/dist/resources/extensions/gsd/auto/milestone-lease-reclaim.js +56 -0
  49. package/dist/resources/extensions/gsd/auto/orchestrator.js +310 -78
  50. package/dist/resources/extensions/gsd/auto/phase-helpers.js +146 -0
  51. package/dist/resources/extensions/gsd/auto/phases.js +17 -2299
  52. package/dist/resources/extensions/gsd/auto/pre-dispatch.js +534 -0
  53. package/dist/resources/extensions/gsd/auto/run-unit.js +2 -1
  54. package/dist/resources/extensions/gsd/auto/session.js +6 -0
  55. package/dist/resources/extensions/gsd/auto/unit-phase.js +694 -0
  56. package/dist/resources/extensions/gsd/auto/workflow-unit-dispatch.js +1 -1
  57. package/dist/resources/extensions/gsd/auto/worktree-safety-phase.js +125 -0
  58. package/dist/resources/extensions/gsd/auto-dashboard.js +16 -4
  59. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +11 -34
  60. package/dist/resources/extensions/gsd/auto-dispatch.js +56 -63
  61. package/dist/resources/extensions/gsd/auto-model-selection.js +44 -13
  62. package/dist/resources/extensions/gsd/auto-post-unit.js +47 -17
  63. package/dist/resources/extensions/gsd/auto-prompts.js +161 -26
  64. package/dist/resources/extensions/gsd/auto-recovery.js +48 -49
  65. package/dist/resources/extensions/gsd/auto-runtime-state.js +14 -0
  66. package/dist/resources/extensions/gsd/auto-start.js +59 -52
  67. package/dist/resources/extensions/gsd/auto-timers.js +16 -2
  68. package/dist/resources/extensions/gsd/auto-tool-tracking.js +50 -0
  69. package/dist/resources/extensions/gsd/auto-unit-closeout.js +45 -21
  70. package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +14 -47
  71. package/dist/resources/extensions/gsd/auto-verification.js +30 -37
  72. package/dist/resources/extensions/gsd/auto-worktree-repair.js +10 -2
  73. package/dist/resources/extensions/gsd/auto-worktree.js +68 -370
  74. package/dist/resources/extensions/gsd/auto.js +71 -29
  75. package/dist/resources/extensions/gsd/blocked-models.js +28 -0
  76. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +29 -8
  77. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +28 -37
  78. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +74 -50
  79. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +2 -2
  80. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +2 -2
  81. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +19 -0
  82. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +316 -161
  83. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +365 -58
  84. package/dist/resources/extensions/gsd/branch-patterns.js +2 -0
  85. package/dist/resources/extensions/gsd/browser-daemon-auto-prep.js +83 -0
  86. package/dist/resources/extensions/gsd/browser-evidence.js +8 -2
  87. package/dist/resources/extensions/gsd/captures.js +5 -15
  88. package/dist/resources/extensions/gsd/closeout-consistency-gate.js +21 -4
  89. package/dist/resources/extensions/gsd/closeout-recovery.js +3 -2
  90. package/dist/resources/extensions/gsd/closeout-wizard.js +92 -0
  91. package/dist/resources/extensions/gsd/codebase-generator.js +8 -4
  92. package/dist/resources/extensions/gsd/commands/catalog.js +6 -62
  93. package/dist/resources/extensions/gsd/commands/context.js +16 -2
  94. package/dist/resources/extensions/gsd/commands/handlers/auto.js +3 -0
  95. package/dist/resources/extensions/gsd/commands-handlers.js +66 -3
  96. package/dist/resources/extensions/gsd/commands-inspect.js +4 -8
  97. package/dist/resources/extensions/gsd/commands-maintenance.js +61 -41
  98. package/dist/resources/extensions/gsd/commands-mcp-status.js +2 -2
  99. package/dist/resources/extensions/gsd/commands-ship.js +2 -2
  100. package/dist/resources/extensions/gsd/commands-verdict.js +12 -2
  101. package/dist/resources/extensions/gsd/commands-workflow-templates.js +9 -2
  102. package/dist/resources/extensions/gsd/consent-question.js +353 -0
  103. package/dist/resources/extensions/gsd/consent-verdict.js +63 -0
  104. package/dist/resources/extensions/gsd/constants.js +0 -2
  105. package/dist/resources/extensions/gsd/crash-recovery.js +12 -15
  106. package/dist/resources/extensions/gsd/db/engine.js +757 -0
  107. package/dist/resources/extensions/gsd/db/queries.js +428 -0
  108. package/dist/resources/extensions/gsd/db/sql-constants.js +11 -0
  109. package/dist/resources/extensions/gsd/db/writers/cascades.js +194 -0
  110. package/dist/resources/extensions/gsd/db/writers/import-restore.js +182 -0
  111. package/dist/resources/extensions/gsd/db/writers/memory.js +149 -0
  112. package/dist/resources/extensions/gsd/db/writers/reconcile.js +458 -0
  113. package/dist/resources/extensions/gsd/db/writers/status.js +70 -0
  114. package/dist/resources/extensions/gsd/db-workspace.js +103 -0
  115. package/dist/resources/extensions/gsd/db-writer.js +8 -17
  116. package/dist/resources/extensions/gsd/delegation-policy.js +2 -10
  117. package/dist/resources/extensions/gsd/discussion-handoff.js +218 -0
  118. package/dist/resources/extensions/gsd/dispatch-guard.js +10 -35
  119. package/dist/resources/extensions/gsd/docs/preferences-reference.md +9 -0
  120. package/dist/resources/extensions/gsd/doctor-engine-checks.js +5 -5
  121. package/dist/resources/extensions/gsd/doctor-environment.js +261 -136
  122. package/dist/resources/extensions/gsd/doctor-format.js +9 -6
  123. package/dist/resources/extensions/gsd/doctor-git-checks.js +6 -21
  124. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +21 -16
  125. package/dist/resources/extensions/gsd/doctor.js +16 -9
  126. package/dist/resources/extensions/gsd/engine-hook-contract.js +70 -0
  127. package/dist/resources/extensions/gsd/error-classifier.js +10 -1
  128. package/dist/resources/extensions/gsd/exec-sandbox.js +30 -10
  129. package/dist/resources/extensions/gsd/files.js +33 -19
  130. package/dist/resources/extensions/gsd/git-conflict-state.js +16 -1
  131. package/dist/resources/extensions/gsd/git-service.js +1 -0
  132. package/dist/resources/extensions/gsd/gitignore.js +3 -0
  133. package/dist/resources/extensions/gsd/gsd-command-home.js +22 -12
  134. package/dist/resources/extensions/gsd/gsd-db.js +186 -2048
  135. package/dist/resources/extensions/gsd/guidance.js +158 -0
  136. package/dist/resources/extensions/gsd/guided-flow.js +174 -473
  137. package/dist/resources/extensions/gsd/guided-unit-completion.js +225 -0
  138. package/dist/resources/extensions/gsd/health-widget.js +87 -28
  139. package/dist/resources/extensions/gsd/markdown-renderer.js +12 -1
  140. package/dist/resources/extensions/gsd/mcp-bridge.js +10 -0
  141. package/dist/resources/extensions/gsd/mcp-filter.js +4 -20
  142. package/dist/resources/extensions/gsd/mcp-tool-name.js +18 -0
  143. package/dist/resources/extensions/gsd/md-importer.js +4 -3
  144. package/dist/resources/extensions/gsd/memory-consolidation-scanner.js +1 -1
  145. package/dist/resources/extensions/gsd/memory-relations.js +1 -1
  146. package/dist/resources/extensions/gsd/migrate/safety.js +22 -11
  147. package/dist/resources/extensions/gsd/migration-auto-check.js +27 -5
  148. package/dist/resources/extensions/gsd/milestone-closeout-proof.js +72 -0
  149. package/dist/resources/extensions/gsd/milestone-closeout.js +97 -28
  150. package/dist/resources/extensions/gsd/milestone-merge-transaction.js +10 -0
  151. package/dist/resources/extensions/gsd/milestone-planning-persistence.js +156 -0
  152. package/dist/resources/extensions/gsd/milestone-readiness.js +77 -0
  153. package/dist/resources/extensions/gsd/milestone-reopen-events.js +3 -5
  154. package/dist/resources/extensions/gsd/milestone-settlement.js +50 -0
  155. package/dist/resources/extensions/gsd/milestone-validation-evidence.js +73 -0
  156. package/dist/resources/extensions/gsd/milestone-validation-verdict.js +57 -0
  157. package/dist/resources/extensions/gsd/model-cost-table.js +1 -0
  158. package/dist/resources/extensions/gsd/model-router.js +3 -0
  159. package/dist/resources/extensions/gsd/notification-store.js +11 -4
  160. package/dist/resources/extensions/gsd/notifications.js +12 -7
  161. package/dist/resources/extensions/gsd/parallel-eligibility.js +3 -6
  162. package/dist/resources/extensions/gsd/parallel-merge.js +14 -11
  163. package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +11 -7
  164. package/dist/resources/extensions/gsd/parallel-orchestrator.js +3 -2
  165. package/dist/resources/extensions/gsd/parsers-legacy.js +16 -4
  166. package/dist/resources/extensions/gsd/paths.js +37 -24
  167. package/dist/resources/extensions/gsd/pre-execution-checks.js +91 -3
  168. package/dist/resources/extensions/gsd/preferences-diagnostics.js +67 -0
  169. package/dist/resources/extensions/gsd/preferences-models.js +14 -48
  170. package/dist/resources/extensions/gsd/preferences.js +161 -29
  171. package/dist/resources/extensions/gsd/projection-flush.js +7 -0
  172. package/dist/resources/extensions/gsd/prompts/complete-slice.md +5 -4
  173. package/dist/resources/extensions/gsd/prompts/execute-task.md +5 -2
  174. package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +3 -1
  175. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +3 -1
  176. package/dist/resources/extensions/gsd/prompts/plan-slice.md +3 -2
  177. package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -1
  178. package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
  179. package/dist/resources/extensions/gsd/prompts/refine-slice.md +3 -2
  180. package/dist/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  181. package/dist/resources/extensions/gsd/prompts/research-milestone.md +1 -1
  182. package/dist/resources/extensions/gsd/prompts/research-slice.md +1 -1
  183. package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  184. package/dist/resources/extensions/gsd/prompts/run-uat.md +9 -5
  185. package/dist/resources/extensions/gsd/prompts/system.md +6 -3
  186. package/dist/resources/extensions/gsd/prompts/triage-captures.md +1 -1
  187. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +1 -1
  188. package/dist/resources/extensions/gsd/prompts/workflow-start.md +2 -1
  189. package/dist/resources/extensions/gsd/provider-error-guidance.js +1 -5
  190. package/dist/resources/extensions/gsd/provider-payload-policy.js +83 -0
  191. package/dist/resources/extensions/gsd/provider-switch-observer.js +1 -1
  192. package/dist/resources/extensions/gsd/publication.js +87 -0
  193. package/dist/resources/extensions/gsd/pull-request-process.js +13 -0
  194. package/dist/resources/extensions/gsd/quality-gate-closure.js +109 -0
  195. package/dist/resources/extensions/gsd/question-transport.js +86 -0
  196. package/dist/resources/extensions/gsd/reactive-graph.js +8 -1
  197. package/dist/resources/extensions/gsd/recovery-classification.js +41 -87
  198. package/dist/resources/extensions/gsd/roadmap-slices.js +33 -5
  199. package/dist/resources/extensions/gsd/safety/destructive-confirmation.js +108 -0
  200. package/dist/resources/extensions/gsd/safety/evidence-collector.js +37 -4
  201. package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +7 -2
  202. package/dist/resources/extensions/gsd/safety/file-change-validator.js +10 -0
  203. package/dist/resources/extensions/gsd/session-lock.js +1 -1
  204. package/dist/resources/extensions/gsd/skill-activation.js +3 -6
  205. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +3 -2
  206. package/dist/resources/extensions/gsd/state-transition-matrix.js +38 -0
  207. package/dist/resources/extensions/gsd/state.js +24 -26
  208. package/dist/resources/extensions/gsd/status-guards.js +56 -8
  209. package/dist/resources/extensions/gsd/stop-notice.js +57 -0
  210. package/dist/resources/extensions/gsd/templates/plan.md +7 -0
  211. package/dist/resources/extensions/gsd/templates/project.md +1 -0
  212. package/dist/resources/extensions/gsd/templates/roadmap.md +1 -1
  213. package/dist/resources/extensions/gsd/templates/uat.md +5 -1
  214. package/dist/resources/extensions/gsd/tool-contract.js +66 -11
  215. package/dist/resources/extensions/gsd/tool-presentation-plan.js +17 -36
  216. package/dist/resources/extensions/gsd/tool-surface-readiness.js +108 -0
  217. package/dist/resources/extensions/gsd/tool-surface-snapshot.js +17 -0
  218. package/dist/resources/extensions/gsd/tools/complete-milestone.js +3 -2
  219. package/dist/resources/extensions/gsd/tools/complete-slice.js +46 -55
  220. package/dist/resources/extensions/gsd/tools/complete-task.js +65 -2
  221. package/dist/resources/extensions/gsd/tools/exec-tool.js +10 -8
  222. package/dist/resources/extensions/gsd/tools/plan-milestone.js +15 -143
  223. package/dist/resources/extensions/gsd/tools/plan-slice.js +14 -8
  224. package/dist/resources/extensions/gsd/tools/plan-task.js +2 -2
  225. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +41 -2
  226. package/dist/resources/extensions/gsd/tools/reopen-milestone.js +13 -31
  227. package/dist/resources/extensions/gsd/tools/reopen-slice.js +16 -35
  228. package/dist/resources/extensions/gsd/tools/reopen-task.js +2 -2
  229. package/dist/resources/extensions/gsd/tools/replan-slice.js +2 -2
  230. package/dist/resources/extensions/gsd/tools/skip-slice.js +18 -36
  231. package/dist/resources/extensions/gsd/tools/validate-milestone.js +15 -78
  232. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +67 -2
  233. package/dist/resources/extensions/gsd/uat-policy.js +57 -25
  234. package/dist/resources/extensions/gsd/uat-run.js +9 -14
  235. package/dist/resources/extensions/gsd/undo.js +8 -7
  236. package/dist/resources/extensions/gsd/unit-closeout.js +138 -0
  237. package/dist/resources/extensions/gsd/unit-context-composer.js +114 -21
  238. package/dist/resources/extensions/gsd/unit-context-manifest.js +4 -27
  239. package/dist/resources/extensions/gsd/unit-registry.js +367 -0
  240. package/dist/resources/extensions/gsd/unit-runtime.js +3 -2
  241. package/dist/resources/extensions/gsd/unit-tool-contracts.js +9 -181
  242. package/dist/resources/extensions/gsd/validation-block-guard.js +2 -0
  243. package/dist/resources/extensions/gsd/verdict-parser.js +1 -1
  244. package/dist/resources/extensions/gsd/verification-verdict.js +2 -1
  245. package/dist/resources/extensions/gsd/web-app-uat.js +117 -0
  246. package/dist/resources/extensions/gsd/workflow-event-ledger.js +91 -0
  247. package/dist/resources/extensions/gsd/workflow-event-vocabulary.js +46 -0
  248. package/dist/resources/extensions/gsd/workflow-events.js +6 -18
  249. package/dist/resources/extensions/gsd/workflow-mcp-auto-prep.js +2 -0
  250. package/dist/resources/extensions/gsd/workflow-mcp-readiness-cache.js +105 -0
  251. package/dist/resources/extensions/gsd/workflow-mcp.js +15 -102
  252. package/dist/resources/extensions/gsd/workflow-reconcile.js +25 -59
  253. package/dist/resources/extensions/gsd/workflow-tool-surface.js +46 -0
  254. package/dist/resources/extensions/gsd/workspace-git-guard.js +2 -0
  255. package/dist/resources/extensions/gsd/worktree-git-recovery.js +293 -0
  256. package/dist/resources/extensions/gsd/worktree-lifecycle.js +12 -3
  257. package/dist/resources/extensions/gsd/worktree-manager.js +52 -29
  258. package/dist/resources/extensions/gsd/worktree-placement.js +59 -0
  259. package/dist/resources/extensions/gsd/worktree-reentry.js +12 -8
  260. package/dist/resources/extensions/gsd/worktree-root.js +28 -6
  261. package/dist/resources/extensions/gsd/worktree-safety.js +36 -31
  262. package/dist/resources/extensions/gsd/worktree-session-state.js +12 -11
  263. package/dist/resources/extensions/gsd/worktree-state-projection.js +33 -4
  264. package/dist/resources/extensions/gsd/worktree-telemetry.js +12 -0
  265. package/dist/resources/extensions/gsd/worktree.js +8 -1
  266. package/dist/resources/extensions/mcp-client/manager.js +6 -1
  267. package/dist/resources/extensions/search-the-web/native-search.js +5 -3
  268. package/dist/resources/extensions/shared/browser-contract.js +59 -0
  269. package/dist/resources/extensions/shared/gsd-browser-cli.js +116 -6
  270. package/dist/resources/extensions/shared/interview-ui.js +2 -2
  271. package/dist/resources/shared/claude-runtime-floor.js +182 -0
  272. package/dist/resources/shared/gsd-browser-path-sync.js +214 -0
  273. package/dist/resources/shared/package-manager-detection.js +1 -1
  274. package/dist/resources/shared/package.json +3 -0
  275. package/dist/resources/skills/create-skill/SKILL.md +3 -0
  276. package/dist/resources/skills/create-skill/references/executable-code.md +1 -1
  277. package/dist/resources/skills/create-skill/references/skill-structure.md +1 -0
  278. package/dist/resources/skills/create-skill/workflows/add-reference.md +8 -3
  279. package/dist/resources/skills/create-skill/workflows/add-script.md +4 -2
  280. package/dist/resources/skills/create-skill/workflows/add-template.md +3 -1
  281. package/dist/resources/skills/create-skill/workflows/add-workflow.md +8 -3
  282. package/dist/resources/skills/create-skill/workflows/upgrade-to-router.md +10 -5
  283. package/dist/resources/skills/create-skill/workflows/verify-skill.md +9 -4
  284. package/dist/resources/skills/spike-wrap-up/SKILL.md +9 -9
  285. package/dist/runtime-checks.d.ts +10 -0
  286. package/dist/runtime-checks.js +27 -0
  287. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  288. package/dist/update-check.d.ts +2 -0
  289. package/dist/update-check.js +24 -1
  290. package/dist/update-cmd.js +40 -3
  291. package/dist/web/standalone/.next/BUILD_ID +1 -1
  292. package/dist/web/standalone/.next/app-path-routes-manifest.json +4 -4
  293. package/dist/web/standalone/.next/build-manifest.json +3 -3
  294. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  295. package/dist/web/standalone/.next/react-loadable-manifest.json +8 -8
  296. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  297. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  298. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  299. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  300. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  301. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  302. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  303. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  304. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  305. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  306. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  307. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  308. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  309. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  310. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  311. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  312. package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
  313. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
  314. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
  315. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
  316. package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
  317. package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
  318. package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
  319. package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
  320. package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  321. package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
  322. package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  323. package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
  324. package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
  325. package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
  326. package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
  327. package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
  328. package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js.nft.json +1 -1
  329. package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
  330. package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
  331. package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  332. package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
  333. package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
  334. package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
  335. package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
  336. package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
  337. package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
  338. package/dist/web/standalone/.next/server/app/api/shutdown/route.js.nft.json +1 -1
  339. package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
  340. package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
  341. package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
  342. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
  343. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
  344. package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
  345. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  346. package/dist/web/standalone/.next/server/app/api/update/route.js.nft.json +1 -1
  347. package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
  348. package/dist/web/standalone/.next/server/app/index.html +1 -1
  349. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  350. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  351. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  352. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  353. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  354. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  355. package/dist/web/standalone/.next/server/app-paths-manifest.json +4 -4
  356. package/dist/web/standalone/.next/server/chunks/5124.js +1 -1
  357. package/dist/web/standalone/.next/server/chunks/{5047.js → 5942.js} +2 -2
  358. package/dist/web/standalone/.next/server/chunks/8357.js +2 -2
  359. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  360. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  361. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  362. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  363. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  364. package/dist/web/standalone/.next/static/chunks/2659.b7b129ee6a769448.js +1 -0
  365. package/dist/web/standalone/.next/static/chunks/2772.bfa657f49f955239.js +1 -0
  366. package/dist/web/standalone/.next/static/chunks/{3616.4113d484a994e411.js → 3616.3c60753b8ffcbd2e.js} +1 -1
  367. package/dist/web/standalone/.next/static/chunks/4283.e4873b058df143a1.js +2 -0
  368. package/dist/web/standalone/.next/static/chunks/5826.a46ecdd1cfe8dabc.js +1 -0
  369. package/dist/web/standalone/.next/static/chunks/796.e0bdc932325d7e03.js +10 -0
  370. package/dist/web/standalone/.next/static/chunks/8785.2e5a118797fb2dd2.js +1 -0
  371. package/dist/web/standalone/.next/static/chunks/{webpack-dda80a1ef5587410.js → webpack-f0285ce91d4ec9ef.js} +1 -1
  372. package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
  373. package/dist/web/standalone/package.json +1 -1
  374. package/dist/web-mode.d.ts +2 -0
  375. package/dist/web-mode.js +20 -8
  376. package/dist/worktree-cli.js +3 -6
  377. package/dist/worktree-status-banner.js +7 -11
  378. package/package.json +4 -3
  379. package/packages/cloud-mcp-gateway/package.json +2 -2
  380. package/packages/contracts/dist/rpc.d.ts +1 -0
  381. package/packages/contracts/dist/rpc.d.ts.map +1 -1
  382. package/packages/contracts/dist/rpc.js.map +1 -1
  383. package/packages/contracts/dist/workflow.d.ts +4 -0
  384. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  385. package/packages/contracts/dist/workflow.js.map +1 -1
  386. package/packages/contracts/package.json +1 -1
  387. package/packages/daemon/package.json +4 -4
  388. package/packages/gsd-agent-core/dist/sdk.d.ts.map +1 -1
  389. package/packages/gsd-agent-core/dist/sdk.js +6 -4
  390. package/packages/gsd-agent-core/dist/sdk.js.map +1 -1
  391. package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts +2 -0
  392. package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts.map +1 -1
  393. package/packages/gsd-agent-core/dist/session/agent-session-extensions.js +14 -0
  394. package/packages/gsd-agent-core/dist/session/agent-session-extensions.js.map +1 -1
  395. package/packages/gsd-agent-core/package.json +5 -5
  396. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts +2 -0
  397. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  398. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js +10 -0
  399. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js.map +1 -1
  400. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +13 -0
  401. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  402. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +58 -6
  403. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  404. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts +2 -0
  405. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts.map +1 -1
  406. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js +34 -5
  407. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js.map +1 -1
  408. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  409. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +113 -40
  410. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  411. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
  412. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js +8 -1
  413. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  414. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.d.ts.map +1 -1
  415. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js +11 -1
  416. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js.map +1 -1
  417. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.d.ts.map +1 -1
  418. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.js +6 -0
  419. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.js.map +1 -1
  420. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts +1 -0
  421. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  422. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +12 -0
  423. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
  424. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.d.ts.map +1 -1
  425. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js +4 -4
  426. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js.map +1 -1
  427. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.d.ts.map +1 -1
  428. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js +4 -0
  429. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js.map +1 -1
  430. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  431. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +3 -1
  432. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -1
  433. package/packages/gsd-agent-modes/package.json +7 -7
  434. package/packages/mcp-server/README.md +12 -3
  435. package/packages/mcp-server/dist/cli-runner.d.ts +40 -0
  436. package/packages/mcp-server/dist/cli-runner.d.ts.map +1 -0
  437. package/packages/mcp-server/dist/cli-runner.js +137 -0
  438. package/packages/mcp-server/dist/cli-runner.js.map +1 -0
  439. package/packages/mcp-server/dist/cli.js +2 -50
  440. package/packages/mcp-server/dist/cli.js.map +1 -1
  441. package/packages/mcp-server/dist/moonshot-tool-schema.d.ts +29 -0
  442. package/packages/mcp-server/dist/moonshot-tool-schema.d.ts.map +1 -0
  443. package/packages/mcp-server/dist/moonshot-tool-schema.js +50 -0
  444. package/packages/mcp-server/dist/moonshot-tool-schema.js.map +1 -0
  445. package/packages/mcp-server/dist/pid-registry.d.ts +46 -0
  446. package/packages/mcp-server/dist/pid-registry.d.ts.map +1 -0
  447. package/packages/mcp-server/dist/pid-registry.js +452 -0
  448. package/packages/mcp-server/dist/pid-registry.js.map +1 -0
  449. package/packages/mcp-server/dist/probe-mode.d.ts +4 -0
  450. package/packages/mcp-server/dist/probe-mode.d.ts.map +1 -0
  451. package/packages/mcp-server/dist/probe-mode.js +10 -0
  452. package/packages/mcp-server/dist/probe-mode.js.map +1 -0
  453. package/packages/mcp-server/dist/server.d.ts +10 -0
  454. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  455. package/packages/mcp-server/dist/server.js +12 -0
  456. package/packages/mcp-server/dist/server.js.map +1 -1
  457. package/packages/mcp-server/dist/stdio-watchdog.d.ts +8 -0
  458. package/packages/mcp-server/dist/stdio-watchdog.d.ts.map +1 -0
  459. package/packages/mcp-server/dist/stdio-watchdog.js +40 -0
  460. package/packages/mcp-server/dist/stdio-watchdog.js.map +1 -0
  461. package/packages/mcp-server/dist/workflow-tools.d.ts +49 -0
  462. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  463. package/packages/mcp-server/dist/workflow-tools.js +209 -103
  464. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  465. package/packages/mcp-server/package.json +5 -4
  466. package/packages/native/package.json +1 -1
  467. package/packages/pi-agent-core/dist/agent-loop.js +43 -2
  468. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  469. package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts +1 -0
  470. package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts.map +1 -1
  471. package/packages/pi-agent-core/dist/harness/env/nodejs.js +34 -3
  472. package/packages/pi-agent-core/dist/harness/env/nodejs.js.map +1 -1
  473. package/packages/pi-agent-core/dist/index.d.ts +1 -0
  474. package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
  475. package/packages/pi-agent-core/dist/index.js +3 -0
  476. package/packages/pi-agent-core/dist/index.js.map +1 -1
  477. package/packages/pi-agent-core/package.json +1 -1
  478. package/packages/pi-ai/README.md +1 -0
  479. package/packages/pi-ai/dist/index.d.ts +2 -0
  480. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  481. package/packages/pi-ai/dist/index.js +2 -0
  482. package/packages/pi-ai/dist/index.js.map +1 -1
  483. package/packages/pi-ai/dist/models.generated.d.ts +183 -76
  484. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  485. package/packages/pi-ai/dist/models.generated.js +193 -112
  486. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  487. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  488. package/packages/pi-ai/dist/providers/anthropic.js +12 -7
  489. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  490. package/packages/pi-ai/dist/providers/google-shared.d.ts +5 -0
  491. package/packages/pi-ai/dist/providers/google-shared.d.ts.map +1 -1
  492. package/packages/pi-ai/dist/providers/google-shared.js +12 -3
  493. package/packages/pi-ai/dist/providers/google-shared.js.map +1 -1
  494. package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
  495. package/packages/pi-ai/dist/providers/openai-completions.js +7 -3
  496. package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
  497. package/packages/pi-ai/dist/utils/moonshot-tool-schema.d.ts +9 -0
  498. package/packages/pi-ai/dist/utils/moonshot-tool-schema.d.ts.map +1 -0
  499. package/packages/pi-ai/dist/utils/moonshot-tool-schema.js +34 -0
  500. package/packages/pi-ai/dist/utils/moonshot-tool-schema.js.map +1 -0
  501. package/packages/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
  502. package/packages/pi-ai/dist/utils/oauth/github-copilot.js +6 -2
  503. package/packages/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
  504. package/packages/pi-ai/package.json +3 -2
  505. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +2 -2
  506. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  507. package/packages/pi-coding-agent/dist/core/auth-storage.js +19 -13
  508. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  509. package/packages/pi-coding-agent/dist/core/capability-patches.d.ts.map +1 -1
  510. package/packages/pi-coding-agent/dist/core/capability-patches.js +3 -1
  511. package/packages/pi-coding-agent/dist/core/capability-patches.js.map +1 -1
  512. package/packages/pi-coding-agent/dist/core/provider-readiness.d.ts.map +1 -1
  513. package/packages/pi-coding-agent/dist/core/provider-readiness.js +13 -6
  514. package/packages/pi-coding-agent/dist/core/provider-readiness.js.map +1 -1
  515. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +3 -0
  516. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  517. package/packages/pi-coding-agent/dist/core/settings-manager.js +11 -0
  518. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  519. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts +11 -0
  520. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
  521. package/packages/pi-coding-agent/dist/core/tools/bash.js +53 -11
  522. package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
  523. package/packages/pi-coding-agent/dist/index.d.ts +1 -1
  524. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  525. package/packages/pi-coding-agent/dist/index.js +1 -1
  526. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  527. package/packages/pi-coding-agent/dist/theme/theme.d.ts.map +1 -1
  528. package/packages/pi-coding-agent/dist/theme/theme.js +45 -17
  529. package/packages/pi-coding-agent/dist/theme/theme.js.map +1 -1
  530. package/packages/pi-coding-agent/dist/utils/shell.d.ts +28 -2
  531. package/packages/pi-coding-agent/dist/utils/shell.d.ts.map +1 -1
  532. package/packages/pi-coding-agent/dist/utils/shell.js +56 -10
  533. package/packages/pi-coding-agent/dist/utils/shell.js.map +1 -1
  534. package/packages/pi-coding-agent/package.json +7 -7
  535. package/packages/pi-tui/dist/components/input.js +1 -1
  536. package/packages/pi-tui/dist/components/input.js.map +1 -1
  537. package/packages/pi-tui/dist/index.d.ts +1 -1
  538. package/packages/pi-tui/dist/index.d.ts.map +1 -1
  539. package/packages/pi-tui/dist/index.js +1 -1
  540. package/packages/pi-tui/dist/index.js.map +1 -1
  541. package/packages/pi-tui/dist/keys.d.ts.map +1 -1
  542. package/packages/pi-tui/dist/keys.js +39 -30
  543. package/packages/pi-tui/dist/keys.js.map +1 -1
  544. package/packages/pi-tui/dist/stdin-buffer.d.ts.map +1 -1
  545. package/packages/pi-tui/dist/stdin-buffer.js +22 -0
  546. package/packages/pi-tui/dist/stdin-buffer.js.map +1 -1
  547. package/packages/pi-tui/dist/terminal-image.d.ts +33 -0
  548. package/packages/pi-tui/dist/terminal-image.d.ts.map +1 -1
  549. package/packages/pi-tui/dist/terminal-image.js +54 -2
  550. package/packages/pi-tui/dist/terminal-image.js.map +1 -1
  551. package/packages/pi-tui/dist/tui.d.ts +8 -0
  552. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  553. package/packages/pi-tui/dist/tui.js +72 -18
  554. package/packages/pi-tui/dist/tui.js.map +1 -1
  555. package/packages/pi-tui/dist/utils.d.ts.map +1 -1
  556. package/packages/pi-tui/dist/utils.js +110 -36
  557. package/packages/pi-tui/dist/utils.js.map +1 -1
  558. package/packages/pi-tui/package.json +2 -2
  559. package/packages/rpc-client/package.json +2 -2
  560. package/pkg/dist/theme/theme.d.ts.map +1 -1
  561. package/pkg/dist/theme/theme.js +45 -17
  562. package/pkg/dist/theme/theme.js.map +1 -1
  563. package/pkg/package.json +1 -1
  564. package/src/resources/GSD-WORKFLOW.md +5 -4
  565. package/src/resources/extensions/ask-user-questions.ts +94 -26
  566. package/src/resources/extensions/async-jobs/async-bash-cancel.test.ts +360 -0
  567. package/src/resources/extensions/async-jobs/async-bash-tool.ts +33 -56
  568. package/src/resources/extensions/async-jobs/await-tool.test.ts +139 -0
  569. package/src/resources/extensions/async-jobs/await-tool.ts +82 -12
  570. package/src/resources/extensions/async-jobs/index.ts +79 -0
  571. package/src/resources/extensions/async-jobs/job-manager.ts +21 -1
  572. package/src/resources/extensions/bg-shell/bg-shell-command.ts +6 -6
  573. package/src/resources/extensions/bg-shell/bg-shell-tool.ts +10 -6
  574. package/src/resources/extensions/bg-shell/overlay.ts +9 -5
  575. package/src/resources/extensions/bg-shell/process-manager.ts +50 -25
  576. package/src/resources/extensions/bg-shell/readiness-detector.ts +12 -0
  577. package/src/resources/extensions/bg-shell/tests/lifecycle-and-utilities.test.ts +48 -1
  578. package/src/resources/extensions/bg-shell/utilities.ts +5 -2
  579. package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +265 -98
  580. package/src/resources/extensions/browser-tools/engine/selection.ts +90 -4
  581. package/src/resources/extensions/browser-tools/index.ts +71 -13
  582. package/src/resources/extensions/browser-tools/tests/browser-engine-selection.test.mjs +83 -13
  583. package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +40 -1
  584. package/src/resources/extensions/browser-tools/tests/managed-gsd-browser-tools.test.mjs +136 -0
  585. package/src/resources/extensions/claude-code-cli/models.ts +9 -0
  586. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +651 -483
  587. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +940 -7
  588. package/src/resources/extensions/claude-code-cli/turn-assembler.ts +324 -0
  589. package/src/resources/extensions/github-sync/templates.ts +3 -3
  590. package/src/resources/extensions/github-sync/tests/templates.test.ts +2 -2
  591. package/src/resources/extensions/gsd/artifact-projection.ts +31 -0
  592. package/src/resources/extensions/gsd/auto/closeout.ts +309 -0
  593. package/src/resources/extensions/gsd/auto/contracts.ts +32 -2
  594. package/src/resources/extensions/gsd/auto/custom-verify-retry-store.ts +21 -3
  595. package/src/resources/extensions/gsd/auto/detect-stuck.ts +32 -9
  596. package/src/resources/extensions/gsd/auto/dispatch-history.ts +168 -0
  597. package/src/resources/extensions/gsd/auto/dispatch-key.ts +39 -0
  598. package/src/resources/extensions/gsd/auto/dispatch.ts +449 -0
  599. package/src/resources/extensions/gsd/auto/finalize.ts +445 -0
  600. package/src/resources/extensions/gsd/auto/loop-deps.ts +3 -1
  601. package/src/resources/extensions/gsd/auto/loop.ts +89 -61
  602. package/src/resources/extensions/gsd/auto/milestone-lease-reclaim.ts +74 -0
  603. package/src/resources/extensions/gsd/auto/orchestrator.ts +350 -81
  604. package/src/resources/extensions/gsd/auto/phase-helpers.ts +199 -0
  605. package/src/resources/extensions/gsd/auto/phases.ts +58 -2981
  606. package/src/resources/extensions/gsd/auto/pre-dispatch.ts +704 -0
  607. package/src/resources/extensions/gsd/auto/run-unit.ts +2 -1
  608. package/src/resources/extensions/gsd/auto/session.ts +7 -0
  609. package/src/resources/extensions/gsd/auto/unit-phase.ts +910 -0
  610. package/src/resources/extensions/gsd/auto/workflow-unit-dispatch.ts +1 -1
  611. package/src/resources/extensions/gsd/auto/worktree-safety-phase.ts +149 -0
  612. package/src/resources/extensions/gsd/auto-dashboard.ts +18 -4
  613. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +18 -48
  614. package/src/resources/extensions/gsd/auto-dispatch.ts +68 -68
  615. package/src/resources/extensions/gsd/auto-model-selection.ts +49 -12
  616. package/src/resources/extensions/gsd/auto-post-unit.ts +56 -16
  617. package/src/resources/extensions/gsd/auto-prompts.ts +225 -44
  618. package/src/resources/extensions/gsd/auto-recovery.ts +50 -50
  619. package/src/resources/extensions/gsd/auto-runtime-state.ts +26 -0
  620. package/src/resources/extensions/gsd/auto-start.ts +65 -53
  621. package/src/resources/extensions/gsd/auto-timers.ts +16 -2
  622. package/src/resources/extensions/gsd/auto-tool-tracking.ts +54 -0
  623. package/src/resources/extensions/gsd/auto-unit-closeout.ts +83 -28
  624. package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +21 -49
  625. package/src/resources/extensions/gsd/auto-verification.ts +33 -36
  626. package/src/resources/extensions/gsd/auto-worktree-repair.ts +13 -2
  627. package/src/resources/extensions/gsd/auto-worktree.ts +83 -386
  628. package/src/resources/extensions/gsd/auto.ts +99 -34
  629. package/src/resources/extensions/gsd/blocked-models.ts +49 -0
  630. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +37 -10
  631. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +29 -37
  632. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +93 -49
  633. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +2 -2
  634. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +2 -2
  635. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +24 -0
  636. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +375 -177
  637. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +452 -58
  638. package/src/resources/extensions/gsd/branch-patterns.ts +3 -0
  639. package/src/resources/extensions/gsd/browser-daemon-auto-prep.ts +108 -0
  640. package/src/resources/extensions/gsd/browser-evidence.ts +18 -2
  641. package/src/resources/extensions/gsd/captures.ts +5 -16
  642. package/src/resources/extensions/gsd/closeout-consistency-gate.ts +27 -5
  643. package/src/resources/extensions/gsd/closeout-recovery.ts +2 -1
  644. package/src/resources/extensions/gsd/closeout-wizard.ts +102 -0
  645. package/src/resources/extensions/gsd/codebase-generator.ts +9 -5
  646. package/src/resources/extensions/gsd/commands/catalog.ts +6 -68
  647. package/src/resources/extensions/gsd/commands/context.ts +16 -2
  648. package/src/resources/extensions/gsd/commands/handlers/auto.ts +3 -0
  649. package/src/resources/extensions/gsd/commands-handlers.ts +64 -3
  650. package/src/resources/extensions/gsd/commands-inspect.ts +7 -8
  651. package/src/resources/extensions/gsd/commands-maintenance.ts +74 -40
  652. package/src/resources/extensions/gsd/commands-mcp-status.ts +2 -2
  653. package/src/resources/extensions/gsd/commands-ship.ts +2 -2
  654. package/src/resources/extensions/gsd/commands-verdict.ts +19 -2
  655. package/src/resources/extensions/gsd/commands-workflow-templates.ts +11 -4
  656. package/src/resources/extensions/gsd/consent-question.ts +431 -0
  657. package/src/resources/extensions/gsd/consent-verdict.ts +86 -0
  658. package/src/resources/extensions/gsd/constants.ts +0 -3
  659. package/src/resources/extensions/gsd/crash-recovery.ts +13 -11
  660. package/src/resources/extensions/gsd/db/engine.ts +811 -0
  661. package/src/resources/extensions/gsd/db/queries.ts +519 -0
  662. package/src/resources/extensions/gsd/db/sql-constants.ts +12 -0
  663. package/src/resources/extensions/gsd/db/writers/cascades.ts +237 -0
  664. package/src/resources/extensions/gsd/db/writers/import-restore.ts +310 -0
  665. package/src/resources/extensions/gsd/db/writers/memory.ts +220 -0
  666. package/src/resources/extensions/gsd/db/writers/reconcile.ts +500 -0
  667. package/src/resources/extensions/gsd/db/writers/status.ts +88 -0
  668. package/src/resources/extensions/gsd/db-workspace.ts +170 -0
  669. package/src/resources/extensions/gsd/db-writer.ts +11 -19
  670. package/src/resources/extensions/gsd/delegation-policy.ts +3 -11
  671. package/src/resources/extensions/gsd/discussion-handoff.ts +276 -0
  672. package/src/resources/extensions/gsd/dispatch-guard.ts +8 -31
  673. package/src/resources/extensions/gsd/docs/preferences-reference.md +9 -0
  674. package/src/resources/extensions/gsd/doctor-engine-checks.ts +5 -4
  675. package/src/resources/extensions/gsd/doctor-environment.ts +272 -155
  676. package/src/resources/extensions/gsd/doctor-format.ts +12 -7
  677. package/src/resources/extensions/gsd/doctor-git-checks.ts +5 -22
  678. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +22 -17
  679. package/src/resources/extensions/gsd/doctor.ts +15 -5
  680. package/src/resources/extensions/gsd/engine-hook-contract.ts +79 -0
  681. package/src/resources/extensions/gsd/error-classifier.ts +12 -1
  682. package/src/resources/extensions/gsd/exec-sandbox.ts +49 -9
  683. package/src/resources/extensions/gsd/files.ts +33 -12
  684. package/src/resources/extensions/gsd/git-conflict-state.ts +17 -1
  685. package/src/resources/extensions/gsd/git-service.ts +1 -0
  686. package/src/resources/extensions/gsd/gitignore.ts +3 -0
  687. package/src/resources/extensions/gsd/gsd-command-home.ts +13 -3
  688. package/src/resources/extensions/gsd/gsd-db.ts +190 -2375
  689. package/src/resources/extensions/gsd/guidance.ts +217 -0
  690. package/src/resources/extensions/gsd/guided-flow.ts +240 -585
  691. package/src/resources/extensions/gsd/guided-unit-completion.ts +275 -0
  692. package/src/resources/extensions/gsd/health-widget.ts +91 -27
  693. package/src/resources/extensions/gsd/markdown-renderer.ts +13 -1
  694. package/src/resources/extensions/gsd/mcp-bridge.ts +39 -0
  695. package/src/resources/extensions/gsd/mcp-filter.ts +4 -24
  696. package/src/resources/extensions/gsd/mcp-tool-name.ts +30 -0
  697. package/src/resources/extensions/gsd/md-importer.ts +3 -3
  698. package/src/resources/extensions/gsd/memory-consolidation-scanner.ts +1 -1
  699. package/src/resources/extensions/gsd/memory-relations.ts +1 -1
  700. package/src/resources/extensions/gsd/migrate/safety.ts +20 -9
  701. package/src/resources/extensions/gsd/migration-auto-check.ts +30 -5
  702. package/src/resources/extensions/gsd/milestone-closeout-proof.ts +131 -0
  703. package/src/resources/extensions/gsd/milestone-closeout.ts +121 -28
  704. package/src/resources/extensions/gsd/milestone-merge-transaction.ts +47 -0
  705. package/src/resources/extensions/gsd/milestone-planning-persistence.ts +224 -0
  706. package/src/resources/extensions/gsd/milestone-readiness.ts +125 -0
  707. package/src/resources/extensions/gsd/milestone-reopen-events.ts +3 -6
  708. package/src/resources/extensions/gsd/milestone-settlement.ts +81 -0
  709. package/src/resources/extensions/gsd/milestone-validation-evidence.ts +95 -0
  710. package/src/resources/extensions/gsd/milestone-validation-verdict.ts +80 -0
  711. package/src/resources/extensions/gsd/model-cost-table.ts +1 -0
  712. package/src/resources/extensions/gsd/model-router.ts +3 -0
  713. package/src/resources/extensions/gsd/notification-store.ts +26 -3
  714. package/src/resources/extensions/gsd/notifications.ts +13 -6
  715. package/src/resources/extensions/gsd/parallel-eligibility.ts +4 -5
  716. package/src/resources/extensions/gsd/parallel-merge.ts +12 -9
  717. package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +10 -7
  718. package/src/resources/extensions/gsd/parallel-orchestrator.ts +6 -2
  719. package/src/resources/extensions/gsd/parsers-legacy.ts +16 -4
  720. package/src/resources/extensions/gsd/paths.ts +42 -22
  721. package/src/resources/extensions/gsd/pre-execution-checks.ts +109 -3
  722. package/src/resources/extensions/gsd/preferences-diagnostics.ts +98 -0
  723. package/src/resources/extensions/gsd/preferences-models.ts +12 -47
  724. package/src/resources/extensions/gsd/preferences-types.ts +16 -0
  725. package/src/resources/extensions/gsd/preferences.ts +191 -28
  726. package/src/resources/extensions/gsd/projection-flush.ts +20 -0
  727. package/src/resources/extensions/gsd/prompts/complete-slice.md +5 -4
  728. package/src/resources/extensions/gsd/prompts/execute-task.md +5 -2
  729. package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +3 -1
  730. package/src/resources/extensions/gsd/prompts/plan-milestone.md +3 -1
  731. package/src/resources/extensions/gsd/prompts/plan-slice.md +3 -2
  732. package/src/resources/extensions/gsd/prompts/quick-task.md +1 -1
  733. package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
  734. package/src/resources/extensions/gsd/prompts/refine-slice.md +3 -2
  735. package/src/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  736. package/src/resources/extensions/gsd/prompts/research-milestone.md +1 -1
  737. package/src/resources/extensions/gsd/prompts/research-slice.md +1 -1
  738. package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  739. package/src/resources/extensions/gsd/prompts/run-uat.md +9 -5
  740. package/src/resources/extensions/gsd/prompts/system.md +6 -3
  741. package/src/resources/extensions/gsd/prompts/triage-captures.md +1 -1
  742. package/src/resources/extensions/gsd/prompts/validate-milestone.md +1 -1
  743. package/src/resources/extensions/gsd/prompts/workflow-start.md +2 -1
  744. package/src/resources/extensions/gsd/provider-error-guidance.ts +4 -9
  745. package/src/resources/extensions/gsd/provider-payload-policy.ts +140 -0
  746. package/src/resources/extensions/gsd/provider-switch-observer.ts +1 -1
  747. package/src/resources/extensions/gsd/publication.ts +122 -0
  748. package/src/resources/extensions/gsd/pull-request-process.ts +41 -0
  749. package/src/resources/extensions/gsd/quality-gate-closure.ts +140 -0
  750. package/src/resources/extensions/gsd/question-transport.ts +138 -0
  751. package/src/resources/extensions/gsd/reactive-graph.ts +11 -1
  752. package/src/resources/extensions/gsd/recovery-classification.ts +47 -88
  753. package/src/resources/extensions/gsd/roadmap-slices.ts +36 -5
  754. package/src/resources/extensions/gsd/safety/destructive-confirmation.ts +134 -0
  755. package/src/resources/extensions/gsd/safety/evidence-collector.ts +36 -4
  756. package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +7 -2
  757. package/src/resources/extensions/gsd/safety/file-change-validator.ts +14 -0
  758. package/src/resources/extensions/gsd/session-lock.ts +1 -1
  759. package/src/resources/extensions/gsd/skill-activation.ts +3 -6
  760. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +6 -2
  761. package/src/resources/extensions/gsd/state-transition-matrix.ts +42 -0
  762. package/src/resources/extensions/gsd/state.ts +31 -27
  763. package/src/resources/extensions/gsd/status-guards.ts +59 -8
  764. package/src/resources/extensions/gsd/stop-notice.ts +75 -0
  765. package/src/resources/extensions/gsd/templates/plan.md +7 -0
  766. package/src/resources/extensions/gsd/templates/project.md +1 -0
  767. package/src/resources/extensions/gsd/templates/roadmap.md +1 -1
  768. package/src/resources/extensions/gsd/templates/uat.md +5 -1
  769. package/src/resources/extensions/gsd/tests/ask-user-questions-render.test.ts +92 -0
  770. package/src/resources/extensions/gsd/tests/auto-abort-pause-regression.test.ts +1 -1
  771. package/src/resources/extensions/gsd/tests/auto-blocked-remediation-message.test.ts +1 -1
  772. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +29 -1
  773. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +649 -26
  774. package/src/resources/extensions/gsd/tests/auto-milestone-target.test.ts +23 -0
  775. package/src/resources/extensions/gsd/tests/auto-model-selection-tool-poisoning.test.ts +18 -0
  776. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +97 -1
  777. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +395 -30
  778. package/src/resources/extensions/gsd/tests/auto-pause-double-entry-guard.test.ts +1 -1
  779. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +80 -2
  780. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +2 -1
  781. package/src/resources/extensions/gsd/tests/auto-post-unit-evidence-crossref-4909.test.ts +46 -0
  782. package/src/resources/extensions/gsd/tests/auto-remote-session-lock-cleanup.test.ts +65 -3
  783. package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +34 -0
  784. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +236 -0
  785. package/src/resources/extensions/gsd/tests/auto-unit-closeout.test.ts +169 -1
  786. package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +2 -2
  787. package/src/resources/extensions/gsd/tests/auto-worktree-repair.test.ts +4 -2
  788. package/src/resources/extensions/gsd/tests/blocked-models.test.ts +19 -0
  789. package/src/resources/extensions/gsd/tests/browser-automation-contract-fixture.ts +39 -0
  790. package/src/resources/extensions/gsd/tests/browser-contract.test.ts +44 -0
  791. package/src/resources/extensions/gsd/tests/browser-daemon-auto-prep.test.ts +144 -0
  792. package/src/resources/extensions/gsd/tests/canonical-milestone-root.test.ts +20 -0
  793. package/src/resources/extensions/gsd/tests/checkout-branch-stash-guard.test.ts +66 -1
  794. package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +44 -0
  795. package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +22 -0
  796. package/src/resources/extensions/gsd/tests/commands-dispatcher-workspace-git.test.ts +11 -0
  797. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +46 -8
  798. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +42 -0
  799. package/src/resources/extensions/gsd/tests/complete-task.test.ts +141 -5
  800. package/src/resources/extensions/gsd/tests/consent-question.test.ts +351 -0
  801. package/src/resources/extensions/gsd/tests/custom-verify-retry-store.test.ts +67 -0
  802. package/src/resources/extensions/gsd/tests/db-writer.test.ts +15 -4
  803. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +12 -11
  804. package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +36 -0
  805. package/src/resources/extensions/gsd/tests/destructive-confirmation.test.ts +303 -0
  806. package/src/resources/extensions/gsd/tests/discuss-routing-fixes.test.ts +12 -2
  807. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +34 -3
  808. package/src/resources/extensions/gsd/tests/dispatch-history.test.ts +328 -0
  809. package/src/resources/extensions/gsd/tests/dispatch-run-uat-browser-tools.test.ts +89 -0
  810. package/src/resources/extensions/gsd/tests/dist-redirect.mjs +8 -0
  811. package/src/resources/extensions/gsd/tests/doctor-git-checks-terminal.test.ts +73 -0
  812. package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +18 -0
  813. package/src/resources/extensions/gsd/tests/dynamic-bash-no-cap.test.ts +132 -0
  814. package/src/resources/extensions/gsd/tests/engine-hook-contract.test.ts +148 -0
  815. package/src/resources/extensions/gsd/tests/engine-interfaces-contract.test.ts +117 -91
  816. package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +113 -0
  817. package/src/resources/extensions/gsd/tests/evidence-xref-gsd-exec.test.ts +157 -0
  818. package/src/resources/extensions/gsd/tests/exec-graceful-kill.test.ts +193 -0
  819. package/src/resources/extensions/gsd/tests/exec-tool.test.ts +29 -1
  820. package/src/resources/extensions/gsd/tests/execute-task-rendering.test.ts +1 -0
  821. package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +35 -1
  822. package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +33 -1
  823. package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-no-blockers.md +1 -5
  824. package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-with-blockers.md +1 -5
  825. package/src/resources/extensions/gsd/tests/gate-state-canonicalization.test.ts +48 -1
  826. package/src/resources/extensions/gsd/tests/gsd-command-home.test.ts +120 -0
  827. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +27 -0
  828. package/src/resources/extensions/gsd/tests/guidance.test.ts +148 -0
  829. package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +18 -6
  830. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +58 -15
  831. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +89 -59
  832. package/src/resources/extensions/gsd/tests/integration/doctor-environment-async.test.ts +104 -0
  833. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +3 -2
  834. package/src/resources/extensions/gsd/tests/integration/gsd-integration-fixture.ts +80 -0
  835. package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +217 -0
  836. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +47 -16
  837. package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +3 -1
  838. package/src/resources/extensions/gsd/tests/mcp-readiness-preflight.test.ts +205 -0
  839. package/src/resources/extensions/gsd/tests/mcp-status.test.ts +6 -5
  840. package/src/resources/extensions/gsd/tests/mcp-tool-name.test.ts +34 -0
  841. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +143 -1
  842. package/src/resources/extensions/gsd/tests/milestone-closeout-proof.test.ts +99 -0
  843. package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +120 -4
  844. package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +1 -1
  845. package/src/resources/extensions/gsd/tests/milestone-merge-transaction.test.ts +46 -0
  846. package/src/resources/extensions/gsd/tests/milestone-readiness.test.ts +65 -0
  847. package/src/resources/extensions/gsd/tests/milestone-report-path.test.ts +1 -1
  848. package/src/resources/extensions/gsd/tests/milestone-settlement.test.ts +92 -0
  849. package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +1 -1
  850. package/src/resources/extensions/gsd/tests/milestone-validation-evidence.test.ts +41 -0
  851. package/src/resources/extensions/gsd/tests/milestone-validation-verdict.test.ts +55 -0
  852. package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +32 -1
  853. package/src/resources/extensions/gsd/tests/notification-store.test.ts +32 -0
  854. package/src/resources/extensions/gsd/tests/notifications.test.ts +64 -9
  855. package/src/resources/extensions/gsd/tests/oauth-api-model-routing.test.ts +167 -0
  856. package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +18 -0
  857. package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +2 -2
  858. package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +143 -0
  859. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +1 -1
  860. package/src/resources/extensions/gsd/tests/phases-terminal-complete-idempotent.test.ts +242 -0
  861. package/src/resources/extensions/gsd/tests/plan-gate-failed-doctor-heal-hint.test.ts +3 -3
  862. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +45 -0
  863. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +2 -0
  864. package/src/resources/extensions/gsd/tests/planning-crossval.test.ts +45 -0
  865. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +63 -2
  866. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +193 -1
  867. package/src/resources/extensions/gsd/tests/preferences-diagnostics.test.ts +67 -0
  868. package/src/resources/extensions/gsd/tests/preferences.test.ts +183 -0
  869. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +56 -2
  870. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +124 -6
  871. package/src/resources/extensions/gsd/tests/provider-error-guidance.test.ts +3 -3
  872. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +11 -4
  873. package/src/resources/extensions/gsd/tests/provider-payload-policy.test.ts +165 -0
  874. package/src/resources/extensions/gsd/tests/publication.test.ts +120 -0
  875. package/src/resources/extensions/gsd/tests/pull-request-process.test.ts +47 -0
  876. package/src/resources/extensions/gsd/tests/recovery-classification-illegal-transition.test.ts +30 -0
  877. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +342 -1
  878. package/src/resources/extensions/gsd/tests/remote-notification-from-desktop.test.ts +31 -81
  879. package/src/resources/extensions/gsd/tests/roadmap-parse-regression.test.ts +40 -0
  880. package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +68 -0
  881. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +51 -2
  882. package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +38 -0
  883. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +80 -0
  884. package/src/resources/extensions/gsd/tests/session-switch-clears-pending-autostart.test.ts +108 -0
  885. package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +300 -41
  886. package/src/resources/extensions/gsd/tests/skill-activation.test.ts +20 -17
  887. package/src/resources/extensions/gsd/tests/stale-queued-milestone.test.ts +27 -0
  888. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +9 -4
  889. package/src/resources/extensions/gsd/tests/state-transition-matrix.test.ts +36 -0
  890. package/src/resources/extensions/gsd/tests/status-guards.test.ts +38 -0
  891. package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +1 -1
  892. package/src/resources/extensions/gsd/tests/stop-notice.test.ts +70 -0
  893. package/src/resources/extensions/gsd/tests/teardown-chdir-failure-clears-registry.test.ts +17 -0
  894. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +80 -2
  895. package/src/resources/extensions/gsd/tests/tool-availability-audit.test.ts +35 -0
  896. package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +8 -0
  897. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +35 -42
  898. package/src/resources/extensions/gsd/tests/tool-surface-readiness.test.ts +329 -0
  899. package/src/resources/extensions/gsd/tests/tool-unavailable-retry.test.ts +33 -0
  900. package/src/resources/extensions/gsd/tests/transport-gate-double-complete.test.ts +139 -0
  901. package/src/resources/extensions/gsd/tests/uat-policy.test.ts +112 -6
  902. package/src/resources/extensions/gsd/tests/unit-closeout.test.ts +209 -0
  903. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +114 -2
  904. package/src/resources/extensions/gsd/tests/unit-registry.test.ts +163 -0
  905. package/src/resources/extensions/gsd/tests/uok-audit-unified.test.ts +8 -0
  906. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +1 -1
  907. package/src/resources/extensions/gsd/tests/validate-milestone-stuck-guard.test.ts +39 -0
  908. package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +2 -0
  909. package/src/resources/extensions/gsd/tests/web-app-uat.test.ts +193 -0
  910. package/src/resources/extensions/gsd/tests/workflow-events.test.ts +19 -0
  911. package/src/resources/extensions/gsd/tests/workflow-mcp-readiness-cache.test.ts +119 -0
  912. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +193 -13
  913. package/src/resources/extensions/gsd/tests/workflow-phase-contract-matrix.test.ts +332 -0
  914. package/src/resources/extensions/gsd/tests/workflow-reconcile.test.ts +20 -0
  915. package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +92 -0
  916. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +275 -40
  917. package/src/resources/extensions/gsd/tests/workspace-git-preflight.test.ts +15 -0
  918. package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +1 -1
  919. package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +41 -4
  920. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +43 -1
  921. package/src/resources/extensions/gsd/tests/worktree-placement.test.ts +113 -0
  922. package/src/resources/extensions/gsd/tests/worktree-project-root-degrade.test.ts +1 -1
  923. package/src/resources/extensions/gsd/tests/worktree-projection-writers.test.ts +1 -1
  924. package/src/resources/extensions/gsd/tests/worktree-reentry.test.ts +1 -1
  925. package/src/resources/extensions/gsd/tests/worktree-safety-phase.test.ts +100 -0
  926. package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +75 -1
  927. package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +12 -6
  928. package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +24 -2
  929. package/src/resources/extensions/gsd/tests/worktree-telemetry.test.ts +22 -0
  930. package/src/resources/extensions/gsd/tests/worktree.test.ts +18 -0
  931. package/src/resources/extensions/gsd/tests/write-gate-seam.test.ts +358 -0
  932. package/src/resources/extensions/gsd/tests/write-gate.test.ts +188 -1
  933. package/src/resources/extensions/gsd/tool-contract.ts +124 -11
  934. package/src/resources/extensions/gsd/tool-presentation-plan.ts +18 -35
  935. package/src/resources/extensions/gsd/tool-surface-readiness.ts +183 -0
  936. package/src/resources/extensions/gsd/tool-surface-snapshot.ts +47 -0
  937. package/src/resources/extensions/gsd/tools/complete-milestone.ts +3 -2
  938. package/src/resources/extensions/gsd/tools/complete-slice.ts +45 -70
  939. package/src/resources/extensions/gsd/tools/complete-task.ts +90 -2
  940. package/src/resources/extensions/gsd/tools/exec-tool.ts +9 -8
  941. package/src/resources/extensions/gsd/tools/plan-milestone.ts +19 -160
  942. package/src/resources/extensions/gsd/tools/plan-slice.ts +14 -8
  943. package/src/resources/extensions/gsd/tools/plan-task.ts +2 -2
  944. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +45 -2
  945. package/src/resources/extensions/gsd/tools/reopen-milestone.ts +13 -40
  946. package/src/resources/extensions/gsd/tools/reopen-slice.ts +16 -44
  947. package/src/resources/extensions/gsd/tools/reopen-task.ts +2 -2
  948. package/src/resources/extensions/gsd/tools/replan-slice.ts +2 -2
  949. package/src/resources/extensions/gsd/tools/skip-slice.ts +18 -44
  950. package/src/resources/extensions/gsd/tools/validate-milestone.ts +25 -84
  951. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +81 -2
  952. package/src/resources/extensions/gsd/uat-policy.ts +80 -25
  953. package/src/resources/extensions/gsd/uat-run.ts +10 -14
  954. package/src/resources/extensions/gsd/undo.ts +9 -8
  955. package/src/resources/extensions/gsd/unit-closeout.ts +201 -0
  956. package/src/resources/extensions/gsd/unit-context-composer.ts +196 -21
  957. package/src/resources/extensions/gsd/unit-context-manifest.ts +4 -28
  958. package/src/resources/extensions/gsd/unit-registry.ts +442 -0
  959. package/src/resources/extensions/gsd/unit-runtime.ts +3 -2
  960. package/src/resources/extensions/gsd/unit-tool-contracts.ts +27 -191
  961. package/src/resources/extensions/gsd/validation-block-guard.ts +2 -0
  962. package/src/resources/extensions/gsd/verdict-parser.ts +1 -1
  963. package/src/resources/extensions/gsd/verification-verdict.ts +4 -2
  964. package/src/resources/extensions/gsd/web-app-uat.ts +144 -0
  965. package/src/resources/extensions/gsd/workflow-event-ledger.ts +131 -0
  966. package/src/resources/extensions/gsd/workflow-event-vocabulary.ts +59 -0
  967. package/src/resources/extensions/gsd/workflow-events.ts +12 -20
  968. package/src/resources/extensions/gsd/workflow-mcp-auto-prep.ts +2 -0
  969. package/src/resources/extensions/gsd/workflow-mcp-readiness-cache.ts +150 -0
  970. package/src/resources/extensions/gsd/workflow-mcp.ts +22 -110
  971. package/src/resources/extensions/gsd/workflow-reconcile.ts +32 -65
  972. package/src/resources/extensions/gsd/workflow-tool-surface.ts +76 -0
  973. package/src/resources/extensions/gsd/workspace-git-guard.ts +1 -0
  974. package/src/resources/extensions/gsd/worktree-git-recovery.ts +314 -0
  975. package/src/resources/extensions/gsd/worktree-lifecycle.ts +20 -25
  976. package/src/resources/extensions/gsd/worktree-manager.ts +53 -29
  977. package/src/resources/extensions/gsd/worktree-placement.ts +63 -0
  978. package/src/resources/extensions/gsd/worktree-reentry.ts +10 -7
  979. package/src/resources/extensions/gsd/worktree-root.ts +29 -6
  980. package/src/resources/extensions/gsd/worktree-safety.ts +49 -44
  981. package/src/resources/extensions/gsd/worktree-session-state.ts +11 -11
  982. package/src/resources/extensions/gsd/worktree-state-projection.ts +55 -7
  983. package/src/resources/extensions/gsd/worktree-telemetry.ts +16 -0
  984. package/src/resources/extensions/gsd/worktree.ts +7 -1
  985. package/src/resources/extensions/mcp-client/manager.ts +7 -1
  986. package/src/resources/extensions/search-the-web/native-search.ts +5 -3
  987. package/src/resources/extensions/shared/browser-contract.ts +66 -0
  988. package/src/resources/extensions/shared/gsd-browser-cli.ts +141 -6
  989. package/src/resources/extensions/shared/interview-ui.ts +15 -2
  990. package/src/resources/shared/claude-runtime-floor.ts +248 -0
  991. package/src/resources/shared/gsd-browser-path-sync.ts +273 -0
  992. package/src/resources/shared/package-manager-detection.ts +1 -1
  993. package/src/resources/shared/package.json +3 -0
  994. package/src/resources/skills/create-skill/SKILL.md +3 -0
  995. package/src/resources/skills/create-skill/references/executable-code.md +1 -1
  996. package/src/resources/skills/create-skill/references/skill-structure.md +1 -0
  997. package/src/resources/skills/create-skill/workflows/add-reference.md +8 -3
  998. package/src/resources/skills/create-skill/workflows/add-script.md +4 -2
  999. package/src/resources/skills/create-skill/workflows/add-template.md +3 -1
  1000. package/src/resources/skills/create-skill/workflows/add-workflow.md +8 -3
  1001. package/src/resources/skills/create-skill/workflows/upgrade-to-router.md +10 -5
  1002. package/src/resources/skills/create-skill/workflows/verify-skill.md +9 -4
  1003. package/src/resources/skills/spike-wrap-up/SKILL.md +9 -9
  1004. package/dist/resources/extensions/gsd/user-input-boundary.js +0 -195
  1005. package/dist/resources/skills/gsd-browser/SKILL.md +0 -41
  1006. package/dist/web/standalone/.next/static/chunks/2659.feb6499ca863ebfc.js +0 -1
  1007. package/dist/web/standalone/.next/static/chunks/2772.151789db0edea835.js +0 -1
  1008. package/dist/web/standalone/.next/static/chunks/4283.10a065467b5340d8.js +0 -2
  1009. package/dist/web/standalone/.next/static/chunks/5826.960dc4634cc9b0d3.js +0 -1
  1010. package/dist/web/standalone/.next/static/chunks/796.46f811c0fac23aab.js +0 -10
  1011. package/dist/web/standalone/.next/static/chunks/8785.d32f7a61f55c1600.js +0 -1
  1012. package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +0 -88
  1013. package/src/resources/extensions/gsd/user-input-boundary.ts +0 -198
  1014. package/src/resources/skills/gsd-browser/SKILL.md +0 -41
  1015. /package/dist/web/standalone/.next/static/{Qbr81pQ-pbQXP4bq2VXLv → pZbHa49xI-knmKlphIRq0}/_buildManifest.js +0 -0
  1016. /package/dist/web/standalone/.next/static/{Qbr81pQ-pbQXP4bq2VXLv → pZbHa49xI-knmKlphIRq0}/_ssgManifest.js +0 -0
@@ -27,13 +27,30 @@ import { homedir } from "node:os";
27
27
  import { createRequire } from "node:module";
28
28
  import { dirname, join } from "node:path";
29
29
  import { PartialMessageBuilder, ZERO_USAGE, mapUsage } from "./partial-builder.js";
30
+ import {
31
+ attachExternalResultsToToolBlocks,
32
+ buildFinalAssistantContent,
33
+ extractToolResultsFromSdkUserMessage,
34
+ handleClaudeCodePartialStreamEvent,
35
+ shouldSuppressDuplicateToolUnavailableBlock,
36
+ } from "./turn-assembler.js";
37
+ import type {
38
+ ExternalToolResultPayload,
39
+ ToolCallWithExternalResult,
40
+ } from "./turn-assembler.js";
30
41
  import {
31
42
  buildWorkflowMcpServers,
32
43
  getRequiredWorkflowToolsForAutoUnit,
33
44
  resolveWorkflowMcpProjectRoot,
34
45
  } from "../gsd/workflow-mcp.js";
46
+ import { resolveWorkflowQuestionToolSurface } from "../gsd/question-transport.js";
35
47
  import { buildProjectGsdMcpServers, ensureProjectWorkflowMcpConfig } from "../gsd/mcp-project-config.js";
36
48
  import { loadProjectGSDPreferences } from "../gsd/preferences.js";
49
+ import { markToolStart, markToolEnd } from "../gsd/auto.js";
50
+ import {
51
+ markInteractiveElicitationStart,
52
+ markInteractiveElicitationEnd,
53
+ } from "../gsd/auto-tool-tracking.js";
37
54
  import {
38
55
  discoverBrowserMcpServerName,
39
56
  discoverMcpServers,
@@ -43,9 +60,23 @@ import {
43
60
  computeMcpDisallowedTools,
44
61
  } from "../gsd/mcp-filter.js";
45
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";
46
78
  import { showInterviewRound, type Question, type RoundResult } from "../shared/tui.js";
47
79
  import type {
48
- BetaRawMessageStreamEvent,
49
80
  SDKAssistantMessage,
50
81
  SDKMessage,
51
82
  SDKPartialAssistantMessage,
@@ -53,25 +84,18 @@ import type {
53
84
  SDKUserMessage,
54
85
  } from "./sdk-types.js";
55
86
 
56
- /** A single content block returned by an external (SDK-executed) tool call. */
57
- export interface ExternalToolResultContentBlock {
58
- type: string;
59
- text?: string;
60
- data?: string;
61
- mimeType?: string;
62
- }
63
-
64
- /** The full result payload returned by an external tool, including content blocks and error status. */
65
- export interface ExternalToolResultPayload {
66
- content: ExternalToolResultContentBlock[];
67
- details?: Record<string, unknown>;
68
- isError: boolean;
69
- }
70
-
71
- /** A `ToolCall` block augmented with the external result attached by the SDK synthetic user message. */
72
- type ToolCallWithExternalResult = ToolCall & {
73
- externalResult?: ExternalToolResultPayload;
74
- };
87
+ export {
88
+ buildFinalAssistantContent,
89
+ extractToolResultsFromSdkUserMessage,
90
+ handleClaudeCodePartialStreamEvent,
91
+ mergePendingToolCalls,
92
+ shouldSuppressDuplicateToolUnavailableBlock,
93
+ } from "./turn-assembler.js";
94
+ export type {
95
+ ExternalToolResultContentBlock,
96
+ ExternalToolResultPayload,
97
+ ToolCallWithExternalResult,
98
+ } from "./turn-assembler.js";
75
99
 
76
100
  interface PromptToolContextOptions {
77
101
  workflowMcpServerName?: string | null;
@@ -83,6 +107,11 @@ interface ClaudeCodeStreamOptions extends SimpleStreamOptions {
83
107
  extensionUIContext?: ExtensionUIContext;
84
108
  onExternalToolCall?: (toolCall: ToolCall) => Promise<void> | void;
85
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;
86
115
  }
87
116
 
88
117
  export function serverToolUseToToolCallLike(block: {
@@ -343,13 +372,18 @@ const GSD_PHASE_PATTERNS: Array<[string, RegExp]> = [
343
372
  ["reassess-roadmap", /\b(?:UNIT:\s*Reassess Roadmap|reassess-roadmap)\b/i],
344
373
  ["complete-slice", /\b(?:UNIT:\s*Complete Slice|complete-slice)\b/i],
345
374
  ["replan-slice", /\b(?:UNIT:\s*Replan Slice|replan-slice)\b/i],
375
+ ["refine-slice", /\b(?:UNIT:\s*Refine Slice|refine-slice)\b/i],
346
376
  ["plan-slice", /\b(?:UNIT:\s*Plan Slice|plan-slice|gsd_plan_slice)\b/i],
347
377
  ["plan-milestone", /\b(?:UNIT:\s*Plan Milestone|plan-milestone|gsd_plan_milestone)\b/i],
348
378
  ["execute-task", /\b(?:UNIT:\s*Execute Task|execute-task|execute-task-simple|reactive-execute)\b/i],
349
379
  ["gate-evaluate", /\b(?:UNIT:\s*Gate Evaluate|gate-evaluate|gsd_save_gate_result)\b/i],
350
380
  ["research-milestone", /\b(?:UNIT:\s*Research Milestone|research-milestone)\b/i],
351
381
  ["research-slice", /\b(?:UNIT:\s*Research Slice|research-slice)\b/i],
382
+ ["research-decision", /\b(?:research decision|research-decision)\b/i],
352
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],
353
387
  ];
354
388
 
355
389
  export function inferGsdPhaseFromContext(context: Context): string | undefined {
@@ -363,6 +397,26 @@ export function inferGsdPhaseFromContext(context: Context): string | undefined {
363
397
  return undefined;
364
398
  }
365
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
+
366
420
  /**
367
421
  * Build a full conversational prompt from GSD's context messages.
368
422
  *
@@ -388,10 +442,15 @@ export function buildPromptFromContext(context: Context, toolContext: PromptTool
388
442
  const workflowToolLine = toolContext.workflowMcpServerName
389
443
  ? "- GSD workflow tools (gsd_exec, gsd_slice_complete, gsd_task_complete, gsd_plan_slice, gsd_save_gate_result, etc.) " +
390
444
  `are MCP tools — call them as mcp__${toolContext.workflowMcpServerName}__<tool_name> ` +
391
- `(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"
392
448
  : "- GSD workflow MCP tools are unavailable in this Claude Code run.\n";
393
449
  const toolSearchLine = toolContext.workflowMcpServerName
394
- ? "- 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"
395
454
  : "- ToolSearch is NOT available — never use it to discover tools\n";
396
455
  const browserToolLine = toolContext.browserMcpServerName
397
456
  ? "- Browser verification uses gsd-browser MCP by default — call browser tools as " +
@@ -502,9 +561,11 @@ export function buildSdkQueryPrompt(
502
561
  parent_tool_use_id: null,
503
562
  };
504
563
 
505
- return (async function* () {
506
- yield sdkMessage;
507
- })();
564
+ return {
565
+ async *[Symbol.asyncIterator]() {
566
+ yield sdkMessage;
567
+ },
568
+ };
508
569
  }
509
570
 
510
571
  // ---------------------------------------------------------------------------
@@ -526,6 +587,59 @@ function makeErrorMessage(model: string, errorMsg: string): AssistantMessage {
526
587
  };
527
588
  }
528
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
+
529
643
  export function isClaudeCodeAbortErrorMessage(message: string | undefined | null): boolean {
530
644
  if (!message) return false;
531
645
  return /\b(?:claude code process aborted by user|request aborted by user|process aborted by user|aborterror)\b/i.test(message);
@@ -1359,7 +1473,27 @@ export function createClaudeCodeCanUseToolHandler(
1359
1473
  // Elicitation handler
1360
1474
  // ---------------------------------------------------------------------------
1361
1475
 
1362
- /** Create an SDK elicitation handler that routes requests through the extension UI dialogs, or undefined if no UI is available. */
1476
+ /**
1477
+ * Create an SDK elicitation handler that routes requests through the extension UI dialogs, or undefined if no UI is available.
1478
+ *
1479
+ * For structured (AskUserQuestion) elicitations, the interview round's result
1480
+ * disambiguates two cases that must not be conflated: an `undefined` result
1481
+ * means the custom UI is unavailable, so we fall back to the simpler `select`
1482
+ * dialogs; an empty-answers result means the user dismissed the question, which
1483
+ * is treated as a clean cancel. Falling back to dialogs on dismissal would
1484
+ * re-ask the same questions (the duplicate-question bug).
1485
+ */
1486
+ /**
1487
+ * Monotonic counter so concurrent/sequential elicitations resolved within the
1488
+ * same millisecond get distinct synthetic in-flight-tool ids (the `cc-elicit-*`
1489
+ * namespace never collides with real MCP toolCallIds).
1490
+ */
1491
+ let _elicitationSeq = 0;
1492
+ function nextElicitationSeq(): number {
1493
+ _elicitationSeq = (_elicitationSeq + 1) % Number.MAX_SAFE_INTEGER;
1494
+ return _elicitationSeq;
1495
+ }
1496
+
1363
1497
  export function createClaudeCodeElicitationHandler(
1364
1498
  ui: ExtensionUIContext | undefined,
1365
1499
  ): ((request: SdkElicitationRequest, options: { signal: AbortSignal }) => Promise<SdkElicitationResult>) | undefined {
@@ -1375,20 +1509,67 @@ export function createClaudeCodeElicitationHandler(
1375
1509
  const headlessAnswer = answerElicitationFromHeadlessAnswers(questions, loadHeadlessAnswers());
1376
1510
  if (headlessAnswer) return headlessAnswer;
1377
1511
 
1378
- const interviewResult = await showInterviewRound(questions, { signal }, { ui } as any).catch(() => undefined);
1379
- if (interviewResult && Object.keys(interviewResult.answers).length > 0) {
1512
+ // The SDK elicitation blocks waiting for human input, but it is not an
1513
+ // MCP tool dispatch, so markToolStart/markToolEnd are never called for
1514
+ // it. Without this the soft/context/idle/hard watchdogs see zero
1515
+ // in-flight tools and re-dispatch (and ultimately abort) the agent
1516
+ // turn hosting this elicitation, tearing the question down (#2676 /
1517
+ // claude-code-cli self-cancel loop). Bracketing the human wait with
1518
+ // the s.active-gated interactive-tool guard makes it visible to
1519
+ // hasInteractiveToolInFlight()/getInFlightToolCount() so those
1520
+ // watchdogs exempt it. No-op outside auto-mode (wrapper self-gates).
1521
+ //
1522
+ // markInteractiveElicitationStart/End is a SEPARATE, ungated signal that
1523
+ // is observable in FOREGROUND (where the s.active-gated markToolStart is a
1524
+ // no-op). The foreground approval-gate pause path (register-hooks
1525
+ // message_update) consults isInteractiveElicitationInFlight() and bails so
1526
+ // it does not tear down the very elicitation that IS the human boundary
1527
+ // (#cc-elicitation-self-cancel). It clears in the finally on every exit.
1528
+ const elicId = "cc-elicit-" + ((request as { id?: string | number }).id ?? `${Date.now()}-${nextElicitationSeq()}`);
1529
+ markInteractiveElicitationStart();
1530
+ markToolStart(elicId, "ask_user_questions");
1531
+ try {
1532
+ const interviewResult = await showInterviewRound(
1533
+ questions,
1534
+ { signal, overlay: true },
1535
+ { ui } as any,
1536
+ ).catch(() => undefined);
1537
+ if (interviewResult === undefined) {
1538
+ // `await` so the dialog human-wait stays inside try/finally and the
1539
+ // in-flight guard is held until the dialog resolves. Without it,
1540
+ // `finally` runs the moment the promise is created and the fallback
1541
+ // wait runs with zero in-flight tools — reintroducing the
1542
+ // self-cancel on this path (Bugbot #1c00624d).
1543
+ return await promptElicitationWithDialogs(request, questions, ui, signal);
1544
+ }
1545
+ if (Object.keys(interviewResult.answers).length === 0) {
1546
+ // A system/host teardown (compaction, session_switch, true
1547
+ // interrupt) that aborted the signal mid-wait sets `interrupted`.
1548
+ // Surface that as a non-affirmative `decline` so it is not
1549
+ // laundered into a clean user-declined `cancel` the model re-asks
1550
+ // against. A genuine user dismissal leaves `interrupted` falsy and
1551
+ // keeps the prior `cancel` semantics.
1552
+ return interviewResult.interrupted ? { action: "decline" } : { action: "cancel" };
1553
+ }
1380
1554
  return {
1381
1555
  action: "accept",
1382
1556
  content: roundResultToElicitationContent(questions, interviewResult),
1383
1557
  };
1558
+ } finally {
1559
+ markToolEnd(elicId);
1560
+ markInteractiveElicitationEnd();
1384
1561
  }
1385
-
1386
- return promptElicitationWithDialogs(request, questions, ui, signal);
1387
1562
  }
1388
1563
 
1389
1564
  const textFields = parseTextInputElicitation(request);
1390
1565
  if (textFields) {
1391
- return promptTextInputElicitation(request, textFields, ui, signal);
1566
+ const elicId = "cc-elicit-" + ((request as { id?: string | number }).id ?? `${Date.now()}-${nextElicitationSeq()}`);
1567
+ markToolStart(elicId, "secure_env_collect");
1568
+ try {
1569
+ return await promptTextInputElicitation(request, textFields, ui, signal);
1570
+ } finally {
1571
+ markToolEnd(elicId);
1572
+ }
1392
1573
  }
1393
1574
 
1394
1575
  return { action: "decline" };
@@ -1468,6 +1649,8 @@ function modelSupportsAdaptiveThinking(modelId: string): boolean {
1468
1649
  || modelId.includes("opus-4.7")
1469
1650
  || modelId.includes("opus-4-8")
1470
1651
  || modelId.includes("opus-4.8")
1652
+ || modelId.includes("fable-5")
1653
+ || modelId.includes("fable.5")
1471
1654
  || modelId.includes("sonnet-4-6")
1472
1655
  || modelId.includes("sonnet-4.6")
1473
1656
  || modelId.includes("sonnet-4-7")
@@ -1493,6 +1676,8 @@ function mapThinkingLevelToAnthropicEffort(level: ThinkingLevel | undefined, mod
1493
1676
  || modelId.includes("opus-4.7")
1494
1677
  || modelId.includes("opus-4-8")
1495
1678
  || modelId.includes("opus-4.8")
1679
+ || modelId.includes("fable-5")
1680
+ || modelId.includes("fable.5")
1496
1681
  ) return "xhigh";
1497
1682
  if (modelId.includes("opus-4-6") || modelId.includes("opus-4.6")) return "max";
1498
1683
  return "high";
@@ -1512,7 +1697,7 @@ function browserMcpServerNameFromAllowedTools(allowedTools: unknown): string | u
1512
1697
  if (typeof toolName !== "string") continue;
1513
1698
  const parsed = parseAllowedMcpToolName(toolName);
1514
1699
  if (!parsed) continue;
1515
- if (parsed.server === "gsd-browser" || parsed.tool.startsWith("browser_")) {
1700
+ if (parsed.server === "gsd-browser" || hasBrowserContractPrefix(parsed.tool)) {
1516
1701
  return parsed.server;
1517
1702
  }
1518
1703
  }
@@ -1525,7 +1710,7 @@ function workflowMcpServerNameFromAllowedTools(allowedTools: unknown): string |
1525
1710
  for (const toolName of allowedTools) {
1526
1711
  if (typeof toolName !== "string") continue;
1527
1712
  const parsed = parseAllowedMcpToolName(toolName);
1528
- if (!parsed || parsed.server === browserServerName || parsed.tool.startsWith("browser_")) continue;
1713
+ if (!parsed || parsed.server === browserServerName || hasBrowserContractPrefix(parsed.tool)) continue;
1529
1714
  return parsed.server;
1530
1715
  }
1531
1716
  return undefined;
@@ -1583,11 +1768,15 @@ function resolveExactWorkflowMcpToolsForPhase(
1583
1768
  workflowExplicitlyBlocked: boolean,
1584
1769
  ): string[] {
1585
1770
  if (!gsdPhase || !workflowServerName || workflowExplicitlyBlocked) return [];
1586
- const requiredTools = gsdPhase === "run-uat"
1771
+ const requestedTools = gsdPhase === "run-uat"
1587
1772
  ? [...RUN_UAT_WORKFLOW_TOOL_NAMES]
1588
- : getRequiredWorkflowToolsForAutoUnit(gsdPhase);
1589
- const supportTools = gsdPhase === "run-uat" ? [] : ["gsd_milestone_status"];
1590
- 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
+ )];
1591
1780
  if (requestedToolNames.length === 0) return [];
1592
1781
  return resolveToolPresentationPlan({
1593
1782
  phase: gsdPhase,
@@ -1597,6 +1786,25 @@ function resolveExactWorkflowMcpToolsForPhase(
1597
1786
  }).presentedToolNames;
1598
1787
  }
1599
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
+
1600
1808
  export function autoInitClaudeCodeWorkflowMcp(cwd: string): void {
1601
1809
  const projectRoot = resolveWorkflowMcpProjectRoot(cwd);
1602
1810
  try {
@@ -1610,6 +1818,70 @@ export function autoInitClaudeCodeWorkflowMcp(cwd: string): void {
1610
1818
  }
1611
1819
  }
1612
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
+
1613
1885
  /**
1614
1886
  * Build the options object passed to the Claude Agent SDK's `query()` call.
1615
1887
  *
@@ -1743,6 +2015,13 @@ export function buildSdkOptions(
1743
2015
  workflowServerName,
1744
2016
  workflowExplicitlyBlocked,
1745
2017
  );
2018
+ const questionToolSurface = resolveWorkflowQuestionToolSurface({
2019
+ workflowServerName,
2020
+ workflowExplicitlyBlocked,
2021
+ workflowMcpTools,
2022
+ exactWorkflowMcpTools,
2023
+ env: process.env,
2024
+ });
1746
2025
  const runUatDisallowedTools = gsdPhase === "run-uat" && workflowServerName
1747
2026
  ? [
1748
2027
  ...RUN_UAT_FORBIDDEN_TOOL_NAMES.filter((toolName) => !toolName.startsWith("mcp__")),
@@ -1753,33 +2032,27 @@ export function buildSdkOptions(
1753
2032
  `mcp__${workflowServerName}__gsd_save_gate_result`,
1754
2033
  ]
1755
2034
  : [];
2035
+ const allowToolSearchForWorkflowMcp = workflowMcpTools.length > 0 || exactWorkflowMcpTools.length > 0;
1756
2036
  const disallowedTools: string[] = [...new Set([
1757
- "ToolSearch",
2037
+ ...(allowToolSearchForWorkflowMcp ? [] : ["ToolSearch"]),
2038
+ ...(gsdPhase ? ["Skill"] : []),
1758
2039
  ...(workflowMcpTools.length > 0 || exactWorkflowMcpTools.length > 0 ? ["AskUserQuestion"] : []),
2040
+ ...questionToolSurface.disallowedTools,
1759
2041
  ...runUatDisallowedTools,
1760
2042
  ...extraDisallowedTools,
1761
2043
  ])];
1762
- const standardClaudeTools = [
1763
- "Read",
1764
- "Write",
1765
- "Edit",
1766
- "Glob",
1767
- "Grep",
1768
- "Bash",
1769
- "Agent",
1770
- "WebFetch",
1771
- "WebSearch",
1772
- ];
2044
+ const nativeTools = resolveClaudeNativeToolsForPhase(gsdPhase);
1773
2045
  const allowedTools = gsdPhase === "run-uat"
1774
2046
  ? [
1775
- ...RUN_UAT_CLAUDE_NATIVE_TOOL_NAMES,
2047
+ ...nativeTools,
1776
2048
  ...(exactWorkflowMcpTools.length > 0 ? exactWorkflowMcpTools : []),
1777
2049
  ...allowedBrowserMcpTools,
1778
2050
  ]
1779
2051
  : [
1780
- ...standardClaudeTools,
2052
+ ...nativeTools,
1781
2053
  ...exactWorkflowMcpTools,
1782
- ...(workflowMcpTools.length > 0 ? workflowMcpTools : ["AskUserQuestion"]),
2054
+ ...(!gsdPhase && workflowMcpTools.length > 0 ? workflowMcpTools : []),
2055
+ ...(workflowMcpTools.length === 0 && exactWorkflowMcpTools.length === 0 ? ["AskUserQuestion"] : []),
1783
2056
  ...allowedBrowserMcpTools,
1784
2057
  ];
1785
2058
  const supportsAdaptive = modelSupportsAdaptiveThinking(modelId);
@@ -1817,6 +2090,8 @@ export function buildSdkOptions(
1817
2090
  || modelId.includes("opus-4.7")
1818
2091
  || modelId.includes("opus-4-8")
1819
2092
  || modelId.includes("opus-4.8")
2093
+ || modelId.includes("fable-5")
2094
+ || modelId.includes("fable.5")
1820
2095
  ) ? ["context-1m-2025-08-07"] : [],
1821
2096
  ...(thinkingConfig ?? {}),
1822
2097
  ...(effort ? { effort } : {}),
@@ -1824,261 +2099,6 @@ export function buildSdkOptions(
1824
2099
  };
1825
2100
  }
1826
2101
 
1827
- /** Normalise heterogeneous SDK tool-result content (string, array, or object) into a uniform `ExternalToolResultContentBlock[]`. */
1828
- function normalizeToolResultContent(content: unknown): ExternalToolResultContentBlock[] {
1829
- if (typeof content === "string") {
1830
- return [{ type: "text", text: content }];
1831
- }
1832
-
1833
- if (!Array.isArray(content)) {
1834
- if (content == null) return [{ type: "text", text: "" }];
1835
- return [{ type: "text", text: JSON.stringify(content) }];
1836
- }
1837
-
1838
- const blocks: ExternalToolResultContentBlock[] = [];
1839
-
1840
- for (const item of content) {
1841
- if (typeof item === "string") {
1842
- blocks.push({ type: "text", text: item });
1843
- continue;
1844
- }
1845
- if (!item || typeof item !== "object") {
1846
- blocks.push({ type: "text", text: String(item) });
1847
- continue;
1848
- }
1849
-
1850
- const block = item as Record<string, unknown>;
1851
- if (block.type === "text") {
1852
- blocks.push({ type: "text", text: typeof block.text === "string" ? block.text : "" });
1853
- continue;
1854
- }
1855
- if (
1856
- block.type === "image"
1857
- && typeof block.data === "string"
1858
- && typeof block.mimeType === "string"
1859
- ) {
1860
- blocks.push({ type: "image", data: block.data, mimeType: block.mimeType });
1861
- continue;
1862
- }
1863
-
1864
- blocks.push({ type: "text", text: JSON.stringify(block) });
1865
- }
1866
-
1867
- return blocks.length > 0 ? blocks : [{ type: "text", text: "" }];
1868
- }
1869
-
1870
- /**
1871
- * Extract a `details` payload from an MCP tool-result block.
1872
- *
1873
- * MCP's `CallToolResult` carries structured data in `structuredContent` — the
1874
- * protocol's supported channel for non-text payloads. Claude Code's synthetic
1875
- * user message may surface that field in one of two shapes depending on SDK
1876
- * version: as a sibling on the `mcp_tool_result` block itself, or as a
1877
- * dedicated content sub-block with `type: "structuredContent"`. Snake-case
1878
- * (`structured_content`) is accepted defensively in case a transport hop
1879
- * rewrites casing. All other shapes fall back to an empty object so callers
1880
- * can rely on `details` being present.
1881
- */
1882
- function extractStructuredDetailsFromBlock(block: Record<string, unknown>): Record<string, unknown> | undefined {
1883
- const sibling = block.structuredContent ?? (block as Record<string, unknown>).structured_content;
1884
- if (sibling && typeof sibling === "object" && !Array.isArray(sibling)) {
1885
- return sibling as Record<string, unknown>;
1886
- }
1887
-
1888
- if (Array.isArray(block.content)) {
1889
- for (const item of block.content) {
1890
- if (!item || typeof item !== "object") continue;
1891
- const sub = item as Record<string, unknown>;
1892
- if (sub.type !== "structuredContent" && sub.type !== "structured_content") continue;
1893
- const payload = sub.structuredContent ?? sub.structured_content ?? sub.data ?? sub.value;
1894
- if (payload && typeof payload === "object" && !Array.isArray(payload)) {
1895
- return payload as Record<string, unknown>;
1896
- }
1897
- }
1898
- }
1899
-
1900
- // Return undefined (not {}) when no structured payload is present, matching
1901
- // the pre-#4477 contract where `details` was nullable. An empty-object
1902
- // sentinel is truthy and breaks downstream consumers that gate on
1903
- // `if (details)`. `undefined` matches the type of the field these results
1904
- // flow into (`Record<string, unknown> | undefined`).
1905
- return undefined;
1906
- }
1907
-
1908
- /**
1909
- * True for items that are MCP `structuredContent` pseudo-blocks living inside
1910
- * a tool-result `content[]` array. These blocks carry the structured payload
1911
- * (extracted separately by `extractStructuredDetailsFromBlock`) and must NOT
1912
- * leak into the visible content rendered to the user — otherwise the renderer
1913
- * stringifies the JSON pseudo-block and shows it next to the actual tool
1914
- * output. See PR #4477 review (post-fix-round).
1915
- */
1916
- function isStructuredContentPseudoBlock(item: unknown): boolean {
1917
- if (!item || typeof item !== "object") return false;
1918
- const type = (item as Record<string, unknown>).type;
1919
- return type === "structuredContent" || type === "structured_content";
1920
- }
1921
-
1922
- /**
1923
- * Strip `structuredContent` pseudo-blocks from a tool-result content array
1924
- * before normalization. The structured payload is extracted via the sibling
1925
- * `structuredContent` field (or a dedicated extractor pass on the raw block);
1926
- * the visible content path must not include the pseudo-block itself.
1927
- */
1928
- function stripStructuredContentPseudoBlocks(content: unknown): unknown {
1929
- if (!Array.isArray(content)) return content;
1930
- return content.filter((item) => !isStructuredContentPseudoBlock(item));
1931
- }
1932
-
1933
- /** Extract tool result payloads from an SDK synthetic user message, keyed by tool-use ID. */
1934
- export function extractToolResultsFromSdkUserMessage(message: SDKUserMessage): Array<{
1935
- toolUseId: string;
1936
- result: ExternalToolResultPayload;
1937
- }> {
1938
- const extracted: Array<{ toolUseId: string; result: ExternalToolResultPayload }> = [];
1939
- const seen = new Set<string>();
1940
- const rawMessage = message.message as Record<string, unknown> | null | undefined;
1941
- const content = Array.isArray(rawMessage?.content) ? rawMessage.content : [];
1942
-
1943
- for (const item of content) {
1944
- if (!item || typeof item !== "object") continue;
1945
- const block = item as Record<string, unknown>;
1946
- const type = typeof block.type === "string" ? block.type : "";
1947
- if (type !== "tool_result" && type !== "mcp_tool_result") continue;
1948
-
1949
- const toolUseId = typeof block.tool_use_id === "string" ? block.tool_use_id : "";
1950
- if (!toolUseId || seen.has(toolUseId)) continue;
1951
- seen.add(toolUseId);
1952
-
1953
- extracted.push({
1954
- toolUseId,
1955
- result: {
1956
- content: normalizeToolResultContent(stripStructuredContentPseudoBlocks(block.content)),
1957
- details: extractStructuredDetailsFromBlock(block),
1958
- isError: block.is_error === true,
1959
- },
1960
- });
1961
- }
1962
-
1963
- if (extracted.length === 0) {
1964
- const fallback = message.tool_use_result;
1965
- if (fallback && typeof fallback === "object") {
1966
- const toolResult = fallback as Record<string, unknown>;
1967
- const toolUseId = typeof toolResult.tool_use_id === "string" ? toolResult.tool_use_id : "";
1968
- if (toolUseId) {
1969
- extracted.push({
1970
- toolUseId,
1971
- result: {
1972
- content: normalizeToolResultContent(stripStructuredContentPseudoBlocks(toolResult.content)),
1973
- details: extractStructuredDetailsFromBlock(toolResult),
1974
- isError: toolResult.is_error === true,
1975
- },
1976
- });
1977
- }
1978
- }
1979
- }
1980
-
1981
- return extracted;
1982
- }
1983
-
1984
- /** Attach external tool results from the SDK synthetic user message to their corresponding tool-call blocks by ID. */
1985
- function attachExternalResultsToToolBlocks(
1986
- toolBlocks: AssistantMessage["content"],
1987
- toolResultsById: ReadonlyMap<string, ExternalToolResultPayload>,
1988
- ): void {
1989
- for (const block of toolBlocks) {
1990
- if (block.type !== "toolCall" && block.type !== "serverToolUse") continue;
1991
- const externalResult = toolResultsById.get(block.id);
1992
- if (!externalResult) continue;
1993
- (block as ToolCallWithExternalResult & { id: string }).externalResult = externalResult;
1994
- }
1995
- }
1996
-
1997
- /**
1998
- * Build the final assistant content that Agent Core consumes in
1999
- * `externalToolExecution` mode. This preserves tool-call blocks, attaches any
2000
- * SDK-produced external results by tool-call id, and then appends the final
2001
- * text/thinking blocks for the completed turn.
2002
- */
2003
- export function buildFinalAssistantContent(params: {
2004
- intermediateToolBlocks: AssistantMessage["content"];
2005
- pendingContent?: AssistantMessage["content"];
2006
- toolResultsById: ReadonlyMap<string, ExternalToolResultPayload>;
2007
- lastThinkingContent?: string;
2008
- lastTextContent?: string;
2009
- fallbackResultText?: string;
2010
- }): AssistantMessage["content"] {
2011
- const mergedToolBlocks = [...params.intermediateToolBlocks];
2012
- if (params.pendingContent) {
2013
- mergePendingToolCalls(mergedToolBlocks, params.pendingContent);
2014
- }
2015
- attachExternalResultsToToolBlocks(mergedToolBlocks, params.toolResultsById);
2016
-
2017
- const finalContent: AssistantMessage["content"] = [...mergedToolBlocks];
2018
- if (params.pendingContent && params.pendingContent.length > 0) {
2019
- for (const block of params.pendingContent) {
2020
- if (block.type === "text" || block.type === "thinking") {
2021
- finalContent.push(block);
2022
- }
2023
- }
2024
- } else {
2025
- if (params.lastThinkingContent) {
2026
- finalContent.push({ type: "thinking", thinking: params.lastThinkingContent });
2027
- }
2028
- if (params.lastTextContent) {
2029
- finalContent.push({ type: "text", text: params.lastTextContent });
2030
- }
2031
- }
2032
-
2033
- if (finalContent.length === 0 && params.fallbackResultText) {
2034
- finalContent.push({ type: "text", text: params.fallbackResultText });
2035
- }
2036
-
2037
- return finalContent;
2038
- }
2039
-
2040
- /**
2041
- * Merge tool-call blocks from the active partial-message builder into the
2042
- * running list of intermediate tool calls, preserving order and de-duping
2043
- * by tool-call id. Exposed for testing the F3 fix (final-turn tool calls
2044
- * dropped when `result` arrives without a preceding synthetic `user`).
2045
- */
2046
- export function mergePendingToolCalls(
2047
- intermediate: AssistantMessage["content"],
2048
- pending: AssistantMessage["content"],
2049
- ): AssistantMessage["content"] {
2050
- const alreadyIncluded = new Set<string>();
2051
- for (const block of intermediate) {
2052
- if (block.type === "toolCall") alreadyIncluded.add(block.id);
2053
- }
2054
- for (const block of pending) {
2055
- if (block.type !== "toolCall") continue;
2056
- if (alreadyIncluded.has(block.id)) continue;
2057
- alreadyIncluded.add(block.id);
2058
- intermediate.push(block);
2059
- }
2060
- return intermediate;
2061
- }
2062
-
2063
- export function handleClaudeCodePartialStreamEvent(
2064
- builder: PartialMessageBuilder | null,
2065
- event: BetaRawMessageStreamEvent,
2066
- modelId: string,
2067
- ): { builder: PartialMessageBuilder | null; assistantEvent: AssistantMessageEvent | null } {
2068
- if (event.type === "message_start") {
2069
- // Claude Code can emit repeated SDK message_start events inside one
2070
- // logical assistant response. Keep appending until a synthetic user
2071
- // tool-result boundary explicitly clears the builder.
2072
- return {
2073
- builder: builder ?? new PartialMessageBuilder((event as any).message?.model ?? modelId),
2074
- assistantEvent: null,
2075
- };
2076
- }
2077
-
2078
- if (!builder) return { builder, assistantEvent: null };
2079
- return { builder, assistantEvent: builder.handleEvent(event) };
2080
- }
2081
-
2082
2102
  // ---------------------------------------------------------------------------
2083
2103
  // streamSimple implementation
2084
2104
  // ---------------------------------------------------------------------------
@@ -2103,6 +2123,20 @@ export function streamViaClaudeCode(
2103
2123
  return stream;
2104
2124
  }
2105
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
+
2106
2140
  /** Async pump that drives the Claude Agent SDK's async-iterable message stream and pushes events into `stream`. */
2107
2141
  async function pumpSdkMessages(
2108
2142
  model: Model<any>,
@@ -2111,38 +2145,30 @@ async function pumpSdkMessages(
2111
2145
  stream: AssistantMessageEventStream,
2112
2146
  ): Promise<void> {
2113
2147
  const modelId = model.id;
2114
- let builder: PartialMessageBuilder | null = null;
2115
2148
  /** Track the last text content seen across all assistant turns for the final message. */
2116
2149
  let lastTextContent = "";
2117
2150
  let lastThinkingContent = "";
2118
- /** Collect tool blocks from intermediate SDK turns for tool execution rendering. */
2119
- const intermediateToolBlocks: AssistantMessage["content"] = [];
2120
- /** Preserve real external tool results from Claude Code's synthetic user messages. */
2121
- const toolResultsById = new Map<string, ExternalToolResultPayload>();
2122
2151
 
2123
2152
  try {
2124
- // Dynamic import — the SDK is an optional dependency.
2125
- const sdkModule = "@anthropic-ai/claude-agent-sdk";
2126
- const sdk = (await import(/* webpackIgnore: true */ sdkModule)) as {
2127
- query: (args: {
2128
- prompt: string | AsyncIterable<unknown>;
2129
- options?: Record<string, unknown>;
2130
- }) => AsyncIterable<SDKMessage>;
2131
- };
2132
-
2133
- // Bridge GSD's AbortSignal to SDK's AbortController
2134
- const controller = new AbortController();
2135
- if (options?.signal) {
2136
- options.signal.addEventListener("abort", () => controller.abort(), { once: true });
2137
- }
2138
-
2139
2153
  const permissionMode = await resolveClaudePermissionMode();
2140
- const uiContext = (options as ClaudeCodeStreamOptions | undefined)?.extensionUIContext;
2141
- const onExternalToolCall = (options as ClaudeCodeStreamOptions | undefined)?.onExternalToolCall;
2142
- 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;
2143
2168
  const cwd = resolveClaudeCodeCwd(options);
2169
+ const projectRoot = resolveWorkflowMcpProjectRoot(cwd);
2144
2170
  autoInitClaudeCodeWorkflowMcp(cwd);
2145
- const gsdPhase = inferGsdPhaseFromContext(context);
2171
+ const gsdPhase = resolveGsdPhaseForSdk(context, projectRoot);
2146
2172
  const canUseToolHandler = createClaudeCodeCanUseToolHandler(uiContext);
2147
2173
  // When no UI is available (headless / auto-mode), auto-approve all
2148
2174
  // tool requests. This replaces the old bypassPermissions workaround.
@@ -2165,20 +2191,16 @@ async function pumpSdkMessages(
2165
2191
  : {}),
2166
2192
  },
2167
2193
  );
2194
+ const workflowMcpServerName = workflowMcpServerNameFromAllowedTools(sdkOpts.allowedTools);
2195
+ const allowPendingToolSearchHydration =
2196
+ Boolean(workflowMcpServerName && gsdPhase)
2197
+ && !(sdkOpts.disallowedTools as string[] | undefined)?.includes("ToolSearch");
2168
2198
  const prompt = buildPromptFromContext(context, {
2169
- workflowMcpServerName: workflowMcpServerNameFromAllowedTools(sdkOpts.allowedTools),
2199
+ workflowMcpServerName,
2170
2200
  browserMcpServerName: browserMcpServerNameFromAllowedTools(sdkOpts.allowedTools),
2171
2201
  });
2172
2202
  const queryPrompt = buildSdkQueryPrompt(context, prompt);
2173
2203
 
2174
- const queryResult = sdk.query({
2175
- prompt: queryPrompt,
2176
- options: {
2177
- ...sdkOpts,
2178
- abortController: controller,
2179
- },
2180
- });
2181
-
2182
2204
  // Emit start with an empty partial
2183
2205
  const initialPartial: AssistantMessage = {
2184
2206
  role: "assistant",
@@ -2191,174 +2213,320 @@ async function pumpSdkMessages(
2191
2213
  timestamp: Date.now(),
2192
2214
  };
2193
2215
  stream.push({ type: "start", partial: initialPartial });
2216
+ const readinessProgressState: WorkflowMcpReadinessProgressState = {};
2194
2217
 
2195
- for await (const msg of queryResult as AsyncIterable<SDKMessage>) {
2196
- if (options?.signal?.aborted) {
2197
- // User-initiated cancel — emit an aborted error so the agent
2198
- // loop classifies this as a deliberate stop, not a transient
2199
- // provider failure that should be retried.
2200
- stream.push({
2201
- type: "error",
2202
- reason: "aborted",
2203
- error: makeAbortedMessage(modelId, lastTextContent),
2204
- });
2205
- 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
+ }
2206
2259
  }
2207
2260
 
2208
- switch (msg.type) {
2209
- // -- Init --
2210
- case "system": {
2211
- // Nothing to emit — the stream is already started.
2212
- 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 });
2213
2268
  }
2214
2269
 
2215
- // -- Streaming partial messages --
2216
- case "stream_event": {
2217
- const partial = msg as SDKPartialAssistantMessage;
2218
-
2219
- const event = partial.event;
2220
-
2221
- const result = handleClaudeCodePartialStreamEvent(builder, event, modelId);
2222
- builder = result.builder;
2223
- const assistantEvent = result.assistantEvent;
2224
- if (assistantEvent) {
2225
- stream.push(assistantEvent);
2226
- if (assistantEvent.type === "toolcall_start") {
2227
- const toolBlock = assistantEvent.partial.content[assistantEvent.contentIndex];
2228
- if (toolBlock?.type === "toolCall") {
2229
- try {
2230
- await onExternalToolCall?.(toolBlock);
2231
- } catch (error) {
2232
- 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;
2233
2348
  }
2234
2349
  }
2350
+ break;
2235
2351
  }
2236
- }
2237
- break;
2238
- }
2239
-
2240
- // -- Complete assistant message (non-streaming fallback) --
2241
- case "assistant": {
2242
- const sdkAssistant = msg as SDKAssistantMessage;
2243
2352
 
2244
- // Capture text content from complete messages
2245
- for (const block of sdkAssistant.message.content) {
2246
- if (block.type === "text") {
2247
- lastTextContent = block.text;
2248
- } else if (block.type === "thinking") {
2249
- 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;
2250
2376
  }
2251
- }
2252
- break;
2253
- }
2254
2377
 
2255
- // -- User message (synthetic tool result — signals turn boundary) --
2256
- case "user": {
2257
- // Capture content from the completed turn before resetting
2258
- if (builder) {
2259
- for (const block of builder.message.content) {
2260
- if (block.type === "text" && block.text) {
2261
- lastTextContent = block.text;
2262
- } else if (block.type === "thinking" && block.thinking) {
2263
- lastThinkingContent = block.thinking;
2264
- } else if (block.type === "toolCall" || block.type === "serverToolUse") {
2265
- // Collect tool blocks for externalToolExecution rendering
2266
- 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
+ }
2267
2389
  }
2390
+ break;
2268
2391
  }
2269
- }
2270
2392
 
2271
- // Extract tool results from the SDK's synthetic user message
2272
- // and attach to corresponding tool call blocks immediately.
2273
- for (const { toolUseId, result } of extractToolResultsFromSdkUserMessage(msg as SDKUserMessage)) {
2274
- toolResultsById.set(toolUseId, result);
2275
- }
2276
- attachExternalResultsToToolBlocks(intermediateToolBlocks, toolResultsById);
2277
-
2278
- // Push a synthetic toolcall_end for each tool call from this turn
2279
- // so the TUI can render tool results in real-time during the SDK
2280
- // session instead of waiting until the entire session completes.
2281
- if (builder) {
2282
- for (const block of builder.message.content) {
2283
- const extResult = (block as ToolCallWithExternalResult).externalResult;
2284
- if (!extResult) continue;
2285
- const contentIndex = builder.message.content.indexOf(block);
2286
- if (contentIndex < 0) continue;
2287
- // Push synthetic completion events with result attached so the
2288
- // chat-controller can update pending ToolExecutionComponents.
2289
- if (block.type === "toolCall") {
2290
- try {
2291
- await onExternalToolResult?.({
2292
- toolCall: block,
2293
- result: extResult,
2294
- });
2295
- } catch (error) {
2296
- 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
+ }
2297
2406
  }
2298
- stream.push({
2299
- type: "toolcall_end",
2300
- contentIndex,
2301
- toolCall: block,
2302
- partial: builder.message,
2303
- });
2304
- } else if (block.type === "serverToolUse") {
2305
- try {
2306
- await onExternalToolResult?.({
2307
- toolCall: serverToolUseToToolCallLike(block),
2308
- result: extResult,
2309
- });
2310
- } catch (error) {
2311
- 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
+ }
2312
2472
  }
2313
- stream.push({
2314
- type: "server_tool_use",
2315
- contentIndex,
2316
- partial: builder.message,
2317
- });
2318
2473
  }
2474
+
2475
+ builder = null;
2476
+ break;
2319
2477
  }
2320
- }
2321
2478
 
2322
- builder = null;
2323
- break;
2324
- }
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
+ };
2325
2502
 
2326
- // -- Result (terminal) --
2327
- case "result": {
2328
- const result = msg as SDKResultMessage;
2329
- const finalContent = buildFinalAssistantContent({
2330
- intermediateToolBlocks,
2331
- pendingContent: builder?.message.content,
2332
- toolResultsById,
2333
- lastThinkingContent,
2334
- lastTextContent,
2335
- fallbackResultText:
2336
- result.subtype === "success" && result.result ? result.result : undefined,
2337
- });
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
+ }
2338
2511
 
2339
- const finalMessage: AssistantMessage = {
2340
- role: "assistant",
2341
- content: finalContent,
2342
- api: "anthropic-messages",
2343
- provider: "claude-code",
2344
- model: modelId,
2345
- usage: mapUsage(result.usage, result.total_cost_usd),
2346
- stopReason: result.is_error ? "error" : "stop",
2347
- timestamp: Date.now(),
2348
- };
2349
-
2350
- if (result.is_error) {
2351
- finalMessage.errorMessage = getResultErrorMessage(result);
2352
- stream.push({ type: "error", reason: "error", error: finalMessage });
2353
- } else {
2354
- stream.push({ type: "done", reason: "stop", message: finalMessage });
2512
+ default:
2513
+ break;
2355
2514
  }
2356
- return;
2515
+ }
2516
+ } finally {
2517
+ options?.signal?.removeEventListener("abort", forwardAbort);
2357
2518
  }
2358
2519
 
2359
- default:
2360
- 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;
2361
2527
  }
2528
+ } finally {
2529
+ if (trackWorkflowMcpSdk) endWorkflowMcpSdkSession();
2362
2530
  }
2363
2531
 
2364
2532
  // Generator exhaustion without a terminal result is a stream interruption,