cartethyia 2.7.4 → 2.7.6

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 (595) hide show
  1. package/.env.example +5 -0
  2. package/README.md +18 -6
  3. package/dist/dashboard/assets/BannedPage-B1N603cM.js +1 -0
  4. package/dist/dashboard/assets/BannedPage-B1N603cM.js.gz +0 -0
  5. package/dist/dashboard/assets/CliToolDetailPage-9q4_4NoK.js +3 -0
  6. package/dist/dashboard/assets/CliToolDetailPage-9q4_4NoK.js.gz +0 -0
  7. package/dist/dashboard/assets/CliToolsPage-DwshGtK-.js +1 -0
  8. package/dist/dashboard/assets/CliToolsPage-DwshGtK-.js.gz +0 -0
  9. package/dist/dashboard/assets/CombosPage-D762MIkp.js +1 -0
  10. package/dist/dashboard/assets/CombosPage-D762MIkp.js.gz +0 -0
  11. package/dist/dashboard/assets/ConsoleLogPage-KRYjHZsX.js +1 -0
  12. package/dist/dashboard/assets/ConsoleLogPage-KRYjHZsX.js.gz +0 -0
  13. package/dist/dashboard/assets/CustomizationPage-DXsxk5uM.js +1 -0
  14. package/dist/dashboard/assets/CustomizationPage-DXsxk5uM.js.gz +0 -0
  15. package/dist/dashboard/assets/HealthEventsModal-BEjAjD4F.js +1 -0
  16. package/dist/dashboard/assets/HealthEventsModal-BEjAjD4F.js.gz +0 -0
  17. package/dist/dashboard/assets/InjectSystemPromptPanel-d5v3K_Yc.js +899 -0
  18. package/dist/dashboard/assets/InjectSystemPromptPanel-d5v3K_Yc.js.gz +0 -0
  19. package/dist/dashboard/assets/LoginPage-Ccv4tjNS.js +1 -0
  20. package/dist/dashboard/assets/LoginPage-Ccv4tjNS.js.gz +0 -0
  21. package/dist/dashboard/assets/{ModelPicker-BMS2t8BA.js → ModelPicker-C6WlpU5E.js} +1 -1
  22. package/dist/dashboard/assets/ModelPicker-C6WlpU5E.js.gz +0 -0
  23. package/dist/dashboard/assets/OverviewPage-DN9fYNWA.js +1 -0
  24. package/dist/dashboard/assets/OverviewPage-DN9fYNWA.js.gz +0 -0
  25. package/dist/dashboard/assets/ProviderDetailPage-BY0ieUgz.js +5 -0
  26. package/dist/dashboard/assets/ProviderDetailPage-BY0ieUgz.js.gz +0 -0
  27. package/dist/dashboard/assets/ProviderIcon-jjqXJDA3.js +1 -0
  28. package/dist/dashboard/assets/ProviderIcon-jjqXJDA3.js.gz +0 -0
  29. package/dist/dashboard/assets/ProvidersPage-DNsbfea2.js +1 -0
  30. package/dist/dashboard/assets/ProvidersPage-DNsbfea2.js.gz +0 -0
  31. package/dist/dashboard/assets/{ProxyPage-lsrx7NYg.js → ProxyPage-DxjvUzSD.js} +1 -1
  32. package/dist/dashboard/assets/ProxyPage-DxjvUzSD.js.gz +0 -0
  33. package/dist/dashboard/assets/QuotaPage-OaHScjpX.js +1 -0
  34. package/dist/dashboard/assets/QuotaPage-OaHScjpX.js.gz +0 -0
  35. package/dist/dashboard/assets/SettingsPage-BW4AKj2H.js +1 -0
  36. package/dist/dashboard/assets/SettingsPage-BW4AKj2H.js.gz +0 -0
  37. package/dist/dashboard/assets/SetupPage-44BZrxFC.js +1 -0
  38. package/dist/dashboard/assets/SetupPage-44BZrxFC.js.gz +0 -0
  39. package/dist/dashboard/assets/{StudioPage-Cq5tW7hW.js → StudioPage-DRPavCdU.js} +4 -4
  40. package/dist/dashboard/assets/StudioPage-DRPavCdU.js.gz +0 -0
  41. package/dist/dashboard/assets/ToolIcon-CfeLA-Z_.js +1 -0
  42. package/dist/dashboard/assets/ToolIcon-CfeLA-Z_.js.gz +0 -0
  43. package/dist/dashboard/assets/UsagePage-B7M7LvMM.js +56 -0
  44. package/dist/dashboard/assets/UsagePage-B7M7LvMM.js.gz +0 -0
  45. package/dist/dashboard/assets/api-keys-KvX83mRe.js +1 -0
  46. package/dist/dashboard/assets/api-keys-KvX83mRe.js.gz +0 -0
  47. package/dist/dashboard/assets/app-DRnQLhsc.js +9 -0
  48. package/dist/dashboard/assets/app-DRnQLhsc.js.gz +0 -0
  49. package/dist/dashboard/assets/app-mweRcsKp.css +2 -0
  50. package/dist/dashboard/assets/app-mweRcsKp.css.gz +0 -0
  51. package/dist/dashboard/assets/assert-CidQVoNo.js +1 -0
  52. package/dist/dashboard/assets/assert-CidQVoNo.js.gz +0 -0
  53. package/dist/dashboard/assets/{badge-D9CS6dZk.js → badge-BaX2GTrn.js} +1 -1
  54. package/dist/dashboard/assets/badge-BaX2GTrn.js.gz +0 -0
  55. package/dist/dashboard/assets/{banner-DympBNq4.js → banner-DFH4Bkte.js} +1 -1
  56. package/dist/dashboard/assets/banner-DFH4Bkte.js.gz +0 -0
  57. package/dist/dashboard/assets/brand/login_register.jpg +0 -0
  58. package/dist/dashboard/assets/brand/login_register_initial.jpg +0 -0
  59. package/dist/dashboard/assets/brand/og_bansos.jpg +0 -0
  60. package/dist/dashboard/assets/brand/og_image.jpg +0 -0
  61. package/dist/dashboard/assets/{card-ibRWU_uT.js → card-CxDw0lK6.js} +1 -1
  62. package/dist/dashboard/assets/card-CxDw0lK6.js.gz +0 -0
  63. package/dist/dashboard/assets/chevron-left-Bf6CaTSJ.js +1 -0
  64. package/dist/dashboard/assets/chevron-left-Bf6CaTSJ.js.gz +0 -0
  65. package/dist/dashboard/assets/circle-question-mark-Cz4un8sH.js +1 -0
  66. package/dist/dashboard/assets/circle-question-mark-Cz4un8sH.js.gz +0 -0
  67. package/dist/dashboard/assets/cli-tools-Bwv5-zGZ.js +1 -0
  68. package/dist/dashboard/assets/cli-tools-Bwv5-zGZ.js.gz +0 -0
  69. package/dist/dashboard/assets/{clipboard-button-DJm-9pz7.js → clipboard-button-DfS1ntiq.js} +1 -1
  70. package/dist/dashboard/assets/clipboard-button-DfS1ntiq.js.gz +0 -0
  71. package/dist/dashboard/assets/dialog-BK-NRr5u.js +1 -0
  72. package/dist/dashboard/assets/dialog-BK-NRr5u.js.gz +0 -0
  73. package/dist/dashboard/assets/{drawer-CqGYeOrd.js → drawer-QqPul6sC.js} +1 -1
  74. package/dist/dashboard/assets/drawer-QqPul6sC.js.gz +0 -0
  75. package/dist/dashboard/assets/entry-BMlYJVFj.js +1 -0
  76. package/dist/dashboard/assets/entry-BMlYJVFj.js.gz +0 -0
  77. package/dist/dashboard/assets/entry-D6WvojeD.js +4 -0
  78. package/dist/dashboard/assets/entry-D6WvojeD.js.gz +0 -0
  79. package/dist/dashboard/assets/entry-Dmx7gBiN.js +1 -0
  80. package/dist/dashboard/assets/entry-Dmx7gBiN.js.gz +0 -0
  81. package/dist/dashboard/assets/{formatters-D-MTJxMr.js → formatters-u7JPB5BX.js} +1 -1
  82. package/dist/dashboard/assets/formatters-u7JPB5BX.js.gz +0 -0
  83. package/dist/dashboard/assets/house-h9AZlJuT.js +1 -0
  84. package/dist/dashboard/assets/house-h9AZlJuT.js.gz +0 -0
  85. package/dist/dashboard/assets/{index-DBNPOfhV.js → index-Ko4dLRnV.js} +2 -2
  86. package/dist/dashboard/assets/index-Ko4dLRnV.js.gz +0 -0
  87. package/dist/dashboard/assets/{inline-BT0zntEr.js → inline-CHJQwxLa.js} +1 -1
  88. package/dist/dashboard/assets/inline-CHJQwxLa.js.gz +0 -0
  89. package/dist/dashboard/assets/{input-Da2ZViWg.js → input-BlmlizVV.js} +1 -1
  90. package/dist/dashboard/assets/input-BlmlizVV.js.gz +0 -0
  91. package/dist/dashboard/assets/{layout-BXNeLw6M.js → layout-Bz93I-yE.js} +1 -1
  92. package/dist/dashboard/assets/layout-Bz93I-yE.js.gz +0 -0
  93. package/dist/dashboard/assets/{list-row-BycOrrIV.js → list-row-Ml16KCfu.js} +1 -1
  94. package/dist/dashboard/assets/list-row-Ml16KCfu.js.gz +0 -0
  95. package/dist/dashboard/assets/live-7_QpnYGu.js +1 -0
  96. package/dist/dashboard/assets/live-7_QpnYGu.js.gz +0 -0
  97. package/dist/dashboard/assets/{mutation-Rr0TIvcj.js → mutation-GU7XdEjz.js} +1 -1
  98. package/dist/dashboard/assets/mutation-GU7XdEjz.js.gz +0 -0
  99. package/dist/dashboard/assets/network-CuMDaTzT.js +1 -0
  100. package/dist/dashboard/assets/network-CuMDaTzT.js.gz +0 -0
  101. package/dist/dashboard/assets/numbers-CoqpaDMx.js +2 -0
  102. package/dist/dashboard/assets/numbers-CoqpaDMx.js.gz +0 -0
  103. package/dist/dashboard/assets/pagination-B5aOoweZ.js +1 -0
  104. package/dist/dashboard/assets/pagination-B5aOoweZ.js.gz +0 -0
  105. package/dist/dashboard/assets/providers/zai.webp +0 -0
  106. package/dist/dashboard/assets/providers/zcode.webp +0 -0
  107. package/dist/dashboard/assets/{query-keys-BloKtaXJ.js → query-keys-YSoQOUh6.js} +1 -1
  108. package/dist/dashboard/assets/{query-keys-BloKtaXJ.js.gz → query-keys-YSoQOUh6.js.gz} +0 -0
  109. package/dist/dashboard/assets/quota-DJ1QlAOq.js +1 -0
  110. package/dist/dashboard/assets/quota-DJ1QlAOq.js.gz +0 -0
  111. package/dist/dashboard/assets/routing-fnCsxgNO.js +1 -0
  112. package/dist/dashboard/assets/routing-fnCsxgNO.js.gz +0 -0
  113. package/dist/dashboard/assets/{select-BIYIBkMU.js → select-BHqpd-bg.js} +2 -2
  114. package/dist/dashboard/assets/select-BHqpd-bg.js.gz +0 -0
  115. package/dist/dashboard/assets/settings-BxslsErn.js +1 -0
  116. package/dist/dashboard/assets/settings-BxslsErn.js.gz +0 -0
  117. package/dist/dashboard/assets/shield-BMQNxORh.js +1 -0
  118. package/dist/dashboard/assets/shield-BMQNxORh.js.gz +0 -0
  119. package/dist/dashboard/assets/{stack-DfgnFDWY.js → stack-j7cXjgYX.js} +1 -1
  120. package/dist/dashboard/assets/stack-j7cXjgYX.js.gz +0 -0
  121. package/dist/dashboard/assets/{state-CkfdYWel.js → state-DHmEnLa2.js} +1 -1
  122. package/dist/dashboard/assets/state-DHmEnLa2.js.gz +0 -0
  123. package/dist/dashboard/assets/{switch-SYm237HG.js → switch-DmZcyTIC.js} +1 -1
  124. package/dist/dashboard/assets/switch-DmZcyTIC.js.gz +0 -0
  125. package/dist/dashboard/assets/{useMutation-BQqCRNIi.js → useMutation-CbCP4w1o.js} +1 -1
  126. package/dist/dashboard/assets/useMutation-CbCP4w1o.js.gz +0 -0
  127. package/dist/dashboard/console-backgrounds.jpg +0 -0
  128. package/dist/dashboard/console-backgrounds_initial.jpg +0 -0
  129. package/dist/dashboard/index.html +2 -2
  130. package/dist/dashboard/index.html.gz +0 -0
  131. package/dist/dashboard/precompressed-assets.json +60 -59
  132. package/migrations/full-postgres/0036_system_prompt_presets_refs.sql +10 -0
  133. package/migrations/full-postgres/0037_share_concurrency_scope.sql +3 -0
  134. package/migrations/full-postgres/0038_add_accounts_quota_snapshot.sql +7 -0
  135. package/migrations/full-postgres/0039_add_telemetry_provider_model_indexes.sql +13 -0
  136. package/migrations/full-postgres/0040_add_models_dialect.sql +3 -0
  137. package/migrations/full-postgres/0041_add_daily_checkin_ledger_account_fk.sql +7 -0
  138. package/migrations/full-postgres/0042_add_telemetry_degenerate_stop.sql +14 -0
  139. package/migrations/lite-sqlite3/0036_system_prompt_presets_refs.sql +14 -0
  140. package/migrations/lite-sqlite3/0037_share_concurrency_scope.sql +3 -0
  141. package/migrations/lite-sqlite3/0038_add_accounts_quota_snapshot.sql +4 -0
  142. package/migrations/lite-sqlite3/0039_add_telemetry_provider_model_indexes.sql +6 -0
  143. package/migrations/lite-sqlite3/0040_add_models_dialect.sql +3 -0
  144. package/migrations/lite-sqlite3/0041_add_daily_checkin_ledger_account_fk.sql +26 -0
  145. package/migrations/lite-sqlite3/0042_add_telemetry_degenerate_stop.sql +12 -0
  146. package/package.json +4 -6
  147. package/scripts/cli/update.ts +15 -41
  148. package/src/boot/app.ts +58 -2
  149. package/src/boot/dependencies.ts +794 -732
  150. package/src/boot/lifecycle.ts +11 -12
  151. package/src/config/cooldowns.ts +34 -55
  152. package/src/config/network.ts +1 -1
  153. package/src/config/package-paths.ts +1 -1
  154. package/src/config/providers.ts +19 -14
  155. package/src/config/resources.ts +0 -5
  156. package/src/config/runtime.ts +2 -5
  157. package/src/config/spec.ts +33 -6
  158. package/src/config/usage.ts +27 -0
  159. package/src/console/api-keys/ban-constants.ts +38 -0
  160. package/src/console/api-keys/contracts.ts +71 -62
  161. package/src/console/api-keys/routes.ts +56 -24
  162. package/src/console/auth/access.ts +4 -4
  163. package/src/console/auth/account-reset.ts +1 -1
  164. package/src/console/auth/audit-recorder.ts +1 -1
  165. package/src/console/auth/lockout.ts +7 -3
  166. package/src/console/auth/row-coercion.ts +57 -12
  167. package/src/console/auth/session-resolver.ts +1 -1
  168. package/src/console/auth/session-service.ts +8 -2
  169. package/src/console/auth/session.ts +37 -31
  170. package/src/console/auth/setup-service.ts +4 -3
  171. package/src/console/auth/user-store.ts +1 -1
  172. package/src/console/backup/9router-map.ts +0 -3
  173. package/src/console/backup/contracts.ts +9 -9
  174. package/src/console/backup/export-endpoint.ts +5 -6
  175. package/src/console/backup/nine-router.ts +1 -7
  176. package/src/console/backup/routes.ts +29 -33
  177. package/src/console/backup/service.ts +468 -468
  178. package/src/console/backup/store.ts +47 -29
  179. package/src/console/backup/validate.ts +11 -1
  180. package/src/console/cli-tools/contracts.ts +43 -299
  181. package/src/console/cli-tools/fs-ops.ts +29 -0
  182. package/src/console/cli-tools/injectors/claude.ts +3 -3
  183. package/src/console/cli-tools/injectors/codex.ts +181 -181
  184. package/src/console/cli-tools/injectors/driver.ts +150 -247
  185. package/src/console/cli-tools/injectors/kilo.ts +146 -21
  186. package/src/console/cli-tools/injectors/opencode.ts +176 -153
  187. package/src/console/cli-tools/routes.ts +7 -1
  188. package/src/console/cli-tools/service.ts +8 -7
  189. package/src/console/cli-tools/store.ts +2 -2
  190. package/src/console/console-router.ts +32 -0
  191. package/src/console/dashboard-assets.ts +9 -9
  192. package/src/console/domain-registration.ts +16 -2
  193. package/src/console/inferhub/client.ts +0 -7
  194. package/src/console/inferhub/key-store.ts +1 -1
  195. package/src/console/inferhub/normalize.ts +2 -2
  196. package/src/console/inferhub/routes.ts +1 -1
  197. package/src/console/inferhub/types.ts +1 -1
  198. package/src/console/observability/contracts.ts +7 -1
  199. package/src/console/observability/live.ts +31 -18
  200. package/src/console/observability/logs.ts +1 -1
  201. package/src/console/observability/sse.ts +62 -8
  202. package/src/console/observability/store.ts +23 -4
  203. package/src/console/providers/catalog/catalog-projections.ts +1 -1
  204. package/src/console/providers/catalog/contracts.ts +39 -0
  205. package/src/console/providers/catalog/model-operations.ts +1 -1
  206. package/src/console/providers/catalog/provider-operations.ts +95 -17
  207. package/src/console/providers/catalog/public-model-store.ts +0 -0
  208. package/src/console/providers/catalog/routes.ts +27 -3
  209. package/src/console/providers/catalog/store.ts +147 -8
  210. package/src/console/providers/detail/routes.ts +1 -1
  211. package/src/console/providers/oauth/callback-listener.ts +100 -18
  212. package/src/console/providers/oauth/routes.ts +92 -13
  213. package/src/console/quota/account-quota-global.ts +41 -3
  214. package/src/console/quota/account-quota-shared.ts +10 -3
  215. package/src/console/quota/account-quota-tenant.ts +259 -66
  216. package/src/console/quota/daily-growth-job.ts +308 -0
  217. package/src/console/quota/native-identity.ts +2 -2
  218. package/src/console/quota/quota-view.ts +1 -1
  219. package/src/console/remote-support/routes.ts +1 -1
  220. package/src/console/remote-support/service.ts +2 -2
  221. package/src/console/routing/model/contracts.ts +1 -1
  222. package/src/console/routing/pools/contracts.ts +2 -2
  223. package/src/console/routing/pools/import-parse.ts +3 -3
  224. package/src/console/routing/pools/relay-deploy.ts +3 -3
  225. package/src/console/settings/contracts.ts +29 -2
  226. package/src/console/settings/store.ts +20 -0
  227. package/src/console/share/share-router.ts +100 -32
  228. package/src/console/share/share-stats.ts +11 -13
  229. package/src/console/share/share-usage.ts +1 -1
  230. package/src/console/shared/errors.ts +2 -2
  231. package/src/console/shared/object.ts +18 -0
  232. package/src/console/shared/read-through-cache.ts +4 -4
  233. package/src/console/shared/transaction.ts +14 -0
  234. package/src/console/system-prompt/contracts.ts +89 -12
  235. package/src/console/system-prompt/routes.ts +98 -45
  236. package/src/console/updates/apply-update.ts +244 -0
  237. package/src/console/updates/routes.ts +252 -97
  238. package/src/main.ts +11 -5
  239. package/src/network/http2-bidi.ts +1 -1
  240. package/src/network/ip-utils.ts +298 -0
  241. package/src/network/outbound-fetch.ts +1 -1
  242. package/src/network/pool/agent.ts +7 -6
  243. package/src/network/pool/byte-accounting.ts +1 -1
  244. package/src/network/pool/resolver.ts +16 -12
  245. package/src/network/pool/selector.ts +150 -136
  246. package/src/network/pool-health-machine.ts +1 -1
  247. package/src/network/rate-limit-verdict.ts +1 -1
  248. package/src/network/retry.ts +1 -1
  249. package/src/network/ssrf.ts +20 -71
  250. package/src/observability/event-log.ts +9 -2
  251. package/src/observability/event-query.ts +61 -291
  252. package/src/observability/log-sanitize.ts +1 -1
  253. package/src/observability/metrics.ts +4 -4
  254. package/src/observability/payload-capture.ts +6 -5
  255. package/src/observability/payload-store.ts +1 -1
  256. package/src/observability/runtime-metrics.ts +1 -1
  257. package/src/observability/telemetry-buffer.ts +19 -3
  258. package/src/observability/telemetry-reconciliation.ts +3 -3
  259. package/src/observability/token-speed.ts +1 -1
  260. package/src/persistence/connection-url.ts +1 -1
  261. package/src/persistence/db-handle.ts +1 -1
  262. package/src/persistence/db-pg.ts +2 -2
  263. package/src/persistence/db-sqlite.ts +3 -3
  264. package/src/persistence/dialect.ts +5 -1
  265. package/src/persistence/readiness.ts +1 -1
  266. package/src/persistence/redis.ts +1 -1
  267. package/src/persistence/schema.ts +121 -40
  268. package/src/persistence/shared-cache.ts +2 -2
  269. package/src/persistence/sort-order.ts +1 -1
  270. package/src/persistence/stores/api-key-store.ts +29 -2
  271. package/src/persistence/stores/share-store.ts +20 -8
  272. package/src/persistence/system-prompt-store.ts +63 -18
  273. package/src/persistence/tenant-preferences.ts +1 -1
  274. package/src/persistence/ttl-cache.ts +3 -3
  275. package/src/persistence/usage-flush.ts +7 -2
  276. package/src/protocol/canonical-model.ts +1 -1
  277. package/src/protocol/codecs.ts +6 -10
  278. package/src/protocol/dsml.ts +8 -125
  279. package/src/protocol/image-clamp.ts +2 -2
  280. package/src/protocol/reasoning-text.ts +1 -1
  281. package/src/protocol/reasoning.ts +7 -52
  282. package/src/protocol/registry.ts +50 -15
  283. package/src/protocol/request/chat.ts +46 -19
  284. package/src/protocol/request/codex.ts +1 -1
  285. package/src/protocol/request/messages.ts +46 -14
  286. package/src/protocol/request/responses.ts +19 -10
  287. package/src/protocol/response/chat.ts +25 -10
  288. package/src/protocol/response/codex.ts +1 -1
  289. package/src/protocol/response/messages.ts +1 -1
  290. package/src/protocol/response/omp-tool-call-markup.ts +1 -1
  291. package/src/protocol/response/responses.ts +1 -1
  292. package/src/protocol/sse-decoder.ts +50 -1
  293. package/src/protocol/stop-reason.ts +2 -2
  294. package/src/protocol/think-split.ts +347 -0
  295. package/src/protocol/translation/attachment-integrity.ts +3 -3
  296. package/src/protocol/translation/cache-controls.ts +8 -20
  297. package/src/protocol/translation/capabilities.ts +6 -6
  298. package/src/protocol/translation/dialect/deepseek.ts +10 -0
  299. package/src/protocol/translation/dialect/inband.ts +39 -0
  300. package/src/protocol/translation/dialect/model-thinking.ts +89 -0
  301. package/src/protocol/translation/dialect/qwen.ts +114 -0
  302. package/src/protocol/translation/dialect/resolver.ts +83 -0
  303. package/src/protocol/translation/dialect/rules.ts +93 -0
  304. package/src/protocol/translation/dialect/thinking-ladder.ts +245 -0
  305. package/src/protocol/translation/dialect/types.ts +58 -0
  306. package/src/protocol/translation/quirks.ts +18 -4
  307. package/src/protocol/translation/thinking.ts +12 -252
  308. package/src/protocol/translation/tool-id.ts +3 -3
  309. package/src/protocol/translation/tool-repair.ts +1 -1
  310. package/src/protocol/upstream/post-json.ts +6 -1
  311. package/src/providers/adapters/compatible-adapter.ts +71 -4
  312. package/src/providers/authentication/jwt-validator.ts +0 -5
  313. package/src/providers/authentication/oauth-client.ts +254 -253
  314. package/src/providers/authentication/oauth-flow-store.ts +42 -7
  315. package/src/providers/bundled-discovery-providers.ts +6 -30
  316. package/src/providers/configured-openai-providers.ts +82 -97
  317. package/src/providers/default-registry.ts +35 -37
  318. package/src/providers/discovery/catalog/catalog-format.ts +13 -2
  319. package/src/providers/discovery/discovery-types.ts +0 -1
  320. package/src/providers/discovery/openai-model-discovery.ts +2 -2
  321. package/src/providers/discovery/probe-phases.ts +48 -13
  322. package/src/providers/discovery/probing-service.ts +6 -8
  323. package/src/providers/integrations/agentrouter/agentrouter.ts +12 -2
  324. package/src/providers/integrations/antigravity/antigravity-oauth.ts +0 -1
  325. package/src/providers/integrations/antigravity/antigravity-protocol.ts +88 -28
  326. package/src/providers/integrations/antigravity/antigravity-quota.ts +18 -6
  327. package/src/providers/integrations/antigravity/antigravity.ts +22 -13
  328. package/src/providers/integrations/buddy/buddy-catalog-shared.ts +1 -1
  329. package/src/providers/integrations/buddy/buddy-chat-shared.ts +20 -4
  330. package/src/providers/integrations/buddy/buddy-cli-headers.ts +19 -52
  331. package/src/providers/integrations/buddy/buddy-identity.ts +86 -0
  332. package/src/providers/integrations/buddy/buddy-oauth-shared.ts +1 -1
  333. package/src/providers/integrations/buddy/codebuddy/cn-provider.ts +1 -2
  334. package/src/providers/integrations/buddy/codebuddy/provider.ts +4 -15
  335. package/src/providers/integrations/buddy/codebuddy/shared.ts +30 -9
  336. package/src/providers/integrations/buddy/workbuddy/provider.ts +5 -9
  337. package/src/providers/integrations/buddy/workbuddy/shared.ts +21 -3
  338. package/src/providers/integrations/claude/claude-cch.ts +148 -148
  339. package/src/providers/integrations/claude/fallback-credit.ts +3 -7
  340. package/src/providers/integrations/cline/cline.ts +1 -1
  341. package/src/providers/integrations/codex/codex-device-code.ts +101 -101
  342. package/src/providers/integrations/codex/codex-oauth.ts +0 -1
  343. package/src/providers/integrations/commandcode/commandcode.ts +75 -115
  344. package/src/providers/integrations/commandcode/quota.ts +131 -51
  345. package/src/providers/integrations/cursor/cursor-http2.ts +0 -3
  346. package/src/providers/integrations/cursor/cursor-quota.ts +2 -6
  347. package/src/providers/integrations/cursor/cursor-request.ts +0 -87
  348. package/src/providers/integrations/cursor/cursor-shared.ts +0 -4
  349. package/src/providers/integrations/cursor/cursor.ts +35 -3
  350. package/src/providers/integrations/cursor/protocol/framing.ts +0 -56
  351. package/src/providers/integrations/cursor/protocol/messages.ts +0 -96
  352. package/src/providers/integrations/factory/factory.ts +9 -9
  353. package/src/providers/integrations/github/github-discovery.ts +70 -12
  354. package/src/providers/integrations/github/github-oauth.ts +184 -14
  355. package/src/providers/integrations/github/github.ts +134 -26
  356. package/src/providers/integrations/grok/grok-oauth.ts +261 -261
  357. package/src/providers/integrations/grok/grok-quota-frame.ts +1 -1
  358. package/src/providers/integrations/grok/grok-quota.ts +16 -7
  359. package/src/providers/integrations/grok/grok-ratelimit-store.ts +0 -5
  360. package/src/providers/integrations/grok/grok-ratelimit.ts +3 -0
  361. package/src/providers/integrations/grok/grok.ts +86 -36
  362. package/src/providers/integrations/kilo/kilo-oauth.ts +1 -1
  363. package/src/providers/integrations/kiro/kiro-cache.ts +31 -0
  364. package/src/providers/integrations/kiro/kiro-catalog.ts +31 -5
  365. package/src/providers/integrations/kiro/kiro-discovery.ts +47 -43
  366. package/src/providers/integrations/kiro/kiro-machine-id.ts +6 -3
  367. package/src/providers/integrations/kiro/kiro-oauth.ts +523 -255
  368. package/src/providers/integrations/kiro/kiro-quota.ts +35 -47
  369. package/src/providers/integrations/kiro/kiro-request.ts +8 -11
  370. package/src/providers/integrations/kiro/kiro-stream.ts +13 -0
  371. package/src/providers/integrations/kiro/kiro.ts +80 -68
  372. package/src/providers/integrations/muse/muse-oauth.ts +0 -1
  373. package/src/providers/integrations/muse/muse-quota.ts +0 -4
  374. package/src/providers/integrations/opencode/fingerprint.ts +7 -5
  375. package/src/providers/integrations/opencode/provider.ts +17 -24
  376. package/src/providers/integrations/qoder/qoder-catalog.ts +94 -11
  377. package/src/providers/integrations/qoder/qoder-oauth.ts +165 -25
  378. package/src/providers/integrations/qoder/qoder-quota.ts +48 -6
  379. package/src/providers/integrations/qoder/qoder-realm.ts +10 -31
  380. package/src/providers/integrations/qoder/qoder-sse.ts +159 -0
  381. package/src/providers/integrations/qoder/qoder-umid.ts +21 -25
  382. package/src/providers/integrations/qoder/qoder-virtual.ts +12 -0
  383. package/src/providers/integrations/qoder/qoder.ts +422 -71
  384. package/src/providers/integrations/shared/connect.ts +0 -54
  385. package/src/providers/integrations/shared/hash.ts +15 -0
  386. package/src/providers/integrations/shared/session-cache.ts +136 -0
  387. package/src/providers/integrations/trae/trae-cache.ts +7 -87
  388. package/src/providers/integrations/trae/trae-catalog.ts +1 -6
  389. package/src/providers/integrations/trae/trae-protocol.ts +17 -8
  390. package/src/providers/integrations/trae/trae-realm.ts +0 -7
  391. package/src/providers/integrations/trae/trae.ts +51 -8
  392. package/src/providers/integrations/xai/xai-oauth.ts +5 -5
  393. package/src/providers/integrations/zcode-start-plan/gifts.ts +265 -0
  394. package/src/providers/integrations/zcode-start-plan/oauth.ts +154 -0
  395. package/src/providers/integrations/zcode-start-plan/provider.ts +131 -0
  396. package/src/providers/integrations/zcode-start-plan/quota.ts +152 -0
  397. package/src/providers/integrations/zcode-start-plan/zcode_prompt.json +10 -0
  398. package/src/providers/operations/account-error-classification.ts +198 -133
  399. package/src/providers/operations/account-health-service.ts +31 -39
  400. package/src/providers/operations/account-reset-service.ts +58 -1
  401. package/src/providers/operations/byok-wire-profile.ts +19 -15
  402. package/src/providers/operations/cli-platform.ts +31 -5
  403. package/src/providers/operations/client-version-resolver.ts +4 -6
  404. package/src/providers/operations/client-versions.ts +10 -7
  405. package/src/providers/operations/provider-catalog-seeder.ts +2 -0
  406. package/src/providers/operations/provider-catalog-service.ts +18 -2
  407. package/src/providers/operations/provider-credential-service.ts +19 -2
  408. package/src/providers/provider-contracts.ts +18 -7
  409. package/src/providers/provider-metadata.ts +17 -2
  410. package/src/providers/provider-model-definition.ts +22 -1
  411. package/src/providers/provider-probe.ts +4 -2
  412. package/src/providers/provider-usage.ts +50 -19
  413. package/src/providers/quota/cache.ts +29 -0
  414. package/src/providers/quota/quota-contracts.ts +4 -0
  415. package/src/providers/quota/refresh.ts +27 -4
  416. package/src/providers/quota/snapshot.ts +94 -0
  417. package/src/providers/search/search-provider.ts +1 -3
  418. package/src/providers/search/search-providers.ts +2 -1
  419. package/src/security/abuse.ts +4 -4
  420. package/src/security/admission/service.ts +13 -6
  421. package/src/security/admission/ttl.ts +61 -61
  422. package/src/security/api-key-auth.ts +17 -3
  423. package/src/security/client-router-fingerprint.ts +4 -4
  424. package/src/security/credential-codec.ts +3 -3
  425. package/src/security/csrf.ts +2 -2
  426. package/src/security/ip-boundary.ts +16 -189
  427. package/src/security/model-access-rule.ts +1 -1
  428. package/src/security/outbound-headers.ts +18 -0
  429. package/src/shared/invoke-guard.ts +47 -0
  430. package/src/transport/contracts.ts +13 -4
  431. package/src/transport/dispatch/attempt-finalize.ts +70 -22
  432. package/src/transport/dispatch/attempt-loop.ts +22 -0
  433. package/src/transport/dispatch/capture-policy.ts +34 -37
  434. package/src/transport/dispatch/empty-stream.ts +23 -20
  435. package/src/transport/dispatch/generation.ts +25 -45
  436. package/src/transport/dispatch/native-shared.ts +127 -0
  437. package/src/transport/dispatch/proxy-request.ts +3 -1
  438. package/src/transport/dispatch/responses-compact.ts +25 -46
  439. package/src/transport/dispatch/streaming/encoder.ts +18 -72
  440. package/src/transport/dispatch/streaming/finalize.ts +2 -2
  441. package/src/transport/dispatch/streaming/stream.ts +7 -3
  442. package/src/transport/dispatch/streaming/thinking-loop.ts +1 -1
  443. package/src/transport/dispatch/systemone.ts +20 -48
  444. package/src/transport/dispatch/token-count.ts +41 -38
  445. package/src/transport/dispatch/websearch.ts +19 -45
  446. package/src/transport/drain-endpoint.ts +1 -1
  447. package/src/transport/failure-policy.ts +21 -1
  448. package/src/transport/guards/auth-guard.ts +0 -6
  449. package/src/transport/guards/body-policy.ts +3 -3
  450. package/src/transport/guards/error-lifecycle.ts +4 -0
  451. package/src/transport/guards/headroom-guard.ts +1 -1
  452. package/src/transport/guards/pipeline.ts +1 -1
  453. package/src/transport/guards/request-context.ts +12 -17
  454. package/src/transport/request/preparer.ts +286 -7
  455. package/src/transport/request/rtk/compress-request.ts +3 -3
  456. package/src/transport/request/rtk/rtk-constants.ts +2 -2
  457. package/src/transport/request/rtk/rtk-filters.ts +8 -8
  458. package/src/transport/request/state.ts +7 -13
  459. package/src/transport/request/system-prompt-injection.ts +74 -11
  460. package/src/transport/request/tenant-preferences.ts +22 -0
  461. package/src/transport/routing/candidate-index.ts +2 -2
  462. package/src/transport/routing/round-robin.ts +1 -1
  463. package/src/transport/routing/route-catalog.ts +17 -18
  464. package/src/transport/routing/route-model.ts +126 -33
  465. package/src/transport/routing/router.ts +159 -37
  466. package/src/transport/shutdown-notice.ts +2 -2
  467. package/src/transport/surface/adapters.ts +3 -3
  468. package/src/transport/surface/chat/encode.ts +7 -7
  469. package/src/transport/surface/chat/parse.ts +7 -7
  470. package/src/transport/surface/completion.ts +2 -2
  471. package/src/transport/surface/content-parts.ts +1 -1
  472. package/src/transport/surface/dialects.ts +2 -2
  473. package/src/transport/surface/messages/parse.ts +3 -3
  474. package/src/transport/surface/reasoning-summary.ts +9 -14
  475. package/src/transport/surface/responses/adapter.ts +1 -1
  476. package/src/transport/surface/responses/errors.ts +0 -9
  477. package/src/transport/vision-handoff-cache.ts +58 -0
  478. package/src/transport/vision-handoff.ts +431 -0
  479. package/src/workers/account-identity-sweep.ts +2 -2
  480. package/src/workers/buddy-growth-tasks.ts +392 -346
  481. package/src/workers/daily-checkin.ts +102 -49
  482. package/src/workers/maintenance-lease.ts +2 -35
  483. package/src/workers/oauth-refresh-sweep.ts +8 -1
  484. package/src/workers/quota-refresh-sweep.ts +120 -82
  485. package/src/workers/scheduler.ts +67 -4
  486. package/src/workers/sweep-runner.ts +24 -5
  487. package/src/workers/zcode-gift-claim.ts +108 -0
  488. package/dist/dashboard/assets/AccountCooldown-Bjo92Qat.js +0 -1
  489. package/dist/dashboard/assets/AccountCooldown-Bjo92Qat.js.gz +0 -0
  490. package/dist/dashboard/assets/BannedPage-ChG5svFb.js +0 -1
  491. package/dist/dashboard/assets/BannedPage-ChG5svFb.js.gz +0 -0
  492. package/dist/dashboard/assets/CliToolDetailPage-BIcWQun7.js +0 -1
  493. package/dist/dashboard/assets/CliToolDetailPage-BIcWQun7.js.gz +0 -0
  494. package/dist/dashboard/assets/CliToolsPage-Bf2VelDe.js +0 -1
  495. package/dist/dashboard/assets/CliToolsPage-Bf2VelDe.js.gz +0 -0
  496. package/dist/dashboard/assets/CombosPage-DCgm5g6g.js +0 -1
  497. package/dist/dashboard/assets/CombosPage-DCgm5g6g.js.gz +0 -0
  498. package/dist/dashboard/assets/ConsoleLogPage-a8mD0QF1.js +0 -1
  499. package/dist/dashboard/assets/ConsoleLogPage-a8mD0QF1.js.gz +0 -0
  500. package/dist/dashboard/assets/CustomizationPage-ggeMSjte.js +0 -1
  501. package/dist/dashboard/assets/CustomizationPage-ggeMSjte.js.gz +0 -0
  502. package/dist/dashboard/assets/HealthEventsModal-DzSWzE_j.js +0 -1
  503. package/dist/dashboard/assets/HealthEventsModal-DzSWzE_j.js.gz +0 -0
  504. package/dist/dashboard/assets/LoginPage-U6AKaJcF.js +0 -1
  505. package/dist/dashboard/assets/LoginPage-U6AKaJcF.js.gz +0 -0
  506. package/dist/dashboard/assets/ModelPicker-BMS2t8BA.js.gz +0 -0
  507. package/dist/dashboard/assets/OverviewPage-D2D4IiHl.js +0 -1
  508. package/dist/dashboard/assets/OverviewPage-D2D4IiHl.js.gz +0 -0
  509. package/dist/dashboard/assets/ProviderDetailPage-CrNf7j_X.js +0 -5
  510. package/dist/dashboard/assets/ProviderDetailPage-CrNf7j_X.js.gz +0 -0
  511. package/dist/dashboard/assets/ProviderIcon-FB6yS4v1.js +0 -1
  512. package/dist/dashboard/assets/ProviderIcon-FB6yS4v1.js.gz +0 -0
  513. package/dist/dashboard/assets/ProvidersPage-BSDbquc1.js +0 -1
  514. package/dist/dashboard/assets/ProvidersPage-BSDbquc1.js.gz +0 -0
  515. package/dist/dashboard/assets/ProxyPage-lsrx7NYg.js.gz +0 -0
  516. package/dist/dashboard/assets/QuotaPage-L0skzML8.js +0 -1
  517. package/dist/dashboard/assets/QuotaPage-L0skzML8.js.gz +0 -0
  518. package/dist/dashboard/assets/SettingsPage-CmAbjRHW.js +0 -1
  519. package/dist/dashboard/assets/SettingsPage-CmAbjRHW.js.gz +0 -0
  520. package/dist/dashboard/assets/SetupPage-f0DE1h0-.js +0 -1
  521. package/dist/dashboard/assets/SetupPage-f0DE1h0-.js.gz +0 -0
  522. package/dist/dashboard/assets/SortableList-ClzpwyET.js +0 -1
  523. package/dist/dashboard/assets/SortableList-ClzpwyET.js.gz +0 -0
  524. package/dist/dashboard/assets/StudioPage-Cq5tW7hW.js.gz +0 -0
  525. package/dist/dashboard/assets/ToolIcon-K1ckcDKg.js +0 -1
  526. package/dist/dashboard/assets/ToolIcon-K1ckcDKg.js.gz +0 -0
  527. package/dist/dashboard/assets/UsagePage-Dfc9rWQn.js +0 -56
  528. package/dist/dashboard/assets/UsagePage-Dfc9rWQn.js.gz +0 -0
  529. package/dist/dashboard/assets/api-keys-C38iXoO4.js +0 -1
  530. package/dist/dashboard/assets/api-keys-C38iXoO4.js.gz +0 -0
  531. package/dist/dashboard/assets/app-BayTTy01.js +0 -9
  532. package/dist/dashboard/assets/app-BayTTy01.js.gz +0 -0
  533. package/dist/dashboard/assets/app-a159k0ub.css +0 -2
  534. package/dist/dashboard/assets/app-a159k0ub.css.gz +0 -0
  535. package/dist/dashboard/assets/assert-DbRA8EG2.js +0 -15
  536. package/dist/dashboard/assets/assert-DbRA8EG2.js.gz +0 -0
  537. package/dist/dashboard/assets/badge-D9CS6dZk.js.gz +0 -0
  538. package/dist/dashboard/assets/banner-DympBNq4.js.gz +0 -0
  539. package/dist/dashboard/assets/card-ibRWU_uT.js.gz +0 -0
  540. package/dist/dashboard/assets/cli-tools-63qBGaRw.js +0 -1
  541. package/dist/dashboard/assets/cli-tools-63qBGaRw.js.gz +0 -0
  542. package/dist/dashboard/assets/clipboard-button-DJm-9pz7.js.gz +0 -0
  543. package/dist/dashboard/assets/dialog-8fiE6tec.js +0 -1
  544. package/dist/dashboard/assets/dialog-8fiE6tec.js.gz +0 -0
  545. package/dist/dashboard/assets/drawer-CqGYeOrd.js.gz +0 -0
  546. package/dist/dashboard/assets/entry-BSAsYsmV.js +0 -1
  547. package/dist/dashboard/assets/entry-BSAsYsmV.js.gz +0 -0
  548. package/dist/dashboard/assets/entry-CiIQULZD.js +0 -4
  549. package/dist/dashboard/assets/entry-CiIQULZD.js.gz +0 -0
  550. package/dist/dashboard/assets/entry-Daz0lJ-W.js +0 -1
  551. package/dist/dashboard/assets/entry-Daz0lJ-W.js.gz +0 -0
  552. package/dist/dashboard/assets/formatters-D-MTJxMr.js.gz +0 -0
  553. package/dist/dashboard/assets/github-badge-CPK47xQx.js +0 -1
  554. package/dist/dashboard/assets/github-badge-CPK47xQx.js.gz +0 -0
  555. package/dist/dashboard/assets/index-DBNPOfhV.js.gz +0 -0
  556. package/dist/dashboard/assets/inline-BT0zntEr.js.gz +0 -0
  557. package/dist/dashboard/assets/input-Da2ZViWg.js.gz +0 -0
  558. package/dist/dashboard/assets/layout-BXNeLw6M.js.gz +0 -0
  559. package/dist/dashboard/assets/list-row-BycOrrIV.js.gz +0 -0
  560. package/dist/dashboard/assets/live-DCQNZpF7.js +0 -1
  561. package/dist/dashboard/assets/live-DCQNZpF7.js.gz +0 -0
  562. package/dist/dashboard/assets/mutation-Rr0TIvcj.js.gz +0 -0
  563. package/dist/dashboard/assets/network-9Yj2ZyLo.js +0 -1
  564. package/dist/dashboard/assets/network-9Yj2ZyLo.js.gz +0 -0
  565. package/dist/dashboard/assets/numbers-CEagj6ZZ.js +0 -2
  566. package/dist/dashboard/assets/numbers-CEagj6ZZ.js.gz +0 -0
  567. package/dist/dashboard/assets/providers/zai-coding-plan.svg +0 -6
  568. package/dist/dashboard/assets/providers/zai-coding-plan.svg.gz +0 -0
  569. package/dist/dashboard/assets/quota-Caw7wqci.js +0 -1
  570. package/dist/dashboard/assets/quota-Caw7wqci.js.gz +0 -0
  571. package/dist/dashboard/assets/routing-CO9zCUus.js +0 -1
  572. package/dist/dashboard/assets/routing-CO9zCUus.js.gz +0 -0
  573. package/dist/dashboard/assets/select-BIYIBkMU.js.gz +0 -0
  574. package/dist/dashboard/assets/settings-jS3-PNSA.js +0 -1
  575. package/dist/dashboard/assets/settings-jS3-PNSA.js.gz +0 -0
  576. package/dist/dashboard/assets/stack-DfgnFDWY.js.gz +0 -0
  577. package/dist/dashboard/assets/state-CkfdYWel.js.gz +0 -0
  578. package/dist/dashboard/assets/stream-retry-5QnVuSSo.js +0 -1
  579. package/dist/dashboard/assets/stream-retry-5QnVuSSo.js.gz +0 -0
  580. package/dist/dashboard/assets/switch-SYm237HG.js.gz +0 -0
  581. package/dist/dashboard/assets/useMutation-BQqCRNIi.js.gz +0 -0
  582. package/src/console/cli-tools/injectors/cline.ts +0 -110
  583. package/src/console/cli-tools/injectors/copilot.ts +0 -108
  584. package/src/console/cli-tools/injectors/cowork.ts +0 -64
  585. package/src/console/cli-tools/injectors/deepseek-tui.ts +0 -85
  586. package/src/console/cli-tools/injectors/droid.ts +0 -96
  587. package/src/console/cli-tools/injectors/grok-build.ts +0 -70
  588. package/src/console/cli-tools/injectors/hermes.ts +0 -101
  589. package/src/console/cli-tools/injectors/jcode.ts +0 -115
  590. package/src/console/cli-tools/injectors/openclaw.ts +0 -161
  591. package/src/network/response-headers.ts +0 -39
  592. package/src/protocol/response/dsml.ts +0 -38
  593. package/src/providers/integrations/xiaomi-mimo/think-stream.ts +0 -229
  594. /package/dist/dashboard/assets/brand/{og_bansos.webp → og_bansos_initial.webp} +0 -0
  595. /package/dist/dashboard/assets/brand/{og_image.webp → og_image_initial.webp} +0 -0
@@ -1,247 +1,150 @@
1
- // Declarative file injector driver and lifecycle contracts.
2
-
3
- import { dirname } from "node:path";
4
- import type {
5
- ApplyInput,
6
- ApplyResult,
7
- DownloadResult,
8
- InjectorSpec,
9
- ToolDef,
10
- ToolId,
11
- ToolInjector,
12
- ToolStatus,
13
- } from "../contracts";
14
- import { TOOL_IDS, TOOL_REGISTRY } from "../contracts";
15
- import { checkBinaryInstalled, ensureDir, ensureV1Suffix, fileExists, keyPrefix } from "../fs-ops";
16
- import { claudeSpec } from './claude';
17
- import { clineSpec } from './cline';
18
- import { codexSpec } from './codex';
19
- import { copilotSpec } from './copilot';
20
- import { coworkSpec } from './cowork';
21
- import { deepseekTuiSpec } from './deepseek-tui';
22
- import { droidSpec } from './droid';
23
- import { grokBuildSpec } from './grok-build';
24
- import { hermesSpec } from './hermes';
25
- import { jcodeSpec } from './jcode';
26
- import { kiloSpec } from './kilo';
27
- import { openclawSpec } from './openclaw';
28
- import { opencodeSpec } from './opencode';
29
-
30
- // ── injectors/driver.ts ──
31
- /**
32
- * Generic driver and declarative spec types for CLI tool injectors.
33
- *
34
- * Implements the probe -> read -> apply -> write lifecycle for file-based
35
- * CLI tool injectors, eliminating repetitive boilerplate while allowing
36
- * tool-specific escape hatches.
37
- */
38
-
39
- /**
40
- * Create a ToolInjector from a declarative InjectorSpec.
41
- */
42
- export function createFileInjector(spec: InjectorSpec): ToolInjector {
43
- return {
44
- toolId: spec.toolId,
45
- async getStatus(): Promise<ToolStatus> {
46
- const path = spec.resolvePath();
47
- const installed = spec.checkInstalled
48
- ? await spec.checkInstalled(path)
49
- : spec.binary
50
- ? await checkBinaryInstalled(spec.binary)
51
- : await fileExists(path);
52
-
53
- const exists = await fileExists(path);
54
- if (!installed && !exists) {
55
- return {
56
- toolId: spec.toolId,
57
- installed: false,
58
- configured: false,
59
- settingsPath: spec.keepSettingsPathOnMissing ? path : null,
60
- currentEndpoint: null,
61
- currentApiKeyPrefix: null,
62
- currentModels: null,
63
- };
64
- }
65
-
66
- if (!exists) {
67
- return {
68
- toolId: spec.toolId,
69
- installed,
70
- configured: false,
71
- settingsPath: path,
72
- currentEndpoint: null,
73
- currentApiKeyPrefix: null,
74
- currentModels: null,
75
- };
76
- }
77
-
78
- const details = await spec.readStatus(path);
79
- return {
80
- toolId: spec.toolId,
81
- installed: true,
82
- configured: details.configured,
83
- settingsPath: path,
84
- currentEndpoint: details.currentEndpoint ?? null,
85
- currentApiKeyPrefix: details.currentApiKeyPrefix ?? keyPrefix(details.rawApiKey) ?? null,
86
- currentModels: details.currentModels ?? null,
87
- ...(details.message ? { message: details.message } : {}),
88
- };
89
- },
90
-
91
- async apply(input: ApplyInput): Promise<ApplyResult> {
92
- const path = spec.resolvePath();
93
- const dir = spec.resolveDir ? spec.resolveDir() : dirname(path);
94
- await ensureDir(dir);
95
- await spec.apply(input, path);
96
- return {
97
- success: true,
98
- settingsPath: path,
99
- message: spec.messages?.applied ?? `${spec.displayName ?? spec.toolId} settings applied`,
100
- };
101
- },
102
-
103
- async reset(): Promise<ApplyResult> {
104
- const path = spec.resolvePath();
105
- const exists = await fileExists(path);
106
- if (!exists && !spec.resetEvenIfMissing) {
107
- return {
108
- success: true,
109
- message: spec.messages?.resetMissing ?? `No settings file to reset`,
110
- };
111
- }
112
- const resetResult = await spec.reset(path);
113
- if (resetResult === false) {
114
- return {
115
- success: true,
116
- message: spec.messages?.resetMissing ?? `No settings file to reset`,
117
- };
118
- }
119
- return {
120
- success: true,
121
- settingsPath: path,
122
- message:
123
- spec.messages?.reset ??
124
- `Cartethyia settings removed from ${spec.displayName ?? spec.toolId}`,
125
- };
126
- },
127
-
128
- async download(input: ApplyInput): Promise<DownloadResult> {
129
- return spec.download(input);
130
- },
131
- };
132
- }
133
-
134
- /** Create a guide injector for a specific tool definition (any `configType: "guide"` entry). */
135
- export function guideInjectorFor(def: ToolDef): ToolInjector {
136
- return {
137
- toolId: def.id,
138
-
139
- async getStatus(): Promise<ToolStatus> {
140
- // Guide tools are always "not installed" from an injection standpoint —
141
- // we can't detect the binary reliably, and config is manual.
142
- return {
143
- toolId: def.id,
144
- installed: false,
145
- configured: false,
146
- settingsPath: null,
147
- currentEndpoint: null,
148
- currentApiKeyPrefix: null,
149
- currentModels: null,
150
- message: "Guide-only tool — use Download Config to get setup instructions",
151
- };
152
- },
153
-
154
- async apply(): Promise<ApplyResult> {
155
- return { success: false, message: `${def.name} is a guide-only tool — use Download Config` };
156
- },
157
-
158
- async reset(): Promise<ApplyResult> {
159
- return { success: true, message: `${def.name} has no injected config to reset` };
160
- },
161
-
162
- async download(input: ApplyInput): Promise<DownloadResult> {
163
- const baseUrl = ensureV1Suffix(input.endpoint);
164
- const model = input.activeModel ?? input.modelIds[0] ?? "";
165
- const apiKey = input.apiKey;
166
- const codeBlock = def.codeBlock;
167
-
168
- if (codeBlock) {
169
- const content = codeBlock.code
170
- .replace(/\{\{baseUrl\}\}/g, baseUrl)
171
- .replace(/\{\{apiKey\}\}/g, apiKey)
172
- .replace(/\{\{model\}\}/g, model);
173
- const ext =
174
- codeBlock.language === "json" ? "json" : codeBlock.language === "bash" ? "sh" : "txt";
175
- return {
176
- content,
177
- filename: `${def.id}-config.${ext}`,
178
- mimeType: codeBlock.language === "json" ? "application/json" : "text/plain",
179
- };
180
- }
181
-
182
- // No code block — generate a simple guide summary.
183
- const steps = def.guideSteps ?? [];
184
- const lines = [`# ${def.name} — Setup Guide`, ""];
185
- for (const step of steps) {
186
- lines.push(`## Step ${step.step}: ${step.title}`);
187
- if (step.desc) lines.push(step.desc);
188
- if (step.value) {
189
- lines.push("```");
190
- lines.push(
191
- step.value
192
- .replace(/\{\{baseUrl\}\}/g, baseUrl)
193
- .replace(/\{\{apiKey\}\}/g, apiKey)
194
- .replace(/\{\{model\}\}/g, model),
195
- );
196
- lines.push("```");
197
- }
198
- lines.push("");
199
- }
200
- lines.push(`Endpoint: ${baseUrl}`);
201
- lines.push(`API Key: ${apiKey}`);
202
- lines.push(`Model: ${model}`);
203
- return { content: lines.join("\n"), filename: `${def.id}-guide.txt`, mimeType: "text/plain" };
204
- },
205
- };
206
- }
207
-
208
- // ── injectors/index.ts ──
209
- /**
210
- * Single dispatch point for CliToolService: given a toolId, look up the
211
- * injector and call getStatus/apply/reset/download.
212
- *
213
- * File-based injectors are driven by a generic driver (createFileInjector)
214
- * configured via declarative specs. Guide-only tools (registry `configType:
215
- * "guide"`) are all built from `guideInjectorFor` — no per-tool constant
216
- * needed; the registry itself is the single source of the list. The map is
217
- * built exhaustively from that registry so a non-guide tool without an
218
- * injector fails loudly at import, never silently at lookup time.
219
- */
220
- const FILE_INJECTORS: Partial<Record<ToolId, ToolInjector>> = {
221
- claude: createFileInjector(claudeSpec),
222
- codex: createFileInjector(codexSpec),
223
- cline: createFileInjector(clineSpec),
224
- opencode: createFileInjector(opencodeSpec),
225
- droid: createFileInjector(droidSpec),
226
- hermes: createFileInjector(hermesSpec),
227
- "grok-build": createFileInjector(grokBuildSpec),
228
- copilot: createFileInjector(copilotSpec),
229
- "deepseek-tui": createFileInjector(deepseekTuiSpec),
230
- jcode: createFileInjector(jcodeSpec),
231
- kilo: createFileInjector(kiloSpec),
232
- openclaw: createFileInjector(openclawSpec),
233
- cowork: createFileInjector(coworkSpec),
234
- };
235
-
236
- export const INJECTORS: Record<ToolId, ToolInjector> = Object.fromEntries(
237
- TOOL_IDS.map((id) => {
238
- const injector =
239
- TOOL_REGISTRY[id].configType === "guide"
240
- ? guideInjectorFor(TOOL_REGISTRY[id])
241
- : FILE_INJECTORS[id];
242
- if (injector === undefined) {
243
- throw new Error(`No injector registered for tool: ${id}`);
244
- }
245
- return [id, injector];
246
- }),
247
- ) as Record<ToolId, ToolInjector>;
1
+ // Declarative file injector driver and lifecycle contracts.
2
+
3
+ import { dirname } from "node:path";
4
+ import type {
5
+ ApplyInput,
6
+ ApplyResult,
7
+ DownloadResult,
8
+ InjectorSpec,
9
+ ToolId,
10
+ ToolInjector,
11
+ ToolStatus,
12
+ } from "../contracts";
13
+ import { TOOL_IDS } from "../contracts";
14
+ import { checkBinaryInstalled, ensureDir, fileExists, keyPrefix } from "../fs-ops";
15
+ import { claudeSpec } from './claude';
16
+ import { codexSpec } from './codex';
17
+ import { kiloSpec } from './kilo';
18
+ import { opencodeSpec } from './opencode';
19
+
20
+ // ── injectors/driver.ts ──
21
+ /**
22
+ * Generic driver and declarative spec types for CLI tool injectors.
23
+ *
24
+ * Implements the probe -> read -> apply -> write lifecycle for file-based
25
+ * CLI tool injectors, eliminating repetitive boilerplate while allowing
26
+ * tool-specific escape hatches.
27
+ */
28
+
29
+ /**
30
+ * Create a ToolInjector from a declarative InjectorSpec.
31
+ */
32
+ export function createFileInjector(spec: InjectorSpec): ToolInjector {
33
+ return {
34
+ toolId: spec.toolId,
35
+ async getStatus(): Promise<ToolStatus> {
36
+ const path = spec.resolvePath();
37
+ const installed = spec.checkInstalled
38
+ ? await spec.checkInstalled(path)
39
+ : spec.binary
40
+ ? await checkBinaryInstalled(spec.binary)
41
+ : await fileExists(path);
42
+
43
+ const exists = await fileExists(path);
44
+ if (!installed && !exists) {
45
+ return {
46
+ toolId: spec.toolId,
47
+ installed: false,
48
+ configured: false,
49
+ settingsPath: spec.keepSettingsPathOnMissing ? path : null,
50
+ currentEndpoint: null,
51
+ currentApiKeyPrefix: null,
52
+ currentModels: null,
53
+ };
54
+ }
55
+
56
+ if (!exists) {
57
+ return {
58
+ toolId: spec.toolId,
59
+ installed,
60
+ configured: false,
61
+ settingsPath: path,
62
+ currentEndpoint: null,
63
+ currentApiKeyPrefix: null,
64
+ currentModels: null,
65
+ };
66
+ }
67
+
68
+ const details = await spec.readStatus(path);
69
+ return {
70
+ toolId: spec.toolId,
71
+ installed: true,
72
+ configured: details.configured,
73
+ settingsPath: path,
74
+ currentEndpoint: details.currentEndpoint ?? null,
75
+ currentApiKeyPrefix: details.currentApiKeyPrefix ?? keyPrefix(details.rawApiKey) ?? null,
76
+ currentModels: details.currentModels ?? null,
77
+ ...(details.message ? { message: details.message } : {}),
78
+ };
79
+ },
80
+
81
+ async apply(input: ApplyInput): Promise<ApplyResult> {
82
+ const path = spec.resolvePath();
83
+ const dir = spec.resolveDir ? spec.resolveDir() : dirname(path);
84
+ await ensureDir(dir);
85
+ const warnings = await spec.apply(input, path);
86
+ return {
87
+ success: true,
88
+ settingsPath: path,
89
+ message: spec.messages?.applied ?? `${spec.displayName ?? spec.toolId} settings applied`,
90
+ ...(Array.isArray(warnings) && warnings.length > 0 ? { warnings } : {}),
91
+ };
92
+ },
93
+
94
+ async reset(): Promise<ApplyResult> {
95
+ const path = spec.resolvePath();
96
+ const exists = await fileExists(path);
97
+ if (!exists && !spec.resetEvenIfMissing) {
98
+ return {
99
+ success: true,
100
+ message: spec.messages?.resetMissing ?? `No settings file to reset`,
101
+ };
102
+ }
103
+ const resetResult = await spec.reset(path);
104
+ if (resetResult === false) {
105
+ return {
106
+ success: true,
107
+ message: spec.messages?.resetMissing ?? `No settings file to reset`,
108
+ };
109
+ }
110
+ return {
111
+ success: true,
112
+ settingsPath: path,
113
+ message:
114
+ spec.messages?.reset ??
115
+ `Cartethyia settings removed from ${spec.displayName ?? spec.toolId}`,
116
+ };
117
+ },
118
+
119
+ async download(input: ApplyInput): Promise<DownloadResult> {
120
+ return spec.download(input);
121
+ },
122
+ };
123
+ }
124
+
125
+ // ── injectors/index.ts ──
126
+ /**
127
+ * Single dispatch point for CliToolService: given a toolId, look up the
128
+ * injector and call getStatus/apply/reset/download.
129
+ *
130
+ * File-based injectors are driven by a generic driver (createFileInjector)
131
+ * configured via declarative specs. The map is built exhaustively from that
132
+ * registry so a tool without an injector fails loudly at import, never
133
+ * silently at lookup time.
134
+ */
135
+ const FILE_INJECTORS: Partial<Record<ToolId, ToolInjector>> = {
136
+ claude: createFileInjector(claudeSpec),
137
+ codex: createFileInjector(codexSpec),
138
+ opencode: createFileInjector(opencodeSpec),
139
+ kilo: createFileInjector(kiloSpec),
140
+ };
141
+
142
+ export const INJECTORS: Record<ToolId, ToolInjector> = Object.fromEntries(
143
+ TOOL_IDS.map((id) => {
144
+ const injector = FILE_INJECTORS[id];
145
+ if (injector === undefined) {
146
+ throw new Error(`No injector registered for tool: ${id}`);
147
+ }
148
+ return [id, injector];
149
+ }),
150
+ ) as Record<ToolId, ToolInjector>;
@@ -1,13 +1,36 @@
1
1
  import { platform } from "node:os";
2
2
  import type {} from "../contracts";
3
- import { resolveApplyTarget, jsonDownload } from "../contracts";
4
- import { homeDir, isLocalEndpoint, join, readJsonFile, writeJsonFile } from "../fs-ops";
3
+ import { jsonDownload } from "../contracts";
4
+ import { homeDir, isLocalEndpoint, join, readJsonFile, writeJsonFileWithBackup } from "../fs-ops";
5
5
  import type { InjectorSpec } from "../contracts";
6
6
 
7
7
  const IS_WIN = platform() === "win32";
8
8
  const IS_MAC = platform() === "darwin";
9
9
 
10
10
  // Kilo Code injector spec.
11
+ //
12
+ // Kilo Code is a fork of OpenCode, but it now reads its own config file —
13
+ // `~/.config/kilo/kilo.jsonc` (Windows: `%USERPROFILE%\.config\kilo\kilo.jsonc`)
14
+ // — with the same provider shape as OpenCode: `provider.<id>.npm/options/models`
15
+ // plus a top-level `model`. Unlike OpenCode, Kilo runs on the AI SDK, so the
16
+ // `npm` value must be an `@ai-sdk/*` package (default `@ai-sdk/openai-compatible`).
17
+ //
18
+ // The older VS Code extension also keeps a credential store at
19
+ // `~/.local/share/kilo/auth.json`; we still write the endpoint there for
20
+ // backward compatibility, but the canonical config is now `kilo.jsonc`.
21
+
22
+ const KILO_PROVIDER_ID = "cartethyia";
23
+
24
+ function resolveKiloConfigDirectory(): string {
25
+ if (IS_WIN) return join(process.env.USERPROFILE ?? homeDir(), ".config", "kilo");
26
+ if (IS_MAC) return join(homeDir(), ".config", "kilo");
27
+ return join(homeDir(), ".config", "kilo");
28
+ }
29
+
30
+ function kiloConfigPath(): string {
31
+ return join(resolveKiloConfigDirectory(), "kilo.jsonc");
32
+ }
33
+
11
34
  function resolveKiloDataDirectory(): string {
12
35
  if (IS_WIN) return join(process.env.LOCALAPPDATA ?? homeDir(), "kilo");
13
36
  if (IS_MAC) return join(homeDir(), "Library", "Application Support", "kilo");
@@ -21,15 +44,52 @@ function kiloVscodeSettingsPath(): string {
21
44
  return join(homeDir(), ".config", "Code", "User", "settings.json");
22
45
  }
23
46
 
47
+ function kiloModelDef(model: string): unknown {
48
+ return {
49
+ name: model,
50
+ limit: { context: 128000, output: 64000 },
51
+ };
52
+ }
53
+
54
+ function buildKiloModels(models: readonly string[]): Record<string, unknown> {
55
+ const map: Record<string, unknown> = {};
56
+ for (const m of models) {
57
+ if (!m) continue;
58
+ map[m] = kiloModelDef(m);
59
+ }
60
+ return map;
61
+ }
62
+
24
63
  export const kiloSpec: InjectorSpec = {
25
64
  toolId: "kilo",
26
65
  displayName: "Kilo Code",
27
66
  binary: "kilo",
28
- resolveDir: resolveKiloDataDirectory,
29
- resolvePath: () => join(resolveKiloDataDirectory(), "auth.json"),
67
+ resolveDir: resolveKiloConfigDirectory,
68
+ resolvePath: kiloConfigPath,
30
69
 
31
70
  async readStatus(path) {
32
- const auth = (await readJsonFile(path)) as Record<
71
+ const config = (await readJsonFile(path)) as {
72
+ provider?: Record<string, { npm?: string; options?: { baseURL?: string; apiKey?: string }; models?: Record<string, unknown> }>;
73
+ model?: string;
74
+ } | null;
75
+ const provider = config?.provider?.[KILO_PROVIDER_ID];
76
+ const endpoint = provider?.options?.baseURL ?? null;
77
+ const models = provider?.models ? Object.keys(provider.models) : null;
78
+ const active =
79
+ typeof config?.model === "string" && config.model.startsWith(`${KILO_PROVIDER_ID}/`)
80
+ ? config.model.split("/").slice(1).join("/")
81
+ : null;
82
+ if (endpoint) {
83
+ return {
84
+ configured: isLocalEndpoint(endpoint),
85
+ currentEndpoint: endpoint,
86
+ rawApiKey: provider?.options?.apiKey ?? null,
87
+ currentModels: active && models ? [active, ...models.filter((m) => m !== active)] : models,
88
+ };
89
+ }
90
+
91
+ // Fallback to the legacy auth.json store (older VS Code extension).
92
+ const auth = (await readJsonFile(join(resolveKiloDataDirectory(), "auth.json"))) as Record<
33
93
  string,
34
94
  { baseUrl?: string; baseURL?: string; apiKey?: string; model?: string }
35
95
  > | null;
@@ -47,22 +107,77 @@ export const kiloSpec: InjectorSpec = {
47
107
  },
48
108
 
49
109
  async apply(input, path) {
50
- const { model, baseUrl } = resolveApplyTarget(input);
51
- const auth = ((await readJsonFile(path)) as Record<string, unknown> | null) ?? {};
52
- auth["openai-compatible"] = { baseUrl, apiKey: input.apiKey, model };
53
- await writeJsonFile(path, auth);
110
+ // Canonical config: ~/.config/kilo/kilo.jsonc
111
+ const existing = (await readJsonFile(path)) as Record<string, unknown> | null;
112
+ const config: Record<string, unknown> = (existing ?? {}) as Record<string, unknown>;
113
+ if (!config.provider || typeof config.provider !== "object") config.provider = {};
114
+ const providers = config.provider as Record<string, unknown>;
115
+ const prior = (providers[KILO_PROVIDER_ID] as Record<string, unknown> | undefined) ?? {};
116
+ const priorModels = (prior.models as Record<string, unknown> | undefined) ?? {};
117
+ const otherProviders = Object.keys(providers).filter((id) => id !== KILO_PROVIDER_ID);
118
+ providers[KILO_PROVIDER_ID] = {
119
+ npm: input.sdk ?? (prior as { npm?: string }).npm ?? "@ai-sdk/openai-compatible",
120
+ options: {
121
+ ...((prior.options as Record<string, unknown> | undefined) ?? {}),
122
+ baseURL: input.endpoint,
123
+ apiKey: input.apiKey,
124
+ },
125
+ models: { ...priorModels, ...buildKiloModels(input.modelIds) },
126
+ };
127
+ const activeModel = input.activeModel ?? input.modelIds[0] ?? "";
128
+ config.model = activeModel === "" ? "" : `${KILO_PROVIDER_ID}/${activeModel}`;
129
+
130
+ // YOLO mode: auto-approve shell/read/write.
131
+ if (input.bypassPermissions === true) {
132
+ config.permissions = [
133
+ { action: "shell", resource: "*", effect: "allow" },
134
+ { action: "external_directory", resource: "*", effect: "allow" },
135
+ { action: "question", resource: "*", effect: "deny" },
136
+ ];
137
+ } else if (input.bypassPermissions === false) {
138
+ delete config.permissions;
139
+ }
140
+
141
+ await writeJsonFileWithBackup(path, config);
142
+
143
+ // Legacy credential store for the older VS Code extension.
144
+ const authPath = join(resolveKiloDataDirectory(), "auth.json");
145
+ const auth = ((await readJsonFile(authPath)) as Record<string, unknown> | null) ?? {};
146
+ auth["openai-compatible"] = { baseUrl: input.endpoint, apiKey: input.apiKey, model: activeModel };
147
+ await writeJsonFileWithBackup(authPath, auth);
54
148
 
55
149
  const settings =
56
150
  ((await readJsonFile(kiloVscodeSettingsPath())) as Record<string, unknown> | null) ?? {};
57
151
  settings["kilo.code.authProviderOverride"] = "openai-compatible";
58
- await writeJsonFile(kiloVscodeSettingsPath(), settings);
152
+ await writeJsonFileWithBackup(kiloVscodeSettingsPath(), settings);
153
+
154
+ return otherProviders.length > 0
155
+ ? [
156
+ `Config already has other provider(s): ${otherProviders.join(", ")}. They were kept as-is — only ${KILO_PROVIDER_ID} was written/updated.`,
157
+ ]
158
+ : undefined;
59
159
  },
60
160
 
61
161
  async reset(path) {
62
- const auth = (await readJsonFile(path)) as Record<string, unknown> | null;
63
- if (!auth) return false;
64
- delete auth["openai-compatible"];
65
- await writeJsonFile(path, auth);
162
+ const config = (await readJsonFile(path)) as Record<string, unknown> | null;
163
+ if (config && config.provider && typeof config.provider === "object") {
164
+ const providers = config.provider as Record<string, unknown>;
165
+ delete providers[KILO_PROVIDER_ID];
166
+ if (Object.keys(providers).length === 0) delete config.provider;
167
+ }
168
+ if (typeof config?.model === "string" && config.model.startsWith(`${KILO_PROVIDER_ID}/`)) {
169
+ delete config.model;
170
+ }
171
+ if (config) await writeJsonFileWithBackup(path, config);
172
+
173
+ const auth = (await readJsonFile(join(resolveKiloDataDirectory(), "auth.json"))) as Record<
174
+ string,
175
+ unknown
176
+ > | null;
177
+ if (auth) {
178
+ delete auth["openai-compatible"];
179
+ await writeJsonFileWithBackup(join(resolveKiloDataDirectory(), "auth.json"), auth);
180
+ }
66
181
 
67
182
  const settings = (await readJsonFile(kiloVscodeSettingsPath())) as Record<
68
183
  string,
@@ -70,21 +185,31 @@ export const kiloSpec: InjectorSpec = {
70
185
  > | null;
71
186
  if (settings && "kilo.code.authProviderOverride" in settings) {
72
187
  delete settings["kilo.code.authProviderOverride"];
73
- await writeJsonFile(kiloVscodeSettingsPath(), settings);
188
+ await writeJsonFileWithBackup(kiloVscodeSettingsPath(), settings);
74
189
  }
75
190
  },
76
191
 
77
192
  download(input) {
78
- const { model, baseUrl } = resolveApplyTarget(input);
79
- return jsonDownload({ "openai-compatible": { baseUrl, apiKey: input.apiKey, model } }, {
80
- filename: "auth.json",
81
- });
193
+ const activeModel = input.activeModel ?? input.modelIds[0] ?? "";
194
+ const config: Record<string, unknown> = {
195
+ provider: {
196
+ [KILO_PROVIDER_ID]: {
197
+ npm: input.sdk ?? "@ai-sdk/openai-compatible",
198
+ options: {
199
+ baseURL: input.endpoint,
200
+ apiKey: input.apiKey,
201
+ },
202
+ models: buildKiloModels(input.modelIds),
203
+ },
204
+ },
205
+ model: activeModel === "" ? "" : `${KILO_PROVIDER_ID}/${activeModel}`,
206
+ };
207
+ return jsonDownload(config, { filename: "kilo.jsonc" });
82
208
  },
83
209
 
84
210
  messages: {
85
211
  applied: "Kilo Code settings applied",
86
212
  reset: "Cartethyia settings removed from Kilo Code",
87
- resetMissing: "No auth file to reset",
213
+ resetMissing: "No config file to reset",
88
214
  },
89
215
  };
90
-