@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
@@ -32,7 +32,7 @@ import { isDbAvailable, getDbPath, refreshOpenDatabaseFromDisk, getTask, getSlic
32
32
  import { renderPlanCheckboxes, renderRoadmapFromDb } from "./markdown-renderer.js";
33
33
  import { parseRoadmap as parseLegacyRoadmap } from "./parsers-legacy.js";
34
34
  import { consumeSignal } from "./session-status-io.js";
35
- import { checkPostUnitHooks, isRetryPending, consumeRetryTrigger, persistHookState, resolveHookArtifactPath, } from "./post-unit-hooks.js";
35
+ import { checkPostUnitHooks, consumeHookFailure, isRetryPending, consumeRetryTrigger, consumeGateBlock, persistHookState, resolveHookArtifactPath, } from "./post-unit-hooks.js";
36
36
  import { hasPendingCaptures, loadPendingCaptures, revertExecutorResolvedCaptures } from "./captures.js";
37
37
  import { debugLog } from "./debug-logger.js";
38
38
  import { runSafely } from "./auto-utils.js";
@@ -323,6 +323,41 @@ function stripKnownIdPrefix(value, id) {
323
323
  return raw.slice(id.length + 1).trim() || undefined;
324
324
  return raw;
325
325
  }
326
+ function parseReactiveBatchTaskIds(unitId) {
327
+ const { task: batchPart } = parseUnitId(unitId);
328
+ if (!batchPart?.startsWith("reactive+"))
329
+ return [];
330
+ const rawIds = batchPart
331
+ .slice("reactive+".length)
332
+ .split(",")
333
+ .map((taskId) => taskId.trim().toUpperCase())
334
+ .filter(Boolean);
335
+ const unique = new Set();
336
+ for (const taskId of rawIds) {
337
+ unique.add(taskId);
338
+ }
339
+ return [...unique];
340
+ }
341
+ function dedupePaths(values) {
342
+ const seen = new Set();
343
+ const result = [];
344
+ for (const value of values) {
345
+ if (!seen.has(value)) {
346
+ seen.add(value);
347
+ result.push(value);
348
+ }
349
+ }
350
+ return result;
351
+ }
352
+ function getPlannedKeyFiles(tasks) {
353
+ return dedupePaths(tasks.flatMap((taskRow) => [
354
+ ...(taskRow.expected_output ?? []),
355
+ ...(taskRow.files ?? []),
356
+ ...(taskRow.key_files ?? []),
357
+ ]));
358
+ }
359
+ export const _parseReactiveBatchTaskIdsForTest = parseReactiveBatchTaskIds;
360
+ export const _getPlannedKeyFilesForTest = getPlannedKeyFiles;
326
361
  function resolveVerificationFailureMarkerPath(unitType, unitId, basePath) {
327
362
  const { milestone: mid, slice: sid, task: tid } = parseUnitId(unitId);
328
363
  switch (unitType) {
@@ -402,6 +437,34 @@ async function buildTaskCommitContextForUnit(basePath, unitId) {
402
437
  issueNumber: ghIssueNumber,
403
438
  };
404
439
  }
440
+ async function buildReactiveTaskCommitContext(_basePath, unitId) {
441
+ const { milestone: mid, slice: sid } = parseUnitId(unitId);
442
+ if (!mid || !sid || !isDbAvailable())
443
+ return undefined;
444
+ const batchTaskIds = parseReactiveBatchTaskIds(unitId);
445
+ if (batchTaskIds.length === 0)
446
+ return undefined;
447
+ const milestone = getMilestone(mid);
448
+ const slice = getSlice(mid, sid);
449
+ const taskRows = batchTaskIds
450
+ .map((tid) => getTask(mid, sid, tid))
451
+ .filter((taskRow) => taskRow !== null);
452
+ const keyFiles = getPlannedKeyFiles(taskRows);
453
+ if (taskRows.length === 0 || keyFiles.length === 0)
454
+ return undefined;
455
+ const taskLabel = taskRows.map((row) => row.id).join(",");
456
+ return {
457
+ taskId: `${sid}/${taskLabel}`,
458
+ taskDisplayId: "reactive-batch",
459
+ taskTitle: `Reactive batch: ${taskLabel}`,
460
+ milestoneId: mid,
461
+ milestoneTitle: stripKnownIdPrefix(milestone?.title, mid),
462
+ sliceId: sid,
463
+ sliceTitle: stripKnownIdPrefix(slice?.title, sid),
464
+ oneLiner: `Reactive execute for ${taskLabel}`,
465
+ keyFiles,
466
+ };
467
+ }
405
468
  async function runPostUnitGitHubSyncIfNeeded(basePath, unit) {
406
469
  if (unit.type === "complete-milestone")
407
470
  return;
@@ -761,6 +824,9 @@ export async function autoCommitUnit(basePath, unitType, unitId, ctx) {
761
824
  if (unitType === "execute-task") {
762
825
  taskContext = await buildTaskCommitContextForUnit(basePath, unitId);
763
826
  }
827
+ else if (unitType === "reactive-execute") {
828
+ taskContext = await buildReactiveTaskCommitContext(basePath, unitId);
829
+ }
764
830
  _resetHasChangesCache();
765
831
  if (LIFECYCLE_ONLY_UNITS.has(unitType)) {
766
832
  return null;
@@ -812,6 +878,22 @@ async function runCloseoutGitAction(pctx, unit, opts) {
812
878
  targetRepositories = getTask(mid, sid, tid)?.target_repositories;
813
879
  }
814
880
  }
881
+ else if (turnAction === "commit" && unit.type === "reactive-execute") {
882
+ taskContext = await buildReactiveTaskCommitContext(s.basePath, unit.id);
883
+ const { milestone: mid, slice: sid } = parseUnitId(unit.id);
884
+ if (mid && sid && isDbAvailable()) {
885
+ const repositories = new Set();
886
+ for (const tid of parseReactiveBatchTaskIds(unit.id)) {
887
+ const taskRow = getTask(mid, sid, tid);
888
+ for (const repoId of taskRow?.target_repositories ?? []) {
889
+ repositories.add(repoId);
890
+ }
891
+ }
892
+ if (repositories.size > 0) {
893
+ targetRepositories = [...repositories];
894
+ }
895
+ }
896
+ }
815
897
  // Invalidate the nativeHasChanges cache before auto-commit (#1853).
816
898
  // The cache has a 10-second TTL and is keyed by basePath. A stale
817
899
  // `false` result causes autoCommit to skip staging entirely.
@@ -1206,12 +1288,19 @@ export async function postUnitPreVerification(pctx, opts) {
1206
1288
  if (safetyConfig.enabled) {
1207
1289
  const { milestone: sMid, slice: sSid, task: sTid } = parseUnitId(s.currentUnit.id);
1208
1290
  // File change validation (execute-task only, after unit execution)
1209
- if (safetyConfig.file_change_validation && s.currentUnit.type === "execute-task" && sMid && sSid && sTid && isDbAvailable()) {
1291
+ if (safetyConfig.file_change_validation && s.currentUnit.type === "execute-task" && sMid && sSid && sTid) {
1210
1292
  try {
1211
- const taskRow = getTask(sMid, sSid, sTid);
1212
- if (taskRow) {
1213
- const expectedOutput = taskRow.expected_output ?? [];
1214
- const plannedFiles = taskRow.files ?? [];
1293
+ const sliceTaskRows = isDbAvailable()
1294
+ ? getSliceTasks(sMid, sSid).filter((t) => isClosedStatus(t.status) || t.id === sTid)
1295
+ : [];
1296
+ if (sliceTaskRows.length > 0) {
1297
+ const expectedOutput = getPlannedKeyFiles(sliceTaskRows.map((taskRow) => ({
1298
+ expected_output: taskRow.expected_output,
1299
+ files: taskRow.files,
1300
+ })));
1301
+ const plannedFiles = getPlannedKeyFiles(sliceTaskRows.map((taskRow) => ({
1302
+ files: taskRow.files,
1303
+ })));
1215
1304
  const audit = validateFileChanges(s.basePath, expectedOutput, plannedFiles, safetyConfig.file_change_allowlist);
1216
1305
  if (audit && audit.violations.length > 0) {
1217
1306
  const warnings = audit.violations.filter(v => v.severity === "warning");
@@ -1223,6 +1312,23 @@ export async function postUnitPreVerification(pctx, opts) {
1223
1312
  }
1224
1313
  }
1225
1314
  }
1315
+ else {
1316
+ const taskRow = getTask(sMid, sSid, sTid);
1317
+ if (taskRow) {
1318
+ const expectedOutput = taskRow.expected_output ?? [];
1319
+ const plannedFiles = taskRow.files ?? [];
1320
+ const audit = validateFileChanges(s.basePath, expectedOutput, plannedFiles, safetyConfig.file_change_allowlist);
1321
+ if (audit && audit.violations.length > 0) {
1322
+ const warnings = audit.violations.filter(v => v.severity === "warning");
1323
+ for (const v of warnings) {
1324
+ logWarning("safety", `file-change: ${v.file} — ${v.reason}`);
1325
+ }
1326
+ if (warnings.length > 0) {
1327
+ ctx.ui.notify(`Safety: ${warnings.length} unexpected file change(s) outside task plan`, "warning");
1328
+ }
1329
+ }
1330
+ }
1331
+ }
1226
1332
  }
1227
1333
  catch (e) {
1228
1334
  debugLog("postUnit", { phase: "safety-file-change", error: String(e) });
@@ -1754,18 +1860,25 @@ export async function postUnitPostVerification(pctx) {
1754
1860
  // ── Post-unit hooks ──
1755
1861
  if (s.currentUnit && !s.stepMode) {
1756
1862
  const hookUnit = checkPostUnitHooks(s.currentUnit.type, s.currentUnit.id, s.basePath);
1863
+ persistHookState(s.basePath);
1757
1864
  if (hookUnit) {
1758
1865
  if (s.currentUnit) {
1759
1866
  await closeoutUnit(ctx, s.basePath, s.currentUnit.type, s.currentUnit.id, s.currentUnit.startedAt, buildSnapshotOpts(s.currentUnit.type, s.currentUnit.id));
1760
1867
  }
1761
- persistHookState(s.basePath);
1762
1868
  return enqueueSidecar(s, ctx, { kind: "hook", unitType: hookUnit.unitType, unitId: hookUnit.unitId, prompt: hookUnit.prompt, model: hookUnit.model }, { hookName: hookUnit.hookName });
1763
1869
  }
1870
+ const hookFailure = consumeHookFailure();
1871
+ if (hookFailure) {
1872
+ ctx.ui.notify(`Post-unit hook ${hookFailure.hookName} failed for ${hookFailure.unitId}: ${hookFailure.reason}. Pausing auto-mode.`, "warning");
1873
+ await pauseAuto(ctx, pi);
1874
+ return "stopped";
1875
+ }
1764
1876
  // Check if a hook requested a retry of the trigger unit
1765
1877
  if (isRetryPending()) {
1766
1878
  const trigger = consumeRetryTrigger();
1767
1879
  if (trigger) {
1768
- ctx.ui.notify(`Hook requested retry of ${trigger.unitType} ${trigger.unitId} — resetting task state.`, "info");
1880
+ persistHookState(s.basePath);
1881
+ ctx.ui.notify(`Hook requested retry of ${trigger.unitType} ${trigger.unitId} — resetting trigger unit state.`, "info");
1769
1882
  await s.orchestration?.retryActiveUnit({
1770
1883
  unitType: trigger.unitType,
1771
1884
  unitId: trigger.unitId,
@@ -1781,8 +1894,8 @@ export async function postUnitPostVerification(pctx) {
1781
1894
  }
1782
1895
  catch (dbErr) {
1783
1896
  // DB unavailable — fail explicitly rather than silently reverting to markdown mutation.
1784
- // Use 'gsd recover' to rebuild DB state from disk if needed.
1785
- logError("engine", `retry state-reset failed (DB unavailable): ${dbErr.message}. Run 'gsd recover' to reconcile.`);
1897
+ // Use 'gsd recover --confirm' to import markdown into the DB if needed.
1898
+ logError("engine", `retry state-reset failed (DB unavailable): ${dbErr.message}. Run 'gsd recover --confirm' to import markdown into the DB.`);
1786
1899
  }
1787
1900
  }
1788
1901
  // 2. Delete SUMMARY.md for the task
@@ -1812,6 +1925,17 @@ export async function postUnitPostVerification(pctx) {
1812
1925
  // Fall through to normal dispatch — deriveState will re-derive the unit
1813
1926
  }
1814
1927
  }
1928
+ const gateBlock = consumeGateBlock();
1929
+ if (gateBlock) {
1930
+ persistHookState(s.basePath);
1931
+ const verdict = gateBlock.verdict ? ` verdict=${gateBlock.verdict};` : "";
1932
+ const artifact = gateBlock.artifact ? ` artifact=${gateBlock.artifact};` : "";
1933
+ const message = `Post-unit gate "${gateBlock.hookName}" blocked ${gateBlock.triggerUnitType} ${gateBlock.triggerUnitId}:` +
1934
+ `${verdict}${artifact} ${gateBlock.reason}. Run /gsd status to inspect, then /gsd auto after recovery.`;
1935
+ ctx.ui.notify(message, "warning");
1936
+ await pauseAuto(ctx, pi);
1937
+ return "stopped";
1938
+ }
1815
1939
  }
1816
1940
  // ── Fast-path stop detection (#3487) ──
1817
1941
  // Before waiting for triage, check if any PENDING captures contain explicit
@@ -30,6 +30,7 @@ import { classifyProject } from "./detection.js";
30
30
  import { hasBrowserRequiredText } from "./browser-evidence.js";
31
31
  import { debugLog } from "./debug-logger.js";
32
32
  import { buildSkillActivationBlock, buildSkillDiscoveryVars } from "./skill-activation.js";
33
+ import { findMilestoneIds } from "./milestone-ids.js";
33
34
  export { buildSkillActivationBlock, buildSkillDiscoveryVars };
34
35
  // ─── Preamble Cap ─────────────────────────────────────────────────────────────
35
36
  /**
@@ -1270,7 +1271,7 @@ export async function checkNeedsRunUat(base, mid, state, prefs) {
1270
1271
  if (hasVerdict(uatContent))
1271
1272
  continue;
1272
1273
  // Also check the ASSESSMENT file — the run-uat prompt writes the verdict
1273
- // there (via gsd_summary_save artifact_type:"ASSESSMENT"), not into the
1274
+ // there (via gsd_uat_result_save), not into the
1274
1275
  // UAT spec file. Without this check the unit re-dispatches indefinitely.
1275
1276
  const assessmentFile = resolveSliceFile(base, mid, sid, "ASSESSMENT");
1276
1277
  if (assessmentFile) {
@@ -1325,21 +1326,44 @@ export async function checkNeedsRunUat(base, mid, state, prefs) {
1325
1326
  }
1326
1327
  return null;
1327
1328
  }
1328
- // ─── Prompt Builders ──────────────────────────────────────────────────────
1329
- /**
1330
- * Build a prompt for the discuss-milestone unit type.
1331
- * Loads the guided-discuss-milestone template and inlines the CONTEXT-DRAFT
1332
- * as a seed when present. The discussion agent interviews the user, writes
1333
- * a full CONTEXT.md, and the phase transitions to pre-planning automatically.
1334
- */
1335
- export async function buildDiscussMilestonePrompt(mid, midTitle, base, structuredQuestionsAvailable = "false", { headless = false } = {}) {
1336
- const discussTemplates = inlineTemplate("context", "Context");
1329
+ export async function buildDiscussMilestoneInlinedContext(mid, base) {
1330
+ const inlined = [];
1331
+ const roadmapInline = await inlineFileOptional(resolveMilestoneFile(base, mid, "ROADMAP"), relMilestoneFile(base, mid, "ROADMAP"), "Milestone Roadmap");
1332
+ if (roadmapInline)
1333
+ inlined.push(roadmapInline);
1334
+ const contextInline = await inlineFileOptional(resolveMilestoneFile(base, mid, "CONTEXT"), relMilestoneFile(base, mid, "CONTEXT"), "Milestone Context");
1335
+ if (contextInline)
1336
+ inlined.push(contextInline);
1337
+ const researchInline = await inlineFileOptional(resolveMilestoneFile(base, mid, "RESEARCH"), relMilestoneFile(base, mid, "RESEARCH"), "Milestone Research");
1338
+ if (researchInline)
1339
+ inlined.push(researchInline);
1340
+ const decisionsPath = resolveGsdRootFile(base, "DECISIONS");
1341
+ if (existsSync(decisionsPath)) {
1342
+ const decisionsContent = await loadFile(decisionsPath);
1343
+ if (decisionsContent) {
1344
+ inlined.push(`### Decisions Register\nSource: \`${relGsdRootFile("DECISIONS")}\`\n\n${decisionsContent.trim()}`);
1345
+ }
1346
+ }
1347
+ const milestoneIds = findMilestoneIds(base);
1348
+ const currentIndex = milestoneIds.indexOf(mid);
1349
+ const priorMilestoneIds = currentIndex >= 0 ? milestoneIds.slice(0, currentIndex) : milestoneIds;
1350
+ for (const priorMid of priorMilestoneIds) {
1351
+ const summaryInline = await inlineFileOptional(resolveMilestoneFile(base, priorMid, "SUMMARY"), relMilestoneFile(base, priorMid, "SUMMARY"), `${priorMid} Prior Milestone Summary`);
1352
+ if (summaryInline)
1353
+ inlined.push(summaryInline);
1354
+ }
1355
+ return inlined.length > 0
1356
+ ? `## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}`
1357
+ : "## Inlined Context\n\n_(no milestone context files found yet — go in blind and ask broad questions)_";
1358
+ }
1359
+ export async function buildDiscussMilestonePrompt(mid, midTitle, base, structuredQuestionsAvailable = "false", { headless = false, commitInstruction = "Do not commit planning artifacts — .gsd/ is managed externally.", fastPathInstruction = "", includeDraftSeed = true, includeContextMode = true, } = {}) {
1360
+ const contextTemplate = inlineTemplate("context", "Context");
1337
1361
  if (headless) {
1338
1362
  const roadmapPath = resolveMilestoneFile(base, mid, "ROADMAP");
1339
1363
  const roadmapContent = roadmapPath ? await loadFile(roadmapPath) : null;
1340
1364
  return loadPrompt("discuss-headless", {
1341
1365
  seedContext: roadmapContent ?? "",
1342
- inlinedTemplates: discussTemplates,
1366
+ inlinedTemplates: contextTemplate,
1343
1367
  workingDirectory: base,
1344
1368
  milestoneId: mid,
1345
1369
  contextPath: relMilestoneFile(base, mid, "CONTEXT"),
@@ -1347,24 +1371,28 @@ export async function buildDiscussMilestonePrompt(mid, midTitle, base, structure
1347
1371
  multiMilestoneCommitInstruction: "Do not commit planning artifacts — .gsd/ is managed externally.",
1348
1372
  });
1349
1373
  }
1350
- const contextModeInstructions = renderContextModeForPrompt("discuss-milestone", base);
1374
+ const rawInlinedContext = await buildDiscussMilestoneInlinedContext(mid, base);
1375
+ const cappedInlinedContext = capPreamble(rawInlinedContext);
1376
+ const discussTemplates = [cappedInlinedContext, contextTemplate].join("\n\n---\n\n");
1351
1377
  const basePrompt = loadPrompt("guided-discuss-milestone", {
1352
1378
  workingDirectory: base,
1353
1379
  milestoneId: mid,
1354
1380
  milestoneTitle: midTitle,
1355
1381
  inlinedTemplates: discussTemplates,
1356
1382
  structuredQuestionsAvailable,
1357
- commitInstruction: "Do not commit planning artifacts — .gsd/ is managed externally.",
1358
- fastPathInstruction: "",
1383
+ commitInstruction,
1384
+ fastPathInstruction,
1359
1385
  });
1360
- const promptWithContextMode = prependContextModeToBlock("discuss-milestone", base, basePrompt);
1386
+ const promptWithContextMode = includeContextMode
1387
+ ? prependContextModeToBlock("discuss-milestone", base, basePrompt)
1388
+ : basePrompt;
1361
1389
  // If a CONTEXT-DRAFT.md exists, append it as seed material
1362
1390
  const draftPath = resolveMilestoneFile(base, mid, "CONTEXT-DRAFT");
1363
1391
  const draftContent = draftPath ? await loadFile(draftPath) : null;
1364
- if (draftContent) {
1392
+ if (includeDraftSeed && draftContent) {
1365
1393
  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}`;
1366
1394
  }
1367
- return contextModeInstructions ? promptWithContextMode : basePrompt;
1395
+ return promptWithContextMode;
1368
1396
  }
1369
1397
  /**
1370
1398
  * Build a prompt for the workflow-preferences unit type (deep mode).
@@ -2351,6 +2379,15 @@ export async function buildCompleteSlicePrompt(mid, midTitle, sid, sTitle, base,
2351
2379
  sliceSummaryPath,
2352
2380
  sliceUatPath,
2353
2381
  gatesToClose,
2382
+ skillActivation: buildSkillActivationBlock({
2383
+ base,
2384
+ milestoneId: mid,
2385
+ milestoneTitle: midTitle,
2386
+ sliceId: sid,
2387
+ sliceTitle: sTitle,
2388
+ extraContext: [inlinedContext],
2389
+ unitType: "complete-slice",
2390
+ }),
2354
2391
  });
2355
2392
  }
2356
2393
  export async function buildCompleteMilestonePrompt(mid, midTitle, base, level) {
@@ -2531,17 +2568,26 @@ export async function buildValidateMilestonePrompt(mid, midTitle, base, level) {
2531
2568
  if (isDbAvailable()) {
2532
2569
  const milestone = getMilestone(mid);
2533
2570
  if (milestone) {
2571
+ const escapeCell = (value) => value.replace(/[\\|]/g, (char) => `\\${char}`).replace(/\r?\n/g, " ");
2534
2572
  const classes = [];
2535
2573
  if (milestone.verification_contract)
2536
- classes.push(`- **Contract:** ${milestone.verification_contract}`);
2574
+ classes.push(`| Contract | ${escapeCell(milestone.verification_contract)} |`);
2537
2575
  if (milestone.verification_integration)
2538
- classes.push(`- **Integration:** ${milestone.verification_integration}`);
2576
+ classes.push(`| Integration | ${escapeCell(milestone.verification_integration)} |`);
2539
2577
  if (milestone.verification_operational)
2540
- classes.push(`- **Operational:** ${milestone.verification_operational}`);
2578
+ classes.push(`| Operational | ${escapeCell(milestone.verification_operational)} |`);
2541
2579
  if (milestone.verification_uat)
2542
- classes.push(`- **UAT:** ${milestone.verification_uat}`);
2580
+ classes.push(`| UAT | ${escapeCell(milestone.verification_uat)} |`);
2543
2581
  if (classes.length > 0) {
2544
- 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")}`;
2582
+ const verificationClasses = [
2583
+ "### Verification Classes (from planning)",
2584
+ "",
2585
+ "These verification tiers were defined during milestone planning. Every row in this table must appear in `verificationClasses` with the same canonical class name.",
2586
+ "",
2587
+ "| Class | Planned Check |",
2588
+ "| --- | --- |",
2589
+ ...classes,
2590
+ ].join("\n");
2545
2591
  inlined.push(verificationClasses);
2546
2592
  trackPromptContext(contextTelemetry, "verification-classes", "inline", verificationClasses);
2547
2593
  }
@@ -802,7 +802,7 @@ export function buildLoopRemediationSteps(unitType, unitId, base) {
802
802
  return [
803
803
  ` 1. Run \`gsd undo-task ${mid}/${sid}/${tid}\` to reset the task state`,
804
804
  ` 2. Resume auto-mode — it will re-execute the task`,
805
- ` 3. If the task keeps failing, run \`gsd recover\` to rebuild DB state from disk`,
805
+ ` 3. If the task keeps failing and markdown should repopulate the DB, run \`gsd recover --confirm\``,
806
806
  ].join("\n");
807
807
  }
808
808
  case "plan-slice":
@@ -814,7 +814,7 @@ export function buildLoopRemediationSteps(unitType, unitId, base) {
814
814
  : relSliceFile(base, mid, sid, "RESEARCH");
815
815
  return [
816
816
  ` 1. Write ${artifactRel} manually (or with the LLM in interactive mode)`,
817
- ` 2. Run \`gsd recover\` to rebuild DB state from disk`,
817
+ ` 2. Run \`gsd recover --confirm\` to import the markdown into the DB`,
818
818
  ` 3. Resume auto-mode`,
819
819
  ].join("\n");
820
820
  }
@@ -824,7 +824,7 @@ export function buildLoopRemediationSteps(unitType, unitId, base) {
824
824
  return [
825
825
  ` 1. Run \`gsd reset-slice ${mid}/${sid}\` to reset the slice and all its tasks`,
826
826
  ` 2. Resume auto-mode — it will re-execute incomplete tasks and re-complete the slice`,
827
- ` 3. If the slice keeps failing, run \`gsd recover\` to rebuild DB state from disk`,
827
+ ` 3. If the slice keeps failing and markdown should repopulate the DB, run \`gsd recover --confirm\``,
828
828
  ].join("\n");
829
829
  }
830
830
  case "validate-milestone": {
@@ -833,7 +833,7 @@ export function buildLoopRemediationSteps(unitType, unitId, base) {
833
833
  const artifactRel = relMilestoneFile(base, mid, "VALIDATION");
834
834
  return [
835
835
  ` 1. Write ${artifactRel} with verdict: pass`,
836
- ` 2. Run \`gsd recover\` to rebuild DB state from disk`,
836
+ ` 2. Run \`gsd recover --confirm\` to import the markdown into the DB`,
837
837
  ` 3. Resume auto-mode`,
838
838
  ].join("\n");
839
839
  }
@@ -20,6 +20,9 @@ export function isAutoActive() {
20
20
  export function isAutoPaused() {
21
21
  return autoSession.paused;
22
22
  }
23
+ export function isAutoCompletionStopInProgress() {
24
+ return autoSession.completionStopInProgress;
25
+ }
23
26
  export function markToolStart(toolCallId, toolName) {
24
27
  markTrackedToolStart(toolCallId, autoSession.active, toolName);
25
28
  }
@@ -28,12 +28,13 @@ import { getAutoWorktreePath, checkoutBranchWithStashGuard } from "./auto-worktr
28
28
  import { readResourceVersion, cleanStaleRuntimeUnits } from "./auto-worktree.js";
29
29
  import { worktreePath as getWorktreeDir, isInsideWorktreesDir } from "./worktree-manager.js";
30
30
  import { emitWorktreeOrphaned } from "./worktree-telemetry.js";
31
+ import { queryJournal } from "./journal.js";
31
32
  import { initMetrics } from "./metrics.js";
32
33
  import { initRoutingHistory } from "./routing-history.js";
33
34
  import { restoreHookState, resetHookState } from "./post-unit-hooks.js";
34
35
  import { resetProactiveHealing, setLevelChangeCallback } from "./doctor-proactive.js";
35
36
  import { snapshotSkills } from "./skill-discovery.js";
36
- import { isDbAvailable, getMilestone, getAllMilestones, insertMilestone, openDatabase, getDbStatus } from "./gsd-db.js";
37
+ import { isDbAvailable, getMilestone, getAllMilestones, insertMilestone, openDatabase, getDbStatus, updateMilestoneStatus } from "./gsd-db.js";
37
38
  import { isClosedStatus } from "./status-guards.js";
38
39
  import { classifyMilestoneSummaryContent } from "./milestone-summary-classifier.js";
39
40
  import { extractVerdict } from "./verdict-parser.js";
@@ -48,6 +49,7 @@ import { resolveProjectRootDbPath } from "./bootstrap/dynamic-tools.js";
48
49
  import { validateDirectory } from "./validate-directory.js";
49
50
  import { isCustomProvider, resolveDefaultSessionModel, resolveDynamicRoutingConfig, } from "./preferences-models.js";
50
51
  import { getSessionModelOverride } from "./session-model-override.js";
52
+ import { setAutoActiveStatus } from "./auto-dashboard.js";
51
53
  export function resolveIsolationNoneBranchCheckout(currentBranch, integrationBranch, isolationMode, isRepo) {
52
54
  if (!isRepo || isolationMode !== "none")
53
55
  return null;
@@ -112,6 +114,40 @@ export function reconcileProjectMilestonesFromDisk(basePath) {
112
114
  return 0;
113
115
  }
114
116
  }
117
+ export function reconcileMergedMilestonesFromJournal(basePath) {
118
+ if (!isDbAvailable())
119
+ return 0;
120
+ const mergedAtByMilestone = new Map();
121
+ for (const entry of queryJournal(basePath, { eventType: "worktree-merged" })) {
122
+ const data = entry.data ?? {};
123
+ const milestoneId = typeof data.milestoneId === "string" ? data.milestoneId : null;
124
+ if (!milestoneId)
125
+ continue;
126
+ if (data.conflict === true)
127
+ continue;
128
+ const endedAt = typeof data.endedAt === "string" ? data.endedAt : entry.ts;
129
+ const previous = mergedAtByMilestone.get(milestoneId);
130
+ if (!previous || endedAt > previous)
131
+ mergedAtByMilestone.set(milestoneId, endedAt);
132
+ }
133
+ let closed = 0;
134
+ for (const [milestoneId, completedAt] of mergedAtByMilestone) {
135
+ const existing = getMilestone(milestoneId);
136
+ if (!existing) {
137
+ insertMilestone({ id: milestoneId, title: milestoneId, status: "complete" });
138
+ updateMilestoneStatus(milestoneId, "complete", completedAt);
139
+ closed++;
140
+ continue;
141
+ }
142
+ if (!isClosedStatus(existing.status)) {
143
+ updateMilestoneStatus(milestoneId, "complete", completedAt);
144
+ closed++;
145
+ }
146
+ }
147
+ if (closed > 0)
148
+ invalidateAllCaches();
149
+ return closed;
150
+ }
115
151
  export function decideSurvivorAction(hasSurvivorBranch, phase) {
116
152
  if (!hasSurvivorBranch)
117
153
  return "none";
@@ -129,6 +165,19 @@ export function resolveSurvivorRecoveryIsolationMode(isolationMode, phase) {
129
165
  function isBlockingStrandedWorkAction(action) {
130
166
  return action.kind === "in-progress-stranded-work" && action.blocksAuto;
131
167
  }
168
+ function strandedWorkEvidence(args) {
169
+ const evidence = [];
170
+ if (args.branch && args.commitsAhead > 0) {
171
+ evidence.push(`branch ${args.branch} has ${args.commitsAhead} commit(s) ahead of ${args.mainBranch}`);
172
+ }
173
+ if (args.dirtyWorktree) {
174
+ evidence.push("the worktree has uncommitted changes");
175
+ }
176
+ if (evidence.length === 0) {
177
+ evidence.push("physical git evidence exists");
178
+ }
179
+ return evidence;
180
+ }
132
181
  function detectWorktreeEvidence(basePath, milestoneId, hasChanges) {
133
182
  const wtDir = getWorktreeDir(basePath, milestoneId);
134
183
  const wtPath = getAutoWorktreePath(basePath, milestoneId);
@@ -148,16 +197,7 @@ function detectWorktreeEvidence(basePath, milestoneId, hasChanges) {
148
197
  };
149
198
  }
150
199
  function strandedWorkMessage(args) {
151
- const evidence = [];
152
- if (args.branch && args.commitsAhead > 0) {
153
- evidence.push(`branch ${args.branch} has ${args.commitsAhead} commit(s) ahead of ${args.mainBranch}`);
154
- }
155
- if (args.dirtyWorktree) {
156
- evidence.push("the worktree has uncommitted changes");
157
- }
158
- if (evidence.length === 0) {
159
- evidence.push("physical git evidence exists");
160
- }
200
+ const evidence = strandedWorkEvidence(args);
161
201
  const wtSuffix = args.worktreeDirExists
162
202
  ? ` Worktree directory at .gsd/worktrees/${args.milestoneId}/ holds live work.`
163
203
  : "";
@@ -168,6 +208,37 @@ function strandedWorkMessage(args) {
168
208
  wtSuffix +
169
209
  ` ${recovery} Park or discard explicitly if abandoning.`);
170
210
  }
211
+ function formatStrandedWorkRecoveryMessage(action) {
212
+ const recoveryMode = action.recoveryMode === "worktree"
213
+ ? "existing worktree"
214
+ : "milestone branch";
215
+ const evidence = strandedWorkEvidence({
216
+ branch: action.branch,
217
+ commitsAhead: action.commitsAhead ?? 0,
218
+ mainBranch: action.mainBranch ?? "main",
219
+ dirtyWorktree: action.dirtyWorktree ?? false,
220
+ });
221
+ const wtSuffix = action.worktreeDirExists
222
+ ? ` Worktree directory at .gsd/worktrees/${action.milestoneId}/ holds live work.`
223
+ : "";
224
+ return (`Resuming saved milestone work for ${action.milestoneId}: ${evidence.join("; ")}.` +
225
+ wtSuffix +
226
+ ` Adopting the ${recoveryMode} before dispatching new units. Park or discard explicitly if abandoning.`);
227
+ }
228
+ function formatStrandedWorkBlockerMessage(action, activeMilestoneId) {
229
+ const target = action.milestoneId;
230
+ const mode = action.recoveryMode === "worktree" ? "existing worktree" : "milestone branch";
231
+ const intro = activeMilestoneId
232
+ ? `Stranded work for ${target} blocks auto-mode before ${activeMilestoneId}.`
233
+ : `Stranded work for ${target} blocks auto-mode, but that milestone is not active in project state.`;
234
+ return [
235
+ intro,
236
+ "Choose one explicit next step:",
237
+ `1. Recover it: run \`/gsd auto ${target}\` to adopt the ${mode}.`,
238
+ `2. Defer it: run \`/gsd park ${target} "reason"\`, then rerun \`/gsd auto\`.`,
239
+ `3. Abandon it: run \`/gsd rethink\` and explicitly discard ${target}.`,
240
+ ].join("\n");
241
+ }
171
242
  export function auditOrphanedMilestoneBranches(basePath, _isolationMode, gitDeps = {}) {
172
243
  const recovered = [];
173
244
  const warnings = [];
@@ -258,6 +329,7 @@ export function auditOrphanedMilestoneBranches(basePath, _isolationMode, gitDeps
258
329
  kind: "in-progress-stranded-work",
259
330
  milestoneId,
260
331
  branch,
332
+ mainBranch,
261
333
  commitsAhead,
262
334
  dirtyWorktree: worktreeEvidence.dirty,
263
335
  worktreeDirExists: worktreeEvidence.dirExists,
@@ -413,6 +485,7 @@ export function auditOrphanedMilestoneBranches(basePath, _isolationMode, gitDeps
413
485
  pushAction({
414
486
  kind: "in-progress-stranded-work",
415
487
  milestoneId: m.id,
488
+ mainBranch,
416
489
  commitsAhead: 0,
417
490
  dirtyWorktree: true,
418
491
  worktreeDirExists: worktreeEvidence.dirExists,
@@ -806,6 +879,7 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
806
879
  await openProjectDbIfPresent(base);
807
880
  registerAutoWorkerForSession(base);
808
881
  reconcileProjectMilestonesFromDisk(base);
882
+ reconcileMergedMilestonesFromJournal(base);
809
883
  // Clean stale runtime unit files for completed milestones (#887).
810
884
  // DB-authoritative: when DB is available, require DB status to be closed
811
885
  // before clearing runtime units. A SUMMARY file alone is no longer
@@ -840,7 +914,12 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
840
914
  for (const msg of auditResult.recovered) {
841
915
  ctx.ui.notify(`Orphan audit: ${msg}`, "info");
842
916
  }
917
+ const deferredStrandedMessages = new Set(auditResult.actions
918
+ .filter(isBlockingStrandedWorkAction)
919
+ .map((action) => action.message));
843
920
  for (const msg of auditResult.warnings) {
921
+ if (deferredStrandedMessages.has(msg))
922
+ continue;
844
923
  const prefix = msg.startsWith("Stranded work") ? "" : "Orphan audit: ";
845
924
  ctx.ui.notify(`${prefix}${msg}`, "warning");
846
925
  }
@@ -900,15 +979,15 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
900
979
  : strandedRecoveryAction;
901
980
  if (blockingStrandedRecoveryAction) {
902
981
  if (!state.activeMilestone) {
903
- ctx.ui.notify(`Stranded work for ${blockingStrandedRecoveryAction.milestoneId} blocks auto-mode, but that milestone is not active in project state. Park or discard it explicitly before continuing.`, "error");
982
+ ctx.ui.notify(formatStrandedWorkBlockerMessage(blockingStrandedRecoveryAction, null), "error");
904
983
  return releaseLockAndReturn();
905
984
  }
906
985
  if (state.activeMilestone.id !== blockingStrandedRecoveryAction.milestoneId) {
907
- ctx.ui.notify(`Stranded work for ${blockingStrandedRecoveryAction.milestoneId} blocks auto-mode before ${state.activeMilestone.id}. Recover, park, or discard ${blockingStrandedRecoveryAction.milestoneId} explicitly before continuing.`, "error");
986
+ ctx.ui.notify(formatStrandedWorkBlockerMessage(blockingStrandedRecoveryAction, state.activeMilestone.id), "error");
908
987
  return releaseLockAndReturn();
909
988
  }
910
989
  strandedRecoveryAction = blockingStrandedRecoveryAction;
911
- ctx.ui.notify(`Recovering stranded work for ${strandedRecoveryAction.milestoneId} before dispatching new units.`, "info");
990
+ ctx.ui.notify(formatStrandedWorkRecoveryMessage(strandedRecoveryAction), "info");
912
991
  }
913
992
  if (process.env.GSD_HEADLESS === "1" &&
914
993
  orphanAuditRecovered &&
@@ -1293,7 +1372,7 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
1293
1372
  if (resolveSkillDiscoveryMode(base) !== "off") {
1294
1373
  snapshotSkills();
1295
1374
  }
1296
- ctx.ui.setStatus("gsd-auto", s.stepMode ? "next" : "auto");
1375
+ setAutoActiveStatus(ctx, s.stepMode ? "next" : "auto");
1297
1376
  ctx.ui.setWidget("gsd-health", undefined);
1298
1377
  const modeLabel = s.stepMode ? "Step-mode" : "Auto-mode";
1299
1378
  const pendingCount = (state.registry ?? []).filter((m) => m.status !== "complete" && m.status !== "parked").length;
@@ -83,7 +83,7 @@ export function clearInFlightTools() {
83
83
  * from the tool handler. When these errors occur, retrying the same unit will
84
84
  * produce the same failure, so the retry loop must be broken.
85
85
  */
86
- const TOOL_INVOCATION_ERROR_RE = /Validation failed for tool|Expected ',' or '\}'(?: after property value)?(?: in JSON)?|Unexpected end of JSON|Unexpected token.*in JSON|does not provide an export named|Named export .* not found|Cannot find module|ERR_MODULE_NOT_FOUND|ERR_MODULE_NOT_EXPORTED|ERR_PACKAGE_PATH_NOT_EXPORTED/i;
86
+ const TOOL_INVOCATION_ERROR_RE = /Validation failed for tool|Input validation error|Invalid arguments for tool|MCP error -32602|No such tool available|Expected ',' or '\}'(?: after property value)?(?: in JSON)?|Unexpected end of JSON|Unexpected token.*in JSON|does not provide an export named|Named export .* not found|Cannot find module|ERR_MODULE_NOT_FOUND|ERR_MODULE_NOT_EXPORTED|ERR_PACKAGE_PATH_NOT_EXPORTED/i;
87
87
  const DETERMINISTIC_POLICY_ERROR_RE = /(?:^|\b)(?:HARD BLOCK:|Blocked: \/gsd queue is a planning tool|Direct writes to \.gsd\/STATE\.md and \.gsd\/gsd\.db are blocked|This is a mechanical gate)/i;
88
88
  /**
89
89
  * Returns true if the error message indicates a deterministic invocation or