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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (326) hide show
  1. package/README.md +30 -12
  2. package/dist/resources/extensions/gsd/auto/infra-errors.js +3 -0
  3. package/dist/resources/extensions/gsd/auto/phases.js +36 -36
  4. package/dist/resources/extensions/gsd/auto-prompts.js +24 -1
  5. package/dist/resources/extensions/gsd/auto-start.js +10 -0
  6. package/dist/resources/extensions/gsd/auto-timers.js +57 -3
  7. package/dist/resources/extensions/gsd/auto-worktree-sync.js +4 -0
  8. package/dist/resources/extensions/gsd/auto-worktree.js +9 -6
  9. package/dist/resources/extensions/gsd/auto.js +30 -3
  10. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +156 -0
  11. package/dist/resources/extensions/gsd/bootstrap/system-context.js +46 -12
  12. package/dist/resources/extensions/gsd/commands/catalog.js +6 -1
  13. package/dist/resources/extensions/gsd/commands/handlers/core.js +1 -0
  14. package/dist/resources/extensions/gsd/commands/handlers/ops.js +5 -0
  15. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +5 -0
  16. package/dist/resources/extensions/gsd/commands-mcp-status.js +187 -0
  17. package/dist/resources/extensions/gsd/db-writer.js +34 -16
  18. package/dist/resources/extensions/gsd/doctor.js +8 -0
  19. package/dist/resources/extensions/gsd/git-service.js +8 -3
  20. package/dist/resources/extensions/gsd/gsd-db.js +12 -1
  21. package/dist/resources/extensions/gsd/markdown-renderer.js +1 -1
  22. package/dist/resources/extensions/gsd/preferences.js +9 -1
  23. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +2 -4
  24. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  25. package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +6 -6
  26. package/dist/resources/extensions/gsd/prompts/replan-slice.md +3 -14
  27. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +7 -37
  28. package/dist/resources/extensions/gsd/provider-error-pause.js +7 -0
  29. package/dist/resources/extensions/gsd/state.js +19 -2
  30. package/dist/resources/extensions/gsd/tools/plan-slice.js +1 -0
  31. package/dist/resources/extensions/gsd/tools/plan-task.js +1 -0
  32. package/dist/resources/extensions/gsd/tools/replan-slice.js +2 -0
  33. package/dist/resources/extensions/gsd/tools/validate-milestone.js +88 -0
  34. package/dist/resources/extensions/gsd/worktree-resolver.js +6 -0
  35. package/dist/resources/extensions/mcp-client/index.js +14 -0
  36. package/dist/web/standalone/.next/BUILD_ID +1 -1
  37. package/dist/web/standalone/.next/app-path-routes-manifest.json +17 -17
  38. package/dist/web/standalone/.next/build-manifest.json +2 -2
  39. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  40. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  41. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  42. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  43. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  44. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  45. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  46. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  47. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  48. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  49. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  50. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  51. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  52. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  53. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  54. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  55. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  56. package/dist/web/standalone/.next/server/app/index.html +1 -1
  57. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  58. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  59. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  60. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  61. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  62. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  63. package/dist/web/standalone/.next/server/app-paths-manifest.json +17 -17
  64. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  65. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  66. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  67. package/package.json +1 -1
  68. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +3 -1
  69. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  70. package/packages/pi-coding-agent/dist/core/auth-storage.js +15 -1
  71. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  72. package/packages/pi-coding-agent/dist/core/auth-storage.test.js +6 -8
  73. package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
  74. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +24 -26
  75. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
  76. package/packages/pi-coding-agent/dist/core/fs-utils.test.js +29 -48
  77. package/packages/pi-coding-agent/dist/core/fs-utils.test.js.map +1 -1
  78. package/packages/pi-coding-agent/dist/core/local-model-check.d.ts +15 -0
  79. package/packages/pi-coding-agent/dist/core/local-model-check.d.ts.map +1 -0
  80. package/packages/pi-coding-agent/dist/core/local-model-check.js +41 -0
  81. package/packages/pi-coding-agent/dist/core/local-model-check.js.map +1 -0
  82. package/packages/pi-coding-agent/dist/core/model-registry.d.ts +11 -0
  83. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  84. package/packages/pi-coding-agent/dist/core/model-registry.js +20 -1
  85. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  86. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js +34 -44
  87. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js.map +1 -1
  88. package/packages/pi-coding-agent/dist/core/session-manager.test.js +30 -34
  89. package/packages/pi-coding-agent/dist/core/session-manager.test.js.map +1 -1
  90. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +3 -0
  91. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  92. package/packages/pi-coding-agent/dist/core/settings-manager.js +6 -0
  93. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  94. package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js +10 -12
  95. package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js.map +1 -1
  96. package/packages/pi-coding-agent/dist/main.d.ts.map +1 -1
  97. package/packages/pi-coding-agent/dist/main.js +17 -0
  98. package/packages/pi-coding-agent/dist/main.js.map +1 -1
  99. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.d.ts +2 -0
  100. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.d.ts.map +1 -0
  101. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.js +32 -0
  102. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.js.map +1 -0
  103. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts +3 -1
  104. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  105. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +8 -1
  106. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
  107. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +2 -0
  108. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  109. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +12 -0
  110. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
  111. package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.d.ts +15 -0
  112. package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.d.ts.map +1 -0
  113. package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.js +40 -0
  114. package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.js.map +1 -0
  115. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  116. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +4 -1
  117. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  118. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts +5 -2
  119. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  120. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js +13 -2
  121. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js.map +1 -1
  122. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  123. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +17 -8
  124. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  125. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  126. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +7 -3
  127. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  128. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js +43 -47
  129. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js.map +1 -1
  130. package/packages/pi-coding-agent/src/core/auth-storage.test.ts +7 -7
  131. package/packages/pi-coding-agent/src/core/auth-storage.ts +15 -1
  132. package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +26 -26
  133. package/packages/pi-coding-agent/src/core/fs-utils.test.ts +31 -43
  134. package/packages/pi-coding-agent/src/core/local-model-check.ts +45 -0
  135. package/packages/pi-coding-agent/src/core/model-registry.ts +21 -1
  136. package/packages/pi-coding-agent/src/core/resolve-config-value.test.ts +40 -45
  137. package/packages/pi-coding-agent/src/core/session-manager.test.ts +33 -33
  138. package/packages/pi-coding-agent/src/core/settings-manager.ts +9 -0
  139. package/packages/pi-coding-agent/src/core/tools/edit-diff.test.ts +17 -17
  140. package/packages/pi-coding-agent/src/main.ts +19 -0
  141. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/timestamp.test.ts +38 -0
  142. package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +10 -0
  143. package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +15 -0
  144. package/packages/pi-coding-agent/src/modes/interactive/components/timestamp.ts +48 -0
  145. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +3 -1
  146. package/packages/pi-coding-agent/src/modes/interactive/components/user-message.ts +18 -3
  147. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +16 -7
  148. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +8 -1
  149. package/packages/pi-coding-agent/src/resources/extensions/memory/storage.test.ts +74 -74
  150. package/src/resources/extensions/gsd/auto/infra-errors.ts +3 -0
  151. package/src/resources/extensions/gsd/auto/phases.ts +45 -48
  152. package/src/resources/extensions/gsd/auto-prompts.ts +24 -1
  153. package/src/resources/extensions/gsd/auto-start.ts +14 -0
  154. package/src/resources/extensions/gsd/auto-timers.ts +64 -3
  155. package/src/resources/extensions/gsd/auto-worktree-sync.ts +5 -0
  156. package/src/resources/extensions/gsd/auto-worktree.ts +9 -6
  157. package/src/resources/extensions/gsd/auto.ts +37 -3
  158. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +148 -0
  159. package/src/resources/extensions/gsd/bootstrap/system-context.ts +48 -11
  160. package/src/resources/extensions/gsd/commands/catalog.ts +6 -1
  161. package/src/resources/extensions/gsd/commands/handlers/core.ts +1 -0
  162. package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -0
  163. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +8 -0
  164. package/src/resources/extensions/gsd/commands-mcp-status.ts +247 -0
  165. package/src/resources/extensions/gsd/db-writer.ts +39 -17
  166. package/src/resources/extensions/gsd/doctor.ts +7 -1
  167. package/src/resources/extensions/gsd/git-service.ts +6 -2
  168. package/src/resources/extensions/gsd/gsd-db.ts +16 -1
  169. package/src/resources/extensions/gsd/markdown-renderer.ts +1 -1
  170. package/src/resources/extensions/gsd/preferences.ts +11 -1
  171. package/src/resources/extensions/gsd/prompts/complete-milestone.md +2 -4
  172. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  173. package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +6 -6
  174. package/src/resources/extensions/gsd/prompts/replan-slice.md +3 -14
  175. package/src/resources/extensions/gsd/prompts/validate-milestone.md +7 -37
  176. package/src/resources/extensions/gsd/provider-error-pause.ts +9 -0
  177. package/src/resources/extensions/gsd/state.ts +19 -1
  178. package/src/resources/extensions/gsd/tests/all-milestones-complete-merge.test.ts +99 -99
  179. package/src/resources/extensions/gsd/tests/auto-lock-creation.test.ts +14 -16
  180. package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +43 -57
  181. package/src/resources/extensions/gsd/tests/auto-pr-bugs.test.ts +88 -0
  182. package/src/resources/extensions/gsd/tests/auto-preflight.test.ts +11 -13
  183. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +465 -523
  184. package/src/resources/extensions/gsd/tests/auto-secrets-gate.test.ts +73 -75
  185. package/src/resources/extensions/gsd/tests/auto-start-needs-discussion.test.ts +34 -56
  186. package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +533 -656
  187. package/src/resources/extensions/gsd/tests/auto-worktree.test.ts +165 -143
  188. package/src/resources/extensions/gsd/tests/cache-staleness-regression.test.ts +29 -52
  189. package/src/resources/extensions/gsd/tests/captures.test.ts +148 -176
  190. package/src/resources/extensions/gsd/tests/claude-import-tui.test.ts +32 -33
  191. package/src/resources/extensions/gsd/tests/collect-from-manifest.test.ts +141 -143
  192. package/src/resources/extensions/gsd/tests/commands-inspect-open-db.test.ts +25 -25
  193. package/src/resources/extensions/gsd/tests/commands-logs.test.ts +81 -81
  194. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +38 -59
  195. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +228 -263
  196. package/src/resources/extensions/gsd/tests/complete-task.test.ts +250 -302
  197. package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +114 -0
  198. package/src/resources/extensions/gsd/tests/context-store.test.ts +354 -367
  199. package/src/resources/extensions/gsd/tests/continue-here.test.ts +68 -72
  200. package/src/resources/extensions/gsd/tests/cost-projection.test.ts +92 -106
  201. package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +27 -35
  202. package/src/resources/extensions/gsd/tests/dashboard-budget.test.ts +220 -237
  203. package/src/resources/extensions/gsd/tests/db-writer.test.ts +465 -416
  204. package/src/resources/extensions/gsd/tests/definition-loader.test.ts +76 -92
  205. package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +68 -83
  206. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +210 -181
  207. package/src/resources/extensions/gsd/tests/derive-state-deps.test.ts +78 -101
  208. package/src/resources/extensions/gsd/tests/derive-state.test.ts +192 -227
  209. package/src/resources/extensions/gsd/tests/detection.test.ts +232 -278
  210. package/src/resources/extensions/gsd/tests/dev-engine-wrapper.test.ts +30 -34
  211. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +164 -180
  212. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +43 -49
  213. package/src/resources/extensions/gsd/tests/dispatch-uat-last-completed.test.ts +28 -32
  214. package/src/resources/extensions/gsd/tests/doctor-completion-deferral.test.ts +27 -29
  215. package/src/resources/extensions/gsd/tests/doctor-delimiter-fix.test.ts +34 -38
  216. package/src/resources/extensions/gsd/tests/doctor-enhancements.test.ts +54 -75
  217. package/src/resources/extensions/gsd/tests/doctor-environment-worktree.test.ts +21 -32
  218. package/src/resources/extensions/gsd/tests/doctor-environment.test.ts +72 -97
  219. package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +38 -44
  220. package/src/resources/extensions/gsd/tests/doctor-git.test.ts +104 -145
  221. package/src/resources/extensions/gsd/tests/doctor-proactive.test.ts +84 -106
  222. package/src/resources/extensions/gsd/tests/doctor-roadmap-summary-atomicity.test.ts +54 -60
  223. package/src/resources/extensions/gsd/tests/doctor-runtime.test.ts +72 -93
  224. package/src/resources/extensions/gsd/tests/doctor.test.ts +104 -134
  225. package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +123 -131
  226. package/src/resources/extensions/gsd/tests/est-annotation-timeout.test.ts +120 -0
  227. package/src/resources/extensions/gsd/tests/exit-command.test.ts +20 -24
  228. package/src/resources/extensions/gsd/tests/feature-branch-lifecycle-integration.test.ts +48 -57
  229. package/src/resources/extensions/gsd/tests/files-loadfile-eisdir.test.ts +5 -7
  230. package/src/resources/extensions/gsd/tests/flag-file-db.test.ts +30 -42
  231. package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +198 -206
  232. package/src/resources/extensions/gsd/tests/git-locale.test.ts +13 -27
  233. package/src/resources/extensions/gsd/tests/git-service.test.ts +285 -388
  234. package/src/resources/extensions/gsd/tests/gitignore-tracked-gsd.test.ts +31 -39
  235. package/src/resources/extensions/gsd/tests/graph-operations.test.ts +63 -69
  236. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +255 -264
  237. package/src/resources/extensions/gsd/tests/gsd-inspect.test.ts +108 -119
  238. package/src/resources/extensions/gsd/tests/gsd-recover.test.ts +81 -103
  239. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +229 -262
  240. package/src/resources/extensions/gsd/tests/headless-answers.test.ts +13 -13
  241. package/src/resources/extensions/gsd/tests/health-widget.test.ts +29 -37
  242. package/src/resources/extensions/gsd/tests/idle-recovery.test.ts +81 -102
  243. package/src/resources/extensions/gsd/tests/infra-error.test.ts +20 -2
  244. package/src/resources/extensions/gsd/tests/init-wizard.test.ts +16 -18
  245. package/src/resources/extensions/gsd/tests/integration-edge.test.ts +41 -46
  246. package/src/resources/extensions/gsd/tests/integration-lifecycle.test.ts +42 -53
  247. package/src/resources/extensions/gsd/tests/integration-mixed-milestones.test.ts +75 -91
  248. package/src/resources/extensions/gsd/tests/integration-proof.test.ts +18 -18
  249. package/src/resources/extensions/gsd/tests/knowledge.test.ts +89 -0
  250. package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +150 -194
  251. package/src/resources/extensions/gsd/tests/mcp-status.test.ts +103 -0
  252. package/src/resources/extensions/gsd/tests/md-importer.test.ts +101 -125
  253. package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +45 -54
  254. package/src/resources/extensions/gsd/tests/memory-store.test.ts +80 -93
  255. package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +66 -0
  256. package/src/resources/extensions/gsd/tests/migrate-command.test.ts +57 -66
  257. package/src/resources/extensions/gsd/tests/migrate-hierarchy.test.ts +83 -93
  258. package/src/resources/extensions/gsd/tests/migrate-parser.test.ts +161 -170
  259. package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +125 -141
  260. package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +107 -131
  261. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +87 -96
  262. package/src/resources/extensions/gsd/tests/migrate-writer.test.ts +125 -164
  263. package/src/resources/extensions/gsd/tests/must-have-parser.test.ts +81 -94
  264. package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +35 -36
  265. package/src/resources/extensions/gsd/tests/overrides.test.ts +99 -106
  266. package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +40 -47
  267. package/src/resources/extensions/gsd/tests/parallel-worker-monitoring.test.ts +25 -28
  268. package/src/resources/extensions/gsd/tests/parallel-workers-multi-milestone-e2e.test.ts +66 -83
  269. package/src/resources/extensions/gsd/tests/park-edge-cases.test.ts +54 -77
  270. package/src/resources/extensions/gsd/tests/park-milestone.test.ts +68 -115
  271. package/src/resources/extensions/gsd/tests/parsers.test.ts +546 -611
  272. package/src/resources/extensions/gsd/tests/paths.test.ts +72 -87
  273. package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +77 -117
  274. package/src/resources/extensions/gsd/tests/preferences.test.ts +27 -0
  275. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +11 -7
  276. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +56 -56
  277. package/src/resources/extensions/gsd/tests/queue-draft-detection.test.ts +93 -119
  278. package/src/resources/extensions/gsd/tests/queue-order.test.ts +70 -82
  279. package/src/resources/extensions/gsd/tests/queue-reorder-e2e.test.ts +42 -55
  280. package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +100 -0
  281. package/src/resources/extensions/gsd/tests/quick-branch-lifecycle.test.ts +45 -73
  282. package/src/resources/extensions/gsd/tests/reassess-prompt.test.ts +28 -38
  283. package/src/resources/extensions/gsd/tests/replan-slice.test.ts +73 -80
  284. package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +71 -74
  285. package/src/resources/extensions/gsd/tests/requirements.test.ts +70 -75
  286. package/src/resources/extensions/gsd/tests/retry-state-reset.test.ts +44 -66
  287. package/src/resources/extensions/gsd/tests/roadmap-parse-regression.test.ts +114 -181
  288. package/src/resources/extensions/gsd/tests/rule-registry.test.ts +63 -65
  289. package/src/resources/extensions/gsd/tests/run-uat.test.ts +66 -128
  290. package/src/resources/extensions/gsd/tests/session-lock-multipath.test.ts +18 -25
  291. package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +37 -44
  292. package/src/resources/extensions/gsd/tests/shared-wal.test.ts +19 -26
  293. package/src/resources/extensions/gsd/tests/sqlite-unavailable-gate.test.ts +63 -0
  294. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +6 -8
  295. package/src/resources/extensions/gsd/tests/stop-auto-merge-back.test.ts +67 -0
  296. package/src/resources/extensions/gsd/tests/symlink-numbered-variants.test.ts +22 -28
  297. package/src/resources/extensions/gsd/tests/terminated-transient.test.ts +49 -0
  298. package/src/resources/extensions/gsd/tests/token-savings.test.ts +54 -56
  299. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +23 -25
  300. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +10 -11
  301. package/src/resources/extensions/gsd/tests/unique-milestone-ids.test.ts +66 -82
  302. package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +46 -47
  303. package/src/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +20 -22
  304. package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +84 -86
  305. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +41 -43
  306. package/src/resources/extensions/gsd/tests/visualizer-views.test.ts +94 -96
  307. package/src/resources/extensions/gsd/tests/windows-path-normalization.test.ts +11 -13
  308. package/src/resources/extensions/gsd/tests/worker-registry.test.ts +27 -29
  309. package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +50 -52
  310. package/src/resources/extensions/gsd/tests/worktree-bugfix.test.ts +10 -13
  311. package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +14 -18
  312. package/src/resources/extensions/gsd/tests/worktree-db.test.ts +38 -39
  313. package/src/resources/extensions/gsd/tests/worktree-e2e.test.ts +17 -21
  314. package/src/resources/extensions/gsd/tests/worktree-health.test.ts +25 -30
  315. package/src/resources/extensions/gsd/tests/worktree-integration.test.ts +30 -37
  316. package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +15 -22
  317. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +59 -66
  318. package/src/resources/extensions/gsd/tests/worktree.test.ts +44 -50
  319. package/src/resources/extensions/gsd/tools/plan-slice.ts +2 -0
  320. package/src/resources/extensions/gsd/tools/plan-task.ts +2 -0
  321. package/src/resources/extensions/gsd/tools/replan-slice.ts +3 -0
  322. package/src/resources/extensions/gsd/tools/validate-milestone.ts +127 -0
  323. package/src/resources/extensions/gsd/worktree-resolver.ts +7 -0
  324. package/src/resources/extensions/mcp-client/index.ts +20 -0
  325. /package/dist/web/standalone/.next/static/{fOnWQBjWXMKUs4bqTg530 → kxxAA66bah_yhPYqLBHE2}/_buildManifest.js +0 -0
  326. /package/dist/web/standalone/.next/static/{fOnWQBjWXMKUs4bqTg530 → kxxAA66bah_yhPYqLBHE2}/_ssgManifest.js +0 -0
@@ -38,361 +38,315 @@ function cleanup(dir: string): void {
38
38
 
39
39
  // ─── detectProjectState ─────────────────────────────────────────────────────────
40
40
 
41
- test("detectProjectState: empty directory returns state=none", () => {
41
+ test("detectProjectState: empty directory returns state=none", (t) => {
42
42
  const dir = makeTempDir("empty");
43
- try {
44
- const result = detectProjectState(dir);
45
- assert.equal(result.state, "none");
46
- assert.equal(result.v1, undefined);
47
- assert.equal(result.v2, undefined);
48
- } finally {
49
- cleanup(dir);
50
- }
43
+ t.after(() => cleanup(dir));
44
+
45
+ const result = detectProjectState(dir);
46
+ assert.equal(result.state, "none");
47
+ assert.equal(result.v1, undefined);
48
+ assert.equal(result.v2, undefined);
51
49
  });
52
50
 
53
- test("detectProjectState: directory with .gsd/milestones/M001 returns v2-gsd", () => {
51
+ test("detectProjectState: directory with .gsd/milestones/M001 returns v2-gsd", (t) => {
54
52
  const dir = makeTempDir("v2-gsd");
55
- try {
56
- mkdirSync(join(dir, ".gsd", "milestones", "M001"), { recursive: true });
57
- const result = detectProjectState(dir);
58
- assert.equal(result.state, "v2-gsd");
59
- assert.ok(result.v2);
60
- assert.equal(result.v2!.milestoneCount, 1);
61
- } finally {
62
- cleanup(dir);
63
- }
53
+ t.after(() => cleanup(dir));
54
+
55
+ mkdirSync(join(dir, ".gsd", "milestones", "M001"), { recursive: true });
56
+ const result = detectProjectState(dir);
57
+ assert.equal(result.state, "v2-gsd");
58
+ assert.ok(result.v2);
59
+ assert.equal(result.v2!.milestoneCount, 1);
64
60
  });
65
61
 
66
- test("detectProjectState: directory with empty .gsd/milestones returns v2-gsd-empty", () => {
62
+ test("detectProjectState: directory with empty .gsd/milestones returns v2-gsd-empty", (t) => {
67
63
  const dir = makeTempDir("v2-empty");
68
- try {
69
- mkdirSync(join(dir, ".gsd", "milestones"), { recursive: true });
70
- const result = detectProjectState(dir);
71
- assert.equal(result.state, "v2-gsd-empty");
72
- assert.ok(result.v2);
73
- assert.equal(result.v2!.milestoneCount, 0);
74
- } finally {
75
- cleanup(dir);
76
- }
64
+ t.after(() => cleanup(dir));
65
+
66
+ mkdirSync(join(dir, ".gsd", "milestones"), { recursive: true });
67
+ const result = detectProjectState(dir);
68
+ assert.equal(result.state, "v2-gsd-empty");
69
+ assert.ok(result.v2);
70
+ assert.equal(result.v2!.milestoneCount, 0);
77
71
  });
78
72
 
79
- test("detectProjectState: directory with .planning/ returns v1-planning", () => {
73
+ test("detectProjectState: directory with .planning/ returns v1-planning", (t) => {
80
74
  const dir = makeTempDir("v1-planning");
81
- try {
82
- mkdirSync(join(dir, ".planning", "phases", "01-setup"), { recursive: true });
83
- writeFileSync(join(dir, ".planning", "ROADMAP.md"), "# Roadmap\n", "utf-8");
84
- const result = detectProjectState(dir);
85
- assert.equal(result.state, "v1-planning");
86
- assert.ok(result.v1);
87
- assert.equal(result.v1!.hasRoadmap, true);
88
- assert.equal(result.v1!.hasPhasesDir, true);
89
- assert.equal(result.v1!.phaseCount, 1);
90
- } finally {
91
- cleanup(dir);
92
- }
75
+ t.after(() => cleanup(dir));
76
+
77
+ mkdirSync(join(dir, ".planning", "phases", "01-setup"), { recursive: true });
78
+ writeFileSync(join(dir, ".planning", "ROADMAP.md"), "# Roadmap\n", "utf-8");
79
+ const result = detectProjectState(dir);
80
+ assert.equal(result.state, "v1-planning");
81
+ assert.ok(result.v1);
82
+ assert.equal(result.v1!.hasRoadmap, true);
83
+ assert.equal(result.v1!.hasPhasesDir, true);
84
+ assert.equal(result.v1!.phaseCount, 1);
93
85
  });
94
86
 
95
- test("detectProjectState: v2 takes priority over v1 when both exist", () => {
87
+ test("detectProjectState: v2 takes priority over v1 when both exist", (t) => {
96
88
  const dir = makeTempDir("both");
97
- try {
98
- mkdirSync(join(dir, ".gsd", "milestones", "M001"), { recursive: true });
99
- mkdirSync(join(dir, ".planning"), { recursive: true });
100
- const result = detectProjectState(dir);
101
- assert.equal(result.state, "v2-gsd");
102
- } finally {
103
- cleanup(dir);
104
- }
89
+ t.after(() => cleanup(dir));
90
+
91
+ mkdirSync(join(dir, ".gsd", "milestones", "M001"), { recursive: true });
92
+ mkdirSync(join(dir, ".planning"), { recursive: true });
93
+ const result = detectProjectState(dir);
94
+ assert.equal(result.state, "v2-gsd");
105
95
  });
106
96
 
107
- test("detectProjectState: detects preferences in .gsd/", () => {
97
+ test("detectProjectState: detects preferences in .gsd/", (t) => {
108
98
  const dir = makeTempDir("prefs");
109
- try {
110
- mkdirSync(join(dir, ".gsd", "milestones"), { recursive: true });
111
- writeFileSync(join(dir, ".gsd", "preferences.md"), "---\nversion: 1\n---\n", "utf-8");
112
- const result = detectProjectState(dir);
113
- assert.ok(result.v2);
114
- assert.equal(result.v2!.hasPreferences, true);
115
- } finally {
116
- cleanup(dir);
117
- }
99
+ t.after(() => cleanup(dir));
100
+
101
+ mkdirSync(join(dir, ".gsd", "milestones"), { recursive: true });
102
+ writeFileSync(join(dir, ".gsd", "preferences.md"), "---\nversion: 1\n---\n", "utf-8");
103
+ const result = detectProjectState(dir);
104
+ assert.ok(result.v2);
105
+ assert.equal(result.v2!.hasPreferences, true);
118
106
  });
119
107
 
120
108
  // ─── detectV1Planning ───────────────────────────────────────────────────────────
121
109
 
122
- test("detectV1Planning: returns null for missing .planning/", () => {
110
+ test("detectV1Planning: returns null for missing .planning/", (t) => {
123
111
  const dir = makeTempDir("no-v1");
124
- try {
125
- assert.equal(detectV1Planning(dir), null);
126
- } finally {
127
- cleanup(dir);
128
- }
112
+ t.after(() => cleanup(dir));
113
+
114
+ assert.equal(detectV1Planning(dir), null);
129
115
  });
130
116
 
131
- test("detectV1Planning: returns null when .planning is a file", () => {
117
+ test("detectV1Planning: returns null when .planning is a file", (t) => {
132
118
  const dir = makeTempDir("v1-file");
133
- try {
134
- writeFileSync(join(dir, ".planning"), "not a directory", "utf-8");
135
- assert.equal(detectV1Planning(dir), null);
136
- } finally {
137
- cleanup(dir);
138
- }
119
+ t.after(() => cleanup(dir));
120
+
121
+ writeFileSync(join(dir, ".planning"), "not a directory", "utf-8");
122
+ assert.equal(detectV1Planning(dir), null);
139
123
  });
140
124
 
141
- test("detectV1Planning: detects phases directory with multiple phases", () => {
125
+ test("detectV1Planning: detects phases directory with multiple phases", (t) => {
142
126
  const dir = makeTempDir("v1-phases");
143
- try {
144
- mkdirSync(join(dir, ".planning", "phases", "01-setup"), { recursive: true });
145
- mkdirSync(join(dir, ".planning", "phases", "02-core"), { recursive: true });
146
- mkdirSync(join(dir, ".planning", "phases", "03-deploy"), { recursive: true });
147
- const result = detectV1Planning(dir);
148
- assert.ok(result);
149
- assert.equal(result!.phaseCount, 3);
150
- assert.equal(result!.hasPhasesDir, true);
151
- } finally {
152
- cleanup(dir);
153
- }
127
+ t.after(() => cleanup(dir));
128
+
129
+ mkdirSync(join(dir, ".planning", "phases", "01-setup"), { recursive: true });
130
+ mkdirSync(join(dir, ".planning", "phases", "02-core"), { recursive: true });
131
+ mkdirSync(join(dir, ".planning", "phases", "03-deploy"), { recursive: true });
132
+ const result = detectV1Planning(dir);
133
+ assert.ok(result);
134
+ assert.equal(result!.phaseCount, 3);
135
+ assert.equal(result!.hasPhasesDir, true);
154
136
  });
155
137
 
156
- test("detectV1Planning: detects ROADMAP.md", () => {
138
+ test("detectV1Planning: detects ROADMAP.md", (t) => {
157
139
  const dir = makeTempDir("v1-roadmap");
158
- try {
159
- mkdirSync(join(dir, ".planning"), { recursive: true });
160
- writeFileSync(join(dir, ".planning", "ROADMAP.md"), "# Roadmap", "utf-8");
161
- const result = detectV1Planning(dir);
162
- assert.ok(result);
163
- assert.equal(result!.hasRoadmap, true);
164
- assert.equal(result!.hasPhasesDir, false);
165
- assert.equal(result!.phaseCount, 0);
166
- } finally {
167
- cleanup(dir);
168
- }
140
+ t.after(() => cleanup(dir));
141
+
142
+ mkdirSync(join(dir, ".planning"), { recursive: true });
143
+ writeFileSync(join(dir, ".planning", "ROADMAP.md"), "# Roadmap", "utf-8");
144
+ const result = detectV1Planning(dir);
145
+ assert.ok(result);
146
+ assert.equal(result!.hasRoadmap, true);
147
+ assert.equal(result!.hasPhasesDir, false);
148
+ assert.equal(result!.phaseCount, 0);
169
149
  });
170
150
 
171
151
  // ─── detectProjectSignals ───────────────────────────────────────────────────────
172
152
 
173
- test("detectProjectSignals: empty directory", () => {
153
+ test("detectProjectSignals: empty directory", (t) => {
174
154
  const dir = makeTempDir("signals-empty");
175
- try {
176
- const signals = detectProjectSignals(dir);
177
- assert.deepEqual(signals.detectedFiles, []);
178
- assert.equal(signals.isGitRepo, false);
179
- assert.equal(signals.isMonorepo, false);
180
- assert.equal(signals.primaryLanguage, undefined);
181
- assert.equal(signals.hasCI, false);
182
- assert.equal(signals.hasTests, false);
183
- assert.deepEqual(signals.verificationCommands, []);
184
- } finally {
185
- cleanup(dir);
186
- }
155
+ t.after(() => cleanup(dir));
156
+
157
+ const signals = detectProjectSignals(dir);
158
+ assert.deepEqual(signals.detectedFiles, []);
159
+ assert.equal(signals.isGitRepo, false);
160
+ assert.equal(signals.isMonorepo, false);
161
+ assert.equal(signals.primaryLanguage, undefined);
162
+ assert.equal(signals.hasCI, false);
163
+ assert.equal(signals.hasTests, false);
164
+ assert.deepEqual(signals.verificationCommands, []);
187
165
  });
188
166
 
189
- test("detectProjectSignals: Node.js project", () => {
167
+ test("detectProjectSignals: Node.js project", (t) => {
190
168
  const dir = makeTempDir("signals-node");
191
- try {
192
- writeFileSync(
193
- join(dir, "package.json"),
194
- JSON.stringify({
195
- name: "test-project",
196
- scripts: {
197
- test: "jest",
198
- build: "tsc",
199
- lint: "eslint .",
200
- },
201
- }),
202
- "utf-8",
203
- );
204
- writeFileSync(join(dir, "package-lock.json"), "{}", "utf-8");
205
- mkdirSync(join(dir, ".git"), { recursive: true });
206
-
207
- const signals = detectProjectSignals(dir);
208
- assert.ok(signals.detectedFiles.includes("package.json"));
209
- assert.equal(signals.primaryLanguage, "javascript/typescript");
210
- assert.equal(signals.isGitRepo, true);
211
- assert.equal(signals.packageManager, "npm");
212
- assert.ok(signals.verificationCommands.includes("npm test"));
213
- assert.ok(signals.verificationCommands.some(c => c.includes("build")));
214
- assert.ok(signals.verificationCommands.some(c => c.includes("lint")));
215
- } finally {
216
- cleanup(dir);
217
- }
169
+ t.after(() => cleanup(dir));
170
+
171
+ writeFileSync(
172
+ join(dir, "package.json"),
173
+ JSON.stringify({
174
+ name: "test-project",
175
+ scripts: {
176
+ test: "jest",
177
+ build: "tsc",
178
+ lint: "eslint .",
179
+ },
180
+ }),
181
+ "utf-8",
182
+ );
183
+ writeFileSync(join(dir, "package-lock.json"), "{}", "utf-8");
184
+ mkdirSync(join(dir, ".git"), { recursive: true });
185
+
186
+ const signals = detectProjectSignals(dir);
187
+ assert.ok(signals.detectedFiles.includes("package.json"));
188
+ assert.equal(signals.primaryLanguage, "javascript/typescript");
189
+ assert.equal(signals.isGitRepo, true);
190
+ assert.equal(signals.packageManager, "npm");
191
+ assert.ok(signals.verificationCommands.includes("npm test"));
192
+ assert.ok(signals.verificationCommands.some(c => c.includes("build")));
193
+ assert.ok(signals.verificationCommands.some(c => c.includes("lint")));
218
194
  });
219
195
 
220
- test("detectProjectSignals: Rust project", () => {
196
+ test("detectProjectSignals: Rust project", (t) => {
221
197
  const dir = makeTempDir("signals-rust");
222
- try {
223
- writeFileSync(join(dir, "Cargo.toml"), '[package]\nname = "test"\n', "utf-8");
224
- const signals = detectProjectSignals(dir);
225
- assert.ok(signals.detectedFiles.includes("Cargo.toml"));
226
- assert.equal(signals.primaryLanguage, "rust");
227
- assert.ok(signals.verificationCommands.includes("cargo test"));
228
- assert.ok(signals.verificationCommands.includes("cargo clippy"));
229
- } finally {
230
- cleanup(dir);
231
- }
198
+ t.after(() => cleanup(dir));
199
+
200
+ writeFileSync(join(dir, "Cargo.toml"), '[package]\nname = "test"\n', "utf-8");
201
+ const signals = detectProjectSignals(dir);
202
+ assert.ok(signals.detectedFiles.includes("Cargo.toml"));
203
+ assert.equal(signals.primaryLanguage, "rust");
204
+ assert.ok(signals.verificationCommands.includes("cargo test"));
205
+ assert.ok(signals.verificationCommands.includes("cargo clippy"));
232
206
  });
233
207
 
234
- test("detectProjectSignals: Go project", () => {
208
+ test("detectProjectSignals: Go project", (t) => {
235
209
  const dir = makeTempDir("signals-go");
236
- try {
237
- writeFileSync(join(dir, "go.mod"), "module example.com/test\n", "utf-8");
238
- const signals = detectProjectSignals(dir);
239
- assert.ok(signals.detectedFiles.includes("go.mod"));
240
- assert.equal(signals.primaryLanguage, "go");
241
- assert.ok(signals.verificationCommands.includes("go test ./..."));
242
- } finally {
243
- cleanup(dir);
244
- }
210
+ t.after(() => cleanup(dir));
211
+
212
+ writeFileSync(join(dir, "go.mod"), "module example.com/test\n", "utf-8");
213
+ const signals = detectProjectSignals(dir);
214
+ assert.ok(signals.detectedFiles.includes("go.mod"));
215
+ assert.equal(signals.primaryLanguage, "go");
216
+ assert.ok(signals.verificationCommands.includes("go test ./..."));
245
217
  });
246
218
 
247
- test("detectProjectSignals: Python project", () => {
219
+ test("detectProjectSignals: Python project", (t) => {
248
220
  const dir = makeTempDir("signals-python");
249
- try {
250
- writeFileSync(join(dir, "pyproject.toml"), "[tool.poetry]\n", "utf-8");
251
- const signals = detectProjectSignals(dir);
252
- assert.ok(signals.detectedFiles.includes("pyproject.toml"));
253
- assert.equal(signals.primaryLanguage, "python");
254
- assert.ok(signals.verificationCommands.includes("pytest"));
255
- } finally {
256
- cleanup(dir);
257
- }
221
+ t.after(() => cleanup(dir));
222
+
223
+ writeFileSync(join(dir, "pyproject.toml"), "[tool.poetry]\n", "utf-8");
224
+ const signals = detectProjectSignals(dir);
225
+ assert.ok(signals.detectedFiles.includes("pyproject.toml"));
226
+ assert.equal(signals.primaryLanguage, "python");
227
+ assert.ok(signals.verificationCommands.includes("pytest"));
258
228
  });
259
229
 
260
- test("detectProjectSignals: monorepo detection via workspaces", () => {
230
+ test("detectProjectSignals: monorepo detection via workspaces", (t) => {
261
231
  const dir = makeTempDir("signals-monorepo");
262
- try {
263
- writeFileSync(
264
- join(dir, "package.json"),
265
- JSON.stringify({ name: "mono", workspaces: ["packages/*"] }),
266
- "utf-8",
267
- );
268
- const signals = detectProjectSignals(dir);
269
- assert.equal(signals.isMonorepo, true);
270
- } finally {
271
- cleanup(dir);
272
- }
232
+ t.after(() => cleanup(dir));
233
+
234
+ writeFileSync(
235
+ join(dir, "package.json"),
236
+ JSON.stringify({ name: "mono", workspaces: ["packages/*"] }),
237
+ "utf-8",
238
+ );
239
+ const signals = detectProjectSignals(dir);
240
+ assert.equal(signals.isMonorepo, true);
273
241
  });
274
242
 
275
- test("detectProjectSignals: monorepo detection via turbo.json", () => {
243
+ test("detectProjectSignals: monorepo detection via turbo.json", (t) => {
276
244
  const dir = makeTempDir("signals-turbo");
277
- try {
278
- writeFileSync(join(dir, "package.json"), JSON.stringify({ name: "test" }), "utf-8");
279
- writeFileSync(join(dir, "turbo.json"), "{}", "utf-8");
280
- const signals = detectProjectSignals(dir);
281
- assert.equal(signals.isMonorepo, true);
282
- } finally {
283
- cleanup(dir);
284
- }
245
+ t.after(() => cleanup(dir));
246
+
247
+ writeFileSync(join(dir, "package.json"), JSON.stringify({ name: "test" }), "utf-8");
248
+ writeFileSync(join(dir, "turbo.json"), "{}", "utf-8");
249
+ const signals = detectProjectSignals(dir);
250
+ assert.equal(signals.isMonorepo, true);
285
251
  });
286
252
 
287
- test("detectProjectSignals: CI detection", () => {
253
+ test("detectProjectSignals: CI detection", (t) => {
288
254
  const dir = makeTempDir("signals-ci");
289
- try {
290
- mkdirSync(join(dir, ".github", "workflows"), { recursive: true });
291
- const signals = detectProjectSignals(dir);
292
- assert.equal(signals.hasCI, true);
293
- } finally {
294
- cleanup(dir);
295
- }
255
+ t.after(() => cleanup(dir));
256
+
257
+ mkdirSync(join(dir, ".github", "workflows"), { recursive: true });
258
+ const signals = detectProjectSignals(dir);
259
+ assert.equal(signals.hasCI, true);
296
260
  });
297
261
 
298
- test("detectProjectSignals: test detection via jest config", () => {
262
+ test("detectProjectSignals: test detection via jest config", (t) => {
299
263
  const dir = makeTempDir("signals-tests");
300
- try {
301
- writeFileSync(join(dir, "jest.config.ts"), "export default {}", "utf-8");
302
- const signals = detectProjectSignals(dir);
303
- assert.equal(signals.hasTests, true);
304
- } finally {
305
- cleanup(dir);
306
- }
264
+ t.after(() => cleanup(dir));
265
+
266
+ writeFileSync(join(dir, "jest.config.ts"), "export default {}", "utf-8");
267
+ const signals = detectProjectSignals(dir);
268
+ assert.equal(signals.hasTests, true);
307
269
  });
308
270
 
309
- test("detectProjectSignals: package manager detection", () => {
271
+ test("detectProjectSignals: package manager detection", (t) => {
310
272
  const dir1 = makeTempDir("pm-pnpm");
311
273
  const dir2 = makeTempDir("pm-yarn");
312
274
  const dir3 = makeTempDir("pm-bun");
313
- try {
314
- writeFileSync(join(dir1, "pnpm-lock.yaml"), "", "utf-8");
315
- writeFileSync(join(dir1, "package.json"), "{}", "utf-8");
316
- assert.equal(detectProjectSignals(dir1).packageManager, "pnpm");
317
-
318
- writeFileSync(join(dir2, "yarn.lock"), "", "utf-8");
319
- writeFileSync(join(dir2, "package.json"), "{}", "utf-8");
320
- assert.equal(detectProjectSignals(dir2).packageManager, "yarn");
321
-
322
- writeFileSync(join(dir3, "bun.lockb"), "", "utf-8");
323
- writeFileSync(join(dir3, "package.json"), "{}", "utf-8");
324
- assert.equal(detectProjectSignals(dir3).packageManager, "bun");
325
- } finally {
275
+ t.after(() => {
326
276
  cleanup(dir1);
327
277
  cleanup(dir2);
328
278
  cleanup(dir3);
329
- }
279
+ });
280
+
281
+ writeFileSync(join(dir1, "pnpm-lock.yaml"), "", "utf-8");
282
+ writeFileSync(join(dir1, "package.json"), "{}", "utf-8");
283
+ assert.equal(detectProjectSignals(dir1).packageManager, "pnpm");
284
+
285
+ writeFileSync(join(dir2, "yarn.lock"), "", "utf-8");
286
+ writeFileSync(join(dir2, "package.json"), "{}", "utf-8");
287
+ assert.equal(detectProjectSignals(dir2).packageManager, "yarn");
288
+
289
+ writeFileSync(join(dir3, "bun.lockb"), "", "utf-8");
290
+ writeFileSync(join(dir3, "package.json"), "{}", "utf-8");
291
+ assert.equal(detectProjectSignals(dir3).packageManager, "bun");
330
292
  });
331
293
 
332
- test("detectProjectSignals: skips default npm test script", () => {
294
+ test("detectProjectSignals: skips default npm test script", (t) => {
333
295
  const dir = makeTempDir("signals-default-test");
334
- try {
335
- writeFileSync(
336
- join(dir, "package.json"),
337
- JSON.stringify({
338
- name: "test",
339
- scripts: { test: 'echo "Error: no test specified" && exit 1' },
340
- }),
341
- "utf-8",
342
- );
343
- const signals = detectProjectSignals(dir);
344
- // Should NOT include the default npm test script
345
- assert.equal(
346
- signals.verificationCommands.some(c => c.includes("test")),
347
- false,
348
- );
349
- } finally {
350
- cleanup(dir);
351
- }
296
+ t.after(() => cleanup(dir));
297
+
298
+ writeFileSync(
299
+ join(dir, "package.json"),
300
+ JSON.stringify({
301
+ name: "test",
302
+ scripts: { test: 'echo "Error: no test specified" && exit 1' },
303
+ }),
304
+ "utf-8",
305
+ );
306
+ const signals = detectProjectSignals(dir);
307
+ // Should NOT include the default npm test script
308
+ assert.equal(
309
+ signals.verificationCommands.some(c => c.includes("test")),
310
+ false,
311
+ );
352
312
  });
353
313
 
354
- test("detectProjectSignals: pnpm uses pnpm commands", () => {
314
+ test("detectProjectSignals: pnpm uses pnpm commands", (t) => {
355
315
  const dir = makeTempDir("signals-pnpm-cmds");
356
- try {
357
- writeFileSync(
358
- join(dir, "package.json"),
359
- JSON.stringify({
360
- name: "test",
361
- scripts: { test: "vitest", build: "tsc" },
362
- }),
363
- "utf-8",
364
- );
365
- writeFileSync(join(dir, "pnpm-lock.yaml"), "", "utf-8");
366
- const signals = detectProjectSignals(dir);
367
- assert.ok(signals.verificationCommands.includes("pnpm test"));
368
- assert.ok(signals.verificationCommands.includes("pnpm run build"));
369
- } finally {
370
- cleanup(dir);
371
- }
316
+ t.after(() => cleanup(dir));
317
+
318
+ writeFileSync(
319
+ join(dir, "package.json"),
320
+ JSON.stringify({
321
+ name: "test",
322
+ scripts: { test: "vitest", build: "tsc" },
323
+ }),
324
+ "utf-8",
325
+ );
326
+ writeFileSync(join(dir, "pnpm-lock.yaml"), "", "utf-8");
327
+ const signals = detectProjectSignals(dir);
328
+ assert.ok(signals.verificationCommands.includes("pnpm test"));
329
+ assert.ok(signals.verificationCommands.includes("pnpm run build"));
372
330
  });
373
331
 
374
- test("detectProjectSignals: Ruby project with rspec", () => {
332
+ test("detectProjectSignals: Ruby project with rspec", (t) => {
375
333
  const dir = makeTempDir("signals-ruby");
376
- try {
377
- writeFileSync(join(dir, "Gemfile"), 'source "https://rubygems.org"\n', "utf-8");
378
- mkdirSync(join(dir, "spec"), { recursive: true });
379
- const signals = detectProjectSignals(dir);
380
- assert.ok(signals.detectedFiles.includes("Gemfile"));
381
- assert.equal(signals.primaryLanguage, "ruby");
382
- assert.ok(signals.verificationCommands.includes("bundle exec rspec"));
383
- } finally {
384
- cleanup(dir);
385
- }
334
+ t.after(() => cleanup(dir));
335
+
336
+ writeFileSync(join(dir, "Gemfile"), 'source "https://rubygems.org"\n', "utf-8");
337
+ mkdirSync(join(dir, "spec"), { recursive: true });
338
+ const signals = detectProjectSignals(dir);
339
+ assert.ok(signals.detectedFiles.includes("Gemfile"));
340
+ assert.equal(signals.primaryLanguage, "ruby");
341
+ assert.ok(signals.verificationCommands.includes("bundle exec rspec"));
386
342
  });
387
343
 
388
- test("detectProjectSignals: Makefile with test target", () => {
344
+ test("detectProjectSignals: Makefile with test target", (t) => {
389
345
  const dir = makeTempDir("signals-make");
390
- try {
391
- writeFileSync(join(dir, "Makefile"), "test:\n\tgo test ./...\n\nbuild:\n\tgo build\n", "utf-8");
392
- const signals = detectProjectSignals(dir);
393
- assert.ok(signals.detectedFiles.includes("Makefile"));
394
- assert.ok(signals.verificationCommands.includes("make test"));
395
- } finally {
396
- cleanup(dir);
397
- }
346
+ t.after(() => cleanup(dir));
347
+
348
+ writeFileSync(join(dir, "Makefile"), "test:\n\tgo test ./...\n\nbuild:\n\tgo build\n", "utf-8");
349
+ const signals = detectProjectSignals(dir);
350
+ assert.ok(signals.detectedFiles.includes("Makefile"));
351
+ assert.ok(signals.verificationCommands.includes("make test"));
398
352
  });