@opengsd/gsd-pi 1.2.0-dev.5457a158 → 1.2.0-dev.822c9439

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 (489) hide show
  1. package/dist/headless-events.js +7 -5
  2. package/dist/mcp-server.js +2 -1
  3. package/dist/resource-loader.d.ts +9 -5
  4. package/dist/resource-loader.js +114 -6
  5. package/dist/resources/.managed-resources-content-hash +1 -1
  6. package/dist/resources/GSD-WORKFLOW.md +5 -4
  7. package/dist/resources/extensions/async-jobs/async-bash-tool.js +30 -64
  8. package/dist/resources/extensions/async-jobs/await-tool.js +80 -12
  9. package/dist/resources/extensions/async-jobs/index.js +65 -0
  10. package/dist/resources/extensions/async-jobs/job-manager.js +12 -1
  11. package/dist/resources/extensions/bg-shell/bg-shell-command.js +6 -6
  12. package/dist/resources/extensions/bg-shell/bg-shell-tool.js +10 -7
  13. package/dist/resources/extensions/bg-shell/overlay.js +9 -6
  14. package/dist/resources/extensions/bg-shell/process-manager.js +54 -25
  15. package/dist/resources/extensions/bg-shell/readiness-detector.js +11 -0
  16. package/dist/resources/extensions/browser-tools/engine/managed-gsd-browser.js +209 -88
  17. package/dist/resources/extensions/browser-tools/engine/selection.js +73 -5
  18. package/dist/resources/extensions/browser-tools/index.js +69 -12
  19. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +3 -2
  20. package/dist/resources/extensions/gsd/auto/custom-verify-retry-store.js +17 -2
  21. package/dist/resources/extensions/gsd/auto/detect-stuck.js +33 -13
  22. package/dist/resources/extensions/gsd/auto/dispatch-history.js +105 -0
  23. package/dist/resources/extensions/gsd/auto/dispatch-key.js +37 -0
  24. package/dist/resources/extensions/gsd/auto/loop.js +4 -1
  25. package/dist/resources/extensions/gsd/auto/orchestrator.js +89 -54
  26. package/dist/resources/extensions/gsd/auto/phases.js +49 -6
  27. package/dist/resources/extensions/gsd/auto/session.js +3 -0
  28. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +11 -34
  29. package/dist/resources/extensions/gsd/auto-dispatch.js +50 -58
  30. package/dist/resources/extensions/gsd/auto-model-selection.js +36 -13
  31. package/dist/resources/extensions/gsd/auto-post-unit.js +30 -12
  32. package/dist/resources/extensions/gsd/auto-prompts.js +78 -19
  33. package/dist/resources/extensions/gsd/auto-start.js +12 -12
  34. package/dist/resources/extensions/gsd/auto-unit-closeout.js +45 -21
  35. package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +5 -4
  36. package/dist/resources/extensions/gsd/auto-verification.js +23 -30
  37. package/dist/resources/extensions/gsd/auto-worktree.js +14 -1
  38. package/dist/resources/extensions/gsd/auto.js +37 -1
  39. package/dist/resources/extensions/gsd/blocked-models.js +28 -0
  40. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +26 -6
  41. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +23 -6
  42. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +2 -2
  43. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +19 -0
  44. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +172 -59
  45. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +302 -80
  46. package/dist/resources/extensions/gsd/browser-daemon-auto-prep.js +83 -0
  47. package/dist/resources/extensions/gsd/browser-evidence.js +8 -2
  48. package/dist/resources/extensions/gsd/closeout-wizard.js +92 -0
  49. package/dist/resources/extensions/gsd/commands/context.js +16 -2
  50. package/dist/resources/extensions/gsd/commands-handlers.js +46 -3
  51. package/dist/resources/extensions/gsd/consent-question.js +353 -0
  52. package/dist/resources/extensions/gsd/consent-verdict.js +63 -0
  53. package/dist/resources/extensions/gsd/constants.js +0 -2
  54. package/dist/resources/extensions/gsd/crash-recovery.js +8 -3
  55. package/dist/resources/extensions/gsd/db/queries.js +26 -0
  56. package/dist/resources/extensions/gsd/dispatch-guard.js +10 -35
  57. package/dist/resources/extensions/gsd/doctor-engine-checks.js +5 -5
  58. package/dist/resources/extensions/gsd/doctor-git-checks.js +2 -18
  59. package/dist/resources/extensions/gsd/engine-hook-contract.js +70 -0
  60. package/dist/resources/extensions/gsd/exec-sandbox.js +30 -10
  61. package/dist/resources/extensions/gsd/files.js +33 -19
  62. package/dist/resources/extensions/gsd/gsd-command-home.js +22 -12
  63. package/dist/resources/extensions/gsd/gsd-db.js +2 -1
  64. package/dist/resources/extensions/gsd/guidance.js +60 -0
  65. package/dist/resources/extensions/gsd/guided-flow.js +6 -3
  66. package/dist/resources/extensions/gsd/markdown-renderer.js +10 -0
  67. package/dist/resources/extensions/gsd/mcp-filter.js +2 -19
  68. package/dist/resources/extensions/gsd/milestone-closeout.js +85 -24
  69. package/dist/resources/extensions/gsd/milestone-planning-persistence.js +2 -2
  70. package/dist/resources/extensions/gsd/milestone-reopen-events.js +3 -5
  71. package/dist/resources/extensions/gsd/parsers-legacy.js +16 -4
  72. package/dist/resources/extensions/gsd/preferences-models.js +2 -2
  73. package/dist/resources/extensions/gsd/projection-flush.js +7 -0
  74. package/dist/resources/extensions/gsd/prompts/complete-slice.md +3 -3
  75. package/dist/resources/extensions/gsd/prompts/execute-task.md +1 -1
  76. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  77. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  78. package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -1
  79. package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
  80. package/dist/resources/extensions/gsd/prompts/refine-slice.md +1 -1
  81. package/dist/resources/extensions/gsd/prompts/replan-slice.md +1 -1
  82. package/dist/resources/extensions/gsd/prompts/research-milestone.md +1 -1
  83. package/dist/resources/extensions/gsd/prompts/research-slice.md +1 -1
  84. package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  85. package/dist/resources/extensions/gsd/prompts/run-uat.md +7 -5
  86. package/dist/resources/extensions/gsd/prompts/system.md +5 -2
  87. package/dist/resources/extensions/gsd/prompts/triage-captures.md +1 -1
  88. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +1 -1
  89. package/dist/resources/extensions/gsd/reactive-graph.js +8 -1
  90. package/dist/resources/extensions/gsd/roadmap-slices.js +25 -3
  91. package/dist/resources/extensions/gsd/safety/destructive-confirmation.js +108 -0
  92. package/dist/resources/extensions/gsd/session-lock.js +1 -1
  93. package/dist/resources/extensions/gsd/state.js +5 -0
  94. package/dist/resources/extensions/gsd/tool-contract.js +14 -3
  95. package/dist/resources/extensions/gsd/tool-presentation-plan.js +4 -4
  96. package/dist/resources/extensions/gsd/tools/complete-milestone.js +3 -2
  97. package/dist/resources/extensions/gsd/tools/complete-slice.js +22 -12
  98. package/dist/resources/extensions/gsd/tools/complete-task.js +3 -2
  99. package/dist/resources/extensions/gsd/tools/exec-tool.js +5 -0
  100. package/dist/resources/extensions/gsd/tools/plan-slice.js +2 -2
  101. package/dist/resources/extensions/gsd/tools/plan-task.js +2 -2
  102. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +2 -2
  103. package/dist/resources/extensions/gsd/tools/reopen-milestone.js +2 -2
  104. package/dist/resources/extensions/gsd/tools/reopen-slice.js +2 -2
  105. package/dist/resources/extensions/gsd/tools/reopen-task.js +2 -2
  106. package/dist/resources/extensions/gsd/tools/replan-slice.js +2 -2
  107. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +67 -2
  108. package/dist/resources/extensions/gsd/uat-policy.js +42 -16
  109. package/dist/resources/extensions/gsd/unit-context-composer.js +65 -0
  110. package/dist/resources/extensions/gsd/unit-registry.js +7 -20
  111. package/dist/resources/extensions/gsd/verdict-parser.js +1 -1
  112. package/dist/resources/extensions/gsd/verification-verdict.js +2 -1
  113. package/dist/resources/extensions/gsd/web-app-uat.js +45 -8
  114. package/dist/resources/extensions/gsd/workflow-event-ledger.js +91 -0
  115. package/dist/resources/extensions/gsd/workflow-event-vocabulary.js +46 -0
  116. package/dist/resources/extensions/gsd/workflow-events.js +6 -18
  117. package/dist/resources/extensions/gsd/workflow-reconcile.js +21 -56
  118. package/dist/resources/extensions/gsd/worktree-lifecycle.js +3 -2
  119. package/dist/resources/extensions/gsd/worktree-manager.js +7 -1
  120. package/dist/resources/extensions/gsd/worktree.js +8 -1
  121. package/dist/resources/extensions/search-the-web/native-search.js +5 -3
  122. package/dist/resources/extensions/shared/browser-contract.js +59 -0
  123. package/dist/resources/extensions/shared/gsd-browser-cli.js +116 -6
  124. package/dist/resources/shared/gsd-browser-path-sync.js +214 -0
  125. package/dist/resources/shared/package-manager-detection.js +1 -1
  126. package/dist/resources/shared/package.json +3 -0
  127. package/dist/resources/skills/create-skill/SKILL.md +3 -0
  128. package/dist/resources/skills/create-skill/references/executable-code.md +1 -1
  129. package/dist/resources/skills/create-skill/references/skill-structure.md +1 -0
  130. package/dist/resources/skills/create-skill/workflows/add-reference.md +8 -3
  131. package/dist/resources/skills/create-skill/workflows/add-script.md +4 -2
  132. package/dist/resources/skills/create-skill/workflows/add-template.md +3 -1
  133. package/dist/resources/skills/create-skill/workflows/add-workflow.md +8 -3
  134. package/dist/resources/skills/create-skill/workflows/upgrade-to-router.md +10 -5
  135. package/dist/resources/skills/create-skill/workflows/verify-skill.md +9 -4
  136. package/dist/resources/skills/spike-wrap-up/SKILL.md +9 -9
  137. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  138. package/dist/update-check.d.ts +2 -0
  139. package/dist/update-check.js +24 -1
  140. package/dist/update-cmd.js +20 -3
  141. package/dist/web/standalone/.next/BUILD_ID +1 -1
  142. package/dist/web/standalone/.next/app-path-routes-manifest.json +11 -11
  143. package/dist/web/standalone/.next/build-manifest.json +3 -3
  144. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  145. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  146. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  147. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  148. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  149. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  150. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  151. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  152. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  153. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  154. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  155. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  156. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  157. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  158. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  159. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  160. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  161. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  162. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/update/route.js.nft.json +1 -1
  164. package/dist/web/standalone/.next/server/app/index.html +1 -1
  165. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  166. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  167. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  168. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  169. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  170. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  171. package/dist/web/standalone/.next/server/app-paths-manifest.json +11 -11
  172. package/dist/web/standalone/.next/server/chunks/8357.js +2 -2
  173. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  174. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  175. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  176. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  177. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  178. package/dist/web/standalone/.next/static/chunks/{796.cf859a427a2cb2ac.js → 796.e0bdc932325d7e03.js} +1 -1
  179. package/dist/web/standalone/.next/static/chunks/{webpack-fbea77b5f9953368.js → webpack-f0285ce91d4ec9ef.js} +1 -1
  180. package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
  181. package/dist/web/standalone/package.json +1 -1
  182. package/package.json +1 -1
  183. package/packages/cloud-mcp-gateway/package.json +2 -2
  184. package/packages/contracts/dist/rpc.d.ts +1 -0
  185. package/packages/contracts/dist/rpc.d.ts.map +1 -1
  186. package/packages/contracts/dist/rpc.js.map +1 -1
  187. package/packages/contracts/package.json +1 -1
  188. package/packages/daemon/package.json +4 -4
  189. package/packages/gsd-agent-core/package.json +5 -5
  190. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +5 -0
  191. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  192. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +5 -0
  193. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  194. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  195. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +7 -0
  196. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  197. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
  198. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js +8 -1
  199. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  200. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.d.ts.map +1 -1
  201. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js +11 -1
  202. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js.map +1 -1
  203. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.d.ts.map +1 -1
  204. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js +4 -4
  205. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js.map +1 -1
  206. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  207. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +3 -1
  208. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -1
  209. package/packages/gsd-agent-modes/package.json +7 -7
  210. package/packages/mcp-server/dist/cli.js +10 -5
  211. package/packages/mcp-server/dist/cli.js.map +1 -1
  212. package/packages/mcp-server/dist/moonshot-tool-schema.d.ts +29 -0
  213. package/packages/mcp-server/dist/moonshot-tool-schema.d.ts.map +1 -0
  214. package/packages/mcp-server/dist/moonshot-tool-schema.js +50 -0
  215. package/packages/mcp-server/dist/moonshot-tool-schema.js.map +1 -0
  216. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  217. package/packages/mcp-server/dist/server.js +4 -0
  218. package/packages/mcp-server/dist/server.js.map +1 -1
  219. package/packages/mcp-server/dist/workflow-tools.d.ts +18 -18
  220. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  221. package/packages/mcp-server/dist/workflow-tools.js +99 -38
  222. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  223. package/packages/mcp-server/package.json +5 -4
  224. package/packages/native/package.json +1 -1
  225. package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts +1 -0
  226. package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts.map +1 -1
  227. package/packages/pi-agent-core/dist/harness/env/nodejs.js +34 -3
  228. package/packages/pi-agent-core/dist/harness/env/nodejs.js.map +1 -1
  229. package/packages/pi-agent-core/dist/index.d.ts +1 -0
  230. package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
  231. package/packages/pi-agent-core/dist/index.js +3 -0
  232. package/packages/pi-agent-core/dist/index.js.map +1 -1
  233. package/packages/pi-agent-core/package.json +1 -1
  234. package/packages/pi-ai/README.md +1 -0
  235. package/packages/pi-ai/dist/image-models.generated.d.ts +2 -2
  236. package/packages/pi-ai/dist/image-models.generated.js +6 -6
  237. package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
  238. package/packages/pi-ai/dist/index.d.ts +2 -0
  239. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  240. package/packages/pi-ai/dist/index.js +2 -0
  241. package/packages/pi-ai/dist/index.js.map +1 -1
  242. package/packages/pi-ai/dist/models.generated.d.ts +239 -153
  243. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  244. package/packages/pi-ai/dist/models.generated.js +256 -145
  245. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  246. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  247. package/packages/pi-ai/dist/providers/anthropic.js +12 -7
  248. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  249. package/packages/pi-ai/dist/providers/google-shared.d.ts +5 -0
  250. package/packages/pi-ai/dist/providers/google-shared.d.ts.map +1 -1
  251. package/packages/pi-ai/dist/providers/google-shared.js +12 -3
  252. package/packages/pi-ai/dist/providers/google-shared.js.map +1 -1
  253. package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
  254. package/packages/pi-ai/dist/providers/openai-completions.js +7 -3
  255. package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
  256. package/packages/pi-ai/dist/utils/moonshot-tool-schema.d.ts +9 -0
  257. package/packages/pi-ai/dist/utils/moonshot-tool-schema.d.ts.map +1 -0
  258. package/packages/pi-ai/dist/utils/moonshot-tool-schema.js +34 -0
  259. package/packages/pi-ai/dist/utils/moonshot-tool-schema.js.map +1 -0
  260. package/packages/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
  261. package/packages/pi-ai/dist/utils/oauth/github-copilot.js +6 -2
  262. package/packages/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
  263. package/packages/pi-ai/package.json +3 -2
  264. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +2 -2
  265. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  266. package/packages/pi-coding-agent/dist/core/auth-storage.js +19 -13
  267. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  268. package/packages/pi-coding-agent/dist/core/provider-readiness.d.ts.map +1 -1
  269. package/packages/pi-coding-agent/dist/core/provider-readiness.js +13 -6
  270. package/packages/pi-coding-agent/dist/core/provider-readiness.js.map +1 -1
  271. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts +11 -0
  272. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
  273. package/packages/pi-coding-agent/dist/core/tools/bash.js +53 -11
  274. package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
  275. package/packages/pi-coding-agent/dist/index.d.ts +1 -1
  276. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  277. package/packages/pi-coding-agent/dist/index.js +1 -1
  278. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  279. package/packages/pi-coding-agent/dist/utils/shell.d.ts +28 -2
  280. package/packages/pi-coding-agent/dist/utils/shell.d.ts.map +1 -1
  281. package/packages/pi-coding-agent/dist/utils/shell.js +56 -10
  282. package/packages/pi-coding-agent/dist/utils/shell.js.map +1 -1
  283. package/packages/pi-coding-agent/package.json +7 -7
  284. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  285. package/packages/pi-tui/dist/tui.js +9 -0
  286. package/packages/pi-tui/dist/tui.js.map +1 -1
  287. package/packages/pi-tui/package.json +2 -2
  288. package/packages/rpc-client/package.json +2 -2
  289. package/pkg/package.json +1 -1
  290. package/src/resources/GSD-WORKFLOW.md +5 -4
  291. package/src/resources/extensions/async-jobs/async-bash-cancel.test.ts +360 -0
  292. package/src/resources/extensions/async-jobs/async-bash-tool.ts +33 -56
  293. package/src/resources/extensions/async-jobs/await-tool.test.ts +139 -0
  294. package/src/resources/extensions/async-jobs/await-tool.ts +82 -12
  295. package/src/resources/extensions/async-jobs/index.ts +79 -0
  296. package/src/resources/extensions/async-jobs/job-manager.ts +21 -1
  297. package/src/resources/extensions/bg-shell/bg-shell-command.ts +6 -6
  298. package/src/resources/extensions/bg-shell/bg-shell-tool.ts +10 -6
  299. package/src/resources/extensions/bg-shell/overlay.ts +9 -5
  300. package/src/resources/extensions/bg-shell/process-manager.ts +50 -25
  301. package/src/resources/extensions/bg-shell/readiness-detector.ts +12 -0
  302. package/src/resources/extensions/bg-shell/tests/lifecycle-and-utilities.test.ts +48 -1
  303. package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +265 -98
  304. package/src/resources/extensions/browser-tools/engine/selection.ts +90 -4
  305. package/src/resources/extensions/browser-tools/index.ts +71 -13
  306. package/src/resources/extensions/browser-tools/tests/browser-engine-selection.test.mjs +83 -13
  307. package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +40 -1
  308. package/src/resources/extensions/browser-tools/tests/managed-gsd-browser-tools.test.mjs +136 -0
  309. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +3 -2
  310. package/src/resources/extensions/gsd/auto/custom-verify-retry-store.ts +21 -3
  311. package/src/resources/extensions/gsd/auto/detect-stuck.ts +32 -9
  312. package/src/resources/extensions/gsd/auto/dispatch-history.ts +152 -0
  313. package/src/resources/extensions/gsd/auto/dispatch-key.ts +39 -0
  314. package/src/resources/extensions/gsd/auto/loop.ts +4 -1
  315. package/src/resources/extensions/gsd/auto/orchestrator.ts +98 -56
  316. package/src/resources/extensions/gsd/auto/phases.ts +65 -26
  317. package/src/resources/extensions/gsd/auto/session.ts +3 -0
  318. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +18 -48
  319. package/src/resources/extensions/gsd/auto-dispatch.ts +48 -61
  320. package/src/resources/extensions/gsd/auto-model-selection.ts +41 -12
  321. package/src/resources/extensions/gsd/auto-post-unit.ts +33 -12
  322. package/src/resources/extensions/gsd/auto-prompts.ts +115 -35
  323. package/src/resources/extensions/gsd/auto-start.ts +12 -14
  324. package/src/resources/extensions/gsd/auto-unit-closeout.ts +83 -28
  325. package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +4 -4
  326. package/src/resources/extensions/gsd/auto-verification.ts +26 -28
  327. package/src/resources/extensions/gsd/auto-worktree.ts +14 -1
  328. package/src/resources/extensions/gsd/auto.ts +44 -1
  329. package/src/resources/extensions/gsd/blocked-models.ts +49 -0
  330. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +34 -5
  331. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +23 -6
  332. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +2 -2
  333. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +24 -0
  334. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +211 -59
  335. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +350 -86
  336. package/src/resources/extensions/gsd/browser-daemon-auto-prep.ts +108 -0
  337. package/src/resources/extensions/gsd/browser-evidence.ts +18 -2
  338. package/src/resources/extensions/gsd/closeout-wizard.ts +102 -0
  339. package/src/resources/extensions/gsd/commands/context.ts +16 -2
  340. package/src/resources/extensions/gsd/commands-handlers.ts +46 -3
  341. package/src/resources/extensions/gsd/consent-question.ts +431 -0
  342. package/src/resources/extensions/gsd/consent-verdict.ts +86 -0
  343. package/src/resources/extensions/gsd/constants.ts +0 -3
  344. package/src/resources/extensions/gsd/crash-recovery.ts +10 -2
  345. package/src/resources/extensions/gsd/db/queries.ts +37 -0
  346. package/src/resources/extensions/gsd/dispatch-guard.ts +8 -31
  347. package/src/resources/extensions/gsd/doctor-engine-checks.ts +5 -4
  348. package/src/resources/extensions/gsd/doctor-git-checks.ts +2 -19
  349. package/src/resources/extensions/gsd/engine-hook-contract.ts +79 -0
  350. package/src/resources/extensions/gsd/exec-sandbox.ts +49 -9
  351. package/src/resources/extensions/gsd/files.ts +33 -12
  352. package/src/resources/extensions/gsd/gsd-command-home.ts +13 -3
  353. package/src/resources/extensions/gsd/gsd-db.ts +4 -3
  354. package/src/resources/extensions/gsd/guidance.ts +78 -0
  355. package/src/resources/extensions/gsd/guided-flow.ts +21 -26
  356. package/src/resources/extensions/gsd/markdown-renderer.ts +11 -0
  357. package/src/resources/extensions/gsd/mcp-filter.ts +2 -23
  358. package/src/resources/extensions/gsd/milestone-closeout.ts +109 -24
  359. package/src/resources/extensions/gsd/milestone-planning-persistence.ts +2 -2
  360. package/src/resources/extensions/gsd/milestone-reopen-events.ts +3 -6
  361. package/src/resources/extensions/gsd/parsers-legacy.ts +16 -4
  362. package/src/resources/extensions/gsd/preferences-models.ts +2 -1
  363. package/src/resources/extensions/gsd/projection-flush.ts +20 -0
  364. package/src/resources/extensions/gsd/prompts/complete-slice.md +3 -3
  365. package/src/resources/extensions/gsd/prompts/execute-task.md +1 -1
  366. package/src/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  367. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  368. package/src/resources/extensions/gsd/prompts/quick-task.md +1 -1
  369. package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
  370. package/src/resources/extensions/gsd/prompts/refine-slice.md +1 -1
  371. package/src/resources/extensions/gsd/prompts/replan-slice.md +1 -1
  372. package/src/resources/extensions/gsd/prompts/research-milestone.md +1 -1
  373. package/src/resources/extensions/gsd/prompts/research-slice.md +1 -1
  374. package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  375. package/src/resources/extensions/gsd/prompts/run-uat.md +7 -5
  376. package/src/resources/extensions/gsd/prompts/system.md +5 -2
  377. package/src/resources/extensions/gsd/prompts/triage-captures.md +1 -1
  378. package/src/resources/extensions/gsd/prompts/validate-milestone.md +1 -1
  379. package/src/resources/extensions/gsd/reactive-graph.ts +11 -1
  380. package/src/resources/extensions/gsd/roadmap-slices.ts +28 -3
  381. package/src/resources/extensions/gsd/safety/destructive-confirmation.ts +134 -0
  382. package/src/resources/extensions/gsd/session-lock.ts +1 -1
  383. package/src/resources/extensions/gsd/state.ts +5 -0
  384. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +97 -1
  385. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +198 -26
  386. package/src/resources/extensions/gsd/tests/auto-remote-session-lock-cleanup.test.ts +65 -3
  387. package/src/resources/extensions/gsd/tests/blocked-models.test.ts +19 -0
  388. package/src/resources/extensions/gsd/tests/browser-automation-contract-fixture.ts +39 -0
  389. package/src/resources/extensions/gsd/tests/browser-contract.test.ts +44 -0
  390. package/src/resources/extensions/gsd/tests/browser-daemon-auto-prep.test.ts +144 -0
  391. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +42 -0
  392. package/src/resources/extensions/gsd/tests/consent-question.test.ts +351 -0
  393. package/src/resources/extensions/gsd/tests/custom-verify-retry-store.test.ts +67 -0
  394. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +10 -10
  395. package/src/resources/extensions/gsd/tests/destructive-confirmation.test.ts +303 -0
  396. package/src/resources/extensions/gsd/tests/discuss-routing-fixes.test.ts +12 -2
  397. package/src/resources/extensions/gsd/tests/dispatch-history.test.ts +273 -0
  398. package/src/resources/extensions/gsd/tests/dispatch-run-uat-browser-tools.test.ts +2 -1
  399. package/src/resources/extensions/gsd/tests/doctor-git-checks-terminal.test.ts +73 -0
  400. package/src/resources/extensions/gsd/tests/dynamic-bash-no-cap.test.ts +132 -0
  401. package/src/resources/extensions/gsd/tests/engine-hook-contract.test.ts +148 -0
  402. package/src/resources/extensions/gsd/tests/exec-graceful-kill.test.ts +193 -0
  403. package/src/resources/extensions/gsd/tests/exec-tool.test.ts +29 -1
  404. package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +35 -1
  405. package/src/resources/extensions/gsd/tests/gsd-command-home.test.ts +120 -0
  406. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +27 -0
  407. package/src/resources/extensions/gsd/tests/guidance.test.ts +23 -0
  408. package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +2 -6
  409. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +7 -11
  410. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +20 -58
  411. package/src/resources/extensions/gsd/tests/integration/gsd-integration-fixture.ts +80 -0
  412. package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +199 -0
  413. package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +3 -1
  414. package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +95 -4
  415. package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +32 -1
  416. package/src/resources/extensions/gsd/tests/oauth-api-model-routing.test.ts +167 -0
  417. package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +18 -0
  418. package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +138 -0
  419. package/src/resources/extensions/gsd/tests/phases-terminal-complete-idempotent.test.ts +242 -0
  420. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +63 -2
  421. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +124 -6
  422. package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +68 -0
  423. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +19 -1
  424. package/src/resources/extensions/gsd/tests/teardown-chdir-failure-clears-registry.test.ts +17 -0
  425. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +76 -0
  426. package/src/resources/extensions/gsd/tests/tool-unavailable-retry.test.ts +33 -0
  427. package/src/resources/extensions/gsd/tests/transport-gate-double-complete.test.ts +139 -0
  428. package/src/resources/extensions/gsd/tests/uat-policy.test.ts +112 -29
  429. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +44 -0
  430. package/src/resources/extensions/gsd/tests/uok-audit-unified.test.ts +8 -0
  431. package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +2 -0
  432. package/src/resources/extensions/gsd/tests/web-app-uat.test.ts +44 -1
  433. package/src/resources/extensions/gsd/tests/workflow-events.test.ts +19 -0
  434. package/src/resources/extensions/gsd/tests/workflow-reconcile.test.ts +20 -0
  435. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +273 -38
  436. package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +22 -0
  437. package/src/resources/extensions/gsd/tests/worktree.test.ts +18 -0
  438. package/src/resources/extensions/gsd/tests/write-gate-seam.test.ts +358 -0
  439. package/src/resources/extensions/gsd/tests/write-gate.test.ts +67 -1
  440. package/src/resources/extensions/gsd/tool-contract.ts +38 -3
  441. package/src/resources/extensions/gsd/tool-presentation-plan.ts +4 -4
  442. package/src/resources/extensions/gsd/tools/complete-milestone.ts +3 -2
  443. package/src/resources/extensions/gsd/tools/complete-slice.ts +22 -12
  444. package/src/resources/extensions/gsd/tools/complete-task.ts +3 -2
  445. package/src/resources/extensions/gsd/tools/exec-tool.ts +4 -0
  446. package/src/resources/extensions/gsd/tools/plan-slice.ts +2 -2
  447. package/src/resources/extensions/gsd/tools/plan-task.ts +2 -2
  448. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +2 -2
  449. package/src/resources/extensions/gsd/tools/reopen-milestone.ts +2 -2
  450. package/src/resources/extensions/gsd/tools/reopen-slice.ts +2 -2
  451. package/src/resources/extensions/gsd/tools/reopen-task.ts +2 -2
  452. package/src/resources/extensions/gsd/tools/replan-slice.ts +2 -2
  453. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +81 -2
  454. package/src/resources/extensions/gsd/uat-policy.ts +62 -16
  455. package/src/resources/extensions/gsd/unit-context-composer.ts +99 -0
  456. package/src/resources/extensions/gsd/unit-registry.ts +7 -20
  457. package/src/resources/extensions/gsd/verdict-parser.ts +1 -1
  458. package/src/resources/extensions/gsd/verification-verdict.ts +4 -2
  459. package/src/resources/extensions/gsd/web-app-uat.ts +51 -8
  460. package/src/resources/extensions/gsd/workflow-event-ledger.ts +131 -0
  461. package/src/resources/extensions/gsd/workflow-event-vocabulary.ts +59 -0
  462. package/src/resources/extensions/gsd/workflow-events.ts +12 -20
  463. package/src/resources/extensions/gsd/workflow-reconcile.ts +29 -62
  464. package/src/resources/extensions/gsd/worktree-lifecycle.ts +3 -8
  465. package/src/resources/extensions/gsd/worktree-manager.ts +6 -1
  466. package/src/resources/extensions/gsd/worktree.ts +7 -1
  467. package/src/resources/extensions/search-the-web/native-search.ts +5 -3
  468. package/src/resources/extensions/shared/browser-contract.ts +66 -0
  469. package/src/resources/extensions/shared/gsd-browser-cli.ts +141 -6
  470. package/src/resources/shared/gsd-browser-path-sync.ts +273 -0
  471. package/src/resources/shared/package-manager-detection.ts +1 -1
  472. package/src/resources/shared/package.json +3 -0
  473. package/src/resources/skills/create-skill/SKILL.md +3 -0
  474. package/src/resources/skills/create-skill/references/executable-code.md +1 -1
  475. package/src/resources/skills/create-skill/references/skill-structure.md +1 -0
  476. package/src/resources/skills/create-skill/workflows/add-reference.md +8 -3
  477. package/src/resources/skills/create-skill/workflows/add-script.md +4 -2
  478. package/src/resources/skills/create-skill/workflows/add-template.md +3 -1
  479. package/src/resources/skills/create-skill/workflows/add-workflow.md +8 -3
  480. package/src/resources/skills/create-skill/workflows/upgrade-to-router.md +10 -5
  481. package/src/resources/skills/create-skill/workflows/verify-skill.md +9 -4
  482. package/src/resources/skills/spike-wrap-up/SKILL.md +9 -9
  483. package/dist/resources/extensions/gsd/user-input-boundary.js +0 -218
  484. package/dist/resources/skills/gsd-browser/SKILL.md +0 -41
  485. package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +0 -173
  486. package/src/resources/extensions/gsd/user-input-boundary.ts +0 -216
  487. package/src/resources/skills/gsd-browser/SKILL.md +0 -41
  488. /package/dist/web/standalone/.next/static/{2p9Rv9pQflAxCBbGVI2vb → yWwBo-w09Y_W-nmeeWFRp}/_buildManifest.js +0 -0
  489. /package/dist/web/standalone/.next/static/{2p9Rv9pQflAxCBbGVI2vb → yWwBo-w09Y_W-nmeeWFRp}/_ssgManifest.js +0 -0
@@ -13,7 +13,8 @@ import type { GSDEcosystemBeforeAgentStartHandler } from "../ecosystem/gsd-exten
13
13
  import { updateSnapshot } from "../ecosystem/gsd-extension-api.js";
14
14
 
15
15
  import { buildMilestoneFileName, clearPathCache, milestonesDir, resolveMilestonePath, resolveSliceFile, resolveSlicePath } from "../paths.js";
16
- import { applyAskUserQuestionsGateResult, canonicalToolName, clearDiscussionFlowState, formatPendingAskUserQuestionsGateMessage, isApprovalGateVerifiedInSnapshot, isMilestoneDepthVerified, isMilestoneDepthVerifiedInSnapshot, isQueuePhaseActive, loadWriteGateSnapshot, markApprovalGateVerified, markDepthVerified, refreshWriteGateStateFromDisk, resetWriteGateState, shouldBlockContextWrite, shouldBlockPlanningUnit, shouldBlockQueueExecution, shouldBlockWorktreeWrite, isGateQuestionId, setPendingGate, clearPendingGate, getPendingGate, shouldBlockPendingGate, shouldBlockPendingGateBash, extractDepthVerificationMilestoneId } from "./write-gate.js";
16
+ import { applyAskUserQuestionsGateResult, clearDiscussionFlowState, formatPendingAskUserQuestionsGateMessage, hostWriteGateAdapter, isApprovalGateVerifiedInSnapshot, isDepthConfirmationAnswer, isMilestoneDepthVerified, isMilestoneDepthVerifiedInSnapshot, isQueuePhaseActive, resetWriteGateState, shouldBlockContextWrite, shouldBlockPlanningUnit, shouldBlockQueueExecution, shouldBlockWorktreeWrite, isGateQuestionId, getPendingGate, shouldBlockPendingGate, shouldBlockPendingGateBash, extractDepthVerificationMilestoneId } from "./write-gate.js";
17
+ import { canonicalToolName } from "../engine-hook-contract.js";
17
18
  import { resolveManifest } from "../unit-context-manifest.js";
18
19
  import { isBlockedStateFile, isBashWriteToStateFile, BLOCKED_WRITE_ERROR } from "../write-intercept.js";
19
20
  import { loadFile, saveFile, formatContinue } from "../files.js";
@@ -39,6 +40,12 @@ import { saveActivityLog } from "../activity-log.js";
39
40
  import { recordToolCall as safetyRecordToolCall, recordToolResult as safetyRecordToolResult, saveEvidenceToDisk } from "../safety/evidence-collector.js";
40
41
  import { parseUnitId } from "../unit-id.js";
41
42
  import { classifyCommand } from "../safety/destructive-guard.js";
43
+ import {
44
+ confirmDestructiveCommand,
45
+ consumeDestructiveConfirmation,
46
+ isDestructiveConfirmGateId,
47
+ requestDestructiveConfirmation,
48
+ } from "../safety/destructive-confirmation.js";
42
49
  import { logWarning as safetyLogWarning } from "../workflow-logger.js";
43
50
  import { isUnitCloseoutTool, runInteractiveUnitCloseout } from "../unit-closeout.js";
44
51
  import { installNotifyInterceptor } from "./notify-interceptor.js";
@@ -49,29 +56,28 @@ import { resolveWorktreeProjectRoot } from "../worktree-root.js";
49
56
  import { extractSubagentAgentClasses } from "./subagent-input.js";
50
57
  import {
51
58
  approvalGateIdForUnit,
59
+ evaluateAskUserQuestionsRound,
60
+ formatUnansweredConsentQuestionMessage,
52
61
  isExplicitApprovalResponse,
53
62
  messageHasPendingAskUserQuestionsTool,
54
- shouldPauseForUserApprovalQuestion,
55
- } from "../user-input-boundary.js";
63
+ shouldPauseForQuestion,
64
+ } from "../consent-question.js";
56
65
  import { resolveSkillManifest } from "../skill-manifest.js";
57
66
  import { applyUnitSkillVisibility, unitHasSkillManifest } from "../skill-scope.js";
58
67
  import { getGuidedUnitContext } from "../guided-unit-context.js";
59
68
  import { registerPlanMilestoneSchemaRecovery } from "./plan-milestone-schema-recovery.js";
60
69
  import { AUTO_UNIT_SCOPED_TOOLS, RUN_UAT_BROWSER_TOOL_NAMES, canonicalWorkflowToolName, isWorkflowAliasTool } from "../auto-unit-tool-scope.js";
70
+ import { hasBrowserContractPrefix } from "../../shared/browser-contract.js";
61
71
  import { filterToolsForProvider } from "../model-router.js";
62
72
  import { mcpToolMatchesBaseName } from "../mcp-tool-name.js";
63
73
  import { RUN_UAT_READ_ONLY_TOOL_NAMES, RUN_UAT_WORKFLOW_TOOL_NAMES } from "../tool-presentation-plan.js";
64
74
  import { supportsSourceObservationsForUnit } from "../source-observations.js";
65
75
  import { clearPendingAutoStart } from "../pending-auto-start.js";
66
76
  import { resolveWorkflowToolBasePath } from "./dynamic-tools.js";
77
+ import { getRequiredWorkflowToolsForUnit } from "../unit-tool-contracts.js";
67
78
 
68
79
  let approvalQuestionAbortInFlight = false;
69
80
 
70
- interface DeferredApprovalGate {
71
- gateId: string;
72
- basePath: string;
73
- }
74
-
75
81
  type WelcomeScreenModule = {
76
82
  buildWelcomeScreenLines(opts: { version: string; remoteChannel?: string; width?: number }): string[];
77
83
  };
@@ -142,7 +148,13 @@ async function installWelcomeHeader(ctx: ExtensionContext): Promise<void> {
142
148
  }
143
149
  }
144
150
 
145
- let deferredApprovalGate: DeferredApprovalGate | null = null;
151
+ /**
152
+ * Approval gates whose durable arming is deferred until tool execution /
153
+ * agent end, keyed by basePath. A Map (not a single slot) so concurrent
154
+ * projects in one process cannot lose each other's deferred gate; entries
155
+ * are bounded — cleared on activation, session boundaries, and verification.
156
+ */
157
+ const deferredApprovalGates = new Map<string, string>();
146
158
 
147
159
  export const MINIMAL_GSD_TOOL_NAMES = [
148
160
  "gsd_exec",
@@ -180,7 +192,7 @@ function withPreservedShimTools(toolNames: readonly string[]): string[] {
180
192
 
181
193
  /** True for the browser automation tools (browser_navigate, browser_click, ...). */
182
194
  function isBrowserTool(toolName: string): boolean {
183
- return canonicalToolName(toolName).startsWith("browser_");
195
+ return hasBrowserContractPrefix(canonicalToolName(toolName));
184
196
  }
185
197
 
186
198
  /**
@@ -261,6 +273,7 @@ export function buildMinimalAutoGsdToolSet(
261
273
  activeToolNames: readonly string[],
262
274
  unitType: string | undefined,
263
275
  registeredToolNames: readonly string[] = activeToolNames,
276
+ warnOnUnresolvedRequiredTools = registeredToolNames !== activeToolNames,
264
277
  ): string[] {
265
278
  if (unitType === "run-uat") {
266
279
  return buildRunUatGsdToolSet(activeToolNames, registeredToolNames);
@@ -276,7 +289,36 @@ export function buildMinimalAutoGsdToolSet(
276
289
  [...activeToolNames, ...registeredToolNames],
277
290
  [...MINIMAL_GSD_TOOL_NAMES, ...unitTools],
278
291
  );
279
- return withPreservedShimTools([...new Set([...preserved, ...scoped])]);
292
+ const result = withPreservedShimTools([...new Set([...preserved, ...scoped])]);
293
+ warnIfRequiredWorkflowToolsUnresolved(unitType, result, warnOnUnresolvedRequiredTools);
294
+ return result;
295
+ }
296
+
297
+ function hasResolvedWorkflowTool(
298
+ resolvedToolNames: readonly string[],
299
+ requiredToolName: string,
300
+ ): boolean {
301
+ return resolvedToolNames.some(
302
+ (name) => name === requiredToolName || mcpToolMatchesBaseName(name, requiredToolName),
303
+ );
304
+ }
305
+
306
+ function warnIfRequiredWorkflowToolsUnresolved(
307
+ unitType: string | undefined,
308
+ scopedToolNames: readonly string[],
309
+ shouldWarn: boolean,
310
+ ): void {
311
+ if (!unitType || !shouldWarn) return;
312
+
313
+ const unresolved = getRequiredWorkflowToolsForUnit(unitType).filter(
314
+ (toolName) => !hasResolvedWorkflowTool(scopedToolNames, toolName),
315
+ );
316
+ if (unresolved.length === 0) return;
317
+
318
+ safetyLogWarning(
319
+ "bootstrap",
320
+ `buildMinimalAutoGsdToolSet(${unitType}): required workflow tool(s) not in active/registered surface after scoping: ${unresolved.join(", ")}. Tool registration may have partially failed, provider filtering may have removed a required tool, or workflow MCP may be disconnected.`,
321
+ );
280
322
  }
281
323
 
282
324
  export function buildRunUatGsdToolSet(
@@ -329,6 +371,7 @@ export function buildRequestScopedGsdToolSet(
329
371
  requestCustomMessages: readonly { customType?: string }[] | undefined,
330
372
  registeredToolNames: readonly string[] = activeToolNames,
331
373
  guidedUnitType?: string,
374
+ warnOnUnresolvedRequiredTools = registeredToolNames !== activeToolNames,
332
375
  ): string[] | undefined {
333
376
  for (let index = (requestCustomMessages?.length ?? 0) - 1; index >= 0; index--) {
334
377
  const currentCustomType = requestCustomMessages?.[index]?.customType;
@@ -339,7 +382,12 @@ export function buildRequestScopedGsdToolSet(
339
382
  currentCustomType === "gsd-triage"
340
383
  ) {
341
384
  if (guidedUnitType) {
342
- return buildMinimalAutoGsdToolSet(activeToolNames, guidedUnitType, registeredToolNames);
385
+ return buildMinimalAutoGsdToolSet(
386
+ activeToolNames,
387
+ guidedUnitType,
388
+ registeredToolNames,
389
+ warnOnUnresolvedRequiredTools,
390
+ );
343
391
  }
344
392
  return buildMinimalGsdWorkflowToolSet(activeToolNames, registeredToolNames);
345
393
  }
@@ -388,11 +436,13 @@ function applyMinimalGsdToolSurface(pi: ExtensionAPI): void {
388
436
  const dash = getAutoRuntimeSnapshot();
389
437
  if (dash.active && dash.currentUnit) {
390
438
  const currentToolNames = pi.getActiveTools();
439
+ const hasRegisteredSurface = typeof pi.getAllTools === "function";
391
440
  const registeredToolNames = resolveRegisteredToolNames(pi, currentToolNames);
392
441
  const scopedToolNames = buildMinimalAutoGsdToolSet(
393
442
  currentToolNames,
394
443
  dash.currentUnit.type,
395
444
  registeredToolNames,
445
+ hasRegisteredSurface,
396
446
  );
397
447
  recordAutoToolSurfaceSnapshot({
398
448
  source: "runtime-scope",
@@ -414,9 +464,10 @@ export function scopeGsdWorkflowToolsForDispatch(
414
464
  ): ScopedGsdWorkflowState | null {
415
465
  if (isFullGsdToolSurfaceRequested()) return null;
416
466
  const current = pi.getActiveTools();
467
+ const hasRegisteredSurface = typeof pi.getAllTools === "function";
417
468
  const registeredToolNames = resolveRegisteredToolNames(pi, current);
418
469
  const scoped = unitType
419
- ? buildMinimalAutoGsdToolSet(current, unitType, registeredToolNames)
470
+ ? buildMinimalAutoGsdToolSet(current, unitType, registeredToolNames, hasRegisteredSurface)
420
471
  : buildMinimalGsdWorkflowToolSet(current, registeredToolNames);
421
472
  recordAutoToolSurfaceSnapshot({
422
473
  source: "dispatch-scope",
@@ -511,13 +562,22 @@ async function applyCompactionThresholdOverride(ctx: ExtensionContext): Promise<
511
562
  }
512
563
 
513
564
  function clearDeferredApprovalGate(basePath?: string): void {
514
- if (!basePath || deferredApprovalGate?.basePath === basePath) {
515
- deferredApprovalGate = null;
565
+ if (!basePath) {
566
+ deferredApprovalGates.clear();
567
+ } else {
568
+ deferredApprovalGates.delete(basePath);
516
569
  }
517
570
  }
518
571
 
519
572
  function deferApprovalGate(gateId: string, basePath: string): void {
520
- deferredApprovalGate = { gateId, basePath };
573
+ // Verified-on-disk wins (same adapter policy as activation/re-arm): if the
574
+ // workflow MCP child already verified this gate, deferring would block
575
+ // tools for a gate that can never legitimately arm.
576
+ const snapshot = hostWriteGateAdapter.readState(basePath);
577
+ if (isApprovalGateVerifiedInSnapshot(snapshot, gateId)) return;
578
+ const milestoneId = extractDepthVerificationMilestoneId(gateId);
579
+ if (milestoneId && isMilestoneDepthVerifiedInSnapshot(snapshot, milestoneId)) return;
580
+ deferredApprovalGates.set(basePath, gateId);
521
581
  }
522
582
 
523
583
  function contextBasePath(ctx?: { cwd?: string }): string {
@@ -574,14 +634,13 @@ function isShellExecutionTool(canonicalName: string): boolean {
574
634
  }
575
635
 
576
636
  function activateDeferredApprovalGate(basePath: string): void {
577
- if (deferredApprovalGate?.basePath !== basePath) return;
578
- const gateId = deferredApprovalGate.gateId;
579
- deferredApprovalGate = null;
580
- const snapshot = refreshWriteGateStateFromDisk(basePath);
581
- const milestoneId = extractDepthVerificationMilestoneId(gateId);
582
- if (isApprovalGateVerifiedInSnapshot(snapshot, gateId)) return;
583
- if (milestoneId && isMilestoneDepthVerifiedInSnapshot(snapshot, milestoneId)) return;
584
- setPendingGate(gateId, basePath);
637
+ const gateId = deferredApprovalGates.get(basePath);
638
+ if (gateId === undefined) return;
639
+ deferredApprovalGates.delete(basePath);
640
+ // hostWriteGateAdapter.setPending applies the verified-on-disk-wins merge
641
+ // policy: it refuses to arm (and thereby clobber) a gate the workflow MCP
642
+ // child already verified on disk.
643
+ hostWriteGateAdapter.setPending(gateId, basePath);
585
644
  }
586
645
 
587
646
  function extractGateQuestionId(input: unknown): string | undefined {
@@ -592,7 +651,7 @@ function extractGateQuestionId(input: unknown): string | undefined {
592
651
 
593
652
  function isApprovalGateBlocking(basePath: string): boolean {
594
653
  return Boolean(getPendingGate(basePath))
595
- || (deferredApprovalGate?.basePath === basePath);
654
+ || deferredApprovalGates.has(basePath);
596
655
  }
597
656
 
598
657
  function isContextDraftSummarySave(toolName: string, input: unknown): boolean {
@@ -737,13 +796,14 @@ function shouldBlockDeferredApprovalTool(
737
796
  input: unknown,
738
797
  basePath: string,
739
798
  ): { block: boolean; reason?: string; displayReason?: string } {
740
- if (deferredApprovalGate?.basePath !== basePath) return { block: false };
799
+ const deferredGateId = deferredApprovalGates.get(basePath);
800
+ if (deferredGateId === undefined) return { block: false };
741
801
  if (toolName === "ask_user_questions") return { block: false };
742
802
  if (isContextDraftSummarySave(toolName, input)) return { block: false };
743
803
  return withDepthGateDisplayReason({
744
804
  block: true,
745
805
  reason: [
746
- `HARD BLOCK: Approval question "${deferredApprovalGate.gateId}" has been shown to the user.`,
806
+ `HARD BLOCK: Approval question "${deferredGateId}" has been shown to the user.`,
747
807
  `Only CONTEXT-DRAFT persistence may finish in this same assistant turn.`,
748
808
  `Wait for the user's answer before calling additional tools.`,
749
809
  ].join(" "),
@@ -873,10 +933,12 @@ export function registerHooks(
873
933
  const beforeAgentBasePath = contextBasePath(ctx);
874
934
  const pendingApprovalGate = getPendingGate(beforeAgentBasePath);
875
935
  if (pendingApprovalGate && isExplicitApprovalResponse(event.prompt, pendingApprovalGate)) {
876
- markApprovalGateVerified(pendingApprovalGate, beforeAgentBasePath);
936
+ // Host adapter explicitly: the ambient write-gate exports env-sniff the
937
+ // adapter per call and are reserved for the MCP child's import surface.
938
+ hostWriteGateAdapter.markApprovalGateVerified(pendingApprovalGate, beforeAgentBasePath);
877
939
  const milestoneId = extractDepthVerificationMilestoneId(pendingApprovalGate);
878
- if (milestoneId) markDepthVerified(milestoneId, beforeAgentBasePath);
879
- clearPendingGate(beforeAgentBasePath);
940
+ if (milestoneId) hostWriteGateAdapter.markDepthVerified(milestoneId, beforeAgentBasePath);
941
+ hostWriteGateAdapter.clearPending(beforeAgentBasePath);
880
942
  if (isAutoPaused() && !isAutoActive()) {
881
943
  const { resumeAutoAfterProviderDelay } = await import("./provider-error-resume.js");
882
944
  void resumeAutoAfterProviderDelay(pi, ctx).catch((err) => {
@@ -1100,7 +1162,7 @@ export function registerHooks(
1100
1162
  }
1101
1163
  }
1102
1164
 
1103
- if (!shouldPauseForUserApprovalQuestion(unitType, [event.message])) return;
1165
+ if (!shouldPauseForQuestion(unitType, [event.message])) return;
1104
1166
 
1105
1167
  const gateId = approvalGateIdForUnit(unitType, unitId);
1106
1168
  if (gateId) {
@@ -1115,7 +1177,7 @@ export function registerHooks(
1115
1177
 
1116
1178
  approvalQuestionAbortInFlight = true;
1117
1179
  ctx.ui.notify(
1118
- `${unitType}${unitId ? ` ${unitId}` : ""} is waiting for your approval - pausing before more tool calls run.`,
1180
+ `${unitType ?? "The discussion"}${unitId ? ` ${unitId}` : ""} is waiting for your approval - pausing before more tool calls run.`,
1119
1181
  "info",
1120
1182
  );
1121
1183
  // The durable pending gate is activated at agent_end so same-turn
@@ -1143,6 +1205,13 @@ export function registerHooks(
1143
1205
  }
1144
1206
  });
1145
1207
 
1208
+ // Engine hook contract (../engine-hook-contract.ts): tool_call is
1209
+ // NATIVE_ONLY_TOOL_HOOKS — it never fires under external engines
1210
+ // (claude-code-cli pre-executes tools). The guards below (loop guard,
1211
+ // pending/deferred gate blocks, queue guard, planning-unit tools policy,
1212
+ // worktree write gate, STATE.md single-writer, context-write depth gate)
1213
+ // are therefore native-engine enforcement only. The write-gate arming
1214
+ // concern has a universal mirror at tool_execution_start below.
1146
1215
  pi.on("tool_call", async (event, ctx) => {
1147
1216
  const discussionBasePath = contextBasePath(ctx);
1148
1217
  const toolName = canonicalToolName(event.toolName);
@@ -1330,6 +1399,11 @@ export function registerHooks(
1330
1399
  });
1331
1400
 
1332
1401
  // ── Safety harness: evidence collection + destructive command blocking ──
1402
+ // Engine hook contract: tool_call is NATIVE_ONLY_TOOL_HOOKS. Evidence
1403
+ // collection here is mirrored universally at tool_execution_start
1404
+ // (safetyRecordToolCall dedupes by toolCallId); the destructive-command
1405
+ // hard gate has NO universal mirror — blocking is impossible once an
1406
+ // external engine has already executed the command.
1333
1407
  pi.on("tool_call", async (event, ctx) => {
1334
1408
  markToolStart(event.toolCallId, event.toolName);
1335
1409
  safetyRecordToolCall(event.toolCallId, event.toolName, event.input as Record<string, unknown>);
@@ -1349,23 +1423,39 @@ export function registerHooks(
1349
1423
 
1350
1424
  // Destructive command classification + hard gate in all modes.
1351
1425
  if (isToolCallEventType("bash", event)) {
1352
- const classification = classifyCommand(event.input.command);
1426
+ const command = event.input.command;
1427
+ const classification = classifyCommand(command);
1353
1428
  if (classification.destructive) {
1429
+ const guardBasePath = contextBasePath(ctx);
1430
+ // Escape hatch: if the user already confirmed this exact command via a
1431
+ // destructive_confirm gate, consume the one-shot token and let it run.
1432
+ // Without this, the block below loops forever — the model cannot satisfy
1433
+ // "confirm in the current turn" because nothing ever clears the gate.
1434
+ if (consumeDestructiveConfirmation(command, guardBasePath)) {
1435
+ safetyLogWarning("safety", `destructive command confirmed: ${classification.labels.join(", ")}`, {
1436
+ command: String(command).slice(0, 200),
1437
+ });
1438
+ return;
1439
+ }
1440
+ // Record the command as pending so an affirmative answer to a
1441
+ // destructive_confirm gate (handled in tool_result) can confirm it.
1442
+ requestDestructiveConfirmation(command, guardBasePath);
1354
1443
  const reason = [
1355
1444
  "HARD BLOCK: destructive Bash command requires explicit human confirmation.",
1356
1445
  `Detected: ${classification.labels.join(", ")}`,
1357
- "Run this via ask_user_questions, wait for the user's response,",
1358
- "then issue the command only when confirmed in the current turn.",
1446
+ "Call ask_user_questions with a question id containing \"destructive_confirm\"",
1447
+ "and a first option that affirms the action; wait for the user's response,",
1448
+ "then re-issue this exact command in the same turn to run it once.",
1359
1449
  ].join(" ");
1360
1450
  safetyLogWarning("safety", `destructive command: ${classification.labels.join(", ")}`, {
1361
- command: String(event.input.command).slice(0, 200),
1451
+ command: String(command).slice(0, 200),
1362
1452
  });
1363
1453
  if (ctx) {
1364
1454
  await maybePauseAutoForApprovalGate(
1365
1455
  ctx,
1366
1456
  pi,
1367
1457
  isAutoActive(),
1368
- "Depth confirmation is waiting for your answer — pausing auto-mode.",
1458
+ "Destructive-command confirmation is waiting for your answer — pausing auto-mode.",
1369
1459
  );
1370
1460
  }
1371
1461
  return { block: true, reason };
@@ -1373,6 +1463,11 @@ export function registerHooks(
1373
1463
  }
1374
1464
  });
1375
1465
 
1466
+ // Engine hook contract: tool_result is NATIVE_ONLY_TOOL_HOOKS — external
1467
+ // engines skip it. Error classification and markToolEnd are mirrored
1468
+ // universally at tool_execution_end; the ask_user_questions gate lifecycle
1469
+ // here is paired with the tool_execution_start arming path, which external
1470
+ // engines do reach.
1376
1471
  pi.on("tool_result", async (event, ctx) => {
1377
1472
  if (isAutoActive() && typeof event.toolCallId === "string") {
1378
1473
  markToolEnd(event.toolCallId);
@@ -1453,11 +1548,70 @@ export function registerHooks(
1453
1548
  clearDeferredApprovalGate(basePath);
1454
1549
  }
1455
1550
 
1456
- if (details?.cancelled || !details?.response) return;
1551
+ // ── Consent Question policy (consent-question.ts): one home for the
1552
+ // answer lifecycle of every ask_user_questions round. Per-question
1553
+ // verdicts come from the consent-verdict leaf — the same engine
1554
+ // applyAskUserQuestionsGateResult consumed above for gate persistence —
1555
+ // so empty answers on fail-closed kinds never pass as real answers (#528)
1556
+ // and cancellations get one unified handler.
1557
+ const roundOutcome = evaluateAskUserQuestionsRound(questions, details ?? {});
1558
+ if (roundOutcome === "cancelled") {
1559
+ resetToolCallLoopGuard();
1560
+ if (ctx) {
1561
+ await maybePauseAutoForApprovalGate(
1562
+ ctx,
1563
+ pi,
1564
+ true,
1565
+ "ask_user_questions was cancelled before receiving a response — pausing auto-mode until you respond.",
1566
+ );
1567
+ }
1568
+ return;
1569
+ }
1570
+ if (roundOutcome === "waiting") {
1571
+ resetToolCallLoopGuard();
1572
+ if (ctx) {
1573
+ await maybePauseAutoForApprovalGate(
1574
+ ctx,
1575
+ pi,
1576
+ true,
1577
+ "A user question received no answer — pausing auto-mode until you respond.",
1578
+ );
1579
+ }
1580
+ return {
1581
+ content: [{
1582
+ type: "text" as const,
1583
+ text: formatUnansweredConsentQuestionMessage(questions),
1584
+ }],
1585
+ };
1586
+ }
1587
+
1588
+ // Cancelled rounds already returned via roundOutcome === "cancelled".
1589
+ if (!details?.response) return;
1590
+
1591
+ // Destructive-command confirmation: an affirmative answer to a
1592
+ // destructive_confirm gate promotes the pending blocked command to a
1593
+ // one-shot confirmed token, which the bash tool_call guard consumes on the
1594
+ // next attempt. Rejecting/declining leaves the command blocked.
1595
+ // (Depth-verification gate handling now lives in
1596
+ // applyAskUserQuestionsGateResult above; only the destructive-confirm gate
1597
+ // is handled inline here.)
1598
+ for (const question of questions) {
1599
+ if (isDestructiveConfirmGateId(question?.id)) {
1600
+ const answer = details.response?.answers?.[question.id];
1601
+ if (isDepthConfirmationAnswer(answer?.selected, question.options)) {
1602
+ confirmDestructiveCommand(basePath);
1603
+ }
1604
+ break;
1605
+ }
1606
+ }
1607
+
1457
1608
  if (!milestoneId) return;
1458
1609
  await saveDiscussionQuestionRound(basePath, milestoneId, questions, details);
1459
1610
  });
1460
1611
 
1612
+ // Engine hook contract: tool_execution_start is UNIVERSAL_TOOL_HOOKS — the
1613
+ // only pre-execution event that fires for every tool call on every engine.
1614
+ // Universal mirrors live here: write-gate arming and evidence collection.
1461
1615
  pi.on("tool_execution_start", async (event, ctx) => {
1462
1616
  const basePath = contextBasePath(ctx);
1463
1617
  const toolName = canonicalToolName(event.toolName);
@@ -1466,31 +1620,23 @@ export function registerHooks(
1466
1620
  if (typeof questionId === "string") {
1467
1621
  // External engines (claude-code-cli) ingest the SDK turn's tool blocks
1468
1622
  // post-hoc, so this event can fire AFTER the workflow MCP child already
1469
- // verified this gate and allowed the CONTEXT save. setPendingGate also
1470
- // revokes verifiedDepthMilestones/verifiedApprovalGates, so an
1471
- // unconditional re-arm here wipes the child's verification and leaves
1472
- // the discuss→auto handoff permanently blocked. Skip the re-arm when
1473
- // the snapshot already records this exact gate as verified — mirrors
1474
- // activateDeferredApprovalGate's guard. Stale verified state cannot
1475
- // leak into a later re-discussion: a successful handoff deletes the
1476
- // snapshot via clearDiscussionFlowState.
1477
- const snapshot = refreshWriteGateStateFromDisk(basePath);
1478
- const gateMilestoneId = extractDepthVerificationMilestoneId(questionId);
1479
- const alreadyVerified =
1480
- isApprovalGateVerifiedInSnapshot(snapshot, questionId) ||
1481
- isMilestoneDepthVerifiedInSnapshot(snapshot, gateMilestoneId);
1482
- if (!alreadyVerified) {
1483
- setPendingGate(questionId, basePath);
1484
- }
1623
+ // verified this gate and allowed the CONTEXT save. Arming also revokes
1624
+ // verifiedDepthMilestones/verifiedApprovalGates, so an unconditional
1625
+ // re-arm here would wipe the child's verification and leave the
1626
+ // discuss→auto handoff permanently blocked. hostWriteGateAdapter
1627
+ // .setPending applies the verified-on-disk-wins policy and skips the
1628
+ // re-arm in that case. Stale verified state cannot leak into a later
1629
+ // re-discussion: a successful handoff deletes the snapshot via
1630
+ // clearDiscussionFlowState.
1631
+ hostWriteGateAdapter.setPending(questionId, basePath);
1485
1632
  clearDeferredApprovalGate(basePath);
1486
1633
  }
1487
1634
  }
1488
1635
 
1489
- // Safety harness: record evidence here, not only in tool_call. External
1490
- // engines (claude-code-cli) pre-execute tools, so the agent loop skips
1491
- // beforeToolCall/tool_call for them tool_execution_start is the only
1492
- // event that fires for every tool call. recordToolCall dedupes by
1493
- // toolCallId, so native tools (which hit both events) record once.
1636
+ // Safety harness: record evidence here, not only in tool_call — see
1637
+ // ../engine-hook-contract.ts for why tool_call never fires under external
1638
+ // engines. recordToolCall dedupes by toolCallId, so native tools (which
1639
+ // hit both events) record once.
1494
1640
  safetyRecordToolCall(event.toolCallId, event.toolName, (event.args ?? {}) as Record<string, unknown>);
1495
1641
  const execDash = getAutoRuntimeSnapshot();
1496
1642
  if (execDash.basePath && execDash.currentUnit?.type === "execute-task") {
@@ -1504,6 +1650,9 @@ export function registerHooks(
1504
1650
  markToolStart(event.toolCallId, event.toolName);
1505
1651
  });
1506
1652
 
1653
+ // Engine hook contract: tool_execution_end is UNIVERSAL_TOOL_HOOKS — fires
1654
+ // for every finalized tool call on every engine, so error classification
1655
+ // and evidence persistence here cover external engines that skip tool_result.
1507
1656
  pi.on("tool_execution_end", async (event) => {
1508
1657
  markToolEnd(event.toolCallId);
1509
1658
  // #2883/#4974: Capture deterministic invocation/policy errors
@@ -1580,6 +1729,7 @@ export function registerHooks(
1580
1729
  return surfaceReduced ? { toolNames: providerCompatible } : undefined;
1581
1730
  }
1582
1731
  const registeredToolNames = resolveRegisteredToolNames(pi, event.activeToolNames);
1732
+ const hasRegisteredSurface = typeof pi.getAllTools === "function";
1583
1733
  const compatibleRegisteredToolNames = filterToolsForProvider(
1584
1734
  registeredToolNames,
1585
1735
  event.selectedModelApi,
@@ -1594,6 +1744,7 @@ export function registerHooks(
1594
1744
  event.requestCustomMessages,
1595
1745
  requestRegisteredToolNames,
1596
1746
  guidedUnit?.unitType,
1747
+ hasRegisteredSurface,
1597
1748
  );
1598
1749
  if (requestScoped) {
1599
1750
  recordAutoToolSurfaceSnapshot({
@@ -1614,6 +1765,7 @@ export function registerHooks(
1614
1765
  dash.currentUnit.type === "run-uat" ? aliasFilteredCompatible : providerCompatible,
1615
1766
  dash.currentUnit.type,
1616
1767
  registeredForUnit,
1768
+ hasRegisteredSurface,
1617
1769
  );
1618
1770
  recordAutoToolSurfaceSnapshot({
1619
1771
  source: "provider-adjustment",