gsd-pi 2.44.0-dev.848dd4c → 2.44.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (298) hide show
  1. package/README.md +12 -30
  2. package/dist/resources/extensions/gsd/auto-start.js +0 -10
  3. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +0 -5
  4. package/dist/web/standalone/.next/BUILD_ID +1 -1
  5. package/dist/web/standalone/.next/app-path-routes-manifest.json +14 -14
  6. package/dist/web/standalone/.next/build-manifest.json +3 -3
  7. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  8. package/dist/web/standalone/.next/required-server-files.json +3 -3
  9. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  10. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  11. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  12. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  13. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  14. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  15. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  16. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  17. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  18. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  19. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  20. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  21. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  22. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  23. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  24. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  25. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  26. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  27. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  28. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  29. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  30. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  31. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  32. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  33. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  34. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  35. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  36. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  37. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  38. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  39. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  40. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  41. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  42. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  43. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  44. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  45. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  46. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  47. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  48. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  49. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  50. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  51. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  52. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  53. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  54. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  55. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  56. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  57. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  58. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  59. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  60. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  61. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  62. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  63. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  64. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  65. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  66. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  67. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  68. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  69. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  70. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  71. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  72. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  73. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +5 -5
  74. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  75. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  76. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  77. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  78. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  79. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  80. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  81. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  82. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  83. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  84. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  85. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  86. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  87. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  88. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  89. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  90. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  91. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  92. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  93. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  94. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  95. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  96. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  97. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  98. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  99. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  100. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  101. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  102. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  103. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  104. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  105. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  106. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  107. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  108. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  109. package/dist/web/standalone/.next/server/app/index.html +1 -1
  110. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  111. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  112. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  113. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  114. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  115. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  116. package/dist/web/standalone/.next/server/app/page.js +2 -2
  117. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  118. package/dist/web/standalone/.next/server/app-paths-manifest.json +14 -14
  119. package/dist/web/standalone/.next/server/chunks/229.js +1 -1
  120. package/dist/web/standalone/.next/server/chunks/471.js +3 -3
  121. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  122. package/dist/web/standalone/.next/server/middleware.js +2 -2
  123. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  124. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  125. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  126. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  127. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  128. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-f2a7482d42a5614b.js → page-2f24283c162b6ab3.js} +1 -1
  129. package/dist/web/standalone/.next/static/chunks/app/{layout-a16c7a7ecdf0c2cf.js → layout-9ecfd95f343793f0.js} +1 -1
  130. package/dist/web/standalone/.next/static/chunks/app/page-7e9530a7122506c5.js +1 -0
  131. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +1 -0
  132. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +1 -0
  133. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  134. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  135. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  136. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  137. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  138. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  139. package/dist/web/standalone/server.js +1 -1
  140. package/package.json +1 -1
  141. package/packages/pi-coding-agent/dist/core/auth-storage.test.js +8 -6
  142. package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
  143. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +26 -24
  144. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
  145. package/packages/pi-coding-agent/dist/core/fs-utils.test.js +48 -29
  146. package/packages/pi-coding-agent/dist/core/fs-utils.test.js.map +1 -1
  147. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js +44 -34
  148. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js.map +1 -1
  149. package/packages/pi-coding-agent/dist/core/session-manager.test.js +34 -30
  150. package/packages/pi-coding-agent/dist/core/session-manager.test.js.map +1 -1
  151. package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js +12 -10
  152. package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js.map +1 -1
  153. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js +47 -43
  154. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js.map +1 -1
  155. package/packages/pi-coding-agent/src/core/auth-storage.test.ts +7 -7
  156. package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +26 -26
  157. package/packages/pi-coding-agent/src/core/fs-utils.test.ts +43 -31
  158. package/packages/pi-coding-agent/src/core/resolve-config-value.test.ts +45 -40
  159. package/packages/pi-coding-agent/src/core/session-manager.test.ts +33 -33
  160. package/packages/pi-coding-agent/src/core/tools/edit-diff.test.ts +17 -17
  161. package/packages/pi-coding-agent/src/resources/extensions/memory/storage.test.ts +74 -74
  162. package/src/resources/extensions/gsd/auto-start.ts +0 -14
  163. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +0 -8
  164. package/src/resources/extensions/gsd/tests/all-milestones-complete-merge.test.ts +99 -99
  165. package/src/resources/extensions/gsd/tests/auto-lock-creation.test.ts +16 -14
  166. package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +57 -43
  167. package/src/resources/extensions/gsd/tests/auto-preflight.test.ts +13 -11
  168. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +523 -465
  169. package/src/resources/extensions/gsd/tests/auto-secrets-gate.test.ts +75 -73
  170. package/src/resources/extensions/gsd/tests/auto-start-needs-discussion.test.ts +56 -34
  171. package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +656 -533
  172. package/src/resources/extensions/gsd/tests/auto-worktree.test.ts +143 -165
  173. package/src/resources/extensions/gsd/tests/cache-staleness-regression.test.ts +52 -29
  174. package/src/resources/extensions/gsd/tests/captures.test.ts +176 -148
  175. package/src/resources/extensions/gsd/tests/claude-import-tui.test.ts +33 -32
  176. package/src/resources/extensions/gsd/tests/collect-from-manifest.test.ts +143 -141
  177. package/src/resources/extensions/gsd/tests/commands-inspect-open-db.test.ts +25 -25
  178. package/src/resources/extensions/gsd/tests/commands-logs.test.ts +81 -81
  179. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +59 -38
  180. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +263 -228
  181. package/src/resources/extensions/gsd/tests/complete-task.test.ts +302 -250
  182. package/src/resources/extensions/gsd/tests/context-store.test.ts +367 -354
  183. package/src/resources/extensions/gsd/tests/continue-here.test.ts +72 -68
  184. package/src/resources/extensions/gsd/tests/cost-projection.test.ts +106 -92
  185. package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +35 -27
  186. package/src/resources/extensions/gsd/tests/dashboard-budget.test.ts +237 -220
  187. package/src/resources/extensions/gsd/tests/db-writer.test.ts +420 -390
  188. package/src/resources/extensions/gsd/tests/definition-loader.test.ts +92 -76
  189. package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +83 -68
  190. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +183 -152
  191. package/src/resources/extensions/gsd/tests/derive-state-deps.test.ts +101 -78
  192. package/src/resources/extensions/gsd/tests/derive-state.test.ts +227 -192
  193. package/src/resources/extensions/gsd/tests/detection.test.ts +278 -232
  194. package/src/resources/extensions/gsd/tests/dev-engine-wrapper.test.ts +34 -30
  195. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +180 -164
  196. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +49 -43
  197. package/src/resources/extensions/gsd/tests/dispatch-uat-last-completed.test.ts +32 -28
  198. package/src/resources/extensions/gsd/tests/doctor-completion-deferral.test.ts +29 -27
  199. package/src/resources/extensions/gsd/tests/doctor-delimiter-fix.test.ts +38 -34
  200. package/src/resources/extensions/gsd/tests/doctor-enhancements.test.ts +75 -54
  201. package/src/resources/extensions/gsd/tests/doctor-environment-worktree.test.ts +32 -21
  202. package/src/resources/extensions/gsd/tests/doctor-environment.test.ts +97 -72
  203. package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +44 -38
  204. package/src/resources/extensions/gsd/tests/doctor-git.test.ts +145 -104
  205. package/src/resources/extensions/gsd/tests/doctor-proactive.test.ts +106 -84
  206. package/src/resources/extensions/gsd/tests/doctor-roadmap-summary-atomicity.test.ts +60 -54
  207. package/src/resources/extensions/gsd/tests/doctor-runtime.test.ts +93 -72
  208. package/src/resources/extensions/gsd/tests/doctor.test.ts +134 -104
  209. package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +131 -123
  210. package/src/resources/extensions/gsd/tests/exit-command.test.ts +24 -20
  211. package/src/resources/extensions/gsd/tests/feature-branch-lifecycle-integration.test.ts +57 -48
  212. package/src/resources/extensions/gsd/tests/files-loadfile-eisdir.test.ts +7 -5
  213. package/src/resources/extensions/gsd/tests/flag-file-db.test.ts +42 -30
  214. package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +206 -198
  215. package/src/resources/extensions/gsd/tests/git-locale.test.ts +27 -13
  216. package/src/resources/extensions/gsd/tests/git-service.test.ts +388 -285
  217. package/src/resources/extensions/gsd/tests/gitignore-tracked-gsd.test.ts +39 -31
  218. package/src/resources/extensions/gsd/tests/graph-operations.test.ts +69 -63
  219. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +264 -255
  220. package/src/resources/extensions/gsd/tests/gsd-inspect.test.ts +119 -108
  221. package/src/resources/extensions/gsd/tests/gsd-recover.test.ts +103 -81
  222. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +262 -229
  223. package/src/resources/extensions/gsd/tests/headless-answers.test.ts +13 -13
  224. package/src/resources/extensions/gsd/tests/health-widget.test.ts +37 -29
  225. package/src/resources/extensions/gsd/tests/idle-recovery.test.ts +102 -81
  226. package/src/resources/extensions/gsd/tests/init-wizard.test.ts +18 -16
  227. package/src/resources/extensions/gsd/tests/integration-edge.test.ts +46 -41
  228. package/src/resources/extensions/gsd/tests/integration-lifecycle.test.ts +53 -42
  229. package/src/resources/extensions/gsd/tests/integration-mixed-milestones.test.ts +91 -75
  230. package/src/resources/extensions/gsd/tests/integration-proof.test.ts +18 -18
  231. package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +194 -150
  232. package/src/resources/extensions/gsd/tests/md-importer.test.ts +125 -101
  233. package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +54 -45
  234. package/src/resources/extensions/gsd/tests/memory-store.test.ts +93 -80
  235. package/src/resources/extensions/gsd/tests/migrate-command.test.ts +66 -57
  236. package/src/resources/extensions/gsd/tests/migrate-hierarchy.test.ts +93 -83
  237. package/src/resources/extensions/gsd/tests/migrate-parser.test.ts +170 -161
  238. package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +141 -125
  239. package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +131 -107
  240. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +96 -87
  241. package/src/resources/extensions/gsd/tests/migrate-writer.test.ts +164 -125
  242. package/src/resources/extensions/gsd/tests/must-have-parser.test.ts +94 -81
  243. package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +36 -35
  244. package/src/resources/extensions/gsd/tests/overrides.test.ts +106 -99
  245. package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +47 -40
  246. package/src/resources/extensions/gsd/tests/parallel-worker-monitoring.test.ts +28 -25
  247. package/src/resources/extensions/gsd/tests/parallel-workers-multi-milestone-e2e.test.ts +83 -66
  248. package/src/resources/extensions/gsd/tests/park-edge-cases.test.ts +77 -54
  249. package/src/resources/extensions/gsd/tests/park-milestone.test.ts +115 -68
  250. package/src/resources/extensions/gsd/tests/parsers.test.ts +611 -546
  251. package/src/resources/extensions/gsd/tests/paths.test.ts +87 -72
  252. package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +117 -77
  253. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +56 -56
  254. package/src/resources/extensions/gsd/tests/queue-draft-detection.test.ts +119 -93
  255. package/src/resources/extensions/gsd/tests/queue-order.test.ts +82 -70
  256. package/src/resources/extensions/gsd/tests/queue-reorder-e2e.test.ts +55 -42
  257. package/src/resources/extensions/gsd/tests/quick-branch-lifecycle.test.ts +73 -45
  258. package/src/resources/extensions/gsd/tests/reassess-prompt.test.ts +38 -28
  259. package/src/resources/extensions/gsd/tests/replan-slice.test.ts +80 -73
  260. package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +74 -71
  261. package/src/resources/extensions/gsd/tests/requirements.test.ts +75 -70
  262. package/src/resources/extensions/gsd/tests/retry-state-reset.test.ts +66 -44
  263. package/src/resources/extensions/gsd/tests/roadmap-parse-regression.test.ts +181 -114
  264. package/src/resources/extensions/gsd/tests/rule-registry.test.ts +65 -63
  265. package/src/resources/extensions/gsd/tests/run-uat.test.ts +128 -66
  266. package/src/resources/extensions/gsd/tests/session-lock-multipath.test.ts +25 -18
  267. package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +44 -37
  268. package/src/resources/extensions/gsd/tests/shared-wal.test.ts +26 -19
  269. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +8 -6
  270. package/src/resources/extensions/gsd/tests/symlink-numbered-variants.test.ts +28 -22
  271. package/src/resources/extensions/gsd/tests/token-savings.test.ts +56 -54
  272. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +25 -23
  273. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +11 -9
  274. package/src/resources/extensions/gsd/tests/unique-milestone-ids.test.ts +82 -66
  275. package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +47 -46
  276. package/src/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +22 -20
  277. package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +86 -84
  278. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +43 -41
  279. package/src/resources/extensions/gsd/tests/visualizer-views.test.ts +96 -94
  280. package/src/resources/extensions/gsd/tests/windows-path-normalization.test.ts +13 -11
  281. package/src/resources/extensions/gsd/tests/worker-registry.test.ts +29 -27
  282. package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +52 -50
  283. package/src/resources/extensions/gsd/tests/worktree-bugfix.test.ts +13 -10
  284. package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +18 -14
  285. package/src/resources/extensions/gsd/tests/worktree-db.test.ts +39 -38
  286. package/src/resources/extensions/gsd/tests/worktree-e2e.test.ts +21 -17
  287. package/src/resources/extensions/gsd/tests/worktree-health.test.ts +30 -25
  288. package/src/resources/extensions/gsd/tests/worktree-integration.test.ts +37 -30
  289. package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +22 -15
  290. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +66 -59
  291. package/src/resources/extensions/gsd/tests/worktree.test.ts +50 -44
  292. package/dist/web/standalone/.next/static/chunks/app/page-b9367c5ae13b99c6.js +0 -1
  293. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +0 -1
  294. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +0 -1
  295. package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +0 -100
  296. package/src/resources/extensions/gsd/tests/sqlite-unavailable-gate.test.ts +0 -63
  297. /package/dist/web/standalone/.next/static/{-zps1Q9mQmioAKLcQiCr8 → mgkxN0mGP6gSUmGPEzbk_}/_buildManifest.js +0 -0
  298. /package/dist/web/standalone/.next/static/{-zps1Q9mQmioAKLcQiCr8 → mgkxN0mGP6gSUmGPEzbk_}/_ssgManifest.js +0 -0
@@ -1,10 +1,11 @@
1
- import { after, describe, test } from 'node:test';
2
- import assert from 'node:assert/strict';
3
1
  import { mkdtempSync, mkdirSync, readFileSync, rmSync, writeFileSync, existsSync } from "node:fs";
4
2
  import { join } from "node:path";
5
3
  import { tmpdir } from "node:os";
6
4
 
7
5
  import { formatDoctorReport, runGSDDoctor, summarizeDoctorIssues, filterDoctorIssues, selectDoctorScope, validateTitle } from "../doctor.js";
6
+ import { createTestContext } from './test-helpers.ts';
7
+
8
+ const { assertEq, assertTrue, report } = createTestContext();
8
9
  const tmpBase = mkdtempSync(join(tmpdir(), "gsd-doctor-test-"));
9
10
  const gsd = join(tmpBase, ".gsd");
10
11
  const mDir = join(gsd, "milestones", "M001");
@@ -60,41 +61,46 @@ Implemented.
60
61
  - log
61
62
  `);
62
63
 
63
- describe('doctor', async () => {
64
- test('doctor diagnose', async () => {
64
+ async function main(): Promise<void> {
65
+ console.log("\n=== doctor diagnose ===");
66
+ {
65
67
  const report = await runGSDDoctor(tmpBase, { fix: false });
66
68
  // Reconciliation issue codes have been removed — doctor should NOT report them
67
- assert.ok(!report.issues.some(issue => issue.code === "all_tasks_done_missing_slice_summary" as any), "does not report removed code all_tasks_done_missing_slice_summary");
68
- assert.ok(!report.issues.some(issue => issue.code === "all_tasks_done_missing_slice_uat" as any), "does not report removed code all_tasks_done_missing_slice_uat");
69
- assert.ok(!report.issues.some(issue => issue.code === "all_tasks_done_roadmap_not_checked" as any), "does not report removed code all_tasks_done_roadmap_not_checked");
70
- });
69
+ assertTrue(!report.issues.some(issue => issue.code === "all_tasks_done_missing_slice_summary" as any), "does not report removed code all_tasks_done_missing_slice_summary");
70
+ assertTrue(!report.issues.some(issue => issue.code === "all_tasks_done_missing_slice_uat" as any), "does not report removed code all_tasks_done_missing_slice_uat");
71
+ assertTrue(!report.issues.some(issue => issue.code === "all_tasks_done_roadmap_not_checked" as any), "does not report removed code all_tasks_done_roadmap_not_checked");
72
+ }
71
73
 
72
- test('doctor formatting', async () => {
74
+ console.log("\n=== doctor formatting ===");
75
+ {
73
76
  const report = await runGSDDoctor(tmpBase, { fix: false });
74
77
  const summary = summarizeDoctorIssues(report.issues);
75
78
  const scoped = filterDoctorIssues(report.issues, { scope: "M001/S01", includeWarnings: true });
76
79
  const text = formatDoctorReport(report, { scope: "M001/S01", includeWarnings: true, maxIssues: 5 });
77
- assert.ok(text.includes("Scope: M001/S01"), "formatted report shows scope");
78
- });
80
+ assertTrue(text.includes("Scope: M001/S01"), "formatted report shows scope");
81
+ }
79
82
 
80
- test('doctor default scope', async () => {
83
+ console.log("\n=== doctor default scope ===");
84
+ {
81
85
  const scope = await selectDoctorScope(tmpBase);
82
- assert.deepStrictEqual(scope, "M001/S01", "default doctor scope targets the active slice");
83
- });
86
+ assertEq(scope, "M001/S01", "default doctor scope targets the active slice");
87
+ }
84
88
 
85
- test('doctor fix', async () => {
89
+ console.log("\n=== doctor fix ===");
90
+ {
86
91
  const report = await runGSDDoctor(tmpBase, { fix: true });
87
92
  // With reconciliation removed, doctor no longer creates placeholder summaries,
88
93
  // UAT files, or marks checkboxes. It only applies infrastructure fixes.
89
94
  // The task checkbox marking (task_summary_without_done_checkbox) is also removed.
90
95
  // Just verify it doesn't crash and produces a report.
91
- assert.ok(report.issues !== undefined, "doctor produces a report with issues array");
92
- });
96
+ assertTrue(report.issues !== undefined, "doctor produces a report with issues array");
97
+ }
93
98
 
94
- after(() => rmSync(tmpBase, { recursive: true, force: true }));
99
+ rmSync(tmpBase, { recursive: true, force: true });
95
100
 
96
101
  // ─── Milestone summary detection: missing summary ──────────────────────
97
- test('doctor detects missing milestone summary', async () => {
102
+ console.log("\n=== doctor detects missing milestone summary ===");
103
+ {
98
104
  const msBase = mkdtempSync(join(tmpdir(), "gsd-doctor-ms-test-"));
99
105
  const msGsd = join(msBase, ".gsd");
100
106
  const msMDir = join(msGsd, "milestones", "M001");
@@ -147,21 +153,22 @@ parent: M001
147
153
  // NO milestone summary — this is the condition we're detecting
148
154
 
149
155
  const report = await runGSDDoctor(msBase, { fix: false });
150
- assert.ok(
156
+ assertTrue(
151
157
  report.issues.some(issue => issue.code === "all_slices_done_missing_milestone_summary"),
152
158
  "detects missing milestone summary when all slices are done"
153
159
  );
154
160
  const msIssue = report.issues.find(issue => issue.code === "all_slices_done_missing_milestone_summary");
155
- assert.deepStrictEqual(msIssue?.scope, "milestone", "milestone summary issue has scope 'milestone'");
156
- assert.deepStrictEqual(msIssue?.severity, "warning", "milestone summary issue has severity 'warning'");
157
- assert.deepStrictEqual(msIssue?.unitId, "M001", "milestone summary issue unitId is 'M001'");
158
- assert.ok(msIssue?.message?.includes("SUMMARY") ?? false, "milestone summary issue message mentions SUMMARY");
161
+ assertEq(msIssue?.scope, "milestone", "milestone summary issue has scope 'milestone'");
162
+ assertEq(msIssue?.severity, "warning", "milestone summary issue has severity 'warning'");
163
+ assertEq(msIssue?.unitId, "M001", "milestone summary issue unitId is 'M001'");
164
+ assertTrue(msIssue?.message?.includes("SUMMARY") ?? false, "milestone summary issue message mentions SUMMARY");
159
165
 
160
166
  rmSync(msBase, { recursive: true, force: true });
161
- });
167
+ }
162
168
 
163
169
  // ─── Milestone summary detection: summary present (no false positive) ──
164
- test('doctor does NOT flag milestone with summary', async () => {
170
+ console.log("\n=== doctor does NOT flag milestone with summary ===");
171
+ {
165
172
  const msBase = mkdtempSync(join(tmpdir(), "gsd-doctor-ms-ok-test-"));
166
173
  const msGsd = join(msBase, ".gsd");
167
174
  const msMDir = join(msGsd, "milestones", "M001");
@@ -211,16 +218,17 @@ parent: M001
211
218
  writeFileSync(join(msMDir, "M001-SUMMARY.md"), `# M001 Summary\n\nMilestone complete.`);
212
219
 
213
220
  const report = await runGSDDoctor(msBase, { fix: false });
214
- assert.ok(
221
+ assertTrue(
215
222
  !report.issues.some(issue => issue.code === "all_slices_done_missing_milestone_summary"),
216
223
  "does NOT report missing milestone summary when summary exists"
217
224
  );
218
225
 
219
226
  rmSync(msBase, { recursive: true, force: true });
220
- });
227
+ }
221
228
 
222
229
  // ─── blocker_discovered_no_replan detection ────────────────────────────
223
- test('doctor detects blocker_discovered_no_replan', async () => {
230
+ console.log("\n=== doctor detects blocker_discovered_no_replan ===");
231
+ {
224
232
  const bBase = mkdtempSync(join(tmpdir(), "gsd-doctor-blocker-test-"));
225
233
  const bGsd = join(bBase, ".gsd");
226
234
  const bMDir = join(bGsd, "milestones", "M001");
@@ -276,17 +284,18 @@ Discovered an issue.
276
284
  // No REPLAN.md — should trigger the issue
277
285
  const report = await runGSDDoctor(bBase, { fix: false });
278
286
  const blockerIssues = report.issues.filter(i => i.code === "blocker_discovered_no_replan");
279
- assert.ok(blockerIssues.length > 0, "detects blocker_discovered_no_replan");
280
- assert.deepStrictEqual(blockerIssues[0]?.severity, "warning", "blocker issue has warning severity");
281
- assert.deepStrictEqual(blockerIssues[0]?.scope, "slice", "blocker issue has slice scope");
282
- assert.ok(blockerIssues[0]?.message?.includes("T01") ?? false, "blocker issue message mentions T01");
283
- assert.ok(blockerIssues[0]?.message?.includes("S01") ?? false, "blocker issue message mentions S01");
287
+ assertTrue(blockerIssues.length > 0, "detects blocker_discovered_no_replan");
288
+ assertEq(blockerIssues[0]?.severity, "warning", "blocker issue has warning severity");
289
+ assertEq(blockerIssues[0]?.scope, "slice", "blocker issue has slice scope");
290
+ assertTrue(blockerIssues[0]?.message?.includes("T01") ?? false, "blocker issue message mentions T01");
291
+ assertTrue(blockerIssues[0]?.message?.includes("S01") ?? false, "blocker issue message mentions S01");
284
292
 
285
293
  rmSync(bBase, { recursive: true, force: true });
286
- });
294
+ }
287
295
 
288
296
  // ─── blocker_discovered with REPLAN.md (no false positive) ─────────────
289
- test('doctor does NOT flag blocker when REPLAN.md exists', async () => {
297
+ console.log("\n=== doctor does NOT flag blocker when REPLAN.md exists ===");
298
+ {
290
299
  const bBase = mkdtempSync(join(tmpdir(), "gsd-doctor-blocker-ok-test-"));
291
300
  const bGsd = join(bBase, ".gsd");
292
301
  const bMDir = join(bGsd, "milestones", "M001");
@@ -336,13 +345,14 @@ Discovered an issue.
336
345
 
337
346
  const report = await runGSDDoctor(bBase, { fix: false });
338
347
  const blockerIssues = report.issues.filter(i => i.code === "blocker_discovered_no_replan");
339
- assert.deepStrictEqual(blockerIssues.length, 0, "no blocker_discovered_no_replan when REPLAN.md exists");
348
+ assertEq(blockerIssues.length, 0, "no blocker_discovered_no_replan when REPLAN.md exists");
340
349
 
341
350
  rmSync(bBase, { recursive: true, force: true });
342
- });
351
+ }
343
352
 
344
353
  // ─── Must-have verification: all addressed → no issue ─────────────────
345
- test('doctor: done task with must-haves all addressed → no issue', async () => {
354
+ console.log("\n=== doctor: done task with must-haves all addressed → no issue ===");
355
+ {
346
356
  const mhBase = mkdtempSync(join(tmpdir(), "gsd-doctor-mh-ok-"));
347
357
  const mhGsd = join(mhBase, ".gsd");
348
358
  const mhMDir = join(mhGsd, "milestones", "M001");
@@ -360,16 +370,17 @@ Discovered an issue.
360
370
  writeFileSync(join(mhTDir, "T01-SUMMARY.md"), `---\nid: T01\nparent: S01\nmilestone: M001\n---\n# T01: Implement\n\n## What Happened\nAdded parseWidgets function. Unit tests pass with zero failures.\n`);
361
371
 
362
372
  const report = await runGSDDoctor(mhBase, { fix: false });
363
- assert.ok(
373
+ assertTrue(
364
374
  !report.issues.some(i => i.code === "task_done_must_haves_not_verified"),
365
375
  "no must-have issue when all must-haves are addressed"
366
376
  );
367
377
 
368
378
  rmSync(mhBase, { recursive: true, force: true });
369
- });
379
+ }
370
380
 
371
381
  // ─── Must-have verification: not addressed → warning fired ───────────
372
- test('doctor: done task with must-haves NOT addressed → warning', async () => {
382
+ console.log("\n=== doctor: done task with must-haves NOT addressed → warning ===");
383
+ {
373
384
  const mhBase = mkdtempSync(join(tmpdir(), "gsd-doctor-mh-fail-"));
374
385
  const mhGsd = join(mhBase, ".gsd");
375
386
  const mhMDir = join(mhGsd, "milestones", "M001");
@@ -388,18 +399,19 @@ Discovered an issue.
388
399
 
389
400
  const report = await runGSDDoctor(mhBase, { fix: false });
390
401
  const mhIssue = report.issues.find(i => i.code === "task_done_must_haves_not_verified");
391
- assert.ok(!!mhIssue, "must-have issue is fired when summary doesn't address all must-haves");
392
- assert.deepStrictEqual(mhIssue?.severity, "warning", "must-have issue is warning severity");
393
- assert.deepStrictEqual(mhIssue?.scope, "task", "must-have issue scope is task");
394
- assert.ok(mhIssue?.message?.includes("3 must-haves") ?? false, "message mentions total must-have count");
395
- assert.ok(mhIssue?.message?.includes("only 1") ?? false, "message mentions addressed count");
396
- assert.deepStrictEqual(mhIssue?.fixable, false, "must-have issue is not fixable");
402
+ assertTrue(!!mhIssue, "must-have issue is fired when summary doesn't address all must-haves");
403
+ assertEq(mhIssue?.severity, "warning", "must-have issue is warning severity");
404
+ assertEq(mhIssue?.scope, "task", "must-have issue scope is task");
405
+ assertTrue(mhIssue?.message?.includes("3 must-haves") ?? false, "message mentions total must-have count");
406
+ assertTrue(mhIssue?.message?.includes("only 1") ?? false, "message mentions addressed count");
407
+ assertEq(mhIssue?.fixable, false, "must-have issue is not fixable");
397
408
 
398
409
  rmSync(mhBase, { recursive: true, force: true });
399
- });
410
+ }
400
411
 
401
412
  // ─── Must-have verification: no task plan → no issue ─────────────────
402
- test('doctor: done task with no task plan file → no issue', async () => {
413
+ console.log("\n=== doctor: done task with no task plan file → no issue ===");
414
+ {
403
415
  const mhBase = mkdtempSync(join(tmpdir(), "gsd-doctor-mh-noplan-"));
404
416
  const mhGsd = join(mhBase, ".gsd");
405
417
  const mhMDir = join(mhGsd, "milestones", "M001");
@@ -414,16 +426,17 @@ Discovered an issue.
414
426
  writeFileSync(join(mhTDir, "T01-SUMMARY.md"), `---\nid: T01\nparent: S01\nmilestone: M001\n---\n# T01: Implement\n\n## What Happened\nDone.\n`);
415
427
 
416
428
  const report = await runGSDDoctor(mhBase, { fix: false });
417
- assert.ok(
429
+ assertTrue(
418
430
  !report.issues.some(i => i.code === "task_done_must_haves_not_verified"),
419
431
  "no must-have issue when task plan file doesn't exist"
420
432
  );
421
433
 
422
434
  rmSync(mhBase, { recursive: true, force: true });
423
- });
435
+ }
424
436
 
425
437
  // ─── Must-have verification: plan exists but no Must-Haves section → no issue
426
- test('doctor: done task with plan but no Must-Haves section → no issue', async () => {
438
+ console.log("\n=== doctor: done task with plan but no Must-Haves section → no issue ===");
439
+ {
427
440
  const mhBase = mkdtempSync(join(tmpdir(), "gsd-doctor-mh-nosect-"));
428
441
  const mhGsd = join(mhBase, ".gsd");
429
442
  const mhMDir = join(mhGsd, "milestones", "M001");
@@ -440,49 +453,55 @@ Discovered an issue.
440
453
  writeFileSync(join(mhTDir, "T01-SUMMARY.md"), `---\nid: T01\nparent: S01\nmilestone: M001\n---\n# T01: Implement\n\n## What Happened\nDone.\n`);
441
454
 
442
455
  const report = await runGSDDoctor(mhBase, { fix: false });
443
- assert.ok(
456
+ assertTrue(
444
457
  !report.issues.some(i => i.code === "task_done_must_haves_not_verified"),
445
458
  "no must-have issue when task plan has no Must-Haves section"
446
459
  );
447
460
 
448
461
  rmSync(mhBase, { recursive: true, force: true });
449
- });
462
+ }
450
463
 
451
464
  // ─── validateTitle: em dash and slash detection ────────────────────────
452
- test('validateTitle: returns null for clean titles', () => {
453
- assert.deepStrictEqual(validateTitle("Foundation"), null, "clean title passes");
454
- assert.deepStrictEqual(validateTitle("Build Core Systems"), null, "clean title with spaces passes");
455
- assert.deepStrictEqual(validateTitle("API v2 Integration"), null, "clean title with version passes");
456
- assert.deepStrictEqual(validateTitle(""), null, "empty title passes");
457
- });
458
-
459
- test('validateTitle: detects em dash', () => {
465
+ console.log("\n=== validateTitle: returns null for clean titles ===");
466
+ {
467
+ assertEq(validateTitle("Foundation"), null, "clean title passes");
468
+ assertEq(validateTitle("Build Core Systems"), null, "clean title with spaces passes");
469
+ assertEq(validateTitle("API v2 Integration"), null, "clean title with version passes");
470
+ assertEq(validateTitle(""), null, "empty title passes");
471
+ }
472
+
473
+ console.log("\n=== validateTitle: detects em dash ===");
474
+ {
460
475
  const result = validateTitle("Foundation — Build Core");
461
- assert.ok(result !== null, "detects em dash in title");
462
- assert.ok(result!.includes("em/en dash"), "message mentions em/en dash");
463
- });
476
+ assertTrue(result !== null, "detects em dash in title");
477
+ assertTrue(result!.includes("em/en dash"), "message mentions em/en dash");
478
+ }
464
479
 
465
- test('validateTitle: detects en dash', () => {
480
+ console.log("\n=== validateTitle: detects en dash ===");
481
+ {
466
482
  const result = validateTitle("Phase 1 – Phase 2");
467
- assert.ok(result !== null, "detects en dash in title");
468
- assert.ok(result!.includes("em/en dash"), "message mentions em/en dash for en dash");
469
- });
483
+ assertTrue(result !== null, "detects en dash in title");
484
+ assertTrue(result!.includes("em/en dash"), "message mentions em/en dash for en dash");
485
+ }
470
486
 
471
- test('validateTitle: detects forward slash', () => {
487
+ console.log("\n=== validateTitle: detects forward slash ===");
488
+ {
472
489
  const result = validateTitle("Client/Server");
473
- assert.ok(result !== null, "detects forward slash in title");
474
- assert.ok(result!.includes("forward slash"), "message mentions forward slash");
475
- });
490
+ assertTrue(result !== null, "detects forward slash in title");
491
+ assertTrue(result!.includes("forward slash"), "message mentions forward slash");
492
+ }
476
493
 
477
- test('validateTitle: detects both em dash and slash', () => {
494
+ console.log("\n=== validateTitle: detects both em dash and slash ===");
495
+ {
478
496
  const result = validateTitle("Client — Server/API");
479
- assert.ok(result !== null, "detects both delimiters");
480
- assert.ok(result!.includes("em/en dash"), "message mentions em/en dash");
481
- assert.ok(result!.includes("forward slash"), "message mentions forward slash");
482
- });
497
+ assertTrue(result !== null, "detects both delimiters");
498
+ assertTrue(result!.includes("em/en dash"), "message mentions em/en dash");
499
+ assertTrue(result!.includes("forward slash"), "message mentions forward slash");
500
+ }
483
501
 
484
502
  // ─── doctor detects delimiter_in_title for milestone ───────────────────
485
- test('doctor detects em dash in milestone title', async () => {
503
+ console.log("\n=== doctor detects em dash in milestone title ===");
504
+ {
486
505
  const dtBase = mkdtempSync(join(tmpdir(), "gsd-doctor-dt-test-"));
487
506
  const dtGsd = join(dtBase, ".gsd");
488
507
  const dtMDir = join(dtGsd, "milestones", "M001");
@@ -497,19 +516,20 @@ Discovered an issue.
497
516
 
498
517
  const report = await runGSDDoctor(dtBase, { fix: false });
499
518
  const dtIssues = report.issues.filter(i => i.code === "delimiter_in_title");
500
- assert.ok(dtIssues.length >= 1, "detects delimiter_in_title for milestone with em dash");
519
+ assertTrue(dtIssues.length >= 1, "detects delimiter_in_title for milestone with em dash");
501
520
  const milestoneIssue = dtIssues.find(i => i.scope === "milestone");
502
- assert.ok(milestoneIssue !== undefined, "delimiter issue has milestone scope");
503
- assert.deepStrictEqual(milestoneIssue?.severity, "warning", "delimiter issue has warning severity");
504
- assert.deepStrictEqual(milestoneIssue?.unitId, "M001", "delimiter issue unitId is M001");
505
- assert.ok(milestoneIssue?.message?.includes("em/en dash") ?? false, "issue message mentions em/en dash");
506
- assert.deepStrictEqual(milestoneIssue?.fixable, true, "delimiter issue is auto-fixable");
521
+ assertTrue(milestoneIssue !== undefined, "delimiter issue has milestone scope");
522
+ assertEq(milestoneIssue?.severity, "warning", "delimiter issue has warning severity");
523
+ assertEq(milestoneIssue?.unitId, "M001", "delimiter issue unitId is M001");
524
+ assertTrue(milestoneIssue?.message?.includes("em/en dash") ?? false, "issue message mentions em/en dash");
525
+ assertEq(milestoneIssue?.fixable, true, "delimiter issue is auto-fixable");
507
526
 
508
527
  rmSync(dtBase, { recursive: true, force: true });
509
- });
528
+ }
510
529
 
511
530
  // ─── doctor detects delimiter_in_title for slice ────────────────────────
512
- test('doctor detects em dash in slice title', async () => {
531
+ console.log("\n=== doctor detects em dash in slice title ===");
532
+ {
513
533
  const dtBase = mkdtempSync(join(tmpdir(), "gsd-doctor-dt-slice-"));
514
534
  const dtGsd = join(dtBase, ".gsd");
515
535
  const dtMDir = join(dtGsd, "milestones", "M001");
@@ -524,17 +544,18 @@ Discovered an issue.
524
544
 
525
545
  const report = await runGSDDoctor(dtBase, { fix: false });
526
546
  const dtIssues = report.issues.filter(i => i.code === "delimiter_in_title");
527
- assert.ok(dtIssues.length >= 1, "detects delimiter_in_title for slice with em dash");
547
+ assertTrue(dtIssues.length >= 1, "detects delimiter_in_title for slice with em dash");
528
548
  const sliceIssue = dtIssues.find(i => i.scope === "slice");
529
- assert.ok(sliceIssue !== undefined, "delimiter issue has slice scope");
530
- assert.deepStrictEqual(sliceIssue?.severity, "warning", "slice delimiter issue has warning severity");
531
- assert.deepStrictEqual(sliceIssue?.unitId, "M001/S01", "slice delimiter issue unitId is M001/S01");
549
+ assertTrue(sliceIssue !== undefined, "delimiter issue has slice scope");
550
+ assertEq(sliceIssue?.severity, "warning", "slice delimiter issue has warning severity");
551
+ assertEq(sliceIssue?.unitId, "M001/S01", "slice delimiter issue unitId is M001/S01");
532
552
 
533
553
  rmSync(dtBase, { recursive: true, force: true });
534
- });
554
+ }
535
555
 
536
556
  // ─── doctor does NOT flag clean titles ──────────────────────────────────
537
- test('doctor does NOT flag milestone with clean title', async () => {
557
+ console.log("\n=== doctor does NOT flag milestone with clean title ===");
558
+ {
538
559
  const dtBase = mkdtempSync(join(tmpdir(), "gsd-doctor-dt-clean-"));
539
560
  const dtGsd = join(dtBase, ".gsd");
540
561
  const dtMDir = join(dtGsd, "milestones", "M001");
@@ -549,13 +570,14 @@ Discovered an issue.
549
570
 
550
571
  const report = await runGSDDoctor(dtBase, { fix: false });
551
572
  const dtIssues = report.issues.filter(i => i.code === "delimiter_in_title");
552
- assert.deepStrictEqual(dtIssues.length, 0, "no delimiter_in_title issues for clean titles");
573
+ assertEq(dtIssues.length, 0, "no delimiter_in_title issues for clean titles");
553
574
 
554
575
  rmSync(dtBase, { recursive: true, force: true });
555
- });
576
+ }
556
577
 
557
578
  // ─── unresolvable_dependency: range syntax dep warns ─────────────────
558
- test('doctor: unresolvable_dependency warns for leftover range ID', async () => {
579
+ console.log("\n=== doctor: unresolvable_dependency warns for leftover range ID ===");
580
+ {
559
581
  // Simulate a roadmap where expandDependencies did NOT expand (pre-fix stored artifact)
560
582
  // by writing a dep that looks like a range but doesn't match any real slice.
561
583
  const base = mkdtempSync(join(tmpdir(), "gsd-doctor-udep-"));
@@ -577,15 +599,16 @@ Discovered an issue.
577
599
 
578
600
  const r = await runGSDDoctor(base, { fix: false });
579
601
  const udepIssues = r.issues.filter(i => i.code === "unresolvable_dependency");
580
- assert.ok(udepIssues.length > 0, "unresolvable_dependency fires for unknown dep S99");
581
- assert.deepStrictEqual(udepIssues[0]?.severity, "warning", "severity is warning");
582
- assert.ok(udepIssues[0]?.message.includes("S99"), "message names the bad dep");
602
+ assertTrue(udepIssues.length > 0, "unresolvable_dependency fires for unknown dep S99");
603
+ assertEq(udepIssues[0]?.severity, "warning", "severity is warning");
604
+ assertTrue(udepIssues[0]?.message.includes("S99"), "message names the bad dep");
583
605
 
584
606
  rmSync(base, { recursive: true, force: true });
585
- });
607
+ }
586
608
 
587
609
  // ─── unresolvable_dependency: valid deps do not warn ─────────────────
588
- test('doctor: no unresolvable_dependency for valid deps', async () => {
610
+ console.log("\n=== doctor: no unresolvable_dependency for valid deps ===");
611
+ {
589
612
  const base = mkdtempSync(join(tmpdir(), "gsd-doctor-udep-ok-"));
590
613
  const mDir2 = join(base, ".gsd", "milestones", "M001");
591
614
  const sDir2 = join(mDir2, "slices", "S01");
@@ -605,8 +628,15 @@ Discovered an issue.
605
628
 
606
629
  const r = await runGSDDoctor(base, { fix: false });
607
630
  const udepIssues = r.issues.filter(i => i.code === "unresolvable_dependency");
608
- assert.deepStrictEqual(udepIssues.length, 0, "no unresolvable_dependency for valid S01 dep");
631
+ assertEq(udepIssues.length, 0, "no unresolvable_dependency for valid S01 dep");
609
632
 
610
633
  rmSync(base, { recursive: true, force: true });
611
- });
634
+ }
635
+
636
+ report();
637
+ }
638
+
639
+ main().catch((error) => {
640
+ console.error(error);
641
+ process.exit(1);
612
642
  });