gsd-pi 2.78.0-dev.aeeb2ca00 → 2.78.1-dev.0fdacd524

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 (471) hide show
  1. package/README.md +8 -7
  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 +77 -38
  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 +90 -46
  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 +26 -12
  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-direct-dispatch.js +55 -21
  28. package/dist/resources/extensions/gsd/auto-dispatch.js +18 -6
  29. package/dist/resources/extensions/gsd/auto-prompts.js +69 -2
  30. package/dist/resources/extensions/gsd/auto-recovery.js +43 -4
  31. package/dist/resources/extensions/gsd/auto-runtime-state.js +31 -0
  32. package/dist/resources/extensions/gsd/auto-start.js +1 -1
  33. package/dist/resources/extensions/gsd/auto-tool-tracking.js +2 -2
  34. package/dist/resources/extensions/gsd/auto-worktree.js +60 -13
  35. package/dist/resources/extensions/gsd/auto.js +39 -14
  36. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +14 -2
  37. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +7 -5
  38. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +2 -2
  39. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +5 -4
  40. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +112 -31
  41. package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +11 -6
  42. package/dist/resources/extensions/gsd/bootstrap/subagent-input.js +22 -0
  43. package/dist/resources/extensions/gsd/bootstrap/system-context.js +45 -8
  44. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +121 -3
  45. package/dist/resources/extensions/gsd/commands/catalog.js +76 -5
  46. package/dist/resources/extensions/gsd/commands/handlers/core.js +23 -1
  47. package/dist/resources/extensions/gsd/commands/handlers/ops.js +8 -0
  48. package/dist/resources/extensions/gsd/commands-config.js +3 -2
  49. package/dist/resources/extensions/gsd/commands-extensions.js +46 -3
  50. package/dist/resources/extensions/gsd/commands-handlers.js +3 -2
  51. package/dist/resources/extensions/gsd/commands-mcp-status.js +3 -1
  52. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +10 -1
  53. package/dist/resources/extensions/gsd/commands-worktree.js +309 -0
  54. package/dist/resources/extensions/gsd/dashboard-overlay.js +1 -1
  55. package/dist/resources/extensions/gsd/docs/preferences-reference.md +10 -0
  56. package/dist/resources/extensions/gsd/doctor-providers.js +2 -1
  57. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +39 -1
  58. package/dist/resources/extensions/gsd/error-classifier.js +1 -1
  59. package/dist/resources/extensions/gsd/forensics.js +10 -8
  60. package/dist/resources/extensions/gsd/git-service.js +12 -5
  61. package/dist/resources/extensions/gsd/gsd-db.js +11 -2
  62. package/dist/resources/extensions/gsd/guided-flow.js +25 -24
  63. package/dist/resources/extensions/gsd/home-dir.js +16 -0
  64. package/dist/resources/extensions/gsd/key-manager.js +2 -1
  65. package/dist/resources/extensions/gsd/memory-store.js +66 -31
  66. package/dist/resources/extensions/gsd/migrate/command.js +3 -2
  67. package/dist/resources/extensions/gsd/milestone-id-reservation.js +36 -0
  68. package/dist/resources/extensions/gsd/model-router.js +114 -9
  69. package/dist/resources/extensions/gsd/native-git-bridge.js +7 -1
  70. package/dist/resources/extensions/gsd/preferences-models.js +91 -15
  71. package/dist/resources/extensions/gsd/preferences-types.js +2 -0
  72. package/dist/resources/extensions/gsd/preferences-validation.js +32 -0
  73. package/dist/resources/extensions/gsd/preferences.js +5 -3
  74. package/dist/resources/extensions/gsd/prompt-loader.js +23 -12
  75. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +10 -0
  76. package/dist/resources/extensions/gsd/prompts/complete-slice.md +10 -0
  77. package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +2 -0
  78. package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +2 -0
  79. package/dist/resources/extensions/gsd/prompts/plan-slice.md +10 -0
  80. package/dist/resources/extensions/gsd/prompts/refine-slice.md +10 -0
  81. package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +2 -0
  82. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +9 -3
  83. package/dist/resources/extensions/gsd/state.js +42 -0
  84. package/dist/resources/extensions/gsd/templates/PREFERENCES.md +1 -0
  85. package/dist/resources/extensions/gsd/tools/memory-tools.js +18 -1
  86. package/dist/resources/extensions/gsd/unit-context-manifest.js +29 -4
  87. package/dist/resources/extensions/gsd/visualizer-overlay.js +1 -1
  88. package/dist/resources/extensions/gsd/watch/header-renderer.js +3 -1
  89. package/dist/resources/extensions/gsd/worktree-command.js +26 -46
  90. package/dist/resources/extensions/gsd/worktree-manager.js +20 -1
  91. package/dist/resources/extensions/gsd/worktree-resolver.js +4 -13
  92. package/dist/resources/extensions/gsd/worktree-root.js +124 -0
  93. package/dist/resources/extensions/gsd/worktree-session-state.js +33 -0
  94. package/dist/resources/extensions/gsd/worktree.js +4 -115
  95. package/dist/resources/extensions/mcp-client/index.js +6 -9
  96. package/dist/resources/extensions/ollama/index.js +15 -2
  97. package/dist/resources/extensions/ollama/model-capabilities.js +31 -0
  98. package/dist/resources/extensions/ollama/ollama-client.js +40 -4
  99. package/dist/resources/extensions/slash-commands/create-extension.js +36 -22
  100. package/dist/resources/extensions/subagent/index.js +324 -178
  101. package/dist/resources/skills/create-gsd-extension/SKILL.md +9 -5
  102. package/dist/resources/skills/create-gsd-extension/references/custom-commands.md +1 -1
  103. package/dist/resources/skills/create-gsd-extension/references/custom-rendering.md +5 -5
  104. package/dist/resources/skills/create-gsd-extension/references/custom-tools.md +4 -4
  105. package/dist/resources/skills/create-gsd-extension/references/custom-ui.md +6 -6
  106. package/dist/resources/skills/create-gsd-extension/references/events-reference.md +3 -3
  107. package/dist/resources/skills/create-gsd-extension/references/packaging-distribution.md +1 -1
  108. package/dist/resources/skills/create-gsd-extension/references/remote-execution-overrides.md +3 -3
  109. package/dist/resources/skills/create-gsd-extension/workflows/create-extension.md +32 -12
  110. package/dist/resources/skills/lint/SKILL.md +4 -0
  111. package/dist/resources/skills/review/SKILL.md +4 -0
  112. package/dist/resources/skills/test/SKILL.md +3 -0
  113. package/dist/rtk-shared.d.ts +3 -0
  114. package/dist/rtk-shared.js +17 -0
  115. package/dist/rtk.d.ts +2 -5
  116. package/dist/rtk.js +3 -20
  117. package/dist/runtime-checks.d.ts +27 -0
  118. package/dist/runtime-checks.js +38 -0
  119. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  120. package/dist/web/standalone/.next/BUILD_ID +1 -1
  121. package/dist/web/standalone/.next/app-path-routes-manifest.json +13 -13
  122. package/dist/web/standalone/.next/build-manifest.json +3 -3
  123. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  124. package/dist/web/standalone/.next/react-loadable-manifest.json +44 -4
  125. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  126. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  127. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  128. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  129. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  130. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  131. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  132. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  133. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  134. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  135. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  136. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  137. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  138. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  139. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  140. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  141. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  142. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  143. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/session/events/route.js +4 -2
  146. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  147. package/dist/web/standalone/.next/server/app/index.html +1 -1
  148. package/dist/web/standalone/.next/server/app/index.rsc +2 -2
  149. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  150. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
  151. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  152. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  153. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  154. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  155. package/dist/web/standalone/.next/server/app-paths-manifest.json +13 -13
  156. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  157. package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
  158. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  159. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  160. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  161. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  162. package/dist/web/standalone/.next/server/webpack-runtime.js +1 -1
  163. package/dist/web/standalone/.next/static/chunks/2556.0527fea66e123b7f.js +1 -0
  164. package/dist/web/standalone/.next/static/chunks/2824.08296bc2f9654698.js +1 -0
  165. package/dist/web/standalone/.next/static/chunks/3026.3af53b279375f082.js +1 -0
  166. package/dist/web/standalone/.next/static/chunks/315.6f68ae79b67d25cf.js +1 -0
  167. package/dist/web/standalone/.next/static/chunks/3497.4bfc60a3b3dea717.js +1 -0
  168. package/dist/web/standalone/.next/static/chunks/5516.4a07c872b5c3a663.js +1 -0
  169. package/dist/web/standalone/.next/static/chunks/8336.31b019697882acfb.js +10 -0
  170. package/dist/web/standalone/.next/static/chunks/8845.c9702695e8c5a9c5.js +2 -0
  171. package/dist/web/standalone/.next/static/chunks/9058.01ef3a463bda88f1.js +20 -0
  172. package/dist/web/standalone/.next/static/chunks/9441.1081da1125d1764f.js +1 -0
  173. package/dist/web/standalone/.next/static/chunks/app/{page-5b113fd32bc2a1c3.js → page-9bf2e0c50fb2ca05.js} +1 -1
  174. package/dist/web/standalone/.next/static/chunks/webpack-f9f0dc45e4f3ac10.js +1 -0
  175. package/dist/web/standalone/package.json +2 -1
  176. package/dist/welcome-screen.js +27 -1
  177. package/dist/worktree-cli.d.ts +1 -0
  178. package/dist/worktree-cli.js +9 -3
  179. package/dist/worktree-status-banner.d.ts +1 -0
  180. package/dist/worktree-status-banner.js +132 -0
  181. package/package.json +1 -3
  182. package/packages/daemon/package.json +2 -2
  183. package/packages/mcp-server/dist/alias-telemetry.d.ts +8 -0
  184. package/packages/mcp-server/dist/alias-telemetry.d.ts.map +1 -0
  185. package/packages/mcp-server/dist/alias-telemetry.js +30 -0
  186. package/packages/mcp-server/dist/alias-telemetry.js.map +1 -0
  187. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  188. package/packages/mcp-server/dist/workflow-tools.js +74 -46
  189. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  190. package/packages/mcp-server/package.json +2 -2
  191. package/packages/mcp-server/src/alias-telemetry.test.ts +78 -0
  192. package/packages/mcp-server/src/alias-telemetry.ts +30 -0
  193. package/packages/mcp-server/src/workflow-tools.test.ts +78 -0
  194. package/packages/mcp-server/src/workflow-tools.ts +93 -58
  195. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  196. package/packages/native/package.json +1 -1
  197. package/packages/native/tsconfig.tsbuildinfo +1 -1
  198. package/packages/pi-agent-core/package.json +1 -1
  199. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  200. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.d.ts +2 -0
  201. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.d.ts.map +1 -0
  202. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.js +231 -0
  203. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.js.map +1 -0
  204. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
  205. package/packages/pi-ai/dist/providers/anthropic-shared.js +48 -19
  206. package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
  207. package/packages/pi-ai/dist/types.d.ts +13 -0
  208. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  209. package/packages/pi-ai/dist/types.js.map +1 -1
  210. package/packages/pi-ai/dist/utils/repair-tool-json.d.ts.map +1 -1
  211. package/packages/pi-ai/dist/utils/repair-tool-json.js +24 -3
  212. package/packages/pi-ai/dist/utils/repair-tool-json.js.map +1 -1
  213. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js +26 -0
  214. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js.map +1 -1
  215. package/packages/pi-ai/package.json +1 -1
  216. package/packages/pi-ai/src/providers/anthropic-shared.cache-breakpoint.test.ts +289 -0
  217. package/packages/pi-ai/src/providers/anthropic-shared.ts +52 -20
  218. package/packages/pi-ai/src/types.ts +13 -0
  219. package/packages/pi-ai/src/utils/repair-tool-json.ts +24 -3
  220. package/packages/pi-ai/src/utils/tests/repair-tool-json.test.ts +32 -0
  221. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  222. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  223. package/packages/pi-coding-agent/dist/core/agent-session.js +6 -0
  224. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  225. package/packages/pi-coding-agent/dist/core/messages.d.ts.map +1 -1
  226. package/packages/pi-coding-agent/dist/core/messages.js +4 -0
  227. package/packages/pi-coding-agent/dist/core/messages.js.map +1 -1
  228. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +19 -2
  229. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
  230. package/packages/pi-coding-agent/dist/core/model-registry.d.ts +10 -0
  231. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  232. package/packages/pi-coding-agent/dist/core/model-registry.js +18 -0
  233. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  234. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +13 -0
  235. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  236. package/packages/pi-coding-agent/dist/core/system-prompt.js +20 -16
  237. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  238. package/packages/pi-coding-agent/dist/core/token-telemetry.d.ts +37 -0
  239. package/packages/pi-coding-agent/dist/core/token-telemetry.d.ts.map +1 -0
  240. package/packages/pi-coding-agent/dist/core/token-telemetry.js +49 -0
  241. package/packages/pi-coding-agent/dist/core/token-telemetry.js.map +1 -0
  242. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.d.ts +2 -0
  243. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.d.ts.map +1 -0
  244. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js +133 -0
  245. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js.map +1 -0
  246. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +1 -1
  247. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  248. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +14 -1
  249. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
  250. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.d.ts +2 -0
  251. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.d.ts.map +1 -0
  252. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.js +78 -0
  253. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.js.map +1 -0
  254. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.d.ts +2 -0
  255. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.d.ts.map +1 -0
  256. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.js +181 -0
  257. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.js.map +1 -0
  258. package/packages/pi-coding-agent/package.json +1 -1
  259. package/packages/pi-coding-agent/src/core/agent-session.ts +7 -0
  260. package/packages/pi-coding-agent/src/core/messages.ts +4 -0
  261. package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +32 -2
  262. package/packages/pi-coding-agent/src/core/model-registry.ts +21 -0
  263. package/packages/pi-coding-agent/src/core/system-prompt.ts +33 -15
  264. package/packages/pi-coding-agent/src/core/token-telemetry.ts +77 -0
  265. package/packages/pi-coding-agent/src/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.ts +212 -0
  266. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +17 -1
  267. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +1 -1
  268. package/packages/pi-coding-agent/src/tests/system-prompt-cache-stability.test.ts +102 -0
  269. package/packages/pi-coding-agent/src/tests/token-telemetry.test.ts +200 -0
  270. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  271. package/packages/pi-tui/dist/__tests__/autocomplete.test.js +17 -3
  272. package/packages/pi-tui/dist/__tests__/autocomplete.test.js.map +1 -1
  273. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.d.ts +2 -0
  274. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.d.ts.map +1 -0
  275. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.js +161 -0
  276. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.js.map +1 -0
  277. package/packages/pi-tui/package.json +1 -1
  278. package/packages/pi-tui/src/__tests__/autocomplete.test.ts +20 -3
  279. package/packages/pi-tui/src/components/__tests__/leak-fixes-runtime.test.ts +219 -0
  280. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  281. package/packages/rpc-client/package.json +1 -1
  282. package/pkg/package.json +1 -1
  283. package/src/resources/extensions/claude-code-cli/readiness.ts +92 -47
  284. package/src/resources/extensions/google-search/index.ts +2 -9
  285. package/src/resources/extensions/gsd/auto/loop.ts +24 -2
  286. package/src/resources/extensions/gsd/auto/phases.ts +6 -14
  287. package/src/resources/extensions/gsd/auto/run-unit.ts +26 -12
  288. package/src/resources/extensions/gsd/auto/session.ts +5 -6
  289. package/src/resources/extensions/gsd/auto/types.ts +1 -0
  290. package/src/resources/extensions/gsd/auto-dashboard.ts +3 -2
  291. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +60 -24
  292. package/src/resources/extensions/gsd/auto-dispatch.ts +18 -6
  293. package/src/resources/extensions/gsd/auto-prompts.ts +66 -2
  294. package/src/resources/extensions/gsd/auto-recovery.ts +46 -8
  295. package/src/resources/extensions/gsd/auto-runtime-state.ts +51 -0
  296. package/src/resources/extensions/gsd/auto-start.ts +1 -1
  297. package/src/resources/extensions/gsd/auto-tool-tracking.ts +2 -4
  298. package/src/resources/extensions/gsd/auto-worktree.ts +82 -12
  299. package/src/resources/extensions/gsd/auto.ts +37 -10
  300. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +15 -13
  301. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +8 -7
  302. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +2 -2
  303. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +10 -9
  304. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +121 -31
  305. package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +12 -6
  306. package/src/resources/extensions/gsd/bootstrap/subagent-input.ts +20 -0
  307. package/src/resources/extensions/gsd/bootstrap/system-context.ts +50 -8
  308. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +141 -11
  309. package/src/resources/extensions/gsd/commands/catalog.ts +82 -5
  310. package/src/resources/extensions/gsd/commands/handlers/core.ts +23 -1
  311. package/src/resources/extensions/gsd/commands/handlers/ops.ts +10 -0
  312. package/src/resources/extensions/gsd/commands-config.ts +3 -2
  313. package/src/resources/extensions/gsd/commands-extensions.ts +43 -3
  314. package/src/resources/extensions/gsd/commands-handlers.ts +3 -2
  315. package/src/resources/extensions/gsd/commands-mcp-status.ts +3 -1
  316. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +15 -1
  317. package/src/resources/extensions/gsd/commands-worktree.ts +383 -0
  318. package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -1
  319. package/src/resources/extensions/gsd/docs/preferences-reference.md +10 -0
  320. package/src/resources/extensions/gsd/doctor-providers.ts +2 -1
  321. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +39 -1
  322. package/src/resources/extensions/gsd/doctor-types.ts +3 -1
  323. package/src/resources/extensions/gsd/error-classifier.ts +1 -1
  324. package/src/resources/extensions/gsd/forensics.ts +12 -7
  325. package/src/resources/extensions/gsd/git-service.ts +13 -5
  326. package/src/resources/extensions/gsd/gsd-db.ts +12 -2
  327. package/src/resources/extensions/gsd/guided-flow.ts +27 -26
  328. package/src/resources/extensions/gsd/home-dir.ts +19 -0
  329. package/src/resources/extensions/gsd/journal.ts +4 -1
  330. package/src/resources/extensions/gsd/key-manager.ts +2 -1
  331. package/src/resources/extensions/gsd/memory-store.ts +81 -28
  332. package/src/resources/extensions/gsd/migrate/command.ts +3 -2
  333. package/src/resources/extensions/gsd/milestone-id-reservation.ts +47 -0
  334. package/src/resources/extensions/gsd/model-router.ts +172 -9
  335. package/src/resources/extensions/gsd/native-git-bridge.ts +7 -1
  336. package/src/resources/extensions/gsd/preferences-models.ts +101 -15
  337. package/src/resources/extensions/gsd/preferences-types.ts +6 -0
  338. package/src/resources/extensions/gsd/preferences-validation.ts +35 -0
  339. package/src/resources/extensions/gsd/preferences.ts +16 -2
  340. package/src/resources/extensions/gsd/prompt-loader.ts +26 -12
  341. package/src/resources/extensions/gsd/prompts/complete-milestone.md +10 -0
  342. package/src/resources/extensions/gsd/prompts/complete-slice.md +10 -0
  343. package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +2 -0
  344. package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +2 -0
  345. package/src/resources/extensions/gsd/prompts/plan-slice.md +10 -0
  346. package/src/resources/extensions/gsd/prompts/refine-slice.md +10 -0
  347. package/src/resources/extensions/gsd/prompts/rewrite-docs.md +2 -0
  348. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +9 -3
  349. package/src/resources/extensions/gsd/state.ts +42 -0
  350. package/src/resources/extensions/gsd/templates/PREFERENCES.md +1 -0
  351. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +179 -1
  352. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +58 -0
  353. package/src/resources/extensions/gsd/tests/auto-session-encapsulation.test.ts +24 -5
  354. package/src/resources/extensions/gsd/tests/auto-supervisor.test.mjs +21 -4
  355. package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +1 -1
  356. package/src/resources/extensions/gsd/tests/budget-prediction.test.ts +138 -211
  357. package/src/resources/extensions/gsd/tests/bundled-skill-triggers.test.ts +50 -27
  358. package/src/resources/extensions/gsd/tests/commands-extensions-version-compare.test.ts +58 -0
  359. package/src/resources/extensions/gsd/tests/commands-worktree-clean.test.ts +48 -0
  360. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +142 -59
  361. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +7 -4
  362. package/src/resources/extensions/gsd/tests/completed-at-reconcile.test.ts +89 -32
  363. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +41 -23
  364. package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +3 -43
  365. package/src/resources/extensions/gsd/tests/debug-logger.test.ts +5 -3
  366. package/src/resources/extensions/gsd/tests/deferred-milestone-dir-4996.test.ts +116 -0
  367. package/src/resources/extensions/gsd/tests/discuss-empty-db-fallback.test.ts +22 -87
  368. package/src/resources/extensions/gsd/tests/discuss-queued-milestones.test.ts +7 -118
  369. package/src/resources/extensions/gsd/tests/discuss-tool-scope-leak.test.ts +18 -60
  370. package/src/resources/extensions/gsd/tests/doctor-orphan-milestone-4996.test.ts +100 -0
  371. package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +14 -76
  372. package/src/resources/extensions/gsd/tests/ensure-preconditions-guard-4996.test.ts +93 -0
  373. package/src/resources/extensions/gsd/tests/false-degraded-mode-warning.test.ts +22 -83
  374. package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +1 -63
  375. package/src/resources/extensions/gsd/tests/find-missing-summaries-closed-runtime.test.ts +47 -0
  376. package/src/resources/extensions/gsd/tests/forensics-stuck-loops.test.ts +26 -1
  377. package/src/resources/extensions/gsd/tests/gitignore-bg-shell-runtime.test.ts +63 -0
  378. package/src/resources/extensions/gsd/tests/google-search-stub.test.ts +25 -65
  379. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +30 -0
  380. package/src/resources/extensions/gsd/tests/gsd-no-project-error-runtime.test.ts +81 -0
  381. package/src/resources/extensions/gsd/tests/headless-answers.test.ts +14 -4
  382. package/src/resources/extensions/gsd/tests/health-widget.test.ts +22 -12
  383. package/src/resources/extensions/gsd/tests/help-menu-coverage.test.ts +57 -0
  384. package/src/resources/extensions/gsd/tests/home-dir.test.ts +52 -0
  385. package/src/resources/extensions/gsd/tests/import-done-milestones-runtime.test.ts +145 -0
  386. package/src/resources/extensions/gsd/tests/init-prefs-routing.test.ts +64 -1
  387. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +72 -1
  388. package/src/resources/extensions/gsd/tests/integration/token-savings.test.ts +0 -23
  389. package/src/resources/extensions/gsd/tests/memory-store.test.ts +128 -0
  390. package/src/resources/extensions/gsd/tests/memory-tools.test.ts +33 -1
  391. package/src/resources/extensions/gsd/tests/merge-self-branch-guard.test.ts +124 -0
  392. package/src/resources/extensions/gsd/tests/milestone-id-gap-reuse-4996.test.ts +152 -0
  393. package/src/resources/extensions/gsd/tests/milestone-report-path.test.ts +18 -1
  394. package/src/resources/extensions/gsd/tests/model-router.test.ts +169 -8
  395. package/src/resources/extensions/gsd/tests/native-git-infra-errors.test.ts +50 -0
  396. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +8 -0
  397. package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +32 -43
  398. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +4 -10
  399. package/src/resources/extensions/gsd/tests/preferences.test.ts +127 -0
  400. package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +16 -0
  401. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +7 -0
  402. package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +6 -6
  403. package/src/resources/extensions/gsd/tests/register-hooks-compaction-checkpoint.test.ts +93 -0
  404. package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +34 -0
  405. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +168 -19
  406. package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +7 -1
  407. package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +23 -1
  408. package/src/resources/extensions/gsd/tests/steer-worktree-path.test.ts +17 -1
  409. package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +101 -0
  410. package/src/resources/extensions/gsd/tests/token-profile.test.ts +51 -4
  411. package/src/resources/extensions/gsd/tests/turn-epoch.test.ts +7 -16
  412. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +38 -3
  413. package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +5 -7
  414. package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +15 -1
  415. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +6 -6
  416. package/src/resources/extensions/gsd/tests/worktree-path-injection.test.ts +235 -0
  417. package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +34 -33
  418. package/src/resources/extensions/gsd/tests/worktree.test.ts +8 -0
  419. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +131 -1
  420. package/src/resources/extensions/gsd/tools/memory-tools.ts +17 -1
  421. package/src/resources/extensions/gsd/unit-context-manifest.ts +44 -12
  422. package/src/resources/extensions/gsd/visualizer-overlay.ts +1 -1
  423. package/src/resources/extensions/gsd/watch/header-renderer.ts +3 -1
  424. package/src/resources/extensions/gsd/workflow-logger.ts +1 -0
  425. package/src/resources/extensions/gsd/worktree-command.ts +31 -44
  426. package/src/resources/extensions/gsd/worktree-manager.ts +40 -1
  427. package/src/resources/extensions/gsd/worktree-resolver.ts +4 -14
  428. package/src/resources/extensions/gsd/worktree-root.ts +144 -0
  429. package/src/resources/extensions/gsd/worktree-session-state.ts +35 -0
  430. package/src/resources/extensions/gsd/worktree.ts +8 -119
  431. package/src/resources/extensions/mcp-client/index.ts +6 -10
  432. package/src/resources/extensions/mcp-client/tests/global-config.test.ts +91 -0
  433. package/src/resources/extensions/ollama/index.ts +16 -2
  434. package/src/resources/extensions/ollama/model-capabilities.ts +34 -0
  435. package/src/resources/extensions/ollama/ollama-client.ts +41 -4
  436. package/src/resources/extensions/ollama/tests/model-capabilities.test.ts +96 -0
  437. package/src/resources/extensions/ollama/tests/ollama-client-timeout-env.test.ts +147 -0
  438. package/src/resources/extensions/slash-commands/create-extension.ts +38 -24
  439. package/src/resources/extensions/subagent/index.ts +165 -7
  440. package/src/resources/skills/create-gsd-extension/SKILL.md +9 -5
  441. package/src/resources/skills/create-gsd-extension/references/custom-commands.md +1 -1
  442. package/src/resources/skills/create-gsd-extension/references/custom-rendering.md +5 -5
  443. package/src/resources/skills/create-gsd-extension/references/custom-tools.md +4 -4
  444. package/src/resources/skills/create-gsd-extension/references/custom-ui.md +6 -6
  445. package/src/resources/skills/create-gsd-extension/references/events-reference.md +3 -3
  446. package/src/resources/skills/create-gsd-extension/references/packaging-distribution.md +1 -1
  447. package/src/resources/skills/create-gsd-extension/references/remote-execution-overrides.md +3 -3
  448. package/src/resources/skills/create-gsd-extension/templates/extension-skeleton.ts +2 -2
  449. package/src/resources/skills/create-gsd-extension/templates/stateful-tool-skeleton.ts +3 -3
  450. package/src/resources/skills/create-gsd-extension/templates/templates.test.ts +58 -0
  451. package/src/resources/skills/create-gsd-extension/workflows/create-extension.md +32 -12
  452. package/src/resources/skills/lint/SKILL.md +4 -0
  453. package/src/resources/skills/review/SKILL.md +4 -0
  454. package/src/resources/skills/test/SKILL.md +3 -0
  455. package/dist/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +0 -601
  456. package/dist/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +0 -651
  457. package/dist/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +0 -91
  458. package/dist/resources/extensions/gsd/tests/auto-supervisor.test.mjs +0 -53
  459. package/dist/resources/extensions/gsd/tests/dist-redirect.mjs +0 -112
  460. package/dist/resources/extensions/gsd/tests/resolve-ts-hooks.mjs +0 -23
  461. package/dist/resources/extensions/gsd/tests/resolve-ts.mjs +0 -5
  462. package/dist/resources/skills/github-workflows/references/gh/tests/__init__.py +0 -0
  463. package/dist/resources/skills/github-workflows/references/gh/tests/test_github_project_setup.py +0 -608
  464. package/dist/web/standalone/.next/static/chunks/2826.e9f5195e91f9cad2.js +0 -11
  465. package/dist/web/standalone/.next/static/chunks/3621.fc7480022c972438.js +0 -20
  466. package/dist/web/standalone/.next/static/chunks/webpack-2e68521d7c82f7c2.js +0 -1
  467. package/src/resources/extensions/gsd/tests/copy-planning-artifacts-samepath.test.ts +0 -22
  468. package/src/resources/extensions/gsd/tests/discuss-slice-structured-questions.test.ts +0 -47
  469. package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +0 -75
  470. /package/dist/web/standalone/.next/static/{cAJH99yNS1UPbeSEiNRrV → 4iu6IYeYfxOq8OidlDqp6}/_buildManifest.js +0 -0
  471. /package/dist/web/standalone/.next/static/{cAJH99yNS1UPbeSEiNRrV → 4iu6IYeYfxOq8OidlDqp6}/_ssgManifest.js +0 -0
@@ -10,7 +10,8 @@ import { existsSync, readFileSync, writeFileSync } from "node:fs";
10
10
  import { homedir } from "node:os";
11
11
  import { join } from "node:path";
12
12
  import type { DynamicRoutingConfig } from "./model-router.js";
13
- import { defaultRoutingConfig } from "./model-router.js";
13
+ import { canonicalModelForTier, defaultRoutingConfig, resolveModelForTier } from "./model-router.js";
14
+ import type { ComplexityTier } from "./complexity-classifier.js";
14
15
  import type { TokenProfile, InlineLevel } from "./types.js";
15
16
 
16
17
  import type {
@@ -43,7 +44,7 @@ export function resolveModelForUnit(unitType: string): string | undefined {
43
44
  * - Extended: `planning: { model: claude-opus-4-6, fallbacks: [glm-5, minimax-m2.5] }`
44
45
  */
45
46
  export function resolveModelWithFallbacksForUnit(unitType: string): ResolvedModelConfig | undefined {
46
- const prefs = loadEffectiveGSDPreferences();
47
+ const prefs = loadEffectiveGSDPreferences(undefined, { availableModelIds: [] });
47
48
  if (!prefs?.preferences.models) return undefined;
48
49
  const m = prefs.preferences.models as GSDModelConfigV2;
49
50
 
@@ -132,7 +133,7 @@ export function resolveModelWithFallbacksForUnit(unitType: string): ResolvedMode
132
133
  export function resolveDefaultSessionModel(
133
134
  sessionProvider?: string,
134
135
  ): { provider: string; id: string } | undefined {
135
- const prefs = loadEffectiveGSDPreferences();
136
+ const prefs = loadEffectiveGSDPreferences(undefined, { availableModelIds: [] });
136
137
  if (!prefs?.preferences.models) return undefined;
137
138
 
138
139
  const m = prefs.preferences.models as GSDModelConfigV2;
@@ -358,22 +359,86 @@ export function resolveAutoSupervisorConfig(): AutoSupervisorConfig {
358
359
 
359
360
  const VALID_TOKEN_PROFILES = new Set<TokenProfile>(["budget", "balanced", "quality", "burn-max"]);
360
361
 
362
+ /**
363
+ * Per-phase tier intentions for each token profile.
364
+ * Profiles express capability tiers, not model IDs. Concrete model
365
+ * resolution happens at runtime via resolveModelForTier() which is
366
+ * provider-agnostic — it picks the best available model at each tier.
367
+ */
368
+ const PROFILE_TIER_MAP: Record<TokenProfile, Record<string, ComplexityTier>> = {
369
+ budget: {
370
+ planning: "standard",
371
+ research: "light",
372
+ execution: "standard",
373
+ execution_simple: "light",
374
+ completion: "light",
375
+ subagent: "light",
376
+ },
377
+ balanced: {
378
+ planning: "standard",
379
+ research: "standard",
380
+ execution: "standard",
381
+ execution_simple: "light",
382
+ completion: "light",
383
+ subagent: "light",
384
+ },
385
+ quality: {
386
+ planning: "heavy",
387
+ research: "standard",
388
+ execution: "standard",
389
+ execution_simple: "light",
390
+ completion: "light",
391
+ subagent: "standard",
392
+ },
393
+ // burn-max intentionally omits a tier map: it never writes model defaults
394
+ // (it preserves the user's explicit model selection), so resolveProfileDefaults
395
+ // skips model resolution for this profile.
396
+ "burn-max": {},
397
+ };
398
+
361
399
  /**
362
400
  * Resolve profile defaults for a given token profile tier.
363
401
  * Returns a partial GSDPreferences that is used as the base layer --
364
402
  * explicit user preferences always override these defaults.
403
+ *
404
+ * Model IDs are resolved from capability tiers, not hardcoded to any
405
+ * provider. When available models are known (runtime), the resolver picks
406
+ * the best match across all configured providers. When not known (e.g.,
407
+ * early startup), falls back to canonical Anthropic model IDs.
408
+ *
409
+ * @param profile The token profile to resolve
410
+ * @param availableModelIds Optional list of available model IDs for cross-provider resolution.
411
+ * Undefined means the registry is unavailable.
412
+ * @param routingConfig Optional routing config for tier model pins.
365
413
  */
366
- export function resolveProfileDefaults(profile: TokenProfile): Partial<GSDPreferences> {
414
+ export function resolveProfileDefaults(
415
+ profile: TokenProfile,
416
+ availableModelIds?: string[],
417
+ routingConfig: DynamicRoutingConfig = defaultRoutingConfig(),
418
+ ): Partial<GSDPreferences> {
419
+ // burn-max never writes model defaults — preserve user-selected models.
420
+ // For the other three profiles, derive concrete model IDs from the tier map
421
+ // against the available-model list when the registry is provided. If callers
422
+ // omit the registry entirely, use canonical fallbacks explicitly.
423
+ const tierMap = PROFILE_TIER_MAP[profile];
424
+ const resolveTierModel = (tier: ComplexityTier): string => Array.isArray(availableModelIds)
425
+ ? resolveModelForTier(tier, availableModelIds, routingConfig)
426
+ : canonicalModelForTier(tier);
427
+ const models: GSDModelConfigV2 | undefined = profile === "burn-max"
428
+ ? undefined
429
+ : {
430
+ planning: resolveTierModel(tierMap.planning),
431
+ research: resolveTierModel(tierMap.research),
432
+ execution: resolveTierModel(tierMap.execution),
433
+ execution_simple: resolveTierModel(tierMap.execution_simple),
434
+ completion: resolveTierModel(tierMap.completion),
435
+ subagent: resolveTierModel(tierMap.subagent),
436
+ };
437
+
367
438
  switch (profile) {
368
439
  case "budget":
369
440
  return {
370
- models: {
371
- planning: "claude-sonnet-4-5-20250514",
372
- execution: "claude-sonnet-4-5-20250514",
373
- execution_simple: "claude-haiku-4-5-20250414",
374
- completion: "claude-haiku-4-5-20250414",
375
- subagent: "claude-haiku-4-5-20250414",
376
- },
441
+ models,
377
442
  phases: {
378
443
  skip_research: true,
379
444
  skip_reassess: true,
@@ -383,9 +448,7 @@ export function resolveProfileDefaults(profile: TokenProfile): Partial<GSDPrefer
383
448
  };
384
449
  case "balanced":
385
450
  return {
386
- models: {
387
- subagent: "claude-sonnet-4-5-20250514",
388
- },
451
+ models,
389
452
  phases: {
390
453
  skip_research: true,
391
454
  skip_reassess: true,
@@ -394,7 +457,7 @@ export function resolveProfileDefaults(profile: TokenProfile): Partial<GSDPrefer
394
457
  };
395
458
  case "quality":
396
459
  return {
397
- models: {},
460
+ models,
398
461
  phases: {
399
462
  skip_research: true,
400
463
  skip_slice_research: true,
@@ -420,6 +483,14 @@ export function resolveProfileDefaults(profile: TokenProfile): Partial<GSDPrefer
420
483
  }
421
484
  }
422
485
 
486
+ /**
487
+ * Get the tier intentions for a profile without resolving to model IDs.
488
+ * Useful for display, debugging, and testing.
489
+ */
490
+ export function getProfileTierMap(profile: TokenProfile): Record<string, ComplexityTier> {
491
+ return { ...PROFILE_TIER_MAP[profile] };
492
+ }
493
+
423
494
  /**
424
495
  * Resolve the effective token profile from preferences.
425
496
  * Returns "balanced" when no profile is set (D046).
@@ -465,3 +536,18 @@ export function resolveSearchProviderFromPreferences(): GSDPreferences["search_p
465
536
  const prefs = loadEffectiveGSDPreferences();
466
537
  return prefs?.preferences.search_provider;
467
538
  }
539
+
540
+ /**
541
+ * Resolve provider IDs excluded from model selection/routing.
542
+ * Returns a normalized, de-duplicated list.
543
+ */
544
+ export function resolveDisabledModelProvidersFromPreferences(): string[] {
545
+ const prefs = loadEffectiveGSDPreferences();
546
+ const raw = prefs?.preferences.disabled_model_providers;
547
+ if (!Array.isArray(raw)) return [];
548
+ return Array.from(new Set(
549
+ raw
550
+ .map((provider) => provider.trim())
551
+ .filter((provider) => provider.length > 0),
552
+ ));
553
+ }
@@ -114,6 +114,7 @@ export const KNOWN_PREFERENCE_KEYS = new Set<string>([
114
114
  "post_unit_hooks",
115
115
  "pre_dispatch_hooks",
116
116
  "dynamic_routing",
117
+ "disabled_model_providers",
117
118
  "uok",
118
119
  "token_profile",
119
120
  "phases",
@@ -132,6 +133,7 @@ export const KNOWN_PREFERENCE_KEYS = new Set<string>([
132
133
  "service_tier",
133
134
  "forensics_dedup",
134
135
  "show_token_cost",
136
+ "min_request_interval_ms",
135
137
  "stale_commit_threshold_minutes",
136
138
  "context_management",
137
139
  "experimental",
@@ -320,6 +322,8 @@ export interface GSDPreferences {
320
322
  post_unit_hooks?: PostUnitHookConfig[];
321
323
  pre_dispatch_hooks?: PreDispatchHookConfig[];
322
324
  dynamic_routing?: DynamicRoutingConfig;
325
+ /** Provider IDs to exclude from /model and automatic model routing while leaving tool auth intact. */
326
+ disabled_model_providers?: string[];
323
327
  /** Unified Orchestration Kernel controls (default-on, with opt-out and emergency legacy fallback). */
324
328
  uok?: UokPreferences;
325
329
  /** Per-model capability overrides. Deep-merged with built-in profiles for capability-aware routing (ADR-004). */
@@ -365,6 +369,8 @@ export interface GSDPreferences {
365
369
  forensics_dedup?: boolean;
366
370
  /** Opt-in: show per-prompt and cumulative session token cost in the footer. Default: false. */
367
371
  show_token_cost?: boolean;
372
+ /** Proactive rate limiting: minimum milliseconds between auto-mode LLM requests. Prevents 429s on rate-limited providers. 0 = disabled (default). */
373
+ min_request_interval_ms?: number;
368
374
  /**
369
375
  * Minutes without a commit before flagging uncommitted changes as stale.
370
376
  * When the threshold is exceeded and the working tree is dirty, doctor will
@@ -610,6 +610,27 @@ export function validatePreferences(preferences: GSDPreferences): {
610
610
  }
611
611
  }
612
612
 
613
+ // ─── Disabled Model Providers ───────────────────────────────────────
614
+ if (preferences.disabled_model_providers !== undefined) {
615
+ if (Array.isArray(preferences.disabled_model_providers)) {
616
+ const allStrings = preferences.disabled_model_providers.every(
617
+ (provider: unknown) => typeof provider === "string",
618
+ );
619
+ if (!allStrings) {
620
+ errors.push("disabled_model_providers must be an array of strings");
621
+ } else {
622
+ const normalized = preferences.disabled_model_providers
623
+ .map((provider) => provider.trim())
624
+ .filter((provider) => provider.length > 0);
625
+ if (normalized.length > 0) {
626
+ validated.disabled_model_providers = Array.from(new Set(normalized));
627
+ }
628
+ }
629
+ } else {
630
+ errors.push("disabled_model_providers must be an array of strings");
631
+ }
632
+ }
633
+
613
634
  // ─── Context Management ──────────────────────────────────────────────
614
635
  if (preferences.context_management !== undefined) {
615
636
  if (typeof preferences.context_management === "object" && preferences.context_management !== null) {
@@ -1101,6 +1122,20 @@ export function validatePreferences(preferences: GSDPreferences): {
1101
1122
  }
1102
1123
  }
1103
1124
 
1125
+ // ─── Auto-Mode Request Interval ───────────────────────────────────
1126
+ if (preferences.min_request_interval_ms !== undefined) {
1127
+ if (
1128
+ typeof preferences.min_request_interval_ms === "number" &&
1129
+ Number.isFinite(preferences.min_request_interval_ms) &&
1130
+ preferences.min_request_interval_ms >= 0 &&
1131
+ preferences.min_request_interval_ms <= 2_147_483_647
1132
+ ) {
1133
+ validated.min_request_interval_ms = Math.floor(preferences.min_request_interval_ms);
1134
+ } else {
1135
+ errors.push("min_request_interval_ms must be a non-negative number <= 2147483647");
1136
+ }
1137
+ }
1138
+
1104
1139
  // ─── Experimental Features ────────────────────────────────────────
1105
1140
  if (preferences.experimental !== undefined) {
1106
1141
  if (typeof preferences.experimental === "object" && preferences.experimental !== null) {
@@ -89,10 +89,12 @@ export {
89
89
  resolveDynamicRoutingConfig,
90
90
  resolveAutoSupervisorConfig,
91
91
  resolveProfileDefaults,
92
+ getProfileTierMap,
92
93
  resolveEffectiveProfile,
93
94
  resolveInlineLevel,
94
95
  resolveContextSelection,
95
96
  resolveSearchProviderFromPreferences,
97
+ resolveDisabledModelProvidersFromPreferences,
96
98
  } from "./preferences-models.js";
97
99
 
98
100
  // ─── Path Constants & Getters ───────────────────────────────────────────────
@@ -146,7 +148,10 @@ export function loadProjectGSDPreferences(basePath?: string): LoadedGSDPreferenc
146
148
  ?? loadPreferencesFile(legacyProjectPreferencesPathLowercase(basePath), "project");
147
149
  }
148
150
 
149
- export function loadEffectiveGSDPreferences(basePath?: string): LoadedGSDPreferences | null {
151
+ export function loadEffectiveGSDPreferences(
152
+ basePath?: string,
153
+ opts?: { availableModelIds?: string[] },
154
+ ): LoadedGSDPreferences | null {
150
155
  const globalPreferences = loadGlobalGSDPreferences();
151
156
  const projectPreferences = loadProjectGSDPreferences(basePath);
152
157
 
@@ -175,7 +180,11 @@ export function loadEffectiveGSDPreferences(basePath?: string): LoadedGSDPrefere
175
180
  // Explicit user preferences always override profile defaults.
176
181
  const profile = result.preferences.token_profile as TokenProfile | undefined;
177
182
  if (profile) {
178
- const profileDefaults = _resolveProfileDefaults(profile);
183
+ const profileDefaults = _resolveProfileDefaults(
184
+ profile,
185
+ opts?.availableModelIds,
186
+ result.preferences.dynamic_routing,
187
+ );
179
188
  result = {
180
189
  ...result,
181
190
  preferences: mergePreferences(profileDefaults as GSDPreferences, result.preferences),
@@ -380,6 +389,10 @@ function mergePreferences(base: GSDPreferences, override: GSDPreferences): GSDPr
380
389
  dynamic_routing: (base.dynamic_routing || override.dynamic_routing)
381
390
  ? { ...(base.dynamic_routing ?? {}), ...(override.dynamic_routing ?? {}) } as DynamicRoutingConfig
382
391
  : undefined,
392
+ disabled_model_providers: mergeStringLists(
393
+ base.disabled_model_providers,
394
+ override.disabled_model_providers,
395
+ ),
383
396
  uok: (base.uok || override.uok)
384
397
  ? {
385
398
  enabled: override.uok?.enabled ?? base.uok?.enabled,
@@ -433,6 +446,7 @@ function mergePreferences(base: GSDPreferences, override: GSDPreferences): GSDPr
433
446
  service_tier: override.service_tier ?? base.service_tier,
434
447
  forensics_dedup: override.forensics_dedup ?? base.forensics_dedup,
435
448
  show_token_cost: override.show_token_cost ?? base.show_token_cost,
449
+ min_request_interval_ms: override.min_request_interval_ms ?? base.min_request_interval_ms,
436
450
  codebase: (base.codebase || override.codebase)
437
451
  ? {
438
452
  ...(base.codebase ?? {}),
@@ -7,14 +7,13 @@
7
7
  * Templates live at prompts/ relative to this module's directory.
8
8
  * They use {{variableName}} syntax for substitution.
9
9
  *
10
- * All templates are eagerly loaded into cache at module init via warmCache().
11
- * This prevents a running session from being invalidated when another `gsd`
12
- * launch overwrites ~/.gsd/agent/ with newer templates via initResources().
13
- * Without eager caching, the in-memory extension code (which knows variable
14
- * set A) can read a newer template from disk (which expects variable set B),
15
- * causing a "template declares {{X}} but no value was provided" crash
16
- * mid-session especially for late-loading templates like complete-milestone
17
- * that aren't read until the end of a long auto-mode run.
10
+ * Templates are snapshotted shortly after module init via warmCache().
11
+ * This keeps import/extension-registration fast while still preventing a
12
+ * running session from being invalidated when another `gsd` launch overwrites
13
+ * ~/.gsd/agent/ with newer templates via initResources(). Without caching, the
14
+ * in-memory extension code (which knows variable set A) can read a newer
15
+ * template from disk (which expects variable set B), causing a
16
+ * "template declares {{X}} but no value was provided" crash mid-session.
18
17
  */
19
18
 
20
19
  import { readFileSync, readdirSync, existsSync } from "node:fs";
@@ -82,8 +81,8 @@ export function getTemplatesDir(): string {
82
81
  return templatesDir;
83
82
  }
84
83
 
85
- // Cache all templates eagerly at module load — a running session uses the
86
- // template versions that were on disk at startup, immune to later overwrites.
84
+ // Cache all templates from a startup snapshot — a running session uses the
85
+ // template versions that were on disk near startup, immune to later overwrites.
87
86
  const templateCache = new Map<string, string>();
88
87
 
89
88
  /**
@@ -124,8 +123,23 @@ function warmCache(): void {
124
123
  }
125
124
  }
126
125
 
127
- // Snapshot all templates at module load time
128
- warmCache();
126
+ let warmCacheScheduled = false;
127
+
128
+ function scheduleWarmCache(): void {
129
+ if (warmCacheScheduled) return;
130
+ warmCacheScheduled = true;
131
+
132
+ const run = () => {
133
+ warmCache();
134
+ };
135
+
136
+ const timer = setTimeout(run, 1000);
137
+ timer.unref?.();
138
+ }
139
+
140
+ // Snapshot the full prompt/template tree after import so extension startup only
141
+ // pays for prompts that are actually needed immediately.
142
+ scheduleWarmCache();
129
143
 
130
144
  /**
131
145
  * Load a prompt template and substitute variables.
@@ -16,6 +16,16 @@ Start with what the excerpts give you. Read full files when the section heads si
16
16
 
17
17
  **On-demand Read ordering:** Complete all slice SUMMARY Reads you need for cross-slice synthesis, the Decision Re-evaluation table, and LEARNINGS **before** calling `gsd_complete_milestone` (step 10). Once that tool runs, the milestone is marked complete in the DB — running out of tool budget between step 10 and the LEARNINGS write (step 12) leaves the milestone committed without its LEARNINGS artifact.
18
18
 
19
+ ### Delegate Review Work
20
+
21
+ This unit runs under the `planning-dispatch` tools-policy: you may use the `subagent` tool to delegate review work that benefits from a fresh context window. For non-trivial milestones, delegate before drafting LEARNINGS:
22
+
23
+ - **Cross-slice integrations or new public APIs** → dispatch the **reviewer** agent with the milestone diff and roadmap; treat its findings as input to your Decision Re-evaluation and LEARNINGS sections.
24
+ - **Touched auth, network, parsing, file IO, shell exec, or crypto** → dispatch the **security** agent for an OWASP-style audit across the merged slices.
25
+ - **Significant test surface added or changed** → dispatch the **tester** agent to assess coverage gaps relative to the milestone success criteria.
26
+
27
+ Subagents read the diff and report findings — they do **not** write user source. Apply their feedback into the milestone summary and any captured decisions before calling `gsd_complete_milestone`.
28
+
19
29
  {{inlinedContext}}
20
30
 
21
31
  Then:
@@ -20,6 +20,16 @@ All relevant context has been preloaded below — the slice plan, all task summa
20
20
 
21
21
  **Match effort to complexity.** A simple slice with 1-2 tasks needs a brief summary and lightweight verification. A complex slice with 5 tasks across multiple subsystems needs thorough verification and a detailed summary. Scale the work below accordingly.
22
22
 
23
+ ### Delegate Review Work
24
+
25
+ This unit runs under the `planning-dispatch` tools-policy: you may use the `subagent` tool to delegate review work that benefits from a fresh context window. Strongly consider delegating when the slice is non-trivial:
26
+
27
+ - **Cross-cutting code or new abstractions** → dispatch the **reviewer** agent with the slice diff and plan; apply High/Critical findings before completing.
28
+ - **Touched auth, network, parsing, file IO, shell exec, or crypto** → dispatch the **security** agent for an OWASP-style audit.
29
+ - **Added or modified tests** → dispatch the **tester** agent to assess coverage gaps relative to the slice plan.
30
+
31
+ Subagents read the diff and report findings — they do **not** write user source. You remain responsible for acting on their feedback before calling `gsd_complete_slice` with `milestoneId` and `sliceId`.
32
+
23
33
  Then:
24
34
  1. Use the **Slice Summary** and **UAT** output templates from the inlined context above
25
35
  2. {{skillActivation}}
@@ -1,3 +1,5 @@
1
+ **Working directory:** `{{workingDirectory}}`. All file reads, writes, and shell commands MUST operate relative to this directory. Do NOT `cd` to any other directory.
2
+
1
3
  Discuss milestone {{milestoneId}} ("{{milestoneTitle}}"). Identify gray areas, ask the user about them, and write `{{milestoneId}}-CONTEXT.md` in the milestone directory with the decisions. Use the **Context** output template below. If a `GSD Skill Preferences` block is present in system context, use it to decide which skills to load and follow; do not override required artifact rules.
2
4
 
3
5
  **Structured questions available: {{structuredQuestionsAvailable}}**
@@ -1,5 +1,7 @@
1
1
  # Parallel Slice Research
2
2
 
3
+ **Working directory:** `{{workingDirectory}}`. All file reads, writes, and shell commands MUST operate relative to this directory. Do NOT `cd` to any other directory.
4
+
3
5
  You are dispatching parallel research agents for **{{sliceCount}} slices** in milestone **{{mid}} — {{midTitle}}**.
4
6
 
5
7
  ## Slices to Research
@@ -20,6 +20,16 @@ Pay particular attention to **Forward Intelligence** sections — they contain h
20
20
 
21
21
  You have full tool access. Before decomposing, explore the relevant code to ground your plan in reality.
22
22
 
23
+ ### Delegate Recon and Sub-Decomposition When Useful
24
+
25
+ This unit runs under the `planning-dispatch` tools-policy: you may use the `subagent` tool to delegate work that benefits from an isolated context window. Prefer delegation over inline work when:
26
+
27
+ - You'd otherwise read more than ~3 files to understand a subsystem → dispatch the **scout** agent for codebase recon and work from its compressed report.
28
+ - The slice spans multiple subsystems and the decomposition isn't obvious → dispatch the **planner** agent or use the **decompose-into-slices** skill on a focused sub-area, then integrate.
29
+ - You need current external information (library docs, API behavior, recent changes) → dispatch the **researcher** agent.
30
+
31
+ **Do not** dispatch implementation-tier agents (`worker`, `refactorer`, `tester`) from this unit — they would write user source and bypass this unit's write isolation. Implementation belongs in `execute-task`.
32
+
23
33
  ### Verify Roadmap Assumptions (JIT Reassessment — ADR-003 §4)
24
34
 
25
35
  Before planning this slice, verify that the roadmap's assumptions still hold given prior slice summaries. Check inlined dependency summaries (below) for discovered constraints, changed approaches, or flagged fragility.
@@ -20,6 +20,16 @@ Pay particular attention to **Forward Intelligence** sections — they contain h
20
20
 
21
21
  ## Your Role in the Pipeline
22
22
 
23
+ ### Delegate Recon When Useful
24
+
25
+ This unit runs under the `planning-dispatch` tools-policy: you may use the `subagent` tool to delegate recon and sub-decomposition. Prefer delegation over inline work when:
26
+
27
+ - You'd otherwise read more than ~3 files to understand a subsystem touched by the sketch → dispatch the **scout** agent and work from its compressed report.
28
+ - A specific area of the refinement needs deeper architectural analysis → dispatch the **planner** agent for a focused sub-plan, then integrate.
29
+ - You need current external information (library docs, API behavior) → dispatch the **researcher** agent.
30
+
31
+ **Do not** dispatch implementation-tier agents (`worker`, `refactorer`, `tester`) — they would write user source and bypass write isolation. Implementation belongs in `execute-task`.
32
+
23
33
  ### Respect the Sketch Scope
24
34
 
25
35
  The sketch scope inlined above is a **hard constraint**. Plan within it. If, after exploring the codebase, the scope is too narrow to deliver the goal, surface this as a deviation in the plan's narrative and still produce the plan — do not silently expand the scope.
@@ -1,5 +1,7 @@
1
1
  You are executing GSD auto-mode.
2
2
 
3
+ **Working directory:** `{{workingDirectory}}`. All file reads, writes, and shell commands MUST operate relative to this directory. Do NOT `cd` to any other directory.
4
+
3
5
  ## UNIT: Rewrite Documents — Apply Override(s) for Milestone {{milestoneId}} ("{{milestoneTitle}}")
4
6
 
5
7
  An override was issued by the user that changes a fundamental decision or approach. Your job is to propagate this change across all active planning documents so they are internally consistent and future tasks execute correctly.
@@ -82,6 +82,7 @@ let sliceState: SliceOrchestratorState | null = null;
82
82
 
83
83
  const SLICE_ORCHESTRATOR_STATE_FILE = "slice-orchestrator.json";
84
84
  const TMP_SUFFIX = ".tmp";
85
+ export const SLICE_WORKER_AUTO_ARGS = ["headless", "--json", "auto"] as const;
85
86
 
86
87
  interface PersistedSliceWorker {
87
88
  milestoneId: string;
@@ -356,7 +357,7 @@ export function getSliceOrchestratorState(): SliceOrchestratorState | null {
356
357
  /**
357
358
  * Start parallel execution for eligible slices within a milestone.
358
359
  *
359
- * For each eligible slice: create a worktree, spawn `gsd --mode json --print "/gsd auto"`
360
+ * For each eligible slice: create a worktree, spawn `gsd headless --json auto`
360
361
  * with env GSD_SLICE_LOCK=<SID> + GSD_MILESTONE_LOCK=<MID> + GSD_PARALLEL_WORKER=1.
361
362
  */
362
363
  export async function startSliceParallel(
@@ -598,8 +599,13 @@ function resolveGsdBin(): string | null {
598
599
 
599
600
  /**
600
601
  * Spawn a worker process for a slice.
601
- * The worker runs `gsd --mode json --print "/gsd auto"` in the slice's worktree
602
+ * The worker runs `gsd headless --json auto` in the slice's worktree
602
603
  * with GSD_SLICE_LOCK, GSD_MILESTONE_LOCK, and GSD_PARALLEL_WORKER set.
604
+ *
605
+ * Print-mode slash commands return after the command handler schedules
606
+ * auto-mode, so the worker process can exit before doing any LLM work. The
607
+ * headless auto entrypoint keeps the process alive until auto-mode reaches a
608
+ * terminal notification, matching milestone-level parallel workers.
603
609
  */
604
610
  function spawnSliceWorker(
605
611
  basePath: string,
@@ -616,7 +622,7 @@ function spawnSliceWorker(
616
622
 
617
623
  let child: ChildProcess;
618
624
  try {
619
- child = spawn(process.execPath, [binPath, "--mode", "json", "--print", "/gsd auto"], {
625
+ child = spawn(process.execPath, [binPath, ...SLICE_WORKER_AUTO_ARGS], {
620
626
  cwd: worker.worktreePath,
621
627
  env: {
622
628
  ...process.env,
@@ -114,6 +114,48 @@ export function isGhostMilestone(basePath: string, mid: string): boolean {
114
114
  return !context && !draft && !roadmap && !summary;
115
115
  }
116
116
 
117
+ /**
118
+ * A "reusable ghost" milestone is an orphaned filesystem stub that is safe
119
+ * to reclaim as the next milestone ID.
120
+ *
121
+ * Stricter than `isGhostMilestone`: returns true ONLY when ALL of the
122
+ * following hold:
123
+ * 1. No DB row exists for `mid` (any status, including "queued") — a DB row
124
+ * means the milestone was intentionally registered by
125
+ * `gsd_milestone_generate_id` and may have an in-flight discuss flow.
126
+ * Reusing it would collide with that flow. (#4996 race window)
127
+ * 2. No worktree directory exists at `gsdRoot/worktrees/{mid}` — a worktree
128
+ * means the milestone is legitimately in-flight.
129
+ * 3. No content files exist (CONTEXT, CONTEXT-DRAFT, ROADMAP, SUMMARY) —
130
+ * any content means the discuss flow already ran.
131
+ *
132
+ * The looser `isGhostMilestone` also classifies queued-row-without-content as
133
+ * a ghost to help state queries filter phantoms. `isReusableGhostMilestone`
134
+ * intentionally does NOT reclaim those — a queued row is sufficient proof of
135
+ * a live in-flight ID reservation.
136
+ *
137
+ * Used by `nextMilestoneIdReserved` and both MCP ID-generator tools to fill
138
+ * gaps left by phantom directories before resorting to max+1.
139
+ */
140
+ export function isReusableGhostMilestone(basePath: string, mid: string): boolean {
141
+ // Condition 1: no DB row (any status).
142
+ if (!isDbAvailable()) return false;
143
+ const dbRow = getMilestone(mid);
144
+ if (dbRow != null) return false;
145
+
146
+ // Condition 2: no worktree.
147
+ const root = gsdRoot(basePath);
148
+ const wtPath = join(root, 'worktrees', mid);
149
+ if (existsSync(wtPath)) return false;
150
+
151
+ // Condition 3: no content files.
152
+ const context = resolveMilestoneFile(basePath, mid, "CONTEXT");
153
+ const draft = resolveMilestoneFile(basePath, mid, "CONTEXT-DRAFT");
154
+ const roadmap = resolveMilestoneFile(basePath, mid, "ROADMAP");
155
+ const summary = resolveMilestoneFile(basePath, mid, "SUMMARY");
156
+ return !context && !draft && !roadmap && !summary;
157
+ }
158
+
117
159
  // ─── Query Functions ───────────────────────────────────────────────────────
118
160
 
119
161
  /**
@@ -39,6 +39,7 @@ dynamic_routing:
39
39
  budget_pressure:
40
40
  cross_provider:
41
41
  hooks:
42
+ disabled_model_providers: []
42
43
  uok:
43
44
  enabled: true
44
45
  legacy_fallback: