gsd-pi 2.44.0 → 2.45.0-dev.6b9da3e

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 (463) hide show
  1. package/README.md +30 -12
  2. package/dist/resources/extensions/gsd/activity-log.js +7 -0
  3. package/dist/resources/extensions/gsd/auto/infra-errors.js +3 -0
  4. package/dist/resources/extensions/gsd/auto/phases.js +37 -36
  5. package/dist/resources/extensions/gsd/auto-prompts.js +24 -1
  6. package/dist/resources/extensions/gsd/auto-start.js +31 -2
  7. package/dist/resources/extensions/gsd/auto-timers.js +57 -3
  8. package/dist/resources/extensions/gsd/auto-worktree-sync.js +4 -0
  9. package/dist/resources/extensions/gsd/auto-worktree.js +9 -6
  10. package/dist/resources/extensions/gsd/auto.js +30 -3
  11. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +156 -0
  12. package/dist/resources/extensions/gsd/bootstrap/system-context.js +46 -12
  13. package/dist/resources/extensions/gsd/commands/catalog.js +7 -1
  14. package/dist/resources/extensions/gsd/commands/handlers/core.js +2 -0
  15. package/dist/resources/extensions/gsd/commands/handlers/ops.js +10 -0
  16. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +5 -0
  17. package/dist/resources/extensions/gsd/commands-mcp-status.js +187 -0
  18. package/dist/resources/extensions/gsd/db-writer.js +34 -16
  19. package/dist/resources/extensions/gsd/doctor.js +8 -0
  20. package/dist/resources/extensions/gsd/git-service.js +8 -3
  21. package/dist/resources/extensions/gsd/gsd-db.js +12 -1
  22. package/dist/resources/extensions/gsd/markdown-renderer.js +1 -1
  23. package/dist/resources/extensions/gsd/preferences.js +9 -1
  24. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +2 -4
  25. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  26. package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +6 -6
  27. package/dist/resources/extensions/gsd/prompts/replan-slice.md +3 -14
  28. package/dist/resources/extensions/gsd/prompts/rethink.md +78 -0
  29. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +7 -37
  30. package/dist/resources/extensions/gsd/provider-error-pause.js +7 -0
  31. package/dist/resources/extensions/gsd/repo-identity.js +45 -7
  32. package/dist/resources/extensions/gsd/rethink.js +115 -0
  33. package/dist/resources/extensions/gsd/state.js +41 -3
  34. package/dist/resources/extensions/gsd/tools/plan-slice.js +1 -0
  35. package/dist/resources/extensions/gsd/tools/plan-task.js +1 -0
  36. package/dist/resources/extensions/gsd/tools/replan-slice.js +2 -0
  37. package/dist/resources/extensions/gsd/tools/validate-milestone.js +88 -0
  38. package/dist/resources/extensions/gsd/worktree-manager.js +32 -2
  39. package/dist/resources/extensions/gsd/worktree-resolver.js +6 -0
  40. package/dist/resources/extensions/mcp-client/index.js +14 -0
  41. package/dist/web/standalone/.next/BUILD_ID +1 -1
  42. package/dist/web/standalone/.next/app-path-routes-manifest.json +8 -8
  43. package/dist/web/standalone/.next/build-manifest.json +4 -4
  44. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  45. package/dist/web/standalone/.next/react-loadable-manifest.json +2 -2
  46. package/dist/web/standalone/.next/required-server-files.json +3 -3
  47. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  48. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  49. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  50. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  51. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  52. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  53. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  54. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  55. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  56. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  57. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  58. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  59. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  60. package/dist/web/standalone/.next/server/app/_not-found.rsc +5 -5
  61. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +5 -5
  62. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  63. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -4
  64. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  65. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  66. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  67. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  68. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  69. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  70. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  71. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  72. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  73. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  74. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  75. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  76. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  77. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  78. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  79. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  80. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  81. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  82. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  83. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  84. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  85. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  86. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  87. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  88. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  89. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  90. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  91. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  92. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  93. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  94. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  95. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  96. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  97. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  98. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  99. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  100. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  101. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  102. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  103. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  104. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  105. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  106. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  107. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  108. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  109. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  110. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  111. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +5 -5
  112. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  113. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  114. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  115. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  116. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  117. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  118. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  119. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  120. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  121. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  122. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  123. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  124. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  125. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  126. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  127. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  128. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  129. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  130. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  132. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  134. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  136. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  138. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  147. package/dist/web/standalone/.next/server/app/index.html +1 -1
  148. package/dist/web/standalone/.next/server/app/index.rsc +6 -6
  149. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  150. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +6 -6
  151. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  152. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -4
  153. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  154. package/dist/web/standalone/.next/server/app/page.js +2 -2
  155. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  156. package/dist/web/standalone/.next/server/app-paths-manifest.json +8 -8
  157. package/dist/web/standalone/.next/server/chunks/229.js +1 -1
  158. package/dist/web/standalone/.next/server/chunks/471.js +3 -3
  159. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  160. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/middleware.js +2 -2
  162. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  163. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  164. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  165. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  166. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  167. package/dist/web/standalone/.next/static/chunks/4024.11ca5c01938e5948.js +9 -0
  168. package/dist/web/standalone/.next/static/chunks/{3721.bf31263de6d5fa46.js → 485.243af25f0cdf50d6.js} +2 -2
  169. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  170. package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
  171. package/dist/web/standalone/.next/static/chunks/app/page-6654a8cca61a3d1c.js +1 -0
  172. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  173. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  174. package/dist/web/standalone/.next/static/chunks/webpack-0a4cd455ec4197d2.js +1 -0
  175. package/dist/web/standalone/.next/static/css/dd4ae3f58ac9b600.css +1 -0
  176. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  177. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  178. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  179. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  180. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  181. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  182. package/dist/web/standalone/server.js +1 -1
  183. package/package.json +1 -1
  184. package/packages/native/dist/stream-process/index.js +2 -2
  185. package/packages/native/src/__tests__/stream-process.test.mjs +34 -0
  186. package/packages/native/src/stream-process/index.ts +2 -2
  187. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +3 -1
  188. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  189. package/packages/pi-coding-agent/dist/core/auth-storage.js +15 -1
  190. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  191. package/packages/pi-coding-agent/dist/core/auth-storage.test.js +6 -8
  192. package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
  193. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +24 -26
  194. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
  195. package/packages/pi-coding-agent/dist/core/fs-utils.test.js +29 -48
  196. package/packages/pi-coding-agent/dist/core/fs-utils.test.js.map +1 -1
  197. package/packages/pi-coding-agent/dist/core/local-model-check.d.ts +15 -0
  198. package/packages/pi-coding-agent/dist/core/local-model-check.d.ts.map +1 -0
  199. package/packages/pi-coding-agent/dist/core/local-model-check.js +41 -0
  200. package/packages/pi-coding-agent/dist/core/local-model-check.js.map +1 -0
  201. package/packages/pi-coding-agent/dist/core/model-registry.d.ts +11 -0
  202. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  203. package/packages/pi-coding-agent/dist/core/model-registry.js +20 -1
  204. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  205. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js +34 -44
  206. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js.map +1 -1
  207. package/packages/pi-coding-agent/dist/core/session-manager.test.js +30 -34
  208. package/packages/pi-coding-agent/dist/core/session-manager.test.js.map +1 -1
  209. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +3 -0
  210. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  211. package/packages/pi-coding-agent/dist/core/settings-manager.js +6 -0
  212. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  213. package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js +10 -12
  214. package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js.map +1 -1
  215. package/packages/pi-coding-agent/dist/main.d.ts.map +1 -1
  216. package/packages/pi-coding-agent/dist/main.js +17 -0
  217. package/packages/pi-coding-agent/dist/main.js.map +1 -1
  218. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.d.ts +2 -0
  219. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.d.ts.map +1 -0
  220. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.js +32 -0
  221. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.js.map +1 -0
  222. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts +3 -1
  223. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  224. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +8 -1
  225. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
  226. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +2 -0
  227. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  228. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +12 -0
  229. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
  230. package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.d.ts +15 -0
  231. package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.d.ts.map +1 -0
  232. package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.js +40 -0
  233. package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.js.map +1 -0
  234. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  235. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +4 -1
  236. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  237. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts +5 -2
  238. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  239. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js +13 -2
  240. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js.map +1 -1
  241. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  242. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +17 -8
  243. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  244. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  245. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +7 -3
  246. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  247. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js +43 -47
  248. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js.map +1 -1
  249. package/packages/pi-coding-agent/package.json +1 -1
  250. package/packages/pi-coding-agent/src/core/auth-storage.test.ts +7 -7
  251. package/packages/pi-coding-agent/src/core/auth-storage.ts +15 -1
  252. package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +26 -26
  253. package/packages/pi-coding-agent/src/core/fs-utils.test.ts +31 -43
  254. package/packages/pi-coding-agent/src/core/local-model-check.ts +45 -0
  255. package/packages/pi-coding-agent/src/core/model-registry.ts +21 -1
  256. package/packages/pi-coding-agent/src/core/resolve-config-value.test.ts +40 -45
  257. package/packages/pi-coding-agent/src/core/session-manager.test.ts +33 -33
  258. package/packages/pi-coding-agent/src/core/settings-manager.ts +9 -0
  259. package/packages/pi-coding-agent/src/core/tools/edit-diff.test.ts +17 -17
  260. package/packages/pi-coding-agent/src/main.ts +19 -0
  261. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/timestamp.test.ts +38 -0
  262. package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +10 -0
  263. package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +15 -0
  264. package/packages/pi-coding-agent/src/modes/interactive/components/timestamp.ts +48 -0
  265. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +3 -1
  266. package/packages/pi-coding-agent/src/modes/interactive/components/user-message.ts +18 -3
  267. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +16 -7
  268. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +8 -1
  269. package/packages/pi-coding-agent/src/resources/extensions/memory/storage.test.ts +74 -74
  270. package/pkg/package.json +1 -1
  271. package/src/resources/extensions/gsd/activity-log.ts +1 -0
  272. package/src/resources/extensions/gsd/auto/infra-errors.ts +3 -0
  273. package/src/resources/extensions/gsd/auto/phases.ts +46 -48
  274. package/src/resources/extensions/gsd/auto-prompts.ts +24 -1
  275. package/src/resources/extensions/gsd/auto-start.ts +39 -2
  276. package/src/resources/extensions/gsd/auto-timers.ts +64 -3
  277. package/src/resources/extensions/gsd/auto-worktree-sync.ts +5 -0
  278. package/src/resources/extensions/gsd/auto-worktree.ts +9 -6
  279. package/src/resources/extensions/gsd/auto.ts +37 -3
  280. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +148 -0
  281. package/src/resources/extensions/gsd/bootstrap/system-context.ts +48 -11
  282. package/src/resources/extensions/gsd/commands/catalog.ts +7 -1
  283. package/src/resources/extensions/gsd/commands/handlers/core.ts +2 -0
  284. package/src/resources/extensions/gsd/commands/handlers/ops.ts +10 -0
  285. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +8 -0
  286. package/src/resources/extensions/gsd/commands-mcp-status.ts +247 -0
  287. package/src/resources/extensions/gsd/db-writer.ts +39 -17
  288. package/src/resources/extensions/gsd/doctor.ts +7 -1
  289. package/src/resources/extensions/gsd/git-service.ts +6 -2
  290. package/src/resources/extensions/gsd/gsd-db.ts +16 -1
  291. package/src/resources/extensions/gsd/markdown-renderer.ts +1 -1
  292. package/src/resources/extensions/gsd/preferences.ts +11 -1
  293. package/src/resources/extensions/gsd/prompts/complete-milestone.md +2 -4
  294. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  295. package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +6 -6
  296. package/src/resources/extensions/gsd/prompts/replan-slice.md +3 -14
  297. package/src/resources/extensions/gsd/prompts/rethink.md +78 -0
  298. package/src/resources/extensions/gsd/prompts/validate-milestone.md +7 -37
  299. package/src/resources/extensions/gsd/provider-error-pause.ts +9 -0
  300. package/src/resources/extensions/gsd/repo-identity.ts +46 -7
  301. package/src/resources/extensions/gsd/rethink.ts +154 -0
  302. package/src/resources/extensions/gsd/state.ts +41 -1
  303. package/src/resources/extensions/gsd/tests/all-milestones-complete-merge.test.ts +99 -99
  304. package/src/resources/extensions/gsd/tests/auto-lock-creation.test.ts +14 -16
  305. package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +43 -57
  306. package/src/resources/extensions/gsd/tests/auto-pr-bugs.test.ts +88 -0
  307. package/src/resources/extensions/gsd/tests/auto-preflight.test.ts +11 -13
  308. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +465 -523
  309. package/src/resources/extensions/gsd/tests/auto-secrets-gate.test.ts +73 -75
  310. package/src/resources/extensions/gsd/tests/auto-start-needs-discussion.test.ts +34 -56
  311. package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +533 -656
  312. package/src/resources/extensions/gsd/tests/auto-worktree.test.ts +165 -143
  313. package/src/resources/extensions/gsd/tests/cache-staleness-regression.test.ts +29 -52
  314. package/src/resources/extensions/gsd/tests/captures.test.ts +148 -176
  315. package/src/resources/extensions/gsd/tests/claude-import-tui.test.ts +32 -33
  316. package/src/resources/extensions/gsd/tests/collect-from-manifest.test.ts +141 -143
  317. package/src/resources/extensions/gsd/tests/commands-inspect-open-db.test.ts +25 -25
  318. package/src/resources/extensions/gsd/tests/commands-logs.test.ts +81 -81
  319. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +38 -59
  320. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +228 -263
  321. package/src/resources/extensions/gsd/tests/complete-task.test.ts +250 -302
  322. package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +114 -0
  323. package/src/resources/extensions/gsd/tests/context-store.test.ts +354 -367
  324. package/src/resources/extensions/gsd/tests/continue-here.test.ts +68 -72
  325. package/src/resources/extensions/gsd/tests/cost-projection.test.ts +92 -106
  326. package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +27 -35
  327. package/src/resources/extensions/gsd/tests/dashboard-budget.test.ts +220 -237
  328. package/src/resources/extensions/gsd/tests/db-writer.test.ts +465 -416
  329. package/src/resources/extensions/gsd/tests/definition-loader.test.ts +76 -92
  330. package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +68 -83
  331. package/src/resources/extensions/gsd/tests/derive-state-db-disk-reconcile.test.ts +121 -0
  332. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +210 -181
  333. package/src/resources/extensions/gsd/tests/derive-state-deps.test.ts +78 -101
  334. package/src/resources/extensions/gsd/tests/derive-state.test.ts +192 -227
  335. package/src/resources/extensions/gsd/tests/detection.test.ts +232 -278
  336. package/src/resources/extensions/gsd/tests/dev-engine-wrapper.test.ts +30 -34
  337. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +164 -180
  338. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +43 -49
  339. package/src/resources/extensions/gsd/tests/dispatch-uat-last-completed.test.ts +28 -32
  340. package/src/resources/extensions/gsd/tests/doctor-completion-deferral.test.ts +27 -29
  341. package/src/resources/extensions/gsd/tests/doctor-delimiter-fix.test.ts +34 -38
  342. package/src/resources/extensions/gsd/tests/doctor-enhancements.test.ts +54 -75
  343. package/src/resources/extensions/gsd/tests/doctor-environment-worktree.test.ts +21 -32
  344. package/src/resources/extensions/gsd/tests/doctor-environment.test.ts +72 -97
  345. package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +38 -44
  346. package/src/resources/extensions/gsd/tests/doctor-git.test.ts +104 -145
  347. package/src/resources/extensions/gsd/tests/doctor-proactive.test.ts +84 -106
  348. package/src/resources/extensions/gsd/tests/doctor-roadmap-summary-atomicity.test.ts +54 -60
  349. package/src/resources/extensions/gsd/tests/doctor-runtime.test.ts +72 -93
  350. package/src/resources/extensions/gsd/tests/doctor.test.ts +104 -134
  351. package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +123 -131
  352. package/src/resources/extensions/gsd/tests/est-annotation-timeout.test.ts +120 -0
  353. package/src/resources/extensions/gsd/tests/exit-command.test.ts +20 -24
  354. package/src/resources/extensions/gsd/tests/feature-branch-lifecycle-integration.test.ts +48 -57
  355. package/src/resources/extensions/gsd/tests/files-loadfile-eisdir.test.ts +5 -7
  356. package/src/resources/extensions/gsd/tests/flag-file-db.test.ts +30 -42
  357. package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +198 -206
  358. package/src/resources/extensions/gsd/tests/git-locale.test.ts +13 -27
  359. package/src/resources/extensions/gsd/tests/git-service.test.ts +285 -388
  360. package/src/resources/extensions/gsd/tests/gitignore-tracked-gsd.test.ts +31 -39
  361. package/src/resources/extensions/gsd/tests/graph-operations.test.ts +63 -69
  362. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +255 -264
  363. package/src/resources/extensions/gsd/tests/gsd-inspect.test.ts +108 -119
  364. package/src/resources/extensions/gsd/tests/gsd-recover.test.ts +81 -103
  365. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +229 -262
  366. package/src/resources/extensions/gsd/tests/headless-answers.test.ts +13 -13
  367. package/src/resources/extensions/gsd/tests/health-widget.test.ts +29 -37
  368. package/src/resources/extensions/gsd/tests/idle-recovery.test.ts +81 -102
  369. package/src/resources/extensions/gsd/tests/infra-error.test.ts +20 -2
  370. package/src/resources/extensions/gsd/tests/inherited-repo-home-dir.test.ts +121 -0
  371. package/src/resources/extensions/gsd/tests/init-wizard.test.ts +16 -18
  372. package/src/resources/extensions/gsd/tests/integration-edge.test.ts +41 -46
  373. package/src/resources/extensions/gsd/tests/integration-lifecycle.test.ts +42 -53
  374. package/src/resources/extensions/gsd/tests/integration-mixed-milestones.test.ts +75 -91
  375. package/src/resources/extensions/gsd/tests/integration-proof.test.ts +18 -18
  376. package/src/resources/extensions/gsd/tests/knowledge.test.ts +89 -0
  377. package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +150 -194
  378. package/src/resources/extensions/gsd/tests/mcp-status.test.ts +103 -0
  379. package/src/resources/extensions/gsd/tests/md-importer.test.ts +101 -125
  380. package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +45 -54
  381. package/src/resources/extensions/gsd/tests/memory-store.test.ts +80 -93
  382. package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +66 -0
  383. package/src/resources/extensions/gsd/tests/migrate-command.test.ts +57 -66
  384. package/src/resources/extensions/gsd/tests/migrate-hierarchy.test.ts +83 -93
  385. package/src/resources/extensions/gsd/tests/migrate-parser.test.ts +161 -170
  386. package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +125 -141
  387. package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +107 -131
  388. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +87 -96
  389. package/src/resources/extensions/gsd/tests/migrate-writer.test.ts +125 -164
  390. package/src/resources/extensions/gsd/tests/must-have-parser.test.ts +81 -94
  391. package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +35 -36
  392. package/src/resources/extensions/gsd/tests/overrides.test.ts +99 -106
  393. package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +40 -47
  394. package/src/resources/extensions/gsd/tests/parallel-worker-monitoring.test.ts +25 -28
  395. package/src/resources/extensions/gsd/tests/parallel-workers-multi-milestone-e2e.test.ts +66 -83
  396. package/src/resources/extensions/gsd/tests/park-edge-cases.test.ts +54 -77
  397. package/src/resources/extensions/gsd/tests/park-milestone.test.ts +68 -115
  398. package/src/resources/extensions/gsd/tests/parsers.test.ts +546 -611
  399. package/src/resources/extensions/gsd/tests/paths.test.ts +72 -87
  400. package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +77 -117
  401. package/src/resources/extensions/gsd/tests/preferences.test.ts +27 -0
  402. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +11 -7
  403. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +56 -56
  404. package/src/resources/extensions/gsd/tests/queue-draft-detection.test.ts +93 -119
  405. package/src/resources/extensions/gsd/tests/queue-order.test.ts +70 -82
  406. package/src/resources/extensions/gsd/tests/queue-reorder-e2e.test.ts +42 -55
  407. package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +100 -0
  408. package/src/resources/extensions/gsd/tests/quick-branch-lifecycle.test.ts +45 -73
  409. package/src/resources/extensions/gsd/tests/reassess-prompt.test.ts +28 -38
  410. package/src/resources/extensions/gsd/tests/recovery-attempts-reset.test.ts +176 -0
  411. package/src/resources/extensions/gsd/tests/replan-slice.test.ts +73 -80
  412. package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +71 -74
  413. package/src/resources/extensions/gsd/tests/requirements.test.ts +70 -75
  414. package/src/resources/extensions/gsd/tests/retry-state-reset.test.ts +44 -66
  415. package/src/resources/extensions/gsd/tests/roadmap-parse-regression.test.ts +114 -181
  416. package/src/resources/extensions/gsd/tests/rule-registry.test.ts +63 -65
  417. package/src/resources/extensions/gsd/tests/run-uat.test.ts +66 -128
  418. package/src/resources/extensions/gsd/tests/session-lock-multipath.test.ts +18 -25
  419. package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +37 -44
  420. package/src/resources/extensions/gsd/tests/shared-wal.test.ts +19 -26
  421. package/src/resources/extensions/gsd/tests/sqlite-unavailable-gate.test.ts +63 -0
  422. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +6 -8
  423. package/src/resources/extensions/gsd/tests/stop-auto-merge-back.test.ts +67 -0
  424. package/src/resources/extensions/gsd/tests/survivor-branch-complete.test.ts +108 -0
  425. package/src/resources/extensions/gsd/tests/symlink-numbered-variants.test.ts +22 -28
  426. package/src/resources/extensions/gsd/tests/terminated-transient.test.ts +49 -0
  427. package/src/resources/extensions/gsd/tests/token-savings.test.ts +54 -56
  428. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +23 -25
  429. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +10 -11
  430. package/src/resources/extensions/gsd/tests/unique-milestone-ids.test.ts +66 -82
  431. package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +46 -47
  432. package/src/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +20 -22
  433. package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +84 -86
  434. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +41 -43
  435. package/src/resources/extensions/gsd/tests/visualizer-views.test.ts +94 -96
  436. package/src/resources/extensions/gsd/tests/windows-path-normalization.test.ts +11 -13
  437. package/src/resources/extensions/gsd/tests/worker-registry.test.ts +27 -29
  438. package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +50 -52
  439. package/src/resources/extensions/gsd/tests/worktree-bugfix.test.ts +10 -13
  440. package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +14 -18
  441. package/src/resources/extensions/gsd/tests/worktree-db.test.ts +38 -39
  442. package/src/resources/extensions/gsd/tests/worktree-e2e.test.ts +17 -21
  443. package/src/resources/extensions/gsd/tests/worktree-health.test.ts +25 -30
  444. package/src/resources/extensions/gsd/tests/worktree-integration.test.ts +30 -37
  445. package/src/resources/extensions/gsd/tests/worktree-submodule-safety.test.ts +65 -0
  446. package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +15 -22
  447. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +59 -66
  448. package/src/resources/extensions/gsd/tests/worktree.test.ts +44 -50
  449. package/src/resources/extensions/gsd/tools/plan-slice.ts +2 -0
  450. package/src/resources/extensions/gsd/tools/plan-task.ts +2 -0
  451. package/src/resources/extensions/gsd/tools/replan-slice.ts +3 -0
  452. package/src/resources/extensions/gsd/tools/validate-milestone.ts +127 -0
  453. package/src/resources/extensions/gsd/worktree-manager.ts +43 -2
  454. package/src/resources/extensions/gsd/worktree-resolver.ts +7 -0
  455. package/src/resources/extensions/mcp-client/index.ts +20 -0
  456. package/dist/web/standalone/.next/static/chunks/4024.0de81b543b28b9fe.js +0 -9
  457. package/dist/web/standalone/.next/static/chunks/app/page-7e9530a7122506c5.js +0 -1
  458. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  459. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  460. package/dist/web/standalone/.next/static/chunks/webpack-9014b5adb127a98a.js +0 -1
  461. package/dist/web/standalone/.next/static/css/8a727f372cf53002.css +0 -1
  462. /package/dist/web/standalone/.next/static/{mgkxN0mGP6gSUmGPEzbk_ → rzO54ZboyINyEt7cVM_uS}/_buildManifest.js +0 -0
  463. /package/dist/web/standalone/.next/static/{mgkxN0mGP6gSUmGPEzbk_ → rzO54ZboyINyEt7cVM_uS}/_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
  });