@opengsd/gsd-pi 1.2.0-dev.844675c9 → 1.2.0-dev.955e4da0

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 (530) hide show
  1. package/dist/cli-web-branch.d.ts +2 -0
  2. package/dist/cli-web-branch.js +9 -2
  3. package/dist/help-text.js +5 -0
  4. package/dist/resources/.managed-resources-content-hash +1 -1
  5. package/dist/resources/extensions/ask-user-questions.js +78 -23
  6. package/dist/resources/extensions/bg-shell/utilities.js +2 -2
  7. package/dist/resources/extensions/claude-code-cli/models.js +9 -0
  8. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +92 -230
  9. package/dist/resources/extensions/claude-code-cli/turn-assembler.js +224 -0
  10. package/dist/resources/extensions/github-sync/templates.js +3 -3
  11. package/dist/resources/extensions/gsd/artifact-projection.js +14 -0
  12. package/dist/resources/extensions/gsd/auto/loop.js +74 -56
  13. package/dist/resources/extensions/gsd/auto/orchestrator.js +142 -15
  14. package/dist/resources/extensions/gsd/auto/phases.js +34 -4
  15. package/dist/resources/extensions/gsd/auto/run-unit.js +2 -1
  16. package/dist/resources/extensions/gsd/auto/session.js +3 -0
  17. package/dist/resources/extensions/gsd/auto-dashboard.js +16 -4
  18. package/dist/resources/extensions/gsd/auto-dispatch.js +6 -5
  19. package/dist/resources/extensions/gsd/auto-model-selection.js +8 -0
  20. package/dist/resources/extensions/gsd/auto-post-unit.js +12 -9
  21. package/dist/resources/extensions/gsd/auto-prompts.js +81 -8
  22. package/dist/resources/extensions/gsd/auto-recovery.js +48 -49
  23. package/dist/resources/extensions/gsd/auto-runtime-state.js +14 -0
  24. package/dist/resources/extensions/gsd/auto-start.js +20 -36
  25. package/dist/resources/extensions/gsd/auto-timers.js +16 -2
  26. package/dist/resources/extensions/gsd/auto-tool-tracking.js +32 -0
  27. package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +4 -29
  28. package/dist/resources/extensions/gsd/auto-verification.js +7 -7
  29. package/dist/resources/extensions/gsd/auto-worktree-repair.js +10 -2
  30. package/dist/resources/extensions/gsd/auto-worktree.js +34 -289
  31. package/dist/resources/extensions/gsd/auto.js +15 -14
  32. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +28 -37
  33. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +20 -43
  34. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +2 -2
  35. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +131 -140
  36. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +89 -8
  37. package/dist/resources/extensions/gsd/captures.js +5 -13
  38. package/dist/resources/extensions/gsd/closeout-consistency-gate.js +21 -4
  39. package/dist/resources/extensions/gsd/closeout-recovery.js +3 -2
  40. package/dist/resources/extensions/gsd/codebase-generator.js +8 -4
  41. package/dist/resources/extensions/gsd/commands/catalog.js +6 -62
  42. package/dist/resources/extensions/gsd/commands/handlers/auto.js +3 -0
  43. package/dist/resources/extensions/gsd/commands-handlers.js +20 -0
  44. package/dist/resources/extensions/gsd/commands-inspect.js +4 -8
  45. package/dist/resources/extensions/gsd/commands-maintenance.js +61 -41
  46. package/dist/resources/extensions/gsd/commands-ship.js +2 -2
  47. package/dist/resources/extensions/gsd/commands-verdict.js +12 -2
  48. package/dist/resources/extensions/gsd/db/engine.js +755 -0
  49. package/dist/resources/extensions/gsd/db/queries.js +372 -0
  50. package/dist/resources/extensions/gsd/db/sql-constants.js +11 -0
  51. package/dist/resources/extensions/gsd/db/writers/cascades.js +194 -0
  52. package/dist/resources/extensions/gsd/db/writers/import-restore.js +182 -0
  53. package/dist/resources/extensions/gsd/db/writers/memory.js +149 -0
  54. package/dist/resources/extensions/gsd/db/writers/reconcile.js +458 -0
  55. package/dist/resources/extensions/gsd/db/writers/status.js +70 -0
  56. package/dist/resources/extensions/gsd/db-workspace.js +103 -0
  57. package/dist/resources/extensions/gsd/delegation-policy.js +2 -10
  58. package/dist/resources/extensions/gsd/discussion-handoff.js +218 -0
  59. package/dist/resources/extensions/gsd/docs/preferences-reference.md +9 -0
  60. package/dist/resources/extensions/gsd/doctor-environment.js +8 -10
  61. package/dist/resources/extensions/gsd/doctor-git-checks.js +4 -3
  62. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +9 -2
  63. package/dist/resources/extensions/gsd/doctor.js +16 -9
  64. package/dist/resources/extensions/gsd/error-classifier.js +1 -1
  65. package/dist/resources/extensions/gsd/git-conflict-state.js +16 -1
  66. package/dist/resources/extensions/gsd/git-service.js +1 -0
  67. package/dist/resources/extensions/gsd/gitignore.js +3 -0
  68. package/dist/resources/extensions/gsd/gsd-db.js +183 -2048
  69. package/dist/resources/extensions/gsd/guided-flow.js +68 -471
  70. package/dist/resources/extensions/gsd/guided-unit-completion.js +225 -0
  71. package/dist/resources/extensions/gsd/markdown-renderer.js +2 -1
  72. package/dist/resources/extensions/gsd/mcp-filter.js +2 -1
  73. package/dist/resources/extensions/gsd/mcp-tool-name.js +26 -0
  74. package/dist/resources/extensions/gsd/md-importer.js +4 -3
  75. package/dist/resources/extensions/gsd/migrate/safety.js +19 -11
  76. package/dist/resources/extensions/gsd/migration-auto-check.js +27 -5
  77. package/dist/resources/extensions/gsd/milestone-closeout-proof.js +72 -0
  78. package/dist/resources/extensions/gsd/milestone-closeout.js +12 -4
  79. package/dist/resources/extensions/gsd/milestone-merge-transaction.js +10 -0
  80. package/dist/resources/extensions/gsd/milestone-planning-persistence.js +156 -0
  81. package/dist/resources/extensions/gsd/milestone-readiness.js +77 -0
  82. package/dist/resources/extensions/gsd/milestone-settlement.js +50 -0
  83. package/dist/resources/extensions/gsd/milestone-validation-evidence.js +73 -0
  84. package/dist/resources/extensions/gsd/milestone-validation-verdict.js +57 -0
  85. package/dist/resources/extensions/gsd/model-cost-table.js +1 -0
  86. package/dist/resources/extensions/gsd/model-router.js +3 -0
  87. package/dist/resources/extensions/gsd/parallel-eligibility.js +3 -6
  88. package/dist/resources/extensions/gsd/parallel-merge.js +14 -11
  89. package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +7 -5
  90. package/dist/resources/extensions/gsd/parallel-orchestrator.js +3 -2
  91. package/dist/resources/extensions/gsd/paths.js +10 -24
  92. package/dist/resources/extensions/gsd/preferences-diagnostics.js +67 -0
  93. package/dist/resources/extensions/gsd/preferences.js +161 -29
  94. package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -0
  95. package/dist/resources/extensions/gsd/prompts/execute-task.md +2 -0
  96. package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +3 -1
  97. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +2 -0
  98. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -0
  99. package/dist/resources/extensions/gsd/prompts/refine-slice.md +1 -0
  100. package/dist/resources/extensions/gsd/prompts/system.md +1 -1
  101. package/dist/resources/extensions/gsd/provider-payload-policy.js +83 -0
  102. package/dist/resources/extensions/gsd/pull-request-process.js +13 -0
  103. package/dist/resources/extensions/gsd/quality-gate-closure.js +109 -0
  104. package/dist/resources/extensions/gsd/question-transport.js +86 -0
  105. package/dist/resources/extensions/gsd/recovery-classification.js +12 -1
  106. package/dist/resources/extensions/gsd/roadmap-slices.js +8 -2
  107. package/dist/resources/extensions/gsd/safety/evidence-collector.js +37 -4
  108. package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +7 -2
  109. package/dist/resources/extensions/gsd/safety/file-change-validator.js +10 -0
  110. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +3 -2
  111. package/dist/resources/extensions/gsd/state-transition-matrix.js +38 -0
  112. package/dist/resources/extensions/gsd/state.js +13 -5
  113. package/dist/resources/extensions/gsd/status-guards.js +56 -8
  114. package/dist/resources/extensions/gsd/templates/plan.md +7 -0
  115. package/dist/resources/extensions/gsd/templates/project.md +1 -0
  116. package/dist/resources/extensions/gsd/templates/roadmap.md +1 -1
  117. package/dist/resources/extensions/gsd/templates/uat.md +5 -1
  118. package/dist/resources/extensions/gsd/tool-contract.js +52 -8
  119. package/dist/resources/extensions/gsd/tool-presentation-plan.js +15 -34
  120. package/dist/resources/extensions/gsd/tool-surface-snapshot.js +17 -0
  121. package/dist/resources/extensions/gsd/tools/complete-slice.js +24 -43
  122. package/dist/resources/extensions/gsd/tools/exec-tool.js +5 -5
  123. package/dist/resources/extensions/gsd/tools/plan-milestone.js +15 -143
  124. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +39 -0
  125. package/dist/resources/extensions/gsd/tools/reopen-milestone.js +11 -29
  126. package/dist/resources/extensions/gsd/tools/reopen-slice.js +14 -33
  127. package/dist/resources/extensions/gsd/tools/skip-slice.js +18 -36
  128. package/dist/resources/extensions/gsd/tools/validate-milestone.js +15 -78
  129. package/dist/resources/extensions/gsd/uat-policy.js +16 -10
  130. package/dist/resources/extensions/gsd/uat-run.js +9 -14
  131. package/dist/resources/extensions/gsd/undo.js +8 -7
  132. package/dist/resources/extensions/gsd/unit-context-composer.js +40 -20
  133. package/dist/resources/extensions/gsd/unit-runtime.js +3 -2
  134. package/dist/resources/extensions/gsd/unit-tool-contracts.js +2 -1
  135. package/dist/resources/extensions/gsd/user-input-boundary.js +23 -0
  136. package/dist/resources/extensions/gsd/validation-block-guard.js +2 -0
  137. package/dist/resources/extensions/gsd/web-app-uat.js +80 -0
  138. package/dist/resources/extensions/gsd/workflow-mcp.js +15 -102
  139. package/dist/resources/extensions/gsd/workflow-reconcile.js +4 -3
  140. package/dist/resources/extensions/gsd/workflow-tool-surface.js +46 -0
  141. package/dist/resources/extensions/gsd/workspace-git-guard.js +2 -0
  142. package/dist/resources/extensions/gsd/worktree-git-recovery.js +287 -0
  143. package/dist/resources/extensions/gsd/worktree-lifecycle.js +9 -1
  144. package/dist/resources/extensions/gsd/worktree-manager.js +45 -28
  145. package/dist/resources/extensions/gsd/worktree-placement.js +59 -0
  146. package/dist/resources/extensions/gsd/worktree-reentry.js +12 -8
  147. package/dist/resources/extensions/gsd/worktree-root.js +17 -6
  148. package/dist/resources/extensions/gsd/worktree-safety.js +8 -5
  149. package/dist/resources/extensions/gsd/worktree-session-state.js +12 -10
  150. package/dist/resources/extensions/gsd/worktree-state-projection.js +33 -4
  151. package/dist/resources/extensions/gsd/worktree-telemetry.js +12 -0
  152. package/dist/resources/extensions/shared/interview-ui.js +2 -2
  153. package/dist/resources/shared/claude-runtime-floor.js +182 -0
  154. package/dist/resources/skills/gsd-browser/SKILL.md +1 -1
  155. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  156. package/dist/update-cmd.js +20 -0
  157. package/dist/web/standalone/.next/BUILD_ID +1 -1
  158. package/dist/web/standalone/.next/app-path-routes-manifest.json +12 -12
  159. package/dist/web/standalone/.next/build-manifest.json +3 -3
  160. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  161. package/dist/web/standalone/.next/react-loadable-manifest.json +8 -8
  162. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  163. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  164. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  165. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  166. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  167. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  168. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  169. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  170. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  171. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  172. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  173. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  174. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  175. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  176. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  177. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  178. package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
  179. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
  180. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
  181. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
  182. package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
  183. package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
  184. package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
  185. package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
  186. package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  187. package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
  188. package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  189. package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
  190. package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
  191. package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
  192. package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
  193. package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
  194. package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js.nft.json +1 -1
  195. package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
  196. package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
  197. package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  198. package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
  199. package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
  200. package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
  201. package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
  202. package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
  203. package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
  204. package/dist/web/standalone/.next/server/app/api/shutdown/route.js.nft.json +1 -1
  205. package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
  206. package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
  207. package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
  208. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
  209. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
  210. package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
  211. package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
  212. package/dist/web/standalone/.next/server/app/index.html +1 -1
  213. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  214. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  215. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  216. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  217. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  218. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  219. package/dist/web/standalone/.next/server/app-paths-manifest.json +12 -12
  220. package/dist/web/standalone/.next/server/chunks/{5047.js → 5942.js} +2 -2
  221. package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
  222. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  223. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  224. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  225. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  226. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  227. package/dist/web/standalone/.next/static/chunks/2659.b7b129ee6a769448.js +1 -0
  228. package/dist/web/standalone/.next/static/chunks/2772.bfa657f49f955239.js +1 -0
  229. package/dist/web/standalone/.next/static/chunks/{3616.4113d484a994e411.js → 3616.3c60753b8ffcbd2e.js} +1 -1
  230. package/dist/web/standalone/.next/static/chunks/4283.e4873b058df143a1.js +2 -0
  231. package/dist/web/standalone/.next/static/chunks/5826.a46ecdd1cfe8dabc.js +1 -0
  232. package/dist/web/standalone/.next/static/chunks/796.cf859a427a2cb2ac.js +10 -0
  233. package/dist/web/standalone/.next/static/chunks/8785.2e5a118797fb2dd2.js +1 -0
  234. package/dist/web/standalone/.next/static/chunks/{webpack-dda80a1ef5587410.js → webpack-fbea77b5f9953368.js} +1 -1
  235. package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
  236. package/dist/web-mode.d.ts +2 -0
  237. package/dist/web-mode.js +20 -8
  238. package/dist/worktree-status-banner.js +7 -3
  239. package/package.json +2 -1
  240. package/packages/cloud-mcp-gateway/package.json +2 -2
  241. package/packages/contracts/package.json +1 -1
  242. package/packages/daemon/package.json +4 -4
  243. package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts +2 -0
  244. package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts.map +1 -1
  245. package/packages/gsd-agent-core/dist/session/agent-session-extensions.js +14 -0
  246. package/packages/gsd-agent-core/dist/session/agent-session-extensions.js.map +1 -1
  247. package/packages/gsd-agent-core/package.json +5 -5
  248. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  249. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +3 -0
  250. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  251. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  252. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +106 -40
  253. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  254. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.d.ts.map +1 -1
  255. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.js +6 -0
  256. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.js.map +1 -1
  257. package/packages/gsd-agent-modes/package.json +7 -7
  258. package/packages/mcp-server/dist/server.d.ts +10 -0
  259. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  260. package/packages/mcp-server/dist/server.js +8 -0
  261. package/packages/mcp-server/dist/server.js.map +1 -1
  262. package/packages/mcp-server/dist/workflow-tools.d.ts +41 -0
  263. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  264. package/packages/mcp-server/dist/workflow-tools.js +32 -22
  265. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  266. package/packages/mcp-server/package.json +3 -3
  267. package/packages/native/package.json +1 -1
  268. package/packages/pi-agent-core/package.json +1 -1
  269. package/packages/pi-ai/dist/image-models.generated.d.ts +2 -2
  270. package/packages/pi-ai/dist/image-models.generated.js +6 -6
  271. package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
  272. package/packages/pi-ai/dist/models.generated.d.ts +295 -98
  273. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  274. package/packages/pi-ai/dist/models.generated.js +309 -154
  275. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  276. package/packages/pi-ai/package.json +1 -1
  277. package/packages/pi-coding-agent/dist/core/capability-patches.d.ts.map +1 -1
  278. package/packages/pi-coding-agent/dist/core/capability-patches.js +3 -1
  279. package/packages/pi-coding-agent/dist/core/capability-patches.js.map +1 -1
  280. package/packages/pi-coding-agent/package.json +7 -7
  281. package/packages/pi-tui/dist/components/input.js +1 -1
  282. package/packages/pi-tui/dist/components/input.js.map +1 -1
  283. package/packages/pi-tui/dist/keys.d.ts.map +1 -1
  284. package/packages/pi-tui/dist/keys.js +39 -30
  285. package/packages/pi-tui/dist/keys.js.map +1 -1
  286. package/packages/pi-tui/dist/stdin-buffer.d.ts.map +1 -1
  287. package/packages/pi-tui/dist/stdin-buffer.js +22 -0
  288. package/packages/pi-tui/dist/stdin-buffer.js.map +1 -1
  289. package/packages/pi-tui/package.json +2 -2
  290. package/packages/rpc-client/package.json +2 -2
  291. package/pkg/package.json +1 -1
  292. package/src/resources/extensions/ask-user-questions.ts +87 -24
  293. package/src/resources/extensions/bg-shell/utilities.ts +2 -2
  294. package/src/resources/extensions/claude-code-cli/models.ts +9 -0
  295. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +114 -281
  296. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +268 -0
  297. package/src/resources/extensions/claude-code-cli/turn-assembler.ts +287 -0
  298. package/src/resources/extensions/github-sync/templates.ts +3 -3
  299. package/src/resources/extensions/github-sync/tests/templates.test.ts +2 -2
  300. package/src/resources/extensions/gsd/artifact-projection.ts +31 -0
  301. package/src/resources/extensions/gsd/auto/contracts.ts +32 -2
  302. package/src/resources/extensions/gsd/auto/loop-deps.ts +3 -1
  303. package/src/resources/extensions/gsd/auto/loop.ts +83 -61
  304. package/src/resources/extensions/gsd/auto/orchestrator.ts +164 -17
  305. package/src/resources/extensions/gsd/auto/phases.ts +45 -4
  306. package/src/resources/extensions/gsd/auto/run-unit.ts +2 -1
  307. package/src/resources/extensions/gsd/auto/session.ts +4 -0
  308. package/src/resources/extensions/gsd/auto-dashboard.ts +18 -4
  309. package/src/resources/extensions/gsd/auto-dispatch.ts +20 -7
  310. package/src/resources/extensions/gsd/auto-model-selection.ts +8 -0
  311. package/src/resources/extensions/gsd/auto-post-unit.ts +16 -8
  312. package/src/resources/extensions/gsd/auto-prompts.ts +107 -9
  313. package/src/resources/extensions/gsd/auto-recovery.ts +50 -50
  314. package/src/resources/extensions/gsd/auto-runtime-state.ts +26 -0
  315. package/src/resources/extensions/gsd/auto-start.ts +25 -34
  316. package/src/resources/extensions/gsd/auto-timers.ts +16 -2
  317. package/src/resources/extensions/gsd/auto-tool-tracking.ts +35 -0
  318. package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +9 -30
  319. package/src/resources/extensions/gsd/auto-verification.ts +7 -8
  320. package/src/resources/extensions/gsd/auto-worktree-repair.ts +13 -2
  321. package/src/resources/extensions/gsd/auto-worktree.ts +53 -306
  322. package/src/resources/extensions/gsd/auto.ts +27 -17
  323. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +29 -37
  324. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +20 -43
  325. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +2 -2
  326. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +147 -153
  327. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +132 -6
  328. package/src/resources/extensions/gsd/captures.ts +5 -14
  329. package/src/resources/extensions/gsd/closeout-consistency-gate.ts +27 -5
  330. package/src/resources/extensions/gsd/closeout-recovery.ts +2 -1
  331. package/src/resources/extensions/gsd/codebase-generator.ts +9 -5
  332. package/src/resources/extensions/gsd/commands/catalog.ts +6 -68
  333. package/src/resources/extensions/gsd/commands/handlers/auto.ts +3 -0
  334. package/src/resources/extensions/gsd/commands-handlers.ts +18 -0
  335. package/src/resources/extensions/gsd/commands-inspect.ts +7 -8
  336. package/src/resources/extensions/gsd/commands-maintenance.ts +74 -40
  337. package/src/resources/extensions/gsd/commands-ship.ts +2 -2
  338. package/src/resources/extensions/gsd/commands-verdict.ts +19 -2
  339. package/src/resources/extensions/gsd/db/engine.ts +809 -0
  340. package/src/resources/extensions/gsd/db/queries.ts +453 -0
  341. package/src/resources/extensions/gsd/db/sql-constants.ts +12 -0
  342. package/src/resources/extensions/gsd/db/writers/cascades.ts +237 -0
  343. package/src/resources/extensions/gsd/db/writers/import-restore.ts +310 -0
  344. package/src/resources/extensions/gsd/db/writers/memory.ts +220 -0
  345. package/src/resources/extensions/gsd/db/writers/reconcile.ts +500 -0
  346. package/src/resources/extensions/gsd/db/writers/status.ts +88 -0
  347. package/src/resources/extensions/gsd/db-workspace.ts +170 -0
  348. package/src/resources/extensions/gsd/delegation-policy.ts +3 -11
  349. package/src/resources/extensions/gsd/discussion-handoff.ts +276 -0
  350. package/src/resources/extensions/gsd/docs/preferences-reference.md +9 -0
  351. package/src/resources/extensions/gsd/doctor-environment.ts +8 -11
  352. package/src/resources/extensions/gsd/doctor-git-checks.ts +3 -3
  353. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +10 -3
  354. package/src/resources/extensions/gsd/doctor.ts +15 -5
  355. package/src/resources/extensions/gsd/error-classifier.ts +1 -1
  356. package/src/resources/extensions/gsd/git-conflict-state.ts +17 -1
  357. package/src/resources/extensions/gsd/git-service.ts +1 -0
  358. package/src/resources/extensions/gsd/gitignore.ts +3 -0
  359. package/src/resources/extensions/gsd/gsd-db.ts +185 -2373
  360. package/src/resources/extensions/gsd/guided-flow.ts +81 -561
  361. package/src/resources/extensions/gsd/guided-unit-completion.ts +275 -0
  362. package/src/resources/extensions/gsd/markdown-renderer.ts +2 -1
  363. package/src/resources/extensions/gsd/mcp-filter.ts +2 -1
  364. package/src/resources/extensions/gsd/mcp-tool-name.ts +35 -0
  365. package/src/resources/extensions/gsd/md-importer.ts +3 -3
  366. package/src/resources/extensions/gsd/migrate/safety.ts +17 -9
  367. package/src/resources/extensions/gsd/migration-auto-check.ts +30 -5
  368. package/src/resources/extensions/gsd/milestone-closeout-proof.ts +131 -0
  369. package/src/resources/extensions/gsd/milestone-closeout.ts +12 -4
  370. package/src/resources/extensions/gsd/milestone-merge-transaction.ts +47 -0
  371. package/src/resources/extensions/gsd/milestone-planning-persistence.ts +224 -0
  372. package/src/resources/extensions/gsd/milestone-readiness.ts +125 -0
  373. package/src/resources/extensions/gsd/milestone-settlement.ts +81 -0
  374. package/src/resources/extensions/gsd/milestone-validation-evidence.ts +95 -0
  375. package/src/resources/extensions/gsd/milestone-validation-verdict.ts +80 -0
  376. package/src/resources/extensions/gsd/model-cost-table.ts +1 -0
  377. package/src/resources/extensions/gsd/model-router.ts +3 -0
  378. package/src/resources/extensions/gsd/parallel-eligibility.ts +4 -5
  379. package/src/resources/extensions/gsd/parallel-merge.ts +12 -9
  380. package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +6 -5
  381. package/src/resources/extensions/gsd/parallel-orchestrator.ts +6 -2
  382. package/src/resources/extensions/gsd/paths.ts +9 -22
  383. package/src/resources/extensions/gsd/preferences-diagnostics.ts +98 -0
  384. package/src/resources/extensions/gsd/preferences-types.ts +16 -0
  385. package/src/resources/extensions/gsd/preferences.ts +191 -28
  386. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -0
  387. package/src/resources/extensions/gsd/prompts/execute-task.md +2 -0
  388. package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +3 -1
  389. package/src/resources/extensions/gsd/prompts/plan-milestone.md +2 -0
  390. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -0
  391. package/src/resources/extensions/gsd/prompts/refine-slice.md +1 -0
  392. package/src/resources/extensions/gsd/prompts/system.md +1 -1
  393. package/src/resources/extensions/gsd/provider-payload-policy.ts +140 -0
  394. package/src/resources/extensions/gsd/pull-request-process.ts +41 -0
  395. package/src/resources/extensions/gsd/quality-gate-closure.ts +140 -0
  396. package/src/resources/extensions/gsd/question-transport.ts +138 -0
  397. package/src/resources/extensions/gsd/recovery-classification.ts +14 -1
  398. package/src/resources/extensions/gsd/roadmap-slices.ts +8 -2
  399. package/src/resources/extensions/gsd/safety/evidence-collector.ts +36 -4
  400. package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +7 -2
  401. package/src/resources/extensions/gsd/safety/file-change-validator.ts +14 -0
  402. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +6 -2
  403. package/src/resources/extensions/gsd/state-transition-matrix.ts +42 -0
  404. package/src/resources/extensions/gsd/state.ts +15 -5
  405. package/src/resources/extensions/gsd/status-guards.ts +59 -8
  406. package/src/resources/extensions/gsd/templates/plan.md +7 -0
  407. package/src/resources/extensions/gsd/templates/project.md +1 -0
  408. package/src/resources/extensions/gsd/templates/roadmap.md +1 -1
  409. package/src/resources/extensions/gsd/templates/uat.md +5 -1
  410. package/src/resources/extensions/gsd/tests/ask-user-questions-render.test.ts +92 -0
  411. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +29 -1
  412. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +444 -5
  413. package/src/resources/extensions/gsd/tests/auto-milestone-target.test.ts +23 -0
  414. package/src/resources/extensions/gsd/tests/auto-model-selection-tool-poisoning.test.ts +18 -0
  415. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +133 -4
  416. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +3 -1
  417. package/src/resources/extensions/gsd/tests/auto-post-unit-evidence-crossref-4909.test.ts +46 -0
  418. package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +34 -0
  419. package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +2 -2
  420. package/src/resources/extensions/gsd/tests/auto-worktree-repair.test.ts +4 -2
  421. package/src/resources/extensions/gsd/tests/canonical-milestone-root.test.ts +20 -0
  422. package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +22 -0
  423. package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +22 -0
  424. package/src/resources/extensions/gsd/tests/commands-dispatcher-workspace-git.test.ts +11 -0
  425. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +38 -1
  426. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +34 -3
  427. package/src/resources/extensions/gsd/tests/dispatch-run-uat-browser-tools.test.ts +88 -0
  428. package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +18 -0
  429. package/src/resources/extensions/gsd/tests/evidence-xref-gsd-exec.test.ts +157 -0
  430. package/src/resources/extensions/gsd/tests/execute-task-rendering.test.ts +1 -0
  431. package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +33 -1
  432. package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-no-blockers.md +1 -5
  433. package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-with-blockers.md +1 -5
  434. package/src/resources/extensions/gsd/tests/gate-state-canonicalization.test.ts +48 -1
  435. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +5 -4
  436. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +1 -1
  437. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +3 -2
  438. package/src/resources/extensions/gsd/tests/mcp-tool-name.test.ts +34 -0
  439. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +143 -1
  440. package/src/resources/extensions/gsd/tests/milestone-closeout-proof.test.ts +99 -0
  441. package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +25 -0
  442. package/src/resources/extensions/gsd/tests/milestone-merge-transaction.test.ts +46 -0
  443. package/src/resources/extensions/gsd/tests/milestone-readiness.test.ts +65 -0
  444. package/src/resources/extensions/gsd/tests/milestone-validation-evidence.test.ts +41 -0
  445. package/src/resources/extensions/gsd/tests/milestone-validation-verdict.test.ts +55 -0
  446. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +45 -0
  447. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +2 -0
  448. package/src/resources/extensions/gsd/tests/planning-crossval.test.ts +45 -0
  449. package/src/resources/extensions/gsd/tests/preferences-diagnostics.test.ts +67 -0
  450. package/src/resources/extensions/gsd/tests/preferences.test.ts +183 -0
  451. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +46 -0
  452. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +9 -0
  453. package/src/resources/extensions/gsd/tests/provider-payload-policy.test.ts +165 -0
  454. package/src/resources/extensions/gsd/tests/pull-request-process.test.ts +47 -0
  455. package/src/resources/extensions/gsd/tests/recovery-classification-illegal-transition.test.ts +30 -0
  456. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +185 -1
  457. package/src/resources/extensions/gsd/tests/roadmap-parse-regression.test.ts +40 -0
  458. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +25 -1
  459. package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +38 -0
  460. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +80 -0
  461. package/src/resources/extensions/gsd/tests/session-switch-clears-pending-autostart.test.ts +108 -0
  462. package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +144 -7
  463. package/src/resources/extensions/gsd/tests/stale-queued-milestone.test.ts +27 -0
  464. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +2 -1
  465. package/src/resources/extensions/gsd/tests/state-transition-matrix.test.ts +36 -0
  466. package/src/resources/extensions/gsd/tests/status-guards.test.ts +38 -0
  467. package/src/resources/extensions/gsd/tests/tool-availability-audit.test.ts +35 -0
  468. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +35 -42
  469. package/src/resources/extensions/gsd/tests/uat-policy.test.ts +23 -0
  470. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +47 -0
  471. package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +86 -1
  472. package/src/resources/extensions/gsd/tests/validate-milestone-stuck-guard.test.ts +39 -0
  473. package/src/resources/extensions/gsd/tests/web-app-uat.test.ts +150 -0
  474. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +126 -9
  475. package/src/resources/extensions/gsd/tests/workspace-git-preflight.test.ts +15 -0
  476. package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +41 -4
  477. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +43 -1
  478. package/src/resources/extensions/gsd/tests/worktree-placement.test.ts +113 -0
  479. package/src/resources/extensions/gsd/tests/worktree-projection-writers.test.ts +1 -1
  480. package/src/resources/extensions/gsd/tests/worktree-reentry.test.ts +1 -1
  481. package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +3 -1
  482. package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +12 -6
  483. package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +2 -2
  484. package/src/resources/extensions/gsd/tests/worktree-telemetry.test.ts +22 -0
  485. package/src/resources/extensions/gsd/tests/write-gate.test.ts +121 -0
  486. package/src/resources/extensions/gsd/tool-contract.ts +86 -8
  487. package/src/resources/extensions/gsd/tool-presentation-plan.ts +16 -33
  488. package/src/resources/extensions/gsd/tool-surface-snapshot.ts +47 -0
  489. package/src/resources/extensions/gsd/tools/complete-slice.ts +23 -58
  490. package/src/resources/extensions/gsd/tools/exec-tool.ts +5 -5
  491. package/src/resources/extensions/gsd/tools/plan-milestone.ts +19 -160
  492. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +43 -0
  493. package/src/resources/extensions/gsd/tools/reopen-milestone.ts +11 -38
  494. package/src/resources/extensions/gsd/tools/reopen-slice.ts +14 -42
  495. package/src/resources/extensions/gsd/tools/skip-slice.ts +18 -44
  496. package/src/resources/extensions/gsd/tools/validate-milestone.ts +25 -84
  497. package/src/resources/extensions/gsd/uat-policy.ts +19 -10
  498. package/src/resources/extensions/gsd/uat-run.ts +10 -14
  499. package/src/resources/extensions/gsd/undo.ts +9 -8
  500. package/src/resources/extensions/gsd/unit-context-composer.ts +85 -20
  501. package/src/resources/extensions/gsd/unit-runtime.ts +3 -2
  502. package/src/resources/extensions/gsd/unit-tool-contracts.ts +2 -1
  503. package/src/resources/extensions/gsd/user-input-boundary.ts +18 -0
  504. package/src/resources/extensions/gsd/validation-block-guard.ts +2 -0
  505. package/src/resources/extensions/gsd/web-app-uat.ts +101 -0
  506. package/src/resources/extensions/gsd/workflow-mcp.ts +22 -110
  507. package/src/resources/extensions/gsd/workflow-reconcile.ts +3 -3
  508. package/src/resources/extensions/gsd/workflow-tool-surface.ts +73 -0
  509. package/src/resources/extensions/gsd/workspace-git-guard.ts +1 -0
  510. package/src/resources/extensions/gsd/worktree-git-recovery.ts +308 -0
  511. package/src/resources/extensions/gsd/worktree-lifecycle.ts +17 -17
  512. package/src/resources/extensions/gsd/worktree-manager.ts +47 -28
  513. package/src/resources/extensions/gsd/worktree-placement.ts +63 -0
  514. package/src/resources/extensions/gsd/worktree-reentry.ts +10 -7
  515. package/src/resources/extensions/gsd/worktree-root.ts +17 -6
  516. package/src/resources/extensions/gsd/worktree-safety.ts +8 -5
  517. package/src/resources/extensions/gsd/worktree-session-state.ts +12 -10
  518. package/src/resources/extensions/gsd/worktree-state-projection.ts +55 -7
  519. package/src/resources/extensions/gsd/worktree-telemetry.ts +16 -0
  520. package/src/resources/extensions/shared/interview-ui.ts +15 -2
  521. package/src/resources/shared/claude-runtime-floor.ts +248 -0
  522. package/src/resources/skills/gsd-browser/SKILL.md +1 -1
  523. package/dist/web/standalone/.next/static/chunks/2659.feb6499ca863ebfc.js +0 -1
  524. package/dist/web/standalone/.next/static/chunks/2772.151789db0edea835.js +0 -1
  525. package/dist/web/standalone/.next/static/chunks/4283.10a065467b5340d8.js +0 -2
  526. package/dist/web/standalone/.next/static/chunks/5826.960dc4634cc9b0d3.js +0 -1
  527. package/dist/web/standalone/.next/static/chunks/796.46f811c0fac23aab.js +0 -10
  528. package/dist/web/standalone/.next/static/chunks/8785.d32f7a61f55c1600.js +0 -1
  529. /package/dist/web/standalone/.next/static/{Qbr81pQ-pbQXP4bq2VXLv → C24pqUd-aru-l0Dp0gLZP}/_buildManifest.js +0 -0
  530. /package/dist/web/standalone/.next/static/{Qbr81pQ-pbQXP4bq2VXLv → C24pqUd-aru-l0Dp0gLZP}/_ssgManifest.js +0 -0
@@ -0,0 +1,156 @@
1
+ // Project/App: gsd-pi
2
+ // File Purpose: Persist planned milestone roadmaps and their DB-backed projections.
3
+ import { clearParseCache } from "./files.js";
4
+ import { isClosedStatus } from "./status-guards.js";
5
+ import { transaction, getMilestone, getMilestoneSlices, getSlice, insertMilestone, insertSlice, upsertMilestonePlanning, upsertSlicePlanning, } from "./gsd-db.js";
6
+ import { invalidateStateCache } from "./state.js";
7
+ import { renderRoadmapFromDb } from "./markdown-renderer.js";
8
+ import { renderAllProjections } from "./workflow-projections.js";
9
+ import { writeManifest } from "./workflow-manifest.js";
10
+ import { appendEvent } from "./workflow-events.js";
11
+ import { logWarning } from "./workflow-logger.js";
12
+ function validatePlanPromotion(params) {
13
+ const existingMilestone = getMilestone(params.milestoneId);
14
+ if (existingMilestone && isClosedStatus(existingMilestone.status)) {
15
+ return `cannot re-plan milestone ${params.milestoneId}: it is already complete`;
16
+ }
17
+ // Guard: refuse to re-plan a milestone that would drop completed slices (#2960).
18
+ // Allow re-planning when all completed slices are still present in the
19
+ // incoming plan — their status is preserved below (#2558). Block only when
20
+ // the new plan omits a completed slice, which could shadow completed work.
21
+ const existingSlices = getMilestoneSlices(params.milestoneId);
22
+ const completedSlices = existingSlices.filter(s => isClosedStatus(s.status));
23
+ if (completedSlices.length > 0) {
24
+ const incomingSliceIds = new Set(params.slices.map(s => s.sliceId));
25
+ const droppedCompleted = completedSlices.filter(s => !incomingSliceIds.has(s.id));
26
+ if (droppedCompleted.length > 0) {
27
+ return `cannot re-plan milestone ${params.milestoneId}: ${droppedCompleted.length} completed slice(s) would be dropped (${droppedCompleted.map(s => s.id).join(", ")}). Use gsd_reassess_roadmap to modify the roadmap.`;
28
+ }
29
+ }
30
+ // Validate depends_on: all dependencies must exist and be complete
31
+ if (params.dependsOn && params.dependsOn.length > 0) {
32
+ for (const depId of params.dependsOn) {
33
+ const dep = getMilestone(depId);
34
+ if (!dep) {
35
+ return `depends_on references unknown milestone: ${depId}`;
36
+ }
37
+ if (!isClosedStatus(dep.status)) {
38
+ return `depends_on milestone ${depId} is not yet complete (status: ${dep.status})`;
39
+ }
40
+ }
41
+ }
42
+ return null;
43
+ }
44
+ function writePlanRows(params) {
45
+ insertMilestone({
46
+ id: params.milestoneId,
47
+ title: params.title,
48
+ status: params.status ?? "active",
49
+ depends_on: params.dependsOn ?? [],
50
+ });
51
+ upsertMilestonePlanning(params.milestoneId, {
52
+ title: params.title,
53
+ status: params.status ?? "active",
54
+ depends_on: params.dependsOn ?? [],
55
+ vision: params.vision,
56
+ successCriteria: params.successCriteria,
57
+ keyRisks: params.keyRisks,
58
+ proofStrategy: params.proofStrategy,
59
+ verificationContract: params.verificationContract,
60
+ verificationIntegration: params.verificationIntegration,
61
+ verificationOperational: params.verificationOperational,
62
+ verificationUat: params.verificationUat,
63
+ definitionOfDone: params.definitionOfDone,
64
+ requirementCoverage: params.requirementCoverage,
65
+ boundaryMapMarkdown: params.boundaryMapMarkdown,
66
+ });
67
+ for (let i = 0; i < params.slices.length; i++) {
68
+ const slice = params.slices[i];
69
+ // Preserve completed/done status on re-plan (#2558).
70
+ // Without this, a re-plan after milestone transition would reset
71
+ // already-completed slices back to "pending".
72
+ const existing = getSlice(params.milestoneId, slice.sliceId);
73
+ const status = existing && (existing.status === "complete" || existing.status === "done")
74
+ ? existing.status
75
+ : "pending";
76
+ insertSlice({
77
+ id: slice.sliceId,
78
+ milestoneId: params.milestoneId,
79
+ title: slice.title,
80
+ status,
81
+ risk: slice.risk,
82
+ depends: slice.depends,
83
+ demo: slice.demo,
84
+ sequence: i + 1, // Preserve agent-ordered sequence (#3356)
85
+ // ADR-011: pass undefined through so ON CONFLICT preserves existing values
86
+ // when the caller omitted the fields on a re-plan.
87
+ isSketch: slice.isSketch,
88
+ sketchScope: slice.sketchScope,
89
+ });
90
+ upsertSlicePlanning(params.milestoneId, slice.sliceId, {
91
+ goal: slice.goal,
92
+ successCriteria: slice.successCriteria,
93
+ proofLevel: slice.proofLevel,
94
+ integrationClosure: slice.integrationClosure,
95
+ observabilityImpact: slice.observabilityImpact,
96
+ });
97
+ }
98
+ }
99
+ async function renderPlanArtifacts(basePath, params) {
100
+ try {
101
+ const renderResult = await renderRoadmapFromDb(basePath, params.milestoneId);
102
+ return renderResult.roadmapPath;
103
+ }
104
+ catch (renderErr) {
105
+ logWarning("tool", `plan_milestone — render failed (DB rows preserved for debugging): ${renderErr.message}`);
106
+ invalidateStateCache();
107
+ return { error: `render failed: ${renderErr.message}` };
108
+ }
109
+ }
110
+ async function runPostPlanHooks(basePath, params) {
111
+ try {
112
+ await renderAllProjections(basePath, params.milestoneId);
113
+ writeManifest(basePath);
114
+ appendEvent(basePath, {
115
+ cmd: "plan-milestone",
116
+ params: { milestoneId: params.milestoneId },
117
+ ts: new Date().toISOString(),
118
+ actor: "agent",
119
+ actor_name: params.actorName,
120
+ trigger_reason: params.triggerReason,
121
+ });
122
+ }
123
+ catch (hookErr) {
124
+ logWarning("tool", `plan-milestone post-mutation hook warning: ${hookErr.message}`);
125
+ }
126
+ }
127
+ export async function persistMilestonePlan(params, basePath) {
128
+ // ── Guards + DB writes inside a single transaction (prevents TOCTOU) ───
129
+ // Guards must be inside the transaction so the state they check cannot
130
+ // change between the read and the write (#2723).
131
+ let guardError = null;
132
+ try {
133
+ transaction(() => {
134
+ guardError = validatePlanPromotion(params);
135
+ if (guardError)
136
+ return;
137
+ writePlanRows(params);
138
+ });
139
+ }
140
+ catch (err) {
141
+ return { error: `db write failed: ${err.message}` };
142
+ }
143
+ if (guardError) {
144
+ return { error: guardError };
145
+ }
146
+ const roadmapPath = await renderPlanArtifacts(basePath, params);
147
+ if (typeof roadmapPath !== "string")
148
+ return roadmapPath;
149
+ invalidateStateCache();
150
+ clearParseCache();
151
+ await runPostPlanHooks(basePath, params);
152
+ return {
153
+ milestoneId: params.milestoneId,
154
+ roadmapPath,
155
+ };
156
+ }
@@ -0,0 +1,77 @@
1
+ // Project/App: gsd-pi
2
+ // File Purpose: Classify milestone readiness from DB status, slices, and artifacts.
3
+ import { readFileSync } from "node:fs";
4
+ import { getMilestone, getMilestoneSlices, isDbAvailable } from "./gsd-db.js";
5
+ import { parseRoadmapSlices } from "./roadmap-slices.js";
6
+ import { logWarning } from "./workflow-logger.js";
7
+ export function classifyMilestoneReadiness(input) {
8
+ const hasContext = input.hasContext === true;
9
+ const hasDraftContext = !hasContext && input.hasDraftContext === true;
10
+ const hasSummary = input.hasSummary === true;
11
+ const sliceCount = input.sliceCount ?? 0;
12
+ const hasExecutablePlan = sliceCount > 0;
13
+ const status = input.status ?? null;
14
+ if (status === "complete" || hasSummary) {
15
+ return { kind: "terminal", hasContext, hasDraftContext, hasExecutablePlan };
16
+ }
17
+ if (status === "queued" && !hasContext && sliceCount === 0) {
18
+ return { kind: "queued-shell", hasContext, hasDraftContext, hasExecutablePlan };
19
+ }
20
+ if ((status === "needs-discussion" && !hasContext) || hasDraftContext) {
21
+ return { kind: "needs-discussion", hasContext, hasDraftContext, hasExecutablePlan };
22
+ }
23
+ if (hasExecutablePlan) {
24
+ return { kind: "executable-plan", hasContext, hasDraftContext, hasExecutablePlan };
25
+ }
26
+ return { kind: "planning-pending", hasContext, hasDraftContext, hasExecutablePlan };
27
+ }
28
+ export function readinessNeedsDiscussion(readiness) {
29
+ return readiness.kind === "needs-discussion" ||
30
+ (readiness.kind === "queued-shell" && readiness.hasDraftContext);
31
+ }
32
+ export function describeMilestoneReadinessPhase(phase) {
33
+ switch (phase) {
34
+ case "needs-discussion":
35
+ return {
36
+ label: "Discuss milestone draft",
37
+ description: "Milestone has a draft context — needs discussion before planning.",
38
+ };
39
+ case "pre-planning":
40
+ return {
41
+ label: "Research & plan milestone",
42
+ description: "Scout the landscape and create the roadmap.",
43
+ };
44
+ default:
45
+ return null;
46
+ }
47
+ }
48
+ function executablePlanSliceCount(milestoneId, roadmapFile) {
49
+ if (isDbAvailable()) {
50
+ return getMilestoneSlices(milestoneId).length;
51
+ }
52
+ if (!roadmapFile)
53
+ return 0;
54
+ try {
55
+ return parseRoadmapSlices(readFileSync(roadmapFile, "utf-8")).length;
56
+ }
57
+ catch (e) {
58
+ logWarning("guided", `failed to parse roadmap slices for ${milestoneId}: ${e.message}`);
59
+ return 0;
60
+ }
61
+ }
62
+ export function assessMilestoneHandoffReadiness(input) {
63
+ const milestone = isDbAvailable() ? getMilestone(input.milestoneId) : null;
64
+ return classifyMilestoneReadiness({
65
+ status: milestone?.status,
66
+ hasContext: input.contextFile != null,
67
+ sliceCount: executablePlanSliceCount(input.milestoneId, input.roadmapFile),
68
+ });
69
+ }
70
+ export function formatAcceptedDiscussHandoffMessage(milestoneId, readiness) {
71
+ if (readiness.hasExecutablePlan)
72
+ return `Milestone ${milestoneId} ready.`;
73
+ if (readiness.hasContext) {
74
+ return `Milestone ${milestoneId} context captured. Continuing the planning pipeline.`;
75
+ }
76
+ return `Milestone ${milestoneId} planning artifacts captured. Continuing the planning pipeline.`;
77
+ }
@@ -0,0 +1,50 @@
1
+ // Project/App: gsd-pi
2
+ // File Purpose: Milestone closeout settlement state across DB proof, artifacts, merge, and cleanup.
3
+ import { isInAutoWorktree } from "./auto-worktree.js";
4
+ import { formatCloseoutProofBlock, proveMilestoneCloseout, } from "./milestone-closeout-proof.js";
5
+ import { resolveCloseoutArtifactProjection } from "./artifact-projection.js";
6
+ function isActiveUnmergedWorktree(input) {
7
+ if (!input.milestoneId || input.milestoneMerged)
8
+ return false;
9
+ return isInAutoWorktree(input.basePath);
10
+ }
11
+ export function evaluateAllCompleteSettlement(input) {
12
+ if (input.statePhase !== "complete") {
13
+ return { ok: true, reason: "not-applicable" };
14
+ }
15
+ if (!isActiveUnmergedWorktree(input)) {
16
+ return { ok: true, reason: "settled" };
17
+ }
18
+ const milestoneId = input.milestoneId;
19
+ if (!milestoneId) {
20
+ return { ok: true, reason: "settled" };
21
+ }
22
+ const projection = resolveCloseoutArtifactProjection({
23
+ milestoneId,
24
+ basePath: input.basePath,
25
+ originalBasePath: input.originalBasePath,
26
+ });
27
+ const proof = proveMilestoneCloseout(milestoneId, {
28
+ refreshFromDisk: true,
29
+ summaryArtifactBasePath: projection.summaryArtifactBasePath,
30
+ });
31
+ if (!proof.ok) {
32
+ return {
33
+ ok: false,
34
+ reason: "closeout-blocked",
35
+ action: "pause",
36
+ message: `${formatCloseoutProofBlock(proof)} The milestone branch has not been merged to main.`,
37
+ nextAction: `Resolve closeout blockers, then retry \`/gsd dispatch complete-milestone ${milestoneId}\`.`,
38
+ milestoneId,
39
+ };
40
+ }
41
+ return {
42
+ ok: false,
43
+ reason: "merge-pending",
44
+ action: "pause",
45
+ message: `Milestone ${milestoneId} is complete, but its worktree branch has not been merged to main. ` +
46
+ `Retry with \`/gsd dispatch complete-milestone ${milestoneId}\` or merge manually.`,
47
+ nextAction: `Retry \`/gsd dispatch complete-milestone ${milestoneId}\` or merge manually.`,
48
+ milestoneId,
49
+ };
50
+ }
@@ -0,0 +1,73 @@
1
+ // Project/App: gsd-pi
2
+ // File Purpose: Forwarded validation evidence rules for milestone validation.
3
+ import { getArtifact, getMilestone, getMilestoneSlices } from "./gsd-db.js";
4
+ import { loadFile } from "./files.js";
5
+ import { resolveSliceFile } from "./paths.js";
6
+ import { compactTextParts, hasBrowserEvidenceText, hasBrowserRequiredText, } from "./browser-evidence.js";
7
+ export function hasRuntimeExecutableUatEvidenceText(text) {
8
+ if (!/\buatType:\s*runtime-executable\b/i.test(text))
9
+ return false;
10
+ if (!/\bverdict:\s*PASS\b/i.test(text))
11
+ return false;
12
+ return /^\|\s*[^|\n]+\s*\|\s*runtime\s*\|\s*PASS\s*\|[^|\n]*\bgsd_uat_exec\b/mi.test(text);
13
+ }
14
+ export async function browserEvidenceGateRequiresAttention(params, basePath) {
15
+ if (params.verdict !== "pass")
16
+ return false;
17
+ const milestone = getMilestone(params.milestoneId);
18
+ const slices = getMilestoneSlices(params.milestoneId);
19
+ const requirementText = compactTextParts([
20
+ milestone?.vision,
21
+ milestone?.success_criteria,
22
+ milestone?.verification_uat,
23
+ params.successCriteriaChecklist,
24
+ params.verificationClasses,
25
+ ...slices.flatMap((slice) => [
26
+ slice.demo,
27
+ slice.goal,
28
+ slice.success_criteria,
29
+ ]),
30
+ ]);
31
+ if (!hasBrowserRequiredText(requirementText))
32
+ return false;
33
+ const sliceEvidencePairs = [];
34
+ for (const slice of slices) {
35
+ const chunks = [];
36
+ const artifactPath = `milestones/${params.milestoneId}/slices/${slice.id}/${slice.id}-ASSESSMENT.md`;
37
+ const artifact = getArtifact(artifactPath);
38
+ if (artifact?.full_content)
39
+ chunks.push(artifact.full_content);
40
+ const assessmentPath = resolveSliceFile(basePath, params.milestoneId, slice.id, "ASSESSMENT");
41
+ const assessmentContent = assessmentPath ? await loadFile(assessmentPath) : null;
42
+ if (assessmentContent)
43
+ chunks.push(assessmentContent);
44
+ sliceEvidencePairs.push({
45
+ sliceRequirementText: compactTextParts([slice.demo, slice.goal, slice.success_criteria]),
46
+ evidenceText: chunks.join("\n\n"),
47
+ });
48
+ }
49
+ const browserRequiringSlices = sliceEvidencePairs.filter((slice) => hasBrowserRequiredText(slice.sliceRequirementText));
50
+ const runtimeBypasses = browserRequiringSlices.length > 0
51
+ ? browserRequiringSlices.every((slice) => hasRuntimeExecutableUatEvidenceText(slice.evidenceText))
52
+ : sliceEvidencePairs.some((slice) => hasRuntimeExecutableUatEvidenceText(slice.evidenceText));
53
+ if (runtimeBypasses)
54
+ return false;
55
+ const persistedEvidence = sliceEvidencePairs.map((slice) => slice.evidenceText).join("\n\n");
56
+ const validationEvidence = compactTextParts([
57
+ params.successCriteriaChecklist,
58
+ params.verificationClasses,
59
+ params.verdictRationale,
60
+ params.remediationPlan,
61
+ ]);
62
+ return !hasBrowserEvidenceText(`${persistedEvidence}\n\n${validationEvidence}`);
63
+ }
64
+ export function applyBrowserEvidenceGate(params) {
65
+ const note = "Browser evidence gate: Browser-observable acceptance criteria were detected, but no persisted ASSESSMENT or validation evidence recorded browser actions with assertions. Downgraded from pass to needs-attention.";
66
+ return {
67
+ ...params,
68
+ verdict: "needs-attention",
69
+ verdictRationale: params.verdictRationale.trim()
70
+ ? `${params.verdictRationale.trim()}\n\n${note}`
71
+ : note,
72
+ };
73
+ }
@@ -0,0 +1,57 @@
1
+ // Project/App: gsd-pi
2
+ // File Purpose: Resolve the authoritative milestone validation verdict across DB and disk projections.
3
+ import { existsSync } from "node:fs";
4
+ import { join } from "node:path";
5
+ import { resolveExpectedArtifactPath } from "./auto-artifact-paths.js";
6
+ import { loadFile } from "./files.js";
7
+ import { getLatestAssessmentByScope, isDbAvailable } from "./gsd-db.js";
8
+ import { gsdProjectionRoot } from "./paths.js";
9
+ import { extractVerdict, isValidMilestoneVerdict, } from "./verdict-parser.js";
10
+ import { resolveCanonicalMilestoneRoot } from "./worktree-manager.js";
11
+ import { resolveWorktreeProjectRoot } from "./worktree-root.js";
12
+ function verdictFromContent(content) {
13
+ if (!content)
14
+ return undefined;
15
+ const verdict = extractVerdict(content);
16
+ return verdict && isValidMilestoneVerdict(verdict) ? verdict : undefined;
17
+ }
18
+ function verdictFromDb(milestoneId) {
19
+ if (!isDbAvailable())
20
+ return undefined;
21
+ const assessment = getLatestAssessmentByScope(milestoneId, "milestone-validation");
22
+ const status = typeof assessment?.status === "string" ? assessment.status : undefined;
23
+ return status && isValidMilestoneVerdict(status) ? status : undefined;
24
+ }
25
+ async function verdictFromValidationPath(path) {
26
+ if (!path || !existsSync(path))
27
+ return undefined;
28
+ return verdictFromContent(await loadFile(path));
29
+ }
30
+ /**
31
+ * Resolve the milestone validation verdict using the same authority order as
32
+ * DB-backed state derivation, with filesystem fallbacks that mirror
33
+ * `resolveExpectedArtifactPath` (canonical worktree projection, then project
34
+ * root). Manual `/gsd verdict` overrides persist to the DB first; a stale
35
+ * worktree-local VALIDATION.md must not re-block auto-mode after the override.
36
+ */
37
+ export async function resolveMilestoneValidationVerdict(basePath, milestoneId) {
38
+ const dbVerdict = verdictFromDb(milestoneId);
39
+ if (dbVerdict)
40
+ return dbVerdict;
41
+ const canonicalBase = resolveCanonicalMilestoneRoot(basePath, milestoneId);
42
+ const canonicalPath = resolveExpectedArtifactPath("validate-milestone", milestoneId, canonicalBase);
43
+ const canonicalVerdict = await verdictFromValidationPath(canonicalPath);
44
+ if (canonicalVerdict)
45
+ return canonicalVerdict;
46
+ const projectRoot = resolveWorktreeProjectRoot(basePath);
47
+ if (projectRoot !== canonicalBase) {
48
+ const projectPath = resolveExpectedArtifactPath("validate-milestone", milestoneId, projectRoot);
49
+ const projectVerdict = await verdictFromValidationPath(projectPath);
50
+ if (projectVerdict)
51
+ return projectVerdict;
52
+ }
53
+ // Last resort: direct canonical projection path even when resolveDir helpers
54
+ // have not materialized the milestone directory yet.
55
+ const directPath = join(gsdProjectionRoot(canonicalBase), "milestones", milestoneId, `${milestoneId}-VALIDATION.md`);
56
+ return verdictFromValidationPath(directPath);
57
+ }
@@ -13,6 +13,7 @@ export const BUNDLED_COST_TABLE = [
13
13
  { id: "claude-opus-4-6", inputPer1k: 0.005, outputPer1k: 0.025, updatedAt: "2026-04-16" },
14
14
  { id: "claude-opus-4-7", inputPer1k: 0.005, outputPer1k: 0.025, updatedAt: "2026-04-16" },
15
15
  { id: "claude-opus-4-8", inputPer1k: 0.005, outputPer1k: 0.025, updatedAt: "2026-05-28" },
16
+ { id: "claude-fable-5", inputPer1k: 0.010, outputPer1k: 0.050, updatedAt: "2026-06-09" },
16
17
  { id: "claude-sonnet-4-6", inputPer1k: 0.003, outputPer1k: 0.015, updatedAt: "2025-03-15" },
17
18
  { id: "claude-haiku-4-5", inputPer1k: 0.0008, outputPer1k: 0.004, updatedAt: "2025-03-15" },
18
19
  { id: "claude-sonnet-4-5-20250514", inputPer1k: 0.003, outputPer1k: 0.015, updatedAt: "2025-03-15" },
@@ -35,6 +35,7 @@ export const MODEL_CAPABILITY_TIER = {
35
35
  "claude-opus-4-6": "heavy",
36
36
  "claude-opus-4-7": "heavy",
37
37
  "claude-opus-4-8": "heavy",
38
+ "claude-fable-5": "heavy",
38
39
  "claude-3-opus-latest": "heavy",
39
40
  "gpt-4-turbo": "heavy",
40
41
  "gpt-5": "heavy",
@@ -61,6 +62,7 @@ const MODEL_COST_PER_1K_INPUT = {
61
62
  "claude-opus-4-6": 0.005,
62
63
  "claude-opus-4-7": 0.005,
63
64
  "claude-opus-4-8": 0.005,
65
+ "claude-fable-5": 0.010,
64
66
  "gpt-4o-mini": 0.00015,
65
67
  "gpt-4o": 0.0025,
66
68
  "gpt-4.1": 0.002,
@@ -94,6 +96,7 @@ export const MODEL_CAPABILITY_PROFILES = {
94
96
  "claude-opus-4-6": { coding: 95, debugging: 90, research: 85, reasoning: 95, speed: 30, longContext: 80, instruction: 90 },
95
97
  "claude-opus-4-7": { coding: 95, debugging: 90, research: 85, reasoning: 95, speed: 30, longContext: 80, instruction: 90 },
96
98
  "claude-opus-4-8": { coding: 97, debugging: 92, research: 87, reasoning: 97, speed: 30, longContext: 85, instruction: 92 },
99
+ "claude-fable-5": { coding: 97, debugging: 92, research: 87, reasoning: 97, speed: 30, longContext: 85, instruction: 92 },
97
100
  "claude-sonnet-4-6": { coding: 85, debugging: 80, research: 75, reasoning: 80, speed: 60, longContext: 75, instruction: 85 },
98
101
  "claude-sonnet-4-5-20250514": { coding: 85, debugging: 80, research: 75, reasoning: 80, speed: 60, longContext: 75, instruction: 85 },
99
102
  "claude-3-5-sonnet-latest": { coding: 82, debugging: 78, research: 72, reasoning: 78, speed: 62, longContext: 70, instruction: 82 },
@@ -4,11 +4,10 @@
4
4
  * Analyzes which milestones can safely run in parallel by checking
5
5
  * dependency satisfaction and file overlap across slice plans.
6
6
  */
7
- import { existsSync } from "node:fs";
8
7
  import { deriveState } from "./state.js";
9
- import { resolveGsdPathContract } from "./paths.js";
10
8
  import { findMilestoneIds } from "./guided-flow.js";
11
- import { isDbAvailable, getMilestoneSlices, getSliceTasks, openDatabase } from "./gsd-db.js";
9
+ import { isDbAvailable, getMilestoneSlices, getSliceTasks } from "./gsd-db.js";
10
+ import { openExistingWorkflowDatabase } from "./db-workspace.js";
12
11
  // ─── File Collection ─────────────────────────────────────────────────────────
13
12
  /**
14
13
  * Collect all `filesLikelyTouched` across every slice plan in a milestone.
@@ -64,9 +63,7 @@ function detectFileOverlaps(fileSets) {
64
63
  */
65
64
  export async function analyzeParallelEligibility(basePath) {
66
65
  if (!isDbAvailable()) {
67
- const { projectDb } = resolveGsdPathContract(basePath);
68
- if (existsSync(projectDb))
69
- openDatabase(projectDb);
66
+ openExistingWorkflowDatabase(basePath);
70
67
  }
71
68
  const milestoneIds = findMilestoneIds(basePath);
72
69
  const state = await deriveState(basePath);
@@ -5,9 +5,9 @@
5
5
  * with safety checks for parallel execution context.
6
6
  */
7
7
  import { existsSync, readdirSync } from "node:fs";
8
- import { join } from "node:path";
9
8
  import { spawnSync } from "node:child_process";
10
9
  import { resolveGsdPathContract } from "./paths.js";
10
+ import { worktreePathFor, worktreesDirs } from "./worktree-placement.js";
11
11
  import { getAutoWorktreePath } from "./auto-worktree.js";
12
12
  import { buildWorktreeLifecycleDeps } from "./auto.js";
13
13
  import { mergeMilestoneStandalone, } from "./worktree-lifecycle.js";
@@ -22,7 +22,7 @@ import { logWarning } from "./workflow-logger.js";
22
22
  * Returns true when milestones.status = 'complete' in project gsd.db.
23
23
  */
24
24
  export function isMilestoneCompleteInProjectDb(basePath, mid) {
25
- const workRoot = join(basePath, ".gsd", "worktrees", mid);
25
+ const workRoot = worktreePathFor(basePath, mid);
26
26
  const dbPath = resolveGsdPathContract(workRoot, basePath).projectDb;
27
27
  if (!existsSync(dbPath))
28
28
  return false;
@@ -41,16 +41,19 @@ export function isMilestoneCompleteInProjectDb(basePath, mid) {
41
41
  */
42
42
  function discoverDbCompletedMilestones(basePath) {
43
43
  const completed = new Set();
44
- const worktreeDir = join(basePath, ".gsd", "worktrees");
45
- try {
46
- for (const entry of readdirSync(worktreeDir)) {
47
- if (entry.startsWith("M") && isMilestoneCompleteInProjectDb(basePath, entry)) {
48
- completed.add(entry);
44
+ for (const worktreeDir of worktreesDirs(basePath)) {
45
+ if (!existsSync(worktreeDir))
46
+ continue;
47
+ try {
48
+ for (const entry of readdirSync(worktreeDir)) {
49
+ if (entry.startsWith("M") && isMilestoneCompleteInProjectDb(basePath, entry)) {
50
+ completed.add(entry);
51
+ }
49
52
  }
50
53
  }
51
- }
52
- catch (e) {
53
- logWarning("parallel", `readdirSync for completed set failed: ${e.message}`);
54
+ catch (e) {
55
+ logWarning("parallel", `readdirSync for completed set failed: ${e.message}`);
56
+ }
54
57
  }
55
58
  return completed;
56
59
  }
@@ -88,7 +91,7 @@ export function determineMergeOrder(workers, order = "sequential", basePath) {
88
91
  title: mid,
89
92
  pid: 0,
90
93
  process: null,
91
- worktreePath: basePath ? join(basePath, ".gsd", "worktrees", mid) : "",
94
+ worktreePath: basePath ? worktreePathFor(basePath, mid) : "",
92
95
  startedAt: 0,
93
96
  state: "stopped",
94
97
  cost: 0,
@@ -7,6 +7,7 @@ import { matchesKey, Key } from "@gsd/pi-tui";
7
7
  import { formatDuration } from "../shared/mod.js";
8
8
  import { formattedShortcutPair } from "./shortcut-defs.js";
9
9
  import { resolveGsdPathContract } from "./paths.js";
10
+ import { worktreePathFor, worktreesDirs } from "./worktree-placement.js";
10
11
  import { renderBar, renderDialogFrame, renderKeyHints, renderProgressBar, safeLine, statusGlyph, } from "./tui/render-kit.js";
11
12
  // ─── Data Helpers ─────────────────────────────────────────────────────────
12
13
  function readJsonSafe(filePath) {
@@ -42,7 +43,6 @@ function tailRead(filePath, maxBytes) {
42
43
  }
43
44
  function discoverWorkers(basePath) {
44
45
  const parallelDir = join(basePath, ".gsd", "parallel");
45
- const worktreeDir = join(basePath, ".gsd", "worktrees");
46
46
  const mids = new Set();
47
47
  if (existsSync(parallelDir)) {
48
48
  try {
@@ -56,7 +56,9 @@ function discoverWorkers(basePath) {
56
56
  }
57
57
  catch { /* skip */ }
58
58
  }
59
- if (existsSync(worktreeDir)) {
59
+ for (const worktreeDir of worktreesDirs(basePath)) {
60
+ if (!existsSync(worktreeDir))
61
+ continue;
60
62
  try {
61
63
  for (const d of readdirSync(worktreeDir)) {
62
64
  if (d.startsWith("M") && existsSync(join(worktreeDir, d, ".gsd", "auto.lock"))) {
@@ -69,7 +71,7 @@ function discoverWorkers(basePath) {
69
71
  return [...mids].sort();
70
72
  }
71
73
  function querySliceProgress(basePath, mid) {
72
- const workRoot = join(basePath, ".gsd", "worktrees", mid);
74
+ const workRoot = worktreePathFor(basePath, mid);
73
75
  const dbPath = resolveGsdPathContract(workRoot, basePath).projectDb;
74
76
  if (!existsSync(dbPath))
75
77
  return [];
@@ -115,7 +117,7 @@ function extractCostFromNdjson(basePath, mid) {
115
117
  }
116
118
  }
117
119
  function queryRecentCompletions(basePath, mid) {
118
- const workRoot = join(basePath, ".gsd", "worktrees", mid);
120
+ const workRoot = worktreePathFor(basePath, mid);
119
121
  const dbPath = resolveGsdPathContract(workRoot, basePath).projectDb;
120
122
  if (!existsSync(dbPath))
121
123
  return [];
@@ -140,7 +142,7 @@ function collectWorkerData(basePath) {
140
142
  const workers = [];
141
143
  for (const mid of mids) {
142
144
  const status = readJsonSafe(join(parallelDir, `${mid}.status.json`));
143
- const lock = readJsonSafe(join(basePath, ".gsd", "worktrees", mid, ".gsd", "auto.lock"));
145
+ const lock = readJsonSafe(join(worktreePathFor(basePath, mid), ".gsd", "auto.lock"));
144
146
  const slices = querySliceProgress(basePath, mid);
145
147
  const pid = lock?.pid || status?.pid || 0;
146
148
  const alive = pid ? isPidAlive(pid) : false;
@@ -12,9 +12,10 @@ import { join, dirname } from "node:path";
12
12
  import { fileURLToPath } from "node:url";
13
13
  import { gsdRoot } from "./paths.js";
14
14
  import { createWorktree, worktreePath } from "./worktree-manager.js";
15
- import { autoWorktreeBranch, fastForwardReusedMilestoneBranchIfSafe, runWorktreePostCreateHook, syncGsdStateToWorktree } from "./auto-worktree.js";
15
+ import { autoWorktreeBranch, fastForwardReusedMilestoneBranchIfSafe, runWorktreePostCreateHook, syncGsdStateToWorktreeByScope } from "./auto-worktree.js";
16
16
  import { nativeBranchExists } from "./native-git-bridge.js";
17
17
  import { readIntegrationBranch } from "./git-service.js";
18
+ import { createWorkspace, scopeMilestone } from "./workspace.js";
18
19
  import { resolveParallelConfig } from "./preferences.js";
19
20
  import { writeSessionStatus, readAllSessionStatuses, readSessionStatus, removeSessionStatus, sendSignal, cleanupStaleSessions, } from "./session-status-io.js";
20
21
  import { analyzeParallelEligibility, } from "./parallel-eligibility.js";
@@ -448,7 +449,7 @@ export function _createMilestoneWorktree(basePath, milestoneId) {
448
449
  // Copy .gsd/ planning artifacts (milestones, CONTEXT, ROADMAP, etc.) from the
449
450
  // project root into the worktree. Without this, workers for newly-planned
450
451
  // milestones can't find their roadmap and exit immediately (#2184 Bug 4).
451
- syncGsdStateToWorktree(basePath, info.path);
452
+ syncGsdStateToWorktreeByScope(scopeMilestone(createWorkspace(basePath), milestoneId), scopeMilestone(createWorkspace(info.path), milestoneId));
452
453
  return info.path;
453
454
  }
454
455
  // ─── Worker Spawning ───────────────────────────────────────────────────
@@ -16,7 +16,7 @@ import { spawnSync } from "node:child_process";
16
16
  import { nativeScanGsdTree } from "./native-parser-bridge.js";
17
17
  import { DIR_CACHE_MAX } from "./constants.js";
18
18
  import { gsdHome } from "./gsd-home.js";
19
- import { isGsdWorktreePath, resolveExternalStateProjectGsdFromWorktreePath, resolveWorktreeProjectRoot } from "./worktree-root.js";
19
+ import { findWorktreeSegment, isGsdWorktreePath, resolveExternalStateProjectGsdFromWorktreePath, resolveWorktreeProjectRoot } from "./worktree-root.js";
20
20
  // ─── Directory Listing Cache ──────────────────────────────────────────────────
21
21
  const dirEntryCache = new Map();
22
22
  const dirListCache = new Map();
@@ -422,31 +422,17 @@ function assertNotGlobalGsdHome(basePath, result) {
422
422
  * When gsdRoot() is called with such a path, we must NOT walk up to the
423
423
  * project root's .gsd — each worktree manages its own .gsd state (#2594).
424
424
  *
425
- * Matches both forward-slash and platform-native separators to handle
426
- * Windows paths (path.sep = '\\') and normalized Unix paths.
425
+ * Layout matching is owned by worktree-root's findWorktreeSegment; this
426
+ * only adds the requirement that a non-empty worktree name follows the
427
+ * marker (the worktrees container dir itself is not a worktree).
427
428
  */
428
429
  function isInsideGsdWorktree(p) {
429
- // Match /.gsd/worktrees/<name> where <name> is the final segment or
430
- // followed by a separator. The <name> segment must be non-empty.
431
- const sepFwd = "/";
432
- const sepNative = "\\";
433
- const markers = [
434
- `${sepFwd}.gsd${sepFwd}worktrees${sepFwd}`,
435
- `${sepNative}.gsd${sepNative}worktrees${sepNative}`,
436
- ];
437
- for (const marker of markers) {
438
- const idx = p.indexOf(marker);
439
- if (idx === -1)
440
- continue;
441
- // Verify there's a non-empty worktree name after the marker
442
- const afterMarker = p.slice(idx + marker.length);
443
- // The name is everything up to the next separator (or end of string)
444
- const nameEnd = afterMarker.search(/[/\\]/);
445
- const name = nameEnd === -1 ? afterMarker : afterMarker.slice(0, nameEnd);
446
- if (name.length > 0)
447
- return true;
448
- }
449
- return false;
430
+ const normalized = p.replaceAll("\\", "/");
431
+ const segment = findWorktreeSegment(normalized);
432
+ if (!segment)
433
+ return false;
434
+ const name = normalized.slice(segment.afterWorktrees).split("/")[0];
435
+ return name.length > 0;
450
436
  }
451
437
  function probeGsdRoot(rawBasePath) {
452
438
  const contract = resolveGsdPathContract(rawBasePath);