gsd-pi 2.78.0 → 2.78.1-dev.9d08d820b

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 (548) hide show
  1. package/README.md +59 -23
  2. package/dist/bundled-resource-path.d.ts +7 -0
  3. package/dist/bundled-resource-path.js +34 -2
  4. package/dist/claude-cli-check.js +104 -33
  5. package/dist/cli-policy.d.ts +13 -0
  6. package/dist/cli-policy.js +17 -0
  7. package/dist/cli.js +95 -55
  8. package/dist/headless-query.d.ts +22 -0
  9. package/dist/headless-query.js +43 -8
  10. package/dist/headless.d.ts +10 -0
  11. package/dist/headless.js +16 -1
  12. package/dist/loader.js +9 -13
  13. package/dist/onboarding.d.ts +10 -0
  14. package/dist/onboarding.js +2 -2
  15. package/dist/provider-migrations.d.ts +2 -2
  16. package/dist/provider-migrations.js +5 -2
  17. package/dist/resource-loader.d.ts +5 -2
  18. package/dist/resource-loader.js +30 -13
  19. package/dist/resources/.managed-resources-content-hash +1 -0
  20. package/dist/resources/extensions/claude-code-cli/readiness.js +128 -32
  21. package/dist/resources/extensions/gsd/auto/loop.js +23 -0
  22. package/dist/resources/extensions/gsd/auto/phases.js +5 -13
  23. package/dist/resources/extensions/gsd/auto/run-unit.js +3 -1
  24. package/dist/resources/extensions/gsd/auto/session.js +5 -6
  25. package/dist/resources/extensions/gsd/auto-dashboard.js +3 -2
  26. package/dist/resources/extensions/gsd/auto-dispatch.js +18 -6
  27. package/dist/resources/extensions/gsd/auto-prompts.js +63 -2
  28. package/dist/resources/extensions/gsd/auto-recovery.js +43 -4
  29. package/dist/resources/extensions/gsd/auto-runtime-state.js +31 -0
  30. package/dist/resources/extensions/gsd/auto-start.js +1 -1
  31. package/dist/resources/extensions/gsd/auto-tool-tracking.js +2 -2
  32. package/dist/resources/extensions/gsd/auto-worktree.js +60 -13
  33. package/dist/resources/extensions/gsd/auto.js +14 -5
  34. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +14 -2
  35. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +7 -5
  36. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +2 -2
  37. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +5 -4
  38. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +100 -31
  39. package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +11 -6
  40. package/dist/resources/extensions/gsd/bootstrap/subagent-input.js +22 -0
  41. package/dist/resources/extensions/gsd/bootstrap/system-context.js +34 -8
  42. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +121 -3
  43. package/dist/resources/extensions/gsd/commands/catalog.js +69 -5
  44. package/dist/resources/extensions/gsd/commands/handlers/core.js +22 -1
  45. package/dist/resources/extensions/gsd/commands-config.js +3 -2
  46. package/dist/resources/extensions/gsd/commands-extensions.js +46 -3
  47. package/dist/resources/extensions/gsd/commands-handlers.js +3 -2
  48. package/dist/resources/extensions/gsd/commands-mcp-status.js +3 -1
  49. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +10 -1
  50. package/dist/resources/extensions/gsd/dashboard-overlay.js +1 -1
  51. package/dist/resources/extensions/gsd/docs/preferences-reference.md +10 -0
  52. package/dist/resources/extensions/gsd/doctor-providers.js +2 -1
  53. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +39 -1
  54. package/dist/resources/extensions/gsd/error-classifier.js +1 -1
  55. package/dist/resources/extensions/gsd/forensics.js +10 -8
  56. package/dist/resources/extensions/gsd/git-service.js +12 -5
  57. package/dist/resources/extensions/gsd/gsd-db.js +11 -2
  58. package/dist/resources/extensions/gsd/guided-flow.js +25 -24
  59. package/dist/resources/extensions/gsd/home-dir.js +16 -0
  60. package/dist/resources/extensions/gsd/key-manager.js +2 -1
  61. package/dist/resources/extensions/gsd/memory-store.js +66 -31
  62. package/dist/resources/extensions/gsd/migrate/command.js +3 -2
  63. package/dist/resources/extensions/gsd/milestone-id-reservation.js +36 -0
  64. package/dist/resources/extensions/gsd/model-router.js +114 -9
  65. package/dist/resources/extensions/gsd/native-git-bridge.js +7 -1
  66. package/dist/resources/extensions/gsd/preferences-models.js +91 -15
  67. package/dist/resources/extensions/gsd/preferences-types.js +2 -0
  68. package/dist/resources/extensions/gsd/preferences-validation.js +32 -0
  69. package/dist/resources/extensions/gsd/preferences.js +5 -3
  70. package/dist/resources/extensions/gsd/prompt-loader.js +23 -12
  71. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +10 -0
  72. package/dist/resources/extensions/gsd/prompts/complete-slice.md +10 -0
  73. package/dist/resources/extensions/gsd/prompts/plan-slice.md +10 -0
  74. package/dist/resources/extensions/gsd/prompts/refine-slice.md +10 -0
  75. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +9 -3
  76. package/dist/resources/extensions/gsd/state.js +42 -0
  77. package/dist/resources/extensions/gsd/templates/PREFERENCES.md +1 -0
  78. package/dist/resources/extensions/gsd/tools/memory-tools.js +18 -1
  79. package/dist/resources/extensions/gsd/unit-context-manifest.js +29 -4
  80. package/dist/resources/extensions/gsd/visualizer-overlay.js +1 -1
  81. package/dist/resources/extensions/gsd/watch/header-renderer.js +3 -1
  82. package/dist/resources/extensions/gsd/worktree-command.js +26 -46
  83. package/dist/resources/extensions/gsd/worktree-manager.js +20 -1
  84. package/dist/resources/extensions/gsd/worktree-resolver.js +4 -13
  85. package/dist/resources/extensions/gsd/worktree-root.js +124 -0
  86. package/dist/resources/extensions/gsd/worktree-session-state.js +33 -0
  87. package/dist/resources/extensions/gsd/worktree.js +4 -115
  88. package/dist/resources/extensions/mcp-client/index.js +6 -3
  89. package/dist/resources/extensions/ollama/index.js +15 -2
  90. package/dist/resources/extensions/ollama/model-capabilities.js +31 -0
  91. package/dist/resources/extensions/ollama/ollama-client.js +40 -4
  92. package/dist/resources/extensions/slash-commands/create-extension.js +36 -22
  93. package/dist/resources/extensions/subagent/index.js +324 -178
  94. package/dist/resources/skills/create-gsd-extension/SKILL.md +9 -5
  95. package/dist/resources/skills/create-gsd-extension/references/custom-commands.md +1 -1
  96. package/dist/resources/skills/create-gsd-extension/references/custom-rendering.md +5 -5
  97. package/dist/resources/skills/create-gsd-extension/references/custom-tools.md +4 -4
  98. package/dist/resources/skills/create-gsd-extension/references/custom-ui.md +6 -6
  99. package/dist/resources/skills/create-gsd-extension/references/events-reference.md +3 -3
  100. package/dist/resources/skills/create-gsd-extension/references/packaging-distribution.md +1 -1
  101. package/dist/resources/skills/create-gsd-extension/references/remote-execution-overrides.md +3 -3
  102. package/dist/resources/skills/create-gsd-extension/workflows/create-extension.md +32 -12
  103. package/dist/rtk-shared.d.ts +3 -0
  104. package/dist/rtk-shared.js +17 -0
  105. package/dist/rtk.d.ts +2 -5
  106. package/dist/rtk.js +3 -20
  107. package/dist/runtime-checks.d.ts +27 -0
  108. package/dist/runtime-checks.js +38 -0
  109. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  110. package/dist/web/standalone/.next/BUILD_ID +1 -1
  111. package/dist/web/standalone/.next/app-path-routes-manifest.json +11 -11
  112. package/dist/web/standalone/.next/build-manifest.json +4 -4
  113. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  114. package/dist/web/standalone/.next/react-loadable-manifest.json +44 -4
  115. package/dist/web/standalone/.next/required-server-files.json +3 -3
  116. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  117. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  118. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  119. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  120. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  121. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  122. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  123. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  124. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  125. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  126. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  127. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  128. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  129. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  130. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  131. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  132. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  133. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  134. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  135. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  136. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  143. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  155. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  175. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  185. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/session/events/route.js +4 -2
  191. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  195. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  197. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  199. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  200. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  201. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  202. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  203. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  204. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  205. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  206. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  207. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  208. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  209. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  210. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  211. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  212. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  213. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  214. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  215. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  216. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  217. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  218. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  219. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  220. package/dist/web/standalone/.next/server/app/index.html +1 -1
  221. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  222. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  223. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  224. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  225. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  226. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  227. package/dist/web/standalone/.next/server/app/page.js +2 -2
  228. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  229. package/dist/web/standalone/.next/server/app-paths-manifest.json +11 -11
  230. package/dist/web/standalone/.next/server/chunks/63.js +3 -3
  231. package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
  232. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  233. package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
  234. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  235. package/dist/web/standalone/.next/server/middleware.js +2 -2
  236. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  237. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  238. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  239. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  240. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  241. package/dist/web/standalone/.next/server/webpack-runtime.js +1 -1
  242. package/dist/web/standalone/.next/static/chunks/2556.0527fea66e123b7f.js +1 -0
  243. package/dist/web/standalone/.next/static/chunks/2824.08296bc2f9654698.js +1 -0
  244. package/dist/web/standalone/.next/static/chunks/3026.3af53b279375f082.js +1 -0
  245. package/dist/web/standalone/.next/static/chunks/315.6f68ae79b67d25cf.js +1 -0
  246. package/dist/web/standalone/.next/static/chunks/3497.4bfc60a3b3dea717.js +1 -0
  247. package/dist/web/standalone/.next/static/chunks/5516.4a07c872b5c3a663.js +1 -0
  248. package/dist/web/standalone/.next/static/chunks/8336.31b019697882acfb.js +10 -0
  249. package/dist/web/standalone/.next/static/chunks/8845.c9702695e8c5a9c5.js +2 -0
  250. package/dist/web/standalone/.next/static/chunks/9058.01ef3a463bda88f1.js +20 -0
  251. package/dist/web/standalone/.next/static/chunks/9441.1081da1125d1764f.js +1 -0
  252. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  253. package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
  254. package/dist/web/standalone/.next/static/chunks/app/page-9bf2e0c50fb2ca05.js +1 -0
  255. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  256. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  257. package/dist/web/standalone/.next/static/chunks/webpack-f9f0dc45e4f3ac10.js +1 -0
  258. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  259. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  260. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  261. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  262. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  263. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  264. package/dist/web/standalone/package.json +2 -1
  265. package/dist/web/standalone/server.js +1 -1
  266. package/dist/worktree-cli.d.ts +1 -0
  267. package/dist/worktree-cli.js +9 -3
  268. package/dist/worktree-status-banner.d.ts +1 -0
  269. package/dist/worktree-status-banner.js +132 -0
  270. package/package.json +1 -3
  271. package/packages/daemon/package.json +2 -2
  272. package/packages/mcp-server/dist/alias-telemetry.d.ts +8 -0
  273. package/packages/mcp-server/dist/alias-telemetry.d.ts.map +1 -0
  274. package/packages/mcp-server/dist/alias-telemetry.js +30 -0
  275. package/packages/mcp-server/dist/alias-telemetry.js.map +1 -0
  276. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  277. package/packages/mcp-server/dist/workflow-tools.js +74 -46
  278. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  279. package/packages/mcp-server/package.json +2 -2
  280. package/packages/mcp-server/src/alias-telemetry.test.ts +78 -0
  281. package/packages/mcp-server/src/alias-telemetry.ts +30 -0
  282. package/packages/mcp-server/src/workflow-tools.test.ts +78 -0
  283. package/packages/mcp-server/src/workflow-tools.ts +93 -58
  284. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  285. package/packages/native/package.json +1 -1
  286. package/packages/native/tsconfig.tsbuildinfo +1 -1
  287. package/packages/pi-agent-core/package.json +1 -1
  288. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  289. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.d.ts +2 -0
  290. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.d.ts.map +1 -0
  291. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.js +231 -0
  292. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.js.map +1 -0
  293. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
  294. package/packages/pi-ai/dist/providers/anthropic-shared.js +48 -19
  295. package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
  296. package/packages/pi-ai/dist/types.d.ts +13 -0
  297. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  298. package/packages/pi-ai/dist/types.js.map +1 -1
  299. package/packages/pi-ai/dist/utils/repair-tool-json.d.ts.map +1 -1
  300. package/packages/pi-ai/dist/utils/repair-tool-json.js +24 -3
  301. package/packages/pi-ai/dist/utils/repair-tool-json.js.map +1 -1
  302. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js +26 -0
  303. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js.map +1 -1
  304. package/packages/pi-ai/package.json +1 -1
  305. package/packages/pi-ai/src/providers/anthropic-shared.cache-breakpoint.test.ts +289 -0
  306. package/packages/pi-ai/src/providers/anthropic-shared.ts +52 -20
  307. package/packages/pi-ai/src/types.ts +13 -0
  308. package/packages/pi-ai/src/utils/repair-tool-json.ts +24 -3
  309. package/packages/pi-ai/src/utils/tests/repair-tool-json.test.ts +32 -0
  310. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  311. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  312. package/packages/pi-coding-agent/dist/core/agent-session.js +6 -0
  313. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  314. package/packages/pi-coding-agent/dist/core/messages.d.ts.map +1 -1
  315. package/packages/pi-coding-agent/dist/core/messages.js +4 -0
  316. package/packages/pi-coding-agent/dist/core/messages.js.map +1 -1
  317. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +19 -2
  318. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
  319. package/packages/pi-coding-agent/dist/core/model-registry.d.ts +10 -0
  320. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  321. package/packages/pi-coding-agent/dist/core/model-registry.js +18 -0
  322. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  323. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +13 -0
  324. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  325. package/packages/pi-coding-agent/dist/core/system-prompt.js +20 -16
  326. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  327. package/packages/pi-coding-agent/dist/core/token-telemetry.d.ts +37 -0
  328. package/packages/pi-coding-agent/dist/core/token-telemetry.d.ts.map +1 -0
  329. package/packages/pi-coding-agent/dist/core/token-telemetry.js +49 -0
  330. package/packages/pi-coding-agent/dist/core/token-telemetry.js.map +1 -0
  331. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.d.ts +2 -0
  332. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.d.ts.map +1 -0
  333. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js +133 -0
  334. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js.map +1 -0
  335. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +1 -1
  336. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  337. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +14 -1
  338. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
  339. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.d.ts +2 -0
  340. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.d.ts.map +1 -0
  341. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.js +78 -0
  342. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.js.map +1 -0
  343. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.d.ts +2 -0
  344. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.d.ts.map +1 -0
  345. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.js +181 -0
  346. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.js.map +1 -0
  347. package/packages/pi-coding-agent/package.json +1 -1
  348. package/packages/pi-coding-agent/src/core/agent-session.ts +7 -0
  349. package/packages/pi-coding-agent/src/core/messages.ts +4 -0
  350. package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +32 -2
  351. package/packages/pi-coding-agent/src/core/model-registry.ts +21 -0
  352. package/packages/pi-coding-agent/src/core/system-prompt.ts +33 -15
  353. package/packages/pi-coding-agent/src/core/token-telemetry.ts +77 -0
  354. package/packages/pi-coding-agent/src/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.ts +212 -0
  355. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +17 -1
  356. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +1 -1
  357. package/packages/pi-coding-agent/src/tests/system-prompt-cache-stability.test.ts +102 -0
  358. package/packages/pi-coding-agent/src/tests/token-telemetry.test.ts +200 -0
  359. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  360. package/packages/pi-tui/dist/__tests__/autocomplete.test.js +17 -3
  361. package/packages/pi-tui/dist/__tests__/autocomplete.test.js.map +1 -1
  362. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.d.ts +2 -0
  363. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.d.ts.map +1 -0
  364. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.js +161 -0
  365. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.js.map +1 -0
  366. package/packages/pi-tui/package.json +1 -1
  367. package/packages/pi-tui/src/__tests__/autocomplete.test.ts +20 -3
  368. package/packages/pi-tui/src/components/__tests__/leak-fixes-runtime.test.ts +219 -0
  369. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  370. package/packages/rpc-client/package.json +1 -1
  371. package/pkg/package.json +1 -1
  372. package/src/resources/extensions/claude-code-cli/readiness.ts +130 -30
  373. package/src/resources/extensions/gsd/auto/loop.ts +24 -2
  374. package/src/resources/extensions/gsd/auto/phases.ts +6 -14
  375. package/src/resources/extensions/gsd/auto/run-unit.ts +3 -1
  376. package/src/resources/extensions/gsd/auto/session.ts +5 -6
  377. package/src/resources/extensions/gsd/auto/types.ts +1 -0
  378. package/src/resources/extensions/gsd/auto-dashboard.ts +3 -2
  379. package/src/resources/extensions/gsd/auto-dispatch.ts +18 -6
  380. package/src/resources/extensions/gsd/auto-prompts.ts +60 -2
  381. package/src/resources/extensions/gsd/auto-recovery.ts +46 -8
  382. package/src/resources/extensions/gsd/auto-runtime-state.ts +51 -0
  383. package/src/resources/extensions/gsd/auto-start.ts +1 -1
  384. package/src/resources/extensions/gsd/auto-tool-tracking.ts +2 -4
  385. package/src/resources/extensions/gsd/auto-worktree.ts +82 -12
  386. package/src/resources/extensions/gsd/auto.ts +14 -4
  387. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +15 -13
  388. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +8 -7
  389. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +2 -2
  390. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +10 -9
  391. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +108 -31
  392. package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +12 -6
  393. package/src/resources/extensions/gsd/bootstrap/subagent-input.ts +20 -0
  394. package/src/resources/extensions/gsd/bootstrap/system-context.ts +39 -8
  395. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +141 -11
  396. package/src/resources/extensions/gsd/commands/catalog.ts +75 -5
  397. package/src/resources/extensions/gsd/commands/handlers/core.ts +22 -1
  398. package/src/resources/extensions/gsd/commands-config.ts +3 -2
  399. package/src/resources/extensions/gsd/commands-extensions.ts +43 -3
  400. package/src/resources/extensions/gsd/commands-handlers.ts +3 -2
  401. package/src/resources/extensions/gsd/commands-mcp-status.ts +3 -1
  402. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +15 -1
  403. package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -1
  404. package/src/resources/extensions/gsd/docs/preferences-reference.md +10 -0
  405. package/src/resources/extensions/gsd/doctor-providers.ts +2 -1
  406. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +39 -1
  407. package/src/resources/extensions/gsd/doctor-types.ts +3 -1
  408. package/src/resources/extensions/gsd/error-classifier.ts +1 -1
  409. package/src/resources/extensions/gsd/forensics.ts +12 -7
  410. package/src/resources/extensions/gsd/git-service.ts +13 -5
  411. package/src/resources/extensions/gsd/gsd-db.ts +12 -2
  412. package/src/resources/extensions/gsd/guided-flow.ts +27 -26
  413. package/src/resources/extensions/gsd/home-dir.ts +19 -0
  414. package/src/resources/extensions/gsd/journal.ts +4 -1
  415. package/src/resources/extensions/gsd/key-manager.ts +2 -1
  416. package/src/resources/extensions/gsd/memory-store.ts +81 -28
  417. package/src/resources/extensions/gsd/migrate/command.ts +3 -2
  418. package/src/resources/extensions/gsd/milestone-id-reservation.ts +47 -0
  419. package/src/resources/extensions/gsd/model-router.ts +172 -9
  420. package/src/resources/extensions/gsd/native-git-bridge.ts +7 -1
  421. package/src/resources/extensions/gsd/preferences-models.ts +101 -15
  422. package/src/resources/extensions/gsd/preferences-types.ts +6 -0
  423. package/src/resources/extensions/gsd/preferences-validation.ts +35 -0
  424. package/src/resources/extensions/gsd/preferences.ts +16 -2
  425. package/src/resources/extensions/gsd/prompt-loader.ts +26 -12
  426. package/src/resources/extensions/gsd/prompts/complete-milestone.md +10 -0
  427. package/src/resources/extensions/gsd/prompts/complete-slice.md +10 -0
  428. package/src/resources/extensions/gsd/prompts/plan-slice.md +10 -0
  429. package/src/resources/extensions/gsd/prompts/refine-slice.md +10 -0
  430. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +9 -3
  431. package/src/resources/extensions/gsd/state.ts +42 -0
  432. package/src/resources/extensions/gsd/templates/PREFERENCES.md +1 -0
  433. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +178 -1
  434. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +58 -0
  435. package/src/resources/extensions/gsd/tests/auto-session-encapsulation.test.ts +24 -5
  436. package/src/resources/extensions/gsd/tests/auto-supervisor.test.mjs +21 -4
  437. package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +1 -1
  438. package/src/resources/extensions/gsd/tests/budget-prediction.test.ts +138 -211
  439. package/src/resources/extensions/gsd/tests/commands-extensions-version-compare.test.ts +58 -0
  440. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +142 -59
  441. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +7 -4
  442. package/src/resources/extensions/gsd/tests/completed-at-reconcile.test.ts +89 -32
  443. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +41 -23
  444. package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +3 -43
  445. package/src/resources/extensions/gsd/tests/debug-logger.test.ts +5 -3
  446. package/src/resources/extensions/gsd/tests/deferred-milestone-dir-4996.test.ts +116 -0
  447. package/src/resources/extensions/gsd/tests/discuss-empty-db-fallback.test.ts +22 -87
  448. package/src/resources/extensions/gsd/tests/discuss-queued-milestones.test.ts +7 -118
  449. package/src/resources/extensions/gsd/tests/discuss-tool-scope-leak.test.ts +18 -60
  450. package/src/resources/extensions/gsd/tests/doctor-orphan-milestone-4996.test.ts +100 -0
  451. package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +14 -76
  452. package/src/resources/extensions/gsd/tests/ensure-preconditions-guard-4996.test.ts +93 -0
  453. package/src/resources/extensions/gsd/tests/false-degraded-mode-warning.test.ts +22 -83
  454. package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +1 -63
  455. package/src/resources/extensions/gsd/tests/find-missing-summaries-closed-runtime.test.ts +47 -0
  456. package/src/resources/extensions/gsd/tests/forensics-stuck-loops.test.ts +26 -1
  457. package/src/resources/extensions/gsd/tests/gitignore-bg-shell-runtime.test.ts +63 -0
  458. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +30 -0
  459. package/src/resources/extensions/gsd/tests/gsd-no-project-error-runtime.test.ts +81 -0
  460. package/src/resources/extensions/gsd/tests/headless-answers.test.ts +14 -4
  461. package/src/resources/extensions/gsd/tests/health-widget.test.ts +22 -12
  462. package/src/resources/extensions/gsd/tests/help-menu-coverage.test.ts +57 -0
  463. package/src/resources/extensions/gsd/tests/home-dir.test.ts +52 -0
  464. package/src/resources/extensions/gsd/tests/import-done-milestones-runtime.test.ts +145 -0
  465. package/src/resources/extensions/gsd/tests/init-prefs-routing.test.ts +64 -1
  466. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +72 -1
  467. package/src/resources/extensions/gsd/tests/integration/token-savings.test.ts +0 -23
  468. package/src/resources/extensions/gsd/tests/memory-store.test.ts +128 -0
  469. package/src/resources/extensions/gsd/tests/memory-tools.test.ts +33 -1
  470. package/src/resources/extensions/gsd/tests/merge-self-branch-guard.test.ts +124 -0
  471. package/src/resources/extensions/gsd/tests/milestone-id-gap-reuse-4996.test.ts +152 -0
  472. package/src/resources/extensions/gsd/tests/milestone-report-path.test.ts +18 -1
  473. package/src/resources/extensions/gsd/tests/model-router.test.ts +169 -8
  474. package/src/resources/extensions/gsd/tests/native-git-infra-errors.test.ts +50 -0
  475. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +8 -0
  476. package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +32 -43
  477. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +4 -10
  478. package/src/resources/extensions/gsd/tests/preferences.test.ts +127 -0
  479. package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +16 -0
  480. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +7 -0
  481. package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +6 -6
  482. package/src/resources/extensions/gsd/tests/register-hooks-compaction-checkpoint.test.ts +93 -0
  483. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +168 -19
  484. package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +7 -1
  485. package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +23 -1
  486. package/src/resources/extensions/gsd/tests/steer-worktree-path.test.ts +17 -1
  487. package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +101 -0
  488. package/src/resources/extensions/gsd/tests/token-profile.test.ts +51 -4
  489. package/src/resources/extensions/gsd/tests/turn-epoch.test.ts +7 -16
  490. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +38 -3
  491. package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +5 -7
  492. package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +15 -1
  493. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +6 -6
  494. package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +34 -33
  495. package/src/resources/extensions/gsd/tests/worktree.test.ts +8 -0
  496. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +131 -1
  497. package/src/resources/extensions/gsd/tools/memory-tools.ts +17 -1
  498. package/src/resources/extensions/gsd/unit-context-manifest.ts +44 -12
  499. package/src/resources/extensions/gsd/visualizer-overlay.ts +1 -1
  500. package/src/resources/extensions/gsd/watch/header-renderer.ts +3 -1
  501. package/src/resources/extensions/gsd/workflow-logger.ts +1 -0
  502. package/src/resources/extensions/gsd/worktree-command.ts +31 -44
  503. package/src/resources/extensions/gsd/worktree-manager.ts +40 -1
  504. package/src/resources/extensions/gsd/worktree-resolver.ts +4 -14
  505. package/src/resources/extensions/gsd/worktree-root.ts +144 -0
  506. package/src/resources/extensions/gsd/worktree-session-state.ts +35 -0
  507. package/src/resources/extensions/gsd/worktree.ts +8 -119
  508. package/src/resources/extensions/mcp-client/index.ts +6 -3
  509. package/src/resources/extensions/mcp-client/tests/global-config.test.ts +91 -0
  510. package/src/resources/extensions/ollama/index.ts +16 -2
  511. package/src/resources/extensions/ollama/model-capabilities.ts +34 -0
  512. package/src/resources/extensions/ollama/ollama-client.ts +41 -4
  513. package/src/resources/extensions/ollama/tests/model-capabilities.test.ts +96 -0
  514. package/src/resources/extensions/ollama/tests/ollama-client-timeout-env.test.ts +147 -0
  515. package/src/resources/extensions/slash-commands/create-extension.ts +38 -24
  516. package/src/resources/extensions/subagent/index.ts +165 -7
  517. package/src/resources/skills/create-gsd-extension/SKILL.md +9 -5
  518. package/src/resources/skills/create-gsd-extension/references/custom-commands.md +1 -1
  519. package/src/resources/skills/create-gsd-extension/references/custom-rendering.md +5 -5
  520. package/src/resources/skills/create-gsd-extension/references/custom-tools.md +4 -4
  521. package/src/resources/skills/create-gsd-extension/references/custom-ui.md +6 -6
  522. package/src/resources/skills/create-gsd-extension/references/events-reference.md +3 -3
  523. package/src/resources/skills/create-gsd-extension/references/packaging-distribution.md +1 -1
  524. package/src/resources/skills/create-gsd-extension/references/remote-execution-overrides.md +3 -3
  525. package/src/resources/skills/create-gsd-extension/templates/extension-skeleton.ts +2 -2
  526. package/src/resources/skills/create-gsd-extension/templates/stateful-tool-skeleton.ts +3 -3
  527. package/src/resources/skills/create-gsd-extension/templates/templates.test.ts +58 -0
  528. package/src/resources/skills/create-gsd-extension/workflows/create-extension.md +32 -12
  529. package/dist/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +0 -601
  530. package/dist/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +0 -651
  531. package/dist/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +0 -91
  532. package/dist/resources/extensions/gsd/tests/auto-supervisor.test.mjs +0 -53
  533. package/dist/resources/extensions/gsd/tests/dist-redirect.mjs +0 -112
  534. package/dist/resources/extensions/gsd/tests/resolve-ts-hooks.mjs +0 -23
  535. package/dist/resources/extensions/gsd/tests/resolve-ts.mjs +0 -5
  536. package/dist/resources/skills/github-workflows/references/gh/tests/__init__.py +0 -0
  537. package/dist/resources/skills/github-workflows/references/gh/tests/test_github_project_setup.py +0 -608
  538. package/dist/web/standalone/.next/static/chunks/2826.e9f5195e91f9cad2.js +0 -11
  539. package/dist/web/standalone/.next/static/chunks/3621.fc7480022c972438.js +0 -20
  540. package/dist/web/standalone/.next/static/chunks/app/page-151349214571e2b6.js +0 -1
  541. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  542. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  543. package/dist/web/standalone/.next/static/chunks/webpack-2e68521d7c82f7c2.js +0 -1
  544. package/src/resources/extensions/gsd/tests/copy-planning-artifacts-samepath.test.ts +0 -22
  545. package/src/resources/extensions/gsd/tests/discuss-slice-structured-questions.test.ts +0 -47
  546. package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +0 -75
  547. /package/dist/web/standalone/.next/static/{C1zT2kEfoLhDdbWPWKrXd → -Ukk6_YxRd4GY4iUOnRUE}/_buildManifest.js +0 -0
  548. /package/dist/web/standalone/.next/static/{C1zT2kEfoLhDdbWPWKrXd → -Ukk6_YxRd4GY4iUOnRUE}/_ssgManifest.js +0 -0
@@ -13,6 +13,7 @@ import {
13
13
  getSlice,
14
14
  updateSliceStatus,
15
15
  getSliceTasks,
16
+ SCHEMA_VERSION,
16
17
  } from '../gsd-db.ts';
17
18
  import { handleCompleteSlice } from '../tools/complete-slice.ts';
18
19
  import type { CompleteSliceParams } from '../types.ts';
@@ -115,19 +116,21 @@ Run the test suite and verify all assertions pass.
115
116
  }
116
117
 
117
118
  // ═══════════════════════════════════════════════════════════════════════════
118
- // complete-slice: Schema v6 migration
119
+ // complete-slice: fresh DB migrates to current schema version
119
120
  // ═══════════════════════════════════════════════════════════════════════════
120
121
 
121
- console.log('\n=== complete-slice: schema v6 migration ===');
122
+ console.log('\n=== complete-slice: fresh DB migrates to current schema version ===');
122
123
  {
123
124
  const dbPath = tempDbPath();
124
125
  openDatabase(dbPath);
125
126
 
126
127
  const adapter = _getAdapter()!;
127
128
 
128
- // Verify schema version is current (v22 quality_gates DDL fix)
129
+ // Pin schema version against the source-of-truth constant so this test
130
+ // survives migration bumps but still catches a "fresh DB was not migrated"
131
+ // regression.
129
132
  const versionRow = adapter.prepare('SELECT MAX(version) as v FROM schema_version').get();
130
- assertEq(versionRow?.['v'], 22, 'schema version should be 22');
133
+ assertEq(versionRow?.['v'], SCHEMA_VERSION, 'fresh DB should be migrated to current SCHEMA_VERSION');
131
134
 
132
135
  // Verify slices table has full_summary_md and full_uat_md columns
133
136
  const cols = adapter.prepare("PRAGMA table_info(slices)").all();
@@ -1,42 +1,99 @@
1
1
  /**
2
- * Regression test for #4129: tasks.completed_at stays NULL when status is
3
- * reconciled to 'complete' via the file-existence path in state.ts.
2
+ * Behavioural regression test for #4129.
4
3
  *
5
- * Root cause: reconcileSliceTasks called
6
- * updateTaskStatus(milestoneId, sliceId, t.id, "complete")
7
- * without a completedAt timestamp, so the column stays NULL.
4
+ * When deriveStateFromDb's reconcileSliceTasks finds a SUMMARY.md on disk
5
+ * for a task whose DB row is still pending, it flips the row to "complete".
6
+ * Before #4129, the call to updateTaskStatus omitted the completedAt
7
+ * timestamp, leaving completed_at NULL forever.
8
8
  *
9
- * Fix: pass new Date().toISOString() as the 5th argument.
9
+ * The fix passes new Date().toISOString() as the 5th argument; this test
10
+ * exercises that path end-to-end and asserts the column is populated.
11
+ *
12
+ * Refs #4829 (rewrite from positional source-grep).
10
13
  */
11
14
 
12
- import { describe, test } from "node:test";
13
- import assert from "node:assert/strict";
14
- import { readFileSync } from "node:fs";
15
- import { join, dirname } from "node:path";
16
- import { fileURLToPath } from "node:url";
17
-
18
- const __dirname = dirname(fileURLToPath(import.meta.url));
19
- const stateSource = readFileSync(join(__dirname, "..", "state.ts"), "utf-8");
20
-
21
- describe("completed-at reconcile (#4129)", () => {
22
- test("reconcileSliceTasks passes a completedAt timestamp when setting status to complete", () => {
23
- // Before the fix, state.ts had:
24
- // updateTaskStatus(milestoneId, sliceId, t.id, "complete")
25
- // which leaves completed_at NULL in the DB.
26
- // After the fix, a timestamp must be passed as the 5th argument.
27
- assert.doesNotMatch(
28
- stateSource,
29
- /updateTaskStatus\(\s*milestoneId\s*,\s*sliceId\s*,\s*t\.id\s*,\s*["']complete["']\s*\)/,
30
- "updateTaskStatus must not be called without a completedAt timestamp when reconciling tasks to 'complete' (#4129)",
31
- );
15
+ import { describe, test, beforeEach, afterEach } from 'node:test';
16
+ import assert from 'node:assert/strict';
17
+ import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from 'node:fs';
18
+ import { join } from 'node:path';
19
+ import { tmpdir } from 'node:os';
20
+
21
+ import { deriveStateFromDb, invalidateStateCache } from '../state.ts';
22
+ import {
23
+ openDatabase,
24
+ closeDatabase,
25
+ insertMilestone,
26
+ insertSlice,
27
+ insertTask,
28
+ getTask,
29
+ } from '../gsd-db.ts';
30
+
31
+ let basePath: string;
32
+
33
+ function setupProject(): void {
34
+ basePath = mkdtempSync(join(tmpdir(), 'gsd-completed-at-'));
35
+ // Project structure with active milestone, one slice, one task whose
36
+ // SUMMARY.md is already on disk — but the DB row is still "pending".
37
+ mkdirSync(join(basePath, '.gsd', 'milestones', 'M001', 'slices', 'S01', 'tasks'), { recursive: true });
38
+
39
+ // CONTEXT + ROADMAP so deriveState identifies M001 as active and S01 as the active slice.
40
+ writeFileSync(
41
+ join(basePath, '.gsd', 'milestones', 'M001', 'M001-CONTEXT.md'),
42
+ '# M001\nActive milestone.\n',
43
+ );
44
+ writeFileSync(
45
+ join(basePath, '.gsd', 'milestones', 'M001', 'M001-ROADMAP.md'),
46
+ `# M001\n\n## Slices\n\n- [ ] **S01: Slice** \`risk:low\` \`depends:[]\`\n - After this: works\n`,
47
+ );
48
+
49
+ // Plan file for the slice so reconcile can populate task list if DB is empty.
50
+ writeFileSync(
51
+ join(basePath, '.gsd', 'milestones', 'M001', 'slices', 'S01', 'S01-PLAN.md'),
52
+ `# S01: Slice\n\n## Tasks\n\n- [ ] **T01: Test task** \`est:30m\`\n - Do: x\n - Verify: y\n`,
53
+ );
54
+
55
+ // The summary file: this is the on-disk evidence that flips the task
56
+ // status to "complete" inside reconcileSliceTasks.
57
+ writeFileSync(
58
+ join(basePath, '.gsd', 'milestones', 'M001', 'slices', 'S01', 'tasks', 'T01-SUMMARY.md'),
59
+ '---\nid: T01\nparent: S01\nmilestone: M001\nblocker_discovered: false\n---\n# T01\n',
60
+ );
61
+ }
62
+
63
+ describe('completed_at reconcile (#4129)', () => {
64
+ beforeEach(() => {
65
+ setupProject();
66
+ openDatabase(join(basePath, '.gsd', 'gsd.db'));
67
+ insertMilestone({ id: 'M001', title: 'M001', status: 'active' });
68
+ insertSlice({ id: 'S01', milestoneId: 'M001', title: 'Slice', status: 'active' });
69
+ // Task is "pending" in DB, but SUMMARY.md exists on disk → reconcile flips it.
70
+ insertTask({ id: 'T01', sliceId: 'S01', milestoneId: 'M001', title: 'Test task', status: 'pending' });
71
+ invalidateStateCache();
72
+ });
73
+
74
+ afterEach(() => {
75
+ closeDatabase();
76
+ try { rmSync(basePath, { recursive: true, force: true }); } catch { /* */ }
32
77
  });
33
78
 
34
- test("reconcileSliceTasks passes new Date().toISOString() as the completedAt argument", () => {
35
- // Positive assertion: the fixed call must include a timestamp.
36
- assert.match(
37
- stateSource,
38
- /updateTaskStatus\(\s*milestoneId\s*,\s*sliceId\s*,\s*t\.id\s*,\s*["']complete["']\s*,\s*new Date\(\)\.toISOString\(\)\s*\)/,
39
- "reconcileSliceTasks must pass new Date().toISOString() as completedAt when setting task status to 'complete' (#4129)",
79
+ test('reconcileSliceTasks sets completed_at when flipping a pending task to complete via SUMMARY.md', async () => {
80
+ const before = getTask('M001', 'S01', 'T01');
81
+ assert.strictEqual(before?.status, 'pending', 'task starts pending');
82
+ assert.strictEqual(before?.completed_at, null, 'task starts with completed_at NULL');
83
+
84
+ // Trigger the reconcile path (state.ts reconcileSliceTasks).
85
+ await deriveStateFromDb(basePath);
86
+
87
+ const after = getTask('M001', 'S01', 'T01');
88
+ assert.strictEqual(after?.status, 'complete', 'task should be flipped to complete');
89
+ assert.ok(
90
+ typeof after?.completed_at === 'string' && after.completed_at.length > 0,
91
+ `completed_at must be populated by reconcileSliceTasks (#4129); got ${JSON.stringify(after?.completed_at)}`,
92
+ );
93
+ // Sanity: timestamp parses as a valid ISO date.
94
+ assert.ok(
95
+ !Number.isNaN(Date.parse(after!.completed_at!)),
96
+ `completed_at should be a valid ISO timestamp, got ${after!.completed_at}`,
40
97
  );
41
98
  });
42
99
  });
@@ -12,7 +12,7 @@ import { mkdtempSync, rmSync, existsSync } from "node:fs";
12
12
  import { join } from "node:path";
13
13
  import { tmpdir } from "node:os";
14
14
 
15
- import { autoLoop, resolveAgentEnd, _resetPendingResolve } from "../auto-loop.js";
15
+ import { autoLoop, resolveAgentEnd, _hasPendingResolveForTest, _resetPendingResolve } from "../auto-loop.js";
16
16
  import type { LoopDeps } from "../auto/loop-deps.js";
17
17
  import type { SessionLockStatus } from "../session-lock.js";
18
18
  import { writeGraph, readGraph, type WorkflowGraph, type GraphStep } from "../graph.ts";
@@ -29,6 +29,17 @@ function makeTmpDir(): string {
29
29
  return dir;
30
30
  }
31
31
 
32
+ async function resolveNextAgentEnd(timeoutMs = 3_000): Promise<void> {
33
+ const deadline = Date.now() + timeoutMs;
34
+ while (!_hasPendingResolveForTest()) {
35
+ if (Date.now() > deadline) {
36
+ throw new Error("Timed out waiting for pending agent_end resolver");
37
+ }
38
+ await new Promise((r) => setTimeout(r, 5));
39
+ }
40
+ resolveAgentEnd({ messages: [{ role: "assistant" }] });
41
+ }
42
+
32
43
  afterEach(() => {
33
44
  _resetPendingResolve();
34
45
  for (const d of tmpDirs) {
@@ -276,19 +287,16 @@ describe("Custom engine loop integration", () => {
276
287
  // We need to resolve resolveAgentEnd for each step.
277
288
 
278
289
  // Step 1: step-a
279
- await new Promise((r) => setTimeout(r, 80));
280
290
  unitCount++;
281
- resolveAgentEnd({ messages: [{ role: "assistant" }] });
291
+ await resolveNextAgentEnd();
282
292
 
283
293
  // Step 2: step-b
284
- await new Promise((r) => setTimeout(r, 80));
285
294
  unitCount++;
286
- resolveAgentEnd({ messages: [{ role: "assistant" }] });
295
+ await resolveNextAgentEnd();
287
296
 
288
297
  // Step 3: step-c
289
- await new Promise((r) => setTimeout(r, 80));
290
298
  unitCount++;
291
- resolveAgentEnd({ messages: [{ role: "assistant" }] });
299
+ await resolveNextAgentEnd();
292
300
 
293
301
  // After step-c completes, engine.reconcile marks it complete, then
294
302
  // next deriveState sees isComplete=true → stopAuto → loop exits
@@ -398,8 +406,7 @@ describe("Custom engine loop integration", () => {
398
406
 
399
407
  const loopPromise = autoLoop(ctx, pi, s, deps);
400
408
 
401
- await new Promise((r) => setTimeout(r, 80));
402
- resolveAgentEnd({ messages: [{ role: "assistant" }] });
409
+ await resolveNextAgentEnd();
403
410
 
404
411
  await loopPromise;
405
412
 
@@ -460,12 +467,10 @@ describe("Custom engine loop integration", () => {
460
467
  const loopPromise = autoLoop(ctx, pi, s, deps);
461
468
 
462
469
  // Resolve step-a
463
- await new Promise((r) => setTimeout(r, 80));
464
- resolveAgentEnd({ messages: [{ role: "assistant" }] });
470
+ await resolveNextAgentEnd();
465
471
 
466
472
  // Resolve step-b
467
- await new Promise((r) => setTimeout(r, 80));
468
- resolveAgentEnd({ messages: [{ role: "assistant" }] });
473
+ await resolveNextAgentEnd();
469
474
 
470
475
  await loopPromise;
471
476
 
@@ -514,7 +519,9 @@ describe("Custom engine loop integration", () => {
514
519
  });
515
520
 
516
521
  const resolver = setInterval(() => {
517
- resolveAgentEnd({ messages: [{ role: "assistant" }] });
522
+ if (_hasPendingResolveForTest()) {
523
+ resolveAgentEnd({ messages: [{ role: "assistant" }] });
524
+ }
518
525
  }, 25);
519
526
  let timeout: NodeJS.Timeout | undefined;
520
527
  try {
@@ -569,7 +576,9 @@ describe("Custom engine loop integration", () => {
569
576
  });
570
577
  const deps1 = makeMockDeps();
571
578
  const resolver1 = setInterval(() => {
572
- resolveAgentEnd({ messages: [{ role: "assistant" }] });
579
+ if (_hasPendingResolveForTest()) {
580
+ resolveAgentEnd({ messages: [{ role: "assistant" }] });
581
+ }
573
582
  if (pi1.calls.length >= 2) {
574
583
  s1.active = false;
575
584
  }
@@ -614,7 +623,9 @@ describe("Custom engine loop integration", () => {
614
623
  },
615
624
  });
616
625
  const resolver2 = setInterval(() => {
617
- resolveAgentEnd({ messages: [{ role: "assistant" }] });
626
+ if (_hasPendingResolveForTest()) {
627
+ resolveAgentEnd({ messages: [{ role: "assistant" }] });
628
+ }
618
629
  }, 25);
619
630
  let timeout2: NodeJS.Timeout | undefined;
620
631
  try {
@@ -640,7 +651,12 @@ describe("Custom engine loop integration", () => {
640
651
  assert.match(stopEntry ?? "", /requested retry 4 times without passing/);
641
652
  });
642
653
 
643
- it("GRAPH.yaml step stays pending when session deactivates before reconcile", async () => {
654
+ it("two-step workflow drives both steps to complete and stops when isComplete fires", async () => {
655
+ // Note (#4831): renamed from "GRAPH.yaml step stays pending when session
656
+ // deactivates before reconcile" — the assertion body never proved the
657
+ // pending-on-deactivate claim and even comments that "the reconcile
658
+ // will still run for step-b". The behaviour this test actually pins is:
659
+ // both steps reconcile complete and stopAuto fires once isComplete.
644
660
  _resetPendingResolve();
645
661
 
646
662
  // Two-step workflow: a → b. We will complete step-a, then force a break
@@ -672,28 +688,30 @@ describe("Custom engine loop integration", () => {
672
688
  const loopPromise = autoLoop(ctx, pi, s, deps);
673
689
 
674
690
  // Resolve step-a successfully
675
- await new Promise((r) => setTimeout(r, 80));
676
- resolveAgentEnd({ messages: [{ role: "assistant" }] });
691
+ await resolveNextAgentEnd();
677
692
 
678
693
  // Step-b enters runUnit — deactivate the session before resolving.
679
694
  // runUnit checks s.active after newSession and returns cancelled if false.
680
695
  // But since newSession resolves synchronously in our mock (before the
681
696
  // active check), the unit still runs. Instead, let's just cancel it.
682
- await new Promise((r) => setTimeout(r, 80));
683
697
  // Resolve as cancelled to simulate a failed session
684
- resolveAgentEnd({ messages: [{ role: "assistant" }] });
698
+ await resolveNextAgentEnd();
685
699
 
686
700
  // The reconcile will still run for step-b in this flow since
687
701
  // runUnitPhase returns "next" (not "break") for completed units.
688
702
  // After both steps complete, the engine detects isComplete and stops.
689
703
  await loopPromise;
690
704
 
691
- // Verify step-a is complete
705
+ // Both steps reconcile complete; the renamed expectation pins that the
706
+ // engine drives the workflow through isComplete rather than leaving any
707
+ // step pending.
692
708
  const finalGraph = readGraph(runDir);
693
709
  const stepA = finalGraph.steps.find(s => s.id === "step-a");
710
+ const stepB = finalGraph.steps.find(s => s.id === "step-b");
694
711
  assert.equal(stepA?.status, "complete", "Step-a should be complete");
712
+ assert.equal(stepB?.status, "complete", "Step-b should be complete");
695
713
 
696
- // Verify the loop stopped appropriately
714
+ // The loop must stop once isComplete fires.
697
715
  assert.ok(
698
716
  deps.callLog.some((e: string) => e.startsWith("stopAuto:")),
699
717
  "stopAuto should have been called",
@@ -16,7 +16,6 @@
16
16
  * retrying can never succeed and causes cost spikes.
17
17
  */
18
18
 
19
- import { readFileSync } from "node:fs";
20
19
  import { join, sep } from "node:path";
21
20
  import { createTestContext } from "./test-helpers.ts";
22
21
 
@@ -89,47 +88,8 @@ assertEq(
89
88
  "Non-worktree path is unchanged",
90
89
  );
91
90
 
92
- // ── Part 2: ensureDbOpen returns structured failure context ──────────────
93
-
94
- console.log("\n=== #2517 Part 2: ensureDbOpen structured diagnostics ===");
95
-
96
- const dynamicToolsSrc = readFileSync(
97
- join(import.meta.dirname, "..", "bootstrap", "dynamic-tools.ts"),
98
- "utf-8",
99
- );
100
-
101
- // ensureDbOpen should surface diagnostic context, not just boolean false
102
- // Check that the catch block logs error details via workflow-logger
103
- assertTrue(
104
- dynamicToolsSrc.includes("ensureDbOpen failed") && dynamicToolsSrc.includes("logWarning"),
105
- "ensureDbOpen catch block surfaces diagnostic information via logWarning instead of bare false (#2517)",
106
- );
107
-
108
- // ── Part 3: post-unit does NOT artifact-retry on db_unavailable ──────────
109
-
110
- console.log("\n=== #2517 Part 3: post-unit db_unavailable is infra-fatal ===");
111
-
112
- const postUnitSrc = readFileSync(
113
- join(import.meta.dirname, "..", "auto-post-unit.ts"),
114
- "utf-8",
115
- );
116
-
117
- // The artifact retry block should check DB availability and skip retry
118
- // when the DB is unavailable (infra failure, not a missing artifact).
119
- assertTrue(
120
- postUnitSrc.includes("db_unavailable") || postUnitSrc.includes("isDbAvailable"),
121
- "post-unit artifact retry path checks DB availability to avoid retry loop (#2517)",
122
- );
123
-
124
- // Verify the retry block is guarded: when !isDbAvailable(), the code must
125
- // NOT return "retry". The pattern should be: if (!verified && !isDbAvailable()) { skip }
126
- // followed by else if (!verified) { ... return "retry" }
127
- const dbUnavailableGuard = postUnitSrc.match(
128
- /!triggerArtifactVerified\s*&&\s*!isDbAvailable\(\)/,
129
- );
130
- assertTrue(
131
- !!dbUnavailableGuard,
132
- "The retry block explicitly guards against !isDbAvailable() before returning 'retry' (#2517)",
133
- );
91
+ // Source-grep checks for ensureDbOpen diagnostics + post-unit retry guard
92
+ // were removed (#4826) — the behavioural retry-loop tests live in
93
+ // auto-post-unit.test.ts and exercise isDbAvailable() directly.
134
94
 
135
95
  report();
@@ -167,9 +167,11 @@ test('auto-prunes old debug logs', () => {
167
167
  enableDebug(tmp);
168
168
 
169
169
  const files = readdirSync(debugDir).filter(f => f.startsWith('debug-') && f.endsWith('.log'));
170
- // Should have at most MAX_DEBUG_LOGS (5) = 5 old + 1 new, but pruned to 5 total
171
- // Actually: prunes to < 5 old, then creates 1 new = at most 5
172
- assert.ok(files.length <= 6, `should have pruned old logs, got ${files.length}`);
170
+ // MAX_DEBUG_LOGS is 5 enableDebug prunes to < 5 old and then creates 1 new,
171
+ // so the directory must hold at most 5 files in total. The previous
172
+ // assertion (<= 6) would have passed even with one stale log left behind
173
+ // (Refs #4831).
174
+ assert.ok(files.length <= 5, `should have pruned old logs to <= 5, got ${files.length}`);
173
175
 
174
176
  disableDebug();
175
177
  });
@@ -0,0 +1,116 @@
1
+ // GSD Extension — Regression test for #4996: deferred milestone dir creation
2
+ // Verifies that showHeadlessMilestoneCreation does not pre-create the milestone
3
+ // directory before the discuss flow runs. The dir should only appear after a
4
+ // writer (saveArtifactToDb / atomicWriteAsync) emits the first artifact.
5
+
6
+ import { describe, it, beforeEach, afterEach } from "node:test";
7
+ import assert from "node:assert/strict";
8
+ import { mkdtempSync, mkdirSync, existsSync, rmSync, readFileSync } from "node:fs";
9
+ import { dirname, join } from "node:path";
10
+ import { tmpdir } from "node:os";
11
+ import { fileURLToPath } from "node:url";
12
+
13
+ import { isReusableGhostMilestone } from "../state.ts";
14
+ import { nextMilestoneIdReserved } from "../milestone-id-reservation.ts";
15
+ import { clearReservedMilestoneIds, findMilestoneIds } from "../milestone-ids.ts";
16
+ import { invalidateAllCaches } from "../cache.ts";
17
+ import { closeDatabase, openDatabase } from "../gsd-db.ts";
18
+
19
+ const __dirname = dirname(fileURLToPath(import.meta.url));
20
+ const GUIDED_FLOW_PATH = join(__dirname, "..", "guided-flow.ts");
21
+
22
+ function getShowHeadlessBody(): string {
23
+ const source = readFileSync(GUIDED_FLOW_PATH, "utf-8");
24
+ const fnStart = source.indexOf("export async function showHeadlessMilestoneCreation");
25
+ assert.ok(fnStart > -1, "showHeadlessMilestoneCreation must exist in guided-flow.ts");
26
+ const nextExport = source.indexOf("\nexport ", fnStart + 1);
27
+ return source.slice(fnStart, nextExport === -1 ? source.length : nextExport);
28
+ }
29
+
30
+ function makeBase(prefix = "gsd-deferred-dir-"): string {
31
+ const base = mkdtempSync(join(tmpdir(), prefix));
32
+ mkdirSync(join(base, ".gsd", "milestones"), { recursive: true });
33
+ return base;
34
+ }
35
+
36
+ describe("showHeadlessMilestoneCreation source guard (#4996)", () => {
37
+ it("does not call mkdirSync in the headless milestone creation path", () => {
38
+ const body = getShowHeadlessBody();
39
+ assert.doesNotMatch(
40
+ body,
41
+ /\bmkdirSync\s*\(/,
42
+ "showHeadlessMilestoneCreation must not pre-create milestone directories",
43
+ );
44
+ });
45
+
46
+ it("does not call mkdir or mkdirp before dispatchWorkflow", () => {
47
+ const body = getShowHeadlessBody();
48
+ const dispatchIdx = body.indexOf("dispatchWorkflow");
49
+ assert.ok(dispatchIdx > -1, "dispatchWorkflow must be present");
50
+
51
+ const beforeDispatch = body.slice(0, dispatchIdx);
52
+ assert.doesNotMatch(
53
+ beforeDispatch,
54
+ /\b(?:mkdir|mkdirp)\s*\(/,
55
+ "showHeadlessMilestoneCreation must defer directory creation until artifact write",
56
+ );
57
+ });
58
+ });
59
+
60
+ describe("deferred milestone dir creation (#4996)", () => {
61
+ let base: string;
62
+
63
+ beforeEach(() => {
64
+ clearReservedMilestoneIds();
65
+ });
66
+
67
+ afterEach(() => {
68
+ try { closeDatabase(); } catch { /* ignore */ }
69
+ try { invalidateAllCaches(); } catch { /* ignore */ }
70
+ try { clearReservedMilestoneIds(); } catch { /* ignore */ }
71
+ try { rmSync(base, { recursive: true, force: true }); } catch { /* ignore */ }
72
+ });
73
+
74
+ it("(a) fresh project: milestones dir has no M001 entry before any discuss flow", () => {
75
+ base = makeBase();
76
+ const nextId = nextMilestoneIdReserved(findMilestoneIds(base), false, base);
77
+ assert.equal(nextId, "M001", "reservation should choose M001 for a fresh project");
78
+
79
+ const ids = findMilestoneIds(base);
80
+ assert.equal(ids.length, 0, "no milestone dirs should exist before any discuss flow");
81
+
82
+ // And specifically M001 should not exist
83
+ const m001Dir = join(base, ".gsd", "milestones", "M001");
84
+ assert.ok(!existsSync(m001Dir), "M001 dir must not exist before the discuss flow runs");
85
+ });
86
+
87
+ it("(b) abandoned discuss flow leaves no orphan: isReusableGhostMilestone returns false for non-existent dir", () => {
88
+ base = makeBase();
89
+ const nextId = nextMilestoneIdReserved(findMilestoneIds(base), false, base);
90
+ assert.equal(nextId, "M001", "reservation should not require a pre-created directory");
91
+
92
+ const m001Dir = join(base, ".gsd", "milestones", "M001");
93
+ assert.ok(!existsSync(m001Dir), "no M001 dir should exist");
94
+ assert.equal(isReusableGhostMilestone(base, "M001"), false, "non-existent milestone should not be reusable");
95
+ // findMilestoneIds only returns dirs that exist
96
+ const ids = findMilestoneIds(base);
97
+ assert.ok(!ids.includes("M001"), "M001 should not appear in findMilestoneIds when no dir exists");
98
+ });
99
+
100
+ it("(c) a stub dir left from a previous bug IS reusable but a newly-generated ID with no dir is not in the ghost list", () => {
101
+ base = makeBase();
102
+ openDatabase(join(base, ".gsd", "gsd.db"));
103
+ // Create a stub to represent a pre-existing phantom
104
+ mkdirSync(join(base, ".gsd", "milestones", "M001", "slices"), { recursive: true });
105
+
106
+ // isReusableGhostMilestone identifies the orphaned stub
107
+ assert.ok(isReusableGhostMilestone(base, "M001"), "pre-existing stub should be identified as reusable ghost");
108
+ const nextId = nextMilestoneIdReserved(findMilestoneIds(base), false, base);
109
+ assert.equal(nextId, "M001", "reservation should reuse the pre-existing ghost");
110
+
111
+ // The new ID (M002, which would be max+1 in this scenario but ghost reuse returns M001)
112
+ // should not have a dir
113
+ const m002Dir = join(base, ".gsd", "milestones", "M002");
114
+ assert.ok(!existsSync(m002Dir), "a freshly-requested ID should have no dir until first artifact write");
115
+ });
116
+ });