@opengsd/gsd-pi 1.3.0-dev.eed73bea → 1.4.0-dev.5fc22c6f

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 (550) hide show
  1. package/README.md +11 -11
  2. package/dist/cli.js +17 -4
  3. package/dist/headless-answers.js +1 -1
  4. package/dist/headless-ui.d.ts +1 -1
  5. package/dist/headless-ui.js +1 -1
  6. package/dist/headless.js +1 -1
  7. package/dist/onboarding.js +11 -0
  8. package/dist/resources/.managed-resources-content-hash +1 -1
  9. package/dist/resources/GSD-WORKFLOW.md +20 -25
  10. package/dist/resources/extensions/claude-code-cli/models.js +9 -0
  11. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +61 -50
  12. package/dist/resources/extensions/cursor-cli/index.js +16 -0
  13. package/dist/resources/extensions/cursor-cli/models.js +63 -0
  14. package/dist/resources/extensions/cursor-cli/package.json +11 -0
  15. package/dist/resources/extensions/cursor-cli/readiness.js +128 -0
  16. package/dist/resources/extensions/cursor-cli/stream-adapter.js +353 -0
  17. package/dist/resources/extensions/gsd/activity-log.js +4 -1
  18. package/dist/resources/extensions/gsd/artifact-verification.js +431 -0
  19. package/dist/resources/extensions/gsd/auto/session.js +11 -0
  20. package/dist/resources/extensions/gsd/auto/verification-retry-policy.js +1 -1
  21. package/dist/resources/extensions/gsd/auto-artifact-paths.js +28 -1
  22. package/dist/resources/extensions/gsd/auto-budget.js +5 -1
  23. package/dist/resources/extensions/gsd/auto-dispatch.js +32 -11
  24. package/dist/resources/extensions/gsd/auto-model-selection.js +36 -18
  25. package/dist/resources/extensions/gsd/auto-post-unit.js +1 -1
  26. package/dist/resources/extensions/gsd/auto-prompts.js +83 -25
  27. package/dist/resources/extensions/gsd/auto-recovery.js +9 -517
  28. package/dist/resources/extensions/gsd/auto-runtime-state.js +4 -5
  29. package/dist/resources/extensions/gsd/auto-start.js +4 -3
  30. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +7 -3
  31. package/dist/resources/extensions/gsd/auto-verification.js +5 -2
  32. package/dist/resources/extensions/gsd/auto-worktree.js +38 -11
  33. package/dist/resources/extensions/gsd/auto.js +32 -10
  34. package/dist/resources/extensions/gsd/bootstrap/core-session-tools.js +39 -0
  35. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +8 -4
  36. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +2 -0
  37. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +147 -23
  38. package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +56 -36
  39. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +29 -5
  40. package/dist/resources/extensions/gsd/closeout-consistency-gate.js +3 -1
  41. package/dist/resources/extensions/gsd/codebase-generator.js +157 -19
  42. package/dist/resources/extensions/gsd/commands/handlers/auto.js +1 -1
  43. package/dist/resources/extensions/gsd/commands/handlers/core.js +40 -4
  44. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +154 -2
  45. package/dist/resources/extensions/gsd/commands-usage.js +1 -1
  46. package/dist/resources/extensions/gsd/commands-worktree.js +11 -2
  47. package/dist/resources/extensions/gsd/db/engine.js +4 -1
  48. package/dist/resources/extensions/gsd/db/queries.js +39 -0
  49. package/dist/resources/extensions/gsd/db-memory-fts-schema.js +34 -0
  50. package/dist/resources/extensions/gsd/db-workspace.js +55 -3
  51. package/dist/resources/extensions/gsd/delegation-policy.js +1 -1
  52. package/dist/resources/extensions/gsd/discussion-handoff.js +8 -3
  53. package/dist/resources/extensions/gsd/docs/preferences-reference.md +10 -4
  54. package/dist/resources/extensions/gsd/doctor-engine-checks.js +227 -5
  55. package/dist/resources/extensions/gsd/doctor-providers.js +38 -10
  56. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +3 -0
  57. package/dist/resources/extensions/gsd/doctor.js +93 -3
  58. package/dist/resources/extensions/gsd/exec-sandbox.js +14 -4
  59. package/dist/resources/extensions/gsd/flat-phase-migration.js +119 -23
  60. package/dist/resources/extensions/gsd/git-service.js +61 -8
  61. package/dist/resources/extensions/gsd/gitignore.js +4 -1
  62. package/dist/resources/extensions/gsd/guidance.js +1 -0
  63. package/dist/resources/extensions/gsd/guided-flow-queue.js +20 -13
  64. package/dist/resources/extensions/gsd/guided-flow.js +40 -2
  65. package/dist/resources/extensions/gsd/json-persistence.js +20 -0
  66. package/dist/resources/extensions/gsd/key-manager.js +1 -0
  67. package/dist/resources/extensions/gsd/knowledge-backfill.js +18 -11
  68. package/dist/resources/extensions/gsd/layout-policy.js +3 -1
  69. package/dist/resources/extensions/gsd/markdown-renderer.js +27 -15
  70. package/dist/resources/extensions/gsd/memory-backfill.js +28 -21
  71. package/dist/resources/extensions/gsd/metrics.js +4 -4
  72. package/dist/resources/extensions/gsd/migrate-external.js +22 -5
  73. package/dist/resources/extensions/gsd/migration-auto-check.js +22 -0
  74. package/dist/resources/extensions/gsd/milestone-ids.js +32 -2
  75. package/dist/resources/extensions/gsd/orphan-stash-audit.js +92 -16
  76. package/dist/resources/extensions/gsd/preferences-diagnostics.js +24 -1
  77. package/dist/resources/extensions/gsd/preferences-models.js +6 -4
  78. package/dist/resources/extensions/gsd/preferences-validation.js +25 -2
  79. package/dist/resources/extensions/gsd/preferences.js +29 -2
  80. package/dist/resources/extensions/gsd/prompts/code-review.md +6 -4
  81. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +2 -2
  82. package/dist/resources/extensions/gsd/prompts/plan-slice.md +5 -3
  83. package/dist/resources/extensions/gsd/redact-secrets.js +37 -0
  84. package/dist/resources/extensions/gsd/repository-registry.js +6 -1
  85. package/dist/resources/extensions/gsd/root-write-leak-guard.js +7 -1
  86. package/dist/resources/extensions/gsd/safe-fs.js +23 -2
  87. package/dist/resources/extensions/gsd/safety/destructive-guard.js +8 -1
  88. package/dist/resources/extensions/gsd/safety/evidence-collector.js +16 -1
  89. package/dist/resources/extensions/gsd/safety/file-change-validator.js +5 -2
  90. package/dist/resources/extensions/gsd/skills/gsd-headless/SKILL.md +7 -9
  91. package/dist/resources/extensions/gsd/skills/gsd-headless/references/commands.md +2 -1
  92. package/dist/resources/extensions/gsd/state/derive/cache.js +28 -0
  93. package/dist/resources/extensions/gsd/state/derive/db-open.js +39 -0
  94. package/dist/resources/extensions/gsd/state/derive/from-db.js +452 -0
  95. package/dist/resources/extensions/gsd/state/derive/index.js +75 -0
  96. package/dist/resources/extensions/gsd/state/derive/interrupted-work.js +21 -0
  97. package/dist/resources/extensions/gsd/state-reconciliation/drift/stale-render.js +27 -33
  98. package/dist/resources/extensions/gsd/state-reconciliation/index.js +48 -23
  99. package/dist/resources/extensions/gsd/state-reconciliation/registry.js +32 -28
  100. package/dist/resources/extensions/gsd/state.js +12 -611
  101. package/dist/resources/extensions/gsd/tools/complete-milestone.js +4 -2
  102. package/dist/resources/extensions/gsd/tools/complete-slice.js +3 -34
  103. package/dist/resources/extensions/gsd/tools/complete-task.js +8 -41
  104. package/dist/resources/extensions/gsd/tools/plan-slice.js +59 -44
  105. package/dist/resources/extensions/gsd/tools/plan-task.js +103 -12
  106. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +40 -0
  107. package/dist/resources/extensions/gsd/undo.js +43 -6
  108. package/dist/resources/extensions/gsd/unit-context-manifest.js +5 -4
  109. package/dist/resources/extensions/gsd/unit-registry.js +11 -3
  110. package/dist/resources/extensions/gsd/unit-runtime.js +21 -0
  111. package/dist/resources/extensions/gsd/verification-gate.js +7 -0
  112. package/dist/resources/extensions/gsd/workflow-manifest.js +126 -13
  113. package/dist/resources/extensions/gsd/workflow-projections.js +19 -14
  114. package/dist/resources/extensions/gsd/workspace.js +26 -8
  115. package/dist/resources/extensions/gsd/worktree-manager.js +140 -5
  116. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  117. package/dist/web/standalone/.next/BUILD_ID +1 -1
  118. package/dist/web/standalone/.next/app-path-routes-manifest.json +12 -12
  119. package/dist/web/standalone/.next/build-manifest.json +3 -3
  120. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  121. package/dist/web/standalone/.next/react-loadable-manifest.json +9 -9
  122. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  123. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  124. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  125. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  126. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  127. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  128. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  129. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  130. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  131. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  132. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  133. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  134. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  135. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  136. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  137. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  138. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  139. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  140. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  141. package/dist/web/standalone/.next/server/app/index.html +1 -1
  142. package/dist/web/standalone/.next/server/app/index.rsc +2 -2
  143. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  144. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
  145. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  146. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  147. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  148. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/app-paths-manifest.json +12 -12
  150. package/dist/web/standalone/.next/server/chunks/8357.js +2 -2
  151. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  152. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  154. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  155. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  156. package/dist/web/standalone/.next/static/chunks/{2659.b7b129ee6a769448.js → 2659.58e950899a9bb82f.js} +1 -1
  157. package/dist/web/standalone/.next/static/chunks/2772.a7c1fcc69a4685ef.js +1 -0
  158. package/dist/web/standalone/.next/static/chunks/{3616.3c60753b8ffcbd2e.js → 3616.61a2af74bb8833c8.js} +1 -1
  159. package/dist/web/standalone/.next/static/chunks/{4283.8e446784528ed9dc.js → 4283.d0d9e0a955e441cb.js} +1 -1
  160. package/dist/web/standalone/.next/static/chunks/{5826.a46ecdd1cfe8dabc.js → 5826.5421d66c72b9f34e.js} +1 -1
  161. package/dist/web/standalone/.next/static/chunks/{8785.481aa5869991b760.js → 8785.e29b3134cab1d153.js} +1 -1
  162. package/dist/web/standalone/.next/static/chunks/8937.640dc9c2aaa1dfad.js +10 -0
  163. package/dist/web/standalone/.next/static/chunks/app/{page-6644fc6ee8ca1247.js → page-72a856634ad14c10.js} +1 -1
  164. package/dist/web/standalone/.next/static/chunks/webpack-9c401904f87ded16.js +1 -0
  165. package/dist/web/standalone/node_modules/@gsd/native/package.json +1 -1
  166. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  167. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  168. package/dist/wizard.d.ts +8 -0
  169. package/dist/wizard.js +8 -1
  170. package/integrations/hermes/__init__.py +31 -0
  171. package/integrations/hermes/tests/test_directory_loader.py +37 -0
  172. package/package.json +8 -8
  173. package/packages/cloud-mcp-gateway/dist/auth-store.d.ts +1 -0
  174. package/packages/cloud-mcp-gateway/dist/auth-store.d.ts.map +1 -1
  175. package/packages/cloud-mcp-gateway/dist/auth-store.js +21 -1
  176. package/packages/cloud-mcp-gateway/dist/auth-store.js.map +1 -1
  177. package/packages/cloud-mcp-gateway/dist/auth-store.test.js +34 -0
  178. package/packages/cloud-mcp-gateway/dist/auth-store.test.js.map +1 -1
  179. package/packages/cloud-mcp-gateway/package.json +2 -2
  180. package/packages/contracts/package.json +1 -1
  181. package/packages/daemon/dist/cloud-runtime.d.ts +2 -0
  182. package/packages/daemon/dist/cloud-runtime.d.ts.map +1 -1
  183. package/packages/daemon/dist/cloud-runtime.js +25 -1
  184. package/packages/daemon/dist/cloud-runtime.js.map +1 -1
  185. package/packages/daemon/dist/cloud-runtime.test.js +51 -0
  186. package/packages/daemon/dist/cloud-runtime.test.js.map +1 -1
  187. package/packages/daemon/dist/message-batcher.d.ts +7 -0
  188. package/packages/daemon/dist/message-batcher.d.ts.map +1 -1
  189. package/packages/daemon/dist/message-batcher.js +13 -0
  190. package/packages/daemon/dist/message-batcher.js.map +1 -1
  191. package/packages/daemon/dist/message-batcher.test.js +48 -0
  192. package/packages/daemon/dist/message-batcher.test.js.map +1 -1
  193. package/packages/daemon/package.json +5 -5
  194. package/packages/gsd-agent-core/dist/agent-session.d.ts +1 -0
  195. package/packages/gsd-agent-core/dist/agent-session.d.ts.map +1 -1
  196. package/packages/gsd-agent-core/dist/agent-session.js +3 -0
  197. package/packages/gsd-agent-core/dist/agent-session.js.map +1 -1
  198. package/packages/gsd-agent-core/dist/compaction/compaction.d.ts +13 -1
  199. package/packages/gsd-agent-core/dist/compaction/compaction.d.ts.map +1 -1
  200. package/packages/gsd-agent-core/dist/compaction/compaction.js +15 -1
  201. package/packages/gsd-agent-core/dist/compaction/compaction.js.map +1 -1
  202. package/packages/gsd-agent-core/dist/extension-ui-snapshot.d.ts +41 -0
  203. package/packages/gsd-agent-core/dist/extension-ui-snapshot.d.ts.map +1 -0
  204. package/packages/gsd-agent-core/dist/extension-ui-snapshot.js +62 -0
  205. package/packages/gsd-agent-core/dist/extension-ui-snapshot.js.map +1 -0
  206. package/packages/gsd-agent-core/dist/index.d.ts +2 -0
  207. package/packages/gsd-agent-core/dist/index.d.ts.map +1 -1
  208. package/packages/gsd-agent-core/dist/index.js +2 -0
  209. package/packages/gsd-agent-core/dist/index.js.map +1 -1
  210. package/packages/gsd-agent-core/dist/session/agent-session-events.js +1 -1
  211. package/packages/gsd-agent-core/dist/session/agent-session-events.js.map +1 -1
  212. package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts +1 -0
  213. package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts.map +1 -1
  214. package/packages/gsd-agent-core/dist/session/agent-session-host.js.map +1 -1
  215. package/packages/gsd-agent-core/dist/session/agent-session-prompt.d.ts +5 -0
  216. package/packages/gsd-agent-core/dist/session/agent-session-prompt.d.ts.map +1 -1
  217. package/packages/gsd-agent-core/dist/session/agent-session-prompt.js +60 -3
  218. package/packages/gsd-agent-core/dist/session/agent-session-prompt.js.map +1 -1
  219. package/packages/gsd-agent-core/dist/transcript-store.d.ts +58 -0
  220. package/packages/gsd-agent-core/dist/transcript-store.d.ts.map +1 -0
  221. package/packages/gsd-agent-core/dist/transcript-store.js +132 -0
  222. package/packages/gsd-agent-core/dist/transcript-store.js.map +1 -0
  223. package/packages/gsd-agent-core/package.json +5 -5
  224. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +2 -0
  225. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  226. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +25 -11
  227. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  228. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.d.ts +4 -0
  229. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.d.ts.map +1 -0
  230. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.js +7 -0
  231. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.js.map +1 -0
  232. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts +3 -24
  233. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  234. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +26 -841
  235. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  236. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.d.ts +58 -0
  237. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.d.ts.map +1 -0
  238. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.js +312 -0
  239. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.js.map +1 -0
  240. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.d.ts +31 -0
  241. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.d.ts.map +1 -0
  242. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.js +130 -0
  243. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.js.map +1 -0
  244. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.d.ts +15 -0
  245. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.d.ts.map +1 -0
  246. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.js +259 -0
  247. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.js.map +1 -0
  248. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.d.ts +13 -0
  249. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.d.ts.map +1 -0
  250. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.js +118 -0
  251. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.js.map +1 -0
  252. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.d.ts +9 -0
  253. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
  254. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.js +1 -1
  255. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.js.map +1 -1
  256. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.d.ts +54 -0
  257. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.d.ts.map +1 -0
  258. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.js +20 -0
  259. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.js.map +1 -0
  260. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts +4 -1
  261. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  262. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +9 -0
  263. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
  264. package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.d.ts +56 -0
  265. package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.d.ts.map +1 -0
  266. package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.js +44 -0
  267. package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.js.map +1 -0
  268. package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.d.ts +5 -0
  269. package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.d.ts.map +1 -0
  270. package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.js +77 -0
  271. package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.js.map +1 -0
  272. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.d.ts +2 -0
  273. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  274. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.js +24 -6
  275. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.js.map +1 -1
  276. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  277. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +18 -0
  278. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -1
  279. package/packages/gsd-agent-modes/package.json +7 -7
  280. package/packages/mcp-server/dist/workflow-tools.js +1 -1
  281. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  282. package/packages/mcp-server/package.json +4 -4
  283. package/packages/native/package.json +1 -1
  284. package/packages/pi-agent-core/dist/agent-loop.js +3 -2
  285. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  286. package/packages/pi-agent-core/package.json +1 -1
  287. package/packages/pi-ai/dist/env-api-keys.d.ts.map +1 -1
  288. package/packages/pi-ai/dist/env-api-keys.js +3 -0
  289. package/packages/pi-ai/dist/env-api-keys.js.map +1 -1
  290. package/packages/pi-ai/dist/models.generated.d.ts +46 -0
  291. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  292. package/packages/pi-ai/dist/models.generated.js +38 -0
  293. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  294. package/packages/pi-ai/dist/types.d.ts +2 -2
  295. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  296. package/packages/pi-ai/dist/types.js.map +1 -1
  297. package/packages/pi-ai/package.json +1 -1
  298. package/packages/pi-coding-agent/README.md +3 -2
  299. package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
  300. package/packages/pi-coding-agent/dist/core/model-resolver.js +1 -0
  301. package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
  302. package/packages/pi-coding-agent/dist/core/session-manager-context.d.ts +9 -0
  303. package/packages/pi-coding-agent/dist/core/session-manager-context.d.ts.map +1 -0
  304. package/packages/pi-coding-agent/dist/core/session-manager-context.js +94 -0
  305. package/packages/pi-coding-agent/dist/core/session-manager-context.js.map +1 -0
  306. package/packages/pi-coding-agent/dist/core/session-manager-list.d.ts +8 -0
  307. package/packages/pi-coding-agent/dist/core/session-manager-list.d.ts.map +1 -0
  308. package/packages/pi-coding-agent/dist/core/session-manager-list.js +244 -0
  309. package/packages/pi-coding-agent/dist/core/session-manager-list.js.map +1 -0
  310. package/packages/pi-coding-agent/dist/core/session-manager-migration.d.ts +12 -0
  311. package/packages/pi-coding-agent/dist/core/session-manager-migration.d.ts.map +1 -0
  312. package/packages/pi-coding-agent/dist/core/session-manager-migration.js +84 -0
  313. package/packages/pi-coding-agent/dist/core/session-manager-migration.js.map +1 -0
  314. package/packages/pi-coding-agent/dist/core/session-manager-types.d.ts +135 -0
  315. package/packages/pi-coding-agent/dist/core/session-manager-types.d.ts.map +1 -0
  316. package/packages/pi-coding-agent/dist/core/session-manager-types.js +2 -0
  317. package/packages/pi-coding-agent/dist/core/session-manager-types.js.map +1 -0
  318. package/packages/pi-coding-agent/dist/core/session-manager.d.ts +6 -154
  319. package/packages/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
  320. package/packages/pi-coding-agent/dist/core/session-manager.js +22 -459
  321. package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
  322. package/packages/pi-coding-agent/dist/theme/theme-schema.d.ts +75 -75
  323. package/packages/pi-coding-agent/dist/theme/theme-schema.d.ts.map +1 -1
  324. package/packages/pi-coding-agent/dist/theme/theme-schema.js +1 -1
  325. package/packages/pi-coding-agent/dist/theme/theme-schema.js.map +1 -1
  326. package/packages/pi-coding-agent/dist/theme/theme.d.ts.map +1 -1
  327. package/packages/pi-coding-agent/dist/theme/theme.js +11 -7
  328. package/packages/pi-coding-agent/dist/theme/theme.js.map +1 -1
  329. package/packages/pi-coding-agent/package.json +7 -7
  330. package/packages/pi-tui/package.json +2 -2
  331. package/packages/rpc-client/dist/rpc-client.js +1 -1
  332. package/packages/rpc-client/dist/rpc-client.js.map +1 -1
  333. package/packages/rpc-client/package.json +2 -2
  334. package/pkg/dist/theme/theme-schema.d.ts +75 -75
  335. package/pkg/dist/theme/theme-schema.d.ts.map +1 -1
  336. package/pkg/dist/theme/theme-schema.js +1 -1
  337. package/pkg/dist/theme/theme-schema.js.map +1 -1
  338. package/pkg/dist/theme/theme.d.ts.map +1 -1
  339. package/pkg/dist/theme/theme.js +11 -7
  340. package/pkg/dist/theme/theme.js.map +1 -1
  341. package/pkg/package.json +1 -1
  342. package/scripts/link-workspace-packages.cjs +14 -4
  343. package/src/resources/GSD-WORKFLOW.md +20 -25
  344. package/src/resources/extensions/claude-code-cli/models.ts +9 -0
  345. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +67 -49
  346. package/src/resources/extensions/claude-code-cli/tests/index.test.ts +14 -0
  347. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +159 -0
  348. package/src/resources/extensions/cursor-cli/index.ts +18 -0
  349. package/src/resources/extensions/cursor-cli/models.ts +65 -0
  350. package/src/resources/extensions/cursor-cli/package.json +11 -0
  351. package/src/resources/extensions/cursor-cli/readiness.ts +143 -0
  352. package/src/resources/extensions/cursor-cli/stream-adapter.ts +440 -0
  353. package/src/resources/extensions/cursor-cli/tests/index.test.ts +54 -0
  354. package/src/resources/extensions/cursor-cli/tests/readiness.test.ts +29 -0
  355. package/src/resources/extensions/cursor-cli/tests/stream-adapter.test.ts +166 -0
  356. package/src/resources/extensions/gsd/activity-log.ts +4 -1
  357. package/src/resources/extensions/gsd/artifact-verification.ts +468 -0
  358. package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
  359. package/src/resources/extensions/gsd/auto/session.ts +14 -0
  360. package/src/resources/extensions/gsd/auto/verification-retry-policy.ts +3 -1
  361. package/src/resources/extensions/gsd/auto-artifact-paths.ts +47 -1
  362. package/src/resources/extensions/gsd/auto-budget.ts +12 -1
  363. package/src/resources/extensions/gsd/auto-dispatch.ts +34 -12
  364. package/src/resources/extensions/gsd/auto-model-selection.ts +49 -18
  365. package/src/resources/extensions/gsd/auto-post-unit.ts +1 -1
  366. package/src/resources/extensions/gsd/auto-prompts.ts +80 -25
  367. package/src/resources/extensions/gsd/auto-recovery.ts +13 -518
  368. package/src/resources/extensions/gsd/auto-runtime-state.ts +4 -5
  369. package/src/resources/extensions/gsd/auto-start.ts +4 -3
  370. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +7 -2
  371. package/src/resources/extensions/gsd/auto-verification.ts +5 -1
  372. package/src/resources/extensions/gsd/auto-worktree.ts +50 -11
  373. package/src/resources/extensions/gsd/auto.ts +36 -8
  374. package/src/resources/extensions/gsd/bootstrap/core-session-tools.ts +44 -0
  375. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +8 -4
  376. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +2 -0
  377. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +171 -23
  378. package/src/resources/extensions/gsd/bootstrap/tests/write-gate-basepath.test.ts +49 -1
  379. package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +60 -37
  380. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +39 -5
  381. package/src/resources/extensions/gsd/closeout-consistency-gate.ts +2 -1
  382. package/src/resources/extensions/gsd/codebase-generator.ts +179 -18
  383. package/src/resources/extensions/gsd/commands/handlers/auto.ts +1 -1
  384. package/src/resources/extensions/gsd/commands/handlers/core.ts +39 -3
  385. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +136 -2
  386. package/src/resources/extensions/gsd/commands-usage.ts +1 -1
  387. package/src/resources/extensions/gsd/commands-worktree.ts +13 -2
  388. package/src/resources/extensions/gsd/db/engine.ts +8 -1
  389. package/src/resources/extensions/gsd/db/queries.ts +40 -0
  390. package/src/resources/extensions/gsd/db-memory-fts-schema.ts +45 -0
  391. package/src/resources/extensions/gsd/db-workspace.ts +61 -3
  392. package/src/resources/extensions/gsd/delegation-policy.ts +1 -1
  393. package/src/resources/extensions/gsd/discussion-handoff.ts +10 -2
  394. package/src/resources/extensions/gsd/docs/preferences-reference.md +10 -4
  395. package/src/resources/extensions/gsd/doctor-engine-checks.ts +275 -5
  396. package/src/resources/extensions/gsd/doctor-providers.ts +39 -10
  397. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +3 -0
  398. package/src/resources/extensions/gsd/doctor-types.ts +8 -1
  399. package/src/resources/extensions/gsd/doctor.ts +95 -3
  400. package/src/resources/extensions/gsd/exec-sandbox.ts +13 -4
  401. package/src/resources/extensions/gsd/flat-phase-migration.ts +142 -22
  402. package/src/resources/extensions/gsd/git-service.ts +70 -9
  403. package/src/resources/extensions/gsd/gitignore.ts +4 -1
  404. package/src/resources/extensions/gsd/guidance.ts +2 -0
  405. package/src/resources/extensions/gsd/guided-flow-queue.ts +20 -13
  406. package/src/resources/extensions/gsd/guided-flow.ts +45 -2
  407. package/src/resources/extensions/gsd/json-persistence.ts +20 -0
  408. package/src/resources/extensions/gsd/key-manager.ts +1 -0
  409. package/src/resources/extensions/gsd/knowledge-backfill.ts +16 -10
  410. package/src/resources/extensions/gsd/layout-policy.ts +2 -1
  411. package/src/resources/extensions/gsd/markdown-renderer.ts +27 -17
  412. package/src/resources/extensions/gsd/memory-backfill.ts +26 -20
  413. package/src/resources/extensions/gsd/metrics.ts +4 -4
  414. package/src/resources/extensions/gsd/migrate-external.ts +17 -4
  415. package/src/resources/extensions/gsd/migration-auto-check.ts +23 -0
  416. package/src/resources/extensions/gsd/milestone-ids.ts +31 -2
  417. package/src/resources/extensions/gsd/model-router.ts +4 -5
  418. package/src/resources/extensions/gsd/orphan-stash-audit.ts +108 -20
  419. package/src/resources/extensions/gsd/preferences-diagnostics.ts +24 -0
  420. package/src/resources/extensions/gsd/preferences-models.ts +6 -3
  421. package/src/resources/extensions/gsd/preferences-validation.ts +28 -2
  422. package/src/resources/extensions/gsd/preferences.ts +38 -4
  423. package/src/resources/extensions/gsd/prompts/code-review.md +6 -4
  424. package/src/resources/extensions/gsd/prompts/plan-milestone.md +2 -2
  425. package/src/resources/extensions/gsd/prompts/plan-slice.md +5 -3
  426. package/src/resources/extensions/gsd/redact-secrets.ts +40 -0
  427. package/src/resources/extensions/gsd/repository-registry.ts +7 -1
  428. package/src/resources/extensions/gsd/root-write-leak-guard.ts +13 -1
  429. package/src/resources/extensions/gsd/safe-fs.ts +22 -2
  430. package/src/resources/extensions/gsd/safety/destructive-guard.ts +9 -1
  431. package/src/resources/extensions/gsd/safety/evidence-collector.ts +16 -1
  432. package/src/resources/extensions/gsd/safety/file-change-validator.ts +8 -2
  433. package/src/resources/extensions/gsd/skills/gsd-headless/SKILL.md +7 -9
  434. package/src/resources/extensions/gsd/skills/gsd-headless/references/commands.md +2 -1
  435. package/src/resources/extensions/gsd/state/derive/cache.ts +46 -0
  436. package/src/resources/extensions/gsd/state/derive/db-open.ts +45 -0
  437. package/src/resources/extensions/gsd/state/derive/from-db.ts +561 -0
  438. package/src/resources/extensions/gsd/state/derive/index.ts +104 -0
  439. package/src/resources/extensions/gsd/state/derive/interrupted-work.ts +31 -0
  440. package/src/resources/extensions/gsd/state-reconciliation/drift/stale-render.ts +36 -30
  441. package/src/resources/extensions/gsd/state-reconciliation/index.ts +50 -24
  442. package/src/resources/extensions/gsd/state-reconciliation/registry.ts +43 -28
  443. package/src/resources/extensions/gsd/state.ts +32 -732
  444. package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +4 -3
  445. package/src/resources/extensions/gsd/tests/auto-artifact-paths.test.ts +98 -1
  446. package/src/resources/extensions/gsd/tests/auto-budget-alerts.test.ts +14 -5
  447. package/src/resources/extensions/gsd/tests/auto-migrating-recovery.test.ts +18 -0
  448. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +178 -0
  449. package/src/resources/extensions/gsd/tests/auto-pause-double-entry-guard.test.ts +36 -0
  450. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +182 -4
  451. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +35 -0
  452. package/src/resources/extensions/gsd/tests/auto-remote-session-lock-cleanup.test.ts +41 -0
  453. package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +30 -0
  454. package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +41 -0
  455. package/src/resources/extensions/gsd/tests/auto-session-scope.test.ts +4 -4
  456. package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +3 -0
  457. package/src/resources/extensions/gsd/tests/auto-timeout-recovery-harness-abort.test.ts +55 -0
  458. package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +8 -0
  459. package/src/resources/extensions/gsd/tests/batch-task-query.test.ts +85 -0
  460. package/src/resources/extensions/gsd/tests/check-auto-start-ready-guard.test.ts +29 -0
  461. package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +365 -0
  462. package/src/resources/extensions/gsd/tests/commands-gsd-core.test.ts +1 -0
  463. package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +62 -1
  464. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +28 -0
  465. package/src/resources/extensions/gsd/tests/complete-slice-reopen-handoff.test.ts +69 -0
  466. package/src/resources/extensions/gsd/tests/db-memory-fts-schema.test.ts +58 -3
  467. package/src/resources/extensions/gsd/tests/decisions-projection-from-memories.test.ts +51 -0
  468. package/src/resources/extensions/gsd/tests/destructive-guard.test.ts +44 -0
  469. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +143 -0
  470. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +138 -1
  471. package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +296 -2
  472. package/src/resources/extensions/gsd/tests/doctor-workspace.test.ts +207 -0
  473. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +16 -0
  474. package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +40 -0
  475. package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +74 -2
  476. package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +87 -19
  477. package/src/resources/extensions/gsd/tests/gate-1b-orphan-discrimination.test.ts +89 -0
  478. package/src/resources/extensions/gsd/tests/gitignore-bg-shell-runtime.test.ts +4 -0
  479. package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +9 -0
  480. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +11 -2
  481. package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +4 -2
  482. package/src/resources/extensions/gsd/tests/json-persistence-atomic.test.ts +47 -0
  483. package/src/resources/extensions/gsd/tests/knowledge-backfill-projection.test.ts +35 -0
  484. package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +122 -0
  485. package/src/resources/extensions/gsd/tests/memory-store.test.ts +48 -0
  486. package/src/resources/extensions/gsd/tests/merge-closeout-consistency-gate.test.ts +31 -1
  487. package/src/resources/extensions/gsd/tests/metrics-prune-cache-invalidation.test.ts +6 -0
  488. package/src/resources/extensions/gsd/tests/metrics.test.ts +1 -0
  489. package/src/resources/extensions/gsd/tests/migrate-external-worktree.test.ts +57 -0
  490. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +70 -0
  491. package/src/resources/extensions/gsd/tests/orphan-stash-audit.test.ts +91 -7
  492. package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +4 -1
  493. package/src/resources/extensions/gsd/tests/pending-autostart-scope.test.ts +2 -2
  494. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +27 -0
  495. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +103 -4
  496. package/src/resources/extensions/gsd/tests/plan-task.test.ts +307 -1
  497. package/src/resources/extensions/gsd/tests/post-mutation-hook.test.ts +4 -2
  498. package/src/resources/extensions/gsd/tests/preferences.test.ts +150 -0
  499. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +142 -0
  500. package/src/resources/extensions/gsd/tests/progressive-planning.test.ts +50 -14
  501. package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +58 -0
  502. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +8 -6
  503. package/src/resources/extensions/gsd/tests/recovery-verify-logs.test.ts +4 -4
  504. package/src/resources/extensions/gsd/tests/redact-secrets.test.ts +56 -0
  505. package/src/resources/extensions/gsd/tests/register-hooks-flat-phase-migration.test.ts +73 -0
  506. package/src/resources/extensions/gsd/tests/register-hooks-loop-guard-auto.test.ts +378 -0
  507. package/src/resources/extensions/gsd/tests/repository-registry.test.ts +41 -2
  508. package/src/resources/extensions/gsd/tests/require-slice-discussion-dispatch.test.ts +55 -0
  509. package/src/resources/extensions/gsd/tests/root-write-leak-guard.test.ts +20 -1
  510. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +15 -3
  511. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +105 -0
  512. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +115 -0
  513. package/src/resources/extensions/gsd/tests/status-per-repo.test.ts +94 -0
  514. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +35 -0
  515. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +203 -0
  516. package/src/resources/extensions/gsd/tests/tool-param-optionality.test.ts +6 -3
  517. package/src/resources/extensions/gsd/tests/undo.test.ts +74 -0
  518. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +66 -18
  519. package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +30 -0
  520. package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +90 -0
  521. package/src/resources/extensions/gsd/tests/validator-scope-parity.test.ts +53 -1
  522. package/src/resources/extensions/gsd/tests/verification-retry-policy.test.ts +69 -4
  523. package/src/resources/extensions/gsd/tests/workflow-manifest.test.ts +96 -15
  524. package/src/resources/extensions/gsd/tests/workflow-mcp-preflight.test.ts +1 -0
  525. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +8 -4
  526. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +214 -6
  527. package/src/resources/extensions/gsd/tests/workspace.test.ts +18 -4
  528. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +39 -0
  529. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +31 -1
  530. package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +32 -0
  531. package/src/resources/extensions/gsd/tools/complete-milestone.ts +3 -2
  532. package/src/resources/extensions/gsd/tools/complete-slice.ts +3 -30
  533. package/src/resources/extensions/gsd/tools/complete-task.ts +7 -39
  534. package/src/resources/extensions/gsd/tools/plan-slice.ts +60 -47
  535. package/src/resources/extensions/gsd/tools/plan-task.ts +135 -12
  536. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +58 -0
  537. package/src/resources/extensions/gsd/undo.ts +47 -6
  538. package/src/resources/extensions/gsd/unit-context-manifest.ts +11 -5
  539. package/src/resources/extensions/gsd/unit-registry.ts +11 -3
  540. package/src/resources/extensions/gsd/unit-runtime.ts +42 -0
  541. package/src/resources/extensions/gsd/verification-gate.ts +8 -0
  542. package/src/resources/extensions/gsd/workflow-manifest.ts +141 -7
  543. package/src/resources/extensions/gsd/workflow-projections.ts +20 -14
  544. package/src/resources/extensions/gsd/workspace.ts +42 -8
  545. package/src/resources/extensions/gsd/worktree-manager.ts +183 -5
  546. package/dist/web/standalone/.next/static/chunks/2772.bfa657f49f955239.js +0 -1
  547. package/dist/web/standalone/.next/static/chunks/796.3976108148518f7d.js +0 -10
  548. package/dist/web/standalone/.next/static/chunks/webpack-7c1d97e39be2da11.js +0 -1
  549. /package/dist/web/standalone/.next/static/{SzEuqWX37DR9MEpEuQjP1 → kIEFsCryyGy6RzifULbJl}/_buildManifest.js +0 -0
  550. /package/dist/web/standalone/.next/static/{SzEuqWX37DR9MEpEuQjP1 → kIEFsCryyGy6RzifULbJl}/_ssgManifest.js +0 -0
@@ -13,12 +13,13 @@
13
13
 
14
14
  import { existsSync, readFileSync } from "node:fs";
15
15
  import { access, readFile } from "node:fs/promises";
16
+ import { homedir } from "node:os";
16
17
  import { delimiter, join } from "node:path";
17
18
  import { AuthStorage } from "@gsd/pi-coding-agent";
18
19
  import { getEnvApiKey } from "@gsd/pi-ai";
20
+ import { isCursorAgentReadyUncached } from "../cursor-cli/readiness.js";
19
21
  import { loadEffectiveGSDPreferences } from "./preferences.js";
20
22
  import { getAuthPath, PROVIDER_REGISTRY, supportsBrowserOAuth, type ProviderCategory } from "./key-manager.js";
21
- import { homedir } from "node:os";
22
23
 
23
24
  // ── Types ──────────────────────────────────────────────────────────────────────
24
25
 
@@ -49,6 +50,7 @@ const CLI_AUTH_PROVIDERS = new Set([
49
50
  "claude-code",
50
51
  "google-gemini-cli",
51
52
  "google-antigravity",
53
+ "cursor-agent",
52
54
  ]);
53
55
 
54
56
  /**
@@ -57,9 +59,9 @@ const CLI_AUTH_PROVIDERS = new Set([
57
59
  * e.g. GitHub Copilot subscriptions can access Claude and GPT models.
58
60
  */
59
61
  const PROVIDER_ROUTES: Record<string, string[]> = {
60
- anthropic: ["github-copilot", "claude-code"],
61
- openai: ["github-copilot", "openai-codex"],
62
- google: ["google-antigravity", "google-gemini-cli"],
62
+ anthropic: ["github-copilot", "claude-code", "cursor-agent"],
63
+ openai: ["github-copilot", "openai-codex", "cursor-agent"],
64
+ google: ["google-antigravity", "google-gemini-cli", "cursor-agent"],
63
65
  };
64
66
 
65
67
  // ── Model → Provider ID mapping ───────────────────────────────────────────────
@@ -86,6 +88,7 @@ function modelToProviderId(model: string): string | null {
86
88
  anthropic: "anthropic",
87
89
  openai: "openai",
88
90
  "github-copilot": "github-copilot",
91
+ "cursor-agent": "cursor-agent",
89
92
  };
90
93
  if (prefixMap[prefix]) return prefixMap[prefix];
91
94
  return rawPrefix;
@@ -95,6 +98,7 @@ function modelToProviderId(model: string): string | null {
95
98
  if (lower.startsWith("claude")) return "anthropic";
96
99
  if (lower.startsWith("gpt-") || lower.startsWith("o1") || lower.startsWith("o3")) return "openai";
97
100
  if (lower.startsWith("gemini")) return "google";
101
+ if (lower.startsWith("composer")) return "cursor-agent";
98
102
  if (lower.startsWith("llama") || lower.startsWith("mixtral")) return "groq";
99
103
  if (lower.startsWith("grok")) return "xai";
100
104
  if (lower.startsWith("mistral") || lower.startsWith("codestral")) return "mistral";
@@ -160,11 +164,13 @@ const CLI_BINARY_MAP: Record<string, string[]> = {
160
164
  "claude-code": ["claude", "claude-code"],
161
165
  "google-gemini-cli": ["gemini"],
162
166
  "google-antigravity": ["agy"],
167
+ "cursor-agent": ["cursor-agent"],
163
168
  };
164
169
 
165
170
  const CLI_AUTH_PATH_CHECK_PROVIDERS = new Set([
166
171
  "google-gemini-cli",
167
172
  "google-antigravity",
173
+ "cursor-agent",
168
174
  ]);
169
175
 
170
176
  let asyncCliBinaryPathCache: Map<string, boolean> | null = null;
@@ -212,6 +218,18 @@ function isCliBinaryInPath(providerId: string): boolean {
212
218
  return pathDirs.some(dir => executableNames.some(name => existsSync(join(dir, name))));
213
219
  }
214
220
 
221
+ function isExternalCliProviderReady(providerId: string): boolean {
222
+ if (providerId === "cursor-agent") return isCursorAgentReadyUncached();
223
+ return isCliBinaryInPath(providerId);
224
+ }
225
+
226
+ function cursorAgentFailureDetail(): string {
227
+ if (!isCliBinaryInPath("cursor-agent")) {
228
+ return "Install Cursor Agent and ensure `cursor-agent` is on PATH";
229
+ }
230
+ return "Run `cursor-agent login` or set CURSOR_API_KEY";
231
+ }
232
+
215
233
  async function isCliBinaryInPathAsync(providerId: string): Promise<boolean> {
216
234
  const executableNames = cliExecutableNames(providerId);
217
235
  if (executableNames.length === 0) return false;
@@ -345,6 +363,12 @@ function resolveKeyFromAuthOrEnv(providerId: string): KeyLookup | null {
345
363
  }
346
364
 
347
365
  function resolveKey(providerId: string): KeyLookup {
366
+ if (providerId === "cursor-agent") {
367
+ return isExternalCliProviderReady(providerId)
368
+ ? { found: true, source: "env", backedOff: false }
369
+ : { found: false, source: "none", backedOff: false };
370
+ }
371
+
348
372
  const direct = resolveKeyFromAuthOrEnv(providerId);
349
373
  if (direct) return direct;
350
374
 
@@ -354,7 +378,7 @@ function resolveKey(providerId: string): KeyLookup {
354
378
 
355
379
  // Cross-provider routes can use a local CLI when it is installed. Explicit
356
380
  // external CLI provider selections are handled in checkLlmProviders() below.
357
- if (CLI_AUTH_PROVIDERS.has(providerId) && isCliBinaryInPath(providerId)) {
381
+ if (CLI_AUTH_PROVIDERS.has(providerId) && isExternalCliProviderReady(providerId)) {
358
382
  return { found: true, source: "env", backedOff: false };
359
383
  }
360
384
 
@@ -373,17 +397,22 @@ function checkLlmProviders(): ProviderCheckResult[] {
373
397
  if (CLI_AUTH_PROVIDERS.has(providerId)) {
374
398
  const info = PROVIDER_REGISTRY.find(p => p.id === providerId);
375
399
  const label = info?.label ?? providerId;
376
- if (CLI_AUTH_PATH_CHECK_PROVIDERS.has(providerId) && !isCliBinaryInPath(providerId)) {
400
+ if (CLI_AUTH_PATH_CHECK_PROVIDERS.has(providerId) && !isExternalCliProviderReady(providerId)) {
377
401
  const binaries = CLI_BINARY_MAP[providerId]?.map(binary => `\`${binary}\``).join(" or ");
402
+ const detail = providerId === "cursor-agent"
403
+ ? cursorAgentFailureDetail()
404
+ : binaries
405
+ ? `Install ${label} and ensure ${binaries} is on PATH`
406
+ : `Install ${label} and ensure its CLI is on PATH`;
378
407
  results.push({
379
408
  name: providerId,
380
409
  label,
381
410
  category: "llm",
382
411
  status: "error",
383
- message: `${label} CLI not found`,
384
- detail: binaries
385
- ? `Install ${label} and ensure ${binaries} is on PATH`
386
- : `Install ${label} and ensure its CLI is on PATH`,
412
+ message: providerId === "cursor-agent" && isCliBinaryInPath(providerId)
413
+ ? `${label} — CLI not authenticated`
414
+ : `${label} CLI not found`,
415
+ detail,
387
416
  required: true,
388
417
  });
389
418
  continue;
@@ -408,6 +408,9 @@ export async function checkRuntimeHealth(
408
408
  if (!existingLines.has(".gsd-worktrees/") && !existingLines.has(".gsd-worktrees")) {
409
409
  missing.push(".gsd-worktrees/");
410
410
  }
411
+ if (!existingLines.has(".gsd-backups/") && !existingLines.has(".gsd-backups")) {
412
+ missing.push(".gsd-backups/");
413
+ }
411
414
  if (!hasBlanketIgnore) {
412
415
  missing.push(...criticalPatterns.filter(p => !existingLines.has(p)));
413
416
  }
@@ -84,14 +84,21 @@ export type DoctorIssueCode =
84
84
  | "db_orphaned_task"
85
85
  | "db_orphaned_slice"
86
86
  | "db_done_task_no_summary"
87
+ | "artifact_file_missing"
88
+ | "artifact_user_content_missing"
87
89
  | "artifact_db_status_divergence"
90
+ | "checkbox_db_status_divergence"
88
91
  | "completed_milestone_reopened"
89
92
  | "db_duplicate_id"
90
93
  | "db_unavailable"
94
+ | "memories_fts_rebuild_missing"
91
95
  | "projection_drift"
92
96
  // Milestone filesystem/DB drift (#4996)
93
97
  | "orphan_milestone_dir"
94
- | "orphan_milestone_db";
98
+ | "orphan_milestone_db"
99
+ // Parent-workspace declared repository checks (#818)
100
+ | "workspace_repo_path_missing"
101
+ | "workspace_repo_not_a_repo";
95
102
 
96
103
  /**
97
104
  * Issue codes that represent global or completion-critical state.
@@ -1,5 +1,6 @@
1
- import { existsSync, mkdirSync, lstatSync, readdirSync, readFileSync } from "node:fs";
2
- import { join } from "node:path";
1
+ import { existsSync, mkdirSync, lstatSync, readdirSync, readFileSync, realpathSync } from "node:fs";
2
+ import { join, resolve } from "node:path";
3
+ import { execFileSync } from "node:child_process";
3
4
 
4
5
  import { loadFile, parseSummary, saveFile, parseTaskPlanMustHaves, countMustHavesMentionedInSummary } from "./files.js";
5
6
  import { parseRoadmap as parseLegacyRoadmap, parsePlan as parseLegacyPlan } from "./parsers-legacy.js";
@@ -16,6 +17,8 @@ import { isClosedStatus } from "./status-guards.js";
16
17
  import type { DoctorIssue, DoctorIssueCode, DoctorReport } from "./doctor-types.js";
17
18
  import { GLOBAL_STATE_CODES } from "./doctor-types.js";
18
19
  import type { RoadmapSliceEntry } from "./types.js";
20
+ import { GIT_NO_PROMPT_ENV } from "./git-constants.js";
21
+ import { createRepositoryRegistryFromPreferences } from "./repository-registry.js";
19
22
  import { checkGitHealth, checkRuntimeHealth, checkGlobalHealth, checkEngineHealth } from "./doctor-checks.js";
20
23
  import { checkEnvironmentHealth } from "./doctor-environment.js";
21
24
  import { runProviderChecks } from "./doctor-providers.js";
@@ -308,6 +311,94 @@ export async function readDoctorHistory(basePath: string, lastN = 50): Promise<D
308
311
  } catch { return []; }
309
312
  }
310
313
 
314
+ /**
315
+ * Resolve the git working-tree root for a path, or null if it is not a repo.
316
+ * Used by the workspace-repository probe to check that a declared child path is
317
+ * itself a git repository (not merely nested inside the parent's repo).
318
+ */
319
+ function resolveGitToplevel(cwd: string): string | null {
320
+ try {
321
+ const out = execFileSync("git", ["rev-parse", "--show-toplevel"], {
322
+ cwd,
323
+ stdio: ["ignore", "pipe", "pipe"],
324
+ encoding: "utf-8",
325
+ env: GIT_NO_PROMPT_ENV,
326
+ }).trim();
327
+ return out ? resolve(out) : null;
328
+ } catch {
329
+ return null;
330
+ }
331
+ }
332
+
333
+ /** realpath that falls back to the resolved path if the link cannot be read. */
334
+ function realpathSafe(p: string): string {
335
+ try {
336
+ return realpathSync(p);
337
+ } catch {
338
+ return resolve(p);
339
+ }
340
+ }
341
+
342
+ /**
343
+ * Parent-workspace probe (#818): validate that every declared child repository
344
+ * exists on disk and is a git repository at its own root. The registry only
345
+ * checks paths stay inside the project root; it never checks existence or
346
+ * git-ness, so a typo'd path (e.g. `frontned`) would otherwise build cleanly
347
+ * and silently produce "no problems found." No-op for single-repo projects.
348
+ */
349
+ function checkWorkspaceRepositoryHealth(
350
+ basePath: string,
351
+ prefs: GSDPreferences | undefined,
352
+ issues: DoctorIssue[],
353
+ ): void {
354
+ if (prefs?.workspace?.mode !== "parent") return;
355
+ let registry;
356
+ try {
357
+ registry = createRepositoryRegistryFromPreferences(basePath, prefs);
358
+ } catch (err) {
359
+ issues.push({
360
+ severity: "error",
361
+ code: "invalid_preferences",
362
+ scope: "project",
363
+ unitId: "workspace",
364
+ message: `workspace registry failed to build: ${err instanceof Error ? err.message : String(err)}`,
365
+ fixable: false,
366
+ });
367
+ return;
368
+ }
369
+ for (const repo of registry.repositories) {
370
+ if (repo.id === "project") continue;
371
+ if (!existsSync(repo.root)) {
372
+ issues.push({
373
+ severity: "error",
374
+ code: "workspace_repo_path_missing",
375
+ scope: "project",
376
+ unitId: `workspace.repositories.${repo.id}`,
377
+ message: `declared repository "${repo.id}" path does not exist on disk: ${repo.root}`,
378
+ fixable: false,
379
+ });
380
+ continue;
381
+ }
382
+ // Must be a repo at its OWN root — a plain dir nested in the parent repo
383
+ // would otherwise pass a bare `nativeIsRepo` check via the enclosing
384
+ // parent's .git. Compare on realpath so symlinked temp roots (macOS
385
+ // /var vs /private/var) don't cause a false mismatch.
386
+ const toplevel = resolveGitToplevel(repo.root);
387
+ const declaredReal = realpathSafe(repo.root);
388
+ const toplevelReal = toplevel ? realpathSafe(toplevel) : null;
389
+ if (toplevelReal !== declaredReal) {
390
+ issues.push({
391
+ severity: "warning",
392
+ code: "workspace_repo_not_a_repo",
393
+ scope: "project",
394
+ unitId: `workspace.repositories.${repo.id}`,
395
+ message: `declared repository "${repo.id}" path is not a git repository at its own root: ${repo.root}`,
396
+ fixable: false,
397
+ });
398
+ }
399
+ }
400
+ }
401
+
311
402
  export async function runGSDDoctor(basePath: string, options?: { fix?: boolean; dryRun?: boolean; scope?: string; fixLevel?: "task" | "all"; isolationMode?: "none" | "worktree" | "branch"; includeBuild?: boolean; includeTests?: boolean }): Promise<DoctorReport> {
312
403
  const issues: DoctorIssue[] = [];
313
404
  const fixesApplied: string[] = [];
@@ -366,6 +457,7 @@ export async function runGSDDoctor(basePath: string, options?: { fix?: boolean;
366
457
  (prefs?.preferences?.git?.isolation === "worktree" ? "worktree" :
367
458
  prefs?.preferences?.git?.isolation === "branch" ? "branch" : "none");
368
459
  await checkGitHealth(basePath, issues, fixesApplied, shouldFix, isolationMode, dryRun);
460
+ checkWorkspaceRepositoryHealth(basePath, prefs?.preferences, issues);
369
461
  const gitMs = Date.now() - t0git;
370
462
 
371
463
  // Runtime health checks — timed
@@ -386,7 +478,7 @@ export async function runGSDDoctor(basePath: string, options?: { fix?: boolean;
386
478
  const envMs = Date.now() - t0env;
387
479
 
388
480
  // Engine health checks — DB constraints and projection drift
389
- await checkEngineHealth(basePath, issues, fixesApplied);
481
+ await checkEngineHealth(basePath, issues, fixesApplied, { repair: fix && !dryRun });
390
482
 
391
483
  const milestonesPath = milestonesDir(basePath);
392
484
  const legacyMilestonesPath2 = legacyMilestonesDir(basePath);
@@ -12,7 +12,8 @@ import { spawn } from "node:child_process";
12
12
  import { existsSync, mkdirSync, writeFileSync } from "node:fs";
13
13
  import { randomUUID } from "node:crypto";
14
14
  import { resolve } from "node:path";
15
- import { killProcessTree, SIGKILL_GRACE_MS, HARD_DEADLINE_MS } from "@gsd/pi-coding-agent";
15
+ import { getShellConfig, killProcessTree, SIGKILL_GRACE_MS, HARD_DEADLINE_MS } from "@gsd/pi-coding-agent";
16
+ import { redactSecrets } from "./redact-secrets.js";
16
17
 
17
18
  export interface ExecSandboxRequest {
18
19
  /** Interpreter to use. */
@@ -138,7 +139,12 @@ function clampTimeout(request: ExecSandboxRequest, opts: ExecSandboxOptions): nu
138
139
  function resolveCommand(runtime: ExecSandboxRequest["runtime"]): { cmd: string; args: string[] } {
139
140
  switch (runtime) {
140
141
  case "bash":
141
- return { cmd: "bash", args: ["-c"] };
142
+ try {
143
+ const { shell, args } = getShellConfig();
144
+ return { cmd: shell, args };
145
+ } catch {
146
+ return { cmd: "bash", args: ["-c"] };
147
+ }
142
148
  case "node":
143
149
  return { cmd: process.execPath, args: ["-e"] };
144
150
  case "python":
@@ -310,8 +316,11 @@ export function runExecSandbox(
310
316
  const stderrBuf = Buffer.concat(stderrChunks);
311
317
  const stdoutSuffix = stdoutTruncated ? "\n[truncated: stdout cap reached]\n" : "";
312
318
  const stderrSuffix = stderrTruncated ? "\n[truncated: stderr cap reached]\n" : "";
313
- writeFileSync(stdoutPath, Buffer.concat([stdoutBuf, Buffer.from(stdoutSuffix, "utf-8")]));
314
- writeFileSync(stderrPath, Buffer.concat([stderrBuf, Buffer.from(stderrSuffix, "utf-8")]));
319
+ // Redact secret-shaped substrings before persisting to .gsd/exec/ (skipped by
320
+ // the secret scanner). The returned digest is derived from the raw buffer
321
+ // below and is redacted downstream when the session is written to activity/.
322
+ writeFileSync(stdoutPath, redactSecrets(Buffer.concat([stdoutBuf, Buffer.from(stdoutSuffix, "utf-8")]).toString("utf-8")));
323
+ writeFileSync(stderrPath, redactSecrets(Buffer.concat([stderrBuf, Buffer.from(stderrSuffix, "utf-8")]).toString("utf-8")));
315
324
 
316
325
  const digestBody = tail(stdoutBuf, opts.digest_chars);
317
326
  const digest =
@@ -11,18 +11,84 @@ import { migrateFromMarkdown } from "./md-importer.js";
11
11
  import { countDbHierarchy } from "./migration-auto-check.js";
12
12
  import { logWarning } from "./workflow-logger.js";
13
13
  import { LAYOUT_SEGMENTS } from "./layout-policy.js";
14
- import { canonicalPhaseDirName, milestonesDir, resolveMilestonePath } from "./paths.js";
14
+ import {
15
+ canonicalPhaseDirName,
16
+ dirIsContentBearingLegacyMilestone,
17
+ milestonesDir,
18
+ resolveMilestonePath,
19
+ } from "./paths.js";
15
20
 
16
21
  const LEGACY_MIGRATING_SEGMENT = "milestones.migrating";
22
+ const RETRYABLE_FS_ERROR_CODES = new Set(["EPERM", "EBUSY", "ENOTEMPTY"]);
23
+ const RM_RETRY_OPTIONS = { recursive: true, force: true, maxRetries: 5, retryDelay: 100 } as const;
24
+
25
+ type FlatPhaseMigrationFsOps = {
26
+ cpSync: typeof cpSync;
27
+ renameSync: typeof renameSync;
28
+ rmSync: typeof rmSync;
29
+ };
30
+
31
+ let fsOps: FlatPhaseMigrationFsOps = { cpSync, renameSync, rmSync };
32
+
33
+ export function _setFlatPhaseMigrationFsOpsForTest(
34
+ overrides: Partial<FlatPhaseMigrationFsOps>,
35
+ ): () => void {
36
+ const previous = fsOps;
37
+ fsOps = { ...fsOps, ...overrides };
38
+ return () => {
39
+ fsOps = previous;
40
+ };
41
+ }
17
42
 
18
43
  function legacyMigratingPath(basePath: string): string {
19
44
  return join(basePath, ".gsd", LEGACY_MIGRATING_SEGMENT);
20
45
  }
21
46
 
47
+ function removePathWithRetries(path: string): void {
48
+ fsOps.rmSync(path, { recursive: true, force: true, maxRetries: RM_RETRY_OPTIONS.maxRetries, retryDelay: RM_RETRY_OPTIONS.retryDelay });
49
+ }
50
+
51
+ function isRetryableFsError(err: unknown): boolean {
52
+ const code = (err as { code?: unknown } | null)?.code;
53
+ return typeof code === "string" && RETRYABLE_FS_ERROR_CODES.has(code);
54
+ }
55
+
56
+ function movePathWithCopyDeleteFallback(src: string, dst: string): void {
57
+ try {
58
+ fsOps.renameSync(src, dst);
59
+ return;
60
+ } catch (err) {
61
+ if (!isRetryableFsError(err)) throw err;
62
+ }
63
+
64
+ try {
65
+ fsOps.cpSync(src, dst, { recursive: true, force: true });
66
+ removePathWithRetries(src);
67
+ } catch (fallbackErr) {
68
+ if (existsSync(src) && existsSync(dst)) {
69
+ try {
70
+ removePathWithRetries(dst);
71
+ } catch {
72
+ // Leave the original error intact; the next run can pre-clean dst.
73
+ }
74
+ }
75
+ throw fallbackErr;
76
+ }
77
+ }
78
+
79
+ function expectedPhaseDirs(basePath: string): string[] {
80
+ return getAllMilestones().map((milestone) =>
81
+ resolveMilestonePath(basePath, milestone.id) ??
82
+ join(milestonesDir(basePath), canonicalPhaseDirName(milestone.id, milestone.title)),
83
+ );
84
+ }
85
+
22
86
  function hasLegacyMilestoneSubdirs(dirPath: string): boolean {
23
87
  if (!existsSync(dirPath)) return false;
24
88
  try {
25
- return readdirSync(dirPath).some(e => statSync(join(dirPath, e)).isDirectory());
89
+ return readdirSync(dirPath).some(
90
+ (e) => statSync(join(dirPath, e)).isDirectory() && dirIsContentBearingLegacyMilestone(join(dirPath, e)),
91
+ );
26
92
  } catch {
27
93
  return false;
28
94
  }
@@ -34,19 +100,26 @@ function rollbackPartialMigration(
34
100
  migratingPath?: string,
35
101
  ): void {
36
102
  // Remove the partially-written phases/ dir.
37
- rmSync(join(basePath, ".gsd", LAYOUT_SEGMENTS.level1), { recursive: true, force: true });
103
+ try {
104
+ removePathWithRetries(join(basePath, ".gsd", LAYOUT_SEGMENTS.level1));
105
+ } catch (removeErr) {
106
+ logWarning(
107
+ "migration",
108
+ `rollback: could not remove partial ${LAYOUT_SEGMENTS.level1}/: ${(removeErr as Error).message}`,
109
+ );
110
+ }
38
111
  // Restore milestones/ — prefer renaming the preserved migrating copy back.
39
112
  const milestonesPath = join(basePath, ".gsd", "milestones");
40
113
  try {
41
114
  if (migratingPath && existsSync(migratingPath) && !existsSync(milestonesPath)) {
42
- renameSync(migratingPath, milestonesPath);
115
+ movePathWithCopyDeleteFallback(migratingPath, milestonesPath);
43
116
  return;
44
117
  }
45
118
  if (existsSync(backupDir)) {
46
119
  cpSync(backupDir, milestonesPath, { recursive: true });
47
120
  }
48
121
  if (migratingPath && existsSync(migratingPath)) {
49
- rmSync(migratingPath, { recursive: true, force: true });
122
+ removePathWithRetries(migratingPath);
50
123
  }
51
124
  } catch (restoreErr) {
52
125
  logWarning(
@@ -70,6 +143,50 @@ export function needsFlatPhaseMigration(basePath: string): boolean {
70
143
  return hasLegacyMilestoneSubdirs(legacyMigratingPath(basePath));
71
144
  }
72
145
 
146
+ /** Retention window before flat-phase migration backups are auto-pruned. */
147
+ export const FLAT_PHASE_BACKUP_RETENTION_MS = 30 * 24 * 60 * 60 * 1000;
148
+
149
+ /**
150
+ * Remove stale flat-phase migration backups after the retention window.
151
+ * Only runs when migration is complete (.gsd/phases/ exists, legacy layout gone).
152
+ * Returns the number of migrate-* directories removed.
153
+ */
154
+ export function pruneStaleFlatPhaseBackups(basePath: string): number {
155
+ if (needsFlatPhaseMigration(basePath)) return 0;
156
+
157
+ const phasesPath = join(basePath, ".gsd", LAYOUT_SEGMENTS.level1);
158
+ if (!existsSync(phasesPath)) return 0;
159
+
160
+ const backupRoot = join(basePath, ".gsd-backups");
161
+ if (!existsSync(backupRoot)) return 0;
162
+
163
+ const now = Date.now();
164
+ let removed = 0;
165
+ for (const entry of readdirSync(backupRoot)) {
166
+ if (!entry.startsWith("migrate-")) continue;
167
+ const dirPath = join(backupRoot, entry);
168
+ try {
169
+ const st = statSync(dirPath);
170
+ if (!st.isDirectory()) continue;
171
+ if (now - st.mtimeMs < FLAT_PHASE_BACKUP_RETENTION_MS) continue;
172
+ rmSync(dirPath, { recursive: true, force: true });
173
+ removed++;
174
+ } catch {
175
+ // Non-fatal: leave backup for manual recovery.
176
+ }
177
+ }
178
+
179
+ try {
180
+ if (readdirSync(backupRoot).length === 0) {
181
+ rmSync(backupRoot, { recursive: true, force: true });
182
+ }
183
+ } catch {
184
+ // Non-fatal.
185
+ }
186
+
187
+ return removed;
188
+ }
189
+
73
190
  /**
74
191
  * Migrate from legacy nested .gsd/milestones/ to flat-phase .gsd/phases/.
75
192
  *
@@ -118,18 +235,29 @@ export async function migrateToFlatPhase(basePath: string): Promise<void> {
118
235
  throw err;
119
236
  }
120
237
 
238
+ if (existsSync(migratingPath)) {
239
+ removePathWithRetries(migratingPath);
240
+ }
241
+
121
242
  // 3. Rename legacy tree aside before rendering so path resolvers target
122
243
  // phases/ instead of writing back into the nested milestones/ layout.
123
244
  // Keep the full tree on disk until render+verify succeed (unlike rmSync).
124
245
  try {
125
- renameSync(milestonesPath, migratingPath);
246
+ movePathWithCopyDeleteFallback(milestonesPath, migratingPath);
126
247
  } catch (err) {
127
248
  logWarning("migration", `failed to rename legacy milestones/ before render: ${(err as Error).message}`);
128
249
  throw err;
129
250
  }
130
- } else {
131
- // Interrupted run: clear any partial phases/ projection before retrying.
132
- rmSync(phasesPath, { recursive: true, force: true });
251
+ }
252
+
253
+ // Clear any stale or partially-rendered flat projection before this run
254
+ // writes. Verification below checks the current DB render, not leftovers.
255
+ try {
256
+ removePathWithRetries(phasesPath);
257
+ } catch (err) {
258
+ logWarning("migration", `failed to clear stale phases/ before render: ${(err as Error).message}`);
259
+ rollbackPartialMigration(basePath, backupDir, migratingPath);
260
+ throw err;
133
261
  }
134
262
 
135
263
  // 4. Render flat-phase from DB
@@ -167,22 +295,14 @@ export async function migrateToFlatPhase(basePath: string): Promise<void> {
167
295
  }
168
296
 
169
297
  const db = countDbHierarchy();
170
- let renderedDirCount = 0;
171
- try {
172
- // /^\d+-/ matches any numeric prefix (01-, 10-, 100-) so M100+ milestones
173
- // whose dirs start with "100-slug" are counted correctly.
174
- renderedDirCount = readdirSync(phasesPath, { withFileTypes: true })
175
- .filter((entry) => entry.isDirectory() && /^\d+-/.test(entry.name)).length;
176
- } catch {
177
- // phases/ doesn't exist or is unreadable — same as zero dirs
178
- }
179
- if (db.milestones > 0 && renderedDirCount !== db.milestones) {
298
+ const missingPhaseDirs = expectedPhaseDirs(basePath).filter((phaseDir) => !existsSync(phaseDir));
299
+ if (db.milestones > 0 && missingPhaseDirs.length > 0) {
180
300
  logWarning(
181
301
  "migration",
182
- `phases/ dir count mismatch: expected ${db.milestones}, found ${renderedDirCount}`,
302
+ `flat-phase migration missing ${missingPhaseDirs.length} expected phase dir(s): ${missingPhaseDirs.join(", ")}`,
183
303
  );
184
304
  rollbackPartialMigration(basePath, backupDir, migratingPath);
185
- throw new Error("flat-phase migration verification failed: phases dir milestone count mismatch");
305
+ throw new Error("flat-phase migration verification failed: missing rendered phase directories");
186
306
  }
187
307
  if (db.slices > 0 && renderResult.rendered === 0) {
188
308
  logWarning(
@@ -195,7 +315,7 @@ export async function migrateToFlatPhase(basePath: string): Promise<void> {
195
315
 
196
316
  // 6. Verified — remove the renamed legacy tree (backup already on disk).
197
317
  try {
198
- rmSync(migratingPath, { recursive: true, force: true });
318
+ removePathWithRetries(migratingPath);
199
319
  } catch (err) {
200
320
  logWarning(
201
321
  "migration",