@opengsd/gsd-pi 1.2.0-dev.e8563f58 → 1.2.0-dev.fbdca60b

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 (432) hide show
  1. package/dist/cli-model-override.d.ts +15 -0
  2. package/dist/cli-model-override.js +21 -0
  3. package/dist/cli.js +1 -18
  4. package/dist/loader.js +6 -4
  5. package/dist/register-agent-bundles.d.ts +11 -2
  6. package/dist/register-agent-bundles.js +18 -4
  7. package/dist/resource-loader.d.ts +10 -5
  8. package/dist/resource-loader.js +121 -6
  9. package/dist/resources/.managed-resources-content-hash +1 -1
  10. package/dist/resources/extensions/ask-user-questions.js +3 -2
  11. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +447 -215
  12. package/dist/resources/extensions/claude-code-cli/turn-assembler.js +33 -1
  13. package/dist/resources/extensions/gsd/auto/closeout.js +215 -0
  14. package/dist/resources/extensions/gsd/auto/dispatch-history.js +21 -6
  15. package/dist/resources/extensions/gsd/auto/dispatch.js +365 -0
  16. package/dist/resources/extensions/gsd/auto/finalize.js +347 -0
  17. package/dist/resources/extensions/gsd/auto/loop.js +4 -1
  18. package/dist/resources/extensions/gsd/auto/milestone-lease-reclaim.js +56 -0
  19. package/dist/resources/extensions/gsd/auto/orchestrator.js +85 -15
  20. package/dist/resources/extensions/gsd/auto/phase-helpers.js +146 -0
  21. package/dist/resources/extensions/gsd/auto/phases.js +17 -2329
  22. package/dist/resources/extensions/gsd/auto/pre-dispatch.js +534 -0
  23. package/dist/resources/extensions/gsd/auto/session.js +3 -0
  24. package/dist/resources/extensions/gsd/auto/unit-phase.js +694 -0
  25. package/dist/resources/extensions/gsd/auto/workflow-unit-dispatch.js +1 -1
  26. package/dist/resources/extensions/gsd/auto/worktree-safety-phase.js +125 -0
  27. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +3 -2
  28. package/dist/resources/extensions/gsd/auto-dispatch.js +11 -2
  29. package/dist/resources/extensions/gsd/auto-post-unit.js +18 -6
  30. package/dist/resources/extensions/gsd/auto-start.js +23 -3
  31. package/dist/resources/extensions/gsd/auto-unit-closeout.js +45 -21
  32. package/dist/resources/extensions/gsd/auto-verification.js +14 -2
  33. package/dist/resources/extensions/gsd/auto-worktree.js +15 -2
  34. package/dist/resources/extensions/gsd/auto.js +45 -2
  35. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +37 -7
  36. package/dist/resources/extensions/gsd/commands/context.js +16 -2
  37. package/dist/resources/extensions/gsd/commands-mcp-status.js +2 -2
  38. package/dist/resources/extensions/gsd/commands-workflow-templates.js +9 -2
  39. package/dist/resources/extensions/gsd/crash-recovery.js +8 -3
  40. package/dist/resources/extensions/gsd/db/engine.js +24 -6
  41. package/dist/resources/extensions/gsd/db/queries.js +30 -0
  42. package/dist/resources/extensions/gsd/db-migration-backup.js +51 -8
  43. package/dist/resources/extensions/gsd/db-transaction.js +27 -23
  44. package/dist/resources/extensions/gsd/db-writer.js +8 -17
  45. package/dist/resources/extensions/gsd/doctor-engine-checks.js +5 -5
  46. package/dist/resources/extensions/gsd/doctor-environment.js +256 -125
  47. package/dist/resources/extensions/gsd/gsd-db.js +15 -20
  48. package/dist/resources/extensions/gsd/guided-flow.js +93 -4
  49. package/dist/resources/extensions/gsd/health-widget.js +87 -28
  50. package/dist/resources/extensions/gsd/mcp-bridge.js +10 -0
  51. package/dist/resources/extensions/gsd/memory-relations.js +1 -1
  52. package/dist/resources/extensions/gsd/milestone-planning-persistence.js +2 -2
  53. package/dist/resources/extensions/gsd/milestone-reopen-events.js +3 -5
  54. package/dist/resources/extensions/gsd/milestone-settlement.js +2 -2
  55. package/dist/resources/extensions/gsd/notifications.js +12 -7
  56. package/dist/resources/extensions/gsd/projection-flush.js +7 -0
  57. package/dist/resources/extensions/gsd/prompts/complete-slice.md +2 -2
  58. package/dist/resources/extensions/gsd/prompts/execute-task.md +3 -2
  59. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  60. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  61. package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -1
  62. package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
  63. package/dist/resources/extensions/gsd/prompts/refine-slice.md +1 -1
  64. package/dist/resources/extensions/gsd/prompts/replan-slice.md +1 -1
  65. package/dist/resources/extensions/gsd/prompts/research-milestone.md +1 -1
  66. package/dist/resources/extensions/gsd/prompts/research-slice.md +1 -1
  67. package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  68. package/dist/resources/extensions/gsd/prompts/run-uat.md +3 -1
  69. package/dist/resources/extensions/gsd/prompts/triage-captures.md +1 -1
  70. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +1 -1
  71. package/dist/resources/extensions/gsd/prompts/workflow-start.md +2 -1
  72. package/dist/resources/extensions/gsd/roadmap-slices.js +25 -3
  73. package/dist/resources/extensions/gsd/session-lock.js +1 -1
  74. package/dist/resources/extensions/gsd/skill-activation.js +3 -6
  75. package/dist/resources/extensions/gsd/state.js +6 -2
  76. package/dist/resources/extensions/gsd/tool-contract.js +14 -3
  77. package/dist/resources/extensions/gsd/tool-surface-readiness.js +83 -31
  78. package/dist/resources/extensions/gsd/tools/complete-milestone.js +3 -2
  79. package/dist/resources/extensions/gsd/tools/complete-slice.js +2 -2
  80. package/dist/resources/extensions/gsd/tools/complete-task.js +65 -2
  81. package/dist/resources/extensions/gsd/tools/plan-slice.js +2 -2
  82. package/dist/resources/extensions/gsd/tools/plan-task.js +2 -2
  83. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +2 -2
  84. package/dist/resources/extensions/gsd/tools/reopen-milestone.js +2 -2
  85. package/dist/resources/extensions/gsd/tools/reopen-slice.js +2 -2
  86. package/dist/resources/extensions/gsd/tools/reopen-task.js +2 -2
  87. package/dist/resources/extensions/gsd/tools/replan-slice.js +2 -2
  88. package/dist/resources/extensions/gsd/unit-context-composer.js +1 -1
  89. package/dist/resources/extensions/gsd/unit-registry.js +34 -4
  90. package/dist/resources/extensions/gsd/verification-verdict.js +2 -1
  91. package/dist/resources/extensions/gsd/workflow-event-ledger.js +91 -0
  92. package/dist/resources/extensions/gsd/workflow-event-vocabulary.js +46 -0
  93. package/dist/resources/extensions/gsd/workflow-events.js +6 -18
  94. package/dist/resources/extensions/gsd/workflow-mcp-auto-prep.js +2 -0
  95. package/dist/resources/extensions/gsd/workflow-mcp-readiness-cache.js +105 -0
  96. package/dist/resources/extensions/gsd/workflow-reconcile.js +21 -56
  97. package/dist/resources/extensions/gsd/worktree-manager.js +7 -1
  98. package/dist/resources/extensions/gsd/worktree-safety.js +28 -26
  99. package/dist/resources/extensions/gsd/worktree.js +8 -1
  100. package/dist/resources/extensions/mcp-client/manager.js +6 -1
  101. package/dist/resources/skills/create-skill/SKILL.md +3 -0
  102. package/dist/resources/skills/create-skill/references/skill-structure.md +1 -0
  103. package/dist/runtime-checks.d.ts +10 -0
  104. package/dist/runtime-checks.js +27 -0
  105. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  106. package/dist/web/standalone/.next/BUILD_ID +1 -1
  107. package/dist/web/standalone/.next/app-path-routes-manifest.json +7 -7
  108. package/dist/web/standalone/.next/build-manifest.json +2 -2
  109. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  110. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  111. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  112. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  113. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  114. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  115. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  116. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  117. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  118. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  119. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  120. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  121. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  122. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  123. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  124. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  125. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  126. package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
  127. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
  128. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
  129. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
  130. package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
  131. package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
  132. package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
  133. package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
  134. package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  135. package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
  136. package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  137. package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
  138. package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
  139. package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
  140. package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
  141. package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
  142. package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js.nft.json +1 -1
  143. package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
  144. package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
  145. package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  146. package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
  147. package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
  148. package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
  149. package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
  150. package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
  151. package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
  152. package/dist/web/standalone/.next/server/app/api/shutdown/route.js.nft.json +1 -1
  153. package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
  154. package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
  155. package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
  156. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
  157. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
  158. package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
  159. package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
  160. package/dist/web/standalone/.next/server/app/index.html +1 -1
  161. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  162. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  163. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  164. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  165. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  166. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  167. package/dist/web/standalone/.next/server/app-paths-manifest.json +7 -7
  168. package/dist/web/standalone/.next/server/chunks/{5942.js → 1128.js} +1 -1
  169. package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
  170. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  171. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  172. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  173. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  174. package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
  175. package/package.json +3 -3
  176. package/packages/cloud-mcp-gateway/package.json +2 -2
  177. package/packages/contracts/package.json +1 -1
  178. package/packages/daemon/package.json +4 -4
  179. package/packages/gsd-agent-core/dist/sdk.d.ts.map +1 -1
  180. package/packages/gsd-agent-core/dist/sdk.js +6 -4
  181. package/packages/gsd-agent-core/dist/sdk.js.map +1 -1
  182. package/packages/gsd-agent-core/package.json +5 -5
  183. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts +2 -0
  184. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  185. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js +10 -0
  186. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js.map +1 -1
  187. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +8 -0
  188. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  189. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +50 -6
  190. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  191. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts +2 -0
  192. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts.map +1 -1
  193. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js +34 -5
  194. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js.map +1 -1
  195. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts +1 -0
  196. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  197. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +17 -0
  198. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
  199. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.d.ts.map +1 -1
  200. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js +4 -0
  201. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js.map +1 -1
  202. package/packages/gsd-agent-modes/package.json +7 -7
  203. package/packages/mcp-server/README.md +12 -3
  204. package/packages/mcp-server/dist/cli-runner.d.ts +40 -0
  205. package/packages/mcp-server/dist/cli-runner.d.ts.map +1 -0
  206. package/packages/mcp-server/dist/cli-runner.js +137 -0
  207. package/packages/mcp-server/dist/cli-runner.js.map +1 -0
  208. package/packages/mcp-server/dist/cli.js +2 -53
  209. package/packages/mcp-server/dist/cli.js.map +1 -1
  210. package/packages/mcp-server/dist/pid-registry.d.ts +46 -0
  211. package/packages/mcp-server/dist/pid-registry.d.ts.map +1 -0
  212. package/packages/mcp-server/dist/pid-registry.js +459 -0
  213. package/packages/mcp-server/dist/pid-registry.js.map +1 -0
  214. package/packages/mcp-server/dist/probe-mode.d.ts +4 -0
  215. package/packages/mcp-server/dist/probe-mode.d.ts.map +1 -0
  216. package/packages/mcp-server/dist/probe-mode.js +10 -0
  217. package/packages/mcp-server/dist/probe-mode.js.map +1 -0
  218. package/packages/mcp-server/dist/stdio-watchdog.d.ts +8 -0
  219. package/packages/mcp-server/dist/stdio-watchdog.d.ts.map +1 -0
  220. package/packages/mcp-server/dist/stdio-watchdog.js +40 -0
  221. package/packages/mcp-server/dist/stdio-watchdog.js.map +1 -0
  222. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  223. package/packages/mcp-server/dist/workflow-tools.js +62 -43
  224. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  225. package/packages/mcp-server/package.json +5 -5
  226. package/packages/native/package.json +1 -1
  227. package/packages/pi-agent-core/dist/agent-loop.js +43 -2
  228. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  229. package/packages/pi-agent-core/package.json +1 -1
  230. package/packages/pi-ai/package.json +1 -1
  231. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +3 -0
  232. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  233. package/packages/pi-coding-agent/dist/core/settings-manager.js +11 -0
  234. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  235. package/packages/pi-coding-agent/dist/theme/theme.d.ts.map +1 -1
  236. package/packages/pi-coding-agent/dist/theme/theme.js +45 -17
  237. package/packages/pi-coding-agent/dist/theme/theme.js.map +1 -1
  238. package/packages/pi-coding-agent/package.json +7 -7
  239. package/packages/pi-tui/README.md +15 -0
  240. package/packages/pi-tui/dist/index.d.ts +2 -2
  241. package/packages/pi-tui/dist/index.d.ts.map +1 -1
  242. package/packages/pi-tui/dist/index.js +2 -2
  243. package/packages/pi-tui/dist/index.js.map +1 -1
  244. package/packages/pi-tui/dist/terminal-image.d.ts +33 -0
  245. package/packages/pi-tui/dist/terminal-image.d.ts.map +1 -1
  246. package/packages/pi-tui/dist/terminal-image.js +54 -2
  247. package/packages/pi-tui/dist/terminal-image.js.map +1 -1
  248. package/packages/pi-tui/dist/terminal.d.ts +12 -0
  249. package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
  250. package/packages/pi-tui/dist/terminal.js +70 -25
  251. package/packages/pi-tui/dist/terminal.js.map +1 -1
  252. package/packages/pi-tui/dist/tui.d.ts +15 -0
  253. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  254. package/packages/pi-tui/dist/tui.js +106 -21
  255. package/packages/pi-tui/dist/tui.js.map +1 -1
  256. package/packages/pi-tui/dist/utils.d.ts.map +1 -1
  257. package/packages/pi-tui/dist/utils.js +110 -36
  258. package/packages/pi-tui/dist/utils.js.map +1 -1
  259. package/packages/pi-tui/package.json +2 -2
  260. package/packages/rpc-client/package.json +2 -2
  261. package/pkg/dist/theme/theme.d.ts.map +1 -1
  262. package/pkg/dist/theme/theme.js +45 -17
  263. package/pkg/dist/theme/theme.js.map +1 -1
  264. package/pkg/package.json +1 -1
  265. package/src/resources/extensions/ask-user-questions.ts +7 -2
  266. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +531 -226
  267. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +672 -7
  268. package/src/resources/extensions/claude-code-cli/turn-assembler.ts +38 -1
  269. package/src/resources/extensions/gsd/auto/closeout.ts +309 -0
  270. package/src/resources/extensions/gsd/auto/dispatch-history.ts +22 -6
  271. package/src/resources/extensions/gsd/auto/dispatch.ts +449 -0
  272. package/src/resources/extensions/gsd/auto/finalize.ts +445 -0
  273. package/src/resources/extensions/gsd/auto/loop.ts +4 -1
  274. package/src/resources/extensions/gsd/auto/milestone-lease-reclaim.ts +74 -0
  275. package/src/resources/extensions/gsd/auto/orchestrator.ts +95 -15
  276. package/src/resources/extensions/gsd/auto/phase-helpers.ts +199 -0
  277. package/src/resources/extensions/gsd/auto/phases.ts +58 -3022
  278. package/src/resources/extensions/gsd/auto/pre-dispatch.ts +704 -0
  279. package/src/resources/extensions/gsd/auto/session.ts +3 -0
  280. package/src/resources/extensions/gsd/auto/unit-phase.ts +910 -0
  281. package/src/resources/extensions/gsd/auto/workflow-unit-dispatch.ts +1 -1
  282. package/src/resources/extensions/gsd/auto/worktree-safety-phase.ts +149 -0
  283. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +10 -16
  284. package/src/resources/extensions/gsd/auto-dispatch.ts +11 -10
  285. package/src/resources/extensions/gsd/auto-post-unit.ts +21 -6
  286. package/src/resources/extensions/gsd/auto-start.ts +24 -4
  287. package/src/resources/extensions/gsd/auto-unit-closeout.ts +83 -28
  288. package/src/resources/extensions/gsd/auto-verification.ts +18 -2
  289. package/src/resources/extensions/gsd/auto-worktree.ts +15 -2
  290. package/src/resources/extensions/gsd/auto.ts +56 -2
  291. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +56 -6
  292. package/src/resources/extensions/gsd/commands/context.ts +16 -2
  293. package/src/resources/extensions/gsd/commands-mcp-status.ts +2 -2
  294. package/src/resources/extensions/gsd/commands-workflow-templates.ts +11 -4
  295. package/src/resources/extensions/gsd/crash-recovery.ts +10 -2
  296. package/src/resources/extensions/gsd/db/engine.ts +26 -6
  297. package/src/resources/extensions/gsd/db/queries.ts +29 -0
  298. package/src/resources/extensions/gsd/db-migration-backup.ts +56 -7
  299. package/src/resources/extensions/gsd/db-transaction.ts +37 -20
  300. package/src/resources/extensions/gsd/db-writer.ts +11 -19
  301. package/src/resources/extensions/gsd/doctor-engine-checks.ts +5 -4
  302. package/src/resources/extensions/gsd/doctor-environment.ts +267 -142
  303. package/src/resources/extensions/gsd/gsd-db.ts +15 -19
  304. package/src/resources/extensions/gsd/guided-flow.ts +145 -24
  305. package/src/resources/extensions/gsd/health-widget.ts +91 -27
  306. package/src/resources/extensions/gsd/mcp-bridge.ts +39 -0
  307. package/src/resources/extensions/gsd/memory-relations.ts +1 -1
  308. package/src/resources/extensions/gsd/milestone-planning-persistence.ts +2 -2
  309. package/src/resources/extensions/gsd/milestone-reopen-events.ts +3 -6
  310. package/src/resources/extensions/gsd/milestone-settlement.ts +2 -2
  311. package/src/resources/extensions/gsd/notifications.ts +13 -6
  312. package/src/resources/extensions/gsd/projection-flush.ts +20 -0
  313. package/src/resources/extensions/gsd/prompts/complete-slice.md +2 -2
  314. package/src/resources/extensions/gsd/prompts/execute-task.md +3 -2
  315. package/src/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  316. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  317. package/src/resources/extensions/gsd/prompts/quick-task.md +1 -1
  318. package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
  319. package/src/resources/extensions/gsd/prompts/refine-slice.md +1 -1
  320. package/src/resources/extensions/gsd/prompts/replan-slice.md +1 -1
  321. package/src/resources/extensions/gsd/prompts/research-milestone.md +1 -1
  322. package/src/resources/extensions/gsd/prompts/research-slice.md +1 -1
  323. package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  324. package/src/resources/extensions/gsd/prompts/run-uat.md +3 -1
  325. package/src/resources/extensions/gsd/prompts/triage-captures.md +1 -1
  326. package/src/resources/extensions/gsd/prompts/validate-milestone.md +1 -1
  327. package/src/resources/extensions/gsd/prompts/workflow-start.md +2 -1
  328. package/src/resources/extensions/gsd/roadmap-slices.ts +28 -3
  329. package/src/resources/extensions/gsd/session-lock.ts +1 -1
  330. package/src/resources/extensions/gsd/skill-activation.ts +3 -6
  331. package/src/resources/extensions/gsd/state.ts +7 -1
  332. package/src/resources/extensions/gsd/tests/auto-abort-pause-regression.test.ts +1 -1
  333. package/src/resources/extensions/gsd/tests/auto-blocked-remediation-message.test.ts +1 -1
  334. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +206 -22
  335. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +6 -1
  336. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +76 -12
  337. package/src/resources/extensions/gsd/tests/auto-pause-double-entry-guard.test.ts +1 -1
  338. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +77 -1
  339. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +2 -1
  340. package/src/resources/extensions/gsd/tests/auto-remote-session-lock-cleanup.test.ts +65 -3
  341. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +236 -0
  342. package/src/resources/extensions/gsd/tests/auto-unit-closeout.test.ts +169 -1
  343. package/src/resources/extensions/gsd/tests/complete-task.test.ts +141 -5
  344. package/src/resources/extensions/gsd/tests/db-migration-backup.test.ts +68 -19
  345. package/src/resources/extensions/gsd/tests/db-transaction.test.ts +59 -0
  346. package/src/resources/extensions/gsd/tests/db-writer.test.ts +15 -4
  347. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +2 -1
  348. package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +62 -0
  349. package/src/resources/extensions/gsd/tests/discuss-routing-fixes.test.ts +12 -2
  350. package/src/resources/extensions/gsd/tests/dispatch-history.test.ts +55 -0
  351. package/src/resources/extensions/gsd/tests/dist-redirect.mjs +8 -0
  352. package/src/resources/extensions/gsd/tests/engine-interfaces-contract.test.ts +117 -91
  353. package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +113 -0
  354. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +19 -0
  355. package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +18 -6
  356. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +15 -0
  357. package/src/resources/extensions/gsd/tests/integration/doctor-environment-async.test.ts +104 -0
  358. package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +18 -0
  359. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +47 -16
  360. package/src/resources/extensions/gsd/tests/mcp-readiness-preflight.test.ts +205 -0
  361. package/src/resources/extensions/gsd/tests/mcp-status.test.ts +6 -5
  362. package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +1 -1
  363. package/src/resources/extensions/gsd/tests/milestone-report-path.test.ts +1 -1
  364. package/src/resources/extensions/gsd/tests/milestone-settlement.test.ts +92 -0
  365. package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +1 -1
  366. package/src/resources/extensions/gsd/tests/notifications.test.ts +64 -9
  367. package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +2 -2
  368. package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +5 -0
  369. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +1 -1
  370. package/src/resources/extensions/gsd/tests/phases-terminal-complete-idempotent.test.ts +242 -0
  371. package/src/resources/extensions/gsd/tests/plan-gate-failed-doctor-heal-hint.test.ts +3 -3
  372. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +63 -2
  373. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +10 -2
  374. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +2 -4
  375. package/src/resources/extensions/gsd/tests/remote-notification-from-desktop.test.ts +31 -81
  376. package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +68 -0
  377. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +26 -2
  378. package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +170 -48
  379. package/src/resources/extensions/gsd/tests/skill-activation.test.ts +20 -17
  380. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +7 -3
  381. package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +1 -1
  382. package/src/resources/extensions/gsd/tests/teardown-chdir-failure-clears-registry.test.ts +17 -0
  383. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +4 -2
  384. package/src/resources/extensions/gsd/tests/tool-surface-readiness.test.ts +184 -10
  385. package/src/resources/extensions/gsd/tests/tool-unavailable-retry.test.ts +33 -0
  386. package/src/resources/extensions/gsd/tests/transport-gate-double-complete.test.ts +139 -0
  387. package/src/resources/extensions/gsd/tests/uok-audit-unified.test.ts +8 -0
  388. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +1 -1
  389. package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +2 -0
  390. package/src/resources/extensions/gsd/tests/workflow-events.test.ts +19 -0
  391. package/src/resources/extensions/gsd/tests/workflow-mcp-readiness-cache.test.ts +119 -0
  392. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +65 -2
  393. package/src/resources/extensions/gsd/tests/workflow-phase-contract-matrix.test.ts +332 -0
  394. package/src/resources/extensions/gsd/tests/workflow-reconcile.test.ts +20 -0
  395. package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +92 -0
  396. package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +1 -1
  397. package/src/resources/extensions/gsd/tests/worktree-project-root-degrade.test.ts +1 -1
  398. package/src/resources/extensions/gsd/tests/worktree-safety-phase.test.ts +100 -0
  399. package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +72 -0
  400. package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +22 -0
  401. package/src/resources/extensions/gsd/tests/worktree.test.ts +18 -0
  402. package/src/resources/extensions/gsd/tool-contract.ts +38 -3
  403. package/src/resources/extensions/gsd/tool-surface-readiness.ts +126 -19
  404. package/src/resources/extensions/gsd/tools/complete-milestone.ts +3 -2
  405. package/src/resources/extensions/gsd/tools/complete-slice.ts +2 -2
  406. package/src/resources/extensions/gsd/tools/complete-task.ts +90 -2
  407. package/src/resources/extensions/gsd/tools/plan-slice.ts +2 -2
  408. package/src/resources/extensions/gsd/tools/plan-task.ts +2 -2
  409. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +2 -2
  410. package/src/resources/extensions/gsd/tools/reopen-milestone.ts +2 -2
  411. package/src/resources/extensions/gsd/tools/reopen-slice.ts +2 -2
  412. package/src/resources/extensions/gsd/tools/reopen-task.ts +2 -2
  413. package/src/resources/extensions/gsd/tools/replan-slice.ts +2 -2
  414. package/src/resources/extensions/gsd/unit-context-composer.ts +1 -1
  415. package/src/resources/extensions/gsd/unit-registry.ts +34 -4
  416. package/src/resources/extensions/gsd/verification-verdict.ts +4 -2
  417. package/src/resources/extensions/gsd/workflow-event-ledger.ts +131 -0
  418. package/src/resources/extensions/gsd/workflow-event-vocabulary.ts +59 -0
  419. package/src/resources/extensions/gsd/workflow-events.ts +12 -20
  420. package/src/resources/extensions/gsd/workflow-mcp-auto-prep.ts +2 -0
  421. package/src/resources/extensions/gsd/workflow-mcp-readiness-cache.ts +150 -0
  422. package/src/resources/extensions/gsd/workflow-reconcile.ts +29 -62
  423. package/src/resources/extensions/gsd/worktree-manager.ts +6 -1
  424. package/src/resources/extensions/gsd/worktree-safety.ts +41 -39
  425. package/src/resources/extensions/gsd/worktree.ts +7 -1
  426. package/src/resources/extensions/mcp-client/manager.ts +7 -1
  427. package/src/resources/skills/create-skill/SKILL.md +3 -0
  428. package/src/resources/skills/create-skill/references/skill-structure.md +1 -0
  429. package/dist/resources/skills/gsd-browser/SKILL.md +0 -41
  430. package/src/resources/skills/gsd-browser/SKILL.md +0 -41
  431. /package/dist/web/standalone/.next/static/{LDHRKiRBIVZmiuMjrL1Vy → 2T9IOdiiM3o3gZ4UbPi8E}/_buildManifest.js +0 -0
  432. /package/dist/web/standalone/.next/static/{LDHRKiRBIVZmiuMjrL1Vy → 2T9IOdiiM3o3gZ4UbPi8E}/_ssgManifest.js +0 -0
@@ -0,0 +1,534 @@
1
+ // Project/App: gsd-pi
2
+ // File Purpose: Auto-loop pre-dispatch phase.
3
+ import { join } from "node:path";
4
+ import { existsSync, cpSync } from "node:fs";
5
+ import { basename } from "node:path";
6
+ import { UokGateRunner } from "../uok/gate-runner.js";
7
+ import { resolveUokFlags } from "../uok/flags.js";
8
+ import { ensurePlanV2Graph, isEmptyPlanV2GraphResult, isMissingFinalizedContextResult, } from "../uok/plan-v2.js";
9
+ import { getEligibleSlices } from "../slice-parallel-eligibility.js";
10
+ import { isSliceParallelActive, startSliceParallel } from "../slice-parallel-orchestrator.js";
11
+ import { reconcileBeforeSpawn } from "../state-reconciliation.js";
12
+ import { countUnmappedActiveRequirements, formatCompletePhaseNextAction, } from "../requirements-backlog.js";
13
+ import { isDbAvailable, getMilestoneSlices } from "../gsd-db.js";
14
+ import { gsdRoot } from "../paths.js";
15
+ import { atomicWriteSync } from "../atomic-write.js";
16
+ import { logWarning } from "../workflow-logger.js";
17
+ import { debugLog } from "../debug-logger.js";
18
+ import { persistStuckRecoveryAttempts, _resolveDispatchGuardBasePath, shouldRunPlanV2Gate, isSamePathLocal, } from "./phase-helpers.js";
19
+ import { closeoutAndStop, generateMilestoneReport, _runMilestoneMergeOnceWithStashRestore, shouldSkipTerminalMilestoneCloseout, } from "./closeout.js";
20
+ function classifyBlocker(blocker) {
21
+ const normalized = blocker.toLowerCase();
22
+ if (normalized.includes("needs-remediation") && normalized.includes("all slices are complete")) {
23
+ return "needs-remediation-dead-end";
24
+ }
25
+ return "other";
26
+ }
27
+ function sanitizeBlockerForUser(blocker) {
28
+ return blocker.replaceAll("gsd_reassess_roadmap", "/gsd dispatch reassess");
29
+ }
30
+ /**
31
+ * Formats blocked resume guidance for users, ensuring internal tool names are
32
+ * never surfaced in notification text.
33
+ */
34
+ function formatBlockedResumeMessage(blockers) {
35
+ const classifiedBlockers = blockers.map((blocker) => ({
36
+ blocker: sanitizeBlockerForUser(blocker),
37
+ kind: classifyBlocker(blocker),
38
+ }));
39
+ const hasNeedsRemediationDeadEnd = classifiedBlockers.some((classifiedBlocker) => classifiedBlocker.kind === "needs-remediation-dead-end");
40
+ if (hasNeedsRemediationDeadEnd) {
41
+ return "Blocked: milestone validation requires remediation but all slices are complete. Run /gsd dispatch reassess to add remediation slices, then /gsd auto to continue.";
42
+ }
43
+ return `Blocked: ${classifiedBlockers.map((classifiedBlocker) => classifiedBlocker.blocker).join(", ")}. Fix and run /gsd auto to resume.`;
44
+ }
45
+ /**
46
+ * Phase 1: Pre-dispatch — resource guard, health gate, state derivation,
47
+ * milestone transition, terminal conditions.
48
+ * Returns break to exit the loop, or next with PreDispatchData on success.
49
+ */
50
+ export async function runPreDispatch(ic, loopState) {
51
+ const { ctx, pi, s, deps, prefs } = ic;
52
+ const uokFlags = resolveUokFlags(prefs);
53
+ const runPreDispatchGate = async (input) => {
54
+ if (!uokFlags.gates)
55
+ return;
56
+ const gateRunner = new UokGateRunner();
57
+ gateRunner.register({
58
+ id: input.gateId,
59
+ type: input.gateType,
60
+ execute: async () => ({
61
+ outcome: input.outcome,
62
+ failureClass: input.failureClass,
63
+ rationale: input.rationale,
64
+ findings: input.findings ?? "",
65
+ }),
66
+ });
67
+ await gateRunner.run(input.gateId, {
68
+ basePath: s.basePath,
69
+ traceId: `pre-dispatch:${ic.flowId}`,
70
+ turnId: `iter-${ic.iteration}`,
71
+ milestoneId: input.milestoneId ?? s.currentMilestoneId ?? undefined,
72
+ unitType: "pre-dispatch",
73
+ unitId: `iter-${ic.iteration}`,
74
+ });
75
+ };
76
+ // Resource version guard
77
+ const staleMsg = deps.checkResourcesStale(s.resourceVersionOnStart);
78
+ if (staleMsg) {
79
+ await runPreDispatchGate({
80
+ gateId: "resource-version-guard",
81
+ gateType: "policy",
82
+ outcome: "fail",
83
+ failureClass: "policy",
84
+ rationale: "resource version guard blocked dispatch",
85
+ findings: staleMsg,
86
+ });
87
+ await deps.stopAuto(ctx, pi, staleMsg);
88
+ debugLog("autoLoop", { phase: "exit", reason: "resources-stale" });
89
+ return { action: "break", reason: "resources-stale" };
90
+ }
91
+ await runPreDispatchGate({
92
+ gateId: "resource-version-guard",
93
+ gateType: "policy",
94
+ outcome: "pass",
95
+ failureClass: "none",
96
+ rationale: "resource version guard passed",
97
+ });
98
+ deps.invalidateAllCaches();
99
+ s.lastPromptCharCount = undefined;
100
+ s.lastBaselineCharCount = undefined;
101
+ // Pre-dispatch health gate
102
+ try {
103
+ const expectedCurrentUnit = null;
104
+ const healthGate = await deps.preDispatchHealthGate(s.basePath);
105
+ if (healthGate.fixesApplied.length > 0) {
106
+ ctx.ui.notify(`Pre-dispatch: ${healthGate.fixesApplied.join(", ")}`, "info");
107
+ }
108
+ if (!healthGate.proceed) {
109
+ await runPreDispatchGate({
110
+ gateId: "pre-dispatch-health-gate",
111
+ gateType: "execution",
112
+ outcome: "manual-attention",
113
+ failureClass: "manual-attention",
114
+ rationale: "pre-dispatch health gate blocked dispatch",
115
+ findings: healthGate.reason,
116
+ });
117
+ ctx.ui.notify(healthGate.reason || "Pre-dispatch health check failed — run /gsd doctor for details.", "error");
118
+ await deps.pauseAuto(ctx, pi, undefined, { expectedCurrentUnit });
119
+ debugLog("autoLoop", { phase: "exit", reason: "health-gate-failed" });
120
+ return { action: "break", reason: "health-gate-failed" };
121
+ }
122
+ await runPreDispatchGate({
123
+ gateId: "pre-dispatch-health-gate",
124
+ gateType: "execution",
125
+ outcome: "pass",
126
+ failureClass: "none",
127
+ rationale: "pre-dispatch health gate passed",
128
+ findings: healthGate.fixesApplied.length > 0 ? healthGate.fixesApplied.join(", ") : "",
129
+ });
130
+ }
131
+ catch (e) {
132
+ await runPreDispatchGate({
133
+ gateId: "pre-dispatch-health-gate",
134
+ gateType: "execution",
135
+ outcome: "manual-attention",
136
+ failureClass: "manual-attention",
137
+ rationale: "pre-dispatch health gate threw unexpectedly",
138
+ findings: String(e),
139
+ });
140
+ logWarning("engine", "Pre-dispatch health gate threw unexpectedly", { error: String(e) });
141
+ }
142
+ // Sync project root artifacts into worktree
143
+ if (s.originalBasePath &&
144
+ !isSamePathLocal(s.basePath, s.originalBasePath) &&
145
+ s.currentMilestoneId &&
146
+ s.scope) {
147
+ deps.worktreeProjection.projectRootToWorktree(s.scope);
148
+ }
149
+ // Derive state — use canonical project root so the cache key is stable
150
+ // across worktree↔project-root path-form alternation. See PR #5236
151
+ // (workspace handle infrastructure) and the Phase A pt 2 plan.
152
+ let state = await deps.deriveState(s.canonicalProjectRoot);
153
+ const { getDeepStageGate } = await import("../auto-dispatch.js");
154
+ const deepStageGate = getDeepStageGate(prefs, s.basePath);
155
+ const canRunDeepSetupGate = state.phase === "pre-planning" ||
156
+ state.phase === "needs-discussion" ||
157
+ state.phase === "planning";
158
+ if (canRunDeepSetupGate &&
159
+ (deepStageGate.status === "pending" || deepStageGate.status === "blocked")) {
160
+ debugLog("autoLoop", {
161
+ phase: "deep-project-stage-gate",
162
+ stage: deepStageGate.stage,
163
+ status: deepStageGate.status,
164
+ reason: deepStageGate.reason,
165
+ });
166
+ return {
167
+ action: "next",
168
+ data: {
169
+ state: {
170
+ ...state,
171
+ phase: "pre-planning",
172
+ activeMilestone: null,
173
+ activeSlice: null,
174
+ activeTask: null,
175
+ nextAction: deepStageGate.reason,
176
+ },
177
+ mid: "PROJECT",
178
+ midTitle: "Project setup",
179
+ },
180
+ };
181
+ }
182
+ if (uokFlags.planV2 && shouldRunPlanV2Gate(state.phase)) {
183
+ let compiled = ensurePlanV2Graph(s.basePath, state);
184
+ if (isEmptyPlanV2GraphResult(compiled)) {
185
+ deps.invalidateAllCaches();
186
+ state = await deps.deriveState(s.canonicalProjectRoot);
187
+ compiled = shouldRunPlanV2Gate(state.phase)
188
+ ? ensurePlanV2Graph(s.basePath, state)
189
+ : {
190
+ ok: true,
191
+ reason: "empty plan-v2 graph recovered by state rederive",
192
+ nodeCount: 0,
193
+ };
194
+ }
195
+ if (!compiled.ok) {
196
+ const reason = compiled.reason ?? "Plan v2 compilation failed";
197
+ if (isMissingFinalizedContextResult(compiled)) {
198
+ await runPreDispatchGate({
199
+ gateId: "plan-v2-gate",
200
+ gateType: "policy",
201
+ outcome: "pass",
202
+ failureClass: "none",
203
+ rationale: "plan v2 missing context recovery deferred to dispatch",
204
+ findings: reason,
205
+ milestoneId: state.activeMilestone?.id ?? undefined,
206
+ });
207
+ }
208
+ else {
209
+ await runPreDispatchGate({
210
+ gateId: "plan-v2-gate",
211
+ gateType: "policy",
212
+ outcome: "manual-attention",
213
+ failureClass: "manual-attention",
214
+ rationale: "plan v2 compile gate failed",
215
+ findings: reason,
216
+ milestoneId: state.activeMilestone?.id ?? undefined,
217
+ });
218
+ ctx.ui.notify(`Plan gate failed-closed: ${reason}\n\nIf this keeps happening, try: /gsd doctor heal`, "error");
219
+ await deps.pauseAuto(ctx, pi);
220
+ return { action: "break", reason: "plan-v2-gate-failed" };
221
+ }
222
+ }
223
+ if (compiled.ok) {
224
+ await runPreDispatchGate({
225
+ gateId: "plan-v2-gate",
226
+ gateType: "policy",
227
+ outcome: "pass",
228
+ failureClass: "none",
229
+ rationale: "plan v2 compile gate passed",
230
+ milestoneId: state.activeMilestone?.id ?? undefined,
231
+ });
232
+ }
233
+ }
234
+ deps.syncCmuxSidebar(prefs, state);
235
+ let mid = state.activeMilestone?.id;
236
+ let midTitle = state.activeMilestone?.title;
237
+ debugLog("autoLoop", {
238
+ phase: "state-derived",
239
+ iteration: ic.iteration,
240
+ mid,
241
+ statePhase: state.phase,
242
+ });
243
+ // ── Slice-level parallelism gate (#2340) ─────────────────────────────
244
+ // When slice_parallel is enabled, check if multiple slices are eligible
245
+ // for parallel execution. If so, dispatch them in parallel and stop the
246
+ // sequential loop. Workers are spawned via slice-parallel-orchestrator.ts.
247
+ if (prefs?.slice_parallel?.enabled &&
248
+ mid &&
249
+ !process.env.GSD_PARALLEL_WORKER &&
250
+ isDbAvailable()) {
251
+ try {
252
+ const projectRoot = _resolveDispatchGuardBasePath(s);
253
+ if (isSliceParallelActive(projectRoot)) {
254
+ ctx.ui.notify("Slice-parallel: workers are still running; waiting for completion before next dispatch.", "info");
255
+ await new Promise((resolve) => setTimeout(resolve, 1000));
256
+ return { action: "continue" };
257
+ }
258
+ const dbSlices = getMilestoneSlices(mid);
259
+ if (dbSlices.length > 0) {
260
+ const doneIds = new Set(dbSlices.filter(sl => sl.status === "complete" || sl.status === "done").map(sl => sl.id));
261
+ const sliceInputs = dbSlices.map(sl => ({
262
+ id: sl.id,
263
+ done: doneIds.has(sl.id),
264
+ depends: sl.depends ?? [],
265
+ }));
266
+ const eligible = getEligibleSlices(sliceInputs, doneIds);
267
+ if (eligible.length > 1) {
268
+ debugLog("autoLoop", {
269
+ phase: "slice-parallel-dispatch",
270
+ iteration: ic.iteration,
271
+ mid,
272
+ eligibleSlices: eligible.map(e => e.id),
273
+ });
274
+ ctx.ui.notify(`Slice-parallel: dispatching ${eligible.length} eligible slices for ${mid}.`, "info");
275
+ // ADR-017 #5707: reconcile before spawning so each worker doesn't
276
+ // independently race on the same drift. Failure aborts the spawn.
277
+ const spawnGate = await reconcileBeforeSpawn(projectRoot);
278
+ if (!spawnGate.ok) {
279
+ ctx.ui.notify(`Slice-parallel: aborting spawn — ${spawnGate.reason}`, "error");
280
+ return { action: "break", reason: `slice-parallel-reconciliation-failed: ${spawnGate.reason}` };
281
+ }
282
+ const result = await startSliceParallel(projectRoot, mid, eligible, {
283
+ maxWorkers: prefs.slice_parallel.max_workers ?? 2,
284
+ useExecutionGraph: uokFlags.executionGraph,
285
+ });
286
+ if (result.started.length > 0) {
287
+ ctx.ui.notify(`Slice-parallel: started ${result.started.length} worker(s): ${result.started.join(", ")}.`, "info");
288
+ return { action: "continue" };
289
+ }
290
+ if (result.errors.length > 0) {
291
+ const detail = result.errors
292
+ .map((err) => `${err.sid}: ${err.error}`)
293
+ .join("; ");
294
+ ctx.ui.notify(`Slice-parallel startup failed; falling back to sequential execution. ${detail}`, "warning");
295
+ }
296
+ // Fall through to sequential if no workers started
297
+ }
298
+ }
299
+ }
300
+ catch (err) {
301
+ debugLog("autoLoop", {
302
+ phase: "slice-parallel-check-error",
303
+ error: err instanceof Error ? err.message : String(err),
304
+ });
305
+ // Non-fatal — fall through to sequential dispatch
306
+ }
307
+ }
308
+ // ── Milestone transition ────────────────────────────────────────────
309
+ if (mid && s.currentMilestoneId && mid !== s.currentMilestoneId) {
310
+ deps.emitJournalEvent({ ts: new Date().toISOString(), flowId: ic.flowId, seq: ic.nextSeq(), eventType: "milestone-transition", data: { from: s.currentMilestoneId, to: mid } });
311
+ ctx.ui.notify(`Milestone ${s.currentMilestoneId} complete. Advancing to ${mid}: ${midTitle}.`, "info");
312
+ deps.sendDesktopNotification("GSD", `Milestone ${s.currentMilestoneId} complete!`, "success", "milestone", basename(s.originalBasePath || s.basePath));
313
+ deps.logCmuxEvent(prefs, `Milestone ${s.currentMilestoneId} complete. Advancing to ${mid}.`, "success");
314
+ const vizPrefs = prefs;
315
+ if (vizPrefs?.auto_visualize) {
316
+ ctx.ui.notify("Run /gsd visualize to see progress overview.", "info");
317
+ }
318
+ if (vizPrefs?.auto_report !== false) {
319
+ try {
320
+ await generateMilestoneReport(s, ctx, s.currentMilestoneId);
321
+ }
322
+ catch (err) {
323
+ ctx.ui.notify(`Report generation failed: ${err instanceof Error ? err.message : String(err)}`, "warning");
324
+ }
325
+ }
326
+ // Reset dispatch counters for new milestone
327
+ s.unitDispatchCount.clear();
328
+ s.unitRecoveryCount.clear();
329
+ s.unitLifetimeDispatches.clear();
330
+ loopState.recentUnits.length = 0;
331
+ loopState.stuckRecoveryAttempts = 0;
332
+ persistStuckRecoveryAttempts(s, loopState);
333
+ // Worktree lifecycle on milestone transition — merge current, enter next.
334
+ // #2909 / #5538-followup: preflight stash + always-on postflight pop.
335
+ {
336
+ const stop = await _runMilestoneMergeOnceWithStashRestore(ic, s.currentMilestoneId);
337
+ if (stop)
338
+ return stop;
339
+ }
340
+ // PR creation (auto_pr) is handled inside mergeMilestoneToMain (#2302)
341
+ deps.invalidateAllCaches();
342
+ state = await deps.deriveState(s.canonicalProjectRoot);
343
+ mid = state.activeMilestone?.id;
344
+ midTitle = state.activeMilestone?.title;
345
+ if (mid) {
346
+ if (deps.getIsolationMode(s.basePath) !== "none") {
347
+ deps.captureIntegrationBranch(s.basePath, mid);
348
+ }
349
+ const enterResult = deps.lifecycle.enterMilestone(mid, ctx.ui);
350
+ if (!enterResult.ok) {
351
+ ctx.ui.notify(`Milestone transition stopped: failed to enter ${mid} (${enterResult.reason}).`, "error");
352
+ if (enterResult.reason === "lease-conflict") {
353
+ await deps.pauseAuto(ctx, pi);
354
+ }
355
+ return { action: "break", reason: "milestone-enter-failed" };
356
+ }
357
+ }
358
+ else {
359
+ // mid is undefined — no milestone to capture integration branch for
360
+ }
361
+ const pendingIds = state.registry
362
+ .filter((m) => m.status !== "complete" && m.status !== "parked")
363
+ .map((m) => m.id);
364
+ deps.pruneQueueOrder(s.basePath, pendingIds);
365
+ // Archive the old completed-units.json instead of wiping it (#2313).
366
+ try {
367
+ const completedKeysPath = join(gsdRoot(s.basePath), "completed-units.json");
368
+ if (existsSync(completedKeysPath) && s.currentMilestoneId) {
369
+ const archivePath = join(gsdRoot(s.basePath), `completed-units-${s.currentMilestoneId}.json`);
370
+ cpSync(completedKeysPath, archivePath);
371
+ }
372
+ atomicWriteSync(completedKeysPath, JSON.stringify([], null, 2));
373
+ }
374
+ catch (e) {
375
+ logWarning("engine", "Failed to archive completed-units on milestone transition", { error: String(e) });
376
+ }
377
+ // Rebuild STATE.md immediately so it reflects the new active milestone.
378
+ // This bypasses the 30-second throttle in the normal rebuild path —
379
+ // milestone transitions are rare and important enough to warrant an
380
+ // immediate write.
381
+ try {
382
+ await deps.rebuildState(s.basePath);
383
+ }
384
+ catch (e) {
385
+ logWarning("engine", "STATE.md rebuild failed after milestone transition", { error: String(e) });
386
+ }
387
+ // Re-project ROADMAP/PLAN markdown from the authoritative DB. Worktree DB
388
+ // reconciliation during merge can leave main-branch markdown stale relative
389
+ // to gsd.db (the 3M/3S/10T vs 3M/5S/16T drift class at /gsd startup).
390
+ try {
391
+ const { rebuildMarkdownProjectionsFromDb } = await import("../commands-maintenance.js");
392
+ await rebuildMarkdownProjectionsFromDb(s.canonicalProjectRoot);
393
+ if (s.basePath !== s.canonicalProjectRoot) {
394
+ await rebuildMarkdownProjectionsFromDb(s.basePath);
395
+ }
396
+ }
397
+ catch (e) {
398
+ logWarning("engine", "markdown projection rebuild failed after milestone transition", { error: String(e) });
399
+ }
400
+ }
401
+ if (mid) {
402
+ s.currentMilestoneId = mid;
403
+ deps.setActiveMilestoneId(s.basePath, mid);
404
+ }
405
+ // ── Terminal conditions ──────────────────────────────────────────────
406
+ if (state.phase === "complete") {
407
+ const closeoutSkip = await shouldSkipTerminalMilestoneCloseout(s, state, mid);
408
+ if (closeoutSkip.skip) {
409
+ debugLog("autoLoop", { phase: "complete", reason: "milestone-already-closed", milestoneId: closeoutSkip.milestoneId });
410
+ return { action: "break", reason: "milestone-complete" };
411
+ }
412
+ }
413
+ if (!mid) {
414
+ if (s.currentUnit) {
415
+ await deps.closeoutUnit(ctx, s.basePath, s.currentUnit.type, s.currentUnit.id, s.currentUnit.startedAt, deps.buildSnapshotOpts(s.currentUnit.type, s.currentUnit.id));
416
+ }
417
+ const incomplete = state.registry.filter((m) => m.status !== "complete" && m.status !== "parked");
418
+ if (incomplete.length === 0 && state.registry.length > 0) {
419
+ // All milestones complete — merge milestone branch before stopping.
420
+ if (s.currentMilestoneId) {
421
+ // #2909 / #5538-followup: preflight stash + always-on postflight pop.
422
+ const stop = await _runMilestoneMergeOnceWithStashRestore(ic, s.currentMilestoneId);
423
+ if (stop)
424
+ return stop;
425
+ // PR creation (auto_pr) is handled inside mergeMilestoneToMain (#2302)
426
+ }
427
+ const unmappedActive = countUnmappedActiveRequirements();
428
+ const completionStopReason = formatCompletePhaseNextAction(unmappedActive);
429
+ deps.sendDesktopNotification("GSD", unmappedActive > 0 ? "All milestones complete — requirements backlog remains" : "All milestones complete!", "success", "milestone", basename(s.originalBasePath || s.basePath));
430
+ deps.logCmuxEvent(prefs, completionStopReason, "success");
431
+ await deps.stopAuto(ctx, pi, completionStopReason, {
432
+ completionWidget: {
433
+ milestoneId: s.currentMilestoneId,
434
+ milestoneTitle: midTitle,
435
+ allMilestonesComplete: true,
436
+ },
437
+ });
438
+ }
439
+ else if (incomplete.length === 0 && state.registry.length === 0) {
440
+ // Empty registry — no milestones visible, likely a path resolution bug
441
+ const diag = `basePath=${s.basePath}, phase=${state.phase}`;
442
+ ctx.ui.notify(`No milestones visible in current scope. Possible path resolution issue.\n Diagnostic: ${diag}`, "error");
443
+ await deps.stopAuto(ctx, pi, `No milestones found — check basePath resolution`);
444
+ }
445
+ else if (state.phase === "blocked") {
446
+ const blockedResumeMessage = formatBlockedResumeMessage(state.blockers);
447
+ // Pause instead of hard-stop so the session is resumable with `/gsd auto`.
448
+ // Hard-stop here was causing premature termination when slice dependencies
449
+ // were temporarily unresolvable (e.g. after reassessment added new slices).
450
+ await deps.pauseAuto(ctx, pi);
451
+ ctx.ui.notify(blockedResumeMessage, "warning");
452
+ deps.sendDesktopNotification("GSD", blockedResumeMessage, "warning", "attention", basename(s.originalBasePath || s.basePath));
453
+ deps.logCmuxEvent(prefs, blockedResumeMessage, "warning");
454
+ }
455
+ else {
456
+ const ids = incomplete.map((m) => m.id).join(", ");
457
+ const diag = `basePath=${s.basePath}, milestones=[${state.registry.map((m) => `${m.id}:${m.status}`).join(", ")}], phase=${state.phase}`;
458
+ ctx.ui.notify(`Unexpected: ${incomplete.length} incomplete milestone(s) (${ids}) but no active milestone.\n Diagnostic: ${diag}`, "error");
459
+ await deps.stopAuto(ctx, pi, `No active milestone — ${incomplete.length} incomplete (${ids}), see diagnostic above`);
460
+ }
461
+ debugLog("autoLoop", { phase: "exit", reason: "no-active-milestone" });
462
+ deps.emitJournalEvent({ ts: new Date().toISOString(), flowId: ic.flowId, seq: ic.nextSeq(), eventType: "terminal", data: { reason: "no-active-milestone" } });
463
+ return { action: "break", reason: "no-active-milestone" };
464
+ }
465
+ if (!midTitle) {
466
+ midTitle = mid;
467
+ ctx.ui.notify(`Milestone ${mid} has no title in roadmap — using ID as fallback.`, "warning");
468
+ }
469
+ // Mid-merge safety check
470
+ const mergeReconcileResult = deps.reconcileMergeState(s.basePath, ctx);
471
+ if (mergeReconcileResult === "blocked") {
472
+ await deps.pauseAuto(ctx, pi);
473
+ debugLog("autoLoop", { phase: "exit", reason: "merge-reconciliation-blocked" });
474
+ return { action: "break", reason: "merge-reconciliation-blocked" };
475
+ }
476
+ if (mergeReconcileResult === "reconciled") {
477
+ deps.invalidateAllCaches();
478
+ state = await deps.deriveState(s.canonicalProjectRoot);
479
+ mid = state.activeMilestone?.id;
480
+ midTitle = state.activeMilestone?.title;
481
+ }
482
+ if (!mid || !midTitle) {
483
+ const noMilestoneReason = !mid
484
+ ? "No active milestone after merge reconciliation"
485
+ : `Milestone ${mid} has no title after reconciliation`;
486
+ await closeoutAndStop(ctx, pi, s, deps, noMilestoneReason);
487
+ debugLog("autoLoop", {
488
+ phase: "exit",
489
+ reason: "no-milestone-after-reconciliation",
490
+ });
491
+ return { action: "break", reason: "no-milestone-after-reconciliation" };
492
+ }
493
+ // Terminal: complete
494
+ if (state.phase === "complete") {
495
+ // Milestone merge on complete (before closeout so branch state is clean).
496
+ if (s.currentMilestoneId) {
497
+ // #2909 / #5538-followup: preflight stash + always-on postflight pop.
498
+ const stop = await _runMilestoneMergeOnceWithStashRestore(ic, s.currentMilestoneId);
499
+ if (stop)
500
+ return stop;
501
+ // PR creation (auto_pr) is handled inside mergeMilestoneToMain (#2302)
502
+ }
503
+ deps.sendDesktopNotification("GSD", `Milestone ${mid} complete!`, "success", "milestone", basename(s.originalBasePath || s.basePath));
504
+ deps.logCmuxEvent(prefs, `Milestone ${mid} complete.`, "success");
505
+ if (s.currentUnit) {
506
+ await deps.closeoutUnit(ctx, s.basePath, s.currentUnit.type, s.currentUnit.id, s.currentUnit.startedAt, deps.buildSnapshotOpts(s.currentUnit.type, s.currentUnit.id));
507
+ s.clearCurrentUnit();
508
+ }
509
+ await deps.stopAuto(ctx, pi, `Milestone ${mid} complete`, {
510
+ completionWidget: {
511
+ milestoneId: mid,
512
+ milestoneTitle: midTitle,
513
+ },
514
+ });
515
+ debugLog("autoLoop", { phase: "exit", reason: "milestone-complete" });
516
+ deps.emitJournalEvent({ ts: new Date().toISOString(), flowId: ic.flowId, seq: ic.nextSeq(), eventType: "terminal", data: { reason: "milestone-complete", milestoneId: mid } });
517
+ return { action: "break", reason: "milestone-complete" };
518
+ }
519
+ // Terminal: blocked — pause instead of hard-stop so the session is resumable.
520
+ if (state.phase === "blocked") {
521
+ const blockedResumeMessage = formatBlockedResumeMessage(state.blockers);
522
+ if (s.currentUnit) {
523
+ await deps.closeoutUnit(ctx, s.basePath, s.currentUnit.type, s.currentUnit.id, s.currentUnit.startedAt, deps.buildSnapshotOpts(s.currentUnit.type, s.currentUnit.id));
524
+ }
525
+ await deps.pauseAuto(ctx, pi);
526
+ ctx.ui.notify(blockedResumeMessage, "warning");
527
+ deps.sendDesktopNotification("GSD", blockedResumeMessage, "warning", "attention", basename(s.originalBasePath || s.basePath));
528
+ deps.logCmuxEvent(prefs, blockedResumeMessage, "warning");
529
+ debugLog("autoLoop", { phase: "exit", reason: "blocked" });
530
+ deps.emitJournalEvent({ ts: new Date().toISOString(), flowId: ic.flowId, seq: ic.nextSeq(), eventType: "terminal", data: { reason: "blocked", blockers: state.blockers } });
531
+ return { action: "break", reason: "blocked" };
532
+ }
533
+ return { action: "next", data: { state, mid, midTitle } };
534
+ }
@@ -126,6 +126,8 @@ export class AutoSession {
126
126
  /** Set when a GSD tool execution ends with isError due to malformed/truncated
127
127
  * JSON arguments. Checked by postUnitPreVerification to break retry loops. */
128
128
  lastToolInvocationError = null;
129
+ /** Consecutive tool-unavailable retries for the current unit (MCP startup race). */
130
+ toolUnavailableRetries = 0;
129
131
  /** Agent-end messages from the just-finished unit, consumed during finalize. */
130
132
  lastUnitAgentEndMessages = null;
131
133
  /** Set when turn-level git action fails during closeout. */
@@ -306,6 +308,7 @@ export class AutoSession {
306
308
  this.lastPreExecFailure = null;
307
309
  this.preExecRetryCount.clear();
308
310
  this.lastToolInvocationError = null;
311
+ this.toolUnavailableRetries = 0;
309
312
  this.lastUnitAgentEndMessages = null;
310
313
  this.lastGitActionFailure = null;
311
314
  this.lastGitActionStatus = null;