cartethyia 2.8.0 → 2.8.1

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 (348) hide show
  1. package/.env.example +3 -3
  2. package/dist/dashboard/assets/{BannedPage-Cc0vKpMG.js → BannedPage-Dq530awD.js} +1 -1
  3. package/dist/dashboard/assets/BannedPage-Dq530awD.js.gz +0 -0
  4. package/dist/dashboard/assets/{CliToolDetailPage-Bqj2aa1T.js → CliToolDetailPage-DZzaS-7S.js} +1 -1
  5. package/dist/dashboard/assets/CliToolDetailPage-DZzaS-7S.js.gz +0 -0
  6. package/dist/dashboard/assets/{CliToolsPage-CXsaOAO2.js → CliToolsPage-DaZZ3cqP.js} +1 -1
  7. package/dist/dashboard/assets/CliToolsPage-DaZZ3cqP.js.gz +0 -0
  8. package/dist/dashboard/assets/{CombosPage-BeLpJ4ma.js → CombosPage-BlC_xdkX.js} +1 -1
  9. package/dist/dashboard/assets/CombosPage-BlC_xdkX.js.gz +0 -0
  10. package/dist/dashboard/assets/{ConsoleLogPage-DnV0uZ3m.js → ConsoleLogPage-D-rqeVtG.js} +1 -1
  11. package/dist/dashboard/assets/ConsoleLogPage-D-rqeVtG.js.gz +0 -0
  12. package/dist/dashboard/assets/{CustomizationPage-CBxAjo63.js → CustomizationPage-7xT5yg2E.js} +1 -1
  13. package/dist/dashboard/assets/CustomizationPage-7xT5yg2E.js.gz +0 -0
  14. package/dist/dashboard/assets/{HealthEventsModal-B5yEE0k6.js → HealthEventsModal-Clq8E9cW.js} +1 -1
  15. package/dist/dashboard/assets/HealthEventsModal-Clq8E9cW.js.gz +0 -0
  16. package/dist/dashboard/assets/{InjectSystemPromptPanel-BWFLECmz.js → InjectSystemPromptPanel-6Teoq9Se.js} +1 -1
  17. package/dist/dashboard/assets/InjectSystemPromptPanel-6Teoq9Se.js.gz +0 -0
  18. package/dist/dashboard/assets/{LoginPage-CgoPc5B9.js → LoginPage-CZuI0MAR.js} +1 -1
  19. package/dist/dashboard/assets/LoginPage-CZuI0MAR.js.gz +0 -0
  20. package/dist/dashboard/assets/{ModelPicker-D9bFQern.js → ModelPicker-C1hNTlkr.js} +1 -1
  21. package/dist/dashboard/assets/ModelPicker-C1hNTlkr.js.gz +0 -0
  22. package/dist/dashboard/assets/{OverviewPage-B_p4tL8k.js → OverviewPage-0yfhSI1C.js} +1 -1
  23. package/dist/dashboard/assets/OverviewPage-0yfhSI1C.js.gz +0 -0
  24. package/dist/dashboard/assets/ProviderDetailPage-xqTxdQ4c.js +8 -0
  25. package/dist/dashboard/assets/ProviderDetailPage-xqTxdQ4c.js.gz +0 -0
  26. package/dist/dashboard/assets/{ProviderIcon-D_0PiZtg.js → ProviderIcon-Ddhm1InL.js} +1 -1
  27. package/dist/dashboard/assets/ProviderIcon-Ddhm1InL.js.gz +0 -0
  28. package/dist/dashboard/assets/{ProvidersPage-CLI2bJTK.js → ProvidersPage-C3fYuu6i.js} +1 -1
  29. package/dist/dashboard/assets/ProvidersPage-C3fYuu6i.js.gz +0 -0
  30. package/dist/dashboard/assets/ProxyPage-CHtJtZ3u.js +9 -0
  31. package/dist/dashboard/assets/ProxyPage-CHtJtZ3u.js.gz +0 -0
  32. package/dist/dashboard/assets/{QuotaPage-DA-a1iSN.js → QuotaPage-D1RV_2BX.js} +1 -1
  33. package/dist/dashboard/assets/QuotaPage-D1RV_2BX.js.gz +0 -0
  34. package/dist/dashboard/assets/{SettingsPage-CctTga2C.js → SettingsPage-BzZAvYSX.js} +1 -1
  35. package/dist/dashboard/assets/SettingsPage-BzZAvYSX.js.gz +0 -0
  36. package/dist/dashboard/assets/{SetupPage-febLU4r1.js → SetupPage--s-EfEIL.js} +1 -1
  37. package/dist/dashboard/assets/SetupPage--s-EfEIL.js.gz +0 -0
  38. package/dist/dashboard/assets/{StudioPage-M6fvR5Wz.js → StudioPage-BjXFGSK4.js} +1 -1
  39. package/dist/dashboard/assets/StudioPage-BjXFGSK4.js.gz +0 -0
  40. package/dist/dashboard/assets/{UsagePage-nyeuRqz9.js → UsagePage-CP8F8BN7.js} +1 -1
  41. package/dist/dashboard/assets/UsagePage-CP8F8BN7.js.gz +0 -0
  42. package/dist/dashboard/assets/{api-keys-BFOlvrJC.js → api-keys-2hc12Uz2.js} +1 -1
  43. package/dist/dashboard/assets/api-keys-2hc12Uz2.js.gz +0 -0
  44. package/dist/dashboard/assets/app-DGXbNfAR.css +2 -0
  45. package/dist/dashboard/assets/app-DGXbNfAR.css.gz +0 -0
  46. package/dist/dashboard/assets/{assert-CqTLw5e7.js → assert-BMcj1xZE.js} +1 -1
  47. package/dist/dashboard/assets/assert-BMcj1xZE.js.gz +0 -0
  48. package/dist/dashboard/assets/{badge-C83EqLB0.js → badge-DkRUuVfz.js} +1 -1
  49. package/dist/dashboard/assets/badge-DkRUuVfz.js.gz +0 -0
  50. package/dist/dashboard/assets/{banner-D1xn7pIe.js → banner-CDjW841Q.js} +1 -1
  51. package/dist/dashboard/assets/banner-CDjW841Q.js.gz +0 -0
  52. package/dist/dashboard/assets/{card-DU3Lq5Lm.js → card-Bto5UlL9.js} +1 -1
  53. package/dist/dashboard/assets/card-Bto5UlL9.js.gz +0 -0
  54. package/dist/dashboard/assets/{cli-tools-Dw1U_drK.js → cli-tools-DaH6g9hL.js} +1 -1
  55. package/dist/dashboard/assets/cli-tools-DaH6g9hL.js.gz +0 -0
  56. package/dist/dashboard/assets/{clipboard-button-CEL5Sg_J.js → clipboard-button-BYKBCzjk.js} +1 -1
  57. package/dist/dashboard/assets/clipboard-button-BYKBCzjk.js.gz +0 -0
  58. package/dist/dashboard/assets/{dialog-BjFR5UHy.js → dialog-DL0Zftwv.js} +1 -1
  59. package/dist/dashboard/assets/dialog-DL0Zftwv.js.gz +0 -0
  60. package/dist/dashboard/assets/{drawer-HvBW0AjI.js → drawer-Dpx_UXaS.js} +1 -1
  61. package/dist/dashboard/assets/drawer-Dpx_UXaS.js.gz +0 -0
  62. package/dist/dashboard/assets/{entry-CECVELyy.js → entry-BV7-1NoM.js} +1 -1
  63. package/dist/dashboard/assets/entry-BV7-1NoM.js.gz +0 -0
  64. package/dist/dashboard/assets/{entry-DYYofQ7W.js → entry-CGvdNU6r.js} +1 -1
  65. package/dist/dashboard/assets/entry-CGvdNU6r.js.gz +0 -0
  66. package/dist/dashboard/assets/{entry-BSu3gFlt.js → entry-DScKYvZj.js} +3 -3
  67. package/dist/dashboard/assets/entry-DScKYvZj.js.gz +0 -0
  68. package/dist/dashboard/assets/{formatters-DLW4i8zK.js → formatters-BS3DZlZj.js} +1 -1
  69. package/dist/dashboard/assets/formatters-BS3DZlZj.js.gz +0 -0
  70. package/dist/dashboard/assets/{index-1-fCqe64.js → index-SQnvvTWX.js} +2 -2
  71. package/dist/dashboard/assets/index-SQnvvTWX.js.gz +0 -0
  72. package/dist/dashboard/assets/{inline-DGvU2oLK.js → inline-Dl-cuLK0.js} +1 -1
  73. package/dist/dashboard/assets/inline-Dl-cuLK0.js.gz +0 -0
  74. package/dist/dashboard/assets/{input-iNnO1X2K.js → input-Bfx0EzRc.js} +1 -1
  75. package/dist/dashboard/assets/input-Bfx0EzRc.js.gz +0 -0
  76. package/dist/dashboard/assets/{layout-0q8UGypb.js → layout-BxhbQ_JS.js} +1 -1
  77. package/dist/dashboard/assets/layout-BxhbQ_JS.js.gz +0 -0
  78. package/dist/dashboard/assets/{list-row-C0w2bQjJ.js → list-row-D49Y4ptn.js} +1 -1
  79. package/dist/dashboard/assets/list-row-D49Y4ptn.js.gz +0 -0
  80. package/dist/dashboard/assets/{live-M5aJ_xCa.js → live-CbVTdX9V.js} +1 -1
  81. package/dist/dashboard/assets/live-CbVTdX9V.js.gz +0 -0
  82. package/dist/dashboard/assets/{network-BKeQGT3K.js → network-JGvDveof.js} +1 -1
  83. package/dist/dashboard/assets/network-JGvDveof.js.gz +0 -0
  84. package/dist/dashboard/assets/{numbers-CivAk3da.js → numbers-Dw6kiew-.js} +1 -1
  85. package/dist/dashboard/assets/numbers-Dw6kiew-.js.gz +0 -0
  86. package/dist/dashboard/assets/{pagination-CpzvI5ep.js → pagination-iUoI8GeE.js} +1 -1
  87. package/dist/dashboard/assets/pagination-iUoI8GeE.js.gz +0 -0
  88. package/dist/dashboard/assets/providers/sensenova-intl.png +0 -0
  89. package/dist/dashboard/assets/providers/sensenova.png +0 -0
  90. package/dist/dashboard/assets/{routing-BFQX2VBc.js → routing-8jZr-3WE.js} +1 -1
  91. package/dist/dashboard/assets/routing-8jZr-3WE.js.gz +0 -0
  92. package/dist/dashboard/assets/{select-CXbck0jG.js → select-oO1FxMVb.js} +1 -1
  93. package/dist/dashboard/assets/select-oO1FxMVb.js.gz +0 -0
  94. package/dist/dashboard/assets/{settings-C_XvMHh9.js → settings-CLr3kdIx.js} +1 -1
  95. package/dist/dashboard/assets/settings-CLr3kdIx.js.gz +0 -0
  96. package/dist/dashboard/assets/{stack-DggRiCxE.js → stack-Y3pDteZr.js} +1 -1
  97. package/dist/dashboard/assets/stack-Y3pDteZr.js.gz +0 -0
  98. package/dist/dashboard/assets/{state-ClFzfbYp.js → state-CArX_Iak.js} +1 -1
  99. package/dist/dashboard/assets/state-CArX_Iak.js.gz +0 -0
  100. package/dist/dashboard/assets/{switch-CTIFxKqS.js → switch-DwlwmDO-.js} +1 -1
  101. package/dist/dashboard/assets/switch-DwlwmDO-.js.gz +0 -0
  102. package/dist/dashboard/assets/{useMutation-BClG3yWj.js → useMutation-DJ9GYEgf.js} +1 -1
  103. package/dist/dashboard/assets/useMutation-DJ9GYEgf.js.gz +0 -0
  104. package/dist/dashboard/index.html +2 -2
  105. package/dist/dashboard/index.html.gz +0 -0
  106. package/dist/dashboard/precompressed-assets.json +51 -51
  107. package/migrations/full-postgres/0047_add_provider_device_flow_proxy.sql +17 -0
  108. package/migrations/lite-sqlite3/0047_add_provider_device_flow_proxy.sql +19 -0
  109. package/package.json +1 -1
  110. package/src/boot/app.ts +1 -1
  111. package/src/boot/dependencies.ts +4 -6
  112. package/src/config/providers.ts +6 -5
  113. package/src/config/spec.ts +8 -8
  114. package/src/console/backup/nine-router.ts +71 -10
  115. package/src/console/backup/service.ts +8 -1
  116. package/src/console/console-router.ts +1 -1
  117. package/src/console/domain-registration.ts +7 -2
  118. package/src/console/inferhub/client.ts +1 -1
  119. package/src/console/observability/live.ts +2 -2
  120. package/src/console/providers/catalog/contracts.ts +9 -3
  121. package/src/console/providers/catalog/model-operations.ts +2 -3
  122. package/src/console/providers/catalog/provider-operations.ts +1 -1
  123. package/src/console/providers/catalog/routes.ts +2 -2
  124. package/src/console/providers/catalog/store.ts +1914 -1907
  125. package/src/console/providers/detail/routes.ts +1 -0
  126. package/src/console/providers/detail/store.ts +4 -0
  127. package/src/console/providers/oauth/callback-listener.ts +30 -11
  128. package/src/console/providers/oauth/device-egress.ts +123 -0
  129. package/src/console/providers/oauth/routes.ts +123 -16
  130. package/src/console/quota/account-quota-tenant.ts +5 -5
  131. package/src/console/quota/account-test-egress.ts +2 -2
  132. package/src/console/quota/daily-growth-job.ts +1 -1
  133. package/src/console/routing/pools/contracts.ts +1 -1
  134. package/src/console/routing/pools/operations.ts +1 -1
  135. package/src/console/routing/pools/probe-verdict.ts +2 -2
  136. package/src/console/routing/pools/relay-deploy.ts +1 -1
  137. package/src/console/routing/pools/store.ts +4 -4
  138. package/src/network/client.ts +67 -0
  139. package/src/network/egress/bidi-session.ts +322 -0
  140. package/src/network/egress/dial.ts +201 -0
  141. package/src/network/egress/factory.ts +191 -0
  142. package/src/network/{outbound-fetch.ts → egress/fetch.ts} +195 -29
  143. package/src/network/egress/tls-profile.ts +123 -0
  144. package/src/network/egress/ws.ts +175 -0
  145. package/src/network/{types.ts → pool/agent-config.ts} +1 -1
  146. package/src/network/pool/agent.ts +2 -2
  147. package/src/network/{pool-cooldown-store.ts → pool/cooldown-store.ts} +7 -7
  148. package/src/network/{pool-health-machine.ts → pool/health.ts} +205 -6
  149. package/src/network/pool/resolver.ts +10 -849
  150. package/src/network/pool/selector.ts +2 -2
  151. package/src/network/ssrf.ts +1 -1
  152. package/src/network/{retry.ts → util/retry.ts} +1 -1
  153. package/src/observability/telemetry-buffer.ts +1 -1
  154. package/src/persistence/schema.ts +9 -0
  155. package/src/persistence/ttl-cache.ts +1 -1
  156. package/src/protocol/codecs.ts +58 -1
  157. package/src/protocol/request/messages.ts +31 -18
  158. package/src/protocol/response/messages.ts +34 -7
  159. package/src/protocol/translation/quirks.ts +15 -0
  160. package/src/protocol/upstream/send-claude-messages.ts +2 -2
  161. package/src/providers/adapters/compatible-adapter.ts +5 -0
  162. package/src/providers/authentication/oauth-client.ts +40 -6
  163. package/src/providers/authentication/oauth-device-flow.ts +7 -3
  164. package/src/providers/authentication/oauth-flow-store.ts +82 -1
  165. package/src/providers/authentication/oauth-refresh-service.ts +766 -739
  166. package/src/providers/default-registry.ts +76 -0
  167. package/src/providers/discovery/discovery-types.ts +7 -0
  168. package/src/providers/discovery/probe-phases.ts +6 -2
  169. package/src/providers/discovery/probing-service.ts +7 -0
  170. package/src/providers/integrations/antigravity/antigravity-protocol.ts +11 -0
  171. package/src/providers/integrations/buddy/account.ts +969 -0
  172. package/src/providers/integrations/buddy/capabilities.ts +10 -10
  173. package/src/providers/integrations/buddy/{buddy-catalog-shared.ts → catalog.ts} +198 -136
  174. package/src/providers/integrations/buddy/{buddy-chat-shared.ts → chat.ts} +5 -5
  175. package/src/providers/integrations/buddy/codebuddy/index.ts +429 -0
  176. package/src/providers/integrations/buddy/codebuddy/shared.ts +4 -4
  177. package/src/providers/integrations/buddy/{buddy-identity.ts → headers.ts} +138 -140
  178. package/src/providers/integrations/buddy/lifecycle.ts +1018 -0
  179. package/src/providers/integrations/buddy/{buddy-media.ts → media.ts} +1 -1
  180. package/src/providers/integrations/cline/cline-oauth.ts +10 -5
  181. package/src/providers/integrations/cline/cline.ts +3 -4
  182. package/src/providers/integrations/clixad/clixad-oauth.ts +98 -0
  183. package/src/providers/integrations/clixad/clixad-quota.ts +132 -0
  184. package/src/providers/integrations/clixad/provider.ts +145 -0
  185. package/src/providers/integrations/codex/codex-oauth.ts +8 -5
  186. package/src/providers/integrations/cursor/cursor-auth.ts +1 -1
  187. package/src/providers/integrations/cursor/cursor-hardening.ts +279 -0
  188. package/src/providers/integrations/cursor/cursor-http2.ts +605 -6
  189. package/src/providers/integrations/cursor/cursor-shared.ts +1 -1
  190. package/src/providers/integrations/cursor/cursor.ts +485 -70
  191. package/src/providers/integrations/deepai/deepai-catalog.ts +149 -0
  192. package/src/providers/integrations/deepai/deepai-common.ts +145 -0
  193. package/src/providers/integrations/deepai/deepai-oauth.ts +129 -0
  194. package/src/providers/integrations/deepai/deepai-quota.ts +97 -0
  195. package/src/providers/integrations/deepai/provider.ts +42 -0
  196. package/src/providers/integrations/devin/devin-auth.ts +7 -0
  197. package/src/providers/integrations/factory/factory-oauth.ts +16 -7
  198. package/src/providers/integrations/freebuff/freebuff.ts +2 -2
  199. package/src/providers/integrations/freepi/freepi-catalog.ts +5 -0
  200. package/src/providers/integrations/freepi/freepi-discovery.ts +2 -2
  201. package/src/providers/integrations/freepi/freepi-headers.ts +2 -2
  202. package/src/providers/integrations/freepi/freepi-protocol.ts +11 -2
  203. package/src/providers/integrations/freepi/freepi-realm.ts +0 -3
  204. package/src/providers/integrations/freepi/freepi-session.ts +158 -0
  205. package/src/providers/integrations/freepi/freepi.ts +80 -54
  206. package/src/providers/integrations/github/github-discovery.ts +30 -13
  207. package/src/providers/integrations/github/github-oauth.ts +217 -44
  208. package/src/providers/integrations/github/github-quota.ts +22 -5
  209. package/src/providers/integrations/github/github.ts +40 -32
  210. package/src/providers/integrations/grok/grok-oauth.ts +4 -4
  211. package/src/providers/integrations/hermes/hermes-oauth.ts +3 -3
  212. package/src/providers/integrations/hermes/hermes.ts +34 -5
  213. package/src/providers/integrations/kilo/kilo-oauth.ts +4 -4
  214. package/src/providers/integrations/kilo/kilo.ts +1 -1
  215. package/src/providers/integrations/kimi/kimi-oauth.ts +3 -3
  216. package/src/providers/integrations/kiro/kiro-oauth.ts +2 -2
  217. package/src/providers/integrations/muse/muse-oauth.ts +5 -5
  218. package/src/providers/integrations/opencode/fingerprint.ts +1 -1
  219. package/src/providers/integrations/openrouter/provider.ts +1 -1
  220. package/src/providers/integrations/perch/perch-protocol.ts +0 -3
  221. package/src/providers/integrations/perch/perch.ts +3 -3
  222. package/src/providers/integrations/qoder/claim-qoder-credits.ts +1 -1
  223. package/src/providers/integrations/qoder/qoder-adapter.ts +19 -113
  224. package/src/providers/integrations/qoder/qoder-auth.ts +8 -1
  225. package/src/providers/integrations/qoder/qoder-catalog.ts +1 -1
  226. package/src/providers/integrations/qoder/qoder-chat.ts +25 -8
  227. package/src/providers/integrations/qoder/qoder-checkin.ts +1 -1
  228. package/src/providers/integrations/qoder/qoder-cosy.ts +37 -9
  229. package/src/providers/integrations/qoder/qoder-oauth.ts +9 -2
  230. package/src/providers/integrations/qoder/qoder-realm.ts +13 -36
  231. package/src/providers/integrations/qoder/qoder-sse.ts +447 -68
  232. package/src/providers/integrations/qoder/qoder-types.ts +9 -0
  233. package/src/providers/integrations/qoder/qoder.ts +3 -25
  234. package/src/providers/integrations/sensenova/provider.ts +144 -0
  235. package/src/providers/integrations/trae/trae-quota.ts +15 -1
  236. package/src/providers/integrations/vercel/provider.ts +117 -0
  237. package/src/providers/integrations/vercel/vercel-quota.ts +96 -0
  238. package/src/providers/integrations/xai/xai-oauth.ts +5 -5
  239. package/src/providers/integrations/zcode-start-plan/gifts.ts +1 -1
  240. package/src/providers/integrations/zcode-start-plan/oauth.ts +3 -3
  241. package/src/providers/integrations/zro/zro.ts +2 -1
  242. package/src/providers/operations/account-refresh-status.ts +14 -0
  243. package/src/providers/operations/client-versions.ts +95 -30
  244. package/src/providers/operations/oauth-refresh-lead.ts +46 -22
  245. package/src/providers/operations/provider-caches.ts +1 -1
  246. package/src/providers/operations/provider-credential-service.ts +22 -25
  247. package/src/providers/operations/session-resolution.ts +17 -1
  248. package/src/providers/provider-contracts.ts +2 -2
  249. package/src/providers/provider-metadata.ts +30 -0
  250. package/src/providers/quota/quota-contracts.ts +2 -0
  251. package/src/providers/quota/refresh.ts +25 -3
  252. package/src/security/ip-boundary.ts +1 -1
  253. package/src/transport/dispatch/attempt-finalize.ts +1 -1
  254. package/src/transport/dispatch/attempt-loop.ts +3 -3
  255. package/src/transport/dispatch/handler-deps.ts +1 -1
  256. package/src/transport/dispatch/leases.ts +1 -1
  257. package/src/transport/dispatch/retry-policy.ts +1 -1
  258. package/src/transport/dispatch/streaming/finalize.ts +2 -2
  259. package/src/transport/dispatch/streaming/stream.ts +1 -1
  260. package/src/transport/dispatch/upstream.ts +1 -1
  261. package/src/transport/shutdown-notice.ts +1 -1
  262. package/src/workers/buddy-growth-tasks.ts +8 -8
  263. package/src/workers/daily-checkin.ts +4 -4
  264. package/src/workers/quota-refresh-sweep.ts +1 -1
  265. package/src/workers/zcode-gift-claim.ts +1 -1
  266. package/dist/dashboard/assets/BannedPage-Cc0vKpMG.js.gz +0 -0
  267. package/dist/dashboard/assets/CliToolDetailPage-Bqj2aa1T.js.gz +0 -0
  268. package/dist/dashboard/assets/CliToolsPage-CXsaOAO2.js.gz +0 -0
  269. package/dist/dashboard/assets/CombosPage-BeLpJ4ma.js.gz +0 -0
  270. package/dist/dashboard/assets/ConsoleLogPage-DnV0uZ3m.js.gz +0 -0
  271. package/dist/dashboard/assets/CustomizationPage-CBxAjo63.js.gz +0 -0
  272. package/dist/dashboard/assets/HealthEventsModal-B5yEE0k6.js.gz +0 -0
  273. package/dist/dashboard/assets/InjectSystemPromptPanel-BWFLECmz.js.gz +0 -0
  274. package/dist/dashboard/assets/LoginPage-CgoPc5B9.js.gz +0 -0
  275. package/dist/dashboard/assets/ModelPicker-D9bFQern.js.gz +0 -0
  276. package/dist/dashboard/assets/OverviewPage-B_p4tL8k.js.gz +0 -0
  277. package/dist/dashboard/assets/ProviderDetailPage-rs5E2rxv.js +0 -8
  278. package/dist/dashboard/assets/ProviderDetailPage-rs5E2rxv.js.gz +0 -0
  279. package/dist/dashboard/assets/ProviderIcon-D_0PiZtg.js.gz +0 -0
  280. package/dist/dashboard/assets/ProvidersPage-CLI2bJTK.js.gz +0 -0
  281. package/dist/dashboard/assets/ProxyPage-BwNC_-Cx.js +0 -9
  282. package/dist/dashboard/assets/ProxyPage-BwNC_-Cx.js.gz +0 -0
  283. package/dist/dashboard/assets/QuotaPage-DA-a1iSN.js.gz +0 -0
  284. package/dist/dashboard/assets/SettingsPage-CctTga2C.js.gz +0 -0
  285. package/dist/dashboard/assets/SetupPage-febLU4r1.js.gz +0 -0
  286. package/dist/dashboard/assets/StudioPage-M6fvR5Wz.js.gz +0 -0
  287. package/dist/dashboard/assets/UsagePage-nyeuRqz9.js.gz +0 -0
  288. package/dist/dashboard/assets/api-keys-BFOlvrJC.js.gz +0 -0
  289. package/dist/dashboard/assets/app-Dx2QgsNj.css +0 -2
  290. package/dist/dashboard/assets/app-Dx2QgsNj.css.gz +0 -0
  291. package/dist/dashboard/assets/assert-CqTLw5e7.js.gz +0 -0
  292. package/dist/dashboard/assets/badge-C83EqLB0.js.gz +0 -0
  293. package/dist/dashboard/assets/banner-D1xn7pIe.js.gz +0 -0
  294. package/dist/dashboard/assets/card-DU3Lq5Lm.js.gz +0 -0
  295. package/dist/dashboard/assets/cli-tools-Dw1U_drK.js.gz +0 -0
  296. package/dist/dashboard/assets/clipboard-button-CEL5Sg_J.js.gz +0 -0
  297. package/dist/dashboard/assets/dialog-BjFR5UHy.js.gz +0 -0
  298. package/dist/dashboard/assets/drawer-HvBW0AjI.js.gz +0 -0
  299. package/dist/dashboard/assets/entry-BSu3gFlt.js.gz +0 -0
  300. package/dist/dashboard/assets/entry-CECVELyy.js.gz +0 -0
  301. package/dist/dashboard/assets/entry-DYYofQ7W.js.gz +0 -0
  302. package/dist/dashboard/assets/formatters-DLW4i8zK.js.gz +0 -0
  303. package/dist/dashboard/assets/index-1-fCqe64.js.gz +0 -0
  304. package/dist/dashboard/assets/inline-DGvU2oLK.js.gz +0 -0
  305. package/dist/dashboard/assets/input-iNnO1X2K.js.gz +0 -0
  306. package/dist/dashboard/assets/layout-0q8UGypb.js.gz +0 -0
  307. package/dist/dashboard/assets/list-row-C0w2bQjJ.js.gz +0 -0
  308. package/dist/dashboard/assets/live-M5aJ_xCa.js.gz +0 -0
  309. package/dist/dashboard/assets/network-BKeQGT3K.js.gz +0 -0
  310. package/dist/dashboard/assets/numbers-CivAk3da.js.gz +0 -0
  311. package/dist/dashboard/assets/pagination-CpzvI5ep.js.gz +0 -0
  312. package/dist/dashboard/assets/routing-BFQX2VBc.js.gz +0 -0
  313. package/dist/dashboard/assets/select-CXbck0jG.js.gz +0 -0
  314. package/dist/dashboard/assets/settings-C_XvMHh9.js.gz +0 -0
  315. package/dist/dashboard/assets/stack-DggRiCxE.js.gz +0 -0
  316. package/dist/dashboard/assets/state-ClFzfbYp.js.gz +0 -0
  317. package/dist/dashboard/assets/switch-CTIFxKqS.js.gz +0 -0
  318. package/dist/dashboard/assets/useMutation-BClG3yWj.js.gz +0 -0
  319. package/src/console/providers/catalog/discover-constants.ts +0 -6
  320. package/src/network/pool-health.ts +0 -198
  321. package/src/providers/integrations/buddy/buddy-checkin.ts +0 -521
  322. package/src/providers/integrations/buddy/buddy-cli-headers.ts +0 -76
  323. package/src/providers/integrations/buddy/buddy-conversation-headers.ts +0 -130
  324. package/src/providers/integrations/buddy/buddy-discovery-shared.ts +0 -234
  325. package/src/providers/integrations/buddy/buddy-growth-shared.ts +0 -496
  326. package/src/providers/integrations/buddy/buddy-oauth-shared.ts +0 -341
  327. package/src/providers/integrations/buddy/buddy-quota-shared.ts +0 -417
  328. package/src/providers/integrations/buddy/buddy-server-tools.ts +0 -240
  329. package/src/providers/integrations/buddy/buddy-usage-shared.ts +0 -221
  330. package/src/providers/integrations/buddy/buddy-usage-store.ts +0 -181
  331. package/src/providers/integrations/buddy/codebuddy/cn-catalog.ts +0 -37
  332. package/src/providers/integrations/buddy/codebuddy/cn-provider.ts +0 -188
  333. package/src/providers/integrations/buddy/codebuddy/oauth.ts +0 -47
  334. package/src/providers/integrations/buddy/codebuddy/provider.ts +0 -179
  335. package/src/providers/integrations/buddy/codebuddy/quota.ts +0 -154
  336. package/src/providers/integrations/qoder/chat-proto.ts +0 -328
  337. package/src/providers/integrations/qoder/qoder-grpc.ts +0 -870
  338. package/src/providers/integrations/qoder/qoder-ide.ts +0 -481
  339. /package/dist/dashboard/assets/{app-DIXLjojg.js → app-C0gTXEoN.js} +0 -0
  340. /package/dist/dashboard/assets/{app-DIXLjojg.js.gz → app-C0gTXEoN.js.gz} +0 -0
  341. /package/src/network/{http2-bidi.ts → bidi.ts} +0 -0
  342. /package/src/network/pool/{byte-accounting.ts → accounting.ts} +0 -0
  343. /package/src/network/pool/{pool-scripts.ts → scripts.ts} +0 -0
  344. /package/src/network/pool/{pool-state.ts → state.ts} +0 -0
  345. /package/src/network/{backoff.ts → util/backoff.ts} +0 -0
  346. /package/src/network/{deduplication.ts → util/dedupe.ts} +0 -0
  347. /package/src/network/{ip-utils.ts → util/ip.ts} +0 -0
  348. /package/src/network/{rate-limit-verdict.ts → verdict.ts} +0 -0
@@ -1,521 +0,0 @@
1
- import { asCoercedNumber as sharedAsNumber, asRecord as sharedAsRecord } from "../../../shared/coerce";
2
-
3
- // Buddy-family daily check-in (daily login credit claim), shared by both
4
- // variants (`cb`, `cbcn`): same Tencent billing facade, same
5
- // status/claim contract — only the endpoint base and identity headers differ
6
- // per variant, and those already live in each provider's own modules.
7
- //
8
- // The desktop client claims a free daily credit grant once per calendar day.
9
- // The gateway mirrors that for every stored account so an operator can see,
10
- // per account, whether today's grant was claimed — without opening the app.
11
- //
12
- // Contract (from the reverse-engineered desktop bundle, vendor/research):
13
- // Status : POST {base}/v2/billing/meter/checkin-activity-status body {}
14
- // Claim : POST {base}/v2/billing/meter/daily-checkin body {}
15
- // Envelope: { code: 0, data: { today_checked_in, streak_days, ... } }
16
- // "already claimed" business code is 1001 (NOT 10001 — that belongs to the
17
- // artifact-release API).
18
- //
19
- // One request per account per day: the sweep asks the status endpoint first and
20
- // only POSTs the claim when the account has not claimed today. A successful
21
- // claim short-circuits the day, so a restart cannot double-post.
22
-
23
- import { providerBaseUrl } from "../../provider-metadata";
24
- import { sleep } from "../../../shared/sleep";
25
- import { BUDDY_PROVIDER_IDS } from "../../provider-metadata";
26
- import { QODER_CHECKIN_PROVIDER_IDS } from "../qoder/qoder-checkin";
27
- import { buildCodeBuddyUserAgent } from "../../operations/client-versions";
28
- import { codebuddyDomain, type CodeBuddyVariant } from "./codebuddy/shared";
29
- /** Providers whose billing facade exposes the daily check-in routes. */
30
- /**
31
- * The Buddy providers the daily check-in claims a credit for. Derived from the
32
- * shared family set so this list cannot drift from the health recorder's or the
33
- * request preparer's.
34
- */
35
- export const DAILY_CHECKIN_PROVIDER_IDS: readonly string[] = [
36
- ...BUDDY_PROVIDER_IDS,
37
- ...QODER_CHECKIN_PROVIDER_IDS,
38
- ];
39
-
40
- /** Abort budget for one upstream check-in request. */
41
- const TIMEOUT_MS = 15_000;
42
-
43
- export const CHECKIN_STATUS_PATH = "/billing/meter/checkin-activity-status";
44
- export const CHECKIN_CLAIM_PATH = "/billing/meter/daily-checkin";
45
-
46
- export type DailyCheckinState =
47
- | "claimed"
48
- | "already_claimed"
49
- | "not_eligible"
50
- | "event_ended"
51
- | "unavailable"
52
- | "error";
53
-
54
- export interface DailyCheckinResult {
55
- readonly providerId: string;
56
- readonly accountId: string;
57
- readonly state: DailyCheckinState;
58
- /** Credits granted by this claim; `null` when nothing was granted. */
59
- readonly credit: number | null;
60
- readonly streakDays: number | null;
61
- /** Provider-facing detail for the audit log; `null` on success. */
62
- readonly error: string | null;
63
- }
64
-
65
- /**
66
- * One `chat_request_send` growth event for `POST {base}/v2/report`.
67
- *
68
- * The growth backend scores conversation activity, not credit grants: one
69
- * report lights the login streak and unlocks the `first_buddy` task. The full
70
- * client shape is sent (not a minimal subset) because the upstream may tighten
71
- * validation later. `userId` is mandatory — the server answers 200 but silently
72
- * drops events without it.
73
- */
74
- export interface BuddyActivityReportEvent {
75
- readonly eventCode: "chat_request_send";
76
- readonly timestamp: number;
77
- readonly reportDelay: number;
78
- readonly mode: string;
79
- readonly conversationId: string;
80
- readonly requestId: string;
81
- readonly inputLength: number;
82
- readonly requestModelId: string;
83
- readonly requestModelName: string;
84
- readonly isPlan: boolean;
85
- readonly isAutoExecuteTerminal: boolean;
86
- readonly isAutoModify: boolean;
87
- readonly codebaseEnable: boolean;
88
- readonly maxToken: number;
89
- readonly maxSteps: number;
90
- readonly temperature: number;
91
- readonly maxRetries: number;
92
- readonly mentionContexts: readonly unknown[];
93
- readonly knowledgeId: readonly unknown[];
94
- readonly knowledgeName: readonly unknown[];
95
- readonly codebaseId: string;
96
- readonly mentionContextCount: number;
97
- readonly command: string;
98
- readonly recommendId: string;
99
- readonly skillId: string;
100
- readonly skillCount: number;
101
- readonly totalCount: number;
102
- readonly presentAt: number;
103
- readonly rootRequestId: string;
104
- readonly parentConversationId: string;
105
- readonly agentName: string;
106
- readonly agentType: string;
107
- readonly product: string;
108
- readonly userId: string;
109
- }
110
-
111
- export const ACTIVITY_REPORT_PATH = "/report";
112
- export type BuddyActivityReportState = "reported" | "unavailable" | "error";
113
-
114
- export interface BuddyActivityReportResult {
115
- readonly providerId: string;
116
- readonly accountId: string;
117
- readonly state: BuddyActivityReportState;
118
- /** Provider-facing detail for the audit log; `null` on success. */
119
- readonly error: string | null;
120
- }
121
-
122
- /**
123
- * Builds one growth-activity event. `conversationId` is caller-generated (a
124
- * synthetic `activity-<millis>` id is fine — the server does not validate it
125
- * against a real conversation); `requestId` defaults to it. The model fields
126
- * mirror the desktop client's own report so the event reads as a normal chat
127
- * send, and `userId` carries the account uid the streak is scored against.
128
- */
129
- export function buildActivityReportEvent(args: {
130
- readonly conversationId: string;
131
- readonly userId: string;
132
- readonly requestId?: string;
133
- readonly now?: number;
134
- }): BuddyActivityReportEvent {
135
- const now = args.now ?? Date.now();
136
- const requestId = args.requestId ?? args.conversationId;
137
- return {
138
- eventCode: "chat_request_send",
139
- timestamp: now,
140
- reportDelay: 0,
141
- mode: "unknown",
142
- conversationId: args.conversationId,
143
- requestId,
144
- inputLength: 0,
145
- requestModelId: "auto",
146
- requestModelName: "Auto",
147
- isPlan: false,
148
- isAutoExecuteTerminal: false,
149
- isAutoModify: false,
150
- codebaseEnable: false,
151
- maxToken: 0,
152
- maxSteps: 0,
153
- temperature: 0,
154
- maxRetries: 0,
155
- mentionContexts: [],
156
- knowledgeId: [],
157
- knowledgeName: [],
158
- codebaseId: "",
159
- mentionContextCount: 0,
160
- command: "",
161
- recommendId: "",
162
- skillId: "",
163
- skillCount: 0,
164
- totalCount: 0,
165
- presentAt: now,
166
- rootRequestId: args.conversationId,
167
- parentConversationId: args.conversationId,
168
- agentName: "default",
169
- agentType: "main",
170
- product: "SaaS",
171
- userId: args.userId,
172
- };
173
- }
174
-
175
- /**
176
- * How the growth report is sent.
177
- *
178
- * The billing facade scores conversation activity, and one event reads as one
179
- * chat send. A single event did not move the growth tasks; four events per
180
- * batch, sent twice with a pause between the rounds, is what does. The pause
181
- * is what keeps the two rounds from landing as one burst. Both numbers apply
182
- * to every buddy variant — the request is built the same way for `cb` and
183
- * `cbcn`, so neither can drift back to a single shot.
184
- */
185
- export const ACTIVITY_REPORT_EVENTS_PER_BATCH = 4;
186
- export const ACTIVITY_REPORT_ROUNDS = 2;
187
- export const ACTIVITY_REPORT_ROUND_DELAY_MS = 1_500;
188
-
189
- /**
190
- * Sends the growth-activity report (`POST {base}/v2/report`, the versioned
191
- * billing-meter path joined the same way as the status/claim routes:
192
- * `VERSION_SEGMENT` supplies nothing for `cb`/`cbcn`, which already end in
193
- * `/v2`).
194
- *
195
- * Two rounds of four events, paused between rounds. Each event carries its
196
- * own conversation and request id: the facade drops a repeated id as a
197
- * duplicate, so a batch of identical events would score as one. The first
198
- * round that fails stops the sequence — a credential or transport failure
199
- * will not be fixed by the second round, and sending it only adds load.
200
- */
201
- export async function fetchBuddyActivityReport(args: {
202
- readonly providerId: string;
203
- readonly accountId: string;
204
- readonly credential: string;
205
- readonly userId: string;
206
- readonly fetcher: typeof fetch;
207
- readonly conversationId?: string;
208
- /** Pause between rounds. Injectable so a test does not wait on the real delay. */
209
- readonly roundDelayMs?: number;
210
- readonly sleep?: (ms: number) => Promise<void>;
211
- }): Promise<BuddyActivityReportResult> {
212
- const { providerId, accountId, credential, userId, fetcher } = args;
213
- const base = { providerId, accountId, error: null };
214
- if (!credential) {
215
- return { ...base, state: "error", error: "Account has no stored credential." };
216
- }
217
- if (!userId) {
218
- return { ...base, state: "error", error: "Account uid is unavailable; cannot report activity." };
219
- }
220
- const headers = {
221
- ...(await checkinHeaders(providerId)),
222
- Authorization: `Bearer ${credential}`,
223
- "X-User-Id": userId,
224
- };
225
- const url = `${providerBaseUrl(providerId)}${VERSION_SEGMENT[providerId] ?? ""}${ACTIVITY_REPORT_PATH}`;
226
- const delayMs = args.roundDelayMs ?? ACTIVITY_REPORT_ROUND_DELAY_MS;
227
- const sleep = args.sleep ?? ((ms: number) => new Promise((resolve) => setTimeout(resolve, ms)));
228
- const conversationId = args.conversationId ?? `activity-${Date.now()}`;
229
-
230
- for (let round = 0; round < ACTIVITY_REPORT_ROUNDS; round += 1) {
231
- if (round > 0 && delayMs > 0) await sleep(delayMs);
232
- const events = Array.from({ length: ACTIVITY_REPORT_EVENTS_PER_BATCH }, (_, index) => {
233
- const sequence = round * ACTIVITY_REPORT_EVENTS_PER_BATCH + index;
234
- return buildActivityReportEvent({
235
- conversationId: `${conversationId}-${sequence}`,
236
- requestId: `${conversationId}-req-${sequence}`,
237
- userId,
238
- });
239
- });
240
- let payload: unknown;
241
- try {
242
- const response = await fetcher(url, {
243
- method: "POST",
244
- headers,
245
- body: JSON.stringify(events),
246
- signal: AbortSignal.timeout(TIMEOUT_MS),
247
- });
248
- if (response.status === 401 || response.status === 403) {
249
- return { ...base, state: "error", error: "Credential invalid or expired." };
250
- }
251
- if (!response.ok) {
252
- return { ...base, state: "error", error: `Activity report API error (${response.status}).` };
253
- }
254
- payload = await response.text().then((text) => (text ? JSON.parse(text) : null));
255
- } catch (error) {
256
- if (error instanceof SyntaxError) {
257
- return { ...base, state: "error", error: "Activity report response returned invalid JSON." };
258
- }
259
- return {
260
- ...base,
261
- state: "error",
262
- error: error instanceof Error ? error.message : "Activity report request failed.",
263
- };
264
- }
265
- const code = envelopeCode(payload);
266
- if (code !== null && code !== 0) {
267
- return { ...base, state: "error", error: `Activity report error (code ${code}).` };
268
- }
269
- }
270
- return { ...base, state: "reported" };
271
- }
272
-
273
- /**
274
- * Check-in business codes, per the desktop bundle's `mapCheckinStatus()`.
275
- * `1001` is "already claimed" — NOT `10001`, which belongs to the
276
- * artifact-release API and never appears in this path.
277
- */
278
- const ALREADY_CLAIMED_CODE = 1001;
279
- const NOT_ELIGIBLE_CODE = 1002;
280
- const EVENT_ENDED_CODE = 1003;
281
- /** Delays between 5xx/network retries on the claim POST, mirroring the buddy gateway's own backoff. */
282
- const CLAIM_RETRY_DELAYS_MS = [1_000, 2_000] as const;
283
- /**
284
- * Check-in paths are joined onto the provider's manifest base URL, which does
285
- * NOT carry a consistent version segment: `cb`/`cbcn` already end in `/v2`,
286
- * so no segment is prepended. This map keeps the join aligned with each
287
- * provider's own quota collector, so the gateways cannot drift apart.
288
- */
289
- const VERSION_SEGMENT: Readonly<Record<string, string>> = {
290
- cb: "",
291
- cbcn: "",
292
- };
293
-
294
- function statusUrl(providerId: string): string {
295
- return `${providerBaseUrl(providerId)}${VERSION_SEGMENT[providerId] ?? ""}${CHECKIN_STATUS_PATH}`;
296
- }
297
-
298
- function claimUrl(providerId: string): string {
299
- return `${providerBaseUrl(providerId)}${VERSION_SEGMENT[providerId] ?? ""}${CHECKIN_CLAIM_PATH}`;
300
- }
301
-
302
- /**
303
- * Per-provider billing headers. The Buddy gateways share the Tencent billing
304
- * facade but each risk-gates on its own client identity: CodeBuddy intl
305
- * wants the `IDE` identity, and CN wants `CLI` (plus its own `X-Domain`).
306
- * Sending the wrong one trips a 403 the same way the chat surface does.
307
- */
308
- async function checkinHeaders(providerId: string): Promise<Record<string, string>> {
309
- const common = {
310
- "X-Product": "SaaS",
311
- "X-Requested-With": "XMLHttpRequest",
312
- "X-CodeBuddy-Request": "1",
313
- "Content-Type": "application/json",
314
- Accept: "application/json",
315
- };
316
- const variant: CodeBuddyVariant = providerId === "cb" ? "IDE" : "CLI";
317
- return {
318
- ...common,
319
- "User-Agent": buildCodeBuddyUserAgent(variant),
320
- "X-IDE-Type": variant,
321
- "X-IDE-Name": variant,
322
- "X-Domain": codebuddyDomain(variant),
323
- };
324
- }
325
-
326
- /**
327
- * Textual "already checked in" fingerprints. The claim POST answers `1001`
328
- * when the envelope is well-formed, but a locale or gateway variant can answer
329
- * the same state as prose (the reference gateway matches `已签到` and
330
- * `already…check…` case-insensitively across the message or raw body), so both
331
- * shapes resolve to `already_claimed` instead of a spurious error.
332
- */
333
- function alreadyClaimedMessage(payload: unknown, rawBody: string): string | null {
334
- const message = asTextField(payload) || rawBody.trim();
335
- if (!message) return null;
336
- if (message.includes("已签到")) return message;
337
- const lower = message.toLowerCase();
338
- if (lower.includes("already") && lower.includes("check")) return message;
339
- return null;
340
- }
341
-
342
- function asTextField(payload: unknown): string | null {
343
- const data = asRecord(payload);
344
- if (!data) return null;
345
- const direct = data["msg"] ?? data["message"];
346
- if (typeof direct === "string" && direct.trim()) return direct.trim();
347
- return null;
348
- }
349
-
350
- /** True when the claim attempt is worth retrying: 5xx or a network throw, never a business code. */
351
- function isRetryableClaim(error: unknown, status: number | null): boolean {
352
- if (status !== null) return status >= 500;
353
- return !(error instanceof DOMException && error.name === "AbortError");
354
- }
355
-
356
- function asRecord(value: unknown): Record<string, unknown> | null {
357
- return sharedAsRecord(value) ?? null;
358
- }
359
-
360
- function asNumber(value: unknown): number | null {
361
- return sharedAsNumber(value) ?? null;
362
- }
363
-
364
-
365
- /** Reads the envelope's business code; `0` means success. */
366
- function envelopeCode(payload: unknown): number | null {
367
- const envelope = asRecord(payload);
368
- if (!envelope || !("code" in envelope)) return null;
369
- return asNumber(envelope["code"]);
370
- }
371
-
372
- /**
373
- * Unwraps the check-in payload. The gateway returns a flat `{ code, data }`,
374
- * while the CodeBuddy billing facade nests Tencent's `data.Response.Data`
375
- * (the same double wrap its quota endpoint uses), so both shapes resolve.
376
- */
377
- function envelopeData(payload: unknown): Record<string, unknown> | null {
378
- const data = asRecord(asRecord(payload)?.["data"]);
379
- if (!data) return null;
380
- if ("today_checked_in" in data || "active" in data || "streak_days" in data) return data;
381
- return asRecord(asRecord(data["Response"])?.["Data"]);
382
- }
383
-
384
- /**
385
- * Performs one account's daily check-in.
386
- *
387
- * Status first, claim only when `today_checked_in` is false — so the daily
388
- * budget is one request for an already-claimed account and two on claim day.
389
- */
390
- export async function fetchDailyCheckin(args: {
391
- readonly providerId: string;
392
- readonly accountId: string;
393
- readonly credential: string;
394
- readonly fetcher: typeof fetch;
395
- /** Overrides the status probe when the caller already knows the state. */
396
- readonly forceClaim?: boolean;
397
- }): Promise<DailyCheckinResult> {
398
- const { providerId, accountId, credential, fetcher } = args;
399
- const base = { providerId, accountId, credit: null, streakDays: null, error: null };
400
-
401
- if (!credential) {
402
- return { ...base, state: "error", error: "Account has no stored credential." };
403
- }
404
-
405
- // `checkinHeaders()` already carries Content-Type/Accept; only auth is
406
- // layered on here so the per-provider identity stays in one place.
407
- const headers = {
408
- ...(await checkinHeaders(providerId)),
409
- Authorization: `Bearer ${credential}`,
410
- };
411
-
412
- let status: unknown;
413
- try {
414
- const response = await fetcher(statusUrl(providerId), {
415
- method: "POST",
416
- headers,
417
- body: "{}",
418
- signal: AbortSignal.timeout(TIMEOUT_MS),
419
- });
420
- if (response.status === 401 || response.status === 403) {
421
- return { ...base, state: "error", error: "Credential invalid or expired." };
422
- }
423
- if (!response.ok) {
424
- return { ...base, state: "error", error: `Check-in status API error (${response.status}).` };
425
- }
426
- status = await response.json().catch(() => null);
427
- } catch (error) {
428
- return {
429
- ...base,
430
- state: "error",
431
- error: error instanceof Error ? error.message : "Check-in status request failed.",
432
- };
433
- }
434
-
435
- const statusCode = envelopeCode(status);
436
- if (statusCode !== null && statusCode !== 0) {
437
- return { ...base, state: "error", error: `Check-in status error (code ${statusCode}).` };
438
- }
439
-
440
- const data = envelopeData(status);
441
- if (!data) return { ...base, state: "unavailable", error: "Check-in activity unavailable." };
442
- if (data["active"] === false) {
443
- return { ...base, state: "unavailable", error: "No check-in activity running." };
444
- }
445
- const streak = asNumber(data["streak_days"]);
446
- if (!args.forceClaim && data["today_checked_in"] === true) {
447
- return { ...base, state: "already_claimed", streakDays: streak };
448
- }
449
-
450
- let claim: unknown;
451
- let claimRaw = "";
452
- let attempt = 0;
453
- for (;;) {
454
- try {
455
- const response = await fetcher(claimUrl(providerId), {
456
- method: "POST",
457
- headers,
458
- body: "{}",
459
- signal: AbortSignal.timeout(TIMEOUT_MS),
460
- });
461
- if (response.status === 401 || response.status === 403) {
462
- return { ...base, state: "error", error: "Credential invalid or expired." };
463
- }
464
- if (response.status >= 500 && attempt < CLAIM_RETRY_DELAYS_MS.length) {
465
- await sleep(CLAIM_RETRY_DELAYS_MS[attempt] as number);
466
- attempt += 1;
467
- continue;
468
- }
469
- if (!response.ok) {
470
- return { ...base, state: "error", error: `Daily check-in API error (${response.status}).` };
471
- }
472
- claimRaw = await response.text().catch(() => "");
473
- claim = claimRaw ? JSON.parse(claimRaw) : null;
474
- break;
475
- } catch (error) {
476
- if (error instanceof SyntaxError) {
477
- return { ...base, state: "error", error: "Daily check-in response returned invalid JSON." };
478
- }
479
- if (isRetryableClaim(error, null) && attempt < CLAIM_RETRY_DELAYS_MS.length) {
480
- await sleep(CLAIM_RETRY_DELAYS_MS[attempt] as number);
481
- attempt += 1;
482
- continue;
483
- }
484
- return {
485
- ...base,
486
- state: "error",
487
- error: error instanceof Error ? error.message : "Daily check-in request failed.",
488
- };
489
- }
490
- }
491
-
492
- const claimCode = envelopeCode(claim);
493
- if (claimCode !== null && claimCode !== 0) {
494
- const alreadyText = alreadyClaimedMessage(claim, claimRaw);
495
- if (claimCode === ALREADY_CLAIMED_CODE || alreadyText) {
496
- return { ...base, state: "already_claimed", streakDays: streak };
497
- }
498
- if (claimCode === NOT_ELIGIBLE_CODE) return { ...base, state: "not_eligible" };
499
- if (claimCode === EVENT_ENDED_CODE) return { ...base, state: "event_ended" };
500
- return { ...base, state: "error", error: `Daily check-in error (code ${claimCode}).` };
501
- }
502
- // Some gateway variants answer the duplicate-claim state as prose with a
503
- // success envelope; catch that before reporting a fresh claim.
504
- if (claimCode === 0) {
505
- const alreadyText = alreadyClaimedMessage(claim, claimRaw);
506
- if (alreadyText) return { ...base, state: "already_claimed", streakDays: streak };
507
- }
508
-
509
- const claimData = envelopeData(claim);
510
- return {
511
- ...base,
512
- state: "claimed",
513
- credit: asNumber(claimData?.["credit"]) ?? asNumber(claimData?.["today_credit"]) ?? null,
514
- streakDays: asNumber(claimData?.["streak_days"]) ?? streak,
515
- };
516
- }
517
-
518
- /** Calendar-day key in UTC, matching the provider's own day boundary. */
519
- export function checkinDayKey(now: Date = new Date()): string {
520
- return now.toISOString().slice(0, 10);
521
- }
@@ -1,76 +0,0 @@
1
- /**
2
- * The header family only the CLI identity sends.
3
- *
4
- * Everything here comes from the two reference gateways, which agree: the
5
- * desktop product sends conversation/tracing headers and a device token, while
6
- * the CLI sends the agent envelope. The CLI still drops the browser *transport*
7
- * headers (`origin`, `referer`, `accept-language`) and the device token, but
8
- * keeps the request-shape markers (`x-requested-with`, `x-codebuddy-request`)
9
- * the reference sends on every call regardless of transport — see the CLI
10
- * branches in each provider's `*-shared.ts`.
11
- *
12
- * The CLI's cloud chat transport is axios (`RestOperations`), not the OpenAI
13
- * Node SDK, so it sends **no** `x-stainless-*` fingerprint. The reference's
14
- * chat request helper sets only `Content-Type`, `Accept`, and `Authorization`
15
- * before the conversation/agent/identity headers are injected; the stainless
16
- * set belongs to the SDK-backed secondary clients, not to CodeBuddy chat.
17
- */
18
-
19
- /**
20
- * The trace family the CLI carries as a child span.
21
- *
22
- * The desktop product omits the parent (`with_parent=False` in the reference);
23
- * the CLI conversation request is a child span, so it also sends `b3`'s fourth
24
- * field and `X-B3-ParentSpanId`. `buddyConversationHeaders` already produces
25
- * `traceparent`, `b3`, and the `X-B3-*` set, so only the parent is added here.
26
- */
27
- export function buddyCliTraceHeaders(
28
- conversation: Readonly<Record<string, string>>,
29
- ): Record<string, string> {
30
- const traceId = conversation["x-trace-id"] ?? conversation["x-b3-traceid"];
31
- const spanId = conversation["x-b3-spanid"];
32
- if (traceId === undefined) return {};
33
- const b3 = `${traceId}-${spanId ?? traceId.slice(0, 16)}-1-${traceId.slice(0, 16)}`;
34
- return { ...(spanId === undefined ? {} : { "X-B3-ParentSpanId": spanId }), b3 };
35
- }
36
-
37
- /**
38
- * The full CLI identity envelope, minus what each caller already supplies.
39
- *
40
- * The caller keeps ownership of `User-Agent`, `X-IDE-*`, `X-Domain`, the
41
- * conversation family, and the OAuth identity headers; only the headers that
42
- * are the same for every CLI dispatch are built here.
43
- *
44
- * No `x-stainless-*` fingerprint: the CLI's chat transport is axios, not the
45
- * OpenAI Node SDK. `X-Private-Data` is added by the caller only when the
46
- * dispatch is actually private — the reference never sends it as `false`.
47
- */
48
- export function buddyCliHeaders(args: {
49
- readonly userId: string;
50
- readonly enterpriseId?: string | undefined;
51
- readonly privateData?: boolean;
52
- }): Record<string, string> {
53
- const enterpriseId =
54
- args.enterpriseId !== undefined && args.enterpriseId.trim().length > 0
55
- ? args.enterpriseId.trim()
56
- : undefined;
57
- return {
58
- "X-Agent-Intent": "craft",
59
- "X-Agent-Type": "main",
60
- // The reference enum is local-agent / cloud-agent / agent-agent, and its
61
- // parser returns "other" for anything unknown or absent. A gateway is none
62
- // of the three, so "other" is the honest value rather than a guess.
63
- "X-Agent-Runtime": "other",
64
- "X-User-Id": args.userId,
65
- ...(args.privateData === true ? { "X-Private-Data": "true" } : {}),
66
- ...(enterpriseId === undefined
67
- ? {}
68
- : {
69
- "X-Enterprise-Id": enterpriseId,
70
- // The tenant falls back to the enterprise: the two are the same value
71
- // for an account that belongs to one enterprise, and the upstream
72
- // reads both.
73
- "X-Tenant-Id": enterpriseId,
74
- }),
75
- };
76
- }