@opengsd/gsd-pi 1.1.1-dev.616a1a1 → 1.1.1-dev.9bb7453

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 (395) hide show
  1. package/dist/cli.js +3 -2
  2. package/dist/help-text.js +10 -6
  3. package/dist/resources/.managed-resources-content-hash +1 -1
  4. package/dist/resources/extensions/browser-tools/engine/managed-gsd-browser.js +495 -0
  5. package/dist/resources/extensions/browser-tools/engine/selection.js +16 -0
  6. package/dist/resources/extensions/browser-tools/extension-manifest.json +2 -2
  7. package/dist/resources/extensions/browser-tools/index.js +57 -9
  8. package/dist/resources/extensions/browser-tools/package.json +5 -1
  9. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +167 -16
  10. package/dist/resources/extensions/gsd/auto/orchestrator.js +0 -1
  11. package/dist/resources/extensions/gsd/auto/phases.js +4 -3
  12. package/dist/resources/extensions/gsd/auto-dashboard.js +92 -17
  13. package/dist/resources/extensions/gsd/auto-dispatch.js +44 -0
  14. package/dist/resources/extensions/gsd/auto-post-unit.js +134 -10
  15. package/dist/resources/extensions/gsd/auto-prompts.js +68 -22
  16. package/dist/resources/extensions/gsd/auto-recovery.js +4 -4
  17. package/dist/resources/extensions/gsd/auto-runtime-state.js +3 -0
  18. package/dist/resources/extensions/gsd/auto-start.js +94 -15
  19. package/dist/resources/extensions/gsd/auto-tool-tracking.js +1 -1
  20. package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +2 -1
  21. package/dist/resources/extensions/gsd/auto.js +31 -6
  22. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +83 -4
  23. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +43 -0
  24. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +39 -14
  25. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +16 -10
  26. package/dist/resources/extensions/gsd/browser-evidence.js +29 -2
  27. package/dist/resources/extensions/gsd/commands/catalog.js +6 -1
  28. package/dist/resources/extensions/gsd/commands/handlers/core.js +6 -2
  29. package/dist/resources/extensions/gsd/commands/handlers/ops.js +9 -5
  30. package/dist/resources/extensions/gsd/commands-handlers.js +76 -11
  31. package/dist/resources/extensions/gsd/commands-maintenance.js +172 -2
  32. package/dist/resources/extensions/gsd/commands-mcp-status.js +109 -60
  33. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +3 -1
  34. package/dist/resources/extensions/gsd/commands-verdict.js +1 -1
  35. package/dist/resources/extensions/gsd/config-overlay.js +2 -1
  36. package/dist/resources/extensions/gsd/dashboard-overlay.js +21 -7
  37. package/dist/resources/extensions/gsd/docs/preferences-reference.md +8 -0
  38. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +2 -2
  39. package/dist/resources/extensions/gsd/error-classifier.js +2 -1
  40. package/dist/resources/extensions/gsd/escalation.js +4 -4
  41. package/dist/resources/extensions/gsd/exec-sandbox.js +2 -0
  42. package/dist/resources/extensions/gsd/forensics.js +74 -2
  43. package/dist/resources/extensions/gsd/gsd-db.js +42 -6
  44. package/dist/resources/extensions/gsd/guided-flow.js +30 -69
  45. package/dist/resources/extensions/gsd/mcp-filter.js +3 -0
  46. package/dist/resources/extensions/gsd/mcp-project-config.js +76 -84
  47. package/dist/resources/extensions/gsd/memory-store.js +4 -1
  48. package/dist/resources/extensions/gsd/migration-auto-check.js +2 -2
  49. package/dist/resources/extensions/gsd/post-unit-hooks.js +9 -0
  50. package/dist/resources/extensions/gsd/preferences-validation.js +39 -0
  51. package/dist/resources/extensions/gsd/prompt-loader.js +7 -0
  52. package/dist/resources/extensions/gsd/prompts/forensics.md +61 -1
  53. package/dist/resources/extensions/gsd/prompts/gate-evaluate.md +3 -1
  54. package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +3 -1
  55. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  56. package/dist/resources/extensions/gsd/prompts/reactive-execute.md +3 -1
  57. package/dist/resources/extensions/gsd/prompts/run-uat.md +48 -24
  58. package/dist/resources/extensions/gsd/prompts/system.md +3 -1
  59. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +3 -3
  60. package/dist/resources/extensions/gsd/rule-registry.js +428 -52
  61. package/dist/resources/extensions/gsd/safety/destructive-guard.js +3 -0
  62. package/dist/resources/extensions/gsd/skill-activation.js +20 -3
  63. package/dist/resources/extensions/gsd/state-reconciliation/drift/artifact-db.js +4 -2
  64. package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +1 -1
  65. package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +18 -1
  66. package/dist/resources/extensions/gsd/state-reconciliation/index.js +6 -0
  67. package/dist/resources/extensions/gsd/state.js +17 -14
  68. package/dist/resources/extensions/gsd/templates/plan.md +3 -1
  69. package/dist/resources/extensions/gsd/tool-presentation-plan.js +120 -0
  70. package/dist/resources/extensions/gsd/tools/complete-slice.js +15 -1
  71. package/dist/resources/extensions/gsd/tools/complete-task.js +11 -1
  72. package/dist/resources/extensions/gsd/tools/exec-tool.js +109 -0
  73. package/dist/resources/extensions/gsd/tools/plan-slice.js +14 -9
  74. package/dist/resources/extensions/gsd/tools/reopen-milestone.js +2 -2
  75. package/dist/resources/extensions/gsd/tools/validate-milestone.js +46 -16
  76. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +403 -3
  77. package/dist/resources/extensions/gsd/unit-context-manifest.js +8 -3
  78. package/dist/resources/extensions/gsd/validation-block-guard.js +2 -0
  79. package/dist/resources/extensions/gsd/verdict-parser.js +59 -15
  80. package/dist/resources/extensions/gsd/verification-gate.js +72 -1
  81. package/dist/resources/extensions/gsd/workflow-mcp-auto-prep.js +3 -1
  82. package/dist/resources/extensions/gsd/workflow-mcp.js +5 -1
  83. package/dist/resources/extensions/gsd/worktree-lifecycle.js +24 -0
  84. package/dist/resources/extensions/mcp-client/manager.js +31 -1
  85. package/dist/resources/extensions/shared/gsd-browser-cli.js +145 -0
  86. package/dist/rtk.d.ts +7 -1
  87. package/dist/rtk.js +27 -11
  88. package/dist/update-check.d.ts +15 -1
  89. package/dist/update-check.js +87 -12
  90. package/dist/update-cmd.d.ts +1 -0
  91. package/dist/update-cmd.js +53 -2
  92. package/dist/web/standalone/.next/BUILD_ID +1 -1
  93. package/dist/web/standalone/.next/app-path-routes-manifest.json +6 -6
  94. package/dist/web/standalone/.next/build-manifest.json +2 -2
  95. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  96. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  97. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  98. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  99. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  100. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  101. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  102. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  103. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  104. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  105. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  106. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  107. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  108. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  109. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  110. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  111. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  112. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  113. package/dist/web/standalone/.next/server/app/index.html +1 -1
  114. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  115. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  116. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  117. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  118. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  119. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  120. package/dist/web/standalone/.next/server/app-paths-manifest.json +6 -6
  121. package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
  122. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  123. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  124. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  125. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  126. package/package.json +5 -3
  127. package/packages/cloud-mcp-gateway/package.json +2 -2
  128. package/packages/contracts/dist/workflow.d.ts +14 -0
  129. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  130. package/packages/contracts/dist/workflow.js +16 -0
  131. package/packages/contracts/dist/workflow.js.map +1 -1
  132. package/packages/contracts/package.json +1 -1
  133. package/packages/daemon/package.json +4 -4
  134. package/packages/gsd-agent-core/dist/agent-session.d.ts +9 -0
  135. package/packages/gsd-agent-core/dist/agent-session.d.ts.map +1 -1
  136. package/packages/gsd-agent-core/dist/agent-session.js +32 -0
  137. package/packages/gsd-agent-core/dist/agent-session.js.map +1 -1
  138. package/packages/gsd-agent-core/dist/index.d.ts +1 -0
  139. package/packages/gsd-agent-core/dist/index.d.ts.map +1 -1
  140. package/packages/gsd-agent-core/dist/index.js +1 -0
  141. package/packages/gsd-agent-core/dist/index.js.map +1 -1
  142. package/packages/gsd-agent-core/dist/session/agent-session-compaction.d.ts +2 -0
  143. package/packages/gsd-agent-core/dist/session/agent-session-compaction.d.ts.map +1 -1
  144. package/packages/gsd-agent-core/dist/session/agent-session-compaction.js +8 -2
  145. package/packages/gsd-agent-core/dist/session/agent-session-compaction.js.map +1 -1
  146. package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts +7 -0
  147. package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts.map +1 -1
  148. package/packages/gsd-agent-core/dist/session/agent-session-host.js.map +1 -1
  149. package/packages/gsd-agent-core/dist/session/agent-session-prompt.d.ts.map +1 -1
  150. package/packages/gsd-agent-core/dist/session/agent-session-prompt.js +69 -1
  151. package/packages/gsd-agent-core/dist/session/agent-session-prompt.js.map +1 -1
  152. package/packages/gsd-agent-core/dist/turn-latency.d.ts +47 -0
  153. package/packages/gsd-agent-core/dist/turn-latency.d.ts.map +1 -0
  154. package/packages/gsd-agent-core/dist/turn-latency.js +123 -0
  155. package/packages/gsd-agent-core/dist/turn-latency.js.map +1 -0
  156. package/packages/gsd-agent-core/package.json +6 -6
  157. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.d.ts +21 -0
  158. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.d.ts.map +1 -0
  159. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.js +213 -0
  160. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.js.map +1 -0
  161. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts +2 -0
  162. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  163. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js +10 -0
  164. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js.map +1 -1
  165. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts +1 -0
  166. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  167. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +92 -31
  168. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  169. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
  170. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js +7 -1
  171. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  172. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-command-handlers.d.ts.map +1 -1
  173. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-command-handlers.js +6 -0
  174. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-command-handlers.js.map +1 -1
  175. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-dialogs.d.ts.map +1 -1
  176. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-dialogs.js +2 -0
  177. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-dialogs.js.map +1 -1
  178. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.d.ts +1 -1
  179. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.d.ts.map +1 -1
  180. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.js +1 -1
  181. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.js.map +1 -1
  182. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  183. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +1 -0
  184. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
  185. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.d.ts.map +1 -1
  186. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js +5 -0
  187. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js.map +1 -1
  188. package/packages/gsd-agent-modes/package.json +7 -7
  189. package/packages/mcp-server/dist/remote-questions.d.ts.map +1 -1
  190. package/packages/mcp-server/dist/remote-questions.js +23 -9
  191. package/packages/mcp-server/dist/remote-questions.js.map +1 -1
  192. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  193. package/packages/mcp-server/dist/workflow-tools.js +84 -2
  194. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  195. package/packages/mcp-server/package.json +3 -3
  196. package/packages/native/package.json +1 -1
  197. package/packages/pi-agent-core/dist/agent-loop.js +38 -0
  198. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  199. package/packages/pi-agent-core/dist/agent.d.ts +5 -1
  200. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  201. package/packages/pi-agent-core/dist/agent.js +2 -0
  202. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  203. package/packages/pi-agent-core/dist/types.d.ts +3 -0
  204. package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
  205. package/packages/pi-agent-core/dist/types.js.map +1 -1
  206. package/packages/pi-agent-core/package.json +1 -1
  207. package/packages/pi-ai/dist/api-registry.d.ts +2 -0
  208. package/packages/pi-ai/dist/api-registry.d.ts.map +1 -1
  209. package/packages/pi-ai/dist/api-registry.js +23 -0
  210. package/packages/pi-ai/dist/api-registry.js.map +1 -1
  211. package/packages/pi-ai/dist/image-models.generated.d.ts +15 -0
  212. package/packages/pi-ai/dist/image-models.generated.d.ts.map +1 -1
  213. package/packages/pi-ai/dist/image-models.generated.js +15 -0
  214. package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
  215. package/packages/pi-ai/dist/models.generated.d.ts +406 -17
  216. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  217. package/packages/pi-ai/dist/models.generated.js +484 -116
  218. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  219. package/packages/pi-ai/dist/stream.js +6 -6
  220. package/packages/pi-ai/dist/stream.js.map +1 -1
  221. package/packages/pi-ai/package.json +1 -1
  222. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  223. package/packages/pi-coding-agent/dist/core/model-registry.js +2 -2
  224. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  225. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +3 -0
  226. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  227. package/packages/pi-coding-agent/dist/core/settings-manager.js +11 -0
  228. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  229. package/packages/pi-coding-agent/package.json +7 -7
  230. package/packages/pi-tui/dist/terminal.d.ts +1 -0
  231. package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
  232. package/packages/pi-tui/dist/terminal.js +8 -4
  233. package/packages/pi-tui/dist/terminal.js.map +1 -1
  234. package/packages/pi-tui/package.json +1 -1
  235. package/packages/rpc-client/package.json +2 -2
  236. package/pkg/package.json +1 -1
  237. package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +579 -0
  238. package/src/resources/extensions/browser-tools/engine/selection.ts +19 -0
  239. package/src/resources/extensions/browser-tools/extension-manifest.json +2 -2
  240. package/src/resources/extensions/browser-tools/index.ts +60 -9
  241. package/src/resources/extensions/browser-tools/package.json +5 -1
  242. package/src/resources/extensions/browser-tools/tests/browser-engine-selection.test.mjs +35 -0
  243. package/src/resources/extensions/browser-tools/tests/managed-gsd-browser-tools.test.mjs +33 -0
  244. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +196 -16
  245. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +239 -63
  246. package/src/resources/extensions/gsd/auto/orchestrator.ts +0 -1
  247. package/src/resources/extensions/gsd/auto/phases.ts +5 -3
  248. package/src/resources/extensions/gsd/auto-dashboard.ts +98 -18
  249. package/src/resources/extensions/gsd/auto-dispatch.ts +53 -0
  250. package/src/resources/extensions/gsd/auto-post-unit.ts +166 -9
  251. package/src/resources/extensions/gsd/auto-prompts.ts +102 -15
  252. package/src/resources/extensions/gsd/auto-recovery.ts +4 -4
  253. package/src/resources/extensions/gsd/auto-runtime-state.ts +4 -0
  254. package/src/resources/extensions/gsd/auto-start.ts +112 -17
  255. package/src/resources/extensions/gsd/auto-tool-tracking.ts +1 -1
  256. package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +2 -1
  257. package/src/resources/extensions/gsd/auto.ts +47 -5
  258. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +90 -4
  259. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +51 -0
  260. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +60 -19
  261. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +21 -10
  262. package/src/resources/extensions/gsd/browser-evidence.ts +26 -2
  263. package/src/resources/extensions/gsd/commands/catalog.ts +6 -1
  264. package/src/resources/extensions/gsd/commands/handlers/core.ts +6 -2
  265. package/src/resources/extensions/gsd/commands/handlers/ops.ts +9 -5
  266. package/src/resources/extensions/gsd/commands-handlers.ts +76 -11
  267. package/src/resources/extensions/gsd/commands-maintenance.ts +197 -2
  268. package/src/resources/extensions/gsd/commands-mcp-status.ts +136 -58
  269. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +4 -1
  270. package/src/resources/extensions/gsd/commands-verdict.ts +1 -1
  271. package/src/resources/extensions/gsd/config-overlay.ts +3 -1
  272. package/src/resources/extensions/gsd/dashboard-overlay.ts +28 -7
  273. package/src/resources/extensions/gsd/docs/preferences-reference.md +8 -0
  274. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +2 -2
  275. package/src/resources/extensions/gsd/error-classifier.ts +2 -1
  276. package/src/resources/extensions/gsd/escalation.ts +4 -4
  277. package/src/resources/extensions/gsd/exec-sandbox.ts +4 -0
  278. package/src/resources/extensions/gsd/forensics.ts +99 -5
  279. package/src/resources/extensions/gsd/gsd-db.ts +46 -8
  280. package/src/resources/extensions/gsd/guided-flow.ts +91 -83
  281. package/src/resources/extensions/gsd/mcp-filter.ts +3 -0
  282. package/src/resources/extensions/gsd/mcp-project-config.ts +105 -88
  283. package/src/resources/extensions/gsd/memory-store.ts +4 -1
  284. package/src/resources/extensions/gsd/migration-auto-check.ts +2 -2
  285. package/src/resources/extensions/gsd/post-unit-hooks.ts +14 -1
  286. package/src/resources/extensions/gsd/preferences-types.ts +1 -1
  287. package/src/resources/extensions/gsd/preferences-validation.ts +36 -0
  288. package/src/resources/extensions/gsd/prompt-loader.ts +8 -0
  289. package/src/resources/extensions/gsd/prompts/forensics.md +61 -1
  290. package/src/resources/extensions/gsd/prompts/gate-evaluate.md +3 -1
  291. package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +3 -1
  292. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  293. package/src/resources/extensions/gsd/prompts/reactive-execute.md +3 -1
  294. package/src/resources/extensions/gsd/prompts/run-uat.md +48 -24
  295. package/src/resources/extensions/gsd/prompts/system.md +3 -1
  296. package/src/resources/extensions/gsd/prompts/validate-milestone.md +3 -3
  297. package/src/resources/extensions/gsd/rule-registry.ts +558 -58
  298. package/src/resources/extensions/gsd/rule-types.ts +2 -0
  299. package/src/resources/extensions/gsd/safety/destructive-guard.ts +3 -0
  300. package/src/resources/extensions/gsd/skill-activation.ts +20 -2
  301. package/src/resources/extensions/gsd/state-reconciliation/drift/artifact-db.ts +4 -2
  302. package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +1 -1
  303. package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +20 -0
  304. package/src/resources/extensions/gsd/state-reconciliation/index.ts +6 -0
  305. package/src/resources/extensions/gsd/state-reconciliation/types.ts +1 -0
  306. package/src/resources/extensions/gsd/state.ts +18 -14
  307. package/src/resources/extensions/gsd/templates/plan.md +3 -1
  308. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +156 -4
  309. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +123 -0
  310. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +143 -2
  311. package/src/resources/extensions/gsd/tests/auto-start-project-milestone-reconcile.test.ts +24 -2
  312. package/src/resources/extensions/gsd/tests/browser-evidence.test.ts +142 -0
  313. package/src/resources/extensions/gsd/tests/commands-dispatcher-validation-block.test.ts +38 -3
  314. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +6 -2
  315. package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +30 -0
  316. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +42 -0
  317. package/src/resources/extensions/gsd/tests/dashboard-overlay.test.ts +45 -0
  318. package/src/resources/extensions/gsd/tests/deep-planning-mode-dispatch.test.ts +53 -0
  319. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +8 -0
  320. package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +50 -13
  321. package/src/resources/extensions/gsd/tests/discuss-milestone-structured-questions.test.ts +31 -0
  322. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +60 -0
  323. package/src/resources/extensions/gsd/tests/doctor-runtime-checks.test.ts +27 -0
  324. package/src/resources/extensions/gsd/tests/escalation.test.ts +16 -27
  325. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +18 -0
  326. package/src/resources/extensions/gsd/tests/exec-tool.test.ts +69 -0
  327. package/src/resources/extensions/gsd/tests/forensics-issue-routing.test.ts +20 -0
  328. package/src/resources/extensions/gsd/tests/forensics-prompt-rendering.test.ts +3 -0
  329. package/src/resources/extensions/gsd/tests/forensics-tool-scope.test.ts +69 -0
  330. package/src/resources/extensions/gsd/tests/gsd-rebuild.test.ts +199 -0
  331. package/src/resources/extensions/gsd/tests/gsd-recover.test.ts +75 -0
  332. package/src/resources/extensions/gsd/tests/guided-discuss-milestone-prompt-rendering.test.ts +40 -1
  333. package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +86 -0
  334. package/src/resources/extensions/gsd/tests/guided-flow.test.ts +12 -9
  335. package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +4 -4
  336. package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +66 -10
  337. package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +13 -6
  338. package/src/resources/extensions/gsd/tests/mcp-filter.test.ts +15 -0
  339. package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +100 -0
  340. package/src/resources/extensions/gsd/tests/mcp-status.test.ts +179 -0
  341. package/src/resources/extensions/gsd/tests/memory-maintenance.test.ts +39 -8
  342. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +3 -3
  343. package/src/resources/extensions/gsd/tests/new-milestone-discuss-routing.test.ts +3 -3
  344. package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +54 -7
  345. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +9 -0
  346. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +39 -1
  347. package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +157 -0
  348. package/src/resources/extensions/gsd/tests/post-unit-retry-on-orchestrator-bridge.test.ts +179 -0
  349. package/src/resources/extensions/gsd/tests/preferences.test.ts +29 -0
  350. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +53 -1
  351. package/src/resources/extensions/gsd/tests/prompt-loader-extension-dir.test.ts +14 -0
  352. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +18 -1
  353. package/src/resources/extensions/gsd/tests/queued-discuss-fast-path.test.ts +7 -8
  354. package/src/resources/extensions/gsd/tests/reactive-executor.test.ts +36 -0
  355. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +35 -0
  356. package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +1 -1
  357. package/src/resources/extensions/gsd/tests/rule-registry.test.ts +75 -0
  358. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +100 -0
  359. package/src/resources/extensions/gsd/tests/skill-activation.test.ts +55 -0
  360. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +6 -2
  361. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +191 -0
  362. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +84 -10
  363. package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +19 -0
  364. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +12 -2
  365. package/src/resources/extensions/gsd/tests/tool-param-optionality.test.ts +7 -1
  366. package/src/resources/extensions/gsd/tests/tui-header-lifecycle.test.ts +29 -6
  367. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +29 -6
  368. package/src/resources/extensions/gsd/tests/validate-milestone-prompt-verification-classes.test.ts +6 -3
  369. package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +133 -0
  370. package/src/resources/extensions/gsd/tests/validation-block-guard.test.ts +21 -0
  371. package/src/resources/extensions/gsd/tests/verification-gate.test.ts +51 -0
  372. package/src/resources/extensions/gsd/tests/workflow-mcp-auto-prep.test.ts +17 -2
  373. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +213 -0
  374. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +25 -0
  375. package/src/resources/extensions/gsd/tool-presentation-plan.ts +167 -0
  376. package/src/resources/extensions/gsd/tools/complete-slice.ts +14 -1
  377. package/src/resources/extensions/gsd/tools/complete-task.ts +20 -2
  378. package/src/resources/extensions/gsd/tools/exec-tool.ts +130 -0
  379. package/src/resources/extensions/gsd/tools/plan-slice.ts +14 -9
  380. package/src/resources/extensions/gsd/tools/reopen-milestone.ts +2 -2
  381. package/src/resources/extensions/gsd/tools/validate-milestone.ts +46 -15
  382. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +489 -3
  383. package/src/resources/extensions/gsd/types.ts +69 -5
  384. package/src/resources/extensions/gsd/unit-context-manifest.ts +14 -5
  385. package/src/resources/extensions/gsd/validation-block-guard.ts +2 -0
  386. package/src/resources/extensions/gsd/verdict-parser.ts +54 -13
  387. package/src/resources/extensions/gsd/verification-gate.ts +87 -1
  388. package/src/resources/extensions/gsd/workflow-mcp-auto-prep.ts +2 -1
  389. package/src/resources/extensions/gsd/workflow-mcp.ts +5 -1
  390. package/src/resources/extensions/gsd/worktree-lifecycle.ts +26 -0
  391. package/src/resources/extensions/mcp-client/manager.ts +33 -1
  392. package/src/resources/extensions/mcp-client/tests/manager.test.ts +35 -0
  393. package/src/resources/extensions/shared/gsd-browser-cli.ts +172 -0
  394. /package/dist/web/standalone/.next/static/{L9N5SPFi7f-Ne4u2uXzCe → jBtwT9v1u2lUA3UEOy_ZH}/_buildManifest.js +0 -0
  395. /package/dist/web/standalone/.next/static/{L9N5SPFi7f-Ne4u2uXzCe → jBtwT9v1u2lUA3UEOy_ZH}/_ssgManifest.js +0 -0
@@ -17,7 +17,7 @@ import { canonicalToolName, clearDiscussionFlowState, isDepthConfirmationAnswer,
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";
20
- import { clearToolInvocationError, getAutoRuntimeSnapshot, isAutoActive, isAutoPaused, markToolEnd, markToolStart, recordToolInvocationError } from "../auto-runtime-state.js";
20
+ import { clearToolInvocationError, getAutoRuntimeSnapshot, isAutoActive, isAutoCompletionStopInProgress, isAutoPaused, markToolEnd, markToolStart, recordToolInvocationError } from "../auto-runtime-state.js";
21
21
 
22
22
  import { checkToolCallLoop, resetToolCallLoopGuard } from "./tool-call-loop-guard.js";
23
23
  import { maybePauseAutoForApprovalGate, resetPendingGatePauseGuard } from "./pending-gate-pause.js";
@@ -36,7 +36,9 @@ import { resolveSkillManifest } from "../skill-manifest.js";
36
36
  import { applyUnitSkillVisibility, unitHasSkillManifest } from "../skill-scope.js";
37
37
  import { getGuidedUnitContext } from "../guided-unit-context.js";
38
38
  import { registerPlanMilestoneSchemaRecovery } from "./plan-milestone-schema-recovery.js";
39
- import { AUTO_UNIT_SCOPED_TOOLS, isWorkflowAliasTool } from "../auto-unit-tool-scope.js";
39
+ import { AUTO_UNIT_SCOPED_TOOLS, RUN_UAT_BROWSER_TOOL_NAMES, isWorkflowAliasTool } from "../auto-unit-tool-scope.js";
40
+ import { filterToolsForProvider } from "../model-router.js";
41
+ import { RUN_UAT_WORKFLOW_TOOL_NAMES } from "../tool-presentation-plan.js";
40
42
 
41
43
  let approvalQuestionAbortInFlight = false;
42
44
 
@@ -123,6 +125,7 @@ export const MINIMAL_GSD_TOOL_NAMES = [
123
125
  "gsd_resume",
124
126
  "gsd_milestone_status",
125
127
  "gsd_checkpoint_db",
128
+ "gsd_plan_milestone",
126
129
  "memory_query",
127
130
  "capture_thought",
128
131
  ] as const;
@@ -226,6 +229,9 @@ export function buildMinimalAutoGsdToolSet(
226
229
  unitType: string | undefined,
227
230
  registeredToolNames: readonly string[] = activeToolNames,
228
231
  ): string[] {
232
+ if (unitType === "run-uat") {
233
+ return buildRunUatGsdToolSet(activeToolNames, registeredToolNames);
234
+ }
229
235
  const unitTools = unitType ? AUTO_UNIT_SCOPED_TOOLS[unitType] ?? [] : [];
230
236
  const autoBaseTools = new Set<string>(MINIMAL_AUTO_BASE_TOOL_NAMES);
231
237
  const availableBaseTools = registeredToolNames.filter((name) => autoBaseTools.has(name));
@@ -240,6 +246,17 @@ export function buildMinimalAutoGsdToolSet(
240
246
  return withPreservedShimTools([...new Set([...preserved, ...scoped])]);
241
247
  }
242
248
 
249
+ export function buildRunUatGsdToolSet(
250
+ activeToolNames: readonly string[],
251
+ registeredToolNames: readonly string[] = activeToolNames,
252
+ ): string[] {
253
+ const scoped = resolveScopedToolNames(
254
+ [...activeToolNames, ...registeredToolNames],
255
+ [...RUN_UAT_WORKFLOW_TOOL_NAMES, "subagent", ...RUN_UAT_BROWSER_TOOL_NAMES],
256
+ );
257
+ return [...new Set(scoped)];
258
+ }
259
+
243
260
  export function buildMinimalGsdWorkflowToolSet(
244
261
  activeToolNames: readonly string[],
245
262
  registeredToolNames: readonly string[] = activeToolNames,
@@ -518,8 +535,9 @@ export function registerHooks(
518
535
 
519
536
  pi.on("session_start", async (_event, ctx) => {
520
537
  const basePath = contextBasePath(ctx);
538
+ const preserveCloseoutSurface = isAutoCompletionStopInProgress();
521
539
  initSessionNotifications(ctx);
522
- if (!isAutoActive()) {
540
+ if (!isAutoActive() && !preserveCloseoutSurface) {
523
541
  const { initHealthWidget } = await import("../health-widget.js");
524
542
  initHealthWidget(ctx);
525
543
  }
@@ -539,15 +557,18 @@ export function registerHooks(
539
557
  const prefs = loadEffectiveGSDPreferences(basePath);
540
558
  process.env.GSD_SHOW_TOKEN_COST = prefs?.preferences.show_token_cost ? "1" : "";
541
559
  } catch { /* non-fatal */ }
542
- await installWelcomeHeader(ctx);
560
+ if (!preserveCloseoutSurface) {
561
+ await installWelcomeHeader(ctx);
562
+ }
543
563
  await loadToolApiKeysForSession();
544
- if (isAutoActive()) {
564
+ if (isAutoActive() || preserveCloseoutSurface) {
545
565
  ctx.ui.setWidget("gsd-health", undefined);
546
566
  }
547
567
  });
548
568
 
549
569
  pi.on("session_switch", async (_event, ctx) => {
550
570
  const basePath = contextBasePath(ctx);
571
+ const preserveCloseoutSurface = isAutoCompletionStopInProgress();
551
572
  initSessionNotifications(ctx);
552
573
  resetWriteGateState(basePath);
553
574
  resetToolCallLoopGuard();
@@ -559,7 +580,7 @@ export function registerHooks(
559
580
  await applyCompactionThresholdOverride(ctx);
560
581
  await prepareWorkflowMcpForHookContext(ctx, basePath);
561
582
  await loadToolApiKeysForSession();
562
- if (!isAutoActive()) {
583
+ if (!isAutoActive() && !preserveCloseoutSurface) {
563
584
  ctx.ui.setWidget("gsd-progress", undefined);
564
585
  ctx.ui.setWidget("gsd-outcome", undefined);
565
586
  const { initHealthWidget } = await import("../health-widget.js");
@@ -1022,9 +1043,8 @@ export function registerHooks(
1022
1043
  if (result.block) return result;
1023
1044
  });
1024
1045
 
1025
- // ── Safety harness: evidence collection + destructive command warnings ──
1046
+ // ── Safety harness: evidence collection + destructive command blocking ──
1026
1047
  pi.on("tool_call", async (event, ctx) => {
1027
- if (!isAutoActive()) return;
1028
1048
  markToolStart(event.toolCallId, event.toolName);
1029
1049
  safetyRecordToolCall(event.toolCallId, event.toolName, event.input as Record<string, unknown>);
1030
1050
 
@@ -1041,17 +1061,28 @@ export function registerHooks(
1041
1061
  }
1042
1062
  }
1043
1063
 
1044
- // Destructive command classification (warn only, never block)
1064
+ // Destructive command classification + hard gate in all modes.
1045
1065
  if (isToolCallEventType("bash", event)) {
1046
1066
  const classification = classifyCommand(event.input.command);
1047
1067
  if (classification.destructive) {
1068
+ const reason = [
1069
+ "HARD BLOCK: destructive Bash command requires explicit human confirmation.",
1070
+ `Detected: ${classification.labels.join(", ")}`,
1071
+ "Run this via ask_user_questions, wait for the user's response,",
1072
+ "then issue the command only when confirmed in the current turn.",
1073
+ ].join(" ");
1048
1074
  safetyLogWarning("safety", `destructive command: ${classification.labels.join(", ")}`, {
1049
1075
  command: String(event.input.command).slice(0, 200),
1050
1076
  });
1051
- ctx.ui.notify(
1052
- `Destructive command detected: ${classification.labels.join(", ")}`,
1053
- "warning",
1054
- );
1077
+ if (ctx) {
1078
+ await maybePauseAutoForApprovalGate(
1079
+ ctx,
1080
+ pi,
1081
+ isAutoActive(),
1082
+ "Depth confirmation is waiting for your answer — pausing auto-mode.",
1083
+ );
1084
+ }
1085
+ return { block: true, reason };
1055
1086
  }
1056
1087
  }
1057
1088
  });
@@ -1320,19 +1351,27 @@ export function registerHooks(
1320
1351
  const fullToolsRequested = isFullGsdToolSurfaceRequested();
1321
1352
  const dropAliases = !fullToolsRequested;
1322
1353
  const dropBrowser = !fullToolsRequested && !isBrowserToolSurfaceRequested();
1323
- const providerCompatible = compatible.filter(
1324
- (name) => !(dropAliases && isWorkflowAliasTool(name)) && !(dropBrowser && isBrowserTool(name)),
1354
+ const aliasFilteredCompatible = compatible.filter(
1355
+ (name) => !(dropAliases && isWorkflowAliasTool(name)),
1356
+ );
1357
+ const providerCompatible = aliasFilteredCompatible.filter(
1358
+ (name) => !(dropBrowser && isBrowserTool(name)),
1325
1359
  );
1326
1360
  const surfaceReduced = providerCompatible.length !== compatible.length;
1327
1361
  if (fullToolsRequested) {
1328
1362
  return surfaceReduced ? { toolNames: providerCompatible } : undefined;
1329
1363
  }
1330
1364
  const registeredToolNames = resolveRegisteredToolNames(pi, event.activeToolNames);
1365
+ const compatibleRegisteredToolNames = filterToolsForProvider(
1366
+ registeredToolNames,
1367
+ event.selectedModelApi,
1368
+ event.selectedModelProvider,
1369
+ ).compatible.filter((name) => !(dropAliases && isWorkflowAliasTool(name)));
1331
1370
  const guidedUnit = getGuidedUnitContext();
1332
1371
  const requestScoped = buildRequestScopedGsdToolSet(
1333
- providerCompatible,
1372
+ guidedUnit?.unitType === "run-uat" ? aliasFilteredCompatible : providerCompatible,
1334
1373
  event.requestCustomMessages,
1335
- registeredToolNames,
1374
+ guidedUnit?.unitType === "run-uat" ? compatibleRegisteredToolNames : registeredToolNames,
1336
1375
  guidedUnit?.unitType,
1337
1376
  );
1338
1377
  if (requestScoped) {
@@ -1342,9 +1381,11 @@ export function registerHooks(
1342
1381
  if (dash.active && dash.currentUnit) {
1343
1382
  return {
1344
1383
  toolNames: buildMinimalAutoGsdToolSet(
1345
- providerCompatible,
1384
+ dash.currentUnit.type === "run-uat" ? aliasFilteredCompatible : providerCompatible,
1346
1385
  dash.currentUnit.type,
1347
- resolveRegisteredToolNames(pi, event.activeToolNames),
1386
+ dash.currentUnit.type === "run-uat"
1387
+ ? compatibleRegisteredToolNames
1388
+ : resolveRegisteredToolNames(pi, event.activeToolNames),
1348
1389
  ),
1349
1390
  };
1350
1391
  }
@@ -679,6 +679,7 @@ const PLANNING_SUBAGENT_TOOLS = new Set(["subagent", "task"]);
679
679
  * manifests still declare per-unit subsets via ToolsPolicy.allowedSubagents.
680
680
  */
681
681
  const PLANNING_DISPATCH_AGENT_REGISTRY = {
682
+ mnemo: { readOnlySpecialist: true },
682
683
  scout: { readOnlySpecialist: true },
683
684
  planner: { readOnlySpecialist: true },
684
685
  reviewer: { readOnlySpecialist: true },
@@ -692,7 +693,7 @@ export const ALLOWED_PLANNING_DISPATCH_AGENTS = new Set<string>(
692
693
  .map(([agentId]) => agentId),
693
694
  );
694
695
 
695
- let warnedMissingPlanningDispatchAgentClasses = false;
696
+ let warnedMissingControlledDispatchAgentClasses = false;
696
697
 
697
698
  function isReadOnlySpecialist(agentId: string): boolean {
698
699
  const metadata = PLANNING_DISPATCH_AGENT_REGISTRY[agentId as keyof typeof PLANNING_DISPATCH_AGENT_REGISTRY];
@@ -703,11 +704,20 @@ function allowedPlanningDispatchAgentsList(): string {
703
704
  return [...ALLOWED_PLANNING_DISPATCH_AGENTS].join(", ");
704
705
  }
705
706
 
706
- function warnMissingPlanningDispatchAgentClasses(unitType: string, mode: string, toolName: string): void {
707
- if (warnedMissingPlanningDispatchAgentClasses) return;
708
- warnedMissingPlanningDispatchAgentClasses = true;
707
+ function allowsControlledSubagentDispatch(
708
+ policy: ToolsPolicy,
709
+ ): policy is ToolsPolicy & { readonly allowedSubagents: readonly string[] } {
710
+ return (
711
+ (policy.mode === "planning-dispatch" || policy.mode === "verification") &&
712
+ Array.isArray((policy as { readonly allowedSubagents?: unknown }).allowedSubagents)
713
+ );
714
+ }
715
+
716
+ function warnMissingControlledDispatchAgentClasses(unitType: string, mode: string, toolName: string): void {
717
+ if (warnedMissingControlledDispatchAgentClasses) return;
718
+ warnedMissingControlledDispatchAgentClasses = true;
709
719
  // TODO(#5060): Remove this migration shim once all subagent/task callers are verified to forward agent identities.
710
- const message = `[write-gate] planning-dispatch: shouldBlockPlanningUnit called for tool "${toolName}" ` +
720
+ const message = `[write-gate] controlled-dispatch: shouldBlockPlanningUnit called for tool "${toolName}" ` +
711
721
  `on unit "${unitType}" without agentClasses - stale caller; blocking dispatch.`;
712
722
  console.warn(message);
713
723
  logWarning("intercept", message, {
@@ -777,8 +787,9 @@ function blockReason(unitType: string, mode: string, what: string): string {
777
787
  * - "docs" → like "planning" but also allows writes to paths
778
788
  * matching `allowedPathGlobs` relative to basePath.
779
789
  * - "verification"
780
- * → allows Bash for project verification commands, but keeps
781
- * writes restricted to .gsd/ and blocks subagent dispatch.
790
+ * → allows Bash for project verification commands, keeps
791
+ * writes restricted to .gsd/, and permits subagent dispatch
792
+ * only when the manifest declares allowedSubagents.
782
793
  *
783
794
  * `pathOrCommand` is the file path for write/edit-shaped tools and the
784
795
  * shell command for bash. Other tools ignore this argument.
@@ -825,7 +836,7 @@ export function shouldBlockPlanningUnit(
825
836
  if (tool.startsWith("gsd_")) return { block: false };
826
837
 
827
838
  if (PLANNING_SUBAGENT_TOOLS.has(tool)) {
828
- if (policy.mode === "planning-dispatch") {
839
+ if (allowsControlledSubagentDispatch(policy)) {
829
840
  const requested = (agentClasses ?? []).map(a => a.trim()).filter(Boolean);
830
841
  const dispatchContract = compileSubagentPermissionContract(policy);
831
842
  const allowedSubagents = dispatchContract.allowedSubagents;
@@ -834,7 +845,7 @@ export function shouldBlockPlanningUnit(
834
845
  // agent identities yet. Block and warn so stale callers surface in telemetry
835
846
  // instead of silently bypassing the gate.
836
847
  if (agentClasses === undefined) {
837
- warnMissingPlanningDispatchAgentClasses(unitType, policy.mode, tool);
848
+ warnMissingControlledDispatchAgentClasses(unitType, policy.mode, tool);
838
849
  return {
839
850
  block: true,
840
851
  reason: blockReason(
@@ -857,7 +868,7 @@ export function shouldBlockPlanningUnit(
857
868
  reason: blockReason(
858
869
  unitType,
859
870
  policy.mode,
860
- `subagent dispatch of "${globallyDisallowed}" not permitted; only read-only specialists (${allowedPlanningDispatchAgentsList()}) may be dispatched from planning-dispatch units`,
871
+ `subagent dispatch of "${globallyDisallowed}" not permitted; only read-only specialists (${allowedPlanningDispatchAgentsList()}) may be dispatched from ${policy.mode} units`,
861
872
  ),
862
873
  };
863
874
  }
@@ -1,11 +1,13 @@
1
1
  // Project/App: gsd-pi
2
2
  // File Purpose: Shared browser-observable UAT requirement and evidence detection.
3
3
 
4
- export const BROWSER_REQUIREMENT_RE = /\b(?:browser|file:\/\/|localhost|dom|localstorage|click(?:ing|ed)?|button|screenshot|snapshot|reload(?:ed)?|page refresh|user-visible|strikethrough|search box)\b/i;
4
+ export const BROWSER_REQUIREMENT_RE = /\b(?:file:\/\/|localhost|playwright|chrome|screenshot|snapshot|browser_(?:assert|batch|find|verify|snapshot_refs))\b|\b(?:open|launch|navigate|load|visit|serve|start)\b.{0,80}\b(?:browser|page|localhost|file:\/\/)\b|\bbrowser\s+(?:check|session|test|uat|tool|automation|interaction|flow)\b/i;
5
5
  export const NO_BROWSER_EVIDENCE_RE = /\b(?:no|without|not|wasn'?t|isn'?t)\s+(?:automated\s+)?(?:live\s+)?browser(?:\s+(?:session|test|uat))?|\bno\s+automated\s+browser\b|\bnot\s+conducted\b/i;
6
6
  export const BROWSER_RUNTIME_RE = /\b(?:browser|playwright|chrome|camoufox|browser_(?:assert|batch|find|verify|snapshot_refs)|screenshot|snapshot|file:\/\/|localhost)\b/i;
7
7
  export const BROWSER_ACTION_RE = /\b(?:open(?:ed)?|navigate(?:d)?|click(?:ed)?|type(?:d)?|reload(?:ed)?|capture(?:d)?|screenshot|snapshot)\b/i;
8
8
  export const BROWSER_ASSERTION_RE = /\b(?:assert(?:ed|ion)?|observed|confirmed|verified|expected|visible|text|count|label|strikethrough|localstorage|screenshot|snapshot|passed)\b/i;
9
+ const NON_REQUIREMENT_BROWSER_HEADING_RE = /^(?:not\s+proven|not\s+covered|out\s+of\s+scope|deferred|follow-?ups?|known\s+limitations|notes\s+for\s+tester)\b/i;
10
+ const NON_REQUIREMENT_BROWSER_LINE_RE = /\b(?:deferred|not\s+proven|not\s+covered|out\s+of\s+scope|future\s+slice|follow-?up|no\s+(?:live\s+)?browser|without\s+(?:a\s+)?browser|not\s+(?:a\s+)?browser)\b/i;
9
11
 
10
12
  export function compactTextParts(parts: Array<string | string[] | null | undefined>): string {
11
13
  return parts.flatMap((part) => Array.isArray(part) ? part : [part])
@@ -14,7 +16,29 @@ export function compactTextParts(parts: Array<string | string[] | null | undefin
14
16
  }
15
17
 
16
18
  export function hasBrowserRequiredText(text: string): boolean {
17
- return BROWSER_REQUIREMENT_RE.test(text);
19
+ let inNonRequirementSection = false;
20
+ let nonRequirementDepth = 0;
21
+ for (const line of text.split(/\r?\n/)) {
22
+ const headingMatch = line.match(/^(#{1,6})\s+(.+?)\s*$/);
23
+ if (headingMatch) {
24
+ const depth = headingMatch[1]!.length;
25
+ const title = headingMatch[2] ?? "";
26
+ // Only update section context when at the same or higher level than the
27
+ // heading that opened the non-requirement zone. A sub-heading deeper than
28
+ // the opening heading must not escape or re-enter the zone on its own.
29
+ if (!inNonRequirementSection || depth <= nonRequirementDepth) {
30
+ inNonRequirementSection = NON_REQUIREMENT_BROWSER_HEADING_RE.test(title);
31
+ nonRequirementDepth = inNonRequirementSection ? depth : 0;
32
+ }
33
+ // Check the heading title itself — section state is already updated, so
34
+ // we correctly skip headings that opened a non-requirement zone.
35
+ if (!inNonRequirementSection && BROWSER_REQUIREMENT_RE.test(title)) return true;
36
+ continue;
37
+ }
38
+ if (inNonRequirementSection || NON_REQUIREMENT_BROWSER_LINE_RE.test(line)) continue;
39
+ if (BROWSER_REQUIREMENT_RE.test(line)) return true;
40
+ }
41
+ return false;
18
42
  }
19
43
 
20
44
  export function hasBrowserEvidenceText(text: string): boolean {
@@ -14,7 +14,7 @@ export interface GsdCommandDefinition {
14
14
  type CompletionMap = Record<string, readonly GsdCommandDefinition[]>;
15
15
 
16
16
  export const GSD_COMMAND_DESCRIPTION =
17
- "GSD — Git Ship Done: /gsd help|start|templates|next|auto|stop|pause|status|widget|visualize|brief|report|queue|quick|discuss|capture|triage|dispatch|verdict|history|undo|undo-task|reset-slice|rate|skip|export|cleanup|closeout|model|mode|prefs|config|keys|hooks|run-hook|skill-health|doctor|debug|logs|forensics|changelog|migrate|remote|steer|knowledge|memory|new-milestone|new-project|parallel|cmux|park|unpark|init|setup|onboarding|inspect|extensions|update|upgrade|fast|mcp|rethink|workflow|codebase|notifications|ship|do|usage|context|session-report|backlog|pr-branch|add-tests|scan|language|worktree|eval-review";
17
+ "GSD — Git Ship Done: /gsd help|start|templates|next|auto|stop|pause|status|widget|visualize|brief|report|queue|quick|discuss|capture|triage|dispatch|verdict|history|undo|undo-task|reset-slice|rate|skip|export|cleanup|closeout|rebuild|model|mode|prefs|config|keys|hooks|run-hook|skill-health|doctor|debug|logs|forensics|changelog|migrate|remote|steer|knowledge|memory|new-milestone|new-project|parallel|cmux|park|unpark|init|setup|onboarding|inspect|extensions|update|upgrade|fast|mcp|rethink|workflow|codebase|notifications|ship|do|usage|context|session-report|backlog|pr-branch|add-tests|scan|language|worktree|eval-review";
18
18
 
19
19
  export const TOP_LEVEL_SUBCOMMANDS: readonly GsdCommandDefinition[] = [
20
20
  { cmd: "help", desc: "Categorized command reference with descriptions" },
@@ -44,6 +44,7 @@ export const TOP_LEVEL_SUBCOMMANDS: readonly GsdCommandDefinition[] = [
44
44
  { cmd: "export", desc: "Alias for /gsd report" },
45
45
  { cmd: "cleanup", desc: "Remove merged branches or snapshots" },
46
46
  { cmd: "closeout", desc: "Recover failed git closeout actions (status, retry, resolve)" },
47
+ { cmd: "rebuild", desc: "Rebuild markdown projections from the canonical DB" },
47
48
  { cmd: "model", desc: "Switch the active session model or open a picker" },
48
49
  { cmd: "mode", desc: "Switch workflow mode (solo/team)" },
49
50
  { cmd: "prefs", desc: "Manage preferences (model selection, timeouts, etc.)" },
@@ -214,6 +215,10 @@ const NESTED_COMPLETIONS: CompletionMap = {
214
215
  { cmd: "retry", desc: "Retry the latest failed closeout git action" },
215
216
  { cmd: "resolve", desc: "Mark closeout resolved after the worktree is clean" },
216
217
  ],
218
+ rebuild: [
219
+ { cmd: "markdown", desc: "Rebuild markdown projections from the canonical DB" },
220
+ { cmd: "database", desc: "Reserved for DB-native rebuilds; does not import markdown" },
221
+ ],
217
222
  knowledge: [
218
223
  { cmd: "rule", desc: "Add a project rule (always/never do X)" },
219
224
  { cmd: "pattern", desc: "Add a code pattern to follow" },
@@ -56,6 +56,7 @@ export function showHelp(ctx: ExtensionCommandContext, args = ""): void {
56
56
  " /gsd keys API key manager (LLM + tool keys)",
57
57
  " /gsd doctor Diagnose and repair .gsd/ state",
58
58
  " /gsd closeout Recover failed git closeout actions",
59
+ " /gsd rebuild Rebuild markdown projections from the DB [markdown]",
59
60
  "",
60
61
  "Use /gsd help full for the complete command reference.",
61
62
  ];
@@ -74,7 +75,7 @@ export function showHelp(ctx: ExtensionCommandContext, args = ""): void {
74
75
  " /gsd new-milestone Create milestone from headless context (used by gsd headless)",
75
76
  " /gsd new-project Bootstrap a new project (use --deep for staged project-level discovery)",
76
77
  " /gsd quick Execute a quick task without full planning overhead",
77
- " /gsd dispatch Dispatch a specific phase directly [research|plan|execute|complete|uat|replan]",
78
+ " /gsd dispatch Dispatch a specific phase directly [research|plan|execute|complete|validate|reassess|uat|replan]",
78
79
  " /gsd verdict <v> Override milestone validation verdict [pass|needs-attention|needs-remediation] [--milestone Mxxx] [--rationale \"...\"]",
79
80
  " /gsd parallel Parallel milestone orchestration [start|status|stop|pause|resume|merge|watch]",
80
81
  " /gsd workflow Custom workflow lifecycle [new|run|list|validate|pause|resume]",
@@ -138,7 +139,7 @@ export function showHelp(ctx: ExtensionCommandContext, args = ""): void {
138
139
  " /gsd skill-health Skill lifecycle dashboard",
139
140
  " /gsd extensions Manage extensions [list|enable|disable|info]",
140
141
  " /gsd fast Toggle OpenAI service tier [on|off|flex|status]",
141
- " /gsd mcp MCP server management [status|check|test|enable|disable|import|delete|init]",
142
+ " /gsd mcp MCP server management [status|check|discover|test|enable|disable|import|delete|init]",
142
143
  "",
143
144
  "MAINTENANCE",
144
145
  " /gsd doctor Diagnose and repair .gsd/ state [audit|fix|heal] [scope]",
@@ -147,6 +148,9 @@ export function showHelp(ctx: ExtensionCommandContext, args = ""): void {
147
148
  " /gsd export Alias for /gsd report",
148
149
  " /gsd cleanup Remove merged branches or snapshots [branches|snapshots]",
149
150
  " /gsd closeout Recover failed git closeout actions [status|retry|resolve] [unit-id]",
151
+ " /gsd rebuild markdown Rebuild markdown projections from the canonical DB",
152
+ " /gsd rebuild database Reserved for DB-native rebuilds; does not import markdown",
153
+ " /gsd recover --confirm Import markdown into the DB after DB loss/corruption",
150
154
  " /gsd worktree Manage worktrees from the TUI [list|merge|clean|remove]",
151
155
  " /gsd migrate Migrate .planning/ (v1) to DB-backed .gsd/ with backup + audit",
152
156
  " /gsd remote Control remote auto-mode [slack|discord|status|disconnect]",
@@ -9,7 +9,7 @@ import { handleDoctor, handleCapture, handleKnowledge, handleRunHook, handleSkil
9
9
  import { handleInspect } from "../../commands-inspect.js";
10
10
  import { handleLogs } from "../../commands-logs.js";
11
11
  import { handleDebug } from "../../commands-debug.js";
12
- import { handleCleanupBranches, handleCleanupSnapshots, handleSkip, handleCleanupProjects, handleCleanupWorktrees, handleRecover } from "../../commands-maintenance.js";
12
+ import { handleCleanupBranches, handleCleanupSnapshots, handleSkip, handleCleanupProjects, handleCleanupWorktrees, handleRecover, handleRebuild } from "../../commands-maintenance.js";
13
13
  import { handleExport } from "../../export.js";
14
14
  import { handleHistory } from "../../history.js";
15
15
  import { handleUndo } from "../../undo.js";
@@ -146,8 +146,12 @@ export async function handleOpsCommand(trimmed: string, ctx: ExtensionCommandCon
146
146
  await handleSkip(trimmed.replace(/^skip\s*/, "").trim(), ctx, projectRoot());
147
147
  return true;
148
148
  }
149
- if (trimmed === "recover") {
150
- await handleRecover(ctx, projectRoot());
149
+ if (trimmed === "recover" || trimmed.startsWith("recover ")) {
150
+ await handleRecover(ctx, projectRoot(), trimmed.replace(/^recover\s*/, "").trim());
151
+ return true;
152
+ }
153
+ if (trimmed === "rebuild" || trimmed.startsWith("rebuild ")) {
154
+ await handleRebuild(ctx, projectRoot(), trimmed.replace(/^rebuild\s*/, "").trim());
151
155
  return true;
152
156
  }
153
157
  if (trimmed === "closeout" || trimmed.startsWith("closeout ")) {
@@ -278,8 +282,8 @@ Examples:
278
282
  await handleInspect(ctx);
279
283
  return true;
280
284
  }
281
- if (trimmed === "update" || trimmed === "upgrade") {
282
- await handleUpdate(ctx);
285
+ if (trimmed === "update" || trimmed.startsWith("update ") || trimmed === "upgrade" || trimmed.startsWith("upgrade ")) {
286
+ await handleUpdate(ctx, trimmed.replace(/^(?:update|upgrade)\s*/, "").trim());
283
287
  return true;
284
288
  }
285
289
  if (trimmed === "fast" || trimmed.startsWith("fast ")) {
@@ -7,6 +7,8 @@
7
7
 
8
8
  import type { ExtensionAPI, ExtensionCommandContext } from "@gsd/pi-coding-agent";
9
9
  import { existsSync, readFileSync, mkdirSync } from "node:fs";
10
+ import { execFileSync } from "node:child_process";
11
+ import { createRequire } from "node:module";
10
12
  import { join, resolve as resolvePath, sep } from "node:path";
11
13
  import { homedir } from "node:os";
12
14
  import { deriveState } from "./state.js";
@@ -37,7 +39,10 @@ import {
37
39
  scopeGsdWorkflowToolsForDispatch,
38
40
  } from "./bootstrap/register-hooks.js";
39
41
 
42
+ const GSD_PI_PACKAGE = "@opengsd/gsd-pi";
43
+ const GSD_BROWSER_PACKAGE = "@opengsd/gsd-browser";
40
44
  const UPDATE_REGISTRY_URL = "https://registry.npmjs.org/@opengsd%2fgsd-pi/latest";
45
+ const BROWSER_UPDATE_REGISTRY_URL = "https://registry.npmjs.org/@opengsd%2fgsd-browser/latest";
41
46
  const UPDATE_FETCH_TIMEOUT_MS = 5000;
42
47
 
43
48
  // Detects a bun-installed gsd via `process.argv[1]`. Mirrors isBunInstall in
@@ -62,12 +67,12 @@ function resolveInstallCommand(pkg: string): string {
62
67
  return `npm install -g ${pkg}`;
63
68
  }
64
69
 
65
- async function fetchLatestVersionForCommand(): Promise<string | null> {
70
+ async function fetchLatestVersionForCommand(registryUrl: string = UPDATE_REGISTRY_URL): Promise<string | null> {
66
71
  const controller = new AbortController();
67
72
  const timeout = setTimeout(() => controller.abort(), UPDATE_FETCH_TIMEOUT_MS);
68
73
 
69
74
  try {
70
- const res = await fetch(UPDATE_REGISTRY_URL, { signal: controller.signal });
75
+ const res = await fetch(registryUrl, { signal: controller.signal });
71
76
  if (!res.ok) return null;
72
77
  const data = (await res.json()) as { version?: string };
73
78
  const latest = typeof data.version === "string" ? data.version.trim().replace(/^v/, "") : "";
@@ -79,6 +84,19 @@ async function fetchLatestVersionForCommand(): Promise<string | null> {
79
84
  }
80
85
  }
81
86
 
87
+ function resolveInstalledPackageVersionForCommand(packageName: string): string | null {
88
+ try {
89
+ const requireFromHere = createRequire(import.meta.url);
90
+ const packageJsonPath = requireFromHere.resolve(`${packageName}/package.json`);
91
+ const pkg = JSON.parse(readFileSync(packageJsonPath, "utf-8")) as { version?: unknown };
92
+ return typeof pkg.version === "string" && pkg.version.trim().length > 0
93
+ ? pkg.version.trim().replace(/^v/, "")
94
+ : null;
95
+ } catch {
96
+ return null;
97
+ }
98
+ }
99
+
82
100
  export function dispatchDoctorHeal(pi: ExtensionAPI, scope: string | undefined, reportText: string, structuredIssues: string): void {
83
101
  const workflowPath = process.env.GSD_WORKFLOW_PATH ?? join(gsdHome(), "agent", "GSD-WORKFLOW.md");
84
102
  const workflow = readFileSync(workflowPath, "utf-8");
@@ -473,34 +491,81 @@ function compareSemverLocal(a: string, b: string): number {
473
491
  return 0
474
492
  }
475
493
 
476
- export async function handleUpdate(ctx: ExtensionCommandContext): Promise<void> {
494
+ function formatCommandVersion(version: string | null): string {
495
+ return version ? `v${version}` : "unknown";
496
+ }
497
+
498
+ function pickHigherVersionForCommand(a: string | null, b: string | null): string | null {
499
+ if (!a) return b;
500
+ if (!b) return a;
501
+ return compareSemverLocal(a, b) >= 0 ? a : b;
502
+ }
503
+
504
+ // Mirrors resolveGsdBrowserPathVersion in src/update-check.ts — duplicated because
505
+ // tsconfig.resources.json rootDir prevents importing from src/.
506
+ function resolveGsdBrowserPathVersionForCommand(env: NodeJS.ProcessEnv = process.env): string | null {
507
+ const explicit = env.GSD_BROWSER_PATH_VERSION?.trim();
508
+ if (explicit) return explicit.match(/\b(\d+\.\d+\.\d+)\b/)?.[1] ?? null;
509
+ try {
510
+ const out = execFileSync("gsd-browser", ["--version"], {
511
+ encoding: "utf-8",
512
+ env,
513
+ stdio: ["ignore", "pipe", "ignore"],
514
+ timeout: 2000,
515
+ });
516
+ return out.match(/\b(\d+\.\d+\.\d+)\b/)?.[1] ?? null;
517
+ } catch {
518
+ return null;
519
+ }
520
+ }
521
+
522
+ export async function handleUpdate(ctx: ExtensionCommandContext, args = ""): Promise<void> {
477
523
  const { execSync } = await import("node:child_process");
478
524
 
479
- const NPM_PACKAGE = "@opengsd/gsd-pi";
480
- const current = process.env.GSD_VERSION || "0.0.0";
525
+ const target = args.trim();
526
+ const browserUpdate = target === "browser" || target === "gsd-browser";
527
+ if (target && !browserUpdate) {
528
+ ctx.ui.notify("Usage: /gsd update [browser]", "warning");
529
+ return;
530
+ }
531
+
532
+ const NPM_PACKAGE = browserUpdate ? GSD_BROWSER_PACKAGE : GSD_PI_PACKAGE;
533
+ const registryUrl = browserUpdate ? BROWSER_UPDATE_REGISTRY_URL : UPDATE_REGISTRY_URL;
534
+ const bundledVersion = browserUpdate
535
+ ? resolveInstalledPackageVersionForCommand(GSD_BROWSER_PACKAGE)
536
+ : null;
537
+ const current = browserUpdate
538
+ ? pickHigherVersionForCommand(bundledVersion, resolveGsdBrowserPathVersionForCommand())
539
+ : process.env.GSD_VERSION || "0.0.0";
540
+ const label = browserUpdate ? "gsd-browser version" : "version";
481
541
 
482
- ctx.ui.notify(`Current version: v${current}\nChecking npm registry...`, "info");
542
+ ctx.ui.notify(`Current ${label}: ${formatCommandVersion(current)}\nChecking npm registry...`, "info");
483
543
 
484
- const latest = await fetchLatestVersionForCommand();
544
+ const latest = await fetchLatestVersionForCommand(registryUrl);
485
545
  if (!latest) {
486
546
  ctx.ui.notify("Failed to reach npm registry. Check your network connection.", "error");
487
547
  return;
488
548
  }
489
549
 
490
- if (compareSemverLocal(latest, current) <= 0) {
491
- ctx.ui.notify(`Already up to date (v${current}).`, "info");
550
+ if (current && compareSemverLocal(latest, current) <= 0) {
551
+ ctx.ui.notify(`Already up to date (${formatCommandVersion(current)}).`, "info");
492
552
  return;
493
553
  }
494
554
 
495
- ctx.ui.notify(`Updating: v${current} → v${latest}...`, "info");
555
+ ctx.ui.notify(`Updating: ${formatCommandVersion(current)} → v${latest}...`, "info");
496
556
 
497
557
  const installCmd = resolveInstallCommand(`${NPM_PACKAGE}@latest`);
498
558
  try {
499
559
  execSync(installCmd, {
500
560
  stdio: ["ignore", "pipe", "ignore"],
501
561
  });
562
+ const newPathVersion = browserUpdate ? resolveGsdBrowserPathVersionForCommand() : null;
563
+ const pathReady = !browserUpdate || (!!newPathVersion && compareSemverLocal(newPathVersion, latest) >= 0);
502
564
  ctx.ui.notify(
503
- `Updated to v${latest}. Restart your GSD session to use the new version.`,
565
+ browserUpdate
566
+ ? `Updated gsd-browser to v${latest}. Restart your GSD session to use the new browser automation version.` +
567
+ (pathReady ? "" : "\nNote: Ensure the npm global bin directory is on your PATH so MCP automation uses the updated binary.")
568
+ : `Updated to v${latest}. Restart your GSD session to use the new version.`,
504
569
  "info",
505
570
  );
506
571
  } catch {