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
@@ -39,55 +39,61 @@ function activeData(overrides: Partial<HealthWidgetData> = {}): HealthWidgetData
39
39
  };
40
40
  }
41
41
 
42
- test("detectHealthWidgetProjectState: no .gsd returns none", (t) => {
42
+ test("detectHealthWidgetProjectState: no .gsd returns none", () => {
43
43
  const dir = makeTempDir("none");
44
- t.after(() => { cleanup(dir); });
45
-
46
- assert.equal(detectHealthWidgetProjectState(dir), "none");
44
+ try {
45
+ assert.equal(detectHealthWidgetProjectState(dir), "none");
46
+ } finally {
47
+ cleanup(dir);
48
+ }
47
49
  });
48
50
 
49
- test("detectHealthWidgetProjectState: bootstrapped .gsd without milestones returns initialized", (t) => {
51
+ test("detectHealthWidgetProjectState: bootstrapped .gsd without milestones returns initialized", () => {
50
52
  const dir = makeTempDir("initialized");
51
- t.after(() => { cleanup(dir); });
52
-
53
- mkdirSync(join(dir, ".gsd"), { recursive: true });
54
- assert.equal(detectHealthWidgetProjectState(dir), "initialized");
53
+ try {
54
+ mkdirSync(join(dir, ".gsd"), { recursive: true });
55
+ assert.equal(detectHealthWidgetProjectState(dir), "initialized");
56
+ } finally {
57
+ cleanup(dir);
58
+ }
55
59
  });
56
60
 
57
- test("detectHealthWidgetProjectState: milestone without metrics returns active", (t) => {
61
+ test("detectHealthWidgetProjectState: milestone without metrics returns active", () => {
58
62
  const dir = makeTempDir("active");
59
- t.after(() => { cleanup(dir); });
60
-
61
- mkdirSync(join(dir, ".gsd", "milestones", "M001"), { recursive: true });
62
- assert.equal(detectHealthWidgetProjectState(dir), "active");
63
+ try {
64
+ mkdirSync(join(dir, ".gsd", "milestones", "M001"), { recursive: true });
65
+ assert.equal(detectHealthWidgetProjectState(dir), "active");
66
+ } finally {
67
+ cleanup(dir);
68
+ }
63
69
  });
64
70
 
65
- test("buildHealthLines: none state shows onboarding copy", (t) => {
71
+ test("buildHealthLines: none state shows onboarding copy", () => {
66
72
  assert.deepEqual(buildHealthLines(activeData({ projectState: "none" })), [
67
73
  " GSD No project loaded — run /gsd to start",
68
74
  ]);
69
75
  });
70
76
 
71
- test("buildHealthLines: initialized state shows continue setup copy", (t) => {
77
+ test("buildHealthLines: initialized state shows continue setup copy", () => {
72
78
  assert.deepEqual(buildHealthLines(activeData({ projectState: "initialized" })), [
73
79
  " GSD Project initialized — run /gsd to continue setup",
74
80
  ]);
75
81
  });
76
82
 
77
- test("buildHealthLines: active state with ledger-driven spend shows spent summary", (t) => {
83
+ test("buildHealthLines: active state with ledger-driven spend shows spent summary", () => {
78
84
  const lines = buildHealthLines(activeData({ budgetSpent: 0.42 }));
79
85
  assert.equal(lines.length, 1);
80
86
  assert.match(lines[0]!, /● System OK/);
81
87
  assert.match(lines[0]!, /Spent: 42\.0¢/);
82
88
  });
83
89
 
84
- test("buildHealthLines: active state with budget ceiling shows percent summary", (t) => {
90
+ test("buildHealthLines: active state with budget ceiling shows percent summary", () => {
85
91
  const lines = buildHealthLines(activeData({ budgetSpent: 2.5, budgetCeiling: 10 }));
86
92
  assert.equal(lines.length, 1);
87
93
  assert.match(lines[0]!, /Budget: \$2\.50\/\$10\.00 \(25%\)/);
88
94
  });
89
95
 
90
- test("buildHealthLines: active state with issues reports issue summary", (t) => {
96
+ test("buildHealthLines: active state with issues reports issue summary", () => {
91
97
  const lines = buildHealthLines(activeData({
92
98
  providerIssue: "✗ OpenAI key missing",
93
99
  environmentErrorCount: 1,
@@ -98,15 +104,17 @@ test("buildHealthLines: active state with issues reports issue summary", (t) =>
98
104
  assert.match(lines[0]!, /Env: 1 error/);
99
105
  });
100
106
 
101
- test("detectHealthWidgetProjectState: metrics file alone does not imply project", (t) => {
107
+ test("detectHealthWidgetProjectState: metrics file alone does not imply project", () => {
102
108
  const dir = makeTempDir("metrics-only");
103
- t.after(() => { cleanup(dir); });
104
-
105
- mkdirSync(join(dir, ".gsd"), { recursive: true });
106
- writeFileSync(
107
- join(dir, ".gsd", "metrics.json"),
108
- JSON.stringify({ version: 1, projectStartedAt: Date.now(), units: [] }),
109
- "utf-8",
110
- );
111
- assert.equal(detectHealthWidgetProjectState(dir), "initialized");
109
+ try {
110
+ mkdirSync(join(dir, ".gsd"), { recursive: true });
111
+ writeFileSync(
112
+ join(dir, ".gsd", "metrics.json"),
113
+ JSON.stringify({ version: 1, projectStartedAt: Date.now(), units: [] }),
114
+ "utf-8",
115
+ );
116
+ assert.equal(detectHealthWidgetProjectState(dir), "initialized");
117
+ } finally {
118
+ cleanup(dir);
119
+ }
112
120
  });
@@ -8,9 +8,9 @@ import {
8
8
  verifyExpectedArtifact,
9
9
  buildLoopRemediationSteps,
10
10
  } from "../auto.ts";
11
- import { describe, test, beforeEach, afterEach } from 'node:test';
12
- import assert from 'node:assert/strict';
11
+ import { createTestContext } from './test-helpers.ts';
13
12
 
13
+ const { assertEq, assertTrue, report } = createTestContext();
14
14
  function createFixtureBase(): string {
15
15
  const base = mkdtempSync(join(tmpdir(), "gsd-idle-recovery-test-"));
16
16
  mkdirSync(join(base, ".gsd", "milestones", "M001", "slices", "S01", "tasks"), { recursive: true });
@@ -23,91 +23,99 @@ function cleanup(base: string): void {
23
23
 
24
24
  // ═══ resolveExpectedArtifactPath ═════════════════════════════════════════════
25
25
 
26
- test('resolveExpectedArtifactPath: research-milestone', () => {
26
+ {
27
+ console.log("\n=== resolveExpectedArtifactPath: research-milestone ===");
27
28
  const base = createFixtureBase();
28
29
  try {
29
30
  const result = resolveExpectedArtifactPath("research-milestone", "M001", base);
30
- assert.ok(result !== null, "should resolve a path");
31
- assert.ok(result!.endsWith("M001-RESEARCH.md"), `path should end with M001-RESEARCH.md, got ${result}`);
31
+ assertTrue(result !== null, "should resolve a path");
32
+ assertTrue(result!.endsWith("M001-RESEARCH.md"), `path should end with M001-RESEARCH.md, got ${result}`);
32
33
  } finally {
33
34
  cleanup(base);
34
35
  }
35
- });
36
+ }
36
37
 
37
- test('resolveExpectedArtifactPath: plan-milestone', () => {
38
+ {
39
+ console.log("\n=== resolveExpectedArtifactPath: plan-milestone ===");
38
40
  const base = createFixtureBase();
39
41
  try {
40
42
  const result = resolveExpectedArtifactPath("plan-milestone", "M001", base);
41
- assert.ok(result !== null, "should resolve a path");
42
- assert.ok(result!.endsWith("M001-ROADMAP.md"), `path should end with M001-ROADMAP.md, got ${result}`);
43
+ assertTrue(result !== null, "should resolve a path");
44
+ assertTrue(result!.endsWith("M001-ROADMAP.md"), `path should end with M001-ROADMAP.md, got ${result}`);
43
45
  } finally {
44
46
  cleanup(base);
45
47
  }
46
- });
48
+ }
47
49
 
48
- test('resolveExpectedArtifactPath: research-slice', () => {
50
+ {
51
+ console.log("\n=== resolveExpectedArtifactPath: research-slice ===");
49
52
  const base = createFixtureBase();
50
53
  try {
51
54
  const result = resolveExpectedArtifactPath("research-slice", "M001/S01", base);
52
- assert.ok(result !== null, "should resolve a path");
53
- assert.ok(result!.endsWith("S01-RESEARCH.md"), `path should end with S01-RESEARCH.md, got ${result}`);
55
+ assertTrue(result !== null, "should resolve a path");
56
+ assertTrue(result!.endsWith("S01-RESEARCH.md"), `path should end with S01-RESEARCH.md, got ${result}`);
54
57
  } finally {
55
58
  cleanup(base);
56
59
  }
57
- });
60
+ }
58
61
 
59
- test('resolveExpectedArtifactPath: plan-slice', () => {
62
+ {
63
+ console.log("\n=== resolveExpectedArtifactPath: plan-slice ===");
60
64
  const base = createFixtureBase();
61
65
  try {
62
66
  const result = resolveExpectedArtifactPath("plan-slice", "M001/S01", base);
63
- assert.ok(result !== null, "should resolve a path");
64
- assert.ok(result!.endsWith("S01-PLAN.md"), `path should end with S01-PLAN.md, got ${result}`);
67
+ assertTrue(result !== null, "should resolve a path");
68
+ assertTrue(result!.endsWith("S01-PLAN.md"), `path should end with S01-PLAN.md, got ${result}`);
65
69
  } finally {
66
70
  cleanup(base);
67
71
  }
68
- });
72
+ }
69
73
 
70
- test('resolveExpectedArtifactPath: complete-milestone', () => {
74
+ {
75
+ console.log("\n=== resolveExpectedArtifactPath: complete-milestone ===");
71
76
  const base = createFixtureBase();
72
77
  try {
73
78
  const result = resolveExpectedArtifactPath("complete-milestone", "M001", base);
74
- assert.ok(result !== null, "should resolve a path");
75
- assert.ok(result!.endsWith("M001-SUMMARY.md"), `path should end with M001-SUMMARY.md, got ${result}`);
79
+ assertTrue(result !== null, "should resolve a path");
80
+ assertTrue(result!.endsWith("M001-SUMMARY.md"), `path should end with M001-SUMMARY.md, got ${result}`);
76
81
  } finally {
77
82
  cleanup(base);
78
83
  }
79
- });
84
+ }
80
85
 
81
- test('resolveExpectedArtifactPath: unknown unit type → null', () => {
86
+ {
87
+ console.log("\n=== resolveExpectedArtifactPath: unknown unit type → null ===");
82
88
  const base = createFixtureBase();
83
89
  try {
84
90
  const result = resolveExpectedArtifactPath("unknown-type", "M001/S01", base);
85
- assert.deepStrictEqual(result, null, "unknown type returns null");
91
+ assertEq(result, null, "unknown type returns null");
86
92
  } finally {
87
93
  cleanup(base);
88
94
  }
89
- });
95
+ }
90
96
 
91
97
  // ═══ writeBlockerPlaceholder ═════════════════════════════════════════════════
92
98
 
93
- test('writeBlockerPlaceholder: writes file for research-slice', () => {
99
+ {
100
+ console.log("\n=== writeBlockerPlaceholder: writes file for research-slice ===");
94
101
  const base = createFixtureBase();
95
102
  try {
96
103
  const result = writeBlockerPlaceholder("research-slice", "M001/S01", base, "idle recovery exhausted 2 attempts");
97
- assert.ok(result !== null, "should return relative path");
104
+ assertTrue(result !== null, "should return relative path");
98
105
  const absPath = resolveExpectedArtifactPath("research-slice", "M001/S01", base)!;
99
- assert.ok(existsSync(absPath), "file should exist on disk");
106
+ assertTrue(existsSync(absPath), "file should exist on disk");
100
107
  const content = readFileSync(absPath, "utf-8");
101
- assert.ok(content.includes("BLOCKER"), "should contain BLOCKER heading");
102
- assert.ok(content.includes("idle recovery exhausted 2 attempts"), "should contain the reason");
103
- assert.ok(content.includes("research-slice"), "should mention the unit type");
104
- assert.ok(content.includes("M001/S01"), "should mention the unit ID");
108
+ assertTrue(content.includes("BLOCKER"), "should contain BLOCKER heading");
109
+ assertTrue(content.includes("idle recovery exhausted 2 attempts"), "should contain the reason");
110
+ assertTrue(content.includes("research-slice"), "should mention the unit type");
111
+ assertTrue(content.includes("M001/S01"), "should mention the unit ID");
105
112
  } finally {
106
113
  cleanup(base);
107
114
  }
108
- });
115
+ }
109
116
 
110
- test('writeBlockerPlaceholder: creates directory if missing', () => {
117
+ {
118
+ console.log("\n=== writeBlockerPlaceholder: creates directory if missing ===");
111
119
  const base = mkdtempSync(join(tmpdir(), "gsd-idle-recovery-test-"));
112
120
  try {
113
121
  // Only create milestone dir, not slice dir
@@ -115,36 +123,38 @@ test('writeBlockerPlaceholder: creates directory if missing', () => {
115
123
  // resolveSlicePath needs the slice dir to exist to resolve, so this should return null
116
124
  const result = writeBlockerPlaceholder("research-slice", "M001/S01", base, "test reason");
117
125
  // Since the slice dir doesn't exist, resolveExpectedArtifactPath returns null
118
- assert.deepStrictEqual(result, null, "returns null when directory structure doesn't exist");
126
+ assertEq(result, null, "returns null when directory structure doesn't exist");
119
127
  } finally {
120
128
  cleanup(base);
121
129
  }
122
- });
130
+ }
123
131
 
124
- test('writeBlockerPlaceholder: writes file for research-milestone', () => {
132
+ {
133
+ console.log("\n=== writeBlockerPlaceholder: writes file for research-milestone ===");
125
134
  const base = createFixtureBase();
126
135
  try {
127
136
  const result = writeBlockerPlaceholder("research-milestone", "M001", base, "hard timeout");
128
- assert.ok(result !== null, "should return relative path");
137
+ assertTrue(result !== null, "should return relative path");
129
138
  const absPath = resolveExpectedArtifactPath("research-milestone", "M001", base)!;
130
- assert.ok(existsSync(absPath), "file should exist on disk");
139
+ assertTrue(existsSync(absPath), "file should exist on disk");
131
140
  const content = readFileSync(absPath, "utf-8");
132
- assert.ok(content.includes("BLOCKER"), "should contain BLOCKER heading");
133
- assert.ok(content.includes("hard timeout"), "should contain the reason");
141
+ assertTrue(content.includes("BLOCKER"), "should contain BLOCKER heading");
142
+ assertTrue(content.includes("hard timeout"), "should contain the reason");
134
143
  } finally {
135
144
  cleanup(base);
136
145
  }
137
- });
146
+ }
138
147
 
139
- test('writeBlockerPlaceholder: unknown type → null', () => {
148
+ {
149
+ console.log("\n=== writeBlockerPlaceholder: unknown type → null ===");
140
150
  const base = createFixtureBase();
141
151
  try {
142
152
  const result = writeBlockerPlaceholder("unknown-type", "M001/S01", base, "test");
143
- assert.deepStrictEqual(result, null, "unknown type returns null");
153
+ assertEq(result, null, "unknown type returns null");
144
154
  } finally {
145
155
  cleanup(base);
146
156
  }
147
- });
157
+ }
148
158
 
149
159
  // ═══ verifyExpectedArtifact: complete-slice roadmap check ════════════════════
150
160
  // Regression for #indefinite-hang: complete-slice must verify roadmap [x] or
@@ -167,7 +177,8 @@ const ROADMAP_COMPLETE = `# M001: Test Milestone
167
177
  > After this: something works
168
178
  `;
169
179
 
170
- test('verifyExpectedArtifact: complete-slice — all artifacts present + roadmap marked [x] returns true', () => {
180
+ {
181
+ console.log("\n=== verifyExpectedArtifact: complete-slice — all artifacts present + roadmap marked [x] returns true ===");
171
182
  const base = createFixtureBase();
172
183
  try {
173
184
  const sliceDir = join(base, ".gsd", "milestones", "M001", "slices", "S01");
@@ -175,13 +186,14 @@ test('verifyExpectedArtifact: complete-slice — all artifacts present + roadmap
175
186
  writeFileSync(join(sliceDir, "S01-UAT.md"), "# UAT\n", "utf-8");
176
187
  writeFileSync(join(base, ".gsd", "milestones", "M001", "M001-ROADMAP.md"), ROADMAP_COMPLETE, "utf-8");
177
188
  const result = verifyExpectedArtifact("complete-slice", "M001/S01", base);
178
- assert.ok(result === true, "SUMMARY + UAT + roadmap [x] should verify as true");
189
+ assertTrue(result === true, "SUMMARY + UAT + roadmap [x] should verify as true");
179
190
  } finally {
180
191
  cleanup(base);
181
192
  }
182
- });
193
+ }
183
194
 
184
- test('verifyExpectedArtifact: complete-slice — SUMMARY + UAT present but roadmap NOT marked [x] returns false', () => {
195
+ {
196
+ console.log("\n=== verifyExpectedArtifact: complete-slice — SUMMARY + UAT present but roadmap NOT marked [x] returns false ===");
185
197
  const base = createFixtureBase();
186
198
  try {
187
199
  const sliceDir = join(base, ".gsd", "milestones", "M001", "slices", "S01");
@@ -189,13 +201,14 @@ test('verifyExpectedArtifact: complete-slice — SUMMARY + UAT present but roadm
189
201
  writeFileSync(join(sliceDir, "S01-UAT.md"), "# UAT\n", "utf-8");
190
202
  writeFileSync(join(base, ".gsd", "milestones", "M001", "M001-ROADMAP.md"), ROADMAP_INCOMPLETE, "utf-8");
191
203
  const result = verifyExpectedArtifact("complete-slice", "M001/S01", base);
192
- assert.ok(result === false, "roadmap not marked [x] should return false (crash recovery scenario)");
204
+ assertTrue(result === false, "roadmap not marked [x] should return false (crash recovery scenario)");
193
205
  } finally {
194
206
  cleanup(base);
195
207
  }
196
- });
208
+ }
197
209
 
198
- test('verifyExpectedArtifact: complete-slice — SUMMARY present but UAT missing returns false', () => {
210
+ {
211
+ console.log("\n=== verifyExpectedArtifact: complete-slice — SUMMARY present but UAT missing returns false ===");
199
212
  const base = createFixtureBase();
200
213
  try {
201
214
  const sliceDir = join(base, ".gsd", "milestones", "M001", "slices", "S01");
@@ -203,13 +216,14 @@ test('verifyExpectedArtifact: complete-slice — SUMMARY present but UAT missing
203
216
  // no UAT file
204
217
  writeFileSync(join(base, ".gsd", "milestones", "M001", "M001-ROADMAP.md"), ROADMAP_COMPLETE, "utf-8");
205
218
  const result = verifyExpectedArtifact("complete-slice", "M001/S01", base);
206
- assert.ok(result === false, "missing UAT should return false");
219
+ assertTrue(result === false, "missing UAT should return false");
207
220
  } finally {
208
221
  cleanup(base);
209
222
  }
210
- });
223
+ }
211
224
 
212
- test('verifyExpectedArtifact: complete-slice — no roadmap file present is lenient (returns true)', () => {
225
+ {
226
+ console.log("\n=== verifyExpectedArtifact: complete-slice — no roadmap file present is lenient (returns true) ===");
213
227
  const base = createFixtureBase();
214
228
  try {
215
229
  const sliceDir = join(base, ".gsd", "milestones", "M001", "slices", "S01");
@@ -217,80 +231,87 @@ test('verifyExpectedArtifact: complete-slice — no roadmap file present is leni
217
231
  writeFileSync(join(sliceDir, "S01-UAT.md"), "# UAT\n", "utf-8");
218
232
  // no roadmap file
219
233
  const result = verifyExpectedArtifact("complete-slice", "M001/S01", base);
220
- assert.ok(result === true, "missing roadmap file should be lenient and return true");
234
+ assertTrue(result === true, "missing roadmap file should be lenient and return true");
221
235
  } finally {
222
236
  cleanup(base);
223
237
  }
224
- });
238
+ }
225
239
 
226
240
  // ═══ buildLoopRemediationSteps ═══════════════════════════════════════════════
227
241
 
228
- test('buildLoopRemediationSteps: execute-task returns concrete steps', () => {
242
+ {
243
+ console.log("\n=== buildLoopRemediationSteps: execute-task returns concrete steps ===");
229
244
  const base = mkdtempSync(join(tmpdir(), "gsd-loop-remediation-test-"));
230
245
  try {
231
246
  mkdirSync(join(base, ".gsd", "milestones", "M002", "slices", "S03", "tasks"), { recursive: true });
232
247
  const result = buildLoopRemediationSteps("execute-task", "M002/S03/T01", base);
233
- assert.ok(result !== null, "should return remediation steps");
234
- assert.ok(result!.includes("gsd undo-task"), "steps include undo-task command");
235
- assert.ok(result!.includes("T01"), "steps mention the task ID");
236
- assert.ok(result!.includes("gsd undo-task"), "steps include gsd undo-task command");
248
+ assertTrue(result !== null, "should return remediation steps");
249
+ assertTrue(result!.includes("gsd undo-task"), "steps include undo-task command");
250
+ assertTrue(result!.includes("T01"), "steps mention the task ID");
251
+ assertTrue(result!.includes("gsd undo-task"), "steps include gsd undo-task command");
237
252
  } finally {
238
253
  rmSync(base, { recursive: true, force: true });
239
254
  }
240
- });
255
+ }
241
256
 
242
- test('buildLoopRemediationSteps: plan-slice returns concrete steps', () => {
257
+ {
258
+ console.log("\n=== buildLoopRemediationSteps: plan-slice returns concrete steps ===");
243
259
  const base = mkdtempSync(join(tmpdir(), "gsd-loop-remediation-test-"));
244
260
  try {
245
261
  mkdirSync(join(base, ".gsd", "milestones", "M001", "slices", "S01"), { recursive: true });
246
262
  const result = buildLoopRemediationSteps("plan-slice", "M001/S01", base);
247
- assert.ok(result !== null, "should return remediation steps for plan-slice");
248
- assert.ok(result!.includes("S01-PLAN.md"), "steps mention the slice plan file");
249
- assert.ok(result!.includes("gsd recover"), "steps include gsd recover command");
263
+ assertTrue(result !== null, "should return remediation steps for plan-slice");
264
+ assertTrue(result!.includes("S01-PLAN.md"), "steps mention the slice plan file");
265
+ assertTrue(result!.includes("gsd recover"), "steps include gsd recover command");
250
266
  } finally {
251
267
  rmSync(base, { recursive: true, force: true });
252
268
  }
253
- });
269
+ }
254
270
 
255
- test('buildLoopRemediationSteps: research-slice returns concrete steps', () => {
271
+ {
272
+ console.log("\n=== buildLoopRemediationSteps: research-slice returns concrete steps ===");
256
273
  const base = mkdtempSync(join(tmpdir(), "gsd-loop-remediation-test-"));
257
274
  try {
258
275
  mkdirSync(join(base, ".gsd", "milestones", "M001", "slices", "S01"), { recursive: true });
259
276
  const result = buildLoopRemediationSteps("research-slice", "M001/S01", base);
260
- assert.ok(result !== null, "should return remediation steps for research-slice");
261
- assert.ok(result!.includes("S01-RESEARCH.md"), "steps mention the slice research file");
262
- assert.ok(result!.includes("gsd recover"), "steps include gsd recover command");
277
+ assertTrue(result !== null, "should return remediation steps for research-slice");
278
+ assertTrue(result!.includes("S01-RESEARCH.md"), "steps mention the slice research file");
279
+ assertTrue(result!.includes("gsd recover"), "steps include gsd recover command");
263
280
  } finally {
264
281
  rmSync(base, { recursive: true, force: true });
265
282
  }
266
- });
283
+ }
267
284
 
268
- test('buildLoopRemediationSteps: unknown type returns null', () => {
285
+ {
286
+ console.log("\n=== buildLoopRemediationSteps: unknown type returns null ===");
269
287
  const base = mkdtempSync(join(tmpdir(), "gsd-loop-remediation-test-"));
270
288
  try {
271
289
  const result = buildLoopRemediationSteps("unknown-type", "M001/S01", base);
272
- assert.deepStrictEqual(result, null, "unknown type returns null");
290
+ assertEq(result, null, "unknown type returns null");
273
291
  } finally {
274
292
  rmSync(base, { recursive: true, force: true });
275
293
  }
276
- });
294
+ }
277
295
 
278
296
  // ═══ verifyExpectedArtifact: hook unit types ═════════════════════════════════
279
297
 
280
- test('verifyExpectedArtifact: hook types always return true', () => {
298
+ console.log("\n=== verifyExpectedArtifact: hook types always return true ===");
299
+
300
+ {
281
301
  const base = createFixtureBase();
282
302
  try {
283
303
  // Hook units don't have standard artifacts — they should always pass
284
304
  const result1 = verifyExpectedArtifact("hook/code-review", "M001/S01/T01", base);
285
- assert.ok(result1, "hook/code-review should always return true");
305
+ assertTrue(result1, "hook/code-review should always return true");
286
306
 
287
307
  const result2 = verifyExpectedArtifact("hook/simplify", "M001/S01/T02", base);
288
- assert.ok(result2, "hook/simplify should always return true");
308
+ assertTrue(result2, "hook/simplify should always return true");
289
309
 
290
310
  const result3 = verifyExpectedArtifact("hook/custom-hook", "M001/S01", base);
291
- assert.ok(result3, "hook/custom-hook at slice level should return true");
311
+ assertTrue(result3, "hook/custom-hook at slice level should return true");
292
312
  } finally {
293
313
  rmSync(base, { recursive: true, force: true });
294
314
  }
295
- });
315
+ }
296
316
 
317
+ report();
@@ -36,17 +36,19 @@ function cleanup(dir: string): void {
36
36
 
37
37
  // ─── Detection Integration Tests ────────────────────────────────────────────────
38
38
 
39
- test("init-wizard: clean folder detected as state=none", (t) => {
39
+ test("init-wizard: clean folder detected as state=none", () => {
40
40
  const dir = makeTempDir("clean");
41
- t.after(() => { cleanup(dir); });
42
-
43
- const detection = detectProjectState(dir);
44
- assert.equal(detection.state, "none");
45
- assert.equal(detection.v1, undefined);
46
- assert.equal(detection.v2, undefined);
41
+ try {
42
+ const detection = detectProjectState(dir);
43
+ assert.equal(detection.state, "none");
44
+ assert.equal(detection.v1, undefined);
45
+ assert.equal(detection.v2, undefined);
46
+ } finally {
47
+ cleanup(dir);
48
+ }
47
49
  });
48
50
 
49
- test("init-wizard: v1 .planning/ triggers v1-planning state", (t) => {
51
+ test("init-wizard: v1 .planning/ triggers v1-planning state", () => {
50
52
  const dir = makeTempDir("v1");
51
53
  try {
52
54
  mkdirSync(join(dir, ".planning", "phases", "01"), { recursive: true });
@@ -63,7 +65,7 @@ test("init-wizard: v1 .planning/ triggers v1-planning state", (t) => {
63
65
  }
64
66
  });
65
67
 
66
- test("init-wizard: existing .gsd/ with milestones skips init", (t) => {
68
+ test("init-wizard: existing .gsd/ with milestones skips init", () => {
67
69
  const dir = makeTempDir("existing");
68
70
  try {
69
71
  mkdirSync(join(dir, ".gsd", "milestones", "M001"), { recursive: true });
@@ -78,7 +80,7 @@ test("init-wizard: existing .gsd/ with milestones skips init", (t) => {
78
80
  }
79
81
  });
80
82
 
81
- test("init-wizard: empty .gsd/ (no milestones) returns v2-gsd-empty", (t) => {
83
+ test("init-wizard: empty .gsd/ (no milestones) returns v2-gsd-empty", () => {
82
84
  const dir = makeTempDir("empty-gsd");
83
85
  try {
84
86
  mkdirSync(join(dir, ".gsd", "milestones"), { recursive: true });
@@ -92,7 +94,7 @@ test("init-wizard: empty .gsd/ (no milestones) returns v2-gsd-empty", (t) => {
92
94
  }
93
95
  });
94
96
 
95
- test("init-wizard: project signals populate from Node.js project", (t) => {
97
+ test("init-wizard: project signals populate from Node.js project", () => {
96
98
  const dir = makeTempDir("node-project");
97
99
  try {
98
100
  writeFileSync(
@@ -119,7 +121,7 @@ test("init-wizard: project signals populate from Node.js project", (t) => {
119
121
  }
120
122
  });
121
123
 
122
- test("init-wizard: v2 .gsd/ preferences detected", (t) => {
124
+ test("init-wizard: v2 .gsd/ preferences detected", () => {
123
125
  const dir = makeTempDir("prefs-detect");
124
126
  try {
125
127
  mkdirSync(join(dir, ".gsd", "milestones"), { recursive: true });
@@ -133,7 +135,7 @@ test("init-wizard: v2 .gsd/ preferences detected", (t) => {
133
135
  }
134
136
  });
135
137
 
136
- test("init-wizard: v2 uppercase PREFERENCES.md also detected", (t) => {
138
+ test("init-wizard: v2 uppercase PREFERENCES.md also detected", () => {
137
139
  const dir = makeTempDir("prefs-upper");
138
140
  try {
139
141
  mkdirSync(join(dir, ".gsd", "milestones"), { recursive: true });
@@ -147,7 +149,7 @@ test("init-wizard: v2 uppercase PREFERENCES.md also detected", (t) => {
147
149
  }
148
150
  });
149
151
 
150
- test("init-wizard: CONTEXT.md detected in v2", (t) => {
152
+ test("init-wizard: CONTEXT.md detected in v2", () => {
151
153
  const dir = makeTempDir("context");
152
154
  try {
153
155
  mkdirSync(join(dir, ".gsd", "milestones"), { recursive: true });
@@ -161,7 +163,7 @@ test("init-wizard: CONTEXT.md detected in v2", (t) => {
161
163
  }
162
164
  });
163
165
 
164
- test("init-wizard: multiple project files detected together", (t) => {
166
+ test("init-wizard: multiple project files detected together", () => {
165
167
  const dir = makeTempDir("multi-files");
166
168
  try {
167
169
  writeFileSync(join(dir, "package.json"), JSON.stringify({ name: "test" }), "utf-8");
@@ -178,7 +180,7 @@ test("init-wizard: multiple project files detected together", (t) => {
178
180
  }
179
181
  });
180
182
 
181
- test("init-wizard: v1 with both .planning/ and .gsd/ prioritizes v2", (t) => {
183
+ test("init-wizard: v1 with both .planning/ and .gsd/ prioritizes v2", () => {
182
184
  const dir = makeTempDir("both-v1-v2");
183
185
  try {
184
186
  mkdirSync(join(dir, ".planning", "phases"), { recursive: true });