cartethyia 2.4.4 → 2.4.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 (304) hide show
  1. package/.env.example +4 -1
  2. package/README.md +18 -0
  3. package/dist/dashboard/assets/AccountCooldown-ChpdzxRH.js.gz +0 -0
  4. package/dist/dashboard/assets/{BannedPage-TDue2X0p.js → BannedPage-QhvbJB9o.js} +1 -1
  5. package/dist/dashboard/assets/BannedPage-QhvbJB9o.js.gz +0 -0
  6. package/dist/dashboard/assets/{CliToolDetailPage-qaHXuiI5.js → CliToolDetailPage-Bcy150Jo.js} +1 -1
  7. package/dist/dashboard/assets/CliToolDetailPage-Bcy150Jo.js.gz +0 -0
  8. package/dist/dashboard/assets/{CliToolsPage-BFuQBKez.js → CliToolsPage-DyNXefph.js} +1 -1
  9. package/dist/dashboard/assets/CliToolsPage-DyNXefph.js.gz +0 -0
  10. package/dist/dashboard/assets/CombosPage-Cak0ljnO.js +1 -0
  11. package/dist/dashboard/assets/CombosPage-Cak0ljnO.js.gz +0 -0
  12. package/dist/dashboard/assets/ConsoleLogPage-CATpAEOz.js +1 -0
  13. package/dist/dashboard/assets/ConsoleLogPage-CATpAEOz.js.gz +0 -0
  14. package/dist/dashboard/assets/{CustomizationPage-BhglcqyR.js → CustomizationPage-D6jEU7nL.js} +1 -1
  15. package/dist/dashboard/assets/CustomizationPage-D6jEU7nL.js.gz +0 -0
  16. package/dist/dashboard/assets/HealthEventsModal-CZkpn0a7.js +1 -0
  17. package/dist/dashboard/assets/HealthEventsModal-CZkpn0a7.js.gz +0 -0
  18. package/dist/dashboard/assets/{LoginPage-CeqROJrT.js → LoginPage-BJlMVN4U.js} +1 -1
  19. package/dist/dashboard/assets/LoginPage-BJlMVN4U.js.gz +0 -0
  20. package/dist/dashboard/assets/ModelPicker-Br3CXEau.js +1 -0
  21. package/dist/dashboard/assets/ModelPicker-Br3CXEau.js.gz +0 -0
  22. package/dist/dashboard/assets/{OverviewPage-CRXSAITY.js → OverviewPage-CQxXbo2g.js} +1 -1
  23. package/dist/dashboard/assets/OverviewPage-CQxXbo2g.js.gz +0 -0
  24. package/dist/dashboard/assets/ProviderDetailPage--0RBNh99.js +3 -0
  25. package/dist/dashboard/assets/ProviderDetailPage--0RBNh99.js.gz +0 -0
  26. package/dist/dashboard/assets/ProviderIcon-paOCq8I0.js.gz +0 -0
  27. package/dist/dashboard/assets/ProvidersPage-1M-C3mbu.js +1 -0
  28. package/dist/dashboard/assets/ProvidersPage-1M-C3mbu.js.gz +0 -0
  29. package/dist/dashboard/assets/ProxyPage-CXiumA53.js +7 -0
  30. package/dist/dashboard/assets/ProxyPage-CXiumA53.js.gz +0 -0
  31. package/dist/dashboard/assets/QuotaPage-BGDIfIYP.js +1 -0
  32. package/dist/dashboard/assets/QuotaPage-BGDIfIYP.js.gz +0 -0
  33. package/dist/dashboard/assets/{SettingsPage-YxRml8AT.js → SettingsPage-BHW4Zt06.js} +1 -1
  34. package/dist/dashboard/assets/SettingsPage-BHW4Zt06.js.gz +0 -0
  35. package/dist/dashboard/assets/SetupPage-VOYC_lIa.js +1 -0
  36. package/dist/dashboard/assets/SetupPage-VOYC_lIa.js.gz +0 -0
  37. package/dist/dashboard/assets/SortableList-DpOTnGuH.js +1 -0
  38. package/dist/dashboard/assets/SortableList-DpOTnGuH.js.gz +0 -0
  39. package/dist/dashboard/assets/StudioPage-BNIDLiU6.js +31 -0
  40. package/dist/dashboard/assets/StudioPage-BNIDLiU6.js.gz +0 -0
  41. package/dist/dashboard/assets/ToolIcon-K1ckcDKg.js.gz +0 -0
  42. package/dist/dashboard/assets/{UsagePage-B6LA4ewF.js → UsagePage-BAFaSDQV.js} +14 -14
  43. package/dist/dashboard/assets/UsagePage-BAFaSDQV.js.gz +0 -0
  44. package/dist/dashboard/assets/api-keys-BETfaMYZ.js +1 -0
  45. package/dist/dashboard/assets/api-keys-BETfaMYZ.js.gz +0 -0
  46. package/dist/dashboard/assets/app-BLCvGdzb.css +2 -0
  47. package/dist/dashboard/assets/app-BLCvGdzb.css.gz +0 -0
  48. package/dist/dashboard/assets/{app-BDJWMThu.js → app-Cjq7nrwu.js} +3 -3
  49. package/dist/dashboard/assets/app-Cjq7nrwu.js.gz +0 -0
  50. package/dist/dashboard/assets/arrow-left-CpBxkoxI.js.gz +0 -0
  51. package/dist/dashboard/assets/arrow-right-Dl5yKnp8.js.gz +0 -0
  52. package/dist/dashboard/assets/{assert-Bwh6DJTK.js → assert-7J6_LVD3.js} +1 -1
  53. package/dist/dashboard/assets/assert-7J6_LVD3.js.gz +0 -0
  54. package/dist/dashboard/assets/backup-file-gdKIlg8U.js.gz +0 -0
  55. package/dist/dashboard/assets/{badge-BwmwEOgA.js → badge-BTyGk_DL.js} +1 -1
  56. package/dist/dashboard/assets/badge-BTyGk_DL.js.gz +0 -0
  57. package/dist/dashboard/assets/{banner-BKBfKTqn.js → banner-bujTWYM4.js} +1 -1
  58. package/dist/dashboard/assets/banner-bujTWYM4.js.gz +0 -0
  59. package/dist/dashboard/assets/brain-Cwed_72z.js.gz +0 -0
  60. package/dist/dashboard/assets/{card-BTdbRFFg.js → card-B0Bnx5CA.js} +1 -1
  61. package/dist/dashboard/assets/card-B0Bnx5CA.js.gz +0 -0
  62. package/dist/dashboard/assets/check-D69FzdvC.js.gz +0 -0
  63. package/dist/dashboard/assets/chevron-right-BXIy5l3h.js.gz +0 -0
  64. package/dist/dashboard/assets/circle-alert-CntYHV5v.js.gz +0 -0
  65. package/dist/dashboard/assets/circle-check-BU3v_mFW.js.gz +0 -0
  66. package/dist/dashboard/assets/cli-tools-DE2ug812.js +1 -0
  67. package/dist/dashboard/assets/cli-tools-DE2ug812.js.gz +0 -0
  68. package/dist/dashboard/assets/clipboard-button-R_rArH8S.js +1 -0
  69. package/dist/dashboard/assets/clipboard-button-R_rArH8S.js.gz +0 -0
  70. package/dist/dashboard/assets/cog-CdWhsajs.js.gz +0 -0
  71. package/dist/dashboard/assets/copy-ngmQ9zcZ.js.gz +0 -0
  72. package/dist/dashboard/assets/{dialog-iocKA3jr.js → dialog-BWIP_EvW.js} +1 -1
  73. package/dist/dashboard/assets/dialog-BWIP_EvW.js.gz +0 -0
  74. package/dist/dashboard/assets/dialog-actions-B1axpEg7.js.gz +0 -0
  75. package/dist/dashboard/assets/download-A0SW9OCW.js.gz +0 -0
  76. package/dist/dashboard/assets/download-dRFo5_Wu.js.gz +0 -0
  77. package/dist/dashboard/assets/{drawer-CDKOTZdY.js → drawer-BKcgVugF.js} +1 -1
  78. package/dist/dashboard/assets/drawer-BKcgVugF.js.gz +0 -0
  79. package/dist/dashboard/assets/entry-7dpgvpJ3.js +4 -0
  80. package/dist/dashboard/assets/entry-7dpgvpJ3.js.gz +0 -0
  81. package/dist/dashboard/assets/entry-CcWkGR4a.js +1 -0
  82. package/dist/dashboard/assets/entry-CcWkGR4a.js.gz +0 -0
  83. package/dist/dashboard/assets/entry-kTiTFrvh.js +1 -0
  84. package/dist/dashboard/assets/entry-kTiTFrvh.js.gz +0 -0
  85. package/dist/dashboard/assets/eye-C_hawfH4.js.gz +0 -0
  86. package/dist/dashboard/assets/eye-off-Bk5g2luF.js.gz +0 -0
  87. package/dist/dashboard/assets/fingerprint-pattern-BWuHtbW4.js.gz +0 -0
  88. package/dist/dashboard/assets/gauge-BbIMy7MB.js.gz +0 -0
  89. package/dist/dashboard/assets/github-badge-Booc5mNe.js +1 -0
  90. package/dist/dashboard/assets/github-badge-Booc5mNe.js.gz +0 -0
  91. package/dist/dashboard/assets/image-BPaouViG.js.gz +0 -0
  92. package/dist/dashboard/assets/{index-BA_ni9Ix.js → index-D70pChfn.js} +2 -2
  93. package/dist/dashboard/assets/index-D70pChfn.js.gz +0 -0
  94. package/dist/dashboard/assets/{inline-DCejSLlA.js → inline-D1TCqM2D.js} +1 -1
  95. package/dist/dashboard/assets/inline-D1TCqM2D.js.gz +0 -0
  96. package/dist/dashboard/assets/{input-Bn4_kNav.js → input-B9oyU93y.js} +1 -1
  97. package/dist/dashboard/assets/input-B9oyU93y.js.gz +0 -0
  98. package/dist/dashboard/assets/jsx-runtime-CXUMngI_.js.gz +0 -0
  99. package/dist/dashboard/assets/key-round-UkavsGxp.js.gz +0 -0
  100. package/dist/dashboard/assets/layers-2-glBbjl.js.gz +0 -0
  101. package/dist/dashboard/assets/{layout-Bv-NxqZ5.js → layout-BArzXirQ.js} +1 -1
  102. package/dist/dashboard/assets/layout-BArzXirQ.js.gz +0 -0
  103. package/dist/dashboard/assets/{list-row-BLA0sldD.js → list-row-BVZzaoHF.js} +1 -1
  104. package/dist/dashboard/assets/list-row-BVZzaoHF.js.gz +0 -0
  105. package/dist/dashboard/assets/{live-YlifPYox.js → live-EmuIayqp.js} +1 -1
  106. package/dist/dashboard/assets/live-EmuIayqp.js.gz +0 -0
  107. package/dist/dashboard/assets/log-in-BmRjy60c.js.gz +0 -0
  108. package/dist/dashboard/assets/message-circle-CCxGwRvv.js.gz +0 -0
  109. package/dist/dashboard/assets/{model-bans-CVvHZ-qz.js → model-bans-CSPQ9xB0.js} +1 -1
  110. package/dist/dashboard/assets/model-bans-CSPQ9xB0.js.gz +0 -0
  111. package/dist/dashboard/assets/mutation-BkoLM5Ba.js +1 -0
  112. package/dist/dashboard/assets/mutation-BkoLM5Ba.js.gz +0 -0
  113. package/dist/dashboard/assets/numbers-CFL4_Dqc.js.gz +0 -0
  114. package/dist/dashboard/assets/pencil-768ysRAr.js.gz +0 -0
  115. package/dist/dashboard/assets/plus-DIdX_g-x.js.gz +0 -0
  116. package/dist/dashboard/assets/power-off-Yjw9GMJh.js +1 -0
  117. package/dist/dashboard/assets/power-off-Yjw9GMJh.js.gz +0 -0
  118. package/dist/dashboard/assets/privacy-mode-GM8bej85.js +1 -0
  119. package/dist/dashboard/assets/privacy-mode-GM8bej85.js.gz +0 -0
  120. package/dist/dashboard/assets/providers/agentrouter.svg.gz +0 -0
  121. package/dist/dashboard/assets/providers/aihubmix.svg.gz +0 -0
  122. package/dist/dashboard/assets/providers/alibaba-coding-plan.svg.gz +0 -0
  123. package/dist/dashboard/assets/providers/alibaba.svg.gz +0 -0
  124. package/dist/dashboard/assets/providers/antigravity.svg.gz +0 -0
  125. package/dist/dashboard/assets/providers/bai.svg.gz +0 -0
  126. package/dist/dashboard/assets/providers/blackbox.svg.gz +0 -0
  127. package/dist/dashboard/assets/providers/claude-code.svg.gz +0 -0
  128. package/dist/dashboard/assets/providers/exa.svg.gz +0 -0
  129. package/dist/dashboard/assets/providers/gmi-cloud.svg.gz +0 -0
  130. package/dist/dashboard/assets/providers/inferhub.svg.gz +0 -0
  131. package/dist/dashboard/assets/providers/muse.svg.gz +0 -0
  132. package/dist/dashboard/assets/providers/nous-research.svg.gz +0 -0
  133. package/dist/dashboard/assets/providers/openai-light.svg.gz +0 -0
  134. package/dist/dashboard/assets/providers/parallel.svg.gz +0 -0
  135. package/dist/dashboard/assets/providers/tokenharbor.svg.gz +0 -0
  136. package/dist/dashboard/assets/providers/zai-coding-plan.svg.gz +0 -0
  137. package/dist/dashboard/assets/{query-keys-ROf-g1Wi.js → query-keys-D7wX2vM5.js} +1 -1
  138. package/dist/dashboard/assets/query-keys-D7wX2vM5.js.gz +0 -0
  139. package/dist/dashboard/assets/quota-DZGyp0N5.js.gz +0 -0
  140. package/dist/dashboard/assets/refresh-cw-BqJFk4sU.js.gz +0 -0
  141. package/dist/dashboard/assets/rotate-ccw-CufcqITi.js.gz +0 -0
  142. package/dist/dashboard/assets/route-CNSNj9Zm.js.gz +0 -0
  143. package/dist/dashboard/assets/{routing-jntw9-Ui.js → routing-BExgxxBU.js} +1 -1
  144. package/dist/dashboard/assets/routing-BExgxxBU.js.gz +0 -0
  145. package/dist/dashboard/assets/scaling-nWE4Cx8f.js.gz +0 -0
  146. package/dist/dashboard/assets/search-JOKus9rb.js.gz +0 -0
  147. package/dist/dashboard/assets/{select-CGUuTQmj.js → select-C9mMoEpJ.js} +1 -1
  148. package/dist/dashboard/assets/select-C9mMoEpJ.js.gz +0 -0
  149. package/dist/dashboard/assets/settings-C4_Gn_wq.js +1 -0
  150. package/dist/dashboard/assets/settings-C4_Gn_wq.js.gz +0 -0
  151. package/dist/dashboard/assets/shield-check-DVS0Foqh.js.gz +0 -0
  152. package/dist/dashboard/assets/sliders-horizontal-ClG7dBeJ.js.gz +0 -0
  153. package/dist/dashboard/assets/sparkles-BRaRUxAU.js.gz +0 -0
  154. package/dist/dashboard/assets/{stack-C1kTcOmP.js → stack-Ca5HxI5i.js} +1 -1
  155. package/dist/dashboard/assets/stack-Ca5HxI5i.js.gz +0 -0
  156. package/dist/dashboard/assets/{state-DHKdg-pm.js → state-CzUPfLXo.js} +1 -1
  157. package/dist/dashboard/assets/state-CzUPfLXo.js.gz +0 -0
  158. package/dist/dashboard/assets/stream-retry-5QnVuSSo.js.gz +0 -0
  159. package/dist/dashboard/assets/{switch-DIDeAiz9.js → switch-DOUIky_i.js} +1 -1
  160. package/dist/dashboard/assets/switch-DOUIky_i.js.gz +0 -0
  161. package/dist/dashboard/assets/terminal-Bd4ee8TA.js +1 -0
  162. package/dist/dashboard/assets/terminal-Bd4ee8TA.js.gz +0 -0
  163. package/dist/dashboard/assets/toast-C76WrMhc.js +2 -0
  164. package/dist/dashboard/assets/toast-C76WrMhc.js.gz +0 -0
  165. package/dist/dashboard/assets/tokens-DDxMbSRL.js.gz +0 -0
  166. package/dist/dashboard/assets/trash-Cppn5c3R.js.gz +0 -0
  167. package/dist/dashboard/assets/use-clipboard-B0Sy03fE.js.gz +0 -0
  168. package/dist/dashboard/assets/use-presence-BSZEBx7U.js.gz +0 -0
  169. package/dist/dashboard/assets/use-reduced-motion-C4B0R6Sz.js.gz +0 -0
  170. package/dist/dashboard/assets/use-timeout-BwcBBRrT.js.gz +0 -0
  171. package/dist/dashboard/assets/{useMutation-DVmwOKU-.js → useMutation-D87FZwH0.js} +1 -1
  172. package/dist/dashboard/assets/useMutation-D87FZwH0.js.gz +0 -0
  173. package/dist/dashboard/assets/wrench-B6E1oEuY.js.gz +0 -0
  174. package/dist/dashboard/index.html +1 -1
  175. package/dist/dashboard/index.html.gz +0 -0
  176. package/dist/dashboard/precompressed-assets.json +123 -0
  177. package/migrations/full-postgres/0013_add_providers_tenant_id_index.sql +22 -0
  178. package/migrations/full-postgres/0014_add_provider_accounts_tenant_id_index.sql +21 -0
  179. package/migrations/lite-sqlite3/0000_baseline.sql +4 -2
  180. package/migrations/lite-sqlite3/0013_add_providers_tenant_id_index.sql +4 -0
  181. package/migrations/lite-sqlite3/0014_add_provider_accounts_tenant_id_index.sql +4 -0
  182. package/package.json +25 -30
  183. package/scripts/cli/{carte-launcher.cjs → bin/carte.cjs} +8 -8
  184. package/scripts/cli/{cli-launcher.cjs → bin/cartethyia.cjs} +167 -134
  185. package/scripts/cli/command/admin.ts +65 -0
  186. package/scripts/cli/command/console-menu.ts +227 -0
  187. package/scripts/cli/{doctor.ts → command/doctor.ts} +257 -258
  188. package/scripts/cli/{setup.ts → command/setup.ts} +8 -12
  189. package/scripts/cli/command/start.ts +13 -0
  190. package/scripts/cli/command/tray.ts +165 -0
  191. package/scripts/cli/command/update.ts +23 -0
  192. package/scripts/cli/{runtime-state.ts → gateway/drain-token.ts} +78 -78
  193. package/scripts/cli/gateway/spawn.ts +101 -0
  194. package/scripts/cli/gateway/stop.ts +51 -0
  195. package/scripts/cli/main.ts +94 -0
  196. package/scripts/cli/support/bun.ts +27 -0
  197. package/scripts/cli/support/env.ts +99 -0
  198. package/scripts/cli/support/platform.ts +64 -0
  199. package/scripts/cli/support/services.ts +88 -0
  200. package/scripts/cli/support/startup-signal.ts +23 -0
  201. package/scripts/cli/support/version.ts +37 -0
  202. package/scripts/cli/tray/hidden-window.vbs +28 -0
  203. package/scripts/cli/{tray.ts → tray/index.ts} +3 -3
  204. package/scripts/cli/{tray.ps1 → tray/windows.ps1} +107 -98
  205. package/scripts/cli/ui/background.ts +49 -0
  206. package/src/boot/app.ts +3 -1
  207. package/src/boot/dependencies.ts +36 -13
  208. package/src/config/providers.ts +27 -1
  209. package/src/config/spec.ts +11 -0
  210. package/src/console/backup/routes.ts +8 -0
  211. package/src/console/cli-tools/contracts.ts +6 -6
  212. package/src/console/console-router.ts +5 -3
  213. package/src/console/dashboard-assets.ts +81 -11
  214. package/src/console/observability/contracts.ts +54 -22
  215. package/src/console/observability/routes.ts +31 -6
  216. package/src/console/observability/store.ts +68 -28
  217. package/src/console/providers/catalog/public-model-store.ts +91 -60
  218. package/src/console/providers/catalog/store.ts +5 -1
  219. package/src/console/quota/account-quota-tenant.ts +9 -6
  220. package/src/console/response-compression.ts +69 -2
  221. package/src/console/routing/pools/probe-verdict.ts +72 -0
  222. package/src/console/share/share-router.ts +7 -4
  223. package/src/console/share/share-stats.ts +12 -5
  224. package/src/console/shared/read-through-cache.ts +133 -7
  225. package/src/console/updates/repository-updates.ts +39 -34
  226. package/src/network/outbound-fetch.ts +113 -25
  227. package/src/network/tls/bun-client-hello.ts +112 -0
  228. package/src/observability/event-log.ts +29 -8
  229. package/src/observability/metrics.ts +40 -13
  230. package/src/observability/runtime-metrics.ts +7 -0
  231. package/src/persistence/schema.ts +40 -2
  232. package/src/protocol/response/codex.ts +9 -75
  233. package/src/protocol/tool-identity.ts +43 -9
  234. package/src/providers/authentication/jwt-validator.ts +130 -187
  235. package/src/providers/authentication/oauth-flow-store.ts +16 -9
  236. package/src/providers/default-registry.ts +4 -0
  237. package/src/providers/discovery/catalog/catalog-format.ts +20 -0
  238. package/src/providers/discovery/models-dev-catalog.ts +39 -22
  239. package/src/providers/discovery/probe-wire.ts +29 -5
  240. package/src/providers/integrations/buddy/buddy-catalog-shared.ts +3 -2
  241. package/src/providers/integrations/buddy/buddy-cli-headers.ts +88 -0
  242. package/src/providers/integrations/buddy/buddy-conversation-headers.ts +4 -0
  243. package/src/providers/integrations/buddy/buddy-discovery-shared.ts +33 -1
  244. package/src/providers/integrations/buddy/buddy-identity.ts +46 -0
  245. package/src/providers/integrations/buddy/buddy-oauth-shared.ts +37 -1
  246. package/src/providers/integrations/buddy/buddy-usage-store.ts +40 -5
  247. package/src/providers/integrations/buddy/codebuddy/provider.ts +2 -2
  248. package/src/providers/integrations/buddy/codebuddy/shared.ts +106 -73
  249. package/src/providers/integrations/buddy/workbuddy/cn-provider.ts +5 -2
  250. package/src/providers/integrations/buddy/workbuddy/quota.ts +172 -159
  251. package/src/providers/integrations/buddy/workbuddy/shared.ts +200 -171
  252. package/src/providers/integrations/codex/codex.ts +5 -8
  253. package/src/providers/integrations/factory/factory-oauth.ts +7 -11
  254. package/src/providers/integrations/opencode/opencode-go-quota.ts +130 -0
  255. package/src/providers/integrations/opencode/provider.ts +42 -3
  256. package/src/providers/integrations/qoder/qoder-oauth.ts +3 -9
  257. package/src/providers/integrations/shared/install-id.ts +29 -2
  258. package/src/providers/operations/client-versions.ts +11 -1
  259. package/src/providers/operations/model-catalog-cache.ts +18 -3
  260. package/src/providers/operations/provider-catalog-service.ts +76 -0
  261. package/src/transport/dispatch/attempt-finalize.ts +7 -1
  262. package/src/transport/dispatch/attempt-loop.ts +9 -7
  263. package/src/transport/dispatch/empty-stream.ts +17 -26
  264. package/src/transport/failure-policy.ts +20 -0
  265. package/src/transport/routing/route-catalog.ts +42 -3
  266. package/src/transport/surface/chat/encode.ts +18 -31
  267. package/src/transport/surface/messages/stream.ts +3 -2
  268. package/src/transport/translation/tool-repair.ts +37 -16
  269. package/src/workers/account-identity-sweep.ts +14 -12
  270. package/src/workers/daily-checkin.ts +62 -0
  271. package/src/workers/quota-refresh-sweep.ts +27 -2
  272. package/dist/dashboard/assets/CombosPage-B7ETkfVH.js +0 -1
  273. package/dist/dashboard/assets/ConsoleLogPage-vkZBxMVo.js +0 -1
  274. package/dist/dashboard/assets/HealthEventsModal-DDkHfwpV.js +0 -1
  275. package/dist/dashboard/assets/ModelPicker-CAiPR5Vd.js +0 -1
  276. package/dist/dashboard/assets/ProviderDetailPage-cNAD_6uN.js +0 -3
  277. package/dist/dashboard/assets/ProvidersPage-Cv5tdxlx.js +0 -1
  278. package/dist/dashboard/assets/ProxyPage-CWvMfzjj.js +0 -7
  279. package/dist/dashboard/assets/QuotaPage-IYQOOHR4.js +0 -1
  280. package/dist/dashboard/assets/SetupPage-BPDNo3Ek.js +0 -1
  281. package/dist/dashboard/assets/SortableList-Bol1ASmI.js +0 -1
  282. package/dist/dashboard/assets/StudioPage-BE5DJONZ.js +0 -31
  283. package/dist/dashboard/assets/api-keys-CjIGQhe7.js +0 -1
  284. package/dist/dashboard/assets/app-Cjgo4-Lf.css +0 -2
  285. package/dist/dashboard/assets/cli-tools-DccaOfhX.js +0 -1
  286. package/dist/dashboard/assets/clipboard-button-DQmMikNQ.js +0 -1
  287. package/dist/dashboard/assets/entry-DTiWhIY-.js +0 -4
  288. package/dist/dashboard/assets/entry-Dm3PpDCO.js +0 -1
  289. package/dist/dashboard/assets/entry-keNDZ_Wz.js +0 -1
  290. package/dist/dashboard/assets/github-badge-BuAJr8oU.js +0 -1
  291. package/dist/dashboard/assets/mutation-BIizFZav.js +0 -1
  292. package/dist/dashboard/assets/privacy-mode-CQjbZ3xk.js +0 -1
  293. package/dist/dashboard/assets/settings-BAS6QbmJ.js +0 -1
  294. package/dist/dashboard/assets/terminal-C9mZ4Ugm.js +0 -1
  295. package/dist/dashboard/assets/toast-DKAdP2mo.js +0 -2
  296. package/scripts/cli/cli.ts +0 -766
  297. package/scripts/cli/version.ts +0 -66
  298. package/scripts/operations/probe-egress.ts +0 -335
  299. package/scripts/operations/restart.ts +0 -120
  300. package/scripts/shared/env.ts +0 -269
  301. /package/{tray-assets → scripts/cli/tray/assets}/cartethyia.ico +0 -0
  302. /package/{tray-assets → scripts/cli/tray/assets}/cartethyia.png +0 -0
  303. /package/scripts/cli/{menu.ts → ui/prompt.ts} +0 -0
  304. /package/scripts/cli/{wordmark.ts → ui/wordmark.ts} +0 -0
@@ -1 +0,0 @@
1
- import{o as e,r as t,t as n}from"./jsx-runtime-CXUMngI_.js";import{n as r,t as i}from"./select-CGUuTQmj.js";import{i as a,n as o}from"./toast-DKAdP2mo.js";import{t as s}from"./eye-off-Bk5g2luF.js";import{t as c}from"./eye-C_hawfH4.js";import{n as l,r as u,t as d}from"./state-DHKdg-pm.js";import{t as f}from"./dialog-iocKA3jr.js";import{t as p}from"./plus-DIdX_g-x.js";import{t as m}from"./trash-Cppn5c3R.js";import{c as h}from"./query-keys-ROf-g1Wi.js";import{t as g}from"./dialog-actions-B1axpEg7.js";import{C as _,J as v,S as y,Z as b,a as x,et as S,g as C,h as w,i as T,m as E,s as D}from"./entry-DTiWhIY-.js";import{n as O,r as k,t as A}from"./card-BTdbRFFg.js";import{t as j}from"./badge-BwmwEOgA.js";import{n as M}from"./input-Bn4_kNav.js";import{t as N}from"./ProviderIcon-paOCq8I0.js";import{t as P}from"./switch-DIDeAiz9.js";import{t as F}from"./stack-C1kTcOmP.js";import{n as I}from"./inline-DCejSLlA.js";import{t as L}from"./list-row-BLA0sldD.js";import{r as R}from"./AccountCooldown-ChpdzxRH.js";var z=e(t(),1),B=n();function ee(e){let t={};for(let[n,r]of e)n.trim()&&(t[n.trim()]=r);return t}function te({pairs:e,onChange:t}){let n=(n,r)=>t(e.map((e,t)=>t===n?r:e)),r=n=>t(e.filter((e,t)=>t!==n));return(0,B.jsxs)(`div`,{className:`form-group`,children:[(0,B.jsxs)(`label`,{className:`form-label block`,children:[(0,B.jsx)(`span`,{className:`block`,children:`Custom Headers`}),(0,B.jsx)(`span`,{className:`form-hint block mt-1`,children:`Optional — sent with every request, override built-in headers on a name collision`})]}),(0,B.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[e.map(([e,t],i)=>(0,B.jsxs)(`div`,{className:`flex min-w-0 gap-3`,children:[(0,B.jsx)(M,{placeholder:`Header-Name`,value:e,onChange:e=>n(i,[e.target.value,t]),className:`font-mono tabular-nums min-w-0 flex-1 text-caption`}),(0,B.jsx)(M,{placeholder:`value`,value:t,onChange:t=>n(i,[e,t.target.value]),className:`font-mono tabular-nums min-w-0 flex-1 text-caption`}),(0,B.jsx)(o,{type:`button`,variant:`ghost`,size:`icon`,"aria-label":`Remove ${e||`header`}`,onClick:()=>r(i),children:(0,B.jsx)(m,{size:13})})]},i)),(0,B.jsxs)(o,{type:`button`,variant:`secondary`,size:`sm`,onClick:()=>t([...e,[``,``]]),children:[(0,B.jsx)(p,{size:13}),` Add header`]})]})]})}function V({children:e}){return(0,B.jsx)(`div`,{className:`provider-grid grid gap-6 w-full min-w-0`,children:e})}var H=a(`relative flex flex-col min-w-0 border border-inner-border rounded-card`,`transition-[transform,border-color,box-shadow]`),U=a(`block flex-1 p-6 no-underline text-inherit`),W=a(`text-body font-semibold overflow-hidden text-ellipsis whitespace-nowrap`);function G(e){let t=e.serviceKinds;return Array.isArray(t)&&t.length>0?t:[`llm`]}var K=/\/(?:v\d+\/)?(?:messages|chat\/completions|responses|completions|embeddings|images\/generations)$/;function ne(e){let t=e.trim().replace(/\/+$/,``);if(t===``)return null;let n,r;try{n=new URL(t),r=n.pathname.replace(/\/+$/,``)}catch{return null}return K.test(r)?n.origin:null}function q({variant:e,open:t,onClose:n}){let r=T(),s=x(),c=y(),l=_(),[u,d]=(0,z.useState)(``),[p,m]=(0,z.useState)(``),[g,v]=(0,z.useState)(``),[b,S]=(0,z.useState)(``),[C,w]=(0,z.useState)(!1),[E,D]=(0,z.useState)(!0),[O,k]=(0,z.useState)([]),[A,j]=(0,z.useState)(null),[N,F]=(0,z.useState)(!1),[R,V]=(0,z.useState)(null),[H,U]=(0,z.useState)(!1),W=e===`anthropic-compatible`,G=W?`messages`:`chat`,[K,q]=(0,z.useState)(G),J=(0,z.useMemo)(()=>ne(g),[g]);(0,z.useEffect)(()=>{t&&(d(``),S(``),q(G),v(``),w(!1),D(!0),k([]),j(null),V(null))},[t]);let Y=async e=>{try{let t=await navigator.clipboard.readText();t.trim()&&e(t.trim())}catch{j(`Clipboard access denied — paste manually instead.`)}},X=async()=>{if(!g.trim()){V({ok:!1,message:`Base URL is required to test the connection.`});return}U(!0),V(null),j(null);try{let e=ee(O),t=await l.mutateAsync({baseUrl:g.trim(),apiKey:b.trim(),wireFamily:K,cliIdentity:E,...Object.keys(e).length>0?{extraHeaders:e}:{}});if(t.ok){let e=typeof t.modelCount==`number`?` — upstream advertised ${t.modelCount} model(s)`:``;V({ok:!0,message:`Connected successfully (${t.latencyMs}ms)${e}.`,...t.warning===void 0?{}:{warning:t.warning}})}else V({ok:!1,message:t.error??`Connection failed.`,...t.warning===void 0?{}:{warning:t.warning}})}catch(e){V({ok:!1,message:h(e,`Connection test failed`)})}finally{U(!1)}};return(0,B.jsx)(f,{open:t,onClose:n,title:W?`Add Custom Anthropic Provider`:`Add Custom OpenAI Provider`,footer:(0,B.jsxs)(B.Fragment,{children:[(0,B.jsx)(o,{variant:`secondary`,type:`button`,onClick:n,children:`Cancel`}),(0,B.jsx)(o,{variant:`primary`,type:`submit`,form:`add-compatible-provider`,disabled:N,children:N?`Creating...`:`Add Provider`})]}),children:(0,B.jsxs)(`form`,{id:`add-compatible-provider`,onSubmit:async e=>{if(e.preventDefault(),!u.trim()){j(`Display Name is required`);return}if(!p.trim()){j(`Provider ID (slug) is required`);return}if(!g.trim()){j(`Base URL is required`);return}let t=ee(O),i=p.trim().toLowerCase();F(!0),j(null);try{let e={providerId:i,label:u.trim(),baseUrl:g.trim(),wireFamily:K,compatibilityProfile:{cli_identity:E,...Object.keys(t).length>0?{extra_headers:t}:{}}};await r.mutateAsync(e),b.trim()&&await s.mutateAsync({providerId:i,request:{credentialKind:`api_key`,secret:b.trim()}}),C&&await c.mutateAsync(i),n()}catch(e){j(h(e,`Failed to create provider`))}finally{F(!1)}},className:`flex flex-col gap-6`,children:[A?(0,B.jsx)(`div`,{className:`text-red text-caption`,children:A}):null,(0,B.jsx)(M,{label:`Display Name`,hint:`Required. A friendly label for this node.`,id:`compat-label`,value:u,onChange:e=>d(e.target.value),placeholder:W?`Anthropic Compatible (Prod)`:`OpenAI Compatible (Prod)`,required:!0}),(0,B.jsx)(M,{label:`Provider ID / Slug`,hint:`Required. Used as the provider prefix for model IDs.`,id:`compat-slug`,value:p,onChange:e=>m(e.target.value),placeholder:W?`ac-prod`:`oc-prod`,required:!0}),(0,B.jsxs)(`div`,{className:`form-group`,children:[(0,B.jsxs)(`label`,{className:`form-label`,htmlFor:`compat-url`,children:[(0,B.jsx)(`span`,{children:`Base URL`}),(0,B.jsxs)(`span`,{className:`form-hint`,children:[`The root only. Do not paste the full endpoint — leave off`,W?" `/v1/messages`.":" `/chat/completions`."]})]}),(0,B.jsxs)(I,{gap:`8px`,children:[(0,B.jsx)(`div`,{className:`flex-1 min-w-0`,children:(0,B.jsx)(M,{id:`compat-url`,value:g,onChange:e=>v(e.target.value),placeholder:W?`https://api.anthropic.com/v1`:`https://api.openai.com/v1`,required:!0})}),(0,B.jsx)(o,{type:`button`,variant:`secondary`,onClick:()=>Y(v),children:`Paste`})]}),J===null?null:(0,B.jsxs)(`p`,{className:`mt-1.5 text-caption text-orange`,children:[`That looks like a full endpoint. Use`,` `,(0,B.jsx)(`code`,{className:`font-mono`,children:J}),` instead — Cartethyia appends the endpoint path itself.`]})]}),W?null:(0,B.jsx)(i,{id:`compat-wire`,label:`API format`,value:K,onValueChange:e=>q(e),options:[{value:`chat`,label:`Chat completions`},{value:`responses`,label:`Responses`}]}),(0,B.jsxs)(`div`,{className:`form-group`,children:[(0,B.jsxs)(`label`,{className:`form-label`,htmlFor:`compat-credential`,children:[(0,B.jsx)(`span`,{children:`API Key`}),(0,B.jsx)(`span`,{className:`form-hint`,children:`Optional — saved with this provider and used to authenticate every request.`})]}),(0,B.jsxs)(I,{gap:`8px`,children:[(0,B.jsx)(`div`,{className:`flex-1 min-w-0`,children:(0,B.jsx)(M,{id:`compat-credential`,type:`password`,placeholder:`sk-...`,value:b,onChange:e=>S(e.target.value)})}),(0,B.jsx)(o,{type:`button`,variant:`secondary`,disabled:H,onClick:()=>void X(),children:H?`Testing...`:`Test connection`}),(0,B.jsx)(o,{type:`button`,variant:`secondary`,onClick:()=>Y(S),children:`Paste`})]}),R?(0,B.jsxs)(B.Fragment,{children:[(0,B.jsxs)(`div`,{className:a(`mt-3 text-caption leading-[1.4] break-words`,R.ok?`text-green`:`text-red`),children:[R.ok?`✓ `:`✗ `,R.message]}),R.warning?(0,B.jsxs)(`div`,{className:`mt-2 text-caption leading-snug break-words text-orange`,children:[`⚠ `,R.warning]}):null]}):null]}),(0,B.jsx)(L,{actions:(0,B.jsx)(P,{checked:C,onChange:w,id:`compat-autofetch`}),children:(0,B.jsxs)(`div`,{children:[(0,B.jsx)(`div`,{className:`text-body font-semibold`,children:`Auto-fetch models`}),(0,B.jsx)(`div`,{className:`mt-1 text-badge text-text-tertiary`,children:`Discover this provider's model list automatically after creation`})]})}),(0,B.jsx)(L,{actions:(0,B.jsx)(P,{checked:E,onChange:D,id:`compat-cli-identity`}),children:(0,B.jsxs)(`div`,{children:[(0,B.jsx)(`div`,{className:`text-body font-semibold`,children:W?`Send request as Claude CLI`:`Send request as Codex CLI`}),(0,B.jsx)(`div`,{className:`mt-1 text-badge text-text-tertiary`,children:W?`Emits official Claude CLI User-Agent and Stainless headers to upstream`:`Emits official codex_cli_rs User-Agent and originator headers to upstream`})]})}),(0,B.jsx)(te,{pairs:O,onChange:k})]})})}function J({customProvider:e}){let t=D(),[n,r]=(0,z.useState)(!1),i=w(e.providerId),s=i.data?.length,c=E(e.providerId),l=c.data,u=ie(l??[]);return(0,B.jsxs)(A,{className:H,children:[(0,B.jsx)(oe,{clientVersion:e.clientVersion}),(0,B.jsx)(v,{to:`/providers/${encodeURIComponent(e.providerId)}`,className:a(U,`pr-20 min-h-38`),children:(0,B.jsxs)(I,{gap:`10px`,children:[(0,B.jsx)(N,{icon:e.wireFamilyDefault===`messages`?`anthropic`:`openai`,name:e.label||e.providerId,size:32,imageSize:24}),(0,B.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,B.jsx)(`div`,{className:W,children:e.label||e.providerId}),(0,B.jsxs)(`div`,{className:`mt-1.5 flex flex-wrap gap-2`,children:[l===void 0?(0,B.jsx)($,{kind:`accounts`,isPending:c.isPending,isError:c.isError,hasData:!1}):l.length===0?e.requiresAccount===!1?(0,B.jsx)(j,{tone:`ok`,children:`Free Endpoint`}):(0,B.jsx)(j,{children:`No connections`}):(0,B.jsx)(ae,{counts:u,total:l.length}),c.isError&&l!==void 0?(0,B.jsx)(j,{tone:`warn`,children:`Connections unavailable`}):null]})]}),(0,B.jsxs)(`div`,{className:`flex flex-col items-end gap-1.5 shrink-0`,children:[(0,B.jsxs)(`span`,{className:`font-mono tabular-nums text-micro font-semibold bg-kbd-bg px-2.5 py-0.5 rounded-chip text-text-secondary`,children:[e.providerId,`/`]}),s!==void 0&&s>0?(0,B.jsxs)(j,{tone:`info`,children:[s,` models`]}):null,i.isError?(0,B.jsx)(j,{tone:`warn`,children:`Models unavailable`}):s===void 0?(0,B.jsx)($,{kind:`models`,isPending:i.isPending,isError:!1,hasData:!1}):s===0?(0,B.jsx)($,{kind:`models`,isPending:!1,isError:!1,hasData:!0,isEmpty:!0}):null]})]})}),(0,B.jsx)(o,{variant:`ghost`,size:`sm`,icon:(0,B.jsx)(m,{size:12}),onClick:()=>r(!0),className:`absolute top-2 right-2 p-2 text-text-tertiary`,title:`Delete ${e.label||e.providerId}`}),(0,B.jsx)(f,{open:n,onClose:()=>r(!1),title:`Delete Custom Provider`,children:(0,B.jsxs)(F,{gap:`12px`,children:[(0,B.jsxs)(`p`,{className:`text-body text-text-secondary`,children:[`Are you sure you want to delete custom provider`,` `,(0,B.jsx)(`strong`,{children:e.label||e.providerId}),`? Its models, accounts, and routing preferences are deleted together, and requests to this provider will no longer route.`]}),t.isError?(0,B.jsx)(`p`,{className:`text-caption text-red`,children:h(t.error,`Delete failed`)}):null,(0,B.jsxs)(g,{children:[(0,B.jsx)(o,{variant:`secondary`,onClick:()=>r(!1),children:`Cancel`}),(0,B.jsx)(o,{variant:`danger`,onClick:()=>{t.mutate(e.providerId,{onSuccess:()=>r(!1),onError:()=>void 0})},disabled:t.isPending,children:t.isPending?`Deleting...`:`Delete Provider`})]})]})})]})}function Y({customProviders:e}){let[t,n]=(0,z.useState)(!1),[i,a]=(0,z.useState)(!1),[l,u]=(0,z.useState)(()=>{try{return window.localStorage.getItem(`cartethyia.customProvidersHidden`)===`1`}catch{return!1}});function d(){u(e=>{let t=!e;try{window.localStorage.setItem(`cartethyia.customProvidersHidden`,t?`1`:`0`)}catch{}return t})}return(0,B.jsxs)(`section`,{className:`flex flex-col gap-5`,children:[(0,B.jsxs)(`div`,{className:`flex items-center justify-between flex-wrap gap-4`,children:[(0,B.jsxs)(`button`,{type:`button`,onClick:d,"aria-expanded":!l,title:l?`Show custom providers`:`Hide custom providers`,className:`inline-flex items-center gap-3 bg-transparent border-none p-0 cursor-pointer text-inherit`,children:[(0,B.jsxs)(`h2`,{className:`text-body-lg font-bold tracking-[-0.01em]`,children:[`Custom Providers`,e.length>0?` (${e.length})`:``]}),(0,B.jsx)(r,{size:14,className:`text-text-tertiary transition-transform`,style:{transform:l?`rotate(-90deg)`:void 0}})]}),(0,B.jsxs)(I,{gap:`8px`,children:[(0,B.jsx)(o,{size:`sm`,variant:`ghost`,icon:l?(0,B.jsx)(c,{size:13}):(0,B.jsx)(s,{size:13}),onClick:d,title:l?`Show custom providers`:`Hide custom providers`,children:l?`Show`:`Hide`}),(0,B.jsx)(o,{size:`sm`,variant:`secondary`,icon:(0,B.jsx)(p,{size:13}),onClick:()=>n(!0),children:`Custom Anthropic`}),(0,B.jsx)(o,{size:`sm`,variant:`secondary`,icon:(0,B.jsx)(p,{size:13}),onClick:()=>a(!0),children:`Custom OpenAI`})]})]}),l?null:e.length===0?(0,B.jsx)(A,{children:(0,B.jsxs)(O,{className:`text-center px-7 py-10 border border-dashed border-inner-border rounded-card`,children:[(0,B.jsx)(`p`,{className:`text-body font-semibold text-text-primary`,children:`No custom providers yet`}),(0,B.jsx)(`p`,{className:`text-badge text-text-tertiary mt-1`,children:`Add an OpenAI- or Anthropic-compatible endpoint with the buttons above.`})]})}):(0,B.jsx)(V,{children:e.map(e=>(0,B.jsx)(J,{customProvider:e},e.providerId))}),(0,B.jsx)(q,{variant:`anthropic-compatible`,open:t,onClose:()=>n(!1)}),(0,B.jsx)(q,{variant:`openai-compatible`,open:i,onClose:()=>a(!1)})]})}var X=new Set([`inferhub`]),Z=new Set([`grok`,`opencode`,`cline`,`hermes`,`commandcode`,`kilo`]),re=new Set([`anthropic`,`openai`,`gemini`,`alibabacp`,`ollamacloud`,`opencode-zen`,`opencode-go`,`mistral`,`meta`,`deepseek`]);function Q(e){return e.oauthFlows?.browser===!0||e.oauthFlows?.device===!0}function ie(e){return{active:e.filter(e=>e.status===`active`).length,cooldown:e.filter(e=>e.status===`cooldown`).length,disabled:e.filter(e=>e.status===`disabled`).length,cooling:R(e)}}function ae({counts:e,total:t}){return e.active>0||e.cooldown>0||e.cooling>0||e.disabled>0?(0,B.jsxs)(B.Fragment,{children:[e.active>0?(0,B.jsxs)(j,{tone:`ok`,dot:!0,children:[e.active,` Healthy`]}):null,e.cooldown>0?(0,B.jsxs)(j,{tone:`warn`,dot:!0,children:[e.cooldown,` Cooldown`]}):null,e.cooling>0?(0,B.jsxs)(j,{tone:`warn`,dot:!0,children:[e.cooling,` Cooling`]}):null,e.disabled>0?(0,B.jsxs)(j,{tone:`warn`,dot:!0,children:[e.disabled,` Unhealthy`]}):null]}):(0,B.jsxs)(j,{tone:`warn`,dot:!0,children:[t,` Connected`]})}function $({kind:e,isPending:t,isError:n,hasData:r,isEmpty:i=!1}){let a=e===`models`?`Models`:`Connections`;return n?(0,B.jsxs)(j,{tone:`warn`,children:[a,` unavailable`]}):t&&!r?(0,B.jsxs)(j,{tone:`info`,children:[`Loading `,a.toLowerCase(),`…`]}):i?(0,B.jsx)(j,{children:e===`models`?`No models`:`No connections`}):null}function oe({clientVersion:e}){return e?(0,B.jsxs)(j,{className:`provider-version-badge absolute -top-4.5 left-5 right-auto z-chip max-w-[calc(100%-var(--spacing)*10)] truncate px-3 py-1 text-micro leading-[1.15] shadow-card max-small:left-4 max-small:max-w-[calc(100%-var(--spacing)*8)]`,tone:e.source===`latest`?`teal`:`default`,title:e.source===`latest`?`Latest discovered client version`:`Pinned fallback; background discovery has not succeeded yet`,children:[`v`,e.version,` · `,e.source]}):null}var se=(0,z.memo)(function({provider:e,serviceKind:t}){let n=X.has(e.providerId.toLowerCase()),r=e.label||e.displayName,i=w(e.providerId),o=i.data?.filter(e=>t===void 0||e.serviceKind===t||t===`llm`&&e.serviceKind===void 0).length,s=E(e.providerId),c=s.data,l=ie(c??[]);return(0,B.jsxs)(A,{className:H,children:[(0,B.jsx)(oe,{clientVersion:e.clientVersion}),n?(0,B.jsx)(`span`,{"aria-label":`Friend sponsor`,title:`Friend sponsor`,className:`absolute top-0 right-0 z-2 w-36 h-36 overflow-hidden pointer-events-none`,children:(0,B.jsx)(`span`,{className:a(`absolute top-9 -right-11 w-38 py-1 rotate-45 bg-accent-soft`,`text-accent text-micro font-extrabold tracking-tight leading-[1.05]`,`text-center uppercase shadow-ribbon`),children:`Friend`})}):null,(0,B.jsx)(v,{to:`/providers/${encodeURIComponent(e.providerId)}${t===void 0?``:`?service=${t}`}`,className:U,children:(0,B.jsxs)(I,{gap:`10px`,children:[(0,B.jsx)(N,{icon:e.providerId,name:r,size:32,imageSize:24}),(0,B.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,B.jsx)(`div`,{className:W,children:r}),(0,B.jsxs)(`div`,{className:`mt-1.5 flex flex-wrap gap-2`,children:[c===void 0?(0,B.jsx)($,{kind:`accounts`,isPending:s.isPending,isError:s.isError,hasData:!1}):c.length===0?e.requiresAccount===!1?(0,B.jsx)(j,{tone:`ok`,children:`Free Endpoint`}):(0,B.jsx)(j,{children:`No connections`}):(0,B.jsx)(ae,{counts:l,total:c.length}),s.isError&&c!==void 0?(0,B.jsx)(j,{tone:`warn`,children:`Connections unavailable`}):null]})]}),(0,B.jsxs)(`div`,{className:`flex flex-col items-end gap-1.5 shrink-0`,children:[(0,B.jsxs)(`span`,{className:`font-mono tabular-nums text-micro font-semibold bg-kbd-bg px-2.5 py-0.5 rounded-chip text-text-secondary`,children:[e.providerId,`/`]}),o!==void 0&&o>0?(0,B.jsxs)(j,{tone:`info`,children:[o,` models`]}):null,i.isError?(0,B.jsx)(j,{tone:`warn`,children:`Models unavailable`}):o===void 0?(0,B.jsx)($,{kind:`models`,isPending:i.isPending,isError:!1,hasData:!1}):o===0?(0,B.jsx)($,{kind:`models`,isPending:!1,isError:!1,hasData:!0,isEmpty:!0}):null]})]})})]})});function ce(e,t){let n=Number(!!t.configured)-Number(!!e.configured);return n===0?(e.label||e.displayName).localeCompare(t.label||t.displayName):n}var le=`cartethyia.providerSectionsCollapsed`;function ue(){try{let e=window.localStorage.getItem(le),t=e?JSON.parse(e):[];return new Set(Array.isArray(t)?t.filter(e=>typeof e==`string`):[])}catch{return new Set}}var de=[{title:`Founding Friend & Sponsors`,subtitle:`Super Cheap inference pool`,filter:e=>X.has(e.providerId.toLowerCase())},{title:`Free Limited Providers`,filter:e=>Z.has(e.providerId.toLowerCase())},{title:`OAuth & Agent Providers`,filter:e=>Q(e)&&!Z.has(e.providerId.toLowerCase())},{title:`Well Known API Key Providers`,subtitle:`The household names — sign up with a key and go`,filter:e=>e.isBuiltIn&&re.has(e.providerId.toLowerCase())&&!X.has(e.providerId.toLowerCase())&&!Z.has(e.providerId.toLowerCase())&&!Q(e)},{title:`Other API Key Providers`,subtitle:`Free tier friendly — no credit card`,filter:e=>e.isBuiltIn&&!re.has(e.providerId.toLowerCase())&&!X.has(e.providerId.toLowerCase())&&!Z.has(e.providerId.toLowerCase())&&!Q(e)}];function fe(){let[e,t]=(0,z.useState)(ue),n=C(),i=(0,z.useMemo)(()=>n.data??[],[n.data]),o=(0,z.useMemo)(()=>[...i.filter(e=>!e.isBuiltIn)].sort(ce),[i]),s=(0,z.useMemo)(()=>i.filter(e=>G(e).includes(`websearch`)),[i]),c=(0,z.useMemo)(()=>i.filter(e=>G(e).includes(`llm`)),[i]),[f,p]=b(),m=f.get(`tab`),g=m===`search`||m===`media`?m:`llm`,_=e=>{p(t=>{let n=new URLSearchParams(t);return e===`llm`?n.delete(`tab`):n.set(`tab`,e),n})},v=(0,z.useMemo)(()=>i.filter(e=>G(e).includes(`imageGeneration`)||G(e).includes(`videoGeneration`)),[i]),y=(0,z.useMemo)(()=>[...s].sort((e,t)=>(e.label||e.displayName).localeCompare(t.label||t.displayName)),[s]),x=(e,t)=>{let n=Number(!!t.configured)-Number(!!e.configured);return n===0?(e.label||e.displayName).localeCompare(t.label||t.displayName):n},w=(0,z.useMemo)(()=>{if(g===`media`)return[{title:`Media Generation`,subtitle:`Providers that can return an image or a video`,providers:v}].filter(e=>e.providers.length>0);if(g===`search`)return[{title:`Search Providers`,subtitle:`Providers that can answer a web search request`,providers:y}].filter(e=>e.providers.length>0);let e=c;return de.map(t=>({...t,providers:e.filter(t.filter).sort(x)})).filter(e=>e.providers.length>0)},[c,y,v,g]),T=n.isPending&&!n.data?(0,B.jsx)(u,{label:`Loading providers...`}):n.isError?(0,B.jsx)(l,{message:h(n.error,`Failed to load providers`),onRetry:()=>n.refetch()}):null;return T?(0,B.jsxs)(A,{children:[(0,B.jsx)(k,{title:`Providers`,icon:(0,B.jsx)(S,{size:16})}),(0,B.jsx)(O,{className:`flex flex-1`,children:T})]}):(0,B.jsx)(F,{gap:`24px`,children:(0,B.jsxs)(A,{children:[(0,B.jsx)(k,{title:`Providers`,subtitle:`Connected pinned first · A–Z`,icon:(0,B.jsx)(S,{size:16})}),(0,B.jsxs)(O,{className:`flex flex-col gap-8`,children:[(0,B.jsxs)(`div`,{className:`flex items-center gap-4 flex-wrap`,children:[(0,B.jsx)(`div`,{className:`flex gap-2`,children:[`llm`,`search`,`media`].map(e=>(0,B.jsxs)(`button`,{onClick:()=>_(e),className:a(`px-6 py-3 rounded-inset text-caption font-semibold border cursor-pointer`,g===e?`border-accent bg-accent-soft text-accent`:`border-inner-border bg-surface-1 text-text-secondary`),children:[e===`llm`?`LLM`:e===`search`?`Search`:`Media`,e===`search`?` (${s.length})`:e===`media`?` (${v.length})`:` (${c.length})`]},e))}),(0,B.jsx)(`span`,{className:`ml-auto text-micro text-text-tertiary`,children:g===`search`?`Fallback runs only when the model invokes Websearch`:g===`media`?`Image and video generation`:`Connected pinned first · A–Z`})]}),g===`llm`?(0,B.jsx)(Y,{customProviders:o}):null,w.length===0?(0,B.jsx)(A,{children:(0,B.jsx)(O,{children:(0,B.jsx)(d,{title:`No providers found`,message:`No providers available.`})})}):w.map(n=>{let i=e.has(n.title);return(0,B.jsxs)(`section`,{className:`flex flex-col gap-6`,children:[(0,B.jsxs)(`button`,{type:`button`,className:`flex items-start gap-4 border-0 bg-transparent p-0 text-left text-inherit`,"aria-expanded":!i,onClick:()=>t(e=>{let t=new Set(e);t.has(n.title)?t.delete(n.title):t.add(n.title);try{window.localStorage.setItem(le,JSON.stringify([...t]))}catch{}return t}),children:[(0,B.jsx)(r,{size:15,className:a(`mt-1 shrink-0 transition-transform`,i&&`-rotate-90`)}),(0,B.jsxs)(F,{gap:`1px`,children:[(0,B.jsxs)(`h2`,{className:`text-body font-bold tracking-[-0.01em]`,children:[n.title,` (`,n.providers.length,`)`,i?` (Hidden)`:``]}),!i&&n.subtitle?(0,B.jsx)(`p`,{className:`mt-1 text-badge text-text-tertiary`,children:n.subtitle}):null]})]}),i?null:(0,B.jsx)(V,{children:n.providers.map(e=>(0,B.jsx)(se,{provider:e,serviceKind:g===`search`?`websearch`:g===`media`?G(e).includes(`imageGeneration`)?`imageGeneration`:`videoGeneration`:`llm`},e.providerId))})]},n.title)})]})]})})}export{fe as default};
@@ -1,7 +0,0 @@
1
- import{n as e,o as t,r as n,t as r}from"./jsx-runtime-CXUMngI_.js";import{i}from"./terminal-C9mZ4Ugm.js";import{t as a}from"./select-CGUuTQmj.js";import{g as o,m as s,n as c,t as l}from"./toast-DKAdP2mo.js";import{t as u}from"./download-A0SW9OCW.js";import{t as d}from"./eye-off-Bk5g2luF.js";import{t as f}from"./eye-C_hawfH4.js";import{t as p}from"./gauge-BbIMy7MB.js";import{a as m,n as h,r as g,t as _}from"./state-DHKdg-pm.js";import{t as v}from"./dialog-iocKA3jr.js";import{t as y}from"./pencil-768ysRAr.js";import{t as b}from"./plus-DIdX_g-x.js";import{i as ee,r as x,t as S}from"./privacy-mode-CQjbZ3xk.js";import{t as C}from"./rotate-ccw-CufcqITi.js";import{t as w}from"./shield-check-DVS0Foqh.js";import{t as te}from"./trash-Cppn5c3R.js";import{S as T,_ as E,c as D,v as O,w as k}from"./assert-Bwh6DJTK.js";import{a as A,c as j,i as M,r as N,t as P}from"./query-keys-ROf-g1Wi.js";import{t as F}from"./useMutation-DVmwOKU-.js";import{F as ne,et as I}from"./entry-DTiWhIY-.js";import{n as re,r as ie,t as ae}from"./card-BTdbRFFg.js";import{n as oe}from"./download-dRFo5_Wu.js";import{t as L}from"./numbers-CFL4_Dqc.js";import{t as R}from"./badge-BwmwEOgA.js";import{n as z}from"./input-Bn4_kNav.js";import{t as B}from"./switch-DIDeAiz9.js";import{t as se}from"./stack-C1kTcOmP.js";import{n as ce}from"./inline-DCejSLlA.js";import{r as V,t as le}from"./layout-Bv-NxqZ5.js";import{n as H}from"./live-YlifPYox.js";var ue=e(`cloud`,[[`path`,{d:`M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z`,key:`p7xjir`}]]),de=e(`power`,[[`path`,{d:`M12 2v10`,key:`mnfbl`}],[`path`,{d:`M18.4 6.6a9 9 0 1 1-12.77.04`,key:`obofu9`}]]),fe=1e6,pe=1e8,me=5e6,he=`sin1`,ge=[{label:`Asia Pacific`,regions:[{id:`sin1`,label:`Singapore`},{id:`hkg1`,label:`Hong Kong`},{id:`icn1`,label:`Seoul`},{id:`hnd1`,label:`Tokyo`},{id:`kix1`,label:`Osaka`},{id:`bom1`,label:`Mumbai`},{id:`syd1`,label:`Sydney`}]},{label:`Europe`,regions:[{id:`fra1`,label:`Frankfurt`},{id:`cdg1`,label:`Paris`},{id:`lhr1`,label:`London`},{id:`arn1`,label:`Stockholm`},{id:`dub1`,label:`Dublin`}]},{label:`North America`,regions:[{id:`iad1`,label:`Washington, D.C.`},{id:`sfo1`,label:`San Francisco`},{id:`pdx1`,label:`Portland`},{id:`cle1`,label:`Cleveland`},{id:`yul1`,label:`Montréal`}]},{label:`Other`,regions:[{id:`gru1`,label:`São Paulo`},{id:`cpt1`,label:`Cape Town`},{id:`dxb1`,label:`Dubai`}]}];function _e(){return T({queryKey:P.network.pools,queryFn:e=>A(`/network/pools`,{signal:E(e)}).then(D),staleTime:N.staleTime,gcTime:N.gcTime})}function ve(){let e=k();return F({mutationFn:e=>A(`/network/pools`,{method:`POST`,body:JSON.stringify(e)}),onSuccess:async()=>{await e.invalidateQueries({queryKey:P.network.pools}),l.success(`Proxy pool created`)},onError:e=>{l.error(`Could not create the proxy pool.`,j(e))}})}function ye(){let e=k();return F({mutationFn:e=>A(`/network/pools/relay/deploy`,{method:`POST`,body:JSON.stringify(e)}),onSuccess:async()=>{await e.invalidateQueries({queryKey:P.network.pools})}})}function be(){return F({mutationFn:e=>A(`/network/pools/test-batch`,{method:`POST`,body:JSON.stringify({targets:e})})})}function xe(){let e=k();return F({mutationFn:({poolId:e,request:t})=>A(`/network/pools/${encodeURIComponent(e)}`,{method:`PATCH`,body:JSON.stringify(t)}),onSuccess:async()=>{await e.invalidateQueries({queryKey:P.network.pools}),l.success(`Proxy updated`)},onError:e=>{l.error(`Could not update the proxy pool.`,j(e))}})}function Se(e){return T({queryKey:[...P.network.pools,e,`health-events`],queryFn:t=>A(`/network/pools/${encodeURIComponent(e??``)}/health-events`,{signal:E(t)}),enabled:!!e,...N,refetchInterval:M.status})}function Ce(){let e=k();return F({mutationFn:e=>A(`/network/pools/${encodeURIComponent(e)}/recover`,{method:`POST`,body:`{}`}),onSuccess:async(t,n)=>{await Promise.all([e.invalidateQueries({queryKey:P.network.pools}),e.invalidateQueries({queryKey:[...P.network.pools,n,`health-events`]})]),l.success(`Proxy pool recovered`)},onError:e=>{l.error(`Could not recover the proxy pool.`,j(e))}})}function we(){let e=k();return F({mutationFn:e=>A(`/network/pools/${encodeURIComponent(e)}`,{method:`DELETE`}),onSuccess:async()=>{await e.invalidateQueries({queryKey:P.network.pools}),l.success(`Proxy pool deleted`)},onError:e=>{l.error(`Could not delete the proxy pool.`,j(e))}})}function Te(){let e=k();return F({mutationFn:({poolId:e,providerId:t})=>A(`/network/pools/${encodeURIComponent(e)}/provider-probe`,{method:`POST`,body:JSON.stringify({providerId:t})}),onSuccess:async()=>{await e.invalidateQueries({queryKey:P.network.pools})}})}function Ee(){return F({mutationFn:({providerId:e,targets:t})=>A(`/network/pools/test-batch/provider`,{method:`POST`,body:JSON.stringify({providerId:e,targets:t})})})}function De(){let e=k();return F({mutationFn:e=>A(`/network/pools/${encodeURIComponent(e)}/health-check`,{method:`POST`,body:`{}`}),onSuccess:async()=>{await e.invalidateQueries({queryKey:P.network.pools}),l.success(`Health check complete`)},onError:e=>{l.error(`Health check failed.`,j(e))}})}function Oe(){let e=k();return F({mutationFn:({poolId:e,bytes:t})=>A(`/network/pools/${encodeURIComponent(e)}/speed-test`,{method:`POST`,body:JSON.stringify({bytes:t})}),onSuccess:async()=>{await e.invalidateQueries({queryKey:P.network.pools})}})}function ke(){let e=k();return F({mutationFn:({poolId:e,providerId:t})=>A(`/network/pools/${encodeURIComponent(e)}/cooldowns/clear`,{method:`POST`,body:JSON.stringify(t?{providerId:t}:{})}),onSuccess:async()=>{await e.invalidateQueries({queryKey:P.network.pools}),l.success(`Provider cooldowns cleared`)},onError:e=>{l.error(`Could not clear provider cooldowns.`,j(e))}})}var U=t(n(),1),W=r(),G={cloudflare:{label:`Cloudflare Workers`,tokenLabel:`Cloudflare API token`,needsAccount:!0,host:`*.workers.dev`,hasRegion:!1},vercel:{label:`Vercel`,tokenLabel:`Vercel API token`,needsAccount:!1,host:`*.vercel.app`,hasRegion:!0},deno:{label:`Deno Deploy`,tokenLabel:`Deno Deploy token`,needsAccount:!1,host:`*.deno.dev`,hasRegion:!1}},Ae=ge.flatMap(e=>e.regions.map(t=>({value:t.id,label:`${e.label} — ${t.label}`})));function je({onClose:e}){let t=ye(),[n,r]=(0,U.useState)(`cloudflare`),[i,o]=(0,U.useState)(he),[s,u]=(0,U.useState)(``),[d,f]=(0,U.useState)(``),[p,h]=(0,U.useState)(``),[g,_]=(0,U.useState)(null),y=G[n],b=s.trim().length>0&&(!y.needsAccount||d.trim().length>0);return(0,W.jsx)(v,{open:!0,onClose:e,title:`Deploy Relay`,description:`Run outbound traffic through a hosted relay (Cloudflare, Vercel, Deno).`,size:`md`,children:(0,W.jsxs)(se,{gap:`12px`,children:[(0,W.jsxs)(`p`,{className:`text-badge text-text-tertiary m-0 flex gap-3`,children:[(0,W.jsx)(I,{size:13,className:`shrink-0 mt-0.5`}),(0,W.jsxs)(`span`,{children:[`Deploys a small relay worker to your own `,y.label,` account and registers its URL (`,(0,W.jsx)(`code`,{children:y.host}),`) as an active HTTP pool. Your API token is used only for the deploy and is never stored.`]})]}),(0,W.jsx)(a,{label:`Relay host`,id:`relay-target`,value:n,onValueChange:e=>r(e),options:O.map(e=>({value:e,label:G[e].label}))}),(0,W.jsx)(z,{label:y.tokenLabel,id:`relay-token`,type:`password`,value:s,placeholder:`Paste a deploy token`,onChange:e=>u(e.target.value)}),y.needsAccount?(0,W.jsx)(z,{label:`Account ID`,id:`relay-account`,value:d,placeholder:`Cloudflare account id`,onChange:e=>f(e.target.value)}):null,(0,W.jsx)(z,{label:`Project name (optional)`,id:`relay-project`,value:p,placeholder:`e.g. cartethyia-relay`,onChange:e=>h(e.target.value)}),y.hasRegion?(0,W.jsx)(a,{label:`Deploy region`,id:`relay-region`,value:i,onValueChange:e=>o(e),options:Ae}):null,y.hasRegion?(0,W.jsx)(`p`,{className:`text-badge text-text-tertiary m-0`,children:`Sets the region on the Vercel project, which is what decides the country outbound traffic leaves from. A region sent on the deployment alone is accepted but does not move the Function.`}):null,(0,W.jsxs)(`div`,{className:`flex items-center gap-5`,children:[(0,W.jsx)(c,{variant:`primary`,size:`sm`,onClick:()=>{b&&t.mutate({target:n,token:s.trim(),...y.needsAccount&&d.trim()?{accountId:d.trim()}:{},...p.trim()?{projectName:p.trim()}:{},...y.hasRegion?{region:i}:{}},{onSuccess:e=>{_(e.relayUrl),u(``),l.success(`Relay deployed to ${e.relayUrl} and registered as a pool.`)},onError:e=>l.error(j(e,`Relay deploy failed.`))})},disabled:!b||t.isPending,children:t.isPending?`Deploying…`:`Deploy relay`}),g?(0,W.jsxs)(`span`,{className:`mt-1 text-badge text-text-tertiary`,children:[`Registered pool at `,(0,W.jsx)(`code`,{children:g})]}):null]}),t.isError?(0,W.jsxs)(`p`,{className:`text-badge text-red m-0 flex gap-3`,children:[(0,W.jsx)(m,{size:13,className:`shrink-0 mt-0.5`}),(0,W.jsx)(`span`,{children:j(t.error,`Relay deploy failed.`)})]}):null]})})}function Me(e,t){if(e!==void 0)return e.endpoint===``||e.endpoint===(t??``)?e.result:void 0}function Ne(e,t,n){switch(t){case`name`:return(e.label||e.endpoint).toLowerCase();case`family`:return e.family===void 0||e.family===null||e.family===``?null:e.family.toLowerCase();case`address`:return e.egressIp??null;case`load`:return n??null}}function Pe(e,t,n,r){let i=n===`asc`?1:-1;return[...e].sort((e,n)=>{let a=Ne(e,t,r(e)),o=Ne(n,t,r(n));return a===null&&o===null?0:a===null?1:o===null?-1:typeof a==`number`&&typeof o==`number`?(a-o)*i:String(a).localeCompare(String(o))*i})}function K(e,t){let n=e.filter(e=>e.status===`active`),r=n.reduce((e,t)=>e+t.maxInflight,0),i=t===void 0?n.reduce((e,t)=>e+(t.inflight??0),0):n.reduce((e,n)=>e+(t.get(n.id)??0),0),a=0,o=0;for(let e of n)(t===void 0?e.inflight??0:t.get(e.id)??0)>=e.maxInflight?o+=1:a+=1;let s=null,c=Date.now(),l=e=>{if(!e)return;let t=Date.parse(e);if(Number.isNaN(t))return;let n=t-c;n<=0||(s===null||n<s)&&(s=n)};for(let t of e){l(t.cooldownUntil);for(let e of t.providerCooldowns??[])l(e.until)}let u=n.filter(e=>e.lastLatencyMs!==void 0&&Number.isFinite(e.lastLatencyMs)),d=u.length===0?null:Math.round(u.reduce((e,t)=>e+(t.lastLatencyMs??0),0)/u.length);return{totalPools:e.length,active:n.length,cooldown:e.filter(e=>e.status===`cooldown`).length,totalMaxConcurrency:r,usedInflight:i,availableCapacity:Math.max(0,r-i),routablePools:a,saturatedPools:o,soonestCooldownMs:s,avgLatencyMs:d,measuredPools:u.length}}var q=[`http`,`https`,`socks5`];function J(e){return/^[a-z][a-z0-9+.-]*:\/\//i.test(e.trim())}function Fe(e,t){let n=e.trim();return t===null||J(n)?n:`${t}://${n}`}function Y(e){return e.find(e=>e.trim()!==``)}function X(e){let t=e.trim().toLowerCase();return t.startsWith(`https://`)?`https`:t.startsWith(`socks5://`)||t.startsWith(`socks://`)?`socks5`:`http`}var Ie=1024**3;function Le(e){let t=e.trim();if(t===``)return null;let n=Number(t);return!Number.isFinite(n)||n<=0?null:Math.max(1,Math.round(n*Ie))}function Z(e,t,n){let r=new Map;if(t.trim().toLowerCase()===``||n<=0)return r;let i=Math.floor(e/n),a=e-i*n;for(let e=0;e<n;e+=1){let t=e===n-1?a:0;r.set(e,i+t)}return r}var Re=4,ze=`cartethyia_proxy_test_payload`,Be=`cartethyia_proxy_check_results`,Ve=[{value:`url`,label:`Test URL`},{value:`opencode`,label:`Test OpenCode`}],He=`opencode`,Ue=4,We=`Mysterious Proxy`;function Q(e){return e.avgLatencyMs===null?`no measurement yet`:`avg across ${e.measuredPools} enabled ${e.measuredPools===1?`pool`:`pools`}`}function Ge(e){let t=e.endpoint||``,n=t.includes(`://`)?t:`${e.kind}://${t}`,r={"https:":`443`,"http:":`80`,"socks5:":`1080`,"socks:":`1080`};try{let e=new URL(n),t=e.port||r[e.protocol]||``,i=`${e.hostname}${t?`:${t}`:``}`;return{name:i,endpoint:`${e.protocol}//${i}${e.pathname===`/`?``:e.pathname}${e.search}`}}catch{return{name:e.label||t,endpoint:t}}}function Ke(e){return e.label||Ge(e).name||e.id}var $=1024**3;function qe(e){if(e.lastSpeedtestStatus===void 0||e.lastSpeedtestAt===void 0)return;let t=e.lastSpeedtestDurationMs??0,n=e.lastSpeedtestBytes??0,r=t>0?n/(t/1e3):void 0;return{poolId:e.id,status:e.lastSpeedtestStatus,bytes:n,durationMs:t,...r===void 0?{}:{bytesPerSecond:r,megabitsPerSecond:r*8/1e6},...e.lastSpeedtestError?{errorMessage:e.lastSpeedtestError}:{},measuredAt:e.lastSpeedtestAt}}function Je(e,t){if(!e)return t;if(!t)return e;let n=e.measuredAt?new Date(e.measuredAt).getTime():0;return(t.measuredAt?new Date(t.measuredAt).getTime():0)>=n?t:e}var Ye=[{value:String(fe),label:`1 MB`},{value:String(me),label:`5 MB`},{value:`50000000`,label:`50 MB`},{value:String(pe),label:`100 MB`}];function Xe({pool:e,onClose:t,actionsRef:n}){let r=xe(),i=Ee(),a=De(),[u,d]=(0,U.useState)(e.label??``),[f,p]=(0,U.useState)(e.family??``),[m,h]=(0,U.useState)(e.endpoint??``),[g,_]=(0,U.useState)(String(e.maxInflight??10)),[v,y]=(0,U.useState)(String(e.weight??100)),[b,ee]=(0,U.useState)(e.quotaBytes?String(Math.round(e.quotaBytes/$*1e3)/1e3):``),[x,S]=(0,U.useState)(null),[C,w]=(0,U.useState)(!1),te=m.trim()===e.endpoint,T=async()=>{w(!0),S(null);try{if(te){let t=await a.mutateAsync(e.id),n=t.status===`healthy`||t.status===`reachable`;S({ok:n,message:t.status===`healthy`?`Connected in ${t.latencyMs??0}ms`:t.errorMessage??`Connection failed`});return}let t=[{kind:e.kind,endpoint:m.trim(),...e.family===null||e.family===void 0?{}:{family:e.family}}],[n]=await i.mutateAsync({providerId:He,targets:t}),r=n?.result;if(!r){S({ok:!1,message:`Probe returned no result`});return}let o=r.status===`allowed`||r.status===`throttled`;S({ok:o,message:r.reason??(r.status===`allowed`?`Reachable${r.latencyMs===void 0?``:` in ${r.latencyMs}ms`}`:r.status===`throttled`?`Reachable; rate limit spent`:`Probe could not complete`)})}catch(e){S({ok:!1,message:j(e,`Connection failed`)})}finally{w(!1)}},E=Le(b),D=async()=>{await r.mutateAsync({poolId:e.id,request:{...u.trim()===e.label?{}:{label:u.trim()||void 0},...f.trim()===(e.family??``)?{}:{family:f.trim()||null},...m.trim()!==e.endpoint&&m.trim()!==``?{endpoint:m.trim()}:{},...Number(g)===e.maxInflight?{}:{maxInflight:Number(g)},...Number(v)===e.weight?{}:{weight:Number(v)},...E===(e.quotaBytes??null)?{}:{quotaBytes:E}}}),l.success(`Proxy updated`),t()};return(0,U.useEffect)(()=>{n?.((0,W.jsxs)(W.Fragment,{children:[(0,W.jsx)(c,{variant:`secondary`,size:`sm`,onClick:t,children:`Cancel`}),(0,W.jsx)(c,{variant:`primary`,size:`sm`,disabled:r.isPending||!m.trim(),onClick:()=>void D(),children:`Save`})]}))}),(0,W.jsxs)(se,{gap:`12px`,children:[(0,W.jsx)(`div`,{children:(0,W.jsx)(z,{label:`Name`,value:u,onChange:e=>d(e.target.value)})}),(0,W.jsx)(`div`,{children:(0,W.jsx)(z,{label:`Family`,value:f,placeholder:`e.g. residential-id`,onChange:e=>p(e.target.value)})}),(0,W.jsx)(`div`,{children:(0,W.jsx)(z,{label:`Endpoint`,value:m,onChange:e=>h(e.target.value),className:`font-mono tabular-nums`})}),(0,W.jsxs)(`div`,{className:`grid grid-cols-2 gap-5`,children:[(0,W.jsx)(`div`,{children:(0,W.jsx)(z,{label:`Max concurrent`,type:`number`,min:1,value:g,onChange:e=>_(e.target.value)})}),(0,W.jsx)(`div`,{children:(0,W.jsx)(z,{label:`Weight`,type:`number`,min:1,value:v,onChange:e=>y(e.target.value)})})]}),(0,W.jsxs)(`div`,{children:[(0,W.jsx)(z,{label:`Bandwidth quota (GB, blank = unmetered)`,type:`number`,min:.001,step:`0.1`,value:b,onChange:e=>ee(e.target.value)}),(0,W.jsx)(`div`,{className:`text-micro text-text-tertiary mt-2`,children:E===null?`No quota — the bar shows a running total only.`:`Bar turns orange at 80% and red once ${L(E)} is exceeded.`})]}),x&&(0,W.jsx)(`div`,{className:`rounded-inset px-6 py-4 text-badge font-semibold ${x.ok?`bg-green-soft text-green`:`bg-red-soft text-red`}`,children:x.message}),(0,W.jsx)(`div`,{children:(0,W.jsx)(c,{variant:`secondary`,size:`sm`,disabled:C,icon:C?(0,W.jsx)(s,{size:13,className:`animate-spin`}):(0,W.jsx)(o,{size:13}),onClick:()=>void T(),children:C?`Testing…`:`Test connection`})})]})}function Ze({endpoint:e,chip:t,onChipChange:n}){return(0,W.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3`,role:`group`,"aria-label":`Scheme for the first endpoint`,children:[(0,W.jsx)(`span`,{className:`text-badge text-text-secondary`,children:`Scheme`}),q.map(r=>{let i=t===r;return(0,W.jsxs)(c,{type:`button`,variant:i?`primary`:`secondary`,size:`sm`,disabled:e===void 0,"aria-pressed":i,"data-scheme":r,onClick:()=>n(i?null:r),className:`font-mono`,children:[r,`://`]},r)}),t!==null&&(0,W.jsxs)(`span`,{className:`text-badge text-text-tertiary`,children:[`→ `,Fe(e??``,t)]})]})}function Qe({onClose:e,actionsRef:t,onProbeResult:n,onHealthResult:r}){let i=ve(),a=be(),o=Ee(),[s,u]=(0,U.useState)(``),[d,f]=(0,U.useState)(``),[p,m]=(0,U.useState)(``),[h,g]=(0,U.useState)(null),[_,v]=(0,U.useState)([]),[y,b]=(0,U.useState)({}),[ee,x]=(0,U.useState)({}),[S,C]=(0,U.useState)(!1),[w,te]=(0,U.useState)(null),T=s.split(`
2
- `).map(e=>e.trim()).filter(Boolean),E=Y(T),D=(0,U.useMemo)(()=>w===null||E===void 0?T:T.map((e,t)=>e===E&&t===0?Fe(e,w):e),[T,w,E]),O=T.length>100,k=Le(p),A=(0,U.useMemo)(()=>D.map(e=>({kind:X(e),endpoint:e})),[D]),M=async()=>{try{let e=await navigator.clipboard.readText();e&&u(t=>t?`${t}\n${e}`:e)}catch{l.error(`Paste failed`,`Clipboard access denied`)}},N=async()=>{if(A.length!==0){v([`Testing ${A.length} proxy target(s)…`]);try{let e=await a.mutateAsync(A),t=e.map(e=>{let t=e.result.status===`healthy`||e.result.status===`reachable`,n=e.result.latencyMs===void 0?``:` · ${e.result.latencyMs}ms`,r=e.result.egressIp?` · ${e.result.egressIp}`:``,i=t?``:` · ${e.result.errorMessage??e.result.status}`;return`${t?`OK `:`FAIL`} ${e.endpoint}${n}${r}${i}`}),n=e.filter(e=>e.result.status===`healthy`||e.result.status===`reachable`).length;x(t=>{let n={...t};for(let t of e)n[t.endpoint]=t.result;return n}),v([`${n}/${e.length} reachable`,...t]),n===e.length?l.success(`All ${e.length} proxies reachable`):l.error(`${e.length-n} of ${e.length} proxies failed`)}catch(e){v([`Test failed: ${j(e,`batch probe failed`)}`]),l.error(`Test failed`,j(e,`batch probe failed`))}}},P=async()=>{if(A.length!==0){v([`Testing ${A.length} proxy target(s) against OpenCode…`]);try{let e=await o.mutateAsync({providerId:He,targets:A}),t=e.map(e=>{let{status:t,latencyMs:n,reason:r}=e.result,i=n===void 0?``:` · ${n}ms`,a=r===void 0?``:` · ${r}`;return`${t===`allowed`?`OK `:t===`blocked`?`BLOCK`:`FAIL`} ${e.endpoint}${i}${a}`});b(t=>{let n={...t};for(let t of e)n[t.endpoint]=t.result;return n});let n=e.filter(e=>e.result.status===`allowed`).length,r=e.filter(e=>e.result.status===`blocked`).length;v([`${n}/${e.length} allowed · ${r} blocked`,...t]),r===0&&n===e.length?l.success(`OpenCode accepted all ${e.length} proxies`):l.error(`OpenCode: ${n} allowed · ${r} blocked`)}catch(e){v([`Test failed: ${j(e,`provider probe failed`)}`]),l.error(`Test failed`,j(e,`provider probe failed`))}}};return(0,U.useEffect)(()=>{t?.((0,W.jsxs)(W.Fragment,{children:[(0,W.jsx)(c,{variant:`secondary`,type:`button`,onClick:e,children:`Cancel`}),(0,W.jsx)(c,{variant:`primary`,type:`submit`,form:`add-proxy-form`,disabled:S||T.length===0,children:S?`Adding…`:`Add ${T.length} Prox${T.length===1?`y`:`ies`}`})]}))},[t,S,T.length,e]),(0,W.jsxs)(`form`,{id:`add-proxy-form`,onSubmit:async t=>{if(t.preventDefault(),T.length!==0){g(null),C(!0);try{let t=k===null?new Map:Z(k,d,D.length),a=Array(T.length),o=0,s=async()=>{for(;o<T.length;){let e=o++,s=D[e];try{let o=await i.mutateAsync({kind:X(s),endpoint:s,...t.has(e)?{quotaBytes:t.get(e)}:{},...d.trim()===``?{}:{family:d.trim()}}),c=y[s],l=ee[s];o?.id&&(l!==void 0&&r?.(o.id,l),c!==void 0&&n?.(o.id,c)),a[e]={ok:!0}}catch(t){a[e]={ok:!1,error:j(t,`Proxy pool creation failed`)}}}};await Promise.all(Array.from({length:Math.min(Re,T.length)},()=>s()));let c=[],f=0;for(let[e,t]of a.entries())t.ok?f++:c.length<3&&c.push(`${T[e].slice(0,48)}…: ${t.error}`);let p=T.length-f,m=a.find(e=>!e.ok)?.error;f>0&&l.success(`Added ${f} proxy pool(s)`,p?`${p} failed: ${m??`see the import details`}`:void 0),p>0&&f===0&&l.error(`Failed to create pool`,m??`See the import details`),p>0&&g(c.join(`
3
- `)),f>0&&(u(``),e())}finally{C(!1)}}},className:`flex flex-col gap-4`,children:[(0,W.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,W.jsx)(`label`,{htmlFor:`proxy-endpoints`,className:`text-caption font-semibold text-text-primary`,children:`Proxy endpoints`}),(0,W.jsx)(c,{variant:`secondary`,size:`sm`,type:`button`,onClick:M,children:`Paste`})]}),(0,W.jsx)(`textarea`,{id:`proxy-endpoints`,value:s,onChange:e=>u(e.target.value),placeholder:`http://proxy.example:8080
4
- https://proxy.example:8443
5
- socks5://proxy.example:1080`,rows:5,"aria-describedby":`proxy-format-hint proxy-line-count`,"aria-invalid":!!h,className:`w-full min-h-32 max-h-64 resize-y overflow-y-auto rounded-control border border-inner-border bg-surface-1 p-3 font-mono text-caption text-text-primary outline-none transition-[border-color,box-shadow] duration-(--dur-micro) ease-spring focus:border-accent focus:shadow-focus`}),(0,W.jsx)(Ze,{endpoint:E,chip:w,onChipChange:te}),(0,W.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-x-4 gap-y-2`,children:[(0,W.jsx)(`p`,{id:`proxy-format-hint`,className:`m-0 text-badge leading-normal text-text-secondary`,children:`HTTP, HTTPS, or SOCKS5 | one per line | authentication optional`}),(0,W.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3`,children:[(0,W.jsxs)(`span`,{id:`proxy-line-count`,role:`status`,"aria-live":`polite`,className:`text-badge ${O?`text-red`:`text-text-tertiary`}`,children:[T.length===1?`1 proxy detected`:`${T.length} proxies detected`,O?` · max 100 per test`:``]}),(0,W.jsx)(c,{variant:`secondary`,size:`sm`,type:`button`,onClick:()=>void N(),disabled:a.isPending||o.isPending||T.length===0||O,children:a.isPending?`Testing…`:`Test URL`}),(0,W.jsx)(c,{variant:`secondary`,size:`sm`,type:`button`,onClick:()=>void P(),disabled:a.isPending||o.isPending||T.length===0||O,children:o.isPending?`Testing…`:`Test OpenCode`})]})]}),h&&(0,W.jsx)(`div`,{role:`alert`,className:`max-h-28 overflow-y-auto rounded-inset bg-red-soft px-4 py-3 text-badge text-red whitespace-pre-wrap break-words`,children:h}),_.length>0&&(0,W.jsx)(`div`,{role:`log`,"aria-label":`Proxy test results`,"aria-live":`polite`,className:`scroll-region max-h-40 overflow-y-auto whitespace-pre-wrap break-all rounded-inset border border-inner-border bg-surface-1 px-3 py-2 font-mono text-badge leading-[1.5] text-text-secondary`,children:_.join(`
6
- `)}),(0,W.jsxs)(`div`,{className:`grid grid-cols-1 gap-4 sm:grid-cols-2`,children:[(0,W.jsx)(z,{id:`proxy-family`,label:`Family`,hint:`Optional`,value:d,placeholder:`e.g. residential-id`,onChange:e=>f(e.target.value),className:`w-full`}),(0,W.jsx)(z,{id:`proxy-quota`,label:`Bandwidth quota (GB)`,hint:`Optional`,type:`number`,min:.001,step:`0.1`,value:p,onChange:e=>m(e.target.value),className:`w-full`})]})]})}function $e(e,t){if(t?.status===`healthy`||t?.status===`reachable`)return t.latencyMs;if(e.lastSuccessAt)return e.lastLatencyMs??void 0}function et(e){if(e===`proxy_payment_required`)return`HTTP 402 Payment Required`;if(e===`proxy_auth_required`)return`HTTP 407 Proxy Authentication Required`}var tt=(0,U.createContext)({byId:new Map,live:!1});function nt({children:e}){let t=H(),n=(0,U.useMemo)(()=>new Map((t.pools??[]).map(e=>[e.poolId,e])),[t.pools]),r=(0,U.useMemo)(()=>({byId:n,live:t.live&&t.pools!==null}),[n,t.live,t.pools]);return(0,W.jsx)(tt.Provider,{value:r,children:e})}function rt({pools:e}){let{byId:t,live:n}=(0,U.useContext)(tt),r=(0,U.useMemo)(()=>K(e,n?new Map([...t].map(([e,t])=>[e,t.currentInflight])):void 0),[e,t,n]),a=(0,U.useMemo)(()=>{let r=0,i=0;for(let a of e){let e=n?t.get(a.id):void 0,o=(a.bytesSentTotal??0)+(a.bytesReceivedTotal??0),s=(e?.bytesSent??0)+(e?.bytesReceived??0);r+=Math.max(o,s),a.quotaBytes&&(i+=a.quotaBytes)}return{used:r,allowance:i}},[e,t,n]);return(0,W.jsxs)(`div`,{className:`signal-grid grid gap-7 w-full min-w-0 mb-7`,children:[(0,W.jsx)(V,{label:`Enabled pool`,value:String(r.active),detail:`/ ${r.totalPools} total`,tone:`accent`,icon:(0,W.jsx)(w,{size:13})}),(0,W.jsx)(V,{label:`Route capacity`,value:String(r.totalMaxConcurrency),detail:`${r.usedInflight} inflight · ${r.availableCapacity} available`,tone:r.availableCapacity===0?`orange`:`teal`,icon:(0,W.jsx)(p,{size:13})}),(0,W.jsx)(V,{label:`Latency`,value:r.avgLatencyMs===null?`—`:`${r.avgLatencyMs}ms`,detail:Q(r),tone:r.avgLatencyMs===null?`accent`:r.avgLatencyMs>2e3?`orange`:`teal`,icon:(0,W.jsx)(i,{size:13})}),(0,W.jsx)(V,{label:`Quota usage`,value:L(a.used),detail:a.allowance>0?`of ${L(a.allowance)} allowance · ${e.length} pools`:`${e.length} pools · no allowance set`,tone:a.allowance>0&&a.used>a.allowance?`red`:a.allowance>0&&a.used/a.allowance>=.8?`orange`:`teal`,icon:(0,W.jsx)(ue,{size:13})})]})}function it(e,t,n,r,i){let a=Ge(e),o=Ke(e),s=e.status!==`disabled`,c=et(e.lastErrorCategory),l=e.status===`disabled`&&c!==void 0,u=e.lastSuccessAt?new Date(e.lastSuccessAt).getTime():0,d=e.lastErrorAt?new Date(e.lastErrorAt).getTime():0,f=!t&&(u>0||d>0)?u>=d:null,p=n?`default`:l?`warn`:t?t.status===`healthy`?`ok`:t.status===`reachable`?`warn`:`err`:f===!0?`ok`:f===!1?`err`:`default`,m=l?e.lastError??c:t?.errorMessage??(f===null?void 0:`last check ${(e.lastHealthCheckAt?new Date(e.lastHealthCheckAt):new Date).toLocaleString()}`),h=$e(e,t),g=r?.currentInflight??e.inflight,_=e.maxInflight>0?Math.min(1,g/e.maxInflight):1,v=e.providerCooldowns??[],y=v.filter(e=>e.blocked===!0),b=v.filter(e=>e.blocked!==!0),ee=v.slice(0,2).map(e=>e.blocked===!0?`${e.providerId} blocked: ${e.reason}`:`${e.providerId} until ${new Date(e.until).toLocaleTimeString()}: ${e.reason}`).join(` · `),x=n?`Testing…`:l?`Proxy reachable`:t?t.status===`healthy`?`Connected`:t.status===`reachable`?`Proxy reachable`:t.status===`timeout`?`Timeout`:`Unhealthy`:f===!0?`Connected`:f===!1?e.lastErrorCategory===`timeout`?`Timeout`:`Unhealthy`:`Untested`,S=(e.bytesSentTotal??0)+(e.bytesReceivedTotal??0),C=(r?.bytesSent??0)+(r?.bytesReceived??0);return{display:a,poolLabel:o,isEnabled:s,checkTone:p,checkTooltip:m,statusText:x,latency:h,inflight:g,load:_,cooldowns:v,blocked:y,cooldownOnly:b,cooldownText:ee,...i===void 0?{}:{probe:i},metered:S,session:C,used:Math.max(S,C),proxyFailureLabel:c}}function at({pool:e,view:t,maskValues:n}){return(0,W.jsxs)(W.Fragment,{children:[(0,W.jsx)(`span`,{className:`block text-caption font-semibold overflow-hidden truncate whitespace-nowrap`,title:n?We:t.poolLabel,children:n?We:t.poolLabel}),(0,W.jsxs)(`div`,{className:`flex items-center gap-3 mt-1.5 min-w-0 flex-wrap`,children:[e.status===`disabled`?(0,W.jsxs)(R,{tone:`disabled`,title:e.lastError,children:[`Disabled`,t.proxyFailureLabel?` · ${t.proxyFailureLabel}`:``]}):(0,W.jsx)(R,{tone:t.checkTone,title:t.checkTooltip,children:t.latency===void 0?t.statusText:`${t.statusText} · ${t.latency}ms`}),t.blocked.length>0?(0,W.jsxs)(R,{tone:`disabled`,title:t.cooldownText,children:[t.blocked.length,` blocked`]}):null,t.probe?(0,W.jsx)(R,{tone:t.probe.status===`blocked`?`disabled`:t.probe.status===`allowed`?`ok`:`warn`,title:t.probe.reason??(t.probe.status===`allowed`?t.probe.httpStatus!==void 0&&t.probe.httpStatus>=400?`Reachable — upstream answered ${t.probe.httpStatus} for the probe body`:`OpenCode served a probe through this pool`:t.probe.status===`throttled`?`OpenCode accepted this egress; the rate is spent`:`The probe could not complete`),children:t.probe.status===`blocked`?`OpenCode blocked`:t.probe.status===`allowed`?t.probe.httpStatus!==void 0&&t.probe.httpStatus>=400?`OpenCode reachable`:`OpenCode OK`:t.probe.status===`throttled`?`OpenCode rate-limited`:`OpenCode unreachable`}):null,t.cooldownOnly.length>0?(0,W.jsxs)(R,{tone:`warn`,title:t.cooldownText,children:[t.cooldownOnly.length,` cooldown`,t.cooldownOnly.length>1?`s`:``]}):null]})]})}function ot({pool:e,view:t,speedResult:n,isSpeedTesting:r,maskIp:i}){return(0,W.jsxs)(W.Fragment,{children:[e.egressIp?(0,W.jsx)(`span`,{className:`font-mono tabular-nums block overflow-hidden text-ellipsis whitespace-nowrap text-badge`,title:i?`IP masked`:`egress ${e.egressIp} · ${t.display.endpoint}`,children:i?`IP masked`:e.egressIp}):(0,W.jsx)(`span`,{className:`text-badge text-text-tertiary`,title:`Test the pool to read its egress address`,children:`not probed`}),(r||n)&&(0,W.jsx)(`div`,{className:`mt-1.5`,children:(0,W.jsx)(R,{tone:r?`default`:n?.status===`ok`?`ok`:`err`,title:r?`Measuring download throughput`:n?.status===`ok`?`${L(n.bytes)} in ${n.durationMs}ms${n.measuredAt?` · last measured ${new Date(n.measuredAt).toLocaleString()}`:``}`:`${n?.errorMessage??`Speed test failed`}${n?.measuredAt?` · last measured ${new Date(n.measuredAt).toLocaleString()}`:``}`,children:r?`Speed…`:n?.status===`ok`?`${(n.megabitsPerSecond??0).toFixed(1)} Mbps`:`Speed failed`})})]})}function st({pool:e,view:t}){let n=e.quotaBytes,r=n&&n>0?Math.min(1,t.used/n):0,i=n!==void 0&&n>0&&t.used>n;return(0,W.jsxs)(W.Fragment,{children:[(0,W.jsxs)(`div`,{title:`${t.inflight}/${e.maxInflight} inflight`,className:`flex items-center gap-3`,children:[(0,W.jsx)(`div`,{className:`flex-1 h-3 rounded-micro overflow-hidden`,children:(0,W.jsx)(`div`,{className:`h-full rounded-micro`,style:{width:`${Math.round(t.load*100)}%`,background:t.load>=.8?`var(--orange)`:`var(--green)`}})}),(0,W.jsxs)(`span`,{className:`font-mono tabular-nums text-micro text-text-secondary whitespace-nowrap`,children:[t.inflight,`/`,e.maxInflight]})]}),(0,W.jsxs)(`div`,{title:n?`${L(t.used)} of ${L(n)} used · ${L(t.metered)} metered lifetime`:`${L(t.used)} carried (no quota set) · ${L(t.session)} this session`,className:`flex items-center gap-3 mt-2`,children:[(0,W.jsx)(`div`,{className:`flex-1 h-3 rounded-micro overflow-hidden`,children:(0,W.jsx)(`div`,{className:`h-full rounded-micro`,style:{width:`${Math.round(r*100)}%`,background:i?`var(--red)`:r>=.8?`var(--orange)`:`var(--teal)`}})}),(0,W.jsxs)(`span`,{className:`font-mono tabular-nums whitespace-nowrap text-micro ${i?`text-red`:`text-text-secondary`}`,children:[L(t.used),n?` / ${L(n)}`:``]})]})]})}function ct({pool:e,view:t,isTesting:n,onDelete:r,onEdit:a,onHealthCheck:l,onActivity:u}){let d=xe(),f=ke(),p=Ce();return(0,W.jsxs)(W.Fragment,{children:[t.cooldowns.length>0&&(0,W.jsx)(c,{size:`icon`,variant:`secondary`,disabled:f.isPending,icon:f.isPending?(0,W.jsx)(s,{size:12,className:`animate-spin`}):(0,W.jsx)(C,{size:12}),onClick:()=>f.mutate({poolId:e.id}),title:`Clear provider cooldowns — ${t.cooldownText}`,label:`Clear`}),(0,W.jsx)(c,{size:`icon`,variant:`secondary`,icon:(0,W.jsx)(i,{size:12}),onClick:()=>u(e),title:`Health and error activity`,label:`Activity`}),e.status===`cooldown`&&(0,W.jsx)(c,{size:`icon`,variant:`secondary`,disabled:p.isPending,icon:(0,W.jsx)(C,{size:12,className:p.isPending?`animate-spin`:``}),onClick:()=>p.mutate(e.id),title:`Recover pool`,children:`Recover`}),!(!t.isEnabled&&t.cooldowns.length>0)&&(0,W.jsx)(c,{size:`icon`,variant:`secondary`,disabled:n,icon:n?(0,W.jsx)(s,{size:12,className:`animate-spin`}):(0,W.jsx)(o,{size:12}),onClick:()=>l(e),title:t.checkTooltip??`Run health check`,label:`Test`}),(0,W.jsx)(c,{size:`icon`,variant:`secondary`,icon:(0,W.jsx)(y,{size:12}),onClick:()=>a(e),title:`Edit pool`,label:`Edit`}),(0,W.jsx)(c,{size:`icon`,variant:`secondary`,icon:(0,W.jsx)(te,{size:12}),onClick:()=>r(e.id),title:`Delete pool`,label:`Delete`}),(0,W.jsx)(B,{className:`ml-3`,checked:t.isEnabled,disabled:d.isPending,onChange:t=>d.mutate({poolId:e.id,request:{status:t?`active`:`disabled`}})})]})}var lt=(0,U.memo)(function({pool:e,isSelected:t,onToggleSelect:n,checkResult:r,isTesting:i,onDelete:a,onEdit:o,onHealthCheck:s,onActivity:c,speedResult:l,isSpeedTesting:u,maskValues:d,maskIp:f,probe:p}){let m=(0,U.useContext)(tt),h=it(e,r,i,(m.live?m.byId.get(e.id):void 0)??null,p);return(0,W.jsxs)(`tr`,{className:h.isEnabled?``:`opacity-60`,children:[(0,W.jsx)(`td`,{className:`w-13`,children:(0,W.jsx)(`input`,{type:`checkbox`,checked:t,onChange:()=>n(e.id),"aria-label":`Select ${h.poolLabel}`})}),(0,W.jsx)(`td`,{className:`min-w-0 max-w-150`,children:(0,W.jsx)(at,{pool:e,view:h,maskValues:d})}),(0,W.jsx)(`td`,{className:`min-w-0 max-w-90`,children:e.family?(0,W.jsx)(`span`,{className:`truncate text-caption font-semibold text-text-secondary`,title:e.family,children:e.family}):(0,W.jsx)(`span`,{className:`text-badge text-text-tertiary`,children:`—`})}),(0,W.jsx)(`td`,{className:`max-w-110`,children:(0,W.jsx)(ot,{pool:e,view:h,speedResult:l,isSpeedTesting:u,maskIp:f})}),(0,W.jsx)(`td`,{className:`min-w-55`,children:(0,W.jsx)(st,{pool:e,view:h})}),(0,W.jsx)(`td`,{className:`whitespace-nowrap pl-36 text-right`,children:(0,W.jsx)(ce,{gap:`4px`,justify:`end`,children:(0,W.jsx)(ct,{pool:e,view:h,isTesting:i,onDelete:a,onEdit:o,onHealthCheck:s,onActivity:c})})})]})});function ut({pool:e,onClose:t}){let n=Se(e.id),r=Ce(),i=n.data??[],a=et(e.lastErrorCategory),o=e.status===`disabled`&&a!==void 0,s=e.status===`active`?`ok`:e.status===`disabled`?`disabled`:`warn`;return(0,W.jsx)(v,{open:!0,onClose:t,title:`Health & Activity — ${Ke(e)}`,children:(0,W.jsxs)(se,{gap:`14px`,children:[(0,W.jsxs)(`div`,{className:`flex items-center gap-8 rounded-panel border bg-surface-2 p-8 ${o?`border-orange`:`border-inner-border`}`,children:[(0,W.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,W.jsx)(`div`,{className:`mb-2.5 text-text-tertiary text-micro font-bold tracking-label uppercase`,children:`Proxy health`}),(0,W.jsx)(`div`,{className:`text-title font-bold leading-[1.3]`,children:o?`Proxy reachable`:`Proxy ${e.status}`}),(0,W.jsx)(`p`,{className:`mt-3 mx-0 mb-0 text-text-secondary text-caption leading-normal wrap-anywhere`,children:o?`${a} · disabled from routing`:e.lastError??`No recent proxy errors.`})]}),(0,W.jsx)(R,{tone:s,dot:!0,children:e.status})]}),e.status===`cooldown`&&(0,W.jsx)(`div`,{className:`flex justify-end`,children:(0,W.jsx)(c,{size:`sm`,variant:`secondary`,disabled:r.isPending,onClick:()=>r.mutate(e.id),icon:(0,W.jsx)(C,{size:12,className:r.isPending?`animate-spin`:``}),children:`Recover Now`})}),n.isPending?(0,W.jsx)(g,{label:`Loading pool activity…`}):null,n.isError?(0,W.jsx)(h,{message:`Failed to load pool activity`,onRetry:()=>void n.refetch()}):null,!n.isPending&&!n.isError&&i.length===0?(0,W.jsx)(_,{title:`No pool activity`,message:`Proxy checks, disable events, and recoveries will appear here.`}):null,i.length>0?(0,W.jsx)(`div`,{className:`grid gap-4 max-h-190 overflow-y-auto pr-1`,children:i.map(e=>(0,W.jsxs)(`div`,{className:`p-6 border border-inner-border rounded-control bg-surface-1`,children:[(0,W.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-4`,children:[(0,W.jsxs)(ce,{gap:`6px`,children:[(0,W.jsxs)(R,{tone:e.toStatus===`active`?`ok`:e.toStatus===`disabled`?`disabled`:`warn`,children:[e.fromStatus??`new`,` → `,e.toStatus]}),e.errorCategory?(0,W.jsx)(R,{tone:e.errorCategory.startsWith(`proxy_`)?`warn`:`err`,children:e.errorCategory}):null]}),(0,W.jsx)(`time`,{className:`text-text-tertiary text-badge tabular-nums`,children:new Date(e.createdAt).toLocaleString()})]}),(0,W.jsx)(`p`,{className:`mt-4 mx-0 mb-0 text-text-secondary text-caption leading-normal wrap-anywhere`,children:e.reason??`No additional details`})]},e.id))}):null]})})}function dt(){let e=_e(),t=we(),n=xe(),r=De(),[i,m]=(0,U.useState)(!1),y=(0,U.useCallback)(()=>m(!1),[]),[C,T]=(0,U.useState)(null),[E,D]=(0,U.useState)(null),[O,k]=(0,U.useState)(!1),[A,M]=(0,U.useState)(null),[N,P]=(0,U.useState)(new Set),F=x(),I=F.enabled,L=S(),z=L.enabled,[B,V]=(0,U.useState)(new Set),[H,fe]=(0,U.useState)(()=>{try{return localStorage.getItem(ze)===`opencode`?`opencode`:`url`}catch{return`url`}});(0,U.useEffect)(()=>{try{localStorage.setItem(ze,H)}catch{}},[H]);let[pe,he]=(0,U.useState)(new Set),[ge,ve]=(0,U.useState)({}),ye=Te(),be=Oe(),[Se,Ce]=(0,U.useState)(me),[Ee,ke]=(0,U.useState)(()=>{try{let e=localStorage.getItem(`cartethyia_proxy_speed_results`);return e?JSON.parse(e):{}}catch{return{}}}),[G,Ae]=(0,U.useState)(new Set),Ne=(0,U.useCallback)((e,t)=>{let n={...t,measuredAt:new Date().toISOString()};ke(t=>{let r={...t,[e]:n};try{localStorage.setItem(`cartethyia_proxy_speed_results`,JSON.stringify(r))}catch{}return r})},[]),[K,q]=(0,U.useState)(()=>{try{let e=localStorage.getItem(Be);return e?JSON.parse(e):{}}catch{return{}}}),[J,Fe]=(0,U.useState)({key:`name`,direction:`asc`}),[Y,X]=(0,U.useState)(null),[Ie,Le]=(0,U.useState)(null),Z=e.data??[],Re=(0,U.useMemo)(()=>Pe(Z,J.key,J.direction,e=>$e(e,K[e.id])),[Z,J,K]),We=(0,U.useCallback)(e=>{let t=e;Fe(e=>e.key===t?{key:t,direction:e.direction===`asc`?`desc`:`asc`}:{key:t,direction:`asc`})},[]),Q=e.isPending,$=e.isError,Ze=Z.length>0&&Z.every(e=>N.has(e.id)),et=()=>{P(Ze?new Set:new Set(Z.map(e=>e.id)))},tt=(0,U.useCallback)(e=>{P(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},[]);(0,U.useEffect)(()=>{try{localStorage.setItem(Be,JSON.stringify(K))}catch{}},[K]);let it=Object.values(K),at=it.length,ot=it.filter(e=>e.status===`healthy`||e.status===`reachable`).length,st=it.filter(e=>e.status!==`healthy`&&e.status!==`reachable`).length,ct=(0,U.useCallback)(e=>{V(t=>new Set(t).add(e.id)),r.mutate(e.id,{onSuccess:t=>{q(n=>({...n,[e.id]:t}));let n=Ke(e);t.status===`healthy`?l.success(`${n}: connected`,`${t.latencyMs??0}ms`):t.status===`reachable`?l.error(`${n}: proxy reachable · disabled`,t.errorMessage):l.error(`${n}: ${t.status===`timeout`?`timeout`:`unhealthy`}`,t.errorMessage)},onError:t=>{let n=Ke(e);l.error(`${n}: check failed`,j(t,`Health check failed`))},onSettled:()=>{V(t=>{let n=new Set(t);return n.delete(e.id),n})}})},[r]),dt=async()=>{let e=Z;if(e.length===0)return;let t=0,n=0,i=0,a=async()=>{for(;;){let a=e[i++];if(!a)return;V(e=>new Set(e).add(a.id));try{let e=await r.mutateAsync(a.id);q(t=>({...t,[a.id]:e})),e.status===`healthy`?t+=1:n+=1}catch(e){n+=1;let t={poolId:a.id,status:`timeout`,errorMessage:j(e,`Health check failed`)};q(e=>({...e,[a.id]:t}))}finally{V(e=>{let t=new Set(e);return t.delete(a.id),t})}}};await Promise.all(Array.from({length:Math.min(8,e.length)},()=>a())),l.success(`Tested ${e.length} pools · ${t} healthy · ${n} failed`)},ft=async()=>{let e=Z.filter(e=>N.has(e.id));if(e.length===0)return;let t=0,n=0,i=0,a=async()=>{for(;;){let a=e[i++];if(!a)return;V(e=>new Set(e).add(a.id));try{let e=await r.mutateAsync(a.id);q(t=>({...t,[a.id]:e})),e.status===`healthy`?t+=1:n+=1}catch(e){n+=1;let t={poolId:a.id,status:`timeout`,errorMessage:j(e,`Health check failed`)};q(e=>({...e,[a.id]:t}))}finally{V(e=>{let t=new Set(e);return t.delete(a.id),t})}}};await Promise.all(Array.from({length:Math.min(8,e.length)},()=>a())),l.success(`Tested ${e.length} pools · ${t} healthy · ${n} failed`)},pt=async()=>{let e=Z.filter(e=>N.has(e.id));if(e.length===0)return;let t=0,n=0,r=0,i=0,a=0,o=async()=>{for(;;){let o=e[a++];if(!o)return;he(e=>new Set(e).add(o.id));try{let e=await ye.mutateAsync({poolId:o.id,providerId:He});ve(t=>({...t,[o.id]:{endpoint:o.endpoint??``,result:e}})),e.status===`allowed`?t+=1:e.status===`blocked`?n+=1:e.status===`throttled`?r+=1:i+=1}catch(e){i+=1,ve(t=>({...t,[o.id]:{endpoint:o.endpoint??``,result:{poolId:o.id,providerId:He,status:`unreachable`,reason:j(e,`Provider probe failed`)}}}))}finally{he(e=>{let t=new Set(e);return t.delete(o.id),t})}}};await Promise.all(Array.from({length:Math.min(Ue,e.length)},()=>o())),l.success(`OpenCode: ${t} allowed · ${n} blocked`+(r>0?` · ${r} rate-limited`:``)+(i>0?` · ${i} unreachable`:``))},mt=async()=>{let e=Z.filter(e=>N.has(e.id));if(e.length===0)return;let t=0;await(async()=>{for(;;){let n=e[t++];if(!n)return;Ae(e=>new Set(e).add(n.id));try{let e=await be.mutateAsync({poolId:n.id,bytes:Se});Ne(n.id,e)}catch(e){Ne(n.id,{poolId:n.id,status:`failed`,bytes:0,durationMs:0,errorMessage:j(e,`Speed test failed`)})}finally{Ae(e=>{let t=new Set(e);return t.delete(n.id),t})}}})(),l.success(`Speed tested ${e.length} pool(s)`)},ht=async()=>{let e=Z.filter(e=>N.has(e.id));e.length!==0&&(await Promise.all(e.map(e=>n.mutateAsync({poolId:e.id,request:{status:`active`}}))),P(new Set),l.success(`Enabled ${e.length} pool(s)`))},gt=async()=>{let e=Z.filter(e=>N.has(e.id));e.length!==0&&(await Promise.all(e.map(e=>n.mutateAsync({poolId:e.id,request:{status:`disabled`}}))),P(new Set),l.success(`Disabled ${e.length} pool(s)`))},_t=()=>{let e=N.size>0?Z.filter(e=>N.has(e.id)):Z;if(e.length===0)return;let t=e.map(e=>Ge(e).endpoint||e.endpoint).join(`
7
- `);oe(`cartethyia-proxies.txt`,t,`text/plain;charset=utf-8`),l.success(`Exported ${e.length} pool(s)`)},vt=(0,U.useCallback)(e=>{let t=Z.find(t=>t.id===e);t&&X([t])},[Z]);return(0,W.jsx)(nt,{children:(0,W.jsxs)(se,{gap:`16px`,children:[(0,W.jsx)(v,{open:i,onClose:y,title:`Add Proxy`,footer:C,children:(0,W.jsx)(Qe,{onClose:y,actionsRef:T,onProbeResult:(e,t)=>{let n=Z.find(t=>t.id===e);ve(r=>({...r,[e]:{endpoint:n?.endpoint??``,result:t}}))},onHealthResult:(e,t)=>{q(n=>({...n,[e]:t}))}})}),(0,W.jsx)(v,{open:A!==null,onClose:()=>M(null),title:`Edit pool`,footer:E,children:A&&(0,W.jsx)(Xe,{pool:A,onClose:()=>M(null),actionsRef:D},A.id)}),(0,W.jsxs)(ae,{style:Z.length===0&&!Q&&!$?{minHeight:`min(78dvh, calc(100dvh - 160px))`,display:`flex`,flexDirection:`column`}:void 0,children:[(0,W.jsx)(ie,{title:`Proxy Pool`,subtitle:`Outbound proxy servers — HTTP, HTTPS, and SOCKS5`,icon:(0,W.jsx)(w,{size:16}),action:(0,W.jsxs)(ce,{gap:`8px`,children:[(0,W.jsx)(c,{variant:`secondary`,size:`sm`,icon:(0,W.jsx)(ue,{size:13}),onClick:()=>k(!0),children:`Deploy relay`}),(0,W.jsx)(c,{variant:`primary`,size:`sm`,icon:(0,W.jsx)(b,{size:13}),onClick:()=>m(!0),children:`Add proxies`})]})}),(0,W.jsxs)(re,{style:Z.length===0&&!Q&&!$?{flex:1,display:`flex`,flexDirection:`column`,gap:`16px`}:void 0,children:[(0,W.jsx)(rt,{pools:Z}),Z.length>0&&(0,W.jsxs)(`div`,{className:`nested-panel flex flex-wrap items-center justify-start overflow-x-auto rounded-card border border-inner-border bg-surface-2 p-4 text-badge`,children:[(0,W.jsxs)(`div`,{className:`flex flex-wrap items-center gap-5`,children:[(0,W.jsxs)(`label`,{className:`flex items-center gap-3 cursor-pointer text-text-secondary`,children:[(0,W.jsx)(`input`,{type:`checkbox`,checked:Ze,onChange:et,"aria-label":`Select all proxies`}),`Select all`,N.size>0&&(0,W.jsxs)(`span`,{className:`text-text-tertiary`,children:[`(`,N.size,`)`]})]}),at>0&&(0,W.jsxs)(ce,{gap:`6px`,children:[(0,W.jsxs)(`span`,{className:`text-text-tertiary`,children:[`Tested `,at,`/`,Z.length]}),ot>0&&(0,W.jsxs)(R,{tone:`ok`,children:[ot,` success`]}),st>0&&(0,W.jsxs)(R,{tone:`err`,children:[st,` errors`]})]})]}),(0,W.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3`,children:[(0,W.jsx)(c,{variant:`ghost`,size:`sm`,icon:I?(0,W.jsx)(d,{size:12}):(0,W.jsx)(f,{size:12}),onClick:()=>F.setEnabled(!I),title:I?`Show proxy names and addresses`:`Hide proxy names and addresses`,children:I?`Unmask`:`Mask`}),(0,W.jsx)(c,{variant:`ghost`,size:`sm`,icon:z?(0,W.jsx)(d,{size:12}):(0,W.jsx)(f,{size:12}),onClick:()=>L.setEnabled(!z),title:z?`Show egress addresses`:`Hide egress addresses`,children:z?`Show IP`:`Mask IP`}),(0,W.jsx)(c,{variant:`secondary`,size:`sm`,disabled:B.size>0||Z.length===0,icon:B.size>0?(0,W.jsx)(s,{size:12,className:`animate-spin`}):(0,W.jsx)(o,{size:12}),onClick:()=>void dt(),children:`Test all`}),(0,W.jsxs)(`div`,{className:`inline-flex items-stretch h-15`,children:[(0,W.jsx)(c,{variant:`secondary`,size:`sm`,className:`rounded-tr-none rounded-br-none`,disabled:B.size>0||pe.size>0||N.size===0,icon:B.size>0||pe.size>0?(0,W.jsx)(s,{size:12,className:`animate-spin`}):(0,W.jsx)(o,{size:12}),onClick:()=>void(H===`opencode`?pt():ft()),children:H===`opencode`?`Test OpenCode`:`Test URL`}),(0,W.jsx)(a,{"aria-label":`Test payload`,value:H,onValueChange:e=>fe(e),options:Ve,disabled:B.size>0||pe.size>0,className:`w-auto min-w-38 h-15 rounded-tl-none rounded-bl-none -ml-0.5`})]}),(0,W.jsxs)(`div`,{className:`inline-flex items-stretch h-15`,children:[(0,W.jsx)(c,{variant:`secondary`,size:`sm`,className:`rounded-tr-none rounded-br-none`,disabled:N.size===0||G.size>0||be.isPending,icon:G.size>0?(0,W.jsx)(s,{size:12,className:`animate-spin`}):(0,W.jsx)(p,{size:12}),onClick:()=>void mt(),children:`Speedtest selected`}),(0,W.jsx)(a,{"aria-label":`Speed test payload size`,value:String(Se),onValueChange:e=>Ce(Number(e)),options:Ye,disabled:G.size>0||be.isPending,className:`w-auto min-w-38 h-15 rounded-tl-none rounded-bl-none -ml-0.5`})]}),(0,W.jsx)(c,{variant:`secondary`,size:`sm`,disabled:Z.length===0,icon:(0,W.jsx)(u,{size:12}),onClick:_t,children:`Export`}),(0,W.jsx)(c,{variant:`secondary`,size:`sm`,disabled:N.size===0||n.isPending,icon:(0,W.jsx)(de,{size:12}),onClick:()=>void ht(),children:`Enable selected`}),(0,W.jsx)(c,{variant:`secondary`,size:`sm`,disabled:N.size===0||n.isPending,icon:(0,W.jsx)(ee,{size:12}),onClick:()=>void gt(),children:`Disable selected`}),(0,W.jsx)(c,{variant:`danger`,size:`sm`,disabled:N.size===0||t.isPending,icon:(0,W.jsx)(te,{size:12}),onClick:()=>{let e=Z.filter(e=>N.has(e.id));e.length!==0&&X(e)},children:`Delete selected`})]})]}),Q&&(0,W.jsx)(g,{}),$&&(0,W.jsx)(h,{title:`Error`,message:`Failed to load network pools`}),!Q&&!$&&Z.length===0&&(0,W.jsx)(`div`,{className:`flex-1 flex items-center justify-center p-12 border border-dashed border-transparent rounded-card bg-transparent text-center`,children:(0,W.jsx)(_,{title:`No proxy pools configured`,message:`The summary above is empty because nothing is routing yet. Use Add proxies or Deploy relay in the header to start one.`})}),!Q&&!$&&Z.length>0&&(0,W.jsx)(`div`,{className:`proxy-table-scroll rounded-control border border-inner-border bg-surface-1`,children:(0,W.jsx)(le,{maxHeight:460,scrollRegion:!0,headers:[``,{key:`name`,label:`Proxy`,sortable:!0},{key:`family`,label:`Family`,sortable:!0},{key:`address`,label:`Address`,sortable:!0},{key:`load`,label:`Load`,sortable:!0},`Actions`],sortKey:J.key,sortDirection:J.direction,onSort:We,children:Re.map(e=>(0,W.jsx)(lt,{pool:e,isSelected:N.has(e.id),onToggleSelect:tt,checkResult:K[e.id],probe:e.providerProbe===void 0?Me(ge[e.id],e.endpoint):{poolId:e.id,providerId:e.providerProbe.providerId,status:e.providerProbe.status,...e.providerProbe.httpStatus===void 0?{}:{httpStatus:e.providerProbe.httpStatus},...e.providerProbe.reason===void 0?{}:{reason:e.providerProbe.reason},...e.providerProbe.latencyMs===void 0?{}:{latencyMs:e.providerProbe.latencyMs}},isTesting:B.has(e.id),onDelete:vt,onEdit:M,onHealthCheck:ct,onActivity:Le,speedResult:Je(Ee[e.id],qe(e)),isSpeedTesting:G.has(e.id),maskValues:I,maskIp:z},e.id))})})]})]}),(0,W.jsx)(ne,{open:Y!==null,onClose:()=>X(null),onConfirm:async()=>{Y&&(await Promise.all(Y.map(e=>t.mutateAsync(e.id))),P(new Set),l.success(`Deleted ${Y.length} pool(s)`),X(null))},title:`Delete proxy pool?`,message:Y&&Y.length===1?`Delete "${Ke(Y[0])}"? This cannot be undone.`:Y?`Delete ${Y.length} proxy pools? This cannot be undone.`:`Delete this proxy pool? This cannot be undone.`,confirmLabel:`Delete`,danger:!0}),Ie?(0,W.jsx)(ut,{pool:Ie,onClose:()=>Le(null)}):null,O?(0,W.jsx)(je,{onClose:()=>k(!1)}):null]})})}export{Qe as ProxyBulkForm,nt as ProxyLiveProvider,Ze as SchemeChipRow,dt as default};
@@ -1 +0,0 @@
1
- import{n as e,o as t,r as n,t as r}from"./jsx-runtime-CXUMngI_.js";import{i}from"./terminal-C9mZ4Ugm.js";import{t as a}from"./check-D69FzdvC.js";import{t as o}from"./select-CGUuTQmj.js";import{t as s}from"./chevron-right-BXIy5l3h.js";import{m as c,n as l,t as u}from"./toast-DKAdP2mo.js";import{t as d}from"./eye-off-Bk5g2luF.js";import{a as f,i as p,n as m,r as h,t as g}from"./state-DHKdg-pm.js";import{t as _}from"./dialog-iocKA3jr.js";import{t as v}from"./refresh-cw-BqJFk4sU.js";import{t as y}from"./rotate-ccw-CufcqITi.js";import{t as b}from"./sliders-horizontal-ClG7dBeJ.js";import{t as x}from"./trash-Cppn5c3R.js";import{c as S}from"./query-keys-ROf-g1Wi.js";import{F as C}from"./entry-DTiWhIY-.js";import{n as w,r as T,t as E}from"./card-BTdbRFFg.js";import{t as D}from"./badge-BwmwEOgA.js";import{t as O}from"./ProviderIcon-paOCq8I0.js";import{t as k}from"./switch-DIDeAiz9.js";import{t as A}from"./stack-C1kTcOmP.js";import{n as j}from"./inline-DCejSLlA.js";import{t as M}from"./layout-Bv-NxqZ5.js";import{a as ee,i as N,n as P,o as F,r as I,s as L,t as R}from"./quota-DZGyp0N5.js";import{a as te,c as z,d as B,f as V,i as H,l as U,n as W,o as ne,p as G,r as re,s as K,t as q,u as J}from"./HealthEventsModal-DDkHfwpV.js";var Y=e(`calendar-check`,[[`path`,{d:`M8 2v3`,key:`1ioesn`}],[`path`,{d:`M16 2v3`,key:`otl347`}],[`rect`,{x:`3`,y:`3`,width:`18`,height:`18`,rx:`2`,key:`h1oib`}],[`path`,{d:`M3 9h18`,key:`1pudct`}],[`path`,{d:`m9 15 2 2 4-4`,key:`1grp1n`}]]),ie=e(`chevron-left`,[[`path`,{d:`m15 18-6-6 6-6`,key:`1wnfg3`}]]),X=e(`clock-3`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`M12 6v6h4`,key:`135r8i`}]]),Z=e(`zap`,[[`path`,{d:`M15.914 4a1.5 1.5 0 00-2.474-1.561l-9 9A1.5 1.5 0 005.5 14h4.002a.5.5 0 01.471.666L8.086 20a1.5 1.5 0 002.475 1.56l9-9A1.5 1.5 0 0018.5 10h-3.997a.5.5 0 01-.472-.667z`,key:`1v7up4`}]]),Q=t(n(),1),$=r();function ae(e){return!!(e.quota?.windows.length&&e.quota.windows.every(e=>e.remainingPercent!==null&&e.remainingPercent<=0))}function oe(e){let t=e.quota?.windows.map(e=>e.resetsAt?new Date(e.resetsAt).getTime():1/0)??[];return Math.min(...t,1/0)}function se({account:e,onClose:t}){let n=H(e.id,!0),r=J(e.id),i=n.data?.credits??[],a=e=>e?new Date(e).toLocaleString():`—`,o=e=>e?new Date(e).toLocaleString():`—`,s=e=>{if(!e)return``;let t=new Date(e).getTime()-Date.now();if(!Number.isFinite(t))return``;if(t<=0)return`expired`;let n=Math.floor(t/864e5);if(n>=1)return`in ${n}d`;let r=Math.floor(t/36e5);return r>=1?`in ${r}h`:`in ${Math.max(1,Math.floor(t/6e4))}m`};return(0,$.jsx)(_,{open:!0,onClose:t,size:`lg`,title:`Saved Rate-Limit Resets — ${e.name}`,children:(0,$.jsxs)(`div`,{className:`flex flex-col gap-7`,children:[(0,$.jsxs)(`div`,{className:`flex items-center justify-between gap-6 rounded-control border border-inner-border bg-surface-2 px-8 py-6`,children:[(0,$.jsxs)(`div`,{className:`min-w-0`,children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-4`,children:[(0,$.jsx)(Z,{size:14,className:`text-status-success`}),(0,$.jsx)(`span`,{className:`text-body font-semibold`,children:`Available resets`})]}),(0,$.jsx)(`p`,{className:`mt-2 text-text-tertiary text-badge leading-normal`,children:`Each credit lifts a spent rate-limit window before its natural reset.`})]}),(0,$.jsxs)(D,{tone:n.data&&n.data.availableCount>0?`ok`:`disabled`,dot:!0,children:[n.data?.availableCount??0,` reset`,(n.data?.availableCount??0)===1?``:`s`]})]}),n.isPending?(0,$.jsx)(h,{label:`Reading saved resets…`}):n.isError?(0,$.jsx)(m,{message:`Failed to read saved resets`,onRetry:()=>void n.refetch()}):i.length===0?(0,$.jsx)(g,{title:`No saved resets`,message:`This account has no saved rate-limit reset credits right now.`,icon:(0,$.jsx)(Z,{size:20})}):(0,$.jsx)(`div`,{className:`max-h-170 overflow-y-auto rounded-control border border-inner-border`,children:(0,$.jsx)(M,{headers:[`Status`,`Title`,`Granted`,`Expires`,``],children:i.map(e=>{let t=(e.status??`available`)===`available`,n=s(e.expiresAt);return(0,$.jsxs)(`tr`,{children:[(0,$.jsx)(`td`,{className:`whitespace-nowrap align-middle`,children:(0,$.jsx)(D,{tone:t?`ok`:e.status===`expired`?`disabled`:`warn`,children:e.status??`available`})}),(0,$.jsx)(`td`,{className:`text-caption font-medium whitespace-nowrap align-middle text-text-primary`,children:e.title??`Rate-limit reset`}),(0,$.jsx)(`td`,{className:`text-badge whitespace-nowrap tabular-nums align-middle text-text-secondary`,children:a(e.grantedAt)}),(0,$.jsxs)(`td`,{className:`text-badge whitespace-nowrap tabular-nums align-middle text-text-secondary`,children:[o(e.expiresAt),n&&(0,$.jsxs)(`span`,{className:`ml-3 text-text-tertiary`,children:[`(`,n,`)`]})]}),(0,$.jsx)(`td`,{className:`whitespace-nowrap text-right align-middle`,children:(0,$.jsx)(l,{size:`sm`,variant:t?`primary`:`secondary`,disabled:!t||r.isPending,onClick:()=>r.mutate({creditId:e.id},{onSuccess:e=>{e.ok?u.success(e.message??`Rate limit reset applied`):u.error(e.message??`Rate limit reset failed`)},onError:e=>{u.error(S(e,`Unable to redeem rate-limit reset`))}}),children:`Use`})})]},e.id)})})}),(0,$.jsx)(j,{justify:`flex-end`,gap:`0px`,children:(0,$.jsx)(l,{variant:`secondary`,size:`sm`,onClick:t,children:`Close`})})]})})}function ce({accounts:e}){let t=(0,Q.useMemo)(()=>{let t=new Map;for(let n of e){if(!W(n.provider))continue;let e=t.get(n.provider);e?e.count+=1:t.set(n.provider,{id:n.provider,label:n.providerName||n.provider,count:1})}return[...t.values()]},[e]),[n,r]=(0,Q.useState)(``),i=(t.find(e=>e.id===n)??t[0])?.id??``,a=V(i),s=i.length===0||a.isPending||t.length===0;return(0,$.jsxs)(`div`,{className:`flex min-w-0 flex-wrap items-center gap-2.5`,"aria-label":`Daily growth actions`,children:[(0,$.jsx)(`div`,{className:`min-w-0 w-67.5`,children:(0,$.jsx)(o,{"aria-label":`Provider for the daily growth pass`,value:i,onValueChange:r,className:`w-full h-16`,options:t.length>0?t.map(e=>({value:e.id,label:`${e.label} · ${e.count}`})):[{value:``,label:`No buddy providers`}]})}),(0,$.jsx)(l,{variant:`secondary`,size:`sm`,title:`Send the activity report, then claim the daily check-in, for every account of this provider`,"aria-label":`Run the daily growth pass for this provider`,disabled:s,className:`shrink-0`,icon:a.isPending?(0,$.jsx)(c,{size:13,className:`animate-spin`}):(0,$.jsx)(Y,{size:13}),onClick:()=>a.mutate(void 0,{onSuccess:e=>{let t=e.data.filter(e=>!e.report.ok).length;t===0?u.success(e.message):u.error(`${e.message} — ${t} report${t===1?``:`s`} failed`)},onError:e=>u.error(S(e,`Unable to run the daily growth pass`))}),children:`Daily growth`})]})}function le({account:e,onToggle:t,onDelete:n,onShowHealth:r,onShowResets:a}){let o=K(e.id),d=B(e.id),p=W(e.provider),m=re(e.provider),h=H(e.id,m),g=e.quota,[_,v]=(0,Q.useState)(0),b=g?.windows??[],C=F(b,_),w=C.pageCount;(0,Q.useEffect)(()=>{v(e=>Math.min(e,Math.max(0,w-1)))},[w]);let T=o.isPending||d.isPending,D=h.data?.availableCount??0,[A,j]=(0,Q.useState)(null),[M,te]=(0,Q.useState)(!1),z=e.checkin?.attemptedToday??!1,V=`${A?A.state===`claimed`?`Checked in${A.credit===null?``:` +${A.credit}`}${A.streakDays===null?``:` · ${A.streakDays}d streak`}`:A.state===`already_claimed`?`Check-in attempted · already claimed`:A.state===`not_eligible`?`Check-in attempted · not eligible`:A.state===`event_ended`?`Check-in attempted · event ended`:`Check-in attempted · unavailable`:z?`Check-in attempted today`:`Check-in due`}${M?` · Reported today`:``}`,U=b.reduce((e,t)=>{let n=t.limit;if(typeof n!=`number`||!Number.isFinite(n))return e;let r=typeof t.remaining==`number`&&Number.isFinite(t.remaining)?t.remaining:typeof t.used==`number`&&Number.isFinite(t.used)?n-t.used:typeof t.remainingPercent==`number`&&Number.isFinite(t.remainingPercent)?n*t.remainingPercent/100:null;return r===null?e:e+Math.max(0,r)},0),ne=(o.error?S(o.error,`Unable to refresh this account`):null)??g?.refreshError??g?.error??e.health?.sanitizedMessage,G=ee(ne),q=G===`Quota tracking is not supported for this provider`?null:G,J=R(e.credentialHint,e.name),X=e.health?.status??`unknown`;return(0,$.jsxs)(E,{className:`flex h-full flex-col overflow-hidden`,"aria-busy":T,children:[(0,$.jsxs)(`div`,{className:`flex flex-wrap items-center gap-5 px-7 py-4`,children:[(0,$.jsx)(O,{icon:e.providerIcon,name:e.providerName,size:32}),(0,$.jsxs)(`div`,{className:`flex-[1_1_160px]`,children:[(0,$.jsxs)(`div`,{className:`flex min-w-0 items-center gap-4`,children:[(0,$.jsx)(`div`,{className:`truncate text-caption font-bold text-text-primary text-body`,children:e.providerName}),g?.plan&&(0,$.jsx)(`span`,{className:`shrink-0 rounded-chip bg-accent-soft px-4 py-1 text-micro font-semibold text-accent`,children:g.plan})]}),(0,$.jsx)(`div`,{className:`truncate text-badge text-text-secondary`,children:J.primary}),J.secondary!==null&&(0,$.jsx)(`div`,{className:`truncate text-micro text-text-tertiary`,children:J.secondary}),g&&(0,$.jsx)(`div`,{className:`truncate text-micro text-text-tertiary`,children:P(g.lastSuccessAt??g.fetchedAt)}),m&&(0,$.jsx)(`div`,{className:`truncate text-micro flex items-center gap-2 text-text-tertiary`,title:`Saved rate-limit reset credits available on this account`,children:h.isPending?`Checking saved resets…`:D>0?(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(Z,{size:10,className:`text-status-success shrink-0`,"aria-hidden":`true`}),(0,$.jsxs)(`span`,{className:`reset-credit-live`,children:[D,` rate-limit reset`,D===1?``:`s`,` available`]})]}):`No rate-limit resets available`}),p&&(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(`div`,{title:`Daily growth state: manual pass result, else the sweep ledger for today`,className:`truncate text-micro text-text-tertiary`,children:d.isPending?`Running growth pass…`:V}),b.some(e=>typeof e.limit==`number`&&Number.isFinite(e.limit))&&(0,$.jsxs)(`div`,{className:`truncate text-micro text-text-tertiary`,children:[`Total credits: `,U.toLocaleString(void 0,{maximumFractionDigits:2})]})]})]}),(0,$.jsxs)(`div`,{className:`flex items-center gap-1.75 gap-3 ml-auto`,children:[m&&(0,$.jsx)(l,{variant:`ghost`,size:`icon`,className:`w-16 h-16 p-0`,title:h.isPending?`Checking saved rate-limit resets…`:D>0?`Saved rate-limit resets (${D} available)`:`Saved rate-limit resets`,"aria-label":`Open saved rate-limit resets for ${e.name}`,disabled:T,onClick:()=>a(e),children:(0,$.jsx)(Z,{size:14})}),p&&(0,$.jsx)(l,{variant:`ghost`,size:`icon`,className:`w-16 h-16 p-0`,title:`Daily growth pass (check-in + activity report) — ${V}`,"aria-label":`Run daily growth pass for ${e.name}`,disabled:T,onClick:()=>d.mutate(void 0,{onSuccess:e=>{let t=e.checkin.data;t&&j({state:t.state,credit:t.credit,streakDays:t.streakDays}),e.report.ok&&te(!0),e.ok?u.success(e.message):u.error(e.message)},onError:e=>{u.error(S(e,`Unable to run daily growth pass`))}}),children:d.isPending?(0,$.jsx)(c,{size:14,className:`animate-spin`}):(0,$.jsx)(Y,{size:14})}),(0,$.jsx)(l,{variant:`ghost`,size:`sm`,title:X===`active`?`Health & Error Log`:`${X} — Inspect account health details`,"aria-label":X===`active`?`Health log for ${e.name}`:`Account is ${X} — inspect health details for ${e.name}`,disabled:T,onClick:()=>r(e),icon:(0,$.jsx)(i,{size:12})}),(0,$.jsx)(l,{variant:`ghost`,size:`sm`,title:`Refresh quota`,"aria-label":`Refresh ${e.name} quota`,disabled:T,onClick:()=>o.mutate(),icon:o.isPending?(0,$.jsx)(c,{size:12,className:`animate-spin`}):(0,$.jsx)(y,{size:12})}),(0,$.jsx)(l,{variant:`ghost`,size:`sm`,title:`Delete account`,"aria-label":`Delete ${e.name}`,onClick:()=>n(e),className:`text-red`,icon:(0,$.jsx)(x,{size:12})}),(0,$.jsx)(k,{checked:e.active,disabled:o.isPending,onChange:n=>t(e,n),label:``,id:`switch-${e.id}`})]})]}),q&&(0,$.jsxs)(`div`,{className:`flex items-center justify-center gap-4 border-t border-inner-border px-8 py-5 text-center text-badge text-red`,role:`alert`,children:[(0,$.jsx)(f,{size:13,className:`shrink-0`}),(0,$.jsx)(`span`,{children:q})]}),g?.windows.length?(0,$.jsxs)(`div`,{className:`quota-window-list flex flex-1 flex-col gap-4 border-t border-inner-border px-7 py-4.5`,children:[(0,$.jsx)(`div`,{className:`quota-window-section-label text-micro font-bold tracking-label text-text-tertiary`,children:`QUOTA WINDOWS`}),C.items.map((e,t)=>{let n=e.remainingPercent??null,r=typeof e.limit==`number`&&Number.isFinite(e.limit)?e.limit:null,i=typeof e.used==`number`&&Number.isFinite(e.used)?e.used:r!==null&&e.usedPercent!==null&&e.usedPercent!==void 0?r*e.usedPercent/100:null,a=L(n),o=n===null?0:Math.max(0,Math.min(100,n)),s=e=>e.toLocaleString(void 0,{maximumFractionDigits:2}),c=e=>{let t=Math.round(e*10)/10;return t>0&&t<.1?`<0.1`:t.toLocaleString(void 0,{maximumFractionDigits:1})},l=I(e.label);return(0,$.jsxs)(`div`,{className:`quota-window-row grid grid-cols-quota-window min-w-0 items-center gap-x-6 gap-y-2 max-small:grid-cols-[minmax(0,1fr)_auto] max-small:gap-x-4 max-small:gap-y-2.5`,children:[(0,$.jsx)(`div`,{className:`quota-window-heading min-w-0 max-small:col-start-1`,children:(0,$.jsx)(`span`,{className:`text-badge font-semibold text-text-primary`,children:l})}),(0,$.jsx)(`div`,{className:`quota-bar-track quota-window-bar min-w-0 w-full h-5 rounded-tiny bg-inner-border overflow-hidden max-small:col-span-full max-small:row-start-2`,role:`progressbar`,"aria-label":`${l} remaining quota`,"aria-valuemin":0,"aria-valuemax":100,"aria-valuenow":n===null?void 0:o,"aria-valuetext":n===null?`Quota only`:`${c(n)}% remaining`,children:(0,$.jsx)(`div`,{className:`quota-bar-fill h-full rounded-tiny transition-[width] duration-(--dur-macro) ease-spring`,style:{width:`${o}%`,background:a.bar}})}),(0,$.jsx)(`span`,{className:`quota-window-remaining whitespace-nowrap text-badge font-bold tabular-nums max-small:col-start-2 max-small:row-start-1`,style:{color:a.text},children:n===null?`—`:`${c(n)}%`}),(0,$.jsxs)(`div`,{className:`quota-window-details col-span-full flex min-w-0 items-center justify-end gap-6 text-micro text-text-tertiary max-small:row-start-3 max-small:flex-wrap max-small:justify-between max-small:gap-4`,children:[(0,$.jsx)(`span`,{className:`quota-window-usage mr-auto tabular-nums max-small:min-w-0`,children:i!==null&&r!==null?`${s(i)} / ${s(r)} Credits`:`Quota only`}),e.resetsAt&&(0,$.jsx)(`span`,{className:`quota-window-reset whitespace-nowrap tabular-nums text-right max-small:ml-auto`,children:N(e.resetsAt,e.recurring)})]})]},`${e.kind??e.label}:${e.resetsAt??`none`}:${t}`)}),C.pageCount>1&&(0,$.jsxs)(`nav`,{"aria-label":`Quota windows for ${e.name}`,className:`quota-window-pagination mt-auto flex items-center justify-between gap-4 border-t border-inner-border pt-4 max-small:flex-wrap`,children:[(0,$.jsxs)(`span`,{"aria-live":`polite`,className:`text-micro text-text-tertiary`,children:[`Showing `,C.startIndex+1,`–`,C.startIndex+C.items.length,` of `,b.length]}),(0,$.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,$.jsx)(l,{variant:`ghost`,size:`sm`,"aria-label":`Previous quota windows for ${e.name}`,disabled:C.page===0,icon:(0,$.jsx)(ie,{size:13}),onClick:()=>v(C.page-1),className:`h-14 px-4 py-0`,children:`Previous`}),(0,$.jsx)(l,{variant:`ghost`,size:`sm`,"aria-label":`Next quota windows for ${e.name}`,disabled:C.page>=C.pageCount-1,icon:(0,$.jsx)(s,{size:13}),onClick:()=>v(C.page+1),className:`h-14 px-4 py-0`,children:`Next`})]})]})]}):q?null:(0,$.jsx)(`div`,{className:`border-t border-inner-border px-7 py-9 text-center text-badge text-text-tertiary`,children:T||e.pending?`Fetching quota…`:`No quota data`})]})}function ue(){let[e,t]=(0,Q.useState)(`all`),[n,r]=(0,Q.useState)(`all`),[i,s]=(0,Q.useState)(!1),{data:c,isLoading:f,isError:m,error:h,isFetching:_,dataUpdatedAt:y,refetch:x}=ne(),S=(0,Q.useMemo)(()=>[...c?.providers??[]].sort((e,t)=>e.name.localeCompare(t.name,void 0,{sensitivity:`base`})),[c?.providers]),D=(0,Q.useMemo)(()=>c?.accounts??[],[c?.accounts]),O=c?.refreshing??0,k=z(),j=G(),M=U(),ee=te(),[N,P]=(0,Q.useState)(null),[F,I]=(0,Q.useState)(null),[L,R]=(0,Q.useState)(null),B=(0,Q.useMemo)(()=>{let t=D.filter(t=>{if(e!==`all`&&t.provider!==e)return!1;let r=!!t.quota?.windows.length;return n===`untracked`?!r:!(!r||n===`active`&&!t.active||n===`disabled`&&t.active)}),r=(e,t)=>e.providerName.localeCompare(t.providerName,void 0,{sensitivity:`base`})||e.name.localeCompare(t.name,void 0,{sensitivity:`base`});return[...t].sort(i?(e,t)=>oe(e)-oe(t)||r(e,t):r)},[n,D,i,e]),V=async(e,t)=>{try{await j.mutateAsync({id:e.id,active:t}),u.success(`${e.name} ${t?`enabled`:`disabled`}`)}catch(e){u.error(e instanceof Error?e.message:`Unable to update account`)}},H=async()=>{let e=D.filter(e=>e.active&&ae(e));await M.mutateAsync({ids:e.map(e=>e.id),active:!1}),u.success(`Disabled ${e.length} empty accounts`)},W=async()=>{let e=D.filter(e=>!e.active&&e.quota?.windows.some(e=>e.remainingPercent!==null&&e.remainingPercent>0));await M.mutateAsync({ids:e.map(e=>e.id),active:!0}),u.success(`Enabled ${e.length} available accounts`)},re=async e=>{await ee.mutateAsync(e.id),u.success(`${e.name} deleted`)},K=y>0?new Date(y).toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`}):`Not updated`,J=D.filter(ae).length;return(0,$.jsxs)(A,{gap:`16px`,className:`dashboard-page min-h-0 flex-1`,children:[(0,$.jsx)(E,{children:(0,$.jsx)(T,{title:`Quota`,subtitle:`Provider account limits and what is left of them`,icon:(0,$.jsx)(b,{size:16})})}),(0,$.jsx)(E,{children:(0,$.jsxs)(w,{className:`flex flex-col gap-5`,children:[(0,$.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-5`,children:[(0,$.jsxs)(`div`,{className:`flex min-w-0 flex-1 flex-wrap items-center gap-4`,children:[(0,$.jsx)(o,{"aria-label":`Filter quota by provider`,value:e,onValueChange:t,className:`w-full h-16 max-small:w-80`,options:[{value:`all`,label:`All Providers`},...S.map(e=>({value:e.id,label:e.name}))]}),(0,$.jsx)(o,{"aria-label":`Filter quota by account`,value:n,onValueChange:r,className:`w-full h-16 max-small:w-67.5`,options:[{value:`all`,label:`With quota`},{value:`active`,label:`Active`},{value:`disabled`,label:`Disabled`},{value:`untracked`,label:`No quota`}]})]}),(0,$.jsxs)(`div`,{className:`flex flex-wrap items-center gap-4`,children:[(0,$.jsx)(l,{variant:i?`secondary`:`ghost`,size:`sm`,onClick:()=>s(e=>!e),"aria-pressed":i,icon:(0,$.jsx)(X,{size:13}),children:`Expiring first`}),(0,$.jsx)(l,{variant:`ghost`,size:`sm`,className:`text-red`,disabled:J===0||_,onClick:()=>void H(),icon:(0,$.jsx)(d,{size:13}),children:`Turn off Empty`}),(0,$.jsx)(l,{variant:`ghost`,size:`sm`,className:`text-green`,disabled:_,onClick:()=>void W(),icon:(0,$.jsx)(a,{size:13}),children:`Turn on Available`})]})]}),(0,$.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-4 border-t border-inner-border pt-5`,children:[(0,$.jsxs)(`span`,{className:`text-badge text-text-tertiary`,children:[B.length,` shown`,J>0?` · ${J} empty`:``]}),(0,$.jsxs)(`span`,{className:`flex min-w-0 flex-wrap items-center gap-x-5 gap-y-3 text-badge text-text-tertiary`,children:[O>0?`Refreshing ${O} account${O===1?``:`s`}…`:`Auto-refresh 60s · ${K}`,(0,$.jsx)(ce,{accounts:D}),(0,$.jsx)(l,{variant:`secondary`,size:`sm`,title:`Queue quota refresh`,"aria-label":`Queue quota refresh`,disabled:_||k.isPending||D.length===0,icon:(0,$.jsx)(v,{size:13,className:k.isPending?`animate-spin`:void 0}),onClick:()=>k.mutate(D.map(e=>e.id),{onSuccess:e=>{u.success(e.failed===0?`Refreshed ${e.succeeded} quota${e.succeeded===1?``:`s`}`:`Refreshed ${e.succeeded}, ${e.failed} failed`)},onError:e=>u.error(e instanceof Error?e.message:`Unable to refresh quota`)}),children:`Refresh`})]})]})]})}),(0,$.jsx)(`div`,{className:`flex min-h-0 flex-1 flex-col gap-6`,children:f?(0,$.jsx)(p,{className:`min-h-0 flex flex-1 flex-col items-center justify-center`,kind:`loading`,title:`Loading quota data`,description:`Reading provider account limits…`}):m?(0,$.jsx)(p,{className:`min-h-0 flex flex-1 flex-col items-center justify-center`,kind:`error`,title:`Unable to load quota data`,description:h instanceof Error?h.message:`Check the console session and retry.`,action:(0,$.jsx)(l,{variant:`secondary`,onClick:()=>void x(),children:`Retry`})}):B.length===0?(0,$.jsx)(`div`,{className:`flex-1 flex items-center justify-center p-12 border border-dashed border-transparent rounded-card bg-transparent text-center`,children:(0,$.jsx)(g,{title:`No account quota data`,message:`Nothing is reporting a quota window yet. Add a provider account and its limits will appear here.`})}):(0,$.jsx)(`div`,{className:`quota-account-grid scroll-region min-h-0 flex-1 gap-6 [align-content:start]`,children:B.map(e=>(0,$.jsx)(le,{account:e,onToggle:(e,t)=>void V(e,t),onDelete:e=>P(e),onShowHealth:e=>I(e),onShowResets:e=>R(e)},e.id))})}),F&&(0,$.jsx)(q,{summary:{providerId:F.provider,accountId:F.id,title:F.name,status:F.health?.status??`unknown`,errorCategory:F.health?.lastErrorCategory??void 0,errorMessage:F.health?.sanitizedMessage??void 0,emptyMessage:`Status transitions, rate limits, quota refreshes, check-ins, and auto-recoveries will appear here.`},onClose:()=>I(null)}),L&&(0,$.jsx)(se,{account:L,onClose:()=>R(null)}),(0,$.jsx)(C,{open:N!==null,onClose:()=>P(null),onConfirm:async()=>{N&&await re(N)},title:`Delete account?`,message:`Delete "${N?.name}"? This cannot be undone.`,confirmLabel:`Delete`,danger:!0})]})}export{ue as default};
@@ -1 +0,0 @@
1
- import{n as e,o as t,r as n,t as r}from"./jsx-runtime-CXUMngI_.js";import{n as i}from"./toast-DKAdP2mo.js";import{a,t as o}from"./query-keys-ROf-g1Wi.js";import{J as s,P as c,Y as l}from"./entry-DTiWhIY-.js";import{n as u}from"./input-Bn4_kNav.js";import{t as d}from"./layout-Bv-NxqZ5.js";import{t as f}from"./backup-file-gdKIlg8U.js";var p=e(`user-plus`,[[`path`,{d:`M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2`,key:`1yyitq`}],[`circle`,{cx:`9`,cy:`7`,r:`4`,key:`nufk8`}],[`line`,{x1:`19`,x2:`19`,y1:`8`,y2:`14`,key:`1bvyxn`}],[`line`,{x1:`22`,x2:`16`,y1:`11`,y2:`11`,key:`1shjgl`}]]),m=t(n(),1),h=r();function g(){let e=l(),[t,n]=(0,m.useState)(null),[r,d]=(0,m.useState)(`admin`),[g,y]=(0,m.useState)(``),[b,x]=(0,m.useState)(``),[S,C]=(0,m.useState)(``),[w,T]=(0,m.useState)(null),[E,D]=(0,m.useState)(!1),[O,k]=(0,m.useState)(`create`),[A,j]=(0,m.useState)(null),[M,N]=(0,m.useState)(null),P=(0,m.useRef)(null);(0,m.useEffect)(()=>{let t=!0;return a(`/auth/first-boot`).then(r=>{t&&(n(r.requires_setup),r.requires_setup||e(`/login`,{replace:!0}))}).catch(()=>{t&&n(!0)}),()=>{t=!1}},[e]);let F=async n=>{if(n.preventDefault(),t===!1){T(`This console already has an account. Sign in instead.`);return}if(!r.trim()){T(`Administrator username is required.`);return}if(b.length<8){T(`Administrator password must be at least 8 characters.`);return}if(b!==S){T(`Passwords do not match.`);return}D(!0),T(null);try{let t=await a(`/auth/setup`,{method:`POST`,body:JSON.stringify({username:r.trim(),password:b,...g.trim()?{display_name:g.trim()}:{}})});if(t.status!==`success`){T(t.message??`Setup failed. Please try again.`);return}c.removeQueries({queryKey:o.session.current}),e(`/login`,{replace:!0})}catch(e){if(e&&typeof e==`object`&&`message`in e){let t=e.message;if(typeof t==`string`){T(t);return}}T(`An unexpected network error occurred.`)}finally{D(!1)}},I=async t=>{D(!0),T(null);try{if(b.length<8){T(`Administrator password must be at least 8 characters.`);return}if(b!==S){T(`Passwords do not match.`);return}let n=await f(t),i=await a(`/auth/setup/restore`,{method:`POST`,body:JSON.stringify({backup:n,username:r.trim(),password:b,...g.trim()?{display_name:g.trim()}:{}})});if(i.status!==`success`){T(i.message??`Restore failed. Please try again.`);return}c.removeQueries({queryKey:o.session.current}),e(`/login`,{replace:!0})}catch(e){if(e instanceof Error){T(e.message);return}T(`An unexpected network error occurred.`)}finally{D(!1)}},L=e=>{if(j(e),T(null),e===null){N(null);return}f(e).then(async t=>{try{let n=await a(`/auth/setup/inspect`,{method:`POST`,body:JSON.stringify({backup:t})});if(n.status!==`success`){N(null),T(n.message??`Could not read that backup.`);return}N({fileName:e.name,version:n.version??0,exportedAt:n.exportedAt??``,rows:n.rows??[],total:n.total??0,warnings:n.warnings??[]})}catch{N(null)}}).catch(e=>{N(null),T(e instanceof Error?e.message:`That file is not a JSON backup.`)})};return t===!1?(0,h.jsx)(`main`,{className:`auth-viewport`,children:(0,h.jsxs)(`div`,{className:`card-solid auth-window`,children:[(0,h.jsxs)(`div`,{className:`auth-header`,children:[(0,h.jsx)(`div`,{className:`auth-logo`,"aria-hidden":`true`}),(0,h.jsx)(`h1`,{className:`auth-title`,children:`Account Already Registered`}),(0,h.jsx)(`p`,{className:`auth-desc`,children:`This console already has an administrator account, so setup is closed. Sign in with the account that was created.`})]}),(0,h.jsxs)(`div`,{className:`flex flex-col gap-7`,children:[(0,h.jsx)(v,{message:`Setup is already finished. Creating a second administrator is not possible from here.`}),(0,h.jsx)(s,{to:`/login`,className:`no-underline`,children:(0,h.jsx)(i,{variant:`primary`,type:`button`,className:`w-full h-20`,children:`Go to sign in`})})]})]})}):(0,h.jsx)(`main`,{className:`auth-viewport`,children:(0,h.jsxs)(`div`,{className:`card-solid auth-window`,children:[(0,h.jsxs)(`div`,{className:`auth-header`,children:[(0,h.jsx)(`div`,{className:`auth-logo`,"aria-hidden":`true`}),(0,h.jsx)(`h1`,{className:`auth-title`,children:`Cartethyia Console Setup`}),(0,h.jsx)(`p`,{className:`auth-desc`,children:O===`create`?`Configure the administrator account for Cartethyia AI Gateway`:`Restore a backup's configuration. A backup carries no accounts, so set the administrator for this install.`})]}),(0,h.jsxs)(`div`,{className:`flex gap-4 mb-7`,children:[(0,h.jsx)(i,{type:`button`,variant:O===`create`?`primary`:`secondary`,onClick:()=>k(`create`),children:`New account`}),(0,h.jsx)(i,{type:`button`,variant:O===`restore`?`primary`:`secondary`,onClick:()=>k(`restore`),children:`Restore backup`})]}),O===`restore`?(0,h.jsxs)(`div`,{className:`flex flex-col gap-7`,children:[(0,h.jsxs)(`div`,{className:`flex items-center gap-2 min-h-10`,children:[(0,h.jsx)(i,{type:`button`,variant:`secondary`,size:`sm`,onClick:()=>P.current?.click(),disabled:E||t===null,children:`Choose file…`}),(0,h.jsx)(i,{type:`button`,variant:`primary`,size:`sm`,disabled:E||t===null||A===null,onClick:()=>{A&&I(A)},children:E?`Restoring…`:`Restore backup`})]}),(0,h.jsx)(`input`,{ref:P,id:`setup-backup`,type:`file`,accept:`application/json,.json,.gz,application/gzip`,disabled:E,className:`hidden`,onChange:e=>{let t=e.target.files?.[0]??null;L(t),e.target.value=``}}),M?(0,h.jsx)(_,{preview:M}):null,(0,h.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,h.jsx)(`p`,{className:`m-0 text-text-secondary text-caption`,children:`A backup holds no sign-in accounts, so restoring one never restores an administrator. Set the account for this install — the file's own passwords are not reused.`}),(0,h.jsx)(u,{label:`Administrator Username`,id:`restore-username`,value:r,onChange:e=>d(e.target.value),required:!0,autoComplete:`username`}),(0,h.jsx)(u,{label:`Master Password`,hint:`(min. 8 chars)`,id:`restore-password`,type:`password`,required:!0,minLength:8,value:b,onChange:e=>x(e.target.value),autoComplete:`new-password`}),(0,h.jsx)(u,{label:`Confirm Password`,id:`restore-confirm`,type:`password`,required:!0,minLength:8,value:S,onChange:e=>C(e.target.value),autoComplete:`new-password`})]}),w?(0,h.jsx)(v,{message:w}):null]}):(0,h.jsxs)(`form`,{onSubmit:F,className:`flex flex-col gap-7`,children:[(0,h.jsx)(u,{label:`Administrator Username`,id:`setup-username`,value:r,onChange:e=>d(e.target.value),required:!0,autoComplete:`username`,placeholder:`e.g. admin, risun`}),(0,h.jsx)(u,{label:`Display Name`,hint:`(optional)`,id:`display-name`,value:g,onChange:e=>y(e.target.value),autoComplete:`name`,placeholder:`e.g. Administrator, risun`}),(0,h.jsx)(u,{label:`Master Password`,hint:`(min. 8 chars)`,id:`setup-password`,type:`password`,required:!0,minLength:8,value:b,onChange:e=>x(e.target.value),autoComplete:`new-password`}),(0,h.jsx)(u,{label:`Confirm Password`,id:`setup-confirm`,type:`password`,required:!0,minLength:8,value:S,onChange:e=>C(e.target.value),autoComplete:`new-password`}),w?(0,h.jsx)(v,{message:w}):null,(0,h.jsx)(i,{variant:`primary`,type:`submit`,disabled:E||t===null,className:`w-full mt-3 h-20`,icon:(0,h.jsx)(p,{size:15}),children:E?`Initializing…`:`Complete Setup`})]})]})})}function _({preview:e}){let t=e.rows.filter(e=>!e.supported),n=e.rows.filter(e=>e.supported),r=e.exportedAt?e.exportedAt.replace(`T`,` `).slice(0,19):`unknown`;return(0,h.jsxs)(`div`,{className:`flex flex-col gap-2 p-3 border border-inner-border rounded-control bg-surface-2`,children:[(0,h.jsxs)(`div`,{className:`flex items-center flex-wrap gap-1.5`,children:[(0,h.jsx)(`span`,{className:`min-w-0 overflow-hidden whitespace-nowrap text-ellipsis text-body font-semibold`,title:e.fileName,children:e.fileName}),(0,h.jsxs)(`span`,{className:`inline-flex items-center flex-none px-3.5 py-px border border-inner-border rounded-md bg-surface-2 text-text-secondary text-badge tabular-nums`,children:[`v`,e.version]}),t.length>0?(0,h.jsxs)(`span`,{className:`inline-flex items-center flex-none px-3.5 py-px border rounded-md bg-surface-2 text-badge tabular-nums border-warning-line text-status-warning`,children:[t.length,` unsupported`]}):null]}),(0,h.jsxs)(`p`,{className:`m-0 text-text-secondary text-caption`,children:[e.total,` rows across `,e.rows.length,` tables · exported `,r]}),t.length>0?(0,h.jsx)(`p`,{className:`m-0 text-caption text-status-warning`,children:t.length===e.rows.length?`None of these tables exist in this build, so nothing can be restored.`:`This build no longer has some of these tables. The rest still restores.`}):null,e.rows.length===0?(0,h.jsx)(`p`,{className:`m-0 text-text-secondary text-caption`,children:`This backup is empty.`}):(0,h.jsx)(`div`,{className:`max-h-110 overflow-auto`,children:(0,h.jsx)(d,{headers:[`Table`,`Section`,`Rows`],dense:!0,children:[...n,...t].map(e=>(0,h.jsxs)(`tr`,{children:[(0,h.jsx)(`td`,{children:e.table}),(0,h.jsx)(`td`,{children:e.section}),(0,h.jsx)(`td`,{className:`text-right`,children:e.supported?e.count:(0,h.jsx)(`span`,{className:`inline-flex items-center flex-none px-3.5 py-px border rounded-md bg-surface-2 text-badge tabular-nums border-warning-line text-status-warning`,children:`unsupported`})})]},`${e.section}/${e.table}`))})})]})}function v({message:e}){return(0,h.jsx)(`div`,{className:`py-5 px-7 rounded-control bg-red-soft text-red text-caption font-medium`,role:`alert`,children:e})}export{g as default};
@@ -1 +0,0 @@
1
- import{n as e,o as t,r as n,t as r}from"./jsx-runtime-CXUMngI_.js";import{n as i}from"./select-CGUuTQmj.js";import{i as a}from"./toast-DKAdP2mo.js";import{n as o}from"./stack-C1kTcOmP.js";var s=e(`chevron-up`,[[`path`,{d:`m18 15-6-6-6 6`,key:`153udz`}]]),c=e(`grip-vertical`,[[`circle`,{cx:`9`,cy:`12`,r:`1`,key:`1vctgf`}],[`circle`,{cx:`9`,cy:`5`,r:`1`,key:`hp0tcf`}],[`circle`,{cx:`9`,cy:`19`,r:`1`,key:`fkjjf6`}],[`circle`,{cx:`15`,cy:`12`,r:`1`,key:`1tmaij`}],[`circle`,{cx:`15`,cy:`5`,r:`1`,key:`19l28e`}],[`circle`,{cx:`15`,cy:`19`,r:`1`,key:`f4zoj3`}]]),l=t(n(),1),u=r();function d({items:e,onReorder:t,disabled:n=!1,gap:r=`10px`,renderItem:d,label:f}){let[p,m]=(0,l.useState)(null),[h,g]=(0,l.useState)(null),_=(0,l.useRef)(null),v=()=>{_.current=null,m(null),g(null)},y=(n,r)=>{if(n===r)return;let i=e.map(e=>e.id),a=i.indexOf(n),o=i.indexOf(r);a!==-1&&o!==-1&&(i.splice(o,0,...i.splice(a,1)),t(i))};return(0,u.jsx)(`div`,{role:`list`,"aria-label":f,className:a(`flex flex-col min-w-0`,o(r)??`gap-5`),children:e.map((r,o)=>{let l=p===r.id,f=h===r.id&&p!==null&&p!==r.id,b=r=>{let i=o+r;if(n||i<0||i>=e.length)return;let a=e.map(e=>e.id),[s]=a.splice(o,1);s!==void 0&&(a.splice(i,0,s),t(a))};return(0,u.jsxs)(`div`,{role:`listitem`,className:a(`relative flex items-stretch gap-5 min-w-0 rounded-card transition-opacity duration-150 ease-spring`,l&&`opacity-50`,f&&`before:absolute before:inset-x-0 before:top-0 before:h-0.5 before:bg-accent before:content-['']`),"data-dragging":l?`true`:void 0,"data-drop-target":f?`true`:void 0,onDragOver:e=>{n||_.current===null||(e.preventDefault(),e.dataTransfer.dropEffect=`move`,h!==r.id&&g(r.id))},onDrop:e=>{e.preventDefault();let t=_.current;t!==null&&y(t,r.id),v()},children:[(0,u.jsxs)(`div`,{className:`flex flex-none flex-col items-center gap-1 pt-4 text-text-tertiary select-none`,children:[(0,u.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,u.jsx)(`span`,{className:`font-mono text-badge tabular-nums leading-none`,children:o+1}),(0,u.jsx)(`button`,{type:`button`,draggable:!n,"aria-label":`Drag item at position ${o+1} to reorder`,title:`Drag to reorder`,disabled:n,onDragStart:e=>{_.current=r.id,m(r.id),e.dataTransfer.effectAllowed=`move`,e.dataTransfer.setData(`text/plain`,r.id)},onDragEnd:v,className:`grid size-7 cursor-grab place-items-center rounded-control text-text-tertiary hover:bg-hover active:cursor-grabbing disabled:cursor-not-allowed`,children:(0,u.jsx)(c,{size:14})})]}),(0,u.jsxs)(`div`,{className:`flex gap-1`,children:[(0,u.jsx)(`button`,{type:`button`,"aria-label":`Move item ${o+1} up`,title:`Move up`,disabled:n||o===0,onClick:()=>b(-1),className:`grid size-7 place-items-center rounded-control text-text-tertiary hover:bg-hover disabled:cursor-not-allowed disabled:opacity-40`,children:(0,u.jsx)(s,{size:14})}),(0,u.jsx)(`button`,{type:`button`,"aria-label":`Move item ${o+1} down`,title:`Move down`,disabled:n||o===e.length-1,onClick:()=>b(1),className:`grid size-7 place-items-center rounded-control text-text-tertiary hover:bg-hover disabled:cursor-not-allowed disabled:opacity-40`,children:(0,u.jsx)(i,{size:14})})]})]}),(0,u.jsx)(`div`,{className:`flex-auto min-w-0`,children:d(r,o)})]},r.id)})})}export{d as t};