gsd-pi 2.82.0-dev.ed17d078d → 3.0.0-dev.1b44e695b

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 (619) 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/detect-stuck.js +1 -1
  11. package/dist/resources/extensions/gsd/auto/infra-errors.js +9 -3
  12. package/dist/resources/extensions/gsd/auto/loop.js +122 -40
  13. package/dist/resources/extensions/gsd/auto/orchestrator.js +15 -4
  14. package/dist/resources/extensions/gsd/auto/phases.js +134 -49
  15. package/dist/resources/extensions/gsd/auto/session.js +6 -0
  16. package/dist/resources/extensions/gsd/auto/unit-runner-events.js +7 -1
  17. package/dist/resources/extensions/gsd/auto/workflow-kernel.js +3 -0
  18. package/dist/resources/extensions/gsd/auto/workflow-memory-pressure.js +12 -0
  19. package/dist/resources/extensions/gsd/auto-budget.js +9 -0
  20. package/dist/resources/extensions/gsd/auto-dashboard.js +66 -1
  21. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +1 -0
  22. package/dist/resources/extensions/gsd/auto-dispatch.js +144 -30
  23. package/dist/resources/extensions/gsd/auto-model-selection.js +2 -0
  24. package/dist/resources/extensions/gsd/auto-post-unit.js +329 -137
  25. package/dist/resources/extensions/gsd/auto-prompts.js +36 -10
  26. package/dist/resources/extensions/gsd/auto-recovery.js +82 -16
  27. package/dist/resources/extensions/gsd/auto-start.js +99 -16
  28. package/dist/resources/extensions/gsd/auto-timers.js +11 -3
  29. package/dist/resources/extensions/gsd/auto-verification.js +146 -34
  30. package/dist/resources/extensions/gsd/auto-worktree.js +185 -26
  31. package/dist/resources/extensions/gsd/auto.js +135 -74
  32. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +65 -10
  33. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +13 -10
  34. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +14 -4
  35. package/dist/resources/extensions/gsd/bootstrap/subagent-input.js +21 -9
  36. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +24 -9
  37. package/dist/resources/extensions/gsd/clean-root-preflight.js +170 -8
  38. package/dist/resources/extensions/gsd/commands/catalog.js +10 -1
  39. package/dist/resources/extensions/gsd/commands/handlers/core.js +38 -0
  40. package/dist/resources/extensions/gsd/commands/handlers/ops.js +20 -0
  41. package/dist/resources/extensions/gsd/commands-bootstrap.js +5 -0
  42. package/dist/resources/extensions/gsd/commands-handlers.js +2 -0
  43. package/dist/resources/extensions/gsd/commands-mcp-status.js +9 -0
  44. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +10 -2
  45. package/dist/resources/extensions/gsd/commands-verdict.js +139 -0
  46. package/dist/resources/extensions/gsd/crash-recovery.js +55 -7
  47. package/dist/resources/extensions/gsd/db/auto-workers.js +30 -0
  48. package/dist/resources/extensions/gsd/db/milestone-leases.js +24 -0
  49. package/dist/resources/extensions/gsd/db/unit-dispatches.js +3 -2
  50. package/dist/resources/extensions/gsd/db-base-schema.js +2 -0
  51. package/dist/resources/extensions/gsd/db-migration-steps.js +4 -0
  52. package/dist/resources/extensions/gsd/db-task-slice-rows.js +2 -0
  53. package/dist/resources/extensions/gsd/dispatch-guard.js +46 -2
  54. package/dist/resources/extensions/gsd/docs/preferences-reference.md +10 -0
  55. package/dist/resources/extensions/gsd/doctor-git-checks.js +46 -1
  56. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +28 -11
  57. package/dist/resources/extensions/gsd/doctor.js +2 -28
  58. package/dist/resources/extensions/gsd/export-html.js +27 -425
  59. package/dist/resources/extensions/gsd/forensics.js +10 -3
  60. package/dist/resources/extensions/gsd/git-service.js +152 -15
  61. package/dist/resources/extensions/gsd/gsd-db.js +76 -33
  62. package/dist/resources/extensions/gsd/guided-flow-queue.js +4 -3
  63. package/dist/resources/extensions/gsd/guided-flow.js +110 -117
  64. package/dist/resources/extensions/gsd/guided-unit-context.js +23 -0
  65. package/dist/resources/extensions/gsd/init-wizard.js +17 -2
  66. package/dist/resources/extensions/gsd/markdown-renderer.js +14 -11
  67. package/dist/resources/extensions/gsd/mcp-filter.js +58 -0
  68. package/dist/resources/extensions/gsd/migrate/parsers.js +121 -2
  69. package/dist/resources/extensions/gsd/migration-auto-check.js +12 -17
  70. package/dist/resources/extensions/gsd/milestone-actions.js +11 -4
  71. package/dist/resources/extensions/gsd/native-git-bridge.js +57 -14
  72. package/dist/resources/extensions/gsd/parallel-orchestrator.js +3 -0
  73. package/dist/resources/extensions/gsd/paths.js +4 -0
  74. package/dist/resources/extensions/gsd/pending-auto-start.js +52 -0
  75. package/dist/resources/extensions/gsd/planning-path-scope.js +9 -3
  76. package/dist/resources/extensions/gsd/post-execution-checks.js +73 -9
  77. package/dist/resources/extensions/gsd/pre-execution-checks.js +54 -19
  78. package/dist/resources/extensions/gsd/preferences-mcp.js +19 -0
  79. package/dist/resources/extensions/gsd/preferences-types.js +3 -0
  80. package/dist/resources/extensions/gsd/preferences-validation.js +147 -0
  81. package/dist/resources/extensions/gsd/preferences.js +6 -0
  82. package/dist/resources/extensions/gsd/prompt-loader.js +1 -1
  83. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  84. package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  85. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
  86. package/dist/resources/extensions/gsd/prompts/discuss.md +9 -9
  87. package/dist/resources/extensions/gsd/prompts/forensics.md +3 -3
  88. package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
  89. package/dist/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
  90. package/dist/resources/extensions/gsd/prompts/plan-slice.md +4 -4
  91. package/dist/resources/extensions/gsd/prompts/queue.md +4 -4
  92. package/dist/resources/extensions/gsd/prompts/reactive-execute.md +1 -1
  93. package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  94. package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  95. package/dist/resources/extensions/gsd/queue-reorder-ui.js +30 -13
  96. package/dist/resources/extensions/gsd/repo-identity.js +39 -22
  97. package/dist/resources/extensions/gsd/repository-registry.js +44 -0
  98. package/dist/resources/extensions/gsd/safety/evidence-collector.js +2 -0
  99. package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +42 -18
  100. package/dist/resources/extensions/gsd/session-lock.js +15 -2
  101. package/dist/resources/extensions/gsd/slice-parallel-conflict.js +2 -2
  102. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +84 -5
  103. package/dist/resources/extensions/gsd/smart-entry-routing.js +36 -0
  104. package/dist/resources/extensions/gsd/state-reconciliation/drift/merge-state.js +6 -1
  105. package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +9 -14
  106. package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +19 -24
  107. package/dist/resources/extensions/gsd/state.js +28 -7
  108. package/dist/resources/extensions/gsd/status-guards.js +14 -2
  109. package/dist/resources/extensions/gsd/templates/PREFERENCES.md +1 -0
  110. package/dist/resources/extensions/gsd/templates/plan.md +9 -5
  111. package/dist/resources/extensions/gsd/templates/task-plan.md +10 -2
  112. package/dist/resources/extensions/gsd/tools/complete-milestone.js +15 -9
  113. package/dist/resources/extensions/gsd/tools/complete-slice.js +56 -10
  114. package/dist/resources/extensions/gsd/tools/exec-tool.js +87 -5
  115. package/dist/resources/extensions/gsd/tools/plan-milestone.js +7 -1
  116. package/dist/resources/extensions/gsd/tools/plan-slice.js +151 -15
  117. package/dist/resources/extensions/gsd/tools/validate-milestone.js +32 -1
  118. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +185 -40
  119. package/dist/resources/extensions/gsd/unit-context-composer.js +2 -0
  120. package/dist/resources/extensions/gsd/unit-context-manifest.js +69 -17
  121. package/dist/resources/extensions/gsd/validation.js +23 -1
  122. package/dist/resources/extensions/gsd/verification-gate.js +142 -7
  123. package/dist/resources/extensions/gsd/verification-verdict.js +26 -0
  124. package/dist/resources/extensions/gsd/workflow-manifest.js +2 -0
  125. package/dist/resources/extensions/gsd/workflow-mcp.js +17 -1
  126. package/dist/resources/extensions/gsd/workflow-projections.js +6 -8
  127. package/dist/resources/extensions/gsd/worktree-lifecycle.js +86 -19
  128. package/dist/resources/extensions/gsd/worktree-manager.js +11 -2
  129. package/dist/resources/extensions/gsd/worktree-safety.js +43 -4
  130. package/dist/resources/extensions/gsd/worktree-state-projection.js +31 -0
  131. package/dist/resources/extensions/gsd/worktree-telemetry.js +32 -0
  132. package/dist/resources/extensions/shared/html-shell.js +388 -0
  133. package/dist/resources/extensions/shared/interview-ui.js +6 -4
  134. package/dist/resources/extensions/shared/next-action-ui.js +13 -5
  135. package/dist/resources/extensions/subagent/index.js +448 -78
  136. package/dist/resources/extensions/subagent/launch.js +77 -0
  137. package/dist/resources/extensions/subagent/run-store.js +148 -0
  138. package/dist/resources/extensions/ttsr/ttsr-manager.js +3 -1
  139. package/dist/resources/extensions/visual-brief/artifact-policy.js +29 -0
  140. package/dist/resources/extensions/visual-brief/extension-manifest.json +8 -0
  141. package/dist/resources/extensions/visual-brief/index.js +5 -0
  142. package/dist/resources/extensions/visual-brief/page-contract.js +124 -0
  143. package/dist/resources/extensions/visual-brief/prompts.js +140 -0
  144. package/dist/resources/skills/forensics/SKILL.md +1 -1
  145. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  146. package/dist/web/standalone/.next/BUILD_ID +1 -1
  147. package/dist/web/standalone/.next/app-path-routes-manifest.json +7 -7
  148. package/dist/web/standalone/.next/build-manifest.json +3 -3
  149. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  150. package/dist/web/standalone/.next/react-loadable-manifest.json +5 -5
  151. package/dist/web/standalone/.next/required-server-files.json +1 -1
  152. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  154. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  155. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  156. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  157. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  158. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  159. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  160. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  161. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  162. package/dist/web/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  163. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  164. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  165. package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -7
  166. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -7
  167. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  168. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -5
  169. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  170. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  171. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -5
  172. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  174. package/dist/web/standalone/.next/server/app/index.html +1 -1
  175. package/dist/web/standalone/.next/server/app/index.rsc +4 -7
  176. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  177. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -7
  178. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  179. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -5
  180. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -5
  181. package/dist/web/standalone/.next/server/app/page.js +2 -2
  182. package/dist/web/standalone/.next/server/app/page.js.nft.json +1 -1
  183. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  184. package/dist/web/standalone/.next/server/app-paths-manifest.json +7 -7
  185. package/dist/web/standalone/.next/server/chunks/4266.js +2 -0
  186. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  187. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  188. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  189. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  190. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  191. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  192. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  193. package/dist/web/standalone/.next/static/chunks/2973.33f26573894b6153.js +2 -0
  194. package/dist/web/standalone/.next/static/chunks/8359.65b24fac92188a6b.js +10 -0
  195. package/dist/web/standalone/.next/static/chunks/9441.ff70bb53f6835771.js +1 -0
  196. package/dist/web/standalone/.next/static/chunks/app/layout-8c10ec293ae0f1d5.js +1 -0
  197. package/dist/web/standalone/.next/static/chunks/{webpack-de742b64187e13fe.js → webpack-855d616060cb6e59.js} +1 -1
  198. package/dist/web/standalone/.next/static/css/746ee28c929d1880.css +1 -0
  199. package/dist/web/standalone/server.js +1 -1
  200. package/package.json +4 -4
  201. package/packages/contracts/dist/rpc.test.js +7 -0
  202. package/packages/contracts/dist/rpc.test.js.map +1 -1
  203. package/packages/contracts/dist/workflow.d.ts +21 -0
  204. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  205. package/packages/contracts/dist/workflow.js +24 -0
  206. package/packages/contracts/dist/workflow.js.map +1 -1
  207. package/packages/contracts/src/rpc.test.ts +8 -0
  208. package/packages/contracts/src/workflow.ts +24 -0
  209. package/packages/daemon/package.json +2 -2
  210. package/packages/mcp-server/README.md +13 -4
  211. package/packages/mcp-server/dist/workflow-tools.d.ts +0 -3
  212. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  213. package/packages/mcp-server/dist/workflow-tools.js +80 -0
  214. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  215. package/packages/mcp-server/package.json +2 -2
  216. package/packages/mcp-server/src/workflow-tools.test.ts +23 -1
  217. package/packages/mcp-server/src/workflow-tools.ts +168 -0
  218. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  219. package/packages/native/package.json +1 -1
  220. package/packages/native/tsconfig.json +2 -1
  221. package/packages/native/tsconfig.tsbuildinfo +1 -1
  222. package/packages/pi-agent-core/package.json +1 -1
  223. package/packages/pi-ai/dist/providers/google-gemini-cli.d.ts.map +1 -1
  224. package/packages/pi-ai/dist/providers/google-gemini-cli.js +5 -0
  225. package/packages/pi-ai/dist/providers/google-gemini-cli.js.map +1 -1
  226. package/packages/pi-ai/dist/providers/google-gemini-cli.test.d.ts +2 -0
  227. package/packages/pi-ai/dist/providers/google-gemini-cli.test.d.ts.map +1 -0
  228. package/packages/pi-ai/dist/providers/google-gemini-cli.test.js +41 -0
  229. package/packages/pi-ai/dist/providers/google-gemini-cli.test.js.map +1 -0
  230. package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
  231. package/packages/pi-ai/dist/providers/openai-codex-responses.js +82 -1
  232. package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
  233. package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts +2 -0
  234. package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts.map +1 -0
  235. package/packages/pi-ai/dist/providers/openai-codex-responses.test.js +52 -0
  236. package/packages/pi-ai/dist/providers/openai-codex-responses.test.js.map +1 -0
  237. package/packages/pi-ai/dist/providers/simple-options.d.ts +2 -4
  238. package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
  239. package/packages/pi-ai/dist/providers/simple-options.js +5 -6
  240. package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
  241. package/packages/pi-ai/dist/providers/simple-options.test.d.ts +2 -0
  242. package/packages/pi-ai/dist/providers/simple-options.test.d.ts.map +1 -0
  243. package/packages/pi-ai/dist/providers/simple-options.test.js +50 -0
  244. package/packages/pi-ai/dist/providers/simple-options.test.js.map +1 -0
  245. package/packages/pi-ai/package.json +1 -1
  246. package/packages/pi-ai/src/providers/google-gemini-cli.test.ts +49 -0
  247. package/packages/pi-ai/src/providers/google-gemini-cli.ts +7 -0
  248. package/packages/pi-ai/src/providers/openai-codex-responses.test.ts +63 -0
  249. package/packages/pi-ai/src/providers/openai-codex-responses.ts +91 -1
  250. package/packages/pi-ai/src/providers/simple-options.test.ts +60 -0
  251. package/packages/pi-ai/src/providers/simple-options.ts +5 -6
  252. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  253. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts +2 -0
  254. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts.map +1 -0
  255. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js +66 -0
  256. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js.map +1 -0
  257. package/packages/pi-coding-agent/dist/core/agent-session.js +1 -1
  258. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  259. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +44 -3
  260. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  261. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +6 -1
  262. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  263. package/packages/pi-coding-agent/dist/core/compaction/compaction.js +7 -2
  264. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  265. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js +14 -1
  266. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js.map +1 -1
  267. package/packages/pi-coding-agent/dist/core/sdk.js +1 -1
  268. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  269. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +8 -2
  270. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
  271. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  272. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +24 -6
  273. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  274. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +1 -1
  275. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  276. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  277. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +82 -97
  278. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  279. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +7 -7
  280. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  281. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +11 -0
  282. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
  283. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js +25 -1
  284. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js.map +1 -1
  285. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +2 -0
  286. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  287. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +24 -10
  288. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  289. package/packages/pi-coding-agent/package.json +1 -1
  290. package/packages/pi-coding-agent/src/core/agent-session-thinking-level.test.ts +79 -0
  291. package/packages/pi-coding-agent/src/core/agent-session.ts +1 -1
  292. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +53 -3
  293. package/packages/pi-coding-agent/src/core/compaction/compaction.test.ts +23 -1
  294. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +7 -2
  295. package/packages/pi-coding-agent/src/core/sdk.ts +1 -1
  296. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +17 -1
  297. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +23 -7
  298. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +1 -1
  299. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +91 -102
  300. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +15 -1
  301. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +9 -9
  302. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-ordering.test.ts +30 -1
  303. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +29 -10
  304. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  305. package/packages/pi-tui/dist/__tests__/terminal.test.d.ts +2 -0
  306. package/packages/pi-tui/dist/__tests__/terminal.test.d.ts.map +1 -0
  307. package/packages/pi-tui/dist/__tests__/terminal.test.js +103 -0
  308. package/packages/pi-tui/dist/__tests__/terminal.test.js.map +1 -0
  309. package/packages/pi-tui/dist/__tests__/tui.test.js +45 -2
  310. package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
  311. package/packages/pi-tui/dist/terminal.d.ts +2 -0
  312. package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
  313. package/packages/pi-tui/dist/terminal.js +12 -0
  314. package/packages/pi-tui/dist/terminal.js.map +1 -1
  315. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  316. package/packages/pi-tui/dist/tui.js +106 -27
  317. package/packages/pi-tui/dist/tui.js.map +1 -1
  318. package/packages/pi-tui/package.json +1 -1
  319. package/packages/pi-tui/src/__tests__/terminal.test.ts +121 -0
  320. package/packages/pi-tui/src/__tests__/tui.test.ts +59 -2
  321. package/packages/pi-tui/src/terminal.ts +11 -0
  322. package/packages/pi-tui/src/tui.ts +108 -27
  323. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  324. package/packages/rpc-client/package.json +1 -1
  325. package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
  326. package/pkg/package.json +1 -1
  327. package/src/resources/GSD-WORKFLOW.md +10 -1
  328. package/src/resources/extensions/claude-code-cli/partial-builder.ts +2 -1
  329. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +52 -6
  330. package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +19 -2
  331. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +49 -2
  332. package/src/resources/extensions/cmux/index.ts +6 -0
  333. package/src/resources/extensions/gsd/auto/contracts.ts +19 -6
  334. package/src/resources/extensions/gsd/auto/detect-stuck.ts +1 -0
  335. package/src/resources/extensions/gsd/auto/infra-errors.ts +9 -3
  336. package/src/resources/extensions/gsd/auto/loop.ts +123 -40
  337. package/src/resources/extensions/gsd/auto/orchestrator.ts +15 -4
  338. package/src/resources/extensions/gsd/auto/phases.ts +160 -60
  339. package/src/resources/extensions/gsd/auto/session.ts +16 -0
  340. package/src/resources/extensions/gsd/auto/types.ts +3 -0
  341. package/src/resources/extensions/gsd/auto/unit-runner-events.ts +6 -2
  342. package/src/resources/extensions/gsd/auto/workflow-kernel.ts +5 -1
  343. package/src/resources/extensions/gsd/auto/workflow-memory-pressure.ts +13 -0
  344. package/src/resources/extensions/gsd/auto-budget.ts +11 -0
  345. package/src/resources/extensions/gsd/auto-dashboard.ts +72 -1
  346. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +1 -0
  347. package/src/resources/extensions/gsd/auto-dispatch.ts +164 -29
  348. package/src/resources/extensions/gsd/auto-model-selection.ts +2 -1
  349. package/src/resources/extensions/gsd/auto-post-unit.ts +369 -148
  350. package/src/resources/extensions/gsd/auto-prompts.ts +36 -13
  351. package/src/resources/extensions/gsd/auto-recovery.ts +86 -13
  352. package/src/resources/extensions/gsd/auto-start.ts +109 -14
  353. package/src/resources/extensions/gsd/auto-timers.ts +10 -3
  354. package/src/resources/extensions/gsd/auto-verification.ts +174 -42
  355. package/src/resources/extensions/gsd/auto-worktree.ts +202 -30
  356. package/src/resources/extensions/gsd/auto.ts +172 -81
  357. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +66 -10
  358. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +13 -10
  359. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +13 -4
  360. package/src/resources/extensions/gsd/bootstrap/subagent-input.ts +19 -7
  361. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +27 -10
  362. package/src/resources/extensions/gsd/clean-root-preflight.ts +174 -8
  363. package/src/resources/extensions/gsd/commands/catalog.ts +10 -1
  364. package/src/resources/extensions/gsd/commands/handlers/core.ts +41 -0
  365. package/src/resources/extensions/gsd/commands/handlers/ops.ts +21 -0
  366. package/src/resources/extensions/gsd/commands-bootstrap.ts +10 -0
  367. package/src/resources/extensions/gsd/commands-handlers.ts +2 -0
  368. package/src/resources/extensions/gsd/commands-mcp-status.ts +8 -0
  369. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +11 -3
  370. package/src/resources/extensions/gsd/commands-verdict.ts +202 -0
  371. package/src/resources/extensions/gsd/crash-recovery.ts +55 -6
  372. package/src/resources/extensions/gsd/db/auto-workers.ts +37 -0
  373. package/src/resources/extensions/gsd/db/milestone-leases.ts +26 -0
  374. package/src/resources/extensions/gsd/db/unit-dispatches.ts +4 -3
  375. package/src/resources/extensions/gsd/db-base-schema.ts +2 -0
  376. package/src/resources/extensions/gsd/db-migration-steps.ts +5 -0
  377. package/src/resources/extensions/gsd/db-task-slice-rows.ts +4 -0
  378. package/src/resources/extensions/gsd/dispatch-guard.ts +60 -2
  379. package/src/resources/extensions/gsd/docs/preferences-reference.md +10 -0
  380. package/src/resources/extensions/gsd/doctor-git-checks.ts +45 -1
  381. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +25 -13
  382. package/src/resources/extensions/gsd/doctor-types.ts +1 -0
  383. package/src/resources/extensions/gsd/doctor.ts +2 -27
  384. package/src/resources/extensions/gsd/export-html.ts +27 -427
  385. package/src/resources/extensions/gsd/forensics.ts +9 -3
  386. package/src/resources/extensions/gsd/git-service.ts +182 -16
  387. package/src/resources/extensions/gsd/gsd-db.ts +80 -31
  388. package/src/resources/extensions/gsd/guided-flow-queue.ts +4 -3
  389. package/src/resources/extensions/gsd/guided-flow.ts +142 -134
  390. package/src/resources/extensions/gsd/guided-unit-context.ts +30 -0
  391. package/src/resources/extensions/gsd/init-wizard.ts +17 -2
  392. package/src/resources/extensions/gsd/journal.ts +8 -1
  393. package/src/resources/extensions/gsd/markdown-renderer.ts +14 -11
  394. package/src/resources/extensions/gsd/mcp-filter.ts +80 -0
  395. package/src/resources/extensions/gsd/migrate/parsers.ts +139 -2
  396. package/src/resources/extensions/gsd/migration-auto-check.ts +15 -23
  397. package/src/resources/extensions/gsd/milestone-actions.ts +10 -4
  398. package/src/resources/extensions/gsd/native-git-bridge.ts +63 -14
  399. package/src/resources/extensions/gsd/parallel-orchestrator.ts +3 -0
  400. package/src/resources/extensions/gsd/paths.ts +5 -0
  401. package/src/resources/extensions/gsd/pending-auto-start.ts +79 -0
  402. package/src/resources/extensions/gsd/planning-path-scope.ts +10 -2
  403. package/src/resources/extensions/gsd/post-execution-checks.ts +87 -12
  404. package/src/resources/extensions/gsd/pre-execution-checks.ts +67 -19
  405. package/src/resources/extensions/gsd/preferences-mcp.ts +27 -0
  406. package/src/resources/extensions/gsd/preferences-types.ts +35 -0
  407. package/src/resources/extensions/gsd/preferences-validation.ts +154 -0
  408. package/src/resources/extensions/gsd/preferences.ts +9 -0
  409. package/src/resources/extensions/gsd/prompt-loader.ts +1 -1
  410. package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  411. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  412. package/src/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
  413. package/src/resources/extensions/gsd/prompts/discuss.md +9 -9
  414. package/src/resources/extensions/gsd/prompts/forensics.md +3 -3
  415. package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
  416. package/src/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
  417. package/src/resources/extensions/gsd/prompts/plan-slice.md +4 -4
  418. package/src/resources/extensions/gsd/prompts/queue.md +4 -4
  419. package/src/resources/extensions/gsd/prompts/reactive-execute.md +1 -1
  420. package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  421. package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  422. package/src/resources/extensions/gsd/queue-reorder-ui.ts +31 -13
  423. package/src/resources/extensions/gsd/repo-identity.ts +45 -25
  424. package/src/resources/extensions/gsd/repository-registry.ts +77 -0
  425. package/src/resources/extensions/gsd/safety/evidence-collector.ts +2 -0
  426. package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +54 -19
  427. package/src/resources/extensions/gsd/session-lock.ts +15 -2
  428. package/src/resources/extensions/gsd/slice-parallel-conflict.ts +2 -2
  429. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +75 -3
  430. package/src/resources/extensions/gsd/smart-entry-routing.ts +77 -0
  431. package/src/resources/extensions/gsd/state-reconciliation/drift/merge-state.ts +8 -1
  432. package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +12 -15
  433. package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +17 -25
  434. package/src/resources/extensions/gsd/state.ts +33 -7
  435. package/src/resources/extensions/gsd/status-guards.ts +16 -2
  436. package/src/resources/extensions/gsd/templates/PREFERENCES.md +1 -0
  437. package/src/resources/extensions/gsd/templates/plan.md +9 -5
  438. package/src/resources/extensions/gsd/templates/task-plan.md +10 -2
  439. package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +1 -1
  440. package/src/resources/extensions/gsd/tests/auto-abort-pause-regression.test.ts +10 -1
  441. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +71 -0
  442. package/src/resources/extensions/gsd/tests/auto-deterministic-error-classification-4973.test.ts +116 -0
  443. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +775 -34
  444. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +245 -28
  445. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +151 -12
  446. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +53 -2
  447. package/src/resources/extensions/gsd/tests/auto-post-unit-step-message.test.ts +18 -6
  448. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +136 -13
  449. package/src/resources/extensions/gsd/tests/auto-remote-session-lock-cleanup.test.ts +64 -0
  450. package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +12 -0
  451. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +1 -0
  452. package/src/resources/extensions/gsd/tests/auto-stop-notification.test.ts +20 -0
  453. package/src/resources/extensions/gsd/tests/auto-workers.test.ts +29 -0
  454. package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +69 -1
  455. package/src/resources/extensions/gsd/tests/autocomplete-regressions-1675.test.ts +21 -0
  456. package/src/resources/extensions/gsd/tests/brief-command.test.ts +89 -0
  457. package/src/resources/extensions/gsd/tests/checkout-branch-stash-guard.test.ts +87 -0
  458. package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +107 -2
  459. package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +32 -4
  460. package/src/resources/extensions/gsd/tests/closeout-git-deferral.test.ts +16 -0
  461. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +378 -0
  462. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +55 -2
  463. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +60 -9
  464. package/src/resources/extensions/gsd/tests/complete-task.test.ts +3 -1
  465. package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +104 -2
  466. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +2 -0
  467. package/src/resources/extensions/gsd/tests/db-authority-regression.test.ts +208 -0
  468. package/src/resources/extensions/gsd/tests/db-task-slice-rows.test.ts +1 -0
  469. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +61 -2
  470. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +111 -1
  471. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +68 -1
  472. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +140 -1
  473. package/src/resources/extensions/gsd/tests/doctor-empty-worktree.test.ts +65 -0
  474. package/src/resources/extensions/gsd/tests/doctor-forensics-db-open-regression.test.ts +50 -0
  475. package/src/resources/extensions/gsd/tests/evidence-cross-ref.test.ts +97 -0
  476. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +99 -1
  477. package/src/resources/extensions/gsd/tests/execution-entry-missing-context-4671.test.ts +15 -1
  478. package/src/resources/extensions/gsd/tests/export-html-enhancements.test.ts +8 -0
  479. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +28 -0
  480. package/src/resources/extensions/gsd/tests/gsdroot-worktree-detection.test.ts +5 -2
  481. package/src/resources/extensions/gsd/tests/guided-discuss-project-prompt-rendering.test.ts +2 -0
  482. package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +106 -0
  483. package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +59 -11
  484. package/src/resources/extensions/gsd/tests/guided-flow.test.ts +21 -0
  485. package/src/resources/extensions/gsd/tests/guided-tool-contract.test.ts +65 -0
  486. package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +7 -7
  487. package/src/resources/extensions/gsd/tests/hook-model-resolution.test.ts +5 -0
  488. package/src/resources/extensions/gsd/tests/infra-error.test.ts +2 -2
  489. package/src/resources/extensions/gsd/tests/infra-errors-cooldown.test.ts +9 -0
  490. package/src/resources/extensions/gsd/tests/init-prefs-routing.test.ts +22 -0
  491. package/src/resources/extensions/gsd/tests/integration/doctor-runtime.test.ts +20 -0
  492. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +226 -2
  493. package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +5 -21
  494. package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +15 -0
  495. package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +6 -1
  496. package/src/resources/extensions/gsd/tests/interrupted-session-auto.test.ts +40 -0
  497. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +49 -3
  498. package/src/resources/extensions/gsd/tests/journal.test.ts +32 -0
  499. package/src/resources/extensions/gsd/tests/mcp-filter.test.ts +287 -0
  500. package/src/resources/extensions/gsd/tests/mcp-status.test.ts +11 -0
  501. package/src/resources/extensions/gsd/tests/merge-db-cycle.test.ts +179 -0
  502. package/src/resources/extensions/gsd/tests/merge-self-branch-guard.test.ts +21 -40
  503. package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +59 -1
  504. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +26 -18
  505. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +80 -2
  506. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +121 -1
  507. package/src/resources/extensions/gsd/tests/parallel-orchestrator-zombie-cleanup.test.ts +55 -0
  508. package/src/resources/extensions/gsd/tests/park-db-sync.test.ts +55 -1
  509. package/src/resources/extensions/gsd/tests/pending-autostart-scope.test.ts +29 -5
  510. package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +2 -1
  511. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +26 -0
  512. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +2 -0
  513. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +343 -3
  514. package/src/resources/extensions/gsd/tests/plan-task.test.ts +18 -1
  515. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +79 -1
  516. package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +105 -3
  517. package/src/resources/extensions/gsd/tests/post-unit-git-failure.test.ts +8 -1
  518. package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +84 -0
  519. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +147 -0
  520. package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +54 -0
  521. package/src/resources/extensions/gsd/tests/preferences-mcp.test.ts +128 -0
  522. package/src/resources/extensions/gsd/tests/preferences.test.ts +75 -0
  523. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +79 -0
  524. package/src/resources/extensions/gsd/tests/progressive-planning.test.ts +42 -1
  525. package/src/resources/extensions/gsd/tests/prompt-loader.test.ts +23 -0
  526. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +37 -1
  527. package/src/resources/extensions/gsd/tests/quality-gates.test.ts +6 -0
  528. package/src/resources/extensions/gsd/tests/queue-reorder-ui.test.ts +54 -0
  529. package/src/resources/extensions/gsd/tests/remediation-completion-guard.test.ts +89 -2
  530. package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +28 -1
  531. package/src/resources/extensions/gsd/tests/repository-registry.test.ts +52 -0
  532. package/src/resources/extensions/gsd/tests/run-uat-replay-cap.test.ts +2 -3
  533. package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +35 -0
  534. package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +59 -1
  535. package/src/resources/extensions/gsd/tests/slice-parallel-conflict.test.ts +2 -2
  536. package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +112 -1
  537. package/src/resources/extensions/gsd/tests/smart-entry-routing.test.ts +113 -0
  538. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +94 -2
  539. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +6 -0
  540. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +119 -23
  541. package/src/resources/extensions/gsd/tests/status-guards.test.ts +17 -1
  542. package/src/resources/extensions/gsd/tests/stuck-state-via-db.test.ts +64 -1
  543. package/src/resources/extensions/gsd/tests/subagent-model-dispatch.test.ts +2 -1
  544. package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +7 -3
  545. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +1 -0
  546. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +131 -9
  547. package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +111 -1
  548. package/src/resources/extensions/gsd/tests/validate-milestone-stuck-guard.test.ts +29 -2
  549. package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +68 -0
  550. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +42 -1
  551. package/src/resources/extensions/gsd/tests/verification-gate.test.ts +188 -1
  552. package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +78 -0
  553. package/src/resources/extensions/gsd/tests/workflow-kernel.test.ts +7 -0
  554. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +19 -1
  555. package/src/resources/extensions/gsd/tests/workflow-memory-pressure.test.ts +21 -1
  556. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +153 -1
  557. package/src/resources/extensions/gsd/tests/worktree-git-pathspec.test.ts +39 -0
  558. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +64 -12
  559. package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +73 -2
  560. package/src/resources/extensions/gsd/tests/worktree-preferences-sync.test.ts +25 -0
  561. package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +90 -0
  562. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +95 -0
  563. package/src/resources/extensions/gsd/tests/worktree-telemetry.test.ts +16 -0
  564. package/src/resources/extensions/gsd/tests/worktree-write-gate.test.ts +27 -0
  565. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +59 -0
  566. package/src/resources/extensions/gsd/tools/complete-milestone.ts +18 -10
  567. package/src/resources/extensions/gsd/tools/complete-slice.ts +57 -10
  568. package/src/resources/extensions/gsd/tools/exec-tool.ts +98 -5
  569. package/src/resources/extensions/gsd/tools/plan-milestone.ts +5 -1
  570. package/src/resources/extensions/gsd/tools/plan-slice.ts +172 -12
  571. package/src/resources/extensions/gsd/tools/validate-milestone.ts +31 -0
  572. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +166 -17
  573. package/src/resources/extensions/gsd/types.ts +1 -1
  574. package/src/resources/extensions/gsd/unit-context-composer.ts +3 -0
  575. package/src/resources/extensions/gsd/unit-context-manifest.ts +86 -19
  576. package/src/resources/extensions/gsd/validation.ts +23 -1
  577. package/src/resources/extensions/gsd/verification-gate.ts +170 -6
  578. package/src/resources/extensions/gsd/verification-verdict.ts +47 -0
  579. package/src/resources/extensions/gsd/workflow-manifest.ts +2 -0
  580. package/src/resources/extensions/gsd/workflow-mcp.ts +18 -1
  581. package/src/resources/extensions/gsd/workflow-projections.ts +6 -8
  582. package/src/resources/extensions/gsd/worktree-lifecycle.ts +98 -20
  583. package/src/resources/extensions/gsd/worktree-manager.ts +14 -2
  584. package/src/resources/extensions/gsd/worktree-safety.ts +57 -10
  585. package/src/resources/extensions/gsd/worktree-state-projection.ts +43 -0
  586. package/src/resources/extensions/gsd/worktree-telemetry.ts +39 -0
  587. package/src/resources/extensions/shared/html-shell.ts +412 -0
  588. package/src/resources/extensions/shared/interview-ui.ts +6 -4
  589. package/src/resources/extensions/shared/next-action-ui.ts +11 -5
  590. package/src/resources/extensions/shared/tests/interview-notes-loop.test.ts +15 -0
  591. package/src/resources/extensions/shared/tests/next-action-ui-hasui.test.ts +32 -0
  592. package/src/resources/extensions/subagent/index.ts +567 -103
  593. package/src/resources/extensions/subagent/launch.ts +131 -0
  594. package/src/resources/extensions/subagent/run-store.ts +218 -0
  595. package/src/resources/extensions/subagent/tests/launch.test.ts +115 -0
  596. package/src/resources/extensions/subagent/tests/run-store.test.ts +111 -0
  597. package/src/resources/extensions/ttsr/ttsr-manager.ts +5 -1
  598. package/src/resources/extensions/visual-brief/artifact-policy.ts +41 -0
  599. package/src/resources/extensions/visual-brief/extension-manifest.json +8 -0
  600. package/src/resources/extensions/visual-brief/index.ts +8 -0
  601. package/src/resources/extensions/visual-brief/page-contract.ts +136 -0
  602. package/src/resources/extensions/visual-brief/prompts.ts +183 -0
  603. package/src/resources/extensions/visual-brief/tests/visual-brief.test.ts +212 -0
  604. package/src/resources/skills/forensics/SKILL.md +1 -1
  605. package/dist/web/standalone/.next/server/chunks/5822.js +0 -2
  606. package/dist/web/standalone/.next/static/chunks/2556.0527fea66e123b7f.js +0 -1
  607. package/dist/web/standalone/.next/static/chunks/8359.e059d86b255fce1c.js +0 -10
  608. package/dist/web/standalone/.next/static/chunks/9441.1081da1125d1764f.js +0 -1
  609. package/dist/web/standalone/.next/static/chunks/app/layout-a16c7a7ecdf0c2cf.js +0 -1
  610. package/dist/web/standalone/.next/static/css/54ec2745c1da488b.css +0 -1
  611. package/dist/web/standalone/.next/static/css/de70bee13400563f.css +0 -1
  612. package/dist/web/standalone/.next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
  613. package/dist/web/standalone/.next/static/media/747892c23ea88013-s.woff2 +0 -0
  614. package/dist/web/standalone/.next/static/media/8d697b304b401681-s.woff2 +0 -0
  615. package/dist/web/standalone/.next/static/media/93f479601ee12b01-s.p.woff2 +0 -0
  616. package/dist/web/standalone/.next/static/media/9610d9e46709d722-s.woff2 +0 -0
  617. package/dist/web/standalone/.next/static/media/ba015fad6dcf6784-s.woff2 +0 -0
  618. /package/dist/web/standalone/.next/static/{YEvjuT-fsFfYQhDSWtueS → Z8H5evS-hDo0qdP22XJPA}/_buildManifest.js +0 -0
  619. /package/dist/web/standalone/.next/static/{YEvjuT-fsFfYQhDSWtueS → Z8H5evS-hDo0qdP22XJPA}/_ssgManifest.js +0 -0
@@ -427,22 +427,38 @@ function hasProjectState(externalPath: string): boolean {
427
427
  *
428
428
  * Returns the resolved external path (may differ from the computed identity).
429
429
  */
430
- function resolveExternalPathWithRecovery(projectPath: string): string {
431
- const computedPath = externalGsdRoot(projectPath);
430
+ function resolveExternalPathWithRecovery(projectPath: string): { path: string; identity: string } {
431
+ const base = process.env.GSD_STATE_DIR || gsdHome();
432
432
  const computedId = repoIdentity(projectPath);
433
+ const computedPath = join(base, "projects", computedId);
434
+ const computedHasState = hasProjectState(computedPath);
435
+ const markerId = readGsdIdMarker(projectPath);
436
+ const markerPath = markerId ? join(base, "projects", markerId) : null;
437
+ const markerHasState = markerPath ? hasProjectState(markerPath) : false;
438
+
439
+ // Split-brain guard: when marker and computed identities disagree and both
440
+ // directories contain state, prefer the marker-backed directory. This keeps
441
+ // all writers anchored to a single canonical project identity even if a
442
+ // transient identity computation produced a stale computed hash.
443
+ if (
444
+ markerId
445
+ && markerPath
446
+ && markerId !== computedId
447
+ && markerHasState
448
+ && computedHasState
449
+ ) {
450
+ return { path: markerPath, identity: markerId };
451
+ }
433
452
 
434
453
  // Check if computed path already has state — fast path, no recovery needed.
435
- if (hasProjectState(computedPath)) {
436
- return computedPath;
454
+ if (computedHasState) {
455
+ return { path: computedPath, identity: computedId };
437
456
  }
438
457
 
439
458
  // Check for .gsd-id marker from a previous location.
440
- const markerId = readGsdIdMarker(projectPath);
441
- if (markerId && markerId !== computedId) {
459
+ if (markerId && markerPath && markerId !== computedId) {
442
460
  // The marker points to a different identity — the repo was likely moved.
443
- const base = process.env.GSD_STATE_DIR || gsdHome();
444
- const markerPath = join(base, "projects", markerId);
445
- if (hasProjectState(markerPath)) {
461
+ if (markerHasState) {
446
462
  // Recover: use the old state directory and update the marker to the new identity.
447
463
  // Move the state from the old hash dir to the new one so future lookups work
448
464
  // without the marker.
@@ -465,12 +481,12 @@ function resolveExternalPathWithRecovery(projectPath: string): string {
465
481
  try { rmSync(markerPath, { recursive: true, force: true }); } catch { /* non-fatal */ }
466
482
  } catch {
467
483
  // If migration fails, just point at the old directory.
468
- return markerPath;
484
+ return { path: markerPath, identity: markerId };
469
485
  }
470
486
  }
471
487
  }
472
488
 
473
- return computedPath;
489
+ return { path: computedPath, identity: computedId };
474
490
  }
475
491
 
476
492
  // ─── Symlink Management ─────────────────────────────────────────────────────
@@ -489,20 +505,21 @@ function resolveExternalPathWithRecovery(projectPath: string): string {
489
505
  * Returns the resolved external path.
490
506
  */
491
507
  export function ensureGsdSymlink(projectPath: string): string {
492
- const result = ensureGsdSymlinkCore(projectPath);
508
+ const { path: result, identity } = ensureGsdSymlinkCore(projectPath);
493
509
 
494
510
  // Write .gsd-id marker so future relocations can recover this state (#2750).
495
511
  // Only write for the project root (not subdirectories or worktrees that
496
512
  // delegate to a parent .gsd).
497
513
  if (!isInsideWorktree(projectPath)) {
498
- writeGsdIdMarker(projectPath, repoIdentity(projectPath));
514
+ writeGsdIdMarker(projectPath, identity);
499
515
  }
500
516
 
501
517
  return result;
502
518
  }
503
519
 
504
- function ensureGsdSymlinkCore(projectPath: string): string {
505
- const externalPath = resolveExternalPathWithRecovery(projectPath);
520
+ function ensureGsdSymlinkCore(projectPath: string): { path: string; identity: string } {
521
+ const resolved = resolveExternalPathWithRecovery(projectPath);
522
+ const externalPath = resolved.path;
506
523
  const localGsd = join(projectPath, ".gsd");
507
524
  const inWorktree = isInsideWorktree(projectPath);
508
525
 
@@ -519,7 +536,7 @@ function ensureGsdSymlinkCore(projectPath: string): string {
519
536
  const localGsdNormalized = normalizeForGuard(localGsd);
520
537
  const gsdHomeNorm = normalizeForGuard(gsdHome());
521
538
  if (localGsdNormalized === gsdHomeNorm) {
522
- return localGsd;
539
+ return { path: localGsd, identity: resolved.identity };
523
540
  }
524
541
 
525
542
  // Guard: If projectPath is a plain subdirectory (not a worktree) of a git
@@ -538,7 +555,10 @@ function ensureGsdSymlinkCore(projectPath: string): string {
538
555
  try {
539
556
  const rootStat = lstatSync(rootGsd);
540
557
  if (rootStat.isSymbolicLink() || rootStat.isDirectory()) {
541
- return rootStat.isSymbolicLink() ? realpathSync(rootGsd) : rootGsd;
558
+ return {
559
+ path: rootStat.isSymbolicLink() ? realpathSync(rootGsd) : rootGsd,
560
+ identity: resolved.identity,
561
+ };
542
562
  }
543
563
  } catch {
544
564
  // Fall through to normal logic if we can't stat root .gsd
@@ -560,12 +580,12 @@ function ensureGsdSymlinkCore(projectPath: string): string {
560
580
  // Write repo metadata once so cleanup commands can identify this directory later.
561
581
  writeRepoMeta(externalPath, getRemoteUrl(projectPath), resolveGitRoot(projectPath));
562
582
 
563
- const replaceWithSymlink = (): string => {
583
+ const replaceWithSymlink = (): { path: string; identity: string } => {
564
584
  rmSync(localGsd, { recursive: true, force: true });
565
585
  // Defensive: remove any residual entry (e.g. dangling symlink) before creating.
566
586
  try { unlinkSync(localGsd); } catch { /* already gone */ }
567
587
  symlinkSync(externalPath, localGsd, "junction");
568
- return externalPath;
588
+ return resolved;
569
589
  };
570
590
 
571
591
  // Check for dangling symlinks (e.g. after relocation recovery removed the old
@@ -585,7 +605,7 @@ function ensureGsdSymlinkCore(projectPath: string): string {
585
605
  // Defensive: remove any residual entry to avoid EEXIST race (#2750).
586
606
  try { unlinkSync(localGsd); } catch { /* nothing to remove */ }
587
607
  symlinkSync(externalPath, localGsd, "junction");
588
- return externalPath;
608
+ return resolved;
589
609
  }
590
610
 
591
611
  try {
@@ -595,7 +615,7 @@ function ensureGsdSymlinkCore(projectPath: string): string {
595
615
  // Already a symlink — verify it points to the right place
596
616
  const target = realpathSync(localGsd);
597
617
  if (target === externalPath) {
598
- return externalPath; // correct symlink, no-op
618
+ return resolved; // correct symlink, no-op
599
619
  }
600
620
  // In a worktree, mismatched symlinks are always stale. Heal them so
601
621
  // the worktree points at the same external state dir as the main repo.
@@ -620,11 +640,11 @@ function ensureGsdSymlinkCore(projectPath: string): string {
620
640
  return replaceWithSymlink();
621
641
  } catch {
622
642
  // Migration failed — preserve old symlink
623
- return target;
643
+ return { path: target, identity: resolved.identity };
624
644
  }
625
645
  }
626
646
  // Outside worktrees, preserve custom overrides or legacy symlinks.
627
- return target;
647
+ return { path: target, identity: resolved.identity };
628
648
  }
629
649
 
630
650
  if (stat.isDirectory()) {
@@ -632,13 +652,13 @@ function ensureGsdSymlinkCore(projectPath: string): string {
632
652
  // In worktrees, keep the directory in place and let syncGsdStateToWorktree
633
653
  // refresh its contents. Replacing a git-tracked .gsd directory with a
634
654
  // symlink makes git think tracked planning files were deleted.
635
- return localGsd;
655
+ return { path: localGsd, identity: resolved.identity };
636
656
  }
637
657
  } catch {
638
658
  // lstat failed — path exists but we can't stat it
639
659
  }
640
660
 
641
- return localGsd;
661
+ return { path: localGsd, identity: resolved.identity };
642
662
  }
643
663
 
644
664
  // ─── Worktree Detection ─────────────────────────────────────────────────────
@@ -0,0 +1,77 @@
1
+ // GSD-2 + Repository registry seam for parent workspace multi-repo resolution.
2
+
3
+ import { isAbsolute, relative, resolve } from "node:path";
4
+ import type { GSDPreferences, WorkspacePreferences, WorkspaceRepositoryPreference } from "./preferences-types.js";
5
+ import { resolveGsdPathContract } from "./paths.js";
6
+
7
+ export interface RegisteredRepository {
8
+ id: string;
9
+ root: string;
10
+ role?: string;
11
+ verification?: string[];
12
+ commitPolicy?: "auto" | "skip";
13
+ }
14
+
15
+ export interface RepositoryRegistry {
16
+ projectRoot: string;
17
+ mode: "project" | "parent";
18
+ repositories: RegisteredRepository[];
19
+ byId: ReadonlyMap<string, RegisteredRepository>;
20
+ }
21
+
22
+ function assertInsideProjectRoot(projectRoot: string, candidateRoot: string, repoId: string): void {
23
+ const rel = relative(projectRoot, candidateRoot);
24
+ if (rel === "") return;
25
+ if (rel.startsWith("..") || isAbsolute(rel)) {
26
+ throw new Error(`workspace.repositories.${repoId}.path resolves outside project root: ${candidateRoot}`);
27
+ }
28
+ }
29
+
30
+ function resolveRepositoryRoot(
31
+ projectRoot: string,
32
+ repoId: string,
33
+ repo: WorkspaceRepositoryPreference,
34
+ ): RegisteredRepository {
35
+ const root = resolve(projectRoot, repo.path);
36
+ assertInsideProjectRoot(projectRoot, root, repoId);
37
+ return {
38
+ id: repoId,
39
+ root,
40
+ role: repo.role,
41
+ verification: repo.verification,
42
+ commitPolicy: repo.commit_policy,
43
+ };
44
+ }
45
+
46
+ export function createRepositoryRegistry(
47
+ basePath: string,
48
+ workspacePrefs?: WorkspacePreferences,
49
+ ): RepositoryRegistry {
50
+ const contract = resolveGsdPathContract(basePath);
51
+ const projectRoot = contract.projectRoot;
52
+ const mode = workspacePrefs?.mode ?? "project";
53
+ const repoMap = new Map<string, RegisteredRepository>();
54
+
55
+ // Backward-compatible default for single-repo projects.
56
+ // Explicit workspacePrefs?.repositories entries can override "project"
57
+ // via resolveRepositoryRoot to customize role/verification/commit policy.
58
+ repoMap.set("project", { id: "project", root: projectRoot });
59
+
60
+ for (const [repoId, repoConfig] of Object.entries(workspacePrefs?.repositories ?? {})) {
61
+ repoMap.set(repoId, resolveRepositoryRoot(projectRoot, repoId, repoConfig));
62
+ }
63
+
64
+ return {
65
+ projectRoot,
66
+ mode,
67
+ repositories: Array.from(repoMap.values()),
68
+ byId: repoMap,
69
+ };
70
+ }
71
+
72
+ export function createRepositoryRegistryFromPreferences(
73
+ basePath: string,
74
+ preferences?: Pick<GSDPreferences, "workspace">,
75
+ ): RepositoryRegistry {
76
+ return createRepositoryRegistry(basePath, preferences?.workspace);
77
+ }
@@ -53,6 +53,8 @@ export type EvidenceEntry = BashEvidence | FileWriteEvidence | FileEditEvidence;
53
53
  const EXECUTION_TOOL_NAMES = new Set([
54
54
  "bash",
55
55
  "Bash",
56
+ "PowerShell",
57
+ "async_bash",
56
58
  "gsd_exec",
57
59
  "gsd_exec_search",
58
60
  "mcp__gsd-workflow__gsd_exec",
@@ -1,3 +1,4 @@
1
+
1
2
  /**
2
3
  * Evidence cross-reference for auto-mode safety harness.
3
4
  * Compares the LLM's claimed verification evidence (command + exitCode)
@@ -14,6 +15,7 @@ export interface ClaimedEvidence {
14
15
  command: string;
15
16
  exitCode: number;
16
17
  verdict: string;
18
+ createdAt?: string;
17
19
  }
18
20
 
19
21
  export interface EvidenceMismatch {
@@ -40,7 +42,7 @@ export function crossReferenceEvidence(
40
42
  );
41
43
  const mismatches: EvidenceMismatch[] = [];
42
44
 
43
- for (const claimed of claimedEvidence) {
45
+ for (const claimed of latestClaimBatch(claimedEvidence)) {
44
46
  // Skip coerced entries — they're already flagged with exitCode: -1
45
47
  // and verdict: "unknown (coerced from string)" by db-tools.ts
46
48
  if (claimed.verdict?.includes("coerced from string")) continue;
@@ -49,10 +51,12 @@ export function crossReferenceEvidence(
49
51
  // Skip entries with empty or generic commands
50
52
  if (!claimed.command || claimed.command.length < 3) continue;
51
53
 
52
- // Find matching bash call by command substring match
53
- const match = findBestMatch(claimed.command, bashCalls);
54
+ // Find matching bash calls by command similarity. A command may be retried
55
+ // after a failed first run; the newest matching execution is the one that
56
+ // supports or rejects a claimed pass.
57
+ const matches = findMatches(claimed.command, bashCalls);
54
58
 
55
- if (!match) {
59
+ if (matches.length === 0) {
56
60
  mismatches.push({
57
61
  severity: "warning",
58
62
  claimed,
@@ -63,6 +67,7 @@ export function crossReferenceEvidence(
63
67
  }
64
68
 
65
69
  // Exit code mismatch: LLM claims success but actual command failed
70
+ const match = latestMatch(matches);
66
71
  if (claimed.exitCode === 0 && match.exitCode !== 0) {
67
72
  mismatches.push({
68
73
  severity: "error",
@@ -79,42 +84,72 @@ export function crossReferenceEvidence(
79
84
  // ─── Internals ──────────────────────────────────────────────────────────────
80
85
 
81
86
  /**
82
- * Find the best matching bash evidence entry for a claimed command.
87
+ * Verification evidence rows are append-only across retries, but a task
88
+ * completion inserts one batch at a single created_at timestamp. When that
89
+ * timestamp is present, safety should judge the newest completion claim only.
90
+ */
91
+ function latestClaimBatch(
92
+ claimedEvidence: readonly ClaimedEvidence[],
93
+ ): readonly ClaimedEvidence[] {
94
+ const dated = claimedEvidence
95
+ .map((claim) => ({
96
+ claim,
97
+ time: typeof claim.createdAt === "string" ? Date.parse(claim.createdAt) : Number.NaN,
98
+ }))
99
+ .filter((entry) => Number.isFinite(entry.time));
100
+
101
+ if (dated.length === 0) return claimedEvidence;
102
+
103
+ const latestTime = Math.max(...dated.map((entry) => entry.time));
104
+ return claimedEvidence.filter((claim) => (
105
+ typeof claim.createdAt === "string" && Date.parse(claim.createdAt) === latestTime
106
+ ));
107
+ }
108
+
109
+ /**
110
+ * Find bash evidence entries matching a claimed command.
83
111
  * Uses substring matching — the claimed command may be a shortened version
84
112
  * of the actual command, or vice versa.
85
113
  */
86
- function findBestMatch(
114
+ function findMatches(
87
115
  claimedCommand: string,
88
116
  bashCalls: readonly BashEvidence[],
89
- ): BashEvidence | null {
117
+ ): BashEvidence[] {
90
118
  const normalized = claimedCommand.trim();
91
119
 
92
- // Exact match first
93
- const exact = bashCalls.find(b => b.command.trim() === normalized);
94
- if (exact) return exact;
120
+ // Exact matches first
121
+ const exact = bashCalls.filter(b => b.command.trim() === normalized);
122
+ if (exact.length > 0) return exact;
95
123
 
96
124
  // Substring match: claimed is contained in actual or actual in claimed
97
- const substring = bashCalls.find(
125
+ const substring = bashCalls.filter(
98
126
  b => b.command.includes(normalized) || normalized.includes(b.command),
99
127
  );
100
- if (substring) return substring;
128
+ if (substring.length > 0) return substring;
101
129
 
102
130
  // Token match: split on whitespace and check significant overlap
103
131
  const claimedTokens = normalized.split(/\s+/).filter(t => t.length > 2);
104
- if (claimedTokens.length === 0) return null;
132
+ if (claimedTokens.length === 0) return [];
105
133
 
106
- let bestMatch: BashEvidence | null = null;
107
- let bestScore = 0;
134
+ const scoredMatches: Array<{ call: BashEvidence; score: number }> = [];
108
135
 
109
136
  for (const call of bashCalls) {
110
137
  const callTokens = new Set(call.command.split(/\s+/));
111
138
  const matchCount = claimedTokens.filter(t => callTokens.has(t)).length;
112
139
  const score = matchCount / claimedTokens.length;
113
- if (score > bestScore && score >= 0.5) {
114
- bestScore = score;
115
- bestMatch = call;
140
+ if (score >= 0.5) {
141
+ scoredMatches.push({ call, score });
116
142
  }
117
143
  }
118
144
 
119
- return bestMatch;
145
+ const bestScore = Math.max(0, ...scoredMatches.map((match) => match.score));
146
+ return scoredMatches
147
+ .filter((match) => match.score === bestScore)
148
+ .map((match) => match.call);
149
+ }
150
+
151
+ function latestMatch(matches: readonly BashEvidence[]): BashEvidence {
152
+ return matches.reduce((latest, match) => (
153
+ match.timestamp > latest.timestamp ? match : latest
154
+ ));
120
155
  }
@@ -19,8 +19,9 @@
19
19
  import { createRequire } from "node:module";
20
20
  import { existsSync, readFileSync, readdirSync, mkdirSync, unlinkSync, rmSync, statSync } from "node:fs";
21
21
  import { join, dirname } from "node:path";
22
- import { gsdRoot } from "./paths.js";
22
+ import { gsdRoot, normalizeRealPath } from "./paths.js";
23
23
  import { atomicWriteSync } from "./atomic-write.js";
24
+ import { markWorkerStoppingByPid } from "./db/auto-workers.js";
24
25
 
25
26
  const _require = createRequire(import.meta.url);
26
27
 
@@ -281,6 +282,13 @@ export function acquireSessionLock(basePath: string): SessionLockResult {
281
282
  // Clean up numbered lock file variants from cloud sync conflicts (#1315)
282
283
  cleanupStrayLockFiles(basePath);
283
284
 
285
+ // If lock metadata points to a dead PID, mark that worker row stopping so
286
+ // crash diagnostics do not keep surfacing it as active.
287
+ const existingPreflight = readExistingLockData(lp);
288
+ if (existingPreflight?.pid && !isPidAlive(existingPreflight.pid)) {
289
+ markWorkerStoppingByPid(normalizeRealPath(basePath), existingPreflight.pid);
290
+ }
291
+
284
292
  // Write our lock data first (the content is informational; the OS lock is the real guard)
285
293
  const lockData: SessionLockData = {
286
294
  pid: process.pid,
@@ -308,7 +316,9 @@ export function acquireSessionLock(basePath: string): SessionLockResult {
308
316
  const lockDir = lockTarget + ".lock";
309
317
  if (existsSync(lockDir)) {
310
318
  const existingData = readExistingLockData(lp);
311
- const isOrphan = !existingData || (existingData.pid && !isPidAlive(existingData.pid));
319
+ const deadPid = existingData?.pid && !isPidAlive(existingData.pid) ? existingData.pid : null;
320
+ if (deadPid) markWorkerStoppingByPid(normalizeRealPath(basePath), deadPid);
321
+ const isOrphan = !existingData || !!deadPid;
312
322
  if (isOrphan) {
313
323
  try { rmSync(lockDir, { recursive: true, force: true }); } catch { /* best-effort */ }
314
324
  try { if (existsSync(lp)) unlinkSync(lp); } catch { /* best-effort */ }
@@ -344,6 +354,9 @@ export function acquireSessionLock(basePath: string): SessionLockResult {
344
354
  // Check: if auto.lock is gone and no process is alive, the lock dir is stale.
345
355
  const existingData = readExistingLockData(lp);
346
356
  const existingPid = existingData?.pid;
357
+ if (existingPid && !isPidAlive(existingPid)) {
358
+ markWorkerStoppingByPid(normalizeRealPath(basePath), existingPid);
359
+ }
347
360
 
348
361
  // If no lock file or no alive process, try to clean up and re-acquire (#1245)
349
362
  if (!existingData || (existingPid && !isPidAlive(existingPid))) {
@@ -55,8 +55,8 @@ export function hasFileConflict(
55
55
  sliceA: string,
56
56
  sliceB: string,
57
57
  ): boolean {
58
- const planPathA = join(basePath, ".gsd", "milestones", mid, sliceA, "PLAN.md");
59
- const planPathB = join(basePath, ".gsd", "milestones", mid, sliceB, "PLAN.md");
58
+ const planPathA = join(basePath, ".gsd", "milestones", mid, "slices", sliceA, `${sliceA}-PLAN.md`);
59
+ const planPathB = join(basePath, ".gsd", "milestones", mid, "slices", sliceB, `${sliceB}-PLAN.md`);
60
60
 
61
61
  // Conservative: missing PLAN = block
62
62
  if (!existsSync(planPathA) || !existsSync(planPathB)) {
@@ -18,13 +18,15 @@ import { randomUUID } from "node:crypto";
18
18
  import {
19
19
  appendFileSync,
20
20
  existsSync,
21
+ lstatSync,
22
+ rmSync,
21
23
  writeFileSync,
22
24
  readFileSync,
23
25
  mkdirSync,
24
26
  renameSync,
25
27
  unlinkSync,
26
28
  } from "node:fs";
27
- import { join, dirname } from "node:path";
29
+ import { isAbsolute, join, dirname, resolve } from "node:path";
28
30
  import { fileURLToPath } from "node:url";
29
31
  import { gsdRoot } from "./paths.js";
30
32
  import { createWorktree, worktreePath, removeWorktree } from "./worktree-manager.js";
@@ -105,6 +107,37 @@ export function _buildSliceWorkerEnvForTest(
105
107
  };
106
108
  }
107
109
 
110
+ function isValidSliceWorktreePath(basePath: string, wtPath: string): boolean {
111
+ if (!existsSync(wtPath)) return false;
112
+ const gitPath = join(wtPath, ".git");
113
+ if (!existsSync(gitPath)) return false;
114
+ try {
115
+ if (!lstatSync(gitPath).isFile()) return false;
116
+ const content = readFileSync(gitPath, "utf8").trim();
117
+ if (!content.startsWith("gitdir: ")) return false;
118
+ const rawGitdir = content.slice("gitdir: ".length).trim();
119
+ if (!rawGitdir) return false;
120
+ const resolvedGitdir = isAbsolute(rawGitdir) ? rawGitdir : resolve(wtPath, rawGitdir);
121
+ const expectedPrefix = join(basePath, ".git", "worktrees").replaceAll("\\", "/");
122
+ const normalized = resolvedGitdir.replaceAll("\\", "/");
123
+ return normalized === expectedPrefix || normalized.startsWith(`${expectedPrefix}/`);
124
+ } catch {
125
+ return false;
126
+ }
127
+ }
128
+
129
+ function isWorkerPidAlive(pid: number): boolean {
130
+ if (!Number.isFinite(pid) || pid <= 0) return false;
131
+ try {
132
+ process.kill(pid, 0);
133
+ return true;
134
+ } catch (err) {
135
+ const code = (err as NodeJS.ErrnoException)?.code;
136
+ if (code === "ESRCH") return false;
137
+ return true;
138
+ }
139
+ }
140
+
108
141
  interface PersistedSliceWorker {
109
142
  milestoneId: string;
110
143
  sliceId: string;
@@ -334,7 +367,24 @@ export function restoreSliceState(basePath: string): PersistedSliceState | null
334
367
  * crash followed by a fresh process is detectable. (Issue #4980 HIGH-8)
335
368
  */
336
369
  export function isSliceParallelActive(basePath?: string): boolean {
337
- if (sliceState?.active === true) return true;
370
+ const hasRunningWorkers = (): boolean => {
371
+ if (!sliceState) return false;
372
+ for (const worker of sliceState.workers.values()) {
373
+ if (worker.state === "running") {
374
+ if (worker.process) return true;
375
+ if (isRecoveredSliceWorkerAlive(worker)) return true;
376
+ }
377
+ }
378
+ return false;
379
+ };
380
+
381
+ if (sliceState?.active === true) {
382
+ if (hasRunningWorkers()) return true;
383
+ sliceState.active = false;
384
+ removeSliceStateFile(sliceState.basePath);
385
+ return false;
386
+ }
387
+
338
388
  if (!basePath) return false;
339
389
  const restored = restoreSliceState(basePath);
340
390
  if (!restored || restored.workers.length === 0) return false;
@@ -365,7 +415,11 @@ export function isSliceParallelActive(basePath?: string): boolean {
365
415
  cost: w.cost,
366
416
  });
367
417
  }
368
- return true;
418
+
419
+ if (hasRunningWorkers()) return true;
420
+ sliceState.active = false;
421
+ removeSliceStateFile(sliceState.basePath);
422
+ return false;
369
423
  }
370
424
 
371
425
  /**
@@ -427,6 +481,9 @@ export async function startSliceParallel(
427
481
  const wtName = `${milestoneId}-${slice.id}`;
428
482
  const wtPath = worktreePath(basePath, wtName);
429
483
 
484
+ if (existsSync(wtPath) && !isValidSliceWorktreePath(basePath, wtPath)) {
485
+ rmSync(wtPath, { recursive: true, force: true });
486
+ }
430
487
  if (!existsSync(wtPath)) {
431
488
  createWorktree(basePath, wtName, { branch: wtBranch });
432
489
  }
@@ -470,6 +527,21 @@ export async function startSliceParallel(
470
527
  }
471
528
  }
472
529
 
530
+ // Guard: if workers died immediately, treat as failed start so callers
531
+ // don't exit auto-mode and re-dispatch in a rapid loop.
532
+ for (let i = started.length - 1; i >= 0; i--) {
533
+ const sid = started[i];
534
+ const worker = sliceState.workers.get(sid);
535
+ if (worker && isWorkerPidAlive(worker.pid)) continue;
536
+ started.splice(i, 1);
537
+ errors.push({ sid, error: "Worker exited immediately after spawn" });
538
+ sliceState.workers.delete(sid);
539
+ const wtName = `${milestoneId}-${sid}`;
540
+ try {
541
+ removeWorktree(basePath, wtName, { deleteBranch: true, force: true });
542
+ } catch { /* ignore cleanup failures */ }
543
+ }
544
+
473
545
  // If nothing started, deactivate
474
546
  if (started.length === 0) {
475
547
  sliceState.active = false;
@@ -0,0 +1,77 @@
1
+ // GSD-2 — Smart entry routing decisions.
2
+ // Pure route selection for /gsd guided wizard choices.
3
+
4
+ export type SmartEntryIsolationMode = "worktree" | "branch" | "none";
5
+
6
+ export type ActiveTaskChoice =
7
+ | "execute"
8
+ | "auto"
9
+ | "status"
10
+ | "milestone_actions";
11
+
12
+ export type ActiveTaskRoute =
13
+ | {
14
+ kind: "auto-bootstrap";
15
+ verboseMode: false;
16
+ options?: {
17
+ step?: true;
18
+ milestoneLock?: string;
19
+ };
20
+ }
21
+ | {
22
+ kind: "guided-dispatch";
23
+ unitType: "execute-task";
24
+ }
25
+ | {
26
+ kind: "status";
27
+ }
28
+ | {
29
+ kind: "milestone-actions";
30
+ };
31
+
32
+ export function resolveGuidedExecuteLaunchMode(
33
+ isolationMode: SmartEntryIsolationMode,
34
+ ): "auto-step" | "guided-dispatch" {
35
+ return isolationMode === "worktree" ? "auto-step" : "guided-dispatch";
36
+ }
37
+
38
+ export function resolveActiveTaskChoiceRoute(input: {
39
+ choice: ActiveTaskChoice;
40
+ isolationMode: SmartEntryIsolationMode;
41
+ milestoneId: string;
42
+ }): ActiveTaskRoute {
43
+ if (input.choice === "auto") {
44
+ return {
45
+ kind: "auto-bootstrap",
46
+ verboseMode: false,
47
+ };
48
+ }
49
+
50
+ if (input.choice === "execute") {
51
+ if (resolveGuidedExecuteLaunchMode(input.isolationMode) === "auto-step") {
52
+ return {
53
+ kind: "auto-bootstrap",
54
+ verboseMode: false,
55
+ options: {
56
+ step: true,
57
+ milestoneLock: input.milestoneId,
58
+ },
59
+ };
60
+ }
61
+
62
+ return {
63
+ kind: "guided-dispatch",
64
+ unitType: "execute-task",
65
+ };
66
+ }
67
+
68
+ if (input.choice === "status") {
69
+ return { kind: "status" };
70
+ }
71
+
72
+ if (input.choice === "milestone_actions") {
73
+ return { kind: "milestone-actions" };
74
+ }
75
+
76
+ throw new Error(`Invalid ActiveTaskChoice: ${input.choice}`);
77
+ }
@@ -23,6 +23,7 @@ import {
23
23
  } from "../../native-git-bridge.js";
24
24
  import type { GSDState } from "../../types.js";
25
25
  import { logError, logWarning } from "../../workflow-logger.js";
26
+ import { isGsdWorktreePath } from "../../worktree-root.js";
26
27
  import type { DriftContext, DriftHandler, DriftRecord } from "../types.js";
27
28
 
28
29
  export type MergeReconcileResult = "clean" | "reconciled" | "blocked";
@@ -46,7 +47,13 @@ function resolveGitDir(basePath: string): string {
46
47
  return isAbsolute(gitDir) ? gitDir : resolve(basePath, gitDir);
47
48
  }
48
49
  } catch (err) {
49
- logWarning("recovery", `gitdir resolution failed: ${getErrorMessage(err)}`);
50
+ const message = getErrorMessage(err);
51
+ logWarning("recovery", `gitdir resolution failed: ${message}`);
52
+ if (isGsdWorktreePath(basePath)) {
53
+ throw new Error(
54
+ `Worktree integrity failure: ${basePath} is not a valid git worktree (git rev-parse failed: ${message.split("\n")[0]}). Repair or recreate the worktree before retrying.`,
55
+ );
56
+ }
50
57
  }
51
58
 
52
59
  return join(basePath, ".git");