@opengsd/gsd-pi 1.8.1 → 1.9.0-dev.5c1a3ff2

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 (546) hide show
  1. package/README.md +10 -8
  2. package/dist/cli.js +5 -1
  3. package/dist/headless-events.d.ts +2 -1
  4. package/dist/headless-events.js +11 -3
  5. package/dist/headless-milestone-readiness.d.ts +29 -0
  6. package/dist/headless-milestone-readiness.js +161 -0
  7. package/dist/headless.js +25 -2
  8. package/dist/print-mode-exit.d.ts +12 -0
  9. package/dist/print-mode-exit.js +14 -0
  10. package/dist/resources/.managed-resources-content-hash +1 -1
  11. package/dist/resources/GSD-WORKFLOW.md +18 -49
  12. package/dist/resources/extensions/browser-tools/capture.js +2 -77
  13. package/dist/resources/extensions/browser-tools/screenshot-constraints.js +83 -0
  14. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +17 -2
  15. package/dist/resources/extensions/claude-code-cli/turn-assembler.js +30 -2
  16. package/dist/resources/extensions/gsd/artifact-verification.js +3 -4
  17. package/dist/resources/extensions/gsd/auto-artifact-paths.js +16 -10
  18. package/dist/resources/extensions/gsd/auto-dispatch.js +74 -19
  19. package/dist/resources/extensions/gsd/auto-post-unit.js +4 -0
  20. package/dist/resources/extensions/gsd/auto-prompts.js +125 -18
  21. package/dist/resources/extensions/gsd/auto-recovery.js +10 -5
  22. package/dist/resources/extensions/gsd/auto-worktree-cleanup.js +4 -0
  23. package/dist/resources/extensions/gsd/auto-worktree-teardown.js +1 -1
  24. package/dist/resources/extensions/gsd/auto.js +5 -1
  25. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +80 -4
  26. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +31 -5
  27. package/dist/resources/extensions/gsd/bootstrap/system-context.js +10 -3
  28. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +88 -50
  29. package/dist/resources/extensions/gsd/command-feedback.js +16 -12
  30. package/dist/resources/extensions/gsd/compat/compat-marker.js +19 -2
  31. package/dist/resources/extensions/gsd/constants.js +12 -13
  32. package/dist/resources/extensions/gsd/context-masker.js +97 -21
  33. package/dist/resources/extensions/gsd/db/command-queue.js +7 -2
  34. package/dist/resources/extensions/gsd/db/engine.js +51 -16
  35. package/dist/resources/extensions/gsd/db/writers/cascades.js +5 -1
  36. package/dist/resources/extensions/gsd/db/writers/status.js +13 -3
  37. package/dist/resources/extensions/gsd/db-base-schema.js +28 -0
  38. package/dist/resources/extensions/gsd/db-migration-steps.js +30 -0
  39. package/dist/resources/extensions/gsd/db-schema-metadata.js +4 -1
  40. package/dist/resources/extensions/gsd/docs/preferences-reference.md +26 -4
  41. package/dist/resources/extensions/gsd/doctor-engine-checks.js +3 -6
  42. package/dist/resources/extensions/gsd/flat-phase-migration.js +156 -21
  43. package/dist/resources/extensions/gsd/git-service.js +19 -7
  44. package/dist/resources/extensions/gsd/gsd-db.js +187 -45
  45. package/dist/resources/extensions/gsd/guided-flow.js +38 -13
  46. package/dist/resources/extensions/gsd/markdown-renderer.js +17 -13
  47. package/dist/resources/extensions/gsd/md-importer.js +107 -20
  48. package/dist/resources/extensions/gsd/migrate/command.js +19 -162
  49. package/dist/resources/extensions/gsd/migrate/execution.js +98 -0
  50. package/dist/resources/extensions/gsd/migrate/plan.js +49 -0
  51. package/dist/resources/extensions/gsd/migrate/planning-writer.js +12 -17
  52. package/dist/resources/extensions/gsd/migrate/presentation.js +64 -0
  53. package/dist/resources/extensions/gsd/model-cost-table.js +2 -0
  54. package/dist/resources/extensions/gsd/model-router.js +11 -0
  55. package/dist/resources/extensions/gsd/parallel-eligibility.js +5 -4
  56. package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +28 -43
  57. package/dist/resources/extensions/gsd/paths.js +55 -11
  58. package/dist/resources/extensions/gsd/phase-anchor.js +7 -2
  59. package/dist/resources/extensions/gsd/planning-subagent-policy.js +37 -0
  60. package/dist/resources/extensions/gsd/planning-subagent-registry.js +25 -0
  61. package/dist/resources/extensions/gsd/post-execution-checks.js +4 -4
  62. package/dist/resources/extensions/gsd/preferences-types.js +5 -0
  63. package/dist/resources/extensions/gsd/preferences-validation.js +48 -1
  64. package/dist/resources/extensions/gsd/preferences.js +17 -0
  65. package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  66. package/dist/resources/extensions/gsd/provider-payload-policy.js +16 -5
  67. package/dist/resources/extensions/gsd/safety/destructive-guard.js +1 -1
  68. package/dist/resources/extensions/gsd/safety/evidence-collector.js +26 -1
  69. package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +30 -5
  70. package/dist/resources/extensions/gsd/skill-activation.js +17 -3
  71. package/dist/resources/extensions/gsd/state-reconciliation/drift/external-markdown-edit.js +27 -13
  72. package/dist/resources/extensions/gsd/state-reconciliation/drift/external-planning-edit.js +13 -3
  73. package/dist/resources/extensions/gsd/stop-notice.js +15 -1
  74. package/dist/resources/extensions/gsd/sync-lock.js +13 -7
  75. package/dist/resources/extensions/gsd/templates/PREFERENCES.md +5 -0
  76. package/dist/resources/extensions/gsd/tools/complete-task.js +94 -6
  77. package/dist/resources/extensions/gsd/tools/plan-task.js +13 -15
  78. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +18 -15
  79. package/dist/resources/extensions/gsd/tools/reopen-milestone.js +14 -5
  80. package/dist/resources/extensions/gsd/tools/reopen-slice.js +15 -5
  81. package/dist/resources/extensions/gsd/tools/reopen-task.js +16 -10
  82. package/dist/resources/extensions/gsd/tools/replan-task.js +128 -0
  83. package/dist/resources/extensions/gsd/tools/rework-brief.js +74 -0
  84. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +81 -0
  85. package/dist/resources/extensions/gsd/unit-context-composer.js +28 -5
  86. package/dist/resources/extensions/gsd/unit-registry.js +4 -0
  87. package/dist/resources/extensions/gsd/uok/plan-v2.js +19 -3
  88. package/dist/resources/extensions/gsd/workflow-projections.js +2 -3
  89. package/dist/resources/extensions/gsd/workspace.js +2 -1
  90. package/dist/resources/extensions/gsd/worktree-state-projection.js +6 -0
  91. package/dist/resources/extensions/mac-tools/index.js +31 -9
  92. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  93. package/dist/web/standalone/.next/BUILD_ID +1 -1
  94. package/dist/web/standalone/.next/app-path-routes-manifest.json +8 -8
  95. package/dist/web/standalone/.next/build-manifest.json +3 -3
  96. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  97. package/dist/web/standalone/.next/required-server-files.json +3 -3
  98. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  99. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  100. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  101. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  102. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  103. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  104. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  105. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  106. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  107. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  108. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  109. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  110. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  111. package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -4
  112. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -4
  113. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  114. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -4
  115. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  116. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  117. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  118. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  119. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  120. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  121. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  122. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  123. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  124. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  125. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  126. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  127. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  128. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  129. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  130. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  131. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  132. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  137. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/mcp-connections/route_client-reference-manifest.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  159. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  169. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  175. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  191. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  195. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  197. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  199. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  200. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  201. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  202. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  203. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  204. package/dist/web/standalone/.next/server/app/index.html +1 -1
  205. package/dist/web/standalone/.next/server/app/index.rsc +5 -5
  206. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  207. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +5 -5
  208. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  209. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -4
  210. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  211. package/dist/web/standalone/.next/server/app/page.js +2 -2
  212. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  213. package/dist/web/standalone/.next/server/app-paths-manifest.json +8 -8
  214. package/dist/web/standalone/.next/server/chunks/2842.js +4 -4
  215. package/dist/web/standalone/.next/server/chunks/8357.js +3 -3
  216. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  217. package/dist/web/standalone/.next/server/middleware.js +3 -3
  218. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  219. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  220. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  221. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-a6fb1847f67f167c.js +1 -0
  222. package/dist/web/standalone/.next/static/chunks/app/{layout-b35cbfff38aaf4cf.js → layout-4ae2d68984392bbf.js} +1 -1
  223. package/dist/web/standalone/.next/static/chunks/app/page-72a856634ad14c10.js +1 -0
  224. package/dist/web/standalone/.next/static/chunks/{main-app-590a74400e35f685.js → main-app-90d1d8d5e5d2dc6b.js} +1 -1
  225. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-1115d46ac61b9823.js +1 -0
  226. package/dist/web/standalone/.next/static/css/3b1ceb7abfb9a230.css +1 -0
  227. package/dist/web/standalone/node_modules/@gsd/native/package.json +1 -1
  228. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  229. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  230. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  231. package/dist/web/standalone/package.json +0 -1
  232. package/dist/web/standalone/server.js +1 -1
  233. package/dist/web-mode.js +31 -3
  234. package/integrations/hermes/open_gsd_hermes/gsd_client.py +1 -1
  235. package/integrations/hermes/pyproject.toml +1 -1
  236. package/package.json +12 -10
  237. package/packages/cloud-mcp-gateway/package.json +2 -2
  238. package/packages/contracts/dist/workflow.d.ts +14 -0
  239. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  240. package/packages/contracts/dist/workflow.js +16 -0
  241. package/packages/contracts/dist/workflow.js.map +1 -1
  242. package/packages/contracts/package.json +1 -1
  243. package/packages/daemon/dist/cloud-config.d.ts +1 -1
  244. package/packages/daemon/dist/cloud-config.d.ts.map +1 -1
  245. package/packages/daemon/dist/cloud-config.js +5 -1
  246. package/packages/daemon/dist/cloud-config.js.map +1 -1
  247. package/packages/daemon/dist/cloud-config.test.js +51 -1
  248. package/packages/daemon/dist/cloud-config.test.js.map +1 -1
  249. package/packages/daemon/dist/local-tool-executor.d.ts.map +1 -1
  250. package/packages/daemon/dist/local-tool-executor.js +2 -0
  251. package/packages/daemon/dist/local-tool-executor.js.map +1 -1
  252. package/packages/daemon/package.json +6 -6
  253. package/packages/gsd-agent-core/dist/compaction/compaction.d.ts.map +1 -1
  254. package/packages/gsd-agent-core/dist/compaction/compaction.js +36 -4
  255. package/packages/gsd-agent-core/dist/compaction/compaction.js.map +1 -1
  256. package/packages/gsd-agent-core/dist/sdk.d.ts.map +1 -1
  257. package/packages/gsd-agent-core/dist/sdk.js +1 -0
  258. package/packages/gsd-agent-core/dist/sdk.js.map +1 -1
  259. package/packages/gsd-agent-core/package.json +5 -5
  260. package/packages/gsd-agent-modes/package.json +7 -7
  261. package/packages/gsd-cloud/dist/cli.d.ts +5 -0
  262. package/packages/gsd-cloud/dist/cli.d.ts.map +1 -0
  263. package/packages/gsd-cloud/dist/cli.js +160 -0
  264. package/packages/gsd-cloud/dist/cli.js.map +1 -0
  265. package/packages/gsd-cloud/dist/cloud-config.d.ts +19 -0
  266. package/packages/gsd-cloud/dist/cloud-config.d.ts.map +1 -0
  267. package/packages/gsd-cloud/dist/cloud-config.js +231 -0
  268. package/packages/gsd-cloud/dist/cloud-config.js.map +1 -0
  269. package/packages/gsd-cloud/dist/cloud-config.test.d.ts +2 -0
  270. package/packages/gsd-cloud/dist/cloud-config.test.d.ts.map +1 -0
  271. package/packages/gsd-cloud/dist/cloud-config.test.js +118 -0
  272. package/packages/gsd-cloud/dist/cloud-config.test.js.map +1 -0
  273. package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.d.ts +2 -0
  274. package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.d.ts.map +1 -0
  275. package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.js +37 -0
  276. package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.js.map +1 -0
  277. package/packages/gsd-cloud/dist/cloud-runtime.d.ts +35 -0
  278. package/packages/gsd-cloud/dist/cloud-runtime.d.ts.map +1 -0
  279. package/packages/gsd-cloud/dist/cloud-runtime.js +258 -0
  280. package/packages/gsd-cloud/dist/cloud-runtime.js.map +1 -0
  281. package/packages/gsd-cloud/dist/cloud-runtime.test.d.ts +2 -0
  282. package/packages/gsd-cloud/dist/cloud-runtime.test.d.ts.map +1 -0
  283. package/packages/gsd-cloud/dist/cloud-runtime.test.js +88 -0
  284. package/packages/gsd-cloud/dist/cloud-runtime.test.js.map +1 -0
  285. package/packages/gsd-cloud/dist/cloud-token.d.ts +3 -0
  286. package/packages/gsd-cloud/dist/cloud-token.d.ts.map +1 -0
  287. package/packages/gsd-cloud/dist/cloud-token.js +37 -0
  288. package/packages/gsd-cloud/dist/cloud-token.js.map +1 -0
  289. package/packages/gsd-cloud/dist/config.d.ts +17 -0
  290. package/packages/gsd-cloud/dist/config.d.ts.map +1 -0
  291. package/packages/gsd-cloud/dist/config.js +146 -0
  292. package/packages/gsd-cloud/dist/config.js.map +1 -0
  293. package/packages/gsd-cloud/dist/device-flow.d.ts +24 -0
  294. package/packages/gsd-cloud/dist/device-flow.d.ts.map +1 -0
  295. package/packages/gsd-cloud/dist/device-flow.js +128 -0
  296. package/packages/gsd-cloud/dist/device-flow.js.map +1 -0
  297. package/packages/gsd-cloud/dist/device-flow.test.d.ts +2 -0
  298. package/packages/gsd-cloud/dist/device-flow.test.d.ts.map +1 -0
  299. package/packages/gsd-cloud/dist/device-flow.test.js +155 -0
  300. package/packages/gsd-cloud/dist/device-flow.test.js.map +1 -0
  301. package/packages/gsd-cloud/dist/executors/claude-executor.d.ts +6 -0
  302. package/packages/gsd-cloud/dist/executors/claude-executor.d.ts.map +1 -0
  303. package/packages/gsd-cloud/dist/executors/claude-executor.js +15 -0
  304. package/packages/gsd-cloud/dist/executors/claude-executor.js.map +1 -0
  305. package/packages/gsd-cloud/dist/executors/codex-executor.d.ts +6 -0
  306. package/packages/gsd-cloud/dist/executors/codex-executor.d.ts.map +1 -0
  307. package/packages/gsd-cloud/dist/executors/codex-executor.js +15 -0
  308. package/packages/gsd-cloud/dist/executors/codex-executor.js.map +1 -0
  309. package/packages/gsd-cloud/dist/executors/executor.d.ts +28 -0
  310. package/packages/gsd-cloud/dist/executors/executor.d.ts.map +1 -0
  311. package/packages/gsd-cloud/dist/executors/executor.js +11 -0
  312. package/packages/gsd-cloud/dist/executors/executor.js.map +1 -0
  313. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.d.ts +34 -0
  314. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.d.ts.map +1 -0
  315. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.js +179 -0
  316. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.js.map +1 -0
  317. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.d.ts +2 -0
  318. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.d.ts.map +1 -0
  319. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.js +44 -0
  320. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.js.map +1 -0
  321. package/packages/gsd-cloud/dist/executors/index.d.ts +17 -0
  322. package/packages/gsd-cloud/dist/executors/index.d.ts.map +1 -0
  323. package/packages/gsd-cloud/dist/executors/index.js +29 -0
  324. package/packages/gsd-cloud/dist/executors/index.js.map +1 -0
  325. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.d.ts +36 -0
  326. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.d.ts.map +1 -0
  327. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.js +176 -0
  328. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.js.map +1 -0
  329. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.d.ts +2 -0
  330. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.d.ts.map +1 -0
  331. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.js +34 -0
  332. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.js.map +1 -0
  333. package/packages/gsd-cloud/dist/index.d.ts +7 -0
  334. package/packages/gsd-cloud/dist/index.d.ts.map +1 -0
  335. package/packages/gsd-cloud/dist/index.js +8 -0
  336. package/packages/gsd-cloud/dist/index.js.map +1 -0
  337. package/packages/gsd-cloud/dist/inject-gateway.d.ts +16 -0
  338. package/packages/gsd-cloud/dist/inject-gateway.d.ts.map +1 -0
  339. package/packages/gsd-cloud/dist/inject-gateway.js +29 -0
  340. package/packages/gsd-cloud/dist/inject-gateway.js.map +1 -0
  341. package/packages/gsd-cloud/dist/inject-gateway.test.d.ts +2 -0
  342. package/packages/gsd-cloud/dist/inject-gateway.test.d.ts.map +1 -0
  343. package/packages/gsd-cloud/dist/inject-gateway.test.js +41 -0
  344. package/packages/gsd-cloud/dist/inject-gateway.test.js.map +1 -0
  345. package/packages/gsd-cloud/dist/logger.d.ts +25 -0
  346. package/packages/gsd-cloud/dist/logger.d.ts.map +1 -0
  347. package/packages/gsd-cloud/dist/logger.js +72 -0
  348. package/packages/gsd-cloud/dist/logger.js.map +1 -0
  349. package/packages/gsd-cloud/dist/types.d.ts +51 -0
  350. package/packages/gsd-cloud/dist/types.d.ts.map +1 -0
  351. package/packages/gsd-cloud/dist/types.js +9 -0
  352. package/packages/gsd-cloud/dist/types.js.map +1 -0
  353. package/packages/gsd-cloud/package.json +3 -3
  354. package/packages/mcp-server/README.md +15 -2
  355. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  356. package/packages/mcp-server/dist/server.js +5 -5
  357. package/packages/mcp-server/dist/server.js.map +1 -1
  358. package/packages/mcp-server/dist/workflow-tools.d.ts +4 -3
  359. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  360. package/packages/mcp-server/dist/workflow-tools.js +64 -2
  361. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  362. package/packages/mcp-server/package.json +4 -4
  363. package/packages/native/package.json +1 -1
  364. package/packages/pi-agent-core/dist/agent.d.ts +5 -1
  365. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  366. package/packages/pi-agent-core/dist/agent.js +2 -0
  367. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  368. package/packages/pi-agent-core/package.json +1 -1
  369. package/packages/pi-ai/dist/models.generated.d.ts +119 -0
  370. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  371. package/packages/pi-ai/dist/models.generated.js +107 -0
  372. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  373. package/packages/pi-ai/dist/providers/amazon-bedrock.js +1 -0
  374. package/packages/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
  375. package/packages/pi-ai/dist/providers/anthropic.js +25 -1
  376. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  377. package/packages/pi-ai/dist/providers/openai-codex-responses.js +1 -1
  378. package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
  379. package/packages/pi-ai/dist/providers/openai-responses.js +1 -1
  380. package/packages/pi-ai/dist/providers/openai-responses.js.map +1 -1
  381. package/packages/pi-ai/package.json +1 -1
  382. package/packages/pi-coding-agent/dist/core/capability-patches.js +1 -1
  383. package/packages/pi-coding-agent/dist/core/capability-patches.js.map +1 -1
  384. package/packages/pi-coding-agent/dist/core/model-resolver.js +1 -1
  385. package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
  386. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +11 -1
  387. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  388. package/packages/pi-coding-agent/dist/core/settings-manager.js +8 -0
  389. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  390. package/packages/pi-coding-agent/package.json +7 -7
  391. package/packages/pi-tui/package.json +2 -2
  392. package/packages/rpc-client/package.json +2 -2
  393. package/pkg/package.json +1 -1
  394. package/src/resources/GSD-WORKFLOW.md +18 -49
  395. package/src/resources/extensions/browser-tools/capture.ts +2 -86
  396. package/src/resources/extensions/browser-tools/screenshot-constraints.ts +94 -0
  397. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +18 -1
  398. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +108 -0
  399. package/src/resources/extensions/claude-code-cli/turn-assembler.ts +30 -2
  400. package/src/resources/extensions/gsd/artifact-verification.ts +3 -8
  401. package/src/resources/extensions/gsd/auto-artifact-paths.ts +16 -9
  402. package/src/resources/extensions/gsd/auto-dispatch.ts +86 -19
  403. package/src/resources/extensions/gsd/auto-post-unit.ts +4 -0
  404. package/src/resources/extensions/gsd/auto-prompts.ts +142 -16
  405. package/src/resources/extensions/gsd/auto-recovery.ts +10 -8
  406. package/src/resources/extensions/gsd/auto-worktree-cleanup.ts +4 -0
  407. package/src/resources/extensions/gsd/auto-worktree-teardown.ts +1 -1
  408. package/src/resources/extensions/gsd/auto.ts +5 -1
  409. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +92 -4
  410. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +39 -10
  411. package/src/resources/extensions/gsd/bootstrap/system-context.ts +11 -3
  412. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +87 -53
  413. package/src/resources/extensions/gsd/command-feedback.ts +19 -12
  414. package/src/resources/extensions/gsd/compat/compat-marker.ts +21 -4
  415. package/src/resources/extensions/gsd/constants.ts +14 -13
  416. package/src/resources/extensions/gsd/context-masker.ts +98 -2
  417. package/src/resources/extensions/gsd/db/command-queue.ts +7 -1
  418. package/src/resources/extensions/gsd/db/engine.ts +53 -17
  419. package/src/resources/extensions/gsd/db/writers/cascades.ts +5 -1
  420. package/src/resources/extensions/gsd/db/writers/status.ts +25 -8
  421. package/src/resources/extensions/gsd/db-base-schema.ts +30 -0
  422. package/src/resources/extensions/gsd/db-migration-steps.ts +32 -0
  423. package/src/resources/extensions/gsd/db-schema-metadata.ts +4 -1
  424. package/src/resources/extensions/gsd/docs/preferences-reference.md +26 -4
  425. package/src/resources/extensions/gsd/doctor-engine-checks.ts +3 -5
  426. package/src/resources/extensions/gsd/flat-phase-migration.ts +160 -19
  427. package/src/resources/extensions/gsd/git-service.ts +19 -6
  428. package/src/resources/extensions/gsd/gsd-db.ts +255 -52
  429. package/src/resources/extensions/gsd/guided-flow.ts +48 -12
  430. package/src/resources/extensions/gsd/markdown-renderer.ts +25 -21
  431. package/src/resources/extensions/gsd/md-importer.ts +114 -16
  432. package/src/resources/extensions/gsd/migrate/command.ts +21 -227
  433. package/src/resources/extensions/gsd/migrate/execution.ts +136 -0
  434. package/src/resources/extensions/gsd/migrate/plan.ts +101 -0
  435. package/src/resources/extensions/gsd/migrate/planning-writer.ts +12 -20
  436. package/src/resources/extensions/gsd/migrate/presentation.ts +83 -0
  437. package/src/resources/extensions/gsd/model-cost-table.ts +2 -0
  438. package/src/resources/extensions/gsd/model-router.ts +12 -0
  439. package/src/resources/extensions/gsd/parallel-eligibility.ts +5 -4
  440. package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +37 -40
  441. package/src/resources/extensions/gsd/paths.ts +62 -11
  442. package/src/resources/extensions/gsd/phase-anchor.ts +8 -2
  443. package/src/resources/extensions/gsd/planning-subagent-policy.ts +58 -0
  444. package/src/resources/extensions/gsd/planning-subagent-registry.ts +31 -0
  445. package/src/resources/extensions/gsd/post-execution-checks.ts +4 -4
  446. package/src/resources/extensions/gsd/preferences-types.ts +16 -0
  447. package/src/resources/extensions/gsd/preferences-validation.ts +62 -0
  448. package/src/resources/extensions/gsd/preferences.ts +25 -0
  449. package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  450. package/src/resources/extensions/gsd/provider-payload-policy.ts +18 -4
  451. package/src/resources/extensions/gsd/safety/destructive-guard.ts +1 -1
  452. package/src/resources/extensions/gsd/safety/evidence-collector.ts +28 -1
  453. package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +31 -5
  454. package/src/resources/extensions/gsd/skill-activation.ts +17 -3
  455. package/src/resources/extensions/gsd/state-reconciliation/drift/external-markdown-edit.ts +30 -13
  456. package/src/resources/extensions/gsd/state-reconciliation/drift/external-planning-edit.ts +16 -3
  457. package/src/resources/extensions/gsd/state-reconciliation/types.ts +2 -2
  458. package/src/resources/extensions/gsd/stop-notice.ts +18 -1
  459. package/src/resources/extensions/gsd/sync-lock.ts +14 -6
  460. package/src/resources/extensions/gsd/templates/PREFERENCES.md +5 -0
  461. package/src/resources/extensions/gsd/tests/auto-artifact-paths.test.ts +7 -7
  462. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +39 -0
  463. package/src/resources/extensions/gsd/tests/before-provider-context-management.test.ts +55 -0
  464. package/src/resources/extensions/gsd/tests/closeout-git-deferral.test.ts +96 -1
  465. package/src/resources/extensions/gsd/tests/command-feedback.test.ts +12 -0
  466. package/src/resources/extensions/gsd/tests/compat-marker.test.ts +104 -0
  467. package/src/resources/extensions/gsd/tests/complete-task.test.ts +362 -1
  468. package/src/resources/extensions/gsd/tests/context-masker.test.ts +204 -8
  469. package/src/resources/extensions/gsd/tests/db-engine-migrate-guards.test.ts +186 -0
  470. package/src/resources/extensions/gsd/tests/db-tools-alias-suppression.test.ts +62 -0
  471. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +29 -0
  472. package/src/resources/extensions/gsd/tests/destructive-confirmation.test.ts +33 -0
  473. package/src/resources/extensions/gsd/tests/destructive-guard.test.ts +14 -0
  474. package/src/resources/extensions/gsd/tests/discuss-routing-fixes.test.ts +123 -0
  475. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +50 -0
  476. package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +49 -0
  477. package/src/resources/extensions/gsd/tests/evidence-cross-ref.test.ts +81 -0
  478. package/src/resources/extensions/gsd/tests/evidence-xref-gsd-exec.test.ts +22 -0
  479. package/src/resources/extensions/gsd/tests/external-edit-scoped-import.test.ts +262 -0
  480. package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +202 -0
  481. package/src/resources/extensions/gsd/tests/gate-storage.test.ts +29 -0
  482. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +25 -0
  483. package/src/resources/extensions/gsd/tests/import-slice-milestone-completion-preserve.test.ts +116 -0
  484. package/src/resources/extensions/gsd/tests/integration/paths.test.ts +22 -4
  485. package/src/resources/extensions/gsd/tests/integration-branch-meta-location.test.ts +62 -0
  486. package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +5 -5
  487. package/src/resources/extensions/gsd/tests/migrate-plan.test.ts +68 -0
  488. package/src/resources/extensions/gsd/tests/migrate-presentation.test.ts +98 -0
  489. package/src/resources/extensions/gsd/tests/migrate-safety-audit.test.ts +1 -1
  490. package/src/resources/extensions/gsd/tests/milestone-leases.test.ts +55 -0
  491. package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +9 -1
  492. package/src/resources/extensions/gsd/tests/model-router.test.ts +1 -1
  493. package/src/resources/extensions/gsd/tests/parallel-eligibility-file-overlap.test.ts +146 -0
  494. package/src/resources/extensions/gsd/tests/parallel-monitor-overlay.test.ts +59 -0
  495. package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +7 -5
  496. package/src/resources/extensions/gsd/tests/phase-anchor.test.ts +32 -4
  497. package/src/resources/extensions/gsd/tests/plan-task.test.ts +26 -23
  498. package/src/resources/extensions/gsd/tests/planning-writer.test.ts +29 -0
  499. package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +22 -0
  500. package/src/resources/extensions/gsd/tests/preferences.test.ts +84 -0
  501. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +4 -0
  502. package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +66 -0
  503. package/src/resources/extensions/gsd/tests/reactive-executor.test.ts +39 -0
  504. package/src/resources/extensions/gsd/tests/reassess-handler.test.ts +50 -0
  505. package/src/resources/extensions/gsd/tests/replan-task-handler.test.ts +103 -0
  506. package/src/resources/extensions/gsd/tests/rework-brief.test.ts +197 -0
  507. package/src/resources/extensions/gsd/tests/service-tier.test.ts +4 -0
  508. package/src/resources/extensions/gsd/tests/single-writer-v3-tool-surface.test.ts +33 -7
  509. package/src/resources/extensions/gsd/tests/skill-activation.test.ts +20 -16
  510. package/src/resources/extensions/gsd/tests/skip-slice-cascades-tasks.test.ts +21 -0
  511. package/src/resources/extensions/gsd/tests/stop-notice.test.ts +17 -0
  512. package/src/resources/extensions/gsd/tests/sync-lock.test.ts +19 -0
  513. package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +13 -7
  514. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +8 -0
  515. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +73 -0
  516. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +93 -1
  517. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -0
  518. package/src/resources/extensions/gsd/tests/workflow-migration-gates.test.ts +139 -0
  519. package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +4 -4
  520. package/src/resources/extensions/gsd/tests/worktree-state-projection.test.ts +36 -0
  521. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +34 -0
  522. package/src/resources/extensions/gsd/tests/write-gate-seam.test.ts +52 -0
  523. package/src/resources/extensions/gsd/tools/complete-task.ts +140 -5
  524. package/src/resources/extensions/gsd/tools/plan-task.ts +14 -16
  525. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +18 -17
  526. package/src/resources/extensions/gsd/tools/reopen-milestone.ts +24 -5
  527. package/src/resources/extensions/gsd/tools/reopen-slice.ts +25 -5
  528. package/src/resources/extensions/gsd/tools/reopen-task.ts +23 -9
  529. package/src/resources/extensions/gsd/tools/replan-task.ts +160 -0
  530. package/src/resources/extensions/gsd/tools/rework-brief.ts +91 -0
  531. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +92 -0
  532. package/src/resources/extensions/gsd/types.ts +11 -0
  533. package/src/resources/extensions/gsd/unit-context-composer.ts +34 -8
  534. package/src/resources/extensions/gsd/unit-registry.ts +4 -0
  535. package/src/resources/extensions/gsd/uok/plan-v2.ts +20 -3
  536. package/src/resources/extensions/gsd/workflow-projections.ts +2 -3
  537. package/src/resources/extensions/gsd/workspace.ts +2 -1
  538. package/src/resources/extensions/gsd/worktree-state-projection.ts +12 -0
  539. package/src/resources/extensions/mac-tools/index.ts +52 -9
  540. package/src/resources/extensions/mac-tools/tests/mac-screenshot-payload.test.cjs +70 -0
  541. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-49f565245e1e4afe.js +0 -1
  542. package/dist/web/standalone/.next/static/chunks/app/page-bc4c723c6a19c6f0.js +0 -1
  543. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ec3eaffc9785ba48.js +0 -1
  544. package/dist/web/standalone/.next/static/css/18c2fdf261bfc1b7.css +0 -1
  545. /package/dist/web/standalone/.next/static/{UaXRrOYxBpG9QBINKhZkg → 6YWV7VAPg-jqjfPswrKZb}/_buildManifest.js +0 -0
  546. /package/dist/web/standalone/.next/static/{UaXRrOYxBpG9QBINKhZkg → 6YWV7VAPg-jqjfPswrKZb}/_ssgManifest.js +0 -0
@@ -0,0 +1,101 @@
1
+ // gsd-pi - /gsd migrate planning service.
2
+ // File Purpose: Resolve, validate, parse, transform, preview, and guard a migration before UI confirmation.
3
+
4
+ import { existsSync } from "node:fs";
5
+
6
+ import {
7
+ assertMigrationHasSlices,
8
+ assertMigrationTargetAvailable,
9
+ resolveMigrationPaths,
10
+ type MigrationPaths,
11
+ } from "./safety.js";
12
+ import { parsePlanningDirectory } from "./parser.js";
13
+ import { generatePreview } from "./preview.js";
14
+ import { transformToGSD } from "./transformer.js";
15
+ import { validatePlanningDirectory } from "./validator.js";
16
+ import type { GSDProject, ValidationIssue, ValidationResult } from "./types.js";
17
+ import type { MigrationPreview } from "./writer.js";
18
+
19
+ export interface SplitValidationIssues {
20
+ warnings: ValidationIssue[];
21
+ fatals: ValidationIssue[];
22
+ }
23
+
24
+ interface MigrationPlanBase extends MigrationPaths {
25
+ warnings: ValidationIssue[];
26
+ fatals: ValidationIssue[];
27
+ }
28
+
29
+ export interface MissingMigrationSourceResult extends MigrationPaths {
30
+ status: "missing-source";
31
+ }
32
+
33
+ export interface InvalidMigrationPlanResult extends MigrationPlanBase {
34
+ status: "invalid";
35
+ validation: ValidationResult;
36
+ }
37
+
38
+ export interface BlockedMigrationPlanResult extends MigrationPlanBase {
39
+ status: "blocked";
40
+ validation: ValidationResult;
41
+ message: string;
42
+ }
43
+
44
+ export interface ReadyMigrationPlanResult extends MigrationPlanBase {
45
+ status: "ready";
46
+ validation: ValidationResult;
47
+ project: GSDProject;
48
+ preview: MigrationPreview;
49
+ }
50
+
51
+ export type MigrationPlanResult =
52
+ | MissingMigrationSourceResult
53
+ | InvalidMigrationPlanResult
54
+ | BlockedMigrationPlanResult
55
+ | ReadyMigrationPlanResult;
56
+
57
+ export function splitValidationIssues(validation: ValidationResult): SplitValidationIssues {
58
+ return {
59
+ warnings: validation.issues.filter((issue) => issue.severity === "warning"),
60
+ fatals: validation.issues.filter((issue) => issue.severity === "fatal"),
61
+ };
62
+ }
63
+
64
+ export async function createMigrationPlan(args: string, cwd: string = process.cwd()): Promise<MigrationPlanResult> {
65
+ const paths = resolveMigrationPaths(args, cwd);
66
+ if (!existsSync(paths.sourcePath)) {
67
+ return { status: "missing-source", ...paths };
68
+ }
69
+
70
+ const validation = await validatePlanningDirectory(paths.sourcePath);
71
+ const issues = splitValidationIssues(validation);
72
+ if (!validation.valid) {
73
+ return { status: "invalid", ...paths, validation, ...issues };
74
+ }
75
+
76
+ const parsed = await parsePlanningDirectory(paths.sourcePath);
77
+ const project = transformToGSD(parsed);
78
+ const preview = generatePreview(project);
79
+
80
+ try {
81
+ assertMigrationHasSlices(preview);
82
+ await assertMigrationTargetAvailable(paths.targetRoot);
83
+ } catch (error) {
84
+ return {
85
+ status: "blocked",
86
+ ...paths,
87
+ validation,
88
+ ...issues,
89
+ message: error instanceof Error ? error.message : String(error),
90
+ };
91
+ }
92
+
93
+ return {
94
+ status: "ready",
95
+ ...paths,
96
+ validation,
97
+ ...issues,
98
+ project,
99
+ preview,
100
+ };
101
+ }
@@ -186,17 +186,14 @@ export async function writePlanningDirectory(
186
186
  });
187
187
 
188
188
  if (tasks.length === 0) {
189
- // Empty phase write a single placeholder plan so the dir isn't empty.
190
- const planPath = join(phaseDir, `${pad(phaseNum)}-01-PLAN.md`);
191
- await saveFile(
192
- planPath,
193
- formatPlanningPlan(phaseNum, 1, slice.title || slice.id, []),
194
- );
195
- paths.push(planPath);
196
- projectionWrites.push({
197
- relPath: toPlanningRel(planPath),
198
- entities: [`${milestone.id}/${slice.id}`],
199
- });
189
+ // Sketch / undecomposed slice zero tasks. Do NOT emit an ingestible
190
+ // *-PLAN.md here: the reverse transform maps one GSDTask per plan file
191
+ // (transformer.ts mapSlice), so a placeholder would materialize a
192
+ // phantom "Plan NN" task and flip the slice from "needs planning" to
193
+ // "has a planned task", causing auto-mode to skip planning (issue #1285).
194
+ // The phase dir is already created (mkdirSync above) and the slice is
195
+ // listed in ROADMAP.md, so it round-trips with tasks = [] — the correct
196
+ // sketch-slice shape.
200
197
  } else {
201
198
  for (let ti = 0; ti < tasks.length; ti++) {
202
199
  const task = tasks[ti]!;
@@ -223,19 +220,14 @@ export async function writePlanningDirectory(
223
220
  }
224
221
  }
225
222
 
226
- // If no slices produced any phases, write a single empty phase so ROADMAP.md
227
- // isn't blank and the layout is still discoverable.
223
+ // If no slices produced any phases, emit a single empty phase dir + ROADMAP
224
+ // entry so the layout stays discoverable. Do NOT write a placeholder
225
+ // *-PLAN.md — an ingestible plan file would round-trip into a phantom task
226
+ // (see the tasks.length === 0 branch above, issue #1285).
228
227
  if (roadmapEntries.length === 0) {
229
228
  const phaseDirName = `${pad(1)}-milestone`;
230
229
  const phaseDir = join(root, "phases", phaseDirName);
231
230
  mkdirSync(phaseDir, { recursive: true });
232
- const planPath = join(phaseDir, `${pad(1)}-01-PLAN.md`);
233
- await saveFile(planPath, formatPlanningPlan(1, 1, milestones[0]!.title || milestones[0]!.id, []));
234
- paths.push(planPath);
235
- projectionWrites.push({
236
- relPath: toPlanningRel(planPath),
237
- entities: [milestones[0]!.id],
238
- });
239
231
  roadmapEntries.push({ number: 1, title: milestones[0]!.title || milestones[0]!.id, done: false });
240
232
  }
241
233
 
@@ -0,0 +1,83 @@
1
+ // gsd-pi - /gsd migrate presentation helpers.
2
+ // File Purpose: Pure formatting for migration previews and post-write review prompts.
3
+
4
+ import { existsSync, readFileSync } from "node:fs";
5
+ import { dirname, join } from "node:path";
6
+ import { fileURLToPath } from "node:url";
7
+
8
+ import { gsdRoot } from "../paths.js";
9
+ import type { MigrationPreview } from "./writer.js";
10
+
11
+ export interface ReviewPromptInput {
12
+ sourcePath: string;
13
+ gsdPath: string;
14
+ preview: MigrationPreview;
15
+ templatePath?: string;
16
+ }
17
+
18
+ function formatRequirements(preview: MigrationPreview): string | null {
19
+ if (preview.requirements.total === 0) return null;
20
+ return `Requirements: ${preview.requirements.total} (${preview.requirements.validated} validated, ${preview.requirements.active} active, ${preview.requirements.deferred} deferred, ${preview.requirements.outOfScope} out of scope)`;
21
+ }
22
+
23
+ function formatLegacyInputs(preview: MigrationPreview): string | null {
24
+ if (!preview.migrationInputs) return null;
25
+ return `Legacy inputs: ${preview.migrationInputs.milestonePhaseDirs} milestone phase dir(s), ${preview.migrationInputs.decisions} decision file(s), ${preview.migrationInputs.seeds} seed file(s)`;
26
+ }
27
+
28
+ export function buildMigrationPreviewSummary(preview: MigrationPreview, targetRoot: string): string[] {
29
+ const lines: string[] = [
30
+ `Decisions: ${preview.decisions.total}`,
31
+ `Milestones: ${preview.milestoneCount}`,
32
+ `Slices: ${preview.totalSlices} (${preview.doneSlices} done — ${preview.sliceCompletionPct}%)`,
33
+ `Tasks: ${preview.totalTasks} (${preview.doneTasks} done — ${preview.taskCompletionPct}%)`,
34
+ ];
35
+
36
+ const requirements = formatRequirements(preview);
37
+ if (requirements) lines.push(requirements);
38
+
39
+ const legacyInputs = formatLegacyInputs(preview);
40
+ if (legacyInputs) lines.push(legacyInputs);
41
+
42
+ const targetGsdPath = gsdRoot(targetRoot);
43
+ if (existsSync(targetGsdPath)) {
44
+ lines.push("");
45
+ lines.push(`⚠ A .gsd directory already exists at ${targetGsdPath}.`);
46
+ lines.push("It will be backed up, deleted, and rewritten fresh before DB import.");
47
+ }
48
+
49
+ return lines;
50
+ }
51
+
52
+ export function formatMigrationPreviewStats(preview: MigrationPreview): string {
53
+ const lines = [
54
+ `- Decisions: ${preview.decisions.total}`,
55
+ `- Milestones: ${preview.milestoneCount}`,
56
+ `- Slices: ${preview.totalSlices} (${preview.doneSlices} done — ${preview.sliceCompletionPct}%)`,
57
+ `- Tasks: ${preview.totalTasks} (${preview.doneTasks} done — ${preview.taskCompletionPct}%)`,
58
+ ];
59
+
60
+ const requirements = formatRequirements(preview);
61
+ if (requirements) lines.push(`- ${requirements}`);
62
+
63
+ const legacyInputs = formatLegacyInputs(preview);
64
+ if (legacyInputs) lines.push(`- ${legacyInputs}`);
65
+
66
+ return lines.join("\n");
67
+ }
68
+
69
+ function defaultReviewTemplatePath(): string {
70
+ const promptsDir = join(dirname(fileURLToPath(import.meta.url)), "..", "prompts");
71
+ return join(promptsDir, "review-migration.md");
72
+ }
73
+
74
+ export function buildReviewPrompt(input: ReviewPromptInput): string {
75
+ const templatePath = input.templatePath ?? defaultReviewTemplatePath();
76
+ let content = readFileSync(templatePath, "utf-8");
77
+
78
+ content = content.replaceAll("{{sourcePath}}", input.sourcePath);
79
+ content = content.replaceAll("{{gsdPath}}", input.gsdPath);
80
+ content = content.replaceAll("{{previewStats}}", formatMigrationPreviewStats(input.preview));
81
+
82
+ return content.trim();
83
+ }
@@ -62,6 +62,8 @@ export const BUNDLED_COST_TABLE: ModelCostEntry[] = [
62
62
  // GPT-5.5 API list price, also used for live Codex OAuth routing.
63
63
  // Source: https://openai.com/api/pricing/
64
64
  { id: "gpt-5.5", inputPer1k: 0.005, outputPer1k: 0.03, updatedAt: "2026-04-23" },
65
+ // Mirrors gpt-5.5 list pricing until OpenAI publishes official gpt-5.6 pricing.
66
+ { id: "gpt-5.6", inputPer1k: 0.005, outputPer1k: 0.03, updatedAt: "2026-07-08" },
65
67
 
66
68
  // Google
67
69
  { id: "gemini-2.0-flash", inputPer1k: 0.0001, outputPer1k: 0.0004, updatedAt: "2025-03-15" },
@@ -111,10 +111,12 @@ export const MODEL_CAPABILITY_TIER: Record<string, ComplexityTier> = {
111
111
  "gpt-5.3-codex": "heavy",
112
112
  "gpt-5.4": "heavy",
113
113
  "gpt-5.5": "heavy",
114
+ "gpt-5.6": "heavy",
114
115
  "o1": "heavy",
115
116
  "o3": "heavy",
116
117
  "o4-mini": "heavy",
117
118
  "o4-mini-deep-research": "heavy",
119
+ "grok-4.5": "heavy",
118
120
  };
119
121
 
120
122
  // ─── Cost Table (per 1K input tokens, approximate USD) ───────────────────────
@@ -149,11 +151,13 @@ const MODEL_COST_PER_1K_INPUT: Record<string, number> = {
149
151
  "gpt-5.3-codex-spark": 0.0003,
150
152
  "gpt-5.4": 0.005,
151
153
  "gpt-5.5": 0.005,
154
+ "gpt-5.6": 0.005,
152
155
  "o4-mini": 0.005,
153
156
  "o4-mini-deep-research": 0.005,
154
157
  "gemini-2.0-flash": 0.0001,
155
158
  "gemini-2.5-pro": 0.00125,
156
159
  "deepseek-chat": 0.00014,
160
+ "grok-4.5": 0.002,
157
161
  };
158
162
 
159
163
  // ─── Capability Profiles Data Table ──────────────────────────────────────────
@@ -198,6 +202,9 @@ export const MODEL_CAPABILITY_PROFILES: Record<string, ModelCapabilities> = {
198
202
  // OpenAI's 2026-04-23 published eval deltas across coding, tool use, and long context.
199
203
  // Source: https://openai.com/index/introducing-gpt-5-5/
200
204
  "gpt-5.5": { coding: 96, debugging: 93, research: 89, reasoning: 95, speed: 42, longContext: 90, instruction: 93 },
205
+ // GPT-5.6 profile is provisional: a small uniform step over gpt-5.5, to be
206
+ // recalibrated once OpenAI publishes official eval results.
207
+ "gpt-5.6": { coding: 97, debugging: 94, research: 90, reasoning: 96, speed: 42, longContext: 91, instruction: 94 },
201
208
 
202
209
  // ── OpenAI o-series (reasoning-first) ──────────────────────────────────────
203
210
  "o1": { coding: 78, debugging: 82, research: 78, reasoning: 90, speed: 20, longContext: 65, instruction: 82 },
@@ -212,6 +219,11 @@ export const MODEL_CAPABILITY_PROFILES: Record<string, ModelCapabilities> = {
212
219
 
213
220
  // ── DeepSeek ───────────────────────────────────────────────────────────────
214
221
  "deepseek-chat": { coding: 75, debugging: 65, research: 55, reasoning: 70, speed: 70, longContext: 55, instruction: 65 },
222
+
223
+ // ── xAI ────────────────────────────────────────────────────────────────────
224
+ // Grok 4.5 (2026-07): Opus-class frontier model tuned for coding and agentic
225
+ // work; notably faster and more token-efficient than peer heavy models.
226
+ "grok-4.5": { coding: 95, debugging: 90, research: 82, reasoning: 93, speed: 55, longContext: 80, instruction: 90 },
215
227
  };
216
228
 
217
229
  // ─── Base Task Requirements Data Table ───────────────────────────────────────
@@ -8,7 +8,7 @@
8
8
  import { deriveState } from "./state.js";
9
9
  import { resolveMilestoneFile, resolveSliceFile } from "./paths.js";
10
10
  import { findMilestoneIds } from "./guided-flow.js";
11
- import { isDbAvailable, getMilestoneSlices, getSliceTasks } from "./gsd-db.js";
11
+ import { isDbAvailable, getMilestoneSlices, getTasksBySliceIds } from "./gsd-db.js";
12
12
  import { openExistingWorkflowDatabase } from "./db-workspace.js";
13
13
  import type { MilestoneRegistryEntry } from "./types.js";
14
14
 
@@ -40,10 +40,11 @@ async function collectTouchedFiles(
40
40
  const files = new Set<string>();
41
41
 
42
42
  if (isDbAvailable()) {
43
- // DB path: query slices and their tasks for file lists
43
+ // DB path: query slices and their tasks for file lists (one batched task
44
+ // query instead of one per slice; file order is irrelevant here — Set dedup)
44
45
  const slices = getMilestoneSlices(milestoneId);
45
- for (const slice of slices) {
46
- const tasks = getSliceTasks(milestoneId, slice.id);
46
+ const tasksBySlice = getTasksBySliceIds(slices.map((slice) => ({ milestoneId, sliceId: slice.id })));
47
+ for (const tasks of tasksBySlice.values()) {
47
48
  for (const task of tasks) {
48
49
  if (Array.isArray(task.files)) {
49
50
  for (const f of task.files) {
@@ -72,6 +72,7 @@ interface WorkerView {
72
72
  totalSlices: number;
73
73
  doneSlices: number;
74
74
  slices: SliceProgress[];
75
+ completions: string[];
75
76
  errors: string[];
76
77
  }
77
78
 
@@ -143,14 +144,21 @@ function discoverWorkers(basePath: string): string[] {
143
144
  return [...mids].sort();
144
145
  }
145
146
 
146
- function querySliceProgress(basePath: string, mid: string, workRoot: string = worktreePathFor(basePath, mid)): SliceProgress[] {
147
+ // Slice progress + recent completions share one DB connection per worker per
148
+ // tick. Opening the isolated worker DB twice per refresh (once for each) was
149
+ // pure churn on the 5s interval.
150
+ function queryWorkerProgress(
151
+ basePath: string,
152
+ mid: string,
153
+ workRoot: string = worktreePathFor(basePath, mid),
154
+ ): { slices: SliceProgress[]; completions: string[] } {
147
155
  const dbPath = resolveGsdPathContract(workRoot, basePath).projectDb;
148
- if (!existsSync(dbPath)) return [];
156
+ if (!existsSync(dbPath)) return { slices: [], completions: [] };
149
157
 
150
158
  const db = openWorkflowDatabaseIsolated(dbPath);
151
- if (!db) return [];
159
+ if (!db) return { slices: [], completions: [] };
152
160
  try {
153
- const rows = db.prepare(
161
+ const sliceRows = db.prepare(
154
162
  `SELECT
155
163
  s.id AS id,
156
164
  s.status AS status,
@@ -162,14 +170,32 @@ function querySliceProgress(basePath: string, mid: string, workRoot: string = wo
162
170
  GROUP BY s.id
163
171
  ORDER BY s.id`,
164
172
  ).all({ ":mid": mid });
165
- return rows.map((row) => ({
173
+ const slices = sliceRows.map((row) => ({
166
174
  id: String(row["id"] ?? ""),
167
175
  status: String(row["status"] ?? ""),
168
176
  total: Number(row["total"] ?? 0),
169
177
  done: Number(row["done"] ?? 0),
170
178
  }));
179
+
180
+ const completionRows = db.prepare(
181
+ `SELECT id, slice_id, one_liner
182
+ FROM tasks
183
+ WHERE milestone_id=:mid
184
+ AND status='complete'
185
+ AND completed_at IS NOT NULL
186
+ ORDER BY completed_at DESC
187
+ LIMIT 5`,
188
+ ).all({ ":mid": mid });
189
+ const completions = completionRows.map((row) => {
190
+ const taskId = String(row["id"] ?? "");
191
+ const sliceId = String(row["slice_id"] ?? "");
192
+ const oneLiner = String(row["one_liner"] ?? "");
193
+ return `✓ ${mid}/${sliceId}/${taskId}${oneLiner ? ": " + oneLiner : ""}`;
194
+ });
195
+
196
+ return { slices, completions };
171
197
  } catch {
172
- return [];
198
+ return { slices: [], completions: [] };
173
199
  } finally {
174
200
  try { db.close(); } catch { /* ignore */ }
175
201
  }
@@ -276,36 +302,6 @@ function extractCostFromNdjson(basePath: string, mid: string): number {
276
302
  }
277
303
  }
278
304
 
279
- function queryRecentCompletions(basePath: string, mid: string): string[] {
280
- const workRoot = worktreePathFor(basePath, mid);
281
- const dbPath = resolveGsdPathContract(workRoot, basePath).projectDb;
282
- if (!existsSync(dbPath)) return [];
283
-
284
- const db = openWorkflowDatabaseIsolated(dbPath);
285
- if (!db) return [];
286
- try {
287
- const rows = db.prepare(
288
- `SELECT id, slice_id, one_liner
289
- FROM tasks
290
- WHERE milestone_id=:mid
291
- AND status='complete'
292
- AND completed_at IS NOT NULL
293
- ORDER BY completed_at DESC
294
- LIMIT 5`,
295
- ).all({ ":mid": mid });
296
- return rows.map((row) => {
297
- const taskId = String(row["id"] ?? "");
298
- const sliceId = String(row["slice_id"] ?? "");
299
- const oneLiner = String(row["one_liner"] ?? "");
300
- return `✓ ${mid}/${sliceId}/${taskId}${oneLiner ? ": " + oneLiner : ""}`;
301
- });
302
- } catch {
303
- return [];
304
- } finally {
305
- try { db.close(); } catch { /* ignore */ }
306
- }
307
- }
308
-
309
305
  function collectWorkerData(basePath: string): WorkerView[] {
310
306
  const mids = discoverWorkers(basePath);
311
307
  const parallelDir = join(basePath, ".gsd", "parallel");
@@ -317,7 +313,7 @@ function collectWorkerData(basePath: string): WorkerView[] {
317
313
  const workRoot = worktreePathFor(basePath, mid);
318
314
  const status = readJsonSafe<StatusJson>(join(parallelDir, `${mid}.status.json`));
319
315
  const lock = readJsonSafe<AutoLock>(join(workRoot, ".gsd", "auto.lock"));
320
- const slices = querySliceProgress(basePath, mid, workRoot);
316
+ const { slices, completions } = queryWorkerProgress(basePath, mid, workRoot);
321
317
 
322
318
  const pid = lock?.pid || status?.pid || 0;
323
319
  const alive = pid ? isPidAlive(pid) : false;
@@ -378,6 +374,7 @@ function collectWorkerData(basePath: string): WorkerView[] {
378
374
  totalSlices: slices.length,
379
375
  doneSlices,
380
376
  slices,
377
+ completions,
381
378
  errors,
382
379
  });
383
380
  }
@@ -443,10 +440,10 @@ export class ParallelMonitorOverlay {
443
440
  if (this.disposed) return;
444
441
  this.workers = collectWorkerData(this.basePath);
445
442
 
446
- // Collect completion events
443
+ // Collect completion events (already read during collectWorkerData's single
444
+ // DB open per worker — no second connection here).
447
445
  for (const wk of this.workers) {
448
- const completions = queryRecentCompletions(this.basePath, wk.mid);
449
- for (const evt of completions) {
446
+ for (const evt of wk.completions) {
450
447
  if (!this.events.includes(evt)) this.events.push(evt);
451
448
  }
452
449
  }
@@ -223,6 +223,26 @@ export function buildTaskFileName(taskId: string, suffix: string): string {
223
223
  return `${taskId}-${suffix}.md`;
224
224
  }
225
225
 
226
+ /**
227
+ * Build a flat-phase task artifact file name.
228
+ * ("S06", "T03", "SUMMARY") → "S06-T03-SUMMARY.md"
229
+ */
230
+ export function buildFlatTaskFileName(sliceId: string, taskId: string, suffix: string): string {
231
+ return `${sliceId}-${taskId}-${suffix}.md`;
232
+ }
233
+
234
+ /**
235
+ * Extract the task ID from a task artifact filename.
236
+ * Supports flat-phase S##-T##-SUFFIX.md plus legacy T##-SUFFIX.md and
237
+ * T##-DESCRIPTOR-SUFFIX.md names.
238
+ */
239
+ export function taskIdFromTaskFileName(fileName: string, suffix: string): string | null {
240
+ const flat = new RegExp(`^S\\d+-(T\\d+)-${suffix}\\.md$`, "i").exec(fileName);
241
+ if (flat?.[1]) return flat[1].toUpperCase();
242
+ const legacy = new RegExp(`^(T\\d+)(?:-.*)?-${suffix}\\.md$`, "i").exec(fileName);
243
+ return legacy?.[1]?.toUpperCase() ?? null;
244
+ }
245
+
226
246
  // ─── Resolvers ─────────────────────────────────────────────────────────────
227
247
 
228
248
  /**
@@ -284,18 +304,15 @@ export function resolveFile(dir: string, idPrefix: string, suffix: string): stri
284
304
  }
285
305
 
286
306
  /**
287
- * Find all task files matching a pattern in a tasks directory.
288
- * Returns sorted file names matching T##-SUFFIX.md or legacy T##-*-SUFFIX.md
307
+ * Find all task files matching a pattern in a tasks directory or flat phase dir.
308
+ * Returns sorted file names matching S##-T##-SUFFIX.md, T##-SUFFIX.md,
309
+ * or legacy T##-*-SUFFIX.md.
289
310
  */
290
311
  export function resolveTaskFiles(tasksDir: string, suffix: string): string[] {
291
312
  if (!existsSync(tasksDir)) return [];
292
313
  try {
293
- // Current convention: T01-PLAN.md
294
- const currentPattern = new RegExp(`^T\\d+-${suffix}\\.md$`, "i");
295
- // Legacy convention: T01-INSTALL-PACKAGES-PLAN.md
296
- const legacyPattern = new RegExp(`^T\\d+-.*-${suffix}\\.md$`, "i");
297
314
  return cachedReaddir(tasksDir)
298
- .filter(f => currentPattern.test(f) || legacyPattern.test(f))
315
+ .filter(f => taskIdFromTaskFileName(f, suffix) !== null)
299
316
  .sort();
300
317
  } catch {
301
318
  return [];
@@ -618,17 +635,20 @@ function legacyMilestonesHasSubdirs(basePath: string): boolean {
618
635
  * See the matching TODO in markdown-renderer.ts detectStaleRenders, which
619
636
  * disabled stale-render detection for the same reason.
620
637
  */
638
+ const LEGACY_MILESTONE_RUNTIME_DIRS = new Set(["anchors"]);
639
+
621
640
  export function dirIsContentBearingLegacyMilestone(dir: string): boolean {
622
641
  try {
623
642
  const entries = readdirSync(dir, { withFileTypes: true });
624
643
  // 1. Any non-META regular file → real legacy content.
625
644
  if (entries.some(e => e.isFile() && !e.name.endsWith("-META.json"))) return true;
626
- // 2. A non-empty subdirectory → real legacy content (e.g. slices/ with slice dirs).
645
+ // 2. A non-empty non-runtime subdirectory → real legacy content (e.g. slices/ with slice dirs).
627
646
  // An *empty* subdir is treated as scaffolding (e.g. git-service.ts may create
628
647
  // an empty slices/ alongside the integration META file) and must NOT flip the
629
648
  // layout — that is the Bugbot finding this guard addresses.
630
649
  return entries.some(e => {
631
650
  if (!e.isDirectory()) return false;
651
+ if (LEGACY_MILESTONE_RUNTIME_DIRS.has(e.name)) return false;
632
652
  try { return readdirSync(join(dir, e.name)).length > 0; } catch { return false; }
633
653
  });
634
654
  } catch {
@@ -928,8 +948,10 @@ export function resolveTaskFile(
928
948
  const isLegacy = phaseDir.startsWith(legacyBase + "/") || phaseDir.startsWith(legacyBase + "\\");
929
949
 
930
950
  if (suffix !== "PLAN" && !isLegacy) {
931
- const flatPath = join(phaseDir, buildTaskFileName(taskId, suffix));
932
- return existsSync(flatPath) ? flatPath : null;
951
+ const flatPath = join(phaseDir, buildFlatTaskFileName(sliceId, taskId, suffix));
952
+ if (existsSync(flatPath)) return flatPath;
953
+ const legacyFlatPath = join(phaseDir, buildTaskFileName(taskId, suffix));
954
+ return existsSync(legacyFlatPath) ? legacyFlatPath : null;
933
955
  }
934
956
 
935
957
  const tDir = resolveTasksDir(basePath, milestoneId, sliceId);
@@ -1063,6 +1085,35 @@ export function targetSliceFile(
1063
1085
  return join(dir, fileName);
1064
1086
  }
1065
1087
 
1088
+ /**
1089
+ * Build the canonical absolute write target for a task file.
1090
+ * Readers that need legacy flat-phase fallback should call resolveTaskFile.
1091
+ */
1092
+ export function targetTaskFile(
1093
+ basePath: string, milestoneId: string, sliceId: string,
1094
+ taskId: string, suffix: string, milestoneTitle?: string
1095
+ ): string {
1096
+ if (suffix === "PLAN") {
1097
+ return targetSliceFile(basePath, milestoneId, sliceId, "PLAN", milestoneTitle);
1098
+ }
1099
+
1100
+ const mDir = resolveMilestonePath(basePath, milestoneId);
1101
+ const legacyBase = legacyMilestonesDir(basePath);
1102
+ const isLegacy = mDir
1103
+ ? mDir.startsWith(legacyBase + "/") || mDir.startsWith(legacyBase + "\\")
1104
+ : isLegacyMilestonesLayout(basePath);
1105
+ const milestoneDir = mDir
1106
+ ?? dirname(targetMilestoneFile(basePath, milestoneId, "ROADMAP", milestoneTitle));
1107
+
1108
+ if (isLegacy) {
1109
+ const slicesDir = join(milestoneDir, "slices");
1110
+ const sliceDir = join(slicesDir, resolveDir(slicesDir, sliceId) ?? sliceId);
1111
+ return join(sliceDir, "tasks", buildTaskFileName(taskId, suffix));
1112
+ }
1113
+
1114
+ return join(milestoneDir, buildFlatTaskFileName(sliceId, taskId, suffix));
1115
+ }
1116
+
1066
1117
  /**
1067
1118
  * Build relative .gsd/ path to a slice file.
1068
1119
  * Preserves an existing compatibility filename when present; otherwise falls
@@ -1102,5 +1153,5 @@ export function relTaskFile(
1102
1153
  return relSliceFile(basePath, milestoneId, sliceId, "PLAN");
1103
1154
  }
1104
1155
  const relS = relSlicePath(basePath, milestoneId, sliceId, milestoneTitle);
1105
- return `${relS}/${buildTaskFileName(taskId, suffix)}`;
1156
+ return `${relS}/${buildFlatTaskFileName(sliceId, taskId, suffix)}`;
1106
1157
  }
@@ -19,13 +19,17 @@ export interface PhaseAnchor {
19
19
  }
20
20
 
21
21
  function anchorsDir(basePath: string, milestoneId: string): string {
22
- return join(gsdRoot(basePath), "milestones", milestoneId, "anchors");
22
+ return join(gsdRoot(basePath), "runtime", "anchors", milestoneId);
23
23
  }
24
24
 
25
25
  function anchorPath(basePath: string, milestoneId: string, phase: string): string {
26
26
  return join(anchorsDir(basePath, milestoneId), `${phase}.json`);
27
27
  }
28
28
 
29
+ function legacyAnchorPath(basePath: string, milestoneId: string, phase: string): string {
30
+ return join(gsdRoot(basePath), "milestones", milestoneId, "anchors", `${phase}.json`);
31
+ }
32
+
29
33
  export function writePhaseAnchor(basePath: string, milestoneId: string, anchor: PhaseAnchor): void {
30
34
  const dir = anchorsDir(basePath, milestoneId);
31
35
  if (!existsSync(dir)) {
@@ -35,7 +39,9 @@ export function writePhaseAnchor(basePath: string, milestoneId: string, anchor:
35
39
  }
36
40
 
37
41
  export function readPhaseAnchor(basePath: string, milestoneId: string, phase: string): PhaseAnchor | null {
38
- const path = anchorPath(basePath, milestoneId, phase);
42
+ const path = existsSync(anchorPath(basePath, milestoneId, phase))
43
+ ? anchorPath(basePath, milestoneId, phase)
44
+ : legacyAnchorPath(basePath, milestoneId, phase);
39
45
  if (!existsSync(path)) return null;
40
46
  try {
41
47
  return JSON.parse(readFileSync(path, "utf-8")) as PhaseAnchor;
@@ -0,0 +1,58 @@
1
+ import { CONFIGURABLE_PLANNING_SUBAGENT_UNITS, type GSDPreferences } from "./preferences-types.js";
2
+ import { loadEffectiveGSDPreferences } from "./preferences.js";
3
+ import type { ToolsPolicy } from "./unit-context-manifest.js";
4
+
5
+ const CONFIGURABLE_UNITS = new Set<string>(CONFIGURABLE_PLANNING_SUBAGENT_UNITS);
6
+
7
+ function configuredAllowedSubagents(
8
+ unitType: string,
9
+ preferences: GSDPreferences | null | undefined,
10
+ ): readonly string[] {
11
+ if (!CONFIGURABLE_UNITS.has(unitType)) return [];
12
+ return preferences?.planning_subagents?.[
13
+ unitType as keyof NonNullable<GSDPreferences["planning_subagents"]>
14
+ ]?.allowed ?? [];
15
+ }
16
+
17
+ function mergeAllowedSubagents(
18
+ current: readonly string[],
19
+ configured: readonly string[],
20
+ ): readonly string[] {
21
+ return Array.from(new Set([...current, ...configured]));
22
+ }
23
+
24
+ export function applyPlanningSubagentPreferences(
25
+ unitType: string,
26
+ policy: ToolsPolicy | null | undefined,
27
+ preferences: GSDPreferences | null | undefined,
28
+ ): ToolsPolicy | null | undefined {
29
+ if (!policy) return policy;
30
+ const configured = configuredAllowedSubagents(unitType, preferences);
31
+ if (configured.length === 0) return policy;
32
+
33
+ if (policy.mode === "planning") {
34
+ return {
35
+ mode: "planning-dispatch",
36
+ allowedSubagents: mergeAllowedSubagents([], configured),
37
+ };
38
+ }
39
+
40
+ if (policy.mode === "planning-dispatch") {
41
+ return {
42
+ ...policy,
43
+ allowedSubagents: mergeAllowedSubagents(policy.allowedSubagents, configured),
44
+ };
45
+ }
46
+
47
+ return policy;
48
+ }
49
+
50
+ export function resolveEffectivePlanningToolsPolicy(
51
+ unitType: string,
52
+ policy: ToolsPolicy | null | undefined,
53
+ basePath?: string,
54
+ ): ToolsPolicy | null | undefined {
55
+ if (!basePath) return policy;
56
+ const preferences = loadEffectiveGSDPreferences(basePath)?.preferences;
57
+ return applyPlanningSubagentPreferences(unitType, policy, preferences);
58
+ }