gsd-pi 2.73.1-dev.d987996 → 2.74.0-dev.14c45ac

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 (365) hide show
  1. package/dist/cli-web-branch.d.ts +4 -3
  2. package/dist/cli-web-branch.js +10 -7
  3. package/dist/cli.js +184 -206
  4. package/dist/headless-query.js +4 -1
  5. package/dist/help-text.js +23 -0
  6. package/dist/logo.d.ts +1 -1
  7. package/dist/logo.js +1 -1
  8. package/dist/onboarding.js +59 -53
  9. package/dist/resource-loader.js +2 -2
  10. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +68 -4
  11. package/dist/resources/extensions/gsd/activity-log.js +16 -0
  12. package/dist/resources/extensions/gsd/auto/detect-stuck.js +11 -4
  13. package/dist/resources/extensions/gsd/auto/loop.js +147 -10
  14. package/dist/resources/extensions/gsd/auto/phases.js +173 -13
  15. package/dist/resources/extensions/gsd/auto/session.js +10 -0
  16. package/dist/resources/extensions/gsd/auto-dispatch.js +22 -4
  17. package/dist/resources/extensions/gsd/auto-model-selection.js +105 -16
  18. package/dist/resources/extensions/gsd/auto-post-unit.js +254 -15
  19. package/dist/resources/extensions/gsd/auto-prompts.js +12 -0
  20. package/dist/resources/extensions/gsd/auto-start.js +23 -6
  21. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +13 -0
  22. package/dist/resources/extensions/gsd/auto-unit-closeout.js +18 -0
  23. package/dist/resources/extensions/gsd/auto-verification.js +186 -3
  24. package/dist/resources/extensions/gsd/auto.js +65 -12
  25. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +21 -8
  26. package/dist/resources/extensions/gsd/commands/catalog.js +26 -1
  27. package/dist/resources/extensions/gsd/commands/handlers/ops.js +25 -0
  28. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +68 -9
  29. package/dist/resources/extensions/gsd/commands-add-tests.js +111 -0
  30. package/dist/resources/extensions/gsd/commands-backlog.js +140 -0
  31. package/dist/resources/extensions/gsd/commands-do.js +79 -0
  32. package/dist/resources/extensions/gsd/commands-extract-learnings.js +225 -0
  33. package/dist/resources/extensions/gsd/commands-handlers.js +8 -2
  34. package/dist/resources/extensions/gsd/commands-maintenance.js +6 -6
  35. package/dist/resources/extensions/gsd/commands-pr-branch.js +180 -0
  36. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +1 -1
  37. package/dist/resources/extensions/gsd/commands-session-report.js +82 -0
  38. package/dist/resources/extensions/gsd/commands-ship.js +187 -0
  39. package/dist/resources/extensions/gsd/db-writer.js +3 -5
  40. package/dist/resources/extensions/gsd/docs/preferences-reference.md +15 -2
  41. package/dist/resources/extensions/gsd/git-service.js +49 -1
  42. package/dist/resources/extensions/gsd/graph-context.js +157 -0
  43. package/dist/resources/extensions/gsd/gsd-db.js +581 -2
  44. package/dist/resources/extensions/gsd/guided-flow.js +23 -0
  45. package/dist/resources/extensions/gsd/index.js +15 -2
  46. package/dist/resources/extensions/gsd/init-wizard.js +1 -0
  47. package/dist/resources/extensions/gsd/journal.js +27 -0
  48. package/dist/resources/extensions/gsd/md-importer.js +3 -4
  49. package/dist/resources/extensions/gsd/memory-store.js +19 -51
  50. package/dist/resources/extensions/gsd/metrics.js +19 -0
  51. package/dist/resources/extensions/gsd/milestone-validation-gates.js +13 -12
  52. package/dist/resources/extensions/gsd/native-git-bridge.js +7 -4
  53. package/dist/resources/extensions/gsd/notification-widget.js +2 -2
  54. package/dist/resources/extensions/gsd/parallel-orchestrator.js +33 -1
  55. package/dist/resources/extensions/gsd/preferences-models.js +63 -3
  56. package/dist/resources/extensions/gsd/preferences-types.js +2 -0
  57. package/dist/resources/extensions/gsd/preferences-validation.js +130 -2
  58. package/dist/resources/extensions/gsd/preferences.js +26 -0
  59. package/dist/resources/extensions/gsd/prompts/add-tests.md +35 -0
  60. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +12 -2
  61. package/dist/resources/extensions/gsd/state.js +66 -15
  62. package/dist/resources/extensions/gsd/templates/PREFERENCES.md +18 -0
  63. package/dist/resources/extensions/gsd/tools/complete-slice.js +20 -0
  64. package/dist/resources/extensions/gsd/tools/validate-milestone.js +39 -4
  65. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +3 -14
  66. package/dist/resources/extensions/gsd/triage-resolution.js +2 -5
  67. package/dist/resources/extensions/gsd/unit-ownership.js +1 -1
  68. package/dist/resources/extensions/gsd/uok/audit-toggle.js +7 -0
  69. package/dist/resources/extensions/gsd/uok/audit.js +40 -0
  70. package/dist/resources/extensions/gsd/uok/contracts.js +1 -0
  71. package/dist/resources/extensions/gsd/uok/execution-graph.js +179 -0
  72. package/dist/resources/extensions/gsd/uok/flags.js +29 -0
  73. package/dist/resources/extensions/gsd/uok/gate-runner.js +109 -0
  74. package/dist/resources/extensions/gsd/uok/gitops.js +53 -0
  75. package/dist/resources/extensions/gsd/uok/kernel.js +80 -0
  76. package/dist/resources/extensions/gsd/uok/loop-adapter.js +133 -0
  77. package/dist/resources/extensions/gsd/uok/model-policy.js +66 -0
  78. package/dist/resources/extensions/gsd/uok/plan-v2.js +132 -0
  79. package/dist/resources/extensions/gsd/workflow-logger.js +22 -0
  80. package/dist/resources/extensions/gsd/workflow-manifest.js +8 -69
  81. package/dist/resources/extensions/gsd/workflow-migration.js +21 -22
  82. package/dist/resources/extensions/gsd/workflow-projections.js +4 -1
  83. package/dist/resources/extensions/gsd/workflow-reconcile.js +14 -11
  84. package/dist/resources/extensions/ttsr/ttsr-manager.js +3 -1
  85. package/dist/tsconfig.extensions.tsbuildinfo +1 -0
  86. package/dist/update-check.d.ts +1 -0
  87. package/dist/update-check.js +13 -5
  88. package/dist/update-cmd.js +4 -3
  89. package/dist/web/standalone/.next/BUILD_ID +1 -1
  90. package/dist/web/standalone/.next/app-path-routes-manifest.json +11 -11
  91. package/dist/web/standalone/.next/build-manifest.json +2 -2
  92. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  93. package/dist/web/standalone/.next/required-server-files.json +1 -1
  94. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  95. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  96. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  97. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  98. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  99. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  100. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  101. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  102. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  103. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  104. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  105. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  106. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  107. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  108. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  109. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  110. package/dist/web/standalone/.next/server/app/index.html +1 -1
  111. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  112. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  113. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  114. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  115. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  116. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  117. package/dist/web/standalone/.next/server/app-paths-manifest.json +11 -11
  118. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  119. package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
  120. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  121. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  122. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  123. package/dist/web/standalone/server.js +1 -1
  124. package/package.json +3 -3
  125. package/packages/daemon/package.json +2 -2
  126. package/packages/mcp-server/dist/index.d.ts +3 -0
  127. package/packages/mcp-server/dist/index.d.ts.map +1 -1
  128. package/packages/mcp-server/dist/index.js +3 -0
  129. package/packages/mcp-server/dist/index.js.map +1 -1
  130. package/packages/mcp-server/dist/readers/graph.d.ts +87 -0
  131. package/packages/mcp-server/dist/readers/graph.d.ts.map +1 -0
  132. package/packages/mcp-server/dist/readers/graph.js +655 -0
  133. package/packages/mcp-server/dist/readers/graph.js.map +1 -0
  134. package/packages/mcp-server/dist/readers/index.d.ts +2 -0
  135. package/packages/mcp-server/dist/readers/index.d.ts.map +1 -1
  136. package/packages/mcp-server/dist/readers/index.js +1 -0
  137. package/packages/mcp-server/dist/readers/index.js.map +1 -1
  138. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  139. package/packages/mcp-server/dist/server.js +65 -0
  140. package/packages/mcp-server/dist/server.js.map +1 -1
  141. package/packages/mcp-server/package.json +2 -2
  142. package/packages/mcp-server/src/index.ts +15 -0
  143. package/packages/mcp-server/src/readers/graph.test.ts +604 -0
  144. package/packages/mcp-server/src/readers/graph.ts +855 -0
  145. package/packages/mcp-server/src/readers/index.ts +12 -0
  146. package/packages/mcp-server/src/server.ts +83 -0
  147. package/packages/mcp-server/tsconfig.json +1 -0
  148. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -0
  149. package/packages/native/package.json +2 -2
  150. package/packages/native/tsconfig.tsbuildinfo +1 -0
  151. package/packages/pi-agent-core/package.json +1 -1
  152. package/packages/pi-agent-core/tsconfig.json +1 -0
  153. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -0
  154. package/packages/pi-ai/dist/index.d.ts +1 -0
  155. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  156. package/packages/pi-ai/dist/index.js +1 -0
  157. package/packages/pi-ai/dist/index.js.map +1 -1
  158. package/packages/pi-ai/dist/utils/overflow.d.ts.map +1 -1
  159. package/packages/pi-ai/dist/utils/overflow.js +12 -0
  160. package/packages/pi-ai/dist/utils/overflow.js.map +1 -1
  161. package/packages/pi-ai/dist/utils/tests/overflow.test.d.ts +2 -0
  162. package/packages/pi-ai/dist/utils/tests/overflow.test.d.ts.map +1 -0
  163. package/packages/pi-ai/dist/utils/tests/overflow.test.js +50 -0
  164. package/packages/pi-ai/dist/utils/tests/overflow.test.js.map +1 -0
  165. package/packages/pi-ai/package.json +1 -1
  166. package/packages/pi-ai/src/index.ts +4 -0
  167. package/packages/pi-ai/src/utils/overflow.ts +14 -1
  168. package/packages/pi-ai/src/utils/tests/overflow.test.ts +58 -0
  169. package/packages/pi-ai/tsconfig.json +1 -0
  170. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -0
  171. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +511 -8
  172. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  173. package/packages/pi-coding-agent/dist/core/compaction/utils.js +5 -5
  174. package/packages/pi-coding-agent/dist/core/compaction/utils.js.map +1 -1
  175. package/packages/pi-coding-agent/dist/core/compaction-utils.test.d.ts +2 -0
  176. package/packages/pi-coding-agent/dist/core/compaction-utils.test.d.ts.map +1 -0
  177. package/packages/pi-coding-agent/dist/core/compaction-utils.test.js +45 -0
  178. package/packages/pi-coding-agent/dist/core/compaction-utils.test.js.map +1 -0
  179. package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.d.ts +2 -0
  180. package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.d.ts.map +1 -0
  181. package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.js +52 -0
  182. package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.js.map +1 -0
  183. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  184. package/packages/pi-coding-agent/dist/core/model-registry.js +2 -2
  185. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  186. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts +12 -2
  187. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  188. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +61 -28
  189. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
  190. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.d.ts +2 -1
  191. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
  192. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.js +9 -3
  193. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.js.map +1 -1
  194. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.d.ts +2 -0
  195. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.d.ts.map +1 -0
  196. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js +52 -0
  197. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js.map +1 -0
  198. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  199. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +165 -20
  200. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  201. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  202. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +11 -3
  203. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  204. package/packages/pi-coding-agent/package.json +1 -1
  205. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +620 -8
  206. package/packages/pi-coding-agent/src/core/compaction/utils.ts +5 -5
  207. package/packages/pi-coding-agent/src/core/compaction-utils.test.ts +50 -0
  208. package/packages/pi-coding-agent/src/core/model-registry-env-fallback.test.ts +59 -0
  209. package/packages/pi-coding-agent/src/core/model-registry.ts +2 -1
  210. package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +74 -32
  211. package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.test.ts +73 -0
  212. package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.ts +9 -3
  213. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +189 -25
  214. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +11 -3
  215. package/packages/pi-coding-agent/src/types/ambient-modules.d.ts +69 -0
  216. package/packages/pi-coding-agent/tsconfig.json +3 -2
  217. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -0
  218. package/packages/pi-tui/dist/__tests__/tui.test.js +60 -1
  219. package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
  220. package/packages/pi-tui/dist/tui.d.ts +8 -0
  221. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  222. package/packages/pi-tui/dist/tui.js +32 -3
  223. package/packages/pi-tui/dist/tui.js.map +1 -1
  224. package/packages/pi-tui/package.json +1 -1
  225. package/packages/pi-tui/src/__tests__/tui.test.ts +76 -1
  226. package/packages/pi-tui/src/tui.ts +31 -3
  227. package/packages/pi-tui/tsconfig.json +1 -0
  228. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -0
  229. package/packages/rpc-client/package.json +1 -1
  230. package/packages/rpc-client/tsconfig.json +1 -0
  231. package/packages/rpc-client/tsconfig.tsbuildinfo +1 -0
  232. package/pkg/package.json +1 -1
  233. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +107 -5
  234. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +111 -2
  235. package/src/resources/extensions/gsd/activity-log.ts +21 -0
  236. package/src/resources/extensions/gsd/auto/detect-stuck.ts +12 -4
  237. package/src/resources/extensions/gsd/auto/loop-deps.ts +10 -0
  238. package/src/resources/extensions/gsd/auto/loop.ts +159 -10
  239. package/src/resources/extensions/gsd/auto/phases.ts +213 -13
  240. package/src/resources/extensions/gsd/auto/session.ts +10 -0
  241. package/src/resources/extensions/gsd/auto-dispatch.ts +26 -10
  242. package/src/resources/extensions/gsd/auto-model-selection.ts +151 -16
  243. package/src/resources/extensions/gsd/auto-post-unit.ts +278 -16
  244. package/src/resources/extensions/gsd/auto-prompts.ts +13 -0
  245. package/src/resources/extensions/gsd/auto-start.ts +30 -6
  246. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +17 -0
  247. package/src/resources/extensions/gsd/auto-unit-closeout.ts +25 -1
  248. package/src/resources/extensions/gsd/auto-verification.ts +225 -3
  249. package/src/resources/extensions/gsd/auto.ts +72 -16
  250. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +24 -8
  251. package/src/resources/extensions/gsd/commands/catalog.ts +26 -1
  252. package/src/resources/extensions/gsd/commands/handlers/ops.ts +25 -0
  253. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +74 -9
  254. package/src/resources/extensions/gsd/commands-add-tests.ts +137 -0
  255. package/src/resources/extensions/gsd/commands-backlog.ts +182 -0
  256. package/src/resources/extensions/gsd/commands-do.ts +109 -0
  257. package/src/resources/extensions/gsd/commands-extract-learnings.ts +304 -0
  258. package/src/resources/extensions/gsd/commands-handlers.ts +8 -2
  259. package/src/resources/extensions/gsd/commands-maintenance.ts +6 -6
  260. package/src/resources/extensions/gsd/commands-pr-branch.ts +234 -0
  261. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +1 -1
  262. package/src/resources/extensions/gsd/commands-session-report.ts +101 -0
  263. package/src/resources/extensions/gsd/commands-ship.ts +219 -0
  264. package/src/resources/extensions/gsd/db-writer.ts +3 -5
  265. package/src/resources/extensions/gsd/docs/preferences-reference.md +15 -2
  266. package/src/resources/extensions/gsd/git-service.ts +68 -0
  267. package/src/resources/extensions/gsd/graph-context.ts +212 -0
  268. package/src/resources/extensions/gsd/gsd-db.ts +788 -3
  269. package/src/resources/extensions/gsd/guided-flow.ts +32 -0
  270. package/src/resources/extensions/gsd/index.ts +18 -2
  271. package/src/resources/extensions/gsd/init-wizard.ts +3 -2
  272. package/src/resources/extensions/gsd/journal.ts +30 -0
  273. package/src/resources/extensions/gsd/md-importer.ts +3 -5
  274. package/src/resources/extensions/gsd/memory-store.ts +31 -62
  275. package/src/resources/extensions/gsd/metrics.ts +26 -0
  276. package/src/resources/extensions/gsd/milestone-validation-gates.ts +13 -14
  277. package/src/resources/extensions/gsd/native-git-bridge.ts +11 -12
  278. package/src/resources/extensions/gsd/notification-widget.ts +2 -2
  279. package/src/resources/extensions/gsd/parallel-orchestrator.ts +40 -1
  280. package/src/resources/extensions/gsd/preferences-models.ts +61 -3
  281. package/src/resources/extensions/gsd/preferences-types.ts +44 -0
  282. package/src/resources/extensions/gsd/preferences-validation.ts +130 -2
  283. package/src/resources/extensions/gsd/preferences.ts +28 -0
  284. package/src/resources/extensions/gsd/prompts/add-tests.md +35 -0
  285. package/src/resources/extensions/gsd/session-lock.ts +14 -2
  286. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +20 -1
  287. package/src/resources/extensions/gsd/state.ts +80 -17
  288. package/src/resources/extensions/gsd/templates/PREFERENCES.md +18 -0
  289. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +9 -5
  290. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +20 -0
  291. package/src/resources/extensions/gsd/tests/auto-post-unit-step-message.test.ts +53 -0
  292. package/src/resources/extensions/gsd/tests/auto-project-root-env.test.ts +7 -3
  293. package/src/resources/extensions/gsd/tests/auto-start-model-capture.test.ts +51 -2
  294. package/src/resources/extensions/gsd/tests/cold-resume-db-reopen.test.ts +6 -2
  295. package/src/resources/extensions/gsd/tests/commands-backlog.test.ts +158 -0
  296. package/src/resources/extensions/gsd/tests/commands-do.test.ts +127 -0
  297. package/src/resources/extensions/gsd/tests/commands-extract-learnings.test.ts +340 -0
  298. package/src/resources/extensions/gsd/tests/commands-pr-branch.test.ts +68 -0
  299. package/src/resources/extensions/gsd/tests/commands-session-report.test.ts +82 -0
  300. package/src/resources/extensions/gsd/tests/commands-ship.test.ts +71 -0
  301. package/src/resources/extensions/gsd/tests/commands-workflow-custom.test.ts +14 -0
  302. package/src/resources/extensions/gsd/tests/complete-milestone-false-merge.test.ts +142 -0
  303. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +2 -2
  304. package/src/resources/extensions/gsd/tests/complete-task.test.ts +2 -2
  305. package/src/resources/extensions/gsd/tests/completed-at-reconcile.test.ts +42 -0
  306. package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +3 -2
  307. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +3 -2
  308. package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +68 -8
  309. package/src/resources/extensions/gsd/tests/derive-state.test.ts +3 -3
  310. package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +154 -0
  311. package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +10 -7
  312. package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +137 -1
  313. package/src/resources/extensions/gsd/tests/graph-context.test.ts +337 -0
  314. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +1 -1
  315. package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +4 -2
  316. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +68 -1
  317. package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -2
  318. package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -3
  319. package/src/resources/extensions/gsd/tests/model-isolation.test.ts +91 -2
  320. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +140 -0
  321. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +79 -1
  322. package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +2 -1
  323. package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +40 -1
  324. package/src/resources/extensions/gsd/tests/preferences.test.ts +47 -0
  325. package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +180 -0
  326. package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +5 -7
  327. package/src/resources/extensions/gsd/tests/token-profile.test.ts +9 -6
  328. package/src/resources/extensions/gsd/tests/uok-audit-unified.test.ts +101 -0
  329. package/src/resources/extensions/gsd/tests/uok-contracts.test.ts +85 -0
  330. package/src/resources/extensions/gsd/tests/uok-execution-graph.test.ts +69 -0
  331. package/src/resources/extensions/gsd/tests/uok-flags.test.ts +39 -0
  332. package/src/resources/extensions/gsd/tests/uok-gate-runner.test.ts +70 -0
  333. package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +85 -0
  334. package/src/resources/extensions/gsd/tests/uok-gitops-wiring.test.ts +35 -0
  335. package/src/resources/extensions/gsd/tests/uok-model-policy.test.ts +89 -0
  336. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +167 -0
  337. package/src/resources/extensions/gsd/tests/uok-preferences.test.ts +42 -0
  338. package/src/resources/extensions/gsd/tests/validate-milestone-stuck-guard.test.ts +179 -0
  339. package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +39 -0
  340. package/src/resources/extensions/gsd/tests/workflow-logger-wiring.test.ts +223 -0
  341. package/src/resources/extensions/gsd/tools/complete-slice.ts +26 -0
  342. package/src/resources/extensions/gsd/tools/validate-milestone.ts +48 -3
  343. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +3 -11
  344. package/src/resources/extensions/gsd/triage-resolution.ts +2 -7
  345. package/src/resources/extensions/gsd/types.ts +1 -1
  346. package/src/resources/extensions/gsd/unit-ownership.ts +2 -2
  347. package/src/resources/extensions/gsd/uok/audit-toggle.ts +9 -0
  348. package/src/resources/extensions/gsd/uok/audit.ts +51 -0
  349. package/src/resources/extensions/gsd/uok/contracts.ts +135 -0
  350. package/src/resources/extensions/gsd/uok/execution-graph.ts +241 -0
  351. package/src/resources/extensions/gsd/uok/flags.ts +45 -0
  352. package/src/resources/extensions/gsd/uok/gate-runner.ts +146 -0
  353. package/src/resources/extensions/gsd/uok/gitops.ts +75 -0
  354. package/src/resources/extensions/gsd/uok/kernel.ts +105 -0
  355. package/src/resources/extensions/gsd/uok/loop-adapter.ts +162 -0
  356. package/src/resources/extensions/gsd/uok/model-policy.ts +112 -0
  357. package/src/resources/extensions/gsd/uok/plan-v2.ts +156 -0
  358. package/src/resources/extensions/gsd/workflow-logger.ts +25 -0
  359. package/src/resources/extensions/gsd/workflow-manifest.ts +9 -104
  360. package/src/resources/extensions/gsd/workflow-migration.ts +21 -29
  361. package/src/resources/extensions/gsd/workflow-projections.ts +8 -1
  362. package/src/resources/extensions/gsd/workflow-reconcile.ts +15 -15
  363. package/src/resources/extensions/ttsr/ttsr-manager.ts +10 -5
  364. /package/dist/web/standalone/.next/static/{cGmbVq2su4f9tMpgIkG8u → ZMKM0OI0CrTgzKWbgfPOg}/_buildManifest.js +0 -0
  365. /package/dist/web/standalone/.next/static/{cGmbVq2su4f9tMpgIkG8u → ZMKM0OI0CrTgzKWbgfPOg}/_ssgManifest.js +0 -0
@@ -0,0 +1,156 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+
4
+ import type { GSDState, Phase } from "../types.js";
5
+ import { gsdRoot, resolveMilestoneFile, resolveSliceFile } from "../paths.js";
6
+ import { isDbAvailable, getMilestoneSlices, getSliceTasks, type SliceRow } from "../gsd-db.js";
7
+ import type { UokGraphNode } from "./contracts.js";
8
+
9
+ const PLAN_V2_CLARIFY_ROUND_LIMIT = 3;
10
+ const EXECUTION_ENTRY_PHASES: ReadonlySet<Phase> = new Set([
11
+ "executing",
12
+ "summarizing",
13
+ "validating-milestone",
14
+ "completing-milestone",
15
+ ]);
16
+
17
+ export interface PlanV2CompileResult {
18
+ ok: boolean;
19
+ reason?: string;
20
+ graphPath?: string;
21
+ nodeCount?: number;
22
+ clarifyRoundLimit?: number;
23
+ researchSynthesized?: boolean;
24
+ draftContextIncluded?: boolean;
25
+ finalizedContextIncluded?: boolean;
26
+ }
27
+
28
+ function graphOutputPath(basePath: string): string {
29
+ return join(gsdRoot(basePath), "runtime", "uok-plan-v2-graph.json");
30
+ }
31
+
32
+ function hasFileContent(path: string | null): boolean {
33
+ if (!path || !existsSync(path)) return false;
34
+ try {
35
+ return readFileSync(path, "utf-8").trim().length > 0;
36
+ } catch {
37
+ return false;
38
+ }
39
+ }
40
+
41
+ function countSliceResearchArtifacts(basePath: string, milestoneId: string, slices: SliceRow[]): number {
42
+ let count = 0;
43
+ for (const slice of slices) {
44
+ if (hasFileContent(resolveSliceFile(basePath, milestoneId, slice.id, "RESEARCH"))) {
45
+ count += 1;
46
+ }
47
+ }
48
+ return count;
49
+ }
50
+
51
+ function isExecutionEntryPhase(phase: Phase): boolean {
52
+ return EXECUTION_ENTRY_PHASES.has(phase);
53
+ }
54
+
55
+ export function compileUnitGraphFromState(basePath: string, state: GSDState): PlanV2CompileResult {
56
+ const mid = state.activeMilestone?.id;
57
+ if (!mid) return { ok: false, reason: "no active milestone" };
58
+ if (!isDbAvailable()) return { ok: false, reason: "database not available" };
59
+
60
+ const slices = getMilestoneSlices(mid).sort((a, b) => Number(a.sequence ?? 0) - Number(b.sequence ?? 0));
61
+ const nodes: UokGraphNode[] = [];
62
+ const clarifyRoundLimit = PLAN_V2_CLARIFY_ROUND_LIMIT;
63
+ const draftContextIncluded = hasFileContent(resolveMilestoneFile(basePath, mid, "CONTEXT-DRAFT"));
64
+ const finalizedContextIncluded = hasFileContent(resolveMilestoneFile(basePath, mid, "CONTEXT"));
65
+ const researchSynthesized = hasFileContent(resolveMilestoneFile(basePath, mid, "RESEARCH"))
66
+ || countSliceResearchArtifacts(basePath, mid, slices) > 0;
67
+
68
+ if (isExecutionEntryPhase(state.phase) && !finalizedContextIncluded) {
69
+ const reason = draftContextIncluded
70
+ ? "milestone context draft exists but finalized CONTEXT.md is missing"
71
+ : "missing milestone CONTEXT.md";
72
+ return {
73
+ ok: false,
74
+ reason,
75
+ clarifyRoundLimit,
76
+ researchSynthesized,
77
+ draftContextIncluded,
78
+ finalizedContextIncluded,
79
+ };
80
+ }
81
+
82
+ for (const slice of slices) {
83
+ const sid = slice.id;
84
+ const tasks = getSliceTasks(mid, sid)
85
+ .sort((a, b) => Number(a.sequence ?? 0) - Number(b.sequence ?? 0));
86
+
87
+ let previousTaskNodeId: string | null = null;
88
+ for (const task of tasks) {
89
+ const nodeId = `execute-task:${mid}:${sid}:${task.id}`;
90
+ const dependsOn = previousTaskNodeId ? [previousTaskNodeId] : [];
91
+ nodes.push({
92
+ id: nodeId,
93
+ kind: "unit",
94
+ dependsOn,
95
+ writes: task.key_files,
96
+ metadata: {
97
+ unitType: "execute-task",
98
+ unitId: `${mid}.${sid}.${task.id}`,
99
+ title: task.title,
100
+ status: task.status,
101
+ },
102
+ });
103
+ previousTaskNodeId = nodeId;
104
+ }
105
+
106
+ if (previousTaskNodeId) {
107
+ nodes.push({
108
+ id: `complete-slice:${mid}:${sid}`,
109
+ kind: "verification",
110
+ dependsOn: [previousTaskNodeId],
111
+ metadata: {
112
+ unitType: "complete-slice",
113
+ unitId: `${mid}.${sid}`,
114
+ title: slice.title,
115
+ status: slice.status,
116
+ },
117
+ });
118
+ }
119
+ }
120
+
121
+ const output = {
122
+ compiledAt: new Date().toISOString(),
123
+ milestoneId: mid,
124
+ pipeline: {
125
+ clarifyRoundLimit,
126
+ researchSynthesized,
127
+ draftContextIncluded,
128
+ finalizedContextIncluded,
129
+ sourcePhase: state.phase,
130
+ },
131
+ nodes,
132
+ };
133
+
134
+ const outPath = graphOutputPath(basePath);
135
+ mkdirSync(join(gsdRoot(basePath), "runtime"), { recursive: true });
136
+ writeFileSync(outPath, JSON.stringify(output, null, 2) + "\n", "utf-8");
137
+
138
+ return {
139
+ ok: true,
140
+ graphPath: outPath,
141
+ nodeCount: nodes.length,
142
+ clarifyRoundLimit,
143
+ researchSynthesized: output.pipeline.researchSynthesized,
144
+ draftContextIncluded: output.pipeline.draftContextIncluded,
145
+ finalizedContextIncluded: output.pipeline.finalizedContextIncluded,
146
+ };
147
+ }
148
+
149
+ export function ensurePlanV2Graph(basePath: string, state: GSDState): PlanV2CompileResult {
150
+ const compiled = compileUnitGraphFromState(basePath, state);
151
+ if (!compiled.ok) return compiled;
152
+ if ((compiled.nodeCount ?? 0) <= 0) {
153
+ return { ok: false, reason: "compiled graph is empty" };
154
+ }
155
+ return compiled;
156
+ }
@@ -20,6 +20,8 @@ import { appendFileSync, readFileSync, existsSync, mkdirSync } from "node:fs";
20
20
  import { join } from "node:path";
21
21
 
22
22
  import { appendNotification } from "./notification-store.js";
23
+ import { buildAuditEnvelope, emitUokAuditEvent } from "./uok/audit.js";
24
+ import { isUnifiedAuditEnabled } from "./uok/audit-toggle.js";
23
25
 
24
26
  // ─── Types ──────────────────────────────────────────────────────────────
25
27
 
@@ -275,6 +277,29 @@ function _push(
275
277
  _buffer.shift();
276
278
  }
277
279
 
280
+ if (_auditBasePath && isUnifiedAuditEnabled()) {
281
+ try {
282
+ emitUokAuditEvent(
283
+ _auditBasePath,
284
+ buildAuditEnvelope({
285
+ traceId: `workflow-log:${component}`,
286
+ turnId: context?.id,
287
+ causedBy: context?.fn ?? context?.tool,
288
+ category: "orchestration",
289
+ type: severity === "error" ? "workflow-log-error" : "workflow-log-warn",
290
+ payload: {
291
+ component,
292
+ message,
293
+ context: context ?? {},
294
+ },
295
+ }),
296
+ );
297
+ } catch (auditEmitErr) {
298
+ // Best-effort: unified audit projection must never block workflow logger.
299
+ _writeStderr(`[gsd:workflow-logger] unified-audit emit failed: ${(auditEmitErr as Error).message}\n`);
300
+ }
301
+ }
302
+
278
303
  // Persist errors to .gsd/audit-log.jsonl so they survive context resets.
279
304
  // Only error-severity entries are persisted — warnings are ephemeral (stderr + buffer)
280
305
  // to avoid log amplification from expected-control-flow catch paths.
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  _getAdapter,
3
- transaction,
3
+ readTransaction,
4
+ restoreManifest,
4
5
  type MilestoneRow,
5
6
  type SliceRow,
6
7
  type TaskRow,
@@ -74,9 +75,7 @@ export function snapshotState(): StateManifest {
74
75
 
75
76
  // Wrap all reads in a deferred transaction so the snapshot is consistent
76
77
  // (all SELECTs see the same DB state even if a concurrent write lands between them).
77
- db.exec("BEGIN DEFERRED");
78
-
79
- try {
78
+ return readTransaction(() => {
80
79
  const rawMilestones = db.prepare("SELECT * FROM milestones ORDER BY id").all() as Record<string, unknown>[];
81
80
  const milestones: MilestoneRow[] = rawMilestones.map((r) => ({
82
81
  id: r["id"] as string,
@@ -186,109 +185,15 @@ export function snapshotState(): StateManifest {
186
185
  verification_evidence,
187
186
  };
188
187
 
189
- db.exec("COMMIT");
190
188
  return result;
191
- } catch (err) {
192
- try { db.exec("ROLLBACK"); } catch { /* ignore rollback failure */ }
193
- throw err;
194
- }
189
+ });
195
190
  }
196
191
 
197
192
  // ─── restore ─────────────────────────────────────────────────────────────
198
-
199
- /**
200
- * Atomically replace all workflow state from a manifest.
201
- * Runs inside a transaction — if any insert fails, no tables are modified.
202
- * Only touches engine tables + decisions. Does NOT modify artifacts or memories.
203
- */
204
- function restore(manifest: StateManifest): void {
205
- const db = requireDb();
206
-
207
- transaction(() => {
208
- // Clear engine tables (order matters for foreign-key-like consistency)
209
- db.exec("DELETE FROM verification_evidence");
210
- db.exec("DELETE FROM tasks");
211
- db.exec("DELETE FROM slices");
212
- db.exec("DELETE FROM milestones");
213
- db.exec("DELETE FROM decisions WHERE 1=1");
214
-
215
- // Restore milestones
216
- const msStmt = db.prepare(
217
- `INSERT INTO milestones (id, title, status, depends_on, created_at, completed_at,
218
- vision, success_criteria, key_risks, proof_strategy,
219
- verification_contract, verification_integration, verification_operational, verification_uat,
220
- definition_of_done, requirement_coverage, boundary_map_markdown)
221
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
222
- );
223
- for (const m of manifest.milestones) {
224
- msStmt.run(
225
- m.id, m.title, m.status,
226
- JSON.stringify(m.depends_on), m.created_at, m.completed_at,
227
- m.vision, JSON.stringify(m.success_criteria), JSON.stringify(m.key_risks),
228
- JSON.stringify(m.proof_strategy),
229
- m.verification_contract, m.verification_integration, m.verification_operational, m.verification_uat,
230
- JSON.stringify(m.definition_of_done), m.requirement_coverage, m.boundary_map_markdown,
231
- );
232
- }
233
-
234
- // Restore slices
235
- const slStmt = db.prepare(
236
- `INSERT INTO slices (milestone_id, id, title, status, risk, depends, demo,
237
- created_at, completed_at, full_summary_md, full_uat_md,
238
- goal, success_criteria, proof_level, integration_closure, observability_impact,
239
- sequence, replan_triggered_at)
240
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
241
- );
242
- for (const s of manifest.slices) {
243
- slStmt.run(
244
- s.milestone_id, s.id, s.title, s.status, s.risk,
245
- JSON.stringify(s.depends), s.demo,
246
- s.created_at, s.completed_at, s.full_summary_md, s.full_uat_md,
247
- s.goal, s.success_criteria, s.proof_level, s.integration_closure, s.observability_impact,
248
- s.sequence, s.replan_triggered_at,
249
- );
250
- }
251
-
252
- // Restore tasks
253
- const tkStmt = db.prepare(
254
- `INSERT INTO tasks (milestone_id, slice_id, id, title, status,
255
- one_liner, narrative, verification_result, duration, completed_at,
256
- blocker_discovered, deviations, known_issues, key_files, key_decisions,
257
- full_summary_md, description, estimate, files, verify,
258
- inputs, expected_output, observability_impact, sequence)
259
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
260
- );
261
- for (const t of manifest.tasks) {
262
- tkStmt.run(
263
- t.milestone_id, t.slice_id, t.id, t.title, t.status,
264
- t.one_liner, t.narrative, t.verification_result, t.duration, t.completed_at,
265
- t.blocker_discovered ? 1 : 0, t.deviations, t.known_issues,
266
- JSON.stringify(t.key_files), JSON.stringify(t.key_decisions),
267
- t.full_summary_md, t.description, t.estimate, JSON.stringify(t.files), t.verify,
268
- JSON.stringify(t.inputs), JSON.stringify(t.expected_output),
269
- t.observability_impact, t.sequence,
270
- );
271
- }
272
-
273
- // Restore decisions
274
- const dcStmt = db.prepare(
275
- `INSERT INTO decisions (seq, id, when_context, scope, decision, choice, rationale, revisable, made_by, superseded_by)
276
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
277
- );
278
- for (const d of manifest.decisions) {
279
- dcStmt.run(d.seq, d.id, d.when_context, d.scope, d.decision, d.choice, d.rationale, d.revisable, d.made_by, d.superseded_by);
280
- }
281
-
282
- // Restore verification evidence
283
- const evStmt = db.prepare(
284
- `INSERT INTO verification_evidence (task_id, slice_id, milestone_id, command, exit_code, verdict, duration_ms, created_at)
285
- VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
286
- );
287
- for (const e of manifest.verification_evidence) {
288
- evStmt.run(e.task_id, e.slice_id, e.milestone_id, e.command, e.exit_code, e.verdict, e.duration_ms, e.created_at);
289
- }
290
- });
291
- }
193
+ //
194
+ // The actual restore() implementation lives in gsd-db.ts (single-writer
195
+ // invariant). This module only orchestrates reading the manifest file
196
+ // and handing it to the writer.
292
197
 
293
198
  // ─── writeManifest ───────────────────────────────────────────────────────
294
199
 
@@ -346,6 +251,6 @@ export function bootstrapFromManifest(basePath: string): boolean {
346
251
  return false;
347
252
  }
348
253
 
349
- restore(manifest);
254
+ restoreManifest(manifest);
350
255
  return true;
351
256
  }
@@ -5,7 +5,7 @@
5
5
 
6
6
  import { existsSync, readdirSync, readFileSync } from "node:fs";
7
7
  import { join } from "node:path";
8
- import { _getAdapter, transaction } from "./gsd-db.js";
8
+ import { _getAdapter, bulkInsertLegacyHierarchy } from "./gsd-db.js";
9
9
  import { parseRoadmap, parsePlan } from "./parsers-legacy.js";
10
10
  import { logWarning } from "./workflow-logger.js";
11
11
 
@@ -219,34 +219,26 @@ export function migrateFromMarkdown(basePath: string): void {
219
219
  return;
220
220
  }
221
221
 
222
- const placeholders = migratedMilestoneIds.map(() => "?").join(",");
223
- transaction(() => {
224
- // Clear existing data to handle stale DB shape (DELETE ... IN (...))
225
- db.prepare(`DELETE FROM tasks WHERE milestone_id IN (${placeholders})`).run(...migratedMilestoneIds);
226
- db.prepare(`DELETE FROM slices WHERE milestone_id IN (${placeholders})`).run(...migratedMilestoneIds);
227
- db.prepare(`DELETE FROM milestones WHERE id IN (${placeholders})`).run(...migratedMilestoneIds);
228
-
229
- // Insert milestones
230
- const insertMilestone = db.prepare("INSERT INTO milestones (id, title, status, created_at) VALUES (?, ?, ?, ?)");
231
- for (const m of milestoneInserts) {
232
- insertMilestone.run(m.id, m.title, m.status, now);
233
- }
234
-
235
- // Insert slices (using v10 column names: depends, sequence)
236
- const insertSlice = db.prepare(
237
- "INSERT INTO slices (id, milestone_id, title, status, risk, depends, sequence, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"
238
- );
239
- for (const s of sliceInserts) {
240
- insertSlice.run(s.id, s.milestoneId, s.title, s.status, s.risk, "[]", s.sequence, now);
241
- }
242
-
243
- // Insert tasks (using v10 column names: sequence, blocker_discovered, full_summary_md)
244
- const insertTask = db.prepare(
245
- "INSERT INTO tasks (id, slice_id, milestone_id, title, description, status, estimate, files, sequence) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"
246
- );
247
- for (const t of taskInserts) {
248
- insertTask.run(t.id, t.sliceId, t.milestoneId, t.title, "", t.status, "", "[]", t.sequence);
249
- }
222
+ bulkInsertLegacyHierarchy({
223
+ milestones: milestoneInserts,
224
+ slices: sliceInserts.map(s => ({
225
+ id: s.id,
226
+ milestoneId: s.milestoneId,
227
+ title: s.title,
228
+ status: s.status,
229
+ risk: s.risk,
230
+ sequence: s.sequence,
231
+ })),
232
+ tasks: taskInserts.map(t => ({
233
+ id: t.id,
234
+ sliceId: t.sliceId,
235
+ milestoneId: t.milestoneId,
236
+ title: t.title,
237
+ status: t.status,
238
+ sequence: t.sequence,
239
+ })),
240
+ clearMilestoneIds: migratedMilestoneIds,
241
+ createdAt: now,
250
242
  });
251
243
  }
252
244
 
@@ -350,7 +350,14 @@ export async function renderStateProjection(basePath: string): Promise<void> {
350
350
  // Probe DB handle — adapter may be set but underlying handle closed
351
351
  const adapter = _getAdapter();
352
352
  if (!adapter) return;
353
- try { adapter.prepare("SELECT 1").get(); } catch { return; }
353
+ try {
354
+ adapter.prepare("SELECT 1").get();
355
+ } catch (err) {
356
+ logWarning("projection", "renderStateProjection: DB handle probe failed, skipping render", {
357
+ error: (err as Error).message,
358
+ });
359
+ return;
360
+ }
354
361
  const state = await deriveState(basePath);
355
362
  const content = renderStateContent(state);
356
363
  const dir = join(basePath, ".gsd");
@@ -10,12 +10,13 @@ import {
10
10
  updateMilestoneStatus,
11
11
  getSliceTasks,
12
12
  insertMilestone,
13
- _getAdapter,
14
13
  getMilestoneSlices,
15
14
  insertVerificationEvidence,
16
15
  upsertDecision,
17
16
  openDatabase,
18
17
  setTaskBlockerDiscovered,
18
+ insertOrIgnoreSlice,
19
+ insertOrIgnoreTask,
19
20
  } from "./gsd-db.js";
20
21
  import { isClosedStatus } from "./status-guards.js";
21
22
  import { invalidateStateCache } from "./state.js";
@@ -164,13 +165,12 @@ function replayEvents(events: WorkflowEvent[]): void {
164
165
  const milestoneId = p["milestoneId"] as string;
165
166
  const sliceId = p["sliceId"] as string;
166
167
  if (milestoneId && sliceId) {
167
- const adapter = _getAdapter();
168
- if (adapter) {
169
- adapter.prepare(
170
- `INSERT OR IGNORE INTO slices (milestone_id, id, title, status, created_at)
171
- VALUES (:mid, :sid, :title, 'pending', :ts)`,
172
- ).run({ ":mid": milestoneId, ":sid": sliceId, ":title": (p["title"] as string) ?? sliceId, ":ts": event.ts });
173
- }
168
+ insertOrIgnoreSlice({
169
+ milestoneId,
170
+ sliceId,
171
+ title: (p["title"] as string) ?? sliceId,
172
+ createdAt: event.ts,
173
+ });
174
174
  }
175
175
  break;
176
176
  }
@@ -182,13 +182,13 @@ function replayEvents(events: WorkflowEvent[]): void {
182
182
  const sliceId = p["sliceId"] as string;
183
183
  const taskId = p["taskId"] as string;
184
184
  if (milestoneId && sliceId && taskId) {
185
- const adapter = _getAdapter();
186
- if (adapter) {
187
- adapter.prepare(
188
- `INSERT OR IGNORE INTO tasks (milestone_id, slice_id, id, title, status, created_at)
189
- VALUES (:mid, :sid, :tid, :title, 'pending', :ts)`,
190
- ).run({ ":mid": milestoneId, ":sid": sliceId, ":tid": taskId, ":title": (p["title"] as string) ?? taskId, ":ts": event.ts });
191
- }
185
+ insertOrIgnoreTask({
186
+ milestoneId,
187
+ sliceId,
188
+ taskId,
189
+ title: (p["title"] as string) ?? taskId,
190
+ createdAt: event.ts,
191
+ });
192
192
  }
193
193
  break;
194
194
  }
@@ -9,9 +9,14 @@
9
9
  * available, testing all patterns in a single DFA pass. Falls back to
10
10
  * per-rule JS RegExp iteration when the native module is not loaded.
11
11
  */
12
- import picomatch from "picomatch";
12
+ import { createRequire } from "node:module";
13
13
  import { debugTime, debugCount, debugPeak } from "../gsd/debug-logger.js";
14
14
 
15
+ const _require = createRequire(import.meta.url);
16
+ type PicomatchMatcher = (input: string) => boolean;
17
+ type PicomatchFn = (pattern: string) => PicomatchMatcher;
18
+ const picomatch = _require("picomatch") as PicomatchFn;
19
+
15
20
  // ── Native TTSR engine (optional) ─────────────────────────────────────
16
21
  let nativeTtsr: {
17
22
  ttsrCompileRules: (rules: { name: string; conditions: string[] }[]) => number;
@@ -65,7 +70,7 @@ export interface TtsrSettings {
65
70
 
66
71
  interface ToolScope {
67
72
  toolName?: string;
68
- pathMatcher?: picomatch.Matcher;
73
+ pathMatcher?: PicomatchMatcher;
69
74
  pathPattern?: string;
70
75
  }
71
76
 
@@ -80,7 +85,7 @@ interface TtsrEntry {
80
85
  rule: Rule;
81
86
  conditions: RegExp[];
82
87
  scope: TtsrScope;
83
- globalPathMatchers?: picomatch.Matcher[];
88
+ globalPathMatchers?: PicomatchMatcher[];
84
89
  }
85
90
 
86
91
  /** Tracks when a rule was last injected (for repeat gating). */
@@ -147,7 +152,7 @@ export class TtsrManager {
147
152
  return compiled;
148
153
  }
149
154
 
150
- #compileGlobalPathMatchers(globs: Rule["globs"]): picomatch.Matcher[] | undefined {
155
+ #compileGlobalPathMatchers(globs: Rule["globs"]): PicomatchMatcher[] | undefined {
151
156
  if (!globs || globs.length === 0) return undefined;
152
157
  const matchers = globs
153
158
  .map((g) => g.trim())
@@ -239,7 +244,7 @@ export class TtsrManager {
239
244
  return pathValue.replaceAll("\\", "/");
240
245
  }
241
246
 
242
- #matchesGlob(matcher: picomatch.Matcher, filePaths: string[] | undefined): boolean {
247
+ #matchesGlob(matcher: PicomatchMatcher, filePaths: string[] | undefined): boolean {
243
248
  if (!filePaths || filePaths.length === 0) return false;
244
249
  for (const filePath of filePaths) {
245
250
  const normalized = this.#normalizePath(filePath);