@opengsd/gsd-pi 1.2.0-dev.e8563f58 → 1.2.0-dev.fbdca60b

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 (432) hide show
  1. package/dist/cli-model-override.d.ts +15 -0
  2. package/dist/cli-model-override.js +21 -0
  3. package/dist/cli.js +1 -18
  4. package/dist/loader.js +6 -4
  5. package/dist/register-agent-bundles.d.ts +11 -2
  6. package/dist/register-agent-bundles.js +18 -4
  7. package/dist/resource-loader.d.ts +10 -5
  8. package/dist/resource-loader.js +121 -6
  9. package/dist/resources/.managed-resources-content-hash +1 -1
  10. package/dist/resources/extensions/ask-user-questions.js +3 -2
  11. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +447 -215
  12. package/dist/resources/extensions/claude-code-cli/turn-assembler.js +33 -1
  13. package/dist/resources/extensions/gsd/auto/closeout.js +215 -0
  14. package/dist/resources/extensions/gsd/auto/dispatch-history.js +21 -6
  15. package/dist/resources/extensions/gsd/auto/dispatch.js +365 -0
  16. package/dist/resources/extensions/gsd/auto/finalize.js +347 -0
  17. package/dist/resources/extensions/gsd/auto/loop.js +4 -1
  18. package/dist/resources/extensions/gsd/auto/milestone-lease-reclaim.js +56 -0
  19. package/dist/resources/extensions/gsd/auto/orchestrator.js +85 -15
  20. package/dist/resources/extensions/gsd/auto/phase-helpers.js +146 -0
  21. package/dist/resources/extensions/gsd/auto/phases.js +17 -2329
  22. package/dist/resources/extensions/gsd/auto/pre-dispatch.js +534 -0
  23. package/dist/resources/extensions/gsd/auto/session.js +3 -0
  24. package/dist/resources/extensions/gsd/auto/unit-phase.js +694 -0
  25. package/dist/resources/extensions/gsd/auto/workflow-unit-dispatch.js +1 -1
  26. package/dist/resources/extensions/gsd/auto/worktree-safety-phase.js +125 -0
  27. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +3 -2
  28. package/dist/resources/extensions/gsd/auto-dispatch.js +11 -2
  29. package/dist/resources/extensions/gsd/auto-post-unit.js +18 -6
  30. package/dist/resources/extensions/gsd/auto-start.js +23 -3
  31. package/dist/resources/extensions/gsd/auto-unit-closeout.js +45 -21
  32. package/dist/resources/extensions/gsd/auto-verification.js +14 -2
  33. package/dist/resources/extensions/gsd/auto-worktree.js +15 -2
  34. package/dist/resources/extensions/gsd/auto.js +45 -2
  35. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +37 -7
  36. package/dist/resources/extensions/gsd/commands/context.js +16 -2
  37. package/dist/resources/extensions/gsd/commands-mcp-status.js +2 -2
  38. package/dist/resources/extensions/gsd/commands-workflow-templates.js +9 -2
  39. package/dist/resources/extensions/gsd/crash-recovery.js +8 -3
  40. package/dist/resources/extensions/gsd/db/engine.js +24 -6
  41. package/dist/resources/extensions/gsd/db/queries.js +30 -0
  42. package/dist/resources/extensions/gsd/db-migration-backup.js +51 -8
  43. package/dist/resources/extensions/gsd/db-transaction.js +27 -23
  44. package/dist/resources/extensions/gsd/db-writer.js +8 -17
  45. package/dist/resources/extensions/gsd/doctor-engine-checks.js +5 -5
  46. package/dist/resources/extensions/gsd/doctor-environment.js +256 -125
  47. package/dist/resources/extensions/gsd/gsd-db.js +15 -20
  48. package/dist/resources/extensions/gsd/guided-flow.js +93 -4
  49. package/dist/resources/extensions/gsd/health-widget.js +87 -28
  50. package/dist/resources/extensions/gsd/mcp-bridge.js +10 -0
  51. package/dist/resources/extensions/gsd/memory-relations.js +1 -1
  52. package/dist/resources/extensions/gsd/milestone-planning-persistence.js +2 -2
  53. package/dist/resources/extensions/gsd/milestone-reopen-events.js +3 -5
  54. package/dist/resources/extensions/gsd/milestone-settlement.js +2 -2
  55. package/dist/resources/extensions/gsd/notifications.js +12 -7
  56. package/dist/resources/extensions/gsd/projection-flush.js +7 -0
  57. package/dist/resources/extensions/gsd/prompts/complete-slice.md +2 -2
  58. package/dist/resources/extensions/gsd/prompts/execute-task.md +3 -2
  59. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  60. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  61. package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -1
  62. package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
  63. package/dist/resources/extensions/gsd/prompts/refine-slice.md +1 -1
  64. package/dist/resources/extensions/gsd/prompts/replan-slice.md +1 -1
  65. package/dist/resources/extensions/gsd/prompts/research-milestone.md +1 -1
  66. package/dist/resources/extensions/gsd/prompts/research-slice.md +1 -1
  67. package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  68. package/dist/resources/extensions/gsd/prompts/run-uat.md +3 -1
  69. package/dist/resources/extensions/gsd/prompts/triage-captures.md +1 -1
  70. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +1 -1
  71. package/dist/resources/extensions/gsd/prompts/workflow-start.md +2 -1
  72. package/dist/resources/extensions/gsd/roadmap-slices.js +25 -3
  73. package/dist/resources/extensions/gsd/session-lock.js +1 -1
  74. package/dist/resources/extensions/gsd/skill-activation.js +3 -6
  75. package/dist/resources/extensions/gsd/state.js +6 -2
  76. package/dist/resources/extensions/gsd/tool-contract.js +14 -3
  77. package/dist/resources/extensions/gsd/tool-surface-readiness.js +83 -31
  78. package/dist/resources/extensions/gsd/tools/complete-milestone.js +3 -2
  79. package/dist/resources/extensions/gsd/tools/complete-slice.js +2 -2
  80. package/dist/resources/extensions/gsd/tools/complete-task.js +65 -2
  81. package/dist/resources/extensions/gsd/tools/plan-slice.js +2 -2
  82. package/dist/resources/extensions/gsd/tools/plan-task.js +2 -2
  83. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +2 -2
  84. package/dist/resources/extensions/gsd/tools/reopen-milestone.js +2 -2
  85. package/dist/resources/extensions/gsd/tools/reopen-slice.js +2 -2
  86. package/dist/resources/extensions/gsd/tools/reopen-task.js +2 -2
  87. package/dist/resources/extensions/gsd/tools/replan-slice.js +2 -2
  88. package/dist/resources/extensions/gsd/unit-context-composer.js +1 -1
  89. package/dist/resources/extensions/gsd/unit-registry.js +34 -4
  90. package/dist/resources/extensions/gsd/verification-verdict.js +2 -1
  91. package/dist/resources/extensions/gsd/workflow-event-ledger.js +91 -0
  92. package/dist/resources/extensions/gsd/workflow-event-vocabulary.js +46 -0
  93. package/dist/resources/extensions/gsd/workflow-events.js +6 -18
  94. package/dist/resources/extensions/gsd/workflow-mcp-auto-prep.js +2 -0
  95. package/dist/resources/extensions/gsd/workflow-mcp-readiness-cache.js +105 -0
  96. package/dist/resources/extensions/gsd/workflow-reconcile.js +21 -56
  97. package/dist/resources/extensions/gsd/worktree-manager.js +7 -1
  98. package/dist/resources/extensions/gsd/worktree-safety.js +28 -26
  99. package/dist/resources/extensions/gsd/worktree.js +8 -1
  100. package/dist/resources/extensions/mcp-client/manager.js +6 -1
  101. package/dist/resources/skills/create-skill/SKILL.md +3 -0
  102. package/dist/resources/skills/create-skill/references/skill-structure.md +1 -0
  103. package/dist/runtime-checks.d.ts +10 -0
  104. package/dist/runtime-checks.js +27 -0
  105. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  106. package/dist/web/standalone/.next/BUILD_ID +1 -1
  107. package/dist/web/standalone/.next/app-path-routes-manifest.json +7 -7
  108. package/dist/web/standalone/.next/build-manifest.json +2 -2
  109. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  110. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  111. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  112. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  113. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  114. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  115. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  116. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  117. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  118. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  119. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  120. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  121. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  122. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  123. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  124. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  125. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  126. package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
  127. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
  128. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
  129. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
  130. package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
  131. package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
  132. package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
  133. package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
  134. package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  135. package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
  136. package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  137. package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
  138. package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
  139. package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
  140. package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
  141. package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
  142. package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js.nft.json +1 -1
  143. package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
  144. package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
  145. package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  146. package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
  147. package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
  148. package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
  149. package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
  150. package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
  151. package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
  152. package/dist/web/standalone/.next/server/app/api/shutdown/route.js.nft.json +1 -1
  153. package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
  154. package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
  155. package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
  156. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
  157. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
  158. package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
  159. package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
  160. package/dist/web/standalone/.next/server/app/index.html +1 -1
  161. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  162. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  163. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  164. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  165. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  166. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  167. package/dist/web/standalone/.next/server/app-paths-manifest.json +7 -7
  168. package/dist/web/standalone/.next/server/chunks/{5942.js → 1128.js} +1 -1
  169. package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
  170. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  171. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  172. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  173. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  174. package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
  175. package/package.json +3 -3
  176. package/packages/cloud-mcp-gateway/package.json +2 -2
  177. package/packages/contracts/package.json +1 -1
  178. package/packages/daemon/package.json +4 -4
  179. package/packages/gsd-agent-core/dist/sdk.d.ts.map +1 -1
  180. package/packages/gsd-agent-core/dist/sdk.js +6 -4
  181. package/packages/gsd-agent-core/dist/sdk.js.map +1 -1
  182. package/packages/gsd-agent-core/package.json +5 -5
  183. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts +2 -0
  184. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  185. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js +10 -0
  186. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js.map +1 -1
  187. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +8 -0
  188. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  189. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +50 -6
  190. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  191. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts +2 -0
  192. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts.map +1 -1
  193. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js +34 -5
  194. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js.map +1 -1
  195. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts +1 -0
  196. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  197. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +17 -0
  198. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
  199. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.d.ts.map +1 -1
  200. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js +4 -0
  201. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js.map +1 -1
  202. package/packages/gsd-agent-modes/package.json +7 -7
  203. package/packages/mcp-server/README.md +12 -3
  204. package/packages/mcp-server/dist/cli-runner.d.ts +40 -0
  205. package/packages/mcp-server/dist/cli-runner.d.ts.map +1 -0
  206. package/packages/mcp-server/dist/cli-runner.js +137 -0
  207. package/packages/mcp-server/dist/cli-runner.js.map +1 -0
  208. package/packages/mcp-server/dist/cli.js +2 -53
  209. package/packages/mcp-server/dist/cli.js.map +1 -1
  210. package/packages/mcp-server/dist/pid-registry.d.ts +46 -0
  211. package/packages/mcp-server/dist/pid-registry.d.ts.map +1 -0
  212. package/packages/mcp-server/dist/pid-registry.js +459 -0
  213. package/packages/mcp-server/dist/pid-registry.js.map +1 -0
  214. package/packages/mcp-server/dist/probe-mode.d.ts +4 -0
  215. package/packages/mcp-server/dist/probe-mode.d.ts.map +1 -0
  216. package/packages/mcp-server/dist/probe-mode.js +10 -0
  217. package/packages/mcp-server/dist/probe-mode.js.map +1 -0
  218. package/packages/mcp-server/dist/stdio-watchdog.d.ts +8 -0
  219. package/packages/mcp-server/dist/stdio-watchdog.d.ts.map +1 -0
  220. package/packages/mcp-server/dist/stdio-watchdog.js +40 -0
  221. package/packages/mcp-server/dist/stdio-watchdog.js.map +1 -0
  222. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  223. package/packages/mcp-server/dist/workflow-tools.js +62 -43
  224. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  225. package/packages/mcp-server/package.json +5 -5
  226. package/packages/native/package.json +1 -1
  227. package/packages/pi-agent-core/dist/agent-loop.js +43 -2
  228. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  229. package/packages/pi-agent-core/package.json +1 -1
  230. package/packages/pi-ai/package.json +1 -1
  231. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +3 -0
  232. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  233. package/packages/pi-coding-agent/dist/core/settings-manager.js +11 -0
  234. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  235. package/packages/pi-coding-agent/dist/theme/theme.d.ts.map +1 -1
  236. package/packages/pi-coding-agent/dist/theme/theme.js +45 -17
  237. package/packages/pi-coding-agent/dist/theme/theme.js.map +1 -1
  238. package/packages/pi-coding-agent/package.json +7 -7
  239. package/packages/pi-tui/README.md +15 -0
  240. package/packages/pi-tui/dist/index.d.ts +2 -2
  241. package/packages/pi-tui/dist/index.d.ts.map +1 -1
  242. package/packages/pi-tui/dist/index.js +2 -2
  243. package/packages/pi-tui/dist/index.js.map +1 -1
  244. package/packages/pi-tui/dist/terminal-image.d.ts +33 -0
  245. package/packages/pi-tui/dist/terminal-image.d.ts.map +1 -1
  246. package/packages/pi-tui/dist/terminal-image.js +54 -2
  247. package/packages/pi-tui/dist/terminal-image.js.map +1 -1
  248. package/packages/pi-tui/dist/terminal.d.ts +12 -0
  249. package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
  250. package/packages/pi-tui/dist/terminal.js +70 -25
  251. package/packages/pi-tui/dist/terminal.js.map +1 -1
  252. package/packages/pi-tui/dist/tui.d.ts +15 -0
  253. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  254. package/packages/pi-tui/dist/tui.js +106 -21
  255. package/packages/pi-tui/dist/tui.js.map +1 -1
  256. package/packages/pi-tui/dist/utils.d.ts.map +1 -1
  257. package/packages/pi-tui/dist/utils.js +110 -36
  258. package/packages/pi-tui/dist/utils.js.map +1 -1
  259. package/packages/pi-tui/package.json +2 -2
  260. package/packages/rpc-client/package.json +2 -2
  261. package/pkg/dist/theme/theme.d.ts.map +1 -1
  262. package/pkg/dist/theme/theme.js +45 -17
  263. package/pkg/dist/theme/theme.js.map +1 -1
  264. package/pkg/package.json +1 -1
  265. package/src/resources/extensions/ask-user-questions.ts +7 -2
  266. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +531 -226
  267. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +672 -7
  268. package/src/resources/extensions/claude-code-cli/turn-assembler.ts +38 -1
  269. package/src/resources/extensions/gsd/auto/closeout.ts +309 -0
  270. package/src/resources/extensions/gsd/auto/dispatch-history.ts +22 -6
  271. package/src/resources/extensions/gsd/auto/dispatch.ts +449 -0
  272. package/src/resources/extensions/gsd/auto/finalize.ts +445 -0
  273. package/src/resources/extensions/gsd/auto/loop.ts +4 -1
  274. package/src/resources/extensions/gsd/auto/milestone-lease-reclaim.ts +74 -0
  275. package/src/resources/extensions/gsd/auto/orchestrator.ts +95 -15
  276. package/src/resources/extensions/gsd/auto/phase-helpers.ts +199 -0
  277. package/src/resources/extensions/gsd/auto/phases.ts +58 -3022
  278. package/src/resources/extensions/gsd/auto/pre-dispatch.ts +704 -0
  279. package/src/resources/extensions/gsd/auto/session.ts +3 -0
  280. package/src/resources/extensions/gsd/auto/unit-phase.ts +910 -0
  281. package/src/resources/extensions/gsd/auto/workflow-unit-dispatch.ts +1 -1
  282. package/src/resources/extensions/gsd/auto/worktree-safety-phase.ts +149 -0
  283. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +10 -16
  284. package/src/resources/extensions/gsd/auto-dispatch.ts +11 -10
  285. package/src/resources/extensions/gsd/auto-post-unit.ts +21 -6
  286. package/src/resources/extensions/gsd/auto-start.ts +24 -4
  287. package/src/resources/extensions/gsd/auto-unit-closeout.ts +83 -28
  288. package/src/resources/extensions/gsd/auto-verification.ts +18 -2
  289. package/src/resources/extensions/gsd/auto-worktree.ts +15 -2
  290. package/src/resources/extensions/gsd/auto.ts +56 -2
  291. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +56 -6
  292. package/src/resources/extensions/gsd/commands/context.ts +16 -2
  293. package/src/resources/extensions/gsd/commands-mcp-status.ts +2 -2
  294. package/src/resources/extensions/gsd/commands-workflow-templates.ts +11 -4
  295. package/src/resources/extensions/gsd/crash-recovery.ts +10 -2
  296. package/src/resources/extensions/gsd/db/engine.ts +26 -6
  297. package/src/resources/extensions/gsd/db/queries.ts +29 -0
  298. package/src/resources/extensions/gsd/db-migration-backup.ts +56 -7
  299. package/src/resources/extensions/gsd/db-transaction.ts +37 -20
  300. package/src/resources/extensions/gsd/db-writer.ts +11 -19
  301. package/src/resources/extensions/gsd/doctor-engine-checks.ts +5 -4
  302. package/src/resources/extensions/gsd/doctor-environment.ts +267 -142
  303. package/src/resources/extensions/gsd/gsd-db.ts +15 -19
  304. package/src/resources/extensions/gsd/guided-flow.ts +145 -24
  305. package/src/resources/extensions/gsd/health-widget.ts +91 -27
  306. package/src/resources/extensions/gsd/mcp-bridge.ts +39 -0
  307. package/src/resources/extensions/gsd/memory-relations.ts +1 -1
  308. package/src/resources/extensions/gsd/milestone-planning-persistence.ts +2 -2
  309. package/src/resources/extensions/gsd/milestone-reopen-events.ts +3 -6
  310. package/src/resources/extensions/gsd/milestone-settlement.ts +2 -2
  311. package/src/resources/extensions/gsd/notifications.ts +13 -6
  312. package/src/resources/extensions/gsd/projection-flush.ts +20 -0
  313. package/src/resources/extensions/gsd/prompts/complete-slice.md +2 -2
  314. package/src/resources/extensions/gsd/prompts/execute-task.md +3 -2
  315. package/src/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  316. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  317. package/src/resources/extensions/gsd/prompts/quick-task.md +1 -1
  318. package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
  319. package/src/resources/extensions/gsd/prompts/refine-slice.md +1 -1
  320. package/src/resources/extensions/gsd/prompts/replan-slice.md +1 -1
  321. package/src/resources/extensions/gsd/prompts/research-milestone.md +1 -1
  322. package/src/resources/extensions/gsd/prompts/research-slice.md +1 -1
  323. package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  324. package/src/resources/extensions/gsd/prompts/run-uat.md +3 -1
  325. package/src/resources/extensions/gsd/prompts/triage-captures.md +1 -1
  326. package/src/resources/extensions/gsd/prompts/validate-milestone.md +1 -1
  327. package/src/resources/extensions/gsd/prompts/workflow-start.md +2 -1
  328. package/src/resources/extensions/gsd/roadmap-slices.ts +28 -3
  329. package/src/resources/extensions/gsd/session-lock.ts +1 -1
  330. package/src/resources/extensions/gsd/skill-activation.ts +3 -6
  331. package/src/resources/extensions/gsd/state.ts +7 -1
  332. package/src/resources/extensions/gsd/tests/auto-abort-pause-regression.test.ts +1 -1
  333. package/src/resources/extensions/gsd/tests/auto-blocked-remediation-message.test.ts +1 -1
  334. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +206 -22
  335. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +6 -1
  336. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +76 -12
  337. package/src/resources/extensions/gsd/tests/auto-pause-double-entry-guard.test.ts +1 -1
  338. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +77 -1
  339. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +2 -1
  340. package/src/resources/extensions/gsd/tests/auto-remote-session-lock-cleanup.test.ts +65 -3
  341. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +236 -0
  342. package/src/resources/extensions/gsd/tests/auto-unit-closeout.test.ts +169 -1
  343. package/src/resources/extensions/gsd/tests/complete-task.test.ts +141 -5
  344. package/src/resources/extensions/gsd/tests/db-migration-backup.test.ts +68 -19
  345. package/src/resources/extensions/gsd/tests/db-transaction.test.ts +59 -0
  346. package/src/resources/extensions/gsd/tests/db-writer.test.ts +15 -4
  347. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +2 -1
  348. package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +62 -0
  349. package/src/resources/extensions/gsd/tests/discuss-routing-fixes.test.ts +12 -2
  350. package/src/resources/extensions/gsd/tests/dispatch-history.test.ts +55 -0
  351. package/src/resources/extensions/gsd/tests/dist-redirect.mjs +8 -0
  352. package/src/resources/extensions/gsd/tests/engine-interfaces-contract.test.ts +117 -91
  353. package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +113 -0
  354. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +19 -0
  355. package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +18 -6
  356. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +15 -0
  357. package/src/resources/extensions/gsd/tests/integration/doctor-environment-async.test.ts +104 -0
  358. package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +18 -0
  359. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +47 -16
  360. package/src/resources/extensions/gsd/tests/mcp-readiness-preflight.test.ts +205 -0
  361. package/src/resources/extensions/gsd/tests/mcp-status.test.ts +6 -5
  362. package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +1 -1
  363. package/src/resources/extensions/gsd/tests/milestone-report-path.test.ts +1 -1
  364. package/src/resources/extensions/gsd/tests/milestone-settlement.test.ts +92 -0
  365. package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +1 -1
  366. package/src/resources/extensions/gsd/tests/notifications.test.ts +64 -9
  367. package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +2 -2
  368. package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +5 -0
  369. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +1 -1
  370. package/src/resources/extensions/gsd/tests/phases-terminal-complete-idempotent.test.ts +242 -0
  371. package/src/resources/extensions/gsd/tests/plan-gate-failed-doctor-heal-hint.test.ts +3 -3
  372. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +63 -2
  373. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +10 -2
  374. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +2 -4
  375. package/src/resources/extensions/gsd/tests/remote-notification-from-desktop.test.ts +31 -81
  376. package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +68 -0
  377. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +26 -2
  378. package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +170 -48
  379. package/src/resources/extensions/gsd/tests/skill-activation.test.ts +20 -17
  380. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +7 -3
  381. package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +1 -1
  382. package/src/resources/extensions/gsd/tests/teardown-chdir-failure-clears-registry.test.ts +17 -0
  383. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +4 -2
  384. package/src/resources/extensions/gsd/tests/tool-surface-readiness.test.ts +184 -10
  385. package/src/resources/extensions/gsd/tests/tool-unavailable-retry.test.ts +33 -0
  386. package/src/resources/extensions/gsd/tests/transport-gate-double-complete.test.ts +139 -0
  387. package/src/resources/extensions/gsd/tests/uok-audit-unified.test.ts +8 -0
  388. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +1 -1
  389. package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +2 -0
  390. package/src/resources/extensions/gsd/tests/workflow-events.test.ts +19 -0
  391. package/src/resources/extensions/gsd/tests/workflow-mcp-readiness-cache.test.ts +119 -0
  392. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +65 -2
  393. package/src/resources/extensions/gsd/tests/workflow-phase-contract-matrix.test.ts +332 -0
  394. package/src/resources/extensions/gsd/tests/workflow-reconcile.test.ts +20 -0
  395. package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +92 -0
  396. package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +1 -1
  397. package/src/resources/extensions/gsd/tests/worktree-project-root-degrade.test.ts +1 -1
  398. package/src/resources/extensions/gsd/tests/worktree-safety-phase.test.ts +100 -0
  399. package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +72 -0
  400. package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +22 -0
  401. package/src/resources/extensions/gsd/tests/worktree.test.ts +18 -0
  402. package/src/resources/extensions/gsd/tool-contract.ts +38 -3
  403. package/src/resources/extensions/gsd/tool-surface-readiness.ts +126 -19
  404. package/src/resources/extensions/gsd/tools/complete-milestone.ts +3 -2
  405. package/src/resources/extensions/gsd/tools/complete-slice.ts +2 -2
  406. package/src/resources/extensions/gsd/tools/complete-task.ts +90 -2
  407. package/src/resources/extensions/gsd/tools/plan-slice.ts +2 -2
  408. package/src/resources/extensions/gsd/tools/plan-task.ts +2 -2
  409. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +2 -2
  410. package/src/resources/extensions/gsd/tools/reopen-milestone.ts +2 -2
  411. package/src/resources/extensions/gsd/tools/reopen-slice.ts +2 -2
  412. package/src/resources/extensions/gsd/tools/reopen-task.ts +2 -2
  413. package/src/resources/extensions/gsd/tools/replan-slice.ts +2 -2
  414. package/src/resources/extensions/gsd/unit-context-composer.ts +1 -1
  415. package/src/resources/extensions/gsd/unit-registry.ts +34 -4
  416. package/src/resources/extensions/gsd/verification-verdict.ts +4 -2
  417. package/src/resources/extensions/gsd/workflow-event-ledger.ts +131 -0
  418. package/src/resources/extensions/gsd/workflow-event-vocabulary.ts +59 -0
  419. package/src/resources/extensions/gsd/workflow-events.ts +12 -20
  420. package/src/resources/extensions/gsd/workflow-mcp-auto-prep.ts +2 -0
  421. package/src/resources/extensions/gsd/workflow-mcp-readiness-cache.ts +150 -0
  422. package/src/resources/extensions/gsd/workflow-reconcile.ts +29 -62
  423. package/src/resources/extensions/gsd/worktree-manager.ts +6 -1
  424. package/src/resources/extensions/gsd/worktree-safety.ts +41 -39
  425. package/src/resources/extensions/gsd/worktree.ts +7 -1
  426. package/src/resources/extensions/mcp-client/manager.ts +7 -1
  427. package/src/resources/skills/create-skill/SKILL.md +3 -0
  428. package/src/resources/skills/create-skill/references/skill-structure.md +1 -0
  429. package/dist/resources/skills/gsd-browser/SKILL.md +0 -41
  430. package/src/resources/skills/gsd-browser/SKILL.md +0 -41
  431. /package/dist/web/standalone/.next/static/{LDHRKiRBIVZmiuMjrL1Vy → 2T9IOdiiM3o3gZ4UbPi8E}/_buildManifest.js +0 -0
  432. /package/dist/web/standalone/.next/static/{LDHRKiRBIVZmiuMjrL1Vy → 2T9IOdiiM3o3gZ4UbPi8E}/_ssgManifest.js +0 -0
@@ -59,6 +59,13 @@ function datePrefix() {
59
59
  const dd = String(d.getDate()).padStart(2, "0");
60
60
  return `${yy}${mm}${dd}`;
61
61
  }
62
+ export function isWorkflowStateComplete(state) {
63
+ if (state.completedAt)
64
+ return true;
65
+ return Array.isArray(state.phases) &&
66
+ state.phases.length > 0 &&
67
+ state.phases.every((phase) => phase.status === "completed");
68
+ }
62
69
  /**
63
70
  * Write a STATE.json file to track workflow execution state.
64
71
  */
@@ -85,7 +92,7 @@ function writeWorkflowState(artifactDir, templateId, templateName, phases, descr
85
92
  * Scan all workflow artifact directories for in-progress STATE.json files.
86
93
  * Returns workflows that were started but not completed.
87
94
  */
88
- function findInProgressWorkflows(basePath) {
95
+ export function findInProgressWorkflows(basePath) {
89
96
  const workflowsRoot = join(gsdRoot(basePath), "workflows");
90
97
  if (!existsSync(workflowsRoot))
91
98
  return [];
@@ -105,7 +112,7 @@ function findInProgressWorkflows(basePath) {
105
112
  try {
106
113
  const raw = readFileSync(statePath, "utf-8");
107
114
  const state = JSON.parse(raw);
108
- if (!state.completedAt) {
115
+ if (!isWorkflowStateComplete(state)) {
109
116
  results.push(state);
110
117
  }
111
118
  }
@@ -186,6 +186,7 @@ export function writeLock(basePath, unitType, unitId, sessionFile) {
186
186
  * stale session-file pointer.
187
187
  */
188
188
  export function clearLock(basePath) {
189
+ const legacyLock = readLegacyLock(basePath);
189
190
  clearLegacyLockFile(basePath);
190
191
  if (!isDbAvailable())
191
192
  return;
@@ -198,9 +199,13 @@ export function clearLock(basePath) {
198
199
  deleteRuntimeKv("worker", staleWorker.worker_id, SESSION_FILE_KV_KEY);
199
200
  return;
200
201
  }
201
- const lock = readLegacyLock(basePath);
202
- if (lock?.pid)
203
- markWorkerStoppingByPid(projectRoot, lock.pid);
202
+ if (legacyLock?.pid) {
203
+ markWorkerStoppingByPid(projectRoot, legacyLock.pid);
204
+ const workerByLegacyPid = getAllAutoWorkers().find((w) => w.pid === legacyLock.pid
205
+ && normalizeRealPath(w.project_root_realpath) === projectRoot);
206
+ if (workerByLegacyPid)
207
+ forceReleaseLeasesForWorker(workerByLegacyPid.worker_id);
208
+ }
204
209
  const worker = findActiveWorkerForCurrentProcess(projectRoot);
205
210
  if (worker)
206
211
  deleteRuntimeKv("worker", worker.worker_id, SESSION_FILE_KV_KEY);
@@ -1,11 +1,13 @@
1
1
  // Project/App: gsd-pi
2
2
  // File Purpose: GSD engine — connection ownership, lifecycle, schema/migrations,
3
3
  // and transaction primitives for the single-writer layer. The shared handle
4
- // (currentDb) lives here; writers (db/writers/*) and the Query Module
5
- // (db/queries.ts) read it through getDb()/getDbOrNull().
4
+ // (currentDb) lives here; domain writers, allowlisted coordination/runtime
5
+ // writers, schema/migration helpers, and the Query Module (db/queries.ts) read
6
+ // it through getDb()/getDbOrNull().
6
7
  //
7
8
  // This file legitimately holds DDL and BEGIN/COMMIT control, so it is
8
- // allowlisted in tests/single-writer-invariant.test.ts alongside db/writers/.
9
+ // allowlisted in tests/single-writer-invariant.test.ts alongside the explicit
10
+ // writer layer.
9
11
  import { createRequire } from "node:module";
10
12
  import { existsSync, copyFileSync, mkdirSync, realpathSync } from "node:fs";
11
13
  import { dirname, join } from "node:path";
@@ -15,7 +17,7 @@ import { createDbAdapter } from "../db-adapter.js";
15
17
  import { createBaseSchemaObjects } from "../db-base-schema.js";
16
18
  import { createCoordinationTablesV24 } from "../db-coordination-schema.js";
17
19
  import { createDbConnectionCache } from "../db-connection-cache.js";
18
- import { backupDatabaseBeforeMigration } from "../db-migration-backup.js";
20
+ import { backupDatabaseBeforeMigration, isMigrationBackupError } from "../db-migration-backup.js";
19
21
  import { applyMigrationV2Artifacts, applyMigrationV3Memories, applyMigrationV4DecisionMadeBy, applyMigrationV5HierarchyTables, applyMigrationV6SliceSummaries, applyMigrationV7Dependencies, applyMigrationV8PlanningFields, applyMigrationV9Ordering, applyMigrationV10ReplanTrigger, applyMigrationV11TaskPlanning, applyMigrationV12QualityGates, applyMigrationV13HotPathIndexes, applyMigrationV14SliceDependencies, applyMigrationV15AuditTables, applyMigrationV16EscalationSource, applyMigrationV17TaskEscalation, applyMigrationV18MemorySources, applyMigrationV19MemoryFts, applyMigrationV20MemoryRelations, applyMigrationV21StructuredMemories, applyMigrationV22QualityGateRepair, applyMigrationV23MilestoneQueue, applyMigrationV26MilestoneCommitAttributions, applyMigrationV27ArtifactHash, applyMigrationV28MemoryLastHitAt, applyMigrationV29RepositoryTargets, } from "../db-migration-steps.js";
20
22
  import { isMemoriesFtsAvailableSchema, tryCreateMemoriesFtsSchema } from "../db-memory-fts-schema.js";
21
23
  import { createDbOpenState } from "../db-open-state.js";
@@ -526,8 +528,9 @@ export function openDatabase(path) {
526
528
  }
527
529
  catch (err) {
528
530
  // Corrupt freelist: DDL fails with "malformed" but VACUUM can rebuild.
529
- // Attempt VACUUM recovery before giving up (see #2519).
530
- if (fileBacked && err instanceof Error && err.message?.includes("malformed")) {
531
+ // Pre-migration backup failures are already pre-DDL and must propagate
532
+ // instead of being masked by VACUUM recovery (see #2519).
533
+ if (shouldAttemptVacuumRecovery(fileBacked, err)) {
531
534
  try {
532
535
  adapter.exec("VACUUM");
533
536
  initSchema(adapter, fileBacked, path);
@@ -572,6 +575,10 @@ export function openDatabase(path) {
572
575
  }
573
576
  return true;
574
577
  }
578
+ function shouldAttemptVacuumRecovery(fileBacked, err) {
579
+ return fileBacked && err instanceof Error && err.message.includes("malformed") && !isMigrationBackupError(err);
580
+ }
581
+ export const _shouldAttemptVacuumRecoveryForTest = shouldAttemptVacuumRecovery;
575
582
  export function closeDatabase() {
576
583
  if (currentDb) {
577
584
  try {
@@ -687,6 +694,7 @@ function createTransactionControls(db) {
687
694
  return {
688
695
  begin: () => db.exec("BEGIN"),
689
696
  beginRead: () => db.exec("BEGIN DEFERRED"),
697
+ beginImmediate: () => db.exec("BEGIN IMMEDIATE"),
690
698
  commit: () => db.exec("COMMIT"),
691
699
  rollback: () => db.exec("ROLLBACK"),
692
700
  };
@@ -705,6 +713,16 @@ export function transaction(fn) {
705
713
  throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
706
714
  return _transactionRunner.transaction(createTransactionControls(currentDb), fn);
707
715
  }
716
+ /**
717
+ * Run a BEGIN IMMEDIATE write transaction for operations that need SQLite's
718
+ * reserved writer lock before issuing updates. Re-entrant like transaction():
719
+ * nested calls run inside the outer transaction without a nested BEGIN.
720
+ */
721
+ export function immediateTransaction(fn) {
722
+ if (!currentDb)
723
+ throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
724
+ return _transactionRunner.immediateTransaction(createTransactionControls(currentDb), fn);
725
+ }
708
726
  /**
709
727
  * Wrap a block of reads in a DEFERRED transaction so that all SELECTs observe
710
728
  * a consistent snapshot of the DB even if a concurrent writer commits between
@@ -218,6 +218,36 @@ export function getMilestoneSlices(milestoneId) {
218
218
  const rows = getDbOrNull().prepare("SELECT * FROM slices WHERE milestone_id = :mid ORDER BY sequence, id").all({ ":mid": milestoneId });
219
219
  return rows.map(rowToSlice);
220
220
  }
221
+ /**
222
+ * Load slices for many milestones in a single query. Returns a Map keyed by
223
+ * milestone_id, preserving `ORDER BY sequence, id` within each bucket.
224
+ */
225
+ export function getSlicesByMilestoneIds(milestoneIds) {
226
+ const db = getDbOrNull();
227
+ if (!db || milestoneIds.length === 0)
228
+ return new Map();
229
+ const idList = [...milestoneIds];
230
+ const placeholders = idList.map((_, i) => `:mid${i}`).join(",");
231
+ const params = {};
232
+ idList.forEach((id, i) => {
233
+ params[`:mid${i}`] = id;
234
+ });
235
+ const rows = db
236
+ .prepare(`SELECT * FROM slices WHERE milestone_id IN (${placeholders}) ORDER BY milestone_id, sequence, id`)
237
+ .all(params);
238
+ const byMilestone = new Map();
239
+ for (const row of rows) {
240
+ const slice = rowToSlice(row);
241
+ const bucket = byMilestone.get(slice.milestone_id);
242
+ if (bucket) {
243
+ bucket.push(slice);
244
+ }
245
+ else {
246
+ byMilestone.set(slice.milestone_id, [slice]);
247
+ }
248
+ }
249
+ return byMilestone;
250
+ }
221
251
  /**
222
252
  * Consolidated DB read for dispatch/gate/completion decisions (ADR-017).
223
253
  * `done` uses the canonical closed-status predicate (`isClosedStatus`) — the
@@ -1,5 +1,23 @@
1
1
  // Project/App: gsd-pi
2
2
  // File Purpose: Pre-migration backup helper for GSD database schema upgrades.
3
+ /** Marks pre-migration backup failures so DB-open recovery cannot mask them. */
4
+ export class MigrationBackupError extends Error {
5
+ constructor(message, cause) {
6
+ super(message, { cause });
7
+ this.name = "MigrationBackupError";
8
+ }
9
+ }
10
+ /** Returns true for errors raised while checkpointing or copying a migration backup. */
11
+ export function isMigrationBackupError(err) {
12
+ return err instanceof MigrationBackupError;
13
+ }
14
+ /**
15
+ * Creates a same-version backup before file-backed schema migrations.
16
+ *
17
+ * Existing same-version backups are reused. New backups fail closed: WAL
18
+ * checkpoint failures, incomplete checkpoints, and copy failures are logged
19
+ * and then rethrown before migration DDL runs.
20
+ */
3
21
  export function backupDatabaseBeforeMigration(db, dbPath, currentVersion, deps) {
4
22
  if (!dbPath || dbPath === ":memory:" || !deps.existsSync(dbPath))
5
23
  return;
@@ -7,16 +25,41 @@ export function backupDatabaseBeforeMigration(db, dbPath, currentVersion, deps)
7
25
  const backupPath = `${dbPath}.backup-v${currentVersion}`;
8
26
  if (deps.existsSync(backupPath))
9
27
  return;
10
- try {
11
- db.exec("PRAGMA wal_checkpoint(TRUNCATE)");
12
- }
13
- catch {
14
- // Checkpoint is best effort; copying the base file is still better than no backup.
15
- }
28
+ checkpointWal(db);
16
29
  deps.copyFileSync(dbPath, backupPath);
17
30
  }
18
31
  catch (backupErr) {
19
- const message = backupErr instanceof Error ? backupErr.message : String(backupErr);
20
- deps.logWarning("db", `Pre-migration backup failed: ${message}`);
32
+ const error = toMigrationBackupError(backupErr);
33
+ deps.logWarning("db", `Pre-migration backup failed: ${error.message}`);
34
+ throw error;
35
+ }
36
+ }
37
+ function checkpointWal(db) {
38
+ const row = db.prepare("PRAGMA wal_checkpoint(TRUNCATE)").get();
39
+ if (!isCheckpointComplete(row)) {
40
+ const busy = formatCheckpointValue(row, "busy");
41
+ const log = formatCheckpointValue(row, "log");
42
+ const checkpointed = formatCheckpointValue(row, "checkpointed");
43
+ throw new MigrationBackupError(`WAL checkpoint incomplete: busy=${busy} log=${log} checkpointed=${checkpointed}`);
21
44
  }
22
45
  }
46
+ function isCheckpointComplete(row) {
47
+ if (!row)
48
+ return false;
49
+ const busy = Number(row["busy"]);
50
+ const log = Number(row["log"]);
51
+ const checkpointed = Number(row["checkpointed"]);
52
+ if (!Number.isFinite(busy) || !Number.isFinite(log) || !Number.isFinite(checkpointed))
53
+ return false;
54
+ return busy === 0 && log === checkpointed;
55
+ }
56
+ function formatCheckpointValue(row, key) {
57
+ const value = row?.[key];
58
+ return value === undefined ? "unknown" : String(value);
59
+ }
60
+ function toMigrationBackupError(err) {
61
+ if (isMigrationBackupError(err))
62
+ return err;
63
+ const message = err instanceof Error ? err.message : String(err);
64
+ return new MigrationBackupError(message, err);
65
+ }
@@ -6,29 +6,26 @@ export class DbTransactionRunner {
6
6
  return this.depth > 0;
7
7
  }
8
8
  transaction(controls, fn) {
9
- if (this.depth > 0) {
10
- return this.runNested(fn);
11
- }
12
- controls.begin();
13
- this.depth++;
14
- try {
15
- const result = fn();
16
- controls.commit();
17
- return result;
18
- }
19
- catch (err) {
20
- controls.rollback();
21
- throw err;
22
- }
23
- finally {
24
- this.depth--;
9
+ return this.runTransaction(controls, () => controls.begin(), fn);
10
+ }
11
+ /**
12
+ * Run a BEGIN IMMEDIATE transaction through the same depth counter as regular
13
+ * transactions so callers can compose it inside existing transaction scopes.
14
+ */
15
+ immediateTransaction(controls, fn) {
16
+ if (!controls.beginImmediate) {
17
+ throw new Error("db transaction controls do not support immediate transactions");
25
18
  }
19
+ return this.runTransaction(controls, () => controls.beginImmediate(), fn);
26
20
  }
27
21
  readTransaction(controls, fn, logRollbackError) {
22
+ return this.runTransaction(controls, () => controls.beginRead(), fn, logRollbackError);
23
+ }
24
+ runTransaction(controls, begin, fn, logRollbackError) {
28
25
  if (this.depth > 0) {
29
26
  return this.runNested(fn);
30
27
  }
31
- controls.beginRead();
28
+ begin();
32
29
  this.depth++;
33
30
  try {
34
31
  const result = fn();
@@ -36,12 +33,7 @@ export class DbTransactionRunner {
36
33
  return result;
37
34
  }
38
35
  catch (err) {
39
- try {
40
- controls.rollback();
41
- }
42
- catch (rollbackErr) {
43
- logRollbackError(rollbackErr instanceof Error ? rollbackErr : new Error(String(rollbackErr)));
44
- }
36
+ this.rollback(controls, logRollbackError);
45
37
  throw err;
46
38
  }
47
39
  finally {
@@ -57,6 +49,18 @@ export class DbTransactionRunner {
57
49
  this.depth--;
58
50
  }
59
51
  }
52
+ rollback(controls, logRollbackError) {
53
+ if (!logRollbackError) {
54
+ controls.rollback();
55
+ return;
56
+ }
57
+ try {
58
+ controls.rollback();
59
+ }
60
+ catch (rollbackErr) {
61
+ logRollbackError(rollbackErr instanceof Error ? rollbackErr : new Error(String(rollbackErr)));
62
+ }
63
+ }
60
64
  }
61
65
  export function createDbTransactionRunner() {
62
66
  return new DbTransactionRunner();
@@ -620,27 +620,18 @@ async function mirrorDecisionToMemory(id, normalizedFields) {
620
620
  /**
621
621
  * Extract a milestone/slice reference from a deferral decision.
622
622
  *
623
- * Detects deferrals by checking:
624
- * - scope contains "defer" (e.g., "deferral", "defer")
625
- * - choice or decision contains "defer" + an M###/S## pattern
623
+ * Detects deferrals when the slice reference is part of the deferral phrase.
626
624
  *
627
625
  * Returns { milestoneId, sliceId } if found, null otherwise.
628
626
  */
629
627
  export function extractDeferredSliceRef(fields) {
630
- const isDeferral = /\bdefer(?:ral|red|ring|s)?\b/i.test(fields.scope) ||
631
- /\bdefer(?:ral|red|ring|s)?\b/i.test(fields.choice) ||
632
- /\bdefer(?:ral|red|ring|s)?\b/i.test(fields.decision);
633
- if (!isDeferral)
634
- return null;
635
- // Look for M###/S## pattern in choice first, then decision
636
- const slicePattern = /\b(M\d{3,4})\/(S\d{2,3})\b/;
637
- const choiceMatch = fields.choice.match(slicePattern);
638
- if (choiceMatch) {
639
- return { milestoneId: choiceMatch[1], sliceId: choiceMatch[2] };
640
- }
641
- const decisionMatch = fields.decision.match(slicePattern);
642
- if (decisionMatch) {
643
- return { milestoneId: decisionMatch[1], sliceId: decisionMatch[2] };
628
+ const defersSlicePattern = /\bdefer(?:ral|red|ring|s)?\b\s+(?:(?:of|the)\s+)*(?:slice\s+)?\b(M\d{3,4})\/(S\d{2,3})\b/i;
629
+ const sliceIsDeferredPattern = /\b(M\d{3,4})\/(S\d{2,3})\b\s+(?:is|was|will be|should be|can be)\s+defer(?:red|ring)?\b/i;
630
+ for (const text of [fields.choice, fields.decision, fields.scope]) {
631
+ const match = text.match(defersSlicePattern) ?? text.match(sliceIsDeferredPattern);
632
+ if (match) {
633
+ return { milestoneId: match[1], sliceId: match[2] };
634
+ }
644
635
  }
645
636
  return null;
646
637
  }
@@ -1,11 +1,11 @@
1
1
  import { existsSync, statSync } from "node:fs";
2
- import { join } from "node:path";
3
2
  import { isDbAvailable, _getAdapter } from "./gsd-db.js";
4
3
  import { isAfter, latestExplicitReopenAt } from "./milestone-reopen-events.js";
5
4
  import { resolveGsdPathContract, resolveMilestoneFile } from "./paths.js";
6
5
  import { deriveState } from "./state.js";
6
+ import { workflowEventLogPath } from "./workflow-event-ledger.js";
7
7
  import { readEvents } from "./workflow-events.js";
8
- import { renderAllProjections } from "./workflow-projections.js";
8
+ import { flushWorkflowProjections } from "./projection-flush.js";
9
9
  export async function checkEngineHealth(basePath, issues, fixesApplied) {
10
10
  const dbPath = resolveGsdPathContract(basePath).projectDb;
11
11
  if (!isDbAvailable() && existsSync(dbPath)) {
@@ -228,7 +228,7 @@ export async function checkEngineHealth(basePath, issues, fixesApplied) {
228
228
  // relative to the event log and re-render them.
229
229
  try {
230
230
  if (isDbAvailable()) {
231
- const eventLogPath = join(basePath, ".gsd", "event-log.jsonl");
231
+ const eventLogPath = workflowEventLogPath(basePath);
232
232
  const events = readEvents(eventLogPath);
233
233
  if (events.length > 0) {
234
234
  const lastEventTs = new Date(events[events.length - 1].ts).getTime();
@@ -239,7 +239,7 @@ export async function checkEngineHealth(basePath, issues, fixesApplied) {
239
239
  const roadmapPath = resolveMilestoneFile(basePath, milestone.id, "ROADMAP");
240
240
  if (!roadmapPath || !existsSync(roadmapPath)) {
241
241
  try {
242
- await renderAllProjections(basePath, milestone.id);
242
+ await flushWorkflowProjections(basePath, { milestoneId: milestone.id });
243
243
  fixesApplied.push(`re-rendered missing projections for ${milestone.id}`);
244
244
  }
245
245
  catch {
@@ -250,7 +250,7 @@ export async function checkEngineHealth(basePath, issues, fixesApplied) {
250
250
  const projectionMtime = statSync(roadmapPath).mtimeMs;
251
251
  if (lastEventTs > projectionMtime) {
252
252
  try {
253
- await renderAllProjections(basePath, milestone.id);
253
+ await flushWorkflowProjections(basePath, { milestoneId: milestone.id });
254
254
  fixesApplied.push(`re-rendered stale projections for ${milestone.id}`);
255
255
  }
256
256
  catch {