gsd-pi 2.78.1-dev.b0759e59b → 2.78.1-dev.d8826a445

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 (300) hide show
  1. package/README.md +8 -5
  2. package/dist/headless-recover.d.ts +23 -0
  3. package/dist/headless-recover.js +93 -0
  4. package/dist/headless.js +9 -0
  5. package/dist/help-text.js +1 -0
  6. package/dist/resources/.managed-resources-content-hash +1 -1
  7. package/dist/resources/extensions/browser-tools/tools/intent.js +8 -1
  8. package/dist/resources/extensions/gsd/auto/phases.js +7 -2
  9. package/dist/resources/extensions/gsd/auto/session.js +3 -0
  10. package/dist/resources/extensions/gsd/auto-dispatch.js +7 -58
  11. package/dist/resources/extensions/gsd/auto-post-unit.js +14 -28
  12. package/dist/resources/extensions/gsd/auto-start.js +1 -8
  13. package/dist/resources/extensions/gsd/auto-worktree.js +244 -216
  14. package/dist/resources/extensions/gsd/auto.js +86 -7
  15. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +1 -1
  16. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +9 -77
  17. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +17 -16
  18. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +67 -55
  19. package/dist/resources/extensions/gsd/commands-codebase.js +2 -2
  20. package/dist/resources/extensions/gsd/commands-handlers.js +5 -5
  21. package/dist/resources/extensions/gsd/commands-logs.js +2 -2
  22. package/dist/resources/extensions/gsd/commands-scan.js +2 -2
  23. package/dist/resources/extensions/gsd/commands-ship.js +2 -2
  24. package/dist/resources/extensions/gsd/commands-workflow-templates.js +5 -5
  25. package/dist/resources/extensions/gsd/db-writer.js +106 -95
  26. package/dist/resources/extensions/gsd/delegation-policy.js +155 -0
  27. package/dist/resources/extensions/gsd/dispatch-guard.js +6 -10
  28. package/dist/resources/extensions/gsd/doctor-engine-checks.js +2 -2
  29. package/dist/resources/extensions/gsd/gsd-db.js +268 -8
  30. package/dist/resources/extensions/gsd/guided-flow-queue.js +1 -1
  31. package/dist/resources/extensions/gsd/guided-flow.js +141 -32
  32. package/dist/resources/extensions/gsd/markdown-renderer.js +14 -51
  33. package/dist/resources/extensions/gsd/metrics.js +287 -1
  34. package/dist/resources/extensions/gsd/parallel-merge.js +14 -13
  35. package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +5 -2
  36. package/dist/resources/extensions/gsd/paths.js +114 -9
  37. package/dist/resources/extensions/gsd/prompts/complete-slice.md +4 -4
  38. package/dist/resources/extensions/gsd/prompts/execute-task.md +3 -3
  39. package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +8 -1
  40. package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +22 -7
  41. package/dist/resources/extensions/gsd/prompts/guided-discuss-requirements.md +6 -2
  42. package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +8 -1
  43. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +6 -0
  44. package/dist/resources/extensions/gsd/queue-order.js +6 -1
  45. package/dist/resources/extensions/gsd/rethink.js +2 -2
  46. package/dist/resources/extensions/gsd/state.js +91 -372
  47. package/dist/resources/extensions/gsd/templates/project.md +10 -0
  48. package/dist/resources/extensions/gsd/tools/complete-milestone.js +6 -5
  49. package/dist/resources/extensions/gsd/tools/complete-slice.js +7 -12
  50. package/dist/resources/extensions/gsd/tools/complete-task.js +19 -31
  51. package/dist/resources/extensions/gsd/tools/validate-milestone.js +7 -5
  52. package/dist/resources/extensions/gsd/workflow-manifest.js +2 -1
  53. package/dist/resources/extensions/gsd/workflow-mcp-auto-prep.js +3 -21
  54. package/dist/resources/extensions/gsd/workflow-mcp.js +2 -2
  55. package/dist/resources/extensions/gsd/workflow-reconcile.js +3 -3
  56. package/dist/resources/extensions/gsd/workspace.js +59 -0
  57. package/dist/resources/extensions/gsd/worktree-command.js +4 -3
  58. package/dist/resources/extensions/gsd/worktree-resolver.js +15 -2
  59. package/dist/resources/extensions/gsd/write-intercept.js +3 -3
  60. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  61. package/dist/web/standalone/.next/BUILD_ID +1 -1
  62. package/dist/web/standalone/.next/app-path-routes-manifest.json +12 -12
  63. package/dist/web/standalone/.next/build-manifest.json +2 -2
  64. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  65. package/dist/web/standalone/.next/required-server-files.json +1 -1
  66. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  67. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  68. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  69. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  70. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  71. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  72. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  73. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  74. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  75. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  76. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  77. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  78. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  79. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  80. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  81. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  82. package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
  83. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
  84. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
  85. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
  86. package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
  87. package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
  88. package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
  89. package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
  90. package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  91. package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
  92. package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  93. package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
  94. package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
  95. package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
  96. package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
  97. package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
  98. package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
  99. package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
  100. package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  101. package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
  102. package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
  103. package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
  104. package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
  105. package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
  106. package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
  107. package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
  108. package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
  109. package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
  110. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
  111. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
  112. package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
  113. package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
  114. package/dist/web/standalone/.next/server/app/index.html +1 -1
  115. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  116. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  117. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  118. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  119. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  120. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  121. package/dist/web/standalone/.next/server/app-paths-manifest.json +12 -12
  122. package/dist/web/standalone/.next/server/chunks/6336.js +1 -0
  123. package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
  124. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  125. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  126. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  127. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  128. package/dist/web/standalone/server.js +1 -1
  129. package/package.json +1 -1
  130. package/packages/mcp-server/README.md +2 -11
  131. package/packages/mcp-server/dist/remote-questions.d.ts +27 -0
  132. package/packages/mcp-server/dist/remote-questions.d.ts.map +1 -1
  133. package/packages/mcp-server/dist/remote-questions.js +28 -0
  134. package/packages/mcp-server/dist/remote-questions.js.map +1 -1
  135. package/packages/mcp-server/dist/server.d.ts +28 -0
  136. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  137. package/packages/mcp-server/dist/server.js +94 -4
  138. package/packages/mcp-server/dist/server.js.map +1 -1
  139. package/packages/mcp-server/dist/workflow-tools.d.ts +6 -0
  140. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  141. package/packages/mcp-server/dist/workflow-tools.js +56 -2
  142. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  143. package/packages/mcp-server/src/mcp-server.test.ts +226 -0
  144. package/packages/mcp-server/src/parse-workflow-args.test.ts +80 -0
  145. package/packages/mcp-server/src/remote-questions.test.ts +103 -0
  146. package/packages/mcp-server/src/remote-questions.ts +35 -0
  147. package/packages/mcp-server/src/server.ts +129 -6
  148. package/packages/mcp-server/src/workflow-tools.ts +62 -3
  149. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  150. package/src/resources/extensions/browser-tools/tools/intent.ts +13 -2
  151. package/src/resources/extensions/gsd/auto/phases.ts +8 -2
  152. package/src/resources/extensions/gsd/auto/session.ts +4 -0
  153. package/src/resources/extensions/gsd/auto-dispatch.ts +14 -62
  154. package/src/resources/extensions/gsd/auto-post-unit.ts +15 -27
  155. package/src/resources/extensions/gsd/auto-start.ts +1 -8
  156. package/src/resources/extensions/gsd/auto-worktree.ts +286 -251
  157. package/src/resources/extensions/gsd/auto.ts +102 -7
  158. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +1 -1
  159. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +9 -84
  160. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +17 -17
  161. package/src/resources/extensions/gsd/bootstrap/tests/write-gate-basepath.test.ts +103 -0
  162. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +80 -55
  163. package/src/resources/extensions/gsd/commands-codebase.ts +2 -2
  164. package/src/resources/extensions/gsd/commands-handlers.ts +5 -5
  165. package/src/resources/extensions/gsd/commands-logs.ts +2 -2
  166. package/src/resources/extensions/gsd/commands-scan.ts +2 -2
  167. package/src/resources/extensions/gsd/commands-ship.ts +2 -2
  168. package/src/resources/extensions/gsd/commands-workflow-templates.ts +5 -5
  169. package/src/resources/extensions/gsd/db-writer.ts +123 -94
  170. package/src/resources/extensions/gsd/delegation-policy.ts +197 -0
  171. package/src/resources/extensions/gsd/dispatch-guard.ts +6 -11
  172. package/src/resources/extensions/gsd/doctor-engine-checks.ts +2 -2
  173. package/src/resources/extensions/gsd/gsd-db.ts +269 -8
  174. package/src/resources/extensions/gsd/guided-flow-queue.ts +1 -1
  175. package/src/resources/extensions/gsd/guided-flow.ts +181 -32
  176. package/src/resources/extensions/gsd/markdown-renderer.ts +13 -64
  177. package/src/resources/extensions/gsd/metrics.ts +321 -1
  178. package/src/resources/extensions/gsd/parallel-merge.ts +14 -13
  179. package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +5 -2
  180. package/src/resources/extensions/gsd/paths.ts +122 -9
  181. package/src/resources/extensions/gsd/prompts/complete-slice.md +4 -4
  182. package/src/resources/extensions/gsd/prompts/execute-task.md +3 -3
  183. package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +8 -1
  184. package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +22 -7
  185. package/src/resources/extensions/gsd/prompts/guided-discuss-requirements.md +6 -2
  186. package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +8 -1
  187. package/src/resources/extensions/gsd/prompts/plan-milestone.md +6 -0
  188. package/src/resources/extensions/gsd/queue-order.ts +6 -1
  189. package/src/resources/extensions/gsd/rethink.ts +2 -2
  190. package/src/resources/extensions/gsd/state.ts +91 -389
  191. package/src/resources/extensions/gsd/templates/project.md +10 -0
  192. package/src/resources/extensions/gsd/tests/artifact-corruption-2630.test.ts +1 -0
  193. package/src/resources/extensions/gsd/tests/auto-discuss-milestone-deadlock-4973.test.ts +14 -14
  194. package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +6 -0
  195. package/src/resources/extensions/gsd/tests/auto-remediate-slice-status.test.ts +21 -34
  196. package/src/resources/extensions/gsd/tests/auto-session-scope.test.ts +331 -0
  197. package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +176 -0
  198. package/src/resources/extensions/gsd/tests/complete-task-rollback-evidence.test.ts +6 -7
  199. package/src/resources/extensions/gsd/tests/complete-task.test.ts +8 -6
  200. package/src/resources/extensions/gsd/tests/completed-at-reconcile.test.ts +12 -27
  201. package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +18 -5
  202. package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +4 -4
  203. package/src/resources/extensions/gsd/tests/db-writer-path-containment.test.ts +152 -0
  204. package/src/resources/extensions/gsd/tests/db-writer-root-artifact.test.ts +221 -0
  205. package/src/resources/extensions/gsd/tests/db-writer-scope.test.ts +230 -0
  206. package/src/resources/extensions/gsd/tests/db-writer.test.ts +14 -16
  207. package/src/resources/extensions/gsd/tests/delegation-policy.test.ts +151 -0
  208. package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +6 -5
  209. package/src/resources/extensions/gsd/tests/derive-state-db-disk-reconcile.test.ts +10 -38
  210. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +136 -56
  211. package/src/resources/extensions/gsd/tests/derive-state-draft.test.ts +3 -0
  212. package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +119 -61
  213. package/src/resources/extensions/gsd/tests/derive-state.test.ts +4 -0
  214. package/src/resources/extensions/gsd/tests/dispatch-backgroundable-annotation.test.ts +55 -0
  215. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +6 -20
  216. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +4 -5
  217. package/src/resources/extensions/gsd/tests/dispatcher-stuck-planning.test.ts +14 -15
  218. package/src/resources/extensions/gsd/tests/draft-promotion.test.ts +3 -23
  219. package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +11 -16
  220. package/src/resources/extensions/gsd/tests/escalation.test.ts +2 -1
  221. package/src/resources/extensions/gsd/tests/gate-1b-orphan-discrimination.test.ts +193 -0
  222. package/src/resources/extensions/gsd/tests/gate-1b-recovery-bound-corrections.test.ts +246 -0
  223. package/src/resources/extensions/gsd/tests/gate-1b-recovery-bound.test.ts +218 -0
  224. package/src/resources/extensions/gsd/tests/gsd-db-failed-open-restore.test.ts +117 -0
  225. package/src/resources/extensions/gsd/tests/gsd-db-workspace-scope.test.ts +226 -0
  226. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +2 -1
  227. package/src/resources/extensions/gsd/tests/gsd-root-canonical.test.ts +66 -0
  228. package/src/resources/extensions/gsd/tests/gsd-root-home-guard.test.ts +68 -5
  229. package/src/resources/extensions/gsd/tests/gsdroot-worktree-detection.test.ts +15 -36
  230. package/src/resources/extensions/gsd/tests/guided-flow-prompt-consolidation.test.ts +4 -4
  231. package/src/resources/extensions/gsd/tests/handler-worktree-write-isolation.test.ts +57 -0
  232. package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +15 -15
  233. package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +15 -5
  234. package/src/resources/extensions/gsd/tests/integration/workspace-collapse-integration.test.ts +371 -0
  235. package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +14 -8
  236. package/src/resources/extensions/gsd/tests/md-importer.test.ts +2 -1
  237. package/src/resources/extensions/gsd/tests/memory-store.test.ts +3 -2
  238. package/src/resources/extensions/gsd/tests/metrics-atomic-merge.test.ts +222 -0
  239. package/src/resources/extensions/gsd/tests/metrics-lock-hardening.test.ts +400 -0
  240. package/src/resources/extensions/gsd/tests/metrics-lock-not-acquired.test.ts +141 -0
  241. package/src/resources/extensions/gsd/tests/metrics-lock-retry-sleep.test.ts +287 -0
  242. package/src/resources/extensions/gsd/tests/metrics-prune-cache-invalidation.test.ts +149 -0
  243. package/src/resources/extensions/gsd/tests/metrics-scope.test.ts +378 -0
  244. package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +329 -0
  245. package/src/resources/extensions/gsd/tests/park-milestone.test.ts +2 -0
  246. package/src/resources/extensions/gsd/tests/path-cache-decoupled.test.ts +209 -0
  247. package/src/resources/extensions/gsd/tests/path-normalization-unified.test.ts +175 -0
  248. package/src/resources/extensions/gsd/tests/paths-cache.test.ts +170 -0
  249. package/src/resources/extensions/gsd/tests/pending-autostart-scope.test.ts +120 -0
  250. package/src/resources/extensions/gsd/tests/progressive-planning.test.ts +25 -16
  251. package/src/resources/extensions/gsd/tests/projection-regression.test.ts +1 -0
  252. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +150 -7
  253. package/src/resources/extensions/gsd/tests/ready-phrase-no-files-4573.test.ts +184 -0
  254. package/src/resources/extensions/gsd/tests/register-hooks-compaction-checkpoint.test.ts +6 -1
  255. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +28 -16
  256. package/src/resources/extensions/gsd/tests/replan-slice.test.ts +3 -0
  257. package/src/resources/extensions/gsd/tests/resolve-ts.mjs +4 -0
  258. package/src/resources/extensions/gsd/tests/resume-missing-worktree-warning.test.ts +209 -0
  259. package/src/resources/extensions/gsd/tests/rogue-file-detection.test.ts +3 -4
  260. package/src/resources/extensions/gsd/tests/slice-disk-reconcile.test.ts +10 -56
  261. package/src/resources/extensions/gsd/tests/stale-slice-rows.test.ts +15 -16
  262. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +1 -0
  263. package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +23 -27
  264. package/src/resources/extensions/gsd/tests/steer-worktree-path.test.ts +13 -14
  265. package/src/resources/extensions/gsd/tests/stop-auto-remote.test.ts +4 -3
  266. package/src/resources/extensions/gsd/tests/sync-layer-scope.test.ts +453 -0
  267. package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +10 -33
  268. package/src/resources/extensions/gsd/tests/teardown-chdir-failure-clears-registry.test.ts +162 -0
  269. package/src/resources/extensions/gsd/tests/teardown-cleanup-parity.test.ts +102 -0
  270. package/src/resources/extensions/gsd/tests/teardown-failure-clears-registry.test.ts +186 -0
  271. package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +1 -1
  272. package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +7 -8
  273. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +9 -15
  274. package/src/resources/extensions/gsd/tests/validator-scope-parity.test.ts +239 -0
  275. package/src/resources/extensions/gsd/tests/workflow-logger-wiring.test.ts +12 -7
  276. package/src/resources/extensions/gsd/tests/workflow-mcp-auto-prep.test.ts +4 -4
  277. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +26 -3
  278. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +9 -15
  279. package/src/resources/extensions/gsd/tests/workspace.test.ts +190 -0
  280. package/src/resources/extensions/gsd/tests/worktree-db-same-file.test.ts +13 -0
  281. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +65 -71
  282. package/src/resources/extensions/gsd/tests/worktree-sync-tasks.test.ts +26 -151
  283. package/src/resources/extensions/gsd/tests/write-gate-predicates.test.ts +35 -35
  284. package/src/resources/extensions/gsd/tests/write-gate.test.ts +67 -52
  285. package/src/resources/extensions/gsd/tests/write-intercept.test.ts +1 -1
  286. package/src/resources/extensions/gsd/tools/complete-milestone.ts +7 -5
  287. package/src/resources/extensions/gsd/tools/complete-slice.ts +7 -14
  288. package/src/resources/extensions/gsd/tools/complete-task.ts +19 -34
  289. package/src/resources/extensions/gsd/tools/validate-milestone.ts +7 -5
  290. package/src/resources/extensions/gsd/workflow-manifest.ts +4 -1
  291. package/src/resources/extensions/gsd/workflow-mcp-auto-prep.ts +2 -18
  292. package/src/resources/extensions/gsd/workflow-mcp.ts +2 -2
  293. package/src/resources/extensions/gsd/workflow-reconcile.ts +3 -3
  294. package/src/resources/extensions/gsd/workspace.ts +95 -0
  295. package/src/resources/extensions/gsd/worktree-command.ts +4 -3
  296. package/src/resources/extensions/gsd/worktree-resolver.ts +16 -2
  297. package/src/resources/extensions/gsd/write-intercept.ts +3 -3
  298. package/dist/web/standalone/.next/server/chunks/8527.js +0 -1
  299. /package/dist/web/standalone/.next/static/{rk1EN3FQTE6Z1yalkW_GE → AT5qi39nKXkdmQIOIoh0f}/_buildManifest.js +0 -0
  300. /package/dist/web/standalone/.next/static/{rk1EN3FQTE6Z1yalkW_GE → AT5qi39nKXkdmQIOIoh0f}/_ssgManifest.js +0 -0
@@ -136,7 +136,7 @@ function openRawDb(path) {
136
136
  const Database = providerModule;
137
137
  return new Database(path);
138
138
  }
139
- export const SCHEMA_VERSION = 22;
139
+ export const SCHEMA_VERSION = 23;
140
140
  function indexExists(db, name) {
141
141
  return !!db.prepare("SELECT 1 as present FROM sqlite_master WHERE type = 'index' AND name = ?").get(name);
142
142
  }
@@ -299,7 +299,8 @@ function initSchema(db, fileBacked) {
299
299
  verification_uat TEXT NOT NULL DEFAULT '',
300
300
  definition_of_done TEXT NOT NULL DEFAULT '[]',
301
301
  requirement_coverage TEXT NOT NULL DEFAULT '',
302
- boundary_map_markdown TEXT NOT NULL DEFAULT ''
302
+ boundary_map_markdown TEXT NOT NULL DEFAULT '',
303
+ sequence INTEGER DEFAULT 0
303
304
  )
304
305
  `);
305
306
  db.exec(`
@@ -1131,6 +1132,16 @@ function migrateSchema(db) {
1131
1132
  ":applied_at": new Date().toISOString(),
1132
1133
  });
1133
1134
  }
1135
+ if (currentVersion < 23) {
1136
+ // v23: milestone queue ordering moves into the canonical DB. The
1137
+ // historical QUEUE-ORDER.json file remains a projection, but runtime
1138
+ // derivation must not read it as authoritative state.
1139
+ ensureColumn(db, "milestones", "sequence", "ALTER TABLE milestones ADD COLUMN sequence INTEGER DEFAULT 0");
1140
+ db.prepare("INSERT INTO schema_version (version, applied_at) VALUES (:version, :applied_at)").run({
1141
+ ":version": 23,
1142
+ ":applied_at": new Date().toISOString(),
1143
+ });
1144
+ }
1134
1145
  db.exec("COMMIT");
1135
1146
  }
1136
1147
  catch (err) {
@@ -1145,6 +1156,193 @@ let _exitHandlerRegistered = false;
1145
1156
  let _dbOpenAttempted = false;
1146
1157
  let _lastDbError = null;
1147
1158
  let _lastDbPhase = null;
1159
+ /**
1160
+ * Identity key of the workspace whose connection is currently active
1161
+ * (currentDb). Set by openDatabaseByWorkspace(); null when the active
1162
+ * connection was opened via the legacy openDatabase(path) path.
1163
+ */
1164
+ let _currentIdentityKey = null;
1165
+ /**
1166
+ * Workspace-scoped connection cache.
1167
+ * Key: GsdWorkspace.identityKey (realpath-normalized project root).
1168
+ * Value: the DB path and open adapter for that workspace.
1169
+ *
1170
+ * Sibling worktrees of the same project share the same identityKey (set by
1171
+ * createWorkspace) and therefore reuse the same cached connection, preserving
1172
+ * shared-WAL semantics. Different projects get distinct cache entries.
1173
+ *
1174
+ * NOTE: Only one connection is "active" at a time (currentDb/currentPath).
1175
+ * The cache allows fast re-activation of a previously opened connection when
1176
+ * callers switch between known workspaces via openDatabaseByWorkspace().
1177
+ */
1178
+ const _dbCache = new Map();
1179
+ /** Test helper: expose the internal cache for inspection. Not for production use. */
1180
+ export function _getDbCache() {
1181
+ return _dbCache;
1182
+ }
1183
+ /**
1184
+ * Close and evict every entry in the workspace connection cache, then call
1185
+ * closeDatabase() to close the active connection.
1186
+ *
1187
+ * Use this for test teardown or process-shutdown paths where every open
1188
+ * connection must be flushed. Normal callers should use closeDatabase() or
1189
+ * closeDatabaseByWorkspace() instead.
1190
+ */
1191
+ export function closeAllDatabases() {
1192
+ // Close all non-active cached connections first.
1193
+ for (const [key, entry] of _dbCache) {
1194
+ if (entry.db === currentDb)
1195
+ continue; // handled by closeDatabase() below
1196
+ _dbCache.delete(key);
1197
+ try {
1198
+ entry.db.exec("PRAGMA wal_checkpoint(TRUNCATE)");
1199
+ }
1200
+ catch { /* best-effort */ }
1201
+ try {
1202
+ entry.db.exec("PRAGMA incremental_vacuum(64)");
1203
+ }
1204
+ catch { /* best-effort */ }
1205
+ try {
1206
+ entry.db.close();
1207
+ }
1208
+ catch { /* best-effort */ }
1209
+ }
1210
+ closeDatabase();
1211
+ }
1212
+ /**
1213
+ * Open (or reuse) the database connection scoped to the given workspace.
1214
+ *
1215
+ * Uses workspace.identityKey as the cache key, so sibling worktrees of the
1216
+ * same project resolve to the same connection. On a cache hit the existing
1217
+ * adapter is reactivated as the current connection without re-opening the
1218
+ * file. On a cache miss, delegates to openDatabase() for the full
1219
+ * open + schema-init + migration flow, then caches the result.
1220
+ *
1221
+ * When switching to a different workspace, the previously active connection
1222
+ * is preserved in the cache (not closed), so callers can switch back to it
1223
+ * cheaply via a subsequent openDatabaseByWorkspace() call.
1224
+ *
1225
+ * @param workspace A GsdWorkspace created by createWorkspace().
1226
+ * @returns true if the connection is open and ready, false otherwise.
1227
+ */
1228
+ export function openDatabaseByWorkspace(workspace) {
1229
+ const key = workspace.identityKey;
1230
+ const dbPath = workspace.contract.projectDb;
1231
+ const cached = _dbCache.get(key);
1232
+ if (cached) {
1233
+ // Reactivate the cached connection as the current singleton.
1234
+ currentDb = cached.db;
1235
+ currentPath = cached.dbPath;
1236
+ currentPid = process.pid;
1237
+ _dbOpenAttempted = true;
1238
+ _currentIdentityKey = key;
1239
+ return true;
1240
+ }
1241
+ // Cache miss — need to open a new connection.
1242
+ //
1243
+ // If there is a currently active workspace connection, stash it in the
1244
+ // cache under its identity key before calling openDatabase(), because
1245
+ // openDatabase() will call closeDatabase() when the path changes (which
1246
+ // would destroy the existing adapter). By nulling out currentDb first,
1247
+ // we prevent openDatabase() from closing the live adapter.
1248
+ let oldDb = null;
1249
+ let oldPath = null;
1250
+ let oldPid = 0;
1251
+ let oldKey = null;
1252
+ if (currentDb !== null && _currentIdentityKey !== null) {
1253
+ // Snapshot the old globals so we can restore them on failure.
1254
+ oldDb = currentDb;
1255
+ oldPath = currentPath;
1256
+ oldPid = currentPid;
1257
+ oldKey = _currentIdentityKey;
1258
+ // Save the current connection so it stays alive in the cache.
1259
+ _dbCache.set(_currentIdentityKey, {
1260
+ dbPath: currentPath,
1261
+ db: currentDb,
1262
+ });
1263
+ // Detach from globals so openDatabase() opens fresh without closing it.
1264
+ currentDb = null;
1265
+ currentPath = null;
1266
+ currentPid = 0;
1267
+ _currentIdentityKey = null;
1268
+ }
1269
+ // Run the full open/schema/migration flow for the new workspace.
1270
+ // openDatabase() can throw on corrupt DB or permission error — catch so we
1271
+ // can restore the previous connection rather than leaving globals null.
1272
+ let opened;
1273
+ try {
1274
+ opened = openDatabase(dbPath);
1275
+ }
1276
+ catch (err) {
1277
+ // Failed to open the new DB. Restore the previous workspace connection so
1278
+ // the caller's workspace remains active (it is still safe in _dbCache).
1279
+ if (oldDb !== null) {
1280
+ currentDb = oldDb;
1281
+ currentPath = oldPath;
1282
+ currentPid = oldPid;
1283
+ _currentIdentityKey = oldKey;
1284
+ }
1285
+ throw err;
1286
+ }
1287
+ if (opened && currentDb) {
1288
+ _dbCache.set(key, { dbPath, db: currentDb });
1289
+ _currentIdentityKey = key;
1290
+ }
1291
+ else if (!opened && oldDb !== null) {
1292
+ // Restore the previous connection so the caller's workspace remains active.
1293
+ // The failed attempt left no live adapter, so the globals stayed null.
1294
+ currentDb = oldDb;
1295
+ currentPath = oldPath;
1296
+ currentPid = oldPid;
1297
+ _currentIdentityKey = oldKey;
1298
+ }
1299
+ return opened;
1300
+ }
1301
+ /**
1302
+ * Open (or reuse) the database connection scoped to the workspace in a
1303
+ * MilestoneScope. Thin delegation to openDatabaseByWorkspace().
1304
+ */
1305
+ export function openDatabaseByScope(scope) {
1306
+ return openDatabaseByWorkspace(scope.workspace);
1307
+ }
1308
+ /**
1309
+ * Close the database connection for the given workspace and remove it from
1310
+ * the cache. If the workspace's connection is currently active (currentDb),
1311
+ * performs a full closeDatabase() including WAL checkpoint. Otherwise only
1312
+ * removes the cache entry (the adapter was already replaced by a later open).
1313
+ */
1314
+ export function closeDatabaseByWorkspace(workspace) {
1315
+ const key = workspace.identityKey;
1316
+ const cached = _dbCache.get(key);
1317
+ if (!cached)
1318
+ return;
1319
+ _dbCache.delete(key);
1320
+ if (currentDb === cached.db) {
1321
+ // This workspace's connection is the active one — full close.
1322
+ closeDatabase();
1323
+ }
1324
+ else {
1325
+ // Connection was displaced by a later open; close the adapter directly.
1326
+ try {
1327
+ cached.db.exec("PRAGMA wal_checkpoint(TRUNCATE)");
1328
+ }
1329
+ catch (e) {
1330
+ logWarning("db", `WAL checkpoint (byWorkspace) failed: ${e.message}`);
1331
+ }
1332
+ try {
1333
+ cached.db.exec("PRAGMA incremental_vacuum(64)");
1334
+ }
1335
+ catch (e) {
1336
+ logWarning("db", `incremental vacuum (byWorkspace) failed: ${e.message}`);
1337
+ }
1338
+ try {
1339
+ cached.db.close();
1340
+ }
1341
+ catch (e) {
1342
+ logWarning("db", `database close (byWorkspace) failed: ${e.message}`);
1343
+ }
1344
+ }
1345
+ }
1148
1346
  export function getDbProvider() {
1149
1347
  loadProvider();
1150
1348
  return providerName;
@@ -1289,6 +1487,13 @@ export function closeDatabase() {
1289
1487
  catch (e) {
1290
1488
  logWarning("db", `database close failed: ${e.message}`);
1291
1489
  }
1490
+ // If this connection was workspace-tracked, evict it from the cache so
1491
+ // subsequent openDatabaseByWorkspace() calls re-open rather than reactivate
1492
+ // a closed adapter.
1493
+ if (_currentIdentityKey !== null) {
1494
+ _dbCache.delete(_currentIdentityKey);
1495
+ _currentIdentityKey = null;
1496
+ }
1292
1497
  currentDb = null;
1293
1498
  currentPath = null;
1294
1499
  currentPid = 0;
@@ -1518,6 +1723,31 @@ export function getActiveRequirements() {
1518
1723
  superseded_by: null,
1519
1724
  }));
1520
1725
  }
1726
+ export function getRequirementCounts() {
1727
+ if (!currentDb) {
1728
+ return { active: 0, validated: 0, deferred: 0, outOfScope: 0, blocked: 0, total: 0 };
1729
+ }
1730
+ const rows = currentDb
1731
+ .prepare("SELECT lower(status) as status, COUNT(*) as count FROM requirements GROUP BY lower(status)")
1732
+ .all();
1733
+ const counts = { active: 0, validated: 0, deferred: 0, outOfScope: 0, blocked: 0, total: 0 };
1734
+ for (const row of rows) {
1735
+ const status = String(row["status"] ?? "");
1736
+ const count = Number(row["count"] ?? 0);
1737
+ counts.total += count;
1738
+ if (status === "active")
1739
+ counts.active += count;
1740
+ else if (status === "validated")
1741
+ counts.validated += count;
1742
+ else if (status === "deferred")
1743
+ counts.deferred += count;
1744
+ else if (status === "out-of-scope" || status === "out_of_scope")
1745
+ counts.outOfScope += count;
1746
+ else if (status === "blocked")
1747
+ counts.blocked += count;
1748
+ }
1749
+ return counts;
1750
+ }
1521
1751
  export function getDbOwnerPid() {
1522
1752
  return currentPid;
1523
1753
  }
@@ -2164,6 +2394,7 @@ function rowToMilestone(row) {
2164
2394
  definition_of_done: JSON.parse(row["definition_of_done"] || "[]"),
2165
2395
  requirement_coverage: row["requirement_coverage"] ?? "",
2166
2396
  boundary_map_markdown: row["boundary_map_markdown"] ?? "",
2397
+ sequence: Number(row["sequence"] ?? 0),
2167
2398
  };
2168
2399
  }
2169
2400
  function rowToArtifact(row) {
@@ -2180,7 +2411,7 @@ function rowToArtifact(row) {
2180
2411
  export function getAllMilestones() {
2181
2412
  if (!currentDb)
2182
2413
  return [];
2183
- const rows = currentDb.prepare("SELECT * FROM milestones ORDER BY id").all();
2414
+ const rows = currentDb.prepare("SELECT * FROM milestones ORDER BY CASE WHEN sequence > 0 THEN 0 ELSE 1 END, sequence, id").all();
2184
2415
  return rows.map(rowToMilestone);
2185
2416
  }
2186
2417
  export function getMilestone(id) {
@@ -2191,6 +2422,23 @@ export function getMilestone(id) {
2191
2422
  return null;
2192
2423
  return rowToMilestone(row);
2193
2424
  }
2425
+ export function setMilestoneQueueOrder(order) {
2426
+ if (!currentDb)
2427
+ throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
2428
+ currentDb.exec("BEGIN IMMEDIATE");
2429
+ try {
2430
+ currentDb.prepare("UPDATE milestones SET sequence = 0").run();
2431
+ const stmt = currentDb.prepare("UPDATE milestones SET sequence = :sequence WHERE id = :id");
2432
+ order.forEach((id, index) => {
2433
+ stmt.run({ ":id": id, ":sequence": index + 1 });
2434
+ });
2435
+ currentDb.exec("COMMIT");
2436
+ }
2437
+ catch (err) {
2438
+ currentDb.exec("ROLLBACK");
2439
+ throw err;
2440
+ }
2441
+ }
2194
2442
  /**
2195
2443
  * Update a milestone's status in the database.
2196
2444
  * Used by park/unpark to keep the DB in sync with the filesystem marker.
@@ -2358,6 +2606,8 @@ export function reconcileWorktreeDb(mainDbPath, worktreeDbPath) {
2358
2606
  // fall through to the main DB's existing value (not a literal default)
2359
2607
  // so reconcile never silently clears state the main tree has recorded.
2360
2608
  const hasDecisionSource = wtInfo.some((col) => col["name"] === "source");
2609
+ const wtMilestoneInfo = adapter.prepare("PRAGMA wt.table_info('milestones')").all();
2610
+ const hasMilestoneSequence = wtMilestoneInfo.some((col) => col["name"] === "sequence");
2361
2611
  const wtSliceInfo = adapter.prepare("PRAGMA wt.table_info('slices')").all();
2362
2612
  const hasIsSketch = wtSliceInfo.some((col) => col["name"] === "is_sketch");
2363
2613
  const hasSketchScope = wtSliceInfo.some((col) => col["name"] === "sketch_scope");
@@ -2415,7 +2665,7 @@ export function reconcileWorktreeDb(mainDbPath, worktreeDbPath) {
2415
2665
  id, title, status, depends_on, created_at, completed_at,
2416
2666
  vision, success_criteria, key_risks, proof_strategy,
2417
2667
  verification_contract, verification_integration, verification_operational, verification_uat,
2418
- definition_of_done, requirement_coverage, boundary_map_markdown
2668
+ definition_of_done, requirement_coverage, boundary_map_markdown, sequence
2419
2669
  )
2420
2670
  SELECT w.id, w.title,
2421
2671
  CASE
@@ -2433,7 +2683,8 @@ export function reconcileWorktreeDb(mainDbPath, worktreeDbPath) {
2433
2683
  END,
2434
2684
  w.vision, w.success_criteria, w.key_risks, w.proof_strategy,
2435
2685
  w.verification_contract, w.verification_integration, w.verification_operational, w.verification_uat,
2436
- w.definition_of_done, w.requirement_coverage, w.boundary_map_markdown
2686
+ w.definition_of_done, w.requirement_coverage, w.boundary_map_markdown,
2687
+ ${hasMilestoneSequence ? "COALESCE(w.sequence, 0)" : "COALESCE(m.sequence, 0)"}
2437
2688
  FROM wt.milestones w
2438
2689
  LEFT JOIN milestones m ON m.id = w.id
2439
2690
  `).run());
@@ -2659,6 +2910,15 @@ export function getAssessment(path) {
2659
2910
  const row = currentDb.prepare(`SELECT * FROM assessments WHERE path = :path`).get({ ":path": path });
2660
2911
  return row ?? null;
2661
2912
  }
2913
+ export function getLatestAssessmentByScope(milestoneId, scope) {
2914
+ if (!currentDb)
2915
+ return null;
2916
+ const row = currentDb.prepare(`SELECT * FROM assessments
2917
+ WHERE milestone_id = :mid AND scope = :scope
2918
+ ORDER BY created_at DESC
2919
+ LIMIT 1`).get({ ":mid": milestoneId, ":scope": scope });
2920
+ return row ?? null;
2921
+ }
2662
2922
  // ─── Quality Gates ───────────────────────────────────────────────────────
2663
2923
  function rowToGate(row) {
2664
2924
  return {
@@ -3027,10 +3287,10 @@ export function restoreManifest(manifest) {
3027
3287
  const msStmt = db.prepare(`INSERT INTO milestones (id, title, status, depends_on, created_at, completed_at,
3028
3288
  vision, success_criteria, key_risks, proof_strategy,
3029
3289
  verification_contract, verification_integration, verification_operational, verification_uat,
3030
- definition_of_done, requirement_coverage, boundary_map_markdown)
3031
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`);
3290
+ definition_of_done, requirement_coverage, boundary_map_markdown, sequence)
3291
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`);
3032
3292
  for (const m of manifest.milestones) {
3033
- msStmt.run(m.id, m.title, m.status, JSON.stringify(m.depends_on), m.created_at, m.completed_at, m.vision, JSON.stringify(m.success_criteria), JSON.stringify(m.key_risks), JSON.stringify(m.proof_strategy), m.verification_contract, m.verification_integration, m.verification_operational, m.verification_uat, JSON.stringify(m.definition_of_done), m.requirement_coverage, m.boundary_map_markdown);
3293
+ msStmt.run(m.id, m.title, m.status, JSON.stringify(m.depends_on), m.created_at, m.completed_at, m.vision, JSON.stringify(m.success_criteria), JSON.stringify(m.key_risks), JSON.stringify(m.proof_strategy), m.verification_contract, m.verification_integration, m.verification_operational, m.verification_uat, JSON.stringify(m.definition_of_done), m.requirement_coverage, m.boundary_map_markdown, m.sequence ?? 0);
3034
3294
  }
3035
3295
  // Restore slices (ADR-011 Phase 1: includes is_sketch + sketch_scope)
3036
3296
  const slStmt = db.prepare(`INSERT INTO slices (milestone_id, id, title, status, risk, depends, demo,
@@ -150,7 +150,7 @@ export async function showQueueAdd(ctx, pi, basePath, state) {
150
150
  ].join(" ");
151
151
  // ── Dispatch the queue prompt ───────────────────────────────────────
152
152
  // Activate the queue phase so the write-gate applies to CONTEXT.md writes
153
- setQueuePhaseActive(true);
153
+ setQueuePhaseActive(true, basePath);
154
154
  const queueInlinedTemplates = inlineTemplate("context", "Context");
155
155
  const prompt = loadPrompt("queue", {
156
156
  preamble,