gsd-pi 2.44.0-dev.62b5d6c → 2.44.0-dev.73f2fd5

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 (326) hide show
  1. package/README.md +30 -12
  2. package/dist/resources/extensions/gsd/auto/infra-errors.js +3 -0
  3. package/dist/resources/extensions/gsd/auto/phases.js +36 -36
  4. package/dist/resources/extensions/gsd/auto-prompts.js +24 -1
  5. package/dist/resources/extensions/gsd/auto-start.js +10 -0
  6. package/dist/resources/extensions/gsd/auto-timers.js +57 -3
  7. package/dist/resources/extensions/gsd/auto-worktree-sync.js +4 -0
  8. package/dist/resources/extensions/gsd/auto-worktree.js +9 -6
  9. package/dist/resources/extensions/gsd/auto.js +30 -3
  10. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +156 -0
  11. package/dist/resources/extensions/gsd/bootstrap/system-context.js +46 -12
  12. package/dist/resources/extensions/gsd/commands/catalog.js +6 -1
  13. package/dist/resources/extensions/gsd/commands/handlers/core.js +1 -0
  14. package/dist/resources/extensions/gsd/commands/handlers/ops.js +5 -0
  15. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +5 -0
  16. package/dist/resources/extensions/gsd/commands-mcp-status.js +187 -0
  17. package/dist/resources/extensions/gsd/db-writer.js +34 -16
  18. package/dist/resources/extensions/gsd/doctor.js +8 -0
  19. package/dist/resources/extensions/gsd/git-service.js +8 -3
  20. package/dist/resources/extensions/gsd/gsd-db.js +12 -1
  21. package/dist/resources/extensions/gsd/markdown-renderer.js +1 -1
  22. package/dist/resources/extensions/gsd/preferences.js +9 -1
  23. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +2 -4
  24. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  25. package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +6 -6
  26. package/dist/resources/extensions/gsd/prompts/replan-slice.md +3 -14
  27. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +7 -37
  28. package/dist/resources/extensions/gsd/provider-error-pause.js +7 -0
  29. package/dist/resources/extensions/gsd/state.js +19 -2
  30. package/dist/resources/extensions/gsd/tools/plan-slice.js +1 -0
  31. package/dist/resources/extensions/gsd/tools/plan-task.js +1 -0
  32. package/dist/resources/extensions/gsd/tools/replan-slice.js +2 -0
  33. package/dist/resources/extensions/gsd/tools/validate-milestone.js +88 -0
  34. package/dist/resources/extensions/gsd/worktree-resolver.js +6 -0
  35. package/dist/resources/extensions/mcp-client/index.js +14 -0
  36. package/dist/web/standalone/.next/BUILD_ID +1 -1
  37. package/dist/web/standalone/.next/app-path-routes-manifest.json +17 -17
  38. package/dist/web/standalone/.next/build-manifest.json +2 -2
  39. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  40. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  41. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  42. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  43. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  44. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  45. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  46. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  47. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  48. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  49. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  50. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  51. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  52. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  53. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  54. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  55. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  56. package/dist/web/standalone/.next/server/app/index.html +1 -1
  57. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  58. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  59. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  60. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  61. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  62. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  63. package/dist/web/standalone/.next/server/app-paths-manifest.json +17 -17
  64. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  65. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  66. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  67. package/package.json +1 -1
  68. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +3 -1
  69. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  70. package/packages/pi-coding-agent/dist/core/auth-storage.js +15 -1
  71. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  72. package/packages/pi-coding-agent/dist/core/auth-storage.test.js +6 -8
  73. package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
  74. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +24 -26
  75. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
  76. package/packages/pi-coding-agent/dist/core/fs-utils.test.js +29 -48
  77. package/packages/pi-coding-agent/dist/core/fs-utils.test.js.map +1 -1
  78. package/packages/pi-coding-agent/dist/core/local-model-check.d.ts +15 -0
  79. package/packages/pi-coding-agent/dist/core/local-model-check.d.ts.map +1 -0
  80. package/packages/pi-coding-agent/dist/core/local-model-check.js +41 -0
  81. package/packages/pi-coding-agent/dist/core/local-model-check.js.map +1 -0
  82. package/packages/pi-coding-agent/dist/core/model-registry.d.ts +11 -0
  83. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  84. package/packages/pi-coding-agent/dist/core/model-registry.js +20 -1
  85. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  86. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js +34 -44
  87. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js.map +1 -1
  88. package/packages/pi-coding-agent/dist/core/session-manager.test.js +30 -34
  89. package/packages/pi-coding-agent/dist/core/session-manager.test.js.map +1 -1
  90. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +3 -0
  91. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  92. package/packages/pi-coding-agent/dist/core/settings-manager.js +6 -0
  93. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  94. package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js +10 -12
  95. package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js.map +1 -1
  96. package/packages/pi-coding-agent/dist/main.d.ts.map +1 -1
  97. package/packages/pi-coding-agent/dist/main.js +17 -0
  98. package/packages/pi-coding-agent/dist/main.js.map +1 -1
  99. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.d.ts +2 -0
  100. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.d.ts.map +1 -0
  101. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.js +32 -0
  102. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.js.map +1 -0
  103. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts +3 -1
  104. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  105. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +8 -1
  106. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
  107. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +2 -0
  108. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  109. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +12 -0
  110. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
  111. package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.d.ts +15 -0
  112. package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.d.ts.map +1 -0
  113. package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.js +40 -0
  114. package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.js.map +1 -0
  115. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  116. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +4 -1
  117. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  118. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts +5 -2
  119. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  120. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js +13 -2
  121. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js.map +1 -1
  122. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  123. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +17 -8
  124. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  125. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  126. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +7 -3
  127. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  128. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js +43 -47
  129. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js.map +1 -1
  130. package/packages/pi-coding-agent/src/core/auth-storage.test.ts +7 -7
  131. package/packages/pi-coding-agent/src/core/auth-storage.ts +15 -1
  132. package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +26 -26
  133. package/packages/pi-coding-agent/src/core/fs-utils.test.ts +31 -43
  134. package/packages/pi-coding-agent/src/core/local-model-check.ts +45 -0
  135. package/packages/pi-coding-agent/src/core/model-registry.ts +21 -1
  136. package/packages/pi-coding-agent/src/core/resolve-config-value.test.ts +40 -45
  137. package/packages/pi-coding-agent/src/core/session-manager.test.ts +33 -33
  138. package/packages/pi-coding-agent/src/core/settings-manager.ts +9 -0
  139. package/packages/pi-coding-agent/src/core/tools/edit-diff.test.ts +17 -17
  140. package/packages/pi-coding-agent/src/main.ts +19 -0
  141. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/timestamp.test.ts +38 -0
  142. package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +10 -0
  143. package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +15 -0
  144. package/packages/pi-coding-agent/src/modes/interactive/components/timestamp.ts +48 -0
  145. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +3 -1
  146. package/packages/pi-coding-agent/src/modes/interactive/components/user-message.ts +18 -3
  147. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +16 -7
  148. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +8 -1
  149. package/packages/pi-coding-agent/src/resources/extensions/memory/storage.test.ts +74 -74
  150. package/src/resources/extensions/gsd/auto/infra-errors.ts +3 -0
  151. package/src/resources/extensions/gsd/auto/phases.ts +45 -48
  152. package/src/resources/extensions/gsd/auto-prompts.ts +24 -1
  153. package/src/resources/extensions/gsd/auto-start.ts +14 -0
  154. package/src/resources/extensions/gsd/auto-timers.ts +64 -3
  155. package/src/resources/extensions/gsd/auto-worktree-sync.ts +5 -0
  156. package/src/resources/extensions/gsd/auto-worktree.ts +9 -6
  157. package/src/resources/extensions/gsd/auto.ts +37 -3
  158. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +148 -0
  159. package/src/resources/extensions/gsd/bootstrap/system-context.ts +48 -11
  160. package/src/resources/extensions/gsd/commands/catalog.ts +6 -1
  161. package/src/resources/extensions/gsd/commands/handlers/core.ts +1 -0
  162. package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -0
  163. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +8 -0
  164. package/src/resources/extensions/gsd/commands-mcp-status.ts +247 -0
  165. package/src/resources/extensions/gsd/db-writer.ts +39 -17
  166. package/src/resources/extensions/gsd/doctor.ts +7 -1
  167. package/src/resources/extensions/gsd/git-service.ts +6 -2
  168. package/src/resources/extensions/gsd/gsd-db.ts +16 -1
  169. package/src/resources/extensions/gsd/markdown-renderer.ts +1 -1
  170. package/src/resources/extensions/gsd/preferences.ts +11 -1
  171. package/src/resources/extensions/gsd/prompts/complete-milestone.md +2 -4
  172. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  173. package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +6 -6
  174. package/src/resources/extensions/gsd/prompts/replan-slice.md +3 -14
  175. package/src/resources/extensions/gsd/prompts/validate-milestone.md +7 -37
  176. package/src/resources/extensions/gsd/provider-error-pause.ts +9 -0
  177. package/src/resources/extensions/gsd/state.ts +19 -1
  178. package/src/resources/extensions/gsd/tests/all-milestones-complete-merge.test.ts +99 -99
  179. package/src/resources/extensions/gsd/tests/auto-lock-creation.test.ts +14 -16
  180. package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +43 -57
  181. package/src/resources/extensions/gsd/tests/auto-pr-bugs.test.ts +88 -0
  182. package/src/resources/extensions/gsd/tests/auto-preflight.test.ts +11 -13
  183. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +465 -523
  184. package/src/resources/extensions/gsd/tests/auto-secrets-gate.test.ts +73 -75
  185. package/src/resources/extensions/gsd/tests/auto-start-needs-discussion.test.ts +34 -56
  186. package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +533 -656
  187. package/src/resources/extensions/gsd/tests/auto-worktree.test.ts +165 -143
  188. package/src/resources/extensions/gsd/tests/cache-staleness-regression.test.ts +29 -52
  189. package/src/resources/extensions/gsd/tests/captures.test.ts +148 -176
  190. package/src/resources/extensions/gsd/tests/claude-import-tui.test.ts +32 -33
  191. package/src/resources/extensions/gsd/tests/collect-from-manifest.test.ts +141 -143
  192. package/src/resources/extensions/gsd/tests/commands-inspect-open-db.test.ts +25 -25
  193. package/src/resources/extensions/gsd/tests/commands-logs.test.ts +81 -81
  194. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +38 -59
  195. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +228 -263
  196. package/src/resources/extensions/gsd/tests/complete-task.test.ts +250 -302
  197. package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +114 -0
  198. package/src/resources/extensions/gsd/tests/context-store.test.ts +354 -367
  199. package/src/resources/extensions/gsd/tests/continue-here.test.ts +68 -72
  200. package/src/resources/extensions/gsd/tests/cost-projection.test.ts +92 -106
  201. package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +27 -35
  202. package/src/resources/extensions/gsd/tests/dashboard-budget.test.ts +220 -237
  203. package/src/resources/extensions/gsd/tests/db-writer.test.ts +465 -416
  204. package/src/resources/extensions/gsd/tests/definition-loader.test.ts +76 -92
  205. package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +68 -83
  206. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +210 -181
  207. package/src/resources/extensions/gsd/tests/derive-state-deps.test.ts +78 -101
  208. package/src/resources/extensions/gsd/tests/derive-state.test.ts +192 -227
  209. package/src/resources/extensions/gsd/tests/detection.test.ts +232 -278
  210. package/src/resources/extensions/gsd/tests/dev-engine-wrapper.test.ts +30 -34
  211. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +164 -180
  212. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +43 -49
  213. package/src/resources/extensions/gsd/tests/dispatch-uat-last-completed.test.ts +28 -32
  214. package/src/resources/extensions/gsd/tests/doctor-completion-deferral.test.ts +27 -29
  215. package/src/resources/extensions/gsd/tests/doctor-delimiter-fix.test.ts +34 -38
  216. package/src/resources/extensions/gsd/tests/doctor-enhancements.test.ts +54 -75
  217. package/src/resources/extensions/gsd/tests/doctor-environment-worktree.test.ts +21 -32
  218. package/src/resources/extensions/gsd/tests/doctor-environment.test.ts +72 -97
  219. package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +38 -44
  220. package/src/resources/extensions/gsd/tests/doctor-git.test.ts +104 -145
  221. package/src/resources/extensions/gsd/tests/doctor-proactive.test.ts +84 -106
  222. package/src/resources/extensions/gsd/tests/doctor-roadmap-summary-atomicity.test.ts +54 -60
  223. package/src/resources/extensions/gsd/tests/doctor-runtime.test.ts +72 -93
  224. package/src/resources/extensions/gsd/tests/doctor.test.ts +104 -134
  225. package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +123 -131
  226. package/src/resources/extensions/gsd/tests/est-annotation-timeout.test.ts +120 -0
  227. package/src/resources/extensions/gsd/tests/exit-command.test.ts +20 -24
  228. package/src/resources/extensions/gsd/tests/feature-branch-lifecycle-integration.test.ts +48 -57
  229. package/src/resources/extensions/gsd/tests/files-loadfile-eisdir.test.ts +5 -7
  230. package/src/resources/extensions/gsd/tests/flag-file-db.test.ts +30 -42
  231. package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +198 -206
  232. package/src/resources/extensions/gsd/tests/git-locale.test.ts +13 -27
  233. package/src/resources/extensions/gsd/tests/git-service.test.ts +285 -388
  234. package/src/resources/extensions/gsd/tests/gitignore-tracked-gsd.test.ts +31 -39
  235. package/src/resources/extensions/gsd/tests/graph-operations.test.ts +63 -69
  236. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +255 -264
  237. package/src/resources/extensions/gsd/tests/gsd-inspect.test.ts +108 -119
  238. package/src/resources/extensions/gsd/tests/gsd-recover.test.ts +81 -103
  239. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +229 -262
  240. package/src/resources/extensions/gsd/tests/headless-answers.test.ts +13 -13
  241. package/src/resources/extensions/gsd/tests/health-widget.test.ts +29 -37
  242. package/src/resources/extensions/gsd/tests/idle-recovery.test.ts +81 -102
  243. package/src/resources/extensions/gsd/tests/infra-error.test.ts +20 -2
  244. package/src/resources/extensions/gsd/tests/init-wizard.test.ts +16 -18
  245. package/src/resources/extensions/gsd/tests/integration-edge.test.ts +41 -46
  246. package/src/resources/extensions/gsd/tests/integration-lifecycle.test.ts +42 -53
  247. package/src/resources/extensions/gsd/tests/integration-mixed-milestones.test.ts +75 -91
  248. package/src/resources/extensions/gsd/tests/integration-proof.test.ts +18 -18
  249. package/src/resources/extensions/gsd/tests/knowledge.test.ts +89 -0
  250. package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +150 -194
  251. package/src/resources/extensions/gsd/tests/mcp-status.test.ts +103 -0
  252. package/src/resources/extensions/gsd/tests/md-importer.test.ts +101 -125
  253. package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +45 -54
  254. package/src/resources/extensions/gsd/tests/memory-store.test.ts +80 -93
  255. package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +66 -0
  256. package/src/resources/extensions/gsd/tests/migrate-command.test.ts +57 -66
  257. package/src/resources/extensions/gsd/tests/migrate-hierarchy.test.ts +83 -93
  258. package/src/resources/extensions/gsd/tests/migrate-parser.test.ts +161 -170
  259. package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +125 -141
  260. package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +107 -131
  261. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +87 -96
  262. package/src/resources/extensions/gsd/tests/migrate-writer.test.ts +125 -164
  263. package/src/resources/extensions/gsd/tests/must-have-parser.test.ts +81 -94
  264. package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +35 -36
  265. package/src/resources/extensions/gsd/tests/overrides.test.ts +99 -106
  266. package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +40 -47
  267. package/src/resources/extensions/gsd/tests/parallel-worker-monitoring.test.ts +25 -28
  268. package/src/resources/extensions/gsd/tests/parallel-workers-multi-milestone-e2e.test.ts +66 -83
  269. package/src/resources/extensions/gsd/tests/park-edge-cases.test.ts +54 -77
  270. package/src/resources/extensions/gsd/tests/park-milestone.test.ts +68 -115
  271. package/src/resources/extensions/gsd/tests/parsers.test.ts +546 -611
  272. package/src/resources/extensions/gsd/tests/paths.test.ts +72 -87
  273. package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +77 -117
  274. package/src/resources/extensions/gsd/tests/preferences.test.ts +27 -0
  275. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +11 -7
  276. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +56 -56
  277. package/src/resources/extensions/gsd/tests/queue-draft-detection.test.ts +93 -119
  278. package/src/resources/extensions/gsd/tests/queue-order.test.ts +70 -82
  279. package/src/resources/extensions/gsd/tests/queue-reorder-e2e.test.ts +42 -55
  280. package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +100 -0
  281. package/src/resources/extensions/gsd/tests/quick-branch-lifecycle.test.ts +45 -73
  282. package/src/resources/extensions/gsd/tests/reassess-prompt.test.ts +28 -38
  283. package/src/resources/extensions/gsd/tests/replan-slice.test.ts +73 -80
  284. package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +71 -74
  285. package/src/resources/extensions/gsd/tests/requirements.test.ts +70 -75
  286. package/src/resources/extensions/gsd/tests/retry-state-reset.test.ts +44 -66
  287. package/src/resources/extensions/gsd/tests/roadmap-parse-regression.test.ts +114 -181
  288. package/src/resources/extensions/gsd/tests/rule-registry.test.ts +63 -65
  289. package/src/resources/extensions/gsd/tests/run-uat.test.ts +66 -128
  290. package/src/resources/extensions/gsd/tests/session-lock-multipath.test.ts +18 -25
  291. package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +37 -44
  292. package/src/resources/extensions/gsd/tests/shared-wal.test.ts +19 -26
  293. package/src/resources/extensions/gsd/tests/sqlite-unavailable-gate.test.ts +63 -0
  294. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +6 -8
  295. package/src/resources/extensions/gsd/tests/stop-auto-merge-back.test.ts +67 -0
  296. package/src/resources/extensions/gsd/tests/symlink-numbered-variants.test.ts +22 -28
  297. package/src/resources/extensions/gsd/tests/terminated-transient.test.ts +49 -0
  298. package/src/resources/extensions/gsd/tests/token-savings.test.ts +54 -56
  299. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +23 -25
  300. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +10 -11
  301. package/src/resources/extensions/gsd/tests/unique-milestone-ids.test.ts +66 -82
  302. package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +46 -47
  303. package/src/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +20 -22
  304. package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +84 -86
  305. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +41 -43
  306. package/src/resources/extensions/gsd/tests/visualizer-views.test.ts +94 -96
  307. package/src/resources/extensions/gsd/tests/windows-path-normalization.test.ts +11 -13
  308. package/src/resources/extensions/gsd/tests/worker-registry.test.ts +27 -29
  309. package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +50 -52
  310. package/src/resources/extensions/gsd/tests/worktree-bugfix.test.ts +10 -13
  311. package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +14 -18
  312. package/src/resources/extensions/gsd/tests/worktree-db.test.ts +38 -39
  313. package/src/resources/extensions/gsd/tests/worktree-e2e.test.ts +17 -21
  314. package/src/resources/extensions/gsd/tests/worktree-health.test.ts +25 -30
  315. package/src/resources/extensions/gsd/tests/worktree-integration.test.ts +30 -37
  316. package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +15 -22
  317. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +59 -66
  318. package/src/resources/extensions/gsd/tests/worktree.test.ts +44 -50
  319. package/src/resources/extensions/gsd/tools/plan-slice.ts +2 -0
  320. package/src/resources/extensions/gsd/tools/plan-task.ts +2 -0
  321. package/src/resources/extensions/gsd/tools/replan-slice.ts +3 -0
  322. package/src/resources/extensions/gsd/tools/validate-milestone.ts +127 -0
  323. package/src/resources/extensions/gsd/worktree-resolver.ts +7 -0
  324. package/src/resources/extensions/mcp-client/index.ts +20 -0
  325. /package/dist/web/standalone/.next/static/{fOnWQBjWXMKUs4bqTg530 → kxxAA66bah_yhPYqLBHE2}/_buildManifest.js +0 -0
  326. /package/dist/web/standalone/.next/static/{fOnWQBjWXMKUs4bqTg530 → kxxAA66bah_yhPYqLBHE2}/_ssgManifest.js +0 -0
@@ -1,15 +1,15 @@
1
+ import { describe, test, after } from 'node:test';
2
+ import assert from 'node:assert/strict';
1
3
  import { parseRequirementCounts } from "../files.ts";
2
4
  import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
3
5
  import { join } from "node:path";
4
6
  import { tmpdir } from "node:os";
5
7
  import { deriveState } from "../state.ts";
6
8
  import { runGSDDoctor } from "../doctor.ts";
7
- import { createTestContext } from './test-helpers.ts';
8
9
 
9
- const { assertEq, assertTrue, report } = createTestContext();
10
- console.log("\n=== requirement counts parser ===");
11
- {
12
- const counts = parseRequirementCounts(`# Requirements
10
+ describe('requirements', () => {
11
+ test('requirement counts parser', () => {
12
+ const counts = parseRequirementCounts(`# Requirements
13
13
 
14
14
  ## Active
15
15
 
@@ -34,73 +34,68 @@ console.log("\n=== requirement counts parser ===");
34
34
  ### R030 — No
35
35
  - Status: out-of-scope
36
36
  `);
37
- assertEq(counts.active, 2, "counts active requirements by section");
38
- assertEq(counts.validated, 1, "counts validated requirements");
39
- assertEq(counts.deferred, 1, "counts deferred requirements");
40
- assertEq(counts.outOfScope, 1, "counts out of scope requirements");
41
- assertEq(counts.blocked, 1, "counts blocked statuses");
42
- }
43
-
44
- const base = mkdtempSync(join(tmpdir(), "gsd-requirements-test-"));
45
- const gsd = join(base, ".gsd");
46
- const mDir = join(gsd, "milestones", "M001");
47
- const sDir = join(mDir, "slices", "S01");
48
- const tDir = join(sDir, "tasks");
49
- mkdirSync(tDir, { recursive: true });
50
- writeFileSync(join(gsd, "REQUIREMENTS.md"), `# Requirements
51
-
52
- ## Active
53
-
54
- ### R001 — Missing owner
55
- - Class: core-capability
56
- - Status: active
57
- - Description: thing
58
- - Why it matters: thing
59
- - Source: user
60
- - Primary owning slice: none yet
61
- - Supporting slices: none
62
- - Validation: unmapped
63
- - Notes: none
64
-
65
- ## Validated
66
-
67
- ## Deferred
68
-
69
- ## Out of Scope
70
-
71
- ## Traceability
72
- `, "utf-8");
73
- writeFileSync(join(mDir, "M001-ROADMAP.md"), `# M001: Demo
74
-
75
- ## Slices
76
- - [ ] **S01: Demo Slice** \`risk:low\` \`depends:[]\`
77
- > After this: demo works
78
- `, "utf-8");
79
- writeFileSync(join(sDir, "S01-PLAN.md"), `# S01: Demo Slice
80
-
81
- **Goal:** Demo
82
- **Demo:** Demo
83
-
84
- ## Must-Haves
85
- - done
86
-
87
- ## Tasks
88
- - [ ] **T01: Implement thing** \`est:10m\`
89
- Task is in progress.
90
- `, "utf-8");
91
-
92
- console.log("\n=== deriveState includes requirements counts ===");
93
- {
94
- const state = await deriveState(base);
95
- assertTrue(state.requirements !== undefined, "state includes requirements summary");
96
- assertEq(state.requirements?.active, 1, "state reports active requirement count");
97
- }
98
-
99
- console.log("\n=== doctor flags orphaned active requirement ===");
100
- {
101
- const report = await runGSDDoctor(base);
102
- assertTrue(report.issues.some(issue => issue.code === "active_requirement_missing_owner"), "doctor flags missing owner");
103
- }
104
-
105
- rmSync(base, { recursive: true, force: true });
106
- report();
37
+ assert.deepStrictEqual(counts.active, 2, "counts active requirements by section");
38
+ assert.deepStrictEqual(counts.validated, 1, "counts validated requirements");
39
+ assert.deepStrictEqual(counts.deferred, 1, "counts deferred requirements");
40
+ assert.deepStrictEqual(counts.outOfScope, 1, "counts out of scope requirements");
41
+ assert.deepStrictEqual(counts.blocked, 1, "counts blocked statuses");
42
+ });
43
+
44
+ const base = mkdtempSync(join(tmpdir(), "gsd-requirements-test-"));
45
+ const gsd = join(base, ".gsd");
46
+ const mDir = join(gsd, "milestones", "M001");
47
+ const sDir = join(mDir, "slices", "S01");
48
+ const tDir = join(sDir, "tasks");
49
+ mkdirSync(tDir, { recursive: true });
50
+ writeFileSync(join(gsd, "REQUIREMENTS.md"), [
51
+ "# Requirements",
52
+ "## Active",
53
+ "### R001 — Missing owner",
54
+ "- Class: core-capability",
55
+ "- Status: active",
56
+ "- Description: thing",
57
+ "- Why it matters: thing",
58
+ "- Source: user",
59
+ "- Primary owning slice: none yet",
60
+ "- Supporting slices: none",
61
+ "- Validation: unmapped",
62
+ "- Notes: none",
63
+ "## Validated",
64
+ "## Deferred",
65
+ "## Out of Scope",
66
+ "## Traceability",
67
+ "",
68
+ ].join("\n"), "utf-8");
69
+ writeFileSync(join(mDir, "M001-ROADMAP.md"), [
70
+ "# M001: Demo",
71
+ "## Slices",
72
+ "- [ ] **S01: Demo Slice** `risk:low` `depends:[]`",
73
+ " > After this: demo works",
74
+ "",
75
+ ].join("\n"), "utf-8");
76
+ writeFileSync(join(sDir, "S01-PLAN.md"), [
77
+ "# S01: Demo Slice",
78
+ "**Goal:** Demo",
79
+ "**Demo:** Demo",
80
+ "## Must-Haves",
81
+ "- done",
82
+ "## Tasks",
83
+ "- [ ] **T01: Implement thing** `est:10m`",
84
+ " Task is in progress.",
85
+ "",
86
+ ].join("\n"), "utf-8");
87
+ test('deriveState includes requirements counts', async () => {
88
+ const state = await deriveState(base);
89
+ assert.ok(state.requirements !== undefined, "state includes requirements summary");
90
+ assert.deepStrictEqual(state.requirements?.active, 1, "state reports active requirement count");
91
+ });
92
+
93
+ test('doctor flags orphaned active requirement', async () => {
94
+ const report = await runGSDDoctor(base);
95
+ assert.ok(report.issues.some(issue => issue.code === "active_requirement_missing_owner"), "doctor flags missing owner");
96
+ });
97
+
98
+ after(() => {
99
+ rmSync(base, { recursive: true, force: true });
100
+ });
101
+ });
@@ -4,10 +4,11 @@
4
4
  // consuming code properly resets all completion state so deriveState
5
5
  // re-derives the task on the next loop iteration.
6
6
 
7
+ import { describe, test } from 'node:test';
8
+ import assert from 'node:assert/strict';
7
9
  import { mkdtempSync, mkdirSync, rmSync, writeFileSync, existsSync, readFileSync, unlinkSync } from "node:fs";
8
10
  import { join } from "node:path";
9
11
  import { tmpdir } from "node:os";
10
- import { createTestContext } from "./test-helpers.ts";
11
12
  import {
12
13
  resetHookState,
13
14
  consumeRetryTrigger,
@@ -16,8 +17,6 @@ import {
16
17
  } from "../post-unit-hooks.ts";
17
18
  import { uncheckTaskInPlan } from "../undo.ts";
18
19
 
19
- const { assertEq, assertTrue, report } = createTestContext();
20
-
21
20
  // ─── Fixture Helpers ───────────────────────────────────────────────────────
22
21
 
23
22
  function createRetryFixture(): { base: string; cleanup: () => void } {
@@ -65,74 +64,65 @@ function createRetryFixture(): { base: string; cleanup: () => void } {
65
64
  // Test: consumeRetryTrigger returns retryArtifact field
66
65
  // ═══════════════════════════════════════════════════════════════════════════
67
66
 
68
- console.log("\n=== consumeRetryTrigger: returns null when no retry pending ===");
69
67
 
70
- {
68
+ describe('retry-state-reset', () => {
69
+ test('consumeRetryTrigger: returns null when no retry pending', () => {
71
70
  resetHookState();
72
71
  const trigger = consumeRetryTrigger();
73
- assertEq(trigger, null, "returns null when no retry pending");
74
- }
72
+ assert.deepStrictEqual(trigger, null, "returns null when no retry pending");
73
+ });
75
74
 
76
75
  // ═══════════════════════════════════════════════════════════════════════════
77
76
  // Test: uncheckTaskInPlan reverses doctor's [x] mark
78
77
  // ═══════════════════════════════════════════════════════════════════════════
79
-
80
- console.log("\n=== Retry reset step 1: uncheck [x] → [ ] in PLAN.md ===");
81
-
82
- {
78
+ test('Retry reset step 1: uncheck [x] → [ ] in PLAN.md', () => {
83
79
  const { base, cleanup } = createRetryFixture();
84
80
  try {
85
81
  const planFile = join(base, ".gsd", "milestones", "M001", "slices", "S01", "S01-PLAN.md");
86
82
 
87
83
  // Precondition: T01 is checked
88
84
  const before = readFileSync(planFile, "utf-8");
89
- assertTrue(before.includes("- [x] **T01:"), "precondition: T01 is checked [x]");
85
+ assert.ok(before.includes("- [x] **T01:"), "precondition: T01 is checked [x]");
90
86
 
91
87
  // Step 1: Uncheck T01
92
88
  const result = uncheckTaskInPlan(base, "M001", "S01", "T01");
93
- assertTrue(result, "uncheckTaskInPlan returns true");
89
+ assert.ok(result, "uncheckTaskInPlan returns true");
94
90
 
95
91
  // Verify T01 is now unchecked
96
92
  const after = readFileSync(planFile, "utf-8");
97
- assertTrue(after.includes("- [ ] **T01:"), "T01 is now unchecked [ ]");
98
- assertTrue(!after.includes("- [x] **T01:"), "T01 no longer has [x]");
93
+ assert.ok(after.includes("- [ ] **T01:"), "T01 is now unchecked [ ]");
94
+ assert.ok(!after.includes("- [x] **T01:"), "T01 no longer has [x]");
99
95
 
100
96
  // T02 is unaffected
101
- assertTrue(after.includes("- [ ] **T02:"), "T02 remains unchanged");
97
+ assert.ok(after.includes("- [ ] **T02:"), "T02 remains unchanged");
102
98
  } finally {
103
99
  cleanup();
104
100
  }
105
- }
101
+ });
106
102
 
107
103
  // ═══════════════════════════════════════════════════════════════════════════
108
104
  // Test: Delete SUMMARY.md for the task
109
105
  // ═══════════════════════════════════════════════════════════════════════════
110
-
111
- console.log("\n=== Retry reset step 2: delete SUMMARY.md ===");
112
-
113
- {
106
+ test('Retry reset step 2: delete SUMMARY.md', () => {
114
107
  const { base, cleanup } = createRetryFixture();
115
108
  try {
116
109
  const summaryFile = join(base, ".gsd", "milestones", "M001", "slices", "S01", "tasks", "T01-SUMMARY.md");
117
110
 
118
111
  // Precondition: SUMMARY exists
119
- assertTrue(existsSync(summaryFile), "precondition: SUMMARY.md exists");
112
+ assert.ok(existsSync(summaryFile), "precondition: SUMMARY.md exists");
120
113
 
121
114
  // Step 2: Delete SUMMARY.md
122
115
  unlinkSync(summaryFile);
123
- assertTrue(!existsSync(summaryFile), "SUMMARY.md deleted");
116
+ assert.ok(!existsSync(summaryFile), "SUMMARY.md deleted");
124
117
  } finally {
125
118
  cleanup();
126
119
  }
127
- }
120
+ });
128
121
 
129
122
  // ═══════════════════════════════════════════════════════════════════════════
130
123
  // Test: Remove from completedUnits array and flush
131
124
  // ═══════════════════════════════════════════════════════════════════════════
132
-
133
- console.log("\n=== Retry reset step 3: remove from completedUnits ===");
134
-
135
- {
125
+ test('Retry reset step 3: remove from completedUnits', () => {
136
126
  const { base, cleanup } = createRetryFixture();
137
127
  try {
138
128
  // Simulate the completedUnits array (as AutoSession would have it)
@@ -146,8 +136,8 @@ console.log("\n=== Retry reset step 3: remove from completedUnits ===");
146
136
  u => !(u.type === "execute-task" && u.id === "M001/S01/T01"),
147
137
  );
148
138
 
149
- assertEq(filtered.length, 1, "one unit removed from completedUnits");
150
- assertEq(filtered[0].id, "M001/S01/T02", "T02 still in completedUnits");
139
+ assert.deepStrictEqual(filtered.length, 1, "one unit removed from completedUnits");
140
+ assert.deepStrictEqual(filtered[0].id, "M001/S01/T02", "T02 still in completedUnits");
151
141
 
152
142
  // Flush to completed-units.json
153
143
  const completedKeysPath = join(base, ".gsd", "completed-units.json");
@@ -155,42 +145,36 @@ console.log("\n=== Retry reset step 3: remove from completedUnits ===");
155
145
  writeFileSync(completedKeysPath, JSON.stringify(keys, null, 2), "utf-8");
156
146
 
157
147
  const onDisk = JSON.parse(readFileSync(completedKeysPath, "utf-8"));
158
- assertEq(onDisk.length, 1, "completed-units.json has one entry");
159
- assertEq(onDisk[0], "execute-task/M001/S01/T02", "only T02 remains in completed-units.json");
148
+ assert.deepStrictEqual(onDisk.length, 1, "completed-units.json has one entry");
149
+ assert.deepStrictEqual(onDisk[0], "execute-task/M001/S01/T02", "only T02 remains in completed-units.json");
160
150
  } finally {
161
151
  cleanup();
162
152
  }
163
- }
153
+ });
164
154
 
165
155
  // ═══════════════════════════════════════════════════════════════════════════
166
156
  // Test: Delete the retry_on artifact
167
157
  // ═══════════════════════════════════════════════════════════════════════════
168
-
169
- console.log("\n=== Retry reset step 4: delete retry_on artifact ===");
170
-
171
- {
158
+ test('Retry reset step 4: delete retry_on artifact', () => {
172
159
  const { base, cleanup } = createRetryFixture();
173
160
  try {
174
161
  const retryArtifactPath = resolveHookArtifactPath(base, "M001/S01/T01", "NEEDS-REWORK.md");
175
162
 
176
163
  // Precondition: artifact exists
177
- assertTrue(existsSync(retryArtifactPath), "precondition: retry artifact exists");
164
+ assert.ok(existsSync(retryArtifactPath), "precondition: retry artifact exists");
178
165
 
179
166
  // Step 4: Delete retry artifact
180
167
  unlinkSync(retryArtifactPath);
181
- assertTrue(!existsSync(retryArtifactPath), "retry artifact deleted");
168
+ assert.ok(!existsSync(retryArtifactPath), "retry artifact deleted");
182
169
  } finally {
183
170
  cleanup();
184
171
  }
185
- }
172
+ });
186
173
 
187
174
  // ═══════════════════════════════════════════════════════════════════════════
188
175
  // Test: Full retry reset sequence (all steps together)
189
176
  // ═══════════════════════════════════════════════════════════════════════════
190
-
191
- console.log("\n=== Full retry reset: all steps combined ===");
192
-
193
- {
177
+ test('Full retry reset: all steps combined', () => {
194
178
  const { base, cleanup } = createRetryFixture();
195
179
  try {
196
180
  const trigger = {
@@ -242,30 +226,27 @@ console.log("\n=== Full retry reset: all steps combined ===");
242
226
  // PLAN.md: T01 unchecked
243
227
  const planFile = join(base, ".gsd", "milestones", "M001", "slices", "S01", "S01-PLAN.md");
244
228
  const planContent = readFileSync(planFile, "utf-8");
245
- assertTrue(planContent.includes("- [ ] **T01:"), "after reset: T01 unchecked in PLAN");
246
- assertTrue(!planContent.includes("- [x] **T01:"), "after reset: T01 not checked in PLAN");
229
+ assert.ok(planContent.includes("- [ ] **T01:"), "after reset: T01 unchecked in PLAN");
230
+ assert.ok(!planContent.includes("- [x] **T01:"), "after reset: T01 not checked in PLAN");
247
231
 
248
232
  // SUMMARY.md: deleted
249
- assertTrue(!existsSync(summaryFile), "after reset: SUMMARY.md deleted");
233
+ assert.ok(!existsSync(summaryFile), "after reset: SUMMARY.md deleted");
250
234
 
251
235
  // completed-units.json: empty
252
236
  const onDisk = JSON.parse(readFileSync(completedKeysPath, "utf-8"));
253
- assertEq(onDisk.length, 0, "after reset: completed-units.json is empty");
237
+ assert.deepStrictEqual(onDisk.length, 0, "after reset: completed-units.json is empty");
254
238
 
255
239
  // Retry artifact: deleted
256
- assertTrue(!existsSync(retryArtifactPath), "after reset: retry artifact deleted");
240
+ assert.ok(!existsSync(retryArtifactPath), "after reset: retry artifact deleted");
257
241
  } finally {
258
242
  cleanup();
259
243
  }
260
- }
244
+ });
261
245
 
262
246
  // ═══════════════════════════════════════════════════════════════════════════
263
247
  // Test: Reset is idempotent — no crash when artifacts are already missing
264
248
  // ═══════════════════════════════════════════════════════════════════════════
265
-
266
- console.log("\n=== Retry reset: idempotent when artifacts already missing ===");
267
-
268
- {
249
+ test('Retry reset: idempotent when artifacts already missing', () => {
269
250
  const base = mkdtempSync(join(tmpdir(), "gsd-retry-idempotent-"));
270
251
  try {
271
252
  // Create minimal structure — NO summary, NO retry artifact, NO plan
@@ -288,41 +269,38 @@ console.log("\n=== Retry reset: idempotent when artifacts already missing ===");
288
269
 
289
270
  // Uncheck — returns false because no PLAN file
290
271
  const uncheckResult = uncheckTaskInPlan(base, mid, sid, tid);
291
- assertTrue(!uncheckResult, "uncheck returns false when no PLAN exists");
272
+ assert.ok(!uncheckResult, "uncheck returns false when no PLAN exists");
292
273
 
293
274
  // Summary does not exist — no crash
294
275
  const summaryFile = join(base, ".gsd", "milestones", "M001", "slices", "S01", "tasks", `${tid}-SUMMARY.md`);
295
- assertTrue(!existsSync(summaryFile), "no summary to delete — safe");
276
+ assert.ok(!existsSync(summaryFile), "no summary to delete — safe");
296
277
 
297
278
  // Retry artifact does not exist — no crash
298
279
  const retryPath = resolveHookArtifactPath(base, trigger.unitId, trigger.retryArtifact);
299
- assertTrue(!existsSync(retryPath), "no retry artifact to delete — safe");
280
+ assert.ok(!existsSync(retryPath), "no retry artifact to delete — safe");
300
281
 
301
282
  // completed-units.json filter on empty array — safe
302
283
  const completedUnits: Array<{ type: string; id: string }> = [];
303
284
  const filtered = completedUnits.filter(
304
285
  u => !(u.type === trigger.unitType && u.id === trigger.unitId),
305
286
  );
306
- assertEq(filtered.length, 0, "filter on empty array is safe");
287
+ assert.deepStrictEqual(filtered.length, 0, "filter on empty array is safe");
307
288
  } finally {
308
289
  rmSync(base, { recursive: true, force: true });
309
290
  }
310
- }
291
+ });
311
292
 
312
293
  // ═══════════════════════════════════════════════════════════════════════════
313
294
  // Test: resolveHookArtifactPath produces correct path for retry artifacts
314
295
  // ═══════════════════════════════════════════════════════════════════════════
315
-
316
- console.log("\n=== resolveHookArtifactPath: correct path for retry artifacts ===");
317
-
318
- {
296
+ test('resolveHookArtifactPath: correct path for retry artifacts', () => {
319
297
  const base = "/project";
320
298
  const path = resolveHookArtifactPath(base, "M001/S01/T01", "NEEDS-REWORK.md");
321
- assertEq(
299
+ assert.deepStrictEqual(
322
300
  path,
323
301
  join(base, ".gsd", "milestones", "M001", "slices", "S01", "tasks", "T01-NEEDS-REWORK.md"),
324
302
  "retry artifact path resolves to task directory with task prefix",
325
303
  );
326
- }
304
+ });
327
305
 
328
- report();
306
+ });