gsd-pi 2.82.0-dev.ed17d078d → 3.0.0-dev.2e8b124f7

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 (580) hide show
  1. package/README.md +93 -18
  2. package/dist/cli.js +20 -9
  3. package/dist/headless-ui.js +13 -6
  4. package/dist/headless.js +9 -2
  5. package/dist/resources/.managed-resources-content-hash +1 -1
  6. package/dist/resources/GSD-WORKFLOW.md +10 -1
  7. package/dist/resources/extensions/claude-code-cli/partial-builder.js +2 -1
  8. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +44 -6
  9. package/dist/resources/extensions/cmux/index.js +5 -0
  10. package/dist/resources/extensions/gsd/auto/infra-errors.js +9 -3
  11. package/dist/resources/extensions/gsd/auto/loop.js +110 -37
  12. package/dist/resources/extensions/gsd/auto/orchestrator.js +13 -2
  13. package/dist/resources/extensions/gsd/auto/phases.js +104 -38
  14. package/dist/resources/extensions/gsd/auto/session.js +6 -0
  15. package/dist/resources/extensions/gsd/auto/unit-runner-events.js +7 -1
  16. package/dist/resources/extensions/gsd/auto/workflow-kernel.js +3 -0
  17. package/dist/resources/extensions/gsd/auto/workflow-memory-pressure.js +12 -0
  18. package/dist/resources/extensions/gsd/auto-dashboard.js +66 -1
  19. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +1 -0
  20. package/dist/resources/extensions/gsd/auto-dispatch.js +71 -20
  21. package/dist/resources/extensions/gsd/auto-model-selection.js +2 -0
  22. package/dist/resources/extensions/gsd/auto-post-unit.js +278 -137
  23. package/dist/resources/extensions/gsd/auto-prompts.js +36 -10
  24. package/dist/resources/extensions/gsd/auto-recovery.js +79 -14
  25. package/dist/resources/extensions/gsd/auto-start.js +90 -14
  26. package/dist/resources/extensions/gsd/auto-timers.js +11 -3
  27. package/dist/resources/extensions/gsd/auto-verification.js +102 -34
  28. package/dist/resources/extensions/gsd/auto-worktree.js +178 -11
  29. package/dist/resources/extensions/gsd/auto.js +107 -54
  30. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +31 -7
  31. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +10 -9
  32. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +5 -4
  33. package/dist/resources/extensions/gsd/bootstrap/subagent-input.js +21 -9
  34. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +24 -9
  35. package/dist/resources/extensions/gsd/clean-root-preflight.js +170 -8
  36. package/dist/resources/extensions/gsd/commands/catalog.js +10 -1
  37. package/dist/resources/extensions/gsd/commands/handlers/core.js +38 -0
  38. package/dist/resources/extensions/gsd/commands/handlers/ops.js +20 -0
  39. package/dist/resources/extensions/gsd/commands-bootstrap.js +5 -0
  40. package/dist/resources/extensions/gsd/commands-handlers.js +2 -0
  41. package/dist/resources/extensions/gsd/commands-mcp-status.js +9 -0
  42. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +10 -2
  43. package/dist/resources/extensions/gsd/commands-verdict.js +139 -0
  44. package/dist/resources/extensions/gsd/crash-recovery.js +52 -7
  45. package/dist/resources/extensions/gsd/db/milestone-leases.js +24 -0
  46. package/dist/resources/extensions/gsd/db/unit-dispatches.js +3 -2
  47. package/dist/resources/extensions/gsd/db-base-schema.js +2 -0
  48. package/dist/resources/extensions/gsd/db-migration-steps.js +4 -0
  49. package/dist/resources/extensions/gsd/db-task-slice-rows.js +2 -0
  50. package/dist/resources/extensions/gsd/dispatch-guard.js +46 -2
  51. package/dist/resources/extensions/gsd/docs/preferences-reference.md +8 -0
  52. package/dist/resources/extensions/gsd/doctor-git-checks.js +46 -1
  53. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +28 -11
  54. package/dist/resources/extensions/gsd/doctor.js +2 -28
  55. package/dist/resources/extensions/gsd/export-html.js +27 -425
  56. package/dist/resources/extensions/gsd/forensics.js +10 -3
  57. package/dist/resources/extensions/gsd/git-service.js +138 -10
  58. package/dist/resources/extensions/gsd/gsd-db.js +76 -33
  59. package/dist/resources/extensions/gsd/guided-flow-queue.js +4 -3
  60. package/dist/resources/extensions/gsd/guided-flow.js +110 -117
  61. package/dist/resources/extensions/gsd/guided-unit-context.js +23 -0
  62. package/dist/resources/extensions/gsd/init-wizard.js +17 -2
  63. package/dist/resources/extensions/gsd/markdown-renderer.js +14 -11
  64. package/dist/resources/extensions/gsd/mcp-filter.js +58 -0
  65. package/dist/resources/extensions/gsd/migrate/parsers.js +10 -0
  66. package/dist/resources/extensions/gsd/migration-auto-check.js +12 -17
  67. package/dist/resources/extensions/gsd/milestone-actions.js +11 -4
  68. package/dist/resources/extensions/gsd/native-git-bridge.js +57 -14
  69. package/dist/resources/extensions/gsd/parallel-orchestrator.js +3 -0
  70. package/dist/resources/extensions/gsd/paths.js +4 -0
  71. package/dist/resources/extensions/gsd/pending-auto-start.js +52 -0
  72. package/dist/resources/extensions/gsd/planning-path-scope.js +9 -3
  73. package/dist/resources/extensions/gsd/post-execution-checks.js +73 -9
  74. package/dist/resources/extensions/gsd/pre-execution-checks.js +38 -11
  75. package/dist/resources/extensions/gsd/preferences-mcp.js +19 -0
  76. package/dist/resources/extensions/gsd/preferences-types.js +2 -0
  77. package/dist/resources/extensions/gsd/preferences-validation.js +138 -0
  78. package/dist/resources/extensions/gsd/preferences.js +2 -0
  79. package/dist/resources/extensions/gsd/prompt-loader.js +1 -1
  80. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  81. package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  82. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
  83. package/dist/resources/extensions/gsd/prompts/discuss.md +9 -9
  84. package/dist/resources/extensions/gsd/prompts/forensics.md +3 -3
  85. package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
  86. package/dist/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
  87. package/dist/resources/extensions/gsd/prompts/plan-slice.md +4 -4
  88. package/dist/resources/extensions/gsd/prompts/queue.md +4 -4
  89. package/dist/resources/extensions/gsd/prompts/reactive-execute.md +1 -1
  90. package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  91. package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  92. package/dist/resources/extensions/gsd/queue-reorder-ui.js +30 -13
  93. package/dist/resources/extensions/gsd/repository-registry.js +44 -0
  94. package/dist/resources/extensions/gsd/safety/evidence-collector.js +2 -0
  95. package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +42 -18
  96. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +59 -2
  97. package/dist/resources/extensions/gsd/smart-entry-routing.js +36 -0
  98. package/dist/resources/extensions/gsd/state-reconciliation/drift/merge-state.js +6 -1
  99. package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +9 -14
  100. package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +19 -24
  101. package/dist/resources/extensions/gsd/state.js +14 -4
  102. package/dist/resources/extensions/gsd/status-guards.js +14 -2
  103. package/dist/resources/extensions/gsd/templates/plan.md +9 -5
  104. package/dist/resources/extensions/gsd/templates/task-plan.md +10 -2
  105. package/dist/resources/extensions/gsd/tools/complete-milestone.js +6 -8
  106. package/dist/resources/extensions/gsd/tools/complete-slice.js +6 -8
  107. package/dist/resources/extensions/gsd/tools/plan-milestone.js +7 -1
  108. package/dist/resources/extensions/gsd/tools/plan-slice.js +151 -15
  109. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +119 -0
  110. package/dist/resources/extensions/gsd/unit-context-composer.js +2 -0
  111. package/dist/resources/extensions/gsd/unit-context-manifest.js +69 -17
  112. package/dist/resources/extensions/gsd/validation.js +23 -1
  113. package/dist/resources/extensions/gsd/verification-gate.js +142 -7
  114. package/dist/resources/extensions/gsd/verification-verdict.js +26 -0
  115. package/dist/resources/extensions/gsd/workflow-manifest.js +2 -0
  116. package/dist/resources/extensions/gsd/workflow-mcp.js +17 -1
  117. package/dist/resources/extensions/gsd/workflow-projections.js +6 -8
  118. package/dist/resources/extensions/gsd/worktree-lifecycle.js +83 -19
  119. package/dist/resources/extensions/gsd/worktree-manager.js +11 -2
  120. package/dist/resources/extensions/gsd/worktree-safety.js +33 -1
  121. package/dist/resources/extensions/gsd/worktree-state-projection.js +31 -0
  122. package/dist/resources/extensions/shared/html-shell.js +388 -0
  123. package/dist/resources/extensions/shared/interview-ui.js +6 -4
  124. package/dist/resources/extensions/subagent/index.js +448 -78
  125. package/dist/resources/extensions/subagent/launch.js +77 -0
  126. package/dist/resources/extensions/subagent/run-store.js +148 -0
  127. package/dist/resources/extensions/ttsr/ttsr-manager.js +3 -1
  128. package/dist/resources/extensions/visual-brief/artifact-policy.js +29 -0
  129. package/dist/resources/extensions/visual-brief/extension-manifest.json +8 -0
  130. package/dist/resources/extensions/visual-brief/index.js +5 -0
  131. package/dist/resources/extensions/visual-brief/page-contract.js +124 -0
  132. package/dist/resources/extensions/visual-brief/prompts.js +140 -0
  133. package/dist/resources/skills/forensics/SKILL.md +1 -1
  134. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  135. package/dist/web/standalone/.next/BUILD_ID +1 -1
  136. package/dist/web/standalone/.next/app-path-routes-manifest.json +10 -10
  137. package/dist/web/standalone/.next/build-manifest.json +3 -3
  138. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  139. package/dist/web/standalone/.next/react-loadable-manifest.json +5 -5
  140. package/dist/web/standalone/.next/required-server-files.json +1 -1
  141. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  142. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  143. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  144. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  145. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  146. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  147. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  148. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  149. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  150. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  151. package/dist/web/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  152. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  154. package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -7
  155. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -7
  156. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  157. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -5
  158. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  159. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  160. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -5
  161. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  163. package/dist/web/standalone/.next/server/app/index.html +1 -1
  164. package/dist/web/standalone/.next/server/app/index.rsc +4 -7
  165. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  166. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -7
  167. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  168. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -5
  169. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -5
  170. package/dist/web/standalone/.next/server/app/page.js +2 -2
  171. package/dist/web/standalone/.next/server/app/page.js.nft.json +1 -1
  172. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  173. package/dist/web/standalone/.next/server/app-paths-manifest.json +10 -10
  174. package/dist/web/standalone/.next/server/chunks/4266.js +2 -0
  175. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  176. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  177. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  178. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  179. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  180. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  181. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  182. package/dist/web/standalone/.next/static/chunks/2973.33f26573894b6153.js +2 -0
  183. package/dist/web/standalone/.next/static/chunks/8359.65b24fac92188a6b.js +10 -0
  184. package/dist/web/standalone/.next/static/chunks/9441.ff70bb53f6835771.js +1 -0
  185. package/dist/web/standalone/.next/static/chunks/app/layout-8c10ec293ae0f1d5.js +1 -0
  186. package/dist/web/standalone/.next/static/chunks/{webpack-de742b64187e13fe.js → webpack-855d616060cb6e59.js} +1 -1
  187. package/dist/web/standalone/.next/static/css/746ee28c929d1880.css +1 -0
  188. package/dist/web/standalone/server.js +1 -1
  189. package/package.json +4 -4
  190. package/packages/contracts/dist/rpc.test.js +7 -0
  191. package/packages/contracts/dist/rpc.test.js.map +1 -1
  192. package/packages/contracts/dist/workflow.d.ts +21 -0
  193. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  194. package/packages/contracts/dist/workflow.js +24 -0
  195. package/packages/contracts/dist/workflow.js.map +1 -1
  196. package/packages/contracts/src/rpc.test.ts +8 -0
  197. package/packages/contracts/src/workflow.ts +24 -0
  198. package/packages/daemon/package.json +2 -2
  199. package/packages/mcp-server/README.md +13 -4
  200. package/packages/mcp-server/dist/workflow-tools.d.ts +0 -3
  201. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  202. package/packages/mcp-server/dist/workflow-tools.js +80 -0
  203. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  204. package/packages/mcp-server/package.json +2 -2
  205. package/packages/mcp-server/src/workflow-tools.test.ts +23 -1
  206. package/packages/mcp-server/src/workflow-tools.ts +168 -0
  207. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  208. package/packages/native/package.json +1 -1
  209. package/packages/native/tsconfig.json +2 -1
  210. package/packages/native/tsconfig.tsbuildinfo +1 -1
  211. package/packages/pi-agent-core/package.json +1 -1
  212. package/packages/pi-ai/dist/providers/google-gemini-cli.d.ts.map +1 -1
  213. package/packages/pi-ai/dist/providers/google-gemini-cli.js +5 -0
  214. package/packages/pi-ai/dist/providers/google-gemini-cli.js.map +1 -1
  215. package/packages/pi-ai/dist/providers/google-gemini-cli.test.d.ts +2 -0
  216. package/packages/pi-ai/dist/providers/google-gemini-cli.test.d.ts.map +1 -0
  217. package/packages/pi-ai/dist/providers/google-gemini-cli.test.js +41 -0
  218. package/packages/pi-ai/dist/providers/google-gemini-cli.test.js.map +1 -0
  219. package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
  220. package/packages/pi-ai/dist/providers/openai-codex-responses.js +82 -1
  221. package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
  222. package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts +2 -0
  223. package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts.map +1 -0
  224. package/packages/pi-ai/dist/providers/openai-codex-responses.test.js +52 -0
  225. package/packages/pi-ai/dist/providers/openai-codex-responses.test.js.map +1 -0
  226. package/packages/pi-ai/dist/providers/simple-options.d.ts +2 -4
  227. package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
  228. package/packages/pi-ai/dist/providers/simple-options.js +5 -6
  229. package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
  230. package/packages/pi-ai/dist/providers/simple-options.test.d.ts +2 -0
  231. package/packages/pi-ai/dist/providers/simple-options.test.d.ts.map +1 -0
  232. package/packages/pi-ai/dist/providers/simple-options.test.js +50 -0
  233. package/packages/pi-ai/dist/providers/simple-options.test.js.map +1 -0
  234. package/packages/pi-ai/package.json +1 -1
  235. package/packages/pi-ai/src/providers/google-gemini-cli.test.ts +49 -0
  236. package/packages/pi-ai/src/providers/google-gemini-cli.ts +7 -0
  237. package/packages/pi-ai/src/providers/openai-codex-responses.test.ts +63 -0
  238. package/packages/pi-ai/src/providers/openai-codex-responses.ts +91 -1
  239. package/packages/pi-ai/src/providers/simple-options.test.ts +60 -0
  240. package/packages/pi-ai/src/providers/simple-options.ts +5 -6
  241. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  242. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts +2 -0
  243. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts.map +1 -0
  244. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js +66 -0
  245. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js.map +1 -0
  246. package/packages/pi-coding-agent/dist/core/agent-session.js +1 -1
  247. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  248. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +44 -3
  249. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  250. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +6 -1
  251. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  252. package/packages/pi-coding-agent/dist/core/compaction/compaction.js +7 -2
  253. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  254. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js +14 -1
  255. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js.map +1 -1
  256. package/packages/pi-coding-agent/dist/core/sdk.js +1 -1
  257. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  258. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +8 -2
  259. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
  260. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  261. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +24 -6
  262. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  263. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +1 -1
  264. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  265. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  266. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +71 -97
  267. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  268. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +7 -7
  269. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  270. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +11 -0
  271. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
  272. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js +25 -1
  273. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js.map +1 -1
  274. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +2 -0
  275. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  276. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +24 -10
  277. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  278. package/packages/pi-coding-agent/package.json +1 -1
  279. package/packages/pi-coding-agent/src/core/agent-session-thinking-level.test.ts +79 -0
  280. package/packages/pi-coding-agent/src/core/agent-session.ts +1 -1
  281. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +53 -3
  282. package/packages/pi-coding-agent/src/core/compaction/compaction.test.ts +23 -1
  283. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +7 -2
  284. package/packages/pi-coding-agent/src/core/sdk.ts +1 -1
  285. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +17 -1
  286. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +23 -7
  287. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +1 -1
  288. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +75 -102
  289. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +15 -1
  290. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +9 -9
  291. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-ordering.test.ts +30 -1
  292. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +29 -10
  293. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  294. package/packages/pi-tui/dist/__tests__/terminal.test.d.ts +2 -0
  295. package/packages/pi-tui/dist/__tests__/terminal.test.d.ts.map +1 -0
  296. package/packages/pi-tui/dist/__tests__/terminal.test.js +103 -0
  297. package/packages/pi-tui/dist/__tests__/terminal.test.js.map +1 -0
  298. package/packages/pi-tui/dist/__tests__/tui.test.js +45 -2
  299. package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
  300. package/packages/pi-tui/dist/terminal.d.ts +2 -0
  301. package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
  302. package/packages/pi-tui/dist/terminal.js +12 -0
  303. package/packages/pi-tui/dist/terminal.js.map +1 -1
  304. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  305. package/packages/pi-tui/dist/tui.js +106 -27
  306. package/packages/pi-tui/dist/tui.js.map +1 -1
  307. package/packages/pi-tui/package.json +1 -1
  308. package/packages/pi-tui/src/__tests__/terminal.test.ts +121 -0
  309. package/packages/pi-tui/src/__tests__/tui.test.ts +59 -2
  310. package/packages/pi-tui/src/terminal.ts +11 -0
  311. package/packages/pi-tui/src/tui.ts +108 -27
  312. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  313. package/packages/rpc-client/package.json +1 -1
  314. package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
  315. package/pkg/package.json +1 -1
  316. package/src/resources/GSD-WORKFLOW.md +10 -1
  317. package/src/resources/extensions/claude-code-cli/partial-builder.ts +2 -1
  318. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +52 -6
  319. package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +19 -2
  320. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +49 -2
  321. package/src/resources/extensions/cmux/index.ts +6 -0
  322. package/src/resources/extensions/gsd/auto/contracts.ts +17 -6
  323. package/src/resources/extensions/gsd/auto/infra-errors.ts +9 -3
  324. package/src/resources/extensions/gsd/auto/loop.ts +111 -38
  325. package/src/resources/extensions/gsd/auto/orchestrator.ts +13 -2
  326. package/src/resources/extensions/gsd/auto/phases.ts +127 -49
  327. package/src/resources/extensions/gsd/auto/session.ts +16 -0
  328. package/src/resources/extensions/gsd/auto/types.ts +3 -0
  329. package/src/resources/extensions/gsd/auto/unit-runner-events.ts +6 -2
  330. package/src/resources/extensions/gsd/auto/workflow-kernel.ts +5 -1
  331. package/src/resources/extensions/gsd/auto/workflow-memory-pressure.ts +13 -0
  332. package/src/resources/extensions/gsd/auto-dashboard.ts +72 -1
  333. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +1 -0
  334. package/src/resources/extensions/gsd/auto-dispatch.ts +74 -20
  335. package/src/resources/extensions/gsd/auto-model-selection.ts +2 -1
  336. package/src/resources/extensions/gsd/auto-post-unit.ts +312 -148
  337. package/src/resources/extensions/gsd/auto-prompts.ts +36 -13
  338. package/src/resources/extensions/gsd/auto-recovery.ts +83 -11
  339. package/src/resources/extensions/gsd/auto-start.ts +99 -12
  340. package/src/resources/extensions/gsd/auto-timers.ts +10 -3
  341. package/src/resources/extensions/gsd/auto-verification.ts +124 -42
  342. package/src/resources/extensions/gsd/auto-worktree.ts +195 -11
  343. package/src/resources/extensions/gsd/auto.ts +100 -42
  344. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +42 -7
  345. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +10 -9
  346. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +5 -4
  347. package/src/resources/extensions/gsd/bootstrap/subagent-input.ts +19 -7
  348. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +27 -10
  349. package/src/resources/extensions/gsd/clean-root-preflight.ts +174 -8
  350. package/src/resources/extensions/gsd/commands/catalog.ts +10 -1
  351. package/src/resources/extensions/gsd/commands/handlers/core.ts +41 -0
  352. package/src/resources/extensions/gsd/commands/handlers/ops.ts +21 -0
  353. package/src/resources/extensions/gsd/commands-bootstrap.ts +10 -0
  354. package/src/resources/extensions/gsd/commands-handlers.ts +2 -0
  355. package/src/resources/extensions/gsd/commands-mcp-status.ts +8 -0
  356. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +11 -3
  357. package/src/resources/extensions/gsd/commands-verdict.ts +202 -0
  358. package/src/resources/extensions/gsd/crash-recovery.ts +52 -6
  359. package/src/resources/extensions/gsd/db/milestone-leases.ts +26 -0
  360. package/src/resources/extensions/gsd/db/unit-dispatches.ts +4 -3
  361. package/src/resources/extensions/gsd/db-base-schema.ts +2 -0
  362. package/src/resources/extensions/gsd/db-migration-steps.ts +5 -0
  363. package/src/resources/extensions/gsd/db-task-slice-rows.ts +4 -0
  364. package/src/resources/extensions/gsd/dispatch-guard.ts +60 -2
  365. package/src/resources/extensions/gsd/docs/preferences-reference.md +8 -0
  366. package/src/resources/extensions/gsd/doctor-git-checks.ts +45 -1
  367. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +25 -13
  368. package/src/resources/extensions/gsd/doctor-types.ts +1 -0
  369. package/src/resources/extensions/gsd/doctor.ts +2 -27
  370. package/src/resources/extensions/gsd/export-html.ts +27 -427
  371. package/src/resources/extensions/gsd/forensics.ts +9 -3
  372. package/src/resources/extensions/gsd/git-service.ts +166 -11
  373. package/src/resources/extensions/gsd/gsd-db.ts +80 -31
  374. package/src/resources/extensions/gsd/guided-flow-queue.ts +4 -3
  375. package/src/resources/extensions/gsd/guided-flow.ts +142 -134
  376. package/src/resources/extensions/gsd/guided-unit-context.ts +30 -0
  377. package/src/resources/extensions/gsd/init-wizard.ts +17 -2
  378. package/src/resources/extensions/gsd/journal.ts +8 -1
  379. package/src/resources/extensions/gsd/markdown-renderer.ts +14 -11
  380. package/src/resources/extensions/gsd/mcp-filter.ts +80 -0
  381. package/src/resources/extensions/gsd/migrate/parsers.ts +11 -0
  382. package/src/resources/extensions/gsd/migration-auto-check.ts +15 -23
  383. package/src/resources/extensions/gsd/milestone-actions.ts +10 -4
  384. package/src/resources/extensions/gsd/native-git-bridge.ts +63 -14
  385. package/src/resources/extensions/gsd/parallel-orchestrator.ts +3 -0
  386. package/src/resources/extensions/gsd/paths.ts +5 -0
  387. package/src/resources/extensions/gsd/pending-auto-start.ts +79 -0
  388. package/src/resources/extensions/gsd/planning-path-scope.ts +10 -2
  389. package/src/resources/extensions/gsd/post-execution-checks.ts +87 -12
  390. package/src/resources/extensions/gsd/pre-execution-checks.ts +49 -11
  391. package/src/resources/extensions/gsd/preferences-mcp.ts +27 -0
  392. package/src/resources/extensions/gsd/preferences-types.ts +33 -0
  393. package/src/resources/extensions/gsd/preferences-validation.ts +145 -0
  394. package/src/resources/extensions/gsd/preferences.ts +5 -0
  395. package/src/resources/extensions/gsd/prompt-loader.ts +1 -1
  396. package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  397. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  398. package/src/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
  399. package/src/resources/extensions/gsd/prompts/discuss.md +9 -9
  400. package/src/resources/extensions/gsd/prompts/forensics.md +3 -3
  401. package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
  402. package/src/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
  403. package/src/resources/extensions/gsd/prompts/plan-slice.md +4 -4
  404. package/src/resources/extensions/gsd/prompts/queue.md +4 -4
  405. package/src/resources/extensions/gsd/prompts/reactive-execute.md +1 -1
  406. package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  407. package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  408. package/src/resources/extensions/gsd/queue-reorder-ui.ts +31 -13
  409. package/src/resources/extensions/gsd/repository-registry.ts +77 -0
  410. package/src/resources/extensions/gsd/safety/evidence-collector.ts +2 -0
  411. package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +54 -19
  412. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +52 -1
  413. package/src/resources/extensions/gsd/smart-entry-routing.ts +77 -0
  414. package/src/resources/extensions/gsd/state-reconciliation/drift/merge-state.ts +8 -1
  415. package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +12 -15
  416. package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +17 -25
  417. package/src/resources/extensions/gsd/state.ts +15 -4
  418. package/src/resources/extensions/gsd/status-guards.ts +16 -2
  419. package/src/resources/extensions/gsd/templates/plan.md +9 -5
  420. package/src/resources/extensions/gsd/templates/task-plan.md +10 -2
  421. package/src/resources/extensions/gsd/tests/auto-abort-pause-regression.test.ts +10 -1
  422. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +71 -0
  423. package/src/resources/extensions/gsd/tests/auto-deterministic-error-classification-4973.test.ts +116 -0
  424. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +300 -1
  425. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +197 -11
  426. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +151 -12
  427. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +53 -2
  428. package/src/resources/extensions/gsd/tests/auto-post-unit-step-message.test.ts +18 -6
  429. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +129 -6
  430. package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +12 -0
  431. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +1 -0
  432. package/src/resources/extensions/gsd/tests/auto-stop-notification.test.ts +20 -0
  433. package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +69 -1
  434. package/src/resources/extensions/gsd/tests/autocomplete-regressions-1675.test.ts +21 -0
  435. package/src/resources/extensions/gsd/tests/brief-command.test.ts +89 -0
  436. package/src/resources/extensions/gsd/tests/checkout-branch-stash-guard.test.ts +87 -0
  437. package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +107 -2
  438. package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +32 -4
  439. package/src/resources/extensions/gsd/tests/closeout-git-deferral.test.ts +16 -0
  440. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +378 -0
  441. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +4 -1
  442. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +5 -9
  443. package/src/resources/extensions/gsd/tests/complete-task.test.ts +3 -1
  444. package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +104 -2
  445. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +2 -0
  446. package/src/resources/extensions/gsd/tests/db-authority-regression.test.ts +208 -0
  447. package/src/resources/extensions/gsd/tests/db-task-slice-rows.test.ts +1 -0
  448. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +61 -2
  449. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +111 -1
  450. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +68 -1
  451. package/src/resources/extensions/gsd/tests/doctor-empty-worktree.test.ts +65 -0
  452. package/src/resources/extensions/gsd/tests/doctor-forensics-db-open-regression.test.ts +50 -0
  453. package/src/resources/extensions/gsd/tests/evidence-cross-ref.test.ts +97 -0
  454. package/src/resources/extensions/gsd/tests/export-html-enhancements.test.ts +8 -0
  455. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +28 -0
  456. package/src/resources/extensions/gsd/tests/gsdroot-worktree-detection.test.ts +5 -2
  457. package/src/resources/extensions/gsd/tests/guided-discuss-project-prompt-rendering.test.ts +2 -0
  458. package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +106 -0
  459. package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +59 -11
  460. package/src/resources/extensions/gsd/tests/guided-flow.test.ts +21 -0
  461. package/src/resources/extensions/gsd/tests/guided-tool-contract.test.ts +65 -0
  462. package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +7 -7
  463. package/src/resources/extensions/gsd/tests/hook-model-resolution.test.ts +5 -0
  464. package/src/resources/extensions/gsd/tests/infra-error.test.ts +2 -2
  465. package/src/resources/extensions/gsd/tests/infra-errors-cooldown.test.ts +9 -0
  466. package/src/resources/extensions/gsd/tests/init-prefs-routing.test.ts +22 -0
  467. package/src/resources/extensions/gsd/tests/integration/doctor-runtime.test.ts +20 -0
  468. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +199 -2
  469. package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +6 -1
  470. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +49 -3
  471. package/src/resources/extensions/gsd/tests/journal.test.ts +32 -0
  472. package/src/resources/extensions/gsd/tests/mcp-filter.test.ts +287 -0
  473. package/src/resources/extensions/gsd/tests/mcp-status.test.ts +11 -0
  474. package/src/resources/extensions/gsd/tests/merge-db-cycle.test.ts +179 -0
  475. package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +24 -1
  476. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +26 -18
  477. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +80 -2
  478. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +121 -1
  479. package/src/resources/extensions/gsd/tests/parallel-orchestrator-zombie-cleanup.test.ts +55 -0
  480. package/src/resources/extensions/gsd/tests/park-db-sync.test.ts +55 -1
  481. package/src/resources/extensions/gsd/tests/pending-autostart-scope.test.ts +29 -5
  482. package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +2 -1
  483. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +26 -0
  484. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +2 -0
  485. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +343 -3
  486. package/src/resources/extensions/gsd/tests/plan-task.test.ts +18 -1
  487. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +79 -1
  488. package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +105 -3
  489. package/src/resources/extensions/gsd/tests/post-unit-git-failure.test.ts +1 -1
  490. package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +84 -0
  491. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +59 -0
  492. package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +54 -0
  493. package/src/resources/extensions/gsd/tests/preferences-mcp.test.ts +128 -0
  494. package/src/resources/extensions/gsd/tests/preferences.test.ts +75 -0
  495. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +78 -0
  496. package/src/resources/extensions/gsd/tests/prompt-loader.test.ts +23 -0
  497. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +37 -1
  498. package/src/resources/extensions/gsd/tests/quality-gates.test.ts +6 -0
  499. package/src/resources/extensions/gsd/tests/queue-reorder-ui.test.ts +54 -0
  500. package/src/resources/extensions/gsd/tests/remediation-completion-guard.test.ts +89 -2
  501. package/src/resources/extensions/gsd/tests/repository-registry.test.ts +52 -0
  502. package/src/resources/extensions/gsd/tests/run-uat-replay-cap.test.ts +2 -3
  503. package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +21 -1
  504. package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +72 -1
  505. package/src/resources/extensions/gsd/tests/smart-entry-routing.test.ts +113 -0
  506. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +86 -2
  507. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +6 -0
  508. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +119 -23
  509. package/src/resources/extensions/gsd/tests/status-guards.test.ts +17 -1
  510. package/src/resources/extensions/gsd/tests/stuck-state-via-db.test.ts +64 -1
  511. package/src/resources/extensions/gsd/tests/subagent-model-dispatch.test.ts +2 -1
  512. package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +7 -3
  513. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +1 -0
  514. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +131 -9
  515. package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +111 -1
  516. package/src/resources/extensions/gsd/tests/validate-milestone-stuck-guard.test.ts +29 -2
  517. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +42 -1
  518. package/src/resources/extensions/gsd/tests/verification-gate.test.ts +173 -1
  519. package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +78 -0
  520. package/src/resources/extensions/gsd/tests/workflow-kernel.test.ts +7 -0
  521. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +19 -1
  522. package/src/resources/extensions/gsd/tests/workflow-memory-pressure.test.ts +21 -1
  523. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +1 -1
  524. package/src/resources/extensions/gsd/tests/worktree-git-pathspec.test.ts +39 -0
  525. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +64 -12
  526. package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +57 -2
  527. package/src/resources/extensions/gsd/tests/worktree-preferences-sync.test.ts +25 -0
  528. package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +46 -0
  529. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +95 -0
  530. package/src/resources/extensions/gsd/tests/worktree-write-gate.test.ts +27 -0
  531. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +59 -0
  532. package/src/resources/extensions/gsd/tools/complete-milestone.ts +8 -10
  533. package/src/resources/extensions/gsd/tools/complete-slice.ts +6 -8
  534. package/src/resources/extensions/gsd/tools/plan-milestone.ts +5 -1
  535. package/src/resources/extensions/gsd/tools/plan-slice.ts +172 -12
  536. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +135 -0
  537. package/src/resources/extensions/gsd/types.ts +1 -1
  538. package/src/resources/extensions/gsd/unit-context-composer.ts +3 -0
  539. package/src/resources/extensions/gsd/unit-context-manifest.ts +86 -19
  540. package/src/resources/extensions/gsd/validation.ts +23 -1
  541. package/src/resources/extensions/gsd/verification-gate.ts +170 -6
  542. package/src/resources/extensions/gsd/verification-verdict.ts +47 -0
  543. package/src/resources/extensions/gsd/workflow-manifest.ts +2 -0
  544. package/src/resources/extensions/gsd/workflow-mcp.ts +18 -1
  545. package/src/resources/extensions/gsd/workflow-projections.ts +6 -8
  546. package/src/resources/extensions/gsd/worktree-lifecycle.ts +93 -20
  547. package/src/resources/extensions/gsd/worktree-manager.ts +14 -2
  548. package/src/resources/extensions/gsd/worktree-safety.ts +45 -6
  549. package/src/resources/extensions/gsd/worktree-state-projection.ts +43 -0
  550. package/src/resources/extensions/shared/html-shell.ts +412 -0
  551. package/src/resources/extensions/shared/interview-ui.ts +6 -4
  552. package/src/resources/extensions/shared/tests/interview-notes-loop.test.ts +15 -0
  553. package/src/resources/extensions/subagent/index.ts +567 -103
  554. package/src/resources/extensions/subagent/launch.ts +131 -0
  555. package/src/resources/extensions/subagent/run-store.ts +218 -0
  556. package/src/resources/extensions/subagent/tests/launch.test.ts +115 -0
  557. package/src/resources/extensions/subagent/tests/run-store.test.ts +111 -0
  558. package/src/resources/extensions/ttsr/ttsr-manager.ts +5 -1
  559. package/src/resources/extensions/visual-brief/artifact-policy.ts +41 -0
  560. package/src/resources/extensions/visual-brief/extension-manifest.json +8 -0
  561. package/src/resources/extensions/visual-brief/index.ts +8 -0
  562. package/src/resources/extensions/visual-brief/page-contract.ts +136 -0
  563. package/src/resources/extensions/visual-brief/prompts.ts +183 -0
  564. package/src/resources/extensions/visual-brief/tests/visual-brief.test.ts +212 -0
  565. package/src/resources/skills/forensics/SKILL.md +1 -1
  566. package/dist/web/standalone/.next/server/chunks/5822.js +0 -2
  567. package/dist/web/standalone/.next/static/chunks/2556.0527fea66e123b7f.js +0 -1
  568. package/dist/web/standalone/.next/static/chunks/8359.e059d86b255fce1c.js +0 -10
  569. package/dist/web/standalone/.next/static/chunks/9441.1081da1125d1764f.js +0 -1
  570. package/dist/web/standalone/.next/static/chunks/app/layout-a16c7a7ecdf0c2cf.js +0 -1
  571. package/dist/web/standalone/.next/static/css/54ec2745c1da488b.css +0 -1
  572. package/dist/web/standalone/.next/static/css/de70bee13400563f.css +0 -1
  573. package/dist/web/standalone/.next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
  574. package/dist/web/standalone/.next/static/media/747892c23ea88013-s.woff2 +0 -0
  575. package/dist/web/standalone/.next/static/media/8d697b304b401681-s.woff2 +0 -0
  576. package/dist/web/standalone/.next/static/media/93f479601ee12b01-s.p.woff2 +0 -0
  577. package/dist/web/standalone/.next/static/media/9610d9e46709d722-s.woff2 +0 -0
  578. package/dist/web/standalone/.next/static/media/ba015fad6dcf6784-s.woff2 +0 -0
  579. /package/dist/web/standalone/.next/static/{YEvjuT-fsFfYQhDSWtueS → zCegwxH2e6vLp1vEZLLuZ}/_buildManifest.js +0 -0
  580. /package/dist/web/standalone/.next/static/{YEvjuT-fsFfYQhDSWtueS → zCegwxH2e6vLp1vEZLLuZ}/_ssgManifest.js +0 -0
@@ -3,7 +3,7 @@
3
3
 
4
4
  import test, { mock } from "node:test";
5
5
  import assert from "node:assert/strict";
6
- import { mkdirSync, mkdtempSync, rmSync } from "node:fs";
6
+ import { mkdirSync, mkdtempSync, realpathSync, rmSync, writeFileSync } from "node:fs";
7
7
  import { tmpdir } from "node:os";
8
8
  import { join } from "node:path";
9
9
 
@@ -30,6 +30,11 @@ import type { LoopDeps } from "../auto/loop-deps.js";
30
30
  import { WorktreeStateProjection } from "../worktree-state-projection.js";
31
31
  import { ModelPolicyDispatchBlockedError } from "../auto-model-selection.js";
32
32
  import type { SessionLockStatus } from "../session-lock.js";
33
+ import { openDatabase, closeDatabase, insertMilestone, insertSlice, insertTask } from "../gsd-db.js";
34
+ import { registerAutoWorker } from "../db/auto-workers.js";
35
+ import { claimMilestoneLease } from "../db/milestone-leases.js";
36
+ import { recordDispatchClaim, markCanceled } from "../db/unit-dispatches.js";
37
+ import { setRuntimeKv, getRuntimeKv } from "../db/runtime-kv.js";
33
38
 
34
39
  // ─── Helpers ─────────────────────────────────────────────────────────────────
35
40
 
@@ -129,6 +134,8 @@ function makeMockPi() {
129
134
  setModelCalls.push(args);
130
135
  return true;
131
136
  },
137
+ getThinkingLevel: () => "off",
138
+ setThinkingLevel: () => {},
132
139
  calls,
133
140
  setModelCalls,
134
141
  } as any;
@@ -965,6 +972,79 @@ test("autoLoop exits on terminal complete state", async (t) => {
965
972
  );
966
973
  });
967
974
 
975
+ test("autoLoop persists stuck counter reset when dispatch recovery continues", async () => {
976
+ _resetPendingResolve();
977
+
978
+ const ctx = makeMockCtx();
979
+ const pi = makeMockPi();
980
+ const basePath = realpathSync(mkdtempSync(join(tmpdir(), "gsd-stuck-counter-reset-")));
981
+ mkdirSync(join(basePath, ".gsd"), { recursive: true });
982
+ mkdirSync(join(basePath, ".gsd", "milestones", "M001", "slices", "S01", "tasks"), { recursive: true });
983
+ writeFileSync(
984
+ join(basePath, ".gsd", "milestones", "M001", "slices", "S01", "S01-PLAN.md"),
985
+ "# Slice Plan\n\n- [ ] **T01:** task one\n",
986
+ );
987
+ writeFileSync(
988
+ join(basePath, ".gsd", "milestones", "M001", "slices", "S01", "tasks", "T01-PLAN.md"),
989
+ "# Task Plan\n",
990
+ );
991
+
992
+ try {
993
+ openDatabase(join(basePath, ".gsd", "gsd.db"));
994
+ insertMilestone({ id: "M001", title: "Test Milestone", status: "active" });
995
+ insertSlice({ id: "S01", milestoneId: "M001", title: "Test Slice", status: "pending" });
996
+ insertTask({ id: "T01", milestoneId: "M001", sliceId: "S01", title: "Task One", status: "pending" });
997
+ const workerId = registerAutoWorker({ projectRootRealpath: basePath });
998
+ const lease = claimMilestoneLease(workerId, "M001");
999
+ assert.equal(lease.ok, true);
1000
+ if (!lease.ok) return;
1001
+
1002
+ for (let i = 0; i < 2; i++) {
1003
+ const claim = recordDispatchClaim({
1004
+ traceId: `stuck-${i}`,
1005
+ workerId,
1006
+ milestoneLeaseToken: lease.token,
1007
+ milestoneId: "M001",
1008
+ sliceId: "S01",
1009
+ unitType: "plan-slice",
1010
+ unitId: "M001/S01",
1011
+ });
1012
+ assert.equal(claim.ok, true);
1013
+ if (!claim.ok) return;
1014
+ markCanceled(claim.dispatchId, "seed stuck window");
1015
+ }
1016
+ setRuntimeKv("global", basePath, "stuck_recovery_attempts", 1);
1017
+
1018
+ const s = makeLoopSession({
1019
+ basePath,
1020
+ originalBasePath: basePath,
1021
+ canonicalProjectRoot: basePath,
1022
+ });
1023
+ const deps = makeMockDeps({
1024
+ resolveDispatch: async () => ({
1025
+ action: "dispatch" as const,
1026
+ unitType: "plan-slice",
1027
+ unitId: "M001/S01",
1028
+ prompt: "plan the slice",
1029
+ }),
1030
+ invalidateAllCaches: () => {
1031
+ s.active = false;
1032
+ },
1033
+ });
1034
+
1035
+ await autoLoop(ctx, pi, s, deps);
1036
+
1037
+ assert.equal(
1038
+ getRuntimeKv<number>("global", basePath, "stuck_recovery_attempts"),
1039
+ 0,
1040
+ "dispatch-level artifact recovery exits through continue, so the reset counter must still persist",
1041
+ );
1042
+ } finally {
1043
+ try { closeDatabase(); } catch { /* noop */ }
1044
+ rmSync(basePath, { recursive: true, force: true });
1045
+ }
1046
+ });
1047
+
968
1048
  test("autoLoop stops before success notification when postflight stash restore needs recovery", async () => {
969
1049
  _resetPendingResolve();
970
1050
 
@@ -1401,6 +1481,81 @@ test("autoLoop calls deriveState → resolveDispatch → runUnit in sequence", a
1401
1481
  );
1402
1482
  });
1403
1483
 
1484
+ test("autoLoop dev path dispatches orchestration.advance results without legacy resolveDispatch", async () => {
1485
+ _resetPendingResolve();
1486
+
1487
+ const ctx = makeMockCtx();
1488
+ ctx.ui.setStatus = () => {};
1489
+ ctx.sessionManager = { getSessionFile: () => "/tmp/session.json" };
1490
+ const pi = makeMockPi();
1491
+ const stateSnapshot = {
1492
+ phase: "executing",
1493
+ activeMilestone: { id: "M002", title: "Advance Milestone", status: "active" },
1494
+ activeSlice: { id: "S03", title: "Slice 3" },
1495
+ activeTask: { id: "T05" },
1496
+ registry: [{ id: "M002", status: "active" }],
1497
+ blockers: [],
1498
+ } as any;
1499
+ let advanceCalls = 0;
1500
+ let s: any;
1501
+ s = makeLoopSession({
1502
+ currentMilestoneId: "M002",
1503
+ orchestration: {
1504
+ start: async () => ({ kind: "stopped" as const, reason: "unused" }),
1505
+ advance: async () => {
1506
+ advanceCalls++;
1507
+ s.pendingOrchestrationDispatch = {
1508
+ unitType: "execute-task",
1509
+ unitId: "M002/S03/T05",
1510
+ prompt: "advance prompt",
1511
+ pauseAfterUatDispatch: false,
1512
+ state: stateSnapshot,
1513
+ mid: "M002",
1514
+ midTitle: "Advance Milestone",
1515
+ };
1516
+ return {
1517
+ kind: "advanced" as const,
1518
+ unit: { unitType: "execute-task", unitId: "M002/S03/T05" },
1519
+ stateSnapshot,
1520
+ };
1521
+ },
1522
+ resume: async () => ({ kind: "stopped" as const, reason: "unused" }),
1523
+ stop: async () => ({ kind: "stopped" as const, reason: "unused" }),
1524
+ getStatus: () => ({ phase: "running" as const, transitionCount: 1 }),
1525
+ },
1526
+ });
1527
+
1528
+ const deps = makeMockDeps({
1529
+ resolveDispatch: async () => {
1530
+ deps.callLog.push("resolveDispatch");
1531
+ throw new Error("legacy resolveDispatch must not run when orchestration is wired");
1532
+ },
1533
+ postUnitPostVerification: async () => {
1534
+ deps.callLog.push("postUnitPostVerification");
1535
+ s.active = false;
1536
+ return "continue" as const;
1537
+ },
1538
+ });
1539
+
1540
+ const loopPromise = autoLoop(ctx, pi, s, deps);
1541
+ await waitForMicrotasks(() => pi.calls.length === 1, "orchestration advance dispatch");
1542
+ resolveAgentEnd(makeEvent());
1543
+ await loopPromise;
1544
+
1545
+ assert.equal(advanceCalls, 1);
1546
+ assert.equal(
1547
+ deps.callLog.includes("resolveDispatch"),
1548
+ false,
1549
+ "orchestration.advance owns dev-path dispatch",
1550
+ );
1551
+ assert.equal(
1552
+ (pi.calls[0] as any[])[0].content,
1553
+ "advance prompt",
1554
+ "runUnit should receive the dispatch prompt captured by advance()",
1555
+ );
1556
+ assert.equal(s.pendingOrchestrationDispatch, null, "pending dispatch should be one-shot");
1557
+ });
1558
+
1404
1559
  test("autoLoop journals post-unit finalize stop after completed unit", async () => {
1405
1560
  _resetPendingResolve();
1406
1561
 
@@ -2725,6 +2880,89 @@ test("runUnitPhase pauses ghost completions before closeout and finalize side ef
2725
2880
  );
2726
2881
  });
2727
2882
 
2883
+ test("runUnitPhase records failed routing outcome when expected artifact is missing", async (t) => {
2884
+ _resetPendingResolve();
2885
+
2886
+ const basePath = mkdtempSync(join(tmpdir(), "gsd-routing-artifact-missing-"));
2887
+ t.after(() => {
2888
+ _resetPendingResolve();
2889
+ rmSync(basePath, { recursive: true, force: true });
2890
+ });
2891
+
2892
+ const recordedOutcomes: Array<{ unitType: string; tier: string; success: boolean }> = [];
2893
+ const deps = makeMockDeps({
2894
+ selectAndApplyModel: async () => ({
2895
+ routing: { tier: "light" } as any,
2896
+ appliedModel: null,
2897
+ }),
2898
+ recordOutcome: (unitType: string, tier: string, success: boolean) => {
2899
+ recordedOutcomes.push({ unitType, tier, success });
2900
+ },
2901
+ });
2902
+ const ctx = {
2903
+ ...makeMockCtx(),
2904
+ ui: {
2905
+ notify: () => {},
2906
+ setStatus: () => {},
2907
+ setWorkingMessage: () => {},
2908
+ },
2909
+ sessionManager: {
2910
+ getEntries: () => [],
2911
+ },
2912
+ modelRegistry: {
2913
+ getProviderAuthMode: () => undefined,
2914
+ isProviderRequestReady: () => true,
2915
+ },
2916
+ } as any;
2917
+ const pi = {
2918
+ ...makeMockPi(),
2919
+ sendMessage: () => {
2920
+ queueMicrotask(() => resolveAgentEnd({ messages: [{ role: "assistant" }] }));
2921
+ },
2922
+ } as any;
2923
+ const s = makeLoopSession({
2924
+ basePath,
2925
+ canonicalProjectRoot: basePath,
2926
+ originalBasePath: basePath,
2927
+ });
2928
+ let seq = 0;
2929
+
2930
+ const result = await runUnitPhase(
2931
+ { ctx, pi, s, deps, prefs: undefined, iteration: 1, flowId: "flow-routing-outcome", nextSeq: () => ++seq },
2932
+ {
2933
+ unitType: "execute-task",
2934
+ unitId: "M001/S01/T01",
2935
+ prompt: "do work",
2936
+ finalPrompt: "do work",
2937
+ pauseAfterUatDispatch: false,
2938
+ state: {
2939
+ phase: "executing",
2940
+ activeMilestone: { id: "M001", title: "Milestone" },
2941
+ activeSlice: { id: "S01", title: "Slice" },
2942
+ activeTask: { id: "T01", title: "Task" },
2943
+ registry: [{ id: "M001", title: "Milestone", status: "active" }],
2944
+ recentDecisions: [],
2945
+ blockers: [],
2946
+ nextAction: "",
2947
+ progress: { milestones: { done: 0, total: 1 } },
2948
+ requirements: { active: 0, validated: 0, deferred: 0, outOfScope: 0, blocked: 0, total: 0 },
2949
+ } as any,
2950
+ mid: "M001",
2951
+ midTitle: "Milestone",
2952
+ isRetry: false,
2953
+ previousTier: undefined,
2954
+ },
2955
+ { recentUnits: [], stuckRecoveryAttempts: 0, consecutiveFinalizeTimeouts: 0 },
2956
+ );
2957
+
2958
+ assert.equal(result.action, "next");
2959
+ assert.deepEqual(
2960
+ recordedOutcomes,
2961
+ [{ unitType: "execute-task", tier: "light", success: false }],
2962
+ "routing history must treat missing artifacts as failed outcomes so retries can escalate",
2963
+ );
2964
+ });
2965
+
2728
2966
  test("resolveAgentEndCancelled without args produces no errorContext field", async () => {
2729
2967
  _resetPendingResolve();
2730
2968
 
@@ -2785,6 +3023,7 @@ test("autoLoop re-iterates when postUnitPreVerification returns retry (#1571)",
2785
3023
  const s = makeLoopSession();
2786
3024
 
2787
3025
  let preVerifyCallCount = 0;
3026
+ const currentUnitSnapshotsAtPreVerify: Array<{ type: string; id: string; startedAt: number } | null> = [];
2788
3027
  // Pre-queued responses: first call returns "retry", second returns "continue"
2789
3028
  const preVerifyResponses = ["retry", "continue"] as const;
2790
3029
 
@@ -2802,6 +3041,7 @@ test("autoLoop re-iterates when postUnitPreVerification returns retry (#1571)",
2802
3041
  },
2803
3042
  postUnitPreVerification: async () => {
2804
3043
  deps.callLog.push("postUnitPreVerification");
3044
+ currentUnitSnapshotsAtPreVerify.push(s.currentUnit);
2805
3045
  const response = preVerifyResponses[preVerifyCallCount++] ?? "continue";
2806
3046
  if (response === "retry") {
2807
3047
  s.pendingVerificationRetry = {
@@ -2832,6 +3072,11 @@ test("autoLoop re-iterates when postUnitPreVerification returns retry (#1571)",
2832
3072
  await loopPromise;
2833
3073
 
2834
3074
  assert.equal(preVerifyCallCount, 2, "preVerification should be called twice");
3075
+ assert.deepEqual(
3076
+ currentUnitSnapshotsAtPreVerify,
3077
+ [null, null],
3078
+ "currentUnit should be cleared before each preVerification run to prevent stale retry scope",
3079
+ );
2835
3080
 
2836
3081
  const postVerifyCalls = deps.callLog.filter(
2837
3082
  (c: string) => c === "runPostUnitVerification",
@@ -3353,6 +3598,60 @@ test("runDispatch runs stuck detection while artifact verification retry is pend
3353
3598
  );
3354
3599
  });
3355
3600
 
3601
+ test("runDispatch falls back to main when dispatch guard cannot read main branch (#5530)", async (t) => {
3602
+ _resetPendingResolve();
3603
+
3604
+ const ctx = makeMockCtx();
3605
+ const pi = makeMockPi();
3606
+ const basePath = mkdtempSync(join(tmpdir(), "gsd-5530-main-branch-fallback-"));
3607
+ t.after(() => rmSync(basePath, { recursive: true, force: true }));
3608
+
3609
+ let guardBranch: string | null = null;
3610
+ const s = makeLoopSession({ basePath });
3611
+ const deps = makeMockDeps({
3612
+ getMainBranch: () => {
3613
+ throw new Error("fatal: detected dubious ownership");
3614
+ },
3615
+ getPriorSliceCompletionBlocker: (_basePath, mainBranch) => {
3616
+ guardBranch = mainBranch;
3617
+ return null;
3618
+ },
3619
+ });
3620
+
3621
+ const result = await runDispatch(
3622
+ {
3623
+ ctx,
3624
+ pi,
3625
+ s,
3626
+ deps,
3627
+ prefs: undefined,
3628
+ iteration: 1,
3629
+ flowId: "test-flow",
3630
+ nextSeq: () => 1,
3631
+ },
3632
+ {
3633
+ state: {
3634
+ phase: "executing",
3635
+ activeMilestone: { id: "M001", title: "Test", status: "active" },
3636
+ activeSlice: { id: "S01", title: "Slice 1" },
3637
+ activeTask: { id: "T01" },
3638
+ registry: [{ id: "M001", status: "active" }],
3639
+ blockers: [],
3640
+ } as any,
3641
+ mid: "M001",
3642
+ midTitle: "Test",
3643
+ },
3644
+ {
3645
+ recentUnits: [],
3646
+ stuckRecoveryAttempts: 0,
3647
+ consecutiveFinalizeTimeouts: 0,
3648
+ },
3649
+ );
3650
+
3651
+ assert.equal(guardBranch, "main");
3652
+ assert.equal(result.action, "next");
3653
+ });
3654
+
3356
3655
  test("dispatch Worktree Safety stops unknown unit types with missing Tool Contract", async (t) => {
3357
3656
  _resetPendingResolve();
3358
3657
 
@@ -13,6 +13,12 @@ import { RuleRegistry, setRegistry, resetRegistry } from "../rule-registry.js";
13
13
  import type { UnifiedRule } from "../rule-types.js";
14
14
  import { supportsStructuredQuestions } from "../workflow-mcp.js";
15
15
 
16
+ function assertBlockedResult(
17
+ result: Awaited<ReturnType<ReturnType<typeof createAutoOrchestrator>["advance"]>>,
18
+ ): asserts result is Extract<typeof result, { kind: "blocked" }> {
19
+ assert.equal(result.kind, "blocked");
20
+ }
21
+
16
22
  function makeState(): GSDState {
17
23
  return {
18
24
  activeMilestone: { id: "M001", title: "Milestone" },
@@ -119,13 +125,13 @@ test("advance() returns blocked when health gate denies", async () => {
119
125
 
120
126
  const result = await orchestrator.advance();
121
127
 
122
- assert.equal(result.kind, "blocked");
128
+ assertBlockedResult(result);
123
129
  assert.equal(result.reason, "doctor-block");
124
130
  assert.equal(result.action, "pause");
125
131
  assert.ok(calls.includes("gate:pre-dispatch-health-gate:manual-attention"));
126
132
  });
127
133
 
128
- test("advance() returns blocked stop when resources are stale", async () => {
134
+ test("advance() returns blocked pause when resources are stale", async () => {
129
135
  const { deps, calls } = makeDeps({
130
136
  health: {
131
137
  checkResourcesStale: () => "resources changed since session start",
@@ -137,14 +143,89 @@ test("advance() returns blocked stop when resources are stale", async () => {
137
143
 
138
144
  const result = await orchestrator.advance();
139
145
 
140
- assert.equal(result.kind, "blocked");
146
+ assertBlockedResult(result);
141
147
  assert.equal(result.reason, "resources changed since session start");
142
- assert.equal(result.action, "stop");
148
+ assert.equal(result.action, "pause");
143
149
  assert.ok(calls.includes("gate:resource-version-guard:fail"));
144
150
  assert.ok(!calls.includes("health.pre"));
145
151
  assert.ok(!calls.includes("state.reconcile"));
146
152
  });
147
153
 
154
+ test("advance() pre-dispatch parity: gate emissions and control-flow action match legacy branches", async () => {
155
+ type Scenario = {
156
+ name: string;
157
+ staleMsg: string | null;
158
+ gateResult: Awaited<ReturnType<AutoOrchestratorDeps["health"]["preAdvanceGate"]>>;
159
+ expectedKind: "advanced" | "blocked";
160
+ expectedAction?: "pause" | "stop";
161
+ expectedReason?: string;
162
+ expectedGates: string[];
163
+ };
164
+ const scenarios: Scenario[] = [
165
+ {
166
+ name: "pass",
167
+ staleMsg: null,
168
+ gateResult: { kind: "pass" },
169
+ expectedKind: "advanced",
170
+ expectedGates: [
171
+ "resource-version-guard:policy:pass:none:resource version guard passed:",
172
+ "pre-dispatch-health-gate:execution:pass:none:pre-dispatch health gate passed:",
173
+ ],
174
+ },
175
+ {
176
+ name: "resource-stale",
177
+ staleMsg: "resources changed since session start",
178
+ gateResult: { kind: "pass" },
179
+ expectedKind: "blocked",
180
+ expectedAction: "pause",
181
+ expectedReason: "resources changed since session start",
182
+ expectedGates: [
183
+ "resource-version-guard:policy:fail:policy:resource version guard blocked dispatch:resources changed since session start",
184
+ ],
185
+ },
186
+ {
187
+ name: "health-gate-fail",
188
+ staleMsg: null,
189
+ gateResult: { kind: "fail", reason: "doctor-block" },
190
+ expectedKind: "blocked",
191
+ expectedAction: "pause",
192
+ expectedReason: "doctor-block",
193
+ expectedGates: [
194
+ "resource-version-guard:policy:pass:none:resource version guard passed:",
195
+ "pre-dispatch-health-gate:execution:manual-attention:manual-attention:pre-dispatch health gate blocked dispatch:doctor-block",
196
+ ],
197
+ },
198
+ ];
199
+
200
+ for (const scenario of scenarios) {
201
+ const gateEvents: string[] = [];
202
+ const { deps } = makeDeps({
203
+ health: {
204
+ checkResourcesStale: () => scenario.staleMsg,
205
+ async preAdvanceGate() { return scenario.gateResult; },
206
+ async postAdvanceRecord() {},
207
+ },
208
+ uokGate: {
209
+ async emit(input) {
210
+ gateEvents.push(
211
+ `${input.gateId}:${input.gateType}:${input.outcome}:${input.failureClass}:${input.rationale}:${input.findings ?? ""}`,
212
+ );
213
+ },
214
+ },
215
+ });
216
+ const orchestrator = createAutoOrchestrator(deps);
217
+ const result = await orchestrator.advance();
218
+
219
+ assert.equal(result.kind, scenario.expectedKind, `${scenario.name} result kind`);
220
+ if (scenario.expectedKind === "blocked") {
221
+ assertBlockedResult(result);
222
+ assert.equal(result.action, scenario.expectedAction, `${scenario.name} blocked action`);
223
+ assert.equal(result.reason, scenario.expectedReason, `${scenario.name} blocked reason`);
224
+ }
225
+ assert.deepEqual(gateEvents, scenario.expectedGates, `${scenario.name} gate parity`);
226
+ }
227
+ });
228
+
148
229
  test("advance() continues past pre-dispatch health gate when it throws", async () => {
149
230
  const { deps, calls } = makeDeps({
150
231
  health: {
@@ -223,7 +304,7 @@ test("advance() blocks before dispatch when State Reconciliation blocks", async
223
304
 
224
305
  const result = await orchestrator.advance();
225
306
 
226
- assert.equal(result.kind, "blocked");
307
+ assertBlockedResult(result);
227
308
  assert.equal(result.reason, "state drift blocked");
228
309
  assert.equal(result.action, "pause");
229
310
  assert.ok(!calls.includes("dispatch.decide"));
@@ -243,7 +324,7 @@ test("advance() blocks before Runtime persistence when Tool Contract fails", asy
243
324
 
244
325
  const result = await orchestrator.advance();
245
326
 
246
- assert.equal(result.kind, "blocked");
327
+ assertBlockedResult(result);
247
328
  assert.equal(result.reason, "unknown Unit");
248
329
  assert.equal(result.action, "pause");
249
330
  assert.ok(!calls.includes("worktree.prepare"));
@@ -266,7 +347,7 @@ test("advance() blocks before Runtime persistence when Worktree Safety fails", a
266
347
 
267
348
  const result = await orchestrator.advance();
268
349
 
269
- assert.equal(result.kind, "blocked");
350
+ assertBlockedResult(result);
270
351
  assert.equal(result.reason, "worktree invalid");
271
352
  assert.equal(result.action, "pause");
272
353
  assert.ok(!calls.includes("journal:advance"));
@@ -274,6 +355,26 @@ test("advance() blocks before Runtime persistence when Worktree Safety fails", a
274
355
  assert.ok(calls.includes("journal:advance-blocked"));
275
356
  });
276
357
 
358
+ test("advance() allows non-worktree isolation prepare result", async () => {
359
+ const { deps, calls } = makeDeps({
360
+ worktree: {
361
+ async prepareForUnit() {
362
+ calls.push("worktree.prepare");
363
+ return { ok: true, reason: "isolation-not-worktree" };
364
+ },
365
+ async syncAfterUnit() { calls.push("worktree.sync"); },
366
+ async cleanupOnStop() { calls.push("worktree.cleanup"); },
367
+ },
368
+ });
369
+ const orchestrator = createAutoOrchestrator(deps);
370
+
371
+ const result = await orchestrator.advance();
372
+
373
+ assert.equal(result.kind, "advanced");
374
+ assert.ok(calls.includes("journal:advance"));
375
+ assert.ok(calls.includes("worktree.sync"));
376
+ });
377
+
277
378
  test("advance() stops when dispatch has no next unit", async () => {
278
379
  const { deps } = makeDeps({
279
380
  dispatch: {
@@ -288,6 +389,52 @@ test("advance() stops when dispatch has no next unit", async () => {
288
389
  assert.equal(orchestrator.getStatus().phase, "stopped");
289
390
  });
290
391
 
392
+ test("advance() surfaces dispatch blocker reason instead of generic no remaining units", async () => {
393
+ const { deps, calls } = makeDeps({
394
+ dispatch: {
395
+ async decideNextUnit() {
396
+ return {
397
+ kind: "blocked",
398
+ reason: "Milestone M001 validation verdict is needs-remediation but all slices are complete.",
399
+ action: "pause",
400
+ };
401
+ },
402
+ },
403
+ });
404
+ const orchestrator = createAutoOrchestrator(deps);
405
+
406
+ const result = await orchestrator.advance();
407
+
408
+ assert.equal(result.kind, "blocked");
409
+ if (result.kind !== "blocked") return;
410
+ assert.equal(result.reason, "Milestone M001 validation verdict is needs-remediation but all slices are complete.");
411
+ assert.equal(result.action, "pause");
412
+ assert.ok(calls.includes("journal:advance-blocked"));
413
+ assert.ok(!calls.includes("journal:advance-stopped"));
414
+ });
415
+
416
+ test("resume() returns blocked when advance detects a dispatch blocker", async () => {
417
+ const { deps } = makeDeps({
418
+ dispatch: {
419
+ async decideNextUnit() {
420
+ return {
421
+ kind: "blocked",
422
+ reason: "remediation required",
423
+ action: "pause",
424
+ };
425
+ },
426
+ },
427
+ });
428
+ const orchestrator = createAutoOrchestrator(deps);
429
+
430
+ const result = await orchestrator.resume();
431
+
432
+ assert.equal(result.kind, "blocked");
433
+ if (result.kind !== "blocked") return;
434
+ assert.equal(result.reason, "remediation required");
435
+ assert.equal(result.action, "pause");
436
+ });
437
+
291
438
  test("advance() uses recovery on error", async () => {
292
439
  const { deps, calls } = makeDeps({
293
440
  runtime: {
@@ -319,7 +466,7 @@ test("advance() is idempotent for the same active unit", async () => {
319
466
  assert.deepEqual(first.unit, { unitType: "execute-task", unitId: "T01" });
320
467
  assert.equal(second.kind, "blocked");
321
468
  assert.equal(second.reason, "idempotent advance: unit already active");
322
- assert.equal(second.action, "stop");
469
+ assert.equal(second.action, "pause");
323
470
 
324
471
  const prepareCalls = calls.filter((c) => c === "worktree.prepare").length;
325
472
  assert.equal(prepareCalls, 1);
@@ -614,7 +761,7 @@ test("stuck-loop: ring saturated with same unit blocks with action 'stop' and st
614
761
  assert.equal(r.kind, "blocked", `round ${i} should be blocked`);
615
762
  if (r.kind !== "blocked") return;
616
763
  assert.equal(r.reason, "idempotent advance: unit already active");
617
- assert.equal(r.action, "stop");
764
+ assert.equal(r.action, "pause");
618
765
  }
619
766
 
620
767
  // The final call (ring now holds STUCK_WINDOW_SIZE copies) returns stuck-loop.
@@ -637,7 +784,7 @@ test("stuck-loop: idempotency block continues to fire with its own reason before
637
784
  assert.equal(first.kind, "advanced");
638
785
  assert.equal(second.kind, "blocked");
639
786
  assert.equal(second.reason, "idempotent advance: unit already active");
640
- assert.equal(second.action, "stop");
787
+ assert.equal(second.action, "pause");
641
788
  });
642
789
 
643
790
  test("stuck-loop: start() resets the ring so a fresh saturation cycle is required", async () => {
@@ -658,6 +805,7 @@ test("stuck-loop: start() resets the ring so a fresh saturation cycle is require
658
805
  const next = await orchestrator.advance();
659
806
  assert.equal(next.kind, "blocked");
660
807
  assert.equal(next.reason, "idempotent advance: unit already active");
808
+ assert.equal(next.action, "pause");
661
809
  });
662
810
 
663
811
  test("stuck-loop: resume() resets the ring", async () => {
@@ -674,6 +822,7 @@ test("stuck-loop: resume() resets the ring", async () => {
674
822
  const next = await orchestrator.advance();
675
823
  assert.equal(next.kind, "blocked");
676
824
  assert.equal(next.reason, "idempotent advance: unit already active");
825
+ assert.equal(next.action, "pause");
677
826
  });
678
827
 
679
828
  test("stuck-loop: stop() resets the ring", async () => {
@@ -797,7 +946,9 @@ test("wired DispatchAdapter forwards session-derived dispatch inputs identically
797
946
  assert.equal(adapterCtx.midTitle, directCtx.midTitle);
798
947
 
799
948
  // Dispatch action equality: both flows reach the same dispatch decision.
800
- assert.ok(adapterResult);
949
+ if (!adapterResult || !("unitType" in adapterResult)) {
950
+ assert.fail("expected adapter result to be a dispatch decision");
951
+ }
801
952
  assert.equal(adapterResult.unitType, "execute-task");
802
953
  assert.equal(adapterResult.unitId, "T01");
803
954
  assert.equal(adapterResult.reason, "test-capture");
@@ -853,9 +1004,11 @@ test("wired DispatchAdapter prefers caller-supplied dispatch inputs over ctx-der
853
1004
  getActiveTools: () => [],
854
1005
  } as any;
855
1006
  const adapter = createWiredDispatchAdapter(ctx, pi, "/tmp/parity-fixture");
1007
+ const session = { basePath: "/tmp/session-fixture" } as any;
856
1008
 
857
1009
  const result = await adapter.decideNextUnit({
858
1010
  stateSnapshot,
1011
+ session,
859
1012
  structuredQuestionsAvailable: "true",
860
1013
  sessionContextWindow: 500_000,
861
1014
  sessionProvider: "openai",
@@ -868,6 +1021,39 @@ test("wired DispatchAdapter prefers caller-supplied dispatch inputs over ctx-der
868
1021
  assert.equal(captured[0].sessionContextWindow, 500_000);
869
1022
  assert.equal(captured[0].sessionProvider, "openai");
870
1023
  assert.equal(captured[0].modelRegistry, overrideModelRegistry);
1024
+ assert.equal(captured[0].session, session);
1025
+ } finally {
1026
+ resetRegistry();
1027
+ }
1028
+ });
1029
+
1030
+ test("wired DispatchAdapter preserves stop reason as a blocked decision", async () => {
1031
+ const stateSnapshot = makeState();
1032
+ const stopRule: UnifiedRule = {
1033
+ name: "test-stop",
1034
+ when: "dispatch",
1035
+ evaluation: "first-match",
1036
+ where: async () => ({
1037
+ action: "stop" as const,
1038
+ reason: "remediation blocker",
1039
+ level: "warning" as const,
1040
+ }),
1041
+ then: (r: unknown) => r,
1042
+ };
1043
+ setRegistry(new RuleRegistry([stopRule]));
1044
+
1045
+ try {
1046
+ const ctx = { model: {}, modelRegistry: { getAll: () => [] } } as any;
1047
+ const pi = { getActiveTools: () => [] } as any;
1048
+ const adapter = createWiredDispatchAdapter(ctx, pi, "/tmp/parity-fixture");
1049
+
1050
+ const result = await adapter.decideNextUnit({ stateSnapshot });
1051
+
1052
+ assert.deepEqual(result, {
1053
+ kind: "blocked",
1054
+ reason: "remediation blocker",
1055
+ action: "pause",
1056
+ });
871
1057
  } finally {
872
1058
  resetRegistry();
873
1059
  }