gsd-pi 2.41.0-dev.0acbce9 → 2.41.0-dev.5a170d0

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 (291) hide show
  1. package/README.md +1 -1
  2. package/dist/cli-web-branch.d.ts +6 -0
  3. package/dist/cli-web-branch.js +17 -0
  4. package/dist/onboarding.js +2 -1
  5. package/dist/resources/extensions/gsd/auto/loop.js +89 -1
  6. package/dist/resources/extensions/gsd/auto/phases.js +28 -10
  7. package/dist/resources/extensions/gsd/auto/session.js +6 -0
  8. package/dist/resources/extensions/gsd/auto-dashboard.js +8 -2
  9. package/dist/resources/extensions/gsd/auto-dispatch.js +19 -2
  10. package/dist/resources/extensions/gsd/auto-post-unit.js +7 -0
  11. package/dist/resources/extensions/gsd/auto-recovery.js +12 -4
  12. package/dist/resources/extensions/gsd/auto-start.js +8 -3
  13. package/dist/resources/extensions/gsd/auto-worktree.js +147 -13
  14. package/dist/resources/extensions/gsd/auto.js +64 -2
  15. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +199 -164
  16. package/dist/resources/extensions/gsd/bootstrap/journal-tools.js +62 -0
  17. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +2 -0
  18. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +16 -0
  19. package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +7 -2
  20. package/dist/resources/extensions/gsd/commands/catalog.js +40 -1
  21. package/dist/resources/extensions/gsd/commands/handlers/core.js +1 -0
  22. package/dist/resources/extensions/gsd/commands/handlers/ops.js +5 -0
  23. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +146 -0
  24. package/dist/resources/extensions/gsd/context-injector.js +74 -0
  25. package/dist/resources/extensions/gsd/context-store.js +4 -3
  26. package/dist/resources/extensions/gsd/custom-execution-policy.js +47 -0
  27. package/dist/resources/extensions/gsd/custom-verification.js +145 -0
  28. package/dist/resources/extensions/gsd/custom-workflow-engine.js +164 -0
  29. package/dist/resources/extensions/gsd/dashboard-overlay.js +1 -0
  30. package/dist/resources/extensions/gsd/db-writer.js +5 -2
  31. package/dist/resources/extensions/gsd/definition-loader.js +352 -0
  32. package/dist/resources/extensions/gsd/detection.js +1 -1
  33. package/dist/resources/extensions/gsd/dev-execution-policy.js +24 -0
  34. package/dist/resources/extensions/gsd/dev-workflow-engine.js +82 -0
  35. package/dist/resources/extensions/gsd/doctor.js +11 -1
  36. package/dist/resources/extensions/gsd/engine-resolver.js +40 -0
  37. package/dist/resources/extensions/gsd/engine-types.js +8 -0
  38. package/dist/resources/extensions/gsd/execution-policy.js +8 -0
  39. package/dist/resources/extensions/gsd/exit-command.js +12 -2
  40. package/dist/resources/extensions/gsd/export.js +9 -13
  41. package/dist/resources/extensions/gsd/extension-manifest.json +2 -2
  42. package/dist/resources/extensions/gsd/files.js +28 -11
  43. package/dist/resources/extensions/gsd/forensics.js +10 -3
  44. package/dist/resources/extensions/gsd/git-service.js +5 -1
  45. package/dist/resources/extensions/gsd/graph.js +225 -0
  46. package/dist/resources/extensions/gsd/gsd-db.js +25 -8
  47. package/dist/resources/extensions/gsd/guided-flow-queue.js +1 -1
  48. package/dist/resources/extensions/gsd/guided-flow.js +7 -3
  49. package/dist/resources/extensions/gsd/journal.js +85 -0
  50. package/dist/resources/extensions/gsd/md-importer.js +5 -0
  51. package/dist/resources/extensions/gsd/milestone-ids.js +1 -1
  52. package/dist/resources/extensions/gsd/native-git-bridge.js +2 -2
  53. package/dist/resources/extensions/gsd/post-unit-hooks.js +24 -412
  54. package/dist/resources/extensions/gsd/preferences-types.js +1 -0
  55. package/dist/resources/extensions/gsd/preferences.js +1 -0
  56. package/dist/resources/extensions/gsd/prompt-loader.js +34 -4
  57. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +11 -10
  58. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +2 -2
  59. package/dist/resources/extensions/gsd/prompts/discuss.md +1 -1
  60. package/dist/resources/extensions/gsd/prompts/queue.md +1 -1
  61. package/dist/resources/extensions/gsd/repo-identity.js +46 -2
  62. package/dist/resources/extensions/gsd/rule-registry.js +489 -0
  63. package/dist/resources/extensions/gsd/rule-types.js +6 -0
  64. package/dist/resources/extensions/gsd/run-manager.js +134 -0
  65. package/dist/resources/extensions/gsd/service-tier.js +138 -0
  66. package/dist/resources/extensions/gsd/structured-data-formatter.js +2 -1
  67. package/dist/resources/extensions/gsd/templates/decisions.md +2 -2
  68. package/dist/resources/extensions/gsd/workflow-engine.js +7 -0
  69. package/dist/resources/extensions/gsd/workflow-templates.js +13 -1
  70. package/dist/resources/extensions/gsd/worktree-manager.js +20 -6
  71. package/dist/resources/extensions/gsd/worktree-resolver.js +19 -2
  72. package/dist/resources/extensions/subagent/index.js +7 -3
  73. package/dist/resources/extensions/voice/index.js +4 -4
  74. package/dist/resources/skills/create-workflow/SKILL.md +103 -0
  75. package/dist/resources/skills/create-workflow/references/feature-patterns.md +128 -0
  76. package/dist/resources/skills/create-workflow/references/verification-policies.md +76 -0
  77. package/dist/resources/skills/create-workflow/references/yaml-schema-v1.md +46 -0
  78. package/dist/resources/skills/create-workflow/templates/blog-post-pipeline.yaml +60 -0
  79. package/dist/resources/skills/create-workflow/templates/code-audit.yaml +60 -0
  80. package/dist/resources/skills/create-workflow/templates/release-checklist.yaml +66 -0
  81. package/dist/resources/skills/create-workflow/templates/workflow-definition.yaml +32 -0
  82. package/dist/resources/skills/create-workflow/workflows/create-from-scratch.md +104 -0
  83. package/dist/resources/skills/create-workflow/workflows/create-from-template.md +72 -0
  84. package/dist/web/standalone/.next/BUILD_ID +1 -1
  85. package/dist/web/standalone/.next/app-path-routes-manifest.json +16 -16
  86. package/dist/web/standalone/.next/build-manifest.json +3 -3
  87. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  88. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  89. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  90. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  91. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  92. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  93. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  94. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  95. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  96. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  97. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  98. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  99. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  100. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  101. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  102. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  103. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  104. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  105. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  106. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  107. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  108. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  109. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  110. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  111. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  112. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  113. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  114. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  115. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  116. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
  117. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +1 -1
  118. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  119. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  120. package/dist/web/standalone/.next/server/app/index.html +1 -1
  121. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  122. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  123. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  124. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  125. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  126. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  127. package/dist/web/standalone/.next/server/app-paths-manifest.json +16 -16
  128. package/dist/web/standalone/.next/server/chunks/229.js +3 -3
  129. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  130. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  132. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  133. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  134. package/dist/web/standalone/.next/static/chunks/4024.c195dc1fdd2adbea.js +9 -0
  135. package/dist/web/standalone/.next/static/chunks/{webpack-9afaaebf6042a1d7.js → webpack-fa307370fcf9fb2c.js} +1 -1
  136. package/dist/web-mode.d.ts +2 -0
  137. package/dist/web-mode.js +29 -7
  138. package/package.json +1 -1
  139. package/packages/native/src/__tests__/text.test.mjs +33 -0
  140. package/packages/pi-coding-agent/dist/core/discovery-cache.test.js +3 -1
  141. package/packages/pi-coding-agent/dist/core/discovery-cache.test.js.map +1 -1
  142. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  143. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js +10 -7
  144. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js.map +1 -1
  145. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  146. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +4 -0
  147. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  148. package/packages/pi-coding-agent/src/core/discovery-cache.test.ts +4 -2
  149. package/packages/pi-coding-agent/src/modes/interactive/components/login-dialog.ts +11 -7
  150. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +5 -0
  151. package/src/resources/extensions/gsd/auto/loop-deps.ts +5 -1
  152. package/src/resources/extensions/gsd/auto/loop.ts +101 -1
  153. package/src/resources/extensions/gsd/auto/phases.ts +30 -10
  154. package/src/resources/extensions/gsd/auto/session.ts +6 -0
  155. package/src/resources/extensions/gsd/auto/types.ts +4 -0
  156. package/src/resources/extensions/gsd/auto-dashboard.ts +9 -2
  157. package/src/resources/extensions/gsd/auto-dispatch.ts +25 -5
  158. package/src/resources/extensions/gsd/auto-post-unit.ts +8 -0
  159. package/src/resources/extensions/gsd/auto-recovery.ts +12 -4
  160. package/src/resources/extensions/gsd/auto-start.ts +8 -3
  161. package/src/resources/extensions/gsd/auto-worktree.ts +162 -18
  162. package/src/resources/extensions/gsd/auto.ts +71 -2
  163. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +209 -162
  164. package/src/resources/extensions/gsd/bootstrap/journal-tools.ts +62 -0
  165. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +2 -0
  166. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +13 -0
  167. package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +9 -2
  168. package/src/resources/extensions/gsd/commands/catalog.ts +40 -1
  169. package/src/resources/extensions/gsd/commands/handlers/core.ts +1 -0
  170. package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -0
  171. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +164 -0
  172. package/src/resources/extensions/gsd/context-injector.ts +100 -0
  173. package/src/resources/extensions/gsd/context-store.ts +4 -3
  174. package/src/resources/extensions/gsd/custom-execution-policy.ts +73 -0
  175. package/src/resources/extensions/gsd/custom-verification.ts +180 -0
  176. package/src/resources/extensions/gsd/custom-workflow-engine.ts +216 -0
  177. package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -0
  178. package/src/resources/extensions/gsd/db-writer.ts +6 -2
  179. package/src/resources/extensions/gsd/definition-loader.ts +462 -0
  180. package/src/resources/extensions/gsd/detection.ts +1 -1
  181. package/src/resources/extensions/gsd/dev-execution-policy.ts +51 -0
  182. package/src/resources/extensions/gsd/dev-workflow-engine.ts +110 -0
  183. package/src/resources/extensions/gsd/doctor.ts +12 -1
  184. package/src/resources/extensions/gsd/engine-resolver.ts +57 -0
  185. package/src/resources/extensions/gsd/engine-types.ts +71 -0
  186. package/src/resources/extensions/gsd/execution-policy.ts +43 -0
  187. package/src/resources/extensions/gsd/exit-command.ts +14 -2
  188. package/src/resources/extensions/gsd/export.ts +8 -15
  189. package/src/resources/extensions/gsd/extension-manifest.json +2 -2
  190. package/src/resources/extensions/gsd/files.ts +29 -12
  191. package/src/resources/extensions/gsd/forensics.ts +9 -3
  192. package/src/resources/extensions/gsd/git-service.ts +5 -4
  193. package/src/resources/extensions/gsd/graph.ts +312 -0
  194. package/src/resources/extensions/gsd/gsd-db.ts +37 -8
  195. package/src/resources/extensions/gsd/guided-flow-queue.ts +1 -1
  196. package/src/resources/extensions/gsd/guided-flow.ts +7 -3
  197. package/src/resources/extensions/gsd/journal.ts +134 -0
  198. package/src/resources/extensions/gsd/md-importer.ts +6 -0
  199. package/src/resources/extensions/gsd/milestone-ids.ts +1 -1
  200. package/src/resources/extensions/gsd/native-git-bridge.ts +2 -2
  201. package/src/resources/extensions/gsd/post-unit-hooks.ts +24 -462
  202. package/src/resources/extensions/gsd/preferences-types.ts +3 -0
  203. package/src/resources/extensions/gsd/preferences.ts +1 -0
  204. package/src/resources/extensions/gsd/prompt-loader.ts +35 -4
  205. package/src/resources/extensions/gsd/prompts/complete-milestone.md +11 -10
  206. package/src/resources/extensions/gsd/prompts/discuss-headless.md +2 -2
  207. package/src/resources/extensions/gsd/prompts/discuss.md +1 -1
  208. package/src/resources/extensions/gsd/prompts/queue.md +1 -1
  209. package/src/resources/extensions/gsd/repo-identity.ts +47 -2
  210. package/src/resources/extensions/gsd/rule-registry.ts +599 -0
  211. package/src/resources/extensions/gsd/rule-types.ts +68 -0
  212. package/src/resources/extensions/gsd/run-manager.ts +180 -0
  213. package/src/resources/extensions/gsd/service-tier.ts +171 -0
  214. package/src/resources/extensions/gsd/structured-data-formatter.ts +3 -1
  215. package/src/resources/extensions/gsd/templates/decisions.md +2 -2
  216. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +103 -120
  217. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +85 -0
  218. package/src/resources/extensions/gsd/tests/auto-secrets-gate.test.ts +2 -2
  219. package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +202 -0
  220. package/src/resources/extensions/gsd/tests/bundled-workflow-defs.test.ts +180 -0
  221. package/src/resources/extensions/gsd/tests/captures.test.ts +12 -1
  222. package/src/resources/extensions/gsd/tests/commands-workflow-custom.test.ts +283 -0
  223. package/src/resources/extensions/gsd/tests/context-injector.test.ts +313 -0
  224. package/src/resources/extensions/gsd/tests/context-store.test.ts +10 -5
  225. package/src/resources/extensions/gsd/tests/continue-here.test.ts +20 -20
  226. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +540 -0
  227. package/src/resources/extensions/gsd/tests/custom-verification.test.ts +382 -0
  228. package/src/resources/extensions/gsd/tests/custom-workflow-engine.test.ts +339 -0
  229. package/src/resources/extensions/gsd/tests/dashboard-custom-engine.test.ts +87 -0
  230. package/src/resources/extensions/gsd/tests/db-writer.test.ts +10 -0
  231. package/src/resources/extensions/gsd/tests/definition-loader.test.ts +778 -0
  232. package/src/resources/extensions/gsd/tests/dev-engine-wrapper.test.ts +318 -0
  233. package/src/resources/extensions/gsd/tests/doctor-completion-deferral.test.ts +15 -10
  234. package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +5 -4
  235. package/src/resources/extensions/gsd/tests/doctor-roadmap-summary-atomicity.test.ts +167 -0
  236. package/src/resources/extensions/gsd/tests/doctor-task-done-missing-summary-slice-loop.test.ts +174 -0
  237. package/src/resources/extensions/gsd/tests/e2e-workflow-pipeline-integration.test.ts +476 -0
  238. package/src/resources/extensions/gsd/tests/engine-interfaces-contract.test.ts +271 -0
  239. package/src/resources/extensions/gsd/tests/exit-command.test.ts +55 -0
  240. package/src/resources/extensions/gsd/tests/graph-operations.test.ts +599 -0
  241. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +8 -1
  242. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +7 -7
  243. package/src/resources/extensions/gsd/tests/iterate-engine-integration.test.ts +429 -0
  244. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +513 -0
  245. package/src/resources/extensions/gsd/tests/journal-query-tool.test.ts +147 -0
  246. package/src/resources/extensions/gsd/tests/journal.test.ts +386 -0
  247. package/src/resources/extensions/gsd/tests/md-importer.test.ts +31 -1
  248. package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
  249. package/src/resources/extensions/gsd/tests/milestone-id-reservation.test.ts +1 -1
  250. package/src/resources/extensions/gsd/tests/parsers.test.ts +110 -0
  251. package/src/resources/extensions/gsd/tests/preferences.test.ts +47 -25
  252. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +3 -1
  253. package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +61 -1
  254. package/src/resources/extensions/gsd/tests/routing-history.test.ts +11 -22
  255. package/src/resources/extensions/gsd/tests/rule-registry.test.ts +413 -0
  256. package/src/resources/extensions/gsd/tests/run-manager.test.ts +229 -0
  257. package/src/resources/extensions/gsd/tests/service-tier.test.ts +98 -0
  258. package/src/resources/extensions/gsd/tests/skill-lifecycle.test.ts +2 -2
  259. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +102 -0
  260. package/src/resources/extensions/gsd/tests/structured-data-formatter.test.ts +4 -3
  261. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +45 -0
  262. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +117 -0
  263. package/src/resources/extensions/gsd/tests/triage-dispatch.test.ts +6 -1
  264. package/src/resources/extensions/gsd/tests/windows-path-normalization.test.ts +99 -0
  265. package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +1 -0
  266. package/src/resources/extensions/gsd/tests/worktree-db.test.ts +4 -0
  267. package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +178 -0
  268. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +195 -105
  269. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +78 -3
  270. package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +140 -0
  271. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +74 -0
  272. package/src/resources/extensions/gsd/types.ts +3 -0
  273. package/src/resources/extensions/gsd/workflow-engine.ts +38 -0
  274. package/src/resources/extensions/gsd/workflow-templates.ts +12 -1
  275. package/src/resources/extensions/gsd/worktree-manager.ts +21 -6
  276. package/src/resources/extensions/gsd/worktree-resolver.ts +30 -9
  277. package/src/resources/extensions/subagent/index.ts +7 -3
  278. package/src/resources/extensions/voice/index.ts +4 -4
  279. package/src/resources/skills/create-workflow/SKILL.md +103 -0
  280. package/src/resources/skills/create-workflow/references/feature-patterns.md +128 -0
  281. package/src/resources/skills/create-workflow/references/verification-policies.md +76 -0
  282. package/src/resources/skills/create-workflow/references/yaml-schema-v1.md +46 -0
  283. package/src/resources/skills/create-workflow/templates/blog-post-pipeline.yaml +60 -0
  284. package/src/resources/skills/create-workflow/templates/code-audit.yaml +60 -0
  285. package/src/resources/skills/create-workflow/templates/release-checklist.yaml +66 -0
  286. package/src/resources/skills/create-workflow/templates/workflow-definition.yaml +32 -0
  287. package/src/resources/skills/create-workflow/workflows/create-from-scratch.md +104 -0
  288. package/src/resources/skills/create-workflow/workflows/create-from-template.md +72 -0
  289. package/dist/web/standalone/.next/static/chunks/4024.279c423e4661ece1.js +0 -9
  290. /package/dist/web/standalone/.next/static/{SwbKZ7JPNFlEmU4f8pKEv → K7GYOOPvQWX6TKYEKhODM}/_buildManifest.js +0 -0
  291. /package/dist/web/standalone/.next/static/{SwbKZ7JPNFlEmU4f8pKEv → K7GYOOPvQWX6TKYEKhODM}/_ssgManifest.js +0 -0
@@ -0,0 +1,599 @@
1
+ /**
2
+ * graph-operations.test.ts — Comprehensive tests for graph.ts DAG operations.
3
+ *
4
+ * Covers: YAML I/O round-trips, DAG queries (getNextPendingStep),
5
+ * immutable step completion, iteration expansion with downstream dep
6
+ * rewriting, initializeGraph conversion, and atomic write safety.
7
+ */
8
+
9
+ import { describe, it } from "node:test";
10
+ import assert from "node:assert/strict";
11
+ import { mkdtempSync, rmSync, readFileSync, writeFileSync, existsSync } from "node:fs";
12
+ import { join } from "node:path";
13
+ import { tmpdir } from "node:os";
14
+
15
+ import {
16
+ readGraph,
17
+ writeGraph,
18
+ getNextPendingStep,
19
+ markStepComplete,
20
+ expandIteration,
21
+ initializeGraph,
22
+ graphFromDefinition,
23
+ type WorkflowGraph,
24
+ type GraphStep,
25
+ } from "../graph.ts";
26
+ import type { WorkflowDefinition } from "../definition-loader.ts";
27
+
28
+ // ─── Helpers ─────────────────────────────────────────────────────────────
29
+
30
+ function makeTmpDir(): string {
31
+ return mkdtempSync(join(tmpdir(), "graph-test-"));
32
+ }
33
+
34
+ function cleanupDir(dir: string): void {
35
+ try { rmSync(dir, { recursive: true, force: true, maxRetries: 3, retryDelay: 100 }); } catch { /* Windows EPERM */ }
36
+ }
37
+
38
+ /** Minimal valid graph for testing. */
39
+ function makeGraph(steps: GraphStep[], name = "test-workflow"): WorkflowGraph {
40
+ return {
41
+ steps,
42
+ metadata: { name, createdAt: "2026-01-01T00:00:00.000Z" },
43
+ };
44
+ }
45
+
46
+ function makeStep(overrides: Partial<GraphStep> & { id: string }): GraphStep {
47
+ return {
48
+ title: overrides.id,
49
+ status: "pending",
50
+ prompt: `Do ${overrides.id}`,
51
+ dependsOn: [],
52
+ ...overrides,
53
+ };
54
+ }
55
+
56
+ // ─── writeGraph + readGraph round-trip ───────────────────────────────────
57
+
58
+ describe("writeGraph + readGraph round-trip", () => {
59
+ it("preserves all fields including parentStepId and dependsOn", () => {
60
+ const dir = makeTmpDir();
61
+ try {
62
+ const graph = makeGraph([
63
+ makeStep({ id: "step-1", title: "First Step", dependsOn: [] }),
64
+ makeStep({
65
+ id: "step-2",
66
+ title: "Second Step",
67
+ dependsOn: ["step-1"],
68
+ parentStepId: "parent-iter",
69
+ }),
70
+ ]);
71
+
72
+ writeGraph(dir, graph);
73
+ const loaded = readGraph(dir);
74
+
75
+ assert.equal(loaded.steps.length, 2);
76
+ assert.equal(loaded.steps[0].id, "step-1");
77
+ assert.equal(loaded.steps[0].title, "First Step");
78
+ assert.equal(loaded.steps[0].status, "pending");
79
+ assert.deepStrictEqual(loaded.steps[0].dependsOn, []);
80
+
81
+ assert.equal(loaded.steps[1].id, "step-2");
82
+ assert.deepStrictEqual(loaded.steps[1].dependsOn, ["step-1"]);
83
+ assert.equal(loaded.steps[1].parentStepId, "parent-iter");
84
+
85
+ assert.equal(loaded.metadata.name, "test-workflow");
86
+ assert.equal(loaded.metadata.createdAt, "2026-01-01T00:00:00.000Z");
87
+ } finally {
88
+ cleanupDir(dir);
89
+ }
90
+ });
91
+
92
+ it("preserves startedAt and finishedAt fields", () => {
93
+ const dir = makeTmpDir();
94
+ try {
95
+ const graph = makeGraph([
96
+ makeStep({
97
+ id: "s1",
98
+ status: "complete",
99
+ startedAt: "2026-01-01T01:00:00.000Z",
100
+ finishedAt: "2026-01-01T01:05:00.000Z",
101
+ }),
102
+ ]);
103
+ writeGraph(dir, graph);
104
+ const loaded = readGraph(dir);
105
+
106
+ assert.equal(loaded.steps[0].startedAt, "2026-01-01T01:00:00.000Z");
107
+ assert.equal(loaded.steps[0].finishedAt, "2026-01-01T01:05:00.000Z");
108
+ } finally {
109
+ cleanupDir(dir);
110
+ }
111
+ });
112
+
113
+ it("creates directory if it does not exist", () => {
114
+ const base = makeTmpDir();
115
+ const nested = join(base, "sub", "dir");
116
+ try {
117
+ const graph = makeGraph([makeStep({ id: "s1" })]);
118
+ writeGraph(nested, graph);
119
+ assert.ok(existsSync(join(nested, "GRAPH.yaml")));
120
+
121
+ const loaded = readGraph(nested);
122
+ assert.equal(loaded.steps[0].id, "s1");
123
+ } finally {
124
+ cleanupDir(base);
125
+ }
126
+ });
127
+ });
128
+
129
+ // ─── readGraph error paths ───────────────────────────────────────────────
130
+
131
+ describe("readGraph error paths", () => {
132
+ it("throws with descriptive error when file is missing", () => {
133
+ const dir = makeTmpDir();
134
+ try {
135
+ assert.throws(
136
+ () => readGraph(dir),
137
+ (err: Error) => {
138
+ assert.ok(err.message.includes("GRAPH.yaml not found"));
139
+ assert.ok(err.message.includes(dir));
140
+ return true;
141
+ },
142
+ );
143
+ } finally {
144
+ cleanupDir(dir);
145
+ }
146
+ });
147
+
148
+ it("throws with descriptive error when YAML is malformed (missing steps)", () => {
149
+ const dir = makeTmpDir();
150
+ try {
151
+ writeFileSync(join(dir, "GRAPH.yaml"), "metadata:\n name: bad\n", "utf-8");
152
+ assert.throws(
153
+ () => readGraph(dir),
154
+ (err: Error) => {
155
+ assert.ok(err.message.includes("missing or invalid 'steps' array"));
156
+ return true;
157
+ },
158
+ );
159
+ } finally {
160
+ cleanupDir(dir);
161
+ }
162
+ });
163
+
164
+ it("throws when steps is not an array", () => {
165
+ const dir = makeTmpDir();
166
+ try {
167
+ writeFileSync(join(dir, "GRAPH.yaml"), "steps: not-an-array\nmetadata:\n name: bad\n", "utf-8");
168
+ assert.throws(
169
+ () => readGraph(dir),
170
+ (err: Error) => {
171
+ assert.ok(err.message.includes("missing or invalid 'steps' array"));
172
+ return true;
173
+ },
174
+ );
175
+ } finally {
176
+ cleanupDir(dir);
177
+ }
178
+ });
179
+ });
180
+
181
+ // ─── getNextPendingStep ──────────────────────────────────────────────────
182
+
183
+ describe("getNextPendingStep", () => {
184
+ it("returns first step with all deps complete", () => {
185
+ const graph = makeGraph([
186
+ makeStep({ id: "a", status: "complete" }),
187
+ makeStep({ id: "b", dependsOn: ["a"] }),
188
+ makeStep({ id: "c", dependsOn: ["b"] }),
189
+ ]);
190
+
191
+ const next = getNextPendingStep(graph);
192
+ assert.equal(next?.id, "b");
193
+ });
194
+
195
+ it("skips steps with incomplete deps", () => {
196
+ const graph = makeGraph([
197
+ makeStep({ id: "a" }),
198
+ makeStep({ id: "b", dependsOn: ["a"] }),
199
+ ]);
200
+
201
+ // 'a' is still pending, so 'b' is blocked, but 'a' has no deps → returns 'a'
202
+ const next = getNextPendingStep(graph);
203
+ assert.equal(next?.id, "a");
204
+ });
205
+
206
+ it("returns null when all steps are complete", () => {
207
+ const graph = makeGraph([
208
+ makeStep({ id: "a", status: "complete" }),
209
+ makeStep({ id: "b", status: "complete" }),
210
+ ]);
211
+
212
+ assert.equal(getNextPendingStep(graph), null);
213
+ });
214
+
215
+ it("returns null when all pending steps are blocked", () => {
216
+ const graph = makeGraph([
217
+ makeStep({ id: "a", status: "active" }), // not complete
218
+ makeStep({ id: "b", dependsOn: ["a"] }), // blocked
219
+ ]);
220
+
221
+ assert.equal(getNextPendingStep(graph), null);
222
+ });
223
+
224
+ it("returns first pending step with no deps when root steps exist", () => {
225
+ const graph = makeGraph([
226
+ makeStep({ id: "a" }),
227
+ makeStep({ id: "b" }),
228
+ ]);
229
+
230
+ const next = getNextPendingStep(graph);
231
+ assert.equal(next?.id, "a");
232
+ });
233
+
234
+ it("skips expanded steps", () => {
235
+ const graph = makeGraph([
236
+ makeStep({ id: "a", status: "expanded" }),
237
+ makeStep({ id: "b" }),
238
+ ]);
239
+
240
+ const next = getNextPendingStep(graph);
241
+ assert.equal(next?.id, "b");
242
+ });
243
+ });
244
+
245
+ // ─── markStepComplete ────────────────────────────────────────────────────
246
+
247
+ describe("markStepComplete", () => {
248
+ it("returns new graph with step status 'complete' (original unchanged)", () => {
249
+ const original = makeGraph([
250
+ makeStep({ id: "a" }),
251
+ makeStep({ id: "b" }),
252
+ ]);
253
+
254
+ const updated = markStepComplete(original, "a");
255
+
256
+ // Original is untouched
257
+ assert.equal(original.steps[0].status, "pending");
258
+
259
+ // New graph has the step complete
260
+ assert.equal(updated.steps[0].status, "complete");
261
+ assert.equal(updated.steps[0].id, "a");
262
+
263
+ // Other steps unchanged
264
+ assert.equal(updated.steps[1].status, "pending");
265
+ });
266
+
267
+ it("sets finishedAt timestamp", () => {
268
+ const graph = makeGraph([makeStep({ id: "a" })]);
269
+ const updated = markStepComplete(graph, "a");
270
+ assert.ok(updated.steps[0].finishedAt);
271
+ // Should be a valid ISO string
272
+ assert.ok(!isNaN(Date.parse(updated.steps[0].finishedAt!)));
273
+ });
274
+
275
+ it("throws for unknown step ID", () => {
276
+ const graph = makeGraph([makeStep({ id: "a" })]);
277
+ assert.throws(
278
+ () => markStepComplete(graph, "nonexistent"),
279
+ (err: Error) => {
280
+ assert.ok(err.message.includes("Step not found"));
281
+ assert.ok(err.message.includes("nonexistent"));
282
+ return true;
283
+ },
284
+ );
285
+ });
286
+
287
+ it("preserves metadata in returned graph", () => {
288
+ const graph = makeGraph([makeStep({ id: "a" })], "my-workflow");
289
+ const updated = markStepComplete(graph, "a");
290
+ assert.equal(updated.metadata.name, "my-workflow");
291
+ assert.equal(updated.metadata.createdAt, "2026-01-01T00:00:00.000Z");
292
+ });
293
+ });
294
+
295
+ // ─── expandIteration ─────────────────────────────────────────────────────
296
+
297
+ describe("expandIteration", () => {
298
+ it("creates instance steps with correct IDs (stepId--001, stepId--002)", () => {
299
+ const graph = makeGraph([
300
+ makeStep({ id: "iter-step", title: "Process items" }),
301
+ makeStep({ id: "final", dependsOn: ["iter-step"] }),
302
+ ]);
303
+
304
+ const expanded = expandIteration(
305
+ graph,
306
+ "iter-step",
307
+ ["apple", "banana", "cherry"],
308
+ "Process {{item}}",
309
+ );
310
+
311
+ // Parent + 3 instances + final = 5 steps
312
+ assert.equal(expanded.steps.length, 5);
313
+
314
+ // Instances are correctly named
315
+ assert.equal(expanded.steps[1].id, "iter-step--001");
316
+ assert.equal(expanded.steps[2].id, "iter-step--002");
317
+ assert.equal(expanded.steps[3].id, "iter-step--003");
318
+ });
319
+
320
+ it("marks parent step as 'expanded'", () => {
321
+ const graph = makeGraph([
322
+ makeStep({ id: "iter", title: "Iterate" }),
323
+ ]);
324
+
325
+ const expanded = expandIteration(graph, "iter", ["a"], "Do {{item}}");
326
+ assert.equal(expanded.steps[0].status, "expanded");
327
+ });
328
+
329
+ it("instance steps have correct titles, prompts, parentStepId, and deps", () => {
330
+ const graph = makeGraph([
331
+ makeStep({ id: "pre", status: "complete" }),
332
+ makeStep({ id: "iter", title: "Process", dependsOn: ["pre"] }),
333
+ ]);
334
+
335
+ const expanded = expandIteration(
336
+ graph,
337
+ "iter",
338
+ ["foo", "bar"],
339
+ "Handle {{item}} carefully",
340
+ );
341
+
342
+ const inst1 = expanded.steps[2]; // after pre and expanded parent
343
+ assert.equal(inst1.title, "Process: foo");
344
+ assert.equal(inst1.prompt, "Handle foo carefully");
345
+ assert.equal(inst1.parentStepId, "iter");
346
+ assert.deepStrictEqual(inst1.dependsOn, ["pre"]);
347
+ assert.equal(inst1.status, "pending");
348
+
349
+ const inst2 = expanded.steps[3];
350
+ assert.equal(inst2.title, "Process: bar");
351
+ assert.equal(inst2.prompt, "Handle bar carefully");
352
+ assert.equal(inst2.parentStepId, "iter");
353
+ });
354
+
355
+ it("rewrites downstream deps from parent ID to all instance IDs", () => {
356
+ const graph = makeGraph([
357
+ makeStep({ id: "iter", title: "Iterate" }),
358
+ makeStep({ id: "after", dependsOn: ["iter"] }),
359
+ ]);
360
+
361
+ const expanded = expandIteration(
362
+ graph,
363
+ "iter",
364
+ ["x", "y"],
365
+ "Do {{item}}",
366
+ );
367
+
368
+ // 'after' should now depend on iter--001 and iter--002
369
+ const afterStep = expanded.steps.find((s) => s.id === "after")!;
370
+ assert.deepStrictEqual(afterStep.dependsOn, ["iter--001", "iter--002"]);
371
+ });
372
+
373
+ it("preserves steps that don't depend on the parent", () => {
374
+ const graph = makeGraph([
375
+ makeStep({ id: "unrelated" }),
376
+ makeStep({ id: "iter", title: "Iterate" }),
377
+ makeStep({ id: "after", dependsOn: ["iter"] }),
378
+ ]);
379
+
380
+ const expanded = expandIteration(graph, "iter", ["a"], "{{item}}");
381
+ const unrelated = expanded.steps.find((s) => s.id === "unrelated")!;
382
+ assert.deepStrictEqual(unrelated.dependsOn, []);
383
+ });
384
+
385
+ it("throws for non-pending parent step", () => {
386
+ const graph = makeGraph([
387
+ makeStep({ id: "iter", status: "complete" }),
388
+ ]);
389
+
390
+ assert.throws(
391
+ () => expandIteration(graph, "iter", ["a"], "{{item}}"),
392
+ (err: Error) => {
393
+ assert.ok(err.message.includes("complete"));
394
+ assert.ok(err.message.includes("expected \"pending\""));
395
+ return true;
396
+ },
397
+ );
398
+ });
399
+
400
+ it("throws for unknown step ID", () => {
401
+ const graph = makeGraph([makeStep({ id: "a" })]);
402
+ assert.throws(
403
+ () => expandIteration(graph, "nonexistent", ["a"], "{{item}}"),
404
+ (err: Error) => {
405
+ assert.ok(err.message.includes("step not found"));
406
+ assert.ok(err.message.includes("nonexistent"));
407
+ return true;
408
+ },
409
+ );
410
+ });
411
+
412
+ it("does not mutate the input graph", () => {
413
+ const graph = makeGraph([
414
+ makeStep({ id: "iter", title: "Iterate" }),
415
+ makeStep({ id: "after", dependsOn: ["iter"] }),
416
+ ]);
417
+
418
+ const originalStepsLength = graph.steps.length;
419
+ const originalAfterDeps = [...graph.steps[1].dependsOn];
420
+
421
+ expandIteration(graph, "iter", ["a", "b"], "{{item}}");
422
+
423
+ // Original unchanged
424
+ assert.equal(graph.steps.length, originalStepsLength);
425
+ assert.equal(graph.steps[0].status, "pending");
426
+ assert.deepStrictEqual(graph.steps[1].dependsOn, originalAfterDeps);
427
+ });
428
+ });
429
+
430
+ // ─── initializeGraph ─────────────────────────────────────────────────────
431
+
432
+ describe("initializeGraph", () => {
433
+ it("converts a valid 3-step definition to graph with all pending steps", () => {
434
+ const def: WorkflowDefinition = {
435
+ version: 1,
436
+ name: "test-workflow",
437
+ steps: [
438
+ { id: "s1", name: "Step One", prompt: "Do step one", requires: [], produces: ["out.md"] },
439
+ { id: "s2", name: "Step Two", prompt: "Do step two", requires: ["s1"], produces: [] },
440
+ { id: "s3", name: "Step Three", prompt: "Do step three", requires: ["s1", "s2"], produces: [] },
441
+ ],
442
+ };
443
+
444
+ const graph = initializeGraph(def);
445
+
446
+ assert.equal(graph.steps.length, 3);
447
+ assert.equal(graph.metadata.name, "test-workflow");
448
+ assert.ok(graph.metadata.createdAt); // ISO string
449
+
450
+ // All pending
451
+ for (const step of graph.steps) {
452
+ assert.equal(step.status, "pending");
453
+ }
454
+
455
+ // Correct mapping
456
+ assert.equal(graph.steps[0].id, "s1");
457
+ assert.equal(graph.steps[0].title, "Step One");
458
+ assert.equal(graph.steps[0].prompt, "Do step one");
459
+ assert.deepStrictEqual(graph.steps[0].dependsOn, []);
460
+
461
+ assert.equal(graph.steps[1].id, "s2");
462
+ assert.deepStrictEqual(graph.steps[1].dependsOn, ["s1"]);
463
+
464
+ assert.equal(graph.steps[2].id, "s3");
465
+ assert.deepStrictEqual(graph.steps[2].dependsOn, ["s1", "s2"]);
466
+ });
467
+
468
+ it("is also exported as graphFromDefinition (backward compat)", () => {
469
+ assert.equal(graphFromDefinition, initializeGraph);
470
+ });
471
+ });
472
+
473
+ // ─── Atomic write safety ─────────────────────────────────────────────────
474
+
475
+ describe("atomic write safety", () => {
476
+ it("final file exists and .tmp file does not exist after write", () => {
477
+ const dir = makeTmpDir();
478
+ try {
479
+ const graph = makeGraph([makeStep({ id: "s1" })]);
480
+ writeGraph(dir, graph);
481
+
482
+ assert.ok(existsSync(join(dir, "GRAPH.yaml")));
483
+ assert.ok(!existsSync(join(dir, "GRAPH.yaml.tmp")));
484
+ } finally {
485
+ cleanupDir(dir);
486
+ }
487
+ });
488
+
489
+ it("YAML content is valid and parseable", () => {
490
+ const dir = makeTmpDir();
491
+ try {
492
+ const graph = makeGraph([makeStep({ id: "s1" })]);
493
+ writeGraph(dir, graph);
494
+
495
+ const content = readFileSync(join(dir, "GRAPH.yaml"), "utf-8");
496
+ // Should contain snake_case keys
497
+ assert.ok(content.includes("created_at"));
498
+ // Should not contain camelCase keys
499
+ assert.ok(!content.includes("createdAt"));
500
+ assert.ok(!content.includes("dependsOn"));
501
+ } finally {
502
+ cleanupDir(dir);
503
+ }
504
+ });
505
+ });
506
+
507
+ // ─── YAML snake_case / camelCase boundary ────────────────────────────────
508
+
509
+ describe("YAML snake_case / camelCase boundary", () => {
510
+ it("writes snake_case to disk and reads back as camelCase", () => {
511
+ const dir = makeTmpDir();
512
+ try {
513
+ const graph = makeGraph([
514
+ makeStep({
515
+ id: "s1",
516
+ dependsOn: ["s0"],
517
+ parentStepId: "parent",
518
+ startedAt: "2026-01-01T00:00:00Z",
519
+ finishedAt: "2026-01-01T00:01:00Z",
520
+ }),
521
+ ]);
522
+
523
+ writeGraph(dir, graph);
524
+
525
+ // Verify raw YAML uses snake_case
526
+ const raw = readFileSync(join(dir, "GRAPH.yaml"), "utf-8");
527
+ assert.ok(raw.includes("depends_on"));
528
+ assert.ok(raw.includes("parent_step_id"));
529
+ assert.ok(raw.includes("started_at"));
530
+ assert.ok(raw.includes("finished_at"));
531
+ assert.ok(raw.includes("created_at"));
532
+
533
+ // Verify read returns camelCase
534
+ const loaded = readGraph(dir);
535
+ assert.deepStrictEqual(loaded.steps[0].dependsOn, ["s0"]);
536
+ assert.equal(loaded.steps[0].parentStepId, "parent");
537
+ assert.equal(loaded.steps[0].startedAt, "2026-01-01T00:00:00Z");
538
+ assert.equal(loaded.steps[0].finishedAt, "2026-01-01T00:01:00Z");
539
+ } finally {
540
+ cleanupDir(dir);
541
+ }
542
+ });
543
+
544
+ it("omits optional fields from YAML when undefined", () => {
545
+ const dir = makeTmpDir();
546
+ try {
547
+ const graph = makeGraph([
548
+ makeStep({ id: "s1" }),
549
+ ]);
550
+
551
+ writeGraph(dir, graph);
552
+ const raw = readFileSync(join(dir, "GRAPH.yaml"), "utf-8");
553
+
554
+ // No depends_on, parent_step_id, started_at, finished_at when undefined/empty
555
+ assert.ok(!raw.includes("depends_on"));
556
+ assert.ok(!raw.includes("parent_step_id"));
557
+ assert.ok(!raw.includes("started_at"));
558
+ assert.ok(!raw.includes("finished_at"));
559
+ } finally {
560
+ cleanupDir(dir);
561
+ }
562
+ });
563
+ });
564
+
565
+ // ─── Edge cases ──────────────────────────────────────────────────────────
566
+
567
+ describe("edge cases", () => {
568
+ it("handles empty items array in expandIteration", () => {
569
+ const graph = makeGraph([
570
+ makeStep({ id: "iter" }),
571
+ ]);
572
+
573
+ const expanded = expandIteration(graph, "iter", [], "{{item}}");
574
+ // Parent marked expanded, no instances created
575
+ assert.equal(expanded.steps.length, 1);
576
+ assert.equal(expanded.steps[0].status, "expanded");
577
+ });
578
+
579
+ it("handles graph with single step", () => {
580
+ const graph = makeGraph([makeStep({ id: "only" })]);
581
+ const next = getNextPendingStep(graph);
582
+ assert.equal(next?.id, "only");
583
+
584
+ const completed = markStepComplete(graph, "only");
585
+ assert.equal(getNextPendingStep(completed), null);
586
+ });
587
+
588
+ it("initializeGraph handles steps with empty requires", () => {
589
+ const def: WorkflowDefinition = {
590
+ version: 1,
591
+ name: "empty-requires",
592
+ steps: [
593
+ { id: "s1", name: "Step", prompt: "Go", requires: [], produces: [] },
594
+ ],
595
+ };
596
+ const graph = initializeGraph(def);
597
+ assert.deepStrictEqual(graph.steps[0].dependsOn, []);
598
+ });
599
+ });
@@ -66,7 +66,7 @@ console.log('\n=== gsd-db: fresh DB schema init (memory) ===');
66
66
  // Check schema_version table
67
67
  const adapter = _getAdapter()!;
68
68
  const version = adapter.prepare('SELECT MAX(version) as version FROM schema_version').get();
69
- assertEq(version?.['version'], 3, 'schema version should be 3');
69
+ assertEq(version?.['version'], 4, 'schema version should be 4');
70
70
 
71
71
  // Check tables exist by querying them
72
72
  const dRows = adapter.prepare('SELECT count(*) as cnt FROM decisions').get();
@@ -93,6 +93,7 @@ console.log('\n=== gsd-db: double-init idempotency ===');
93
93
  choice: 'option A',
94
94
  rationale: 'because',
95
95
  revisable: 'yes',
96
+ made_by: 'agent',
96
97
  superseded_by: null,
97
98
  });
98
99
 
@@ -123,6 +124,7 @@ console.log('\n=== gsd-db: insert + get decision ===');
123
124
  choice: 'node:sqlite',
124
125
  rationale: 'built-in, zero deps',
125
126
  revisable: 'yes, if perf insufficient',
127
+ made_by: 'agent',
126
128
  superseded_by: null,
127
129
  });
128
130
 
@@ -186,6 +188,7 @@ console.log('\n=== gsd-db: active_decisions view excludes superseded ===');
186
188
  choice: 'JSON',
187
189
  rationale: 'simple',
188
190
  revisable: 'yes',
191
+ made_by: 'agent',
189
192
  superseded_by: 'D002', // superseded!
190
193
  });
191
194
 
@@ -197,6 +200,7 @@ console.log('\n=== gsd-db: active_decisions view excludes superseded ===');
197
200
  choice: 'SQLite',
198
201
  rationale: 'better querying',
199
202
  revisable: 'yes',
203
+ made_by: 'agent',
200
204
  superseded_by: null, // active
201
205
  });
202
206
 
@@ -208,6 +212,7 @@ console.log('\n=== gsd-db: active_decisions view excludes superseded ===');
208
212
  choice: 'WAL',
209
213
  rationale: 'concurrent reads',
210
214
  revisable: 'no',
215
+ made_by: 'agent',
211
216
  superseded_by: null, // active
212
217
  });
213
218
 
@@ -294,6 +299,7 @@ console.log('\n=== gsd-db: transaction rollback on error ===');
294
299
  choice: 'test',
295
300
  rationale: 'test',
296
301
  revisable: 'test',
302
+ made_by: 'agent',
297
303
  superseded_by: null,
298
304
  });
299
305
 
@@ -309,6 +315,7 @@ console.log('\n=== gsd-db: transaction rollback on error ===');
309
315
  choice: 'test',
310
316
  rationale: 'test',
311
317
  revisable: 'test',
318
+ made_by: 'agent',
312
319
  superseded_by: null,
313
320
  });
314
321
  throw new Error('intentional failure');