@opengsd/gsd-pi 1.2.0-dev.84c56d87 → 1.2.0-dev.8e6112e9

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 (631) 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/headless-events.js +7 -5
  5. package/dist/loader.js +6 -4
  6. package/dist/mcp-server.js +2 -1
  7. package/dist/register-agent-bundles.d.ts +11 -2
  8. package/dist/register-agent-bundles.js +18 -4
  9. package/dist/resource-loader.d.ts +10 -5
  10. package/dist/resource-loader.js +121 -6
  11. package/dist/resources/.managed-resources-content-hash +1 -1
  12. package/dist/resources/GSD-WORKFLOW.md +5 -4
  13. package/dist/resources/extensions/ask-user-questions.js +3 -2
  14. package/dist/resources/extensions/async-jobs/async-bash-tool.js +30 -64
  15. package/dist/resources/extensions/async-jobs/await-tool.js +80 -12
  16. package/dist/resources/extensions/async-jobs/index.js +65 -0
  17. package/dist/resources/extensions/async-jobs/job-manager.js +12 -1
  18. package/dist/resources/extensions/bg-shell/bg-shell-command.js +6 -6
  19. package/dist/resources/extensions/bg-shell/bg-shell-tool.js +10 -7
  20. package/dist/resources/extensions/bg-shell/overlay.js +9 -6
  21. package/dist/resources/extensions/bg-shell/process-manager.js +54 -25
  22. package/dist/resources/extensions/bg-shell/readiness-detector.js +11 -0
  23. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +447 -215
  24. package/dist/resources/extensions/claude-code-cli/turn-assembler.js +33 -1
  25. package/dist/resources/extensions/gsd/auto/closeout.js +215 -0
  26. package/dist/resources/extensions/gsd/auto/custom-verify-retry-store.js +17 -2
  27. package/dist/resources/extensions/gsd/auto/detect-stuck.js +33 -13
  28. package/dist/resources/extensions/gsd/auto/dispatch-history.js +120 -0
  29. package/dist/resources/extensions/gsd/auto/dispatch-key.js +37 -0
  30. package/dist/resources/extensions/gsd/auto/dispatch.js +365 -0
  31. package/dist/resources/extensions/gsd/auto/finalize.js +347 -0
  32. package/dist/resources/extensions/gsd/auto/loop.js +7 -1
  33. package/dist/resources/extensions/gsd/auto/milestone-lease-reclaim.js +56 -0
  34. package/dist/resources/extensions/gsd/auto/orchestrator.js +174 -69
  35. package/dist/resources/extensions/gsd/auto/phase-helpers.js +146 -0
  36. package/dist/resources/extensions/gsd/auto/phases.js +17 -2329
  37. package/dist/resources/extensions/gsd/auto/pre-dispatch.js +534 -0
  38. package/dist/resources/extensions/gsd/auto/session.js +3 -0
  39. package/dist/resources/extensions/gsd/auto/unit-phase.js +694 -0
  40. package/dist/resources/extensions/gsd/auto/workflow-unit-dispatch.js +1 -1
  41. package/dist/resources/extensions/gsd/auto/worktree-safety-phase.js +125 -0
  42. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +11 -34
  43. package/dist/resources/extensions/gsd/auto-dispatch.js +50 -58
  44. package/dist/resources/extensions/gsd/auto-model-selection.js +36 -13
  45. package/dist/resources/extensions/gsd/auto-post-unit.js +30 -12
  46. package/dist/resources/extensions/gsd/auto-prompts.js +78 -19
  47. package/dist/resources/extensions/gsd/auto-start.js +35 -15
  48. package/dist/resources/extensions/gsd/auto-unit-closeout.js +45 -21
  49. package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +5 -4
  50. package/dist/resources/extensions/gsd/auto-verification.js +23 -30
  51. package/dist/resources/extensions/gsd/auto-worktree.js +15 -2
  52. package/dist/resources/extensions/gsd/auto.js +52 -2
  53. package/dist/resources/extensions/gsd/blocked-models.js +28 -0
  54. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +26 -6
  55. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +60 -13
  56. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +2 -2
  57. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +145 -50
  58. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +302 -80
  59. package/dist/resources/extensions/gsd/browser-daemon-auto-prep.js +83 -0
  60. package/dist/resources/extensions/gsd/closeout-wizard.js +92 -0
  61. package/dist/resources/extensions/gsd/commands/context.js +16 -2
  62. package/dist/resources/extensions/gsd/commands-handlers.js +46 -3
  63. package/dist/resources/extensions/gsd/commands-mcp-status.js +2 -2
  64. package/dist/resources/extensions/gsd/commands-workflow-templates.js +9 -2
  65. package/dist/resources/extensions/gsd/consent-question.js +353 -0
  66. package/dist/resources/extensions/gsd/consent-verdict.js +63 -0
  67. package/dist/resources/extensions/gsd/constants.js +0 -2
  68. package/dist/resources/extensions/gsd/crash-recovery.js +8 -3
  69. package/dist/resources/extensions/gsd/db/engine.js +5 -3
  70. package/dist/resources/extensions/gsd/db/queries.js +56 -0
  71. package/dist/resources/extensions/gsd/db-writer.js +8 -17
  72. package/dist/resources/extensions/gsd/dispatch-guard.js +10 -35
  73. package/dist/resources/extensions/gsd/doctor-engine-checks.js +5 -5
  74. package/dist/resources/extensions/gsd/doctor-environment.js +256 -125
  75. package/dist/resources/extensions/gsd/doctor-git-checks.js +2 -18
  76. package/dist/resources/extensions/gsd/engine-hook-contract.js +70 -0
  77. package/dist/resources/extensions/gsd/exec-sandbox.js +30 -10
  78. package/dist/resources/extensions/gsd/files.js +33 -19
  79. package/dist/resources/extensions/gsd/gsd-command-home.js +22 -12
  80. package/dist/resources/extensions/gsd/gsd-db.js +11 -8
  81. package/dist/resources/extensions/gsd/guidance.js +60 -0
  82. package/dist/resources/extensions/gsd/guided-flow.js +93 -4
  83. package/dist/resources/extensions/gsd/health-widget.js +87 -28
  84. package/dist/resources/extensions/gsd/markdown-renderer.js +10 -0
  85. package/dist/resources/extensions/gsd/mcp-bridge.js +10 -0
  86. package/dist/resources/extensions/gsd/memory-relations.js +1 -1
  87. package/dist/resources/extensions/gsd/milestone-closeout.js +85 -24
  88. package/dist/resources/extensions/gsd/milestone-planning-persistence.js +2 -2
  89. package/dist/resources/extensions/gsd/milestone-reopen-events.js +3 -5
  90. package/dist/resources/extensions/gsd/milestone-settlement.js +2 -2
  91. package/dist/resources/extensions/gsd/notifications.js +12 -7
  92. package/dist/resources/extensions/gsd/parsers-legacy.js +16 -4
  93. package/dist/resources/extensions/gsd/preferences-models.js +2 -2
  94. package/dist/resources/extensions/gsd/projection-flush.js +7 -0
  95. package/dist/resources/extensions/gsd/prompts/complete-slice.md +4 -4
  96. package/dist/resources/extensions/gsd/prompts/execute-task.md +3 -2
  97. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  98. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  99. package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -1
  100. package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
  101. package/dist/resources/extensions/gsd/prompts/refine-slice.md +1 -1
  102. package/dist/resources/extensions/gsd/prompts/replan-slice.md +1 -1
  103. package/dist/resources/extensions/gsd/prompts/research-milestone.md +1 -1
  104. package/dist/resources/extensions/gsd/prompts/research-slice.md +1 -1
  105. package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  106. package/dist/resources/extensions/gsd/prompts/run-uat.md +9 -5
  107. package/dist/resources/extensions/gsd/prompts/system.md +5 -2
  108. package/dist/resources/extensions/gsd/prompts/triage-captures.md +1 -1
  109. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +1 -1
  110. package/dist/resources/extensions/gsd/prompts/workflow-start.md +2 -1
  111. package/dist/resources/extensions/gsd/reactive-graph.js +8 -1
  112. package/dist/resources/extensions/gsd/roadmap-slices.js +25 -3
  113. package/dist/resources/extensions/gsd/safety/destructive-confirmation.js +108 -0
  114. package/dist/resources/extensions/gsd/session-lock.js +1 -1
  115. package/dist/resources/extensions/gsd/skill-activation.js +3 -6
  116. package/dist/resources/extensions/gsd/state.js +11 -2
  117. package/dist/resources/extensions/gsd/tool-contract.js +14 -3
  118. package/dist/resources/extensions/gsd/tool-presentation-plan.js +4 -4
  119. package/dist/resources/extensions/gsd/tool-surface-readiness.js +83 -31
  120. package/dist/resources/extensions/gsd/tools/complete-milestone.js +3 -2
  121. package/dist/resources/extensions/gsd/tools/complete-slice.js +22 -12
  122. package/dist/resources/extensions/gsd/tools/complete-task.js +65 -2
  123. package/dist/resources/extensions/gsd/tools/exec-tool.js +5 -0
  124. package/dist/resources/extensions/gsd/tools/plan-slice.js +2 -2
  125. package/dist/resources/extensions/gsd/tools/plan-task.js +2 -2
  126. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +2 -2
  127. package/dist/resources/extensions/gsd/tools/reopen-milestone.js +2 -2
  128. package/dist/resources/extensions/gsd/tools/reopen-slice.js +2 -2
  129. package/dist/resources/extensions/gsd/tools/reopen-task.js +2 -2
  130. package/dist/resources/extensions/gsd/tools/replan-slice.js +2 -2
  131. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +67 -2
  132. package/dist/resources/extensions/gsd/uat-policy.js +40 -15
  133. package/dist/resources/extensions/gsd/unit-context-composer.js +65 -0
  134. package/dist/resources/extensions/gsd/unit-registry.js +34 -4
  135. package/dist/resources/extensions/gsd/verdict-parser.js +1 -1
  136. package/dist/resources/extensions/gsd/verification-verdict.js +2 -1
  137. package/dist/resources/extensions/gsd/workflow-event-ledger.js +91 -0
  138. package/dist/resources/extensions/gsd/workflow-event-vocabulary.js +46 -0
  139. package/dist/resources/extensions/gsd/workflow-events.js +6 -18
  140. package/dist/resources/extensions/gsd/workflow-mcp-auto-prep.js +2 -0
  141. package/dist/resources/extensions/gsd/workflow-mcp-readiness-cache.js +105 -0
  142. package/dist/resources/extensions/gsd/workflow-reconcile.js +21 -56
  143. package/dist/resources/extensions/gsd/worktree-lifecycle.js +3 -2
  144. package/dist/resources/extensions/gsd/worktree-manager.js +7 -1
  145. package/dist/resources/extensions/gsd/worktree-safety.js +28 -26
  146. package/dist/resources/extensions/gsd/worktree.js +8 -1
  147. package/dist/resources/extensions/mcp-client/manager.js +6 -1
  148. package/dist/resources/extensions/shared/gsd-browser-cli.js +45 -3
  149. package/dist/resources/shared/gsd-browser-path-sync.js +214 -0
  150. package/dist/resources/shared/package-manager-detection.js +1 -1
  151. package/dist/resources/shared/package.json +3 -0
  152. package/dist/resources/skills/create-skill/SKILL.md +3 -0
  153. package/dist/resources/skills/create-skill/references/skill-structure.md +1 -0
  154. package/dist/runtime-checks.d.ts +10 -0
  155. package/dist/runtime-checks.js +27 -0
  156. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  157. package/dist/update-check.d.ts +2 -0
  158. package/dist/update-check.js +24 -1
  159. package/dist/update-cmd.js +20 -3
  160. package/dist/web/standalone/.next/BUILD_ID +1 -1
  161. package/dist/web/standalone/.next/app-path-routes-manifest.json +6 -6
  162. package/dist/web/standalone/.next/build-manifest.json +3 -3
  163. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  164. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  165. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  166. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  167. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  168. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  169. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  170. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  171. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  172. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  173. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  174. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  175. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  176. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  177. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  178. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  179. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  180. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  181. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/update/route.js.nft.json +1 -1
  183. package/dist/web/standalone/.next/server/app/index.html +1 -1
  184. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  185. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  186. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  187. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  188. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  189. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  190. package/dist/web/standalone/.next/server/app-paths-manifest.json +6 -6
  191. package/dist/web/standalone/.next/server/chunks/8357.js +2 -2
  192. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  194. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  195. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  196. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  197. package/dist/web/standalone/.next/static/chunks/{796.cf859a427a2cb2ac.js → 796.e0bdc932325d7e03.js} +1 -1
  198. package/dist/web/standalone/.next/static/chunks/{webpack-fbea77b5f9953368.js → webpack-f0285ce91d4ec9ef.js} +1 -1
  199. package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
  200. package/dist/web/standalone/node_modules/postcss/lib/container.js +26 -18
  201. package/dist/web/standalone/node_modules/postcss/lib/css-syntax-error.js +47 -14
  202. package/dist/web/standalone/node_modules/postcss/lib/declaration.js +4 -4
  203. package/dist/web/standalone/node_modules/postcss/lib/fromJSON.js +3 -3
  204. package/dist/web/standalone/node_modules/postcss/lib/input.js +54 -29
  205. package/dist/web/standalone/node_modules/postcss/lib/lazy-result.js +47 -37
  206. package/dist/web/standalone/node_modules/postcss/lib/map-generator.js +26 -9
  207. package/dist/web/standalone/node_modules/postcss/lib/no-work-result.js +57 -55
  208. package/dist/web/standalone/node_modules/postcss/lib/node.js +99 -31
  209. package/dist/web/standalone/node_modules/postcss/lib/parse.js +1 -1
  210. package/dist/web/standalone/node_modules/postcss/lib/parser.js +10 -9
  211. package/dist/web/standalone/node_modules/postcss/lib/postcss.js +12 -12
  212. package/dist/web/standalone/node_modules/postcss/lib/previous-map.js +30 -11
  213. package/dist/web/standalone/node_modules/postcss/lib/processor.js +7 -7
  214. package/dist/web/standalone/node_modules/postcss/lib/result.js +5 -5
  215. package/dist/web/standalone/node_modules/postcss/lib/rule.js +6 -6
  216. package/dist/web/standalone/node_modules/postcss/lib/stringifier.js +69 -28
  217. package/dist/web/standalone/node_modules/postcss/lib/tokenize.js +6 -2
  218. package/dist/web/standalone/node_modules/postcss/package.json +48 -48
  219. package/package.json +3 -3
  220. package/packages/cloud-mcp-gateway/package.json +2 -2
  221. package/packages/contracts/dist/rpc.d.ts +1 -0
  222. package/packages/contracts/dist/rpc.d.ts.map +1 -1
  223. package/packages/contracts/dist/rpc.js.map +1 -1
  224. package/packages/contracts/package.json +1 -1
  225. package/packages/daemon/package.json +4 -4
  226. package/packages/gsd-agent-core/dist/sdk.d.ts.map +1 -1
  227. package/packages/gsd-agent-core/dist/sdk.js +6 -4
  228. package/packages/gsd-agent-core/dist/sdk.js.map +1 -1
  229. package/packages/gsd-agent-core/package.json +5 -5
  230. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts +2 -0
  231. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  232. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js +10 -0
  233. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js.map +1 -1
  234. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +13 -0
  235. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  236. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +55 -6
  237. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  238. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts +2 -0
  239. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts.map +1 -1
  240. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js +34 -5
  241. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js.map +1 -1
  242. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  243. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +7 -0
  244. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  245. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
  246. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js +8 -1
  247. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  248. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.d.ts.map +1 -1
  249. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js +11 -1
  250. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js.map +1 -1
  251. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts +1 -0
  252. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  253. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +12 -0
  254. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
  255. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.d.ts.map +1 -1
  256. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js +4 -4
  257. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js.map +1 -1
  258. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.d.ts.map +1 -1
  259. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js +4 -0
  260. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js.map +1 -1
  261. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  262. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +3 -1
  263. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -1
  264. package/packages/gsd-agent-modes/package.json +7 -7
  265. package/packages/mcp-server/README.md +12 -3
  266. package/packages/mcp-server/dist/cli-runner.d.ts +40 -0
  267. package/packages/mcp-server/dist/cli-runner.d.ts.map +1 -0
  268. package/packages/mcp-server/dist/cli-runner.js +137 -0
  269. package/packages/mcp-server/dist/cli-runner.js.map +1 -0
  270. package/packages/mcp-server/dist/cli.js +2 -53
  271. package/packages/mcp-server/dist/cli.js.map +1 -1
  272. package/packages/mcp-server/dist/moonshot-tool-schema.d.ts +29 -0
  273. package/packages/mcp-server/dist/moonshot-tool-schema.d.ts.map +1 -0
  274. package/packages/mcp-server/dist/moonshot-tool-schema.js +50 -0
  275. package/packages/mcp-server/dist/moonshot-tool-schema.js.map +1 -0
  276. package/packages/mcp-server/dist/pid-registry.d.ts +46 -0
  277. package/packages/mcp-server/dist/pid-registry.d.ts.map +1 -0
  278. package/packages/mcp-server/dist/pid-registry.js +452 -0
  279. package/packages/mcp-server/dist/pid-registry.js.map +1 -0
  280. package/packages/mcp-server/dist/probe-mode.d.ts +4 -0
  281. package/packages/mcp-server/dist/probe-mode.d.ts.map +1 -0
  282. package/packages/mcp-server/dist/probe-mode.js +10 -0
  283. package/packages/mcp-server/dist/probe-mode.js.map +1 -0
  284. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  285. package/packages/mcp-server/dist/server.js +4 -0
  286. package/packages/mcp-server/dist/server.js.map +1 -1
  287. package/packages/mcp-server/dist/stdio-watchdog.d.ts +8 -0
  288. package/packages/mcp-server/dist/stdio-watchdog.d.ts.map +1 -0
  289. package/packages/mcp-server/dist/stdio-watchdog.js +40 -0
  290. package/packages/mcp-server/dist/stdio-watchdog.js.map +1 -0
  291. package/packages/mcp-server/dist/workflow-tools.d.ts +18 -18
  292. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  293. package/packages/mcp-server/dist/workflow-tools.js +161 -81
  294. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  295. package/packages/mcp-server/package.json +5 -4
  296. package/packages/native/package.json +1 -1
  297. package/packages/pi-agent-core/dist/agent-loop.js +43 -2
  298. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  299. package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts +1 -0
  300. package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts.map +1 -1
  301. package/packages/pi-agent-core/dist/harness/env/nodejs.js +34 -3
  302. package/packages/pi-agent-core/dist/harness/env/nodejs.js.map +1 -1
  303. package/packages/pi-agent-core/dist/index.d.ts +1 -0
  304. package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
  305. package/packages/pi-agent-core/dist/index.js +3 -0
  306. package/packages/pi-agent-core/dist/index.js.map +1 -1
  307. package/packages/pi-agent-core/package.json +1 -1
  308. package/packages/pi-ai/README.md +1 -0
  309. package/packages/pi-ai/dist/image-models.generated.d.ts +2 -2
  310. package/packages/pi-ai/dist/image-models.generated.js +6 -6
  311. package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
  312. package/packages/pi-ai/dist/index.d.ts +2 -0
  313. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  314. package/packages/pi-ai/dist/index.js +2 -0
  315. package/packages/pi-ai/dist/index.js.map +1 -1
  316. package/packages/pi-ai/dist/models.generated.d.ts +419 -221
  317. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  318. package/packages/pi-ai/dist/models.generated.js +460 -261
  319. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  320. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  321. package/packages/pi-ai/dist/providers/anthropic.js +12 -7
  322. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  323. package/packages/pi-ai/dist/providers/google-shared.d.ts +5 -0
  324. package/packages/pi-ai/dist/providers/google-shared.d.ts.map +1 -1
  325. package/packages/pi-ai/dist/providers/google-shared.js +12 -3
  326. package/packages/pi-ai/dist/providers/google-shared.js.map +1 -1
  327. package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
  328. package/packages/pi-ai/dist/providers/openai-completions.js +7 -3
  329. package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
  330. package/packages/pi-ai/dist/utils/moonshot-tool-schema.d.ts +9 -0
  331. package/packages/pi-ai/dist/utils/moonshot-tool-schema.d.ts.map +1 -0
  332. package/packages/pi-ai/dist/utils/moonshot-tool-schema.js +34 -0
  333. package/packages/pi-ai/dist/utils/moonshot-tool-schema.js.map +1 -0
  334. package/packages/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
  335. package/packages/pi-ai/dist/utils/oauth/github-copilot.js +6 -2
  336. package/packages/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
  337. package/packages/pi-ai/package.json +3 -2
  338. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +2 -2
  339. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  340. package/packages/pi-coding-agent/dist/core/auth-storage.js +19 -13
  341. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  342. package/packages/pi-coding-agent/dist/core/provider-readiness.d.ts.map +1 -1
  343. package/packages/pi-coding-agent/dist/core/provider-readiness.js +13 -6
  344. package/packages/pi-coding-agent/dist/core/provider-readiness.js.map +1 -1
  345. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +3 -0
  346. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  347. package/packages/pi-coding-agent/dist/core/settings-manager.js +11 -0
  348. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  349. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts +11 -0
  350. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
  351. package/packages/pi-coding-agent/dist/core/tools/bash.js +53 -11
  352. package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
  353. package/packages/pi-coding-agent/dist/index.d.ts +1 -1
  354. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  355. package/packages/pi-coding-agent/dist/index.js +1 -1
  356. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  357. package/packages/pi-coding-agent/dist/theme/theme.d.ts.map +1 -1
  358. package/packages/pi-coding-agent/dist/theme/theme.js +45 -17
  359. package/packages/pi-coding-agent/dist/theme/theme.js.map +1 -1
  360. package/packages/pi-coding-agent/dist/utils/shell.d.ts +28 -2
  361. package/packages/pi-coding-agent/dist/utils/shell.d.ts.map +1 -1
  362. package/packages/pi-coding-agent/dist/utils/shell.js +56 -10
  363. package/packages/pi-coding-agent/dist/utils/shell.js.map +1 -1
  364. package/packages/pi-coding-agent/package.json +7 -7
  365. package/packages/pi-tui/dist/index.d.ts +1 -1
  366. package/packages/pi-tui/dist/index.d.ts.map +1 -1
  367. package/packages/pi-tui/dist/index.js +1 -1
  368. package/packages/pi-tui/dist/index.js.map +1 -1
  369. package/packages/pi-tui/dist/terminal-image.d.ts +33 -0
  370. package/packages/pi-tui/dist/terminal-image.d.ts.map +1 -1
  371. package/packages/pi-tui/dist/terminal-image.js +54 -2
  372. package/packages/pi-tui/dist/terminal-image.js.map +1 -1
  373. package/packages/pi-tui/dist/tui.d.ts +8 -0
  374. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  375. package/packages/pi-tui/dist/tui.js +63 -18
  376. package/packages/pi-tui/dist/tui.js.map +1 -1
  377. package/packages/pi-tui/dist/utils.d.ts.map +1 -1
  378. package/packages/pi-tui/dist/utils.js +110 -36
  379. package/packages/pi-tui/dist/utils.js.map +1 -1
  380. package/packages/pi-tui/package.json +2 -2
  381. package/packages/rpc-client/package.json +2 -2
  382. package/pkg/dist/theme/theme.d.ts.map +1 -1
  383. package/pkg/dist/theme/theme.js +45 -17
  384. package/pkg/dist/theme/theme.js.map +1 -1
  385. package/pkg/package.json +1 -1
  386. package/src/resources/GSD-WORKFLOW.md +5 -4
  387. package/src/resources/extensions/ask-user-questions.ts +7 -2
  388. package/src/resources/extensions/async-jobs/async-bash-cancel.test.ts +360 -0
  389. package/src/resources/extensions/async-jobs/async-bash-tool.ts +33 -56
  390. package/src/resources/extensions/async-jobs/await-tool.test.ts +139 -0
  391. package/src/resources/extensions/async-jobs/await-tool.ts +82 -12
  392. package/src/resources/extensions/async-jobs/index.ts +79 -0
  393. package/src/resources/extensions/async-jobs/job-manager.ts +21 -1
  394. package/src/resources/extensions/bg-shell/bg-shell-command.ts +6 -6
  395. package/src/resources/extensions/bg-shell/bg-shell-tool.ts +10 -6
  396. package/src/resources/extensions/bg-shell/overlay.ts +9 -5
  397. package/src/resources/extensions/bg-shell/process-manager.ts +50 -25
  398. package/src/resources/extensions/bg-shell/readiness-detector.ts +12 -0
  399. package/src/resources/extensions/bg-shell/tests/lifecycle-and-utilities.test.ts +48 -1
  400. package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +40 -1
  401. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +531 -226
  402. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +672 -7
  403. package/src/resources/extensions/claude-code-cli/turn-assembler.ts +38 -1
  404. package/src/resources/extensions/gsd/auto/closeout.ts +309 -0
  405. package/src/resources/extensions/gsd/auto/custom-verify-retry-store.ts +21 -3
  406. package/src/resources/extensions/gsd/auto/detect-stuck.ts +32 -9
  407. package/src/resources/extensions/gsd/auto/dispatch-history.ts +168 -0
  408. package/src/resources/extensions/gsd/auto/dispatch-key.ts +39 -0
  409. package/src/resources/extensions/gsd/auto/dispatch.ts +449 -0
  410. package/src/resources/extensions/gsd/auto/finalize.ts +445 -0
  411. package/src/resources/extensions/gsd/auto/loop.ts +7 -1
  412. package/src/resources/extensions/gsd/auto/milestone-lease-reclaim.ts +74 -0
  413. package/src/resources/extensions/gsd/auto/orchestrator.ts +193 -71
  414. package/src/resources/extensions/gsd/auto/phase-helpers.ts +199 -0
  415. package/src/resources/extensions/gsd/auto/phases.ts +58 -3022
  416. package/src/resources/extensions/gsd/auto/pre-dispatch.ts +704 -0
  417. package/src/resources/extensions/gsd/auto/session.ts +3 -0
  418. package/src/resources/extensions/gsd/auto/unit-phase.ts +910 -0
  419. package/src/resources/extensions/gsd/auto/workflow-unit-dispatch.ts +1 -1
  420. package/src/resources/extensions/gsd/auto/worktree-safety-phase.ts +149 -0
  421. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +18 -48
  422. package/src/resources/extensions/gsd/auto-dispatch.ts +48 -61
  423. package/src/resources/extensions/gsd/auto-model-selection.ts +41 -12
  424. package/src/resources/extensions/gsd/auto-post-unit.ts +33 -12
  425. package/src/resources/extensions/gsd/auto-prompts.ts +115 -35
  426. package/src/resources/extensions/gsd/auto-start.ts +36 -18
  427. package/src/resources/extensions/gsd/auto-unit-closeout.ts +83 -28
  428. package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +4 -4
  429. package/src/resources/extensions/gsd/auto-verification.ts +26 -28
  430. package/src/resources/extensions/gsd/auto-worktree.ts +15 -2
  431. package/src/resources/extensions/gsd/auto.ts +64 -2
  432. package/src/resources/extensions/gsd/blocked-models.ts +49 -0
  433. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +34 -5
  434. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +79 -12
  435. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +2 -2
  436. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +163 -55
  437. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +350 -86
  438. package/src/resources/extensions/gsd/browser-daemon-auto-prep.ts +108 -0
  439. package/src/resources/extensions/gsd/closeout-wizard.ts +102 -0
  440. package/src/resources/extensions/gsd/commands/context.ts +16 -2
  441. package/src/resources/extensions/gsd/commands-handlers.ts +46 -3
  442. package/src/resources/extensions/gsd/commands-mcp-status.ts +2 -2
  443. package/src/resources/extensions/gsd/commands-workflow-templates.ts +11 -4
  444. package/src/resources/extensions/gsd/consent-question.ts +431 -0
  445. package/src/resources/extensions/gsd/consent-verdict.ts +86 -0
  446. package/src/resources/extensions/gsd/constants.ts +0 -3
  447. package/src/resources/extensions/gsd/crash-recovery.ts +10 -2
  448. package/src/resources/extensions/gsd/db/engine.ts +5 -3
  449. package/src/resources/extensions/gsd/db/queries.ts +66 -0
  450. package/src/resources/extensions/gsd/db-writer.ts +11 -19
  451. package/src/resources/extensions/gsd/dispatch-guard.ts +8 -31
  452. package/src/resources/extensions/gsd/doctor-engine-checks.ts +5 -4
  453. package/src/resources/extensions/gsd/doctor-environment.ts +267 -142
  454. package/src/resources/extensions/gsd/doctor-git-checks.ts +2 -19
  455. package/src/resources/extensions/gsd/engine-hook-contract.ts +79 -0
  456. package/src/resources/extensions/gsd/exec-sandbox.ts +49 -9
  457. package/src/resources/extensions/gsd/files.ts +33 -12
  458. package/src/resources/extensions/gsd/gsd-command-home.ts +13 -3
  459. package/src/resources/extensions/gsd/gsd-db.ts +13 -10
  460. package/src/resources/extensions/gsd/guidance.ts +78 -0
  461. package/src/resources/extensions/gsd/guided-flow.ts +145 -24
  462. package/src/resources/extensions/gsd/health-widget.ts +91 -27
  463. package/src/resources/extensions/gsd/markdown-renderer.ts +11 -0
  464. package/src/resources/extensions/gsd/mcp-bridge.ts +39 -0
  465. package/src/resources/extensions/gsd/memory-relations.ts +1 -1
  466. package/src/resources/extensions/gsd/milestone-closeout.ts +109 -24
  467. package/src/resources/extensions/gsd/milestone-planning-persistence.ts +2 -2
  468. package/src/resources/extensions/gsd/milestone-reopen-events.ts +3 -6
  469. package/src/resources/extensions/gsd/milestone-settlement.ts +2 -2
  470. package/src/resources/extensions/gsd/notifications.ts +13 -6
  471. package/src/resources/extensions/gsd/parsers-legacy.ts +16 -4
  472. package/src/resources/extensions/gsd/preferences-models.ts +2 -1
  473. package/src/resources/extensions/gsd/projection-flush.ts +20 -0
  474. package/src/resources/extensions/gsd/prompts/complete-slice.md +4 -4
  475. package/src/resources/extensions/gsd/prompts/execute-task.md +3 -2
  476. package/src/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  477. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  478. package/src/resources/extensions/gsd/prompts/quick-task.md +1 -1
  479. package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
  480. package/src/resources/extensions/gsd/prompts/refine-slice.md +1 -1
  481. package/src/resources/extensions/gsd/prompts/replan-slice.md +1 -1
  482. package/src/resources/extensions/gsd/prompts/research-milestone.md +1 -1
  483. package/src/resources/extensions/gsd/prompts/research-slice.md +1 -1
  484. package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  485. package/src/resources/extensions/gsd/prompts/run-uat.md +9 -5
  486. package/src/resources/extensions/gsd/prompts/system.md +5 -2
  487. package/src/resources/extensions/gsd/prompts/triage-captures.md +1 -1
  488. package/src/resources/extensions/gsd/prompts/validate-milestone.md +1 -1
  489. package/src/resources/extensions/gsd/prompts/workflow-start.md +2 -1
  490. package/src/resources/extensions/gsd/reactive-graph.ts +11 -1
  491. package/src/resources/extensions/gsd/roadmap-slices.ts +28 -3
  492. package/src/resources/extensions/gsd/safety/destructive-confirmation.ts +134 -0
  493. package/src/resources/extensions/gsd/session-lock.ts +1 -1
  494. package/src/resources/extensions/gsd/skill-activation.ts +3 -6
  495. package/src/resources/extensions/gsd/state.ts +12 -1
  496. package/src/resources/extensions/gsd/tests/auto-abort-pause-regression.test.ts +1 -1
  497. package/src/resources/extensions/gsd/tests/auto-blocked-remediation-message.test.ts +1 -1
  498. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +206 -22
  499. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +97 -1
  500. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +273 -37
  501. package/src/resources/extensions/gsd/tests/auto-pause-double-entry-guard.test.ts +1 -1
  502. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +77 -1
  503. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +2 -1
  504. package/src/resources/extensions/gsd/tests/auto-remote-session-lock-cleanup.test.ts +65 -3
  505. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +236 -0
  506. package/src/resources/extensions/gsd/tests/auto-unit-closeout.test.ts +169 -1
  507. package/src/resources/extensions/gsd/tests/blocked-models.test.ts +19 -0
  508. package/src/resources/extensions/gsd/tests/browser-daemon-auto-prep.test.ts +144 -0
  509. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +42 -0
  510. package/src/resources/extensions/gsd/tests/complete-task.test.ts +141 -5
  511. package/src/resources/extensions/gsd/tests/consent-question.test.ts +351 -0
  512. package/src/resources/extensions/gsd/tests/custom-verify-retry-store.test.ts +67 -0
  513. package/src/resources/extensions/gsd/tests/db-writer.test.ts +15 -4
  514. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +12 -11
  515. package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +36 -0
  516. package/src/resources/extensions/gsd/tests/destructive-confirmation.test.ts +303 -0
  517. package/src/resources/extensions/gsd/tests/discuss-routing-fixes.test.ts +12 -2
  518. package/src/resources/extensions/gsd/tests/dispatch-history.test.ts +328 -0
  519. package/src/resources/extensions/gsd/tests/dist-redirect.mjs +8 -0
  520. package/src/resources/extensions/gsd/tests/doctor-git-checks-terminal.test.ts +73 -0
  521. package/src/resources/extensions/gsd/tests/dynamic-bash-no-cap.test.ts +132 -0
  522. package/src/resources/extensions/gsd/tests/engine-hook-contract.test.ts +148 -0
  523. package/src/resources/extensions/gsd/tests/engine-interfaces-contract.test.ts +117 -91
  524. package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +113 -0
  525. package/src/resources/extensions/gsd/tests/exec-graceful-kill.test.ts +193 -0
  526. package/src/resources/extensions/gsd/tests/exec-tool.test.ts +29 -1
  527. package/src/resources/extensions/gsd/tests/gsd-command-home.test.ts +120 -0
  528. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +27 -0
  529. package/src/resources/extensions/gsd/tests/guidance.test.ts +23 -0
  530. package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +18 -6
  531. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +15 -0
  532. package/src/resources/extensions/gsd/tests/integration/doctor-environment-async.test.ts +104 -0
  533. package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +217 -0
  534. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +47 -16
  535. package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +3 -1
  536. package/src/resources/extensions/gsd/tests/mcp-readiness-preflight.test.ts +205 -0
  537. package/src/resources/extensions/gsd/tests/mcp-status.test.ts +6 -5
  538. package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +95 -4
  539. package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +1 -1
  540. package/src/resources/extensions/gsd/tests/milestone-report-path.test.ts +1 -1
  541. package/src/resources/extensions/gsd/tests/milestone-settlement.test.ts +92 -0
  542. package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +1 -1
  543. package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +32 -1
  544. package/src/resources/extensions/gsd/tests/notifications.test.ts +64 -9
  545. package/src/resources/extensions/gsd/tests/oauth-api-model-routing.test.ts +167 -0
  546. package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +18 -0
  547. package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +2 -2
  548. package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +143 -0
  549. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +1 -1
  550. package/src/resources/extensions/gsd/tests/phases-terminal-complete-idempotent.test.ts +242 -0
  551. package/src/resources/extensions/gsd/tests/plan-gate-failed-doctor-heal-hint.test.ts +3 -3
  552. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +63 -2
  553. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +10 -2
  554. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +124 -6
  555. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +2 -4
  556. package/src/resources/extensions/gsd/tests/remote-notification-from-desktop.test.ts +31 -81
  557. package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +68 -0
  558. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +26 -2
  559. package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +170 -48
  560. package/src/resources/extensions/gsd/tests/skill-activation.test.ts +20 -17
  561. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +7 -3
  562. package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +1 -1
  563. package/src/resources/extensions/gsd/tests/teardown-chdir-failure-clears-registry.test.ts +17 -0
  564. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +45 -2
  565. package/src/resources/extensions/gsd/tests/tool-surface-readiness.test.ts +184 -10
  566. package/src/resources/extensions/gsd/tests/tool-unavailable-retry.test.ts +33 -0
  567. package/src/resources/extensions/gsd/tests/transport-gate-double-complete.test.ts +139 -0
  568. package/src/resources/extensions/gsd/tests/uat-policy.test.ts +88 -0
  569. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +44 -0
  570. package/src/resources/extensions/gsd/tests/uok-audit-unified.test.ts +8 -0
  571. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +1 -1
  572. package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +2 -0
  573. package/src/resources/extensions/gsd/tests/workflow-events.test.ts +19 -0
  574. package/src/resources/extensions/gsd/tests/workflow-mcp-readiness-cache.test.ts +119 -0
  575. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +65 -2
  576. package/src/resources/extensions/gsd/tests/workflow-phase-contract-matrix.test.ts +332 -0
  577. package/src/resources/extensions/gsd/tests/workflow-reconcile.test.ts +20 -0
  578. package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +92 -0
  579. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +273 -38
  580. package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +1 -1
  581. package/src/resources/extensions/gsd/tests/worktree-project-root-degrade.test.ts +1 -1
  582. package/src/resources/extensions/gsd/tests/worktree-safety-phase.test.ts +100 -0
  583. package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +72 -0
  584. package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +22 -0
  585. package/src/resources/extensions/gsd/tests/worktree.test.ts +18 -0
  586. package/src/resources/extensions/gsd/tests/write-gate-seam.test.ts +358 -0
  587. package/src/resources/extensions/gsd/tests/write-gate.test.ts +67 -1
  588. package/src/resources/extensions/gsd/tool-contract.ts +38 -3
  589. package/src/resources/extensions/gsd/tool-presentation-plan.ts +4 -4
  590. package/src/resources/extensions/gsd/tool-surface-readiness.ts +126 -19
  591. package/src/resources/extensions/gsd/tools/complete-milestone.ts +3 -2
  592. package/src/resources/extensions/gsd/tools/complete-slice.ts +22 -12
  593. package/src/resources/extensions/gsd/tools/complete-task.ts +90 -2
  594. package/src/resources/extensions/gsd/tools/exec-tool.ts +4 -0
  595. package/src/resources/extensions/gsd/tools/plan-slice.ts +2 -2
  596. package/src/resources/extensions/gsd/tools/plan-task.ts +2 -2
  597. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +2 -2
  598. package/src/resources/extensions/gsd/tools/reopen-milestone.ts +2 -2
  599. package/src/resources/extensions/gsd/tools/reopen-slice.ts +2 -2
  600. package/src/resources/extensions/gsd/tools/reopen-task.ts +2 -2
  601. package/src/resources/extensions/gsd/tools/replan-slice.ts +2 -2
  602. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +81 -2
  603. package/src/resources/extensions/gsd/uat-policy.ts +60 -15
  604. package/src/resources/extensions/gsd/unit-context-composer.ts +99 -0
  605. package/src/resources/extensions/gsd/unit-registry.ts +34 -4
  606. package/src/resources/extensions/gsd/verdict-parser.ts +1 -1
  607. package/src/resources/extensions/gsd/verification-verdict.ts +4 -2
  608. package/src/resources/extensions/gsd/workflow-event-ledger.ts +131 -0
  609. package/src/resources/extensions/gsd/workflow-event-vocabulary.ts +59 -0
  610. package/src/resources/extensions/gsd/workflow-events.ts +12 -20
  611. package/src/resources/extensions/gsd/workflow-mcp-auto-prep.ts +2 -0
  612. package/src/resources/extensions/gsd/workflow-mcp-readiness-cache.ts +150 -0
  613. package/src/resources/extensions/gsd/workflow-reconcile.ts +29 -62
  614. package/src/resources/extensions/gsd/worktree-lifecycle.ts +3 -8
  615. package/src/resources/extensions/gsd/worktree-manager.ts +6 -1
  616. package/src/resources/extensions/gsd/worktree-safety.ts +41 -39
  617. package/src/resources/extensions/gsd/worktree.ts +7 -1
  618. package/src/resources/extensions/mcp-client/manager.ts +7 -1
  619. package/src/resources/extensions/shared/gsd-browser-cli.ts +54 -3
  620. package/src/resources/shared/gsd-browser-path-sync.ts +273 -0
  621. package/src/resources/shared/package-manager-detection.ts +1 -1
  622. package/src/resources/shared/package.json +3 -0
  623. package/src/resources/skills/create-skill/SKILL.md +3 -0
  624. package/src/resources/skills/create-skill/references/skill-structure.md +1 -0
  625. package/dist/resources/extensions/gsd/user-input-boundary.js +0 -218
  626. package/dist/resources/skills/gsd-browser/SKILL.md +0 -41
  627. package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +0 -173
  628. package/src/resources/extensions/gsd/user-input-boundary.ts +0 -216
  629. package/src/resources/skills/gsd-browser/SKILL.md +0 -41
  630. /package/dist/web/standalone/.next/static/{AOpDeK_gJHU8OZjRo31gQ → pZbHa49xI-knmKlphIRq0}/_buildManifest.js +0 -0
  631. /package/dist/web/standalone/.next/static/{AOpDeK_gJHU8OZjRo31gQ → pZbHa49xI-knmKlphIRq0}/_ssgManifest.js +0 -0
@@ -12,7 +12,7 @@
12
12
  import { debugCount, debugLog, debugTime } from "../debug-logger.js";
13
13
  import { reconcileBeforeDispatch } from "../state-reconciliation.js";
14
14
  import { isLegalEdge, IllegalPhaseTransitionError } from "../state-transition-matrix.js";
15
- import { resolveDispatch } from "../auto-dispatch.js";
15
+ import { hasPendingDeepStage, resolveDispatch } from "../auto-dispatch.js";
16
16
  import { classifyFailure } from "../recovery-classification.js";
17
17
  import { verifyExpectedArtifact, refreshRecoveryDbForArtifact } from "../auto-recovery.js";
18
18
  import { invalidateAllCaches } from "../cache.js";
@@ -42,21 +42,15 @@ import { isDbAvailable, getSlice, getTask, } from "../gsd-db.js";
42
42
  import { refreshWorkflowDatabaseFromDisk } from "../db-workspace.js";
43
43
  import { getErrorMessage } from "../error-utils.js";
44
44
  import { logWarning } from "../workflow-logger.js";
45
+ import { normalizeRealPath } from "../paths.js";
46
+ import { buildDispatchKey, createDispatchHistory, STUCK_WINDOW_SIZE, } from "./dispatch-history.js";
45
47
  import { existsSync, readFileSync } from "node:fs";
46
48
  import { join } from "node:path";
47
49
  import { evaluateAllCompleteSettlement } from "../milestone-settlement.js";
50
+ import { hasHeldMilestoneLease, reclaimMissingMilestoneLease } from "./milestone-lease-reclaim.js";
48
51
  function now() {
49
52
  return Date.now();
50
53
  }
51
- /**
52
- * Size of the dispatch-decision ring buffer used by the Auto Orchestration
53
- * module's stuck-loop detector. When the same `${unitType}:${unitId}` key
54
- * fills the window, advance() blocks with `action: "stop"`.
55
- *
56
- * Mirrors the legacy `STUCK_WINDOW_SIZE` in auto/phases.ts so behaviour is
57
- * preserved across the eventual cutover (issue #5791).
58
- */
59
- export const STUCK_WINDOW_SIZE = 6;
60
54
  function noRemainingUnitsOutcome(stateSnapshot) {
61
55
  if (stateSnapshot.phase === "complete") {
62
56
  return {
@@ -118,14 +112,26 @@ function shouldAdoptActiveMilestone(state, activeSession, activeDispatchBasePath
118
112
  export async function decideOrchestratorDispatch(ctx, pi, dispatchBasePath, session, input) {
119
113
  const state = input.stateSnapshot;
120
114
  const active = state.activeMilestone;
121
- if (!active)
122
- return null;
123
115
  const activeSession = input.session ?? session;
124
116
  const activeDispatchBasePath = activeSession?.basePath || dispatchBasePath;
125
- if (activeSession && shouldAdoptActiveMilestone(state, activeSession, activeDispatchBasePath)) {
117
+ const prefs = loadEffectiveGSDPreferences(activeDispatchBasePath)?.preferences;
118
+ if (!active) {
119
+ if (state.phase !== "pre-planning")
120
+ return null;
121
+ if (!hasPendingDeepStage(prefs, activeDispatchBasePath)) {
122
+ return {
123
+ kind: "blocked",
124
+ reason: state.nextAction || "No active milestone. Run /gsd unpark <id> or create a new milestone.",
125
+ action: "stop",
126
+ };
127
+ }
128
+ }
129
+ if (active && activeSession && shouldAdoptActiveMilestone(state, activeSession, activeDispatchBasePath)) {
126
130
  activeSession.currentMilestoneId = active.id;
131
+ activeSession.milestoneLeaseToken = null;
127
132
  }
128
- const prefs = loadEffectiveGSDPreferences(activeDispatchBasePath)?.preferences;
133
+ const dispatchMid = active?.id ?? activeSession?.currentMilestoneId ?? "";
134
+ const dispatchMidTitle = active?.title ?? "";
129
135
  // Derive session-derived dispatch inputs the same way phases.ts:runDispatch does
130
136
  // (#5789). Prefer caller-supplied values when present so test harnesses and
131
137
  // alternative wirings can inject deterministic snapshots; otherwise pull from
@@ -153,8 +159,15 @@ export async function decideOrchestratorDispatch(ctx, pi, dispatchBasePath, sess
153
159
  })
154
160
  ? "true"
155
161
  : "false");
162
+ // Only replay a milestone-scoped verification retry when a milestone is
163
+ // active. Pre-PR (#712 fix), `!active` returned null before reaching this
164
+ // block, so the retry was preserved for a future tick. The new
165
+ // pre-planning + deep-pending fall-through must keep that contract:
166
+ // otherwise a stale execute-task / complete-slice / complete-milestone
167
+ // retry whose target milestone has since been parked would preempt
168
+ // project-level deep rules like `discuss-project`.
156
169
  const pendingRetry = session?.pendingVerificationRetryDispatch;
157
- if (session && pendingRetry) {
170
+ if (session && pendingRetry && active) {
158
171
  session.pendingVerificationRetryDispatch = null;
159
172
  const alreadyClosedReason = getAlreadyClosedDispatchReason(pendingRetry.unitType, pendingRetry.unitId);
160
173
  if (alreadyClosedReason) {
@@ -172,8 +185,8 @@ export async function decideOrchestratorDispatch(ctx, pi, dispatchBasePath, sess
172
185
  }
173
186
  const action = await resolveDispatch({
174
187
  basePath: activeDispatchBasePath,
175
- mid: active.id,
176
- midTitle: active.title,
188
+ mid: dispatchMid,
189
+ midTitle: dispatchMidTitle,
177
190
  state,
178
191
  prefs,
179
192
  session: activeSession,
@@ -218,8 +231,8 @@ export async function decideOrchestratorDispatch(ctx, pi, dispatchBasePath, sess
218
231
  prompt: action.prompt,
219
232
  pauseAfterUatDispatch: action.pauseAfterDispatch ?? false,
220
233
  state,
221
- mid: active.id,
222
- midTitle: active.title,
234
+ mid: dispatchMid,
235
+ midTitle: dispatchMidTitle,
223
236
  };
224
237
  session.pendingOrchestrationDispatch = pending;
225
238
  }
@@ -244,7 +257,9 @@ export class AutoOrchestrator {
244
257
  seq = 0;
245
258
  lastAdvanceKey = null;
246
259
  lastFinalizedUnitKey = null;
247
- dispatchKeyWindow = [];
260
+ // Dispatch History module (#482): the dispatch-decision window with
261
+ // cross-session DB rehydration and full detect-stuck rules.
262
+ dispatchHistory;
248
263
  // ADR-030 Phase Transition Invariant: the prior advance's reconciled Phase,
249
264
  // the "from" endpoint of the edge check. In-memory; reset on start/resume/stop
250
265
  // so the first advance of a session has no edge to assert.
@@ -260,6 +275,13 @@ export class AutoOrchestrator {
260
275
  this.runtimeBasePath = context.runtimeBasePath;
261
276
  this.s = context.session;
262
277
  this.flowId = `auto-orchestrator-${Date.now()}`;
278
+ this.dispatchHistory = createDispatchHistory({
279
+ windowSize: STUCK_WINDOW_SIZE,
280
+ // Same stable scope the auto-loop uses for stuck-state persistence so
281
+ // rehydration reads the rows the dispatch ledger wrote for this project.
282
+ resolveScopeId: () => normalizeRealPath(this.s.scope?.workspace.projectRoot ??
283
+ (this.s.originalBasePath || this.s.basePath || this.runtimeBasePath)) || null,
284
+ });
263
285
  }
264
286
  // ── Live base-path resolution (was the wiring factory's getLiveDispatchBasePath) ──
265
287
  getLiveDispatchBasePath() {
@@ -456,6 +478,29 @@ export class AutoOrchestrator {
456
478
  },
457
479
  };
458
480
  }
481
+ async mergePendingCompleteMilestone(milestoneId) {
482
+ const result = this.buildLifecycle().exitMilestone(milestoneId, { merge: true }, this.ctx.ui);
483
+ if (!result.ok) {
484
+ const detail = result.cause instanceof Error
485
+ ? result.cause.message
486
+ : result.reason;
487
+ return {
488
+ ok: false,
489
+ reason: `Milestone ${milestoneId} is complete, but the system-owned merge failed: ${detail}`,
490
+ };
491
+ }
492
+ this.s.milestoneMergedInPhases = true;
493
+ this.s.milestoneSettlement = { ok: true, reason: "settled" };
494
+ try {
495
+ const projectRoot = this.s.originalBasePath || this.s.canonicalProjectRoot || this.runtimeBasePath;
496
+ const { rebuildMarkdownProjectionsFromDb } = await import("../commands-maintenance.js");
497
+ await rebuildMarkdownProjectionsFromDb(projectRoot);
498
+ }
499
+ catch (err) {
500
+ logWarning("engine", `markdown projection rebuild after settlement merge failed: ${err instanceof Error ? err.message : String(err)}`);
501
+ }
502
+ return { ok: true };
503
+ }
459
504
  clearPendingDispatch() {
460
505
  this.s.pendingOrchestrationDispatch = null;
461
506
  }
@@ -516,9 +561,6 @@ export class AutoOrchestrator {
516
561
  reason: `No Unit manifest is registered for ${unitType}`,
517
562
  };
518
563
  }
519
- if (isolationMode !== "worktree") {
520
- return { ok: true, reason: "not-required" };
521
- }
522
564
  const writeScope = manifest.tools.mode === "all" || manifest.tools.mode === "docs"
523
565
  ? "source-writing"
524
566
  : "planning-only";
@@ -526,7 +568,21 @@ export class AutoOrchestrator {
526
568
  const activeBasePath = this.getLiveDispatchBasePath();
527
569
  const snapshot = await deriveState(activeBasePath);
528
570
  const milestoneId = snapshot.activeMilestone?.id ?? null;
529
- const expectedBranch = milestoneId ? autoWorktreeBranch(milestoneId) : null;
571
+ const buildExpectedBranch = (mode) => mode !== "none" && milestoneId ? autoWorktreeBranch(milestoneId) : null;
572
+ // The milestone lease coordinates concurrent workers on an isolated
573
+ // milestone worktree/branch. `none` mode has no per-milestone isolation
574
+ // and does not reliably claim a lease, so requiring one there would
575
+ // falsely fail dispatch; enforce it only in isolated modes.
576
+ const buildLease = (mode) => milestoneId && this.s.workerId
577
+ ? {
578
+ required: writeScope === "source-writing" && mode !== "none",
579
+ held: hasHeldMilestoneLease(this.s, milestoneId),
580
+ owner: this.s.workerId,
581
+ }
582
+ : undefined;
583
+ if (writeScope === "source-writing") {
584
+ reclaimMissingMilestoneLease(this.s, milestoneId, isolationMode, "orchestrator");
585
+ }
530
586
  let result = safety.validateUnitRoot({
531
587
  unitType,
532
588
  unitId,
@@ -535,7 +591,8 @@ export class AutoOrchestrator {
535
591
  unitRoot: activeBasePath,
536
592
  milestoneId,
537
593
  isolationMode,
538
- expectedBranch,
594
+ expectedBranch: buildExpectedBranch(isolationMode),
595
+ lease: buildLease(isolationMode),
539
596
  });
540
597
  if (!result.ok) {
541
598
  const repaired = await repairAutoWorktreeSafetyFailure({
@@ -553,16 +610,20 @@ export class AutoOrchestrator {
553
610
  this.rebuildScope(this.s.basePath, this.s.currentMilestoneId);
554
611
  return { ok: true };
555
612
  },
556
- revalidate: () => safety.validateUnitRoot({
557
- unitType,
558
- unitId,
559
- writeScope,
560
- projectRoot: this.runtimeBasePath,
561
- unitRoot: this.getLiveDispatchBasePath(),
562
- milestoneId,
563
- isolationMode: this.getEffectiveUnitIsolationMode(this.runtimeBasePath),
564
- expectedBranch,
565
- }),
613
+ revalidate: () => {
614
+ const revalidatedMode = this.getEffectiveUnitIsolationMode(this.runtimeBasePath);
615
+ return safety.validateUnitRoot({
616
+ unitType,
617
+ unitId,
618
+ writeScope,
619
+ projectRoot: this.runtimeBasePath,
620
+ unitRoot: this.getLiveDispatchBasePath(),
621
+ milestoneId,
622
+ isolationMode: revalidatedMode,
623
+ expectedBranch: buildExpectedBranch(revalidatedMode),
624
+ lease: buildLease(revalidatedMode),
625
+ });
626
+ },
566
627
  });
567
628
  result = repaired.result;
568
629
  if (result.ok) {
@@ -612,7 +673,7 @@ export class AutoOrchestrator {
612
673
  * skipped result) instead of stopping.
613
674
  */
614
675
  tryStuckArtifactRecovery(unitType, unitId) {
615
- const key = `${unitType}:${unitId}`;
676
+ const key = buildDispatchKey(unitType, unitId);
616
677
  if (this.lastStuckRecoveryKey === key)
617
678
  return false; // already tried this episode
618
679
  const basePath = this.getLiveDispatchBasePath();
@@ -627,7 +688,7 @@ export class AutoOrchestrator {
627
688
  return false;
628
689
  this.lastStuckRecoveryKey = key;
629
690
  invalidateAllCaches();
630
- this.dispatchKeyWindow = [];
691
+ this.dispatchHistory.clearOnRecovery();
631
692
  this.lastAdvanceKey = null;
632
693
  this.lastFinalizedUnitKey = null;
633
694
  return true;
@@ -653,7 +714,12 @@ export class AutoOrchestrator {
653
714
  async start(_sessionContext) {
654
715
  this.lastAdvanceKey = null;
655
716
  this.lastFinalizedUnitKey = null;
656
- this.dispatchKeyWindow = [];
717
+ // #482: the DB dispatch ledger is the source of truth across sessions.
718
+ // Discard any in-memory window and rebuild it from the ledger so a unit
719
+ // that was re-dispatched in previous sessions is detected as stuck here
720
+ // instead of silently re-dispatching forever.
721
+ this.dispatchHistory.clearOnRecovery();
722
+ this.dispatchHistory.rehydrate();
657
723
  this.lastStuckRecoveryKey = null;
658
724
  this.lastDerivedPhase = null;
659
725
  this.status.phase = "running";
@@ -750,10 +816,39 @@ export class AutoOrchestrator {
750
816
  if (!decision) {
751
817
  const settlementBlock = this.evaluateNoRemainingUnitsSettlement(reconciliation.stateSnapshot);
752
818
  if (settlementBlock) {
819
+ const settlement = this.s.milestoneSettlement;
820
+ if (settlement && !settlement.ok && settlement.reason === "merge-pending") {
821
+ const merged = await this.mergePendingCompleteMilestone(settlement.milestoneId);
822
+ if (merged.ok) {
823
+ const terminalOutcome = noRemainingUnitsOutcome(reconciliation.stateSnapshot);
824
+ const stopped = {
825
+ kind: "stopped",
826
+ reason: terminalOutcome.displayReason,
827
+ stateSnapshot: reconciliation.stateSnapshot,
828
+ terminalOutcome,
829
+ };
830
+ this.status.phase = "stopped";
831
+ this.status.activeUnit = undefined;
832
+ this.lastAdvanceKey = null;
833
+ this.dispatchHistory.clearOnRecovery();
834
+ this.bumpTransition();
835
+ this.journalTransition({ name: "advance-stopped", reason: stopped.reason });
836
+ this.postAdvanceRecord(stopped);
837
+ return stopped;
838
+ }
839
+ settlementBlock.reason = merged.reason;
840
+ settlementBlock.terminalOutcome = {
841
+ code: "settlement-blocked",
842
+ displayReason: merged.reason,
843
+ nextAction: `Fix the merge failure, then retry \`/gsd dispatch complete-milestone ${settlement.milestoneId}\`.`,
844
+ milestoneId: settlement.milestoneId,
845
+ allMilestonesComplete: false,
846
+ };
847
+ }
753
848
  this.status.phase = "paused";
754
849
  this.status.activeUnit = undefined;
755
850
  this.lastAdvanceKey = null;
756
- this.dispatchKeyWindow = [];
851
+ this.dispatchHistory.clearOnRecovery();
757
852
  this.bumpTransition();
758
853
  this.journalTransition({ name: "advance-blocked", reason: settlementBlock.reason });
759
854
  this.postAdvanceRecord(settlementBlock);
@@ -769,7 +864,7 @@ export class AutoOrchestrator {
769
864
  this.status.phase = "stopped";
770
865
  this.status.activeUnit = undefined;
771
866
  this.lastAdvanceKey = null;
772
- this.dispatchKeyWindow = [];
867
+ this.dispatchHistory.clearOnRecovery();
773
868
  this.bumpTransition();
774
869
  this.journalTransition({ name: "advance-stopped", reason: stopped.reason });
775
870
  this.postAdvanceRecord(stopped);
@@ -817,16 +912,12 @@ export class AutoOrchestrator {
817
912
  this.postAdvanceRecord(blocked);
818
913
  return blocked;
819
914
  }
820
- const nextKey = `${decision.unitType}:${decision.unitId}`;
821
- // Record every dispatch decision in the ring buffer before pre-flight
915
+ // Record every dispatch decision in the history window before pre-flight
822
916
  // checks so the stuck-loop detector observes the full decision history
823
917
  // (including decisions that idempotency would otherwise short-circuit).
824
- // The ring is capped at STUCK_WINDOW_SIZE and evicts oldest-first.
825
- this.dispatchKeyWindow.push(nextKey);
826
- if (this.dispatchKeyWindow.length > STUCK_WINDOW_SIZE) {
827
- this.dispatchKeyWindow.shift();
828
- }
829
- const matchingCount = this.dispatchKeyWindow.filter((k) => k === nextKey).length;
918
+ // The window is capped at STUCK_WINDOW_SIZE and evicts oldest-first.
919
+ const nextKey = this.dispatchHistory.recordDispatch(decision.unitType, decision.unitId);
920
+ const matchingCount = this.dispatchHistory.countMatching(nextKey);
830
921
  if (this.lastFinalizedUnitKey === nextKey) {
831
922
  // #442: the unit re-dispatched immediately after finalizing may have
832
923
  // actually completed on disk with a stale DB. Verify + recover before
@@ -858,22 +949,30 @@ export class AutoOrchestrator {
858
949
  // checks coexist: idempotency for the common immediate-repeat case,
859
950
  // stuck-loop for the saturated-window case.
860
951
  if (this.lastAdvanceKey === nextKey && matchingCount < STUCK_WINDOW_SIZE) {
952
+ // Unit already active — benign no-op. Return skipped so the loop re-polls
953
+ // without cancelling the in-flight unit (blocked+pause would force-cancel it).
861
954
  this.clearPendingDispatch();
862
- const blocked = { kind: "blocked", reason: "idempotent advance: unit already active", action: "pause" };
955
+ const skipped = { kind: "skipped", reason: "idempotent advance: unit already active" };
863
956
  this.journalTransition({
864
- name: "advance-blocked",
865
- reason: blocked.reason,
957
+ name: "advance-skipped",
958
+ reason: skipped.reason,
866
959
  unitType: decision.unitType,
867
960
  unitId: decision.unitId,
868
961
  });
869
- this.postAdvanceRecord(blocked);
870
- return blocked;
962
+ this.postAdvanceRecord(skipped);
963
+ return skipped;
871
964
  }
872
- // Stuck-loop detection: when the ring is saturated with copies of
873
- // `nextKey` (count >= STUCK_WINDOW_SIZE), the orchestrator has been
874
- // picking the same unit across the whole window and must hard-stop with
875
- // a diagnosable reason.
876
- if (matchingCount >= STUCK_WINDOW_SIZE) {
965
+ // Stuck-loop detection: when the window is saturated with copies of
966
+ // `nextKey` (count >= STUCK_WINDOW_SIZE), consult the Dispatch History
967
+ // module's full detect-stuck rule set for the verdict instead of the old
968
+ // bare saturation count. This keeps the saturation threshold (the window
969
+ // deliberately records benign idempotent repeats, so earlier-firing
970
+ // rules would false-positive on pause/resume re-advances) while gaining
971
+ // retry-budget suppression and diagnosable rule reasons. A saturated
972
+ // window with no verdict means the dispatch ledger says we are inside
973
+ // the unit's retry-backoff budget — let the retry proceed.
974
+ const stuckVerdict = matchingCount >= STUCK_WINDOW_SIZE ? this.dispatchHistory.detectStuck() : null;
975
+ if (stuckVerdict) {
877
976
  // #442: before declaring a stuck loop, verify the unit didn't actually
878
977
  // complete on disk (stale DB) and recover if so — legacy graduated
879
978
  // stuck-recovery parity. Otherwise hard-stop with a diagnosable reason.
@@ -884,7 +983,7 @@ export class AutoOrchestrator {
884
983
  this.clearPendingDispatch();
885
984
  const blocked = {
886
985
  kind: "blocked",
887
- reason: `stuck-loop: ${nextKey} picked ${matchingCount} times`,
986
+ reason: `stuck-loop: ${stuckVerdict.reason}`,
888
987
  action: "stop",
889
988
  };
890
989
  this.journalTransition({
@@ -974,7 +1073,7 @@ export class AutoOrchestrator {
974
1073
  if (result.kind === "stopped") {
975
1074
  this.lastAdvanceKey = null;
976
1075
  this.lastFinalizedUnitKey = null;
977
- this.dispatchKeyWindow = [];
1076
+ this.dispatchHistory.clearOnRecovery();
978
1077
  this.status.activeUnit = undefined;
979
1078
  }
980
1079
  this.bumpTransition();
@@ -1003,8 +1102,14 @@ export class AutoOrchestrator {
1003
1102
  async resume() {
1004
1103
  this.lastAdvanceKey = null;
1005
1104
  this.lastFinalizedUnitKey = null;
1006
- // Preserve dispatchKeyWindow across resume so stuck-loop detection
1007
- // accumulates across pause/resume cycles rather than resetting each time.
1105
+ // Preserve the dispatch-history window across an in-process resume so
1106
+ // stuck-loop detection accumulates across pause/resume cycles rather than
1107
+ // resetting each time (#572 regression). When the window is empty (fresh
1108
+ // orchestrator resuming a prior session), rehydrate it from the DB
1109
+ // dispatch ledger so cross-session re-dispatch loops are detected (#482).
1110
+ if (this.dispatchHistory.getRecentWindow().length === 0) {
1111
+ this.dispatchHistory.rehydrate();
1112
+ }
1008
1113
  this.lastStuckRecoveryKey = null;
1009
1114
  // ADR-030: drop the prior "from" — the first advance after resume has no
1010
1115
  // edge to assert (avoids a false illegal-edge across the pause boundary).
@@ -1025,10 +1130,10 @@ export class AutoOrchestrator {
1025
1130
  this.lastAdvanceKey = null;
1026
1131
  this.lastFinalizedUnitKey = null;
1027
1132
  this.lastDerivedPhase = null;
1028
- // Preserve dispatchKeyWindow on pause so stuck-loop detection accumulates
1029
- // across pause/resume cycles. Only clear on a hard stop.
1133
+ // Preserve the dispatch-history window on pause so stuck-loop detection
1134
+ // accumulates across pause/resume cycles. Only clear on a hard stop.
1030
1135
  if (reason !== "pause") {
1031
- this.dispatchKeyWindow = [];
1136
+ this.dispatchHistory.clearOnRecovery();
1032
1137
  }
1033
1138
  this.lastStuckRecoveryKey = null;
1034
1139
  this.bumpTransition();
@@ -1040,9 +1145,9 @@ export class AutoOrchestrator {
1040
1145
  return { ...this.status, activeUnit: this.status.activeUnit ? { ...this.status.activeUnit } : undefined };
1041
1146
  }
1042
1147
  async completeActiveUnit(unit) {
1043
- const unitKey = `${unit.unitType}:${unit.unitId}`;
1148
+ const unitKey = buildDispatchKey(unit.unitType, unit.unitId);
1044
1149
  const activeUnitKey = this.status.activeUnit
1045
- ? `${this.status.activeUnit.unitType}:${this.status.activeUnit.unitId}`
1150
+ ? buildDispatchKey(this.status.activeUnit.unitType, this.status.activeUnit.unitId)
1046
1151
  : null;
1047
1152
  if (activeUnitKey !== unitKey)
1048
1153
  return;
@@ -1059,9 +1164,9 @@ export class AutoOrchestrator {
1059
1164
  });
1060
1165
  }
1061
1166
  async retryActiveUnit(unit) {
1062
- const unitKey = `${unit.unitType}:${unit.unitId}`;
1167
+ const unitKey = buildDispatchKey(unit.unitType, unit.unitId);
1063
1168
  const activeUnitKey = this.status.activeUnit
1064
- ? `${this.status.activeUnit.unitType}:${this.status.activeUnit.unitId}`
1169
+ ? buildDispatchKey(this.status.activeUnit.unitType, this.status.activeUnit.unitId)
1065
1170
  : null;
1066
1171
  if (activeUnitKey !== unitKey && this.lastFinalizedUnitKey !== unitKey)
1067
1172
  return;
@@ -0,0 +1,146 @@
1
+ // Project/App: gsd-pi
2
+ // File Purpose: Shared helpers used across auto-loop phase modules.
3
+ import { setRuntimeKv } from "../db/runtime-kv.js";
4
+ import { debugLog } from "../debug-logger.js";
5
+ import { normalizeRealPath } from "../paths.js";
6
+ import { resolveWorktreeProjectRoot, normalizeWorktreePathForCompare } from "../worktree-root.js";
7
+ import { decideVerificationRetry, verificationRetryKey } from "./verification-retry-policy.js";
8
+ const STUCK_RECOVERY_ATTEMPTS_KEY = "stuck_recovery_attempts";
9
+ /** Compare two paths for physical identity, tolerating trailing slashes and symlinks. */
10
+ export function isSamePathLocal(a, b) {
11
+ return normalizeWorktreePathForCompare(a) === normalizeWorktreePathForCompare(b);
12
+ }
13
+ export function isIsolatedWorktreeSession(s) {
14
+ return Boolean(s.originalBasePath)
15
+ && Boolean(s.basePath)
16
+ && !isSamePathLocal(s.originalBasePath, s.basePath);
17
+ }
18
+ export function persistStuckRecoveryAttempts(s, loopState) {
19
+ const scopeId = normalizeRealPath(s.scope?.workspace.projectRoot ?? (s.originalBasePath || s.basePath));
20
+ if (!scopeId)
21
+ return;
22
+ try {
23
+ setRuntimeKv("global", scopeId, STUCK_RECOVERY_ATTEMPTS_KEY, loopState.stuckRecoveryAttempts);
24
+ }
25
+ catch (err) {
26
+ debugLog("autoLoop", {
27
+ phase: "save-stuck-state-failed",
28
+ error: err instanceof Error ? err.message : String(err),
29
+ });
30
+ }
31
+ }
32
+ export async function applyVerificationRetryPolicy(ic, unitType, phase) {
33
+ const { ctx, pi, s, deps } = ic;
34
+ const retryInfo = s.pendingVerificationRetry;
35
+ const key = unitType && retryInfo
36
+ ? verificationRetryKey(unitType, retryInfo.unitId)
37
+ : undefined;
38
+ const decision = decideVerificationRetry({
39
+ unitType,
40
+ retryInfo,
41
+ previousFailureHash: key ? s.verificationRetryFailureHashes.get(key) : undefined,
42
+ });
43
+ if (decision.action === "pause") {
44
+ s.pendingVerificationRetry = null;
45
+ debugLog("autoLoop", {
46
+ phase: `${phase}-paused`,
47
+ reason: decision.reason,
48
+ unitType,
49
+ unitId: retryInfo?.unitId,
50
+ failureHash: decision.failureHash,
51
+ });
52
+ ctx.ui.notify(decision.reason === "duplicate-failure-context"
53
+ ? `Verification retry for ${unitType ?? "unit"} ${retryInfo?.unitId ?? "unknown"} produced the same failure context. Pausing auto-mode instead of re-dispatching.`
54
+ : "Verification retry requested without retry context. Pausing auto-mode instead of re-dispatching.", "warning");
55
+ await deps.pauseAuto(ctx, pi);
56
+ return { action: "break", reason: decision.reason };
57
+ }
58
+ s.verificationRetryFailureHashes.set(decision.key, decision.failureHash);
59
+ debugLog("autoLoop", {
60
+ phase: `${phase}-backoff`,
61
+ iteration: ic.iteration,
62
+ unitType,
63
+ unitId: retryInfo?.unitId,
64
+ attempt: retryInfo?.attempt,
65
+ delayMs: decision.delayMs,
66
+ baseDelayMs: decision.baseDelayMs,
67
+ failureHash: decision.failureHash,
68
+ });
69
+ await new Promise((resolve) => setTimeout(resolve, decision.delayMs));
70
+ return null;
71
+ }
72
+ export function rememberRetryDispatch(s, unit, iterData) {
73
+ if (!unit)
74
+ return;
75
+ s.pendingVerificationRetryDispatch = {
76
+ unitType: unit.type,
77
+ unitId: unit.id,
78
+ prompt: iterData.prompt,
79
+ pauseAfterUatDispatch: iterData.pauseAfterUatDispatch,
80
+ state: iterData.state,
81
+ mid: iterData.mid,
82
+ midTitle: iterData.midTitle,
83
+ };
84
+ }
85
+ /**
86
+ * Resolve the base path for milestone reports.
87
+ * Prefers originalBasePath (project root) over basePath (which may be a worktree).
88
+ */
89
+ export function _resolveReportBasePath(s) {
90
+ return resolveWorktreeProjectRoot(s.basePath, s.originalBasePath);
91
+ }
92
+ /**
93
+ * Resolve the authoritative project base for dispatch guards.
94
+ * Prior-milestone completion lives at the project root, even when the active
95
+ * unit is running inside an auto worktree.
96
+ */
97
+ export function _resolveDispatchGuardBasePath(s) {
98
+ return resolveWorktreeProjectRoot(s.basePath, s.originalBasePath);
99
+ }
100
+ const PLAN_V2_GATE_PHASES = new Set([
101
+ "executing",
102
+ "summarizing",
103
+ "validating-milestone",
104
+ "completing-milestone",
105
+ ]);
106
+ export function shouldRunPlanV2Gate(phase) {
107
+ return PLAN_V2_GATE_PHASES.has(phase);
108
+ }
109
+ export function _resolveCurrentUnitStartedAtForTest(currentUnit) {
110
+ return currentUnit?.startedAt;
111
+ }
112
+ export async function emitCancelledUnitEnd(ic, unitType, unitId, unitStartSeq, errorContext) {
113
+ ic.deps.emitJournalEvent({
114
+ ts: new Date().toISOString(),
115
+ flowId: ic.flowId,
116
+ seq: ic.nextSeq(),
117
+ eventType: "unit-end",
118
+ data: {
119
+ unitType,
120
+ unitId,
121
+ status: "cancelled",
122
+ artifactVerified: false,
123
+ ...(errorContext ? { errorContext } : {}),
124
+ },
125
+ causedBy: { flowId: ic.flowId, seq: unitStartSeq },
126
+ });
127
+ }
128
+ export function _buildCancelledUnitStopReason(unitType, unitId, errorContext) {
129
+ const cancellationMessage = errorContext?.message ?? "unknown";
130
+ const isSessionCreationFailure = errorContext?.category === "session-failed";
131
+ if (isSessionCreationFailure) {
132
+ return {
133
+ notifyMessage: `Session creation failed for ${unitType} ${unitId}: ${cancellationMessage}. Stopping auto-mode.`,
134
+ stopReason: `Session creation failed: ${cancellationMessage}`,
135
+ loopReason: "session-failed",
136
+ };
137
+ }
138
+ return {
139
+ notifyMessage: `Unit ${unitType} ${unitId} aborted after dispatch: ${cancellationMessage}. Stopping auto-mode.`,
140
+ stopReason: `Unit aborted: ${cancellationMessage}`,
141
+ loopReason: "unit-aborted",
142
+ };
143
+ }
144
+ export function _isPauseOriginCancelledResult(isPaused, errorContext) {
145
+ return isPaused && !errorContext;
146
+ }