gsd-pi 2.44.0-dev.848dd4c → 2.44.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (298) hide show
  1. package/README.md +12 -30
  2. package/dist/resources/extensions/gsd/auto-start.js +0 -10
  3. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +0 -5
  4. package/dist/web/standalone/.next/BUILD_ID +1 -1
  5. package/dist/web/standalone/.next/app-path-routes-manifest.json +14 -14
  6. package/dist/web/standalone/.next/build-manifest.json +3 -3
  7. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  8. package/dist/web/standalone/.next/required-server-files.json +3 -3
  9. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  10. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  11. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  12. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  13. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  14. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  15. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  16. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  17. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  18. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  19. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  20. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  21. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  22. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  23. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  24. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  25. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  26. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  27. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  28. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  29. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  30. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  31. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  32. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  33. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  34. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  35. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  36. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  37. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  38. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  39. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  40. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  41. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  42. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  43. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  44. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  45. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  46. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  47. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  48. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  49. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  50. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  51. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  52. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  53. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  54. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  55. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  56. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  57. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  58. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  59. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  60. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  61. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  62. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  63. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  64. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  65. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  66. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  67. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  68. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  69. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  70. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  71. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  72. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  73. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +5 -5
  74. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  75. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  76. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  77. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  78. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  79. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  80. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  81. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  82. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  83. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  84. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  85. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  86. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  87. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  88. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  89. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  90. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  91. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  92. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  93. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  94. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  95. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  96. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  97. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  98. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  99. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  100. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  101. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  102. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  103. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  104. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  105. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  106. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  107. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  108. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  109. package/dist/web/standalone/.next/server/app/index.html +1 -1
  110. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  111. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  112. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  113. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  114. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  115. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  116. package/dist/web/standalone/.next/server/app/page.js +2 -2
  117. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  118. package/dist/web/standalone/.next/server/app-paths-manifest.json +14 -14
  119. package/dist/web/standalone/.next/server/chunks/229.js +1 -1
  120. package/dist/web/standalone/.next/server/chunks/471.js +3 -3
  121. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  122. package/dist/web/standalone/.next/server/middleware.js +2 -2
  123. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  124. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  125. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  126. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  127. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  128. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-f2a7482d42a5614b.js → page-2f24283c162b6ab3.js} +1 -1
  129. package/dist/web/standalone/.next/static/chunks/app/{layout-a16c7a7ecdf0c2cf.js → layout-9ecfd95f343793f0.js} +1 -1
  130. package/dist/web/standalone/.next/static/chunks/app/page-7e9530a7122506c5.js +1 -0
  131. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +1 -0
  132. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +1 -0
  133. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  134. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  135. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  136. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  137. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  138. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  139. package/dist/web/standalone/server.js +1 -1
  140. package/package.json +1 -1
  141. package/packages/pi-coding-agent/dist/core/auth-storage.test.js +8 -6
  142. package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
  143. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +26 -24
  144. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
  145. package/packages/pi-coding-agent/dist/core/fs-utils.test.js +48 -29
  146. package/packages/pi-coding-agent/dist/core/fs-utils.test.js.map +1 -1
  147. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js +44 -34
  148. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js.map +1 -1
  149. package/packages/pi-coding-agent/dist/core/session-manager.test.js +34 -30
  150. package/packages/pi-coding-agent/dist/core/session-manager.test.js.map +1 -1
  151. package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js +12 -10
  152. package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js.map +1 -1
  153. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js +47 -43
  154. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js.map +1 -1
  155. package/packages/pi-coding-agent/src/core/auth-storage.test.ts +7 -7
  156. package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +26 -26
  157. package/packages/pi-coding-agent/src/core/fs-utils.test.ts +43 -31
  158. package/packages/pi-coding-agent/src/core/resolve-config-value.test.ts +45 -40
  159. package/packages/pi-coding-agent/src/core/session-manager.test.ts +33 -33
  160. package/packages/pi-coding-agent/src/core/tools/edit-diff.test.ts +17 -17
  161. package/packages/pi-coding-agent/src/resources/extensions/memory/storage.test.ts +74 -74
  162. package/src/resources/extensions/gsd/auto-start.ts +0 -14
  163. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +0 -8
  164. package/src/resources/extensions/gsd/tests/all-milestones-complete-merge.test.ts +99 -99
  165. package/src/resources/extensions/gsd/tests/auto-lock-creation.test.ts +16 -14
  166. package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +57 -43
  167. package/src/resources/extensions/gsd/tests/auto-preflight.test.ts +13 -11
  168. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +523 -465
  169. package/src/resources/extensions/gsd/tests/auto-secrets-gate.test.ts +75 -73
  170. package/src/resources/extensions/gsd/tests/auto-start-needs-discussion.test.ts +56 -34
  171. package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +656 -533
  172. package/src/resources/extensions/gsd/tests/auto-worktree.test.ts +143 -165
  173. package/src/resources/extensions/gsd/tests/cache-staleness-regression.test.ts +52 -29
  174. package/src/resources/extensions/gsd/tests/captures.test.ts +176 -148
  175. package/src/resources/extensions/gsd/tests/claude-import-tui.test.ts +33 -32
  176. package/src/resources/extensions/gsd/tests/collect-from-manifest.test.ts +143 -141
  177. package/src/resources/extensions/gsd/tests/commands-inspect-open-db.test.ts +25 -25
  178. package/src/resources/extensions/gsd/tests/commands-logs.test.ts +81 -81
  179. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +59 -38
  180. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +263 -228
  181. package/src/resources/extensions/gsd/tests/complete-task.test.ts +302 -250
  182. package/src/resources/extensions/gsd/tests/context-store.test.ts +367 -354
  183. package/src/resources/extensions/gsd/tests/continue-here.test.ts +72 -68
  184. package/src/resources/extensions/gsd/tests/cost-projection.test.ts +106 -92
  185. package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +35 -27
  186. package/src/resources/extensions/gsd/tests/dashboard-budget.test.ts +237 -220
  187. package/src/resources/extensions/gsd/tests/db-writer.test.ts +420 -390
  188. package/src/resources/extensions/gsd/tests/definition-loader.test.ts +92 -76
  189. package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +83 -68
  190. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +183 -152
  191. package/src/resources/extensions/gsd/tests/derive-state-deps.test.ts +101 -78
  192. package/src/resources/extensions/gsd/tests/derive-state.test.ts +227 -192
  193. package/src/resources/extensions/gsd/tests/detection.test.ts +278 -232
  194. package/src/resources/extensions/gsd/tests/dev-engine-wrapper.test.ts +34 -30
  195. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +180 -164
  196. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +49 -43
  197. package/src/resources/extensions/gsd/tests/dispatch-uat-last-completed.test.ts +32 -28
  198. package/src/resources/extensions/gsd/tests/doctor-completion-deferral.test.ts +29 -27
  199. package/src/resources/extensions/gsd/tests/doctor-delimiter-fix.test.ts +38 -34
  200. package/src/resources/extensions/gsd/tests/doctor-enhancements.test.ts +75 -54
  201. package/src/resources/extensions/gsd/tests/doctor-environment-worktree.test.ts +32 -21
  202. package/src/resources/extensions/gsd/tests/doctor-environment.test.ts +97 -72
  203. package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +44 -38
  204. package/src/resources/extensions/gsd/tests/doctor-git.test.ts +145 -104
  205. package/src/resources/extensions/gsd/tests/doctor-proactive.test.ts +106 -84
  206. package/src/resources/extensions/gsd/tests/doctor-roadmap-summary-atomicity.test.ts +60 -54
  207. package/src/resources/extensions/gsd/tests/doctor-runtime.test.ts +93 -72
  208. package/src/resources/extensions/gsd/tests/doctor.test.ts +134 -104
  209. package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +131 -123
  210. package/src/resources/extensions/gsd/tests/exit-command.test.ts +24 -20
  211. package/src/resources/extensions/gsd/tests/feature-branch-lifecycle-integration.test.ts +57 -48
  212. package/src/resources/extensions/gsd/tests/files-loadfile-eisdir.test.ts +7 -5
  213. package/src/resources/extensions/gsd/tests/flag-file-db.test.ts +42 -30
  214. package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +206 -198
  215. package/src/resources/extensions/gsd/tests/git-locale.test.ts +27 -13
  216. package/src/resources/extensions/gsd/tests/git-service.test.ts +388 -285
  217. package/src/resources/extensions/gsd/tests/gitignore-tracked-gsd.test.ts +39 -31
  218. package/src/resources/extensions/gsd/tests/graph-operations.test.ts +69 -63
  219. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +264 -255
  220. package/src/resources/extensions/gsd/tests/gsd-inspect.test.ts +119 -108
  221. package/src/resources/extensions/gsd/tests/gsd-recover.test.ts +103 -81
  222. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +262 -229
  223. package/src/resources/extensions/gsd/tests/headless-answers.test.ts +13 -13
  224. package/src/resources/extensions/gsd/tests/health-widget.test.ts +37 -29
  225. package/src/resources/extensions/gsd/tests/idle-recovery.test.ts +102 -81
  226. package/src/resources/extensions/gsd/tests/init-wizard.test.ts +18 -16
  227. package/src/resources/extensions/gsd/tests/integration-edge.test.ts +46 -41
  228. package/src/resources/extensions/gsd/tests/integration-lifecycle.test.ts +53 -42
  229. package/src/resources/extensions/gsd/tests/integration-mixed-milestones.test.ts +91 -75
  230. package/src/resources/extensions/gsd/tests/integration-proof.test.ts +18 -18
  231. package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +194 -150
  232. package/src/resources/extensions/gsd/tests/md-importer.test.ts +125 -101
  233. package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +54 -45
  234. package/src/resources/extensions/gsd/tests/memory-store.test.ts +93 -80
  235. package/src/resources/extensions/gsd/tests/migrate-command.test.ts +66 -57
  236. package/src/resources/extensions/gsd/tests/migrate-hierarchy.test.ts +93 -83
  237. package/src/resources/extensions/gsd/tests/migrate-parser.test.ts +170 -161
  238. package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +141 -125
  239. package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +131 -107
  240. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +96 -87
  241. package/src/resources/extensions/gsd/tests/migrate-writer.test.ts +164 -125
  242. package/src/resources/extensions/gsd/tests/must-have-parser.test.ts +94 -81
  243. package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +36 -35
  244. package/src/resources/extensions/gsd/tests/overrides.test.ts +106 -99
  245. package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +47 -40
  246. package/src/resources/extensions/gsd/tests/parallel-worker-monitoring.test.ts +28 -25
  247. package/src/resources/extensions/gsd/tests/parallel-workers-multi-milestone-e2e.test.ts +83 -66
  248. package/src/resources/extensions/gsd/tests/park-edge-cases.test.ts +77 -54
  249. package/src/resources/extensions/gsd/tests/park-milestone.test.ts +115 -68
  250. package/src/resources/extensions/gsd/tests/parsers.test.ts +611 -546
  251. package/src/resources/extensions/gsd/tests/paths.test.ts +87 -72
  252. package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +117 -77
  253. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +56 -56
  254. package/src/resources/extensions/gsd/tests/queue-draft-detection.test.ts +119 -93
  255. package/src/resources/extensions/gsd/tests/queue-order.test.ts +82 -70
  256. package/src/resources/extensions/gsd/tests/queue-reorder-e2e.test.ts +55 -42
  257. package/src/resources/extensions/gsd/tests/quick-branch-lifecycle.test.ts +73 -45
  258. package/src/resources/extensions/gsd/tests/reassess-prompt.test.ts +38 -28
  259. package/src/resources/extensions/gsd/tests/replan-slice.test.ts +80 -73
  260. package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +74 -71
  261. package/src/resources/extensions/gsd/tests/requirements.test.ts +75 -70
  262. package/src/resources/extensions/gsd/tests/retry-state-reset.test.ts +66 -44
  263. package/src/resources/extensions/gsd/tests/roadmap-parse-regression.test.ts +181 -114
  264. package/src/resources/extensions/gsd/tests/rule-registry.test.ts +65 -63
  265. package/src/resources/extensions/gsd/tests/run-uat.test.ts +128 -66
  266. package/src/resources/extensions/gsd/tests/session-lock-multipath.test.ts +25 -18
  267. package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +44 -37
  268. package/src/resources/extensions/gsd/tests/shared-wal.test.ts +26 -19
  269. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +8 -6
  270. package/src/resources/extensions/gsd/tests/symlink-numbered-variants.test.ts +28 -22
  271. package/src/resources/extensions/gsd/tests/token-savings.test.ts +56 -54
  272. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +25 -23
  273. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +11 -9
  274. package/src/resources/extensions/gsd/tests/unique-milestone-ids.test.ts +82 -66
  275. package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +47 -46
  276. package/src/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +22 -20
  277. package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +86 -84
  278. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +43 -41
  279. package/src/resources/extensions/gsd/tests/visualizer-views.test.ts +96 -94
  280. package/src/resources/extensions/gsd/tests/windows-path-normalization.test.ts +13 -11
  281. package/src/resources/extensions/gsd/tests/worker-registry.test.ts +29 -27
  282. package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +52 -50
  283. package/src/resources/extensions/gsd/tests/worktree-bugfix.test.ts +13 -10
  284. package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +18 -14
  285. package/src/resources/extensions/gsd/tests/worktree-db.test.ts +39 -38
  286. package/src/resources/extensions/gsd/tests/worktree-e2e.test.ts +21 -17
  287. package/src/resources/extensions/gsd/tests/worktree-health.test.ts +30 -25
  288. package/src/resources/extensions/gsd/tests/worktree-integration.test.ts +37 -30
  289. package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +22 -15
  290. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +66 -59
  291. package/src/resources/extensions/gsd/tests/worktree.test.ts +50 -44
  292. package/dist/web/standalone/.next/static/chunks/app/page-b9367c5ae13b99c6.js +0 -1
  293. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +0 -1
  294. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +0 -1
  295. package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +0 -100
  296. package/src/resources/extensions/gsd/tests/sqlite-unavailable-gate.test.ts +0 -63
  297. /package/dist/web/standalone/.next/static/{-zps1Q9mQmioAKLcQiCr8 → mgkxN0mGP6gSUmGPEzbk_}/_buildManifest.js +0 -0
  298. /package/dist/web/standalone/.next/static/{-zps1Q9mQmioAKLcQiCr8 → mgkxN0mGP6gSUmGPEzbk_}/_ssgManifest.js +0 -0
@@ -1,3 +1,4 @@
1
+ import { createTestContext } from './test-helpers.ts';
1
2
  import {
2
3
  openDatabase,
3
4
  closeDatabase,
@@ -20,90 +21,94 @@ import {
20
21
  formatMemoriesForPrompt,
21
22
  } from '../memory-store.ts';
22
23
  import type { MemoryAction } from '../memory-store.ts';
23
- import { describe, test, beforeEach, afterEach } from 'node:test';
24
- import assert from 'node:assert/strict';
24
+
25
+ const { assertEq, assertTrue, assertMatch, report } = createTestContext();
25
26
 
26
27
  // ═══════════════════════════════════════════════════════════════════════════
27
28
  // memory-store: fallback when DB not open
28
29
  // ═══════════════════════════════════════════════════════════════════════════
29
30
 
30
- test('memory-store: fallback returns empty when DB not open', () => {
31
+ console.log('\n=== memory-store: fallback returns empty when DB not open ===');
32
+ {
31
33
  closeDatabase();
32
- assert.ok(!isDbAvailable(), 'DB should not be available');
34
+ assertTrue(!isDbAvailable(), 'DB should not be available');
33
35
 
34
- assert.deepStrictEqual(getActiveMemories(), [], 'getActiveMemories returns [] when DB closed');
35
- assert.deepStrictEqual(getActiveMemoriesRanked(), [], 'getActiveMemoriesRanked returns [] when DB closed');
36
- assert.deepStrictEqual(nextMemoryId(), 'MEM001', 'nextMemoryId returns MEM001 when DB closed');
37
- assert.deepStrictEqual(createMemory({ category: 'test', content: 'test' }), null, 'createMemory returns null when DB closed');
38
- assert.ok(!reinforceMemory('MEM001'), 'reinforceMemory returns false when DB closed');
39
- assert.ok(!isUnitProcessed('test/key'), 'isUnitProcessed returns false when DB closed');
40
- });
36
+ assertEq(getActiveMemories(), [], 'getActiveMemories returns [] when DB closed');
37
+ assertEq(getActiveMemoriesRanked(), [], 'getActiveMemoriesRanked returns [] when DB closed');
38
+ assertEq(nextMemoryId(), 'MEM001', 'nextMemoryId returns MEM001 when DB closed');
39
+ assertEq(createMemory({ category: 'test', content: 'test' }), null, 'createMemory returns null when DB closed');
40
+ assertTrue(!reinforceMemory('MEM001'), 'reinforceMemory returns false when DB closed');
41
+ assertTrue(!isUnitProcessed('test/key'), 'isUnitProcessed returns false when DB closed');
42
+ }
41
43
 
42
44
  // ═══════════════════════════════════════════════════════════════════════════
43
45
  // memory-store: CRUD operations
44
46
  // ═══════════════════════════════════════════════════════════════════════════
45
47
 
46
- test('memory-store: create and query memories', () => {
48
+ console.log('\n=== memory-store: create and query memories ===');
49
+ {
47
50
  openDatabase(':memory:');
48
51
 
49
52
  // Create memories
50
53
  const id1 = createMemory({ category: 'gotcha', content: 'esbuild drops .node binaries' });
51
- assert.ok(id1 !== null, 'createMemory should return an ID');
52
- assert.deepStrictEqual(id1, 'MEM001', 'first memory ID should be MEM001');
54
+ assertTrue(id1 !== null, 'createMemory should return an ID');
55
+ assertEq(id1, 'MEM001', 'first memory ID should be MEM001');
53
56
 
54
57
  const id2 = createMemory({ category: 'convention', content: 'use :memory: for tests', confidence: 0.9 });
55
- assert.deepStrictEqual(id2, 'MEM002', 'second memory ID should be MEM002');
58
+ assertEq(id2, 'MEM002', 'second memory ID should be MEM002');
56
59
 
57
60
  const id3 = createMemory({ category: 'architecture', content: 'extensions discovered from src/resources/' });
58
- assert.deepStrictEqual(id3, 'MEM003', 'third memory ID should be MEM003');
61
+ assertEq(id3, 'MEM003', 'third memory ID should be MEM003');
59
62
 
60
63
  // Query all active
61
64
  const active = getActiveMemories();
62
- assert.deepStrictEqual(active.length, 3, 'should have 3 active memories');
63
- assert.deepStrictEqual(active[0].category, 'gotcha', 'first memory category');
64
- assert.deepStrictEqual(active[0].content, 'esbuild drops .node binaries', 'first memory content');
65
- assert.deepStrictEqual(active[1].confidence, 0.9, 'second memory confidence');
65
+ assertEq(active.length, 3, 'should have 3 active memories');
66
+ assertEq(active[0].category, 'gotcha', 'first memory category');
67
+ assertEq(active[0].content, 'esbuild drops .node binaries', 'first memory content');
68
+ assertEq(active[1].confidence, 0.9, 'second memory confidence');
66
69
 
67
70
  closeDatabase();
68
- });
71
+ }
69
72
 
70
73
  // ═══════════════════════════════════════════════════════════════════════════
71
74
  // memory-store: update and reinforce
72
75
  // ═══════════════════════════════════════════════════════════════════════════
73
76
 
74
- test('memory-store: update and reinforce', () => {
77
+ console.log('\n=== memory-store: update and reinforce ===');
78
+ {
75
79
  openDatabase(':memory:');
76
80
 
77
81
  createMemory({ category: 'gotcha', content: 'original content' });
78
82
 
79
83
  // Update content
80
84
  const updated = updateMemoryContent('MEM001', 'revised content', 0.95);
81
- assert.ok(updated, 'updateMemoryContent should return true');
85
+ assertTrue(updated, 'updateMemoryContent should return true');
82
86
 
83
87
  const active = getActiveMemories();
84
- assert.deepStrictEqual(active[0].content, 'revised content', 'content should be updated');
85
- assert.deepStrictEqual(active[0].confidence, 0.95, 'confidence should be updated');
88
+ assertEq(active[0].content, 'revised content', 'content should be updated');
89
+ assertEq(active[0].confidence, 0.95, 'confidence should be updated');
86
90
 
87
91
  // Reinforce
88
92
  const reinforced = reinforceMemory('MEM001');
89
- assert.ok(reinforced, 'reinforceMemory should return true');
93
+ assertTrue(reinforced, 'reinforceMemory should return true');
90
94
 
91
95
  const after = getActiveMemories();
92
- assert.deepStrictEqual(after[0].hit_count, 1, 'hit_count should be 1 after reinforce');
96
+ assertEq(after[0].hit_count, 1, 'hit_count should be 1 after reinforce');
93
97
 
94
98
  // Reinforce again
95
99
  reinforceMemory('MEM001');
96
100
  const after2 = getActiveMemories();
97
- assert.deepStrictEqual(after2[0].hit_count, 2, 'hit_count should be 2 after second reinforce');
101
+ assertEq(after2[0].hit_count, 2, 'hit_count should be 2 after second reinforce');
98
102
 
99
103
  closeDatabase();
100
- });
104
+ }
101
105
 
102
106
  // ═══════════════════════════════════════════════════════════════════════════
103
107
  // memory-store: supersede
104
108
  // ═══════════════════════════════════════════════════════════════════════════
105
109
 
106
- test('memory-store: supersede', () => {
110
+ console.log('\n=== memory-store: supersede ===');
111
+ {
107
112
  openDatabase(':memory:');
108
113
 
109
114
  createMemory({ category: 'convention', content: 'old convention' });
@@ -112,17 +117,18 @@ test('memory-store: supersede', () => {
112
117
  supersedeMemory('MEM001', 'MEM002');
113
118
 
114
119
  const active = getActiveMemories();
115
- assert.deepStrictEqual(active.length, 1, 'should have 1 active memory after supersede');
116
- assert.deepStrictEqual(active[0].id, 'MEM002', 'active memory should be MEM002');
120
+ assertEq(active.length, 1, 'should have 1 active memory after supersede');
121
+ assertEq(active[0].id, 'MEM002', 'active memory should be MEM002');
117
122
 
118
123
  closeDatabase();
119
- });
124
+ }
120
125
 
121
126
  // ═══════════════════════════════════════════════════════════════════════════
122
127
  // memory-store: ranked query ordering
123
128
  // ═══════════════════════════════════════════════════════════════════════════
124
129
 
125
- test('memory-store: ranked query ordering', () => {
130
+ console.log('\n=== memory-store: ranked query ordering ===');
131
+ {
126
132
  openDatabase(':memory:');
127
133
 
128
134
  // Low confidence, no hits
@@ -136,43 +142,45 @@ test('memory-store: ranked query ordering', () => {
136
142
  for (let i = 0; i < 10; i++) reinforceMemory('MEM003');
137
143
 
138
144
  const ranked = getActiveMemoriesRanked(10);
139
- assert.deepStrictEqual(ranked.length, 3, 'should have 3 ranked memories');
145
+ assertEq(ranked.length, 3, 'should have 3 ranked memories');
140
146
  // MEM003: 0.7 * (1 + 10*0.1) = 0.7 * 2.0 = 1.4
141
147
  // MEM002: 0.95 * (1 + 0*0.1) = 0.95
142
148
  // MEM001: 0.5 * (1 + 0*0.1) = 0.5
143
- assert.deepStrictEqual(ranked[0].id, 'MEM003', 'highest ranked should be MEM003 (reinforced)');
144
- assert.deepStrictEqual(ranked[1].id, 'MEM002', 'second ranked should be MEM002 (high confidence)');
145
- assert.deepStrictEqual(ranked[2].id, 'MEM001', 'lowest ranked should be MEM001');
149
+ assertEq(ranked[0].id, 'MEM003', 'highest ranked should be MEM003 (reinforced)');
150
+ assertEq(ranked[1].id, 'MEM002', 'second ranked should be MEM002 (high confidence)');
151
+ assertEq(ranked[2].id, 'MEM001', 'lowest ranked should be MEM001');
146
152
 
147
153
  // Test limit
148
154
  const limited = getActiveMemoriesRanked(2);
149
- assert.deepStrictEqual(limited.length, 2, 'limit should cap results');
155
+ assertEq(limited.length, 2, 'limit should cap results');
150
156
 
151
157
  closeDatabase();
152
- });
158
+ }
153
159
 
154
160
  // ═══════════════════════════════════════════════════════════════════════════
155
161
  // memory-store: processed unit tracking
156
162
  // ═══════════════════════════════════════════════════════════════════════════
157
163
 
158
- test('memory-store: processed unit tracking', () => {
164
+ console.log('\n=== memory-store: processed unit tracking ===');
165
+ {
159
166
  openDatabase(':memory:');
160
167
 
161
- assert.ok(!isUnitProcessed('execute-task/M001/S01/T01'), 'should not be processed initially');
168
+ assertTrue(!isUnitProcessed('execute-task/M001/S01/T01'), 'should not be processed initially');
162
169
 
163
170
  markUnitProcessed('execute-task/M001/S01/T01', '/path/to/activity.jsonl');
164
171
 
165
- assert.ok(isUnitProcessed('execute-task/M001/S01/T01'), 'should be processed after marking');
166
- assert.ok(!isUnitProcessed('execute-task/M001/S01/T02'), 'different key should not be processed');
172
+ assertTrue(isUnitProcessed('execute-task/M001/S01/T01'), 'should be processed after marking');
173
+ assertTrue(!isUnitProcessed('execute-task/M001/S01/T02'), 'different key should not be processed');
167
174
 
168
175
  closeDatabase();
169
- });
176
+ }
170
177
 
171
178
  // ═══════════════════════════════════════════════════════════════════════════
172
179
  // memory-store: enforce memory cap
173
180
  // ═══════════════════════════════════════════════════════════════════════════
174
181
 
175
- test('memory-store: enforce memory cap', () => {
182
+ console.log('\n=== memory-store: enforce memory cap ===');
183
+ {
176
184
  openDatabase(':memory:');
177
185
 
178
186
  // Create 5 memories with varying confidence
@@ -186,22 +194,23 @@ test('memory-store: enforce memory cap', () => {
186
194
  enforceMemoryCap(3);
187
195
 
188
196
  const active = getActiveMemories();
189
- assert.deepStrictEqual(active.length, 3, 'should have 3 active memories after cap enforcement');
197
+ assertEq(active.length, 3, 'should have 3 active memories after cap enforcement');
190
198
 
191
199
  // The 2 lowest-ranked (MEM003=0.3 and MEM002=0.5) should be superseded
192
200
  const ids = active.map(m => m.id).sort();
193
- assert.ok(ids.includes('MEM001'), 'MEM001 (0.9) should survive');
194
- assert.ok(ids.includes('MEM004'), 'MEM004 (0.95) should survive');
195
- assert.ok(ids.includes('MEM005'), 'MEM005 (0.7) should survive');
201
+ assertTrue(ids.includes('MEM001'), 'MEM001 (0.9) should survive');
202
+ assertTrue(ids.includes('MEM004'), 'MEM004 (0.95) should survive');
203
+ assertTrue(ids.includes('MEM005'), 'MEM005 (0.7) should survive');
196
204
 
197
205
  closeDatabase();
198
- });
206
+ }
199
207
 
200
208
  // ═══════════════════════════════════════════════════════════════════════════
201
209
  // memory-store: applyMemoryActions transaction
202
210
  // ═══════════════════════════════════════════════════════════════════════════
203
211
 
204
- test('memory-store: applyMemoryActions', () => {
212
+ console.log('\n=== memory-store: applyMemoryActions ===');
213
+ {
205
214
  openDatabase(':memory:');
206
215
 
207
216
  const actions: MemoryAction[] = [
@@ -212,7 +221,7 @@ test('memory-store: applyMemoryActions', () => {
212
221
  applyMemoryActions(actions, 'execute-task', 'M001/S01/T01');
213
222
 
214
223
  let active = getActiveMemories();
215
- assert.deepStrictEqual(active.length, 2, 'should have 2 memories after CREATE actions');
224
+ assertEq(active.length, 2, 'should have 2 memories after CREATE actions');
216
225
 
217
226
  // Now apply UPDATE + REINFORCE
218
227
  const updateActions: MemoryAction[] = [
@@ -223,8 +232,8 @@ test('memory-store: applyMemoryActions', () => {
223
232
  applyMemoryActions(updateActions, 'execute-task', 'M001/S01/T02');
224
233
 
225
234
  active = getActiveMemories();
226
- assert.deepStrictEqual(active.find(m => m.id === 'MEM001')?.content, 'updated gotcha', 'MEM001 should be updated');
227
- assert.deepStrictEqual(active.find(m => m.id === 'MEM002')?.hit_count, 1, 'MEM002 should be reinforced');
235
+ assertEq(active.find(m => m.id === 'MEM001')?.content, 'updated gotcha', 'MEM001 should be updated');
236
+ assertEq(active.find(m => m.id === 'MEM002')?.hit_count, 1, 'MEM002 should be reinforced');
228
237
 
229
238
  // SUPERSEDE
230
239
  const supersedeActions: MemoryAction[] = [
@@ -235,18 +244,19 @@ test('memory-store: applyMemoryActions', () => {
235
244
  applyMemoryActions(supersedeActions, 'execute-task', 'M001/S01/T03');
236
245
 
237
246
  active = getActiveMemories();
238
- assert.deepStrictEqual(active.length, 2, 'should have 2 active after supersede');
239
- assert.ok(!active.find(m => m.id === 'MEM001'), 'MEM001 should be superseded');
240
- assert.ok(!!active.find(m => m.id === 'MEM003'), 'MEM003 should be active');
247
+ assertEq(active.length, 2, 'should have 2 active after supersede');
248
+ assertTrue(!active.find(m => m.id === 'MEM001'), 'MEM001 should be superseded');
249
+ assertTrue(!!active.find(m => m.id === 'MEM003'), 'MEM003 should be active');
241
250
 
242
251
  closeDatabase();
243
- });
252
+ }
244
253
 
245
254
  // ═══════════════════════════════════════════════════════════════════════════
246
255
  // memory-store: formatMemoriesForPrompt
247
256
  // ═══════════════════════════════════════════════════════════════════════════
248
257
 
249
- test('memory-store: formatMemoriesForPrompt', () => {
258
+ console.log('\n=== memory-store: formatMemoriesForPrompt ===');
259
+ {
250
260
  openDatabase(':memory:');
251
261
 
252
262
  createMemory({ category: 'gotcha', content: 'esbuild drops .node binaries' });
@@ -257,18 +267,18 @@ test('memory-store: formatMemoriesForPrompt', () => {
257
267
  const memories = getActiveMemoriesRanked(30);
258
268
  const formatted = formatMemoriesForPrompt(memories);
259
269
 
260
- assert.ok(formatted.includes('## Project Memory (auto-learned)'), 'should have header');
261
- assert.ok(formatted.includes('### Gotcha'), 'should have gotcha category');
262
- assert.ok(formatted.includes('### Convention'), 'should have convention category');
263
- assert.ok(formatted.includes('### Architecture'), 'should have architecture category');
264
- assert.ok(formatted.includes('- esbuild drops .node binaries'), 'should have gotcha content');
265
- assert.ok(formatted.includes('- use :memory: for tests'), 'should have convention content');
270
+ assertTrue(formatted.includes('## Project Memory (auto-learned)'), 'should have header');
271
+ assertTrue(formatted.includes('### Gotcha'), 'should have gotcha category');
272
+ assertTrue(formatted.includes('### Convention'), 'should have convention category');
273
+ assertTrue(formatted.includes('### Architecture'), 'should have architecture category');
274
+ assertTrue(formatted.includes('- esbuild drops .node binaries'), 'should have gotcha content');
275
+ assertTrue(formatted.includes('- use :memory: for tests'), 'should have convention content');
266
276
 
267
277
  // Test empty memories
268
278
  closeDatabase();
269
279
  openDatabase(':memory:');
270
280
  const emptyFormatted = formatMemoriesForPrompt([]);
271
- assert.deepStrictEqual(emptyFormatted, '', 'empty memories should return empty string');
281
+ assertEq(emptyFormatted, '', 'empty memories should return empty string');
272
282
 
273
283
  // Test token budget truncation
274
284
  closeDatabase();
@@ -278,55 +288,58 @@ test('memory-store: formatMemoriesForPrompt', () => {
278
288
  }
279
289
  const budgetMemories = getActiveMemoriesRanked(30);
280
290
  const truncated = formatMemoriesForPrompt(budgetMemories, 500);
281
- assert.ok(truncated.length < 2500, `formatted length ${truncated.length} should be under budget`);
291
+ assertTrue(truncated.length < 2500, `formatted length ${truncated.length} should be under budget`);
282
292
 
283
293
  closeDatabase();
284
- });
294
+ }
285
295
 
286
296
  // ═══════════════════════════════════════════════════════════════════════════
287
297
  // memory-store: ID generation
288
298
  // ═══════════════════════════════════════════════════════════════════════════
289
299
 
290
- test('memory-store: ID generation', () => {
300
+ console.log('\n=== memory-store: ID generation ===');
301
+ {
291
302
  openDatabase(':memory:');
292
303
 
293
- assert.deepStrictEqual(nextMemoryId(), 'MEM001', 'first ID should be MEM001');
304
+ assertEq(nextMemoryId(), 'MEM001', 'first ID should be MEM001');
294
305
 
295
306
  createMemory({ category: 'test', content: 'test' });
296
- assert.deepStrictEqual(nextMemoryId(), 'MEM002', 'after first create, next should be MEM002');
307
+ assertEq(nextMemoryId(), 'MEM002', 'after first create, next should be MEM002');
297
308
 
298
309
  // Create several more
299
310
  for (let i = 0; i < 98; i++) createMemory({ category: 'test', content: `test ${i}` });
300
- assert.deepStrictEqual(nextMemoryId(), 'MEM100', 'after 99 creates, next should be MEM100');
311
+ assertEq(nextMemoryId(), 'MEM100', 'after 99 creates, next should be MEM100');
301
312
 
302
313
  closeDatabase();
303
- });
314
+ }
304
315
 
305
316
  // ═══════════════════════════════════════════════════════════════════════════
306
317
  // memory-store: schema migration (v2 → v3)
307
318
  // ═══════════════════════════════════════════════════════════════════════════
308
319
 
309
- test('memory-store: schema includes memories table', () => {
320
+ console.log('\n=== memory-store: schema includes memories table ===');
321
+ {
310
322
  openDatabase(':memory:');
311
323
 
312
324
  const adapter = _getAdapter()!;
313
325
 
314
326
  // Verify memories table exists
315
327
  const memCount = adapter.prepare('SELECT count(*) as cnt FROM memories').get();
316
- assert.deepStrictEqual(memCount?.['cnt'], 0, 'memories table should exist and be empty');
328
+ assertEq(memCount?.['cnt'], 0, 'memories table should exist and be empty');
317
329
 
318
330
  // Verify memory_processed_units table exists
319
331
  const procCount = adapter.prepare('SELECT count(*) as cnt FROM memory_processed_units').get();
320
- assert.deepStrictEqual(procCount?.['cnt'], 0, 'memory_processed_units table should exist and be empty');
332
+ assertEq(procCount?.['cnt'], 0, 'memory_processed_units table should exist and be empty');
321
333
 
322
334
  // Verify active_memories view exists
323
335
  const viewCount = adapter.prepare('SELECT count(*) as cnt FROM active_memories').get();
324
- assert.deepStrictEqual(viewCount?.['cnt'], 0, 'active_memories view should exist');
336
+ assertEq(viewCount?.['cnt'], 0, 'active_memories view should exist');
325
337
 
326
338
  // Verify schema version is 10 (after M001 planning migrations)
327
339
  const version = adapter.prepare('SELECT MAX(version) as v FROM schema_version').get();
328
- assert.deepStrictEqual(version?.['v'], 10, 'schema version should be 10');
340
+ assertEq(version?.['v'], 10, 'schema version should be 10');
329
341
 
330
342
  closeDatabase();
331
- });
343
+ }
332
344
 
345
+ report();
@@ -15,9 +15,9 @@ import {
15
15
  writeGSDDirectory,
16
16
  } from '../migrate/index.ts';
17
17
  import { deriveState } from '../state.ts';
18
- import { describe, test, beforeEach, afterEach } from 'node:test';
19
- import assert from 'node:assert/strict';
18
+ import { createTestContext } from './test-helpers.ts';
20
19
 
20
+ const { assertEq, assertTrue, report } = createTestContext();
21
21
  // ─── Fixture Helpers ───────────────────────────────────────────────────────
22
22
 
23
23
  const SAMPLE_PROJECT = `# Integration Test Project
@@ -195,9 +195,11 @@ function createCompleteFixture(): string {
195
195
  // Tests
196
196
  // ═══════════════════════════════════════════════════════════════════════════
197
197
 
198
- // ─── Test 1: Path resolution — .planning appended when missing ─────────
198
+ async function main(): Promise<void> {
199
199
 
200
- test('Path resolution: .planning appended when source path lacks it', () => {
200
+ // ─── Test 1: Path resolution .planning appended when missing ─────────
201
+ console.log('\n=== Path resolution: .planning appended when source path lacks it ===');
202
+ {
201
203
  const base = createCompleteFixture();
202
204
  try {
203
205
  // Simulate the command's path resolution logic
@@ -205,16 +207,16 @@ test('Path resolution: .planning appended when source path lacks it', () => {
205
207
  if (!sourcePath.endsWith('.planning')) {
206
208
  sourcePath = join(sourcePath, '.planning');
207
209
  }
208
- assert.ok(sourcePath.endsWith('.planning'), 'path-resolution: .planning appended');
209
- assert.ok(existsSync(sourcePath), 'path-resolution: appended path exists');
210
+ assertTrue(sourcePath.endsWith('.planning'), 'path-resolution: .planning appended');
211
+ assertTrue(existsSync(sourcePath), 'path-resolution: appended path exists');
210
212
  } finally {
211
213
  rmSync(base, { recursive: true, force: true });
212
214
  }
213
- });
215
+ }
214
216
 
215
217
  // ─── Test 2: Path resolution — .planning used as-is ────────────────────
216
-
217
- test('Path resolution: .planning used as-is when already present', () => {
218
+ console.log('\n=== Path resolution: .planning used as-is when already present ===');
219
+ {
218
220
  const base = createCompleteFixture();
219
221
  try {
220
222
  const planningPath = join(base, '.planning');
@@ -222,39 +224,39 @@ test('Path resolution: .planning used as-is when already present', () => {
222
224
  if (!sourcePath.endsWith('.planning')) {
223
225
  sourcePath = join(sourcePath, '.planning');
224
226
  }
225
- assert.deepStrictEqual(sourcePath, resolve(planningPath), 'path-resolution: .planning not double-appended');
226
- assert.ok(existsSync(sourcePath), 'path-resolution: direct path exists');
227
+ assertEq(sourcePath, resolve(planningPath), 'path-resolution: .planning not double-appended');
228
+ assertTrue(existsSync(sourcePath), 'path-resolution: direct path exists');
227
229
  } finally {
228
230
  rmSync(base, { recursive: true, force: true });
229
231
  }
230
- });
232
+ }
231
233
 
232
234
  // ─── Test 3: Validation gating — non-existent path ─────────────────────
233
-
234
- test('Validation gating: non-existent path returns invalid', async () => {
235
+ console.log('\n=== Validation gating: non-existent path returns invalid ===');
236
+ {
235
237
  const fakePath = join(tmpdir(), 'gsd-cmd-nonexistent-' + Date.now(), '.planning');
236
238
  const result = await validatePlanningDirectory(fakePath);
237
- assert.deepStrictEqual(result.valid, false, 'validation: non-existent path is invalid');
238
- assert.ok(result.issues.length > 0, 'validation: has issues for non-existent path');
239
+ assertEq(result.valid, false, 'validation: non-existent path is invalid');
240
+ assertTrue(result.issues.length > 0, 'validation: has issues for non-existent path');
239
241
  const hasFatal = result.issues.some(i => i.severity === 'fatal');
240
- assert.ok(hasFatal, 'validation: non-existent path has fatal issue');
241
- });
242
+ assertTrue(hasFatal, 'validation: non-existent path has fatal issue');
243
+ }
242
244
 
243
245
  // ─── Test 4: Validation gating — valid fixture passes ──────────────────
244
-
245
- test('Validation gating: valid fixture passes validation', async () => {
246
+ console.log('\n=== Validation gating: valid fixture passes validation ===');
247
+ {
246
248
  const base = createCompleteFixture();
247
249
  try {
248
250
  const result = await validatePlanningDirectory(join(base, '.planning'));
249
- assert.ok(result.valid === true, 'validation: valid fixture passes');
251
+ assertTrue(result.valid === true, 'validation: valid fixture passes');
250
252
  } finally {
251
253
  rmSync(base, { recursive: true, force: true });
252
254
  }
253
- });
255
+ }
254
256
 
255
257
  // ─── Test 5: Full pipeline round-trip ──────────────────────────────────
256
-
257
- test('Full pipeline: parse → transform → preview → write → deriveState', async () => {
258
+ console.log('\n=== Full pipeline: parse → transform → preview → write → deriveState ===');
259
+ {
258
260
  const base = createCompleteFixture();
259
261
  const writeTarget = mkdtempSync(join(tmpdir(), 'gsd-cmd-write-'));
260
262
  try {
@@ -262,17 +264,17 @@ test('Full pipeline: parse → transform → preview → write → deriveState',
262
264
 
263
265
  // (a) Validate
264
266
  const validation = await validatePlanningDirectory(planningPath);
265
- assert.ok(validation.valid === true, 'pipeline: validation passes');
267
+ assertTrue(validation.valid === true, 'pipeline: validation passes');
266
268
 
267
269
  // (b) Parse
268
270
  const parsed = await parsePlanningDirectory(planningPath);
269
- assert.ok(parsed.roadmap !== null, 'pipeline: roadmap parsed');
270
- assert.ok(Object.keys(parsed.phases).length >= 2, 'pipeline: phases parsed');
271
+ assertTrue(parsed.roadmap !== null, 'pipeline: roadmap parsed');
272
+ assertTrue(Object.keys(parsed.phases).length >= 2, 'pipeline: phases parsed');
271
273
 
272
274
  // (c) Transform
273
275
  const project = transformToGSD(parsed);
274
- assert.ok(project.milestones.length >= 1, 'pipeline: has milestones');
275
- assert.ok(project.milestones[0].slices.length >= 1, 'pipeline: has slices');
276
+ assertTrue(project.milestones.length >= 1, 'pipeline: has milestones');
277
+ assertTrue(project.milestones[0].slices.length >= 1, 'pipeline: has slices');
276
278
 
277
279
  // Count totals for preview verification
278
280
  let totalTasks = 0;
@@ -292,69 +294,76 @@ test('Full pipeline: parse → transform → preview → write → deriveState',
292
294
 
293
295
  // (d) Preview — verify counts match project data
294
296
  const preview = generatePreview(project);
295
- assert.deepStrictEqual(preview.milestoneCount, project.milestones.length, 'pipeline: preview milestoneCount');
296
- assert.deepStrictEqual(preview.totalSlices, totalSlices, 'pipeline: preview totalSlices');
297
- assert.deepStrictEqual(preview.totalTasks, totalTasks, 'pipeline: preview totalTasks');
298
- assert.deepStrictEqual(preview.doneSlices, doneSlices, 'pipeline: preview doneSlices');
299
- assert.deepStrictEqual(preview.doneTasks, doneTasks, 'pipeline: preview doneTasks');
297
+ assertEq(preview.milestoneCount, project.milestones.length, 'pipeline: preview milestoneCount');
298
+ assertEq(preview.totalSlices, totalSlices, 'pipeline: preview totalSlices');
299
+ assertEq(preview.totalTasks, totalTasks, 'pipeline: preview totalTasks');
300
+ assertEq(preview.doneSlices, doneSlices, 'pipeline: preview doneSlices');
301
+ assertEq(preview.doneTasks, doneTasks, 'pipeline: preview doneTasks');
300
302
 
301
303
  // Completion percentages
302
304
  const expectedSlicePct = totalSlices > 0 ? Math.round((doneSlices / totalSlices) * 100) : 0;
303
305
  const expectedTaskPct = totalTasks > 0 ? Math.round((doneTasks / totalTasks) * 100) : 0;
304
- assert.deepStrictEqual(preview.sliceCompletionPct, expectedSlicePct, 'pipeline: preview sliceCompletionPct');
305
- assert.deepStrictEqual(preview.taskCompletionPct, expectedTaskPct, 'pipeline: preview taskCompletionPct');
306
+ assertEq(preview.sliceCompletionPct, expectedSlicePct, 'pipeline: preview sliceCompletionPct');
307
+ assertEq(preview.taskCompletionPct, expectedTaskPct, 'pipeline: preview taskCompletionPct');
306
308
 
307
309
  // Requirements in preview
308
- assert.deepStrictEqual(preview.requirements.active, 1, 'pipeline: preview requirements active');
309
- assert.deepStrictEqual(preview.requirements.validated, 1, 'pipeline: preview requirements validated');
310
- assert.deepStrictEqual(preview.requirements.total, 2, 'pipeline: preview requirements total');
310
+ assertEq(preview.requirements.active, 1, 'pipeline: preview requirements active');
311
+ assertEq(preview.requirements.validated, 1, 'pipeline: preview requirements validated');
312
+ assertEq(preview.requirements.total, 2, 'pipeline: preview requirements total');
311
313
 
312
314
  // (e) Write
313
315
  const result = await writeGSDDirectory(project, writeTarget);
314
- assert.ok(result.paths.length > 0, 'pipeline: files written');
316
+ assertTrue(result.paths.length > 0, 'pipeline: files written');
315
317
 
316
318
  // Key files exist
317
319
  const gsd = join(writeTarget, '.gsd');
318
- assert.ok(existsSync(join(gsd, 'PROJECT.md')), 'pipeline: PROJECT.md written');
319
- assert.ok(existsSync(join(gsd, 'STATE.md')), 'pipeline: STATE.md written');
320
- assert.ok(existsSync(join(gsd, 'REQUIREMENTS.md')), 'pipeline: REQUIREMENTS.md written');
320
+ assertTrue(existsSync(join(gsd, 'PROJECT.md')), 'pipeline: PROJECT.md written');
321
+ assertTrue(existsSync(join(gsd, 'STATE.md')), 'pipeline: STATE.md written');
322
+ assertTrue(existsSync(join(gsd, 'REQUIREMENTS.md')), 'pipeline: REQUIREMENTS.md written');
321
323
 
322
324
  const m001 = join(gsd, 'milestones', 'M001');
323
- assert.ok(existsSync(join(m001, 'M001-ROADMAP.md')), 'pipeline: M001-ROADMAP.md written');
324
- assert.ok(existsSync(join(m001, 'M001-CONTEXT.md')), 'pipeline: M001-CONTEXT.md written');
325
+ assertTrue(existsSync(join(m001, 'M001-ROADMAP.md')), 'pipeline: M001-ROADMAP.md written');
326
+ assertTrue(existsSync(join(m001, 'M001-CONTEXT.md')), 'pipeline: M001-CONTEXT.md written');
325
327
 
326
328
  // At least one slice plan exists
327
329
  const s01Plan = join(m001, 'slices', 'S01', 'S01-PLAN.md');
328
- assert.ok(existsSync(s01Plan), 'pipeline: S01-PLAN.md written');
330
+ assertTrue(existsSync(s01Plan), 'pipeline: S01-PLAN.md written');
329
331
 
330
332
  // (f) deriveState — coherent state from written output
331
333
  console.log(' --- deriveState ---');
332
334
  const state = await deriveState(writeTarget);
333
- assert.ok(state.phase !== undefined, 'pipeline: deriveState returns phase');
334
- assert.ok(state.activeMilestone !== null, 'pipeline: deriveState has activeMilestone');
335
- assert.deepStrictEqual(state.activeMilestone!.id, 'M001', 'pipeline: deriveState activeMilestone is M001');
336
- assert.ok(state.progress!.slices !== undefined, 'pipeline: deriveState has slices progress');
337
- assert.ok(state.progress!.tasks !== undefined, 'pipeline: deriveState has tasks progress');
335
+ assertTrue(state.phase !== undefined, 'pipeline: deriveState returns phase');
336
+ assertTrue(state.activeMilestone !== null, 'pipeline: deriveState has activeMilestone');
337
+ assertEq(state.activeMilestone!.id, 'M001', 'pipeline: deriveState activeMilestone is M001');
338
+ assertTrue(state.progress!.slices !== undefined, 'pipeline: deriveState has slices progress');
339
+ assertTrue(state.progress!.tasks !== undefined, 'pipeline: deriveState has tasks progress');
338
340
 
339
341
  } finally {
340
342
  rmSync(base, { recursive: true, force: true });
341
343
  rmSync(writeTarget, { recursive: true, force: true });
342
344
  }
343
- });
345
+ }
344
346
 
345
347
  // ─── Test 6: .gsd/ exists detection ────────────────────────────────────
346
-
347
- test('.gsd/ exists detection', () => {
348
+ console.log('\n=== .gsd/ exists detection ===');
349
+ {
348
350
  const base = mkdtempSync(join(tmpdir(), 'gsd-cmd-exists-'));
349
351
  try {
350
352
  // No .gsd/ yet
351
- assert.ok(!existsSync(join(base, '.gsd')), 'exists-detection: .gsd absent initially');
353
+ assertTrue(!existsSync(join(base, '.gsd')), 'exists-detection: .gsd absent initially');
352
354
 
353
355
  // Create .gsd/
354
356
  mkdirSync(join(base, '.gsd'), { recursive: true });
355
- assert.ok(existsSync(join(base, '.gsd')), 'exists-detection: .gsd detected after creation');
357
+ assertTrue(existsSync(join(base, '.gsd')), 'exists-detection: .gsd detected after creation');
356
358
  } finally {
357
359
  rmSync(base, { recursive: true, force: true });
358
360
  }
359
- });
361
+ }
362
+
363
+ report();
364
+ }
360
365
 
366
+ main().catch((err) => {
367
+ console.error('Unhandled error:', err);
368
+ process.exit(1);
369
+ });