@opengsd/gsd-pi 1.2.0-dev.84c56d87 → 1.2.0-dev.9ad8ae33

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 (460) 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 +10 -5
  4. package/dist/resource-loader.js +121 -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/gsd/auto/custom-verify-retry-store.js +17 -2
  17. package/dist/resources/extensions/gsd/auto/detect-stuck.js +33 -13
  18. package/dist/resources/extensions/gsd/auto/dispatch-history.js +105 -0
  19. package/dist/resources/extensions/gsd/auto/dispatch-key.js +37 -0
  20. package/dist/resources/extensions/gsd/auto/loop.js +4 -1
  21. package/dist/resources/extensions/gsd/auto/orchestrator.js +89 -54
  22. package/dist/resources/extensions/gsd/auto/phases.js +49 -6
  23. package/dist/resources/extensions/gsd/auto/session.js +3 -0
  24. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +11 -34
  25. package/dist/resources/extensions/gsd/auto-dispatch.js +50 -58
  26. package/dist/resources/extensions/gsd/auto-model-selection.js +36 -13
  27. package/dist/resources/extensions/gsd/auto-post-unit.js +30 -12
  28. package/dist/resources/extensions/gsd/auto-prompts.js +78 -19
  29. package/dist/resources/extensions/gsd/auto-start.js +35 -15
  30. package/dist/resources/extensions/gsd/auto-unit-closeout.js +45 -21
  31. package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +5 -4
  32. package/dist/resources/extensions/gsd/auto-verification.js +23 -30
  33. package/dist/resources/extensions/gsd/auto-worktree.js +14 -1
  34. package/dist/resources/extensions/gsd/auto.js +37 -1
  35. package/dist/resources/extensions/gsd/blocked-models.js +28 -0
  36. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +26 -6
  37. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +23 -6
  38. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +2 -2
  39. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +145 -50
  40. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +302 -80
  41. package/dist/resources/extensions/gsd/browser-daemon-auto-prep.js +83 -0
  42. package/dist/resources/extensions/gsd/closeout-wizard.js +92 -0
  43. package/dist/resources/extensions/gsd/commands/context.js +16 -2
  44. package/dist/resources/extensions/gsd/commands-handlers.js +46 -3
  45. package/dist/resources/extensions/gsd/consent-question.js +353 -0
  46. package/dist/resources/extensions/gsd/consent-verdict.js +63 -0
  47. package/dist/resources/extensions/gsd/constants.js +0 -2
  48. package/dist/resources/extensions/gsd/crash-recovery.js +8 -3
  49. package/dist/resources/extensions/gsd/db/queries.js +26 -0
  50. package/dist/resources/extensions/gsd/db-writer.js +8 -17
  51. package/dist/resources/extensions/gsd/dispatch-guard.js +10 -35
  52. package/dist/resources/extensions/gsd/doctor-engine-checks.js +5 -5
  53. package/dist/resources/extensions/gsd/doctor-git-checks.js +2 -18
  54. package/dist/resources/extensions/gsd/engine-hook-contract.js +70 -0
  55. package/dist/resources/extensions/gsd/exec-sandbox.js +30 -10
  56. package/dist/resources/extensions/gsd/files.js +33 -19
  57. package/dist/resources/extensions/gsd/gsd-command-home.js +22 -12
  58. package/dist/resources/extensions/gsd/gsd-db.js +2 -1
  59. package/dist/resources/extensions/gsd/guidance.js +60 -0
  60. package/dist/resources/extensions/gsd/guided-flow.js +6 -3
  61. package/dist/resources/extensions/gsd/markdown-renderer.js +10 -0
  62. package/dist/resources/extensions/gsd/milestone-closeout.js +85 -24
  63. package/dist/resources/extensions/gsd/milestone-planning-persistence.js +2 -2
  64. package/dist/resources/extensions/gsd/milestone-reopen-events.js +3 -5
  65. package/dist/resources/extensions/gsd/parsers-legacy.js +16 -4
  66. package/dist/resources/extensions/gsd/preferences-models.js +2 -2
  67. package/dist/resources/extensions/gsd/projection-flush.js +7 -0
  68. package/dist/resources/extensions/gsd/prompts/complete-slice.md +3 -3
  69. package/dist/resources/extensions/gsd/prompts/execute-task.md +1 -1
  70. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  71. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  72. package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -1
  73. package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
  74. package/dist/resources/extensions/gsd/prompts/refine-slice.md +1 -1
  75. package/dist/resources/extensions/gsd/prompts/replan-slice.md +1 -1
  76. package/dist/resources/extensions/gsd/prompts/research-milestone.md +1 -1
  77. package/dist/resources/extensions/gsd/prompts/research-slice.md +1 -1
  78. package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  79. package/dist/resources/extensions/gsd/prompts/run-uat.md +7 -5
  80. package/dist/resources/extensions/gsd/prompts/system.md +5 -2
  81. package/dist/resources/extensions/gsd/prompts/triage-captures.md +1 -1
  82. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +1 -1
  83. package/dist/resources/extensions/gsd/reactive-graph.js +8 -1
  84. package/dist/resources/extensions/gsd/roadmap-slices.js +25 -3
  85. package/dist/resources/extensions/gsd/safety/destructive-confirmation.js +108 -0
  86. package/dist/resources/extensions/gsd/session-lock.js +1 -1
  87. package/dist/resources/extensions/gsd/state.js +5 -0
  88. package/dist/resources/extensions/gsd/tool-contract.js +14 -3
  89. package/dist/resources/extensions/gsd/tool-presentation-plan.js +4 -4
  90. package/dist/resources/extensions/gsd/tools/complete-milestone.js +3 -2
  91. package/dist/resources/extensions/gsd/tools/complete-slice.js +22 -12
  92. package/dist/resources/extensions/gsd/tools/complete-task.js +3 -2
  93. package/dist/resources/extensions/gsd/tools/exec-tool.js +5 -0
  94. package/dist/resources/extensions/gsd/tools/plan-slice.js +2 -2
  95. package/dist/resources/extensions/gsd/tools/plan-task.js +2 -2
  96. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +2 -2
  97. package/dist/resources/extensions/gsd/tools/reopen-milestone.js +2 -2
  98. package/dist/resources/extensions/gsd/tools/reopen-slice.js +2 -2
  99. package/dist/resources/extensions/gsd/tools/reopen-task.js +2 -2
  100. package/dist/resources/extensions/gsd/tools/replan-slice.js +2 -2
  101. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +67 -2
  102. package/dist/resources/extensions/gsd/uat-policy.js +40 -15
  103. package/dist/resources/extensions/gsd/unit-context-composer.js +65 -0
  104. package/dist/resources/extensions/gsd/verdict-parser.js +1 -1
  105. package/dist/resources/extensions/gsd/verification-verdict.js +2 -1
  106. package/dist/resources/extensions/gsd/workflow-event-ledger.js +91 -0
  107. package/dist/resources/extensions/gsd/workflow-event-vocabulary.js +46 -0
  108. package/dist/resources/extensions/gsd/workflow-events.js +6 -18
  109. package/dist/resources/extensions/gsd/workflow-reconcile.js +21 -56
  110. package/dist/resources/extensions/gsd/worktree-lifecycle.js +3 -2
  111. package/dist/resources/extensions/gsd/worktree-manager.js +7 -1
  112. package/dist/resources/extensions/gsd/worktree.js +8 -1
  113. package/dist/resources/extensions/shared/gsd-browser-cli.js +45 -3
  114. package/dist/resources/shared/gsd-browser-path-sync.js +214 -0
  115. package/dist/resources/shared/package-manager-detection.js +1 -1
  116. package/dist/resources/shared/package.json +3 -0
  117. package/dist/resources/skills/create-skill/SKILL.md +3 -0
  118. package/dist/resources/skills/create-skill/references/skill-structure.md +1 -0
  119. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  120. package/dist/update-check.d.ts +2 -0
  121. package/dist/update-check.js +24 -1
  122. package/dist/update-cmd.js +20 -3
  123. package/dist/web/standalone/.next/BUILD_ID +1 -1
  124. package/dist/web/standalone/.next/app-path-routes-manifest.json +6 -6
  125. package/dist/web/standalone/.next/build-manifest.json +3 -3
  126. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  127. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  128. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  129. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  130. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  131. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  132. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  133. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  134. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  135. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  136. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  137. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  138. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  139. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  140. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  141. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  142. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  143. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  144. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/update/route.js.nft.json +1 -1
  146. package/dist/web/standalone/.next/server/app/index.html +1 -1
  147. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  148. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  149. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  150. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  151. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  152. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  153. package/dist/web/standalone/.next/server/app-paths-manifest.json +6 -6
  154. package/dist/web/standalone/.next/server/chunks/8357.js +2 -2
  155. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  156. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  157. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  158. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  159. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  160. package/dist/web/standalone/.next/static/chunks/{796.cf859a427a2cb2ac.js → 796.e0bdc932325d7e03.js} +1 -1
  161. package/dist/web/standalone/.next/static/chunks/{webpack-fbea77b5f9953368.js → webpack-f0285ce91d4ec9ef.js} +1 -1
  162. package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
  163. package/dist/web/standalone/node_modules/postcss/lib/container.js +26 -18
  164. package/dist/web/standalone/node_modules/postcss/lib/css-syntax-error.js +47 -14
  165. package/dist/web/standalone/node_modules/postcss/lib/declaration.js +4 -4
  166. package/dist/web/standalone/node_modules/postcss/lib/fromJSON.js +3 -3
  167. package/dist/web/standalone/node_modules/postcss/lib/input.js +54 -29
  168. package/dist/web/standalone/node_modules/postcss/lib/lazy-result.js +47 -37
  169. package/dist/web/standalone/node_modules/postcss/lib/map-generator.js +26 -9
  170. package/dist/web/standalone/node_modules/postcss/lib/no-work-result.js +57 -55
  171. package/dist/web/standalone/node_modules/postcss/lib/node.js +99 -31
  172. package/dist/web/standalone/node_modules/postcss/lib/parse.js +1 -1
  173. package/dist/web/standalone/node_modules/postcss/lib/parser.js +10 -9
  174. package/dist/web/standalone/node_modules/postcss/lib/postcss.js +12 -12
  175. package/dist/web/standalone/node_modules/postcss/lib/previous-map.js +30 -11
  176. package/dist/web/standalone/node_modules/postcss/lib/processor.js +7 -7
  177. package/dist/web/standalone/node_modules/postcss/lib/result.js +5 -5
  178. package/dist/web/standalone/node_modules/postcss/lib/rule.js +6 -6
  179. package/dist/web/standalone/node_modules/postcss/lib/stringifier.js +69 -28
  180. package/dist/web/standalone/node_modules/postcss/lib/tokenize.js +6 -2
  181. package/dist/web/standalone/node_modules/postcss/package.json +48 -48
  182. package/package.json +2 -2
  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 +419 -221
  243. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  244. package/packages/pi-ai/dist/models.generated.js +460 -261
  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/package.json +2 -2
  285. package/packages/rpc-client/package.json +2 -2
  286. package/pkg/package.json +1 -1
  287. package/src/resources/GSD-WORKFLOW.md +5 -4
  288. package/src/resources/extensions/async-jobs/async-bash-cancel.test.ts +360 -0
  289. package/src/resources/extensions/async-jobs/async-bash-tool.ts +33 -56
  290. package/src/resources/extensions/async-jobs/await-tool.test.ts +139 -0
  291. package/src/resources/extensions/async-jobs/await-tool.ts +82 -12
  292. package/src/resources/extensions/async-jobs/index.ts +79 -0
  293. package/src/resources/extensions/async-jobs/job-manager.ts +21 -1
  294. package/src/resources/extensions/bg-shell/bg-shell-command.ts +6 -6
  295. package/src/resources/extensions/bg-shell/bg-shell-tool.ts +10 -6
  296. package/src/resources/extensions/bg-shell/overlay.ts +9 -5
  297. package/src/resources/extensions/bg-shell/process-manager.ts +50 -25
  298. package/src/resources/extensions/bg-shell/readiness-detector.ts +12 -0
  299. package/src/resources/extensions/bg-shell/tests/lifecycle-and-utilities.test.ts +48 -1
  300. package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +40 -1
  301. package/src/resources/extensions/gsd/auto/custom-verify-retry-store.ts +21 -3
  302. package/src/resources/extensions/gsd/auto/detect-stuck.ts +32 -9
  303. package/src/resources/extensions/gsd/auto/dispatch-history.ts +152 -0
  304. package/src/resources/extensions/gsd/auto/dispatch-key.ts +39 -0
  305. package/src/resources/extensions/gsd/auto/loop.ts +4 -1
  306. package/src/resources/extensions/gsd/auto/orchestrator.ts +98 -56
  307. package/src/resources/extensions/gsd/auto/phases.ts +65 -26
  308. package/src/resources/extensions/gsd/auto/session.ts +3 -0
  309. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +18 -48
  310. package/src/resources/extensions/gsd/auto-dispatch.ts +48 -61
  311. package/src/resources/extensions/gsd/auto-model-selection.ts +41 -12
  312. package/src/resources/extensions/gsd/auto-post-unit.ts +33 -12
  313. package/src/resources/extensions/gsd/auto-prompts.ts +115 -35
  314. package/src/resources/extensions/gsd/auto-start.ts +36 -18
  315. package/src/resources/extensions/gsd/auto-unit-closeout.ts +83 -28
  316. package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +4 -4
  317. package/src/resources/extensions/gsd/auto-verification.ts +26 -28
  318. package/src/resources/extensions/gsd/auto-worktree.ts +14 -1
  319. package/src/resources/extensions/gsd/auto.ts +44 -1
  320. package/src/resources/extensions/gsd/blocked-models.ts +49 -0
  321. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +34 -5
  322. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +23 -6
  323. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +2 -2
  324. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +163 -55
  325. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +350 -86
  326. package/src/resources/extensions/gsd/browser-daemon-auto-prep.ts +108 -0
  327. package/src/resources/extensions/gsd/closeout-wizard.ts +102 -0
  328. package/src/resources/extensions/gsd/commands/context.ts +16 -2
  329. package/src/resources/extensions/gsd/commands-handlers.ts +46 -3
  330. package/src/resources/extensions/gsd/consent-question.ts +431 -0
  331. package/src/resources/extensions/gsd/consent-verdict.ts +86 -0
  332. package/src/resources/extensions/gsd/constants.ts +0 -3
  333. package/src/resources/extensions/gsd/crash-recovery.ts +10 -2
  334. package/src/resources/extensions/gsd/db/queries.ts +37 -0
  335. package/src/resources/extensions/gsd/db-writer.ts +11 -19
  336. package/src/resources/extensions/gsd/dispatch-guard.ts +8 -31
  337. package/src/resources/extensions/gsd/doctor-engine-checks.ts +5 -4
  338. package/src/resources/extensions/gsd/doctor-git-checks.ts +2 -19
  339. package/src/resources/extensions/gsd/engine-hook-contract.ts +79 -0
  340. package/src/resources/extensions/gsd/exec-sandbox.ts +49 -9
  341. package/src/resources/extensions/gsd/files.ts +33 -12
  342. package/src/resources/extensions/gsd/gsd-command-home.ts +13 -3
  343. package/src/resources/extensions/gsd/gsd-db.ts +4 -3
  344. package/src/resources/extensions/gsd/guidance.ts +78 -0
  345. package/src/resources/extensions/gsd/guided-flow.ts +21 -26
  346. package/src/resources/extensions/gsd/markdown-renderer.ts +11 -0
  347. package/src/resources/extensions/gsd/milestone-closeout.ts +109 -24
  348. package/src/resources/extensions/gsd/milestone-planning-persistence.ts +2 -2
  349. package/src/resources/extensions/gsd/milestone-reopen-events.ts +3 -6
  350. package/src/resources/extensions/gsd/parsers-legacy.ts +16 -4
  351. package/src/resources/extensions/gsd/preferences-models.ts +2 -1
  352. package/src/resources/extensions/gsd/projection-flush.ts +20 -0
  353. package/src/resources/extensions/gsd/prompts/complete-slice.md +3 -3
  354. package/src/resources/extensions/gsd/prompts/execute-task.md +1 -1
  355. package/src/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  356. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  357. package/src/resources/extensions/gsd/prompts/quick-task.md +1 -1
  358. package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
  359. package/src/resources/extensions/gsd/prompts/refine-slice.md +1 -1
  360. package/src/resources/extensions/gsd/prompts/replan-slice.md +1 -1
  361. package/src/resources/extensions/gsd/prompts/research-milestone.md +1 -1
  362. package/src/resources/extensions/gsd/prompts/research-slice.md +1 -1
  363. package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  364. package/src/resources/extensions/gsd/prompts/run-uat.md +7 -5
  365. package/src/resources/extensions/gsd/prompts/system.md +5 -2
  366. package/src/resources/extensions/gsd/prompts/triage-captures.md +1 -1
  367. package/src/resources/extensions/gsd/prompts/validate-milestone.md +1 -1
  368. package/src/resources/extensions/gsd/reactive-graph.ts +11 -1
  369. package/src/resources/extensions/gsd/roadmap-slices.ts +28 -3
  370. package/src/resources/extensions/gsd/safety/destructive-confirmation.ts +134 -0
  371. package/src/resources/extensions/gsd/session-lock.ts +1 -1
  372. package/src/resources/extensions/gsd/state.ts +5 -0
  373. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +97 -1
  374. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +198 -26
  375. package/src/resources/extensions/gsd/tests/auto-remote-session-lock-cleanup.test.ts +65 -3
  376. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +236 -0
  377. package/src/resources/extensions/gsd/tests/blocked-models.test.ts +19 -0
  378. package/src/resources/extensions/gsd/tests/browser-daemon-auto-prep.test.ts +144 -0
  379. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +42 -0
  380. package/src/resources/extensions/gsd/tests/consent-question.test.ts +351 -0
  381. package/src/resources/extensions/gsd/tests/custom-verify-retry-store.test.ts +67 -0
  382. package/src/resources/extensions/gsd/tests/db-writer.test.ts +15 -4
  383. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +10 -10
  384. package/src/resources/extensions/gsd/tests/destructive-confirmation.test.ts +303 -0
  385. package/src/resources/extensions/gsd/tests/discuss-routing-fixes.test.ts +12 -2
  386. package/src/resources/extensions/gsd/tests/dispatch-history.test.ts +273 -0
  387. package/src/resources/extensions/gsd/tests/doctor-git-checks-terminal.test.ts +73 -0
  388. package/src/resources/extensions/gsd/tests/dynamic-bash-no-cap.test.ts +132 -0
  389. package/src/resources/extensions/gsd/tests/engine-hook-contract.test.ts +148 -0
  390. package/src/resources/extensions/gsd/tests/exec-graceful-kill.test.ts +193 -0
  391. package/src/resources/extensions/gsd/tests/exec-tool.test.ts +29 -1
  392. package/src/resources/extensions/gsd/tests/gsd-command-home.test.ts +120 -0
  393. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +27 -0
  394. package/src/resources/extensions/gsd/tests/guidance.test.ts +23 -0
  395. package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +2 -6
  396. package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +199 -0
  397. package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +3 -1
  398. package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +95 -4
  399. package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +32 -1
  400. package/src/resources/extensions/gsd/tests/oauth-api-model-routing.test.ts +167 -0
  401. package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +18 -0
  402. package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +138 -0
  403. package/src/resources/extensions/gsd/tests/phases-terminal-complete-idempotent.test.ts +242 -0
  404. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +63 -2
  405. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +124 -6
  406. package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +68 -0
  407. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +19 -1
  408. package/src/resources/extensions/gsd/tests/teardown-chdir-failure-clears-registry.test.ts +17 -0
  409. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +41 -0
  410. package/src/resources/extensions/gsd/tests/tool-unavailable-retry.test.ts +33 -0
  411. package/src/resources/extensions/gsd/tests/transport-gate-double-complete.test.ts +139 -0
  412. package/src/resources/extensions/gsd/tests/uat-policy.test.ts +88 -0
  413. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +44 -0
  414. package/src/resources/extensions/gsd/tests/uok-audit-unified.test.ts +8 -0
  415. package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +2 -0
  416. package/src/resources/extensions/gsd/tests/workflow-events.test.ts +19 -0
  417. package/src/resources/extensions/gsd/tests/workflow-reconcile.test.ts +20 -0
  418. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +273 -38
  419. package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +22 -0
  420. package/src/resources/extensions/gsd/tests/worktree.test.ts +18 -0
  421. package/src/resources/extensions/gsd/tests/write-gate-seam.test.ts +358 -0
  422. package/src/resources/extensions/gsd/tests/write-gate.test.ts +67 -1
  423. package/src/resources/extensions/gsd/tool-contract.ts +38 -3
  424. package/src/resources/extensions/gsd/tool-presentation-plan.ts +4 -4
  425. package/src/resources/extensions/gsd/tools/complete-milestone.ts +3 -2
  426. package/src/resources/extensions/gsd/tools/complete-slice.ts +22 -12
  427. package/src/resources/extensions/gsd/tools/complete-task.ts +3 -2
  428. package/src/resources/extensions/gsd/tools/exec-tool.ts +4 -0
  429. package/src/resources/extensions/gsd/tools/plan-slice.ts +2 -2
  430. package/src/resources/extensions/gsd/tools/plan-task.ts +2 -2
  431. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +2 -2
  432. package/src/resources/extensions/gsd/tools/reopen-milestone.ts +2 -2
  433. package/src/resources/extensions/gsd/tools/reopen-slice.ts +2 -2
  434. package/src/resources/extensions/gsd/tools/reopen-task.ts +2 -2
  435. package/src/resources/extensions/gsd/tools/replan-slice.ts +2 -2
  436. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +81 -2
  437. package/src/resources/extensions/gsd/uat-policy.ts +60 -15
  438. package/src/resources/extensions/gsd/unit-context-composer.ts +99 -0
  439. package/src/resources/extensions/gsd/verdict-parser.ts +1 -1
  440. package/src/resources/extensions/gsd/verification-verdict.ts +4 -2
  441. package/src/resources/extensions/gsd/workflow-event-ledger.ts +131 -0
  442. package/src/resources/extensions/gsd/workflow-event-vocabulary.ts +59 -0
  443. package/src/resources/extensions/gsd/workflow-events.ts +12 -20
  444. package/src/resources/extensions/gsd/workflow-reconcile.ts +29 -62
  445. package/src/resources/extensions/gsd/worktree-lifecycle.ts +3 -8
  446. package/src/resources/extensions/gsd/worktree-manager.ts +6 -1
  447. package/src/resources/extensions/gsd/worktree.ts +7 -1
  448. package/src/resources/extensions/shared/gsd-browser-cli.ts +54 -3
  449. package/src/resources/shared/gsd-browser-path-sync.ts +273 -0
  450. package/src/resources/shared/package-manager-detection.ts +1 -1
  451. package/src/resources/shared/package.json +3 -0
  452. package/src/resources/skills/create-skill/SKILL.md +3 -0
  453. package/src/resources/skills/create-skill/references/skill-structure.md +1 -0
  454. package/dist/resources/extensions/gsd/user-input-boundary.js +0 -218
  455. package/dist/resources/skills/gsd-browser/SKILL.md +0 -41
  456. package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +0 -173
  457. package/src/resources/extensions/gsd/user-input-boundary.ts +0 -216
  458. package/src/resources/skills/gsd-browser/SKILL.md +0 -41
  459. /package/dist/web/standalone/.next/static/{AOpDeK_gJHU8OZjRo31gQ → FBNo5cT_chy7YNoAQsU3o}/_buildManifest.js +0 -0
  460. /package/dist/web/standalone/.next/static/{AOpDeK_gJHU8OZjRo31gQ → FBNo5cT_chy7YNoAQsU3o}/_ssgManifest.js +0 -0
@@ -7,7 +7,8 @@ import { isToolCallEventType } from "@gsd/pi-coding-agent";
7
7
  import { ALWAYS_PRESERVED_SHIM_TOOL_NAMES } from "@gsd/pi-ai";
8
8
  import { updateSnapshot } from "../ecosystem/gsd-extension-api.js";
9
9
  import { buildMilestoneFileName, clearPathCache, milestonesDir, resolveMilestonePath, resolveSliceFile, resolveSlicePath } from "../paths.js";
10
- import { applyAskUserQuestionsGateResult, canonicalToolName, clearDiscussionFlowState, formatPendingAskUserQuestionsGateMessage, isApprovalGateVerifiedInSnapshot, isMilestoneDepthVerified, isMilestoneDepthVerifiedInSnapshot, isQueuePhaseActive, markApprovalGateVerified, markDepthVerified, refreshWriteGateStateFromDisk, resetWriteGateState, shouldBlockContextWrite, shouldBlockPlanningUnit, shouldBlockQueueExecution, shouldBlockWorktreeWrite, isGateQuestionId, setPendingGate, clearPendingGate, getPendingGate, shouldBlockPendingGate, shouldBlockPendingGateBash, extractDepthVerificationMilestoneId } from "./write-gate.js";
10
+ import { applyAskUserQuestionsGateResult, clearDiscussionFlowState, formatPendingAskUserQuestionsGateMessage, hostWriteGateAdapter, isApprovalGateVerifiedInSnapshot, isDepthConfirmationAnswer, isMilestoneDepthVerified, isMilestoneDepthVerifiedInSnapshot, isQueuePhaseActive, resetWriteGateState, shouldBlockContextWrite, shouldBlockPlanningUnit, shouldBlockQueueExecution, shouldBlockWorktreeWrite, isGateQuestionId, getPendingGate, shouldBlockPendingGate, shouldBlockPendingGateBash, extractDepthVerificationMilestoneId } from "./write-gate.js";
11
+ import { canonicalToolName } from "../engine-hook-contract.js";
11
12
  import { resolveManifest } from "../unit-context-manifest.js";
12
13
  import { isBlockedStateFile, isBashWriteToStateFile, BLOCKED_WRITE_ERROR } from "../write-intercept.js";
13
14
  import { loadFile, saveFile, formatContinue } from "../files.js";
@@ -19,6 +20,7 @@ import { saveActivityLog } from "../activity-log.js";
19
20
  import { recordToolCall as safetyRecordToolCall, recordToolResult as safetyRecordToolResult, saveEvidenceToDisk } from "../safety/evidence-collector.js";
20
21
  import { parseUnitId } from "../unit-id.js";
21
22
  import { classifyCommand } from "../safety/destructive-guard.js";
23
+ import { confirmDestructiveCommand, consumeDestructiveConfirmation, isDestructiveConfirmGateId, requestDestructiveConfirmation, } from "../safety/destructive-confirmation.js";
22
24
  import { logWarning as safetyLogWarning } from "../workflow-logger.js";
23
25
  import { isUnitCloseoutTool, runInteractiveUnitCloseout } from "../unit-closeout.js";
24
26
  import { installNotifyInterceptor } from "./notify-interceptor.js";
@@ -27,7 +29,7 @@ import { initNotificationWidget } from "../notification-widget.js";
27
29
  import { notifyPreferenceDiagnostics } from "../preferences-diagnostics.js";
28
30
  import { resolveWorktreeProjectRoot } from "../worktree-root.js";
29
31
  import { extractSubagentAgentClasses } from "./subagent-input.js";
30
- import { approvalGateIdForUnit, isExplicitApprovalResponse, messageHasPendingAskUserQuestionsTool, shouldPauseForUserApprovalQuestion, } from "../user-input-boundary.js";
32
+ import { approvalGateIdForUnit, evaluateAskUserQuestionsRound, formatUnansweredConsentQuestionMessage, isExplicitApprovalResponse, messageHasPendingAskUserQuestionsTool, shouldPauseForQuestion, } from "../consent-question.js";
31
33
  import { applyUnitSkillVisibility, unitHasSkillManifest } from "../skill-scope.js";
32
34
  import { getGuidedUnitContext } from "../guided-unit-context.js";
33
35
  import { registerPlanMilestoneSchemaRecovery } from "./plan-milestone-schema-recovery.js";
@@ -108,7 +110,13 @@ async function installWelcomeHeader(ctx) {
108
110
  /* non-fatal */
109
111
  }
110
112
  }
111
- let deferredApprovalGate = null;
113
+ /**
114
+ * Approval gates whose durable arming is deferred until tool execution /
115
+ * agent end, keyed by basePath. A Map (not a single slot) so concurrent
116
+ * projects in one process cannot lose each other's deferred gate; entries
117
+ * are bounded — cleared on activation, session boundaries, and verification.
118
+ */
119
+ const deferredApprovalGates = new Map();
112
120
  export const MINIMAL_GSD_TOOL_NAMES = [
113
121
  "gsd_exec",
114
122
  "gsd_exec_search",
@@ -407,12 +415,24 @@ async function applyCompactionThresholdOverride(ctx) {
407
415
  }
408
416
  }
409
417
  function clearDeferredApprovalGate(basePath) {
410
- if (!basePath || deferredApprovalGate?.basePath === basePath) {
411
- deferredApprovalGate = null;
418
+ if (!basePath) {
419
+ deferredApprovalGates.clear();
420
+ }
421
+ else {
422
+ deferredApprovalGates.delete(basePath);
412
423
  }
413
424
  }
414
425
  function deferApprovalGate(gateId, basePath) {
415
- deferredApprovalGate = { gateId, basePath };
426
+ // Verified-on-disk wins (same adapter policy as activation/re-arm): if the
427
+ // workflow MCP child already verified this gate, deferring would block
428
+ // tools for a gate that can never legitimately arm.
429
+ const snapshot = hostWriteGateAdapter.readState(basePath);
430
+ if (isApprovalGateVerifiedInSnapshot(snapshot, gateId))
431
+ return;
432
+ const milestoneId = extractDepthVerificationMilestoneId(gateId);
433
+ if (milestoneId && isMilestoneDepthVerifiedInSnapshot(snapshot, milestoneId))
434
+ return;
435
+ deferredApprovalGates.set(basePath, gateId);
416
436
  }
417
437
  function contextBasePath(ctx) {
418
438
  return typeof ctx?.cwd === "string" ? ctx.cwd : process.cwd();
@@ -462,17 +482,14 @@ function isShellExecutionTool(canonicalName) {
462
482
  canonicalName === "powershell";
463
483
  }
464
484
  function activateDeferredApprovalGate(basePath) {
465
- if (deferredApprovalGate?.basePath !== basePath)
485
+ const gateId = deferredApprovalGates.get(basePath);
486
+ if (gateId === undefined)
466
487
  return;
467
- const gateId = deferredApprovalGate.gateId;
468
- deferredApprovalGate = null;
469
- const snapshot = refreshWriteGateStateFromDisk(basePath);
470
- const milestoneId = extractDepthVerificationMilestoneId(gateId);
471
- if (isApprovalGateVerifiedInSnapshot(snapshot, gateId))
472
- return;
473
- if (milestoneId && isMilestoneDepthVerifiedInSnapshot(snapshot, milestoneId))
474
- return;
475
- setPendingGate(gateId, basePath);
488
+ deferredApprovalGates.delete(basePath);
489
+ // hostWriteGateAdapter.setPending applies the verified-on-disk-wins merge
490
+ // policy: it refuses to arm (and thereby clobber) a gate the workflow MCP
491
+ // child already verified on disk.
492
+ hostWriteGateAdapter.setPending(gateId, basePath);
476
493
  }
477
494
  function extractGateQuestionId(input) {
478
495
  const questions = input?.questions ?? [];
@@ -481,7 +498,7 @@ function extractGateQuestionId(input) {
481
498
  }
482
499
  function isApprovalGateBlocking(basePath) {
483
500
  return Boolean(getPendingGate(basePath))
484
- || (deferredApprovalGate?.basePath === basePath);
501
+ || deferredApprovalGates.has(basePath);
485
502
  }
486
503
  function isContextDraftSummarySave(toolName, input) {
487
504
  if (toolName !== "gsd_summary_save" && toolName !== "summary_save")
@@ -588,7 +605,8 @@ function withDepthGateDisplayReason(result, displayReason = "Depth confirmation
588
605
  return { ...result, displayReason };
589
606
  }
590
607
  function shouldBlockDeferredApprovalTool(toolName, input, basePath) {
591
- if (deferredApprovalGate?.basePath !== basePath)
608
+ const deferredGateId = deferredApprovalGates.get(basePath);
609
+ if (deferredGateId === undefined)
592
610
  return { block: false };
593
611
  if (toolName === "ask_user_questions")
594
612
  return { block: false };
@@ -597,7 +615,7 @@ function shouldBlockDeferredApprovalTool(toolName, input, basePath) {
597
615
  return withDepthGateDisplayReason({
598
616
  block: true,
599
617
  reason: [
600
- `HARD BLOCK: Approval question "${deferredApprovalGate.gateId}" has been shown to the user.`,
618
+ `HARD BLOCK: Approval question "${deferredGateId}" has been shown to the user.`,
601
619
  `Only CONTEXT-DRAFT persistence may finish in this same assistant turn.`,
602
620
  `Wait for the user's answer before calling additional tools.`,
603
621
  ].join(" "),
@@ -713,11 +731,13 @@ export function registerHooks(pi, ecosystemHandlers) {
713
731
  const beforeAgentBasePath = contextBasePath(ctx);
714
732
  const pendingApprovalGate = getPendingGate(beforeAgentBasePath);
715
733
  if (pendingApprovalGate && isExplicitApprovalResponse(event.prompt, pendingApprovalGate)) {
716
- markApprovalGateVerified(pendingApprovalGate, beforeAgentBasePath);
734
+ // Host adapter explicitly: the ambient write-gate exports env-sniff the
735
+ // adapter per call and are reserved for the MCP child's import surface.
736
+ hostWriteGateAdapter.markApprovalGateVerified(pendingApprovalGate, beforeAgentBasePath);
717
737
  const milestoneId = extractDepthVerificationMilestoneId(pendingApprovalGate);
718
738
  if (milestoneId)
719
- markDepthVerified(milestoneId, beforeAgentBasePath);
720
- clearPendingGate(beforeAgentBasePath);
739
+ hostWriteGateAdapter.markDepthVerified(milestoneId, beforeAgentBasePath);
740
+ hostWriteGateAdapter.clearPending(beforeAgentBasePath);
721
741
  if (isAutoPaused() && !isAutoActive()) {
722
742
  const { resumeAutoAfterProviderDelay } = await import("./provider-error-resume.js");
723
743
  void resumeAutoAfterProviderDelay(pi, ctx).catch((err) => {
@@ -918,7 +938,7 @@ export function registerHooks(pi, ecosystemHandlers) {
918
938
  unitId = milestoneId;
919
939
  }
920
940
  }
921
- if (!shouldPauseForUserApprovalQuestion(unitType, [event.message]))
941
+ if (!shouldPauseForQuestion(unitType, [event.message]))
922
942
  return;
923
943
  const gateId = approvalGateIdForUnit(unitType, unitId);
924
944
  if (gateId) {
@@ -932,7 +952,7 @@ export function registerHooks(pi, ecosystemHandlers) {
932
952
  deferApprovalGate(gateId, contextBasePath(ctx));
933
953
  }
934
954
  approvalQuestionAbortInFlight = true;
935
- ctx.ui.notify(`${unitType}${unitId ? ` ${unitId}` : ""} is waiting for your approval - pausing before more tool calls run.`, "info");
955
+ ctx.ui.notify(`${unitType ?? "The discussion"}${unitId ? ` ${unitId}` : ""} is waiting for your approval - pausing before more tool calls run.`, "info");
936
956
  // The durable pending gate is activated at agent_end so same-turn
937
957
  // CONTEXT-DRAFT persistence can finish after the text boundary streams.
938
958
  // The tool_call hook below still blocks non-draft tools in this turn.
@@ -958,6 +978,13 @@ export function registerHooks(pi, ecosystemHandlers) {
958
978
  saveActivityLog(ctx, dash.basePath, dash.currentUnit.type, dash.currentUnit.id);
959
979
  }
960
980
  });
981
+ // Engine hook contract (../engine-hook-contract.ts): tool_call is
982
+ // NATIVE_ONLY_TOOL_HOOKS — it never fires under external engines
983
+ // (claude-code-cli pre-executes tools). The guards below (loop guard,
984
+ // pending/deferred gate blocks, queue guard, planning-unit tools policy,
985
+ // worktree write gate, STATE.md single-writer, context-write depth gate)
986
+ // are therefore native-engine enforcement only. The write-gate arming
987
+ // concern has a universal mirror at tool_execution_start below.
961
988
  pi.on("tool_call", async (event, ctx) => {
962
989
  const discussionBasePath = contextBasePath(ctx);
963
990
  const toolName = canonicalToolName(event.toolName);
@@ -1092,6 +1119,11 @@ export function registerHooks(pi, ecosystemHandlers) {
1092
1119
  }
1093
1120
  });
1094
1121
  // ── Safety harness: evidence collection + destructive command blocking ──
1122
+ // Engine hook contract: tool_call is NATIVE_ONLY_TOOL_HOOKS. Evidence
1123
+ // collection here is mirrored universally at tool_execution_start
1124
+ // (safetyRecordToolCall dedupes by toolCallId); the destructive-command
1125
+ // hard gate has NO universal mirror — blocking is impossible once an
1126
+ // external engine has already executed the command.
1095
1127
  pi.on("tool_call", async (event, ctx) => {
1096
1128
  markToolStart(event.toolCallId, event.toolName);
1097
1129
  safetyRecordToolCall(event.toolCallId, event.toolName, event.input);
@@ -1109,24 +1141,45 @@ export function registerHooks(pi, ecosystemHandlers) {
1109
1141
  }
1110
1142
  // Destructive command classification + hard gate in all modes.
1111
1143
  if (isToolCallEventType("bash", event)) {
1112
- const classification = classifyCommand(event.input.command);
1144
+ const command = event.input.command;
1145
+ const classification = classifyCommand(command);
1113
1146
  if (classification.destructive) {
1147
+ const guardBasePath = contextBasePath(ctx);
1148
+ // Escape hatch: if the user already confirmed this exact command via a
1149
+ // destructive_confirm gate, consume the one-shot token and let it run.
1150
+ // Without this, the block below loops forever — the model cannot satisfy
1151
+ // "confirm in the current turn" because nothing ever clears the gate.
1152
+ if (consumeDestructiveConfirmation(command, guardBasePath)) {
1153
+ safetyLogWarning("safety", `destructive command confirmed: ${classification.labels.join(", ")}`, {
1154
+ command: String(command).slice(0, 200),
1155
+ });
1156
+ return;
1157
+ }
1158
+ // Record the command as pending so an affirmative answer to a
1159
+ // destructive_confirm gate (handled in tool_result) can confirm it.
1160
+ requestDestructiveConfirmation(command, guardBasePath);
1114
1161
  const reason = [
1115
1162
  "HARD BLOCK: destructive Bash command requires explicit human confirmation.",
1116
1163
  `Detected: ${classification.labels.join(", ")}`,
1117
- "Run this via ask_user_questions, wait for the user's response,",
1118
- "then issue the command only when confirmed in the current turn.",
1164
+ "Call ask_user_questions with a question id containing \"destructive_confirm\"",
1165
+ "and a first option that affirms the action; wait for the user's response,",
1166
+ "then re-issue this exact command in the same turn to run it once.",
1119
1167
  ].join(" ");
1120
1168
  safetyLogWarning("safety", `destructive command: ${classification.labels.join(", ")}`, {
1121
- command: String(event.input.command).slice(0, 200),
1169
+ command: String(command).slice(0, 200),
1122
1170
  });
1123
1171
  if (ctx) {
1124
- await maybePauseAutoForApprovalGate(ctx, pi, isAutoActive(), "Depth confirmation is waiting for your answer — pausing auto-mode.");
1172
+ await maybePauseAutoForApprovalGate(ctx, pi, isAutoActive(), "Destructive-command confirmation is waiting for your answer — pausing auto-mode.");
1125
1173
  }
1126
1174
  return { block: true, reason };
1127
1175
  }
1128
1176
  }
1129
1177
  });
1178
+ // Engine hook contract: tool_result is NATIVE_ONLY_TOOL_HOOKS — external
1179
+ // engines skip it. Error classification and markToolEnd are mirrored
1180
+ // universally at tool_execution_end; the ask_user_questions gate lifecycle
1181
+ // here is paired with the tool_execution_start arming path, which external
1182
+ // engines do reach.
1130
1183
  pi.on("tool_result", async (event, ctx) => {
1131
1184
  if (isAutoActive() && typeof event.toolCallId === "string") {
1132
1185
  markToolEnd(event.toolCallId);
@@ -1202,12 +1255,58 @@ export function registerHooks(pi, ecosystemHandlers) {
1202
1255
  if (gateResult.status === "verified") {
1203
1256
  clearDeferredApprovalGate(basePath);
1204
1257
  }
1205
- if (details?.cancelled || !details?.response)
1258
+ // ── Consent Question policy (consent-question.ts): one home for the
1259
+ // answer lifecycle of every ask_user_questions round. Per-question
1260
+ // verdicts come from the consent-verdict leaf — the same engine
1261
+ // applyAskUserQuestionsGateResult consumed above for gate persistence —
1262
+ // so empty answers on fail-closed kinds never pass as real answers (#528)
1263
+ // and cancellations get one unified handler.
1264
+ const roundOutcome = evaluateAskUserQuestionsRound(questions, details ?? {});
1265
+ if (roundOutcome === "cancelled") {
1266
+ resetToolCallLoopGuard();
1267
+ if (ctx) {
1268
+ await maybePauseAutoForApprovalGate(ctx, pi, true, "ask_user_questions was cancelled before receiving a response — pausing auto-mode until you respond.");
1269
+ }
1270
+ return;
1271
+ }
1272
+ if (roundOutcome === "waiting") {
1273
+ resetToolCallLoopGuard();
1274
+ if (ctx) {
1275
+ await maybePauseAutoForApprovalGate(ctx, pi, true, "A user question received no answer — pausing auto-mode until you respond.");
1276
+ }
1277
+ return {
1278
+ content: [{
1279
+ type: "text",
1280
+ text: formatUnansweredConsentQuestionMessage(questions),
1281
+ }],
1282
+ };
1283
+ }
1284
+ // Cancelled rounds already returned via roundOutcome === "cancelled".
1285
+ if (!details?.response)
1206
1286
  return;
1287
+ // Destructive-command confirmation: an affirmative answer to a
1288
+ // destructive_confirm gate promotes the pending blocked command to a
1289
+ // one-shot confirmed token, which the bash tool_call guard consumes on the
1290
+ // next attempt. Rejecting/declining leaves the command blocked.
1291
+ // (Depth-verification gate handling now lives in
1292
+ // applyAskUserQuestionsGateResult above; only the destructive-confirm gate
1293
+ // is handled inline here.)
1294
+ for (const question of questions) {
1295
+ if (isDestructiveConfirmGateId(question?.id)) {
1296
+ const answer = details.response?.answers?.[question.id];
1297
+ if (isDepthConfirmationAnswer(answer?.selected, question.options)) {
1298
+ confirmDestructiveCommand(basePath);
1299
+ }
1300
+ break;
1301
+ }
1302
+ }
1207
1303
  if (!milestoneId)
1208
1304
  return;
1209
1305
  await saveDiscussionQuestionRound(basePath, milestoneId, questions, details);
1210
1306
  });
1307
+ // Engine hook contract: tool_execution_start is UNIVERSAL_TOOL_HOOKS — the
1308
+ // only pre-execution event that fires for every tool call on every engine.
1309
+ // Universal mirrors live here: write-gate arming and evidence collection.
1211
1310
  pi.on("tool_execution_start", async (event, ctx) => {
1212
1311
  const basePath = contextBasePath(ctx);
1213
1312
  const toolName = canonicalToolName(event.toolName);
@@ -1216,29 +1315,22 @@ export function registerHooks(pi, ecosystemHandlers) {
1216
1315
  if (typeof questionId === "string") {
1217
1316
  // External engines (claude-code-cli) ingest the SDK turn's tool blocks
1218
1317
  // post-hoc, so this event can fire AFTER the workflow MCP child already
1219
- // verified this gate and allowed the CONTEXT save. setPendingGate also
1220
- // revokes verifiedDepthMilestones/verifiedApprovalGates, so an
1221
- // unconditional re-arm here wipes the child's verification and leaves
1222
- // the discuss→auto handoff permanently blocked. Skip the re-arm when
1223
- // the snapshot already records this exact gate as verified — mirrors
1224
- // activateDeferredApprovalGate's guard. Stale verified state cannot
1225
- // leak into a later re-discussion: a successful handoff deletes the
1226
- // snapshot via clearDiscussionFlowState.
1227
- const snapshot = refreshWriteGateStateFromDisk(basePath);
1228
- const gateMilestoneId = extractDepthVerificationMilestoneId(questionId);
1229
- const alreadyVerified = isApprovalGateVerifiedInSnapshot(snapshot, questionId) ||
1230
- isMilestoneDepthVerifiedInSnapshot(snapshot, gateMilestoneId);
1231
- if (!alreadyVerified) {
1232
- setPendingGate(questionId, basePath);
1233
- }
1318
+ // verified this gate and allowed the CONTEXT save. Arming also revokes
1319
+ // verifiedDepthMilestones/verifiedApprovalGates, so an unconditional
1320
+ // re-arm here would wipe the child's verification and leave the
1321
+ // discuss→auto handoff permanently blocked. hostWriteGateAdapter
1322
+ // .setPending applies the verified-on-disk-wins policy and skips the
1323
+ // re-arm in that case. Stale verified state cannot leak into a later
1324
+ // re-discussion: a successful handoff deletes the snapshot via
1325
+ // clearDiscussionFlowState.
1326
+ hostWriteGateAdapter.setPending(questionId, basePath);
1234
1327
  clearDeferredApprovalGate(basePath);
1235
1328
  }
1236
1329
  }
1237
- // Safety harness: record evidence here, not only in tool_call. External
1238
- // engines (claude-code-cli) pre-execute tools, so the agent loop skips
1239
- // beforeToolCall/tool_call for them tool_execution_start is the only
1240
- // event that fires for every tool call. recordToolCall dedupes by
1241
- // toolCallId, so native tools (which hit both events) record once.
1330
+ // Safety harness: record evidence here, not only in tool_call — see
1331
+ // ../engine-hook-contract.ts for why tool_call never fires under external
1332
+ // engines. recordToolCall dedupes by toolCallId, so native tools (which
1333
+ // hit both events) record once.
1242
1334
  safetyRecordToolCall(event.toolCallId, event.toolName, (event.args ?? {}));
1243
1335
  const execDash = getAutoRuntimeSnapshot();
1244
1336
  if (execDash.basePath && execDash.currentUnit?.type === "execute-task") {
@@ -1251,6 +1343,9 @@ export function registerHooks(pi, ecosystemHandlers) {
1251
1343
  return;
1252
1344
  markToolStart(event.toolCallId, event.toolName);
1253
1345
  });
1346
+ // Engine hook contract: tool_execution_end is UNIVERSAL_TOOL_HOOKS — fires
1347
+ // for every finalized tool call on every engine, so error classification
1348
+ // and evidence persistence here cover external engines that skip tool_result.
1254
1349
  pi.on("tool_execution_end", async (event) => {
1255
1350
  markToolEnd(event.toolCallId);
1256
1351
  // #2883/#4974: Capture deterministic invocation/policy errors