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,10 +1,11 @@
1
- import { describe, test } from 'node:test';
2
- import assert from 'node:assert/strict';
3
1
  import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from 'node:fs';
4
2
  import { join } from 'node:path';
5
3
  import { tmpdir } from 'node:os';
6
4
 
7
5
  import { deriveState } from '../state.ts';
6
+ import { createTestContext } from './test-helpers.ts';
7
+
8
+ const { assertEq, assertTrue, report } = createTestContext();
8
9
  // ─── Fixture Helpers ───────────────────────────────────────────────────────
9
10
 
10
11
  function createFixtureBase(): string {
@@ -62,11 +63,12 @@ function cleanup(base: string): void {
62
63
  // Test Groups
63
64
  // ═══════════════════════════════════════════════════════════════════════════
64
65
 
65
- describe('derive-state-deps', async () => {
66
+ async function main(): Promise<void> {
66
67
 
67
68
  // ─── Test Group 1: blocked-deps ────────────────────────────────────────
68
69
  // M001 is incomplete (no SUMMARY), M002 depends_on M001 → M002 is pending
69
- test('blocked-deps', async () => {
70
+ console.log('\n=== blocked-deps ===');
71
+ {
70
72
  const base = createFixtureBase();
71
73
  try {
72
74
  // M001: incomplete (one slice, no SUMMARY)
@@ -106,18 +108,19 @@ describe('derive-state-deps', async () => {
106
108
 
107
109
  const state = await deriveState(base);
108
110
 
109
- assert.deepStrictEqual(state.registry[0]?.status, 'active', 'blocked-deps: M001 is active');
110
- assert.deepStrictEqual(state.registry[1]?.status, 'pending', 'blocked-deps: M002 is pending (dep-blocked)');
111
- assert.deepStrictEqual(state.phase, 'executing', 'blocked-deps: phase is executing (M001 is active)');
112
- assert.deepStrictEqual(state.activeMilestone?.id, 'M001', 'blocked-deps: activeMilestone is M001');
111
+ assertEq(state.registry[0]?.status, 'active', 'blocked-deps: M001 is active');
112
+ assertEq(state.registry[1]?.status, 'pending', 'blocked-deps: M002 is pending (dep-blocked)');
113
+ assertEq(state.phase, 'executing', 'blocked-deps: phase is executing (M001 is active)');
114
+ assertEq(state.activeMilestone?.id, 'M001', 'blocked-deps: activeMilestone is M001');
113
115
  } finally {
114
116
  cleanup(base);
115
117
  }
116
- });
118
+ }
117
119
 
118
120
  // ─── Test Group 2: unblocked-deps ──────────────────────────────────────
119
121
  // M001 is complete (all slices [x] + SUMMARY), M002 depends_on M001 → M002 becomes active
120
- test('unblocked-deps', async () => {
122
+ console.log('\n=== unblocked-deps ===');
123
+ {
121
124
  const base = createFixtureBase();
122
125
  try {
123
126
  // M001: complete (all slices done + SUMMARY present)
@@ -147,18 +150,19 @@ describe('derive-state-deps', async () => {
147
150
 
148
151
  const state = await deriveState(base);
149
152
 
150
- assert.deepStrictEqual(state.registry[0]?.status, 'complete', 'unblocked-deps: M001 is complete');
151
- assert.deepStrictEqual(state.registry[1]?.status, 'active', 'unblocked-deps: M002 is active');
152
- assert.deepStrictEqual(state.activeMilestone?.id, 'M002', 'unblocked-deps: activeMilestone is M002');
153
- assert.ok(state.phase !== 'blocked', 'unblocked-deps: phase is not blocked');
153
+ assertEq(state.registry[0]?.status, 'complete', 'unblocked-deps: M001 is complete');
154
+ assertEq(state.registry[1]?.status, 'active', 'unblocked-deps: M002 is active');
155
+ assertEq(state.activeMilestone?.id, 'M002', 'unblocked-deps: activeMilestone is M002');
156
+ assertTrue(state.phase !== 'blocked', 'unblocked-deps: phase is not blocked');
154
157
  } finally {
155
158
  cleanup(base);
156
159
  }
157
- });
160
+ }
158
161
 
159
162
  // ─── Test Group 3: all-blocked ─────────────────────────────────────────
160
163
  // M001 depends_on M002, M002 depends_on M001 — circular dep, neither can activate
161
- test('all-blocked', async () => {
164
+ console.log('\n=== all-blocked ===');
165
+ {
162
166
  const base = createFixtureBase();
163
167
  try {
164
168
  // M001: depends on M002
@@ -187,17 +191,18 @@ describe('derive-state-deps', async () => {
187
191
 
188
192
  const state = await deriveState(base);
189
193
 
190
- assert.deepStrictEqual(state.phase, 'blocked', 'all-blocked: phase is blocked');
191
- assert.ok(state.activeMilestone === null || state.activeMilestone !== null, 'all-blocked: state is consistent');
192
- assert.ok(state.blockers.length > 0, 'all-blocked: blockers array is non-empty');
194
+ assertEq(state.phase, 'blocked', 'all-blocked: phase is blocked');
195
+ assertTrue(state.activeMilestone === null || state.activeMilestone !== null, 'all-blocked: state is consistent');
196
+ assertTrue(state.blockers.length > 0, 'all-blocked: blockers array is non-empty');
193
197
  } finally {
194
198
  cleanup(base);
195
199
  }
196
- });
200
+ }
197
201
 
198
202
  // ─── Test Group 4: absent-context ──────────────────────────────────────
199
203
  // Neither M001 nor M002 has a CONTEXT.md → no dep constraints, normal sequential behavior
200
- test('absent-context', async () => {
204
+ console.log('\n=== absent-context ===');
205
+ {
201
206
  const base = createFixtureBase();
202
207
  try {
203
208
  // M001: incomplete, no CONTEXT.md
@@ -224,18 +229,19 @@ describe('derive-state-deps', async () => {
224
229
 
225
230
  const state = await deriveState(base);
226
231
 
227
- assert.deepStrictEqual(state.registry[0]?.status, 'active', 'absent-context: M001 is active');
228
- assert.deepStrictEqual(state.registry[1]?.status, 'pending', 'absent-context: M002 is pending');
229
- assert.deepStrictEqual(state.activeMilestone?.id, 'M001', 'absent-context: activeMilestone is M001');
230
- assert.ok(state.phase !== 'blocked', 'absent-context: phase is not blocked');
232
+ assertEq(state.registry[0]?.status, 'active', 'absent-context: M001 is active');
233
+ assertEq(state.registry[1]?.status, 'pending', 'absent-context: M002 is pending');
234
+ assertEq(state.activeMilestone?.id, 'M001', 'absent-context: activeMilestone is M001');
235
+ assertTrue(state.phase !== 'blocked', 'absent-context: phase is not blocked');
231
236
  } finally {
232
237
  cleanup(base);
233
238
  }
234
- });
239
+ }
235
240
 
236
241
  // ─── Test Group 5: forward-dep ─────────────────────────────────────────
237
242
  // M001 depends_on M002, but M002 is already complete → M001 can activate
238
- test('forward-dep', async () => {
243
+ console.log('\n=== forward-dep ===');
244
+ {
239
245
  const base = createFixtureBase();
240
246
  try {
241
247
  // M001: depends on M002, but M002 is complete so M001 is unblocked
@@ -265,17 +271,18 @@ describe('derive-state-deps', async () => {
265
271
 
266
272
  const state = await deriveState(base);
267
273
 
268
- assert.deepStrictEqual(state.activeMilestone?.id, 'M001', 'forward-dep: activeMilestone is M001');
269
- assert.deepStrictEqual(state.registry[1]?.status, 'complete', 'forward-dep: M002 is complete');
270
- assert.ok(state.phase !== 'blocked', 'forward-dep: phase is not blocked');
274
+ assertEq(state.activeMilestone?.id, 'M001', 'forward-dep: activeMilestone is M001');
275
+ assertEq(state.registry[1]?.status, 'complete', 'forward-dep: M002 is complete');
276
+ assertTrue(state.phase !== 'blocked', 'forward-dep: phase is not blocked');
271
277
  } finally {
272
278
  cleanup(base);
273
279
  }
274
- });
280
+ }
275
281
 
276
282
  // ─── Test Group 6: empty-deps-list ─────────────────────────────────────
277
283
  // M002 has `depends_on: []` — empty list means no constraint, normal sequential behavior
278
- test('empty-deps-list', async () => {
284
+ console.log('\n=== empty-deps-list ===');
285
+ {
279
286
  const base = createFixtureBase();
280
287
  try {
281
288
  // M001: incomplete, no context
@@ -303,19 +310,20 @@ describe('derive-state-deps', async () => {
303
310
 
304
311
  const state = await deriveState(base);
305
312
 
306
- assert.deepStrictEqual(state.registry[0]?.status, 'active', 'empty-deps-list: M001 is active');
307
- assert.deepStrictEqual(state.registry[1]?.status, 'pending', 'empty-deps-list: M002 is pending (M001 not done yet)');
308
- assert.ok(state.phase !== 'blocked', 'empty-deps-list: phase is not blocked');
313
+ assertEq(state.registry[0]?.status, 'active', 'empty-deps-list: M001 is active');
314
+ assertEq(state.registry[1]?.status, 'pending', 'empty-deps-list: M002 is pending (M001 not done yet)');
315
+ assertTrue(state.phase !== 'blocked', 'empty-deps-list: phase is not blocked');
309
316
  } finally {
310
317
  cleanup(base);
311
318
  }
312
- });
319
+ }
313
320
 
314
321
  // ─── Test Group 7: unique-id-deps ──────────────────────────────────────
315
322
  // M004-0zjrg0 is complete, M005-b0m2hl depends_on M004-0zjrg0 → M005 should activate.
316
323
  // Regression: parseContextDependsOn() used .toUpperCase(), converting "M004-0zjrg0"
317
324
  // to "M004-0ZJRG0", breaking the case-sensitive lookup in completeMilestoneIds.
318
- test('unique-id-deps: unique milestone IDs with lowercase hex suffix', async () => {
325
+ console.log('\n=== unique-id-deps: unique milestone IDs with lowercase hex suffix ===');
326
+ {
319
327
  const base = createFixtureBase();
320
328
  try {
321
329
  // M004-0zjrg0: complete (all slices done + SUMMARY present)
@@ -336,22 +344,23 @@ describe('derive-state-deps', async () => {
336
344
 
337
345
  const state = await deriveState(base);
338
346
 
339
- assert.deepStrictEqual(state.registry.find(e => e.id === 'M004-0zjrg0')?.status, 'complete',
347
+ assertEq(state.registry.find(e => e.id === 'M004-0zjrg0')?.status, 'complete',
340
348
  'unique-id-deps: M004-0zjrg0 is complete');
341
- assert.deepStrictEqual(state.registry.find(e => e.id === 'M005-b0m2hl')?.status, 'active',
349
+ assertEq(state.registry.find(e => e.id === 'M005-b0m2hl')?.status, 'active',
342
350
  'unique-id-deps: M005-b0m2hl is active (dep on M004-0zjrg0 met)');
343
- assert.deepStrictEqual(state.activeMilestone?.id, 'M005-b0m2hl',
351
+ assertEq(state.activeMilestone?.id, 'M005-b0m2hl',
344
352
  'unique-id-deps: activeMilestone is M005-b0m2hl');
345
- assert.ok(state.phase !== 'blocked',
353
+ assertTrue(state.phase !== 'blocked',
346
354
  'unique-id-deps: phase is not blocked');
347
355
  } finally {
348
356
  cleanup(base);
349
357
  }
350
- });
358
+ }
351
359
 
352
360
  // ─── Test Group 8: unique-id-deps-blocked ─────────────────────────────
353
361
  // M004-0zjrg0 is NOT complete, M005-b0m2hl depends_on M004-0zjrg0 → M005 should be pending
354
- test('unique-id-deps-blocked: unique ID dep not yet met', async () => {
362
+ console.log('\n=== unique-id-deps-blocked: unique ID dep not yet met ===');
363
+ {
355
364
  const base = createFixtureBase();
356
365
  try {
357
366
  // M004-0zjrg0: incomplete (slice not done)
@@ -379,19 +388,20 @@ describe('derive-state-deps', async () => {
379
388
 
380
389
  const state = await deriveState(base);
381
390
 
382
- assert.deepStrictEqual(state.activeMilestone?.id, 'M004-0zjrg0',
391
+ assertEq(state.activeMilestone?.id, 'M004-0zjrg0',
383
392
  'unique-id-deps-blocked: activeMilestone is M004-0zjrg0');
384
- assert.deepStrictEqual(state.registry.find(e => e.id === 'M005-b0m2hl')?.status, 'pending',
393
+ assertEq(state.registry.find(e => e.id === 'M005-b0m2hl')?.status, 'pending',
385
394
  'unique-id-deps-blocked: M005-b0m2hl is pending (dep not met)');
386
395
  } finally {
387
396
  cleanup(base);
388
397
  }
389
- });
398
+ }
390
399
 
391
400
  // ─── Test Group 9: draft-context-deps ────────────────────────────────
392
401
  // M001 is incomplete, M002 has only CONTEXT-DRAFT.md (no CONTEXT.md) with
393
402
  // depends_on: [M001] → M002 should remain pending, not be promoted to active.
394
- test('draft-context-deps: depends_on read from CONTEXT-DRAFT.md', async () => {
403
+ console.log('\n=== draft-context-deps: depends_on read from CONTEXT-DRAFT.md ===');
404
+ {
395
405
  const base = createFixtureBase();
396
406
  try {
397
407
  // M001: incomplete (one slice, no SUMMARY)
@@ -429,17 +439,18 @@ describe('derive-state-deps', async () => {
429
439
 
430
440
  const state = await deriveState(base);
431
441
 
432
- assert.deepStrictEqual(state.registry[0]?.status, 'active', 'draft-context-deps: M001 is active');
433
- assert.deepStrictEqual(state.registry[1]?.status, 'pending', 'draft-context-deps: M002 is pending (dep-blocked via draft)');
434
- assert.deepStrictEqual(state.activeMilestone?.id, 'M001', 'draft-context-deps: activeMilestone is M001');
442
+ assertEq(state.registry[0]?.status, 'active', 'draft-context-deps: M001 is active');
443
+ assertEq(state.registry[1]?.status, 'pending', 'draft-context-deps: M002 is pending (dep-blocked via draft)');
444
+ assertEq(state.activeMilestone?.id, 'M001', 'draft-context-deps: activeMilestone is M001');
435
445
  } finally {
436
446
  cleanup(base);
437
447
  }
438
- });
448
+ }
439
449
 
440
450
  // ─── Test Group 10: draft-context-deps-no-roadmap ──────────────────────
441
451
  // Same as above but without roadmaps — milestones discovered from directory only.
442
- test('draft-context-deps-no-roadmap: depends_on from draft without roadmap', async () => {
452
+ console.log('\n=== draft-context-deps-no-roadmap: depends_on from draft without roadmap ===');
453
+ {
443
454
  const base = createFixtureBase();
444
455
  try {
445
456
  // M001: exists as directory only (no roadmap, no summary)
@@ -452,38 +463,40 @@ describe('derive-state-deps', async () => {
452
463
  const state = await deriveState(base);
453
464
 
454
465
  const m002Entry = state.registry.find(e => e.id === 'M002');
455
- assert.deepStrictEqual(m002Entry?.status, 'pending', 'draft-no-roadmap: M002 is pending (dep-blocked via draft)');
466
+ assertEq(m002Entry?.status, 'pending', 'draft-no-roadmap: M002 is pending (dep-blocked via draft)');
456
467
  } finally {
457
468
  cleanup(base);
458
469
  }
459
- });
470
+ }
460
471
 
461
472
  // ─── Test Group 11: parseContextDependsOn preserves case ──────────────
462
473
  // Direct unit test: verify the parsed dep ID matches the input exactly
463
- test('parseContextDependsOn: preserves case of unique IDs', async () => {
474
+ console.log('\n=== parseContextDependsOn: preserves case of unique IDs ===');
475
+ {
464
476
  const { parseContextDependsOn } = await import('../files.ts');
465
477
 
466
478
  const deps1 = parseContextDependsOn('---\ndepends_on: [M004-0zjrg0]\n---\n');
467
- assert.deepStrictEqual(deps1[0], 'M004-0zjrg0',
479
+ assertEq(deps1[0], 'M004-0zjrg0',
468
480
  'parseContextDependsOn preserves lowercase hex suffix');
469
481
 
470
482
  const deps2 = parseContextDependsOn('---\ndepends_on: [M001, M004-abc123]\n---\n');
471
- assert.deepStrictEqual(deps2[0], 'M001', 'preserves classic uppercase ID');
472
- assert.deepStrictEqual(deps2[1], 'M004-abc123', 'preserves mixed-case unique ID');
483
+ assertEq(deps2[0], 'M001', 'preserves classic uppercase ID');
484
+ assertEq(deps2[1], 'M004-abc123', 'preserves mixed-case unique ID');
473
485
 
474
486
  const deps3 = parseContextDependsOn('---\ndepends_on: []\n---\n');
475
- assert.deepStrictEqual(deps3.length, 0, 'empty deps returns empty array');
487
+ assertEq(deps3.length, 0, 'empty deps returns empty array');
476
488
 
477
489
  const deps4 = parseContextDependsOn(null);
478
- assert.deepStrictEqual(deps4.length, 0, 'null content returns empty array');
479
- });
490
+ assertEq(deps4.length, 0, 'null content returns empty array');
491
+ }
480
492
 
481
493
  // ─── Test Group 10: draft-only-deps-blocked (#1724) ────────────────────
482
494
  // M002 has only CONTEXT-DRAFT.md (no CONTEXT.md) with depends_on: [M001].
483
495
  // M001 is incomplete → M002 must remain pending, not get promoted to active.
484
496
  // Regression: before #1724, parseContextDependsOn received null for draft-only
485
497
  // milestones, returning [], which caused dep-blocked milestones to be promoted.
486
- test('draft-only-deps-blocked: CONTEXT-DRAFT.md depends_on blocks promotion', async () => {
498
+ console.log('\n=== draft-only-deps-blocked: CONTEXT-DRAFT.md depends_on blocks promotion ===');
499
+ {
487
500
  const base = createFixtureBase();
488
501
  try {
489
502
  // M001: incomplete (one slice, no SUMMARY)
@@ -512,21 +525,22 @@ describe('derive-state-deps', async () => {
512
525
 
513
526
  const state = await deriveState(base);
514
527
 
515
- assert.deepStrictEqual(state.activeMilestone?.id, 'M001',
528
+ assertEq(state.activeMilestone?.id, 'M001',
516
529
  'draft-only-deps-blocked: activeMilestone is M001');
517
- assert.deepStrictEqual(state.registry.find(e => e.id === 'M002')?.status, 'pending',
530
+ assertEq(state.registry.find(e => e.id === 'M002')?.status, 'pending',
518
531
  'draft-only-deps-blocked: M002 is pending (dep on M001 not met, read from CONTEXT-DRAFT)');
519
- assert.ok(state.phase !== 'blocked',
532
+ assertTrue(state.phase !== 'blocked',
520
533
  'draft-only-deps-blocked: phase is not blocked (M001 is active)');
521
534
  } finally {
522
535
  cleanup(base);
523
536
  }
524
- });
537
+ }
525
538
 
526
539
  // ─── Test Group 11: draft-only-deps-unblocked (#1724) ─────────────────
527
540
  // M001 is complete, M002 has only CONTEXT-DRAFT.md with depends_on: [M001].
528
541
  // M002 should become active because its dep is satisfied.
529
- test('draft-only-deps-unblocked: CONTEXT-DRAFT.md dep met → milestone activates', async () => {
542
+ console.log('\n=== draft-only-deps-unblocked: CONTEXT-DRAFT.md dep met → milestone activates ===');
543
+ {
530
544
  const base = createFixtureBase();
531
545
  try {
532
546
  // M001: complete
@@ -547,21 +561,22 @@ describe('derive-state-deps', async () => {
547
561
 
548
562
  const state = await deriveState(base);
549
563
 
550
- assert.deepStrictEqual(state.registry.find(e => e.id === 'M001')?.status, 'complete',
564
+ assertEq(state.registry.find(e => e.id === 'M001')?.status, 'complete',
551
565
  'draft-only-deps-unblocked: M001 is complete');
552
- assert.deepStrictEqual(state.registry.find(e => e.id === 'M002')?.status, 'active',
566
+ assertEq(state.registry.find(e => e.id === 'M002')?.status, 'active',
553
567
  'draft-only-deps-unblocked: M002 is active (dep on M001 met via CONTEXT-DRAFT)');
554
- assert.deepStrictEqual(state.activeMilestone?.id, 'M002',
568
+ assertEq(state.activeMilestone?.id, 'M002',
555
569
  'draft-only-deps-unblocked: activeMilestone is M002');
556
570
  } finally {
557
571
  cleanup(base);
558
572
  }
559
- });
573
+ }
560
574
 
561
575
  // ─── Test Group 12: draft-only-deps-with-roadmap (#1724) ──────────────
562
576
  // M002 has a roadmap + only CONTEXT-DRAFT.md with depends_on: [M001].
563
577
  // Tests the has-roadmap code path (second occurrence of the fix).
564
- test('draft-only-deps-with-roadmap: has-roadmap path reads CONTEXT-DRAFT deps', async () => {
578
+ console.log('\n=== draft-only-deps-with-roadmap: has-roadmap path reads CONTEXT-DRAFT deps ===');
579
+ {
565
580
  const base = createFixtureBase();
566
581
  try {
567
582
  // M001: incomplete
@@ -599,19 +614,20 @@ describe('derive-state-deps', async () => {
599
614
 
600
615
  const state = await deriveState(base);
601
616
 
602
- assert.deepStrictEqual(state.activeMilestone?.id, 'M001',
617
+ assertEq(state.activeMilestone?.id, 'M001',
603
618
  'draft-only-deps-with-roadmap: activeMilestone is M001');
604
- assert.deepStrictEqual(state.registry.find(e => e.id === 'M002')?.status, 'pending',
619
+ assertEq(state.registry.find(e => e.id === 'M002')?.status, 'pending',
605
620
  'draft-only-deps-with-roadmap: M002 is pending (dep read from CONTEXT-DRAFT in has-roadmap path)');
606
621
  } finally {
607
622
  cleanup(base);
608
623
  }
609
- });
624
+ }
610
625
 
611
626
  // ─── Test Group 13: draft-only-no-deps (#1724) ────────────────────────
612
627
  // M002 has only CONTEXT-DRAFT.md with NO depends_on field.
613
628
  // Should behave same as no context file — normal sequential behavior.
614
- test('draft-only-no-deps: CONTEXT-DRAFT without depends_on → no constraint', async () => {
629
+ console.log('\n=== draft-only-no-deps: CONTEXT-DRAFT without depends_on → no constraint ===');
630
+ {
615
631
  const base = createFixtureBase();
616
632
  try {
617
633
  // M001: complete
@@ -632,10 +648,17 @@ describe('derive-state-deps', async () => {
632
648
 
633
649
  const state = await deriveState(base);
634
650
 
635
- assert.deepStrictEqual(state.registry.find(e => e.id === 'M002')?.status, 'active',
651
+ assertEq(state.registry.find(e => e.id === 'M002')?.status, 'active',
636
652
  'draft-only-no-deps: M002 is active (no deps constraint in draft)');
637
653
  } finally {
638
654
  cleanup(base);
639
655
  }
640
- });
656
+ }
657
+
658
+ report();
659
+ }
660
+
661
+ main().catch((error) => {
662
+ console.error(error);
663
+ process.exit(1);
641
664
  });