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,5 +1,3 @@
1
- import { describe, test } from 'node:test';
2
- import assert from 'node:assert/strict';
3
1
  /**
4
2
  * doctor-proactive.test.ts — Tests for proactive healing layer.
5
3
  *
@@ -24,6 +22,10 @@ import {
24
22
  resetProactiveHealing,
25
23
  formatHealthSummary,
26
24
  } from "../doctor-proactive.ts";
25
+ import { createTestContext } from "./test-helpers.ts";
26
+
27
+ const { assertEq, assertTrue, report } = createTestContext();
28
+
27
29
  function run(cmd: string, cwd: string): string {
28
30
  return execSync(cmd, { cwd, stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" }).trim();
29
31
  }
@@ -68,40 +70,44 @@ _None_
68
70
  return dir;
69
71
  }
70
72
 
71
- describe('doctor-proactive', async () => {
73
+ async function main(): Promise<void> {
72
74
  const cleanups: string[] = [];
73
75
 
74
76
  try {
75
77
  // ─── Health Score Tracking ─────────────────────────────────────────
76
- test('health tracking: initial state', () => {
78
+ console.log("\n=== health tracking: initial state ===");
79
+ {
77
80
  resetProactiveHealing();
78
- assert.deepStrictEqual(getHealthTrend(), "unknown", "trend is unknown with no data");
79
- assert.deepStrictEqual(getConsecutiveErrorUnits(), 0, "no consecutive errors initially");
80
- assert.deepStrictEqual(getHealthHistory().length, 0, "no history initially");
81
- });
81
+ assertEq(getHealthTrend(), "unknown", "trend is unknown with no data");
82
+ assertEq(getConsecutiveErrorUnits(), 0, "no consecutive errors initially");
83
+ assertEq(getHealthHistory().length, 0, "no history initially");
84
+ }
82
85
 
83
- test('health tracking: recording snapshots', () => {
86
+ console.log("\n=== health tracking: recording snapshots ===");
87
+ {
84
88
  resetProactiveHealing();
85
89
  recordHealthSnapshot(0, 2, 1);
86
90
  recordHealthSnapshot(0, 1, 0);
87
91
  recordHealthSnapshot(0, 0, 0);
88
92
 
89
- assert.deepStrictEqual(getHealthHistory().length, 3, "3 snapshots recorded");
90
- assert.deepStrictEqual(getConsecutiveErrorUnits(), 0, "no consecutive errors after clean units");
91
- });
93
+ assertEq(getHealthHistory().length, 3, "3 snapshots recorded");
94
+ assertEq(getConsecutiveErrorUnits(), 0, "no consecutive errors after clean units");
95
+ }
92
96
 
93
- test('health tracking: consecutive error counting', () => {
97
+ console.log("\n=== health tracking: consecutive error counting ===");
98
+ {
94
99
  resetProactiveHealing();
95
100
  recordHealthSnapshot(2, 1, 0); // errors
96
101
  recordHealthSnapshot(1, 0, 0); // errors
97
102
  recordHealthSnapshot(1, 0, 0); // errors
98
- assert.deepStrictEqual(getConsecutiveErrorUnits(), 3, "3 consecutive error units");
103
+ assertEq(getConsecutiveErrorUnits(), 3, "3 consecutive error units");
99
104
 
100
105
  recordHealthSnapshot(0, 0, 0); // clean
101
- assert.deepStrictEqual(getConsecutiveErrorUnits(), 0, "streak reset on clean unit");
102
- });
106
+ assertEq(getConsecutiveErrorUnits(), 0, "streak reset on clean unit");
107
+ }
103
108
 
104
- test('health tracking: trend detection', () => {
109
+ console.log("\n=== health tracking: trend detection ===");
110
+ {
105
111
  resetProactiveHealing();
106
112
  // Record 5 older snapshots with low issues
107
113
  for (let i = 0; i < 5; i++) {
@@ -111,10 +117,11 @@ describe('doctor-proactive', async () => {
111
117
  for (let i = 0; i < 5; i++) {
112
118
  recordHealthSnapshot(3, 5, 0);
113
119
  }
114
- assert.deepStrictEqual(getHealthTrend(), "degrading", "detects degrading trend");
115
- });
120
+ assertEq(getHealthTrend(), "degrading", "detects degrading trend");
121
+ }
116
122
 
117
- test('health tracking: improving trend', () => {
123
+ console.log("\n=== health tracking: improving trend ===");
124
+ {
118
125
  resetProactiveHealing();
119
126
  // Record 5 older snapshots with high issues
120
127
  for (let i = 0; i < 5; i++) {
@@ -124,29 +131,32 @@ describe('doctor-proactive', async () => {
124
131
  for (let i = 0; i < 5; i++) {
125
132
  recordHealthSnapshot(0, 0, 0);
126
133
  }
127
- assert.deepStrictEqual(getHealthTrend(), "improving", "detects improving trend");
128
- });
134
+ assertEq(getHealthTrend(), "improving", "detects improving trend");
135
+ }
129
136
 
130
- test('health tracking: stable trend', () => {
137
+ console.log("\n=== health tracking: stable trend ===");
138
+ {
131
139
  resetProactiveHealing();
132
140
  for (let i = 0; i < 10; i++) {
133
141
  recordHealthSnapshot(1, 1, 0);
134
142
  }
135
- assert.deepStrictEqual(getHealthTrend(), "stable", "detects stable trend");
136
- });
143
+ assertEq(getHealthTrend(), "stable", "detects stable trend");
144
+ }
137
145
 
138
146
  // ─── Auto-Heal Escalation ─────────────────────────────────────────
139
- test('escalation: below threshold', () => {
147
+ console.log("\n=== escalation: below threshold ===");
148
+ {
140
149
  resetProactiveHealing();
141
150
  recordHealthSnapshot(1, 0, 0);
142
151
  recordHealthSnapshot(1, 0, 0);
143
152
  recordHealthSnapshot(1, 0, 0);
144
153
  const result = checkHealEscalation(1, [{ code: "test", message: "test error", unitId: "M001/S01" }]);
145
- assert.deepStrictEqual(result.shouldEscalate, false, "no escalation below threshold");
146
- assert.ok(result.reason.includes("3/5"), "reason shows progress toward threshold");
147
- });
154
+ assertEq(result.shouldEscalate, false, "no escalation below threshold");
155
+ assertTrue(result.reason.includes("3/5"), "reason shows progress toward threshold");
156
+ }
148
157
 
149
- test('escalation: at threshold', () => {
158
+ console.log("\n=== escalation: at threshold ===");
159
+ {
150
160
  resetProactiveHealing();
151
161
  // Need 5+ consecutive error units AND degrading/stable trend
152
162
  for (let i = 0; i < 5; i++) {
@@ -156,19 +166,21 @@ describe('doctor-proactive', async () => {
156
166
  recordHealthSnapshot(2, 1, 0); // recent error snapshots
157
167
  }
158
168
  const result = checkHealEscalation(2, [{ code: "test", message: "test error", unitId: "M001/S01" }]);
159
- assert.deepStrictEqual(result.shouldEscalate, true, "escalates at threshold with degrading trend");
160
- assert.ok(result.reason.includes("5 consecutive"), "reason mentions consecutive count");
161
- });
169
+ assertEq(result.shouldEscalate, true, "escalates at threshold with degrading trend");
170
+ assertTrue(result.reason.includes("5 consecutive"), "reason mentions consecutive count");
171
+ }
162
172
 
163
- test('escalation: no double escalation', () => {
173
+ console.log("\n=== escalation: no double escalation ===");
174
+ {
164
175
  // Don't reset — should already be escalated from previous test
165
176
  recordHealthSnapshot(2, 0, 0);
166
177
  const result = checkHealEscalation(2, [{ code: "test", message: "test error", unitId: "M001/S01" }]);
167
- assert.deepStrictEqual(result.shouldEscalate, false, "no double escalation in same session");
168
- assert.ok(result.reason.includes("already escalated"), "reason explains why no escalation");
169
- });
178
+ assertEq(result.shouldEscalate, false, "no double escalation in same session");
179
+ assertTrue(result.reason.includes("already escalated"), "reason explains why no escalation");
180
+ }
170
181
 
171
- test('escalation: deferred when improving', () => {
182
+ console.log("\n=== escalation: deferred when improving ===");
183
+ {
172
184
  resetProactiveHealing();
173
185
  // 5 older snapshots with high errors
174
186
  for (let i = 0; i < 5; i++) {
@@ -179,34 +191,37 @@ describe('doctor-proactive', async () => {
179
191
  recordHealthSnapshot(1, 0, 0);
180
192
  }
181
193
  const result = checkHealEscalation(1, [{ code: "test", message: "test error", unitId: "M001/S01" }]);
182
- assert.deepStrictEqual(result.shouldEscalate, false, "no escalation when trend is improving");
183
- assert.ok(result.reason.includes("improving"), "reason mentions improving trend");
184
- });
194
+ assertEq(result.shouldEscalate, false, "no escalation when trend is improving");
195
+ assertTrue(result.reason.includes("improving"), "reason mentions improving trend");
196
+ }
185
197
 
186
198
  // ─── Health Summary Formatting ────────────────────────────────────
187
- test('formatHealthSummary', () => {
199
+ console.log("\n=== formatHealthSummary ===");
200
+ {
188
201
  resetProactiveHealing();
189
- assert.deepStrictEqual(formatHealthSummary(), "No health data yet.", "empty summary when no data");
202
+ assertEq(formatHealthSummary(), "No health data yet.", "empty summary when no data");
190
203
 
191
204
  recordHealthSnapshot(2, 3, 1);
192
205
  const summary = formatHealthSummary();
193
- assert.ok(summary.includes("2 errors") && summary.includes("3 warnings"), "summary includes error/warning counts");
194
- assert.ok(summary.includes("1 fix applied"), "summary includes fix count");
195
- assert.ok(summary.includes("1 of 5 consecutive errors"), "summary includes error streak");
196
- });
206
+ assertTrue(summary.includes("2 errors") && summary.includes("3 warnings"), "summary includes error/warning counts");
207
+ assertTrue(summary.includes("1 fix applied"), "summary includes fix count");
208
+ assertTrue(summary.includes("1 of 5 consecutive errors"), "summary includes error streak");
209
+ }
197
210
 
198
211
  // ─── Pre-Dispatch Health Gate ─────────────────────────────────────
199
- test('health gate: clean state', async () => {
212
+ console.log("\n=== health gate: clean state ===");
213
+ {
200
214
  const dir = realpathSync(mkdtempSync(join(tmpdir(), "doc-proactive-")));
201
215
  cleanups.push(dir);
202
216
  mkdirSync(join(dir, ".gsd"), { recursive: true });
203
217
 
204
218
  const result = await preDispatchHealthGate(dir);
205
- assert.ok(result.proceed, "gate passes on clean state");
206
- assert.deepStrictEqual(result.issues.length, 0, "no issues on clean state");
207
- });
219
+ assertTrue(result.proceed, "gate passes on clean state");
220
+ assertEq(result.issues.length, 0, "no issues on clean state");
221
+ }
208
222
 
209
- test('health gate: missing STATE.md does NOT block dispatch (#889)', async () => {
223
+ console.log("\n=== health gate: missing STATE.md does NOT block dispatch (#889) ===");
224
+ {
210
225
  const dir = realpathSync(mkdtempSync(join(tmpdir(), "doc-proactive-")));
211
226
  cleanups.push(dir);
212
227
  // Create milestones dir but no STATE.md — mimics fresh worktree
@@ -214,12 +229,13 @@ describe('doctor-proactive', async () => {
214
229
  writeFileSync(join(dir, ".gsd", "milestones", "M001", "M001-ROADMAP.md"), "# Roadmap\n");
215
230
 
216
231
  const result = await preDispatchHealthGate(dir);
217
- assert.ok(result.proceed, "gate must NOT block when STATE.md is missing (deadlock #889)");
218
- assert.deepStrictEqual(result.issues.length, 0, "missing STATE.md is not a blocking issue");
219
- assert.ok(result.fixesApplied.some((f: string) => f.includes("STATE.md")), "reports STATE.md status as info");
220
- });
232
+ assertTrue(result.proceed, "gate must NOT block when STATE.md is missing (deadlock #889)");
233
+ assertEq(result.issues.length, 0, "missing STATE.md is not a blocking issue");
234
+ assertTrue(result.fixesApplied.some((f: string) => f.includes("STATE.md")), "reports STATE.md status as info");
235
+ }
221
236
 
222
- test('health gate: stale crash lock auto-cleared', async () => {
237
+ console.log("\n=== health gate: stale crash lock auto-cleared ===");
238
+ {
223
239
  const dir = realpathSync(mkdtempSync(join(tmpdir(), "doc-proactive-")));
224
240
  cleanups.push(dir);
225
241
  mkdirSync(join(dir, ".gsd"), { recursive: true });
@@ -232,12 +248,12 @@ describe('doctor-proactive', async () => {
232
248
  }));
233
249
 
234
250
  const result = await preDispatchHealthGate(dir);
235
- assert.ok(result.proceed, "gate passes after auto-clearing stale lock");
236
- assert.ok(result.fixesApplied.some(f => f.includes("cleared stale auto.lock")), "reports lock cleared");
237
- assert.ok(!existsSync(join(dir, ".gsd", "auto.lock")), "lock file removed");
238
- });
251
+ assertTrue(result.proceed, "gate passes after auto-clearing stale lock");
252
+ assertTrue(result.fixesApplied.some(f => f.includes("cleared stale auto.lock")), "reports lock cleared");
253
+ assertTrue(!existsSync(join(dir, ".gsd", "auto.lock")), "lock file removed");
254
+ }
239
255
 
240
- test('health gate: corrupt merge state auto-healed', async () => {
256
+ console.log("\n=== health gate: corrupt merge state auto-healed ===");
241
257
  if (process.platform !== "win32") {
242
258
  {
243
259
  const dir = createGitRepo();
@@ -248,35 +264,36 @@ describe('doctor-proactive', async () => {
248
264
  writeFileSync(join(dir, ".git", "MERGE_HEAD"), headHash + "\n");
249
265
 
250
266
  const result = await preDispatchHealthGate(dir);
251
- assert.ok(result.proceed, "gate passes after auto-healing merge state");
252
- assert.ok(result.fixesApplied.some(f => f.includes("cleaned merge state")), "reports merge state cleaned");
253
- assert.ok(!existsSync(join(dir, ".git", "MERGE_HEAD")), "MERGE_HEAD removed");
267
+ assertTrue(result.proceed, "gate passes after auto-healing merge state");
268
+ assertTrue(result.fixesApplied.some(f => f.includes("cleaned merge state")), "reports merge state cleaned");
269
+ assertTrue(!existsSync(join(dir, ".git", "MERGE_HEAD")), "MERGE_HEAD removed");
254
270
  }
255
271
  } else {
256
272
  console.log(" (skipped on Windows)");
257
273
  }
258
- });
259
274
 
260
- test('health gate: STATE.md missing — auto-healed', async () => {
275
+ console.log("\n=== health gate: STATE.md missing — auto-healed ===");
276
+ {
261
277
  const dir = realpathSync(mkdtempSync(join(tmpdir(), "doc-proactive-")));
262
278
  cleanups.push(dir);
263
279
  // Minimal .gsd structure: milestones dir exists but no STATE.md
264
280
  mkdirSync(join(dir, ".gsd", "milestones"), { recursive: true });
265
281
 
266
282
  const stateFile = join(dir, ".gsd", "STATE.md");
267
- assert.ok(!existsSync(stateFile), "STATE.md does not exist before gate");
283
+ assertTrue(!existsSync(stateFile), "STATE.md does not exist before gate");
268
284
 
269
285
  const result = await preDispatchHealthGate(dir);
270
- assert.ok(result.proceed, "gate passes after rebuilding STATE.md");
271
- assert.ok(
286
+ assertTrue(result.proceed, "gate passes after rebuilding STATE.md");
287
+ assertTrue(
272
288
  result.fixesApplied.some(f => f.includes("rebuilt missing STATE.md")),
273
289
  "reports STATE.md rebuilt",
274
290
  );
275
- assert.ok(existsSync(stateFile), "STATE.md created by auto-heal");
276
- assert.ok(result.issues.length === 0, "no blocking issues after heal");
277
- });
291
+ assertTrue(existsSync(stateFile), "STATE.md created by auto-heal");
292
+ assertTrue(result.issues.length === 0, "no blocking issues after heal");
293
+ }
278
294
 
279
- test('health gate: stale integration branch uses detected fallback', async () => {
295
+ console.log("\n=== health gate: stale integration branch uses detected fallback ===");
296
+ {
280
297
  const dir = createRepoWithActiveMilestone();
281
298
  cleanups.push(dir);
282
299
 
@@ -284,15 +301,16 @@ describe('doctor-proactive', async () => {
284
301
  writeFileSync(metaPath, JSON.stringify({ integrationBranch: "feature/missing" }, null, 2));
285
302
 
286
303
  const result = await preDispatchHealthGate(dir);
287
- assert.ok(result.proceed, "gate does not block when stale integration branch has detected fallback");
288
- assert.deepStrictEqual(result.issues.length, 0, "stale integration branch with fallback is not a blocking issue");
289
- assert.ok(
304
+ assertTrue(result.proceed, "gate does not block when stale integration branch has detected fallback");
305
+ assertEq(result.issues.length, 0, "stale integration branch with fallback is not a blocking issue");
306
+ assertTrue(
290
307
  result.fixesApplied.some(f => f.includes('feature/missing') && f.includes('main')),
291
308
  "fixesApplied reports stale recorded branch and detected fallback branch",
292
309
  );
293
- });
310
+ }
294
311
 
295
- test('health gate: stale integration branch uses configured fallback', async () => {
312
+ console.log("\n=== health gate: stale integration branch uses configured fallback ===");
313
+ {
296
314
  const dir = createRepoWithActiveMilestone();
297
315
  cleanups.push(dir);
298
316
 
@@ -305,16 +323,16 @@ describe('doctor-proactive', async () => {
305
323
  process.chdir(dir);
306
324
  try {
307
325
  const result = await preDispatchHealthGate(dir);
308
- assert.ok(result.proceed, "gate does not block when configured main_branch can be used as fallback");
309
- assert.deepStrictEqual(result.issues.length, 0, "configured fallback is not treated as a blocking issue");
310
- assert.ok(
326
+ assertTrue(result.proceed, "gate does not block when configured main_branch can be used as fallback");
327
+ assertEq(result.issues.length, 0, "configured fallback is not treated as a blocking issue");
328
+ assertTrue(
311
329
  result.fixesApplied.some(f => f.includes('feature/missing') && f.includes('trunk')),
312
330
  "fixesApplied reports stale recorded branch and configured fallback branch",
313
331
  );
314
332
  } finally {
315
333
  process.chdir(previousCwd);
316
334
  }
317
- });
335
+ }
318
336
 
319
337
  } finally {
320
338
  resetProactiveHealing();
@@ -322,4 +340,8 @@ describe('doctor-proactive', async () => {
322
340
  try { rmSync(dir, { recursive: true, force: true }); } catch { /* ignore */ }
323
341
  }
324
342
  }
325
- });
343
+
344
+ report();
345
+ }
346
+
347
+ main();
@@ -58,66 +58,72 @@ Done.
58
58
  `);
59
59
  }
60
60
 
61
- test("fixLevel:task — roadmap checkbox is never toggled by doctor (reconciliation removed)", async (t) => {
61
+ test("fixLevel:task — roadmap checkbox is never toggled by doctor (reconciliation removed)", async () => {
62
62
  const tmp = makeTmp("no-roadmap-toggle");
63
- t.after(() => rmSync(tmp, { recursive: true, force: true }));
64
-
65
- buildScaffold(tmp);
66
-
67
- const report = await runGSDDoctor(tmp, { fix: true, fixLevel: "task" });
68
-
69
- // Roadmap must remain unchecked doctor no longer touches checkboxes
70
- const roadmapContent = readFileSync(join(tmp, ".gsd", "milestones", "M001", "M001-ROADMAP.md"), "utf8");
71
- assert.ok(
72
- roadmapContent.includes("- [ ] **S01"),
73
- "roadmap should remain unchecked — doctor no longer toggles checkboxes"
74
- );
75
-
76
- // No summary or UAT stubs created
77
- const sliceSummaryPath = join(tmp, ".gsd", "milestones", "M001", "slices", "S01", "S01-SUMMARY.md");
78
- assert.ok(!existsSync(sliceSummaryPath), "summary should NOT be created");
63
+ try {
64
+ buildScaffold(tmp);
65
+
66
+ const report = await runGSDDoctor(tmp, { fix: true, fixLevel: "task" });
67
+
68
+ // Roadmap must remain unchecked — doctor no longer touches checkboxes
69
+ const roadmapContent = readFileSync(join(tmp, ".gsd", "milestones", "M001", "M001-ROADMAP.md"), "utf8");
70
+ assert.ok(
71
+ roadmapContent.includes("- [ ] **S01"),
72
+ "roadmap should remain unchecked — doctor no longer toggles checkboxes"
73
+ );
74
+
75
+ // No summary or UAT stubs created
76
+ const sliceSummaryPath = join(tmp, ".gsd", "milestones", "M001", "slices", "S01", "S01-SUMMARY.md");
77
+ assert.ok(!existsSync(sliceSummaryPath), "summary should NOT be created");
78
+ } finally {
79
+ rmSync(tmp, { recursive: true, force: true });
80
+ }
79
81
  });
80
82
 
81
- test("fixLevel:all — roadmap checkbox is never toggled by doctor (reconciliation removed)", async (t) => {
83
+ test("fixLevel:all — roadmap checkbox is never toggled by doctor (reconciliation removed)", async () => {
82
84
  const tmp = makeTmp("all-no-toggle");
83
- t.after(() => rmSync(tmp, { recursive: true, force: true }));
84
-
85
- buildScaffold(tmp);
86
-
87
- const report = await runGSDDoctor(tmp, { fix: true });
88
-
89
- // Even at fixLevel:all, doctor no longer creates stubs or toggles checkboxes
90
- const roadmapContent = readFileSync(join(tmp, ".gsd", "milestones", "M001", "M001-ROADMAP.md"), "utf8");
91
- assert.ok(
92
- roadmapContent.includes("- [ ] **S01"),
93
- "roadmap should remain unchecked — reconciliation removed"
94
- );
95
-
96
- const sliceSummaryPath = join(tmp, ".gsd", "milestones", "M001", "slices", "S01", "S01-SUMMARY.md");
97
- assert.ok(!existsSync(sliceSummaryPath), "summary should NOT be created");
85
+ try {
86
+ buildScaffold(tmp);
87
+
88
+ const report = await runGSDDoctor(tmp, { fix: true });
89
+
90
+ // Even at fixLevel:all, doctor no longer creates stubs or toggles checkboxes
91
+ const roadmapContent = readFileSync(join(tmp, ".gsd", "milestones", "M001", "M001-ROADMAP.md"), "utf8");
92
+ assert.ok(
93
+ roadmapContent.includes("- [ ] **S01"),
94
+ "roadmap should remain unchecked — reconciliation removed"
95
+ );
96
+
97
+ const sliceSummaryPath = join(tmp, ".gsd", "milestones", "M001", "slices", "S01", "S01-SUMMARY.md");
98
+ assert.ok(!existsSync(sliceSummaryPath), "summary should NOT be created");
99
+ } finally {
100
+ rmSync(tmp, { recursive: true, force: true });
101
+ }
98
102
  });
99
103
 
100
- test("consecutive doctor runs produce no reconciliation codes", async (t) => {
104
+ test("consecutive doctor runs produce no reconciliation codes", async () => {
101
105
  const tmp = makeTmp("consecutive-clean");
102
- t.after(() => rmSync(tmp, { recursive: true, force: true }));
103
-
104
- buildScaffold(tmp);
105
-
106
- await runGSDDoctor(tmp, { fix: true, fixLevel: "task" });
107
- const report2 = await runGSDDoctor(tmp, { fix: true, fixLevel: "task" });
108
-
109
- const REMOVED_CODES = [
110
- "task_done_missing_summary",
111
- "task_summary_without_done_checkbox",
112
- "all_tasks_done_missing_slice_summary",
113
- "all_tasks_done_missing_slice_uat",
114
- "all_tasks_done_roadmap_not_checked",
115
- "slice_checked_missing_summary",
116
- "slice_checked_missing_uat",
117
- ];
118
-
119
- const codes = report2.issues.map(i => i.code);
120
- for (const removed of REMOVED_CODES) {
121
- assert.ok(!codes.includes(removed as any), `should NOT report removed code: ${removed}`);
106
+ try {
107
+ buildScaffold(tmp);
108
+
109
+ await runGSDDoctor(tmp, { fix: true, fixLevel: "task" });
110
+ const report2 = await runGSDDoctor(tmp, { fix: true, fixLevel: "task" });
111
+
112
+ const REMOVED_CODES = [
113
+ "task_done_missing_summary",
114
+ "task_summary_without_done_checkbox",
115
+ "all_tasks_done_missing_slice_summary",
116
+ "all_tasks_done_missing_slice_uat",
117
+ "all_tasks_done_roadmap_not_checked",
118
+ "slice_checked_missing_summary",
119
+ "slice_checked_missing_uat",
120
+ ];
121
+
122
+ const codes = report2.issues.map(i => i.code);
123
+ for (const removed of REMOVED_CODES) {
124
+ assert.ok(!codes.includes(removed as any), `should NOT report removed code: ${removed}`);
125
+ }
126
+ } finally {
127
+ rmSync(tmp, { recursive: true, force: true });
122
128
  }
123
129
  });