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
@@ -0,0 +1,202 @@
1
+ import type { ExtensionCommandContext } from "@gsd/pi-coding-agent";
2
+
3
+ import { loadFile } from "./files.js";
4
+ import { resolveMilestoneFile } from "./paths.js";
5
+ import { deriveState } from "./state.js";
6
+ import { executeValidateMilestone } from "./tools/workflow-tool-executors.js";
7
+ import {
8
+ VALIDATION_VERDICTS,
9
+ extractVerdict,
10
+ isValidMilestoneVerdict,
11
+ type ValidationVerdict,
12
+ } from "./verdict-parser.js";
13
+
14
+ const USAGE =
15
+ 'Usage: /gsd verdict <pass|needs-attention|needs-remediation> [--milestone Mxxx] [--rationale "..."]';
16
+
17
+ interface ParsedArgs {
18
+ verdict?: ValidationVerdict;
19
+ milestoneId?: string;
20
+ rationale?: string;
21
+ }
22
+
23
+ interface ParsedValidation {
24
+ verdict: string | undefined;
25
+ remediationRound: number;
26
+ successCriteriaChecklist: string;
27
+ sliceDeliveryAudit: string;
28
+ crossSliceIntegration: string;
29
+ requirementCoverage: string;
30
+ verificationClasses?: string;
31
+ verdictRationale: string;
32
+ remediationPlan?: string;
33
+ }
34
+
35
+ function tokenize(raw: string): string[] {
36
+ const tokens: string[] = [];
37
+ const re = /"([^"]*)"|(\S+)/g;
38
+ let match: RegExpExecArray | null;
39
+ while ((match = re.exec(raw)) !== null) {
40
+ tokens.push(match[1] ?? match[2]);
41
+ }
42
+ return tokens;
43
+ }
44
+
45
+ function parseArgs(raw: string): ParsedArgs | { error: string } {
46
+ const tokens = tokenize(raw);
47
+ const out: ParsedArgs = {};
48
+ for (let i = 0; i < tokens.length; i++) {
49
+ const t = tokens[i];
50
+ if (t === "--milestone") {
51
+ const next = tokens[++i];
52
+ if (!next) return { error: "--milestone requires a milestone ID" };
53
+ out.milestoneId = next;
54
+ } else if (t === "--rationale") {
55
+ const next = tokens[++i];
56
+ if (next == null) return { error: "--rationale requires a value" };
57
+ out.rationale = next;
58
+ } else if (!out.verdict) {
59
+ if (!isValidMilestoneVerdict(t)) {
60
+ return {
61
+ error: `Invalid verdict "${t}". Must be one of: ${VALIDATION_VERDICTS.join(", ")}`,
62
+ };
63
+ }
64
+ out.verdict = t;
65
+ } else {
66
+ return { error: `Unexpected argument: ${t}` };
67
+ }
68
+ }
69
+ return out;
70
+ }
71
+
72
+ function extractRemediationRound(content: string): number {
73
+ const fm = content.match(/^---\n([\s\S]*?)\n---/);
74
+ if (!fm) return 0;
75
+ const m = fm[1].match(/^remediation_round:\s*(\d+)/im);
76
+ return m ? Number.parseInt(m[1], 10) : 0;
77
+ }
78
+
79
+ function extractSection(content: string, heading: string): string | undefined {
80
+ const escaped = heading.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
81
+ // Match section bodies bounded by the next "## " heading or end-of-string.
82
+ // Leading "\n" prefix lets a single pattern handle first-line headings too.
83
+ // No /m flag — we want `$` to mean end-of-string, not end-of-line.
84
+ const re = new RegExp(`\\n## ${escaped}\\s*\\n([\\s\\S]*?)(?=\\n## |$)`);
85
+ const m = ("\n" + content).match(re);
86
+ if (!m) return undefined;
87
+ return m[1].replace(/\s+$/, "");
88
+ }
89
+
90
+ export function parseValidationFile(content: string): ParsedValidation {
91
+ return {
92
+ verdict: extractVerdict(content),
93
+ remediationRound: extractRemediationRound(content),
94
+ successCriteriaChecklist: extractSection(content, "Success Criteria Checklist") ?? "",
95
+ sliceDeliveryAudit: extractSection(content, "Slice Delivery Audit") ?? "",
96
+ crossSliceIntegration: extractSection(content, "Cross-Slice Integration") ?? "",
97
+ requirementCoverage: extractSection(content, "Requirement Coverage") ?? "",
98
+ verificationClasses: extractSection(content, "Verification Class Compliance"),
99
+ verdictRationale: extractSection(content, "Verdict Rationale") ?? "",
100
+ remediationPlan: extractSection(content, "Remediation Plan"),
101
+ };
102
+ }
103
+
104
+ export async function handleVerdict(
105
+ rawArgs: string,
106
+ ctx: ExtensionCommandContext,
107
+ basePath: string,
108
+ ): Promise<void> {
109
+ if (!rawArgs.trim()) {
110
+ ctx.ui.notify(USAGE, "warning");
111
+ return;
112
+ }
113
+
114
+ const parsed = parseArgs(rawArgs);
115
+ if ("error" in parsed) {
116
+ ctx.ui.notify(`${parsed.error}\n${USAGE}`, "warning");
117
+ return;
118
+ }
119
+ if (!parsed.verdict) {
120
+ ctx.ui.notify(USAGE, "warning");
121
+ return;
122
+ }
123
+
124
+ let milestoneId = parsed.milestoneId;
125
+ if (!milestoneId) {
126
+ const state = await deriveState(basePath);
127
+ if (!state.activeMilestone) {
128
+ ctx.ui.notify(
129
+ "No active milestone — pass --milestone Mxxx to target a specific milestone.",
130
+ "warning",
131
+ );
132
+ return;
133
+ }
134
+ milestoneId = state.activeMilestone.id;
135
+ }
136
+
137
+ const validationPath = resolveMilestoneFile(basePath, milestoneId, "VALIDATION");
138
+ if (!validationPath) {
139
+ ctx.ui.notify(
140
+ `No VALIDATION file found for ${milestoneId}. Run gsd_validate_milestone first to produce one.`,
141
+ "warning",
142
+ );
143
+ return;
144
+ }
145
+ const existing = await loadFile(validationPath);
146
+ if (!existing) {
147
+ ctx.ui.notify(
148
+ `Could not read VALIDATION file for ${milestoneId} (${validationPath}).`,
149
+ "warning",
150
+ );
151
+ return;
152
+ }
153
+
154
+ const current = parseValidationFile(existing);
155
+
156
+ if (parsed.verdict !== "pass" && !parsed.rationale) {
157
+ ctx.ui.notify(
158
+ `--rationale is required when overriding to ${parsed.verdict}.`,
159
+ "warning",
160
+ );
161
+ return;
162
+ }
163
+
164
+ const verdictRationale =
165
+ parsed.rationale ?? "Manually overridden via /gsd verdict";
166
+
167
+ const result = await executeValidateMilestone(
168
+ {
169
+ milestoneId,
170
+ verdict: parsed.verdict,
171
+ remediationRound: current.remediationRound,
172
+ successCriteriaChecklist: current.successCriteriaChecklist,
173
+ sliceDeliveryAudit: current.sliceDeliveryAudit,
174
+ crossSliceIntegration: current.crossSliceIntegration,
175
+ requirementCoverage: current.requirementCoverage,
176
+ verificationClasses: current.verificationClasses,
177
+ verdictRationale,
178
+ remediationPlan: current.remediationPlan,
179
+ },
180
+ basePath,
181
+ );
182
+
183
+ if (result.isError) {
184
+ const msg =
185
+ result.content[0]?.type === "text" ? result.content[0].text : "Unknown error";
186
+ ctx.ui.notify(msg, "error");
187
+ return;
188
+ }
189
+
190
+ const prevVerdict = current.verdict ?? "unknown";
191
+ ctx.ui.notify(
192
+ `Milestone ${milestoneId} verdict: ${prevVerdict} -> ${parsed.verdict}`,
193
+ "success",
194
+ );
195
+
196
+ if (parsed.verdict === "needs-remediation") {
197
+ ctx.ui.notify(
198
+ "Follow up with gsd_reassess_roadmap to add remediation slices, then re-run /gsd auto.",
199
+ "info",
200
+ );
201
+ }
202
+ }
@@ -30,9 +30,12 @@ import { join } from "node:path";
30
30
  import {
31
31
  findStaleWorkerForProject,
32
32
  getAllAutoWorkers,
33
+ markWorkerCrashed,
34
+ markWorkerStopping,
33
35
  type AutoWorkerRow,
34
36
  } from "./db/auto-workers.js";
35
- import { getLatestForUnit, type DispatchStatus } from "./db/unit-dispatches.js";
37
+ import { forceReleaseLeasesForWorker } from "./db/milestone-leases.js";
38
+ import { markLatestActiveForWorkerCanceled, type DispatchStatus } from "./db/unit-dispatches.js";
36
39
  import { getRuntimeKv, setRuntimeKv, deleteRuntimeKv } from "./db/runtime-kv.js";
37
40
  import { _getAdapter, isDbAvailable } from "./gsd-db.js";
38
41
  import { gsdRoot, normalizeRealPath } from "./paths.js";
@@ -56,6 +59,15 @@ function lockPath(basePath: string): string {
56
59
  return join(gsdRoot(basePath), effectiveLockFile());
57
60
  }
58
61
 
62
+ function clearLegacyLockFile(basePath: string): void {
63
+ try {
64
+ const p = lockPath(basePath);
65
+ if (existsSync(p)) unlinkSync(p);
66
+ } catch {
67
+ // Best-effort.
68
+ }
69
+ }
70
+
59
71
  function readLegacyLock(basePath: string): LockData | null {
60
72
  try {
61
73
  const p = lockPath(basePath);
@@ -185,12 +197,18 @@ export function writeLock(
185
197
  // Best-effort — never throw from the lock writer.
186
198
  }
187
199
 
188
- if (!isDbAvailable() || !sessionFile) return;
200
+ if (!isDbAvailable()) return;
189
201
  try {
190
202
  const projectRoot = normalizeRealPath(basePath);
191
203
  const worker = findActiveWorkerForCurrentProcess(projectRoot);
192
204
  if (!worker) return;
193
- setRuntimeKv("worker", worker.worker_id, SESSION_FILE_KV_KEY, sessionFile);
205
+ if (sessionFile) {
206
+ setRuntimeKv("worker", worker.worker_id, SESSION_FILE_KV_KEY, sessionFile);
207
+ } else {
208
+ // Preliminary unit locks (before runUnit/newSession settles) must clear
209
+ // any prior pointer so crash recovery cannot ingest stale cross-unit context.
210
+ deleteRuntimeKv("worker", worker.worker_id, SESSION_FILE_KV_KEY);
211
+ }
194
212
  } catch {
195
213
  // Best-effort — never throw from the lock writer.
196
214
  }
@@ -204,18 +222,46 @@ export function writeLock(
204
222
  * stale session-file pointer.
205
223
  */
206
224
  export function clearLock(basePath: string): void {
225
+ clearLegacyLockFile(basePath);
226
+
227
+ if (!isDbAvailable()) return;
207
228
  try {
208
- const p = lockPath(basePath);
209
- if (existsSync(p)) unlinkSync(p);
229
+ const projectRoot = normalizeRealPath(basePath);
230
+ const staleWorker = findStaleWorkerForProject(projectRoot);
231
+ if (staleWorker) {
232
+ markWorkerCrashed(staleWorker.worker_id);
233
+ forceReleaseLeasesForWorker(staleWorker.worker_id);
234
+ deleteRuntimeKv("worker", staleWorker.worker_id, SESSION_FILE_KV_KEY);
235
+ return;
236
+ }
237
+ const worker = findActiveWorkerForCurrentProcess(projectRoot);
238
+ if (worker) deleteRuntimeKv("worker", worker.worker_id, SESSION_FILE_KV_KEY);
239
+
240
+ const stale = findStaleWorkerForProject(projectRoot);
241
+ if (stale) {
242
+ markWorkerStopping(stale.worker_id);
243
+ deleteRuntimeKv("worker", stale.worker_id, SESSION_FILE_KV_KEY);
244
+ }
210
245
  } catch {
211
246
  // Best-effort.
212
247
  }
248
+ }
249
+
250
+ /**
251
+ * Clear a stale DB-backed worker lock after readCrashLock/findStaleWorkerForProject
252
+ * has identified a dead worker. Unlike clearLock(), this targets the stale
253
+ * worker row instead of the current process's active worker.
254
+ */
255
+ export function clearStaleWorkerLock(basePath: string): void {
256
+ clearLegacyLockFile(basePath);
213
257
 
214
258
  if (!isDbAvailable()) return;
215
259
  try {
216
260
  const projectRoot = normalizeRealPath(basePath);
217
- const worker = findActiveWorkerForCurrentProcess(projectRoot);
261
+ const worker = findStaleWorkerForProject(projectRoot);
218
262
  if (!worker) return;
263
+ markLatestActiveForWorkerCanceled(worker.worker_id, "crash-recovered");
264
+ markWorkerCrashed(worker.worker_id);
219
265
  deleteRuntimeKv("worker", worker.worker_id, SESSION_FILE_KV_KEY);
220
266
  } catch {
221
267
  // Best-effort.
@@ -255,6 +255,32 @@ export function releaseMilestoneLease(
255
255
  });
256
256
  }
257
257
 
258
+ /**
259
+ * Force-release all held leases for a worker.
260
+ *
261
+ * Used by crash recovery once PID liveness has confirmed the worker is dead.
262
+ * No fencing token is required because this path is cleanup-only for a
263
+ * non-running process.
264
+ */
265
+ export function forceReleaseLeasesForWorker(workerId: string): number {
266
+ if (!isDbAvailable()) return 0;
267
+ const db = _getAdapter()!;
268
+ let changes = 0;
269
+ transaction(() => {
270
+ const result = db.prepare(
271
+ `UPDATE milestone_leases
272
+ SET status = 'released'
273
+ WHERE worker_id = :worker_id
274
+ AND status = 'held'`,
275
+ ).run({ ":worker_id": workerId });
276
+ changes =
277
+ typeof (result as { changes?: unknown }).changes === "number"
278
+ ? (result as { changes: number }).changes
279
+ : 0;
280
+ });
281
+ return changes;
282
+ }
283
+
258
284
  /**
259
285
  * Read current lease row for diagnostics. Returns null if no row exists.
260
286
  */
@@ -524,17 +524,18 @@ export function getRecentUnitKeysForProjectRoot(
524
524
  if (!isDbAvailable()) return [];
525
525
  const db = _getAdapter()!;
526
526
  const rows = db.prepare(
527
- `SELECT ud.unit_id
527
+ `SELECT ud.unit_type, ud.unit_id
528
528
  FROM unit_dispatches ud
529
529
  INNER JOIN workers w ON w.worker_id = ud.worker_id
530
530
  WHERE w.project_root_realpath = :project_root_realpath
531
+ AND w.status != 'crashed'
531
532
  ORDER BY ud.started_at DESC, ud.id DESC
532
533
  LIMIT :limit`,
533
534
  ).all({
534
535
  ":project_root_realpath": projectRootRealpath,
535
536
  ":limit": limit,
536
- }) as Array<{ unit_id: string }>;
537
- return rows.reverse().map((r) => ({ key: r.unit_id }));
537
+ }) as Array<{ unit_type: string; unit_id: string }>;
538
+ return rows.reverse().map((r) => ({ key: `${r.unit_type}/${r.unit_id}` }));
538
539
  }
539
540
 
540
541
  /**
@@ -168,6 +168,7 @@ export function createBaseSchemaObjects(db: DbAdapter, hooks: BaseSchemaHooks):
168
168
  proof_level TEXT NOT NULL DEFAULT '',
169
169
  integration_closure TEXT NOT NULL DEFAULT '',
170
170
  observability_impact TEXT NOT NULL DEFAULT '',
171
+ target_repositories TEXT NOT NULL DEFAULT '[]',
171
172
  sequence INTEGER DEFAULT 0,
172
173
  replan_triggered_at TEXT DEFAULT NULL,
173
174
  is_sketch INTEGER NOT NULL DEFAULT 0,
@@ -208,6 +209,7 @@ export function createBaseSchemaObjects(db: DbAdapter, hooks: BaseSchemaHooks):
208
209
  expected_output TEXT NOT NULL DEFAULT '[]',
209
210
  observability_impact TEXT NOT NULL DEFAULT '',
210
211
  full_plan_md TEXT NOT NULL DEFAULT '',
212
+ target_repositories TEXT NOT NULL DEFAULT '[]',
211
213
  sequence INTEGER DEFAULT 0,
212
214
  PRIMARY KEY (milestone_id, slice_id, id),
213
215
  FOREIGN KEY (milestone_id, slice_id) REFERENCES slices(milestone_id, id)
@@ -424,6 +424,11 @@ export function applyMigrationV28MemoryLastHitAt(db: DbAdapter): void {
424
424
  ensureColumn(db, "memories", "last_hit_at", "ALTER TABLE memories ADD COLUMN last_hit_at TEXT DEFAULT NULL");
425
425
  }
426
426
 
427
+ export function applyMigrationV29RepositoryTargets(db: DbAdapter): void {
428
+ ensureColumn(db, "slices", "target_repositories", "ALTER TABLE slices ADD COLUMN target_repositories TEXT NOT NULL DEFAULT '[]'");
429
+ ensureColumn(db, "tasks", "target_repositories", "ALTER TABLE tasks ADD COLUMN target_repositories TEXT NOT NULL DEFAULT '[]'");
430
+ }
431
+
427
432
  export interface MigrationV22Hooks {
428
433
  copyQualityGateRowsToRepairedTable(db: DbAdapter): void;
429
434
  }
@@ -22,6 +22,7 @@ export interface SliceRow {
22
22
  replan_triggered_at: string | null;
23
23
  is_sketch: number;
24
24
  sketch_scope: string;
25
+ target_repositories?: string[];
25
26
  }
26
27
 
27
28
  export interface TaskRow {
@@ -55,6 +56,7 @@ export interface TaskRow {
55
56
  escalation_awaiting_review: number;
56
57
  escalation_artifact_path: string | null;
57
58
  escalation_override_applied_at: string | null;
59
+ target_repositories?: string[];
58
60
  }
59
61
 
60
62
  type DbRow = Record<string, unknown>;
@@ -107,6 +109,7 @@ export function rowToSlice(row: DbRow): SliceRow {
107
109
  replan_triggered_at: (row["replan_triggered_at"] as string) ?? null,
108
110
  is_sketch: (row["is_sketch"] as number) ?? 0,
109
111
  sketch_scope: (row["sketch_scope"] as string) ?? "",
112
+ target_repositories: parseTaskArrayColumn(row["target_repositories"]),
110
113
  };
111
114
  }
112
115
 
@@ -142,5 +145,6 @@ export function rowToTask(row: DbRow): TaskRow {
142
145
  escalation_awaiting_review: (row["escalation_awaiting_review"] as number) ?? 0,
143
146
  escalation_artifact_path: (row["escalation_artifact_path"] as string) ?? null,
144
147
  escalation_override_applied_at: (row["escalation_override_applied_at"] as string) ?? null,
148
+ target_repositories: parseTaskArrayColumn(row["target_repositories"]),
145
149
  };
146
150
  }
@@ -5,9 +5,10 @@ import { findMilestoneIds } from "./guided-flow.js";
5
5
  import { parseUnitId } from "./unit-id.js";
6
6
  import { isDbAvailable, getMilestoneSlices, getMilestone } from "./gsd-db.js";
7
7
  import { parseRoadmap } from "./parsers-legacy.js";
8
- import { isClosedStatus } from "./status-guards.js";
8
+ import { isClosedStatus, isSkippedForDispatch } from "./status-guards.js";
9
9
  import { classifyMilestoneSummaryContent } from "./milestone-summary-classifier.js";
10
10
  import { readFileSync } from "node:fs";
11
+ import type { LoopState } from "./auto/types.js";
11
12
 
12
13
  const SLICE_DISPATCH_TYPES = new Set([
13
14
  "research-slice",
@@ -17,6 +18,63 @@ const SLICE_DISPATCH_TYPES = new Set([
17
18
  "complete-slice",
18
19
  ]);
19
20
 
21
+ const CONSECUTIVE_SAME_UNIT_CAP_TYPES = new Set([
22
+ "complete-milestone",
23
+ "validate-milestone",
24
+ "research-slice",
25
+ ]);
26
+ const CONSECUTIVE_SAME_UNIT_CAP = 2;
27
+
28
+ type ConsecutiveDispatchState = Pick<
29
+ LoopState,
30
+ "consecutiveDispatchCount" | "lastDispatchedKey" | "lastDispatchPhase"
31
+ >;
32
+
33
+ /**
34
+ * Prevent repeated dispatches of the same unit within the same phase.
35
+ *
36
+ * Applies only to unit types in `CONSECUTIVE_SAME_UNIT_CAP_TYPES`. The first
37
+ * dispatch for a unit/phase pair starts a counter, unit or phase changes reset
38
+ * tracking, and dispatch is blocked once the counter reaches
39
+ * `CONSECUTIVE_SAME_UNIT_CAP`.
40
+ *
41
+ * Side effects: mutates `state.consecutiveDispatchCount`,
42
+ * `state.lastDispatchedKey`, and `state.lastDispatchPhase`.
43
+ *
44
+ * Returns `null` when dispatch is allowed, or a blocker message (including
45
+ * guidance to run `/gsd resume`) when the cap is reached.
46
+ */
47
+ export function getConsecutiveDispatchBlocker(
48
+ state: ConsecutiveDispatchState,
49
+ phase: string,
50
+ unitType: string,
51
+ unitId: string,
52
+ ): string | null {
53
+ if (!CONSECUTIVE_SAME_UNIT_CAP_TYPES.has(unitType)) return null;
54
+ if (!state.consecutiveDispatchCount) state.consecutiveDispatchCount = new Map<string, number>();
55
+
56
+ const key = `${unitType}:${unitId}`;
57
+ const phaseChanged = state.lastDispatchPhase !== phase;
58
+ const switchedUnit = state.lastDispatchedKey !== key;
59
+ if (phaseChanged || switchedUnit) {
60
+ state.consecutiveDispatchCount.clear();
61
+ state.consecutiveDispatchCount.set(key, 1);
62
+ state.lastDispatchedKey = key;
63
+ state.lastDispatchPhase = phase;
64
+ return null;
65
+ }
66
+
67
+ const count = state.consecutiveDispatchCount.get(key) ?? 0;
68
+ if (count >= CONSECUTIVE_SAME_UNIT_CAP) {
69
+ return `Cannot dispatch ${unitType} ${unitId}: dispatched ${count} consecutive times; same-unit repeat cap reached. Resolve via /gsd resume.`;
70
+ }
71
+
72
+ state.consecutiveDispatchCount.set(key, count + 1);
73
+ state.lastDispatchedKey = key;
74
+ state.lastDispatchPhase = phase;
75
+ return null;
76
+ }
77
+
20
78
  export function getPriorSliceCompletionBlocker(
21
79
  base: string,
22
80
  _mainBranch: string,
@@ -58,7 +116,7 @@ export function getPriorSliceCompletionBlocker(
58
116
  // DB-backed projects must not treat SUMMARY.md as authoritative.
59
117
  if (isDbAvailable()) {
60
118
  const milestoneRow = getMilestone(mid);
61
- if (milestoneRow && isClosedStatus(milestoneRow.status)) continue;
119
+ if (milestoneRow && isSkippedForDispatch(milestoneRow.status)) continue;
62
120
  } else {
63
121
  const summaryPath = resolveMilestoneFile(base, mid, "SUMMARY");
64
122
  let summaryContent: string | null = null;
@@ -147,6 +147,14 @@ Setting `prefer_skills: []` does **not** disable skill discovery — it just mea
147
147
 
148
148
  - `unique_milestone_ids`: boolean — when `true`, generates milestone IDs in `M{seq}-{rand6}` format (e.g. `M001-eh88as`) instead of plain sequential `M001`. Prevents ID collisions in team workflows where multiple contributors create milestones concurrently. Both formats coexist — existing `M001`-style milestones remain valid. Default: `false`.
149
149
 
150
+ - `workspace`: optional parent-workspace repository registry. Keys:
151
+ - `mode`: `"project"` or `"parent"` — registry mode for repository lookup. Default: `"project"`.
152
+ - `repositories`: object keyed by repository id. A default `"project"` repository pointing at the project root is always available, even when not listed here (and can be overridden by explicitly defining `"project"`). Each repository supports:
153
+ - `path`: string — repository root path relative to project root.
154
+ - `role`: string — optional human label for prompts/reporting.
155
+ - `verification`: string[] — optional default verification commands.
156
+ - `commit_policy`: `"auto"` or `"skip"` — optional turn-commit policy for auto-mode commit actions. Defaults to `"auto"` when omitted. `"skip"` suppresses commit execution for that target repo.
157
+
150
158
  - `budget_ceiling`: number — maximum dollar amount to spend on auto-mode. When reached, behavior is controlled by `budget_enforcement`. Default: no limit.
151
159
 
152
160
  - `budget_enforcement`: `"warn"`, `"pause"`, or `"halt"` — action taken when `budget_ceiling` is reached.
@@ -9,7 +9,7 @@ import { parseRoadmap as parseLegacyRoadmap } from "./parsers-legacy.js";
9
9
  import { isDbAvailable, getMilestone } from "./gsd-db.js";
10
10
  import { resolveMilestoneFile } from "./paths.js";
11
11
  import { deriveState, isMilestoneComplete } from "./state.js";
12
- import { listWorktrees, resolveGitDir, worktreesDir } from "./worktree-manager.js";
12
+ import { createWorktree, listWorktrees, resolveGitDir, worktreesDir } from "./worktree-manager.js";
13
13
  import { abortAndReset } from "./git-self-heal.js";
14
14
  import { RUNTIME_EXCLUSION_PATHS, resolveMilestoneIntegrationBranch, writeIntegrationBranch } from "./git-service.js";
15
15
  import { nativeIsRepo, nativeWorktreeList, nativeWorktreeRemove, nativeBranchList, nativeBranchDelete, nativeLsFiles, nativeRmCached, nativeHasChanges, nativeLastCommitEpoch, nativeGetCurrentBranch, nativeAddTracked, nativeCommit } from "./native-git-bridge.js";
@@ -54,6 +54,19 @@ function isSameOrNestedPath(candidate: string, container: string): boolean {
54
54
  normalizedCandidate.startsWith(`${normalizedContainer}/`);
55
55
  }
56
56
 
57
+ function hasProjectContentOnDisk(dirPath: string): boolean {
58
+ try {
59
+ for (const entry of readdirSync(dirPath, { withFileTypes: true })) {
60
+ if (entry.name === ".git" || entry.name === ".gsd") continue;
61
+ if (entry.name === ".DS_Store") continue;
62
+ return true;
63
+ }
64
+ } catch {
65
+ return false;
66
+ }
67
+ return false;
68
+ }
69
+
57
70
  function getSnapshotDiffCheckFailure(basePath: string): string | null {
58
71
  const failures: string[] = [];
59
72
 
@@ -123,6 +136,37 @@ export async function checkGitHealth(
123
136
  ? await isCompletedMilestoneTerminal(basePath, milestoneId)
124
137
  : false;
125
138
 
139
+ if (!isComplete && !hasProjectContentOnDisk(wt.path) && hasProjectContentOnDisk(basePath)) {
140
+ issues.push({
141
+ severity: "error",
142
+ code: "worktree_empty_with_project_content",
143
+ scope: "milestone",
144
+ unitId: milestoneId,
145
+ message: `Worktree ${wt.path} has no project content, but project root ${basePath} does. Run doctor --fix to recreate the worktree.`,
146
+ fixable: true,
147
+ });
148
+
149
+ if (shouldFix("worktree_empty_with_project_content")) {
150
+ try {
151
+ nativeWorktreeRemove(basePath, wt.path, true);
152
+ const recreated = createWorktree(basePath, milestoneId, {
153
+ branch: wt.branch,
154
+ reuseExistingBranch: true,
155
+ });
156
+ const reset = spawnSync("git", ["reset", "--hard"], {
157
+ cwd: recreated.path,
158
+ encoding: "utf-8",
159
+ });
160
+ if (reset.status !== 0) {
161
+ throw new Error(reset.stderr || reset.error?.message || "git reset --hard failed");
162
+ }
163
+ fixesApplied.push(`recreated empty worktree ${wt.path}`);
164
+ } catch {
165
+ fixesApplied.push(`failed to recreate empty worktree ${wt.path}`);
166
+ }
167
+ }
168
+ }
169
+
126
170
  if (isComplete) {
127
171
  issues.push({
128
172
  severity: "warning",
@@ -7,7 +7,7 @@ import { milestonesDir, gsdRoot, resolveGsdRootFile } from "./paths.js";
7
7
  import { deriveState, isGhostMilestone, isReusableGhostMilestone } from "./state.js";
8
8
  import { saveFile } from "./files.js";
9
9
  import { nativeIsRepo, nativeForEachRef, nativeUpdateRef } from "./native-git-bridge.js";
10
- import { readCrashLock, isLockProcessAlive, clearLock } from "./crash-recovery.js";
10
+ import { readCrashLock, isLockProcessAlive, clearStaleWorkerLock } from "./crash-recovery.js";
11
11
  import { getActiveAutoWorkers } from "./db/auto-workers.js";
12
12
  import { normalizeRealPath } from "./paths.js";
13
13
  import { ensureGitignore, isGsdGitignored } from "./gitignore.js";
@@ -56,7 +56,7 @@ export async function checkRuntimeHealth(
56
56
  });
57
57
 
58
58
  if (shouldFix("stale_crash_lock")) {
59
- clearLock(basePath);
59
+ clearStaleWorkerLock(basePath);
60
60
  fixesApplied.push("cleared stale auto-mode worker state");
61
61
  }
62
62
  }
@@ -80,17 +80,29 @@ export async function checkRuntimeHealth(
80
80
  // heartbeat for this project?" — readCrashLock returns null for
81
81
  // healthy live workers (it surfaces stale ones only), so we must
82
82
  // consult getActiveAutoWorkers directly.
83
- const projectRoot = normalizeRealPath(basePath);
84
- const activeWorkers = getActiveAutoWorkers().filter(
85
- (w) => w.project_root_realpath === projectRoot && isLockProcessAlive({
86
- pid: w.pid,
87
- startedAt: w.started_at,
88
- unitType: "starting",
89
- unitId: "bootstrap",
90
- unitStartedAt: w.started_at,
91
- }),
92
- );
93
- const lockHolderAlive = activeWorkers.length > 0;
83
+ let lockHolderAlive = false;
84
+ try {
85
+ const projectRoot = normalizeRealPath(basePath);
86
+ for (const worker of getActiveAutoWorkers()) {
87
+ if (worker.project_root_realpath !== projectRoot) continue;
88
+ try {
89
+ if (isLockProcessAlive({
90
+ pid: worker.pid,
91
+ startedAt: worker.started_at,
92
+ unitType: "starting",
93
+ unitId: "bootstrap",
94
+ unitStartedAt: worker.started_at,
95
+ })) {
96
+ lockHolderAlive = true;
97
+ break;
98
+ }
99
+ } catch {
100
+ // Ignore malformed worker rows or transient PID probe failures.
101
+ }
102
+ }
103
+ } catch {
104
+ // If worker lookup fails, continue with the stranded lock diagnosis.
105
+ }
94
106
  if (!lockHolderAlive) {
95
107
  issues.push({
96
108
  severity: "error",
@@ -51,6 +51,7 @@ export type DoctorIssueCode =
51
51
  // Git / worktree integrity checks
52
52
  | "integration_branch_missing"
53
53
  | "worktree_directory_orphaned"
54
+ | "worktree_empty_with_project_content"
54
55
  // GSD state structural checks
55
56
  | "circular_slice_dependency"
56
57
  | "orphaned_slice_directory"