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

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 (375) hide show
  1. package/dist/cli-web-branch.d.ts +2 -0
  2. package/dist/cli-web-branch.js +9 -2
  3. package/dist/help-text.js +5 -0
  4. package/dist/resources/.managed-resources-content-hash +1 -1
  5. package/dist/resources/extensions/ask-user-questions.js +78 -23
  6. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +84 -228
  7. package/dist/resources/extensions/claude-code-cli/turn-assembler.js +224 -0
  8. package/dist/resources/extensions/github-sync/templates.js +3 -3
  9. package/dist/resources/extensions/gsd/artifact-projection.js +14 -0
  10. package/dist/resources/extensions/gsd/auto/loop.js +74 -56
  11. package/dist/resources/extensions/gsd/auto/orchestrator.js +109 -11
  12. package/dist/resources/extensions/gsd/auto/phases.js +28 -3
  13. package/dist/resources/extensions/gsd/auto/run-unit.js +2 -1
  14. package/dist/resources/extensions/gsd/auto/session.js +3 -0
  15. package/dist/resources/extensions/gsd/auto-dashboard.js +16 -4
  16. package/dist/resources/extensions/gsd/auto-dispatch.js +6 -5
  17. package/dist/resources/extensions/gsd/auto-model-selection.js +8 -0
  18. package/dist/resources/extensions/gsd/auto-post-unit.js +4 -3
  19. package/dist/resources/extensions/gsd/auto-prompts.js +81 -8
  20. package/dist/resources/extensions/gsd/auto-recovery.js +48 -49
  21. package/dist/resources/extensions/gsd/auto-runtime-state.js +14 -0
  22. package/dist/resources/extensions/gsd/auto-start.js +12 -23
  23. package/dist/resources/extensions/gsd/auto-timers.js +16 -2
  24. package/dist/resources/extensions/gsd/auto-tool-tracking.js +32 -0
  25. package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +4 -29
  26. package/dist/resources/extensions/gsd/auto-verification.js +7 -7
  27. package/dist/resources/extensions/gsd/auto-worktree.js +21 -19
  28. package/dist/resources/extensions/gsd/auto.js +11 -7
  29. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +28 -37
  30. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +11 -37
  31. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +2 -2
  32. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +100 -138
  33. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +63 -4
  34. package/dist/resources/extensions/gsd/closeout-consistency-gate.js +21 -4
  35. package/dist/resources/extensions/gsd/codebase-generator.js +8 -4
  36. package/dist/resources/extensions/gsd/commands/handlers/auto.js +3 -0
  37. package/dist/resources/extensions/gsd/commands-handlers.js +20 -0
  38. package/dist/resources/extensions/gsd/commands-inspect.js +4 -8
  39. package/dist/resources/extensions/gsd/commands-maintenance.js +61 -41
  40. package/dist/resources/extensions/gsd/commands-ship.js +2 -2
  41. package/dist/resources/extensions/gsd/commands-verdict.js +12 -2
  42. package/dist/resources/extensions/gsd/db-workspace.js +103 -0
  43. package/dist/resources/extensions/gsd/delegation-policy.js +2 -10
  44. package/dist/resources/extensions/gsd/discussion-handoff.js +218 -0
  45. package/dist/resources/extensions/gsd/docs/preferences-reference.md +9 -0
  46. package/dist/resources/extensions/gsd/doctor.js +16 -9
  47. package/dist/resources/extensions/gsd/error-classifier.js +1 -1
  48. package/dist/resources/extensions/gsd/git-conflict-state.js +16 -1
  49. package/dist/resources/extensions/gsd/gsd-db.js +12 -0
  50. package/dist/resources/extensions/gsd/guided-flow.js +34 -468
  51. package/dist/resources/extensions/gsd/guided-unit-completion.js +225 -0
  52. package/dist/resources/extensions/gsd/markdown-renderer.js +2 -1
  53. package/dist/resources/extensions/gsd/mcp-filter.js +2 -1
  54. package/dist/resources/extensions/gsd/mcp-tool-name.js +26 -0
  55. package/dist/resources/extensions/gsd/md-importer.js +4 -3
  56. package/dist/resources/extensions/gsd/migrate/safety.js +2 -2
  57. package/dist/resources/extensions/gsd/migration-auto-check.js +3 -2
  58. package/dist/resources/extensions/gsd/milestone-closeout-proof.js +72 -0
  59. package/dist/resources/extensions/gsd/milestone-closeout.js +12 -4
  60. package/dist/resources/extensions/gsd/milestone-merge-transaction.js +10 -0
  61. package/dist/resources/extensions/gsd/milestone-planning-persistence.js +156 -0
  62. package/dist/resources/extensions/gsd/milestone-readiness.js +77 -0
  63. package/dist/resources/extensions/gsd/milestone-settlement.js +50 -0
  64. package/dist/resources/extensions/gsd/milestone-validation-evidence.js +73 -0
  65. package/dist/resources/extensions/gsd/milestone-validation-verdict.js +57 -0
  66. package/dist/resources/extensions/gsd/parallel-eligibility.js +3 -6
  67. package/dist/resources/extensions/gsd/parallel-orchestrator.js +3 -2
  68. package/dist/resources/extensions/gsd/preferences-diagnostics.js +67 -0
  69. package/dist/resources/extensions/gsd/preferences.js +147 -29
  70. package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -0
  71. package/dist/resources/extensions/gsd/prompts/execute-task.md +2 -0
  72. package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +3 -1
  73. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +2 -0
  74. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -0
  75. package/dist/resources/extensions/gsd/prompts/refine-slice.md +1 -0
  76. package/dist/resources/extensions/gsd/prompts/system.md +1 -1
  77. package/dist/resources/extensions/gsd/provider-payload-policy.js +83 -0
  78. package/dist/resources/extensions/gsd/pull-request-process.js +13 -0
  79. package/dist/resources/extensions/gsd/quality-gate-closure.js +109 -0
  80. package/dist/resources/extensions/gsd/question-transport.js +86 -0
  81. package/dist/resources/extensions/gsd/roadmap-slices.js +8 -2
  82. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +3 -2
  83. package/dist/resources/extensions/gsd/state.js +13 -5
  84. package/dist/resources/extensions/gsd/templates/plan.md +7 -0
  85. package/dist/resources/extensions/gsd/templates/project.md +1 -0
  86. package/dist/resources/extensions/gsd/templates/roadmap.md +1 -1
  87. package/dist/resources/extensions/gsd/templates/uat.md +5 -1
  88. package/dist/resources/extensions/gsd/tool-contract.js +52 -8
  89. package/dist/resources/extensions/gsd/tool-presentation-plan.js +15 -34
  90. package/dist/resources/extensions/gsd/tool-surface-snapshot.js +17 -0
  91. package/dist/resources/extensions/gsd/tools/plan-milestone.js +15 -143
  92. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +39 -0
  93. package/dist/resources/extensions/gsd/tools/validate-milestone.js +15 -78
  94. package/dist/resources/extensions/gsd/uat-policy.js +16 -10
  95. package/dist/resources/extensions/gsd/uat-run.js +9 -14
  96. package/dist/resources/extensions/gsd/unit-context-composer.js +40 -20
  97. package/dist/resources/extensions/gsd/unit-runtime.js +3 -2
  98. package/dist/resources/extensions/gsd/unit-tool-contracts.js +2 -1
  99. package/dist/resources/extensions/gsd/user-input-boundary.js +23 -0
  100. package/dist/resources/extensions/gsd/validation-block-guard.js +2 -0
  101. package/dist/resources/extensions/gsd/web-app-uat.js +80 -0
  102. package/dist/resources/extensions/gsd/workflow-mcp.js +15 -102
  103. package/dist/resources/extensions/gsd/workflow-reconcile.js +4 -3
  104. package/dist/resources/extensions/gsd/workflow-tool-surface.js +46 -0
  105. package/dist/resources/extensions/gsd/workspace-git-guard.js +2 -0
  106. package/dist/resources/extensions/gsd/worktree-state-projection.js +33 -4
  107. package/dist/resources/extensions/gsd/worktree-telemetry.js +12 -0
  108. package/dist/resources/extensions/shared/interview-ui.js +2 -2
  109. package/dist/resources/shared/claude-runtime-floor.js +182 -0
  110. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  111. package/dist/update-cmd.js +20 -0
  112. package/dist/web/standalone/.next/BUILD_ID +1 -1
  113. package/dist/web/standalone/.next/app-path-routes-manifest.json +7 -7
  114. package/dist/web/standalone/.next/build-manifest.json +3 -3
  115. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  116. package/dist/web/standalone/.next/react-loadable-manifest.json +8 -8
  117. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  118. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  119. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  120. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  121. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  122. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  123. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  124. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  125. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  126. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  127. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  128. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  129. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  130. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  131. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  132. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  133. package/dist/web/standalone/.next/server/app/index.html +1 -1
  134. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  135. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  136. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  137. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  138. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  139. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  140. package/dist/web/standalone/.next/server/app-paths-manifest.json +7 -7
  141. package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
  142. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  143. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  144. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  145. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  146. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  147. package/dist/web/standalone/.next/static/chunks/2659.b7b129ee6a769448.js +1 -0
  148. package/dist/web/standalone/.next/static/chunks/2772.bfa657f49f955239.js +1 -0
  149. package/dist/web/standalone/.next/static/chunks/{3616.4113d484a994e411.js → 3616.3c60753b8ffcbd2e.js} +1 -1
  150. package/dist/web/standalone/.next/static/chunks/4283.e4873b058df143a1.js +2 -0
  151. package/dist/web/standalone/.next/static/chunks/5826.a46ecdd1cfe8dabc.js +1 -0
  152. package/dist/web/standalone/.next/static/chunks/796.cf859a427a2cb2ac.js +10 -0
  153. package/dist/web/standalone/.next/static/chunks/8785.2e5a118797fb2dd2.js +1 -0
  154. package/dist/web/standalone/.next/static/chunks/{webpack-dda80a1ef5587410.js → webpack-fbea77b5f9953368.js} +1 -1
  155. package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
  156. package/dist/web-mode.d.ts +2 -0
  157. package/dist/web-mode.js +20 -8
  158. package/package.json +2 -1
  159. package/packages/cloud-mcp-gateway/package.json +2 -2
  160. package/packages/contracts/package.json +1 -1
  161. package/packages/daemon/package.json +4 -4
  162. package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts +2 -0
  163. package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts.map +1 -1
  164. package/packages/gsd-agent-core/dist/session/agent-session-extensions.js +14 -0
  165. package/packages/gsd-agent-core/dist/session/agent-session-extensions.js.map +1 -1
  166. package/packages/gsd-agent-core/package.json +5 -5
  167. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  168. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +106 -40
  169. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  170. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.d.ts.map +1 -1
  171. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.js +6 -0
  172. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.js.map +1 -1
  173. package/packages/gsd-agent-modes/package.json +7 -7
  174. package/packages/mcp-server/dist/server.d.ts +10 -0
  175. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  176. package/packages/mcp-server/dist/server.js +8 -0
  177. package/packages/mcp-server/dist/server.js.map +1 -1
  178. package/packages/mcp-server/dist/workflow-tools.d.ts +41 -0
  179. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  180. package/packages/mcp-server/dist/workflow-tools.js +2 -1
  181. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  182. package/packages/mcp-server/package.json +3 -3
  183. package/packages/native/package.json +1 -1
  184. package/packages/pi-agent-core/package.json +1 -1
  185. package/packages/pi-ai/dist/models.generated.d.ts +8 -93
  186. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  187. package/packages/pi-ai/dist/models.generated.js +35 -120
  188. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  189. package/packages/pi-ai/package.json +1 -1
  190. package/packages/pi-coding-agent/package.json +7 -7
  191. package/packages/pi-tui/dist/components/input.js +1 -1
  192. package/packages/pi-tui/dist/components/input.js.map +1 -1
  193. package/packages/pi-tui/dist/keys.d.ts.map +1 -1
  194. package/packages/pi-tui/dist/keys.js +39 -30
  195. package/packages/pi-tui/dist/keys.js.map +1 -1
  196. package/packages/pi-tui/dist/stdin-buffer.d.ts.map +1 -1
  197. package/packages/pi-tui/dist/stdin-buffer.js +22 -0
  198. package/packages/pi-tui/dist/stdin-buffer.js.map +1 -1
  199. package/packages/pi-tui/package.json +2 -2
  200. package/packages/rpc-client/package.json +2 -2
  201. package/pkg/package.json +1 -1
  202. package/src/resources/extensions/ask-user-questions.ts +87 -24
  203. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +108 -281
  204. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +240 -0
  205. package/src/resources/extensions/claude-code-cli/turn-assembler.ts +287 -0
  206. package/src/resources/extensions/github-sync/templates.ts +3 -3
  207. package/src/resources/extensions/github-sync/tests/templates.test.ts +2 -2
  208. package/src/resources/extensions/gsd/artifact-projection.ts +31 -0
  209. package/src/resources/extensions/gsd/auto/contracts.ts +32 -2
  210. package/src/resources/extensions/gsd/auto/loop-deps.ts +2 -0
  211. package/src/resources/extensions/gsd/auto/loop.ts +83 -61
  212. package/src/resources/extensions/gsd/auto/orchestrator.ts +125 -12
  213. package/src/resources/extensions/gsd/auto/phases.ts +35 -3
  214. package/src/resources/extensions/gsd/auto/run-unit.ts +2 -1
  215. package/src/resources/extensions/gsd/auto/session.ts +4 -0
  216. package/src/resources/extensions/gsd/auto-dashboard.ts +18 -4
  217. package/src/resources/extensions/gsd/auto-dispatch.ts +20 -7
  218. package/src/resources/extensions/gsd/auto-model-selection.ts +8 -0
  219. package/src/resources/extensions/gsd/auto-post-unit.ts +4 -3
  220. package/src/resources/extensions/gsd/auto-prompts.ts +107 -9
  221. package/src/resources/extensions/gsd/auto-recovery.ts +50 -50
  222. package/src/resources/extensions/gsd/auto-runtime-state.ts +26 -0
  223. package/src/resources/extensions/gsd/auto-start.ts +17 -20
  224. package/src/resources/extensions/gsd/auto-timers.ts +16 -2
  225. package/src/resources/extensions/gsd/auto-tool-tracking.ts +35 -0
  226. package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +9 -30
  227. package/src/resources/extensions/gsd/auto-verification.ts +7 -8
  228. package/src/resources/extensions/gsd/auto-worktree.ts +33 -26
  229. package/src/resources/extensions/gsd/auto.ts +15 -8
  230. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +29 -37
  231. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +10 -37
  232. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +2 -2
  233. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +116 -151
  234. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +107 -3
  235. package/src/resources/extensions/gsd/closeout-consistency-gate.ts +27 -5
  236. package/src/resources/extensions/gsd/codebase-generator.ts +9 -5
  237. package/src/resources/extensions/gsd/commands/handlers/auto.ts +3 -0
  238. package/src/resources/extensions/gsd/commands-handlers.ts +18 -0
  239. package/src/resources/extensions/gsd/commands-inspect.ts +7 -8
  240. package/src/resources/extensions/gsd/commands-maintenance.ts +74 -40
  241. package/src/resources/extensions/gsd/commands-ship.ts +2 -2
  242. package/src/resources/extensions/gsd/commands-verdict.ts +19 -2
  243. package/src/resources/extensions/gsd/db-workspace.ts +170 -0
  244. package/src/resources/extensions/gsd/delegation-policy.ts +3 -11
  245. package/src/resources/extensions/gsd/discussion-handoff.ts +276 -0
  246. package/src/resources/extensions/gsd/docs/preferences-reference.md +9 -0
  247. package/src/resources/extensions/gsd/doctor.ts +15 -5
  248. package/src/resources/extensions/gsd/error-classifier.ts +1 -1
  249. package/src/resources/extensions/gsd/git-conflict-state.ts +17 -1
  250. package/src/resources/extensions/gsd/gsd-db.ts +12 -0
  251. package/src/resources/extensions/gsd/guided-flow.ts +47 -558
  252. package/src/resources/extensions/gsd/guided-unit-completion.ts +275 -0
  253. package/src/resources/extensions/gsd/markdown-renderer.ts +2 -1
  254. package/src/resources/extensions/gsd/mcp-filter.ts +2 -1
  255. package/src/resources/extensions/gsd/mcp-tool-name.ts +35 -0
  256. package/src/resources/extensions/gsd/md-importer.ts +3 -3
  257. package/src/resources/extensions/gsd/migrate/safety.ts +2 -2
  258. package/src/resources/extensions/gsd/migration-auto-check.ts +2 -2
  259. package/src/resources/extensions/gsd/milestone-closeout-proof.ts +131 -0
  260. package/src/resources/extensions/gsd/milestone-closeout.ts +12 -4
  261. package/src/resources/extensions/gsd/milestone-merge-transaction.ts +47 -0
  262. package/src/resources/extensions/gsd/milestone-planning-persistence.ts +224 -0
  263. package/src/resources/extensions/gsd/milestone-readiness.ts +125 -0
  264. package/src/resources/extensions/gsd/milestone-settlement.ts +81 -0
  265. package/src/resources/extensions/gsd/milestone-validation-evidence.ts +95 -0
  266. package/src/resources/extensions/gsd/milestone-validation-verdict.ts +80 -0
  267. package/src/resources/extensions/gsd/parallel-eligibility.ts +4 -5
  268. package/src/resources/extensions/gsd/parallel-orchestrator.ts +6 -2
  269. package/src/resources/extensions/gsd/preferences-diagnostics.ts +98 -0
  270. package/src/resources/extensions/gsd/preferences-types.ts +16 -0
  271. package/src/resources/extensions/gsd/preferences.ts +173 -28
  272. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -0
  273. package/src/resources/extensions/gsd/prompts/execute-task.md +2 -0
  274. package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +3 -1
  275. package/src/resources/extensions/gsd/prompts/plan-milestone.md +2 -0
  276. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -0
  277. package/src/resources/extensions/gsd/prompts/refine-slice.md +1 -0
  278. package/src/resources/extensions/gsd/prompts/system.md +1 -1
  279. package/src/resources/extensions/gsd/provider-payload-policy.ts +140 -0
  280. package/src/resources/extensions/gsd/pull-request-process.ts +41 -0
  281. package/src/resources/extensions/gsd/quality-gate-closure.ts +140 -0
  282. package/src/resources/extensions/gsd/question-transport.ts +138 -0
  283. package/src/resources/extensions/gsd/roadmap-slices.ts +8 -2
  284. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +6 -2
  285. package/src/resources/extensions/gsd/state.ts +15 -5
  286. package/src/resources/extensions/gsd/templates/plan.md +7 -0
  287. package/src/resources/extensions/gsd/templates/project.md +1 -0
  288. package/src/resources/extensions/gsd/templates/roadmap.md +1 -1
  289. package/src/resources/extensions/gsd/templates/uat.md +5 -1
  290. package/src/resources/extensions/gsd/tests/ask-user-questions-render.test.ts +92 -0
  291. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +29 -1
  292. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +321 -5
  293. package/src/resources/extensions/gsd/tests/auto-milestone-target.test.ts +23 -0
  294. package/src/resources/extensions/gsd/tests/auto-model-selection-tool-poisoning.test.ts +18 -0
  295. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +133 -4
  296. package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +34 -0
  297. package/src/resources/extensions/gsd/tests/canonical-milestone-root.test.ts +20 -0
  298. package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +22 -0
  299. package/src/resources/extensions/gsd/tests/commands-dispatcher-workspace-git.test.ts +11 -0
  300. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +38 -1
  301. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +34 -3
  302. package/src/resources/extensions/gsd/tests/dispatch-run-uat-browser-tools.test.ts +88 -0
  303. package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +18 -0
  304. package/src/resources/extensions/gsd/tests/execute-task-rendering.test.ts +1 -0
  305. package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-no-blockers.md +1 -5
  306. package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-with-blockers.md +1 -5
  307. package/src/resources/extensions/gsd/tests/gate-state-canonicalization.test.ts +48 -1
  308. package/src/resources/extensions/gsd/tests/mcp-tool-name.test.ts +34 -0
  309. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +58 -0
  310. package/src/resources/extensions/gsd/tests/milestone-closeout-proof.test.ts +99 -0
  311. package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +25 -0
  312. package/src/resources/extensions/gsd/tests/milestone-merge-transaction.test.ts +46 -0
  313. package/src/resources/extensions/gsd/tests/milestone-readiness.test.ts +65 -0
  314. package/src/resources/extensions/gsd/tests/milestone-validation-evidence.test.ts +41 -0
  315. package/src/resources/extensions/gsd/tests/milestone-validation-verdict.test.ts +55 -0
  316. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +45 -0
  317. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +2 -0
  318. package/src/resources/extensions/gsd/tests/planning-crossval.test.ts +45 -0
  319. package/src/resources/extensions/gsd/tests/preferences-diagnostics.test.ts +67 -0
  320. package/src/resources/extensions/gsd/tests/preferences.test.ts +183 -0
  321. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +46 -0
  322. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +9 -0
  323. package/src/resources/extensions/gsd/tests/provider-payload-policy.test.ts +165 -0
  324. package/src/resources/extensions/gsd/tests/pull-request-process.test.ts +47 -0
  325. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +94 -0
  326. package/src/resources/extensions/gsd/tests/roadmap-parse-regression.test.ts +40 -0
  327. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +25 -1
  328. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +80 -0
  329. package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +101 -1
  330. package/src/resources/extensions/gsd/tests/stale-queued-milestone.test.ts +27 -0
  331. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +2 -1
  332. package/src/resources/extensions/gsd/tests/tool-availability-audit.test.ts +35 -0
  333. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +35 -42
  334. package/src/resources/extensions/gsd/tests/uat-policy.test.ts +23 -0
  335. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +47 -0
  336. package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +86 -1
  337. package/src/resources/extensions/gsd/tests/validate-milestone-stuck-guard.test.ts +39 -0
  338. package/src/resources/extensions/gsd/tests/web-app-uat.test.ts +150 -0
  339. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +126 -9
  340. package/src/resources/extensions/gsd/tests/workspace-git-preflight.test.ts +15 -0
  341. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +21 -0
  342. package/src/resources/extensions/gsd/tests/worktree-projection-writers.test.ts +1 -1
  343. package/src/resources/extensions/gsd/tests/worktree-telemetry.test.ts +22 -0
  344. package/src/resources/extensions/gsd/tests/write-gate.test.ts +79 -0
  345. package/src/resources/extensions/gsd/tool-contract.ts +86 -8
  346. package/src/resources/extensions/gsd/tool-presentation-plan.ts +16 -33
  347. package/src/resources/extensions/gsd/tool-surface-snapshot.ts +47 -0
  348. package/src/resources/extensions/gsd/tools/plan-milestone.ts +19 -160
  349. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +43 -0
  350. package/src/resources/extensions/gsd/tools/validate-milestone.ts +25 -84
  351. package/src/resources/extensions/gsd/uat-policy.ts +19 -10
  352. package/src/resources/extensions/gsd/uat-run.ts +10 -14
  353. package/src/resources/extensions/gsd/unit-context-composer.ts +85 -20
  354. package/src/resources/extensions/gsd/unit-runtime.ts +3 -2
  355. package/src/resources/extensions/gsd/unit-tool-contracts.ts +2 -1
  356. package/src/resources/extensions/gsd/user-input-boundary.ts +18 -0
  357. package/src/resources/extensions/gsd/validation-block-guard.ts +2 -0
  358. package/src/resources/extensions/gsd/web-app-uat.ts +101 -0
  359. package/src/resources/extensions/gsd/workflow-mcp.ts +22 -110
  360. package/src/resources/extensions/gsd/workflow-reconcile.ts +3 -3
  361. package/src/resources/extensions/gsd/workflow-tool-surface.ts +73 -0
  362. package/src/resources/extensions/gsd/workspace-git-guard.ts +1 -0
  363. package/src/resources/extensions/gsd/worktree-lifecycle.ts +7 -16
  364. package/src/resources/extensions/gsd/worktree-state-projection.ts +55 -7
  365. package/src/resources/extensions/gsd/worktree-telemetry.ts +16 -0
  366. package/src/resources/extensions/shared/interview-ui.ts +15 -2
  367. package/src/resources/shared/claude-runtime-floor.ts +248 -0
  368. package/dist/web/standalone/.next/static/chunks/2659.feb6499ca863ebfc.js +0 -1
  369. package/dist/web/standalone/.next/static/chunks/2772.151789db0edea835.js +0 -1
  370. package/dist/web/standalone/.next/static/chunks/4283.10a065467b5340d8.js +0 -2
  371. package/dist/web/standalone/.next/static/chunks/5826.960dc4634cc9b0d3.js +0 -1
  372. package/dist/web/standalone/.next/static/chunks/796.46f811c0fac23aab.js +0 -10
  373. package/dist/web/standalone/.next/static/chunks/8785.d32f7a61f55c1600.js +0 -1
  374. /package/dist/web/standalone/.next/static/{Qbr81pQ-pbQXP4bq2VXLv → 3PtrU9qGPEXwNLWkIyiqk}/_buildManifest.js +0 -0
  375. /package/dist/web/standalone/.next/static/{Qbr81pQ-pbQXP4bq2VXLv → 3PtrU9qGPEXwNLWkIyiqk}/_ssgManifest.js +0 -0
@@ -2,14 +2,14 @@
2
2
  // File Purpose: Registers workspace-aware dynamic filesystem and shell tools.
3
3
  import { existsSync, readdirSync } from "node:fs";
4
4
  import { homedir } from "node:os";
5
- import { dirname, join } from "node:path";
5
+ import { join } from "node:path";
6
6
 
7
7
  import type { ExtensionAPI } from "@gsd/pi-coding-agent";
8
8
  import { createBashTool, createEditTool, createReadTool, createWriteTool } from "@gsd/pi-coding-agent";
9
9
 
10
10
  import { DEFAULT_BASH_TIMEOUT_SECS } from "../constants.js";
11
- import { setLogBasePath, logWarning } from "../workflow-logger.js";
12
- import { resolveGsdPathContract } from "../paths.js";
11
+ import { logWarning } from "../workflow-logger.js";
12
+ import { openWorkflowDatabase } from "../db-workspace.js";
13
13
  import { getAutoWorktreePath } from "../auto-worktree.js";
14
14
  import { resolveWorktreeProjectRoot } from "../worktree-root.js";
15
15
 
@@ -64,45 +64,18 @@ export function resolveWorkflowToolBasePath(
64
64
  return cwd;
65
65
  }
66
66
 
67
- /**
68
- * Resolve the correct DB path for the current working directory.
69
- * If `basePath` is inside a `.gsd/worktrees/<MID>/` directory, returns
70
- * the project root's `.gsd/gsd.db` (shared WAL — R012). Otherwise
71
- * returns `<basePath>/.gsd/gsd.db`.
72
- */
73
- export function resolveProjectRootDbPath(basePath: string): string {
74
- return resolveGsdPathContract(basePath).projectDb;
75
- }
67
+ export { resolveProjectRootDbPath } from "../db-workspace.js";
76
68
 
77
69
  export async function ensureDbOpen(basePath: string = safeWorkspaceCwd()): Promise<boolean> {
78
- try {
79
- const db = await import("../gsd-db.js");
80
- const contract = resolveGsdPathContract(basePath);
81
- const dbPath = contract.projectDb;
82
- const gsdDir = contract.projectGsd;
83
- const projectRoot = dirname(dirname(dbPath));
84
-
85
- // Open existing DB file (may be at project root for worktrees)
86
- if (existsSync(dbPath)) {
87
- const opened = db.openDatabase(dbPath);
88
- if (opened) setLogBasePath(projectRoot);
89
- return opened;
90
- }
91
-
92
- // No DB file — create an empty authoritative DB. Markdown migration is
93
- // explicit-only; runtime startup must not import projections into state.
94
- if (existsSync(gsdDir)) {
95
- const opened = db.openDatabase(dbPath);
96
- if (opened) setLogBasePath(projectRoot);
97
- return opened;
98
- }
70
+ const result = openWorkflowDatabase(basePath);
71
+ if (result.ok) return true;
99
72
 
73
+ if (result.reason === "missing-gsd-dir") {
100
74
  logWarning("bootstrap", "ensureDbOpen failed — no .gsd directory found");
101
- return false;
102
- } catch (err) {
103
- logWarning("bootstrap", `ensureDbOpen failed: ${(err as Error).message ?? String(err)}`);
104
- return false;
75
+ } else {
76
+ logWarning("bootstrap", `ensureDbOpen failed: ${result.error?.message ?? "open failed"}`);
105
77
  }
78
+ return false;
106
79
  }
107
80
 
108
81
  export function registerDynamicTools(pi: ExtensionAPI): void {
@@ -5,6 +5,7 @@
5
5
  import { Type } from "@sinclair/typebox";
6
6
  import type { ExtensionAPI } from "@gsd/pi-coding-agent";
7
7
  import { ensureDbOpen, resolveCtxCwd } from "./dynamic-tools.js";
8
+ import { checkpointWorkflowDatabase } from "../db-workspace.js";
8
9
 
9
10
 
10
11
  export function registerQueryTools(pi: ExtensionAPI): void {
@@ -57,8 +58,7 @@ export function registerQueryTools(pi: ExtensionAPI): void {
57
58
  details: { operation: "checkpoint_db", error: "db_unavailable" },
58
59
  };
59
60
  }
60
- const { checkpointDatabase } = await import("../gsd-db.js");
61
- checkpointDatabase();
61
+ checkpointWorkflowDatabase();
62
62
  return {
63
63
  content: [{ type: "text", text: "WAL checkpoint complete. gsd.db is now up to date and safe to stage with git add." }],
64
64
  details: { operation: "checkpoint_db", status: "ok" },
@@ -13,7 +13,7 @@ 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 { canonicalToolName, clearDiscussionFlowState, isDepthConfirmationAnswer, isMilestoneDepthVerified, isQueuePhaseActive, markApprovalGateVerified, markDepthVerified, resetWriteGateState, shouldBlockContextWrite, shouldBlockPlanningUnit, shouldBlockQueueExecution, shouldBlockWorktreeWrite, isGateQuestionId, setPendingGate, clearPendingGate, getPendingGate, shouldBlockPendingGate, shouldBlockPendingGateBash, extractDepthVerificationMilestoneId } from "./write-gate.js";
16
+ import { applyAskUserQuestionsGateResult, canonicalToolName, clearDiscussionFlowState, formatPendingAskUserQuestionsGateMessage, isMilestoneDepthVerified, isQueuePhaseActive, markApprovalGateVerified, markDepthVerified, resetWriteGateState, shouldBlockContextWrite, shouldBlockPlanningUnit, shouldBlockQueueExecution, shouldBlockWorktreeWrite, isGateQuestionId, setPendingGate, clearPendingGate, getPendingGate, shouldBlockPendingGate, shouldBlockPendingGateBash, extractDepthVerificationMilestoneId } from "./write-gate.js";
17
17
  import { resolveManifest } from "../unit-context-manifest.js";
18
18
  import { isBlockedStateFile, isBashWriteToStateFile, BLOCKED_WRITE_ERROR } from "../write-intercept.js";
19
19
  import { loadFile, saveFile, formatContinue } from "../files.js";
@@ -25,10 +25,13 @@ import {
25
25
  isAutoActive,
26
26
  isAutoCompletionStopInProgress,
27
27
  isAutoPaused,
28
+ isInteractiveElicitationInFlight,
28
29
  markToolEnd,
29
30
  markToolStart,
31
+ recordAutoToolSurfaceSnapshot,
30
32
  recordToolInvocationError,
31
33
  } from "../auto-runtime-state.js";
34
+ import { applyProviderPayloadPolicy } from "../provider-payload-policy.js";
32
35
 
33
36
  import { checkToolCallLoop, resetToolCallLoopGuard } from "./tool-call-loop-guard.js";
34
37
  import { maybePauseAutoForApprovalGate, resetPendingGatePauseGuard } from "./pending-gate-pause.js";
@@ -40,17 +43,24 @@ import { logWarning as safetyLogWarning } from "../workflow-logger.js";
40
43
  import { installNotifyInterceptor } from "./notify-interceptor.js";
41
44
  import { initNotificationStore } from "../notification-store.js";
42
45
  import { initNotificationWidget } from "../notification-widget.js";
46
+ import { notifyPreferenceDiagnostics } from "../preferences-diagnostics.js";
43
47
  import { resolveWorktreeProjectRoot } from "../worktree-root.js";
44
48
  import { extractSubagentAgentClasses } from "./subagent-input.js";
45
- import { approvalGateIdForUnit, isExplicitApprovalResponse, shouldPauseForUserApprovalQuestion } from "../user-input-boundary.js";
49
+ import {
50
+ approvalGateIdForUnit,
51
+ isExplicitApprovalResponse,
52
+ messageHasPendingAskUserQuestionsTool,
53
+ shouldPauseForUserApprovalQuestion,
54
+ } from "../user-input-boundary.js";
46
55
  import { resolveSkillManifest } from "../skill-manifest.js";
47
56
  import { applyUnitSkillVisibility, unitHasSkillManifest } from "../skill-scope.js";
48
57
  import { getGuidedUnitContext } from "../guided-unit-context.js";
49
58
  import { registerPlanMilestoneSchemaRecovery } from "./plan-milestone-schema-recovery.js";
50
- import { AUTO_UNIT_SCOPED_TOOLS, RUN_UAT_BROWSER_TOOL_NAMES, isWorkflowAliasTool } from "../auto-unit-tool-scope.js";
59
+ import { AUTO_UNIT_SCOPED_TOOLS, RUN_UAT_BROWSER_TOOL_NAMES, canonicalWorkflowToolName, isWorkflowAliasTool } from "../auto-unit-tool-scope.js";
51
60
  import { filterToolsForProvider } from "../model-router.js";
61
+ import { mcpToolMatchesBaseName } from "../mcp-tool-name.js";
52
62
  import { RUN_UAT_READ_ONLY_TOOL_NAMES, RUN_UAT_WORKFLOW_TOOL_NAMES } from "../tool-presentation-plan.js";
53
- import { injectSourceContextBlockIntoPayload, supportsSourceObservationsForUnit } from "../source-observations.js";
63
+ import { supportsSourceObservationsForUnit } from "../source-observations.js";
54
64
 
55
65
  let approvalQuestionAbortInFlight = false;
56
66
 
@@ -210,16 +220,22 @@ function resolveScopedToolNames(
210
220
 
211
221
  for (const requested of requestedToolNames) {
212
222
  const scopedMatches: string[] = [];
223
+ const aliasFallbacks: string[] = [];
213
224
 
214
225
  for (const activeName of activeToolNames) {
215
- if (!activeName.startsWith("mcp__")) continue;
216
- const toolSeparator = activeName.indexOf("__", "mcp__".length);
217
- if (toolSeparator < 0) continue;
218
- if (activeName.slice(toolSeparator + 2) === requested) {
226
+ if (mcpToolMatchesBaseName(activeName, requested)) {
219
227
  scopedMatches.push(activeName);
228
+ } else if (isWorkflowAliasTool(activeName) && canonicalWorkflowToolName(activeName) === requested) {
229
+ aliasFallbacks.push(activeName);
220
230
  }
221
231
  }
222
232
 
233
+ // Only use alias as fallback when canonical is absent — not directly and not via MCP scoping.
234
+ // Prevents the alias from resurfacing alongside the canonical when both are in the active set.
235
+ if (!exact.has(requested) && scopedMatches.length === 0) {
236
+ scopedMatches.push(...aliasFallbacks);
237
+ }
238
+
223
239
  if (requested.startsWith("browser_") && scopedMatches.length > 0) {
224
240
  for (const match of scopedMatches) resolved.add(match);
225
241
  continue;
@@ -276,7 +292,7 @@ export function buildRunUatGsdToolSet(
276
292
  const resolved = [...new Set(scoped)];
277
293
 
278
294
  const unresolved = RUN_UAT_WORKFLOW_TOOL_NAMES.filter(
279
- (tool) => !resolved.some((name) => name === tool || (name.startsWith("mcp__") && name.endsWith(`__${tool}`))),
295
+ (tool) => !resolved.some((name) => name === tool || mcpToolMatchesBaseName(name, tool)),
280
296
  );
281
297
  if (unresolved.length > 0) {
282
298
  safetyLogWarning(
@@ -368,11 +384,21 @@ function applyMinimalGsdToolSurface(pi: ExtensionAPI): void {
368
384
  if (isFullGsdToolSurfaceRequested()) return;
369
385
  const dash = getAutoRuntimeSnapshot();
370
386
  if (dash.active && dash.currentUnit) {
371
- pi.setActiveTools(buildMinimalAutoGsdToolSet(
372
- pi.getActiveTools(),
387
+ const currentToolNames = pi.getActiveTools();
388
+ const registeredToolNames = resolveRegisteredToolNames(pi, currentToolNames);
389
+ const scopedToolNames = buildMinimalAutoGsdToolSet(
390
+ currentToolNames,
373
391
  dash.currentUnit.type,
374
- resolveRegisteredToolNames(pi, pi.getActiveTools()),
375
- ));
392
+ registeredToolNames,
393
+ );
394
+ recordAutoToolSurfaceSnapshot({
395
+ source: "runtime-scope",
396
+ unitType: dash.currentUnit.type,
397
+ modelFacingToolNames: scopedToolNames,
398
+ registeredToolNames,
399
+ scopedToolNames,
400
+ });
401
+ pi.setActiveTools(scopedToolNames);
376
402
  return;
377
403
  }
378
404
  if (!isGeneralGsdToolScopingRequested()) return;
@@ -389,6 +415,13 @@ export function scopeGsdWorkflowToolsForDispatch(
389
415
  const scoped = unitType
390
416
  ? buildMinimalAutoGsdToolSet(current, unitType, registeredToolNames)
391
417
  : buildMinimalGsdWorkflowToolSet(current, registeredToolNames);
418
+ recordAutoToolSurfaceSnapshot({
419
+ source: "dispatch-scope",
420
+ unitType,
421
+ modelFacingToolNames: scoped,
422
+ registeredToolNames,
423
+ scopedToolNames: scoped,
424
+ });
392
425
  const toolsChanged = !(scoped.length === current.length && scoped.every((name, index) => name === current[index]));
393
426
  const canScopeSkills = unitHasSkillManifest(unitType) && pi.getVisibleSkills && pi.setVisibleSkills;
394
427
  if (!toolsChanged && !canScopeSkills) {
@@ -697,6 +730,7 @@ function initSessionNotifications(ctx: ExtensionContext): void {
697
730
  initNotificationStore(resolveNotificationStoreBasePath(contextBasePath(ctx)));
698
731
  installNotifyInterceptor(ctx);
699
732
  initNotificationWidget(ctx);
733
+ notifyPreferenceDiagnostics(ctx, contextBasePath(ctx), { surface: "session-start" });
700
734
  }
701
735
 
702
736
  async function prepareWorkflowMcpForHookContext(
@@ -994,6 +1028,18 @@ export function registerHooks(
994
1028
 
995
1029
  pi.on("message_update", async (event, ctx: ExtensionContext) => {
996
1030
  if (approvalQuestionAbortInFlight) return;
1031
+ // If the model asked via ask_user_questions, that in-flight elicitation IS
1032
+ // the human boundary. Arming the pause/gate here (and emitting the "waiting
1033
+ // for your approval - pausing" notice) would tear it down and trigger the
1034
+ // foreground self-cancel/re-ask loop. The marker is set only by the
1035
+ // claude-code-cli SDK elicitation handler and is ungated, so it is true in
1036
+ // foreground; under the native-TUI provider it is always false and this path
1037
+ // runs unchanged (#cc-elicitation-self-cancel).
1038
+ if (isInteractiveElicitationInFlight()) return;
1039
+ // Prose with "?" can stream before the MCP tool/elicitation starts. When the
1040
+ // structured ask_user_questions call is already in the partial message, the
1041
+ // tool IS the human boundary — do not arm the text-based approval pause.
1042
+ if (messageHasPendingAskUserQuestionsTool(event.message)) return;
997
1043
 
998
1044
  const dash = getAutoRuntimeSnapshot();
999
1045
  if (dash.active) return;
@@ -1328,81 +1374,37 @@ export function registerHooks(
1328
1374
 
1329
1375
  const details = event.details as any;
1330
1376
 
1331
- // ── Discussion gate enforcement: handle gate question responses ──
1332
- // If the result is cancelled or has no response, the pending gate stays active
1333
- // so the model is blocked from non-read-only tools until it re-asks.
1334
- // If the user responded at all (even "needs adjustment"), clear the pending gate
1335
- // because the user engaged — the prompt handles the re-ask-after-adjustment flow.
1336
1377
  const questions: any[] = (event.input as any)?.questions ?? [];
1337
- const currentPendingGate = getPendingGate(basePath);
1338
- if (currentPendingGate) {
1339
- if (details?.cancelled || !details?.response) {
1340
- // Gate stays pending. Direct the agent to the most reliable recovery
1341
- // path — re-calling ask_user_questions with the same gate id — without
1342
- // misrepresenting the plain-text path. The plain-text path also works
1343
- // (isExplicitApprovalResponse on the next before_agent_start clears
1344
- // the gate when the user replies with an approval keyword), but the
1345
- // structured re-ask is more deterministic and gives the user a clear UI.
1346
- resetToolCallLoopGuard();
1347
- const interrupted = details?.interrupted === true;
1348
- if (ctx) {
1349
- await maybePauseAutoForApprovalGate(
1350
- ctx,
1351
- pi,
1352
- true,
1353
- interrupted
1354
- ? "Depth confirmation was interrupted — pausing auto-mode until you respond."
1355
- : "Depth confirmation is waiting for your answer — pausing auto-mode.",
1356
- );
1357
- }
1358
- return {
1359
- content: [{
1360
- type: "text" as const,
1361
- text: [
1362
- `Waiting for depth confirmation on gate "${currentPendingGate}".`,
1363
- interrupted
1364
- ? "The confirmation question was interrupted before a response was recorded."
1365
- : "No user response was received for the confirmation question.",
1366
- "Do not infer approval from earlier or prior messages.",
1367
- "Do not proceed, write files, save artifacts, or call other tools.",
1368
- `Re-call ask_user_questions with the same gate question id ("${currentPendingGate}") and wait for the user's response.`,
1369
- ].join(" "),
1370
- }],
1371
- };
1372
- } else {
1373
- const pendingQuestion = questions.find((question) => question?.id === currentPendingGate);
1374
- if (pendingQuestion) {
1375
- const answer = details.response?.answers?.[currentPendingGate];
1376
- if (isDepthConfirmationAnswer(answer?.selected, pendingQuestion.options)) {
1377
- markApprovalGateVerified(currentPendingGate, basePath);
1378
- const milestoneIdFromGate = extractDepthVerificationMilestoneId(currentPendingGate);
1379
- if (milestoneIdFromGate) markDepthVerified(milestoneIdFromGate, basePath);
1380
- clearPendingGate(basePath);
1381
- clearDeferredApprovalGate(basePath);
1382
- }
1383
- }
1378
+ const gateResult = applyAskUserQuestionsGateResult({
1379
+ basePath,
1380
+ questions,
1381
+ details,
1382
+ fallbackMilestoneId: milestoneId,
1383
+ });
1384
+ if (gateResult.status === "waiting") {
1385
+ resetToolCallLoopGuard();
1386
+ if (ctx) {
1387
+ await maybePauseAutoForApprovalGate(
1388
+ ctx,
1389
+ pi,
1390
+ true,
1391
+ gateResult.interrupted
1392
+ ? "Depth confirmation was interrupted — pausing auto-mode until you respond."
1393
+ : "Depth confirmation is waiting for your answer — pausing auto-mode.",
1394
+ );
1384
1395
  }
1396
+ return {
1397
+ content: [{
1398
+ type: "text" as const,
1399
+ text: formatPendingAskUserQuestionsGateMessage(gateResult.pendingGateId, gateResult.interrupted),
1400
+ }],
1401
+ };
1385
1402
  }
1386
-
1387
- if (details?.cancelled || !details?.response) return;
1388
-
1389
- for (const question of questions) {
1390
- if (typeof question.id === "string" && question.id.includes("depth_verification")) {
1391
- // Only unlock the gate if the user selected the first option (confirmation).
1392
- // Cross-references against the question's defined options to reject free-form "Other" text.
1393
- const answer = details.response?.answers?.[question.id];
1394
- const inferredMilestoneId = extractDepthVerificationMilestoneId(question.id) ?? milestoneId;
1395
- if (isDepthConfirmationAnswer(answer?.selected, question.options)) {
1396
- if (currentPendingGate && question.id !== currentPendingGate) break;
1397
- markApprovalGateVerified(question.id, basePath);
1398
- markDepthVerified(inferredMilestoneId, basePath);
1399
- clearPendingGate(basePath);
1400
- clearDeferredApprovalGate(basePath);
1401
- }
1402
- break;
1403
- }
1403
+ if (gateResult.status === "verified") {
1404
+ clearDeferredApprovalGate(basePath);
1404
1405
  }
1405
1406
 
1407
+ if (details?.cancelled || !details?.response) return;
1406
1408
  if (!milestoneId) return;
1407
1409
  await saveDiscussionQuestionRound(basePath, milestoneId, questions, details);
1408
1410
  });
@@ -1458,66 +1460,10 @@ export function registerHooks(
1458
1460
  const payload = event.payload as Record<string, unknown> | null;
1459
1461
  if (!payload || typeof payload !== "object") return;
1460
1462
 
1461
- // ── Context Management ──────────────────────────────────────────────
1462
- // Load preferences once for both masking and truncation.
1463
- try {
1464
- const { loadEffectiveGSDPreferences } = await import("../preferences.js");
1465
- const {
1466
- createObservationMask,
1467
- createResponsesInputObservationMask,
1468
- truncateContextResultMessages,
1469
- truncateResponsesInputResultItems,
1470
- } = await import("../context-masker.js");
1471
- const prefs = loadEffectiveGSDPreferences();
1472
- const cmConfig = prefs?.preferences.context_management;
1473
-
1474
- // Observation masking: replace old tool results with placeholders.
1475
- // Only active during auto-mode when context_management.observation_masking is enabled.
1476
- if (isAutoActive() && cmConfig?.observation_masking !== false) {
1477
- const keepTurns = cmConfig?.observation_mask_turns ?? 8;
1478
- const messages = payload.messages;
1479
- if (Array.isArray(messages)) {
1480
- payload.messages = createObservationMask(keepTurns)(messages);
1481
- }
1482
- const input = payload.input;
1483
- if (Array.isArray(input)) {
1484
- payload.input = createResponsesInputObservationMask(keepTurns)(input);
1485
- }
1486
- }
1487
-
1488
- // Tool result truncation: cap individual tool result content length.
1489
- // Applies in ALL modes (auto + interactive) to prevent context bloat.
1490
- // In pi-ai format, toolResult messages have role: "toolResult" and content: TextContent[].
1491
- // Creates new objects to avoid mutating shared conversation state.
1492
- const maxChars = cmConfig?.tool_result_max_chars ?? 800;
1493
- const msgs = payload.messages;
1494
- if (Array.isArray(msgs)) {
1495
- payload.messages = truncateContextResultMessages(msgs as any, maxChars);
1496
- }
1497
- const input = payload.input;
1498
- if (Array.isArray(input)) {
1499
- payload.input = truncateResponsesInputResultItems(input as any, maxChars);
1500
- }
1501
- } catch { /* non-fatal */ }
1502
-
1503
- try {
1504
- if (isAutoActive()) {
1505
- const sourceContextBlock = getSourceObservationStore().renderActiveBlock();
1506
- if (sourceContextBlock) {
1507
- const nextPayload = injectSourceContextBlockIntoPayload(payload, sourceContextBlock);
1508
- Object.assign(payload, nextPayload);
1509
- }
1510
- }
1511
- } catch { /* non-fatal */ }
1512
-
1513
- // ── Service Tier ────────────────────────────────────────────────────
1514
- const modelId = event.model?.id;
1515
- if (!modelId) return payload;
1516
- const { getEffectiveServiceTier, supportsServiceTier } = await import("../service-tier.js");
1517
- const tier = getEffectiveServiceTier();
1518
- if (!tier || !supportsServiceTier(modelId)) return payload;
1519
- payload.service_tier = tier;
1520
- return payload;
1463
+ return applyProviderPayloadPolicy({
1464
+ payload,
1465
+ modelId: event.model?.id,
1466
+ });
1521
1467
  });
1522
1468
 
1523
1469
  // Capability-aware model routing hook (ADR-004)
@@ -1559,25 +1505,44 @@ export function registerHooks(
1559
1505
  event.selectedModelProvider,
1560
1506
  ).compatible.filter((name) => !(dropAliases && isWorkflowAliasTool(name)));
1561
1507
  const guidedUnit = getGuidedUnitContext();
1508
+ const requestRegisteredToolNames = guidedUnit?.unitType === "run-uat"
1509
+ ? compatibleRegisteredToolNames
1510
+ : registeredToolNames;
1562
1511
  const requestScoped = buildRequestScopedGsdToolSet(
1563
1512
  guidedUnit?.unitType === "run-uat" ? aliasFilteredCompatible : providerCompatible,
1564
1513
  event.requestCustomMessages,
1565
- guidedUnit?.unitType === "run-uat" ? compatibleRegisteredToolNames : registeredToolNames,
1514
+ requestRegisteredToolNames,
1566
1515
  guidedUnit?.unitType,
1567
1516
  );
1568
1517
  if (requestScoped) {
1518
+ recordAutoToolSurfaceSnapshot({
1519
+ source: "provider-adjustment",
1520
+ unitType: guidedUnit?.unitType,
1521
+ modelFacingToolNames: requestScoped,
1522
+ registeredToolNames: requestRegisteredToolNames,
1523
+ scopedToolNames: requestScoped,
1524
+ });
1569
1525
  return { toolNames: requestScoped };
1570
1526
  }
1571
1527
  const dash = getAutoRuntimeSnapshot();
1572
1528
  if (dash.active && dash.currentUnit) {
1529
+ const registeredForUnit = dash.currentUnit.type === "run-uat"
1530
+ ? compatibleRegisteredToolNames
1531
+ : resolveRegisteredToolNames(pi, event.activeToolNames);
1532
+ const scopedToolNames = buildMinimalAutoGsdToolSet(
1533
+ dash.currentUnit.type === "run-uat" ? aliasFilteredCompatible : providerCompatible,
1534
+ dash.currentUnit.type,
1535
+ registeredForUnit,
1536
+ );
1537
+ recordAutoToolSurfaceSnapshot({
1538
+ source: "provider-adjustment",
1539
+ unitType: dash.currentUnit.type,
1540
+ modelFacingToolNames: scopedToolNames,
1541
+ registeredToolNames: registeredForUnit,
1542
+ scopedToolNames,
1543
+ });
1573
1544
  return {
1574
- toolNames: buildMinimalAutoGsdToolSet(
1575
- dash.currentUnit.type === "run-uat" ? aliasFilteredCompatible : providerCompatible,
1576
- dash.currentUnit.type,
1577
- dash.currentUnit.type === "run-uat"
1578
- ? compatibleRegisteredToolNames
1579
- : resolveRegisteredToolNames(pi, event.activeToolNames),
1580
- ),
1545
+ toolNames: scopedToolNames,
1581
1546
  };
1582
1547
  }
1583
1548
  if (isGeneralGsdToolScopingRequested()) {
@@ -5,6 +5,7 @@ import { isAbsolute, join, relative, resolve, sep } from "node:path";
5
5
  import { minimatch } from "minimatch";
6
6
 
7
7
  import { GSD_PHASE_SCOPE_DISPLAY_REASON, shouldBlockAutoUnitToolCall } from "../auto-unit-tool-scope.js";
8
+ import { stripMcpToolPrefix } from "../mcp-tool-name.js";
8
9
  import { getIsolationMode } from "../preferences.js";
9
10
  import { compileSubagentPermissionContract, type ToolsPolicy } from "../unit-context-manifest.js";
10
11
  import { logWarning } from "../workflow-logger.js";
@@ -123,9 +124,7 @@ const GATE_SAFE_TOOLS = new Set([
123
124
  ]);
124
125
 
125
126
  export function canonicalToolName(toolName: string): string {
126
- if (!toolName.startsWith("mcp__")) return toolName;
127
- const toolSeparator = toolName.indexOf("__", "mcp__".length);
128
- return toolSeparator >= 0 ? toolName.slice(toolSeparator + 2) : toolName;
127
+ return stripMcpToolPrefix(toolName);
129
128
  }
130
129
 
131
130
  export interface WriteGateSnapshot {
@@ -462,6 +461,111 @@ export function isDepthConfirmationAnswer(
462
461
  return false;
463
462
  }
464
463
 
464
+ export interface AskUserQuestionsGateQuestion {
465
+ id?: unknown;
466
+ options?: Array<{ label?: string }>;
467
+ }
468
+
469
+ export interface AskUserQuestionsGateDetails {
470
+ cancelled?: boolean;
471
+ interrupted?: boolean;
472
+ response?: {
473
+ answers?: Record<string, { selected?: unknown } | undefined>;
474
+ } | null;
475
+ }
476
+
477
+ export type AskUserQuestionsGateResult =
478
+ | { status: "not-gate" }
479
+ | { status: "waiting"; pendingGateId: string; interrupted: boolean }
480
+ | { status: "verified"; gateId: string; milestoneId: string | null }
481
+ | { status: "answered"; gateId: string };
482
+
483
+ function findGateQuestion(
484
+ questions: AskUserQuestionsGateQuestion[],
485
+ gateId: string,
486
+ ): AskUserQuestionsGateQuestion | undefined {
487
+ return questions.find((question) => question?.id === gateId);
488
+ }
489
+
490
+ function readSelectedGateAnswer(
491
+ details: AskUserQuestionsGateDetails,
492
+ questionId: string,
493
+ ): unknown {
494
+ return details.response?.answers?.[questionId]?.selected;
495
+ }
496
+
497
+ function verifyAnsweredGate(
498
+ basePath: string,
499
+ question: AskUserQuestionsGateQuestion,
500
+ fallbackMilestoneId?: string | null,
501
+ ): AskUserQuestionsGateResult {
502
+ const gateId = typeof question.id === "string" ? question.id : "";
503
+ const milestoneId = extractDepthVerificationMilestoneId(gateId) ?? fallbackMilestoneId ?? null;
504
+ markApprovalGateVerified(gateId, basePath);
505
+ markDepthVerified(milestoneId, basePath);
506
+ clearPendingGate(basePath);
507
+ return { status: "verified", gateId, milestoneId };
508
+ }
509
+
510
+ export function applyAskUserQuestionsGateResult(options: {
511
+ basePath: string;
512
+ questions: AskUserQuestionsGateQuestion[];
513
+ details: AskUserQuestionsGateDetails;
514
+ fallbackMilestoneId?: string | null;
515
+ }): AskUserQuestionsGateResult {
516
+ const { basePath, questions, details, fallbackMilestoneId } = options;
517
+ const currentPendingGate = getPendingGate(basePath);
518
+ if (currentPendingGate) {
519
+ if (details.cancelled || !details.response) {
520
+ return {
521
+ status: "waiting",
522
+ pendingGateId: currentPendingGate,
523
+ interrupted: details.interrupted === true,
524
+ };
525
+ }
526
+
527
+ const pendingQuestion = findGateQuestion(questions, currentPendingGate);
528
+ if (pendingQuestion) {
529
+ const selected = readSelectedGateAnswer(details, currentPendingGate);
530
+ if (isDepthConfirmationAnswer(selected, pendingQuestion.options)) {
531
+ return verifyAnsweredGate(basePath, pendingQuestion, fallbackMilestoneId);
532
+ }
533
+ return { status: "answered", gateId: currentPendingGate };
534
+ }
535
+ }
536
+
537
+ if (details.cancelled || !details.response) return { status: "not-gate" };
538
+
539
+ for (const question of questions) {
540
+ if (typeof question.id !== "string" || !isGateQuestionId(question.id)) continue;
541
+ const selected = readSelectedGateAnswer(details, question.id);
542
+ if (!isDepthConfirmationAnswer(selected, question.options)) {
543
+ return { status: "answered", gateId: question.id };
544
+ }
545
+ if (currentPendingGate && question.id !== currentPendingGate) {
546
+ return { status: "answered", gateId: currentPendingGate };
547
+ }
548
+ return verifyAnsweredGate(basePath, question, fallbackMilestoneId);
549
+ }
550
+
551
+ return { status: "not-gate" };
552
+ }
553
+
554
+ export function formatPendingAskUserQuestionsGateMessage(
555
+ pendingGateId: string,
556
+ interrupted: boolean,
557
+ ): string {
558
+ return [
559
+ `Waiting for depth confirmation on gate "${pendingGateId}".`,
560
+ interrupted
561
+ ? "The confirmation question was interrupted before a response was recorded."
562
+ : "No user response was received for the confirmation question.",
563
+ "Do not infer approval from earlier or prior messages.",
564
+ "Do not proceed, write files, save artifacts, or call other tools.",
565
+ `Re-call ask_user_questions with the same gate question id ("${pendingGateId}") and wait for the user's response.`,
566
+ ].join(" ");
567
+ }
568
+
465
569
  export function shouldBlockContextWrite(
466
570
  toolName: string,
467
571
  inputPath: string,