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,11 +1,13 @@
1
- import { describe, test } from 'node:test';
2
- import assert from 'node:assert/strict';
3
1
  import { mkdtempSync, mkdirSync, rmSync, realpathSync } from "node:fs";
4
2
  import { join } from "node:path";
5
3
  import { tmpdir } from "node:os";
6
4
  import { spawnSync } from "node:child_process";
7
5
 
8
6
  import { gsdRoot, _clearGsdRootCache } from "../paths.ts";
7
+ import { createTestContext } from "./test-helpers.ts";
8
+
9
+ const { assertEq, assertTrue, report } = createTestContext();
10
+
9
11
  /** Create a tmp dir and resolve symlinks + 8.3 short names (macOS /var→/private/var, Windows RUNNER~1→runneradmin). */
10
12
  function tmp(): string {
11
13
  const p = mkdtempSync(join(tmpdir(), "gsd-paths-test-"));
@@ -21,78 +23,91 @@ function initGit(dir: string): void {
21
23
  spawnSync("git", ["commit", "--allow-empty", "-m", "init"], { cwd: dir });
22
24
  }
23
25
 
24
- describe('paths', () => {
25
- test('Case 1: .gsd exists at basePath — fast path', () => {
26
- const root = tmp();
27
- try {
28
- mkdirSync(join(root, ".gsd"));
29
- _clearGsdRootCache();
30
- const result = gsdRoot(root);
31
- assert.deepStrictEqual(result, join(root, ".gsd"), "fast path: returns basePath/.gsd");
32
- } finally { cleanup(root); }
33
- });
26
+ // ── tests ──────────────────────────────────────────────────────────────────
27
+
28
+ {
29
+ // Case 1: .gsd exists at basePath — fast path
30
+ const root = tmp();
31
+ try {
32
+ mkdirSync(join(root, ".gsd"));
33
+ _clearGsdRootCache();
34
+ const result = gsdRoot(root);
35
+ assertEq(result, join(root, ".gsd"), "fast path: returns basePath/.gsd");
36
+ } finally { cleanup(root); }
37
+ }
38
+
39
+ {
40
+ // Case 2: .gsd exists at git root, cwd is a subdirectory
41
+ const root = tmp();
42
+ try {
43
+ initGit(root);
44
+ mkdirSync(join(root, ".gsd"));
45
+ const sub = join(root, "src", "deep");
46
+ mkdirSync(sub, { recursive: true });
47
+ _clearGsdRootCache();
48
+ const result = gsdRoot(sub);
49
+ assertEq(result, join(root, ".gsd"), "git-root probe: finds .gsd at git root from subdirectory");
50
+ } finally { cleanup(root); }
51
+ }
34
52
 
35
- test('Case 2: .gsd exists at git root, cwd is a subdirectory', () => {
36
- const root = tmp();
37
- try {
38
- initGit(root);
39
- mkdirSync(join(root, ".gsd"));
40
- const sub = join(root, "src", "deep");
41
- mkdirSync(sub, { recursive: true });
42
- _clearGsdRootCache();
43
- const result = gsdRoot(sub);
44
- assert.deepStrictEqual(result, join(root, ".gsd"), "git-root probe: finds .gsd at git root from subdirectory");
45
- } finally { cleanup(root); }
46
- });
53
+ {
54
+ // Case 3: .gsd in an ancestor — walk-up finds it (git repo with no .gsd at root)
55
+ const root = tmp();
56
+ try {
57
+ // Init a git repo so git probe returns root — but put .gsd one level deeper
58
+ // to force the walk-up path: root/project/.gsd, cwd = root/project/src/deep
59
+ initGit(root);
60
+ const project = join(root, "project");
61
+ mkdirSync(join(project, ".gsd"), { recursive: true });
62
+ const deep = join(project, "src", "deep");
63
+ mkdirSync(deep, { recursive: true });
64
+ _clearGsdRootCache();
65
+ // git probe returns root (no .gsd there), so walk-up takes over and finds project/.gsd
66
+ const result = gsdRoot(deep);
67
+ assertEq(result, join(project, ".gsd"), "walk-up: finds .gsd in ancestor when git root has none");
68
+ } finally { cleanup(root); }
69
+ }
47
70
 
48
- test('Case 3: .gsd in an ancestor — walk-up finds it', () => {
49
- const root = tmp();
50
- try {
51
- initGit(root);
52
- const project = join(root, "project");
53
- mkdirSync(join(project, ".gsd"), { recursive: true });
54
- const deep = join(project, "src", "deep");
55
- mkdirSync(deep, { recursive: true });
56
- _clearGsdRootCache();
57
- const result = gsdRoot(deep);
58
- assert.deepStrictEqual(result, join(project, ".gsd"), "walk-up: finds .gsd in ancestor when git root has none");
59
- } finally { cleanup(root); }
60
- });
71
+ {
72
+ // Case 4: .gsd nowhere — fallback returns original basePath/.gsd
73
+ // Use an isolated git repo so we fully control the environment above basePath
74
+ const root = tmp();
75
+ try {
76
+ initGit(root); // git root = root, no .gsd anywhere
77
+ const sub = join(root, "src");
78
+ mkdirSync(sub, { recursive: true });
79
+ _clearGsdRootCache();
80
+ const result = gsdRoot(sub);
81
+ // git probe finds root (no .gsd), walk-up finds nothing fallback = sub/.gsd
82
+ assertEq(result, join(sub, ".gsd"), "fallback: returns basePath/.gsd when .gsd not found anywhere");
83
+ } finally { cleanup(root); }
84
+ }
61
85
 
62
- test('Case 4: .gsd nowhere — fallback returns original basePath/.gsd', () => {
63
- const root = tmp();
64
- try {
65
- initGit(root);
66
- const sub = join(root, "src");
67
- mkdirSync(sub, { recursive: true });
68
- _clearGsdRootCache();
69
- const result = gsdRoot(sub);
70
- assert.deepStrictEqual(result, join(sub, ".gsd"), "fallback: returns basePath/.gsd when .gsd not found anywhere");
71
- } finally { cleanup(root); }
72
- });
86
+ {
87
+ // Case 5: cache — second call returns same value without re-probing
88
+ const root = tmp();
89
+ try {
90
+ mkdirSync(join(root, ".gsd"));
91
+ _clearGsdRootCache();
92
+ const first = gsdRoot(root);
93
+ const second = gsdRoot(root);
94
+ assertEq(first, second, "cache: same result returned on second call");
95
+ assertTrue(first === second, "cache: identity check (same string)");
96
+ } finally { cleanup(root); }
97
+ }
73
98
 
74
- test('Case 5: cache — second call returns same value without re-probing', () => {
75
- const root = tmp();
76
- try {
77
- mkdirSync(join(root, ".gsd"));
78
- _clearGsdRootCache();
79
- const first = gsdRoot(root);
80
- const second = gsdRoot(root);
81
- assert.deepStrictEqual(first, second, "cache: same result returned on second call");
82
- assert.ok(first === second, "cache: identity check (same string)");
83
- } finally { cleanup(root); }
84
- });
99
+ {
100
+ // Case 6: .gsd at basePath takes precedence over ancestor .gsd
101
+ const outer = tmp();
102
+ try {
103
+ initGit(outer);
104
+ mkdirSync(join(outer, ".gsd"));
105
+ const inner = join(outer, "nested");
106
+ mkdirSync(join(inner, ".gsd"), { recursive: true });
107
+ _clearGsdRootCache();
108
+ const result = gsdRoot(inner);
109
+ assertEq(result, join(inner, ".gsd"), "precedence: nearest .gsd wins over ancestor");
110
+ } finally { cleanup(outer); }
111
+ }
85
112
 
86
- test('Case 6: .gsd at basePath takes precedence over ancestor .gsd', () => {
87
- const outer = tmp();
88
- try {
89
- initGit(outer);
90
- mkdirSync(join(outer, ".gsd"));
91
- const inner = join(outer, "nested");
92
- mkdirSync(join(inner, ".gsd"), { recursive: true });
93
- _clearGsdRootCache();
94
- const result = gsdRoot(inner);
95
- assert.deepStrictEqual(result, join(inner, ".gsd"), "precedence: nearest .gsd wins over ancestor");
96
- } finally { cleanup(outer); }
97
- });
98
- });
113
+ report();
@@ -1,10 +1,9 @@
1
1
  // GSD Extension — Hook Engine Tests (Post-Unit, Pre-Dispatch, State Persistence)
2
2
 
3
- import { describe, test } from 'node:test';
4
- import assert from 'node:assert/strict';
5
3
  import { mkdtempSync, mkdirSync, rmSync, writeFileSync, existsSync, readFileSync } from "node:fs";
6
4
  import { join } from "node:path";
7
5
  import { tmpdir } from "node:os";
6
+ import { createTestContext } from "./test-helpers.ts";
8
7
  import {
9
8
  checkPostUnitHooks,
10
9
  getActiveHook,
@@ -21,6 +20,8 @@ import {
21
20
  triggerHookManually,
22
21
  } from "../post-unit-hooks.ts";
23
22
 
23
+ const { assertEq, assertTrue, assertMatch, report } = createTestContext();
24
+
24
25
  // ─── Fixture Helpers ───────────────────────────────────────────────────────
25
26
 
26
27
  function createFixtureBase(): string {
@@ -35,14 +36,14 @@ function createFixtureBase(): string {
35
36
 
36
37
  // ─── resolveHookArtifactPath ───────────────────────────────────────────────
37
38
 
39
+ console.log("\n=== resolveHookArtifactPath ===");
38
40
 
39
- describe('post-unit-hooks', () => {
40
- test('resolveHookArtifactPath', () => {
41
+ {
41
42
  const base = "/project";
42
43
 
43
44
  // Task-level
44
45
  const taskPath = resolveHookArtifactPath(base, "M001/S01/T01", "REVIEW-PASS.md");
45
- assert.deepStrictEqual(
46
+ assertEq(
46
47
  taskPath,
47
48
  join(base, ".gsd", "milestones", "M001", "slices", "S01", "tasks", "T01-REVIEW-PASS.md"),
48
49
  "task-level artifact path",
@@ -50,7 +51,7 @@ test('resolveHookArtifactPath', () => {
50
51
 
51
52
  // Slice-level
52
53
  const slicePath = resolveHookArtifactPath(base, "M001/S01", "REVIEW-PASS.md");
53
- assert.deepStrictEqual(
54
+ assertEq(
54
55
  slicePath,
55
56
  join(base, ".gsd", "milestones", "M001", "slices", "S01", "REVIEW-PASS.md"),
56
57
  "slice-level artifact path",
@@ -58,106 +59,129 @@ test('resolveHookArtifactPath', () => {
58
59
 
59
60
  // Milestone-level
60
61
  const milestonePath = resolveHookArtifactPath(base, "M001", "REVIEW-PASS.md");
61
- assert.deepStrictEqual(
62
+ assertEq(
62
63
  milestonePath,
63
64
  join(base, ".gsd", "milestones", "M001", "REVIEW-PASS.md"),
64
65
  "milestone-level artifact path",
65
66
  );
66
- });
67
+ }
67
68
 
68
69
  // ─── resetHookState ────────────────────────────────────────────────────────
69
- test('resetHookState', () => {
70
+
71
+ console.log("\n=== resetHookState ===");
72
+
73
+ {
70
74
  resetHookState();
71
- assert.deepStrictEqual(getActiveHook(), null, "no active hook after reset");
72
- assert.ok(!isRetryPending(), "no retry pending after reset");
73
- assert.deepStrictEqual(consumeRetryTrigger(), null, "no retry trigger after reset");
74
- });
75
+ assertEq(getActiveHook(), null, "no active hook after reset");
76
+ assertTrue(!isRetryPending(), "no retry pending after reset");
77
+ assertEq(consumeRetryTrigger(), null, "no retry trigger after reset");
78
+ }
75
79
 
76
80
  // ─── checkPostUnitHooks with no hooks configured ───────────────────────────
77
- test('No hooks configured', () => {
81
+
82
+ console.log("\n=== No hooks configured ===");
83
+
84
+ {
78
85
  resetHookState();
79
86
  const base = createFixtureBase();
80
87
  try {
81
88
  const result = checkPostUnitHooks("execute-task", "M001/S01/T01", base);
82
- assert.deepStrictEqual(result, null, "returns null when no hooks configured");
89
+ assertEq(result, null, "returns null when no hooks configured");
83
90
  } finally {
84
91
  rmSync(base, { recursive: true, force: true });
85
92
  }
86
- });
93
+ }
87
94
 
88
95
  // ─── Hook units don't trigger hooks (no hook-on-hook) ──────────────────────
89
- test('Hook-on-hook prevention', () => {
96
+
97
+ console.log("\n=== Hook-on-hook prevention ===");
98
+
99
+ {
90
100
  resetHookState();
91
101
  const base = createFixtureBase();
92
102
  try {
93
103
  const result = checkPostUnitHooks("hook/code-review", "M001/S01/T01", base);
94
- assert.deepStrictEqual(result, null, "hook units don't trigger other hooks");
104
+ assertEq(result, null, "hook units don't trigger other hooks");
95
105
  } finally {
96
106
  rmSync(base, { recursive: true, force: true });
97
107
  }
98
- });
108
+ }
99
109
 
100
110
  // ─── consumeRetryTrigger clears state ──────────────────────────────────────
101
- test('consumeRetryTrigger clears state', () => {
111
+
112
+ console.log("\n=== consumeRetryTrigger clears state ===");
113
+
114
+ {
102
115
  resetHookState();
103
- assert.deepStrictEqual(consumeRetryTrigger(), null, "no trigger initially");
104
- assert.ok(!isRetryPending(), "no retry initially");
105
- });
116
+ assertEq(consumeRetryTrigger(), null, "no trigger initially");
117
+ assertTrue(!isRetryPending(), "no retry initially");
118
+ }
106
119
 
107
120
  // ─── Variable substitution in prompts ──────────────────────────────────────
108
- test('Variable substitution', () => {
121
+
122
+ console.log("\n=== Variable substitution ===");
123
+
124
+ {
109
125
  const base = "/project";
110
126
 
111
127
  // 3-part ID
112
128
  const path3 = resolveHookArtifactPath(base, "M002/S03/T05", "result.md");
113
- assert.ok(path3.includes("M002"), "3-part ID extracts milestoneId");
114
- assert.ok(path3.includes("S03"), "3-part ID extracts sliceId");
115
- assert.ok(path3.includes("T05"), "3-part ID extracts taskId");
116
- assert.ok(path3.includes("milestones"), "3-part ID includes milestones/ segment");
129
+ assertTrue(path3.includes("M002"), "3-part ID extracts milestoneId");
130
+ assertTrue(path3.includes("S03"), "3-part ID extracts sliceId");
131
+ assertTrue(path3.includes("T05"), "3-part ID extracts taskId");
132
+ assertTrue(path3.includes("milestones"), "3-part ID includes milestones/ segment");
117
133
 
118
134
  // 2-part ID
119
135
  const path2 = resolveHookArtifactPath(base, "M002/S03", "result.md");
120
- assert.ok(path2.includes("M002"), "2-part ID extracts milestoneId");
121
- assert.ok(path2.includes("S03"), "2-part ID extracts sliceId");
122
- assert.ok(path2.includes("milestones"), "2-part ID includes milestones/ segment");
136
+ assertTrue(path2.includes("M002"), "2-part ID extracts milestoneId");
137
+ assertTrue(path2.includes("S03"), "2-part ID extracts sliceId");
138
+ assertTrue(path2.includes("milestones"), "2-part ID includes milestones/ segment");
123
139
 
124
140
  // 1-part ID
125
141
  const path1 = resolveHookArtifactPath(base, "M002", "result.md");
126
- assert.ok(path1.includes("M002"), "1-part ID extracts milestoneId");
127
- assert.ok(path1.includes("milestones"), "1-part ID includes milestones/ segment");
128
- });
142
+ assertTrue(path1.includes("M002"), "1-part ID extracts milestoneId");
143
+ assertTrue(path1.includes("milestones"), "1-part ID includes milestones/ segment");
144
+ }
129
145
 
130
146
  // ═══════════════════════════════════════════════════════════════════════════
131
147
  // Phase 2: Pre-Dispatch Hook Tests
132
148
  // ═══════════════════════════════════════════════════════════════════════════
133
- test('Pre-dispatch: no hooks configured', () => {
149
+
150
+ console.log("\n=== Pre-dispatch: no hooks configured ===");
151
+
152
+ {
134
153
  const base = createFixtureBase();
135
154
  try {
136
155
  const result = runPreDispatchHooks("execute-task", "M001/S01/T01", "original prompt", base);
137
- assert.deepStrictEqual(result.action, "proceed", "proceeds when no hooks");
138
- assert.deepStrictEqual(result.prompt, "original prompt", "prompt unchanged");
139
- assert.deepStrictEqual(result.firedHooks.length, 0, "no hooks fired");
156
+ assertEq(result.action, "proceed", "proceeds when no hooks");
157
+ assertEq(result.prompt, "original prompt", "prompt unchanged");
158
+ assertEq(result.firedHooks.length, 0, "no hooks fired");
140
159
  } finally {
141
160
  rmSync(base, { recursive: true, force: true });
142
161
  }
143
- });
162
+ }
163
+
164
+ console.log("\n=== Pre-dispatch: hook units bypass ===");
144
165
 
145
- test('Pre-dispatch: hook units bypass', () => {
166
+ {
146
167
  const base = createFixtureBase();
147
168
  try {
148
169
  const result = runPreDispatchHooks("hook/review", "M001/S01/T01", "hook prompt", base);
149
- assert.deepStrictEqual(result.action, "proceed", "hook units always proceed");
150
- assert.deepStrictEqual(result.prompt, "hook prompt", "hook prompt unchanged");
151
- assert.deepStrictEqual(result.firedHooks.length, 0, "no hooks fired for hook units");
170
+ assertEq(result.action, "proceed", "hook units always proceed");
171
+ assertEq(result.prompt, "hook prompt", "hook prompt unchanged");
172
+ assertEq(result.firedHooks.length, 0, "no hooks fired for hook units");
152
173
  } finally {
153
174
  rmSync(base, { recursive: true, force: true });
154
175
  }
155
- });
176
+ }
156
177
 
157
178
  // ═══════════════════════════════════════════════════════════════════════════
158
179
  // Phase 3: State Persistence Tests
159
180
  // ═══════════════════════════════════════════════════════════════════════════
160
- test('State persistence: persist and restore', () => {
181
+
182
+ console.log("\n=== State persistence: persist and restore ===");
183
+
184
+ {
161
185
  const base = createFixtureBase();
162
186
  try {
163
187
  resetHookState();
@@ -165,17 +189,19 @@ test('State persistence: persist and restore', () => {
165
189
  // Persist empty state
166
190
  persistHookState(base);
167
191
  const filePath = join(base, ".gsd", "hook-state.json");
168
- assert.ok(existsSync(filePath), "hook-state.json created");
192
+ assertTrue(existsSync(filePath), "hook-state.json created");
169
193
 
170
194
  const content = JSON.parse(readFileSync(filePath, "utf-8"));
171
- assert.deepStrictEqual(typeof content.savedAt, "string", "savedAt is a string");
172
- assert.deepStrictEqual(Object.keys(content.cycleCounts).length, 0, "empty cycle counts");
195
+ assertEq(typeof content.savedAt, "string", "savedAt is a string");
196
+ assertEq(Object.keys(content.cycleCounts).length, 0, "empty cycle counts");
173
197
  } finally {
174
198
  rmSync(base, { recursive: true, force: true });
175
199
  }
176
- });
200
+ }
201
+
202
+ console.log("\n=== State persistence: restore from disk ===");
177
203
 
178
- test('State persistence: restore from disk', () => {
204
+ {
179
205
  const base = createFixtureBase();
180
206
  try {
181
207
  resetHookState();
@@ -196,14 +222,16 @@ test('State persistence: restore from disk', () => {
196
222
  // Verify by persisting and reading back
197
223
  persistHookState(base);
198
224
  const restored = JSON.parse(readFileSync(stateFile, "utf-8"));
199
- assert.deepStrictEqual(restored.cycleCounts["review/execute-task/M001/S01/T01"], 2, "cycle count restored for review");
200
- assert.deepStrictEqual(restored.cycleCounts["simplify/execute-task/M001/S01/T02"], 1, "cycle count restored for simplify");
225
+ assertEq(restored.cycleCounts["review/execute-task/M001/S01/T01"], 2, "cycle count restored for review");
226
+ assertEq(restored.cycleCounts["simplify/execute-task/M001/S01/T02"], 1, "cycle count restored for simplify");
201
227
  } finally {
202
228
  rmSync(base, { recursive: true, force: true });
203
229
  }
204
- });
230
+ }
231
+
232
+ console.log("\n=== State persistence: clear ===");
205
233
 
206
- test('State persistence: clear', () => {
234
+ {
207
235
  const base = createFixtureBase();
208
236
  try {
209
237
  resetHookState();
@@ -218,65 +246,77 @@ test('State persistence: clear', () => {
218
246
  clearPersistedHookState(base);
219
247
 
220
248
  const cleared = JSON.parse(readFileSync(stateFile, "utf-8"));
221
- assert.deepStrictEqual(Object.keys(cleared.cycleCounts).length, 0, "cycle counts cleared");
249
+ assertEq(Object.keys(cleared.cycleCounts).length, 0, "cycle counts cleared");
222
250
  } finally {
223
251
  rmSync(base, { recursive: true, force: true });
224
252
  }
225
- });
253
+ }
226
254
 
227
- test('State persistence: restore handles missing file', () => {
255
+ console.log("\n=== State persistence: restore handles missing file ===");
256
+
257
+ {
228
258
  const base = createFixtureBase();
229
259
  try {
230
260
  resetHookState();
231
261
  // Should not throw
232
262
  restoreHookState(base);
233
- assert.deepStrictEqual(getActiveHook(), null, "no active hook after restore from missing file");
263
+ assertEq(getActiveHook(), null, "no active hook after restore from missing file");
234
264
  } finally {
235
265
  rmSync(base, { recursive: true, force: true });
236
266
  }
237
- });
267
+ }
238
268
 
239
- test('State persistence: restore handles corrupt file', () => {
269
+ console.log("\n=== State persistence: restore handles corrupt file ===");
270
+
271
+ {
240
272
  const base = createFixtureBase();
241
273
  try {
242
274
  resetHookState();
243
275
  writeFileSync(join(base, ".gsd", "hook-state.json"), "not json", "utf-8");
244
276
  // Should not throw
245
277
  restoreHookState(base);
246
- assert.deepStrictEqual(getActiveHook(), null, "no active hook after corrupt restore");
278
+ assertEq(getActiveHook(), null, "no active hook after corrupt restore");
247
279
  } finally {
248
280
  rmSync(base, { recursive: true, force: true });
249
281
  }
250
- });
282
+ }
251
283
 
252
284
  // ═══════════════════════════════════════════════════════════════════════════
253
285
  // Phase 3: Hook Status Reporting Tests
254
286
  // ═══════════════════════════════════════════════════════════════════════════
255
- test('Hook status: no hooks', () => {
287
+
288
+ console.log("\n=== Hook status: no hooks ===");
289
+
290
+ {
256
291
  resetHookState();
257
292
  const entries = getHookStatus();
258
293
  // No preferences file = no hooks
259
- assert.deepStrictEqual(entries.length, 0, "no entries when no hooks configured");
294
+ assertEq(entries.length, 0, "no entries when no hooks configured");
260
295
 
261
296
  const formatted = formatHookStatus();
262
- assert.match(formatted, /No hooks configured/, "status message says no hooks");
263
- });
297
+ assertMatch(formatted, /No hooks configured/, "status message says no hooks");
298
+ }
264
299
 
265
300
  // ═══════════════════════════════════════════════════════════════════════════
266
301
  // Phase 4: Manual Hook Trigger Tests
267
302
  // ═══════════════════════════════════════════════════════════════════════════
268
- test('triggerHookManually: hook not found', () => {
303
+
304
+ console.log("\n=== triggerHookManually: hook not found ===");
305
+
306
+ {
269
307
  resetHookState();
270
308
  const base = createFixtureBase();
271
309
  try {
272
310
  const result = triggerHookManually("nonexistent-hook", "execute-task", "M001/S01/T01", base);
273
- assert.deepStrictEqual(result, null, "returns null when hook not found");
311
+ assertEq(result, null, "returns null when hook not found");
274
312
  } finally {
275
313
  rmSync(base, { recursive: true, force: true });
276
314
  }
277
- });
315
+ }
278
316
 
279
- test('triggerHookManually: with configured hook', () => {
317
+ console.log("\n=== triggerHookManually: with configured hook ===");
318
+
319
+ {
280
320
  resetHookState();
281
321
  const base = createFixtureBase();
282
322
  try {
@@ -285,16 +325,16 @@ test('triggerHookManually: with configured hook', () => {
285
325
  const result = triggerHookManually("code-review", "execute-task", "M001/S01/T01", base);
286
326
  // Result depends on whether code-review hook is configured in preferences
287
327
  // The function should either return null or a valid HookDispatchResult
288
- assert.ok(result === null || typeof result === "object", "returns null or object");
328
+ assertTrue(result === null || typeof result === "object", "returns null or object");
289
329
  if (result) {
290
- assert.deepStrictEqual(result.hookName, "code-review", "hook name in result");
291
- assert.deepStrictEqual(result.unitType, "hook/code-review", "unit type is hook-prefixed");
292
- assert.deepStrictEqual(result.unitId, "M001/S01/T01", "unit ID preserved");
293
- assert.ok(typeof result.prompt === "string", "prompt is a string");
330
+ assertEq(result.hookName, "code-review", "hook name in result");
331
+ assertEq(result.unitType, "hook/code-review", "unit type is hook-prefixed");
332
+ assertEq(result.unitId, "M001/S01/T01", "unit ID preserved");
333
+ assertTrue(typeof result.prompt === "string", "prompt is a string");
294
334
  }
295
335
  } finally {
296
336
  rmSync(base, { recursive: true, force: true });
297
337
  }
298
- });
338
+ }
299
339
 
300
- });
340
+ report();