@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
@@ -91,6 +91,7 @@ import { nativeHasChanges, nativeIsRepo, _resetHasChangesCache } from "./native-
91
91
  import { debugLog, isDebugEnabled } from "./debug-logger.js";
92
92
  import { resolveCanonicalMilestoneRoot } from "./worktree-manager.js";
93
93
  import { resolveWorktreeProjectRoot } from "./worktree-root.js";
94
+ import { detectWorktreeName } from "./worktree.js";
94
95
  import { probeGitConflictState } from "./git-conflict-state.js";
95
96
  import { runTurnGitAction } from "./git-service.js";
96
97
  import { parseUnitId } from "./unit-id.js";
@@ -340,6 +341,29 @@ function isRegistryMilestoneComplete(state: GSDState, mid: string): boolean {
340
341
  );
341
342
  }
342
343
 
344
+ function normalizeMilestoneScope(value: string | null | undefined): string | null {
345
+ const trimmed = value?.trim();
346
+ if (!trimmed || !MILESTONE_ID_RE.test(trimmed)) return null;
347
+ return trimmed;
348
+ }
349
+
350
+ function resolveDispatchMilestoneScope(
351
+ ctx: DispatchContext,
352
+ ): { id: string; source: string } | null {
353
+ const sessionMilestone = normalizeMilestoneScope(ctx.session?.currentMilestoneId);
354
+ if (sessionMilestone) return { id: sessionMilestone, source: "session.currentMilestoneId" };
355
+
356
+ const sessionWorktree = normalizeMilestoneScope(
357
+ ctx.session?.basePath ? detectWorktreeName(ctx.session.basePath) : null,
358
+ );
359
+ if (sessionWorktree) return { id: sessionWorktree, source: "session.basePath worktree" };
360
+
361
+ const baseWorktree = normalizeMilestoneScope(detectWorktreeName(ctx.basePath));
362
+ if (baseWorktree) return { id: baseWorktree, source: "basePath worktree" };
363
+
364
+ return null;
365
+ }
366
+
343
367
  function hasMilestonePassedDiscuss(basePath: string, mid: string): boolean {
344
368
  if (isDbAvailable()) {
345
369
  try {
@@ -598,6 +622,7 @@ export const DISPATCH_RULES: DispatchRule[] = [
598
622
  structuredQuestionsAvailable,
599
623
  { headless: !!process.env.GSD_HEADLESS },
600
624
  ),
625
+ pauseAfterDispatch: !process.env.GSD_HEADLESS,
601
626
  };
602
627
  },
603
628
  },
@@ -748,6 +773,7 @@ export const DISPATCH_RULES: DispatchRule[] = [
748
773
  structuredQuestionsAvailable,
749
774
  { headless: !!process.env.GSD_HEADLESS },
750
775
  ),
776
+ pauseAfterDispatch: !process.env.GSD_HEADLESS,
751
777
  };
752
778
  },
753
779
  },
@@ -781,6 +807,7 @@ export const DISPATCH_RULES: DispatchRule[] = [
781
807
  unitType: "discuss-project",
782
808
  unitId: "PROJECT",
783
809
  prompt: await buildDiscussProjectPrompt(basePath, structuredQuestionsAvailable),
810
+ pauseAfterDispatch: !process.env.GSD_HEADLESS,
784
811
  };
785
812
  },
786
813
  },
@@ -802,6 +829,7 @@ export const DISPATCH_RULES: DispatchRule[] = [
802
829
  unitType: "discuss-requirements",
803
830
  unitId: "REQUIREMENTS",
804
831
  prompt: await buildDiscussRequirementsPrompt(basePath, structuredQuestionsAvailable),
832
+ pauseAfterDispatch: !process.env.GSD_HEADLESS,
805
833
  };
806
834
  },
807
835
  },
@@ -916,6 +944,7 @@ export const DISPATCH_RULES: DispatchRule[] = [
916
944
  structuredQuestionsAvailable,
917
945
  { headless: !!process.env.GSD_HEADLESS },
918
946
  ),
947
+ pauseAfterDispatch: !process.env.GSD_HEADLESS,
919
948
  };
920
949
  },
921
950
  },
@@ -1631,6 +1660,19 @@ import { getRegistry } from "./rule-registry.js";
1631
1660
  export async function resolveDispatch(
1632
1661
  ctx: DispatchContext,
1633
1662
  ): Promise<DispatchAction> {
1663
+ if (ctx.mid && isDbAvailable()) {
1664
+ const milestone = getMilestone(ctx.mid);
1665
+ if (milestone && isClosedStatus(milestone.status)) {
1666
+ return {
1667
+ action: "stop",
1668
+ reason:
1669
+ `Milestone ${ctx.mid} is closed (status: ${milestone.status}); auto-mode will not reopen or recover it implicitly. ` +
1670
+ "Use an explicit reopen command before planning or executing more work for this milestone.",
1671
+ level: "warning",
1672
+ };
1673
+ }
1674
+ }
1675
+
1634
1676
  const activeMid = ctx.state.activeMilestone?.id;
1635
1677
  if (activeMid && ctx.mid !== activeMid) {
1636
1678
  return {
@@ -1642,6 +1684,17 @@ export async function resolveDispatch(
1642
1684
  };
1643
1685
  }
1644
1686
 
1687
+ const scopedMilestone = resolveDispatchMilestoneScope(ctx);
1688
+ if (scopedMilestone && ctx.mid !== scopedMilestone.id) {
1689
+ return {
1690
+ action: "stop",
1691
+ reason:
1692
+ `Dispatch milestone mismatch: context mid "${ctx.mid}" does not match ${scopedMilestone.source} "${scopedMilestone.id}". ` +
1693
+ "The active worktree/session and derived project state disagree; recover, park, or discard the stranded milestone before continuing.",
1694
+ level: "warning",
1695
+ };
1696
+ }
1697
+
1645
1698
  // Delegate to registry when available
1646
1699
  try {
1647
1700
  const registry = getRegistry();
@@ -55,8 +55,10 @@ import { parseRoadmap as parseLegacyRoadmap } from "./parsers-legacy.js";
55
55
  import { consumeSignal } from "./session-status-io.js";
56
56
  import {
57
57
  checkPostUnitHooks,
58
+ consumeHookFailure,
58
59
  isRetryPending,
59
60
  consumeRetryTrigger,
61
+ consumeGateBlock,
60
62
  persistHookState,
61
63
  resolveHookArtifactPath,
62
64
  } from "./post-unit-hooks.js";
@@ -394,6 +396,50 @@ function stripKnownIdPrefix(value: string | undefined | null, id: string): strin
394
396
  return raw;
395
397
  }
396
398
 
399
+ function parseReactiveBatchTaskIds(unitId: string): string[] {
400
+ const { task: batchPart } = parseUnitId(unitId);
401
+ if (!batchPart?.startsWith("reactive+")) return [];
402
+
403
+ const rawIds = batchPart
404
+ .slice("reactive+".length)
405
+ .split(",")
406
+ .map((taskId) => taskId.trim().toUpperCase())
407
+ .filter(Boolean);
408
+
409
+ const unique = new Set<string>();
410
+ for (const taskId of rawIds) {
411
+ unique.add(taskId);
412
+ }
413
+ return [...unique];
414
+ }
415
+
416
+ function dedupePaths(values: string[]): string[] {
417
+ const seen = new Set<string>();
418
+ const result: string[] = [];
419
+ for (const value of values) {
420
+ if (!seen.has(value)) {
421
+ seen.add(value);
422
+ result.push(value);
423
+ }
424
+ }
425
+ return result;
426
+ }
427
+
428
+ function getPlannedKeyFiles(tasks: Array<
429
+ { expected_output?: string[]; files?: string[]; key_files?: string[] }
430
+ >): string[] {
431
+ return dedupePaths(
432
+ tasks.flatMap((taskRow) => [
433
+ ...(taskRow.expected_output ?? []),
434
+ ...(taskRow.files ?? []),
435
+ ...(taskRow.key_files ?? []),
436
+ ]),
437
+ );
438
+ }
439
+
440
+ export const _parseReactiveBatchTaskIdsForTest = parseReactiveBatchTaskIds;
441
+ export const _getPlannedKeyFilesForTest = getPlannedKeyFiles;
442
+
397
443
  function resolveVerificationFailureMarkerPath(
398
444
  unitType: string,
399
445
  unitId: string,
@@ -481,6 +527,40 @@ async function buildTaskCommitContextForUnit(
481
527
  };
482
528
  }
483
529
 
530
+ async function buildReactiveTaskCommitContext(
531
+ _basePath: string,
532
+ unitId: string,
533
+ ): Promise<TaskCommitContext | undefined> {
534
+ const { milestone: mid, slice: sid } = parseUnitId(unitId);
535
+ if (!mid || !sid || !isDbAvailable()) return undefined;
536
+
537
+ const batchTaskIds = parseReactiveBatchTaskIds(unitId);
538
+ if (batchTaskIds.length === 0) return undefined;
539
+
540
+ const milestone = getMilestone(mid);
541
+ const slice = getSlice(mid, sid);
542
+ const taskRows = batchTaskIds
543
+ .map((tid) => getTask(mid, sid, tid))
544
+ .filter((taskRow): taskRow is NonNullable<ReturnType<typeof getTask>> => taskRow !== null);
545
+
546
+ const keyFiles = getPlannedKeyFiles(taskRows);
547
+ if (taskRows.length === 0 || keyFiles.length === 0) return undefined;
548
+
549
+ const taskLabel = taskRows.map((row) => row.id).join(",");
550
+
551
+ return {
552
+ taskId: `${sid}/${taskLabel}`,
553
+ taskDisplayId: "reactive-batch",
554
+ taskTitle: `Reactive batch: ${taskLabel}`,
555
+ milestoneId: mid,
556
+ milestoneTitle: stripKnownIdPrefix(milestone?.title, mid),
557
+ sliceId: sid,
558
+ sliceTitle: stripKnownIdPrefix(slice?.title, sid),
559
+ oneLiner: `Reactive execute for ${taskLabel}`,
560
+ keyFiles,
561
+ };
562
+ }
563
+
484
564
  async function runPostUnitGitHubSyncIfNeeded(
485
565
  basePath: string,
486
566
  unit: NonNullable<AutoSession["currentUnit"]>,
@@ -943,6 +1023,8 @@ export async function autoCommitUnit(
943
1023
 
944
1024
  if (unitType === "execute-task") {
945
1025
  taskContext = await buildTaskCommitContextForUnit(basePath, unitId);
1026
+ } else if (unitType === "reactive-execute") {
1027
+ taskContext = await buildReactiveTaskCommitContext(basePath, unitId);
946
1028
  }
947
1029
 
948
1030
  _resetHasChangesCache();
@@ -1005,6 +1087,21 @@ async function runCloseoutGitAction(
1005
1087
  if (mid && sid && tid && isDbAvailable()) {
1006
1088
  targetRepositories = getTask(mid, sid, tid)?.target_repositories;
1007
1089
  }
1090
+ } else if (turnAction === "commit" && unit.type === "reactive-execute") {
1091
+ taskContext = await buildReactiveTaskCommitContext(s.basePath, unit.id);
1092
+ const { milestone: mid, slice: sid } = parseUnitId(unit.id);
1093
+ if (mid && sid && isDbAvailable()) {
1094
+ const repositories = new Set<string>();
1095
+ for (const tid of parseReactiveBatchTaskIds(unit.id)) {
1096
+ const taskRow = getTask(mid, sid, tid);
1097
+ for (const repoId of taskRow?.target_repositories ?? []) {
1098
+ repositories.add(repoId);
1099
+ }
1100
+ }
1101
+ if (repositories.size > 0) {
1102
+ targetRepositories = [...repositories];
1103
+ }
1104
+ }
1008
1105
  }
1009
1106
 
1010
1107
  // Invalidate the nativeHasChanges cache before auto-commit (#1853).
@@ -1436,12 +1533,24 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
1436
1533
  const { milestone: sMid, slice: sSid, task: sTid } = parseUnitId(s.currentUnit.id);
1437
1534
 
1438
1535
  // File change validation (execute-task only, after unit execution)
1439
- if (safetyConfig.file_change_validation && s.currentUnit.type === "execute-task" && sMid && sSid && sTid && isDbAvailable()) {
1536
+ if (safetyConfig.file_change_validation && s.currentUnit.type === "execute-task" && sMid && sSid && sTid) {
1440
1537
  try {
1441
- const taskRow = getTask(sMid, sSid, sTid);
1442
- if (taskRow) {
1443
- const expectedOutput = taskRow.expected_output ?? [];
1444
- const plannedFiles = taskRow.files ?? [];
1538
+ const sliceTaskRows = isDbAvailable()
1539
+ ? getSliceTasks(sMid, sSid).filter((t) => isClosedStatus(t.status) || t.id === sTid)
1540
+ : [];
1541
+
1542
+ if (sliceTaskRows.length > 0) {
1543
+ const expectedOutput = getPlannedKeyFiles(
1544
+ sliceTaskRows.map((taskRow) => ({
1545
+ expected_output: taskRow.expected_output,
1546
+ files: taskRow.files,
1547
+ })),
1548
+ );
1549
+ const plannedFiles = getPlannedKeyFiles(
1550
+ sliceTaskRows.map((taskRow) => ({
1551
+ files: taskRow.files,
1552
+ })),
1553
+ );
1445
1554
  const audit = validateFileChanges(s.basePath, expectedOutput, plannedFiles, safetyConfig.file_change_allowlist);
1446
1555
  if (audit && audit.violations.length > 0) {
1447
1556
  const warnings = audit.violations.filter(v => v.severity === "warning");
@@ -1455,6 +1564,30 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
1455
1564
  );
1456
1565
  }
1457
1566
  }
1567
+ } else {
1568
+ const taskRow = getTask(sMid, sSid, sTid);
1569
+ if (taskRow) {
1570
+ const expectedOutput = taskRow.expected_output ?? [];
1571
+ const plannedFiles = taskRow.files ?? [];
1572
+ const audit = validateFileChanges(
1573
+ s.basePath,
1574
+ expectedOutput,
1575
+ plannedFiles,
1576
+ safetyConfig.file_change_allowlist,
1577
+ );
1578
+ if (audit && audit.violations.length > 0) {
1579
+ const warnings = audit.violations.filter(v => v.severity === "warning");
1580
+ for (const v of warnings) {
1581
+ logWarning("safety", `file-change: ${v.file} — ${v.reason}`);
1582
+ }
1583
+ if (warnings.length > 0) {
1584
+ ctx.ui.notify(
1585
+ `Safety: ${warnings.length} unexpected file change(s) outside task plan`,
1586
+ "warning",
1587
+ );
1588
+ }
1589
+ }
1590
+ }
1458
1591
  }
1459
1592
  } catch (e) {
1460
1593
  debugLog("postUnit", { phase: "safety-file-change", error: String(e) });
@@ -2096,11 +2229,11 @@ export async function postUnitPostVerification(pctx: PostUnitContext): Promise<"
2096
2229
  // ── Post-unit hooks ──
2097
2230
  if (s.currentUnit && !s.stepMode) {
2098
2231
  const hookUnit = checkPostUnitHooks(s.currentUnit.type, s.currentUnit.id, s.basePath);
2232
+ persistHookState(s.basePath);
2099
2233
  if (hookUnit) {
2100
2234
  if (s.currentUnit) {
2101
2235
  await closeoutUnit(ctx, s.basePath, s.currentUnit.type, s.currentUnit.id, s.currentUnit.startedAt, buildSnapshotOpts(s.currentUnit.type, s.currentUnit.id));
2102
2236
  }
2103
- persistHookState(s.basePath);
2104
2237
 
2105
2238
  return enqueueSidecar(
2106
2239
  s, ctx,
@@ -2109,12 +2242,23 @@ export async function postUnitPostVerification(pctx: PostUnitContext): Promise<"
2109
2242
  );
2110
2243
  }
2111
2244
 
2245
+ const hookFailure = consumeHookFailure();
2246
+ if (hookFailure) {
2247
+ ctx.ui.notify(
2248
+ `Post-unit hook ${hookFailure.hookName} failed for ${hookFailure.unitId}: ${hookFailure.reason}. Pausing auto-mode.`,
2249
+ "warning",
2250
+ );
2251
+ await pauseAuto(ctx, pi);
2252
+ return "stopped";
2253
+ }
2254
+
2112
2255
  // Check if a hook requested a retry of the trigger unit
2113
2256
  if (isRetryPending()) {
2114
2257
  const trigger = consumeRetryTrigger();
2115
2258
  if (trigger) {
2259
+ persistHookState(s.basePath);
2116
2260
  ctx.ui.notify(
2117
- `Hook requested retry of ${trigger.unitType} ${trigger.unitId} — resetting task state.`,
2261
+ `Hook requested retry of ${trigger.unitType} ${trigger.unitId} — resetting trigger unit state.`,
2118
2262
  "info",
2119
2263
  );
2120
2264
 
@@ -2134,8 +2278,8 @@ export async function postUnitPostVerification(pctx: PostUnitContext): Promise<"
2134
2278
  await renderPlanCheckboxes(s.canonicalProjectRoot, mid, sid);
2135
2279
  } catch (dbErr) {
2136
2280
  // DB unavailable — fail explicitly rather than silently reverting to markdown mutation.
2137
- // Use 'gsd recover' to rebuild DB state from disk if needed.
2138
- logError("engine", `retry state-reset failed (DB unavailable): ${(dbErr as Error).message}. Run 'gsd recover' to reconcile.`);
2281
+ // Use 'gsd recover --confirm' to import markdown into the DB if needed.
2282
+ logError("engine", `retry state-reset failed (DB unavailable): ${(dbErr as Error).message}. Run 'gsd recover --confirm' to import markdown into the DB.`);
2139
2283
  }
2140
2284
  }
2141
2285
 
@@ -2168,6 +2312,19 @@ export async function postUnitPostVerification(pctx: PostUnitContext): Promise<"
2168
2312
  // Fall through to normal dispatch — deriveState will re-derive the unit
2169
2313
  }
2170
2314
  }
2315
+
2316
+ const gateBlock = consumeGateBlock();
2317
+ if (gateBlock) {
2318
+ persistHookState(s.basePath);
2319
+ const verdict = gateBlock.verdict ? ` verdict=${gateBlock.verdict};` : "";
2320
+ const artifact = gateBlock.artifact ? ` artifact=${gateBlock.artifact};` : "";
2321
+ const message =
2322
+ `Post-unit gate "${gateBlock.hookName}" blocked ${gateBlock.triggerUnitType} ${gateBlock.triggerUnitId}:` +
2323
+ `${verdict}${artifact} ${gateBlock.reason}. Run /gsd status to inspect, then /gsd auto after recovery.`;
2324
+ ctx.ui.notify(message, "warning");
2325
+ await pauseAuto(ctx, pi);
2326
+ return "stopped";
2327
+ }
2171
2328
  }
2172
2329
 
2173
2330
  // ── Fast-path stop detection (#3487) ──
@@ -45,6 +45,7 @@ import { classifyProject, type ProjectClassification } from "./detection.js";
45
45
  import { hasBrowserRequiredText } from "./browser-evidence.js";
46
46
  import { debugLog } from "./debug-logger.js";
47
47
  import { buildSkillActivationBlock, buildSkillDiscoveryVars } from "./skill-activation.js";
48
+ import { findMilestoneIds } from "./milestone-ids.js";
48
49
 
49
50
  export { buildSkillActivationBlock, buildSkillDiscoveryVars };
50
51
 
@@ -1428,7 +1429,7 @@ export async function checkNeedsRunUat(
1428
1429
  // If the UAT file already contains a verdict, UAT has been run — skip
1429
1430
  if (hasVerdict(uatContent)) continue;
1430
1431
  // Also check the ASSESSMENT file — the run-uat prompt writes the verdict
1431
- // there (via gsd_summary_save artifact_type:"ASSESSMENT"), not into the
1432
+ // there (via gsd_uat_result_save), not into the
1432
1433
  // UAT spec file. Without this check the unit re-dispatches indefinitely.
1433
1434
  const assessmentFile = resolveSliceFile(base, mid, sid, "ASSESSMENT");
1434
1435
  if (assessmentFile) {
@@ -1482,21 +1483,84 @@ export async function checkNeedsRunUat(
1482
1483
  * as a seed when present. The discussion agent interviews the user, writes
1483
1484
  * a full CONTEXT.md, and the phase transitions to pre-planning automatically.
1484
1485
  */
1486
+ export interface DiscussMilestonePromptOptions {
1487
+ headless?: boolean;
1488
+ commitInstruction?: string;
1489
+ fastPathInstruction?: string;
1490
+ includeDraftSeed?: boolean;
1491
+ includeContextMode?: boolean;
1492
+ }
1493
+
1494
+ export async function buildDiscussMilestoneInlinedContext(mid: string, base: string): Promise<string> {
1495
+ const inlined: string[] = [];
1496
+
1497
+ const roadmapInline = await inlineFileOptional(
1498
+ resolveMilestoneFile(base, mid, "ROADMAP"),
1499
+ relMilestoneFile(base, mid, "ROADMAP"),
1500
+ "Milestone Roadmap",
1501
+ );
1502
+ if (roadmapInline) inlined.push(roadmapInline);
1503
+
1504
+ const contextInline = await inlineFileOptional(
1505
+ resolveMilestoneFile(base, mid, "CONTEXT"),
1506
+ relMilestoneFile(base, mid, "CONTEXT"),
1507
+ "Milestone Context",
1508
+ );
1509
+ if (contextInline) inlined.push(contextInline);
1510
+
1511
+ const researchInline = await inlineFileOptional(
1512
+ resolveMilestoneFile(base, mid, "RESEARCH"),
1513
+ relMilestoneFile(base, mid, "RESEARCH"),
1514
+ "Milestone Research",
1515
+ );
1516
+ if (researchInline) inlined.push(researchInline);
1517
+
1518
+ const decisionsPath = resolveGsdRootFile(base, "DECISIONS");
1519
+ if (existsSync(decisionsPath)) {
1520
+ const decisionsContent = await loadFile(decisionsPath);
1521
+ if (decisionsContent) {
1522
+ inlined.push(`### Decisions Register\nSource: \`${relGsdRootFile("DECISIONS")}\`\n\n${decisionsContent.trim()}`);
1523
+ }
1524
+ }
1525
+
1526
+ const milestoneIds = findMilestoneIds(base);
1527
+ const currentIndex = milestoneIds.indexOf(mid);
1528
+ const priorMilestoneIds = currentIndex >= 0 ? milestoneIds.slice(0, currentIndex) : milestoneIds;
1529
+ for (const priorMid of priorMilestoneIds) {
1530
+ const summaryInline = await inlineFileOptional(
1531
+ resolveMilestoneFile(base, priorMid, "SUMMARY"),
1532
+ relMilestoneFile(base, priorMid, "SUMMARY"),
1533
+ `${priorMid} Prior Milestone Summary`,
1534
+ );
1535
+ if (summaryInline) inlined.push(summaryInline);
1536
+ }
1537
+
1538
+ return inlined.length > 0
1539
+ ? `## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}`
1540
+ : "## Inlined Context\n\n_(no milestone context files found yet — go in blind and ask broad questions)_";
1541
+ }
1542
+
1485
1543
  export async function buildDiscussMilestonePrompt(
1486
1544
  mid: string,
1487
1545
  midTitle: string,
1488
1546
  base: string,
1489
1547
  structuredQuestionsAvailable = "false",
1490
- { headless = false }: { headless?: boolean } = {},
1548
+ {
1549
+ headless = false,
1550
+ commitInstruction = "Do not commit planning artifacts — .gsd/ is managed externally.",
1551
+ fastPathInstruction = "",
1552
+ includeDraftSeed = true,
1553
+ includeContextMode = true,
1554
+ }: DiscussMilestonePromptOptions = {},
1491
1555
  ): Promise<string> {
1492
- const discussTemplates = inlineTemplate("context", "Context");
1556
+ const contextTemplate = inlineTemplate("context", "Context");
1493
1557
 
1494
1558
  if (headless) {
1495
1559
  const roadmapPath = resolveMilestoneFile(base, mid, "ROADMAP");
1496
1560
  const roadmapContent = roadmapPath ? await loadFile(roadmapPath) : null;
1497
1561
  return loadPrompt("discuss-headless", {
1498
1562
  seedContext: roadmapContent ?? "",
1499
- inlinedTemplates: discussTemplates,
1563
+ inlinedTemplates: contextTemplate,
1500
1564
  workingDirectory: base,
1501
1565
  milestoneId: mid,
1502
1566
  contextPath: relMilestoneFile(base, mid, "CONTEXT"),
@@ -1505,7 +1569,9 @@ export async function buildDiscussMilestonePrompt(
1505
1569
  });
1506
1570
  }
1507
1571
 
1508
- const contextModeInstructions = renderContextModeForPrompt("discuss-milestone", base);
1572
+ const rawInlinedContext = await buildDiscussMilestoneInlinedContext(mid, base);
1573
+ const cappedInlinedContext = capPreamble(rawInlinedContext);
1574
+ const discussTemplates = [cappedInlinedContext, contextTemplate].join("\n\n---\n\n");
1509
1575
 
1510
1576
  const basePrompt = loadPrompt("guided-discuss-milestone", {
1511
1577
  workingDirectory: base,
@@ -1513,20 +1579,22 @@ export async function buildDiscussMilestonePrompt(
1513
1579
  milestoneTitle: midTitle,
1514
1580
  inlinedTemplates: discussTemplates,
1515
1581
  structuredQuestionsAvailable,
1516
- commitInstruction: "Do not commit planning artifacts — .gsd/ is managed externally.",
1517
- fastPathInstruction: "",
1582
+ commitInstruction,
1583
+ fastPathInstruction,
1518
1584
  });
1519
- const promptWithContextMode = prependContextModeToBlock("discuss-milestone", base, basePrompt);
1585
+ const promptWithContextMode = includeContextMode
1586
+ ? prependContextModeToBlock("discuss-milestone", base, basePrompt)
1587
+ : basePrompt;
1520
1588
 
1521
1589
  // If a CONTEXT-DRAFT.md exists, append it as seed material
1522
1590
  const draftPath = resolveMilestoneFile(base, mid, "CONTEXT-DRAFT");
1523
1591
  const draftContent = draftPath ? await loadFile(draftPath) : null;
1524
1592
 
1525
- if (draftContent) {
1593
+ if (includeDraftSeed && draftContent) {
1526
1594
  return `${promptWithContextMode}\n\n## Prior Discussion (Draft Seed)\n\nThe following draft was captured from a prior multi-milestone discussion. Use it as seed material — the user has already provided this context. Start with a brief reflection on what the draft covers, then probe for any gaps or open questions before writing the full CONTEXT.md.\n\n${draftContent}`;
1527
1595
  }
1528
1596
 
1529
- return contextModeInstructions ? promptWithContextMode : basePrompt;
1597
+ return promptWithContextMode;
1530
1598
  }
1531
1599
 
1532
1600
  /**
@@ -2711,6 +2779,15 @@ export async function buildCompleteSlicePrompt(
2711
2779
  sliceSummaryPath,
2712
2780
  sliceUatPath,
2713
2781
  gatesToClose,
2782
+ skillActivation: buildSkillActivationBlock({
2783
+ base,
2784
+ milestoneId: mid,
2785
+ milestoneTitle: midTitle,
2786
+ sliceId: sid,
2787
+ sliceTitle: sTitle,
2788
+ extraContext: [inlinedContext],
2789
+ unitType: "complete-slice",
2790
+ }),
2714
2791
  });
2715
2792
  }
2716
2793
 
@@ -2909,13 +2986,23 @@ export async function buildValidateMilestonePrompt(
2909
2986
  if (isDbAvailable()) {
2910
2987
  const milestone = getMilestone(mid);
2911
2988
  if (milestone) {
2989
+ const escapeCell = (value: string) =>
2990
+ value.replace(/[\\|]/g, (char) => `\\${char}`).replace(/\r?\n/g, " ");
2912
2991
  const classes: string[] = [];
2913
- if (milestone.verification_contract) classes.push(`- **Contract:** ${milestone.verification_contract}`);
2914
- if (milestone.verification_integration) classes.push(`- **Integration:** ${milestone.verification_integration}`);
2915
- if (milestone.verification_operational) classes.push(`- **Operational:** ${milestone.verification_operational}`);
2916
- if (milestone.verification_uat) classes.push(`- **UAT:** ${milestone.verification_uat}`);
2992
+ if (milestone.verification_contract) classes.push(`| Contract | ${escapeCell(milestone.verification_contract)} |`);
2993
+ if (milestone.verification_integration) classes.push(`| Integration | ${escapeCell(milestone.verification_integration)} |`);
2994
+ if (milestone.verification_operational) classes.push(`| Operational | ${escapeCell(milestone.verification_operational)} |`);
2995
+ if (milestone.verification_uat) classes.push(`| UAT | ${escapeCell(milestone.verification_uat)} |`);
2917
2996
  if (classes.length > 0) {
2918
- const verificationClasses = `### Verification Classes (from planning)\n\nThese verification tiers were defined during milestone planning. Each non-empty class must be checked for evidence during validation.\n\n${classes.join("\n")}`;
2997
+ const verificationClasses = [
2998
+ "### Verification Classes (from planning)",
2999
+ "",
3000
+ "These verification tiers were defined during milestone planning. Every row in this table must appear in `verificationClasses` with the same canonical class name.",
3001
+ "",
3002
+ "| Class | Planned Check |",
3003
+ "| --- | --- |",
3004
+ ...classes,
3005
+ ].join("\n");
2919
3006
  inlined.push(verificationClasses);
2920
3007
  trackPromptContext(contextTelemetry, "verification-classes", "inline", verificationClasses);
2921
3008
  }
@@ -867,7 +867,7 @@ export function buildLoopRemediationSteps(
867
867
  return [
868
868
  ` 1. Run \`gsd undo-task ${mid}/${sid}/${tid}\` to reset the task state`,
869
869
  ` 2. Resume auto-mode — it will re-execute the task`,
870
- ` 3. If the task keeps failing, run \`gsd recover\` to rebuild DB state from disk`,
870
+ ` 3. If the task keeps failing and markdown should repopulate the DB, run \`gsd recover --confirm\``,
871
871
  ].join("\n");
872
872
  }
873
873
  case "plan-slice":
@@ -879,7 +879,7 @@ export function buildLoopRemediationSteps(
879
879
  : relSliceFile(base, mid, sid, "RESEARCH");
880
880
  return [
881
881
  ` 1. Write ${artifactRel} manually (or with the LLM in interactive mode)`,
882
- ` 2. Run \`gsd recover\` to rebuild DB state from disk`,
882
+ ` 2. Run \`gsd recover --confirm\` to import the markdown into the DB`,
883
883
  ` 3. Resume auto-mode`,
884
884
  ].join("\n");
885
885
  }
@@ -888,7 +888,7 @@ export function buildLoopRemediationSteps(
888
888
  return [
889
889
  ` 1. Run \`gsd reset-slice ${mid}/${sid}\` to reset the slice and all its tasks`,
890
890
  ` 2. Resume auto-mode — it will re-execute incomplete tasks and re-complete the slice`,
891
- ` 3. If the slice keeps failing, run \`gsd recover\` to rebuild DB state from disk`,
891
+ ` 3. If the slice keeps failing and markdown should repopulate the DB, run \`gsd recover --confirm\``,
892
892
  ].join("\n");
893
893
  }
894
894
  case "validate-milestone": {
@@ -896,7 +896,7 @@ export function buildLoopRemediationSteps(
896
896
  const artifactRel = relMilestoneFile(base, mid, "VALIDATION");
897
897
  return [
898
898
  ` 1. Write ${artifactRel} with verdict: pass`,
899
- ` 2. Run \`gsd recover\` to rebuild DB state from disk`,
899
+ ` 2. Run \`gsd recover --confirm\` to import the markdown into the DB`,
900
900
  ` 3. Resume auto-mode`,
901
901
  ].join("\n");
902
902
  }
@@ -42,6 +42,10 @@ export function isAutoPaused(): boolean {
42
42
  return autoSession.paused;
43
43
  }
44
44
 
45
+ export function isAutoCompletionStopInProgress(): boolean {
46
+ return autoSession.completionStopInProgress;
47
+ }
48
+
45
49
  export function markToolStart(toolCallId: string, toolName?: string): void {
46
50
  markTrackedToolStart(toolCallId, autoSession.active, toolName);
47
51
  }