@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
@@ -6,7 +6,8 @@ import { tmpdir } from "node:os";
6
6
  import { join } from "node:path";
7
7
  import { randomUUID } from "node:crypto";
8
8
 
9
- import { runDispatch, runPreDispatch } from "../auto/phases.ts";
9
+ import { runDispatch } from "../auto/dispatch.ts";
10
+ import { runPreDispatch } from "../auto/pre-dispatch.ts";
10
11
  import { AutoSession } from "../auto/session.ts";
11
12
  import { resolveUnitSupervisionTimeouts } from "../auto-timers.ts";
12
13
  import { bootstrapAutoSession } from "../auto-start.ts";
@@ -15,7 +16,7 @@ import { resolveDispatch, setResearchProjectPromptBuilderForTest } from "../auto
15
16
  import { resolveExpectedArtifactPath, verifyExpectedArtifact, writeBlockerPlaceholder } from "../auto-recovery.ts";
16
17
  import { finalizeProjectResearchTimeout } from "../project-research-policy.ts";
17
18
  import { resetRegistry } from "../rule-registry.ts";
18
- import { approvalGateIdForUnit, isAwaitingUserInput, isExplicitApprovalResponse, shouldPauseForUserApprovalQuestion } from "../user-input-boundary.ts";
19
+ import { approvalGateIdForUnit, isAwaitingUserInput, isExplicitApprovalResponse, shouldPauseForQuestion } from "../consent-question.ts";
19
20
  import {
20
21
  clearPendingAutoStart,
21
22
  checkDeepProjectSetupAfterTurn,
@@ -1402,7 +1403,7 @@ test("deep project setup: user-quoted remote question failure does not pause aut
1402
1403
  ];
1403
1404
 
1404
1405
  assert.equal(isAwaitingUserInput(messages), false);
1405
- assert.equal(shouldPauseForUserApprovalQuestion("discuss-project", messages), false);
1406
+ assert.equal(shouldPauseForQuestion("discuss-project", messages), false);
1406
1407
  });
1407
1408
 
1408
1409
  test("deep project setup: plain-text approval wait is treated as waiting for user input", () => {
@@ -1426,7 +1427,7 @@ test("deep project setup: opening interview question does not trigger approval a
1426
1427
  ];
1427
1428
 
1428
1429
  assert.equal(isAwaitingUserInput(messages), true);
1429
- assert.equal(shouldPauseForUserApprovalQuestion("discuss-project", messages), false);
1430
+ assert.equal(shouldPauseForQuestion("discuss-project", messages), false);
1430
1431
  });
1431
1432
 
1432
1433
  test("deep project setup: grounding interview question with requirements context does not trigger approval abort", () => {
@@ -1441,7 +1442,7 @@ test("deep project setup: grounding interview question with requirements context
1441
1442
  ];
1442
1443
 
1443
1444
  assert.equal(isAwaitingUserInput(messages), true);
1444
- assert.equal(shouldPauseForUserApprovalQuestion("discuss-project", messages), false);
1445
+ assert.equal(shouldPauseForQuestion("discuss-project", messages), false);
1445
1446
  });
1446
1447
 
1447
1448
  test("deep project setup: persistence and anti-goals interview prompt does not trigger approval abort", () => {
@@ -1460,7 +1461,7 @@ test("deep project setup: persistence and anti-goals interview prompt does not t
1460
1461
  ];
1461
1462
 
1462
1463
  assert.equal(isAwaitingUserInput(messages), true);
1463
- assert.equal(shouldPauseForUserApprovalQuestion("discuss-project", messages), false);
1464
+ assert.equal(shouldPauseForQuestion("discuss-project", messages), false);
1464
1465
  });
1465
1466
 
1466
1467
  test("deep project setup: discovery questions before writing PROJECT do not trigger approval abort", () => {
@@ -1479,7 +1480,7 @@ test("deep project setup: discovery questions before writing PROJECT do not trig
1479
1480
  ];
1480
1481
 
1481
1482
  assert.equal(isAwaitingUserInput(messages), true);
1482
- assert.equal(shouldPauseForUserApprovalQuestion("discuss-project", messages), false);
1483
+ assert.equal(shouldPauseForQuestion("discuss-project", messages), false);
1483
1484
  });
1484
1485
 
1485
1486
  test("deep project setup: discovery question mentioning write intent does not trigger approval abort", () => {
@@ -1491,7 +1492,7 @@ test("deep project setup: discovery question mentioning write intent does not tr
1491
1492
  ];
1492
1493
 
1493
1494
  assert.equal(isAwaitingUserInput(messages), true);
1494
- assert.equal(shouldPauseForUserApprovalQuestion("discuss-project", messages), false);
1495
+ assert.equal(shouldPauseForQuestion("discuss-project", messages), false);
1495
1496
  });
1496
1497
 
1497
1498
  test("deep project setup: scope discovery question mentioning add does not trigger approval abort", () => {
@@ -1503,7 +1504,7 @@ test("deep project setup: scope discovery question mentioning add does not trigg
1503
1504
  ];
1504
1505
 
1505
1506
  assert.equal(isAwaitingUserInput(messages), true);
1506
- assert.equal(shouldPauseForUserApprovalQuestion("discuss-project", messages), false);
1507
+ assert.equal(shouldPauseForQuestion("discuss-project", messages), false);
1507
1508
  });
1508
1509
 
1509
1510
  test("deep project setup: requirements preview question from screenshot is treated as waiting", () => {
@@ -1523,12 +1524,12 @@ test("deep project setup: requirements preview question from screenshot is treat
1523
1524
  ];
1524
1525
 
1525
1526
  assert.equal(isAwaitingUserInput(messages), true);
1526
- assert.equal(shouldPauseForUserApprovalQuestion("discuss-requirements", messages), true);
1527
+ assert.equal(shouldPauseForQuestion("discuss-requirements", messages), true);
1527
1528
  });
1528
1529
 
1529
1530
  test("deep project setup: research decision question triggers approval boundary pause", () => {
1530
1531
  assert.equal(
1531
- shouldPauseForUserApprovalQuestion("research-decision", [
1532
+ shouldPauseForQuestion("research-decision", [
1532
1533
  {
1533
1534
  role: "assistant",
1534
1535
  content: "Run domain research now? (y/n)",
@@ -569,6 +569,42 @@ describe('derive-state-helpers', () => {
569
569
  }
570
570
  });
571
571
 
572
+ // ─── Batch slice query: multi-milestone slices loaded in one query ─────
573
+ test('buildRegistryAndFindActive: batched slice query preserves ordering across milestones', async () => {
574
+ const base = createFixtureBase();
575
+ try {
576
+ // M001 is complete so the loop advances past it.
577
+ writeFile(base, 'milestones/M001/M001-ROADMAP.md', ROADMAP_CONTENT);
578
+ writeFile(base, 'milestones/M001/M001-SUMMARY.md', '# M001 Summary\n\nDone.');
579
+ // M002 is a queued shell milestone with no context and no slices — should be deferred.
580
+ mkdirSync(join(base, '.gsd', 'milestones', 'M002'), { recursive: true });
581
+ // M003 is the real active milestone with slices in non-trivial sequence order.
582
+ writeFile(base, 'milestones/M003/M003-CONTEXT.md', '# M003: Real\n\nReal milestone.');
583
+
584
+ openDatabase(':memory:');
585
+ insertMilestone({ id: 'M001', title: 'Complete', status: 'complete' });
586
+ insertMilestone({ id: 'M002', title: 'Shell', status: 'queued' });
587
+ insertMilestone({ id: 'M003', title: 'Real', status: 'active' });
588
+ // Slices intentionally inserted with out-of-order sequences to prove ordering.
589
+ insertSlice({ id: 'S01', milestoneId: 'M001', title: 'M1 Second', status: 'complete', risk: 'low', depends: [], sequence: 2 });
590
+ insertSlice({ id: 'S02', milestoneId: 'M001', title: 'M1 First', status: 'complete', risk: 'low', depends: [], sequence: 1 });
591
+ insertSlice({ id: 'S03', milestoneId: 'M003', title: 'M3 Second', status: 'active', risk: 'low', depends: [], sequence: 5 });
592
+ insertSlice({ id: 'S04', milestoneId: 'M003', title: 'M3 First', status: 'active', risk: 'low', depends: [], sequence: 3 });
593
+
594
+ invalidateStateCache();
595
+ const state = await deriveStateFromDb(base);
596
+
597
+ assert.equal(state.activeMilestone?.id, 'M003', 'batched: M003 is active after complete M001 and shell M002');
598
+ assert.equal(state.activeSlice?.id, 'S04', 'batched: first slice by sequence is active');
599
+ assert.equal(state.registry.find(e => e.id === 'M001')?.status, 'complete', 'batched: M001 complete');
600
+ assert.equal(state.registry.find(e => e.id === 'M002')?.status, 'pending', 'batched: shell M002 deferred to pending');
601
+ assert.equal(state.registry.find(e => e.id === 'M003')?.status, 'active', 'batched: M003 active');
602
+ } finally {
603
+ closeDatabase();
604
+ cleanup(base);
605
+ }
606
+ });
607
+
572
608
  // ─── Deferred queued shell: shell milestone deferred, real one promoted ──
573
609
  test('buildRegistryAndFindActive: queued shell deferred, later real milestone becomes active (#3470)', async () => {
574
610
  const base = createFixtureBase();
@@ -0,0 +1,303 @@
1
+ /**
2
+ * Tests for the destructive-command confirmation escape hatch.
3
+ *
4
+ * Regression target: the destructive-guard hard block had no confirmation
5
+ * path. Re-issuing a force push after confirming via ask_user_questions hit
6
+ * the identical HARD BLOCK every time — an unwinnable loop. These tests pin
7
+ * the block → confirm → allow-once flow and its safety invariants.
8
+ *
9
+ * Two layers of coverage:
10
+ * 1. Unit — the confirmation-token module in isolation (block/confirm/consume
11
+ * and every safety invariant).
12
+ * 2. Integration — the real registerHooks() bash tool_call guard +
13
+ * ask_user_questions tool_result handler driven end-to-end, proving the
14
+ * loop is escapable through the actual wiring, not just the helper module.
15
+ */
16
+
17
+ import test from "node:test";
18
+ import assert from "node:assert/strict";
19
+
20
+ import { registerHooks } from "../bootstrap/register-hooks.ts";
21
+ import { classifyCommand } from "../safety/destructive-guard.ts";
22
+ import {
23
+ DESTRUCTIVE_CONFIRM_GATE_MARKER,
24
+ confirmDestructiveCommand,
25
+ consumeDestructiveConfirmation,
26
+ isDestructiveConfirmGateId,
27
+ normalizeDestructiveCommand,
28
+ peekPendingDestructiveCommand,
29
+ requestDestructiveConfirmation,
30
+ resetDestructiveConfirmation,
31
+ } from "../safety/destructive-confirmation.ts";
32
+
33
+ const BASE = "/tmp/gsd-destructive-confirm-test";
34
+ const FORCE_PUSH = "git push --force-with-lease origin feature/PO-566-chart-supply-chain";
35
+
36
+ function blocked(command: string, basePath: string): boolean {
37
+ // Mirror the guard's decision: a classified-destructive command is blocked
38
+ // unless a matching confirmation token is consumed in this same check.
39
+ if (!classifyCommand(command).destructive) return false;
40
+ return !consumeDestructiveConfirmation(command, basePath);
41
+ }
42
+
43
+ test("repro: destructive command loops forever without confirmation", () => {
44
+ resetDestructiveConfirmation(BASE);
45
+ // Every attempt blocks — this is the bug the escape hatch fixes.
46
+ assert.equal(blocked(FORCE_PUSH, BASE), true, "first attempt blocks");
47
+ assert.equal(blocked(FORCE_PUSH, BASE), true, "retry still blocks");
48
+ assert.equal(blocked(FORCE_PUSH, BASE), true, "and again — unwinnable loop");
49
+ });
50
+
51
+ test("block then confirm then retry allows the exact command once", () => {
52
+ resetDestructiveConfirmation(BASE);
53
+
54
+ // 1. Guard blocks and records the pending command.
55
+ assert.equal(blocked(FORCE_PUSH, BASE), true, "initial attempt blocks");
56
+ requestDestructiveConfirmation(FORCE_PUSH, BASE);
57
+ assert.equal(peekPendingDestructiveCommand(BASE), normalizeDestructiveCommand(FORCE_PUSH));
58
+
59
+ // 2. User confirms via ask_user_questions affirmative answer.
60
+ const confirmed = confirmDestructiveCommand(BASE);
61
+ assert.equal(confirmed, normalizeDestructiveCommand(FORCE_PUSH));
62
+
63
+ // 3. Retry in the same turn now passes.
64
+ assert.equal(blocked(FORCE_PUSH, BASE), false, "confirmed command passes once");
65
+ });
66
+
67
+ test("confirmation is one-shot — a second destructive command re-blocks", () => {
68
+ resetDestructiveConfirmation(BASE);
69
+
70
+ requestDestructiveConfirmation(FORCE_PUSH, BASE);
71
+ confirmDestructiveCommand(BASE);
72
+ assert.equal(blocked(FORCE_PUSH, BASE), false, "first run consumes the token");
73
+ assert.equal(blocked(FORCE_PUSH, BASE), true, "identical second run re-blocks");
74
+ });
75
+
76
+ test("confirmation is command-bound — a different command is not approved", () => {
77
+ resetDestructiveConfirmation(BASE);
78
+
79
+ requestDestructiveConfirmation(FORCE_PUSH, BASE);
80
+ confirmDestructiveCommand(BASE);
81
+
82
+ // A different destructive command must not ride the force-push confirmation.
83
+ assert.equal(blocked("rm -rf node_modules", BASE), true, "unrelated destructive cmd re-blocks");
84
+ // The original token is still intact for its exact command.
85
+ assert.equal(blocked(FORCE_PUSH, BASE), false, "original confirmed command still passes once");
86
+ });
87
+
88
+ test("cosmetic whitespace reformatting still matches the confirmed token", () => {
89
+ resetDestructiveConfirmation(BASE);
90
+
91
+ requestDestructiveConfirmation("git push --force origin main", BASE);
92
+ confirmDestructiveCommand(BASE);
93
+ assert.equal(blocked("git push --force origin main", BASE), false, "whitespace-normalized match passes");
94
+ });
95
+
96
+ test("requesting a new confirmation invalidates a stale confirmed token", () => {
97
+ resetDestructiveConfirmation(BASE);
98
+
99
+ requestDestructiveConfirmation(FORCE_PUSH, BASE);
100
+ confirmDestructiveCommand(BASE);
101
+ // New block for a different command before the first was consumed.
102
+ requestDestructiveConfirmation("git reset --hard HEAD~3", BASE);
103
+ assert.equal(blocked(FORCE_PUSH, BASE), true, "old confirmation no longer valid after new request");
104
+ });
105
+
106
+ test("confirm with nothing pending returns null and approves nothing", () => {
107
+ resetDestructiveConfirmation(BASE);
108
+ assert.equal(confirmDestructiveCommand(BASE), null, "no pending command -> null");
109
+ assert.equal(blocked(FORCE_PUSH, BASE), true, "no spurious approval");
110
+ });
111
+
112
+ test("tokens are isolated per basePath", () => {
113
+ const a = "/tmp/gsd-confirm-ws-a";
114
+ const b = "/tmp/gsd-confirm-ws-b";
115
+ resetDestructiveConfirmation(a);
116
+ resetDestructiveConfirmation(b);
117
+
118
+ requestDestructiveConfirmation(FORCE_PUSH, a);
119
+ confirmDestructiveCommand(a);
120
+
121
+ assert.equal(blocked(FORCE_PUSH, b), true, "workspace B is unaffected by workspace A's confirmation");
122
+ assert.equal(blocked(FORCE_PUSH, a), false, "workspace A still passes once");
123
+ });
124
+
125
+ test("gate id marker detection", () => {
126
+ assert.equal(isDestructiveConfirmGateId(`${DESTRUCTIVE_CONFIRM_GATE_MARKER}_push`), true);
127
+ assert.equal(isDestructiveConfirmGateId("depth_verification_M001"), false);
128
+ assert.equal(isDestructiveConfirmGateId(undefined), false);
129
+ assert.equal(isDestructiveConfirmGateId(123), false);
130
+ });
131
+
132
+ test("non-destructive commands are never gated regardless of token state", () => {
133
+ resetDestructiveConfirmation(BASE);
134
+ assert.equal(blocked("git status", BASE), false);
135
+ assert.equal(blocked("ls -la", BASE), false);
136
+ });
137
+
138
+ // ─── Integration: real registerHooks() wiring, driven end-to-end ────────────
139
+ // The unit tests above exercise the token module directly. These drive the
140
+ // actual registered bash tool_call guard and ask_user_questions tool_result
141
+ // handler, proving the loop the user hit is escapable through the real hooks —
142
+ // not just the helper. Mirrors the harness in
143
+ // register-hooks-depth-verification.test.ts.
144
+
145
+ type Handler = (event: any, ctx?: any) => Promise<any> | any;
146
+
147
+ function makeHookHarness(): {
148
+ handlers: Map<string, Handler[]>;
149
+ pi: any;
150
+ } {
151
+ const handlers = new Map<string, Handler[]>();
152
+ const pi = {
153
+ on(event: string, handler: Handler) {
154
+ const existing = handlers.get(event) ?? [];
155
+ existing.push(handler);
156
+ handlers.set(event, existing);
157
+ },
158
+ } as any;
159
+ return { handlers, pi };
160
+ }
161
+
162
+ /** Run every bash tool_call guard and return the first block result, if any. */
163
+ async function runBashGuard(
164
+ handlers: Map<string, Handler[]>,
165
+ command: string,
166
+ ctx: any,
167
+ ): Promise<{ block?: boolean; reason?: string } | undefined> {
168
+ let block: { block?: boolean; reason?: string } | undefined;
169
+ for (const handler of handlers.get("tool_call") ?? []) {
170
+ const result = await handler(
171
+ { toolCallId: "bash-1", toolName: "bash", input: { command } },
172
+ ctx,
173
+ );
174
+ if (result?.block) block = result;
175
+ }
176
+ return block;
177
+ }
178
+
179
+ /** Deliver an affirmative ask_user_questions answer for a destructive gate. */
180
+ async function answerConfirmGate(
181
+ handlers: Map<string, Handler[]>,
182
+ questionId: string,
183
+ ctx: any,
184
+ ): Promise<void> {
185
+ const questions = [
186
+ {
187
+ id: questionId,
188
+ question: "Run this destructive command?",
189
+ options: [{ label: "Yes, run it (Recommended)" }, { label: "No, cancel" }],
190
+ },
191
+ ];
192
+ for (const handler of handlers.get("tool_result") ?? []) {
193
+ await handler(
194
+ {
195
+ toolName: "ask_user_questions",
196
+ input: { questions },
197
+ details: {
198
+ response: { answers: { [questionId]: { selected: "Yes, run it (Recommended)" } } },
199
+ },
200
+ },
201
+ ctx,
202
+ );
203
+ }
204
+ }
205
+
206
+ test("integration: real hooks block a force push, then allow it once after confirmation", async (t) => {
207
+ const dir = "/tmp/gsd-destructive-confirm-int-allow";
208
+ const ctx = { cwd: dir, ui: { notify: () => undefined } } as any;
209
+ resetDestructiveConfirmation(dir);
210
+ t.after(() => resetDestructiveConfirmation(dir));
211
+
212
+ const { handlers, pi } = makeHookHarness();
213
+ registerHooks(pi, []);
214
+
215
+ // 1. First attempt is hard-blocked by the real guard, with instructions that
216
+ // name the destructive_confirm gate.
217
+ const firstBlock = await runBashGuard(handlers, FORCE_PUSH, ctx);
218
+ assert.equal(firstBlock?.block, true, "real guard blocks the first attempt");
219
+ assert.match(firstBlock?.reason ?? "", /HARD BLOCK: destructive Bash command/);
220
+ assert.match(firstBlock?.reason ?? "", /force push/);
221
+ assert.match(firstBlock?.reason ?? "", /destructive_confirm/);
222
+
223
+ // 2. User answers an affirmative destructive_confirm gate.
224
+ await answerConfirmGate(handlers, "destructive_confirm_force_push", ctx);
225
+
226
+ // 3. Re-issuing the exact command in the same turn now runs once (no block).
227
+ const secondAttempt = await runBashGuard(handlers, FORCE_PUSH, ctx);
228
+ assert.equal(secondAttempt, undefined, "confirmed command passes the real guard once");
229
+
230
+ // 4. One-shot: an immediate identical third attempt re-blocks.
231
+ const thirdAttempt = await runBashGuard(handlers, FORCE_PUSH, ctx);
232
+ assert.equal(thirdAttempt?.block, true, "second run of the same command re-blocks (one-shot)");
233
+ });
234
+
235
+ test("integration: declining the confirm gate leaves the command blocked", async (t) => {
236
+ const dir = "/tmp/gsd-destructive-confirm-int-decline";
237
+ const ctx = { cwd: dir, ui: { notify: () => undefined } } as any;
238
+ resetDestructiveConfirmation(dir);
239
+ t.after(() => resetDestructiveConfirmation(dir));
240
+
241
+ const { handlers, pi } = makeHookHarness();
242
+ registerHooks(pi, []);
243
+
244
+ assert.equal((await runBashGuard(handlers, FORCE_PUSH, ctx))?.block, true, "first attempt blocks");
245
+
246
+ // Decline: the non-affirmative (non-first) option must NOT promote a token.
247
+ const questions = [
248
+ {
249
+ id: "destructive_confirm_force_push",
250
+ question: "Run this destructive command?",
251
+ options: [{ label: "Yes, run it (Recommended)" }, { label: "No, cancel" }],
252
+ },
253
+ ];
254
+ for (const handler of handlers.get("tool_result") ?? []) {
255
+ await handler(
256
+ {
257
+ toolName: "ask_user_questions",
258
+ input: { questions },
259
+ details: {
260
+ response: { answers: { "destructive_confirm_force_push": { selected: "No, cancel" } } },
261
+ },
262
+ },
263
+ ctx,
264
+ );
265
+ }
266
+
267
+ assert.equal(
268
+ (await runBashGuard(handlers, FORCE_PUSH, ctx))?.block,
269
+ true,
270
+ "declined command stays blocked",
271
+ );
272
+ });
273
+
274
+ test("integration: a confirm token does not leak to a different destructive command", async (t) => {
275
+ const dir = "/tmp/gsd-destructive-confirm-int-bound";
276
+ const ctx = { cwd: dir, ui: { notify: () => undefined } } as any;
277
+ resetDestructiveConfirmation(dir);
278
+ t.after(() => resetDestructiveConfirmation(dir));
279
+
280
+ const { handlers, pi } = makeHookHarness();
281
+ registerHooks(pi, []);
282
+
283
+ await runBashGuard(handlers, FORCE_PUSH, ctx);
284
+ await answerConfirmGate(handlers, "destructive_confirm_force_push", ctx);
285
+
286
+ // A different destructive command must not ride the force-push confirmation.
287
+ // In the real guard, blocking this command also records it as pending, which
288
+ // invalidates the stale force-push token (stale-token safety invariant) — so
289
+ // the original confirmation is consumed/cleared, not left dangling.
290
+ assert.equal(
291
+ (await runBashGuard(handlers, "rm -rf build", ctx))?.block,
292
+ true,
293
+ "unrelated destructive command is still blocked",
294
+ );
295
+ // Because the unrelated block invalidated the stale token, the original
296
+ // force-push now re-blocks too: a confirmation never survives an intervening
297
+ // destructive command. This is stricter (safer) than per-command isolation.
298
+ assert.equal(
299
+ (await runBashGuard(handlers, FORCE_PUSH, ctx))?.block,
300
+ true,
301
+ "force-push token was invalidated by the intervening destructive block",
302
+ );
303
+ });
@@ -39,7 +39,11 @@ function makeDiscussPi() {
39
39
  tmp,
40
40
  pi: {
41
41
  getActiveTools: () => ["gsd_summary_save", "bash"],
42
+ emitAdjustToolSet: async () => undefined,
43
+ emitBeforeModelSelect: async () => undefined,
44
+ setModel: async () => true,
42
45
  setActiveTools: () => {},
46
+ setThinkingLevel: () => {},
43
47
  sendMessage: (message: { content?: unknown }) => {
44
48
  sent.push(message);
45
49
  },
@@ -53,6 +57,7 @@ function makeDiscussPi() {
53
57
  }
54
58
 
55
59
  function makeDiscussCtx(notifications: Array<{ message: string; level?: string }> = []) {
60
+ const model = { provider: "anthropic", id: "claude-sonnet-4-6", api: "anthropic-messages" };
56
61
  return {
57
62
  hasUI: true,
58
63
  sessionManager: {
@@ -65,8 +70,13 @@ function makeDiscussCtx(notifications: Array<{ message: string; level?: string }
65
70
  setStatus: () => {},
66
71
  },
67
72
  waitForIdle: async () => {},
68
- model: undefined,
69
- modelRegistry: { getProviderAuthMode: () => undefined },
73
+ model,
74
+ modelRegistry: {
75
+ getAvailable: () => [model],
76
+ getAll: () => [model],
77
+ getProviderAuthMode: () => "apiKey",
78
+ isProviderRequestReady: () => true,
79
+ },
70
80
  };
71
81
  }
72
82