gsd-pi 2.78.0 → 2.78.1-dev.8a893322c

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 (559) hide show
  1. package/README.md +60 -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/google-search/index.js +2 -6
  22. package/dist/resources/extensions/gsd/auto/loop.js +23 -0
  23. package/dist/resources/extensions/gsd/auto/phases.js +5 -13
  24. package/dist/resources/extensions/gsd/auto/run-unit.js +3 -1
  25. package/dist/resources/extensions/gsd/auto/session.js +5 -6
  26. package/dist/resources/extensions/gsd/auto-dashboard.js +3 -2
  27. package/dist/resources/extensions/gsd/auto-dispatch.js +18 -6
  28. package/dist/resources/extensions/gsd/auto-prompts.js +63 -2
  29. package/dist/resources/extensions/gsd/auto-recovery.js +43 -4
  30. package/dist/resources/extensions/gsd/auto-runtime-state.js +31 -0
  31. package/dist/resources/extensions/gsd/auto-start.js +1 -1
  32. package/dist/resources/extensions/gsd/auto-tool-tracking.js +2 -2
  33. package/dist/resources/extensions/gsd/auto-worktree.js +60 -13
  34. package/dist/resources/extensions/gsd/auto.js +14 -5
  35. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +14 -2
  36. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +7 -5
  37. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +2 -2
  38. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +5 -4
  39. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +112 -31
  40. package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +11 -6
  41. package/dist/resources/extensions/gsd/bootstrap/subagent-input.js +22 -0
  42. package/dist/resources/extensions/gsd/bootstrap/system-context.js +45 -8
  43. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +121 -3
  44. package/dist/resources/extensions/gsd/commands/catalog.js +76 -5
  45. package/dist/resources/extensions/gsd/commands/handlers/core.js +23 -1
  46. package/dist/resources/extensions/gsd/commands/handlers/ops.js +8 -0
  47. package/dist/resources/extensions/gsd/commands-config.js +3 -2
  48. package/dist/resources/extensions/gsd/commands-extensions.js +46 -3
  49. package/dist/resources/extensions/gsd/commands-handlers.js +3 -2
  50. package/dist/resources/extensions/gsd/commands-mcp-status.js +3 -1
  51. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +10 -1
  52. package/dist/resources/extensions/gsd/commands-worktree.js +309 -0
  53. package/dist/resources/extensions/gsd/dashboard-overlay.js +1 -1
  54. package/dist/resources/extensions/gsd/docs/preferences-reference.md +10 -0
  55. package/dist/resources/extensions/gsd/doctor-providers.js +2 -1
  56. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +39 -1
  57. package/dist/resources/extensions/gsd/error-classifier.js +1 -1
  58. package/dist/resources/extensions/gsd/forensics.js +10 -8
  59. package/dist/resources/extensions/gsd/git-service.js +12 -5
  60. package/dist/resources/extensions/gsd/gsd-db.js +11 -2
  61. package/dist/resources/extensions/gsd/guided-flow.js +25 -24
  62. package/dist/resources/extensions/gsd/home-dir.js +16 -0
  63. package/dist/resources/extensions/gsd/key-manager.js +2 -1
  64. package/dist/resources/extensions/gsd/memory-store.js +66 -31
  65. package/dist/resources/extensions/gsd/migrate/command.js +3 -2
  66. package/dist/resources/extensions/gsd/milestone-id-reservation.js +36 -0
  67. package/dist/resources/extensions/gsd/model-router.js +114 -9
  68. package/dist/resources/extensions/gsd/native-git-bridge.js +7 -1
  69. package/dist/resources/extensions/gsd/preferences-models.js +91 -15
  70. package/dist/resources/extensions/gsd/preferences-types.js +2 -0
  71. package/dist/resources/extensions/gsd/preferences-validation.js +32 -0
  72. package/dist/resources/extensions/gsd/preferences.js +5 -3
  73. package/dist/resources/extensions/gsd/prompt-loader.js +23 -12
  74. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +10 -0
  75. package/dist/resources/extensions/gsd/prompts/complete-slice.md +10 -0
  76. package/dist/resources/extensions/gsd/prompts/plan-slice.md +10 -0
  77. package/dist/resources/extensions/gsd/prompts/refine-slice.md +10 -0
  78. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +9 -3
  79. package/dist/resources/extensions/gsd/state.js +42 -0
  80. package/dist/resources/extensions/gsd/templates/PREFERENCES.md +1 -0
  81. package/dist/resources/extensions/gsd/tools/memory-tools.js +18 -1
  82. package/dist/resources/extensions/gsd/unit-context-manifest.js +29 -4
  83. package/dist/resources/extensions/gsd/visualizer-overlay.js +1 -1
  84. package/dist/resources/extensions/gsd/watch/header-renderer.js +3 -1
  85. package/dist/resources/extensions/gsd/worktree-command.js +26 -46
  86. package/dist/resources/extensions/gsd/worktree-manager.js +20 -1
  87. package/dist/resources/extensions/gsd/worktree-resolver.js +4 -13
  88. package/dist/resources/extensions/gsd/worktree-root.js +124 -0
  89. package/dist/resources/extensions/gsd/worktree-session-state.js +33 -0
  90. package/dist/resources/extensions/gsd/worktree.js +4 -115
  91. package/dist/resources/extensions/mcp-client/index.js +6 -9
  92. package/dist/resources/extensions/ollama/index.js +15 -2
  93. package/dist/resources/extensions/ollama/model-capabilities.js +31 -0
  94. package/dist/resources/extensions/ollama/ollama-client.js +40 -4
  95. package/dist/resources/extensions/slash-commands/create-extension.js +36 -22
  96. package/dist/resources/extensions/subagent/index.js +324 -178
  97. package/dist/resources/skills/create-gsd-extension/SKILL.md +9 -5
  98. package/dist/resources/skills/create-gsd-extension/references/custom-commands.md +1 -1
  99. package/dist/resources/skills/create-gsd-extension/references/custom-rendering.md +5 -5
  100. package/dist/resources/skills/create-gsd-extension/references/custom-tools.md +4 -4
  101. package/dist/resources/skills/create-gsd-extension/references/custom-ui.md +6 -6
  102. package/dist/resources/skills/create-gsd-extension/references/events-reference.md +3 -3
  103. package/dist/resources/skills/create-gsd-extension/references/packaging-distribution.md +1 -1
  104. package/dist/resources/skills/create-gsd-extension/references/remote-execution-overrides.md +3 -3
  105. package/dist/resources/skills/create-gsd-extension/workflows/create-extension.md +32 -12
  106. package/dist/rtk-shared.d.ts +3 -0
  107. package/dist/rtk-shared.js +17 -0
  108. package/dist/rtk.d.ts +2 -5
  109. package/dist/rtk.js +3 -20
  110. package/dist/runtime-checks.d.ts +27 -0
  111. package/dist/runtime-checks.js +38 -0
  112. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  113. package/dist/web/standalone/.next/BUILD_ID +1 -1
  114. package/dist/web/standalone/.next/app-path-routes-manifest.json +15 -15
  115. package/dist/web/standalone/.next/build-manifest.json +4 -4
  116. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  117. package/dist/web/standalone/.next/react-loadable-manifest.json +44 -4
  118. package/dist/web/standalone/.next/required-server-files.json +3 -3
  119. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  120. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  121. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  122. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  123. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  124. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  125. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  126. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  127. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  128. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  129. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  130. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  132. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  133. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  134. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  135. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  136. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  137. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  138. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  139. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  146. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  158. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  178. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  188. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/session/events/route.js +4 -2
  194. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  195. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  197. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  199. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  200. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  201. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  202. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  203. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  204. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  205. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  206. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  207. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  208. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  209. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  210. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  211. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  212. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  213. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  214. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  215. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  216. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  217. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  218. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  219. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  220. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  221. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  222. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  223. package/dist/web/standalone/.next/server/app/index.html +1 -1
  224. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  225. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  226. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  227. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  228. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  229. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  230. package/dist/web/standalone/.next/server/app/page.js +2 -2
  231. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  232. package/dist/web/standalone/.next/server/app-paths-manifest.json +15 -15
  233. package/dist/web/standalone/.next/server/chunks/63.js +3 -3
  234. package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
  235. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  236. package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
  237. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  238. package/dist/web/standalone/.next/server/middleware.js +2 -2
  239. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  240. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  241. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  242. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  243. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  244. package/dist/web/standalone/.next/server/webpack-runtime.js +1 -1
  245. package/dist/web/standalone/.next/static/chunks/2556.0527fea66e123b7f.js +1 -0
  246. package/dist/web/standalone/.next/static/chunks/2824.08296bc2f9654698.js +1 -0
  247. package/dist/web/standalone/.next/static/chunks/3026.3af53b279375f082.js +1 -0
  248. package/dist/web/standalone/.next/static/chunks/315.6f68ae79b67d25cf.js +1 -0
  249. package/dist/web/standalone/.next/static/chunks/3497.4bfc60a3b3dea717.js +1 -0
  250. package/dist/web/standalone/.next/static/chunks/5516.4a07c872b5c3a663.js +1 -0
  251. package/dist/web/standalone/.next/static/chunks/8336.31b019697882acfb.js +10 -0
  252. package/dist/web/standalone/.next/static/chunks/8845.c9702695e8c5a9c5.js +2 -0
  253. package/dist/web/standalone/.next/static/chunks/9058.01ef3a463bda88f1.js +20 -0
  254. package/dist/web/standalone/.next/static/chunks/9441.1081da1125d1764f.js +1 -0
  255. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  256. package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
  257. package/dist/web/standalone/.next/static/chunks/app/page-9bf2e0c50fb2ca05.js +1 -0
  258. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  259. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  260. package/dist/web/standalone/.next/static/chunks/webpack-f9f0dc45e4f3ac10.js +1 -0
  261. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  262. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  263. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  264. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  265. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  266. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  267. package/dist/web/standalone/package.json +2 -1
  268. package/dist/web/standalone/server.js +1 -1
  269. package/dist/welcome-screen.js +27 -1
  270. package/dist/worktree-cli.d.ts +1 -0
  271. package/dist/worktree-cli.js +9 -3
  272. package/dist/worktree-status-banner.d.ts +1 -0
  273. package/dist/worktree-status-banner.js +132 -0
  274. package/package.json +1 -3
  275. package/packages/daemon/package.json +2 -2
  276. package/packages/mcp-server/dist/alias-telemetry.d.ts +8 -0
  277. package/packages/mcp-server/dist/alias-telemetry.d.ts.map +1 -0
  278. package/packages/mcp-server/dist/alias-telemetry.js +30 -0
  279. package/packages/mcp-server/dist/alias-telemetry.js.map +1 -0
  280. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  281. package/packages/mcp-server/dist/workflow-tools.js +74 -46
  282. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  283. package/packages/mcp-server/package.json +2 -2
  284. package/packages/mcp-server/src/alias-telemetry.test.ts +78 -0
  285. package/packages/mcp-server/src/alias-telemetry.ts +30 -0
  286. package/packages/mcp-server/src/workflow-tools.test.ts +78 -0
  287. package/packages/mcp-server/src/workflow-tools.ts +93 -58
  288. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  289. package/packages/native/package.json +1 -1
  290. package/packages/native/tsconfig.tsbuildinfo +1 -1
  291. package/packages/pi-agent-core/package.json +1 -1
  292. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  293. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.d.ts +2 -0
  294. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.d.ts.map +1 -0
  295. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.js +231 -0
  296. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.js.map +1 -0
  297. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
  298. package/packages/pi-ai/dist/providers/anthropic-shared.js +48 -19
  299. package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
  300. package/packages/pi-ai/dist/types.d.ts +13 -0
  301. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  302. package/packages/pi-ai/dist/types.js.map +1 -1
  303. package/packages/pi-ai/dist/utils/repair-tool-json.d.ts.map +1 -1
  304. package/packages/pi-ai/dist/utils/repair-tool-json.js +24 -3
  305. package/packages/pi-ai/dist/utils/repair-tool-json.js.map +1 -1
  306. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js +26 -0
  307. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js.map +1 -1
  308. package/packages/pi-ai/package.json +1 -1
  309. package/packages/pi-ai/src/providers/anthropic-shared.cache-breakpoint.test.ts +289 -0
  310. package/packages/pi-ai/src/providers/anthropic-shared.ts +52 -20
  311. package/packages/pi-ai/src/types.ts +13 -0
  312. package/packages/pi-ai/src/utils/repair-tool-json.ts +24 -3
  313. package/packages/pi-ai/src/utils/tests/repair-tool-json.test.ts +32 -0
  314. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  315. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  316. package/packages/pi-coding-agent/dist/core/agent-session.js +6 -0
  317. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  318. package/packages/pi-coding-agent/dist/core/messages.d.ts.map +1 -1
  319. package/packages/pi-coding-agent/dist/core/messages.js +4 -0
  320. package/packages/pi-coding-agent/dist/core/messages.js.map +1 -1
  321. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +19 -2
  322. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
  323. package/packages/pi-coding-agent/dist/core/model-registry.d.ts +10 -0
  324. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  325. package/packages/pi-coding-agent/dist/core/model-registry.js +18 -0
  326. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  327. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +13 -0
  328. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  329. package/packages/pi-coding-agent/dist/core/system-prompt.js +20 -16
  330. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  331. package/packages/pi-coding-agent/dist/core/token-telemetry.d.ts +37 -0
  332. package/packages/pi-coding-agent/dist/core/token-telemetry.d.ts.map +1 -0
  333. package/packages/pi-coding-agent/dist/core/token-telemetry.js +49 -0
  334. package/packages/pi-coding-agent/dist/core/token-telemetry.js.map +1 -0
  335. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.d.ts +2 -0
  336. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.d.ts.map +1 -0
  337. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js +133 -0
  338. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js.map +1 -0
  339. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +1 -1
  340. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  341. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +14 -1
  342. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
  343. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.d.ts +2 -0
  344. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.d.ts.map +1 -0
  345. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.js +78 -0
  346. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.js.map +1 -0
  347. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.d.ts +2 -0
  348. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.d.ts.map +1 -0
  349. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.js +181 -0
  350. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.js.map +1 -0
  351. package/packages/pi-coding-agent/package.json +1 -1
  352. package/packages/pi-coding-agent/src/core/agent-session.ts +7 -0
  353. package/packages/pi-coding-agent/src/core/messages.ts +4 -0
  354. package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +32 -2
  355. package/packages/pi-coding-agent/src/core/model-registry.ts +21 -0
  356. package/packages/pi-coding-agent/src/core/system-prompt.ts +33 -15
  357. package/packages/pi-coding-agent/src/core/token-telemetry.ts +77 -0
  358. package/packages/pi-coding-agent/src/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.ts +212 -0
  359. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +17 -1
  360. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +1 -1
  361. package/packages/pi-coding-agent/src/tests/system-prompt-cache-stability.test.ts +102 -0
  362. package/packages/pi-coding-agent/src/tests/token-telemetry.test.ts +200 -0
  363. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  364. package/packages/pi-tui/dist/__tests__/autocomplete.test.js +17 -3
  365. package/packages/pi-tui/dist/__tests__/autocomplete.test.js.map +1 -1
  366. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.d.ts +2 -0
  367. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.d.ts.map +1 -0
  368. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.js +161 -0
  369. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.js.map +1 -0
  370. package/packages/pi-tui/package.json +1 -1
  371. package/packages/pi-tui/src/__tests__/autocomplete.test.ts +20 -3
  372. package/packages/pi-tui/src/components/__tests__/leak-fixes-runtime.test.ts +219 -0
  373. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  374. package/packages/rpc-client/package.json +1 -1
  375. package/pkg/package.json +1 -1
  376. package/src/resources/extensions/claude-code-cli/readiness.ts +130 -30
  377. package/src/resources/extensions/google-search/index.ts +2 -9
  378. package/src/resources/extensions/gsd/auto/loop.ts +24 -2
  379. package/src/resources/extensions/gsd/auto/phases.ts +6 -14
  380. package/src/resources/extensions/gsd/auto/run-unit.ts +3 -1
  381. package/src/resources/extensions/gsd/auto/session.ts +5 -6
  382. package/src/resources/extensions/gsd/auto/types.ts +1 -0
  383. package/src/resources/extensions/gsd/auto-dashboard.ts +3 -2
  384. package/src/resources/extensions/gsd/auto-dispatch.ts +18 -6
  385. package/src/resources/extensions/gsd/auto-prompts.ts +60 -2
  386. package/src/resources/extensions/gsd/auto-recovery.ts +46 -8
  387. package/src/resources/extensions/gsd/auto-runtime-state.ts +51 -0
  388. package/src/resources/extensions/gsd/auto-start.ts +1 -1
  389. package/src/resources/extensions/gsd/auto-tool-tracking.ts +2 -4
  390. package/src/resources/extensions/gsd/auto-worktree.ts +82 -12
  391. package/src/resources/extensions/gsd/auto.ts +14 -4
  392. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +15 -13
  393. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +8 -7
  394. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +2 -2
  395. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +10 -9
  396. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +121 -31
  397. package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +12 -6
  398. package/src/resources/extensions/gsd/bootstrap/subagent-input.ts +20 -0
  399. package/src/resources/extensions/gsd/bootstrap/system-context.ts +50 -8
  400. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +141 -11
  401. package/src/resources/extensions/gsd/commands/catalog.ts +82 -5
  402. package/src/resources/extensions/gsd/commands/handlers/core.ts +23 -1
  403. package/src/resources/extensions/gsd/commands/handlers/ops.ts +10 -0
  404. package/src/resources/extensions/gsd/commands-config.ts +3 -2
  405. package/src/resources/extensions/gsd/commands-extensions.ts +43 -3
  406. package/src/resources/extensions/gsd/commands-handlers.ts +3 -2
  407. package/src/resources/extensions/gsd/commands-mcp-status.ts +3 -1
  408. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +15 -1
  409. package/src/resources/extensions/gsd/commands-worktree.ts +383 -0
  410. package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -1
  411. package/src/resources/extensions/gsd/docs/preferences-reference.md +10 -0
  412. package/src/resources/extensions/gsd/doctor-providers.ts +2 -1
  413. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +39 -1
  414. package/src/resources/extensions/gsd/doctor-types.ts +3 -1
  415. package/src/resources/extensions/gsd/error-classifier.ts +1 -1
  416. package/src/resources/extensions/gsd/forensics.ts +12 -7
  417. package/src/resources/extensions/gsd/git-service.ts +13 -5
  418. package/src/resources/extensions/gsd/gsd-db.ts +12 -2
  419. package/src/resources/extensions/gsd/guided-flow.ts +27 -26
  420. package/src/resources/extensions/gsd/home-dir.ts +19 -0
  421. package/src/resources/extensions/gsd/journal.ts +4 -1
  422. package/src/resources/extensions/gsd/key-manager.ts +2 -1
  423. package/src/resources/extensions/gsd/memory-store.ts +81 -28
  424. package/src/resources/extensions/gsd/migrate/command.ts +3 -2
  425. package/src/resources/extensions/gsd/milestone-id-reservation.ts +47 -0
  426. package/src/resources/extensions/gsd/model-router.ts +172 -9
  427. package/src/resources/extensions/gsd/native-git-bridge.ts +7 -1
  428. package/src/resources/extensions/gsd/preferences-models.ts +101 -15
  429. package/src/resources/extensions/gsd/preferences-types.ts +6 -0
  430. package/src/resources/extensions/gsd/preferences-validation.ts +35 -0
  431. package/src/resources/extensions/gsd/preferences.ts +16 -2
  432. package/src/resources/extensions/gsd/prompt-loader.ts +26 -12
  433. package/src/resources/extensions/gsd/prompts/complete-milestone.md +10 -0
  434. package/src/resources/extensions/gsd/prompts/complete-slice.md +10 -0
  435. package/src/resources/extensions/gsd/prompts/plan-slice.md +10 -0
  436. package/src/resources/extensions/gsd/prompts/refine-slice.md +10 -0
  437. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +9 -3
  438. package/src/resources/extensions/gsd/state.ts +42 -0
  439. package/src/resources/extensions/gsd/templates/PREFERENCES.md +1 -0
  440. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +178 -1
  441. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +58 -0
  442. package/src/resources/extensions/gsd/tests/auto-session-encapsulation.test.ts +24 -5
  443. package/src/resources/extensions/gsd/tests/auto-supervisor.test.mjs +21 -4
  444. package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +1 -1
  445. package/src/resources/extensions/gsd/tests/budget-prediction.test.ts +138 -211
  446. package/src/resources/extensions/gsd/tests/bundled-skill-triggers.test.ts +50 -27
  447. package/src/resources/extensions/gsd/tests/commands-extensions-version-compare.test.ts +58 -0
  448. package/src/resources/extensions/gsd/tests/commands-worktree-clean.test.ts +48 -0
  449. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +142 -59
  450. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +7 -4
  451. package/src/resources/extensions/gsd/tests/completed-at-reconcile.test.ts +89 -32
  452. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +41 -23
  453. package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +3 -43
  454. package/src/resources/extensions/gsd/tests/debug-logger.test.ts +5 -3
  455. package/src/resources/extensions/gsd/tests/deferred-milestone-dir-4996.test.ts +116 -0
  456. package/src/resources/extensions/gsd/tests/discuss-empty-db-fallback.test.ts +22 -87
  457. package/src/resources/extensions/gsd/tests/discuss-queued-milestones.test.ts +7 -118
  458. package/src/resources/extensions/gsd/tests/discuss-tool-scope-leak.test.ts +18 -60
  459. package/src/resources/extensions/gsd/tests/doctor-orphan-milestone-4996.test.ts +100 -0
  460. package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +14 -76
  461. package/src/resources/extensions/gsd/tests/ensure-preconditions-guard-4996.test.ts +93 -0
  462. package/src/resources/extensions/gsd/tests/false-degraded-mode-warning.test.ts +22 -83
  463. package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +1 -63
  464. package/src/resources/extensions/gsd/tests/find-missing-summaries-closed-runtime.test.ts +47 -0
  465. package/src/resources/extensions/gsd/tests/forensics-stuck-loops.test.ts +26 -1
  466. package/src/resources/extensions/gsd/tests/gitignore-bg-shell-runtime.test.ts +63 -0
  467. package/src/resources/extensions/gsd/tests/google-search-stub.test.ts +25 -65
  468. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +30 -0
  469. package/src/resources/extensions/gsd/tests/gsd-no-project-error-runtime.test.ts +81 -0
  470. package/src/resources/extensions/gsd/tests/headless-answers.test.ts +14 -4
  471. package/src/resources/extensions/gsd/tests/health-widget.test.ts +22 -12
  472. package/src/resources/extensions/gsd/tests/help-menu-coverage.test.ts +57 -0
  473. package/src/resources/extensions/gsd/tests/home-dir.test.ts +52 -0
  474. package/src/resources/extensions/gsd/tests/import-done-milestones-runtime.test.ts +145 -0
  475. package/src/resources/extensions/gsd/tests/init-prefs-routing.test.ts +64 -1
  476. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +72 -1
  477. package/src/resources/extensions/gsd/tests/integration/token-savings.test.ts +0 -23
  478. package/src/resources/extensions/gsd/tests/memory-store.test.ts +128 -0
  479. package/src/resources/extensions/gsd/tests/memory-tools.test.ts +33 -1
  480. package/src/resources/extensions/gsd/tests/merge-self-branch-guard.test.ts +124 -0
  481. package/src/resources/extensions/gsd/tests/milestone-id-gap-reuse-4996.test.ts +152 -0
  482. package/src/resources/extensions/gsd/tests/milestone-report-path.test.ts +18 -1
  483. package/src/resources/extensions/gsd/tests/model-router.test.ts +169 -8
  484. package/src/resources/extensions/gsd/tests/native-git-infra-errors.test.ts +50 -0
  485. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +8 -0
  486. package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +32 -43
  487. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +4 -10
  488. package/src/resources/extensions/gsd/tests/preferences.test.ts +127 -0
  489. package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +16 -0
  490. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +7 -0
  491. package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +6 -6
  492. package/src/resources/extensions/gsd/tests/register-hooks-compaction-checkpoint.test.ts +93 -0
  493. package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +34 -0
  494. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +168 -19
  495. package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +7 -1
  496. package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +23 -1
  497. package/src/resources/extensions/gsd/tests/steer-worktree-path.test.ts +17 -1
  498. package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +101 -0
  499. package/src/resources/extensions/gsd/tests/token-profile.test.ts +51 -4
  500. package/src/resources/extensions/gsd/tests/turn-epoch.test.ts +7 -16
  501. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +38 -3
  502. package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +5 -7
  503. package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +15 -1
  504. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +6 -6
  505. package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +34 -33
  506. package/src/resources/extensions/gsd/tests/worktree.test.ts +8 -0
  507. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +131 -1
  508. package/src/resources/extensions/gsd/tools/memory-tools.ts +17 -1
  509. package/src/resources/extensions/gsd/unit-context-manifest.ts +44 -12
  510. package/src/resources/extensions/gsd/visualizer-overlay.ts +1 -1
  511. package/src/resources/extensions/gsd/watch/header-renderer.ts +3 -1
  512. package/src/resources/extensions/gsd/workflow-logger.ts +1 -0
  513. package/src/resources/extensions/gsd/worktree-command.ts +31 -44
  514. package/src/resources/extensions/gsd/worktree-manager.ts +40 -1
  515. package/src/resources/extensions/gsd/worktree-resolver.ts +4 -14
  516. package/src/resources/extensions/gsd/worktree-root.ts +144 -0
  517. package/src/resources/extensions/gsd/worktree-session-state.ts +35 -0
  518. package/src/resources/extensions/gsd/worktree.ts +8 -119
  519. package/src/resources/extensions/mcp-client/index.ts +6 -10
  520. package/src/resources/extensions/mcp-client/tests/global-config.test.ts +91 -0
  521. package/src/resources/extensions/ollama/index.ts +16 -2
  522. package/src/resources/extensions/ollama/model-capabilities.ts +34 -0
  523. package/src/resources/extensions/ollama/ollama-client.ts +41 -4
  524. package/src/resources/extensions/ollama/tests/model-capabilities.test.ts +96 -0
  525. package/src/resources/extensions/ollama/tests/ollama-client-timeout-env.test.ts +147 -0
  526. package/src/resources/extensions/slash-commands/create-extension.ts +38 -24
  527. package/src/resources/extensions/subagent/index.ts +165 -7
  528. package/src/resources/skills/create-gsd-extension/SKILL.md +9 -5
  529. package/src/resources/skills/create-gsd-extension/references/custom-commands.md +1 -1
  530. package/src/resources/skills/create-gsd-extension/references/custom-rendering.md +5 -5
  531. package/src/resources/skills/create-gsd-extension/references/custom-tools.md +4 -4
  532. package/src/resources/skills/create-gsd-extension/references/custom-ui.md +6 -6
  533. package/src/resources/skills/create-gsd-extension/references/events-reference.md +3 -3
  534. package/src/resources/skills/create-gsd-extension/references/packaging-distribution.md +1 -1
  535. package/src/resources/skills/create-gsd-extension/references/remote-execution-overrides.md +3 -3
  536. package/src/resources/skills/create-gsd-extension/templates/extension-skeleton.ts +2 -2
  537. package/src/resources/skills/create-gsd-extension/templates/stateful-tool-skeleton.ts +3 -3
  538. package/src/resources/skills/create-gsd-extension/templates/templates.test.ts +58 -0
  539. package/src/resources/skills/create-gsd-extension/workflows/create-extension.md +32 -12
  540. package/dist/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +0 -601
  541. package/dist/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +0 -651
  542. package/dist/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +0 -91
  543. package/dist/resources/extensions/gsd/tests/auto-supervisor.test.mjs +0 -53
  544. package/dist/resources/extensions/gsd/tests/dist-redirect.mjs +0 -112
  545. package/dist/resources/extensions/gsd/tests/resolve-ts-hooks.mjs +0 -23
  546. package/dist/resources/extensions/gsd/tests/resolve-ts.mjs +0 -5
  547. package/dist/resources/skills/github-workflows/references/gh/tests/__init__.py +0 -0
  548. package/dist/resources/skills/github-workflows/references/gh/tests/test_github_project_setup.py +0 -608
  549. package/dist/web/standalone/.next/static/chunks/2826.e9f5195e91f9cad2.js +0 -11
  550. package/dist/web/standalone/.next/static/chunks/3621.fc7480022c972438.js +0 -20
  551. package/dist/web/standalone/.next/static/chunks/app/page-151349214571e2b6.js +0 -1
  552. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  553. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  554. package/dist/web/standalone/.next/static/chunks/webpack-2e68521d7c82f7c2.js +0 -1
  555. package/src/resources/extensions/gsd/tests/copy-planning-artifacts-samepath.test.ts +0 -22
  556. package/src/resources/extensions/gsd/tests/discuss-slice-structured-questions.test.ts +0 -47
  557. package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +0 -75
  558. /package/dist/web/standalone/.next/static/{C1zT2kEfoLhDdbWPWKrXd → QK8fABiGPmonfTgboN0Y9}/_buildManifest.js +0 -0
  559. /package/dist/web/standalone/.next/static/{C1zT2kEfoLhDdbWPWKrXd → QK8fABiGPmonfTgboN0Y9}/_ssgManifest.js +0 -0
@@ -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
+ });
@@ -1,28 +1,22 @@
1
1
  /**
2
- * discuss-empty-db-fallback.test.ts Tests for #2892.
2
+ * Behavioural regression tests for #2892.
3
3
  *
4
- * When the DB is open but empty (e.g., after crash/truncation),
5
- * getMilestoneSlices() returns [] and showDiscuss() incorrectly declares
6
- * "All slices are complete." The fix adds a roadmap fallback: when the DB
7
- * returns zero slices but a ROADMAP file exists, parse slices from the
8
- * roadmap instead of treating zero slices as "all complete."
4
+ * When the DB is open but empty (e.g. after crash/truncation),
5
+ * getMilestoneSlices() returns []. The fix in showDiscuss() falls back to
6
+ * parsing slices from the on-disk ROADMAP file instead of declaring "all
7
+ * slices are complete." These tests pin the parser contract that the
8
+ * fallback depends on: incomplete checkboxes (`[ ]`) yield `done=false`
9
+ * slices and completed checkboxes (`[x]`) yield `done=true`.
10
+ *
11
+ * The earlier source-grep / regex-on-showDiscuss-body tests (audit verdicts
12
+ * SOURCE_GREP / POSITIONAL — see #4826/#4829) were dropped; they pinned a
13
+ * specific surface form rather than behaviour.
9
14
  */
10
15
 
11
16
  import { describe, test } from "node:test";
12
17
  import assert from "node:assert/strict";
13
- import { readFileSync } from "node:fs";
14
- import { fileURLToPath } from "node:url";
15
- import { dirname, join } from "node:path";
16
18
  import { parseRoadmapSlices } from "../roadmap-slices.ts";
17
19
 
18
- // ─── Helpers ─────────────────────────────────────────────────────────────────
19
-
20
- function readGuidedFlowSource(): string {
21
- const thisFile = fileURLToPath(import.meta.url);
22
- const thisDir = dirname(thisFile);
23
- return readFileSync(join(thisDir, "..", "guided-flow.ts"), "utf-8");
24
- }
25
-
26
20
  const SAMPLE_ROADMAP = `# M012 Roadmap
27
21
 
28
22
  ## Slices
@@ -34,80 +28,23 @@ const SAMPLE_ROADMAP = `# M012 Roadmap
34
28
  > After this: dashboard renders
35
29
  `;
36
30
 
37
- // ─── Tests ───────────────────────────────────────────────────────────────────
38
-
39
- describe("discuss-empty-db-fallback (#2892)", () => {
40
-
41
- test("1. parseRoadmapSlices extracts slices from a valid ROADMAP", () => {
31
+ describe("discuss-empty-db-fallback parser contract (#2892)", () => {
32
+ test("parseRoadmapSlices extracts slices from a valid ROADMAP", () => {
42
33
  const slices = parseRoadmapSlices(SAMPLE_ROADMAP);
43
34
  assert.strictEqual(slices.length, 3, "should parse 3 slices from sample roadmap");
44
- assert.strictEqual(slices[0]!.id, "S01");
45
- assert.strictEqual(slices[1]!.id, "S02");
46
- assert.strictEqual(slices[2]!.id, "S03");
47
- // All slices are incomplete ([ ] not [x])
48
- assert.ok(slices.every(s => !s.done), "all slices should be incomplete");
49
- });
50
-
51
- test("2. guided-flow imports parseRoadmapSlices for roadmap fallback", () => {
52
- const source = readGuidedFlowSource();
53
- assert.ok(
54
- source.includes("parseRoadmapSlices"),
55
- "guided-flow must import parseRoadmapSlices to support roadmap fallback when DB is empty",
56
- );
35
+ const ids = slices.map(s => s.id).sort();
36
+ assert.deepStrictEqual(ids, ["S01", "S02", "S03"]);
57
37
  });
58
38
 
59
- test("3. guided-flow has roadmap fallback when normSlices is empty but roadmapContent exists", () => {
60
- const source = readGuidedFlowSource();
61
- // The fix must add a fallback that checks normSlices.length === 0 && roadmapContent
62
- // and repopulates normSlices from the roadmap before the pendingSlices guard.
63
- //
64
- // Pattern: after DB query produces normSlices, if empty + roadmap exists,
65
- // fall back to parseRoadmapSlices(roadmapContent).
66
- const fallbackPattern = /normSlices\.length\s*===\s*0\s*&&\s*roadmapContent/;
39
+ test("incomplete checkboxes yield done=false (so fallback shows them as pending)", () => {
40
+ const slices = parseRoadmapSlices(SAMPLE_ROADMAP);
67
41
  assert.ok(
68
- fallbackPattern.test(source),
69
- "guided-flow must check normSlices.length === 0 && roadmapContent to trigger roadmap fallback",
42
+ slices.every(s => s.done === false),
43
+ "all 3 incomplete roadmap slices must be done=false otherwise the empty-DB fallback would falsely report them complete (#2892)",
70
44
  );
71
45
  });
72
46
 
73
- test("4. guided-flow no longer has unguarded pendingSlices === 0 exit after DB-only query", () => {
74
- const source = readGuidedFlowSource();
75
- // Extract the showDiscuss function body
76
- const fnMatch = source.match(
77
- /async function showDiscuss\s*\([^)]*\)[^{]*\{([\s\S]*?)\nfunction\s/,
78
- );
79
- assert.ok(!!fnMatch, "showDiscuss function body must be found");
80
-
81
- if (fnMatch) {
82
- const body = fnMatch[1]!;
83
- // After the DB query block (isDbAvailable/getMilestoneSlices), there should
84
- // be a roadmap fallback BEFORE the pendingSlices.length === 0 check.
85
- // Find the getMilestoneSlices call and the pendingSlices === 0 check
86
- const dbQueryIdx = body.indexOf("getMilestoneSlices");
87
- const fallbackIdx = body.indexOf("parseRoadmapSlices");
88
- const pendingGuardIdx = body.indexOf('pendingSlices.length === 0');
89
-
90
- assert.ok(dbQueryIdx > 0, "getMilestoneSlices call must exist");
91
- assert.ok(fallbackIdx > 0, "parseRoadmapSlices fallback must exist");
92
- assert.ok(pendingGuardIdx > 0, "pendingSlices.length === 0 guard must exist");
93
- assert.ok(
94
- fallbackIdx > dbQueryIdx && fallbackIdx < pendingGuardIdx,
95
- "parseRoadmapSlices fallback must appear BETWEEN DB query and pendingSlices === 0 guard",
96
- );
97
- }
98
- });
99
-
100
- test("5. roadmap-parsed slices map to NormSlice format with done=false by default", () => {
101
- // When falling back to roadmap, incomplete slices ([ ]) should map to done:false,
102
- // ensuring they appear as pending and are NOT falsely reported as complete.
103
- const slices = parseRoadmapSlices(SAMPLE_ROADMAP);
104
- const normSlices = slices.map(s => ({ id: s.id, done: s.done, title: s.title }));
105
- const pendingSlices = normSlices.filter(s => !s.done);
106
- assert.strictEqual(pendingSlices.length, 3,
107
- "all 3 incomplete roadmap slices should be pending — not falsely treated as complete");
108
- });
109
-
110
- test("6. roadmap with completed slices correctly reports them as done", () => {
47
+ test("completed checkboxes yield done=true; mixed roadmap surfaces only the open slices as pending", () => {
111
48
  const completedRoadmap = `# M012 Roadmap
112
49
 
113
50
  ## Slices
@@ -119,9 +56,7 @@ describe("discuss-empty-db-fallback (#2892)", () => {
119
56
  > After this: dashboard renders
120
57
  `;
121
58
  const slices = parseRoadmapSlices(completedRoadmap);
122
- const normSlices = slices.map(s => ({ id: s.id, done: s.done, title: s.title }));
123
- const pendingSlices = normSlices.filter(s => !s.done);
124
- assert.strictEqual(pendingSlices.length, 1, "only S02 should be pending");
125
- assert.strictEqual(pendingSlices[0]!.id, "S02");
59
+ const pendingIds = slices.filter(s => !s.done).map(s => s.id);
60
+ assert.deepStrictEqual(pendingIds, ["S02"], "only S02 should be reported as pending");
126
61
  });
127
62
  });
@@ -16,11 +16,9 @@
16
16
 
17
17
  import { describe, test, afterEach } from "node:test";
18
18
  import assert from "node:assert/strict";
19
- import { mkdtempSync, mkdirSync, rmSync, writeFileSync, readFileSync } from "node:fs";
19
+ import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
20
20
  import { join } from "node:path";
21
21
  import { tmpdir } from "node:os";
22
- import { fileURLToPath } from "node:url";
23
- import { dirname } from "node:path";
24
22
 
25
23
  import { deriveState } from "../state.ts";
26
24
  import { invalidateAllCaches } from "../cache.ts";
@@ -57,12 +55,6 @@ function writeRoadmap(base: string, mid: string, content: string): void {
57
55
  writeFileSync(join(base, ".gsd", "milestones", mid, `${mid}-ROADMAP.md`), content);
58
56
  }
59
57
 
60
- function readGuidedFlowSource(): string {
61
- const thisFile = fileURLToPath(import.meta.url);
62
- const thisDir = dirname(thisFile);
63
- return readFileSync(join(thisDir, "..", "guided-flow.ts"), "utf-8");
64
- }
65
-
66
58
  // ─── Tests ────────────────────────────────────────────────────────────────────
67
59
 
68
60
  describe("discuss-queued-milestones (#2307)", () => {
@@ -169,113 +161,10 @@ describe("discuss-queued-milestones (#2307)", () => {
169
161
  }
170
162
  });
171
163
 
172
- test("6. guided-flow no longer hard-exits when no active milestone but pending exist", () => {
173
- const source = readGuidedFlowSource();
174
-
175
- // The old guard was a simple early-exit:
176
- // if (!state.activeMilestone) {
177
- // ctx.ui.notify("No active milestone. Run /gsd to create one first.", "warning");
178
- // return;
179
- // }
180
- //
181
- // The new guard should check for pending milestones and route instead.
182
- const oldGuardPattern = /if\s*\(!state\.activeMilestone\)\s*\{\s*ctx\.ui\.notify\("No active milestone/;
183
- assert.ok(
184
- !oldGuardPattern.test(source),
185
- "guided-flow must not unconditionally exit when activeMilestone is null",
186
- );
187
- });
188
-
189
- test("7. showDiscussQueuedMilestone helper exists in guided-flow", () => {
190
- const source = readGuidedFlowSource();
191
- assert.ok(
192
- source.includes("showDiscussQueuedMilestone"),
193
- "guided-flow must export showDiscussQueuedMilestone helper",
194
- );
195
- });
196
-
197
- test("8. dispatchDiscussForMilestone helper exists in guided-flow", () => {
198
- const source = readGuidedFlowSource();
199
- assert.ok(
200
- source.includes("dispatchDiscussForMilestone"),
201
- "guided-flow must export dispatchDiscussForMilestone helper",
202
- );
203
- });
204
-
205
- test("9. dispatchDiscussForMilestone does not set pendingAutoStart", () => {
206
- const source = readGuidedFlowSource();
207
-
208
- // Extract the dispatchDiscussForMilestone function body
209
- const fnMatch = source.match(
210
- /async function dispatchDiscussForMilestone\s*\([^)]*\)[^{]*\{([\s\S]*?)\n\}/,
211
- );
212
- assert.ok(!!fnMatch, "dispatchDiscussForMilestone function body must be present");
213
-
214
- if (fnMatch) {
215
- assert.ok(
216
- !fnMatch[1].includes("pendingAutoStart"),
217
- "dispatchDiscussForMilestone must NOT set pendingAutoStart — discussing a queued milestone must not activate it",
218
- );
219
- }
220
- });
221
-
222
- test("10. slice picker includes queued milestone option when pending milestones exist", () => {
223
- const source = readGuidedFlowSource();
224
- assert.ok(
225
- source.includes("discuss_queued_milestone"),
226
- "slice picker must include a 'discuss_queued_milestone' action id for queued milestones",
227
- );
228
- assert.ok(
229
- source.includes("Discuss a queued milestone"),
230
- "slice picker must label the queued milestone action clearly",
231
- );
232
- });
233
-
234
- test("11. queued milestone picker labels entries with [queued]", () => {
235
- const source = readGuidedFlowSource();
236
- assert.ok(
237
- source.includes("[queued]"),
238
- "queued milestone picker must label entries with [queued] to distinguish from active",
239
- );
240
- });
241
-
242
- // ─── #3150: allDiscussed early-return must not block queued milestone discussion ──
243
-
244
- test("12. allDiscussed path checks for pending milestones before returning (#3150)", () => {
245
- const source = readGuidedFlowSource();
246
-
247
- // Extract the allDiscussed block — the if (allDiscussed) { ... } body
248
- const allDiscussedMatch = source.match(
249
- /const allDiscussed = pendingSlices\.every\([\s\S]*?\n if \(allDiscussed\) \{([\s\S]*?)\n \}/,
250
- );
251
- assert.ok(!!allDiscussedMatch, "allDiscussed guard block must exist in showDiscuss()");
252
-
253
- if (allDiscussedMatch) {
254
- const body = allDiscussedMatch[1];
255
- // The fix must check for pending milestones and route to showDiscussQueuedMilestone
256
- assert.ok(
257
- body.includes("pending") && body.includes("showDiscussQueuedMilestone"),
258
- "allDiscussed block must check for pending milestones and call showDiscussQueuedMilestone before returning (#3150)",
259
- );
260
- }
261
- });
262
-
263
- test("13. pendingSlices.length===0 path checks for pending milestones before returning (#3150)", () => {
264
- const source = readGuidedFlowSource();
265
-
266
- // Find the pendingSlices.length === 0 guard block
267
- const zeroSlicesMatch = source.match(
268
- /if \(pendingSlices\.length === 0\) \{([\s\S]*?)\n \}/,
269
- );
270
- assert.ok(!!zeroSlicesMatch, "pendingSlices.length === 0 guard block must exist in showDiscuss()");
271
-
272
- if (zeroSlicesMatch) {
273
- const body = zeroSlicesMatch[1];
274
- // The fix must check for pending milestones and route to showDiscussQueuedMilestone
275
- assert.ok(
276
- body.includes("pending") && body.includes("showDiscussQueuedMilestone"),
277
- "pendingSlices.length===0 block must check for pending milestones and call showDiscussQueuedMilestone before returning (#3150)",
278
- );
279
- }
280
- });
164
+ // The earlier tests 6-13 source-grepped guided-flow.ts for identifier
165
+ // names (showDiscussQueuedMilestone, dispatchDiscussForMilestone),
166
+ // UI-copy strings ("[queued]", "Discuss a queued milestone"), and
167
+ // regex-on-function-body assertions for the #3150 routing — all
168
+ // structural rather than behavioural (Refs #4826). They were dropped
169
+ // when this file was tightened against handler-level assertions.
281
170
  });
@@ -1,77 +1,35 @@
1
- // GSD-2 — Regression test for #3616: discuss tool scoping must not leak into subsequent sessions
2
- // Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
3
-
4
- /**
5
- * Bug #3616: After a discuss session narrows the active tool set via
6
- * setActiveTools(), the narrowed list persisted into the next auto-mode
7
- * session because newSession() did not restore extension tools when cwd
8
- * was unchanged. This caused gsd_plan_slice and other DB tools to be
9
- * missing from plan-slice subagent sessions.
10
- *
11
- * This test verifies the structural properties that prevent the leak:
12
- * 1. guided-flow.ts narrows tools ONLY for discuss-* unit types
13
- * 2. The narrowed set explicitly excludes gsd_plan_slice (a HEAVY_TOOL)
14
- * 3. agent-session.ts:newSession() has an else-branch that restores
15
- * all extension tools even when cwd hasn't changed
16
- */
1
+ // GSD-2 — Behavioural regression test for #3616.
2
+ //
3
+ // Bug: After a discuss session narrows the active tool set via setActiveTools,
4
+ // the narrowed list persisted into the next auto-mode session because newSession()
5
+ // did not restore extension tools when cwd was unchanged. This caused
6
+ // gsd_plan_slice and other DB tools to be missing from plan-slice subagent
7
+ // sessions.
8
+ //
9
+ // The behavioural invariant we can pin without grepping source: gsd_plan_slice
10
+ // (a heavy planning tool) is NOT inside the discuss allowlist. The remaining
11
+ // guarantees (newSession including all extension tools in both branches) are
12
+ // covered by agent-session.test.ts inside packages/pi-coding-agent.
13
+ //
14
+ // Refs #4826 (rewrite from source-grep on guided-flow.ts / agent-session.ts).
17
15
 
18
16
  import { describe, test } from "node:test";
19
17
  import assert from "node:assert/strict";
20
- import { readFileSync } from "node:fs";
21
- import { join, dirname } from "node:path";
22
- import { fileURLToPath } from "node:url";
23
18
 
24
19
  import { DISCUSS_TOOLS_ALLOWLIST } from "../constants.ts";
25
- import { extractSourceRegion } from "./test-helpers.ts";
26
-
27
- const __dirname = dirname(fileURLToPath(import.meta.url));
28
- const guidedFlowSource = readFileSync(join(__dirname, "..", "guided-flow.ts"), "utf-8");
29
20
 
30
21
  describe("#3616 — discuss tool scoping must not leak across sessions", () => {
31
22
  test("gsd_plan_slice is NOT in DISCUSS_TOOLS_ALLOWLIST", () => {
32
23
  assert.ok(
33
24
  !DISCUSS_TOOLS_ALLOWLIST.includes("gsd_plan_slice"),
34
- "gsd_plan_slice should be excluded from discuss scope (it's a heavy planning tool)",
35
- );
36
- });
37
-
38
- test("tool scoping only activates for discuss-* unit types", () => {
39
- // The guard must be: if (unitType?.startsWith("discuss-"))
40
- assert.ok(
41
- guidedFlowSource.includes('unitType?.startsWith("discuss-")'),
42
- "tool scoping should only trigger for discuss-* unit types",
25
+ `gsd_plan_slice (a heavy planning tool) must be excluded from the discuss scope; allowlist=${JSON.stringify(DISCUSS_TOOLS_ALLOWLIST)}`,
43
26
  );
44
27
  });
45
28
 
46
- test("discuss tool scoping uses setActiveTools (not setTools) for reversibility", () => {
47
- // setActiveTools changes the active subset but doesn't remove tools from
48
- // the registry. newSession()'s _refreshToolRegistry can restore them.
49
- assert.ok(
50
- guidedFlowSource.includes("pi.setActiveTools(scopedTools)"),
51
- "should use pi.setActiveTools to narrow tools (preserving registry)",
52
- );
53
- });
54
-
55
- test("newSession() in agent-session.ts has defense against tool narrowing persistence", () => {
56
- const agentSessionSource = readFileSync(
57
- join(process.cwd(), "packages/pi-coding-agent/src/core/agent-session.ts"),
58
- "utf-8",
59
- );
60
- const newSessionStart = agentSessionSource.indexOf("async newSession(options?:");
61
- assert.ok(newSessionStart >= 0, "should find newSession");
62
- const body = extractSourceRegion(agentSessionSource, "async newSession(options?:");
63
-
64
- // Both branches (cwd-changed and cwd-unchanged) must include extension tools
65
- assert.ok(
66
- body.includes("includeAllExtensionTools: true"),
67
- "newSession() must include all extension tools in both branches",
68
- );
69
-
70
- // Count occurrences — should be at least 2 (one per branch)
71
- const matches = body.match(/includeAllExtensionTools:\s*true/g);
29
+ test("DISCUSS_TOOLS_ALLOWLIST is non-empty (sanity)", () => {
72
30
  assert.ok(
73
- matches && matches.length >= 2,
74
- `expected >=2 includeAllExtensionTools:true in newSession(), got ${matches?.length ?? 0}`,
31
+ DISCUSS_TOOLS_ALLOWLIST.length > 0,
32
+ "discuss scope should include at least one tool — empty allowlist would break /gsd discuss",
75
33
  );
76
34
  });
77
35
  });
@@ -0,0 +1,100 @@
1
+ // GSD Extension — Regression test for #4996: doctor orphan milestone dir check
2
+ // Verifies that checkRuntimeHealth reports orphan_milestone_dir for empty stub
3
+ // dirs with no DB row, does not report populated dirs, and does not report
4
+ // legitimate in-flight worktree-only milestone dirs.
5
+
6
+ import { describe, it, afterEach } from "node:test";
7
+ import assert from "node:assert/strict";
8
+ import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from "node:fs";
9
+ import { join } from "node:path";
10
+ import { tmpdir } from "node:os";
11
+
12
+ import { checkRuntimeHealth } from "../doctor-runtime-checks.ts";
13
+ import {
14
+ openDatabase,
15
+ closeDatabase,
16
+ insertMilestone,
17
+ } from "../gsd-db.ts";
18
+ import { invalidateAllCaches } from "../cache.ts";
19
+ import type { DoctorIssue, DoctorIssueCode } from "../doctor-types.ts";
20
+
21
+ function makeBase(prefix = "gsd-doctor-orphan-"): string {
22
+ const base = mkdtempSync(join(tmpdir(), prefix));
23
+ mkdirSync(join(base, ".gsd", "milestones"), { recursive: true });
24
+ return base;
25
+ }
26
+
27
+ function stubDir(base: string, mid: string): void {
28
+ mkdirSync(join(base, ".gsd", "milestones", mid, "slices"), { recursive: true });
29
+ }
30
+
31
+ function populateDir(base: string, mid: string): void {
32
+ mkdirSync(join(base, ".gsd", "milestones", mid), { recursive: true });
33
+ writeFileSync(join(base, ".gsd", "milestones", mid, `${mid}-CONTEXT.md`), `# ${mid}\n`);
34
+ }
35
+
36
+ describe("gsd_doctor orphan milestone directory check (#4996)", () => {
37
+ let base: string;
38
+
39
+ afterEach(() => {
40
+ try { closeDatabase(); } catch { /* ignore */ }
41
+ try { invalidateAllCaches(); } catch { /* ignore */ }
42
+ try { rmSync(base, { recursive: true, force: true }); } catch { /* ignore */ }
43
+ });
44
+
45
+ it("(a) empty stub dir with no DB row is reported as orphan_milestone_dir", async () => {
46
+ base = makeBase();
47
+ stubDir(base, "M003");
48
+
49
+ const issues: DoctorIssue[] = [];
50
+ const fixes: string[] = [];
51
+ await checkRuntimeHealth(base, issues, fixes, () => false);
52
+
53
+ const orphan = issues.find(i => i.code === "orphan_milestone_dir" && i.unitId === "M003");
54
+ assert.ok(orphan, "should report orphan_milestone_dir for empty stub");
55
+ assert.equal(orphan?.severity, "warning");
56
+ assert.equal(orphan?.fixable, true);
57
+ assert.ok(orphan?.message.includes("M003"), "message should name the milestone");
58
+ });
59
+
60
+ it("(b) populated milestone dir is NOT reported", async () => {
61
+ base = makeBase();
62
+ populateDir(base, "M001");
63
+
64
+ const issues: DoctorIssue[] = [];
65
+ const fixes: string[] = [];
66
+ await checkRuntimeHealth(base, issues, fixes, () => false);
67
+
68
+ const orphan = issues.find(i => i.code === "orphan_milestone_dir" && i.unitId === "M001");
69
+ assert.ok(!orphan, "populated milestone dir must not be reported as orphan");
70
+ });
71
+
72
+ it("(c) worktree-only milestone (no content files, no DB row, but worktree exists) is NOT reported", async () => {
73
+ base = makeBase();
74
+ stubDir(base, "M003");
75
+ // Simulate a legitimate in-flight worktree
76
+ mkdirSync(join(base, ".gsd", "worktrees", "M003"), { recursive: true });
77
+
78
+ const issues: DoctorIssue[] = [];
79
+ const fixes: string[] = [];
80
+ await checkRuntimeHealth(base, issues, fixes, () => false);
81
+
82
+ const orphan = issues.find(i => i.code === "orphan_milestone_dir" && i.unitId === "M003");
83
+ assert.ok(!orphan, "milestone with a worktree must not be reported as orphan");
84
+ });
85
+
86
+ it("(d) queued DB row (in-flight ID) is NOT reported as orphan", async () => {
87
+ base = makeBase();
88
+ stubDir(base, "M003");
89
+ const dbPath = join(base, ".gsd", "gsd.db");
90
+ openDatabase(dbPath);
91
+ insertMilestone({ id: "M003", status: "queued" });
92
+
93
+ const issues: DoctorIssue[] = [];
94
+ const fixes: string[] = [];
95
+ await checkRuntimeHealth(base, issues, fixes, () => false);
96
+
97
+ const orphan = issues.find(i => i.code === "orphan_milestone_dir" && i.unitId === "M003");
98
+ assert.ok(!orphan, "queued DB row must block orphan report (in-flight race protection)");
99
+ });
100
+ });