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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (631) hide show
  1. package/dist/cli-model-override.d.ts +15 -0
  2. package/dist/cli-model-override.js +21 -0
  3. package/dist/cli.js +1 -18
  4. package/dist/headless-events.js +7 -5
  5. package/dist/loader.js +6 -4
  6. package/dist/mcp-server.js +2 -1
  7. package/dist/register-agent-bundles.d.ts +11 -2
  8. package/dist/register-agent-bundles.js +18 -4
  9. package/dist/resource-loader.d.ts +10 -5
  10. package/dist/resource-loader.js +121 -6
  11. package/dist/resources/.managed-resources-content-hash +1 -1
  12. package/dist/resources/GSD-WORKFLOW.md +5 -4
  13. package/dist/resources/extensions/ask-user-questions.js +3 -2
  14. package/dist/resources/extensions/async-jobs/async-bash-tool.js +30 -64
  15. package/dist/resources/extensions/async-jobs/await-tool.js +80 -12
  16. package/dist/resources/extensions/async-jobs/index.js +65 -0
  17. package/dist/resources/extensions/async-jobs/job-manager.js +12 -1
  18. package/dist/resources/extensions/bg-shell/bg-shell-command.js +6 -6
  19. package/dist/resources/extensions/bg-shell/bg-shell-tool.js +10 -7
  20. package/dist/resources/extensions/bg-shell/overlay.js +9 -6
  21. package/dist/resources/extensions/bg-shell/process-manager.js +54 -25
  22. package/dist/resources/extensions/bg-shell/readiness-detector.js +11 -0
  23. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +447 -215
  24. package/dist/resources/extensions/claude-code-cli/turn-assembler.js +33 -1
  25. package/dist/resources/extensions/gsd/auto/closeout.js +215 -0
  26. package/dist/resources/extensions/gsd/auto/custom-verify-retry-store.js +17 -2
  27. package/dist/resources/extensions/gsd/auto/detect-stuck.js +33 -13
  28. package/dist/resources/extensions/gsd/auto/dispatch-history.js +120 -0
  29. package/dist/resources/extensions/gsd/auto/dispatch-key.js +37 -0
  30. package/dist/resources/extensions/gsd/auto/dispatch.js +365 -0
  31. package/dist/resources/extensions/gsd/auto/finalize.js +347 -0
  32. package/dist/resources/extensions/gsd/auto/loop.js +7 -1
  33. package/dist/resources/extensions/gsd/auto/milestone-lease-reclaim.js +56 -0
  34. package/dist/resources/extensions/gsd/auto/orchestrator.js +174 -69
  35. package/dist/resources/extensions/gsd/auto/phase-helpers.js +146 -0
  36. package/dist/resources/extensions/gsd/auto/phases.js +17 -2329
  37. package/dist/resources/extensions/gsd/auto/pre-dispatch.js +534 -0
  38. package/dist/resources/extensions/gsd/auto/session.js +3 -0
  39. package/dist/resources/extensions/gsd/auto/unit-phase.js +694 -0
  40. package/dist/resources/extensions/gsd/auto/workflow-unit-dispatch.js +1 -1
  41. package/dist/resources/extensions/gsd/auto/worktree-safety-phase.js +125 -0
  42. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +11 -34
  43. package/dist/resources/extensions/gsd/auto-dispatch.js +50 -58
  44. package/dist/resources/extensions/gsd/auto-model-selection.js +36 -13
  45. package/dist/resources/extensions/gsd/auto-post-unit.js +30 -12
  46. package/dist/resources/extensions/gsd/auto-prompts.js +78 -19
  47. package/dist/resources/extensions/gsd/auto-start.js +35 -15
  48. package/dist/resources/extensions/gsd/auto-unit-closeout.js +45 -21
  49. package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +5 -4
  50. package/dist/resources/extensions/gsd/auto-verification.js +23 -30
  51. package/dist/resources/extensions/gsd/auto-worktree.js +15 -2
  52. package/dist/resources/extensions/gsd/auto.js +52 -2
  53. package/dist/resources/extensions/gsd/blocked-models.js +28 -0
  54. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +26 -6
  55. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +60 -13
  56. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +2 -2
  57. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +145 -50
  58. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +302 -80
  59. package/dist/resources/extensions/gsd/browser-daemon-auto-prep.js +83 -0
  60. package/dist/resources/extensions/gsd/closeout-wizard.js +92 -0
  61. package/dist/resources/extensions/gsd/commands/context.js +16 -2
  62. package/dist/resources/extensions/gsd/commands-handlers.js +46 -3
  63. package/dist/resources/extensions/gsd/commands-mcp-status.js +2 -2
  64. package/dist/resources/extensions/gsd/commands-workflow-templates.js +9 -2
  65. package/dist/resources/extensions/gsd/consent-question.js +353 -0
  66. package/dist/resources/extensions/gsd/consent-verdict.js +63 -0
  67. package/dist/resources/extensions/gsd/constants.js +0 -2
  68. package/dist/resources/extensions/gsd/crash-recovery.js +8 -3
  69. package/dist/resources/extensions/gsd/db/engine.js +5 -3
  70. package/dist/resources/extensions/gsd/db/queries.js +56 -0
  71. package/dist/resources/extensions/gsd/db-writer.js +8 -17
  72. package/dist/resources/extensions/gsd/dispatch-guard.js +10 -35
  73. package/dist/resources/extensions/gsd/doctor-engine-checks.js +5 -5
  74. package/dist/resources/extensions/gsd/doctor-environment.js +256 -125
  75. package/dist/resources/extensions/gsd/doctor-git-checks.js +2 -18
  76. package/dist/resources/extensions/gsd/engine-hook-contract.js +70 -0
  77. package/dist/resources/extensions/gsd/exec-sandbox.js +30 -10
  78. package/dist/resources/extensions/gsd/files.js +33 -19
  79. package/dist/resources/extensions/gsd/gsd-command-home.js +22 -12
  80. package/dist/resources/extensions/gsd/gsd-db.js +11 -8
  81. package/dist/resources/extensions/gsd/guidance.js +60 -0
  82. package/dist/resources/extensions/gsd/guided-flow.js +93 -4
  83. package/dist/resources/extensions/gsd/health-widget.js +87 -28
  84. package/dist/resources/extensions/gsd/markdown-renderer.js +10 -0
  85. package/dist/resources/extensions/gsd/mcp-bridge.js +10 -0
  86. package/dist/resources/extensions/gsd/memory-relations.js +1 -1
  87. package/dist/resources/extensions/gsd/milestone-closeout.js +85 -24
  88. package/dist/resources/extensions/gsd/milestone-planning-persistence.js +2 -2
  89. package/dist/resources/extensions/gsd/milestone-reopen-events.js +3 -5
  90. package/dist/resources/extensions/gsd/milestone-settlement.js +2 -2
  91. package/dist/resources/extensions/gsd/notifications.js +12 -7
  92. package/dist/resources/extensions/gsd/parsers-legacy.js +16 -4
  93. package/dist/resources/extensions/gsd/preferences-models.js +2 -2
  94. package/dist/resources/extensions/gsd/projection-flush.js +7 -0
  95. package/dist/resources/extensions/gsd/prompts/complete-slice.md +4 -4
  96. package/dist/resources/extensions/gsd/prompts/execute-task.md +3 -2
  97. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  98. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  99. package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -1
  100. package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
  101. package/dist/resources/extensions/gsd/prompts/refine-slice.md +1 -1
  102. package/dist/resources/extensions/gsd/prompts/replan-slice.md +1 -1
  103. package/dist/resources/extensions/gsd/prompts/research-milestone.md +1 -1
  104. package/dist/resources/extensions/gsd/prompts/research-slice.md +1 -1
  105. package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  106. package/dist/resources/extensions/gsd/prompts/run-uat.md +9 -5
  107. package/dist/resources/extensions/gsd/prompts/system.md +5 -2
  108. package/dist/resources/extensions/gsd/prompts/triage-captures.md +1 -1
  109. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +1 -1
  110. package/dist/resources/extensions/gsd/prompts/workflow-start.md +2 -1
  111. package/dist/resources/extensions/gsd/reactive-graph.js +8 -1
  112. package/dist/resources/extensions/gsd/roadmap-slices.js +25 -3
  113. package/dist/resources/extensions/gsd/safety/destructive-confirmation.js +108 -0
  114. package/dist/resources/extensions/gsd/session-lock.js +1 -1
  115. package/dist/resources/extensions/gsd/skill-activation.js +3 -6
  116. package/dist/resources/extensions/gsd/state.js +11 -2
  117. package/dist/resources/extensions/gsd/tool-contract.js +14 -3
  118. package/dist/resources/extensions/gsd/tool-presentation-plan.js +4 -4
  119. package/dist/resources/extensions/gsd/tool-surface-readiness.js +83 -31
  120. package/dist/resources/extensions/gsd/tools/complete-milestone.js +3 -2
  121. package/dist/resources/extensions/gsd/tools/complete-slice.js +22 -12
  122. package/dist/resources/extensions/gsd/tools/complete-task.js +65 -2
  123. package/dist/resources/extensions/gsd/tools/exec-tool.js +5 -0
  124. package/dist/resources/extensions/gsd/tools/plan-slice.js +2 -2
  125. package/dist/resources/extensions/gsd/tools/plan-task.js +2 -2
  126. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +2 -2
  127. package/dist/resources/extensions/gsd/tools/reopen-milestone.js +2 -2
  128. package/dist/resources/extensions/gsd/tools/reopen-slice.js +2 -2
  129. package/dist/resources/extensions/gsd/tools/reopen-task.js +2 -2
  130. package/dist/resources/extensions/gsd/tools/replan-slice.js +2 -2
  131. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +67 -2
  132. package/dist/resources/extensions/gsd/uat-policy.js +40 -15
  133. package/dist/resources/extensions/gsd/unit-context-composer.js +65 -0
  134. package/dist/resources/extensions/gsd/unit-registry.js +34 -4
  135. package/dist/resources/extensions/gsd/verdict-parser.js +1 -1
  136. package/dist/resources/extensions/gsd/verification-verdict.js +2 -1
  137. package/dist/resources/extensions/gsd/workflow-event-ledger.js +91 -0
  138. package/dist/resources/extensions/gsd/workflow-event-vocabulary.js +46 -0
  139. package/dist/resources/extensions/gsd/workflow-events.js +6 -18
  140. package/dist/resources/extensions/gsd/workflow-mcp-auto-prep.js +2 -0
  141. package/dist/resources/extensions/gsd/workflow-mcp-readiness-cache.js +105 -0
  142. package/dist/resources/extensions/gsd/workflow-reconcile.js +21 -56
  143. package/dist/resources/extensions/gsd/worktree-lifecycle.js +3 -2
  144. package/dist/resources/extensions/gsd/worktree-manager.js +7 -1
  145. package/dist/resources/extensions/gsd/worktree-safety.js +28 -26
  146. package/dist/resources/extensions/gsd/worktree.js +8 -1
  147. package/dist/resources/extensions/mcp-client/manager.js +6 -1
  148. package/dist/resources/extensions/shared/gsd-browser-cli.js +45 -3
  149. package/dist/resources/shared/gsd-browser-path-sync.js +214 -0
  150. package/dist/resources/shared/package-manager-detection.js +1 -1
  151. package/dist/resources/shared/package.json +3 -0
  152. package/dist/resources/skills/create-skill/SKILL.md +3 -0
  153. package/dist/resources/skills/create-skill/references/skill-structure.md +1 -0
  154. package/dist/runtime-checks.d.ts +10 -0
  155. package/dist/runtime-checks.js +27 -0
  156. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  157. package/dist/update-check.d.ts +2 -0
  158. package/dist/update-check.js +24 -1
  159. package/dist/update-cmd.js +20 -3
  160. package/dist/web/standalone/.next/BUILD_ID +1 -1
  161. package/dist/web/standalone/.next/app-path-routes-manifest.json +6 -6
  162. package/dist/web/standalone/.next/build-manifest.json +3 -3
  163. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  164. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  165. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  166. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  167. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  168. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  169. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  170. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  171. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  172. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  173. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  174. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  175. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  176. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  177. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  178. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  179. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  180. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  181. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/update/route.js.nft.json +1 -1
  183. package/dist/web/standalone/.next/server/app/index.html +1 -1
  184. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  185. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  186. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  187. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  188. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  189. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  190. package/dist/web/standalone/.next/server/app-paths-manifest.json +6 -6
  191. package/dist/web/standalone/.next/server/chunks/8357.js +2 -2
  192. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  194. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  195. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  196. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  197. package/dist/web/standalone/.next/static/chunks/{796.cf859a427a2cb2ac.js → 796.e0bdc932325d7e03.js} +1 -1
  198. package/dist/web/standalone/.next/static/chunks/{webpack-fbea77b5f9953368.js → webpack-f0285ce91d4ec9ef.js} +1 -1
  199. package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
  200. package/dist/web/standalone/node_modules/postcss/lib/container.js +26 -18
  201. package/dist/web/standalone/node_modules/postcss/lib/css-syntax-error.js +47 -14
  202. package/dist/web/standalone/node_modules/postcss/lib/declaration.js +4 -4
  203. package/dist/web/standalone/node_modules/postcss/lib/fromJSON.js +3 -3
  204. package/dist/web/standalone/node_modules/postcss/lib/input.js +54 -29
  205. package/dist/web/standalone/node_modules/postcss/lib/lazy-result.js +47 -37
  206. package/dist/web/standalone/node_modules/postcss/lib/map-generator.js +26 -9
  207. package/dist/web/standalone/node_modules/postcss/lib/no-work-result.js +57 -55
  208. package/dist/web/standalone/node_modules/postcss/lib/node.js +99 -31
  209. package/dist/web/standalone/node_modules/postcss/lib/parse.js +1 -1
  210. package/dist/web/standalone/node_modules/postcss/lib/parser.js +10 -9
  211. package/dist/web/standalone/node_modules/postcss/lib/postcss.js +12 -12
  212. package/dist/web/standalone/node_modules/postcss/lib/previous-map.js +30 -11
  213. package/dist/web/standalone/node_modules/postcss/lib/processor.js +7 -7
  214. package/dist/web/standalone/node_modules/postcss/lib/result.js +5 -5
  215. package/dist/web/standalone/node_modules/postcss/lib/rule.js +6 -6
  216. package/dist/web/standalone/node_modules/postcss/lib/stringifier.js +69 -28
  217. package/dist/web/standalone/node_modules/postcss/lib/tokenize.js +6 -2
  218. package/dist/web/standalone/node_modules/postcss/package.json +48 -48
  219. package/package.json +3 -3
  220. package/packages/cloud-mcp-gateway/package.json +2 -2
  221. package/packages/contracts/dist/rpc.d.ts +1 -0
  222. package/packages/contracts/dist/rpc.d.ts.map +1 -1
  223. package/packages/contracts/dist/rpc.js.map +1 -1
  224. package/packages/contracts/package.json +1 -1
  225. package/packages/daemon/package.json +4 -4
  226. package/packages/gsd-agent-core/dist/sdk.d.ts.map +1 -1
  227. package/packages/gsd-agent-core/dist/sdk.js +6 -4
  228. package/packages/gsd-agent-core/dist/sdk.js.map +1 -1
  229. package/packages/gsd-agent-core/package.json +5 -5
  230. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts +2 -0
  231. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  232. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js +10 -0
  233. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js.map +1 -1
  234. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +13 -0
  235. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  236. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +55 -6
  237. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  238. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts +2 -0
  239. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts.map +1 -1
  240. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js +34 -5
  241. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js.map +1 -1
  242. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  243. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +7 -0
  244. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  245. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
  246. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js +8 -1
  247. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  248. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.d.ts.map +1 -1
  249. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js +11 -1
  250. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js.map +1 -1
  251. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts +1 -0
  252. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  253. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +12 -0
  254. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
  255. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.d.ts.map +1 -1
  256. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js +4 -4
  257. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js.map +1 -1
  258. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.d.ts.map +1 -1
  259. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js +4 -0
  260. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js.map +1 -1
  261. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  262. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +3 -1
  263. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -1
  264. package/packages/gsd-agent-modes/package.json +7 -7
  265. package/packages/mcp-server/README.md +12 -3
  266. package/packages/mcp-server/dist/cli-runner.d.ts +40 -0
  267. package/packages/mcp-server/dist/cli-runner.d.ts.map +1 -0
  268. package/packages/mcp-server/dist/cli-runner.js +137 -0
  269. package/packages/mcp-server/dist/cli-runner.js.map +1 -0
  270. package/packages/mcp-server/dist/cli.js +2 -53
  271. package/packages/mcp-server/dist/cli.js.map +1 -1
  272. package/packages/mcp-server/dist/moonshot-tool-schema.d.ts +29 -0
  273. package/packages/mcp-server/dist/moonshot-tool-schema.d.ts.map +1 -0
  274. package/packages/mcp-server/dist/moonshot-tool-schema.js +50 -0
  275. package/packages/mcp-server/dist/moonshot-tool-schema.js.map +1 -0
  276. package/packages/mcp-server/dist/pid-registry.d.ts +46 -0
  277. package/packages/mcp-server/dist/pid-registry.d.ts.map +1 -0
  278. package/packages/mcp-server/dist/pid-registry.js +452 -0
  279. package/packages/mcp-server/dist/pid-registry.js.map +1 -0
  280. package/packages/mcp-server/dist/probe-mode.d.ts +4 -0
  281. package/packages/mcp-server/dist/probe-mode.d.ts.map +1 -0
  282. package/packages/mcp-server/dist/probe-mode.js +10 -0
  283. package/packages/mcp-server/dist/probe-mode.js.map +1 -0
  284. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  285. package/packages/mcp-server/dist/server.js +4 -0
  286. package/packages/mcp-server/dist/server.js.map +1 -1
  287. package/packages/mcp-server/dist/stdio-watchdog.d.ts +8 -0
  288. package/packages/mcp-server/dist/stdio-watchdog.d.ts.map +1 -0
  289. package/packages/mcp-server/dist/stdio-watchdog.js +40 -0
  290. package/packages/mcp-server/dist/stdio-watchdog.js.map +1 -0
  291. package/packages/mcp-server/dist/workflow-tools.d.ts +18 -18
  292. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  293. package/packages/mcp-server/dist/workflow-tools.js +161 -81
  294. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  295. package/packages/mcp-server/package.json +5 -4
  296. package/packages/native/package.json +1 -1
  297. package/packages/pi-agent-core/dist/agent-loop.js +43 -2
  298. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  299. package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts +1 -0
  300. package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts.map +1 -1
  301. package/packages/pi-agent-core/dist/harness/env/nodejs.js +34 -3
  302. package/packages/pi-agent-core/dist/harness/env/nodejs.js.map +1 -1
  303. package/packages/pi-agent-core/dist/index.d.ts +1 -0
  304. package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
  305. package/packages/pi-agent-core/dist/index.js +3 -0
  306. package/packages/pi-agent-core/dist/index.js.map +1 -1
  307. package/packages/pi-agent-core/package.json +1 -1
  308. package/packages/pi-ai/README.md +1 -0
  309. package/packages/pi-ai/dist/image-models.generated.d.ts +2 -2
  310. package/packages/pi-ai/dist/image-models.generated.js +6 -6
  311. package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
  312. package/packages/pi-ai/dist/index.d.ts +2 -0
  313. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  314. package/packages/pi-ai/dist/index.js +2 -0
  315. package/packages/pi-ai/dist/index.js.map +1 -1
  316. package/packages/pi-ai/dist/models.generated.d.ts +419 -221
  317. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  318. package/packages/pi-ai/dist/models.generated.js +460 -261
  319. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  320. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  321. package/packages/pi-ai/dist/providers/anthropic.js +12 -7
  322. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  323. package/packages/pi-ai/dist/providers/google-shared.d.ts +5 -0
  324. package/packages/pi-ai/dist/providers/google-shared.d.ts.map +1 -1
  325. package/packages/pi-ai/dist/providers/google-shared.js +12 -3
  326. package/packages/pi-ai/dist/providers/google-shared.js.map +1 -1
  327. package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
  328. package/packages/pi-ai/dist/providers/openai-completions.js +7 -3
  329. package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
  330. package/packages/pi-ai/dist/utils/moonshot-tool-schema.d.ts +9 -0
  331. package/packages/pi-ai/dist/utils/moonshot-tool-schema.d.ts.map +1 -0
  332. package/packages/pi-ai/dist/utils/moonshot-tool-schema.js +34 -0
  333. package/packages/pi-ai/dist/utils/moonshot-tool-schema.js.map +1 -0
  334. package/packages/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
  335. package/packages/pi-ai/dist/utils/oauth/github-copilot.js +6 -2
  336. package/packages/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
  337. package/packages/pi-ai/package.json +3 -2
  338. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +2 -2
  339. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  340. package/packages/pi-coding-agent/dist/core/auth-storage.js +19 -13
  341. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  342. package/packages/pi-coding-agent/dist/core/provider-readiness.d.ts.map +1 -1
  343. package/packages/pi-coding-agent/dist/core/provider-readiness.js +13 -6
  344. package/packages/pi-coding-agent/dist/core/provider-readiness.js.map +1 -1
  345. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +3 -0
  346. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  347. package/packages/pi-coding-agent/dist/core/settings-manager.js +11 -0
  348. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  349. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts +11 -0
  350. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
  351. package/packages/pi-coding-agent/dist/core/tools/bash.js +53 -11
  352. package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
  353. package/packages/pi-coding-agent/dist/index.d.ts +1 -1
  354. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  355. package/packages/pi-coding-agent/dist/index.js +1 -1
  356. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  357. package/packages/pi-coding-agent/dist/theme/theme.d.ts.map +1 -1
  358. package/packages/pi-coding-agent/dist/theme/theme.js +45 -17
  359. package/packages/pi-coding-agent/dist/theme/theme.js.map +1 -1
  360. package/packages/pi-coding-agent/dist/utils/shell.d.ts +28 -2
  361. package/packages/pi-coding-agent/dist/utils/shell.d.ts.map +1 -1
  362. package/packages/pi-coding-agent/dist/utils/shell.js +56 -10
  363. package/packages/pi-coding-agent/dist/utils/shell.js.map +1 -1
  364. package/packages/pi-coding-agent/package.json +7 -7
  365. package/packages/pi-tui/dist/index.d.ts +1 -1
  366. package/packages/pi-tui/dist/index.d.ts.map +1 -1
  367. package/packages/pi-tui/dist/index.js +1 -1
  368. package/packages/pi-tui/dist/index.js.map +1 -1
  369. package/packages/pi-tui/dist/terminal-image.d.ts +33 -0
  370. package/packages/pi-tui/dist/terminal-image.d.ts.map +1 -1
  371. package/packages/pi-tui/dist/terminal-image.js +54 -2
  372. package/packages/pi-tui/dist/terminal-image.js.map +1 -1
  373. package/packages/pi-tui/dist/tui.d.ts +8 -0
  374. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  375. package/packages/pi-tui/dist/tui.js +63 -18
  376. package/packages/pi-tui/dist/tui.js.map +1 -1
  377. package/packages/pi-tui/dist/utils.d.ts.map +1 -1
  378. package/packages/pi-tui/dist/utils.js +110 -36
  379. package/packages/pi-tui/dist/utils.js.map +1 -1
  380. package/packages/pi-tui/package.json +2 -2
  381. package/packages/rpc-client/package.json +2 -2
  382. package/pkg/dist/theme/theme.d.ts.map +1 -1
  383. package/pkg/dist/theme/theme.js +45 -17
  384. package/pkg/dist/theme/theme.js.map +1 -1
  385. package/pkg/package.json +1 -1
  386. package/src/resources/GSD-WORKFLOW.md +5 -4
  387. package/src/resources/extensions/ask-user-questions.ts +7 -2
  388. package/src/resources/extensions/async-jobs/async-bash-cancel.test.ts +360 -0
  389. package/src/resources/extensions/async-jobs/async-bash-tool.ts +33 -56
  390. package/src/resources/extensions/async-jobs/await-tool.test.ts +139 -0
  391. package/src/resources/extensions/async-jobs/await-tool.ts +82 -12
  392. package/src/resources/extensions/async-jobs/index.ts +79 -0
  393. package/src/resources/extensions/async-jobs/job-manager.ts +21 -1
  394. package/src/resources/extensions/bg-shell/bg-shell-command.ts +6 -6
  395. package/src/resources/extensions/bg-shell/bg-shell-tool.ts +10 -6
  396. package/src/resources/extensions/bg-shell/overlay.ts +9 -5
  397. package/src/resources/extensions/bg-shell/process-manager.ts +50 -25
  398. package/src/resources/extensions/bg-shell/readiness-detector.ts +12 -0
  399. package/src/resources/extensions/bg-shell/tests/lifecycle-and-utilities.test.ts +48 -1
  400. package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +40 -1
  401. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +531 -226
  402. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +672 -7
  403. package/src/resources/extensions/claude-code-cli/turn-assembler.ts +38 -1
  404. package/src/resources/extensions/gsd/auto/closeout.ts +309 -0
  405. package/src/resources/extensions/gsd/auto/custom-verify-retry-store.ts +21 -3
  406. package/src/resources/extensions/gsd/auto/detect-stuck.ts +32 -9
  407. package/src/resources/extensions/gsd/auto/dispatch-history.ts +168 -0
  408. package/src/resources/extensions/gsd/auto/dispatch-key.ts +39 -0
  409. package/src/resources/extensions/gsd/auto/dispatch.ts +449 -0
  410. package/src/resources/extensions/gsd/auto/finalize.ts +445 -0
  411. package/src/resources/extensions/gsd/auto/loop.ts +7 -1
  412. package/src/resources/extensions/gsd/auto/milestone-lease-reclaim.ts +74 -0
  413. package/src/resources/extensions/gsd/auto/orchestrator.ts +193 -71
  414. package/src/resources/extensions/gsd/auto/phase-helpers.ts +199 -0
  415. package/src/resources/extensions/gsd/auto/phases.ts +58 -3022
  416. package/src/resources/extensions/gsd/auto/pre-dispatch.ts +704 -0
  417. package/src/resources/extensions/gsd/auto/session.ts +3 -0
  418. package/src/resources/extensions/gsd/auto/unit-phase.ts +910 -0
  419. package/src/resources/extensions/gsd/auto/workflow-unit-dispatch.ts +1 -1
  420. package/src/resources/extensions/gsd/auto/worktree-safety-phase.ts +149 -0
  421. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +18 -48
  422. package/src/resources/extensions/gsd/auto-dispatch.ts +48 -61
  423. package/src/resources/extensions/gsd/auto-model-selection.ts +41 -12
  424. package/src/resources/extensions/gsd/auto-post-unit.ts +33 -12
  425. package/src/resources/extensions/gsd/auto-prompts.ts +115 -35
  426. package/src/resources/extensions/gsd/auto-start.ts +36 -18
  427. package/src/resources/extensions/gsd/auto-unit-closeout.ts +83 -28
  428. package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +4 -4
  429. package/src/resources/extensions/gsd/auto-verification.ts +26 -28
  430. package/src/resources/extensions/gsd/auto-worktree.ts +15 -2
  431. package/src/resources/extensions/gsd/auto.ts +64 -2
  432. package/src/resources/extensions/gsd/blocked-models.ts +49 -0
  433. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +34 -5
  434. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +79 -12
  435. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +2 -2
  436. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +163 -55
  437. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +350 -86
  438. package/src/resources/extensions/gsd/browser-daemon-auto-prep.ts +108 -0
  439. package/src/resources/extensions/gsd/closeout-wizard.ts +102 -0
  440. package/src/resources/extensions/gsd/commands/context.ts +16 -2
  441. package/src/resources/extensions/gsd/commands-handlers.ts +46 -3
  442. package/src/resources/extensions/gsd/commands-mcp-status.ts +2 -2
  443. package/src/resources/extensions/gsd/commands-workflow-templates.ts +11 -4
  444. package/src/resources/extensions/gsd/consent-question.ts +431 -0
  445. package/src/resources/extensions/gsd/consent-verdict.ts +86 -0
  446. package/src/resources/extensions/gsd/constants.ts +0 -3
  447. package/src/resources/extensions/gsd/crash-recovery.ts +10 -2
  448. package/src/resources/extensions/gsd/db/engine.ts +5 -3
  449. package/src/resources/extensions/gsd/db/queries.ts +66 -0
  450. package/src/resources/extensions/gsd/db-writer.ts +11 -19
  451. package/src/resources/extensions/gsd/dispatch-guard.ts +8 -31
  452. package/src/resources/extensions/gsd/doctor-engine-checks.ts +5 -4
  453. package/src/resources/extensions/gsd/doctor-environment.ts +267 -142
  454. package/src/resources/extensions/gsd/doctor-git-checks.ts +2 -19
  455. package/src/resources/extensions/gsd/engine-hook-contract.ts +79 -0
  456. package/src/resources/extensions/gsd/exec-sandbox.ts +49 -9
  457. package/src/resources/extensions/gsd/files.ts +33 -12
  458. package/src/resources/extensions/gsd/gsd-command-home.ts +13 -3
  459. package/src/resources/extensions/gsd/gsd-db.ts +13 -10
  460. package/src/resources/extensions/gsd/guidance.ts +78 -0
  461. package/src/resources/extensions/gsd/guided-flow.ts +145 -24
  462. package/src/resources/extensions/gsd/health-widget.ts +91 -27
  463. package/src/resources/extensions/gsd/markdown-renderer.ts +11 -0
  464. package/src/resources/extensions/gsd/mcp-bridge.ts +39 -0
  465. package/src/resources/extensions/gsd/memory-relations.ts +1 -1
  466. package/src/resources/extensions/gsd/milestone-closeout.ts +109 -24
  467. package/src/resources/extensions/gsd/milestone-planning-persistence.ts +2 -2
  468. package/src/resources/extensions/gsd/milestone-reopen-events.ts +3 -6
  469. package/src/resources/extensions/gsd/milestone-settlement.ts +2 -2
  470. package/src/resources/extensions/gsd/notifications.ts +13 -6
  471. package/src/resources/extensions/gsd/parsers-legacy.ts +16 -4
  472. package/src/resources/extensions/gsd/preferences-models.ts +2 -1
  473. package/src/resources/extensions/gsd/projection-flush.ts +20 -0
  474. package/src/resources/extensions/gsd/prompts/complete-slice.md +4 -4
  475. package/src/resources/extensions/gsd/prompts/execute-task.md +3 -2
  476. package/src/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  477. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  478. package/src/resources/extensions/gsd/prompts/quick-task.md +1 -1
  479. package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
  480. package/src/resources/extensions/gsd/prompts/refine-slice.md +1 -1
  481. package/src/resources/extensions/gsd/prompts/replan-slice.md +1 -1
  482. package/src/resources/extensions/gsd/prompts/research-milestone.md +1 -1
  483. package/src/resources/extensions/gsd/prompts/research-slice.md +1 -1
  484. package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  485. package/src/resources/extensions/gsd/prompts/run-uat.md +9 -5
  486. package/src/resources/extensions/gsd/prompts/system.md +5 -2
  487. package/src/resources/extensions/gsd/prompts/triage-captures.md +1 -1
  488. package/src/resources/extensions/gsd/prompts/validate-milestone.md +1 -1
  489. package/src/resources/extensions/gsd/prompts/workflow-start.md +2 -1
  490. package/src/resources/extensions/gsd/reactive-graph.ts +11 -1
  491. package/src/resources/extensions/gsd/roadmap-slices.ts +28 -3
  492. package/src/resources/extensions/gsd/safety/destructive-confirmation.ts +134 -0
  493. package/src/resources/extensions/gsd/session-lock.ts +1 -1
  494. package/src/resources/extensions/gsd/skill-activation.ts +3 -6
  495. package/src/resources/extensions/gsd/state.ts +12 -1
  496. package/src/resources/extensions/gsd/tests/auto-abort-pause-regression.test.ts +1 -1
  497. package/src/resources/extensions/gsd/tests/auto-blocked-remediation-message.test.ts +1 -1
  498. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +206 -22
  499. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +97 -1
  500. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +273 -37
  501. package/src/resources/extensions/gsd/tests/auto-pause-double-entry-guard.test.ts +1 -1
  502. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +77 -1
  503. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +2 -1
  504. package/src/resources/extensions/gsd/tests/auto-remote-session-lock-cleanup.test.ts +65 -3
  505. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +236 -0
  506. package/src/resources/extensions/gsd/tests/auto-unit-closeout.test.ts +169 -1
  507. package/src/resources/extensions/gsd/tests/blocked-models.test.ts +19 -0
  508. package/src/resources/extensions/gsd/tests/browser-daemon-auto-prep.test.ts +144 -0
  509. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +42 -0
  510. package/src/resources/extensions/gsd/tests/complete-task.test.ts +141 -5
  511. package/src/resources/extensions/gsd/tests/consent-question.test.ts +351 -0
  512. package/src/resources/extensions/gsd/tests/custom-verify-retry-store.test.ts +67 -0
  513. package/src/resources/extensions/gsd/tests/db-writer.test.ts +15 -4
  514. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +12 -11
  515. package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +36 -0
  516. package/src/resources/extensions/gsd/tests/destructive-confirmation.test.ts +303 -0
  517. package/src/resources/extensions/gsd/tests/discuss-routing-fixes.test.ts +12 -2
  518. package/src/resources/extensions/gsd/tests/dispatch-history.test.ts +328 -0
  519. package/src/resources/extensions/gsd/tests/dist-redirect.mjs +8 -0
  520. package/src/resources/extensions/gsd/tests/doctor-git-checks-terminal.test.ts +73 -0
  521. package/src/resources/extensions/gsd/tests/dynamic-bash-no-cap.test.ts +132 -0
  522. package/src/resources/extensions/gsd/tests/engine-hook-contract.test.ts +148 -0
  523. package/src/resources/extensions/gsd/tests/engine-interfaces-contract.test.ts +117 -91
  524. package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +113 -0
  525. package/src/resources/extensions/gsd/tests/exec-graceful-kill.test.ts +193 -0
  526. package/src/resources/extensions/gsd/tests/exec-tool.test.ts +29 -1
  527. package/src/resources/extensions/gsd/tests/gsd-command-home.test.ts +120 -0
  528. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +27 -0
  529. package/src/resources/extensions/gsd/tests/guidance.test.ts +23 -0
  530. package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +18 -6
  531. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +15 -0
  532. package/src/resources/extensions/gsd/tests/integration/doctor-environment-async.test.ts +104 -0
  533. package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +217 -0
  534. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +47 -16
  535. package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +3 -1
  536. package/src/resources/extensions/gsd/tests/mcp-readiness-preflight.test.ts +205 -0
  537. package/src/resources/extensions/gsd/tests/mcp-status.test.ts +6 -5
  538. package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +95 -4
  539. package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +1 -1
  540. package/src/resources/extensions/gsd/tests/milestone-report-path.test.ts +1 -1
  541. package/src/resources/extensions/gsd/tests/milestone-settlement.test.ts +92 -0
  542. package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +1 -1
  543. package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +32 -1
  544. package/src/resources/extensions/gsd/tests/notifications.test.ts +64 -9
  545. package/src/resources/extensions/gsd/tests/oauth-api-model-routing.test.ts +167 -0
  546. package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +18 -0
  547. package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +2 -2
  548. package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +143 -0
  549. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +1 -1
  550. package/src/resources/extensions/gsd/tests/phases-terminal-complete-idempotent.test.ts +242 -0
  551. package/src/resources/extensions/gsd/tests/plan-gate-failed-doctor-heal-hint.test.ts +3 -3
  552. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +63 -2
  553. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +10 -2
  554. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +124 -6
  555. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +2 -4
  556. package/src/resources/extensions/gsd/tests/remote-notification-from-desktop.test.ts +31 -81
  557. package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +68 -0
  558. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +26 -2
  559. package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +170 -48
  560. package/src/resources/extensions/gsd/tests/skill-activation.test.ts +20 -17
  561. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +7 -3
  562. package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +1 -1
  563. package/src/resources/extensions/gsd/tests/teardown-chdir-failure-clears-registry.test.ts +17 -0
  564. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +45 -2
  565. package/src/resources/extensions/gsd/tests/tool-surface-readiness.test.ts +184 -10
  566. package/src/resources/extensions/gsd/tests/tool-unavailable-retry.test.ts +33 -0
  567. package/src/resources/extensions/gsd/tests/transport-gate-double-complete.test.ts +139 -0
  568. package/src/resources/extensions/gsd/tests/uat-policy.test.ts +88 -0
  569. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +44 -0
  570. package/src/resources/extensions/gsd/tests/uok-audit-unified.test.ts +8 -0
  571. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +1 -1
  572. package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +2 -0
  573. package/src/resources/extensions/gsd/tests/workflow-events.test.ts +19 -0
  574. package/src/resources/extensions/gsd/tests/workflow-mcp-readiness-cache.test.ts +119 -0
  575. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +65 -2
  576. package/src/resources/extensions/gsd/tests/workflow-phase-contract-matrix.test.ts +332 -0
  577. package/src/resources/extensions/gsd/tests/workflow-reconcile.test.ts +20 -0
  578. package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +92 -0
  579. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +273 -38
  580. package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +1 -1
  581. package/src/resources/extensions/gsd/tests/worktree-project-root-degrade.test.ts +1 -1
  582. package/src/resources/extensions/gsd/tests/worktree-safety-phase.test.ts +100 -0
  583. package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +72 -0
  584. package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +22 -0
  585. package/src/resources/extensions/gsd/tests/worktree.test.ts +18 -0
  586. package/src/resources/extensions/gsd/tests/write-gate-seam.test.ts +358 -0
  587. package/src/resources/extensions/gsd/tests/write-gate.test.ts +67 -1
  588. package/src/resources/extensions/gsd/tool-contract.ts +38 -3
  589. package/src/resources/extensions/gsd/tool-presentation-plan.ts +4 -4
  590. package/src/resources/extensions/gsd/tool-surface-readiness.ts +126 -19
  591. package/src/resources/extensions/gsd/tools/complete-milestone.ts +3 -2
  592. package/src/resources/extensions/gsd/tools/complete-slice.ts +22 -12
  593. package/src/resources/extensions/gsd/tools/complete-task.ts +90 -2
  594. package/src/resources/extensions/gsd/tools/exec-tool.ts +4 -0
  595. package/src/resources/extensions/gsd/tools/plan-slice.ts +2 -2
  596. package/src/resources/extensions/gsd/tools/plan-task.ts +2 -2
  597. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +2 -2
  598. package/src/resources/extensions/gsd/tools/reopen-milestone.ts +2 -2
  599. package/src/resources/extensions/gsd/tools/reopen-slice.ts +2 -2
  600. package/src/resources/extensions/gsd/tools/reopen-task.ts +2 -2
  601. package/src/resources/extensions/gsd/tools/replan-slice.ts +2 -2
  602. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +81 -2
  603. package/src/resources/extensions/gsd/uat-policy.ts +60 -15
  604. package/src/resources/extensions/gsd/unit-context-composer.ts +99 -0
  605. package/src/resources/extensions/gsd/unit-registry.ts +34 -4
  606. package/src/resources/extensions/gsd/verdict-parser.ts +1 -1
  607. package/src/resources/extensions/gsd/verification-verdict.ts +4 -2
  608. package/src/resources/extensions/gsd/workflow-event-ledger.ts +131 -0
  609. package/src/resources/extensions/gsd/workflow-event-vocabulary.ts +59 -0
  610. package/src/resources/extensions/gsd/workflow-events.ts +12 -20
  611. package/src/resources/extensions/gsd/workflow-mcp-auto-prep.ts +2 -0
  612. package/src/resources/extensions/gsd/workflow-mcp-readiness-cache.ts +150 -0
  613. package/src/resources/extensions/gsd/workflow-reconcile.ts +29 -62
  614. package/src/resources/extensions/gsd/worktree-lifecycle.ts +3 -8
  615. package/src/resources/extensions/gsd/worktree-manager.ts +6 -1
  616. package/src/resources/extensions/gsd/worktree-safety.ts +41 -39
  617. package/src/resources/extensions/gsd/worktree.ts +7 -1
  618. package/src/resources/extensions/mcp-client/manager.ts +7 -1
  619. package/src/resources/extensions/shared/gsd-browser-cli.ts +54 -3
  620. package/src/resources/shared/gsd-browser-path-sync.ts +273 -0
  621. package/src/resources/shared/package-manager-detection.ts +1 -1
  622. package/src/resources/shared/package.json +3 -0
  623. package/src/resources/skills/create-skill/SKILL.md +3 -0
  624. package/src/resources/skills/create-skill/references/skill-structure.md +1 -0
  625. package/dist/resources/extensions/gsd/user-input-boundary.js +0 -218
  626. package/dist/resources/skills/gsd-browser/SKILL.md +0 -41
  627. package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +0 -173
  628. package/src/resources/extensions/gsd/user-input-boundary.ts +0 -216
  629. package/src/resources/skills/gsd-browser/SKILL.md +0 -41
  630. /package/dist/web/standalone/.next/static/{AOpDeK_gJHU8OZjRo31gQ → pZbHa49xI-knmKlphIRq0}/_buildManifest.js +0 -0
  631. /package/dist/web/standalone/.next/static/{AOpDeK_gJHU8OZjRo31gQ → pZbHa49xI-knmKlphIRq0}/_ssgManifest.js +0 -0
@@ -1,22 +1,107 @@
1
1
  // Project/App: gsd-pi
2
2
  // File Purpose: Shared closeout detection and merge actions for /gsd home and smart entry.
3
+ import { existsSync, readdirSync, statSync } from "node:fs";
4
+ import { join } from "node:path";
3
5
  import { setAutoOutcomeWidget } from "./auto-dashboard.js";
4
6
  import { invalidateAllCaches } from "./cache.js";
7
+ import { isDbAvailable } from "./db/engine.js";
8
+ import { getMilestone } from "./db/queries.js";
9
+ import { MILESTONE_ID_RE } from "./milestone-ids.js";
5
10
  import { mergeCompletedMilestone } from "./parallel-merge.js";
6
11
  import { cleanupQuickBranch, detectStrandedQuickBranch } from "./quick.js";
12
+ import { isClosedStatus } from "./status-guards.js";
7
13
  import { findUnmergedCompletedMilestones, } from "./unmerged-milestone-guard.js";
8
14
  import { appendRequirementsBacklogToSummary } from "./requirements-backlog.js";
15
+ import { nativeBranchList, nativeIsRepo } from "./native-git-bridge.js";
16
+ import { allWorktreesDirs } from "./worktree-manager.js";
9
17
  const MILESTONE_MERGE_CLOSEOUT_COMMANDS = [
10
18
  "/gsd status for overview",
11
19
  "/gsd visualize to inspect",
12
20
  "/gsd notifications for history",
13
21
  "/gsd start for new work",
14
22
  ];
23
+ function listMilestoneWorktreeIds(basePath) {
24
+ const ids = new Set();
25
+ for (const wtDir of allWorktreesDirs(basePath)) {
26
+ if (!existsSync(wtDir))
27
+ continue;
28
+ for (const entry of readdirSync(wtDir)) {
29
+ if (!MILESTONE_ID_RE.test(entry))
30
+ continue;
31
+ try {
32
+ if (statSync(join(wtDir, entry)).isDirectory())
33
+ ids.add(entry);
34
+ }
35
+ catch {
36
+ // skip unreadable entries
37
+ }
38
+ }
39
+ }
40
+ return [...ids].sort();
41
+ }
42
+ function listMilestoneBranchIds(basePath) {
43
+ try {
44
+ return nativeBranchList(basePath, "milestone/*")
45
+ .map((branch) => branch.replace(/^milestone\//, ""))
46
+ .filter((id) => MILESTONE_ID_RE.test(id))
47
+ .sort();
48
+ }
49
+ catch {
50
+ return [];
51
+ }
52
+ }
53
+ /**
54
+ * A milestone ID is "stranded residue" only when its worktree/branch artifacts
55
+ * exist for a milestone the DB does not consider currently in flight — i.e. the
56
+ * row is closed (complete/done/skipped/closed) or absent. Active, pending,
57
+ * blocked, parked, queued, and deferred rows describe normal in-flight or
58
+ * intentionally-preserved state, never residue. Returning `false` skips the ID;
59
+ * returning `true` keeps it in the hint.
60
+ */
61
+ function isStrandedMilestoneId(milestoneId) {
62
+ if (!isDbAvailable())
63
+ return true;
64
+ const row = getMilestone(milestoneId);
65
+ if (!row)
66
+ return true;
67
+ return isClosedStatus(row.status);
68
+ }
69
+ /** Surface stranded milestone git residue when closeout guards did not classify it. */
70
+ export function detectIdleMilestoneResidueHint(basePath) {
71
+ if (!nativeIsRepo(basePath))
72
+ return null;
73
+ const gsdDir = join(basePath, ".gsd");
74
+ const dbPath = join(gsdDir, "gsd.db");
75
+ if (!existsSync(gsdDir) || !existsSync(dbPath)) {
76
+ return {
77
+ milestoneIds: [],
78
+ message: "This git repo has no local GSD workflow database (.gsd/gsd.db). " +
79
+ "Workflow state may live in an external worktree, or run /gsd new-project to initialize here.",
80
+ };
81
+ }
82
+ const worktreeIds = listMilestoneWorktreeIds(basePath);
83
+ const branchIds = listMilestoneBranchIds(basePath);
84
+ const candidateIds = [...new Set([...worktreeIds, ...branchIds])].sort();
85
+ const milestoneIds = candidateIds.filter(isStrandedMilestoneId);
86
+ if (milestoneIds.length === 0)
87
+ return null;
88
+ const listed = milestoneIds.join(", ");
89
+ const recovery = milestoneIds.length === 1
90
+ ? `/gsd dispatch complete-milestone ${milestoneIds[0]}`
91
+ : "/gsd doctor --fix";
92
+ return {
93
+ milestoneIds,
94
+ message: `Stranded milestone git residue detected (${listed}: worktree dir and/or milestone/* branch). ` +
95
+ `Run ${recovery} or /gsd status to recover closeout before starting new work.`,
96
+ };
97
+ }
15
98
  export async function loadCloseoutContext(basePath) {
16
99
  const unmergedMilestones = await findUnmergedCompletedMilestones(basePath);
100
+ const idleResidueHint = unmergedMilestones.length === 0 ? detectIdleMilestoneResidueHint(basePath) : null;
17
101
  return {
18
102
  strandedQuick: detectStrandedQuickBranch(basePath),
19
103
  unmergedMilestones,
104
+ idleResidueHint,
20
105
  };
21
106
  }
22
107
  export function getPrimaryCloseoutRecommendation(closeout) {
@@ -62,6 +147,13 @@ export function buildIdleMenuSummary(state, closeout) {
62
147
  `${blocker.milestoneId} is complete but not merged into ${blocker.integrationBranch}.`,
63
148
  ];
64
149
  }
150
+ // Surface idle residue before the completion summary so smart entry shows
151
+ // the same recovery text /gsd home would: a closed/unknown milestone with
152
+ // lingering worktree/branch artifacts must not be hidden behind the
153
+ // "all milestones complete" message.
154
+ if (closeout.idleResidueHint) {
155
+ return [closeout.idleResidueHint.message];
156
+ }
65
157
  if (state.phase === "complete") {
66
158
  const last = state.lastCompletedMilestone;
67
159
  return appendRequirementsBacklogToSummary(state, [
@@ -1,4 +1,4 @@
1
- import { checkRemoteAutoSession, isAutoActive, isAutoPaused, stopAutoRemote } from "../auto.js";
1
+ import { checkRemoteAutoSession, forceStopAutoRemote, isAutoActive, isAutoPaused, stopAutoRemote } from "../auto.js";
2
2
  import { validateDirectory } from "../validate-directory.js";
3
3
  import { resolveProjectRoot } from "../worktree.js";
4
4
  import { showNextAction } from "../../shared/tui.js";
@@ -135,5 +135,19 @@ export async function guardRemoteSession(ctx, pi) {
135
135
  }
136
136
  return false;
137
137
  }
138
- return choice === "force";
138
+ if (choice === "force") {
139
+ const result = forceStopAutoRemote(projectRoot());
140
+ if (result.error) {
141
+ ctx.ui.notify(`Failed to force-stop remote auto-mode: ${result.error}`, "error");
142
+ return false;
143
+ }
144
+ if (result.found) {
145
+ ctx.ui.notify(`Force-stopped auto-mode session (PID ${result.pid}). Starting a new session.`, "warning");
146
+ }
147
+ else {
148
+ ctx.ui.notify("Remote session is no longer running. Starting a new session.", "info");
149
+ }
150
+ return true;
151
+ }
152
+ return false;
139
153
  }
@@ -7,7 +7,7 @@
7
7
  import { existsSync, readFileSync, mkdirSync } from "node:fs";
8
8
  import { execFileSync } from "node:child_process";
9
9
  import { createRequire } from "node:module";
10
- import { join, resolve as resolvePath, sep } from "node:path";
10
+ import { join, resolve as resolvePath, sep, win32 as pathWin32 } from "node:path";
11
11
  import { homedir } from "node:os";
12
12
  import { deriveState } from "./state.js";
13
13
  import { gsdRoot } from "./paths.js";
@@ -20,6 +20,7 @@ import { getAutoWorktreePath } from "./auto-worktree.js";
20
20
  import { currentDirectoryRoot, projectRoot } from "./commands/context.js";
21
21
  import { loadPrompt } from "./prompt-loader.js";
22
22
  import { buildClaudeRuntimeFloorAdvisory } from "../../shared/claude-runtime-floor.js";
23
+ import { reconcileGsdBrowserPathAfterInstall } from "../../shared/gsd-browser-path-sync.js";
23
24
  import { isPnpmInstall } from "../../shared/package-manager-detection.js";
24
25
  import { buildDoctorHealIssuePayload, buildDoctorHealSummary, buildWorkflowDispatchContent, } from "./workflow-protocol.js";
25
26
  import { restoreGsdWorkflowTools, scopeGsdWorkflowToolsForDispatch, } from "./bootstrap/register-hooks.js";
@@ -51,8 +52,31 @@ function resolveInstallCommand(pkg) {
51
52
  return `bun add -g ${pkg}`;
52
53
  if (isPnpmInstall())
53
54
  return `pnpm add -g ${pkg}`;
55
+ const npmPrefix = resolveWindowsNpmGlobalPrefix();
56
+ if (npmPrefix)
57
+ return `npm --prefix ${quoteWindowsArg(npmPrefix)} install -g ${pkg}`;
54
58
  return `npm install -g ${pkg}`;
55
59
  }
60
+ function resolveWindowsNpmGlobalPrefix(argv1 = process.argv[1], platform = process.platform) {
61
+ if (platform !== "win32" || !argv1)
62
+ return null;
63
+ const normalized = pathWin32.normalize(argv1);
64
+ const marker = `${pathWin32.sep}node_modules${pathWin32.sep}`;
65
+ const index = normalized.toLowerCase().lastIndexOf(marker);
66
+ if (index <= 0)
67
+ return null;
68
+ const prefix = normalized.slice(0, index);
69
+ // Verify this is a real npm global prefix: such a directory always contains
70
+ // npm's own bin shim (`npm.cmd`) as a sibling of `node_modules/`. Local
71
+ // project `node_modules/`, npx caches, and other non-global layouts do not,
72
+ // so without this check `--prefix` would target the wrong directory.
73
+ if (!existsSync(pathWin32.join(prefix, "npm.cmd")))
74
+ return null;
75
+ return prefix;
76
+ }
77
+ function quoteWindowsArg(value) {
78
+ return `"${value.replace(/"/g, '\\"')}"`;
79
+ }
56
80
  function notifyClaudeRuntimeFloorAdvisory(ctx) {
57
81
  let advisory = null;
58
82
  try {
@@ -484,11 +508,30 @@ export async function handleUpdate(ctx, args = "") {
484
508
  execSync(installCmd, {
485
509
  stdio: ["ignore", "pipe", "ignore"],
486
510
  });
511
+ let reconcile = null;
512
+ if (browserUpdate) {
513
+ try {
514
+ reconcile = reconcileGsdBrowserPathAfterInstall({
515
+ latestVersion: latest,
516
+ compareSemver: compareSemverLocal,
517
+ resolvePathVersion: resolveGsdBrowserPathVersionForCommand,
518
+ });
519
+ }
520
+ catch {
521
+ // Reconciliation is best-effort: the install above already succeeded,
522
+ // so a reconcile failure must not flip the result to "Update failed".
523
+ reconcile = null;
524
+ }
525
+ }
487
526
  const newPathVersion = browserUpdate ? resolveGsdBrowserPathVersionForCommand() : null;
488
- const pathReady = !browserUpdate || (!!newPathVersion && compareSemverLocal(newPathVersion, latest) >= 0);
527
+ const pathNote = browserUpdate && !(newPathVersion && compareSemverLocal(newPathVersion, latest) >= 0)
528
+ ? (reconcile?.message
529
+ ?? "Ensure the npm global bin directory is on your PATH so MCP automation uses the updated binary.")
530
+ : "";
489
531
  ctx.ui.notify(browserUpdate
490
532
  ? `Updated gsd-browser to v${latest}. Restart your GSD session to use the new browser automation version.` +
491
- (pathReady ? "" : "\nNote: Ensure the npm global bin directory is on your PATH so MCP automation uses the updated binary.")
533
+ (reconcile?.action === "synced" && reconcile.message ? `\n${reconcile.message}` : "") +
534
+ (pathNote ? `\nNote: ${pathNote}` : "")
492
535
  : `Updated to v${latest}. Restart your GSD session to use the new version.`, "info");
493
536
  if (!browserUpdate)
494
537
  notifyClaudeRuntimeFloorAdvisory(ctx);
@@ -59,7 +59,7 @@ export function formatMcpStatusReport(servers) {
59
59
  : s.connected
60
60
  ? `connected — ${s.toolCount} tools`
61
61
  : s.available
62
- ? `available — ${s.toolCount} tools`
62
+ ? `probe available — ${s.toolCount} tools`
63
63
  : "disconnected";
64
64
  const warningText = s.envWarnings?.length ? ` — ${s.envWarnings.length} warning(s)` : "";
65
65
  lines.push(` ${icon} ${s.name} (${s.transport}) — ${status}${warningText}`);
@@ -83,7 +83,7 @@ export function formatMcpServerDetail(server) {
83
83
  lines.push(` Error: ${server.error}`);
84
84
  }
85
85
  else if (server.connected || server.available) {
86
- lines.push(` Status: ${server.connected ? "connected" : "available"}`);
86
+ lines.push(` Status: ${server.connected ? "connected" : "probe available"}`);
87
87
  lines.push(` Tools: ${server.toolCount}`);
88
88
  if (server.tools.length > 0) {
89
89
  lines.push("");
@@ -59,6 +59,13 @@ function datePrefix() {
59
59
  const dd = String(d.getDate()).padStart(2, "0");
60
60
  return `${yy}${mm}${dd}`;
61
61
  }
62
+ export function isWorkflowStateComplete(state) {
63
+ if (state.completedAt)
64
+ return true;
65
+ return Array.isArray(state.phases) &&
66
+ state.phases.length > 0 &&
67
+ state.phases.every((phase) => phase.status === "completed");
68
+ }
62
69
  /**
63
70
  * Write a STATE.json file to track workflow execution state.
64
71
  */
@@ -85,7 +92,7 @@ function writeWorkflowState(artifactDir, templateId, templateName, phases, descr
85
92
  * Scan all workflow artifact directories for in-progress STATE.json files.
86
93
  * Returns workflows that were started but not completed.
87
94
  */
88
- function findInProgressWorkflows(basePath) {
95
+ export function findInProgressWorkflows(basePath) {
89
96
  const workflowsRoot = join(gsdRoot(basePath), "workflows");
90
97
  if (!existsSync(workflowsRoot))
91
98
  return [];
@@ -105,7 +112,7 @@ function findInProgressWorkflows(basePath) {
105
112
  try {
106
113
  const raw = readFileSync(statePath, "utf-8");
107
114
  const state = JSON.parse(raw);
108
- if (!state.completedAt) {
115
+ if (!isWorkflowStateComplete(state)) {
109
116
  results.push(state);
110
117
  }
111
118
  }
@@ -0,0 +1,353 @@
1
+ /**
2
+ * Consent Question module — the single home for the user-question lifecycle:
3
+ * classification → gating → answer validation → cancellation.
4
+ *
5
+ * Every question the assistant puts to a human is classified into a kind, and
6
+ * the kind alone decides the fail policy:
7
+ *
8
+ * - "gate" — mechanical write gates (depth verification, destructive
9
+ * confirm). Fail-closed; structural answer validation is
10
+ * delegated to the write-gate validators.
11
+ * - "consent" — approval/confirmation questions ("ready to write?",
12
+ * "is this correct?"). Fail-closed.
13
+ * - "decision" — explicit user decisions (research vs skip). Fail-closed.
14
+ * - "informational" — anything that is not asking the user to consent or
15
+ * decide. Fail-open.
16
+ *
17
+ * Fail-closed means an empty/missing answer is NEVER treated as an answer —
18
+ * evaluateAnswer returns "waiting" so callers pause instead of proceeding.
19
+ * This fixes #528 (empty `selected` on a non-gate question used to pass
20
+ * through as a real answer) by construction.
21
+ *
22
+ * shouldPauseForQuestion replaces the old unit-type allowlist: a classified
23
+ * consent/decision question pauses regardless of unit type, including
24
+ * interactive mode where no unit is active. This fixes #682 (prose approval
25
+ * questions outside the 4 allowlisted discuss units rendered as un-gated
26
+ * prose menus) by construction.
27
+ */
28
+ import { isGateQuestionId } from "./bootstrap/write-gate.js";
29
+ import { evaluateGateAnswer, hasNotesValue, hasSelectedValue, } from "./consent-verdict.js";
30
+ import { isDestructiveConfirmGateId } from "./safety/destructive-confirmation.js";
31
+ /** Fail policy is derived from the kind — there is no per-question override. */
32
+ export function failPolicyForKind(kind) {
33
+ return kind === "informational" ? "open" : "closed";
34
+ }
35
+ // ── Prose detectors (moved from user-input-boundary) ────────────────────────
36
+ const REMOTE_QUESTION_FAILURE_RE = /(?:Remote (?:auth failed|questions failed|channel configured but returned no result|questions timed out|questions timed out or failed)|Failed to send questions via)/i;
37
+ const APPROVAL_WAIT_RE = /\bwait(?:ing)?\s+for\s+(?:your\s+)?(?:confirmation|approval|input|response|answer)\b/i;
38
+ const APPROVAL_QUESTION_RE = /\b(?:confirm|confirmation|approve|approval|approved|captured|correct|correctly|happy\s+with|ready\s+to\s+(?:write|save|proceed|ship)|(?:want|need)\s+to\s+adjust|should\s+I\s+(?:write|save|proceed)|do\s+you\s+want\s+me\s+to\s+(?:write|save|proceed)|ship\s+it)\b/i;
39
+ const APPROVAL_RIGHT_QUESTION_RE = /\b(?:does|do|is|are|was|were|did)\b[^\n?]{0,120}\bright\b/i;
40
+ const APPROVAL_CHANGE_QUESTION_RE = /\b(?:anything\s+else|anything|something)\s+to\s+(?:adjust|add|remove|reclassify)\b/i;
41
+ const RESEARCH_DECISION_QUESTION_RE = /\b(?:research|skip)\b/i;
42
+ const ASK_USER_QUESTIONS_CANCELLED_RE = /ask_user_questions was cancelled before receiving a response/i;
43
+ /** Scan question-mark-terminated fragments of `text` against `patterns`. */
44
+ function hasQuestionMatching(text, patterns) {
45
+ for (let i = 0; i < text.length; i++) {
46
+ if (text[i] !== "?")
47
+ continue;
48
+ const previousBreak = Math.max(text.lastIndexOf("\n", i), text.lastIndexOf(".", i), text.lastIndexOf("!", i), text.lastIndexOf("?", i - 1));
49
+ const fragment = text.slice(previousBreak + 1, i + 1);
50
+ if (patterns.some((pattern) => pattern.test(fragment)))
51
+ return true;
52
+ }
53
+ return false;
54
+ }
55
+ export function hasApprovalQuestion(text) {
56
+ return hasQuestionMatching(text, [
57
+ APPROVAL_QUESTION_RE,
58
+ APPROVAL_RIGHT_QUESTION_RE,
59
+ APPROVAL_CHANGE_QUESTION_RE,
60
+ ]);
61
+ }
62
+ export function hasResearchDecisionQuestion(text) {
63
+ return hasQuestionMatching(text, [RESEARCH_DECISION_QUESTION_RE]);
64
+ }
65
+ /**
66
+ * Detect a plain-text "Next steps:" menu — numbered options with an "Other"
67
+ * choice — emitted as prose instead of a structured ask_user_questions call.
68
+ * Without this, auto-mode treats the menu as informational and loops on its
69
+ * own turn until tokens are exhausted (#454).
70
+ */
71
+ export function hasPlainTextNextStepsMenu(lines) {
72
+ const nextStepsIndex = lines.findIndex((line) => /^next steps\s*:?$/i.test(line));
73
+ if (nextStepsIndex < 0)
74
+ return false;
75
+ const menuLines = lines.slice(nextStepsIndex + 1);
76
+ const numberedOptions = menuLines.filter((line) => /^\d+[.)]\s+\S/.test(line));
77
+ return numberedOptions.length >= 2 && numberedOptions.some((line) => /\bother\b/i.test(line));
78
+ }
79
+ // ── Message text extraction (moved from user-input-boundary) ────────────────
80
+ function extractMessageText(msg, includeThinking) {
81
+ if (!msg || typeof msg !== "object")
82
+ return "";
83
+ const content = msg.content;
84
+ if (typeof content === "string")
85
+ return content;
86
+ if (!Array.isArray(content))
87
+ return "";
88
+ const parts = [];
89
+ for (const block of content) {
90
+ if (!block || typeof block !== "object")
91
+ continue;
92
+ const typed = block;
93
+ if (typed.type === "text" && typeof typed.text === "string") {
94
+ parts.push(typed.text);
95
+ }
96
+ // Thinking blocks are internal reasoning, not user-visible — included only
97
+ // when the caller asks for the full transcript text.
98
+ if (includeThinking && typed.type === "thinking" && typeof typed.thinking === "string") {
99
+ parts.push(typed.thinking);
100
+ }
101
+ }
102
+ return parts.join("\n");
103
+ }
104
+ function lastAssistantMessageText(messages, includeThinking) {
105
+ if (!Array.isArray(messages))
106
+ return "";
107
+ for (let i = messages.length - 1; i >= 0; i--) {
108
+ const msg = messages[i];
109
+ if (!msg || typeof msg !== "object")
110
+ continue;
111
+ if (msg.role !== "assistant")
112
+ continue;
113
+ const text = extractMessageText(msg, includeThinking).trim();
114
+ if (text)
115
+ return text;
116
+ }
117
+ return "";
118
+ }
119
+ export function lastAssistantText(messages) {
120
+ return lastAssistantMessageText(messages, true);
121
+ }
122
+ function lastAssistantVisibleText(messages) {
123
+ return lastAssistantMessageText(messages, false);
124
+ }
125
+ function anyMessageMatches(messages, patterns) {
126
+ if (!Array.isArray(messages))
127
+ return false;
128
+ return messages.some((msg) => {
129
+ if (!msg || typeof msg !== "object")
130
+ return false;
131
+ if (msg.role === "user")
132
+ return false;
133
+ const text = extractMessageText(msg, false);
134
+ return patterns.some((pattern) => pattern.test(text));
135
+ });
136
+ }
137
+ // ── Classification ──────────────────────────────────────────────────────────
138
+ const APPROVAL_GATE_ID_RE = /^depth_verification_.+_confirm$/;
139
+ /**
140
+ * Classify a question — structured (by id) or prose (by text) — into a kind.
141
+ *
142
+ * Structured questions with a recognized gate id are gates; every other
143
+ * structured question is asking the user something, so it classifies as
144
+ * consent (fail-closed). Prose classifies by the approval/decision detectors;
145
+ * prose that matches neither is informational (fail-open).
146
+ */
147
+ export function classifyQuestion(input) {
148
+ if (isDestructiveConfirmGateId(input.id)) {
149
+ return { kind: "gate", gateSubKind: "destructive-confirm" };
150
+ }
151
+ if (typeof input.id === "string" && isGateQuestionId(input.id)) {
152
+ return {
153
+ kind: "gate",
154
+ gateSubKind: APPROVAL_GATE_ID_RE.test(input.id) ? "approval" : "depth-verification",
155
+ };
156
+ }
157
+ // Any other structured question is a real elicitation of the user.
158
+ if (typeof input.id === "string" || Array.isArray(input.options)) {
159
+ return { kind: "consent" };
160
+ }
161
+ const text = input.text ?? "";
162
+ if (input.unitType === "research-decision" && hasResearchDecisionQuestion(text)) {
163
+ return { kind: "decision" };
164
+ }
165
+ if (hasApprovalQuestion(text)) {
166
+ return { kind: "consent" };
167
+ }
168
+ return { kind: "informational" };
169
+ }
170
+ /**
171
+ * THE single policy point for whether a question's answer counts as answered.
172
+ *
173
+ * - cancelled rounds → "cancelled" for every kind.
174
+ * - gate: delegates to evaluateGateAnswer in the consent-verdict leaf — the
175
+ * same verdict engine write-gate's applyAskUserQuestionsGateResult consumes;
176
+ * confirm option → "verified", any other real selection → "declined",
177
+ * empty/missing → "waiting" (fail-closed).
178
+ * - consent/decision: a non-empty selection or non-empty notes → "answered";
179
+ * empty/missing → "waiting" (fail-closed; fixes #528).
180
+ * - informational: always "answered" (fail-open).
181
+ */
182
+ export function evaluateAnswer(options) {
183
+ const { question, details } = options;
184
+ if (details.cancelled)
185
+ return "cancelled";
186
+ const { kind } = classifyQuestion({ id: question.id, options: question.options });
187
+ if (failPolicyForKind(kind) === "open")
188
+ return "answered";
189
+ if (kind === "gate") {
190
+ // Gates keep strict structural validation: only the confirmation option
191
+ // verifies; notes never satisfy a gate.
192
+ return evaluateGateAnswer(question, details);
193
+ }
194
+ const questionId = typeof question.id === "string" ? question.id : "";
195
+ const answer = details.response?.answers?.[questionId];
196
+ if (hasSelectedValue(answer?.selected))
197
+ return "answered";
198
+ // Notes-only is a real user utterance for consent/decision questions, but
199
+ // never for gates (handled above).
200
+ if (hasNotesValue(answer?.notes))
201
+ return "answered";
202
+ return "waiting";
203
+ }
204
+ const OUTCOME_PRECEDENCE = [
205
+ "cancelled",
206
+ "waiting",
207
+ "declined",
208
+ "verified",
209
+ "answered",
210
+ ];
211
+ /**
212
+ * Evaluate a whole ask_user_questions round. The round outcome is the most
213
+ * blocking per-question outcome (cancelled > waiting > declined > verified >
214
+ * answered). An empty round with a response is "answered"; an empty round
215
+ * without a response is "waiting" only when cancelled is not set and there is
216
+ * nothing to validate — callers treat a missing response with no questions as
217
+ * a no-op, so it reports "answered" here.
218
+ */
219
+ export function evaluateAskUserQuestionsRound(questions, details) {
220
+ if (details.cancelled)
221
+ return "cancelled";
222
+ let worst = "answered";
223
+ for (const question of questions) {
224
+ const outcome = evaluateAnswer({ question, details });
225
+ if (OUTCOME_PRECEDENCE.indexOf(outcome) < OUTCOME_PRECEDENCE.indexOf(worst)) {
226
+ worst = outcome;
227
+ }
228
+ }
229
+ return worst;
230
+ }
231
+ export function formatUnansweredConsentQuestionMessage(questions) {
232
+ const ids = questions
233
+ .map((question) => (typeof question.id === "string" ? question.id : null))
234
+ .filter((id) => Boolean(id));
235
+ return [
236
+ `ask_user_questions returned without a selection${ids.length ? ` for ${ids.join(", ")}` : ""}.`,
237
+ "An empty answer is not consent — do not infer approval or proceed.",
238
+ "Re-call ask_user_questions with the same question(s) and wait for the user's response.",
239
+ ].join(" ");
240
+ }
241
+ // ── Pause gating (replaces the unit-type allowlist) ─────────────────────────
242
+ /**
243
+ * Shared preamble for the awaiting-input predicates: cancellation and remote
244
+ * delivery failures always pause (an undelivered question can never be
245
+ * answered, so proceeding would be fail-open), as does an explicit
246
+ * "waiting for your approval/input" phrase in the last assistant text.
247
+ *
248
+ * Returns `forced: true` when the boundary is unconditional, plus the last
249
+ * assistant visible text for the caller's own classification.
250
+ */
251
+ function awaitingBoundary(messages) {
252
+ if (anyMessageMatches(messages, [ASK_USER_QUESTIONS_CANCELLED_RE, REMOTE_QUESTION_FAILURE_RE])) {
253
+ return { forced: true, text: "" };
254
+ }
255
+ const text = lastAssistantVisibleText(messages);
256
+ if (text && APPROVAL_WAIT_RE.test(text))
257
+ return { forced: true, text };
258
+ return { forced: false, text };
259
+ }
260
+ /**
261
+ * Decide whether the assistant should pause for a prose user question.
262
+ *
263
+ * Unlike the retired USER_APPROVAL_UNIT_TYPES allowlist, this pauses for any
264
+ * classified consent/decision question regardless of unit type — including
265
+ * interactive mode where no unit is active (#682).
266
+ */
267
+ export function shouldPauseForQuestion(unitType, messages) {
268
+ const { forced, text } = awaitingBoundary(messages);
269
+ if (forced)
270
+ return true;
271
+ // Streaming hot path: this runs on every message_update for every unit type.
272
+ // The classifiers only ever match question-mark-terminated fragments, so
273
+ // text without a "?" can never classify as consent/decision — bail before
274
+ // the multi-regex scan.
275
+ if (!text || !text.includes("?"))
276
+ return false;
277
+ const { kind } = classifyQuestion({ text, unitType });
278
+ return kind === "consent" || kind === "decision";
279
+ }
280
+ // ── Awaiting-input boundaries (moved from user-input-boundary) ──────────────
281
+ export function isAwaitingUserInput(messages) {
282
+ const { forced, text } = awaitingBoundary(messages);
283
+ if (forced)
284
+ return true;
285
+ if (!text)
286
+ return false;
287
+ const lines = text.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
288
+ if (lines.some((line) => line.endsWith("?")))
289
+ return true;
290
+ if (hasPlainTextNextStepsMenu(lines))
291
+ return true;
292
+ return hasApprovalQuestion(text);
293
+ }
294
+ export function isAwaitingApprovalBoundary(messages) {
295
+ // With no unit type, classification reduces to the approval detectors —
296
+ // exactly the approval boundary.
297
+ return shouldPauseForQuestion(undefined, messages);
298
+ }
299
+ // ── Approval gate ids + explicit responses (moved from user-input-boundary) ─
300
+ export function approvalGateIdForUnit(unitType, unitId) {
301
+ if (!unitType)
302
+ return null;
303
+ if (unitType === "discuss-project")
304
+ return "depth_verification_project_confirm";
305
+ if (unitType === "discuss-requirements")
306
+ return "depth_verification_requirements_confirm";
307
+ if (unitType === "research-decision")
308
+ return "depth_verification_research_decision_confirm";
309
+ if (unitType === "discuss-milestone") {
310
+ const safeUnitId = typeof unitId === "string" && /^[A-Za-z0-9_-]+$/.test(unitId)
311
+ ? unitId
312
+ : "milestone";
313
+ return `depth_verification_${safeUnitId}_confirm`;
314
+ }
315
+ return null;
316
+ }
317
+ const CHANGE_REQUEST_RESPONSE_RE = /\b(?:no|nope|nah|not\s+yet|don't|do\s+not|change|add|remove|reclassify|adjust|clarify|missing|instead|but|however|wait|hold)\b/i;
318
+ const APPROVAL_RESPONSE_RE = /^(?:y|yes|yeah|yep|approve|approved|confirm|confirmed|correct|right|looks\s+(?:good|right)|sounds\s+good|all\s+good|ok|okay|go\s+ahead|proceed|write\s+it|save\s+it|do\s+it)\b/i;
319
+ const RESEARCH_DECISION_RESPONSE_RE = /^(?:research|run\s+research|do\s+research|skip|skip\s+research|no\s+research)\b/i;
320
+ export function isExplicitApprovalResponse(input, pendingGateId) {
321
+ const text = input?.trim() ?? "";
322
+ if (!text)
323
+ return false;
324
+ if (pendingGateId?.includes("research_decision")) {
325
+ return RESEARCH_DECISION_RESPONSE_RE.test(text);
326
+ }
327
+ if (CHANGE_REQUEST_RESPONSE_RE.test(text))
328
+ return false;
329
+ return APPROVAL_RESPONSE_RE.test(text);
330
+ }
331
+ /** True when an assistant message already has an in-flight ask_user_questions tool call. */
332
+ export function messageHasPendingAskUserQuestionsTool(message) {
333
+ if (!message || typeof message !== "object")
334
+ return false;
335
+ const content = message.content;
336
+ if (!Array.isArray(content))
337
+ return false;
338
+ return content.some((block) => {
339
+ if (!block || typeof block !== "object")
340
+ return false;
341
+ // Claude Code marks completion by attaching externalResult, not by setting state.
342
+ // Streaming blocks often carry no state; serverToolUse is the claude-code-cli MCP path.
343
+ const tool = block;
344
+ if (tool.type !== "toolCall" && tool.type !== "serverToolUse")
345
+ return false;
346
+ const name = String(tool.name ?? "").toLowerCase();
347
+ if (!name.includes("ask_user_questions"))
348
+ return false;
349
+ if (tool.externalResult !== undefined)
350
+ return false;
351
+ return tool.state !== "completed" && tool.state !== "done";
352
+ });
353
+ }