@opengsd/gsd-pi 1.5.0 → 1.6.0

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 (499) hide show
  1. package/README.md +10 -10
  2. package/dist/resources/.managed-resources-content-hash +1 -1
  3. package/dist/resources/extensions/ask-user-questions.js +1 -1
  4. package/dist/resources/extensions/browser-tools/engine/managed-gsd-browser.js +114 -36
  5. package/dist/resources/extensions/gsd/activity-log.js +1 -1
  6. package/dist/resources/extensions/gsd/auto/closeout.js +97 -5
  7. package/dist/resources/extensions/gsd/auto/orchestrator.js +20 -13
  8. package/dist/resources/extensions/gsd/auto/pre-dispatch.js +6 -3
  9. package/dist/resources/extensions/gsd/auto/unit-phase.js +5 -9
  10. package/dist/resources/extensions/gsd/auto-artifact-paths.js +14 -5
  11. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +11 -7
  12. package/dist/resources/extensions/gsd/auto-dispatch.js +69 -17
  13. package/dist/resources/extensions/gsd/auto-model-selection.js +28 -1
  14. package/dist/resources/extensions/gsd/auto-post-unit.js +4 -3
  15. package/dist/resources/extensions/gsd/auto-prompts.js +29 -117
  16. package/dist/resources/extensions/gsd/auto-recovery.js +50 -6
  17. package/dist/resources/extensions/gsd/auto-start.js +57 -33
  18. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +12 -2
  19. package/dist/resources/extensions/gsd/auto-timers.js +9 -2
  20. package/dist/resources/extensions/gsd/auto-worktree-branch-lifecycle.js +189 -0
  21. package/dist/resources/extensions/gsd/auto-worktree-cleanup.js +133 -0
  22. package/dist/resources/extensions/gsd/auto-worktree-conflict-auto-resolve.js +35 -0
  23. package/dist/resources/extensions/gsd/auto-worktree-creation.js +130 -0
  24. package/dist/resources/extensions/gsd/auto-worktree-entry.js +118 -0
  25. package/dist/resources/extensions/gsd/auto-worktree-merge-already-merged.js +98 -0
  26. package/dist/resources/extensions/gsd/auto-worktree-merge-branch-head.js +52 -0
  27. package/dist/resources/extensions/gsd/auto-worktree-merge-cleanup.js +87 -0
  28. package/dist/resources/extensions/gsd/auto-worktree-merge-code-changes.js +46 -0
  29. package/dist/resources/extensions/gsd/auto-worktree-merge-db-ready.js +68 -0
  30. package/dist/resources/extensions/gsd/auto-worktree-merge-integration-branch.js +51 -0
  31. package/dist/resources/extensions/gsd/auto-worktree-merge-message.js +106 -0
  32. package/dist/resources/extensions/gsd/auto-worktree-merge-pre-teardown.js +64 -0
  33. package/dist/resources/extensions/gsd/auto-worktree-merge-stash.js +168 -0
  34. package/dist/resources/extensions/gsd/auto-worktree-merge.js +302 -0
  35. package/dist/resources/extensions/gsd/auto-worktree-milestone-shelter.js +119 -0
  36. package/dist/resources/extensions/gsd/auto-worktree-path-resolution.js +5 -0
  37. package/dist/resources/extensions/gsd/auto-worktree-path-utils.js +5 -0
  38. package/dist/resources/extensions/gsd/auto-worktree-resource-version.js +41 -0
  39. package/dist/resources/extensions/gsd/auto-worktree-runtime-cleanup.js +99 -0
  40. package/dist/resources/extensions/gsd/auto-worktree-session-registry.js +57 -0
  41. package/dist/resources/extensions/gsd/auto-worktree-sync.js +249 -0
  42. package/dist/resources/extensions/gsd/auto-worktree-teardown.js +120 -0
  43. package/dist/resources/extensions/gsd/auto-worktree.js +20 -2073
  44. package/dist/resources/extensions/gsd/auto.js +106 -34
  45. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +1 -1
  46. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +20 -2
  47. package/dist/resources/extensions/gsd/bootstrap/system-context.js +1 -1
  48. package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +185 -27
  49. package/dist/resources/extensions/gsd/codebase-generator.js +7 -1
  50. package/dist/resources/extensions/gsd/commands-handlers.js +1 -1
  51. package/dist/resources/extensions/gsd/commands-workflow-templates.js +3 -3
  52. package/dist/resources/extensions/gsd/compat/compat-marker.js +44 -0
  53. package/dist/resources/extensions/gsd/config-overlay.js +7 -2
  54. package/dist/resources/extensions/gsd/db/engine.js +33 -0
  55. package/dist/resources/extensions/gsd/db/queries.js +9 -9
  56. package/dist/resources/extensions/gsd/db/writers/cascades.js +20 -2
  57. package/dist/resources/extensions/gsd/db-adapter.js +30 -3
  58. package/dist/resources/extensions/gsd/docs/preferences-reference.md +3 -3
  59. package/dist/resources/extensions/gsd/doctor-engine-checks.js +93 -11
  60. package/dist/resources/extensions/gsd/flat-phase-migration.js +32 -3
  61. package/dist/resources/extensions/gsd/forensics.js +1 -1
  62. package/dist/resources/extensions/gsd/git-conflict-resolve.js +2 -2
  63. package/dist/resources/extensions/gsd/git-service.js +45 -0
  64. package/dist/resources/extensions/gsd/gsd-db.js +23 -11
  65. package/dist/resources/extensions/gsd/guided-flow.js +22 -17
  66. package/dist/resources/extensions/gsd/journal.js +1 -1
  67. package/dist/resources/extensions/gsd/markdown-renderer.js +34 -79
  68. package/dist/resources/extensions/gsd/md-importer.js +89 -23
  69. package/dist/resources/extensions/gsd/metrics.js +2 -2
  70. package/dist/resources/extensions/gsd/migration-auto-check.js +30 -3
  71. package/dist/resources/extensions/gsd/milestone-merge-transaction.js +11 -0
  72. package/dist/resources/extensions/gsd/milestone-settlement.js +1 -1
  73. package/dist/resources/extensions/gsd/parallel-merge.js +1 -1
  74. package/dist/resources/extensions/gsd/parallel-orchestrator.js +3 -1
  75. package/dist/resources/extensions/gsd/paths.js +87 -52
  76. package/dist/resources/extensions/gsd/post-unit-hooks.js +27 -0
  77. package/dist/resources/extensions/gsd/preferences-models.js +66 -15
  78. package/dist/resources/extensions/gsd/preferences-skills.js +10 -16
  79. package/dist/resources/extensions/gsd/preferences-types.js +1 -0
  80. package/dist/resources/extensions/gsd/preferences-validation.js +148 -10
  81. package/dist/resources/extensions/gsd/preferences.js +20 -0
  82. package/dist/resources/extensions/gsd/prompts/system.md +6 -6
  83. package/dist/resources/extensions/gsd/quick.js +12 -3
  84. package/dist/resources/extensions/gsd/rule-registry.js +106 -10
  85. package/dist/resources/extensions/gsd/skill-discovery.js +36 -23
  86. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +2 -1
  87. package/dist/resources/extensions/gsd/state/derive/from-db.js +88 -153
  88. package/dist/resources/extensions/gsd/state-reconciliation/drift/artifact-db.js +1 -10
  89. package/dist/resources/extensions/gsd/state-reconciliation/drift/completion.js +3 -24
  90. package/dist/resources/extensions/gsd/state-reconciliation/index.js +10 -0
  91. package/dist/resources/extensions/gsd/tool-contract.js +14 -0
  92. package/dist/resources/extensions/gsd/tools/complete-milestone.js +3 -5
  93. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +16 -10
  94. package/dist/resources/extensions/gsd/tools/reopen-slice.js +5 -0
  95. package/dist/resources/extensions/gsd/tools/reopen-task.js +13 -5
  96. package/dist/resources/extensions/gsd/tools/validate-milestone.js +3 -8
  97. package/dist/resources/extensions/gsd/uat-dispatch.js +94 -0
  98. package/dist/resources/extensions/gsd/unit-registry.js +12 -2
  99. package/dist/resources/extensions/gsd/unmerged-milestone-guard.js +1 -1
  100. package/dist/resources/extensions/gsd/uok/audit-toggle.js +31 -2
  101. package/dist/resources/extensions/gsd/uok/audit.js +3 -0
  102. package/dist/resources/extensions/gsd/uok/gate-runner.js +22 -30
  103. package/dist/resources/extensions/gsd/uok/gitops.js +18 -15
  104. package/dist/resources/extensions/gsd/uok/kernel.js +120 -46
  105. package/dist/resources/extensions/gsd/uok/model-policy.js +17 -14
  106. package/dist/resources/extensions/gsd/validation-block-guard.js +2 -1
  107. package/dist/resources/extensions/gsd/workflow-event-ledger.js +1 -1
  108. package/dist/resources/extensions/gsd/workflow-logger.js +1 -1
  109. package/dist/resources/extensions/gsd/workflow-projections.js +9 -26
  110. package/dist/resources/extensions/gsd/workspace-git-preflight.js +2 -2
  111. package/dist/resources/extensions/gsd/workspace.js +5 -14
  112. package/dist/resources/extensions/gsd/worktree-command.js +1 -1
  113. package/dist/resources/extensions/gsd/worktree-lifecycle.js +14 -9
  114. package/dist/resources/extensions/gsd/worktree-reentry.js +2 -1
  115. package/dist/resources/extensions/shared/gsd-browser-cli.js +29 -0
  116. package/dist/resources/extensions/shared/interview-ui.js +62 -9
  117. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  118. package/dist/web/standalone/.next/BUILD_ID +1 -1
  119. package/dist/web/standalone/.next/app-path-routes-manifest.json +9 -9
  120. package/dist/web/standalone/.next/build-manifest.json +2 -2
  121. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  122. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  123. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  124. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  125. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  126. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  127. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  128. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  129. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  130. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  131. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  132. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  133. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  134. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  135. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  136. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  137. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  138. package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
  139. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
  140. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
  141. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
  142. package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
  143. package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
  144. package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
  145. package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
  146. package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  147. package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
  148. package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  149. package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
  150. package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
  151. package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
  152. package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
  153. package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
  154. package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js.nft.json +1 -1
  155. package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
  156. package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
  157. package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  158. package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
  159. package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
  160. package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
  161. package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
  162. package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
  163. package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
  164. package/dist/web/standalone/.next/server/app/api/shutdown/route.js.nft.json +1 -1
  165. package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
  166. package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
  167. package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
  168. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
  169. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
  170. package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
  171. package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
  172. package/dist/web/standalone/.next/server/app/index.html +1 -1
  173. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  174. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  175. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  176. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  177. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  178. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  179. package/dist/web/standalone/.next/server/app-paths-manifest.json +9 -9
  180. package/dist/web/standalone/.next/server/chunks/{1128.js → 1991.js} +1 -1
  181. package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
  182. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  183. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  184. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  185. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  186. package/dist/web/standalone/node_modules/@gsd/native/package.json +1 -1
  187. package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
  188. package/dist/worktree-cli-create.d.ts +10 -0
  189. package/dist/worktree-cli-create.js +11 -0
  190. package/dist/worktree-cli-format.d.ts +12 -0
  191. package/dist/worktree-cli-format.js +38 -0
  192. package/dist/worktree-cli-plan.d.ts +16 -0
  193. package/dist/worktree-cli-plan.js +19 -0
  194. package/dist/worktree-cli-session.d.ts +13 -0
  195. package/dist/worktree-cli-session.js +18 -0
  196. package/dist/worktree-cli-status.d.ts +35 -0
  197. package/dist/worktree-cli-status.js +54 -0
  198. package/dist/worktree-cli.d.ts +1 -16
  199. package/dist/worktree-cli.js +28 -122
  200. package/integrations/hermes/open_gsd_hermes/gsd_client.py +25 -36
  201. package/integrations/hermes/pyproject.toml +1 -1
  202. package/integrations/hermes/tests/test_gsd_client_timeout.py +4 -4
  203. package/package.json +6 -6
  204. package/packages/cloud-mcp-gateway/package.json +2 -2
  205. package/packages/contracts/package.json +1 -1
  206. package/packages/daemon/dist/orchestrator-agent.d.ts +21 -0
  207. package/packages/daemon/dist/orchestrator-agent.d.ts.map +1 -0
  208. package/packages/daemon/dist/orchestrator-agent.js +113 -0
  209. package/packages/daemon/dist/orchestrator-agent.js.map +1 -0
  210. package/packages/daemon/dist/orchestrator-tools.d.ts +12 -0
  211. package/packages/daemon/dist/orchestrator-tools.d.ts.map +1 -0
  212. package/packages/daemon/dist/orchestrator-tools.js +137 -0
  213. package/packages/daemon/dist/orchestrator-tools.js.map +1 -0
  214. package/packages/daemon/dist/orchestrator.d.ts +4 -56
  215. package/packages/daemon/dist/orchestrator.d.ts.map +1 -1
  216. package/packages/daemon/dist/orchestrator.js +13 -303
  217. package/packages/daemon/dist/orchestrator.js.map +1 -1
  218. package/packages/daemon/dist/orchestrator.test.js +11 -1
  219. package/packages/daemon/dist/orchestrator.test.js.map +1 -1
  220. package/packages/daemon/package.json +4 -4
  221. package/packages/gsd-agent-core/dist/export-html/template.js +53 -4
  222. package/packages/gsd-agent-core/package.json +5 -5
  223. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  224. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +3 -2
  225. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  226. package/packages/gsd-agent-modes/package.json +7 -7
  227. package/packages/mcp-server/package.json +4 -4
  228. package/packages/native/package.json +1 -1
  229. package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  230. package/packages/pi-agent-core/dist/agent-loop.js +14 -9
  231. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  232. package/packages/pi-agent-core/package.json +1 -1
  233. package/packages/pi-ai/dist/index.d.ts +1 -0
  234. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  235. package/packages/pi-ai/dist/index.js +1 -0
  236. package/packages/pi-ai/dist/index.js.map +1 -1
  237. package/packages/pi-ai/dist/providers/transform-messages.d.ts.map +1 -1
  238. package/packages/pi-ai/dist/providers/transform-messages.js +7 -3
  239. package/packages/pi-ai/dist/providers/transform-messages.js.map +1 -1
  240. package/packages/pi-ai/dist/tool-result-content.d.ts +3 -0
  241. package/packages/pi-ai/dist/tool-result-content.d.ts.map +1 -0
  242. package/packages/pi-ai/dist/tool-result-content.js +62 -0
  243. package/packages/pi-ai/dist/tool-result-content.js.map +1 -0
  244. package/packages/pi-ai/dist/types.d.ts +8 -20
  245. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  246. package/packages/pi-ai/dist/types.js.map +1 -1
  247. package/packages/pi-ai/package.json +1 -1
  248. package/packages/pi-coding-agent/dist/core/package-manager.d.ts +9 -0
  249. package/packages/pi-coding-agent/dist/core/package-manager.d.ts.map +1 -1
  250. package/packages/pi-coding-agent/dist/core/package-manager.js +74 -53
  251. package/packages/pi-coding-agent/dist/core/package-manager.js.map +1 -1
  252. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +6 -0
  253. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
  254. package/packages/pi-coding-agent/dist/core/resource-loader.js +30 -2
  255. package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
  256. package/packages/pi-coding-agent/dist/core/skill-directories.d.ts +66 -0
  257. package/packages/pi-coding-agent/dist/core/skill-directories.d.ts.map +1 -0
  258. package/packages/pi-coding-agent/dist/core/skill-directories.js +138 -0
  259. package/packages/pi-coding-agent/dist/core/skill-directories.js.map +1 -0
  260. package/packages/pi-coding-agent/dist/core/skills.d.ts +4 -1
  261. package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
  262. package/packages/pi-coding-agent/dist/core/skills.js +4 -1
  263. package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
  264. package/packages/pi-coding-agent/dist/index.d.ts +1 -0
  265. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  266. package/packages/pi-coding-agent/dist/index.js +1 -0
  267. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  268. package/packages/pi-coding-agent/package.json +7 -7
  269. package/packages/pi-tui/package.json +2 -2
  270. package/packages/rpc-client/package.json +2 -2
  271. package/pkg/dist/core/export-html/template.js +53 -4
  272. package/pkg/package.json +1 -1
  273. package/src/resources/extensions/ask-user-questions.ts +1 -1
  274. package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +146 -33
  275. package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +25 -0
  276. package/src/resources/extensions/browser-tools/tests/managed-gsd-browser-tools.test.mjs +93 -0
  277. package/src/resources/extensions/gsd/activity-log.ts +1 -1
  278. package/src/resources/extensions/gsd/auto/closeout.ts +114 -7
  279. package/src/resources/extensions/gsd/auto/orchestrator.ts +21 -14
  280. package/src/resources/extensions/gsd/auto/pre-dispatch.ts +6 -3
  281. package/src/resources/extensions/gsd/auto/unit-phase.ts +5 -9
  282. package/src/resources/extensions/gsd/auto-artifact-paths.ts +14 -4
  283. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +13 -7
  284. package/src/resources/extensions/gsd/auto-dispatch.ts +77 -16
  285. package/src/resources/extensions/gsd/auto-model-selection.ts +33 -1
  286. package/src/resources/extensions/gsd/auto-post-unit.ts +4 -2
  287. package/src/resources/extensions/gsd/auto-prompts.ts +53 -113
  288. package/src/resources/extensions/gsd/auto-recovery.ts +50 -6
  289. package/src/resources/extensions/gsd/auto-start.ts +62 -31
  290. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +12 -2
  291. package/src/resources/extensions/gsd/auto-timers.ts +9 -2
  292. package/src/resources/extensions/gsd/auto-worktree-branch-lifecycle.ts +237 -0
  293. package/src/resources/extensions/gsd/auto-worktree-cleanup.ts +166 -0
  294. package/src/resources/extensions/gsd/auto-worktree-conflict-auto-resolve.ts +37 -0
  295. package/src/resources/extensions/gsd/auto-worktree-creation.ts +171 -0
  296. package/src/resources/extensions/gsd/auto-worktree-entry.ts +154 -0
  297. package/src/resources/extensions/gsd/auto-worktree-merge-already-merged.ts +161 -0
  298. package/src/resources/extensions/gsd/auto-worktree-merge-branch-head.ts +83 -0
  299. package/src/resources/extensions/gsd/auto-worktree-merge-cleanup.ts +132 -0
  300. package/src/resources/extensions/gsd/auto-worktree-merge-code-changes.ts +71 -0
  301. package/src/resources/extensions/gsd/auto-worktree-merge-db-ready.ts +112 -0
  302. package/src/resources/extensions/gsd/auto-worktree-merge-integration-branch.ts +99 -0
  303. package/src/resources/extensions/gsd/auto-worktree-merge-message.ts +166 -0
  304. package/src/resources/extensions/gsd/auto-worktree-merge-pre-teardown.ts +93 -0
  305. package/src/resources/extensions/gsd/auto-worktree-merge-stash.ts +213 -0
  306. package/src/resources/extensions/gsd/auto-worktree-merge.ts +391 -0
  307. package/src/resources/extensions/gsd/auto-worktree-milestone-shelter.ts +159 -0
  308. package/src/resources/extensions/gsd/auto-worktree-path-resolution.ts +6 -0
  309. package/src/resources/extensions/gsd/auto-worktree-path-utils.ts +10 -0
  310. package/src/resources/extensions/gsd/auto-worktree-resource-version.ts +44 -0
  311. package/src/resources/extensions/gsd/auto-worktree-runtime-cleanup.ts +119 -0
  312. package/src/resources/extensions/gsd/auto-worktree-session-registry.ts +71 -0
  313. package/src/resources/extensions/gsd/auto-worktree-sync.ts +370 -0
  314. package/src/resources/extensions/gsd/auto-worktree-teardown.ts +161 -0
  315. package/src/resources/extensions/gsd/auto-worktree.ts +69 -2429
  316. package/src/resources/extensions/gsd/auto.ts +114 -47
  317. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +1 -1
  318. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +20 -2
  319. package/src/resources/extensions/gsd/bootstrap/system-context.ts +1 -1
  320. package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +218 -27
  321. package/src/resources/extensions/gsd/codebase-generator.ts +7 -1
  322. package/src/resources/extensions/gsd/commands-handlers.ts +1 -1
  323. package/src/resources/extensions/gsd/commands-workflow-templates.ts +3 -3
  324. package/src/resources/extensions/gsd/compat/compat-marker.ts +47 -0
  325. package/src/resources/extensions/gsd/config-overlay.ts +7 -1
  326. package/src/resources/extensions/gsd/db/engine.ts +36 -0
  327. package/src/resources/extensions/gsd/db/queries.ts +9 -9
  328. package/src/resources/extensions/gsd/db/writers/cascades.ts +23 -1
  329. package/src/resources/extensions/gsd/db-adapter.ts +29 -3
  330. package/src/resources/extensions/gsd/docs/preferences-reference.md +3 -3
  331. package/src/resources/extensions/gsd/doctor-engine-checks.ts +109 -10
  332. package/src/resources/extensions/gsd/flat-phase-migration.ts +34 -3
  333. package/src/resources/extensions/gsd/forensics.ts +1 -1
  334. package/src/resources/extensions/gsd/git-conflict-resolve.ts +2 -2
  335. package/src/resources/extensions/gsd/git-service.ts +53 -0
  336. package/src/resources/extensions/gsd/gsd-db.ts +33 -11
  337. package/src/resources/extensions/gsd/guided-flow.ts +26 -18
  338. package/src/resources/extensions/gsd/journal.ts +1 -1
  339. package/src/resources/extensions/gsd/markdown-renderer.ts +52 -91
  340. package/src/resources/extensions/gsd/md-importer.ts +93 -22
  341. package/src/resources/extensions/gsd/metrics.ts +2 -2
  342. package/src/resources/extensions/gsd/migration-auto-check.ts +32 -3
  343. package/src/resources/extensions/gsd/milestone-merge-transaction.ts +15 -0
  344. package/src/resources/extensions/gsd/milestone-settlement.ts +1 -1
  345. package/src/resources/extensions/gsd/parallel-merge.ts +1 -1
  346. package/src/resources/extensions/gsd/parallel-orchestrator.ts +3 -1
  347. package/src/resources/extensions/gsd/paths.ts +108 -51
  348. package/src/resources/extensions/gsd/post-unit-hooks.ts +32 -0
  349. package/src/resources/extensions/gsd/preferences-models.ts +74 -20
  350. package/src/resources/extensions/gsd/preferences-skills.ts +10 -16
  351. package/src/resources/extensions/gsd/preferences-types.ts +54 -1
  352. package/src/resources/extensions/gsd/preferences-validation.ts +146 -9
  353. package/src/resources/extensions/gsd/preferences.ts +20 -0
  354. package/src/resources/extensions/gsd/prompts/system.md +6 -6
  355. package/src/resources/extensions/gsd/quick.ts +11 -3
  356. package/src/resources/extensions/gsd/rule-registry.ts +111 -9
  357. package/src/resources/extensions/gsd/skill-discovery.ts +47 -23
  358. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +3 -1
  359. package/src/resources/extensions/gsd/state/derive/from-db.ts +201 -157
  360. package/src/resources/extensions/gsd/state-reconciliation/drift/artifact-db.ts +1 -9
  361. package/src/resources/extensions/gsd/state-reconciliation/drift/completion.ts +2 -22
  362. package/src/resources/extensions/gsd/state-reconciliation/index.ts +14 -0
  363. package/src/resources/extensions/gsd/tests/auto-artifact-paths.test.ts +169 -1
  364. package/src/resources/extensions/gsd/tests/auto-loop-no-copy-artifacts.test.ts +2 -1
  365. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +41 -2
  366. package/src/resources/extensions/gsd/tests/auto-post-unit-artifact-diagnostic.test.ts +48 -1
  367. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +57 -0
  368. package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +1 -1
  369. package/src/resources/extensions/gsd/tests/auto-start-project-milestone-reconcile.test.ts +29 -1
  370. package/src/resources/extensions/gsd/tests/auto-timeout-recovery-supervisor-inflight-guard.test.ts +159 -0
  371. package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +2 -1
  372. package/src/resources/extensions/gsd/tests/auto-worktree-auto-resolve.test.ts +1 -1
  373. package/src/resources/extensions/gsd/tests/auto-worktree-merge-already-merged.test.ts +177 -0
  374. package/src/resources/extensions/gsd/tests/auto-worktree-merge-branch-head.test.ts +118 -0
  375. package/src/resources/extensions/gsd/tests/auto-worktree-merge-cleanup.test.ts +115 -0
  376. package/src/resources/extensions/gsd/tests/auto-worktree-merge-code-changes.test.ts +76 -0
  377. package/src/resources/extensions/gsd/tests/auto-worktree-merge-db-ready.test.ts +140 -0
  378. package/src/resources/extensions/gsd/tests/auto-worktree-merge-integration-branch.test.ts +123 -0
  379. package/src/resources/extensions/gsd/tests/auto-worktree-merge-message.test.ts +114 -0
  380. package/src/resources/extensions/gsd/tests/auto-worktree-merge-pre-teardown.test.ts +84 -0
  381. package/src/resources/extensions/gsd/tests/auto-worktree-merge-stash.test.ts +70 -0
  382. package/src/resources/extensions/gsd/tests/auto-worktree-milestone-shelter.test.ts +52 -0
  383. package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +6 -6
  384. package/src/resources/extensions/gsd/tests/auto-worktree-resource-version.test.ts +59 -0
  385. package/src/resources/extensions/gsd/tests/auto-worktree-untracked-content.test.ts +3 -1
  386. package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +22 -0
  387. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +3 -1
  388. package/src/resources/extensions/gsd/tests/compat-marker.test.ts +85 -0
  389. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +45 -0
  390. package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +1 -1
  391. package/src/resources/extensions/gsd/tests/db-adapter.test.ts +39 -0
  392. package/src/resources/extensions/gsd/tests/db-writable-probe.test.ts +66 -0
  393. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +4 -0
  394. package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +174 -0
  395. package/src/resources/extensions/gsd/tests/fast-forward-reused-milestone-branch.test.ts +1 -1
  396. package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +71 -1
  397. package/src/resources/extensions/gsd/tests/flat-phase-renderer.test.ts +46 -1
  398. package/src/resources/extensions/gsd/tests/flat-phase-validation-path.test.ts +72 -32
  399. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +40 -0
  400. package/src/resources/extensions/gsd/tests/import-completion-lost-update.test.ts +196 -0
  401. package/src/resources/extensions/gsd/tests/integration/all-milestones-complete-merge.test.ts +4 -6
  402. package/src/resources/extensions/gsd/tests/integration/auto-stash-merge.test.ts +2 -1
  403. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +3 -3
  404. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +7 -8
  405. package/src/resources/extensions/gsd/tests/integration/feature-branch-lifecycle-integration.test.ts +2 -5
  406. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +76 -0
  407. package/src/resources/extensions/gsd/tests/integration/merge-cwd-restore.test.ts +1 -1
  408. package/src/resources/extensions/gsd/tests/integration/merge-preserve-worktree-on-preteardown-error.test.ts +1 -1
  409. package/src/resources/extensions/gsd/tests/integration/merge-strategy-regular.test.ts +2 -1
  410. package/src/resources/extensions/gsd/tests/integration/milestone-transition-worktree.test.ts +5 -7
  411. package/src/resources/extensions/gsd/tests/integration/paths.test.ts +88 -1
  412. package/src/resources/extensions/gsd/tests/integration/workspace-collapse-integration.test.ts +2 -4
  413. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +16 -15
  414. package/src/resources/extensions/gsd/tests/merge-closeout-consistency-gate.test.ts +1 -1
  415. package/src/resources/extensions/gsd/tests/merge-db-cycle.test.ts +1 -1
  416. package/src/resources/extensions/gsd/tests/merge-self-branch-guard.test.ts +1 -1
  417. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +91 -0
  418. package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +2 -1
  419. package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +439 -0
  420. package/src/resources/extensions/gsd/tests/milestone-merge-transaction.test.ts +24 -0
  421. package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +1 -1
  422. package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +3 -3
  423. package/src/resources/extensions/gsd/tests/parallel-worker-lock-contention.test.ts +1 -1
  424. package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +0 -1
  425. package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +269 -0
  426. package/src/resources/extensions/gsd/tests/post-unit-retry-on-orchestrator-bridge.test.ts +8 -1
  427. package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +1 -4
  428. package/src/resources/extensions/gsd/tests/preferences.test.ts +19 -0
  429. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +5 -0
  430. package/src/resources/extensions/gsd/tests/read-uat-gate-verdict.test.ts +54 -0
  431. package/src/resources/extensions/gsd/tests/reassess-handler.test.ts +49 -1
  432. package/src/resources/extensions/gsd/tests/reopen-slice.test.ts +52 -0
  433. package/src/resources/extensions/gsd/tests/rule-registry.test.ts +95 -1
  434. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +20 -0
  435. package/src/resources/extensions/gsd/tests/sibling-model-fallbacks.test.ts +189 -0
  436. package/src/resources/extensions/gsd/tests/single-field-model-thinking.test.ts +156 -0
  437. package/src/resources/extensions/gsd/tests/skill-discovery.test.ts +46 -0
  438. package/src/resources/extensions/gsd/tests/skipped-validation-db-atomicity.test.ts +6 -1
  439. package/src/resources/extensions/gsd/tests/stale-worktree-cwd.test.ts +3 -5
  440. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +32 -0
  441. package/src/resources/extensions/gsd/tests/stash-pop-gsd-conflict.test.ts +2 -1
  442. package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +2 -1
  443. package/src/resources/extensions/gsd/tests/steer-worktree-path.test.ts +1 -1
  444. package/src/resources/extensions/gsd/tests/supervisor-model-swap-inflight-guard.test.ts +181 -0
  445. package/src/resources/extensions/gsd/tests/supervisor-model-swap-thinking-clamp.test.ts +122 -0
  446. package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +1 -1
  447. package/src/resources/extensions/gsd/tests/system-flat-phase-layout.test.ts +33 -0
  448. package/src/resources/extensions/gsd/tests/teardown-chdir-failure-clears-registry.test.ts +4 -4
  449. package/src/resources/extensions/gsd/tests/teardown-cleanup-parity.test.ts +2 -1
  450. package/src/resources/extensions/gsd/tests/teardown-failure-clears-registry.test.ts +4 -4
  451. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +196 -0
  452. package/src/resources/extensions/gsd/tests/uat-dispatch.test.ts +211 -0
  453. package/src/resources/extensions/gsd/tests/uat-stuck-loop-orphaned-worktree.test.ts +1 -1
  454. package/src/resources/extensions/gsd/tests/unit-registry.test.ts +26 -1
  455. package/src/resources/extensions/gsd/tests/uok-gate-runner.test.ts +39 -0
  456. package/src/resources/extensions/gsd/tests/uok-kernel-path.test.ts +226 -2
  457. package/src/resources/extensions/gsd/tests/uok-model-policy.test.ts +6 -0
  458. package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +213 -2
  459. package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +1 -1
  460. package/src/resources/extensions/gsd/tests/worktree-db-respawn-truncation.test.ts +1 -1
  461. package/src/resources/extensions/gsd/tests/worktree-db-same-file.test.ts +1 -3
  462. package/src/resources/extensions/gsd/tests/worktree-expected-warnings.test.ts +1 -1
  463. package/src/resources/extensions/gsd/tests/worktree-git-pathspec.test.ts +1 -1
  464. package/src/resources/extensions/gsd/tests/worktree-main-branch.test.ts +1 -1
  465. package/src/resources/extensions/gsd/tests/worktree-preferences-sync.test.ts +1 -1
  466. package/src/resources/extensions/gsd/tests/worktree-reentry.test.ts +2 -1
  467. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +5 -2
  468. package/src/resources/extensions/gsd/tests/worktree-sync-overwrite-loop.test.ts +1 -1
  469. package/src/resources/extensions/gsd/tests/worktree-sync-tasks.test.ts +1 -1
  470. package/src/resources/extensions/gsd/tool-contract.ts +29 -0
  471. package/src/resources/extensions/gsd/tools/complete-milestone.ts +9 -5
  472. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +19 -8
  473. package/src/resources/extensions/gsd/tools/reopen-slice.ts +5 -0
  474. package/src/resources/extensions/gsd/tools/reopen-task.ts +13 -5
  475. package/src/resources/extensions/gsd/tools/validate-milestone.ts +13 -9
  476. package/src/resources/extensions/gsd/types.ts +23 -4
  477. package/src/resources/extensions/gsd/uat-dispatch.ts +176 -0
  478. package/src/resources/extensions/gsd/unit-registry.ts +16 -2
  479. package/src/resources/extensions/gsd/unmerged-milestone-guard.ts +1 -1
  480. package/src/resources/extensions/gsd/uok/audit-toggle.ts +32 -2
  481. package/src/resources/extensions/gsd/uok/audit.ts +2 -0
  482. package/src/resources/extensions/gsd/uok/gate-runner.ts +26 -36
  483. package/src/resources/extensions/gsd/uok/gitops.ts +21 -18
  484. package/src/resources/extensions/gsd/uok/kernel.ts +169 -48
  485. package/src/resources/extensions/gsd/uok/model-policy.ts +20 -17
  486. package/src/resources/extensions/gsd/validation-block-guard.ts +2 -1
  487. package/src/resources/extensions/gsd/workflow-event-ledger.ts +1 -1
  488. package/src/resources/extensions/gsd/workflow-logger.ts +1 -1
  489. package/src/resources/extensions/gsd/workflow-projections.ts +9 -24
  490. package/src/resources/extensions/gsd/workspace-git-preflight.ts +2 -2
  491. package/src/resources/extensions/gsd/workspace.ts +5 -21
  492. package/src/resources/extensions/gsd/worktree-command.ts +1 -1
  493. package/src/resources/extensions/gsd/worktree-lifecycle.ts +19 -15
  494. package/src/resources/extensions/gsd/worktree-reentry.ts +2 -1
  495. package/src/resources/extensions/shared/gsd-browser-cli.ts +29 -0
  496. package/src/resources/extensions/shared/interview-ui.ts +58 -11
  497. package/src/resources/extensions/shared/tests/interview-ui-border.test.ts +32 -0
  498. /package/dist/web/standalone/.next/static/{bCg3aYrFN1DKZr2dqgE7L → 6xYMOzxVhsQgryneJ5KRc}/_buildManifest.js +0 -0
  499. /package/dist/web/standalone/.next/static/{bCg3aYrFN1DKZr2dqgE7L → 6xYMOzxVhsQgryneJ5KRc}/_ssgManifest.js +0 -0
@@ -1,7 +1,7 @@
1
1
  // Project/App: gsd-pi
2
2
  // File Purpose: DB-backed GSD state derivation pipeline stage.
3
3
 
4
- import type { ActiveRef, GSDState, MilestoneRegistryEntry } from '../../types.js';
4
+ import type { ActiveRef, GSDState, MilestoneRegistryEntry, Phase } from '../../types.js';
5
5
  import { join } from 'node:path';
6
6
  import { existsSync } from 'node:fs';
7
7
  import { isClosedStatus, isDeferredStatus } from '../../status-guards.js';
@@ -41,6 +41,59 @@ import {
41
41
 
42
42
  const isStatusDone = isClosedStatus;
43
43
 
44
+ type MilestoneProgress = { done: number; total: number };
45
+ type SliceProgress = { done: number; total: number };
46
+ type TaskProgress = { done: number; total: number };
47
+
48
+ interface DerivedStateContext {
49
+ activeMilestone: ActiveRef | null;
50
+ activeSlice?: ActiveRef | null;
51
+ activeTask?: ActiveRef | null;
52
+ registry: MilestoneRegistryEntry[];
53
+ requirements: GSDState["requirements"];
54
+ milestoneProgress: MilestoneProgress;
55
+ sliceProgress?: SliceProgress;
56
+ taskProgress?: TaskProgress;
57
+ }
58
+
59
+ interface DerivedStateOptions {
60
+ blockers?: string[];
61
+ lastCompletedMilestone?: ActiveRef | null;
62
+ includeActiveWorkspace?: boolean;
63
+ }
64
+
65
+ function buildProgress(context: DerivedStateContext): NonNullable<GSDState["progress"]> {
66
+ return {
67
+ milestones: context.milestoneProgress,
68
+ ...(context.sliceProgress ? { slices: context.sliceProgress } : {}),
69
+ ...(context.taskProgress ? { tasks: context.taskProgress } : {}),
70
+ };
71
+ }
72
+
73
+ function buildDerivedState(
74
+ context: DerivedStateContext,
75
+ phase: Phase,
76
+ nextAction: string,
77
+ options: DerivedStateOptions = {},
78
+ ): GSDState {
79
+ return {
80
+ activeMilestone: context.activeMilestone,
81
+ activeSlice: context.activeSlice ?? null,
82
+ activeTask: context.activeTask ?? null,
83
+ phase,
84
+ recentDecisions: [],
85
+ blockers: options.blockers ?? [],
86
+ nextAction,
87
+ ...(options.lastCompletedMilestone !== undefined
88
+ ? { lastCompletedMilestone: options.lastCompletedMilestone }
89
+ : {}),
90
+ ...(options.includeActiveWorkspace ? { activeWorkspace: undefined } : {}),
91
+ registry: context.registry,
92
+ requirements: context.requirements,
93
+ progress: buildProgress(context),
94
+ };
95
+ }
96
+
44
97
  function stripMilestonePrefix(title: string): string {
45
98
  return title.replace(/^M\d+(?:-[a-z0-9]{6})?[^:]*:\s*/, '') || title;
46
99
  }
@@ -182,58 +235,47 @@ function handleNoActiveMilestone(
182
235
  const pendingEntries = registry.filter(e => e.status === 'pending');
183
236
  const parkedEntries = registry.filter(e => e.status === 'parked');
184
237
 
238
+ const context: DerivedStateContext = {
239
+ activeMilestone: null,
240
+ registry,
241
+ requirements,
242
+ milestoneProgress,
243
+ };
244
+
185
245
  if (pendingEntries.length > 0) {
186
246
  const blockerDetails = pendingEntries
187
247
  .filter(e => e.dependsOn && e.dependsOn.length > 0)
188
248
  .map(e => `${e.id} is waiting on unmet deps: ${e.dependsOn!.join(', ')}`);
189
- return {
190
- activeMilestone: null, activeSlice: null, activeTask: null,
191
- phase: 'blocked',
192
- recentDecisions: [], blockers: blockerDetails.length > 0
249
+ return buildDerivedState(context, 'blocked', 'Resolve milestone dependencies before proceeding.', {
250
+ blockers: blockerDetails.length > 0
193
251
  ? blockerDetails
194
252
  : ['All remaining milestones are dep-blocked but no deps listed — check CONTEXT.md files'],
195
- nextAction: 'Resolve milestone dependencies before proceeding.',
196
- registry, requirements,
197
- progress: { milestones: milestoneProgress },
198
- };
253
+ });
199
254
  }
200
255
 
201
256
  if (parkedEntries.length > 0) {
202
257
  const parkedIds = parkedEntries.map(e => e.id).join(', ');
203
- return {
204
- activeMilestone: null, activeSlice: null, activeTask: null,
205
- phase: 'pre-planning',
206
- recentDecisions: [], blockers: [],
207
- nextAction: `All remaining milestones are parked (${parkedIds}). Run /gsd unpark <id> or create a new milestone.`,
208
- registry, requirements,
209
- progress: { milestones: milestoneProgress },
210
- };
258
+ return buildDerivedState(
259
+ context,
260
+ 'pre-planning',
261
+ `All remaining milestones are parked (${parkedIds}). Run /gsd unpark <id> or create a new milestone.`,
262
+ );
211
263
  }
212
264
 
213
265
  if (registry.length === 0) {
214
- return {
215
- activeMilestone: null, activeSlice: null, activeTask: null,
216
- phase: 'pre-planning',
217
- recentDecisions: [], blockers: [],
218
- nextAction: 'No milestones found. Run /gsd to create one.',
219
- registry: [], requirements,
220
- progress: { milestones: { done: 0, total: 0 } },
221
- };
266
+ return buildDerivedState(
267
+ { ...context, registry: [], milestoneProgress: { done: 0, total: 0 } },
268
+ 'pre-planning',
269
+ 'No milestones found. Run /gsd to create one.',
270
+ );
222
271
  }
223
272
 
224
273
  const lastEntry = registry[registry.length - 1];
225
274
  const unmappedActive = countUnmappedActiveRequirements();
226
275
  const completionNote = formatCompletePhaseNextAction(unmappedActive);
227
- return {
228
- activeMilestone: null,
276
+ return buildDerivedState(context, 'complete', completionNote, {
229
277
  lastCompletedMilestone: lastEntry ? { id: lastEntry.id, title: lastEntry.title } : null,
230
- activeSlice: null, activeTask: null,
231
- phase: 'complete',
232
- recentDecisions: [], blockers: [],
233
- nextAction: completionNote,
234
- registry, requirements,
235
- progress: { milestones: milestoneProgress },
236
- };
278
+ });
237
279
  }
238
280
 
239
281
  async function handleAllSlicesDone(
@@ -248,52 +290,48 @@ async function handleAllSlicesDone(
248
290
  const verdict = typeof validation?.status === "string" ? validation.status : undefined;
249
291
  const validationTerminal = verdict != null && verdict !== "";
250
292
 
293
+ const context: DerivedStateContext = {
294
+ activeMilestone,
295
+ registry,
296
+ requirements,
297
+ milestoneProgress,
298
+ sliceProgress,
299
+ };
300
+
251
301
  if (!validationTerminal) {
252
- return {
253
- activeMilestone, activeSlice: null, activeTask: null,
254
- phase: 'validating-milestone',
255
- recentDecisions: [], blockers: [],
256
- nextAction: `Validate milestone ${activeMilestone.id} before completion.`,
257
- registry, requirements,
258
- progress: { milestones: milestoneProgress, slices: sliceProgress },
259
- };
302
+ return buildDerivedState(
303
+ context,
304
+ 'validating-milestone',
305
+ `Validate milestone ${activeMilestone.id} before completion.`,
306
+ );
260
307
  }
261
308
 
262
309
  // All roadmap slices are done (enforced by caller) and verdict is
263
310
  // needs-remediation — remediation cannot progress without new slices.
264
311
  // Return blocked instead of re-dispatching validate-milestone (#4506).
265
312
  if (verdict === 'needs-attention') {
266
- return {
267
- activeMilestone, activeSlice: null, activeTask: null,
268
- phase: 'blocked',
269
- recentDecisions: [],
270
- blockers: [formatNeedsAttentionBlocker(activeMilestone.id)],
271
- nextAction: `Resolve ${activeMilestone.id} validation attention before proceeding.`,
272
- registry, requirements,
273
- progress: { milestones: milestoneProgress, slices: sliceProgress },
274
- };
313
+ return buildDerivedState(
314
+ context,
315
+ 'blocked',
316
+ `Resolve ${activeMilestone.id} validation attention before proceeding.`,
317
+ { blockers: [formatNeedsAttentionBlocker(activeMilestone.id)] },
318
+ );
275
319
  }
276
320
 
277
321
  if (verdict === 'needs-remediation') {
278
- return {
279
- activeMilestone, activeSlice: null, activeTask: null,
280
- phase: 'blocked',
281
- recentDecisions: [],
282
- blockers: [formatNeedsRemediationBlocker(activeMilestone.id)],
283
- nextAction: `Resolve ${activeMilestone.id} remediation before proceeding.`,
284
- registry, requirements,
285
- progress: { milestones: milestoneProgress, slices: sliceProgress },
286
- };
322
+ return buildDerivedState(
323
+ context,
324
+ 'blocked',
325
+ `Resolve ${activeMilestone.id} remediation before proceeding.`,
326
+ { blockers: [formatNeedsRemediationBlocker(activeMilestone.id)] },
327
+ );
287
328
  }
288
329
 
289
- return {
290
- activeMilestone, activeSlice: null, activeTask: null,
291
- phase: 'completing-milestone',
292
- recentDecisions: [], blockers: [],
293
- nextAction: `All slices complete in ${activeMilestone.id}. Write milestone summary.`,
294
- registry, requirements,
295
- progress: { milestones: milestoneProgress, slices: sliceProgress },
296
- };
330
+ return buildDerivedState(
331
+ context,
332
+ 'completing-milestone',
333
+ `All slices complete in ${activeMilestone.id}. Write milestone summary.`,
334
+ );
297
335
  }
298
336
 
299
337
  function resolveSliceDependencies(activeMilestoneSlices: SliceRow[]): { activeSlice: ActiveRef | null, activeSliceRow: SliceRow | null } {
@@ -356,13 +394,16 @@ export async function deriveStateFromDb(
356
394
  : allMilestones;
357
395
 
358
396
  if (milestones.length === 0) {
359
- return {
360
- activeMilestone: null, activeSlice: null, activeTask: null,
361
- phase: 'pre-planning', recentDecisions: [], blockers: [],
362
- nextAction: 'No milestones found. Run /gsd to create one.',
363
- registry: [], requirements,
364
- progress: { milestones: { done: 0, total: 0 } },
365
- };
397
+ return buildDerivedState(
398
+ {
399
+ activeMilestone: null,
400
+ registry: [],
401
+ requirements,
402
+ milestoneProgress: { done: 0, total: 0 },
403
+ },
404
+ 'pre-planning',
405
+ 'No milestones found. Run /gsd to create one.',
406
+ );
366
407
  }
367
408
 
368
409
  const { completeMilestoneIds, parkedMilestoneIds } = buildCompletenessSet(basePath, milestones);
@@ -384,12 +425,11 @@ export async function deriveStateFromDb(
384
425
  const nextAction = activeMilestoneHasDraft
385
426
  ? `Discuss draft context for milestone ${activeMilestone.id}.`
386
427
  : `Plan milestone ${activeMilestone.id}.`;
387
- return {
388
- activeMilestone, activeSlice: null, activeTask: null,
389
- phase, recentDecisions: [], blockers: [],
390
- nextAction, registry, requirements,
391
- progress: { milestones: milestoneProgress },
392
- };
428
+ return buildDerivedState(
429
+ { activeMilestone, registry, requirements, milestoneProgress },
430
+ phase,
431
+ nextAction,
432
+ );
393
433
  }
394
434
 
395
435
  const allSlicesDone = activeMilestoneSlices.every(s => isStatusDone(s.status));
@@ -397,6 +437,13 @@ export async function deriveStateFromDb(
397
437
  done: activeMilestoneSlices.filter(s => isStatusDone(s.status)).length,
398
438
  total: activeMilestoneSlices.length,
399
439
  };
440
+ const sliceStateContext: DerivedStateContext = {
441
+ activeMilestone,
442
+ registry,
443
+ requirements,
444
+ milestoneProgress,
445
+ sliceProgress,
446
+ };
400
447
 
401
448
  if (allSlicesDone) {
402
449
  return handleAllSlicesDone(basePath, activeMilestone, registry, requirements, milestoneProgress, sliceProgress);
@@ -407,21 +454,19 @@ export async function deriveStateFromDb(
407
454
  // If locked slice wasn't found, it returns null but logs warning, we need to return 'blocked'
408
455
  const sliceLock = process.env.GSD_PARALLEL_WORKER ? process.env.GSD_SLICE_LOCK : undefined;
409
456
  if (sliceLock) {
410
- return {
411
- activeMilestone, activeSlice: null, activeTask: null,
412
- phase: 'blocked', recentDecisions: [], blockers: [`GSD_SLICE_LOCK=${sliceLock} not found in active milestone slices`],
413
- nextAction: 'Slice lock references a non-existent slice — check orchestrator dispatch.',
414
- registry, requirements,
415
- progress: { milestones: milestoneProgress, slices: sliceProgress },
416
- };
457
+ return buildDerivedState(
458
+ sliceStateContext,
459
+ 'blocked',
460
+ 'Slice lock references a non-existent slice — check orchestrator dispatch.',
461
+ { blockers: [`GSD_SLICE_LOCK=${sliceLock} not found in active milestone slices`] },
462
+ );
417
463
  }
418
- return {
419
- activeMilestone, activeSlice: null, activeTask: null,
420
- phase: 'blocked', recentDecisions: [], blockers: ['No slice eligible — check dependency ordering'],
421
- nextAction: 'Resolve dependency blockers or plan next slice.',
422
- registry, requirements,
423
- progress: { milestones: milestoneProgress, slices: sliceProgress },
424
- };
464
+ return buildDerivedState(
465
+ sliceStateContext,
466
+ 'blocked',
467
+ 'Resolve dependency blockers or plan next slice.',
468
+ { blockers: ['No slice eligible — check dependency ordering'] },
469
+ );
425
470
  }
426
471
  const { activeSlice } = activeSliceContext;
427
472
  const activeSliceRow = activeSliceContext.activeSliceRow;
@@ -432,13 +477,11 @@ export async function deriveStateFromDb(
432
477
  // PLAN.md and preference flags are projections/configuration and are
433
478
  // deliberately not used to infer whether the slice itself is a sketch.
434
479
  if (activeSliceRow?.is_sketch === 1) {
435
- return {
436
- activeMilestone, activeSlice, activeTask: null,
437
- phase: 'refining', recentDecisions: [], blockers: [],
438
- nextAction: `Refine sketch slice ${activeSlice.id} (${activeSlice.title}) using prior slice context.`,
439
- registry, requirements,
440
- progress: { milestones: milestoneProgress, slices: sliceProgress },
441
- };
480
+ return buildDerivedState(
481
+ { ...sliceStateContext, activeSlice },
482
+ 'refining',
483
+ `Refine sketch slice ${activeSlice.id} (${activeSlice.title}) using prior slice context.`,
484
+ );
442
485
  }
443
486
 
444
487
  const tasks = getSliceTasks(activeMilestone.id, activeSlice.id);
@@ -447,30 +490,35 @@ export async function deriveStateFromDb(
447
490
  done: tasks.filter(t => isStatusDone(t.status)).length,
448
491
  total: tasks.length,
449
492
  };
493
+ const taskStateContext: DerivedStateContext = {
494
+ ...sliceStateContext,
495
+ activeSlice,
496
+ taskProgress,
497
+ };
450
498
 
451
499
  const activeTaskRow = tasks.find(t => !isStatusDone(t.status));
452
500
 
453
501
  if (!activeTaskRow && tasks.length > 0) {
454
- return {
455
- activeMilestone, activeSlice, activeTask: null,
456
- phase: 'summarizing', recentDecisions: [], blockers: [],
457
- nextAction: `All tasks done in ${activeSlice.id}. Write slice summary and complete slice.`,
458
- registry, requirements,
459
- progress: { milestones: milestoneProgress, slices: sliceProgress, tasks: taskProgress },
460
- };
502
+ return buildDerivedState(
503
+ taskStateContext,
504
+ 'summarizing',
505
+ `All tasks done in ${activeSlice.id}. Write slice summary and complete slice.`,
506
+ );
461
507
  }
462
508
 
463
509
  if (!activeTaskRow) {
464
- return {
465
- activeMilestone, activeSlice, activeTask: null,
466
- phase: 'planning', recentDecisions: [], blockers: [],
467
- nextAction: `Slice ${activeSlice.id} has no DB tasks. Plan slice tasks before execution.`,
468
- registry, requirements,
469
- progress: { milestones: milestoneProgress, slices: sliceProgress, tasks: taskProgress },
470
- };
510
+ return buildDerivedState(
511
+ taskStateContext,
512
+ 'planning',
513
+ `Slice ${activeSlice.id} has no DB tasks. Plan slice tasks before execution.`,
514
+ );
471
515
  }
472
516
 
473
517
  const activeTask: ActiveRef = { id: activeTaskRow.id, title: activeTaskRow.title };
518
+ const activeTaskStateContext: DerivedStateContext = {
519
+ ...taskStateContext,
520
+ activeTask,
521
+ };
474
522
 
475
523
  // ── Quality gate evaluation check ──────────────────────────────────
476
524
  // Pause before execution only when gates owned by the `gate-evaluate`
@@ -485,28 +533,26 @@ export async function deriveStateFromDb(
485
533
  "gate-evaluate",
486
534
  );
487
535
  if (pendingGateCount > 0) {
488
- return {
489
- activeMilestone, activeSlice, activeTask: null,
490
- phase: 'evaluating-gates', recentDecisions: [], blockers: [],
491
- nextAction: `Evaluate ${pendingGateCount} quality gate(s) for ${activeSlice.id} before execution.`,
492
- registry, requirements,
493
- progress: { milestones: milestoneProgress, slices: sliceProgress, tasks: taskProgress },
494
- };
536
+ return buildDerivedState(
537
+ taskStateContext,
538
+ 'evaluating-gates',
539
+ `Evaluate ${pendingGateCount} quality gate(s) for ${activeSlice.id} before execution.`,
540
+ );
495
541
  }
496
542
 
497
543
  const blockerTaskId = await detectBlockers(basePath, activeMilestone.id, activeSlice.id, tasks);
498
544
  if (blockerTaskId) {
499
545
  const replanHistory = getReplanHistory(activeMilestone.id, activeSlice.id);
500
546
  if (replanHistory.length === 0) {
501
- return {
502
- activeMilestone, activeSlice, activeTask,
503
- phase: 'replanning-slice', recentDecisions: [],
504
- blockers: [`Task ${blockerTaskId} discovered a blocker requiring slice replan`],
505
- nextAction: `Task ${blockerTaskId} reported blocker_discovered. Replan slice ${activeSlice.id} before continuing.`,
506
- activeWorkspace: undefined,
507
- registry, requirements,
508
- progress: { milestones: milestoneProgress, slices: sliceProgress, tasks: taskProgress },
509
- };
547
+ return buildDerivedState(
548
+ activeTaskStateContext,
549
+ 'replanning-slice',
550
+ `Task ${blockerTaskId} reported blocker_discovered. Replan slice ${activeSlice.id} before continuing.`,
551
+ {
552
+ blockers: [`Task ${blockerTaskId} discovered a blocker requiring slice replan`],
553
+ includeActiveWorkspace: true,
554
+ },
555
+ );
510
556
  }
511
557
  }
512
558
 
@@ -522,15 +568,15 @@ export async function deriveStateFromDb(
522
568
  // and the user's prior resolution never lands.
523
569
  const escalatingTaskId = detectPendingEscalation(tasks, basePath);
524
570
  if (escalatingTaskId) {
525
- return {
526
- activeMilestone, activeSlice, activeTask,
527
- phase: 'escalating-task', recentDecisions: [],
528
- blockers: [`Task ${escalatingTaskId} requires a user decision before the loop can proceed`],
529
- nextAction: `Run /gsd escalate show ${escalatingTaskId} to review, then /gsd escalate resolve ${escalatingTaskId} <choice> to proceed.`,
530
- activeWorkspace: undefined,
531
- registry, requirements,
532
- progress: { milestones: milestoneProgress, slices: sliceProgress, tasks: taskProgress },
533
- };
571
+ return buildDerivedState(
572
+ activeTaskStateContext,
573
+ 'escalating-task',
574
+ `Run /gsd escalate show ${escalatingTaskId} to review, then /gsd escalate resolve ${escalatingTaskId} <choice> to proceed.`,
575
+ {
576
+ blockers: [`Task ${escalatingTaskId} requires a user decision before the loop can proceed`],
577
+ includeActiveWorkspace: true,
578
+ },
579
+ );
534
580
  }
535
581
 
536
582
  if (!blockerTaskId) {
@@ -538,24 +584,22 @@ export async function deriveStateFromDb(
538
584
  if (isTriggered) {
539
585
  const replanHistory = getReplanHistory(activeMilestone.id, activeSlice.id);
540
586
  if (replanHistory.length === 0) {
541
- return {
542
- activeMilestone, activeSlice, activeTask,
543
- phase: 'replanning-slice', recentDecisions: [],
544
- blockers: ['Triage replan trigger detected slice replan required'],
545
- nextAction: `Triage replan triggered for slice ${activeSlice.id}. Replan before continuing.`,
546
- activeWorkspace: undefined,
547
- registry, requirements,
548
- progress: { milestones: milestoneProgress, slices: sliceProgress, tasks: taskProgress },
549
- };
587
+ return buildDerivedState(
588
+ activeTaskStateContext,
589
+ 'replanning-slice',
590
+ `Triage replan triggered for slice ${activeSlice.id}. Replan before continuing.`,
591
+ {
592
+ blockers: ['Triage replan trigger detected — slice replan required'],
593
+ includeActiveWorkspace: true,
594
+ },
595
+ );
550
596
  }
551
597
  }
552
598
  }
553
599
 
554
- return {
555
- activeMilestone, activeSlice, activeTask,
556
- phase: 'executing', recentDecisions: [], blockers: [],
557
- nextAction: `Execute ${activeTask.id}: ${activeTask.title} in slice ${activeSlice.id}.`,
558
- registry, requirements,
559
- progress: { milestones: milestoneProgress, slices: sliceProgress, tasks: taskProgress },
560
- };
600
+ return buildDerivedState(
601
+ activeTaskStateContext,
602
+ 'executing',
603
+ `Execute ${activeTask.id}: ${activeTask.title} in slice ${activeSlice.id}.`,
604
+ );
561
605
  }
@@ -213,21 +213,13 @@ function detectArtifactDbStatusDriftForMilestone(
213
213
 
214
214
  for (const task of tasks) {
215
215
  if (isClosedStatus(task.status)) continue;
216
- // Flat-phase: task summaries live in the phase dir as TID-SUMMARY.md
217
- let diskTaskSummary = resolveTaskFile(
216
+ const diskTaskSummary = resolveTaskFile(
218
217
  basePath,
219
218
  milestoneId,
220
219
  slice.id,
221
220
  task.id,
222
221
  "SUMMARY",
223
222
  );
224
- if (!diskTaskSummary) {
225
- const phaseDir = resolveMilestonePath(basePath, milestoneId);
226
- if (phaseDir) {
227
- const flatSummary = join(phaseDir, `${task.id}-SUMMARY.md`);
228
- if (existsSync(flatSummary)) diskTaskSummary = flatSummary;
229
- }
230
- }
231
223
  if (!diskTaskSummary || !existsSync(diskTaskSummary)) continue;
232
224
  addUniqueDrift(drifts, seen, {
233
225
  kind: "artifact-db-status-divergence",
@@ -20,11 +20,9 @@ import {
20
20
  } from "../../gsd-db.js";
21
21
  import {
22
22
  resolveMilestoneFile,
23
- resolveMilestonePath,
24
23
  resolveSliceFile,
25
24
  resolveTaskFile,
26
25
  } from "../../paths.js";
27
- import { join } from "node:path";
28
26
  import type { GSDState } from "../../types.js";
29
27
  import type { DriftContext, DriftHandler, DriftRecord } from "../types.js";
30
28
 
@@ -105,23 +103,13 @@ function collectMilestoneCompletionDrift(
105
103
  for (const task of getSliceTasks(mid, slice.id)) {
106
104
  if (!COMPLETE_STATUSES.has(task.status)) continue;
107
105
  if (task.completed_at !== null) continue;
108
- // Flat-phase: task summaries live in the phase dir as TID-SUMMARY.md.
109
- // Legacy: resolveTaskFile returns the tasks/TID/TID-SUMMARY.md path.
110
- let taskSummary = resolveTaskFile(
106
+ const taskSummary = resolveTaskFile(
111
107
  ctx.basePath,
112
108
  mid,
113
109
  slice.id,
114
110
  task.id,
115
111
  "SUMMARY",
116
112
  );
117
- // Flat-phase fallback: check the phase dir directly
118
- if (!taskSummary) {
119
- const phaseDir = resolveMilestonePath(ctx.basePath, mid);
120
- if (phaseDir) {
121
- const flatSummary = join(phaseDir, `${task.id}-SUMMARY.md`);
122
- if (existsSync(flatSummary)) taskSummary = flatSummary;
123
- }
124
- }
125
113
  if (taskSummary && existsSync(taskSummary)) {
126
114
  drifts.push({
127
115
  kind: "missing-completion-timestamp",
@@ -182,15 +170,7 @@ export function repairMissingCompletionTimestamp(
182
170
  task.completed_at !== null ||
183
171
  !COMPLETE_STATUSES.has(task.status)
184
172
  ) return;
185
- // Flat-phase: task summaries live in the phase dir as TID-SUMMARY.md
186
- let summary = resolveTaskFile(ctx.basePath, mid, sid, tid, "SUMMARY");
187
- if (!summary) {
188
- const phaseDir = resolveMilestonePath(ctx.basePath, mid);
189
- if (phaseDir) {
190
- const flatSummary = join(phaseDir, `${tid}-SUMMARY.md`);
191
- if (existsSync(flatSummary)) summary = flatSummary;
192
- }
193
- }
173
+ const summary = resolveTaskFile(ctx.basePath, mid, sid, tid, "SUMMARY");
194
174
  const ts = summary ? summaryMtimeIso(summary) : null;
195
175
  if (!ts) return;
196
176
  updateTaskStatus(mid, sid, tid, task.status, ts);
@@ -73,6 +73,20 @@ export async function reconcileBeforeDispatch(
73
73
  if (!deps.dryRun) {
74
74
  const { capturePlanningCompatIfNeeded } = await import("../compat/planning-compat.js");
75
75
  await capturePlanningCompatIfNeeded(basePath);
76
+
77
+ // Self-heal phantom projection entries (#1257): a renamed/removed phase
78
+ // directory leaves stale `.compat.json` projection paths that no detector
79
+ // ever prunes (they all skip missing files), so the marker drifts from disk
80
+ // reality permanently. Drop entries whose backing file is gone before the
81
+ // detect passes run. Gated on !dryRun to keep detection read-only.
82
+ const { pruneOrphanedProjectionEntries } = await import("../compat/compat-marker.js");
83
+ const prunedCount = pruneOrphanedProjectionEntries(basePath);
84
+ if (prunedCount > 0) {
85
+ logWarning(
86
+ "reconcile",
87
+ `pruned ${prunedCount} orphaned projection entr${prunedCount === 1 ? "y" : "ies"} from .compat.json (backing file no longer on disk)`,
88
+ );
89
+ }
76
90
  }
77
91
 
78
92
  for (let pass = 0; pass < MAX_PASSES; pass++) {