@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
@@ -22,8 +22,8 @@ import {
22
22
  createAutoOrchestrator,
23
23
  decideOrchestratorDispatch,
24
24
  resolveLiveOrchestratorBasePath,
25
- STUCK_WINDOW_SIZE,
26
25
  } from "../auto/orchestrator.js";
26
+ import { STUCK_WINDOW_SIZE } from "../auto/dispatch-history.js";
27
27
  import type { OrchestratorContext } from "../auto/orchestrator.js";
28
28
  import type { AutoOrchestrationModule, AutoSessionContext } from "../auto/contracts.js";
29
29
  import type { GSDState } from "../types.js";
@@ -41,6 +41,10 @@ import {
41
41
  openDatabase,
42
42
  } from "../gsd-db.js";
43
43
  import { AutoSession } from "../auto/session.js";
44
+ import { registerAutoWorker } from "../db/auto-workers.js";
45
+ import { claimMilestoneLease, getMilestoneLease, releaseMilestoneLease } from "../db/milestone-leases.js";
46
+ import { recordDispatchClaim, markFailed } from "../db/unit-dispatches.js";
47
+ import { normalizeRealPath } from "../paths.js";
44
48
  import { acquireSessionLock, releaseSessionLock } from "../session-lock.js";
45
49
  import { queryJournal } from "../journal.js";
46
50
  import { invalidateAllCaches } from "../cache.js";
@@ -304,6 +308,71 @@ test("advance() sets active unit and is reflected in status", async (t) => {
304
308
  });
305
309
  });
306
310
 
311
+ test("advance() reclaims a released milestone lease before isolated source dispatch", async (t) => {
312
+ const f = makeFixture();
313
+ t.after(() => f.cleanup());
314
+
315
+ writeFileSync(
316
+ join(f.base, ".gsd", "PREFERENCES.md"),
317
+ "---\ngit:\n isolation: branch\n---\n",
318
+ );
319
+ execFileSync("git", ["checkout", "-b", "milestone/M001"], { cwd: f.base, stdio: "ignore" });
320
+
321
+ const priorWorkerId = registerAutoWorker({ projectRootRealpath: f.base });
322
+ const priorLease = claimMilestoneLease(priorWorkerId, "M001");
323
+ assert.equal(priorLease.ok, true);
324
+ if (!priorLease.ok) return;
325
+ assert.equal(releaseMilestoneLease(priorWorkerId, "M001", priorLease.token), true);
326
+
327
+ const resumedWorkerId = registerAutoWorker({ projectRootRealpath: f.base });
328
+ f.session.workerId = resumedWorkerId;
329
+ f.session.currentMilestoneId = null;
330
+ f.session.milestoneLeaseToken = null;
331
+
332
+ const result = await f.orchestrator.advance();
333
+
334
+ assert.equal(result.kind, "advanced", JSON.stringify(result));
335
+ assert.equal(f.session.currentMilestoneId, "M001");
336
+ assert.equal(f.session.milestoneLeaseToken, priorLease.token + 1);
337
+ const lease = getMilestoneLease("M001");
338
+ assert.equal(lease?.worker_id, resumedWorkerId);
339
+ assert.equal(lease?.status, "held");
340
+ assert.ok(f.journalNames().includes("advance"));
341
+ assert.ok(!f.journalNames().includes("advance-blocked"));
342
+ });
343
+
344
+ test("advance() claims the active milestone lease even when session still holds a prior milestone token", async (t) => {
345
+ const f = makeFixture();
346
+ t.after(() => f.cleanup());
347
+
348
+ writeFileSync(
349
+ join(f.base, ".gsd", "PREFERENCES.md"),
350
+ "---\ngit:\n isolation: branch\n---\n",
351
+ );
352
+ execFileSync("git", ["checkout", "-b", "milestone/M001"], { cwd: f.base, stdio: "ignore" });
353
+
354
+ insertMilestone({ id: "M000", title: "Prior", status: "complete" });
355
+ const workerId = registerAutoWorker({ projectRootRealpath: f.base });
356
+ const staleLease = claimMilestoneLease(workerId, "M000");
357
+ assert.equal(staleLease.ok, true);
358
+ if (!staleLease.ok) return;
359
+
360
+ f.session.workerId = workerId;
361
+ f.session.currentMilestoneId = "M000";
362
+ f.session.milestoneLeaseToken = staleLease.token;
363
+
364
+ const result = await f.orchestrator.advance();
365
+
366
+ assert.equal(result.kind, "advanced", JSON.stringify(result));
367
+ assert.equal(f.session.currentMilestoneId, "M001");
368
+ const activeLease = getMilestoneLease("M001");
369
+ assert.equal(activeLease?.worker_id, workerId);
370
+ assert.equal(activeLease?.status, "held");
371
+ assert.equal(f.session.milestoneLeaseToken, activeLease?.fencing_token);
372
+ assert.ok(f.journalNames().includes("advance"));
373
+ assert.ok(!f.journalNames().includes("advance-blocked"));
374
+ });
375
+
307
376
  test("advance() blocks source dispatch when an earlier slice is incomplete", async (t) => {
308
377
  const f = makeFixture({
309
378
  dispatch: () => ({
@@ -421,7 +490,7 @@ test("advance() reports completion when complete state has no next unit", async
421
490
  assert.equal(f.orchestrator.getStatus().phase, "stopped");
422
491
  });
423
492
 
424
- test("advance() blocks all-complete stop when completed milestone is still unmerged in a worktree", async (t) => {
493
+ test("advance() merges a completed milestone worktree before all-complete stop", async (t) => {
425
494
  const f = makeFixture({ complete: true, noTask: true });
426
495
  t.after(() => f.cleanup());
427
496
 
@@ -462,17 +531,16 @@ test("advance() blocks all-complete stop when completed milestone is still unmer
462
531
 
463
532
  const result = await f.orchestrator.advance();
464
533
 
465
- assert.equal(result.kind, "blocked");
466
- if (result.kind !== "blocked") return;
467
- assert.equal(result.action, "pause");
468
- assert.equal(result.terminalOutcome?.code, "settlement-blocked");
469
- assert.match(result.reason, /worktree branch has not been merged to main/);
470
- assert.doesNotMatch(result.reason, /quality gate Q3 is still pending/);
471
- assert.equal(f.orchestrator.getStatus().phase, "paused");
472
- assert.equal(f.session.milestoneSettlement?.ok, false);
534
+ assert.equal(result.kind, "stopped");
535
+ if (result.kind !== "stopped") return;
536
+ assert.equal(result.reason, "All milestones complete");
537
+ assert.equal(result.terminalOutcome?.code, "all-complete");
538
+ assert.equal(f.orchestrator.getStatus().phase, "stopped");
539
+ assert.equal(f.session.milestoneMergedInPhases, true);
540
+ assert.deepEqual(f.session.milestoneSettlement, { ok: true, reason: "settled" });
473
541
  const names = f.journalNames();
474
- assert.ok(names.includes("advance-blocked"));
475
- assert.ok(!names.includes("advance-stopped"));
542
+ assert.ok(names.includes("advance-stopped"));
543
+ assert.ok(!names.includes("advance-blocked"));
476
544
  });
477
545
 
478
546
  test("advance() stopped clears previous activeUnit and resets idempotent lock", async (t) => {
@@ -518,13 +586,12 @@ test("advance() is idempotent for the same active unit", async (t) => {
518
586
  if (first.kind === "advanced") {
519
587
  assert.deepEqual(first.unit, { unitType: "execute-task", unitId: "M001/S01/T01" });
520
588
  }
521
- assert.equal(second.kind, "blocked");
522
- if (second.kind !== "blocked") return;
589
+ assert.equal(second.kind, "skipped");
590
+ if (second.kind !== "skipped") return;
523
591
  assert.equal(second.reason, "idempotent advance: unit already active");
524
- assert.equal(second.action, "pause");
525
592
  });
526
593
 
527
- test("idempotency block fires with its own reason before saturation", async (t) => {
594
+ test("idempotency skip fires with its own reason before saturation", async (t) => {
528
595
  const f = makeFixture();
529
596
  t.after(() => f.cleanup());
530
597
 
@@ -532,10 +599,9 @@ test("idempotency block fires with its own reason before saturation", async (t)
532
599
  const second = await f.orchestrator.advance();
533
600
 
534
601
  assert.equal(first.kind, "advanced");
535
- assert.equal(second.kind, "blocked");
536
- if (second.kind !== "blocked") return;
602
+ assert.equal(second.kind, "skipped");
603
+ if (second.kind !== "skipped") return;
537
604
  assert.equal(second.reason, "idempotent advance: unit already active");
538
- assert.equal(second.action, "pause");
539
605
  });
540
606
 
541
607
  test("completeActiveUnit clears in-flight idempotency and stops stale same-unit advance", async (t) => {
@@ -671,12 +737,12 @@ test("resume() clears idempotent lock and allows re-advance", async (t) => {
671
737
  t.after(() => f.cleanup());
672
738
 
673
739
  const first = await f.orchestrator.advance();
674
- const blocked = await f.orchestrator.advance();
740
+ const idempotent = await f.orchestrator.advance();
675
741
  const resumed = await f.orchestrator.resume();
676
742
  const next = await f.orchestrator.advance();
677
743
 
678
744
  assert.equal(first.kind, "advanced");
679
- assert.equal(blocked.kind, "blocked");
745
+ assert.equal(idempotent.kind, "skipped");
680
746
  assert.equal(resumed.kind, "resumed");
681
747
  assert.equal(next.kind, "advanced");
682
748
  });
@@ -686,11 +752,11 @@ test("start() clears prior idempotent lock", async (t) => {
686
752
  t.after(() => f.cleanup());
687
753
 
688
754
  await f.orchestrator.advance();
689
- const blocked = await f.orchestrator.advance();
755
+ const idempotent = await f.orchestrator.advance();
690
756
  const restarted = await f.orchestrator.start(SESSION_CONTEXT);
691
757
  const next = await f.orchestrator.advance();
692
758
 
693
- assert.equal(blocked.kind, "blocked");
759
+ assert.equal(idempotent.kind, "skipped");
694
760
  assert.equal(restarted.kind, "started");
695
761
  assert.equal(next.kind, "advanced");
696
762
  });
@@ -700,32 +766,28 @@ test("stop() clears idempotent unit lock so advance can run again", async (t) =>
700
766
  t.after(() => f.cleanup());
701
767
 
702
768
  const first = await f.orchestrator.advance();
703
- const blocked = await f.orchestrator.advance();
769
+ const idempotent = await f.orchestrator.advance();
704
770
  const stopped = await f.orchestrator.stop("reset");
705
771
  const second = await f.orchestrator.advance();
706
772
 
707
773
  assert.equal(first.kind, "advanced");
708
- assert.equal(blocked.kind, "blocked");
774
+ assert.equal(idempotent.kind, "skipped");
709
775
  assert.equal(stopped.kind, "stopped");
710
776
  assert.equal(second.kind, "advanced");
711
777
  });
712
778
 
713
- test("blocked path journals advance-blocked and records a health snapshot", async (t) => {
779
+ test("idempotent path journals advance-skipped and records a health snapshot", async (t) => {
714
780
  const f = makeFixture();
715
781
  t.after(() => f.cleanup());
716
782
 
717
783
  await f.orchestrator.advance();
718
784
  await f.orchestrator.advance();
719
785
 
720
- assert.ok(f.journalNames().includes("advance-blocked"));
786
+ assert.ok(f.journalNames().includes("advance-skipped"));
721
787
  });
722
788
 
723
789
  // ─── Stuck-loop ring buffer (issue #5787) ──────────────────────────────────
724
790
 
725
- test("STUCK_WINDOW_SIZE matches the legacy auto/phases.ts constant", () => {
726
- assert.equal(STUCK_WINDOW_SIZE, 6);
727
- });
728
-
729
791
  test("stuck-loop: empty ring on a freshly constructed orchestrator advances normally", async (t) => {
730
792
  const f = makeFixture();
731
793
  t.after(() => f.cleanup());
@@ -761,21 +823,24 @@ test("stuck-loop: ring saturated with same unit blocks with action 'stop' and st
761
823
  // First call advances.
762
824
  assert.equal(results[0].kind, "advanced");
763
825
 
764
- // Intermediate calls are blocked by idempotency (not stuck-loop yet).
826
+ // Intermediate calls are skipped by idempotency (not stuck-loop yet).
765
827
  for (let i = 1; i < STUCK_WINDOW_SIZE - 1; i++) {
766
828
  const r = results[i];
767
- assert.equal(r.kind, "blocked", `round ${i} should be blocked`);
768
- if (r.kind !== "blocked") return;
829
+ assert.equal(r.kind, "skipped", `round ${i} should be skipped`);
830
+ if (r.kind !== "skipped") return;
769
831
  assert.equal(r.reason, "idempotent advance: unit already active");
770
- assert.equal(r.action, "pause");
771
832
  }
772
833
 
773
- // The final call (ring now holds STUCK_WINDOW_SIZE copies) returns stuck-loop.
834
+ // The final call (ring now holds STUCK_WINDOW_SIZE copies) returns stuck-loop
835
+ // with the detect-stuck rule verdict in the reason.
774
836
  const last = results[STUCK_WINDOW_SIZE - 1];
775
837
  assert.equal(last.kind, "blocked");
776
838
  if (last.kind !== "blocked") return;
777
839
  assert.equal(last.action, "stop");
778
- assert.equal(last.reason, `stuck-loop: execute-task:M001/S01/T01 picked ${STUCK_WINDOW_SIZE} times`);
840
+ assert.ok(
841
+ last.reason.startsWith("stuck-loop: execute-task:M001/S01/T01 derived"),
842
+ `expected detect-stuck verdict reason, got: ${last.reason}`,
843
+ );
779
844
  });
780
845
 
781
846
  test("stuck-loop: start() resets the ring so a fresh saturation cycle is required", async (t) => {
@@ -855,6 +920,80 @@ test("stuck-loop: stop('user-request') resets the ring (hard stop)", async (t) =
855
920
  assert.equal(next.kind, "advanced");
856
921
  });
857
922
 
923
+ test("stuck-loop #482 regression: start() rehydrates the window from the dispatch ledger so cross-session re-dispatch loops are detected", async (t) => {
924
+ const f = makeFixture();
925
+ t.after(() => f.cleanup());
926
+
927
+ // Simulate a PRIOR session: the dispatch ledger recorded the same unit
928
+ // being re-dispatched repeatedly without progress. The orchestrator under test is a
929
+ // fresh instance (as it would be after a session restart) — before the
930
+ // Dispatch History module, start() reset the window to [] and the loop
931
+ // would silently re-dispatch the unit forever (#482: 146 re-dispatches).
932
+ const worker = registerAutoWorker({ projectRootRealpath: normalizeRealPath(f.base) });
933
+ const lease = claimMilestoneLease(worker, "M001");
934
+ assert.equal(lease.ok, true);
935
+ if (!lease.ok) return;
936
+ for (let i = 0; i < STUCK_WINDOW_SIZE - 1; i++) {
937
+ const claim = recordDispatchClaim({
938
+ traceId: `prior-session-${i}`,
939
+ workerId: worker,
940
+ milestoneLeaseToken: lease.token,
941
+ milestoneId: "M001",
942
+ unitType: "execute-task",
943
+ unitId: "M001/S01/T01",
944
+ });
945
+ assert.equal(claim.ok, true);
946
+ if (!claim.ok) return;
947
+ markFailed(claim.dispatchId, { errorSummary: "" });
948
+ }
949
+
950
+ const started = await f.orchestrator.start(SESSION_CONTEXT);
951
+ assert.equal(started.kind, "started");
952
+
953
+ // The very next decision for the same unit must trip the stuck verdict
954
+ // instead of advancing.
955
+ const result = await f.orchestrator.advance();
956
+ assert.equal(result.kind, "blocked");
957
+ if (result.kind !== "blocked") return;
958
+ assert.equal(result.action, "stop");
959
+ assert.ok(result.reason.startsWith("stuck-loop:"), `expected stuck-loop reason, got: ${result.reason}`);
960
+ });
961
+
962
+ test("stuck-loop #482: resume() with an empty window rehydrates from the dispatch ledger", async (t) => {
963
+ const f = makeFixture();
964
+ t.after(() => f.cleanup());
965
+
966
+ const worker = registerAutoWorker({ projectRootRealpath: normalizeRealPath(f.base) });
967
+ const lease = claimMilestoneLease(worker, "M001");
968
+ assert.equal(lease.ok, true);
969
+ if (!lease.ok) return;
970
+ for (let i = 0; i < STUCK_WINDOW_SIZE - 1; i++) {
971
+ const claim = recordDispatchClaim({
972
+ traceId: `prior-session-resume-${i}`,
973
+ workerId: worker,
974
+ milestoneLeaseToken: lease.token,
975
+ milestoneId: "M001",
976
+ unitType: "execute-task",
977
+ unitId: "M001/S01/T01",
978
+ });
979
+ assert.equal(claim.ok, true);
980
+ if (!claim.ok) return;
981
+ markFailed(claim.dispatchId, { errorSummary: "" });
982
+ }
983
+
984
+ // Fresh orchestrator resuming a prior session: window starts empty, so
985
+ // resume() must rehydrate (while in-process resume keeps the live window —
986
+ // see the #572 preservation tests above).
987
+ const resumed = await f.orchestrator.resume();
988
+ assert.equal(resumed.kind, "resumed");
989
+
990
+ const result = await f.orchestrator.advance();
991
+ assert.equal(result.kind, "blocked");
992
+ if (result.kind !== "blocked") return;
993
+ assert.equal(result.action, "stop");
994
+ assert.ok(result.reason.startsWith("stuck-loop:"), `expected stuck-loop reason, got: ${result.reason}`);
995
+ });
996
+
858
997
  test("stuck-loop: journal records the stuck-loop reason on advance-blocked", async (t) => {
859
998
  const f = makeFixture();
860
999
  t.after(() => f.cleanup());
@@ -1148,6 +1287,103 @@ test("decideOrchestratorDispatch forwards constructor session when advance input
1148
1287
  }
1149
1288
  });
1150
1289
 
1290
+ test("decideOrchestratorDispatch evaluates deep pre-planning rules without an active milestone", async (t) => {
1291
+ const base = mkdtempSync(join(tmpdir(), "gsd-orchestrator-no-active-"));
1292
+ t.after(() => {
1293
+ resetRegistry();
1294
+ rmSync(base, { recursive: true, force: true });
1295
+ });
1296
+ resetRegistry();
1297
+ mkdirSync(join(base, ".gsd"), { recursive: true });
1298
+ writeFileSync(
1299
+ join(base, ".gsd", "PREFERENCES.md"),
1300
+ [
1301
+ "---",
1302
+ "planning_depth: deep",
1303
+ "workflow_prefs_captured: true",
1304
+ "---",
1305
+ "",
1306
+ ].join("\n"),
1307
+ );
1308
+
1309
+ const stateSnapshot: GSDState = {
1310
+ ...makeState(),
1311
+ activeMilestone: null,
1312
+ phase: "pre-planning",
1313
+ nextAction: "All remaining milestones are parked (M027). Run /gsd unpark M027 or create a new milestone.",
1314
+ registry: [{ id: "M027", title: "Parked", status: "parked" }],
1315
+ };
1316
+ const ctx = { model: {}, modelRegistry: { getAll: () => [] } } as never;
1317
+ const pi = { getActiveTools: () => [] } as never;
1318
+ const session = {
1319
+ basePath: base,
1320
+ originalBasePath: base,
1321
+ currentMilestoneId: "M027",
1322
+ } as never;
1323
+
1324
+ const result = await decideOrchestratorDispatch(ctx, pi, base, session, { stateSnapshot });
1325
+
1326
+ assert.ok(result && "unitType" in result, `expected project-level dispatch, got ${JSON.stringify(result)}`);
1327
+ assert.equal(result.unitType, "discuss-project");
1328
+ assert.equal(result.unitId, "PROJECT");
1329
+ });
1330
+
1331
+ test("decideOrchestratorDispatch does not replay milestone-scoped verification retry when no milestone is active", async (t) => {
1332
+ const base = mkdtempSync(join(tmpdir(), "gsd-orchestrator-no-active-retry-"));
1333
+ t.after(() => {
1334
+ resetRegistry();
1335
+ rmSync(base, { recursive: true, force: true });
1336
+ });
1337
+ resetRegistry();
1338
+ mkdirSync(join(base, ".gsd"), { recursive: true });
1339
+ writeFileSync(
1340
+ join(base, ".gsd", "PREFERENCES.md"),
1341
+ [
1342
+ "---",
1343
+ "planning_depth: deep",
1344
+ "workflow_prefs_captured: true",
1345
+ "---",
1346
+ "",
1347
+ ].join("\n"),
1348
+ );
1349
+
1350
+ const stateSnapshot: GSDState = {
1351
+ ...makeState(),
1352
+ activeMilestone: null,
1353
+ phase: "pre-planning",
1354
+ nextAction: "All remaining milestones are parked (M027). Run /gsd unpark M027 or create a new milestone.",
1355
+ registry: [{ id: "M027", title: "Parked", status: "parked" }],
1356
+ };
1357
+ const ctx = { model: {}, modelRegistry: { getAll: () => [] } } as never;
1358
+ const pi = { getActiveTools: () => [] } as never;
1359
+ const stalePendingRetry = {
1360
+ unitType: "execute-task",
1361
+ unitId: "M027.S1.T1",
1362
+ prompt: "stale retry prompt",
1363
+ pauseAfterUatDispatch: false,
1364
+ state: stateSnapshot,
1365
+ mid: "M027",
1366
+ midTitle: "Parked",
1367
+ };
1368
+ const session = {
1369
+ basePath: base,
1370
+ originalBasePath: base,
1371
+ currentMilestoneId: "M027",
1372
+ pendingVerificationRetryDispatch: stalePendingRetry,
1373
+ } as never;
1374
+
1375
+ const result = await decideOrchestratorDispatch(ctx, pi, base, session, { stateSnapshot });
1376
+
1377
+ assert.ok(result && "unitType" in result, `expected project-level dispatch, got ${JSON.stringify(result)}`);
1378
+ assert.equal(result.unitType, "discuss-project");
1379
+ assert.equal(result.unitId, "PROJECT");
1380
+ // The stale retry must be preserved for a future tick, not consumed by this
1381
+ // no-active-milestone path (mirrors pre-#712-fix behavior where !active
1382
+ // returned null before touching the retry).
1383
+ const sess = session as unknown as { pendingVerificationRetryDispatch: unknown };
1384
+ assert.equal(sess.pendingVerificationRetryDispatch, stalePendingRetry);
1385
+ });
1386
+
1151
1387
  test("decideOrchestratorDispatch adopts next active milestone after the session milestone is closed", async (t) => {
1152
1388
  const base = mkdtempSync(join(tmpdir(), "gsd-orchestrator-milestone-adopt-"));
1153
1389
  t.after(() => rmSync(base, { recursive: true, force: true }));
@@ -13,7 +13,7 @@ import { join } from "node:path";
13
13
  import { capturePauseAutoUnitIdentity, pauseAuto, isAutoActive } from "../auto.ts";
14
14
  import { _resetPendingResolve, _setCurrentResolve } from "../auto/resolve.ts";
15
15
  import { autoSession } from "../auto-runtime-state.ts";
16
- import { _isPauseOriginCancelledResult } from "../auto/phases.ts";
16
+ import { _isPauseOriginCancelledResult } from "../auto/phase-helpers.ts";
17
17
 
18
18
  test("pauseAuto sets s.active = false synchronously before first await (blocks concurrent re-entry)", async () => {
19
19
  const base = mkdtempSync(join(tmpdir(), "gsd-double-pause-guard-"));
@@ -7,10 +7,17 @@ import { mkdirSync, mkdtempSync, realpathSync, rmSync, writeFileSync } from "nod
7
7
  import { tmpdir } from "node:os";
8
8
  import { join } from "node:path";
9
9
 
10
- import { cleanupAfterLoopExit, pauseAuto, rerootCommandSession, stopAuto } from "../auto.ts";
10
+ import {
11
+ anchorProcessCwdForAutoResume,
12
+ cleanupAfterLoopExit,
13
+ pauseAuto,
14
+ rerootCommandSession,
15
+ stopAuto,
16
+ } from "../auto.ts";
11
17
  import { autoSession } from "../auto-runtime-state.ts";
12
18
  import { closeDatabase, insertMilestone, insertSlice, openDatabase } from "../gsd-db.ts";
13
19
  import { getAutoWorker, registerAutoWorker } from "../db/auto-workers.ts";
20
+ import { claimMilestoneLease, getMilestoneLease } from "../db/milestone-leases.ts";
14
21
  import { readPausedSessionMetadata } from "../interrupted-session.ts";
15
22
  import { WorktreeLifecycle } from "../worktree-lifecycle.ts";
16
23
 
@@ -107,6 +114,25 @@ test("cleanupAfterLoopExit preserves paused worktree session and visible failure
107
114
  }
108
115
  });
109
116
 
117
+ test("anchorProcessCwdForAutoResume recovers when current cwd was deleted", () => {
118
+ const base = mkdtempSync(join(tmpdir(), "gsd-resume-cwd-anchor-"));
119
+ const deletedCwd = join(base, ".gsd-worktrees", "M002");
120
+ const previousCwd = process.cwd();
121
+
122
+ mkdirSync(deletedCwd, { recursive: true });
123
+
124
+ try {
125
+ process.chdir(deletedCwd);
126
+ rmSync(deletedCwd, { recursive: true, force: true });
127
+
128
+ assert.equal(anchorProcessCwdForAutoResume(base), true);
129
+ assert.equal(realpathSync(process.cwd()), realpathSync(base));
130
+ } finally {
131
+ process.chdir(previousCwd);
132
+ rmSync(base, { recursive: true, force: true });
133
+ }
134
+ });
135
+
110
136
  test("cleanupAfterLoopExit clears status and progress widget without replacing outcome surface", async () => {
111
137
  const statusCalls: unknown[] = [];
112
138
  const widgetCalls: unknown[] = [];
@@ -276,6 +302,56 @@ test("pauseAuto marks active worker as stopping and clears workerId", async () =
276
302
  }
277
303
  });
278
304
 
305
+ test("pauseAuto preserves worker lease across transient provider auto-resume pauses", async () => {
306
+ const base = mkdtempSync(join(tmpdir(), "gsd-pause-provider-lease-"));
307
+ const previousCwd = process.cwd();
308
+ const dbPath = join(base, ".gsd", "gsd.db");
309
+ mkdirSync(join(base, ".gsd"), { recursive: true });
310
+
311
+ autoSession.reset();
312
+ autoSession.active = true;
313
+ autoSession.basePath = base;
314
+ autoSession.originalBasePath = base;
315
+ autoSession.currentMilestoneId = "M001";
316
+
317
+ try {
318
+ openDatabase(dbPath);
319
+ insertMilestone({ id: "M001", title: "Milestone 1", status: "active" });
320
+ const workerId = registerAutoWorker({ projectRootRealpath: base });
321
+ const lease = claimMilestoneLease(workerId, "M001");
322
+ assert.equal(lease.ok, true);
323
+ if (!lease.ok) return;
324
+
325
+ autoSession.workerId = workerId;
326
+ autoSession.milestoneLeaseToken = lease.token;
327
+ process.chdir(base);
328
+
329
+ await pauseAuto(undefined, undefined, {
330
+ message: "Provider error: socket closed",
331
+ category: "provider",
332
+ isTransient: true,
333
+ });
334
+
335
+ assert.equal(autoSession.paused, true);
336
+ assert.equal(autoSession.workerId, workerId);
337
+ assert.equal(autoSession.milestoneLeaseToken, lease.token);
338
+ assert.equal(getAutoWorker(workerId)?.status, "active");
339
+ const row = getMilestoneLease("M001");
340
+ assert.equal(row?.worker_id, workerId);
341
+ assert.equal(row?.status, "held");
342
+ assert.equal(row?.fencing_token, lease.token);
343
+ } finally {
344
+ autoSession.reset();
345
+ try {
346
+ closeDatabase();
347
+ } catch {
348
+ /* noop */
349
+ }
350
+ process.chdir(previousCwd);
351
+ rmSync(base, { recursive: true, force: true });
352
+ }
353
+ });
354
+
279
355
  test("pauseAuto records the expected worktree path when paused from project root", async () => {
280
356
  const base = mkdtempSync(join(tmpdir(), "gsd-pause-worktree-path-"));
281
357
  const previousCwd = process.cwd();
@@ -7,7 +7,8 @@ import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
7
7
  import { join } from "node:path";
8
8
  import { tmpdir } from "node:os";
9
9
 
10
- import { resolveDispatchRecoveryAttempts, runFinalize } from "../auto/phases.ts";
10
+ import { resolveDispatchRecoveryAttempts } from "../auto/unit-phase.ts";
11
+ import { runFinalize } from "../auto/finalize.ts";
11
12
  import { AutoSession } from "../auto/session.ts";
12
13
  import { readUnitRuntimeRecord, writeUnitRuntimeRecord } from "../unit-runtime.ts";
13
14
  import { captureRootDirtySnapshot } from "../root-write-leak-guard.ts";
@@ -1,12 +1,13 @@
1
1
  import test from "node:test";
2
2
  import assert from "node:assert/strict";
3
- import { mkdtempSync, mkdirSync, rmSync } from "node:fs";
3
+ import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
4
4
  import { join } from "node:path";
5
5
  import { tmpdir } from "node:os";
6
6
 
7
- import { checkRemoteAutoSession } from "../auto.ts";
7
+ import { checkRemoteAutoSession, forceStopAutoRemote } from "../auto.ts";
8
8
  import { openDatabase, closeDatabase, _getAdapter } from "../gsd-db.ts";
9
- import { registerAutoWorker } from "../db/auto-workers.ts";
9
+ import { getAutoWorker, registerAutoWorker } from "../db/auto-workers.ts";
10
+ import { claimMilestoneLease, getMilestoneLease } from "../db/milestone-leases.ts";
10
11
  import { normalizeRealPath } from "../paths.ts";
11
12
  import { readCrashLock } from "../crash-recovery.ts";
12
13
 
@@ -35,6 +36,29 @@ function setWorkerPid(workerId: string, pid: number): void {
35
36
  ).run({ ":pid": pid, ":worker_id": workerId });
36
37
  }
37
38
 
39
+ function insertMilestone(id: string): void {
40
+ const db = _getAdapter()!;
41
+ db.prepare(
42
+ `INSERT INTO milestones (id, title, status, created_at)
43
+ VALUES (:id, :title, 'active', :created_at)`,
44
+ ).run({
45
+ ":id": id,
46
+ ":title": id,
47
+ ":created_at": new Date().toISOString(),
48
+ });
49
+ }
50
+
51
+ function writeLegacyLock(base: string, pid: number): void {
52
+ const now = new Date().toISOString();
53
+ writeFileSync(join(base, ".gsd", "auto.lock"), JSON.stringify({
54
+ pid,
55
+ startedAt: now,
56
+ unitType: "execute-task",
57
+ unitId: "M001/S01/T01",
58
+ unitStartedAt: now,
59
+ }));
60
+ }
61
+
38
62
  function findDeadPidCandidate(): number {
39
63
  const candidates = [99_999, 199_999, 299_999, 399_999];
40
64
  for (const pid of candidates) {
@@ -62,3 +86,41 @@ test("checkRemoteAutoSession clears stale lock state when lock PID is dead", (t)
62
86
  assert.deepEqual(remote, { running: false });
63
87
  assert.equal(readCrashLock(base), null, "stale lock should be cleared by remote session check");
64
88
  });
89
+
90
+ test("forceStopAutoRemote escalates a live remote PID and releases worker state", (t) => {
91
+ const base = makeBase();
92
+ t.after(() => cleanup(base));
93
+
94
+ openDatabase(join(base, ".gsd", "gsd.db"));
95
+ const workerId = registerAutoWorker({ projectRootRealpath: normalizeRealPath(base) });
96
+ const pid = 424_242;
97
+ setWorkerPid(workerId, pid);
98
+ insertMilestone("M001");
99
+ writeLegacyLock(base, pid);
100
+ const lease = claimMilestoneLease(workerId, "M001");
101
+ assert.equal(lease.ok, true, "precondition: worker holds a milestone lease");
102
+
103
+ const signals: Array<NodeJS.Signals | 0> = [];
104
+ const originalKill = process.kill;
105
+ process.kill = ((target: number, signal?: NodeJS.Signals | number) => {
106
+ assert.equal(target, pid);
107
+ signals.push((signal ?? 0) as NodeJS.Signals | 0);
108
+ return true;
109
+ }) as typeof process.kill;
110
+ t.after(() => {
111
+ process.kill = originalKill;
112
+ });
113
+
114
+ const result = forceStopAutoRemote(base);
115
+
116
+ assert.deepEqual(result, { found: true, pid });
117
+ assert.ok(signals.includes("SIGTERM"), "force stop should request graceful termination first");
118
+ assert.ok(signals.includes("SIGKILL"), "force stop should escalate when the PID is still alive");
119
+ assert.equal(getAutoWorker(workerId)?.status, "stopping");
120
+ assert.equal(
121
+ getMilestoneLease("M001")?.status,
122
+ "released",
123
+ "force stop should release held milestone leases",
124
+ );
125
+ assert.equal(readCrashLock(base), null, "force stop should remove the visible remote lock");
126
+ });