tokenhop 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (599) hide show
  1. package/app/.next-cli-build/BUILD_ID +1 -1
  2. package/app/.next-cli-build/app-path-routes-manifest.json +7 -7
  3. package/app/.next-cli-build/build-manifest.json +3 -3
  4. package/app/.next-cli-build/prerender-manifest.json +3 -3
  5. package/app/.next-cli-build/react-loadable-manifest.json +43 -43
  6. package/app/.next-cli-build/server/app/(dashboard)/dashboard/[...missing]/page.js +1 -1
  7. package/app/.next-cli-build/server/app/(dashboard)/dashboard/[...missing]/page.js.nft.json +1 -1
  8. package/app/.next-cli-build/server/app/(dashboard)/dashboard/[...missing]/page_client-reference-manifest.js +1 -1
  9. package/app/.next-cli-build/server/app/(dashboard)/dashboard/basic-chat/page.js +1 -1
  10. package/app/.next-cli-build/server/app/(dashboard)/dashboard/basic-chat/page.js.nft.json +1 -1
  11. package/app/.next-cli-build/server/app/(dashboard)/dashboard/basic-chat/page_client-reference-manifest.js +1 -1
  12. package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/[toolId]/page.js +1 -1
  13. package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/[toolId]/page.js.nft.json +1 -1
  14. package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/[toolId]/page_client-reference-manifest.js +1 -1
  15. package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/page.js +1 -1
  16. package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/page.js.nft.json +1 -1
  17. package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/page_client-reference-manifest.js +1 -1
  18. package/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/page.js +1 -1
  19. package/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/page.js.nft.json +1 -1
  20. package/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/page_client-reference-manifest.js +1 -1
  21. package/app/.next-cli-build/server/app/(dashboard)/dashboard/console-log/page.js +1 -1
  22. package/app/.next-cli-build/server/app/(dashboard)/dashboard/console-log/page.js.nft.json +1 -1
  23. package/app/.next-cli-build/server/app/(dashboard)/dashboard/console-log/page_client-reference-manifest.js +1 -1
  24. package/app/.next-cli-build/server/app/(dashboard)/dashboard/endpoint/page.js +1 -1
  25. package/app/.next-cli-build/server/app/(dashboard)/dashboard/endpoint/page.js.nft.json +1 -1
  26. package/app/.next-cli-build/server/app/(dashboard)/dashboard/endpoint/page_client-reference-manifest.js +1 -1
  27. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page.js +1 -1
  28. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page.js.nft.json +1 -1
  29. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page_client-reference-manifest.js +1 -1
  30. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/page.js +1 -1
  31. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/page.js.nft.json +1 -1
  32. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/page_client-reference-manifest.js +1 -1
  33. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/combo/[id]/page.js +1 -1
  34. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/combo/[id]/page.js.nft.json +1 -1
  35. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/combo/[id]/page_client-reference-manifest.js +1 -1
  36. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/page.js +1 -1
  37. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/page.js.nft.json +1 -1
  38. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/page_client-reference-manifest.js +1 -1
  39. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/web/page.js +1 -1
  40. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/web/page.js.nft.json +1 -1
  41. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/web/page_client-reference-manifest.js +1 -1
  42. package/app/.next-cli-build/server/app/(dashboard)/dashboard/mitm/page.js +1 -1
  43. package/app/.next-cli-build/server/app/(dashboard)/dashboard/mitm/page.js.nft.json +1 -1
  44. package/app/.next-cli-build/server/app/(dashboard)/dashboard/mitm/page_client-reference-manifest.js +1 -1
  45. package/app/.next-cli-build/server/app/(dashboard)/dashboard/page.js +1 -1
  46. package/app/.next-cli-build/server/app/(dashboard)/dashboard/page.js.nft.json +1 -1
  47. package/app/.next-cli-build/server/app/(dashboard)/dashboard/page_client-reference-manifest.js +1 -1
  48. package/app/.next-cli-build/server/app/(dashboard)/dashboard/profile/page.js +1 -1
  49. package/app/.next-cli-build/server/app/(dashboard)/dashboard/profile/page.js.nft.json +1 -1
  50. package/app/.next-cli-build/server/app/(dashboard)/dashboard/profile/page_client-reference-manifest.js +1 -1
  51. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/[id]/page.js +2 -2
  52. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/[id]/page.js.nft.json +1 -1
  53. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/[id]/page_client-reference-manifest.js +1 -1
  54. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/new/page.js +1 -1
  55. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/new/page.js.nft.json +1 -1
  56. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/new/page_client-reference-manifest.js +1 -1
  57. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/page.js +1 -1
  58. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/page.js.nft.json +1 -1
  59. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/page_client-reference-manifest.js +1 -1
  60. package/app/.next-cli-build/server/app/(dashboard)/dashboard/proxy-pools/page.js +1 -1
  61. package/app/.next-cli-build/server/app/(dashboard)/dashboard/proxy-pools/page.js.nft.json +1 -1
  62. package/app/.next-cli-build/server/app/(dashboard)/dashboard/proxy-pools/page_client-reference-manifest.js +1 -1
  63. package/app/.next-cli-build/server/app/(dashboard)/dashboard/pxpipe/page.js +1 -1
  64. package/app/.next-cli-build/server/app/(dashboard)/dashboard/pxpipe/page.js.nft.json +1 -1
  65. package/app/.next-cli-build/server/app/(dashboard)/dashboard/pxpipe/page_client-reference-manifest.js +1 -1
  66. package/app/.next-cli-build/server/app/(dashboard)/dashboard/quota/page.js +1 -1
  67. package/app/.next-cli-build/server/app/(dashboard)/dashboard/quota/page.js.nft.json +1 -1
  68. package/app/.next-cli-build/server/app/(dashboard)/dashboard/quota/page_client-reference-manifest.js +1 -1
  69. package/app/.next-cli-build/server/app/(dashboard)/dashboard/settings/page.js +1 -1
  70. package/app/.next-cli-build/server/app/(dashboard)/dashboard/settings/page.js.nft.json +1 -1
  71. package/app/.next-cli-build/server/app/(dashboard)/dashboard/settings/page_client-reference-manifest.js +1 -1
  72. package/app/.next-cli-build/server/app/(dashboard)/dashboard/skills/page.js +1 -1
  73. package/app/.next-cli-build/server/app/(dashboard)/dashboard/skills/page.js.nft.json +1 -1
  74. package/app/.next-cli-build/server/app/(dashboard)/dashboard/skills/page_client-reference-manifest.js +1 -1
  75. package/app/.next-cli-build/server/app/(dashboard)/dashboard/token-saver/page.js +1 -1
  76. package/app/.next-cli-build/server/app/(dashboard)/dashboard/token-saver/page.js.nft.json +1 -1
  77. package/app/.next-cli-build/server/app/(dashboard)/dashboard/token-saver/page_client-reference-manifest.js +1 -1
  78. package/app/.next-cli-build/server/app/(dashboard)/dashboard/translator/page.js +1 -1
  79. package/app/.next-cli-build/server/app/(dashboard)/dashboard/translator/page.js.nft.json +1 -1
  80. package/app/.next-cli-build/server/app/(dashboard)/dashboard/translator/page_client-reference-manifest.js +1 -1
  81. package/app/.next-cli-build/server/app/(dashboard)/dashboard/ui-kit/page.js +1 -1
  82. package/app/.next-cli-build/server/app/(dashboard)/dashboard/ui-kit/page.js.nft.json +1 -1
  83. package/app/.next-cli-build/server/app/(dashboard)/dashboard/ui-kit/page_client-reference-manifest.js +1 -1
  84. package/app/.next-cli-build/server/app/(dashboard)/dashboard/usage/page.js +1 -1
  85. package/app/.next-cli-build/server/app/(dashboard)/dashboard/usage/page.js.nft.json +1 -1
  86. package/app/.next-cli-build/server/app/(dashboard)/dashboard/usage/page_client-reference-manifest.js +1 -1
  87. package/app/.next-cli-build/server/app/_global-error/page.js.nft.json +1 -1
  88. package/app/.next-cli-build/server/app/_global-error/page_client-reference-manifest.js +1 -1
  89. package/app/.next-cli-build/server/app/_global-error.html +1 -1
  90. package/app/.next-cli-build/server/app/_global-error.rsc +1 -1
  91. package/app/.next-cli-build/server/app/_global-error.segments/_full.segment.rsc +1 -1
  92. package/app/.next-cli-build/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  93. package/app/.next-cli-build/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  94. package/app/.next-cli-build/server/app/_not-found/page.js +1 -1
  95. package/app/.next-cli-build/server/app/_not-found/page.js.nft.json +1 -1
  96. package/app/.next-cli-build/server/app/_not-found/page_client-reference-manifest.js +1 -1
  97. package/app/.next-cli-build/server/app/_not-found.html +1 -1
  98. package/app/.next-cli-build/server/app/_not-found.rsc +4 -4
  99. package/app/.next-cli-build/server/app/_not-found.segments/_full.segment.rsc +4 -4
  100. package/app/.next-cli-build/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +4 -4
  101. package/app/.next-cli-build/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  102. package/app/.next-cli-build/server/app/api/auth/login/route.js.nft.json +1 -1
  103. package/app/.next-cli-build/server/app/api/auth/logout/route.js.nft.json +1 -1
  104. package/app/.next-cli-build/server/app/api/auth/oidc/callback/route.js.nft.json +1 -1
  105. package/app/.next-cli-build/server/app/api/auth/oidc/start/route.js.nft.json +1 -1
  106. package/app/.next-cli-build/server/app/api/auth/oidc/test/route.js.nft.json +1 -1
  107. package/app/.next-cli-build/server/app/api/auth/reset-password/route.js.nft.json +1 -1
  108. package/app/.next-cli-build/server/app/api/auth/saml/acs/route.js.nft.json +1 -1
  109. package/app/.next-cli-build/server/app/api/auth/saml/metadata/route.js.nft.json +1 -1
  110. package/app/.next-cli-build/server/app/api/auth/saml/start/route.js.nft.json +1 -1
  111. package/app/.next-cli-build/server/app/api/auth/saml/test/route.js.nft.json +1 -1
  112. package/app/.next-cli-build/server/app/api/auth/status/route.js.nft.json +1 -1
  113. package/app/.next-cli-build/server/app/api/cli-tool-settings/[toolId]/route.js.nft.json +1 -1
  114. package/app/.next-cli-build/server/app/api/cli-tool-settings/route.js.nft.json +1 -1
  115. package/app/.next-cli-build/server/app/api/cli-tools/all-statuses/route.js +4 -4
  116. package/app/.next-cli-build/server/app/api/cli-tools/all-statuses/route.js.nft.json +1 -1
  117. package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/alias/route.js +2 -2
  118. package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/alias/route.js.nft.json +1 -1
  119. package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/route.js.nft.json +1 -1
  120. package/app/.next-cli-build/server/app/api/cli-tools/claude-settings/route.js +2 -2
  121. package/app/.next-cli-build/server/app/api/cli-tools/claude-settings/route.js.nft.json +1 -1
  122. package/app/.next-cli-build/server/app/api/cli-tools/cline-settings/route.js +2 -2
  123. package/app/.next-cli-build/server/app/api/cli-tools/cline-settings/route.js.nft.json +1 -1
  124. package/app/.next-cli-build/server/app/api/cli-tools/codex-settings/route.js +2 -2
  125. package/app/.next-cli-build/server/app/api/cli-tools/codex-settings/route.js.nft.json +1 -1
  126. package/app/.next-cli-build/server/app/api/cli-tools/copilot-settings/route.js +2 -2
  127. package/app/.next-cli-build/server/app/api/cli-tools/copilot-settings/route.js.nft.json +1 -1
  128. package/app/.next-cli-build/server/app/api/cli-tools/cowork-mcp-registry/route.js +1 -1
  129. package/app/.next-cli-build/server/app/api/cli-tools/cowork-mcp-registry/route.js.nft.json +1 -1
  130. package/app/.next-cli-build/server/app/api/cli-tools/cowork-mcp-tools/route.js +1 -1
  131. package/app/.next-cli-build/server/app/api/cli-tools/cowork-mcp-tools/route.js.nft.json +1 -1
  132. package/app/.next-cli-build/server/app/api/cli-tools/cowork-settings/route.js +1 -1
  133. package/app/.next-cli-build/server/app/api/cli-tools/cowork-settings/route.js.nft.json +1 -1
  134. package/app/.next-cli-build/server/app/api/cli-tools/deepseek-tui-settings/route.js +3 -3
  135. package/app/.next-cli-build/server/app/api/cli-tools/deepseek-tui-settings/route.js.nft.json +1 -1
  136. package/app/.next-cli-build/server/app/api/cli-tools/devin-settings/route.js +2 -2
  137. package/app/.next-cli-build/server/app/api/cli-tools/devin-settings/route.js.nft.json +1 -1
  138. package/app/.next-cli-build/server/app/api/cli-tools/droid-settings/route.js +1 -1
  139. package/app/.next-cli-build/server/app/api/cli-tools/droid-settings/route.js.nft.json +1 -1
  140. package/app/.next-cli-build/server/app/api/cli-tools/grok-build-settings/route.js +1 -1
  141. package/app/.next-cli-build/server/app/api/cli-tools/grok-build-settings/route.js.nft.json +1 -1
  142. package/app/.next-cli-build/server/app/api/cli-tools/hermes-settings/route.js +3 -3
  143. package/app/.next-cli-build/server/app/api/cli-tools/hermes-settings/route.js.nft.json +1 -1
  144. package/app/.next-cli-build/server/app/api/cli-tools/jcode-settings/route.js +3 -3
  145. package/app/.next-cli-build/server/app/api/cli-tools/jcode-settings/route.js.nft.json +1 -1
  146. package/app/.next-cli-build/server/app/api/cli-tools/kilo-settings/route.js +1 -1
  147. package/app/.next-cli-build/server/app/api/cli-tools/kilo-settings/route.js.nft.json +1 -1
  148. package/app/.next-cli-build/server/app/api/cli-tools/openclaw-settings/route.js +2 -2
  149. package/app/.next-cli-build/server/app/api/cli-tools/openclaw-settings/route.js.nft.json +1 -1
  150. package/app/.next-cli-build/server/app/api/cli-tools/opencode-settings/route.js +2 -2
  151. package/app/.next-cli-build/server/app/api/cli-tools/opencode-settings/route.js.nft.json +1 -1
  152. package/app/.next-cli-build/server/app/api/combos/[id]/headroom/route.js +1 -1
  153. package/app/.next-cli-build/server/app/api/combos/[id]/headroom/route.js.nft.json +1 -1
  154. package/app/.next-cli-build/server/app/api/combos/[id]/route.js +1 -1
  155. package/app/.next-cli-build/server/app/api/combos/[id]/route.js.nft.json +1 -1
  156. package/app/.next-cli-build/server/app/api/combos/[id]/test/route.js +1 -1
  157. package/app/.next-cli-build/server/app/api/combos/[id]/test/route.js.nft.json +1 -1
  158. package/app/.next-cli-build/server/app/api/combos/route.js +1 -1
  159. package/app/.next-cli-build/server/app/api/combos/route.js.nft.json +1 -1
  160. package/app/.next-cli-build/server/app/api/gateway/status/route.js.nft.json +1 -1
  161. package/app/.next-cli-build/server/app/api/headroom/extras/route.js.nft.json +1 -1
  162. package/app/.next-cli-build/server/app/api/headroom/proxy/[...path]/route.js.nft.json +1 -1
  163. package/app/.next-cli-build/server/app/api/headroom/restart/route.js.nft.json +1 -1
  164. package/app/.next-cli-build/server/app/api/headroom/start/route.js.nft.json +1 -1
  165. package/app/.next-cli-build/server/app/api/headroom/status/route.js.nft.json +1 -1
  166. package/app/.next-cli-build/server/app/api/headroom/stop/route.js.nft.json +1 -1
  167. package/app/.next-cli-build/server/app/api/health/route.js.nft.json +1 -1
  168. package/app/.next-cli-build/server/app/api/home/live-routes/route.js.nft.json +1 -1
  169. package/app/.next-cli-build/server/app/api/home/quota/route.js +1 -1
  170. package/app/.next-cli-build/server/app/api/home/quota/route.js.nft.json +1 -1
  171. package/app/.next-cli-build/server/app/api/home/summary/route.js.nft.json +1 -1
  172. package/app/.next-cli-build/server/app/api/init/route.js.nft.json +1 -1
  173. package/app/.next-cli-build/server/app/api/keys/[id]/route.js.nft.json +1 -1
  174. package/app/.next-cli-build/server/app/api/keys/route.js.nft.json +1 -1
  175. package/app/.next-cli-build/server/app/api/locale/route.js.nft.json +1 -1
  176. package/app/.next-cli-build/server/app/api/mcp/[plugin]/message/route.js.nft.json +1 -1
  177. package/app/.next-cli-build/server/app/api/mcp/[plugin]/sse/route.js.nft.json +1 -1
  178. package/app/.next-cli-build/server/app/api/media-providers/tts/deepgram/voices/route.js.nft.json +1 -1
  179. package/app/.next-cli-build/server/app/api/media-providers/tts/elevenlabs/voices/route.js +1 -1
  180. package/app/.next-cli-build/server/app/api/media-providers/tts/elevenlabs/voices/route.js.nft.json +1 -1
  181. package/app/.next-cli-build/server/app/api/media-providers/tts/inworld/voices/route.js.nft.json +1 -1
  182. package/app/.next-cli-build/server/app/api/media-providers/tts/minimax/voices/route.js.nft.json +1 -1
  183. package/app/.next-cli-build/server/app/api/media-providers/tts/voices/route.js +1 -1
  184. package/app/.next-cli-build/server/app/api/media-providers/tts/voices/route.js.nft.json +1 -1
  185. package/app/.next-cli-build/server/app/api/models/alias/route.js +1 -1
  186. package/app/.next-cli-build/server/app/api/models/alias/route.js.nft.json +1 -1
  187. package/app/.next-cli-build/server/app/api/models/availability/route.js.nft.json +1 -1
  188. package/app/.next-cli-build/server/app/api/models/catalog-sync/route.js.nft.json +1 -1
  189. package/app/.next-cli-build/server/app/api/models/custom/route.js +1 -1
  190. package/app/.next-cli-build/server/app/api/models/custom/route.js.nft.json +1 -1
  191. package/app/.next-cli-build/server/app/api/models/disabled/route.js.nft.json +1 -1
  192. package/app/.next-cli-build/server/app/api/models/route.js +1 -1
  193. package/app/.next-cli-build/server/app/api/models/route.js.nft.json +1 -1
  194. package/app/.next-cli-build/server/app/api/models/test/route.js +1 -1
  195. package/app/.next-cli-build/server/app/api/models/test/route.js.nft.json +1 -1
  196. package/app/.next-cli-build/server/app/api/oauth/[provider]/[action]/route.js +1 -1
  197. package/app/.next-cli-build/server/app/api/oauth/[provider]/[action]/route.js.nft.json +1 -1
  198. package/app/.next-cli-build/server/app/api/oauth/codex/bulk-import/route.js +1 -1
  199. package/app/.next-cli-build/server/app/api/oauth/codex/bulk-import/route.js.nft.json +1 -1
  200. package/app/.next-cli-build/server/app/api/oauth/codex/import-token/route.js +1 -1
  201. package/app/.next-cli-build/server/app/api/oauth/codex/import-token/route.js.nft.json +1 -1
  202. package/app/.next-cli-build/server/app/api/oauth/cursor/auto-import/route.js.nft.json +1 -1
  203. package/app/.next-cli-build/server/app/api/oauth/cursor/import/route.js +1 -1
  204. package/app/.next-cli-build/server/app/api/oauth/cursor/import/route.js.nft.json +1 -1
  205. package/app/.next-cli-build/server/app/api/oauth/gitlab/pat/route.js.nft.json +1 -1
  206. package/app/.next-cli-build/server/app/api/oauth/grok-cli/bulk-import/route.js.nft.json +1 -1
  207. package/app/.next-cli-build/server/app/api/oauth/iflow/cookie/route.js.nft.json +1 -1
  208. package/app/.next-cli-build/server/app/api/oauth/kiro/api-key/route.js.nft.json +1 -1
  209. package/app/.next-cli-build/server/app/api/oauth/kiro/auto-import/route.js.nft.json +1 -1
  210. package/app/.next-cli-build/server/app/api/oauth/kiro/import/route.js.nft.json +1 -1
  211. package/app/.next-cli-build/server/app/api/oauth/kiro/import-cli-proxy/route.js.nft.json +1 -1
  212. package/app/.next-cli-build/server/app/api/oauth/kiro/social-authorize/route.js.nft.json +1 -1
  213. package/app/.next-cli-build/server/app/api/oauth/kiro/social-exchange/route.js.nft.json +1 -1
  214. package/app/.next-cli-build/server/app/api/oauth/xiaomi-mimo/api-key/route.js.nft.json +1 -1
  215. package/app/.next-cli-build/server/app/api/oauth/xiaomi-mimo/auto-import/route.js +1 -1
  216. package/app/.next-cli-build/server/app/api/oauth/xiaomi-mimo/auto-import/route.js.nft.json +1 -1
  217. package/app/.next-cli-build/server/app/api/pricing/route.js.nft.json +1 -1
  218. package/app/.next-cli-build/server/app/api/provider-nodes/[id]/route.js.nft.json +1 -1
  219. package/app/.next-cli-build/server/app/api/provider-nodes/route.js +1 -1
  220. package/app/.next-cli-build/server/app/api/provider-nodes/route.js.nft.json +1 -1
  221. package/app/.next-cli-build/server/app/api/provider-nodes/validate/route.js +1 -1
  222. package/app/.next-cli-build/server/app/api/provider-nodes/validate/route.js.nft.json +1 -1
  223. package/app/.next-cli-build/server/app/api/providers/[id]/models/route.js +1 -1
  224. package/app/.next-cli-build/server/app/api/providers/[id]/models/route.js.nft.json +1 -1
  225. package/app/.next-cli-build/server/app/api/providers/[id]/route.js.nft.json +1 -1
  226. package/app/.next-cli-build/server/app/api/providers/[id]/test/route.js +1 -1
  227. package/app/.next-cli-build/server/app/api/providers/[id]/test/route.js.nft.json +1 -1
  228. package/app/.next-cli-build/server/app/api/providers/[id]/test-models/route.js +1 -1
  229. package/app/.next-cli-build/server/app/api/providers/[id]/test-models/route.js.nft.json +1 -1
  230. package/app/.next-cli-build/server/app/api/providers/client/route.js +1 -1
  231. package/app/.next-cli-build/server/app/api/providers/client/route.js.nft.json +1 -1
  232. package/app/.next-cli-build/server/app/api/providers/kilo/free-models/route.js.nft.json +1 -1
  233. package/app/.next-cli-build/server/app/api/providers/route.js +1 -1
  234. package/app/.next-cli-build/server/app/api/providers/route.js.nft.json +1 -1
  235. package/app/.next-cli-build/server/app/api/providers/suggested-models/route.js.nft.json +1 -1
  236. package/app/.next-cli-build/server/app/api/providers/test-batch/route.js +1 -1
  237. package/app/.next-cli-build/server/app/api/providers/test-batch/route.js.nft.json +1 -1
  238. package/app/.next-cli-build/server/app/api/providers/validate/route.js +1 -1
  239. package/app/.next-cli-build/server/app/api/providers/validate/route.js.nft.json +1 -1
  240. package/app/.next-cli-build/server/app/api/proxy-pools/[id]/route.js.nft.json +1 -1
  241. package/app/.next-cli-build/server/app/api/proxy-pools/[id]/test/route.js.nft.json +1 -1
  242. package/app/.next-cli-build/server/app/api/proxy-pools/cloudflare-deploy/route.js.nft.json +1 -1
  243. package/app/.next-cli-build/server/app/api/proxy-pools/deno-deploy/route.js.nft.json +1 -1
  244. package/app/.next-cli-build/server/app/api/proxy-pools/route.js.nft.json +1 -1
  245. package/app/.next-cli-build/server/app/api/proxy-pools/vercel-deploy/route.js.nft.json +1 -1
  246. package/app/.next-cli-build/server/app/api/pxpipe/health/route.js.nft.json +1 -1
  247. package/app/.next-cli-build/server/app/api/pxpipe/install/route.js.nft.json +1 -1
  248. package/app/.next-cli-build/server/app/api/pxpipe/logs/route.js.nft.json +1 -1
  249. package/app/.next-cli-build/server/app/api/pxpipe/restart/route.js.nft.json +1 -1
  250. package/app/.next-cli-build/server/app/api/pxpipe/start/route.js.nft.json +1 -1
  251. package/app/.next-cli-build/server/app/api/pxpipe/stats/route.js.nft.json +1 -1
  252. package/app/.next-cli-build/server/app/api/pxpipe/status/route.js.nft.json +1 -1
  253. package/app/.next-cli-build/server/app/api/pxpipe/stop/route.js.nft.json +1 -1
  254. package/app/.next-cli-build/server/app/api/settings/config/export/route.js.nft.json +1 -1
  255. package/app/.next-cli-build/server/app/api/settings/config/import/route.js +1 -1
  256. package/app/.next-cli-build/server/app/api/settings/config/import/route.js.nft.json +1 -1
  257. package/app/.next-cli-build/server/app/api/settings/database/route.js +1 -1
  258. package/app/.next-cli-build/server/app/api/settings/database/route.js.nft.json +1 -1
  259. package/app/.next-cli-build/server/app/api/settings/environment/route.js.nft.json +1 -1
  260. package/app/.next-cli-build/server/app/api/settings/proxy-test/route.js.nft.json +1 -1
  261. package/app/.next-cli-build/server/app/api/settings/require-login/route.js.nft.json +1 -1
  262. package/app/.next-cli-build/server/app/api/settings/route.js.nft.json +1 -1
  263. package/app/.next-cli-build/server/app/api/shell/savings-milestone/route.js.nft.json +1 -1
  264. package/app/.next-cli-build/server/app/api/shell/summary/route.js +1 -1
  265. package/app/.next-cli-build/server/app/api/shell/summary/route.js.nft.json +1 -1
  266. package/app/.next-cli-build/server/app/api/shutdown/route.js.nft.json +1 -1
  267. package/app/.next-cli-build/server/app/api/tags/route.js.nft.json +1 -1
  268. package/app/.next-cli-build/server/app/api/translator/console-logs/route.js +1 -1
  269. package/app/.next-cli-build/server/app/api/translator/console-logs/route.js.nft.json +1 -1
  270. package/app/.next-cli-build/server/app/api/translator/console-logs/stream/route.js +1 -1
  271. package/app/.next-cli-build/server/app/api/translator/console-logs/stream/route.js.nft.json +1 -1
  272. package/app/.next-cli-build/server/app/api/translator/load/route.js.nft.json +1 -1
  273. package/app/.next-cli-build/server/app/api/translator/save/route.js.nft.json +1 -1
  274. package/app/.next-cli-build/server/app/api/translator/send/route.js +1 -1
  275. package/app/.next-cli-build/server/app/api/translator/send/route.js.nft.json +1 -1
  276. package/app/.next-cli-build/server/app/api/translator/translate/route.js +1 -1
  277. package/app/.next-cli-build/server/app/api/translator/translate/route.js.nft.json +1 -1
  278. package/app/.next-cli-build/server/app/api/tunnel/disable/route.js.nft.json +1 -1
  279. package/app/.next-cli-build/server/app/api/tunnel/enable/route.js.nft.json +1 -1
  280. package/app/.next-cli-build/server/app/api/tunnel/status/route.js.nft.json +1 -1
  281. package/app/.next-cli-build/server/app/api/tunnel/tailscale-check/route.js.nft.json +1 -1
  282. package/app/.next-cli-build/server/app/api/tunnel/tailscale-disable/route.js.nft.json +1 -1
  283. package/app/.next-cli-build/server/app/api/tunnel/tailscale-enable/route.js.nft.json +1 -1
  284. package/app/.next-cli-build/server/app/api/tunnel/tailscale-install/route.js +2 -2
  285. package/app/.next-cli-build/server/app/api/tunnel/tailscale-install/route.js.nft.json +1 -1
  286. package/app/.next-cli-build/server/app/api/usage/[connectionId]/codex-reset-credits/route.js +1 -1
  287. package/app/.next-cli-build/server/app/api/usage/[connectionId]/codex-reset-credits/route.js.nft.json +1 -1
  288. package/app/.next-cli-build/server/app/api/usage/[connectionId]/route.js +1 -1
  289. package/app/.next-cli-build/server/app/api/usage/[connectionId]/route.js.nft.json +1 -1
  290. package/app/.next-cli-build/server/app/api/usage/chart/route.js.nft.json +1 -1
  291. package/app/.next-cli-build/server/app/api/usage/history/route.js.nft.json +1 -1
  292. package/app/.next-cli-build/server/app/api/usage/last-activity/route.js.nft.json +1 -1
  293. package/app/.next-cli-build/server/app/api/usage/logs/route.js.nft.json +1 -1
  294. package/app/.next-cli-build/server/app/api/usage/providers/route.js +1 -1
  295. package/app/.next-cli-build/server/app/api/usage/providers/route.js.nft.json +1 -1
  296. package/app/.next-cli-build/server/app/api/usage/request-details/route.js.nft.json +1 -1
  297. package/app/.next-cli-build/server/app/api/usage/request-logs/route.js.nft.json +1 -1
  298. package/app/.next-cli-build/server/app/api/usage/savings/route.js.nft.json +1 -1
  299. package/app/.next-cli-build/server/app/api/usage/stats/route.js.nft.json +1 -1
  300. package/app/.next-cli-build/server/app/api/usage/stream/route.js.nft.json +1 -1
  301. package/app/.next-cli-build/server/app/api/v1/api/chat/route.js +1 -1
  302. package/app/.next-cli-build/server/app/api/v1/api/chat/route.js.nft.json +1 -1
  303. package/app/.next-cli-build/server/app/api/v1/audio/speech/route.js +1 -1
  304. package/app/.next-cli-build/server/app/api/v1/audio/speech/route.js.nft.json +1 -1
  305. package/app/.next-cli-build/server/app/api/v1/audio/transcriptions/route.js +1 -1
  306. package/app/.next-cli-build/server/app/api/v1/audio/transcriptions/route.js.nft.json +1 -1
  307. package/app/.next-cli-build/server/app/api/v1/audio/voices/route.js +1 -1
  308. package/app/.next-cli-build/server/app/api/v1/audio/voices/route.js.nft.json +1 -1
  309. package/app/.next-cli-build/server/app/api/v1/chat/completions/route.js +1 -1
  310. package/app/.next-cli-build/server/app/api/v1/chat/completions/route.js.nft.json +1 -1
  311. package/app/.next-cli-build/server/app/api/v1/embeddings/route.js +1 -1
  312. package/app/.next-cli-build/server/app/api/v1/embeddings/route.js.nft.json +1 -1
  313. package/app/.next-cli-build/server/app/api/v1/images/generations/route.js +1 -1
  314. package/app/.next-cli-build/server/app/api/v1/images/generations/route.js.nft.json +1 -1
  315. package/app/.next-cli-build/server/app/api/v1/messages/count_tokens/route.js +1 -1
  316. package/app/.next-cli-build/server/app/api/v1/messages/count_tokens/route.js.nft.json +1 -1
  317. package/app/.next-cli-build/server/app/api/v1/messages/route.js +1 -1
  318. package/app/.next-cli-build/server/app/api/v1/messages/route.js.nft.json +1 -1
  319. package/app/.next-cli-build/server/app/api/v1/models/[...model]/route.js +1 -1
  320. package/app/.next-cli-build/server/app/api/v1/models/[...model]/route.js.nft.json +1 -1
  321. package/app/.next-cli-build/server/app/api/v1/models/info/route.js +1 -1
  322. package/app/.next-cli-build/server/app/api/v1/models/info/route.js.nft.json +1 -1
  323. package/app/.next-cli-build/server/app/api/v1/models/route.js +1 -1
  324. package/app/.next-cli-build/server/app/api/v1/models/route.js.nft.json +1 -1
  325. package/app/.next-cli-build/server/app/api/v1/responses/compact/route.js +1 -1
  326. package/app/.next-cli-build/server/app/api/v1/responses/compact/route.js.nft.json +1 -1
  327. package/app/.next-cli-build/server/app/api/v1/responses/route.js +1 -1
  328. package/app/.next-cli-build/server/app/api/v1/responses/route.js.nft.json +1 -1
  329. package/app/.next-cli-build/server/app/api/v1/route.js +1 -1
  330. package/app/.next-cli-build/server/app/api/v1/route.js.nft.json +1 -1
  331. package/app/.next-cli-build/server/app/api/v1/search/route.js +2 -2
  332. package/app/.next-cli-build/server/app/api/v1/search/route.js.nft.json +1 -1
  333. package/app/.next-cli-build/server/app/api/v1/videos/[id]/route.js +1 -1
  334. package/app/.next-cli-build/server/app/api/v1/videos/[id]/route.js.nft.json +1 -1
  335. package/app/.next-cli-build/server/app/api/v1/videos/edits/route.js +1 -1
  336. package/app/.next-cli-build/server/app/api/v1/videos/edits/route.js.nft.json +1 -1
  337. package/app/.next-cli-build/server/app/api/v1/videos/extensions/route.js +1 -1
  338. package/app/.next-cli-build/server/app/api/v1/videos/extensions/route.js.nft.json +1 -1
  339. package/app/.next-cli-build/server/app/api/v1/videos/generations/route.js +1 -1
  340. package/app/.next-cli-build/server/app/api/v1/videos/generations/route.js.nft.json +1 -1
  341. package/app/.next-cli-build/server/app/api/v1/web/fetch/route.js +1 -1
  342. package/app/.next-cli-build/server/app/api/v1/web/fetch/route.js.nft.json +1 -1
  343. package/app/.next-cli-build/server/app/api/v1beta/models/[...path]/route.js +1 -1
  344. package/app/.next-cli-build/server/app/api/v1beta/models/[...path]/route.js.nft.json +1 -1
  345. package/app/.next-cli-build/server/app/api/v1beta/models/route.js +1 -1
  346. package/app/.next-cli-build/server/app/api/v1beta/models/route.js.nft.json +1 -1
  347. package/app/.next-cli-build/server/app/api/version/shutdown/route.js.nft.json +1 -1
  348. package/app/.next-cli-build/server/app/callback/page.js +1 -1
  349. package/app/.next-cli-build/server/app/callback/page.js.nft.json +1 -1
  350. package/app/.next-cli-build/server/app/callback/page_client-reference-manifest.js +1 -1
  351. package/app/.next-cli-build/server/app/callback.html +1 -1
  352. package/app/.next-cli-build/server/app/callback.rsc +4 -4
  353. package/app/.next-cli-build/server/app/callback.segments/_full.segment.rsc +4 -4
  354. package/app/.next-cli-build/server/app/callback.segments/_tree.segment.rsc +1 -1
  355. package/app/.next-cli-build/server/app/callback.segments/callback/__PAGE__.segment.rsc +4 -4
  356. package/app/.next-cli-build/server/app/dashboard/basic-chat.html +2 -2
  357. package/app/.next-cli-build/server/app/dashboard/basic-chat.rsc +10 -10
  358. package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard/basic-chat/__PAGE__.segment.rsc +10 -10
  359. package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_full.segment.rsc +10 -10
  360. package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_tree.segment.rsc +1 -1
  361. package/app/.next-cli-build/server/app/dashboard/combos.html +2 -2
  362. package/app/.next-cli-build/server/app/dashboard/combos.rsc +10 -10
  363. package/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard/combos/__PAGE__.segment.rsc +10 -10
  364. package/app/.next-cli-build/server/app/dashboard/combos.segments/_full.segment.rsc +10 -10
  365. package/app/.next-cli-build/server/app/dashboard/combos.segments/_tree.segment.rsc +1 -1
  366. package/app/.next-cli-build/server/app/dashboard/endpoint.html +1 -1
  367. package/app/.next-cli-build/server/app/dashboard/endpoint.rsc +7 -7
  368. package/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard/endpoint/__PAGE__.segment.rsc +7 -7
  369. package/app/.next-cli-build/server/app/dashboard/endpoint.segments/_full.segment.rsc +7 -7
  370. package/app/.next-cli-build/server/app/dashboard/endpoint.segments/_tree.segment.rsc +1 -1
  371. package/app/.next-cli-build/server/app/dashboard/media-providers/web.html +2 -2
  372. package/app/.next-cli-build/server/app/dashboard/media-providers/web.rsc +10 -10
  373. package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers/web/__PAGE__.segment.rsc +10 -10
  374. package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_full.segment.rsc +10 -10
  375. package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_tree.segment.rsc +1 -1
  376. package/app/.next-cli-build/server/app/dashboard/media-providers.html +1 -1
  377. package/app/.next-cli-build/server/app/dashboard/media-providers.rsc +9 -9
  378. package/app/.next-cli-build/server/app/dashboard/media-providers.segments/!KGRhc2hib2FyZCk/dashboard/media-providers/__PAGE__.segment.rsc +9 -9
  379. package/app/.next-cli-build/server/app/dashboard/media-providers.segments/_full.segment.rsc +9 -9
  380. package/app/.next-cli-build/server/app/dashboard/media-providers.segments/_tree.segment.rsc +1 -1
  381. package/app/.next-cli-build/server/app/dashboard/mitm.html +2 -2
  382. package/app/.next-cli-build/server/app/dashboard/mitm.rsc +10 -10
  383. package/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard/mitm/__PAGE__.segment.rsc +10 -10
  384. package/app/.next-cli-build/server/app/dashboard/mitm.segments/_full.segment.rsc +10 -10
  385. package/app/.next-cli-build/server/app/dashboard/mitm.segments/_tree.segment.rsc +1 -1
  386. package/app/.next-cli-build/server/app/dashboard/profile.html +1 -1
  387. package/app/.next-cli-build/server/app/dashboard/profile.rsc +9 -9
  388. package/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard/profile/__PAGE__.segment.rsc +9 -9
  389. package/app/.next-cli-build/server/app/dashboard/profile.segments/_full.segment.rsc +9 -9
  390. package/app/.next-cli-build/server/app/dashboard/profile.segments/_tree.segment.rsc +1 -1
  391. package/app/.next-cli-build/server/app/dashboard/providers/new.html +2 -2
  392. package/app/.next-cli-build/server/app/dashboard/providers/new.rsc +10 -10
  393. package/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers/new/__PAGE__.segment.rsc +10 -10
  394. package/app/.next-cli-build/server/app/dashboard/providers/new.segments/_full.segment.rsc +10 -10
  395. package/app/.next-cli-build/server/app/dashboard/providers/new.segments/_tree.segment.rsc +1 -1
  396. package/app/.next-cli-build/server/app/dashboard/proxy-pools.html +2 -2
  397. package/app/.next-cli-build/server/app/dashboard/proxy-pools.rsc +9 -9
  398. package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard/proxy-pools/__PAGE__.segment.rsc +9 -9
  399. package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_full.segment.rsc +9 -9
  400. package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_tree.segment.rsc +1 -1
  401. package/app/.next-cli-build/server/app/dashboard/pxpipe.html +2 -2
  402. package/app/.next-cli-build/server/app/dashboard/pxpipe.rsc +9 -9
  403. package/app/.next-cli-build/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk/dashboard/pxpipe/__PAGE__.segment.rsc +9 -9
  404. package/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_full.segment.rsc +9 -9
  405. package/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_tree.segment.rsc +1 -1
  406. package/app/.next-cli-build/server/app/dashboard/quota.html +1 -1
  407. package/app/.next-cli-build/server/app/dashboard/quota.rsc +10 -10
  408. package/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard/quota/__PAGE__.segment.rsc +10 -10
  409. package/app/.next-cli-build/server/app/dashboard/quota.segments/_full.segment.rsc +10 -10
  410. package/app/.next-cli-build/server/app/dashboard/quota.segments/_tree.segment.rsc +1 -1
  411. package/app/.next-cli-build/server/app/dashboard/settings/pricing/page.js +1 -1
  412. package/app/.next-cli-build/server/app/dashboard/settings/pricing/page.js.nft.json +1 -1
  413. package/app/.next-cli-build/server/app/dashboard/settings/pricing/page_client-reference-manifest.js +1 -1
  414. package/app/.next-cli-build/server/app/dashboard/settings/pricing.html +1 -1
  415. package/app/.next-cli-build/server/app/dashboard/settings/pricing.rsc +4 -4
  416. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_full.segment.rsc +4 -4
  417. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_tree.segment.rsc +1 -1
  418. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing/__PAGE__.segment.rsc +4 -4
  419. package/app/.next-cli-build/server/app/dashboard/settings.html +2 -2
  420. package/app/.next-cli-build/server/app/dashboard/settings.rsc +10 -10
  421. package/app/.next-cli-build/server/app/dashboard/settings.segments/!KGRhc2hib2FyZCk/dashboard/settings/__PAGE__.segment.rsc +10 -10
  422. package/app/.next-cli-build/server/app/dashboard/settings.segments/_full.segment.rsc +10 -10
  423. package/app/.next-cli-build/server/app/dashboard/settings.segments/_tree.segment.rsc +1 -1
  424. package/app/.next-cli-build/server/app/dashboard/skills.html +2 -2
  425. package/app/.next-cli-build/server/app/dashboard/skills.rsc +7 -7
  426. package/app/.next-cli-build/server/app/dashboard/skills.segments/!KGRhc2hib2FyZCk/dashboard/skills/__PAGE__.segment.rsc +7 -7
  427. package/app/.next-cli-build/server/app/dashboard/skills.segments/_full.segment.rsc +7 -7
  428. package/app/.next-cli-build/server/app/dashboard/skills.segments/_tree.segment.rsc +1 -1
  429. package/app/.next-cli-build/server/app/dashboard/token-saver.html +1 -1
  430. package/app/.next-cli-build/server/app/dashboard/token-saver.rsc +10 -10
  431. package/app/.next-cli-build/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk/dashboard/token-saver/__PAGE__.segment.rsc +10 -10
  432. package/app/.next-cli-build/server/app/dashboard/token-saver.segments/_full.segment.rsc +10 -10
  433. package/app/.next-cli-build/server/app/dashboard/token-saver.segments/_tree.segment.rsc +1 -1
  434. package/app/.next-cli-build/server/app/dashboard/translator.html +2 -2
  435. package/app/.next-cli-build/server/app/dashboard/translator.rsc +10 -10
  436. package/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard/translator/__PAGE__.segment.rsc +10 -10
  437. package/app/.next-cli-build/server/app/dashboard/translator.segments/_full.segment.rsc +10 -10
  438. package/app/.next-cli-build/server/app/dashboard/translator.segments/_tree.segment.rsc +1 -1
  439. package/app/.next-cli-build/server/app/dashboard/ui-kit.html +1 -1
  440. package/app/.next-cli-build/server/app/dashboard/ui-kit.rsc +9 -9
  441. package/app/.next-cli-build/server/app/dashboard/ui-kit.segments/!KGRhc2hib2FyZCk/dashboard/ui-kit/__PAGE__.segment.rsc +9 -9
  442. package/app/.next-cli-build/server/app/dashboard/ui-kit.segments/_full.segment.rsc +9 -9
  443. package/app/.next-cli-build/server/app/dashboard/ui-kit.segments/_tree.segment.rsc +1 -1
  444. package/app/.next-cli-build/server/app/dashboard/usage.html +1 -1
  445. package/app/.next-cli-build/server/app/dashboard/usage.rsc +10 -10
  446. package/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard/usage/__PAGE__.segment.rsc +10 -10
  447. package/app/.next-cli-build/server/app/dashboard/usage.segments/_full.segment.rsc +10 -10
  448. package/app/.next-cli-build/server/app/dashboard/usage.segments/_tree.segment.rsc +1 -1
  449. package/app/.next-cli-build/server/app/dashboard.html +1 -1
  450. package/app/.next-cli-build/server/app/dashboard.rsc +10 -10
  451. package/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk/dashboard/__PAGE__.segment.rsc +10 -10
  452. package/app/.next-cli-build/server/app/dashboard.segments/_full.segment.rsc +10 -10
  453. package/app/.next-cli-build/server/app/dashboard.segments/_tree.segment.rsc +1 -1
  454. package/app/.next-cli-build/server/app/index.html +1 -1
  455. package/app/.next-cli-build/server/app/index.rsc +4 -4
  456. package/app/.next-cli-build/server/app/index.segments/__PAGE__.segment.rsc +4 -4
  457. package/app/.next-cli-build/server/app/index.segments/_full.segment.rsc +4 -4
  458. package/app/.next-cli-build/server/app/index.segments/_tree.segment.rsc +1 -1
  459. package/app/.next-cli-build/server/app/landing/page.js +1 -1
  460. package/app/.next-cli-build/server/app/landing/page.js.nft.json +1 -1
  461. package/app/.next-cli-build/server/app/landing/page_client-reference-manifest.js +1 -1
  462. package/app/.next-cli-build/server/app/landing.html +1 -1
  463. package/app/.next-cli-build/server/app/landing.rsc +5 -5
  464. package/app/.next-cli-build/server/app/landing.segments/_full.segment.rsc +5 -5
  465. package/app/.next-cli-build/server/app/landing.segments/_tree.segment.rsc +1 -1
  466. package/app/.next-cli-build/server/app/landing.segments/landing/__PAGE__.segment.rsc +5 -5
  467. package/app/.next-cli-build/server/app/login/page.js +1 -1
  468. package/app/.next-cli-build/server/app/login/page.js.nft.json +1 -1
  469. package/app/.next-cli-build/server/app/login/page_client-reference-manifest.js +1 -1
  470. package/app/.next-cli-build/server/app/login.html +1 -1
  471. package/app/.next-cli-build/server/app/login.rsc +4 -4
  472. package/app/.next-cli-build/server/app/login.segments/_full.segment.rsc +4 -4
  473. package/app/.next-cli-build/server/app/login.segments/_tree.segment.rsc +1 -1
  474. package/app/.next-cli-build/server/app/login.segments/login/__PAGE__.segment.rsc +4 -4
  475. package/app/.next-cli-build/server/app/manifest.webmanifest/route.js.nft.json +1 -1
  476. package/app/.next-cli-build/server/app/page.js +1 -1
  477. package/app/.next-cli-build/server/app/page.js.nft.json +1 -1
  478. package/app/.next-cli-build/server/app/page_client-reference-manifest.js +1 -1
  479. package/app/.next-cli-build/server/app/skills/[...slug]/route.js.nft.json +1 -1
  480. package/app/.next-cli-build/server/app-paths-manifest.json +7 -7
  481. package/app/.next-cli-build/server/chunks/1152.js +1 -1
  482. package/app/.next-cli-build/server/chunks/1336.js +1 -1
  483. package/app/.next-cli-build/server/chunks/1432.js +1 -1
  484. package/app/.next-cli-build/server/chunks/1533.js +1 -1
  485. package/app/.next-cli-build/server/chunks/1764.js +1 -1
  486. package/app/.next-cli-build/server/chunks/1854.js +1 -0
  487. package/app/.next-cli-build/server/chunks/2380.js +7 -7
  488. package/app/.next-cli-build/server/chunks/24.js +1 -1
  489. package/app/.next-cli-build/server/chunks/2460.js +1 -1
  490. package/app/.next-cli-build/server/chunks/2592.js +1 -1
  491. package/app/.next-cli-build/server/chunks/318.js +10 -9
  492. package/app/.next-cli-build/server/chunks/3558.js +1 -1
  493. package/app/.next-cli-build/server/chunks/3593.js +1 -1
  494. package/app/.next-cli-build/server/chunks/3676.js +1 -1
  495. package/app/.next-cli-build/server/chunks/368.js +1 -0
  496. package/app/.next-cli-build/server/chunks/3919.js +1 -1
  497. package/app/.next-cli-build/server/chunks/3943.js +1 -1
  498. package/app/.next-cli-build/server/chunks/4037.js +1 -1
  499. package/app/.next-cli-build/server/chunks/4123.js +1 -1
  500. package/app/.next-cli-build/server/chunks/4125.js +1 -1
  501. package/app/.next-cli-build/server/chunks/4199.js +1 -1
  502. package/app/.next-cli-build/server/chunks/4334.js +1 -1
  503. package/app/.next-cli-build/server/chunks/4406.js +2 -2
  504. package/app/.next-cli-build/server/chunks/4521.js +1 -1
  505. package/app/.next-cli-build/server/chunks/4730.js +1 -1
  506. package/app/.next-cli-build/server/chunks/4780.js +1 -1
  507. package/app/.next-cli-build/server/chunks/4903.js +1 -0
  508. package/app/.next-cli-build/server/chunks/5055.js +1 -0
  509. package/app/.next-cli-build/server/chunks/5260.js +1 -0
  510. package/app/.next-cli-build/server/chunks/5335.js +1 -0
  511. package/app/.next-cli-build/server/chunks/5765.js +1 -0
  512. package/app/.next-cli-build/server/chunks/5827.js +1 -0
  513. package/app/.next-cli-build/server/chunks/6000.js +1 -0
  514. package/app/.next-cli-build/server/chunks/620.js +1 -0
  515. package/app/.next-cli-build/server/chunks/6252.js +1 -1
  516. package/app/.next-cli-build/server/chunks/6328.js +1 -0
  517. package/app/.next-cli-build/server/chunks/6403.js +1 -0
  518. package/app/.next-cli-build/server/chunks/6496.js +1 -1
  519. package/app/.next-cli-build/server/chunks/6565.js +1 -0
  520. package/app/.next-cli-build/server/chunks/6734.js +1 -1
  521. package/app/.next-cli-build/server/chunks/7211.js +1 -1
  522. package/app/.next-cli-build/server/chunks/7616.js +1 -1
  523. package/app/.next-cli-build/server/chunks/7716.js +1 -1
  524. package/app/.next-cli-build/server/chunks/7819.js +1 -1
  525. package/app/.next-cli-build/server/chunks/7828.js +1 -1
  526. package/app/.next-cli-build/server/chunks/7901.js +1 -1
  527. package/app/.next-cli-build/server/chunks/8171.js +1 -1
  528. package/app/.next-cli-build/server/chunks/8255.js +1 -1
  529. package/app/.next-cli-build/server/chunks/8372.js +1 -1
  530. package/app/.next-cli-build/server/chunks/8416.js +1 -1
  531. package/app/.next-cli-build/server/chunks/8895.js +12 -12
  532. package/app/.next-cli-build/server/chunks/8988.js +1 -0
  533. package/app/.next-cli-build/server/chunks/9219.js +1 -0
  534. package/app/.next-cli-build/server/chunks/9243.js +1 -0
  535. package/app/.next-cli-build/server/chunks/9326.js +1 -0
  536. package/app/.next-cli-build/server/chunks/9343.js +1 -1
  537. package/app/.next-cli-build/server/chunks/9489.js +3 -0
  538. package/app/.next-cli-build/server/chunks/9578.js +1 -1
  539. package/app/.next-cli-build/server/chunks/9594.js +1 -0
  540. package/app/.next-cli-build/server/chunks/965.js +1 -1
  541. package/app/.next-cli-build/server/chunks/9899.js +1 -1
  542. package/app/.next-cli-build/server/instrumentation.js +1 -1
  543. package/app/.next-cli-build/server/instrumentation.js.nft.json +1 -1
  544. package/app/.next-cli-build/server/middleware-build-manifest.js +1 -1
  545. package/app/.next-cli-build/server/middleware-react-loadable-manifest.js +1 -1
  546. package/app/.next-cli-build/server/middleware.js.nft.json +1 -1
  547. package/app/.next-cli-build/server/pages/404.html +1 -1
  548. package/app/.next-cli-build/server/pages/500.html +1 -1
  549. package/app/.next-cli-build/server/server-reference-manifest.js +1 -1
  550. package/app/.next-cli-build/server/server-reference-manifest.json +1 -1
  551. package/app/.next-cli-build/static/chunks/{198-145d0ed2ec3c54f5.js → 198-0c7f5eadfd257db1.js} +1 -1
  552. package/app/.next-cli-build/static/chunks/{3670-e7a22341025498f8.js → 3670-90f5cd325f460eb5.js} +1 -1
  553. package/app/.next-cli-build/static/chunks/5014-a5d960f4c6bc6297.js +1 -0
  554. package/app/.next-cli-build/static/chunks/{6174.18e2c57e892d721a.js → 6174.f1da2912aec81c15.js} +1 -1
  555. package/app/.next-cli-build/static/chunks/6448-71a8c2ac8d9ecc09.js +1 -0
  556. package/app/.next-cli-build/static/chunks/7899-83edd7bbf1a98c4a.js +1 -0
  557. package/app/.next-cli-build/static/chunks/8105-bdd81b911fed8537.js +1 -0
  558. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/combos/{page-8147ae8fa9c04381.js → page-42bfc760fbea3b96.js} +1 -1
  559. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/console-log/{page-9cbf62f78701882a.js → page-084fc21b1dbae00d.js} +1 -1
  560. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/providers/[id]/{page-5f91e148400a241b.js → page-59ee0b412f972940.js} +3 -3
  561. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/providers/new/{page-dac4ab98fc595054.js → page-de53f51d191eec46.js} +1 -1
  562. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/providers/page-463f9fa33be9426a.js +1 -0
  563. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/translator/{page-06f4e52ee3b63f82.js → page-243d3da0a2c6cbe9.js} +1 -1
  564. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/ui-kit/{page-6c982cc50b6af101.js → page-998f8c5a36dac961.js} +1 -1
  565. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/usage/page-923f864ec0be0fc8.js +1 -0
  566. package/app/.next-cli-build/static/chunks/app/(dashboard)/{layout-dd9d1e49b2f69197.js → layout-96ebd2b46f1f8d39.js} +1 -1
  567. package/app/.next-cli-build/static/chunks/app/landing/{page-02b7bfebd65c41f1.js → page-bcaea5febe1c68c0.js} +1 -1
  568. package/app/.next-cli-build/static/chunks/webpack-8693ccf029e9af63.js +1 -0
  569. package/app/custom-server.js +0 -37
  570. package/app/package.json +1 -1
  571. package/app/src/lib/db/adapters/sqljsAdapter.js +39 -4
  572. package/app/src/lib/oauth/services/xai.js +19 -12
  573. package/app/src/shared/services/quotaAutoPing.js +43 -8
  574. package/app/src/shared/services/quotaSnapshotPoller.js +2 -1
  575. package/app/src/sse/services/backgroundTokenRefresh.js +13 -1
  576. package/package.json +1 -1
  577. package/src/cli/menus/combos.js +3 -1
  578. package/app/.next-cli-build/server/chunks/1026.js +0 -1
  579. package/app/.next-cli-build/server/chunks/2384.js +0 -1
  580. package/app/.next-cli-build/server/chunks/3093.js +0 -1
  581. package/app/.next-cli-build/server/chunks/331.js +0 -1
  582. package/app/.next-cli-build/server/chunks/3414.js +0 -1
  583. package/app/.next-cli-build/server/chunks/3586.js +0 -1
  584. package/app/.next-cli-build/server/chunks/4278.js +0 -1
  585. package/app/.next-cli-build/server/chunks/6158.js +0 -1
  586. package/app/.next-cli-build/server/chunks/6354.js +0 -1
  587. package/app/.next-cli-build/server/chunks/6769.js +0 -1
  588. package/app/.next-cli-build/server/chunks/7261.js +0 -1
  589. package/app/.next-cli-build/server/chunks/8635.js +0 -3
  590. package/app/.next-cli-build/server/chunks/994.js +0 -1
  591. package/app/.next-cli-build/static/chunks/5014-a441cde708542153.js +0 -1
  592. package/app/.next-cli-build/static/chunks/6448-4eabf683083596e6.js +0 -1
  593. package/app/.next-cli-build/static/chunks/7899-e6a70cb9d3684f7f.js +0 -1
  594. package/app/.next-cli-build/static/chunks/8105-5c7e7c73b4bd532d.js +0 -1
  595. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/providers/page-9fadf2c38665c20c.js +0 -1
  596. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/usage/page-7571538830147099.js +0 -1
  597. package/app/.next-cli-build/static/chunks/webpack-187fa25c98ba99f3.js +0 -1
  598. /package/app/.next-cli-build/static/{3Qm_WgU2xvFJ9U_G7SKhT → J4xdfHpBUAMOCO5dsemSj}/_buildManifest.js +0 -0
  599. /package/app/.next-cli-build/static/{3Qm_WgU2xvFJ9U_G7SKhT → J4xdfHpBUAMOCO5dsemSj}/_ssgManifest.js +0 -0
@@ -1 +1 @@
1
- (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[7018],{1620:(e,t,r)=>{"use strict";r.d(t,{D:()=>o});var a=r(12115),n=r(90085);function s(e){let t=window.matchMedia("(prefers-color-scheme: dark)");return t.addEventListener("change",e),()=>t.removeEventListener("change",e)}function l(){return window.matchMedia("(prefers-color-scheme: dark)").matches}function i(){return!1}function o(){let{theme:e,setTheme:t,toggleTheme:r,initTheme:o}=(0,n.A)(),d=(0,a.useSyncExternalStore)(s,l,i);(0,a.useEffect)(()=>{o()},[o]),(0,a.useEffect)(()=>{if("system"!==e)return;let t=window.matchMedia("(prefers-color-scheme: dark)"),r=()=>o();return t.addEventListener("change",r),()=>t.removeEventListener("change",r)},[e,o]);let c="dark"===e||"system"===e&&d;return{theme:e,setTheme:t,toggleTheme:r,isDark:c}}},1934:(e,t,r)=>{"use strict";r.d(t,{v:()=>l});var a=r(12115);let n=e=>{let t,r=new Set,a=(e,a)=>{let n="function"==typeof e?e(t):e;if(!Object.is(n,t)){let e=t;t=(null!=a?a:"object"!=typeof n||null===n)?n:Object.assign({},t,n),r.forEach(r=>r(t,e))}},n=()=>t,s={setState:a,getState:n,getInitialState:()=>l,subscribe:e=>(r.add(e),()=>r.delete(e))},l=t=e(a,n,s);return s},s=e=>{let t=e?n(e):n,r=e=>(function(e,t=e=>e){let r=a.useSyncExternalStore(e.subscribe,a.useCallback(()=>t(e.getState()),[e,t]),a.useCallback(()=>t(e.getInitialState()),[e,t]));return a.useDebugValue(r),r})(t,e);return Object.assign(r,t),r},l=e=>e?s(e):s},4553:(e,t,r)=>{"use strict";r.d(t,{DM:()=>l,Hc:()=>c,qt:()=>o,qx:()=>d});var a=r(35652);let{BRAND_IDS:n,DEFAULT_BRAND_ID:s,ACTIVE_BRAND_ID:l,isActiveBrand:i,BRAND:o,LEGACY:d,ACTIVE:c,UPSTREAM_CLIENT_IDS:m,envName:u,readEnv:x,warnLegacyOnce:h,header:p,legacyHeaderNames:f}=r.n(a)()},4650:(e,t,r)=>{"use strict";async function a(e){if("u">typeof navigator&&navigator?.clipboard?.writeText)try{await navigator.clipboard.writeText(String(e));return}catch{}if("u"<typeof document)throw Error("copyTextToClipboard: clipboard API unavailable");let t=document.createElement("textarea");t.value=String(e),t.style.position="fixed",t.style.opacity="0",document.body.appendChild(t),t.select();let r=!1;try{r=document.execCommand("copy")}finally{document.body.removeChild(t)}if(!r)throw Error("copyTextToClipboard: execCommand('copy') failed")}function n(e,{min:t,max:r}={}){if(""===e||null==e)return e;let a=Number(e);if(!Number.isFinite(a))return e;let s=a;return Number.isFinite(t)&&(s=Math.max(t,s)),Number.isFinite(r)&&(s=Math.min(r,s)),s}function s(e,{min:t,max:r,step:a=1,direction:l}={}){let i=""===e||null==e?NaN:Number(n(e,{min:t,max:r})),o=Number.isFinite(i)?i:Number.isFinite(t)?t:0,d=Math.max(String(a).split(".")[1]?.length??0,String(o).split(".")[1]?.length??0);return n(Number((o+l*a).toFixed(Math.min(d,10))),{min:t,max:r})}function l(e,t,{length:r,rtl:a=!1}={}){if(!Number.isInteger(r)||r<=0)return e;let n=(e%r+r)%r;switch(t){case"ArrowRight":return(n+(a?-1:1)+r)%r;case"ArrowLeft":return(n+(a?1:-1)+r)%r;case"ArrowDown":return(n+1)%r;case"ArrowUp":return(n-1+r)%r;case"Home":return 0;case"End":return r-1;default:return n}}function i(e){return["ArrowRight","ArrowLeft","ArrowDown","ArrowUp","Home","End"].includes(e)}r.d(t,{CD:()=>s,Ck:()=>o,Ec:()=>c,GO:()=>d,Gc:()=>u,JF:()=>i,N:()=>n,V7:()=>m,eM:()=>a,lZ:()=>l,qM:()=>x});let o={primary:"bg-lime text-on-lime border border-transparent shadow-[inset_0_0_0_1px_rgba(0,0,0,0.14)] hover:brightness-95",secondary:"bg-raised text-text border border-line hover:bg-line/60",ghost:"bg-transparent text-text border border-line hover:bg-raised",danger:"bg-err-bg text-err border border-transparent hover:bg-err/15",outline:"bg-transparent text-muted border border-line hover:bg-raised hover:text-text",success:"bg-ok-bg text-ok border border-transparent hover:bg-ok/15"},d={sm:"h-10 px-3 text-sm rounded-lg",md:"h-11 px-4 text-sm rounded-lg",lg:"h-11 px-6 text-sm rounded-lg"},c={sm:"h-9 text-xs",md:"h-9 text-sm",lg:"h-11 text-sm"};function m(e="primary",t="md"){let r=o[e];if(!r)throw Error(`buttonClasses: unknown variant "${e}"`);let a=d[t];if(!a)throw Error(`buttonClasses: unknown size "${t}"`);return`${r} ${a}`}function u(e,{hint:t,error:r}={}){return r?`${e}-error`:t?`${e}-hint`:void 0}function x(e){return null!=e&&!1!==e&&""!==e}},6587:(e,t,r)=>{"use strict";r.d(t,{default:()=>i});var a=r(95155),n=r(14051),s=r.n(n),l=r(31474);function i({icon:e,label:t,"aria-label":r,loading:n=!1,disabled:s=!1,className:o,suffix:d,...c}){return(0,a.jsxs)("button",{...c,type:c.type||"button","aria-label":t??r,disabled:s||n,"aria-busy":n||void 0,className:(0,l.cn)("inline-flex size-10 shrink-0 items-center justify-center rounded-lg border border-line bg-raised text-muted","transition-colors duration-150 hover:bg-line/60 hover:text-text","focus-visible:outline-none focus-visible:shadow-focus","disabled:cursor-not-allowed disabled:opacity-50",o),children:[(0,a.jsx)("span",{className:(0,l.cn)("material-symbols-outlined text-[20px]",n&&"animate-spin"),"aria-hidden":"true",children:n?"progress_activity":e}),d]})}i.propTypes={icon:s().string.isRequired,label:function(e,t,r){return e.label||e["aria-label"]||e["aria-labelledby"]?null:Error(`${r}: provide "label", "aria-label" or "aria-labelledby".`)},"aria-label":s().string,"aria-labelledby":s().string,loading:s().bool,disabled:s().bool,className:s().string,suffix:s().node}},8247:(e,t,r)=>{"use strict";r.d(t,{HY:()=>o,Kw:()=>d});let a={"perplexity-agent":"perplexity","gitlab-duo":"gitlab","vercel-ai-gateway":"vercel","ollama-search":"ollama"};function n(e){return e.startsWith("openai-compatible")?"oai-cc":e.startsWith("anthropic-compatible")?"anthropic-m":""}let s=new Set;function l(e){return e&&"string"==typeof e?e.trim().toLowerCase():""}let i=new Set(["meta-code"]);function o(e){let t=function(e){let t=l(e);if(!t||s.has(t))return"";let r=a[t]||n(t)||t;return s.has(r)?"":r}(e);return t?`/providers/${t}.${i.has(t)?"svg":"webp"}`:null}function d(e){let t=l(e);t&&s.add(t);let r=a[t]||n(t);r&&s.add(r)}},10185:(e,t,r)=>{"use strict";r.d(t,{default:()=>d});var a=r(95155),n=r(14051),s=r.n(n),l=r(12115),i=r(31474),o=r(4650);function d({value:e,copyValue:t,label:r="Copy to clipboard",showCopyButton:n=!0,className:s,...c}){let[m,u]=(0,l.useState)(null),x=(0,l.useRef)(null);(0,l.useEffect)(()=>()=>clearTimeout(x.current),[]);let h=e=>{u(e),clearTimeout(x.current),x.current=setTimeout(()=>u(null),2e3)},p=async()=>{try{await (0,o.eM)(t??e),h("copied")}catch{h("error")}};return(0,a.jsxs)("div",{className:(0,i.cn)("flex h-11 items-center gap-2 rounded-lg border border-line bg-raised ps-3 pe-1.5 transition-colors","focus-within:border-coral focus-within:shadow-focus",s),...c,children:[(0,a.jsx)("code",{title:String(t??e),className:"min-w-0 flex-1 truncate font-mono text-sm text-text",children:e}),n?(0,a.jsx)("button",{type:"button","aria-label":r,onClick:p,className:"inline-flex size-8 shrink-0 items-center justify-center rounded-md text-muted transition-colors hover:bg-line/60 hover:text-text focus-visible:shadow-focus",children:(0,a.jsx)("span",{className:"material-symbols-outlined text-[18px]","aria-hidden":"true",children:"copied"===m?"check":"error"===m?"error":"content_copy"})}):null,n?(0,a.jsx)("span",{"aria-live":"polite",className:"sr-only",children:"copied"===m?"Copied":"error"===m?"Copy failed":""}):null]})}d.propTypes={value:s().oneOfType([s().string,s().number]).isRequired,copyValue:s().string,label:s().string,showCopyButton:s().bool,className:s().string}},19123:(e,t,r)=>{"use strict";r.d(t,{default:()=>i});var a=r(95155),n=r(14051),s=r.n(n),l=r(50770);function i({children:e,variant:t="neutral",size:r="md",dot:n=!1,className:s}){return(0,a.jsxs)("span",{className:`inline-flex items-center gap-1.5 rounded-full font-semibold whitespace-nowrap ${(0,l.S3)(t,r)}${s?` ${s}`:""}`,children:[n&&(0,a.jsx)("span",{"aria-hidden":"true",className:"size-2 rounded-full bg-current"}),e]})}i.propTypes={children:s().node,variant:s().oneOf(l.XY),size:s().oneOf(Object.keys(l.vO)),dot:s().bool,className:s().string}},28745:(e,t,r)=>{"use strict";r.d(t,{vQ:()=>s,UY:()=>d,Nu:()=>l,B2:()=>o,h0:()=>i});var a=r(4553),n=r(41463);let s={name:`${a.Hc.name} Proxy`,description:"AI infrastructure management",version:"1.0.0",build:{channel:n.env.NEXT_PUBLIC_BUILD_CHANNEL||"",sha:n.env.NEXT_PUBLIC_BUILD_SHA||""}},l={changelogUrl:"https://raw.githubusercontent.com/tokenhop/tokenhop/refs/heads/master/CHANGELOG.md"},i={appPort:20128},o={storageKey:"theme",defaultTheme:"dark"},d={maxLines:200,pollIntervalMs:1e3}},31692:(e,t,r)=>{"use strict";r.d(t,{Zr:()=>n});let a=e=>t=>{try{let r=e(t);if(r instanceof Promise)return r;return{then:e=>a(e)(r),catch(e){return this}}}catch(e){return{then(e){return this},catch:t=>a(t)(e)}}},n=(e,t)=>(r,n,s)=>{let l,i={storage:function(e){let t;try{t=e()}catch(e){return}return{getItem:e=>{var r;let a=e=>null===e?null:JSON.parse(e,void 0),n=null!=(r=t.getItem(e))?r:null;return n instanceof Promise?n.then(a):a(n)},setItem:(e,r)=>t.setItem(e,JSON.stringify(r,void 0)),removeItem:e=>t.removeItem(e)}}(()=>window.localStorage),partialize:e=>e,version:0,merge:(e,t)=>({...t,...e}),...t},o=!1,d=0,c=new Set,m=new Set,u=i.storage;if(!u)return e((...e)=>{console.warn(`[zustand persist middleware] Unable to update item '${i.name}', the given storage is currently unavailable.`),r(...e)},n,s);let x=()=>{let e=i.partialize({...n()});return u.setItem(i.name,{state:e,version:i.version})},h=s.setState;s.setState=(e,t)=>(h(e,t),x());let p=e((...e)=>(r(...e),x()),n,s);s.getInitialState=()=>p;let f=()=>{var e,t;if(!u)return;let s=++d;o=!1,c.forEach(e=>{var t;return e(null!=(t=n())?t:p)});let h=(null==(t=i.onRehydrateStorage)?void 0:t.call(i,null!=(e=n())?e:p))||void 0;return a(u.getItem.bind(u))(i.name).then(e=>{if(e)if("number"!=typeof e.version||e.version===i.version)return[!1,e.state];else{if(i.migrate){let t=i.migrate(e.state,e.version);return t instanceof Promise?t.then(e=>[!0,e]):[!0,t]}console.error("State loaded from storage couldn't be migrated since no migrate function was provided")}return[!1,void 0]}).then(e=>{var t;if(s!==d)return;let[a,o]=e;if(r(l=i.merge(o,null!=(t=n())?t:p),!0),a)return x()}).then(()=>{s===d&&(null==h||h(n(),void 0),l=n(),o=!0,m.forEach(e=>e(l)))}).catch(e=>{s===d&&(null==h||h(void 0,e))})};return s.persist={setOptions:e=>{i={...i,...e},e.storage&&(u=e.storage)},clearStorage:()=>{++d,null==u||u.removeItem(i.name)},getOptions:()=>i,rehydrate:()=>f(),hasHydrated:()=>o,onHydrate:e=>(c.add(e),()=>{c.delete(e)}),onFinishHydration:e=>(m.add(e),()=>{m.delete(e)})},i.skipHydration||f(),l||p}},35652:(e,t,r)=>{"use strict";var a,n=r(41463);let s=Object.freeze(["9router","tokenhop"]),l="tokenhop";function i(e,t){if(s.includes(e))return e;let r=s.map(e=>`"${e}"`).join(", ");throw Error(`${t}: unknown brand ${JSON.stringify(e)}; allowed values: ${r}`)}let o=""==(a="tokenhop")?l:i(a,"NEXT_PUBLIC_BRAND"),d=Object.freeze({name:"tokenhop",slug:"tokenhop",envPrefix:"TOKENHOP_",headerPrefix:"x-tokenhop-",jcodeApiKeyEnv:"JCODE_TOKENHOP_API_KEY",defaultApiKey:"sk_tokenhop",dataDirName:"tokenhop",samlIssuerDefault:"urn:tokenhop:sp",mitmCaCommonName:"tokenhop MITM Root CA",mitmCaOrg:"tokenhop",mitmCertFile:"tokenhop-root-ca.crt",pidFile:"tokenhop.pid",autostartLabel:"dev.tokenhop.autostart",autostartDesktopFile:"tokenhop.desktop",autostartVbsFile:"tokenhop.vbs",clientConfigKey:"tokenhop",customModelIdPrefix:"custom:tokenhop-",storageKeyPrefix:"tokenhop.",eventPrefix:"tokenhop:",backupFilePrefix:"tokenhop-backup-",npmPackage:"tokenhop",appPackage:"tokenhop-app",repoSlug:"tokenhop/tokenhop",repoUrl:"https://github.com/tokenhop/tokenhop",imageName:"ghcr.io/tokenhop/tokenhop",websiteUrl:"https://tokenhop.ai",docsUrl:"https://tokenhop.dev",wordmark:"tokenhop",favicon:"/brand/favicon.svg",faviconIco:"/brand/favicon.ico",appIcon192:"/brand/icons/icon-192.svg",appIcon512:"/brand/icons/icon-512.svg",trayIconName:"icon-tokenhop",trayIconTemplate:!0}),c=Object.freeze({names:Object.freeze(["9Router","9router"]),slug:"9router",envPrefixes:Object.freeze(["NINEROUTER_","NINE_ROUTER_"]),headerPrefix:"x-9router-",jcodeApiKeyEnv:"JCODE_9ROUTER_API_KEY",defaultApiKey:"sk_9router",dataDirName:"9router",samlIssuerDefault:"urn:9router:sp",mitmCaCommonName:"9Router MITM Root CA",mitmCaOrg:"9Router",mitmCertFile:"9router-root-ca.crt",pidFile:"9router.pid",autostartLabel:"com.9router.autostart",autostartDesktopFile:"9router.desktop",autostartVbsFile:"9router.vbs",clientConfigKeys:Object.freeze(["9router","9Router"]),customModelIdPrefix:"custom:9Router-",storageKeyPrefix:"9router.",eventPrefix:"9router:",backupFilePrefix:"9router-backup-",npmPackage:"9router",appPackage:"9router-app",repoSlug:"yandy-r/9router",repoUrl:"https://github.com/yandy-r/9router",imageName:"ghcr.io/yandy-r/9router",wordmark:"router",favicon:"/favicon.svg",faviconIco:"/favicon.ico",appIcon192:"/icons/icon-192.svg",appIcon512:"/icons/icon-512.svg",trayIconName:"icon",trayIconTemplate:!1}),m=Object.freeze({kimiPlatform:"9router",clineUserAgentProduct:"9Router",clineClientType:"9router",devinMcpClientName:"9router",coworkMcpClientName:"9router",cursorMcpProvider:"9router",glmMcpClientName:"9router",xaiUserAgent:"grok-cli/9router",xiaomiKeyNamePrefix:"9router-xmd-",githubUserAgent:"9Router",proxyTestUserAgent:"9Router",denoRelayKind:"9router-relay"}),u=new Set(["repoSlug","repoUrl","imageName","websiteUrl","docsUrl"]),x={name:"names",envPrefix:"envPrefixes",clientConfigKey:"clientConfigKeys"},h="tokenhop"===o?d:Object.freeze(Object.fromEntries(Object.keys(d).map(e=>{let t;return[e,u.has(e)?d[e]:Array.isArray(t=c[x[e]||e])?t[0]:t]}))),p=new Set;function f(e,t,r){if("tokenhop"!==o)return!1;let a=`${e}\u0000${t}`;return!p.has(a)&&(p.add(a),console.warn(`[tokenhop] deprecated ${e} "${t}" → use "${r}" (legacy support ends in v2.0.0)`),!0)}let b=/^[A-Z0-9]+(_[A-Z0-9]+)*$/;function g(e){if("string"!=typeof e||!b.test(e))throw Error(`envName: invalid suffix ${JSON.stringify(e)}; expected e.g. "PEER_TOKEN"`);return d.envPrefix+e}let v=/^(?!x-)[a-z0-9]+(-[a-z0-9]+)*$/;function y(e){return h.headerPrefix+function(e,t){if("string"!=typeof e||!v.test(e))throw Error(`${t}: invalid header name ${JSON.stringify(e)}; expected a bare lowercase name like "connection-id"`);return e}(e,"header")}e.exports={BRAND_IDS:s,DEFAULT_BRAND_ID:l,ACTIVE_BRAND_ID:o,isActiveBrand:function(e){return i(e,"isActiveBrand")===o},BRAND:d,LEGACY:c,ACTIVE:h,UPSTREAM_CLIENT_IDS:m,envName:g,readEnv:function(e,t=n.env){let r=g(e);if(void 0!==t[r])return t[r];for(let a of c.envPrefixes){let n=a+e;if(void 0!==t[n])return f("env var",n,r),t[n]}},warnLegacyOnce:f,header:y,legacyHeaderNames:function(e){let t=y(e);return[c.headerPrefix+e].filter(e=>e!==t)}}},38587:(e,t,r)=>{"use strict";r.d(t,{default:()=>l});var a=r(95155),n=r(1620),s=r(31474);function l({className:e,variant:t="default"}){let{isDark:r,toggleTheme:i}=(0,n.D)(),o={default:(0,s.cn)("flex items-center justify-center size-10 rounded-full","text-muted hover:text-text","hover:bg-raised transition-colors"),card:(0,s.cn)("flex items-center justify-center size-11 rounded-full","bg-panel/60 hover:bg-panel","border border-line","backdrop-blur-md shadow-sm hover:shadow-card","text-muted hover:text-coral-ink","transition-all group")};return(0,a.jsx)("button",{onClick:i,className:(0,s.cn)(o[t],e),"aria-label":`Switch to ${r?"light":"dark"} mode`,title:`Switch to ${r?"light":"dark"} mode`,children:(0,a.jsx)("span",{className:(0,s.cn)("material-symbols-outlined text-[22px]","card"===t&&"transition-transform duration-300 group-hover:rotate-12"),children:r?"light_mode":"dark_mode"})})}},42586:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>U});var a=r(95155),n=r(92542),s=r(4553),l=r(98500),i=r.n(l),o=r(12115),d=r(38587),c=r(6587),m=r(48593);let u=[{label:"Features",href:"#features"},{label:"How it Works",href:"#how-it-works"},{label:"Docs",href:"https://github.com/tokenhop/tokenhop#readme",target:"_blank",rel:"noopener noreferrer"},{label:"GitHub",href:"https://github.com/tokenhop/tokenhop",target:"_blank",rel:"noopener noreferrer",external:!0}];function x(){let[e,t]=(0,o.useState)(!1);return(0,o.useEffect)(()=>{if(!e)return;let r=e=>{"Escape"===e.key&&t(!1)};return document.addEventListener("keydown",r),()=>document.removeEventListener("keydown",r)},[e]),(0,a.jsxs)("header",{className:"fixed inset-x-0 top-0 z-50 border-b border-line bg-panel/80 backdrop-blur-md",children:[(0,a.jsxs)("nav",{"aria-label":"Primary",className:"mx-auto flex h-16 max-w-7xl items-center justify-between px-4 sm:px-6",children:[(0,a.jsx)(i(),{href:"/","aria-label":`${s.Hc.name} home`,className:"flex min-h-[44px] items-center gap-3 rounded-lg",children:(0,a.jsx)(m.A,{})}),(0,a.jsx)("div",{className:"hidden items-center gap-1 md:flex",children:u.map(e=>(0,a.jsxs)("a",{href:e.href,target:e.target,rel:e.rel,className:"inline-flex min-h-[44px] items-center gap-1 rounded-lg px-3 text-sm font-medium text-muted transition-colors hover:text-text",children:[e.label,e.external&&(0,a.jsx)("span",{className:"material-symbols-outlined text-[14px]","aria-hidden":"true",children:"open_in_new"})]},e.label))}),(0,a.jsxs)("div",{className:"flex items-center gap-2",children:[(0,a.jsx)(d.default,{className:"min-h-[44px] min-w-[44px]"}),(0,a.jsx)(n.default,{variant:"primary",size:"md",href:"/dashboard",className:"hidden sm:inline-flex",children:"Get started"}),(0,a.jsx)(c.default,{icon:e?"close":"menu",label:e?"Close menu":"Open menu","aria-expanded":e,"aria-controls":"landing-mobile-menu",onClick:()=>t(e=>!e),className:"min-h-[44px] min-w-[44px] md:hidden"})]})]}),e&&(0,a.jsx)("div",{id:"landing-mobile-menu",className:"border-t border-line bg-panel/95 backdrop-blur-md md:hidden",children:(0,a.jsxs)("div",{className:"flex flex-col gap-1 p-4 sm:p-6",children:[u.map(e=>(0,a.jsx)("a",{href:e.href,target:e.target,rel:e.rel,onClick:()=>t(!1),className:"inline-flex min-h-[44px] items-center rounded-lg px-3 text-sm font-medium text-muted transition-colors hover:text-text",children:e.label},e.label)),(0,a.jsx)(n.default,{variant:"primary",size:"md",href:"/dashboard",fullWidth:!0,className:"mt-2",children:"Get started"})]})})]})}var h=r(14051),p=r.n(h),f=r(19123),b=r(10185);function g({endpoint:e="http://localhost:20128/v1"}){return(0,a.jsxs)("section",{className:"relative flex min-h-[90vh] flex-col items-center justify-center overflow-hidden px-4 pt-32 pb-20 sm:px-6",children:[(0,a.jsx)("div",{"aria-hidden":"true",className:"pointer-events-none absolute inset-x-0 top-0 h-[420px] bg-coral-bg [mask-image:radial-gradient(ellipse_60%_100%_at_50%_0%,black,transparent)]"}),(0,a.jsxs)("div",{className:"relative z-10 flex w-full max-w-4xl flex-col items-center gap-8 text-center",children:[(0,a.jsx)(f.default,{variant:"neutral",dot:!0,children:"Open source \xb7 MIT"}),(0,a.jsxs)("h1",{className:"font-display text-[42px] leading-[1.05] font-bold tracking-[-0.02em] text-balance text-text sm:text-5xl md:text-6xl",children:["One endpoint for ",(0,a.jsx)("br",{}),(0,a.jsx)("span",{className:"text-coral",children:"all AI providers"})]}),(0,a.jsx)("p",{className:"mx-auto max-w-2xl text-lg font-light text-muted md:text-xl",children:"AI endpoint proxy with web dashboard - A JavaScript port of CLIProxyAPI. Works seamlessly with Claude Code, OpenAI Codex, Cline, RooCode, and other CLI tools."}),(0,a.jsx)("div",{className:"w-full max-w-md",children:(0,a.jsx)(b.default,{value:e,copyValue:e,label:"Copy endpoint URL"})}),(0,a.jsxs)("div",{className:"flex w-full flex-wrap items-center justify-center gap-4",children:[(0,a.jsx)(n.default,{variant:"primary",size:"md",href:"/dashboard",icon:"rocket_launch",children:"Get started"}),(0,a.jsx)(n.default,{variant:"secondary",size:"md",href:"https://github.com/tokenhop/tokenhop",target:"_blank",rel:"noopener noreferrer",icon:"code",children:"View on GitHub"})]})]})]})}g.propTypes={endpoint:p().string};var v=r(7256),y=r(8247);function k({src:e,providerId:t,alt:r,size:n=32,className:s="",fallbackText:l,fallbackColor:i}){let d=function(e,t){if(t)return(0,y.HY)(t);if(!e)return null;let r=String(e).match(/^\/providers\/([^/]+)\.(?:png|webp|svg)$/i);return r?(0,y.HY)(r[1]):e}(e,t),[c,m]=(0,o.useState)(!1),u=d?.match(/^\/providers\/([^/]+)\.(?:png|webp|svg)$/i)?.[1],x=(0,v.Do)(t??u),h=i??x.color;return!d||c?(0,a.jsx)("span",{role:"img","aria-label":r??t??"provider",className:`inline-flex shrink-0 items-center justify-center rounded-lg font-display font-bold text-white shadow-[inset_0_0_0_1px_rgba(255,255,255,0.14)] ${s}`.trim(),style:{width:n,height:n,backgroundColor:h,fontSize:Math.max(10,Math.floor(.38*n))},children:l??x.monogram}):(0,a.jsx)("img",{src:d,alt:r,width:n,height:n,className:s,loading:"lazy",decoding:"async",onError:()=>{u&&(0,y.Kw)(u),t&&(0,y.Kw)(t),m(!0)}})}k.propTypes={src:p().string,providerId:p().string,alt:p().string,size:p().number,className:p().string,fallbackText:p().string,fallbackColor:p().string};let j=[{id:"claude",name:"Claude Code",image:"/providers/claude.webp"},{id:"codex",name:"OpenAI Codex",image:"/providers/codex.webp"},{id:"cline",name:"Cline",image:"/providers/cline.webp"},{id:"cursor",name:"Cursor",image:"/providers/cursor.webp"}],w=[{id:"openai",name:"OpenAI"},{id:"anthropic",name:"Anthropic"},{id:"gemini",name:"Gemini"},{id:"github",name:"GitHub Copilot"}],N=["M 60 50 C 250 70, 250 180, 360 180","M 60 140 C 250 140, 250 180, 360 180","M 60 210 C 250 210, 250 180, 360 180","M 60 300 C 250 280, 250 180, 360 180"],C=["M 440 180 C 550 180, 550 50, 740 50","M 440 180 C 550 180, 550 130, 740 130","M 440 180 C 550 180, 550 230, 740 230","M 440 180 C 550 180, 550 310, 740 310"],E=e=>e?"border-lime-ink bg-lime-bg text-lime-ink ring-2 ring-lime-ink":"border-line bg-raised text-text";function _(){let[e,t]=(0,o.useState)(0);return(0,o.useEffect)(()=>{let e=window.matchMedia("(prefers-reduced-motion: reduce)"),r=null,a=()=>{clearInterval(r),r=e.matches?null:setInterval(()=>t(e=>(e+1)%w.length),2e3)};return a(),e.addEventListener("change",a),()=>{clearInterval(r),e.removeEventListener("change",a)}},[]),(0,a.jsxs)("div",{className:"w-full max-w-4xl",children:[(0,a.jsxs)("ul",{className:"sr-only",children:[(0,a.jsx)("li",{children:`Requests from Claude Code, OpenAI Codex, Cline and Cursor go to the ${s.Hc.name} hub.`}),(0,a.jsx)("li",{children:"The hub routes each request to OpenAI, Anthropic, Gemini or GitHub Copilot."})]}),(0,a.jsxs)("div",{"aria-hidden":"true",className:"mx-auto flex max-w-md flex-col gap-2 px-4 md:hidden",children:[(0,a.jsx)("div",{className:"grid grid-cols-2 gap-2",children:j.map(e=>(0,a.jsx)("span",{className:"rounded-lg border border-line bg-raised px-3 py-2 text-center text-sm font-medium text-text",children:e.name},e.id))}),(0,a.jsx)("span",{className:"material-symbols-outlined self-center text-[22px] text-subtle","aria-hidden":"true",children:"arrow_downward"}),(0,a.jsx)("span",{className:"rounded-xl border-2 border-coral bg-panel px-4 py-3 text-center font-display text-base font-bold text-text",children:`${s.Hc.name} hub`}),(0,a.jsx)("span",{className:"material-symbols-outlined self-center text-[22px] text-lime-ink","aria-hidden":"true",children:"arrow_downward"}),(0,a.jsx)("div",{className:"grid grid-cols-2 gap-2",children:w.map((t,r)=>(0,a.jsx)("span",{className:`rounded-lg border px-3 py-2 text-center text-sm font-semibold ${E(e===r)}`,children:t.name},t.id))})]}),(0,a.jsxs)("div",{"aria-hidden":"true",className:"relative mt-16 hidden h-[360px] w-full items-center justify-center md:flex",children:[(0,a.jsxs)("div",{className:"relative z-20 flex size-32 flex-col items-center justify-center gap-1 rounded-full border-2 border-coral bg-panel shadow-card",children:[(0,a.jsx)("span",{className:"material-symbols-outlined text-4xl text-coral",children:"hub"}),(0,a.jsx)("span",{className:"text-xs font-bold tracking-widest text-text uppercase",children:`${s.Hc.name}`}),(0,a.jsx)("span",{className:"absolute inset-0 rounded-full border border-coral opacity-40 motion-safe:animate-ping"})]}),(0,a.jsx)("div",{className:"absolute start-0 top-1/2 flex -translate-y-1/2 flex-col gap-7",children:j.map(e=>(0,a.jsx)("div",{className:"flex size-16 items-center justify-center overflow-hidden rounded-2xl border border-line bg-raised p-2",children:(0,a.jsx)(k,{src:e.image,alt:"",size:48,className:"max-h-12 max-w-12 rounded-xl object-contain",fallbackText:e.name.slice(0,2).toUpperCase()})},e.id))}),(0,a.jsxs)("svg",{"aria-hidden":"true",className:"pointer-events-none absolute inset-0 z-10 size-full rtl:-scale-x-100",viewBox:"0 0 896 360",preserveAspectRatio:"none",xmlns:"http://www.w3.org/2000/svg",children:[N.map(e=>(0,a.jsx)("path",{d:e,fill:"none",strokeDasharray:"5 9",strokeWidth:"2",className:"stroke-subtle motion-safe:animate-flow"},e)),C.map((t,r)=>(0,a.jsx)("path",{d:t,fill:"none",strokeDasharray:e===r?"5 9":void 0,strokeWidth:e===r?3:2,className:e===r?"stroke-lime-ink motion-safe:animate-flow":"stroke-line"},t))]}),(0,a.jsx)("div",{className:"absolute end-0 top-0 bottom-0 flex flex-col justify-between py-6",children:w.map((t,r)=>(0,a.jsx)("span",{className:`flex min-w-[140px] items-center justify-center rounded-lg border px-4 py-2 text-xs font-bold transition-colors ${E(e===r)}`,children:t.name},t.id))})]})]})}function I(){return(0,a.jsx)("section",{className:"border-y border-line bg-raised/40 py-24",id:"how-it-works",children:(0,a.jsxs)("div",{className:"mx-auto max-w-7xl px-4 sm:px-6",children:[(0,a.jsxs)("div",{className:"mb-16",children:[(0,a.jsx)("p",{className:"mb-2 text-xs font-semibold tracking-[0.08em] text-subtle uppercase",children:"How it works"}),(0,a.jsx)("h2",{className:"mb-4 font-display text-3xl font-bold tracking-[-0.02em] text-text md:text-4xl",children:`How ${s.Hc.name} works`}),(0,a.jsx)("p",{className:"max-w-xl text-lg text-muted",children:"Data flows seamlessly from your application through our intelligent routing layer to the best provider for the job."})]}),(0,a.jsxs)("div",{className:"relative grid grid-cols-1 gap-8 md:grid-cols-3",children:[(0,a.jsx)("div",{"aria-hidden":"true",className:"absolute top-12 start-[16%] end-[16%] hidden h-[2px] bg-line md:block"}),(0,a.jsxs)("div",{className:"relative flex flex-col gap-6",children:[(0,a.jsx)("div",{className:"z-10 mx-auto flex h-24 w-24 items-center justify-center rounded-2xl border border-line bg-panel shadow-card md:mx-0",children:(0,a.jsx)("span",{className:"material-symbols-outlined text-4xl text-muted","aria-hidden":"true",children:"terminal"})}),(0,a.jsxs)("div",{className:"text-start",children:[(0,a.jsx)("h3",{className:"mb-2 text-xl font-bold text-text",children:"1. CLI & SDKs"}),(0,a.jsx)("p",{className:"text-sm text-muted",children:"Your requests start from your favorite tools or our unified SDK. Just change the base URL."})]})]}),(0,a.jsxs)("div",{className:"relative flex flex-col gap-6 md:items-center md:text-center",children:[(0,a.jsx)("div",{className:"z-10 mx-auto flex h-24 w-24 items-center justify-center rounded-2xl border-2 border-coral bg-panel shadow-card",children:(0,a.jsx)("span",{className:"material-symbols-outlined text-4xl text-coral motion-safe:animate-pulse motion-reduce:animate-none","aria-hidden":"true",children:"hub"})}),(0,a.jsxs)("div",{className:"text-start md:text-center",children:[(0,a.jsx)("h3",{className:"mb-2 text-xl font-bold text-coral",children:`2. ${s.Hc.name} hub`}),(0,a.jsx)("p",{className:"text-sm text-muted",children:"Our engine analyzes the prompt, checks provider health, and routes for lowest latency or cost."})]})]}),(0,a.jsxs)("div",{className:"relative flex flex-col gap-6 md:items-end md:text-end",children:[(0,a.jsx)("div",{className:"z-10 mx-auto flex h-24 w-24 items-center justify-center rounded-2xl border border-line bg-panel shadow-card md:mx-0",children:(0,a.jsx)("span",{className:"material-symbols-outlined text-4xl text-muted","aria-hidden":"true",children:"cloud"})}),(0,a.jsxs)("div",{className:"text-start md:text-end",children:[(0,a.jsx)("h3",{className:"mb-2 text-xl font-bold text-text",children:"3. AI providers"}),(0,a.jsx)("p",{className:"text-sm text-muted",children:"The request is fulfilled by OpenAI, Anthropic, Gemini, or others instantly."})]})]})]})]})})}let A=[{icon:"link",title:"Unified endpoint",desc:"Access all providers via a single standard API URL."},{icon:"bolt",title:"Easy setup",desc:"Get up and running in minutes with one Docker command."},{icon:"shield_with_heart",title:"Model fallback",desc:"Automatically switch providers on failure or high latency."},{icon:"monitoring",title:"Usage tracking",desc:"Detailed analytics and cost monitoring across all models."},{icon:"key",title:"OAuth & API keys",desc:"Securely manage credentials in one vault."},{icon:"cloud_sync",title:"Cloud sync",desc:"Sync your configurations across devices instantly."},{icon:"terminal",title:"CLI support",desc:"Works with Claude Code, Codex, Cline, Cursor, and more."},{icon:"dashboard",title:"Dashboard",desc:"Visual dashboard for real-time traffic analysis."}];function $(){return(0,a.jsx)("section",{className:"px-4 py-24 sm:px-6",id:"features",children:(0,a.jsxs)("div",{className:"mx-auto max-w-7xl",children:[(0,a.jsxs)("div",{className:"mb-16",children:[(0,a.jsx)("p",{className:"mb-2 text-xs font-semibold tracking-[0.08em] text-subtle uppercase",children:"Features"}),(0,a.jsx)("h2",{className:"mb-4 font-display text-3xl font-bold tracking-[-0.02em] text-text md:text-4xl",children:"Powerful features"}),(0,a.jsx)("p",{className:"max-w-xl text-lg text-muted",children:"Everything you need to manage your AI infrastructure in one place, built for scale."})]}),(0,a.jsx)("div",{className:"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4",children:A.map(e=>(0,a.jsxs)("article",{className:"rounded-2xl border border-line bg-panel p-6 shadow-card transition-colors hover:border-coral/40",children:[(0,a.jsx)("div",{className:"mb-4 flex size-10 items-center justify-center rounded-[10px] bg-coral-bg text-coral-ink",children:(0,a.jsx)("span",{className:"material-symbols-outlined text-[20px]","aria-hidden":"true",children:e.icon})}),(0,a.jsx)("h3",{className:"mb-2 text-base font-semibold text-text",children:e.title}),(0,a.jsx)("p",{className:"text-sm leading-relaxed text-muted",children:e.desc})]},e.title))})]})})}let O=`docker run -d -p 20128:20128 -v ~/.${s.Hc.dataDirName}:/app/data -e INITIAL_PASSWORD=change-me ghcr.io/tokenhop/tokenhop`,S=[{title:`Install ${s.Hc.name}`,desc:"Run the Docker image to start the server instantly"},{title:"Open dashboard",desc:"Configure providers and API keys via web interface"},{title:"Route requests",desc:"Point your CLI tools to http://localhost:20128"}],P=[{text:`Starting ${s.Hc.name}...`,tone:"signal-terminal-log"},{text:"Server running on http://localhost:20128",tone:"signal-terminal-info"},{text:"Dashboard: http://localhost:20128/dashboard",tone:"signal-terminal-info"},{text:"Ready to route",tone:"signal-terminal-log"}];function z(){return(0,a.jsx)("section",{className:"px-4 py-24 sm:px-6",id:"get-started",children:(0,a.jsx)("div",{className:"mx-auto max-w-7xl",children:(0,a.jsxs)("div",{className:"flex flex-col items-start gap-16 lg:flex-row",children:[(0,a.jsxs)("div",{className:"flex-1",children:[(0,a.jsx)("p",{className:"mb-2 text-xs font-semibold tracking-[0.08em] text-subtle uppercase",children:"Get started"}),(0,a.jsx)("h2",{className:"mb-6 font-display text-3xl font-bold tracking-[-0.02em] text-text md:text-4xl",children:"Get started in 30 seconds"}),(0,a.jsx)("p",{className:"mb-8 text-lg text-muted",children:`Install ${s.Hc.name}, configure your providers via web dashboard, and start routing AI requests.`}),(0,a.jsx)("ol",{className:"flex list-none flex-col gap-6 p-0",children:S.map((e,t)=>(0,a.jsxs)("li",{className:"flex gap-4",children:[(0,a.jsx)("span",{"aria-hidden":"true",className:"flex size-8 flex-none items-center justify-center rounded-full bg-coral-bg font-semibold text-coral-ink",children:t+1}),(0,a.jsxs)("div",{children:[(0,a.jsx)("h3",{className:"text-lg font-bold text-text",children:e.title}),(0,a.jsx)("p",{className:"mt-1 text-sm text-muted",children:e.desc})]})]},e.title))})]}),(0,a.jsx)("div",{className:"dark w-full min-w-0 flex-1",children:(0,a.jsxs)("div",{className:"signal-terminal overflow-hidden rounded-2xl border border-line shadow-card",children:[(0,a.jsxs)("div",{className:"flex items-center gap-2 border-b border-line px-4 py-3",children:[(0,a.jsxs)("span",{"aria-hidden":"true",className:"flex gap-2",children:[(0,a.jsx)("span",{className:"size-3 rounded-full bg-line"}),(0,a.jsx)("span",{className:"size-3 rounded-full bg-line"}),(0,a.jsx)("span",{className:"size-3 rounded-full bg-line"})]}),(0,a.jsx)("span",{className:"ms-2 font-mono text-xs text-muted",children:"terminal"})]}),(0,a.jsxs)("div",{className:"overflow-x-auto p-6 font-mono text-sm leading-relaxed",children:[(0,a.jsx)(b.default,{value:`$ ${O}`,copyValue:O,label:"Copy install command",className:"mb-6"}),(0,a.jsx)("p",{className:"sr-only",children:`Starting ${s.Hc.name}. Server running on http://localhost:20128. Dashboard at http://localhost:20128/dashboard. Ready to route.`}),(0,a.jsx)("div",{"aria-hidden":"true",className:"mb-6 flex flex-col gap-1",children:P.map(e=>(0,a.jsxs)("span",{className:e.tone,children:[(0,a.jsx)("span",{className:"signal-terminal-time me-2",children:">"}),e.text]},e.text))}),(0,a.jsxs)("p",{className:"mb-2 border-t border-line pt-4 text-xs",children:[(0,a.jsx)("span",{className:"material-symbols-outlined me-1 inline-block align-[-2px] text-[14px]","aria-hidden":"true",children:"edit_note"}),"Configure providers in dashboard or use environment variables"]}),(0,a.jsxs)("p",{className:"text-xs",children:[(0,a.jsx)("span",{className:"signal-terminal-debug",children:"Data location:"}),(0,a.jsx)("br",{}),(0,a.jsx)("span",{className:"signal-terminal-time",children:"macOS/Linux:"})," ",`~/.${s.Hc.dataDirName}/db/data.sqlite`,(0,a.jsx)("br",{}),(0,a.jsx)("span",{className:"signal-terminal-time",children:"Windows:"})," ",`%APPDATA%/${s.Hc.dataDirName}/db/data.sqlite`]})]})]})})]})})})}let H=s.DM===s.qt.slug,D=[{label:"Features",href:"#features"},{label:"Dashboard",href:"/dashboard"},{label:"Changelog",href:"https://github.com/tokenhop/tokenhop",target:"_blank",rel:"noopener noreferrer"}],M=[{label:"Documentation",href:"https://github.com/tokenhop/tokenhop#readme",target:"_blank",rel:"noopener noreferrer"},{label:"GitHub",href:"https://github.com/tokenhop/tokenhop",target:"_blank",rel:"noopener noreferrer"},{label:"Docker",href:"https://github.com/tokenhop/tokenhop/pkgs/container/tokenhop",target:"_blank",rel:"noopener noreferrer"},...H?[{label:"npm",href:`https://www.npmjs.com/package/${s.qt.npmPackage}`,target:"_blank",rel:"noopener noreferrer"}]:[]],R=H?{label:`Based on ${s.qx.names[0]} by decolua`,href:`https://github.com/decolua/${s.qx.slug}`}:null,T=[{label:"MIT License",href:"https://github.com/tokenhop/tokenhop/blob/master/LICENSE",target:"_blank",rel:"noopener noreferrer"}];function L(){return(0,a.jsx)("footer",{className:"border-t border-line bg-raised/30 px-4 pt-16 pb-8 sm:px-6",children:(0,a.jsxs)("div",{className:"mx-auto max-w-7xl",children:[(0,a.jsxs)("div",{className:"mb-16 grid grid-cols-2 gap-8 md:grid-cols-4 lg:grid-cols-5",children:[(0,a.jsxs)("div",{className:"col-span-2 lg:col-span-2",children:[(0,a.jsx)(i(),{href:"/","aria-label":`${s.Hc.name} home`,className:"mb-6 inline-flex min-h-[44px] items-center gap-3 rounded-lg",children:(0,a.jsx)(m.A,{})}),(0,a.jsx)("p",{className:"mb-6 max-w-xs text-sm leading-relaxed text-muted",children:"The unified endpoint for AI generation. Connect, route, and manage your AI providers with ease."}),(0,a.jsx)("div",{className:"flex gap-4",children:(0,a.jsxs)("a",{className:"inline-flex min-h-[44px] min-w-[44px] items-center justify-center rounded-lg text-muted transition-colors hover:text-text focus-visible:shadow-focus",href:"https://github.com/tokenhop/tokenhop",target:"_blank",rel:"noopener noreferrer",children:[(0,a.jsx)("span",{className:"sr-only",children:`${s.Hc.name} on GitHub`}),(0,a.jsx)("span",{className:"material-symbols-outlined text-[20px]","aria-hidden":"true",children:"code"})]})})]}),(0,a.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,a.jsx)("h2",{className:"font-sans text-sm font-semibold text-text",children:"Product"}),D.map(e=>(0,a.jsx)("a",{className:"inline-flex min-h-[44px] items-center text-sm text-muted transition-colors hover:text-coral focus-visible:shadow-focus",href:e.href,target:e.target,rel:e.rel,children:e.label},e.label))]}),(0,a.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,a.jsx)("h2",{className:"font-sans text-sm font-semibold text-text",children:"Resources"}),M.map(e=>(0,a.jsx)("a",{className:"inline-flex min-h-[44px] items-center text-sm text-muted transition-colors hover:text-coral focus-visible:shadow-focus",href:e.href,target:e.target,rel:e.rel,children:e.label},e.label))]}),(0,a.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,a.jsx)("h2",{className:"font-sans text-sm font-semibold text-text",children:"Legal"}),T.map(e=>(0,a.jsx)("a",{className:"inline-flex min-h-[44px] items-center text-sm text-muted transition-colors hover:text-coral focus-visible:shadow-focus",href:e.href,target:e.target,rel:e.rel,children:e.label},e.label))]})]}),(0,a.jsxs)("div",{className:"flex flex-col items-center justify-between gap-4 border-t border-line pt-8 sm:flex-row",children:[(0,a.jsxs)("div",{className:"flex flex-col gap-1",children:[(0,a.jsx)("p",{className:"text-sm text-muted",children:`\xa9 2025 ${s.Hc.name}. All rights reserved.`}),R&&(0,a.jsx)("a",{className:"inline-flex min-h-[44px] items-center text-sm text-muted transition-colors hover:text-text focus-visible:shadow-focus",href:R.href,target:"_blank",rel:"noopener noreferrer",children:R.label})]}),(0,a.jsxs)("div",{className:"flex gap-6",children:[(0,a.jsx)("a",{className:"inline-flex min-h-[44px] items-center text-sm text-muted transition-colors hover:text-text focus-visible:shadow-focus",href:"https://github.com/tokenhop/tokenhop",target:"_blank",rel:"noopener noreferrer",children:"GitHub"}),(0,a.jsx)("a",{className:"inline-flex min-h-[44px] items-center text-sm text-muted transition-colors hover:text-text focus-visible:shadow-focus",href:"https://github.com/tokenhop/tokenhop/pkgs/container/tokenhop",target:"_blank",rel:"noopener noreferrer",children:"Docker"})]})]})]})})}function U(){return(0,a.jsxs)("div",{className:"relative overflow-x-hidden bg-bg font-sans text-text antialiased",children:[(0,a.jsx)("div",{"aria-hidden":"true",className:"landing-grid pointer-events-none fixed inset-0"}),(0,a.jsx)(x,{}),(0,a.jsxs)("main",{className:"relative",children:[(0,a.jsxs)("div",{className:"relative",children:[(0,a.jsx)(g,{}),(0,a.jsx)("div",{className:"flex justify-center pb-20",children:(0,a.jsx)(_,{})})]}),(0,a.jsx)(z,{}),(0,a.jsx)(I,{}),(0,a.jsx)($,{}),(0,a.jsxs)("section",{className:"relative overflow-hidden px-4 py-24 sm:px-6","aria-labelledby":"cta-title",children:[(0,a.jsx)("div",{"aria-hidden":"true",className:"pointer-events-none absolute inset-0 bg-coral-bg [mask-image:radial-gradient(ellipse_70%_100%_at_50%_100%,black,transparent)]"}),(0,a.jsxs)("div",{className:"relative z-10 mx-auto max-w-4xl text-center",children:[(0,a.jsx)("h2",{id:"cta-title",className:"mb-6 font-display text-4xl font-bold tracking-[-0.02em] text-text md:text-5xl",children:"Ready to simplify your AI infrastructure?"}),(0,a.jsx)("p",{className:"mx-auto mb-10 max-w-2xl text-xl text-muted",children:`Join developers who are streamlining their AI integrations with ${s.Hc.name}. Open source and free to start.`}),(0,a.jsxs)("div",{className:"flex flex-col items-center justify-center gap-4 sm:flex-row",children:[(0,a.jsx)(n.default,{variant:"primary",size:"md",href:"/dashboard",className:"w-full sm:w-auto",children:"Start free"}),(0,a.jsx)(n.default,{variant:"secondary",size:"md",href:"https://github.com/tokenhop/tokenhop#readme",target:"_blank",rel:"noopener noreferrer",className:"w-full sm:w-auto",children:"Read documentation"})]})]})]})]}),(0,a.jsx)(L,{})]})}},48593:(e,t,r)=>{"use strict";r.d(t,{A:()=>l});var a=r(12115),n=r(4553),s=r(92466);function l({size:e=36,className:t=""}){return(0,a.createElement)("span",{className:`flex items-center gap-2.5 ${t}`},(0,a.createElement)(s.A,{size:e,decorative:!0}),(0,a.createElement)("span",{className:"font-display font-bold tracking-[-0.02em] text-text",style:{fontSize:22*e/36}},n.Hc.wordmark))}},50770:(e,t,r)=>{"use strict";r.d(t,{PK:()=>h,S3:()=>o,XY:()=>i,lN:()=>d,pN:()=>f,pi:()=>x,r4:()=>u,vE:()=>m,vO:()=>s});let a={connected:"ok",healthy:"ok",active:"ok",ok:"ok",success:"ok",cooldown:"warn",warning:"warn",low:"warn",warn:"warn",error:"err",empty:"err",err:"err",oauth:"info",info:"info","api-key":"brand",brand:"brand",live:"live",disabled:"neutral",off:"neutral",neutral:"neutral"},n={ok:"bg-ok-bg text-ok",warn:"bg-warn-bg text-warn",err:"bg-err-bg text-err",info:"bg-sky-bg text-sky-ink",brand:"bg-coral-bg text-coral-ink",live:"bg-lime-bg text-lime-ink",neutral:"bg-raised text-muted shadow-[inset_0_0_0_1px_var(--signal-line)]"},s={xs:"h-5 px-2 text-[11px]",sm:"h-5 px-2 text-[11px]",md:"h-6 px-2.5 text-xs",lg:"h-7 px-3 text-sm"},l={default:"neutral",primary:"brand",success:"ok",warning:"warn",error:"err"},i=[...new Set([...Object.keys(n),...Object.keys(l),...Object.keys(a)])];function o(e="neutral",t="md"){let r=s[t];if(!r)throw Error(`pillClasses: unknown size "${t}"`);return`${n[function(e){if(n[e])return e;let t=l[e]??a[e];if(!t)throw Error(`resolvePillVariant: unknown variant "${e}"`);return t}(e)]} ${r}`}let d={ok:"bg-ok",warn:"bg-warn",err:"bg-err",live:"bg-lime",info:"bg-sky",brand:"bg-coral",neutral:"bg-subtle"},c=new Set(["unlimited","credits"]);function m(e,t){if(void 0!==t&&!c.has(t))throw Error(`meterVariant: unknown kind "${t}"`);if("number"!=typeof e||!Number.isFinite(e))throw Error(`meterVariant: expected a finite number, got ${e}`);return"unlimited"===t?"live":"credits"===t?"info":e<=20?"err":e<=45?"warn":"ok"}function u(e){if("number"!=typeof e||!Number.isFinite(e))throw Error(`meterValue: expected a finite number, got ${e}`);return Math.min(100,Math.max(0,e))}let x="border-b border-line",h="whitespace-nowrap text-xs font-semibold text-muted",p={LOG:"signal-terminal-log",INFO:"signal-terminal-info",WARN:"signal-terminal-warn",ERROR:"signal-terminal-error",DEBUG:"signal-terminal-debug"};function f(e){let t=p[e];if(!t)throw Error(`terminalLevelClass: unknown level "${e}"`);return t}},90085:(e,t,r)=>{"use strict";r.d(t,{A:()=>i});var a=r(1934),n=r(31692),s=r(28745);function l(e){let t=document.documentElement,r=window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light";"dark"===("system"===e?r:e)?t.classList.add("dark"):t.classList.remove("dark")}let i=(0,a.v)((0,n.Zr)((e,t)=>({theme:s.B2.defaultTheme,setTheme:t=>{e({theme:t}),l(t)},toggleTheme:()=>{let r="dark"===t().theme?"light":"dark";e({theme:r}),l(r)},initTheme:()=>{l(t().theme)}}),{name:s.B2.storageKey}))},92466:(e,t,r)=>{"use strict";r.d(t,{A:()=>l});var a=r(12115),n=r(4553);let s=()=>[(0,a.createElement)("path",{key:"stem",d:"M25 11V41.5C25 48.5 28.8 52 35.5 52H40",fill:"none",stroke:"currentColor",strokeWidth:7.5,strokeLinecap:"round"}),(0,a.createElement)("path",{key:"arc",d:"M14 26.5C22 18.5 34 18 42 24",fill:"none",stroke:"currentColor",strokeWidth:6.5,strokeLinecap:"round"}),(0,a.createElement)("path",{key:"dot",d:"M43 29a6.5 6.5 0 1 0 13 0a6.5 6.5 0 1 0-13 0z",fill:"currentColor"})];function l({size:e=36,decorative:t=!1,className:r="",x:i,y:o}){let d=t?{"aria-hidden":"true"}:{role:"img","aria-label":n.Hc.name};return"number"==typeof i&&"number"==typeof o?function({x:e,y:t,size:r,aria:l}){if(n.DM===n.qx.slug){let s=r/96,i=e+r/2,o=t+r/2;return(0,a.createElement)("g",l,(0,a.createElement)("rect",{x:e,y:t,width:r,height:r,rx:28*s,fill:"var(--signal-coral)"}),(0,a.createElement)("text",{x:i,y:o-2*s,textAnchor:"middle",fill:"var(--signal-on-coral)",fontSize:`${42*s}`,fontWeight:"800",fontFamily:"var(--signal-font-display)"},"9"),(0,a.createElement)("text",{x:i,y:o+22*s,textAnchor:"middle",fill:"var(--signal-on-coral)",fontSize:`${11*s}`,fontWeight:"700",letterSpacing:`${1.1*s}`},n.Hc.wordmark))}return(0,a.createElement)("svg",{...l,x:e,y:t,width:r,height:r,viewBox:"0 0 64 64",color:"var(--signal-text)"},(0,a.createElement)("rect",{width:64,height:64,rx:16,fill:"var(--signal-coral)"}),...s())}({x:i,y:o,size:e,aria:d}):n.DM===n.qx.slug?(0,a.createElement)("span",{...d,className:`-rotate-[8deg] flex items-center justify-center bg-coral font-display font-extrabold text-on-coral shadow-card ${r}`,style:{width:e,height:e,fontSize:22*e/36,borderRadius:11*e/36}},"9"):(0,a.createElement)("svg",{...d,viewBox:"0 0 64 64",width:e,height:e,className:r,focusable:"false"},(0,a.createElement)("rect",{width:64,height:64,rx:16,fill:"var(--signal-coral)"}),...s())}},92542:(e,t,r)=>{"use strict";r.d(t,{default:()=>c});var a=r(95155),n=r(98500),s=r.n(n),l=r(14051),i=r.n(l),o=r(31474),d=r(4650);function c({children:e,variant:t="primary",size:r="md",icon:n,iconRight:l,href:i,disabled:m=!1,loading:u=!1,fullWidth:x=!1,className:h,...p}){let f=(0,o.cn)("inline-flex items-center justify-center gap-2 font-semibold transition-all duration-150 ease-out cursor-pointer","active:scale-[0.97] focus-visible:outline-none focus-visible:shadow-focus","disabled:opacity-50 disabled:cursor-not-allowed disabled:active:scale-100","aria-disabled:opacity-50 aria-disabled:cursor-not-allowed aria-disabled:active:scale-100",(0,d.V7)(t,r),x&&"w-full",h),b=(0,a.jsxs)(a.Fragment,{children:[u?(0,a.jsx)("span",{className:"material-symbols-outlined animate-spin text-[18px]","aria-hidden":"true",children:"progress_activity"}):n?(0,a.jsx)("span",{className:"material-symbols-outlined text-[18px]","aria-hidden":"true",children:n}):null,e,l&&!u&&(0,a.jsx)("span",{className:"material-symbols-outlined text-[18px] rtl:-scale-x-100","aria-hidden":"true",children:l})]});if(i&&!(m||u)){let{type:e,...t}=p;return t.className=f,/^(https?:|mailto:|tel:|#)/.test(i)?(0,a.jsx)("a",{href:i,...t,children:b}):(0,a.jsx)(s(),{href:i,...t,children:b})}return(0,a.jsx)("button",{className:f,disabled:m||u,"aria-busy":u||void 0,...p,children:b})}c.propTypes={children:i().node,variant:i().oneOf(Object.keys(d.Ck)),size:i().oneOf(Object.keys(d.GO)),icon:i().string,iconRight:i().string,href:i().string,disabled:i().bool,loading:i().bool,fullWidth:i().bool,className:i().string}},99013:(e,t,r)=>{Promise.resolve().then(r.bind(r,42586))}},e=>{e.O(0,[1610,2903,8441,3794,7358],()=>e(e.s=99013)),_N_E=e.O()}]);
1
+ (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[7018],{1620:(e,t,r)=>{"use strict";r.d(t,{D:()=>o});var a=r(12115),n=r(90085);function s(e){let t=window.matchMedia("(prefers-color-scheme: dark)");return t.addEventListener("change",e),()=>t.removeEventListener("change",e)}function l(){return window.matchMedia("(prefers-color-scheme: dark)").matches}function i(){return!1}function o(){let{theme:e,setTheme:t,toggleTheme:r,initTheme:o}=(0,n.A)(),d=(0,a.useSyncExternalStore)(s,l,i);(0,a.useEffect)(()=>{o()},[o]),(0,a.useEffect)(()=>{if("system"!==e)return;let t=window.matchMedia("(prefers-color-scheme: dark)"),r=()=>o();return t.addEventListener("change",r),()=>t.removeEventListener("change",r)},[e,o]);let c="dark"===e||"system"===e&&d;return{theme:e,setTheme:t,toggleTheme:r,isDark:c}}},1934:(e,t,r)=>{"use strict";r.d(t,{v:()=>l});var a=r(12115);let n=e=>{let t,r=new Set,a=(e,a)=>{let n="function"==typeof e?e(t):e;if(!Object.is(n,t)){let e=t;t=(null!=a?a:"object"!=typeof n||null===n)?n:Object.assign({},t,n),r.forEach(r=>r(t,e))}},n=()=>t,s={setState:a,getState:n,getInitialState:()=>l,subscribe:e=>(r.add(e),()=>r.delete(e))},l=t=e(a,n,s);return s},s=e=>{let t=e?n(e):n,r=e=>(function(e,t=e=>e){let r=a.useSyncExternalStore(e.subscribe,a.useCallback(()=>t(e.getState()),[e,t]),a.useCallback(()=>t(e.getInitialState()),[e,t]));return a.useDebugValue(r),r})(t,e);return Object.assign(r,t),r},l=e=>e?s(e):s},4553:(e,t,r)=>{"use strict";r.d(t,{DM:()=>l,Hc:()=>c,qt:()=>o,qx:()=>d});var a=r(35652);let{BRAND_IDS:n,DEFAULT_BRAND_ID:s,ACTIVE_BRAND_ID:l,isActiveBrand:i,BRAND:o,LEGACY:d,ACTIVE:c,UPSTREAM_CLIENT_IDS:m,envName:u,readEnv:x,warnLegacyOnce:h,header:p,legacyHeaderNames:f}=r.n(a)()},4650:(e,t,r)=>{"use strict";async function a(e){if("u">typeof navigator&&navigator?.clipboard?.writeText)try{await navigator.clipboard.writeText(String(e));return}catch{}if("u"<typeof document)throw Error("copyTextToClipboard: clipboard API unavailable");let t=document.createElement("textarea");t.value=String(e),t.style.position="fixed",t.style.opacity="0",document.body.appendChild(t),t.select();let r=!1;try{r=document.execCommand("copy")}finally{document.body.removeChild(t)}if(!r)throw Error("copyTextToClipboard: execCommand('copy') failed")}function n(e,{min:t,max:r}={}){if(""===e||null==e)return e;let a=Number(e);if(!Number.isFinite(a))return e;let s=a;return Number.isFinite(t)&&(s=Math.max(t,s)),Number.isFinite(r)&&(s=Math.min(r,s)),s}function s(e,{min:t,max:r,step:a=1,direction:l}={}){let i=""===e||null==e?NaN:Number(n(e,{min:t,max:r})),o=Number.isFinite(i)?i:Number.isFinite(t)?t:0,d=Math.max(String(a).split(".")[1]?.length??0,String(o).split(".")[1]?.length??0);return n(Number((o+l*a).toFixed(Math.min(d,10))),{min:t,max:r})}function l(e,t,{length:r,rtl:a=!1}={}){if(!Number.isInteger(r)||r<=0)return e;let n=(e%r+r)%r;switch(t){case"ArrowRight":return(n+(a?-1:1)+r)%r;case"ArrowLeft":return(n+(a?1:-1)+r)%r;case"ArrowDown":return(n+1)%r;case"ArrowUp":return(n-1+r)%r;case"Home":return 0;case"End":return r-1;default:return n}}function i(e){return["ArrowRight","ArrowLeft","ArrowDown","ArrowUp","Home","End"].includes(e)}r.d(t,{CD:()=>s,Ck:()=>o,Ec:()=>c,GO:()=>d,Gc:()=>u,JF:()=>i,N:()=>n,V7:()=>m,eM:()=>a,lZ:()=>l,qM:()=>x});let o={primary:"bg-lime text-on-lime border border-transparent shadow-[inset_0_0_0_1px_rgba(0,0,0,0.14)] hover:brightness-95",secondary:"bg-raised text-text border border-line hover:bg-line/60",ghost:"bg-transparent text-text border border-line hover:bg-raised",danger:"bg-err-bg text-err border border-transparent hover:bg-err/15",outline:"bg-transparent text-muted border border-line hover:bg-raised hover:text-text",success:"bg-ok-bg text-ok border border-transparent hover:bg-ok/15"},d={sm:"h-10 px-3 text-sm rounded-lg",md:"h-11 px-4 text-sm rounded-lg",lg:"h-11 px-6 text-sm rounded-lg"},c={sm:"h-9 text-xs",md:"h-9 text-sm",lg:"h-11 text-sm"};function m(e="primary",t="md"){let r=o[e];if(!r)throw Error(`buttonClasses: unknown variant "${e}"`);let a=d[t];if(!a)throw Error(`buttonClasses: unknown size "${t}"`);return`${r} ${a}`}function u(e,{hint:t,error:r}={}){return r?`${e}-error`:t?`${e}-hint`:void 0}function x(e){return null!=e&&!1!==e&&""!==e}},6587:(e,t,r)=>{"use strict";r.d(t,{default:()=>i});var a=r(95155),n=r(14051),s=r.n(n),l=r(31474);function i({icon:e,label:t,"aria-label":r,loading:n=!1,disabled:s=!1,className:o,suffix:d,...c}){return(0,a.jsxs)("button",{...c,type:c.type||"button","aria-label":t??r,disabled:s||n,"aria-busy":n||void 0,className:(0,l.cn)("inline-flex size-10 shrink-0 items-center justify-center rounded-lg border border-line bg-raised text-muted","transition-colors duration-150 hover:bg-line/60 hover:text-text","focus-visible:outline-none focus-visible:shadow-focus","disabled:cursor-not-allowed disabled:opacity-50",o),children:[(0,a.jsx)("span",{className:(0,l.cn)("material-symbols-outlined text-[20px]",n&&"animate-spin"),"aria-hidden":"true",children:n?"progress_activity":e}),d]})}i.propTypes={icon:s().string.isRequired,label:function(e,t,r){return e.label||e["aria-label"]||e["aria-labelledby"]?null:Error(`${r}: provide "label", "aria-label" or "aria-labelledby".`)},"aria-label":s().string,"aria-labelledby":s().string,loading:s().bool,disabled:s().bool,className:s().string,suffix:s().node}},8247:(e,t,r)=>{"use strict";r.d(t,{HY:()=>o,Kw:()=>d});let a={"perplexity-agent":"perplexity","gitlab-duo":"gitlab","vercel-ai-gateway":"vercel","ollama-search":"ollama"};function n(e){return e.startsWith("openai-compatible")?"oai-cc":e.startsWith("anthropic-compatible")?"anthropic-m":""}let s=new Set;function l(e){return e&&"string"==typeof e?e.trim().toLowerCase():""}let i=new Set(["meta-code"]);function o(e){let t=function(e){let t=l(e);if(!t||s.has(t))return"";let r=a[t]||n(t)||t;return s.has(r)?"":r}(e);return t?`/providers/${t}.${i.has(t)?"svg":"webp"}`:null}function d(e){let t=l(e);t&&s.add(t);let r=a[t]||n(t);r&&s.add(r)}},10185:(e,t,r)=>{"use strict";r.d(t,{default:()=>d});var a=r(95155),n=r(14051),s=r.n(n),l=r(12115),i=r(31474),o=r(4650);function d({value:e,copyValue:t,label:r="Copy to clipboard",showCopyButton:n=!0,className:s,...c}){let[m,u]=(0,l.useState)(null),x=(0,l.useRef)(null);(0,l.useEffect)(()=>()=>clearTimeout(x.current),[]);let h=e=>{u(e),clearTimeout(x.current),x.current=setTimeout(()=>u(null),2e3)},p=async()=>{try{await (0,o.eM)(t??e),h("copied")}catch{h("error")}};return(0,a.jsxs)("div",{className:(0,i.cn)("flex h-11 items-center gap-2 rounded-lg border border-line bg-raised ps-3 pe-1.5 transition-colors","focus-within:border-coral focus-within:shadow-focus",s),...c,children:[(0,a.jsx)("code",{title:String(t??e),className:"min-w-0 flex-1 truncate font-mono text-sm text-text",children:e}),n?(0,a.jsx)("button",{type:"button","aria-label":r,onClick:p,className:"inline-flex size-8 shrink-0 items-center justify-center rounded-md text-muted transition-colors hover:bg-line/60 hover:text-text focus-visible:shadow-focus",children:(0,a.jsx)("span",{className:"material-symbols-outlined text-[18px]","aria-hidden":"true",children:"copied"===m?"check":"error"===m?"error":"content_copy"})}):null,n?(0,a.jsx)("span",{"aria-live":"polite",className:"sr-only",children:"copied"===m?"Copied":"error"===m?"Copy failed":""}):null]})}d.propTypes={value:s().oneOfType([s().string,s().number]).isRequired,copyValue:s().string,label:s().string,showCopyButton:s().bool,className:s().string}},19123:(e,t,r)=>{"use strict";r.d(t,{default:()=>i});var a=r(95155),n=r(14051),s=r.n(n),l=r(50770);function i({children:e,variant:t="neutral",size:r="md",dot:n=!1,className:s}){return(0,a.jsxs)("span",{className:`inline-flex items-center gap-1.5 rounded-full font-semibold whitespace-nowrap ${(0,l.S3)(t,r)}${s?` ${s}`:""}`,children:[n&&(0,a.jsx)("span",{"aria-hidden":"true",className:"size-2 rounded-full bg-current"}),e]})}i.propTypes={children:s().node,variant:s().oneOf(l.XY),size:s().oneOf(Object.keys(l.vO)),dot:s().bool,className:s().string}},28745:(e,t,r)=>{"use strict";r.d(t,{vQ:()=>s,UY:()=>d,Nu:()=>l,B2:()=>o,h0:()=>i});var a=r(4553),n=r(41463);let s={name:`${a.Hc.name} Proxy`,description:"AI infrastructure management",version:"1.0.1",build:{channel:n.env.NEXT_PUBLIC_BUILD_CHANNEL||"",sha:n.env.NEXT_PUBLIC_BUILD_SHA||""}},l={changelogUrl:"https://raw.githubusercontent.com/tokenhop/tokenhop/refs/heads/master/CHANGELOG.md"},i={appPort:20128},o={storageKey:"theme",defaultTheme:"dark"},d={maxLines:200,pollIntervalMs:1e3}},31692:(e,t,r)=>{"use strict";r.d(t,{Zr:()=>n});let a=e=>t=>{try{let r=e(t);if(r instanceof Promise)return r;return{then:e=>a(e)(r),catch(e){return this}}}catch(e){return{then(e){return this},catch:t=>a(t)(e)}}},n=(e,t)=>(r,n,s)=>{let l,i={storage:function(e){let t;try{t=e()}catch(e){return}return{getItem:e=>{var r;let a=e=>null===e?null:JSON.parse(e,void 0),n=null!=(r=t.getItem(e))?r:null;return n instanceof Promise?n.then(a):a(n)},setItem:(e,r)=>t.setItem(e,JSON.stringify(r,void 0)),removeItem:e=>t.removeItem(e)}}(()=>window.localStorage),partialize:e=>e,version:0,merge:(e,t)=>({...t,...e}),...t},o=!1,d=0,c=new Set,m=new Set,u=i.storage;if(!u)return e((...e)=>{console.warn(`[zustand persist middleware] Unable to update item '${i.name}', the given storage is currently unavailable.`),r(...e)},n,s);let x=()=>{let e=i.partialize({...n()});return u.setItem(i.name,{state:e,version:i.version})},h=s.setState;s.setState=(e,t)=>(h(e,t),x());let p=e((...e)=>(r(...e),x()),n,s);s.getInitialState=()=>p;let f=()=>{var e,t;if(!u)return;let s=++d;o=!1,c.forEach(e=>{var t;return e(null!=(t=n())?t:p)});let h=(null==(t=i.onRehydrateStorage)?void 0:t.call(i,null!=(e=n())?e:p))||void 0;return a(u.getItem.bind(u))(i.name).then(e=>{if(e)if("number"!=typeof e.version||e.version===i.version)return[!1,e.state];else{if(i.migrate){let t=i.migrate(e.state,e.version);return t instanceof Promise?t.then(e=>[!0,e]):[!0,t]}console.error("State loaded from storage couldn't be migrated since no migrate function was provided")}return[!1,void 0]}).then(e=>{var t;if(s!==d)return;let[a,o]=e;if(r(l=i.merge(o,null!=(t=n())?t:p),!0),a)return x()}).then(()=>{s===d&&(null==h||h(n(),void 0),l=n(),o=!0,m.forEach(e=>e(l)))}).catch(e=>{s===d&&(null==h||h(void 0,e))})};return s.persist={setOptions:e=>{i={...i,...e},e.storage&&(u=e.storage)},clearStorage:()=>{++d,null==u||u.removeItem(i.name)},getOptions:()=>i,rehydrate:()=>f(),hasHydrated:()=>o,onHydrate:e=>(c.add(e),()=>{c.delete(e)}),onFinishHydration:e=>(m.add(e),()=>{m.delete(e)})},i.skipHydration||f(),l||p}},35652:(e,t,r)=>{"use strict";var a,n=r(41463);let s=Object.freeze(["9router","tokenhop"]),l="tokenhop";function i(e,t){if(s.includes(e))return e;let r=s.map(e=>`"${e}"`).join(", ");throw Error(`${t}: unknown brand ${JSON.stringify(e)}; allowed values: ${r}`)}let o=""==(a="tokenhop")?l:i(a,"NEXT_PUBLIC_BRAND"),d=Object.freeze({name:"tokenhop",slug:"tokenhop",envPrefix:"TOKENHOP_",headerPrefix:"x-tokenhop-",jcodeApiKeyEnv:"JCODE_TOKENHOP_API_KEY",defaultApiKey:"sk_tokenhop",dataDirName:"tokenhop",samlIssuerDefault:"urn:tokenhop:sp",mitmCaCommonName:"tokenhop MITM Root CA",mitmCaOrg:"tokenhop",mitmCertFile:"tokenhop-root-ca.crt",pidFile:"tokenhop.pid",autostartLabel:"dev.tokenhop.autostart",autostartDesktopFile:"tokenhop.desktop",autostartVbsFile:"tokenhop.vbs",clientConfigKey:"tokenhop",customModelIdPrefix:"custom:tokenhop-",storageKeyPrefix:"tokenhop.",eventPrefix:"tokenhop:",backupFilePrefix:"tokenhop-backup-",npmPackage:"tokenhop",appPackage:"tokenhop-app",repoSlug:"tokenhop/tokenhop",repoUrl:"https://github.com/tokenhop/tokenhop",imageName:"ghcr.io/tokenhop/tokenhop",websiteUrl:"https://tokenhop.ai",docsUrl:"https://tokenhop.dev",wordmark:"tokenhop",favicon:"/brand/favicon.svg",faviconIco:"/brand/favicon.ico",appIcon192:"/brand/icons/icon-192.svg",appIcon512:"/brand/icons/icon-512.svg",trayIconName:"icon-tokenhop",trayIconTemplate:!0}),c=Object.freeze({names:Object.freeze(["9Router","9router"]),slug:"9router",envPrefixes:Object.freeze(["NINEROUTER_","NINE_ROUTER_"]),headerPrefix:"x-9router-",jcodeApiKeyEnv:"JCODE_9ROUTER_API_KEY",defaultApiKey:"sk_9router",dataDirName:"9router",samlIssuerDefault:"urn:9router:sp",mitmCaCommonName:"9Router MITM Root CA",mitmCaOrg:"9Router",mitmCertFile:"9router-root-ca.crt",pidFile:"9router.pid",autostartLabel:"com.9router.autostart",autostartDesktopFile:"9router.desktop",autostartVbsFile:"9router.vbs",clientConfigKeys:Object.freeze(["9router","9Router"]),customModelIdPrefix:"custom:9Router-",storageKeyPrefix:"9router.",eventPrefix:"9router:",backupFilePrefix:"9router-backup-",npmPackage:"9router",appPackage:"9router-app",repoSlug:"yandy-r/9router",repoUrl:"https://github.com/yandy-r/9router",imageName:"ghcr.io/yandy-r/9router",wordmark:"router",favicon:"/favicon.svg",faviconIco:"/favicon.ico",appIcon192:"/icons/icon-192.svg",appIcon512:"/icons/icon-512.svg",trayIconName:"icon",trayIconTemplate:!1}),m=Object.freeze({kimiPlatform:"9router",clineUserAgentProduct:"9Router",clineClientType:"9router",devinMcpClientName:"9router",coworkMcpClientName:"9router",cursorMcpProvider:"9router",glmMcpClientName:"9router",xaiUserAgent:"grok-cli/9router",xiaomiKeyNamePrefix:"9router-xmd-",githubUserAgent:"9Router",proxyTestUserAgent:"9Router",denoRelayKind:"9router-relay"}),u=new Set(["repoSlug","repoUrl","imageName","websiteUrl","docsUrl"]),x={name:"names",envPrefix:"envPrefixes",clientConfigKey:"clientConfigKeys"},h="tokenhop"===o?d:Object.freeze(Object.fromEntries(Object.keys(d).map(e=>{let t;return[e,u.has(e)?d[e]:Array.isArray(t=c[x[e]||e])?t[0]:t]}))),p=new Set;function f(e,t,r){if("tokenhop"!==o)return!1;let a=`${e}\u0000${t}`;return!p.has(a)&&(p.add(a),console.warn(`[tokenhop] deprecated ${e} "${t}" → use "${r}" (legacy support ends in v2.0.0)`),!0)}let b=/^[A-Z0-9]+(_[A-Z0-9]+)*$/;function g(e){if("string"!=typeof e||!b.test(e))throw Error(`envName: invalid suffix ${JSON.stringify(e)}; expected e.g. "PEER_TOKEN"`);return d.envPrefix+e}let v=/^(?!x-)[a-z0-9]+(-[a-z0-9]+)*$/;function y(e){return h.headerPrefix+function(e,t){if("string"!=typeof e||!v.test(e))throw Error(`${t}: invalid header name ${JSON.stringify(e)}; expected a bare lowercase name like "connection-id"`);return e}(e,"header")}e.exports={BRAND_IDS:s,DEFAULT_BRAND_ID:l,ACTIVE_BRAND_ID:o,isActiveBrand:function(e){return i(e,"isActiveBrand")===o},BRAND:d,LEGACY:c,ACTIVE:h,UPSTREAM_CLIENT_IDS:m,envName:g,readEnv:function(e,t=n.env){let r=g(e);if(void 0!==t[r])return t[r];for(let a of c.envPrefixes){let n=a+e;if(void 0!==t[n])return f("env var",n,r),t[n]}},warnLegacyOnce:f,header:y,legacyHeaderNames:function(e){let t=y(e);return[c.headerPrefix+e].filter(e=>e!==t)}}},38587:(e,t,r)=>{"use strict";r.d(t,{default:()=>l});var a=r(95155),n=r(1620),s=r(31474);function l({className:e,variant:t="default"}){let{isDark:r,toggleTheme:i}=(0,n.D)(),o={default:(0,s.cn)("flex items-center justify-center size-10 rounded-full","text-muted hover:text-text","hover:bg-raised transition-colors"),card:(0,s.cn)("flex items-center justify-center size-11 rounded-full","bg-panel/60 hover:bg-panel","border border-line","backdrop-blur-md shadow-sm hover:shadow-card","text-muted hover:text-coral-ink","transition-all group")};return(0,a.jsx)("button",{onClick:i,className:(0,s.cn)(o[t],e),"aria-label":`Switch to ${r?"light":"dark"} mode`,title:`Switch to ${r?"light":"dark"} mode`,children:(0,a.jsx)("span",{className:(0,s.cn)("material-symbols-outlined text-[22px]","card"===t&&"transition-transform duration-300 group-hover:rotate-12"),children:r?"light_mode":"dark_mode"})})}},42586:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>U});var a=r(95155),n=r(92542),s=r(4553),l=r(98500),i=r.n(l),o=r(12115),d=r(38587),c=r(6587),m=r(48593);let u=[{label:"Features",href:"#features"},{label:"How it Works",href:"#how-it-works"},{label:"Docs",href:"https://github.com/tokenhop/tokenhop#readme",target:"_blank",rel:"noopener noreferrer"},{label:"GitHub",href:"https://github.com/tokenhop/tokenhop",target:"_blank",rel:"noopener noreferrer",external:!0}];function x(){let[e,t]=(0,o.useState)(!1);return(0,o.useEffect)(()=>{if(!e)return;let r=e=>{"Escape"===e.key&&t(!1)};return document.addEventListener("keydown",r),()=>document.removeEventListener("keydown",r)},[e]),(0,a.jsxs)("header",{className:"fixed inset-x-0 top-0 z-50 border-b border-line bg-panel/80 backdrop-blur-md",children:[(0,a.jsxs)("nav",{"aria-label":"Primary",className:"mx-auto flex h-16 max-w-7xl items-center justify-between px-4 sm:px-6",children:[(0,a.jsx)(i(),{href:"/","aria-label":`${s.Hc.name} home`,className:"flex min-h-[44px] items-center gap-3 rounded-lg",children:(0,a.jsx)(m.A,{})}),(0,a.jsx)("div",{className:"hidden items-center gap-1 md:flex",children:u.map(e=>(0,a.jsxs)("a",{href:e.href,target:e.target,rel:e.rel,className:"inline-flex min-h-[44px] items-center gap-1 rounded-lg px-3 text-sm font-medium text-muted transition-colors hover:text-text",children:[e.label,e.external&&(0,a.jsx)("span",{className:"material-symbols-outlined text-[14px]","aria-hidden":"true",children:"open_in_new"})]},e.label))}),(0,a.jsxs)("div",{className:"flex items-center gap-2",children:[(0,a.jsx)(d.default,{className:"min-h-[44px] min-w-[44px]"}),(0,a.jsx)(n.default,{variant:"primary",size:"md",href:"/dashboard",className:"hidden sm:inline-flex",children:"Get started"}),(0,a.jsx)(c.default,{icon:e?"close":"menu",label:e?"Close menu":"Open menu","aria-expanded":e,"aria-controls":"landing-mobile-menu",onClick:()=>t(e=>!e),className:"min-h-[44px] min-w-[44px] md:hidden"})]})]}),e&&(0,a.jsx)("div",{id:"landing-mobile-menu",className:"border-t border-line bg-panel/95 backdrop-blur-md md:hidden",children:(0,a.jsxs)("div",{className:"flex flex-col gap-1 p-4 sm:p-6",children:[u.map(e=>(0,a.jsx)("a",{href:e.href,target:e.target,rel:e.rel,onClick:()=>t(!1),className:"inline-flex min-h-[44px] items-center rounded-lg px-3 text-sm font-medium text-muted transition-colors hover:text-text",children:e.label},e.label)),(0,a.jsx)(n.default,{variant:"primary",size:"md",href:"/dashboard",fullWidth:!0,className:"mt-2",children:"Get started"})]})})]})}var h=r(14051),p=r.n(h),f=r(19123),b=r(10185);function g({endpoint:e="http://localhost:20128/v1"}){return(0,a.jsxs)("section",{className:"relative flex min-h-[90vh] flex-col items-center justify-center overflow-hidden px-4 pt-32 pb-20 sm:px-6",children:[(0,a.jsx)("div",{"aria-hidden":"true",className:"pointer-events-none absolute inset-x-0 top-0 h-[420px] bg-coral-bg [mask-image:radial-gradient(ellipse_60%_100%_at_50%_0%,black,transparent)]"}),(0,a.jsxs)("div",{className:"relative z-10 flex w-full max-w-4xl flex-col items-center gap-8 text-center",children:[(0,a.jsx)(f.default,{variant:"neutral",dot:!0,children:"Open source \xb7 MIT"}),(0,a.jsxs)("h1",{className:"font-display text-[42px] leading-[1.05] font-bold tracking-[-0.02em] text-balance text-text sm:text-5xl md:text-6xl",children:["One endpoint for ",(0,a.jsx)("br",{}),(0,a.jsx)("span",{className:"text-coral",children:"all AI providers"})]}),(0,a.jsx)("p",{className:"mx-auto max-w-2xl text-lg font-light text-muted md:text-xl",children:"AI endpoint proxy with web dashboard - A JavaScript port of CLIProxyAPI. Works seamlessly with Claude Code, OpenAI Codex, Cline, RooCode, and other CLI tools."}),(0,a.jsx)("div",{className:"w-full max-w-md",children:(0,a.jsx)(b.default,{value:e,copyValue:e,label:"Copy endpoint URL"})}),(0,a.jsxs)("div",{className:"flex w-full flex-wrap items-center justify-center gap-4",children:[(0,a.jsx)(n.default,{variant:"primary",size:"md",href:"/dashboard",icon:"rocket_launch",children:"Get started"}),(0,a.jsx)(n.default,{variant:"secondary",size:"md",href:"https://github.com/tokenhop/tokenhop",target:"_blank",rel:"noopener noreferrer",icon:"code",children:"View on GitHub"})]})]})]})}g.propTypes={endpoint:p().string};var v=r(7256),y=r(8247);function k({src:e,providerId:t,alt:r,size:n=32,className:s="",fallbackText:l,fallbackColor:i}){let d=function(e,t){if(t)return(0,y.HY)(t);if(!e)return null;let r=String(e).match(/^\/providers\/([^/]+)\.(?:png|webp|svg)$/i);return r?(0,y.HY)(r[1]):e}(e,t),[c,m]=(0,o.useState)(!1),u=d?.match(/^\/providers\/([^/]+)\.(?:png|webp|svg)$/i)?.[1],x=(0,v.Do)(t??u),h=i??x.color;return!d||c?(0,a.jsx)("span",{role:"img","aria-label":r??t??"provider",className:`inline-flex shrink-0 items-center justify-center rounded-lg font-display font-bold text-white shadow-[inset_0_0_0_1px_rgba(255,255,255,0.14)] ${s}`.trim(),style:{width:n,height:n,backgroundColor:h,fontSize:Math.max(10,Math.floor(.38*n))},children:l??x.monogram}):(0,a.jsx)("img",{src:d,alt:r,width:n,height:n,className:s,loading:"lazy",decoding:"async",onError:()=>{u&&(0,y.Kw)(u),t&&(0,y.Kw)(t),m(!0)}})}k.propTypes={src:p().string,providerId:p().string,alt:p().string,size:p().number,className:p().string,fallbackText:p().string,fallbackColor:p().string};let j=[{id:"claude",name:"Claude Code",image:"/providers/claude.webp"},{id:"codex",name:"OpenAI Codex",image:"/providers/codex.webp"},{id:"cline",name:"Cline",image:"/providers/cline.webp"},{id:"cursor",name:"Cursor",image:"/providers/cursor.webp"}],w=[{id:"openai",name:"OpenAI"},{id:"anthropic",name:"Anthropic"},{id:"gemini",name:"Gemini"},{id:"github",name:"GitHub Copilot"}],N=["M 60 50 C 250 70, 250 180, 360 180","M 60 140 C 250 140, 250 180, 360 180","M 60 210 C 250 210, 250 180, 360 180","M 60 300 C 250 280, 250 180, 360 180"],C=["M 440 180 C 550 180, 550 50, 740 50","M 440 180 C 550 180, 550 130, 740 130","M 440 180 C 550 180, 550 230, 740 230","M 440 180 C 550 180, 550 310, 740 310"],E=e=>e?"border-lime-ink bg-lime-bg text-lime-ink ring-2 ring-lime-ink":"border-line bg-raised text-text";function _(){let[e,t]=(0,o.useState)(0);return(0,o.useEffect)(()=>{let e=window.matchMedia("(prefers-reduced-motion: reduce)"),r=null,a=()=>{clearInterval(r),r=e.matches?null:setInterval(()=>t(e=>(e+1)%w.length),2e3)};return a(),e.addEventListener("change",a),()=>{clearInterval(r),e.removeEventListener("change",a)}},[]),(0,a.jsxs)("div",{className:"w-full max-w-4xl",children:[(0,a.jsxs)("ul",{className:"sr-only",children:[(0,a.jsx)("li",{children:`Requests from Claude Code, OpenAI Codex, Cline and Cursor go to the ${s.Hc.name} hub.`}),(0,a.jsx)("li",{children:"The hub routes each request to OpenAI, Anthropic, Gemini or GitHub Copilot."})]}),(0,a.jsxs)("div",{"aria-hidden":"true",className:"mx-auto flex max-w-md flex-col gap-2 px-4 md:hidden",children:[(0,a.jsx)("div",{className:"grid grid-cols-2 gap-2",children:j.map(e=>(0,a.jsx)("span",{className:"rounded-lg border border-line bg-raised px-3 py-2 text-center text-sm font-medium text-text",children:e.name},e.id))}),(0,a.jsx)("span",{className:"material-symbols-outlined self-center text-[22px] text-subtle","aria-hidden":"true",children:"arrow_downward"}),(0,a.jsx)("span",{className:"rounded-xl border-2 border-coral bg-panel px-4 py-3 text-center font-display text-base font-bold text-text",children:`${s.Hc.name} hub`}),(0,a.jsx)("span",{className:"material-symbols-outlined self-center text-[22px] text-lime-ink","aria-hidden":"true",children:"arrow_downward"}),(0,a.jsx)("div",{className:"grid grid-cols-2 gap-2",children:w.map((t,r)=>(0,a.jsx)("span",{className:`rounded-lg border px-3 py-2 text-center text-sm font-semibold ${E(e===r)}`,children:t.name},t.id))})]}),(0,a.jsxs)("div",{"aria-hidden":"true",className:"relative mt-16 hidden h-[360px] w-full items-center justify-center md:flex",children:[(0,a.jsxs)("div",{className:"relative z-20 flex size-32 flex-col items-center justify-center gap-1 rounded-full border-2 border-coral bg-panel shadow-card",children:[(0,a.jsx)("span",{className:"material-symbols-outlined text-4xl text-coral",children:"hub"}),(0,a.jsx)("span",{className:"text-xs font-bold tracking-widest text-text uppercase",children:`${s.Hc.name}`}),(0,a.jsx)("span",{className:"absolute inset-0 rounded-full border border-coral opacity-40 motion-safe:animate-ping"})]}),(0,a.jsx)("div",{className:"absolute start-0 top-1/2 flex -translate-y-1/2 flex-col gap-7",children:j.map(e=>(0,a.jsx)("div",{className:"flex size-16 items-center justify-center overflow-hidden rounded-2xl border border-line bg-raised p-2",children:(0,a.jsx)(k,{src:e.image,alt:"",size:48,className:"max-h-12 max-w-12 rounded-xl object-contain",fallbackText:e.name.slice(0,2).toUpperCase()})},e.id))}),(0,a.jsxs)("svg",{"aria-hidden":"true",className:"pointer-events-none absolute inset-0 z-10 size-full rtl:-scale-x-100",viewBox:"0 0 896 360",preserveAspectRatio:"none",xmlns:"http://www.w3.org/2000/svg",children:[N.map(e=>(0,a.jsx)("path",{d:e,fill:"none",strokeDasharray:"5 9",strokeWidth:"2",className:"stroke-subtle motion-safe:animate-flow"},e)),C.map((t,r)=>(0,a.jsx)("path",{d:t,fill:"none",strokeDasharray:e===r?"5 9":void 0,strokeWidth:e===r?3:2,className:e===r?"stroke-lime-ink motion-safe:animate-flow":"stroke-line"},t))]}),(0,a.jsx)("div",{className:"absolute end-0 top-0 bottom-0 flex flex-col justify-between py-6",children:w.map((t,r)=>(0,a.jsx)("span",{className:`flex min-w-[140px] items-center justify-center rounded-lg border px-4 py-2 text-xs font-bold transition-colors ${E(e===r)}`,children:t.name},t.id))})]})]})}function I(){return(0,a.jsx)("section",{className:"border-y border-line bg-raised/40 py-24",id:"how-it-works",children:(0,a.jsxs)("div",{className:"mx-auto max-w-7xl px-4 sm:px-6",children:[(0,a.jsxs)("div",{className:"mb-16",children:[(0,a.jsx)("p",{className:"mb-2 text-xs font-semibold tracking-[0.08em] text-subtle uppercase",children:"How it works"}),(0,a.jsx)("h2",{className:"mb-4 font-display text-3xl font-bold tracking-[-0.02em] text-text md:text-4xl",children:`How ${s.Hc.name} works`}),(0,a.jsx)("p",{className:"max-w-xl text-lg text-muted",children:"Data flows seamlessly from your application through our intelligent routing layer to the best provider for the job."})]}),(0,a.jsxs)("div",{className:"relative grid grid-cols-1 gap-8 md:grid-cols-3",children:[(0,a.jsx)("div",{"aria-hidden":"true",className:"absolute top-12 start-[16%] end-[16%] hidden h-[2px] bg-line md:block"}),(0,a.jsxs)("div",{className:"relative flex flex-col gap-6",children:[(0,a.jsx)("div",{className:"z-10 mx-auto flex h-24 w-24 items-center justify-center rounded-2xl border border-line bg-panel shadow-card md:mx-0",children:(0,a.jsx)("span",{className:"material-symbols-outlined text-4xl text-muted","aria-hidden":"true",children:"terminal"})}),(0,a.jsxs)("div",{className:"text-start",children:[(0,a.jsx)("h3",{className:"mb-2 text-xl font-bold text-text",children:"1. CLI & SDKs"}),(0,a.jsx)("p",{className:"text-sm text-muted",children:"Your requests start from your favorite tools or our unified SDK. Just change the base URL."})]})]}),(0,a.jsxs)("div",{className:"relative flex flex-col gap-6 md:items-center md:text-center",children:[(0,a.jsx)("div",{className:"z-10 mx-auto flex h-24 w-24 items-center justify-center rounded-2xl border-2 border-coral bg-panel shadow-card",children:(0,a.jsx)("span",{className:"material-symbols-outlined text-4xl text-coral motion-safe:animate-pulse motion-reduce:animate-none","aria-hidden":"true",children:"hub"})}),(0,a.jsxs)("div",{className:"text-start md:text-center",children:[(0,a.jsx)("h3",{className:"mb-2 text-xl font-bold text-coral",children:`2. ${s.Hc.name} hub`}),(0,a.jsx)("p",{className:"text-sm text-muted",children:"Our engine analyzes the prompt, checks provider health, and routes for lowest latency or cost."})]})]}),(0,a.jsxs)("div",{className:"relative flex flex-col gap-6 md:items-end md:text-end",children:[(0,a.jsx)("div",{className:"z-10 mx-auto flex h-24 w-24 items-center justify-center rounded-2xl border border-line bg-panel shadow-card md:mx-0",children:(0,a.jsx)("span",{className:"material-symbols-outlined text-4xl text-muted","aria-hidden":"true",children:"cloud"})}),(0,a.jsxs)("div",{className:"text-start md:text-end",children:[(0,a.jsx)("h3",{className:"mb-2 text-xl font-bold text-text",children:"3. AI providers"}),(0,a.jsx)("p",{className:"text-sm text-muted",children:"The request is fulfilled by OpenAI, Anthropic, Gemini, or others instantly."})]})]})]})]})})}let A=[{icon:"link",title:"Unified endpoint",desc:"Access all providers via a single standard API URL."},{icon:"bolt",title:"Easy setup",desc:"Get up and running in minutes with one Docker command."},{icon:"shield_with_heart",title:"Model fallback",desc:"Automatically switch providers on failure or high latency."},{icon:"monitoring",title:"Usage tracking",desc:"Detailed analytics and cost monitoring across all models."},{icon:"key",title:"OAuth & API keys",desc:"Securely manage credentials in one vault."},{icon:"cloud_sync",title:"Cloud sync",desc:"Sync your configurations across devices instantly."},{icon:"terminal",title:"CLI support",desc:"Works with Claude Code, Codex, Cline, Cursor, and more."},{icon:"dashboard",title:"Dashboard",desc:"Visual dashboard for real-time traffic analysis."}];function $(){return(0,a.jsx)("section",{className:"px-4 py-24 sm:px-6",id:"features",children:(0,a.jsxs)("div",{className:"mx-auto max-w-7xl",children:[(0,a.jsxs)("div",{className:"mb-16",children:[(0,a.jsx)("p",{className:"mb-2 text-xs font-semibold tracking-[0.08em] text-subtle uppercase",children:"Features"}),(0,a.jsx)("h2",{className:"mb-4 font-display text-3xl font-bold tracking-[-0.02em] text-text md:text-4xl",children:"Powerful features"}),(0,a.jsx)("p",{className:"max-w-xl text-lg text-muted",children:"Everything you need to manage your AI infrastructure in one place, built for scale."})]}),(0,a.jsx)("div",{className:"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4",children:A.map(e=>(0,a.jsxs)("article",{className:"rounded-2xl border border-line bg-panel p-6 shadow-card transition-colors hover:border-coral/40",children:[(0,a.jsx)("div",{className:"mb-4 flex size-10 items-center justify-center rounded-[10px] bg-coral-bg text-coral-ink",children:(0,a.jsx)("span",{className:"material-symbols-outlined text-[20px]","aria-hidden":"true",children:e.icon})}),(0,a.jsx)("h3",{className:"mb-2 text-base font-semibold text-text",children:e.title}),(0,a.jsx)("p",{className:"text-sm leading-relaxed text-muted",children:e.desc})]},e.title))})]})})}let O=`docker run -d -p 20128:20128 -v ~/.${s.Hc.dataDirName}:/app/data -e INITIAL_PASSWORD=change-me ghcr.io/tokenhop/tokenhop`,S=[{title:`Install ${s.Hc.name}`,desc:"Run the Docker image to start the server instantly"},{title:"Open dashboard",desc:"Configure providers and API keys via web interface"},{title:"Route requests",desc:"Point your CLI tools to http://localhost:20128"}],P=[{text:`Starting ${s.Hc.name}...`,tone:"signal-terminal-log"},{text:"Server running on http://localhost:20128",tone:"signal-terminal-info"},{text:"Dashboard: http://localhost:20128/dashboard",tone:"signal-terminal-info"},{text:"Ready to route",tone:"signal-terminal-log"}];function z(){return(0,a.jsx)("section",{className:"px-4 py-24 sm:px-6",id:"get-started",children:(0,a.jsx)("div",{className:"mx-auto max-w-7xl",children:(0,a.jsxs)("div",{className:"flex flex-col items-start gap-16 lg:flex-row",children:[(0,a.jsxs)("div",{className:"flex-1",children:[(0,a.jsx)("p",{className:"mb-2 text-xs font-semibold tracking-[0.08em] text-subtle uppercase",children:"Get started"}),(0,a.jsx)("h2",{className:"mb-6 font-display text-3xl font-bold tracking-[-0.02em] text-text md:text-4xl",children:"Get started in 30 seconds"}),(0,a.jsx)("p",{className:"mb-8 text-lg text-muted",children:`Install ${s.Hc.name}, configure your providers via web dashboard, and start routing AI requests.`}),(0,a.jsx)("ol",{className:"flex list-none flex-col gap-6 p-0",children:S.map((e,t)=>(0,a.jsxs)("li",{className:"flex gap-4",children:[(0,a.jsx)("span",{"aria-hidden":"true",className:"flex size-8 flex-none items-center justify-center rounded-full bg-coral-bg font-semibold text-coral-ink",children:t+1}),(0,a.jsxs)("div",{children:[(0,a.jsx)("h3",{className:"text-lg font-bold text-text",children:e.title}),(0,a.jsx)("p",{className:"mt-1 text-sm text-muted",children:e.desc})]})]},e.title))})]}),(0,a.jsx)("div",{className:"dark w-full min-w-0 flex-1",children:(0,a.jsxs)("div",{className:"signal-terminal overflow-hidden rounded-2xl border border-line shadow-card",children:[(0,a.jsxs)("div",{className:"flex items-center gap-2 border-b border-line px-4 py-3",children:[(0,a.jsxs)("span",{"aria-hidden":"true",className:"flex gap-2",children:[(0,a.jsx)("span",{className:"size-3 rounded-full bg-line"}),(0,a.jsx)("span",{className:"size-3 rounded-full bg-line"}),(0,a.jsx)("span",{className:"size-3 rounded-full bg-line"})]}),(0,a.jsx)("span",{className:"ms-2 font-mono text-xs text-muted",children:"terminal"})]}),(0,a.jsxs)("div",{className:"overflow-x-auto p-6 font-mono text-sm leading-relaxed",children:[(0,a.jsx)(b.default,{value:`$ ${O}`,copyValue:O,label:"Copy install command",className:"mb-6"}),(0,a.jsx)("p",{className:"sr-only",children:`Starting ${s.Hc.name}. Server running on http://localhost:20128. Dashboard at http://localhost:20128/dashboard. Ready to route.`}),(0,a.jsx)("div",{"aria-hidden":"true",className:"mb-6 flex flex-col gap-1",children:P.map(e=>(0,a.jsxs)("span",{className:e.tone,children:[(0,a.jsx)("span",{className:"signal-terminal-time me-2",children:">"}),e.text]},e.text))}),(0,a.jsxs)("p",{className:"mb-2 border-t border-line pt-4 text-xs",children:[(0,a.jsx)("span",{className:"material-symbols-outlined me-1 inline-block align-[-2px] text-[14px]","aria-hidden":"true",children:"edit_note"}),"Configure providers in dashboard or use environment variables"]}),(0,a.jsxs)("p",{className:"text-xs",children:[(0,a.jsx)("span",{className:"signal-terminal-debug",children:"Data location:"}),(0,a.jsx)("br",{}),(0,a.jsx)("span",{className:"signal-terminal-time",children:"macOS/Linux:"})," ",`~/.${s.Hc.dataDirName}/db/data.sqlite`,(0,a.jsx)("br",{}),(0,a.jsx)("span",{className:"signal-terminal-time",children:"Windows:"})," ",`%APPDATA%/${s.Hc.dataDirName}/db/data.sqlite`]})]})]})})]})})})}let H=s.DM===s.qt.slug,D=[{label:"Features",href:"#features"},{label:"Dashboard",href:"/dashboard"},{label:"Changelog",href:"https://github.com/tokenhop/tokenhop",target:"_blank",rel:"noopener noreferrer"}],M=[{label:"Documentation",href:"https://github.com/tokenhop/tokenhop#readme",target:"_blank",rel:"noopener noreferrer"},{label:"GitHub",href:"https://github.com/tokenhop/tokenhop",target:"_blank",rel:"noopener noreferrer"},{label:"Docker",href:"https://github.com/tokenhop/tokenhop/pkgs/container/tokenhop",target:"_blank",rel:"noopener noreferrer"},...H?[{label:"npm",href:`https://www.npmjs.com/package/${s.qt.npmPackage}`,target:"_blank",rel:"noopener noreferrer"}]:[]],R=H?{label:`Based on ${s.qx.names[0]} by decolua`,href:`https://github.com/decolua/${s.qx.slug}`}:null,T=[{label:"MIT License",href:"https://github.com/tokenhop/tokenhop/blob/master/LICENSE",target:"_blank",rel:"noopener noreferrer"}];function L(){return(0,a.jsx)("footer",{className:"border-t border-line bg-raised/30 px-4 pt-16 pb-8 sm:px-6",children:(0,a.jsxs)("div",{className:"mx-auto max-w-7xl",children:[(0,a.jsxs)("div",{className:"mb-16 grid grid-cols-2 gap-8 md:grid-cols-4 lg:grid-cols-5",children:[(0,a.jsxs)("div",{className:"col-span-2 lg:col-span-2",children:[(0,a.jsx)(i(),{href:"/","aria-label":`${s.Hc.name} home`,className:"mb-6 inline-flex min-h-[44px] items-center gap-3 rounded-lg",children:(0,a.jsx)(m.A,{})}),(0,a.jsx)("p",{className:"mb-6 max-w-xs text-sm leading-relaxed text-muted",children:"The unified endpoint for AI generation. Connect, route, and manage your AI providers with ease."}),(0,a.jsx)("div",{className:"flex gap-4",children:(0,a.jsxs)("a",{className:"inline-flex min-h-[44px] min-w-[44px] items-center justify-center rounded-lg text-muted transition-colors hover:text-text focus-visible:shadow-focus",href:"https://github.com/tokenhop/tokenhop",target:"_blank",rel:"noopener noreferrer",children:[(0,a.jsx)("span",{className:"sr-only",children:`${s.Hc.name} on GitHub`}),(0,a.jsx)("span",{className:"material-symbols-outlined text-[20px]","aria-hidden":"true",children:"code"})]})})]}),(0,a.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,a.jsx)("h2",{className:"font-sans text-sm font-semibold text-text",children:"Product"}),D.map(e=>(0,a.jsx)("a",{className:"inline-flex min-h-[44px] items-center text-sm text-muted transition-colors hover:text-coral focus-visible:shadow-focus",href:e.href,target:e.target,rel:e.rel,children:e.label},e.label))]}),(0,a.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,a.jsx)("h2",{className:"font-sans text-sm font-semibold text-text",children:"Resources"}),M.map(e=>(0,a.jsx)("a",{className:"inline-flex min-h-[44px] items-center text-sm text-muted transition-colors hover:text-coral focus-visible:shadow-focus",href:e.href,target:e.target,rel:e.rel,children:e.label},e.label))]}),(0,a.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,a.jsx)("h2",{className:"font-sans text-sm font-semibold text-text",children:"Legal"}),T.map(e=>(0,a.jsx)("a",{className:"inline-flex min-h-[44px] items-center text-sm text-muted transition-colors hover:text-coral focus-visible:shadow-focus",href:e.href,target:e.target,rel:e.rel,children:e.label},e.label))]})]}),(0,a.jsxs)("div",{className:"flex flex-col items-center justify-between gap-4 border-t border-line pt-8 sm:flex-row",children:[(0,a.jsxs)("div",{className:"flex flex-col gap-1",children:[(0,a.jsx)("p",{className:"text-sm text-muted",children:`\xa9 2025 ${s.Hc.name}. All rights reserved.`}),R&&(0,a.jsx)("a",{className:"inline-flex min-h-[44px] items-center text-sm text-muted transition-colors hover:text-text focus-visible:shadow-focus",href:R.href,target:"_blank",rel:"noopener noreferrer",children:R.label})]}),(0,a.jsxs)("div",{className:"flex gap-6",children:[(0,a.jsx)("a",{className:"inline-flex min-h-[44px] items-center text-sm text-muted transition-colors hover:text-text focus-visible:shadow-focus",href:"https://github.com/tokenhop/tokenhop",target:"_blank",rel:"noopener noreferrer",children:"GitHub"}),(0,a.jsx)("a",{className:"inline-flex min-h-[44px] items-center text-sm text-muted transition-colors hover:text-text focus-visible:shadow-focus",href:"https://github.com/tokenhop/tokenhop/pkgs/container/tokenhop",target:"_blank",rel:"noopener noreferrer",children:"Docker"})]})]})]})})}function U(){return(0,a.jsxs)("div",{className:"relative overflow-x-hidden bg-bg font-sans text-text antialiased",children:[(0,a.jsx)("div",{"aria-hidden":"true",className:"landing-grid pointer-events-none fixed inset-0"}),(0,a.jsx)(x,{}),(0,a.jsxs)("main",{className:"relative",children:[(0,a.jsxs)("div",{className:"relative",children:[(0,a.jsx)(g,{}),(0,a.jsx)("div",{className:"flex justify-center pb-20",children:(0,a.jsx)(_,{})})]}),(0,a.jsx)(z,{}),(0,a.jsx)(I,{}),(0,a.jsx)($,{}),(0,a.jsxs)("section",{className:"relative overflow-hidden px-4 py-24 sm:px-6","aria-labelledby":"cta-title",children:[(0,a.jsx)("div",{"aria-hidden":"true",className:"pointer-events-none absolute inset-0 bg-coral-bg [mask-image:radial-gradient(ellipse_70%_100%_at_50%_100%,black,transparent)]"}),(0,a.jsxs)("div",{className:"relative z-10 mx-auto max-w-4xl text-center",children:[(0,a.jsx)("h2",{id:"cta-title",className:"mb-6 font-display text-4xl font-bold tracking-[-0.02em] text-text md:text-5xl",children:"Ready to simplify your AI infrastructure?"}),(0,a.jsx)("p",{className:"mx-auto mb-10 max-w-2xl text-xl text-muted",children:`Join developers who are streamlining their AI integrations with ${s.Hc.name}. Open source and free to start.`}),(0,a.jsxs)("div",{className:"flex flex-col items-center justify-center gap-4 sm:flex-row",children:[(0,a.jsx)(n.default,{variant:"primary",size:"md",href:"/dashboard",className:"w-full sm:w-auto",children:"Start free"}),(0,a.jsx)(n.default,{variant:"secondary",size:"md",href:"https://github.com/tokenhop/tokenhop#readme",target:"_blank",rel:"noopener noreferrer",className:"w-full sm:w-auto",children:"Read documentation"})]})]})]})]}),(0,a.jsx)(L,{})]})}},48593:(e,t,r)=>{"use strict";r.d(t,{A:()=>l});var a=r(12115),n=r(4553),s=r(92466);function l({size:e=36,className:t=""}){return(0,a.createElement)("span",{className:`flex items-center gap-2.5 ${t}`},(0,a.createElement)(s.A,{size:e,decorative:!0}),(0,a.createElement)("span",{className:"font-display font-bold tracking-[-0.02em] text-text",style:{fontSize:22*e/36}},n.Hc.wordmark))}},50770:(e,t,r)=>{"use strict";r.d(t,{PK:()=>h,S3:()=>o,XY:()=>i,lN:()=>d,pN:()=>f,pi:()=>x,r4:()=>u,vE:()=>m,vO:()=>s});let a={connected:"ok",healthy:"ok",active:"ok",ok:"ok",success:"ok",cooldown:"warn",warning:"warn",low:"warn",warn:"warn",error:"err",empty:"err",err:"err",oauth:"info",info:"info","api-key":"brand",brand:"brand",live:"live",disabled:"neutral",off:"neutral",neutral:"neutral"},n={ok:"bg-ok-bg text-ok",warn:"bg-warn-bg text-warn",err:"bg-err-bg text-err",info:"bg-sky-bg text-sky-ink",brand:"bg-coral-bg text-coral-ink",live:"bg-lime-bg text-lime-ink",neutral:"bg-raised text-muted shadow-[inset_0_0_0_1px_var(--signal-line)]"},s={xs:"h-5 px-2 text-[11px]",sm:"h-5 px-2 text-[11px]",md:"h-6 px-2.5 text-xs",lg:"h-7 px-3 text-sm"},l={default:"neutral",primary:"brand",success:"ok",warning:"warn",error:"err"},i=[...new Set([...Object.keys(n),...Object.keys(l),...Object.keys(a)])];function o(e="neutral",t="md"){let r=s[t];if(!r)throw Error(`pillClasses: unknown size "${t}"`);return`${n[function(e){if(n[e])return e;let t=l[e]??a[e];if(!t)throw Error(`resolvePillVariant: unknown variant "${e}"`);return t}(e)]} ${r}`}let d={ok:"bg-ok",warn:"bg-warn",err:"bg-err",live:"bg-lime",info:"bg-sky",brand:"bg-coral",neutral:"bg-subtle"},c=new Set(["unlimited","credits"]);function m(e,t){if(void 0!==t&&!c.has(t))throw Error(`meterVariant: unknown kind "${t}"`);if("number"!=typeof e||!Number.isFinite(e))throw Error(`meterVariant: expected a finite number, got ${e}`);return"unlimited"===t?"live":"credits"===t?"info":e<=20?"err":e<=45?"warn":"ok"}function u(e){if("number"!=typeof e||!Number.isFinite(e))throw Error(`meterValue: expected a finite number, got ${e}`);return Math.min(100,Math.max(0,e))}let x="border-b border-line",h="whitespace-nowrap text-xs font-semibold text-muted",p={LOG:"signal-terminal-log",INFO:"signal-terminal-info",WARN:"signal-terminal-warn",ERROR:"signal-terminal-error",DEBUG:"signal-terminal-debug"};function f(e){let t=p[e];if(!t)throw Error(`terminalLevelClass: unknown level "${e}"`);return t}},90085:(e,t,r)=>{"use strict";r.d(t,{A:()=>i});var a=r(1934),n=r(31692),s=r(28745);function l(e){let t=document.documentElement,r=window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light";"dark"===("system"===e?r:e)?t.classList.add("dark"):t.classList.remove("dark")}let i=(0,a.v)((0,n.Zr)((e,t)=>({theme:s.B2.defaultTheme,setTheme:t=>{e({theme:t}),l(t)},toggleTheme:()=>{let r="dark"===t().theme?"light":"dark";e({theme:r}),l(r)},initTheme:()=>{l(t().theme)}}),{name:s.B2.storageKey}))},92466:(e,t,r)=>{"use strict";r.d(t,{A:()=>l});var a=r(12115),n=r(4553);let s=()=>[(0,a.createElement)("path",{key:"stem",d:"M25 11V41.5C25 48.5 28.8 52 35.5 52H40",fill:"none",stroke:"currentColor",strokeWidth:7.5,strokeLinecap:"round"}),(0,a.createElement)("path",{key:"arc",d:"M14 26.5C22 18.5 34 18 42 24",fill:"none",stroke:"currentColor",strokeWidth:6.5,strokeLinecap:"round"}),(0,a.createElement)("path",{key:"dot",d:"M43 29a6.5 6.5 0 1 0 13 0a6.5 6.5 0 1 0-13 0z",fill:"currentColor"})];function l({size:e=36,decorative:t=!1,className:r="",x:i,y:o}){let d=t?{"aria-hidden":"true"}:{role:"img","aria-label":n.Hc.name};return"number"==typeof i&&"number"==typeof o?function({x:e,y:t,size:r,aria:l}){if(n.DM===n.qx.slug){let s=r/96,i=e+r/2,o=t+r/2;return(0,a.createElement)("g",l,(0,a.createElement)("rect",{x:e,y:t,width:r,height:r,rx:28*s,fill:"var(--signal-coral)"}),(0,a.createElement)("text",{x:i,y:o-2*s,textAnchor:"middle",fill:"var(--signal-on-coral)",fontSize:`${42*s}`,fontWeight:"800",fontFamily:"var(--signal-font-display)"},"9"),(0,a.createElement)("text",{x:i,y:o+22*s,textAnchor:"middle",fill:"var(--signal-on-coral)",fontSize:`${11*s}`,fontWeight:"700",letterSpacing:`${1.1*s}`},n.Hc.wordmark))}return(0,a.createElement)("svg",{...l,x:e,y:t,width:r,height:r,viewBox:"0 0 64 64",color:"var(--signal-text)"},(0,a.createElement)("rect",{width:64,height:64,rx:16,fill:"var(--signal-coral)"}),...s())}({x:i,y:o,size:e,aria:d}):n.DM===n.qx.slug?(0,a.createElement)("span",{...d,className:`-rotate-[8deg] flex items-center justify-center bg-coral font-display font-extrabold text-on-coral shadow-card ${r}`,style:{width:e,height:e,fontSize:22*e/36,borderRadius:11*e/36}},"9"):(0,a.createElement)("svg",{...d,viewBox:"0 0 64 64",width:e,height:e,className:r,focusable:"false"},(0,a.createElement)("rect",{width:64,height:64,rx:16,fill:"var(--signal-coral)"}),...s())}},92542:(e,t,r)=>{"use strict";r.d(t,{default:()=>c});var a=r(95155),n=r(98500),s=r.n(n),l=r(14051),i=r.n(l),o=r(31474),d=r(4650);function c({children:e,variant:t="primary",size:r="md",icon:n,iconRight:l,href:i,disabled:m=!1,loading:u=!1,fullWidth:x=!1,className:h,...p}){let f=(0,o.cn)("inline-flex items-center justify-center gap-2 font-semibold transition-all duration-150 ease-out cursor-pointer","active:scale-[0.97] focus-visible:outline-none focus-visible:shadow-focus","disabled:opacity-50 disabled:cursor-not-allowed disabled:active:scale-100","aria-disabled:opacity-50 aria-disabled:cursor-not-allowed aria-disabled:active:scale-100",(0,d.V7)(t,r),x&&"w-full",h),b=(0,a.jsxs)(a.Fragment,{children:[u?(0,a.jsx)("span",{className:"material-symbols-outlined animate-spin text-[18px]","aria-hidden":"true",children:"progress_activity"}):n?(0,a.jsx)("span",{className:"material-symbols-outlined text-[18px]","aria-hidden":"true",children:n}):null,e,l&&!u&&(0,a.jsx)("span",{className:"material-symbols-outlined text-[18px] rtl:-scale-x-100","aria-hidden":"true",children:l})]});if(i&&!(m||u)){let{type:e,...t}=p;return t.className=f,/^(https?:|mailto:|tel:|#)/.test(i)?(0,a.jsx)("a",{href:i,...t,children:b}):(0,a.jsx)(s(),{href:i,...t,children:b})}return(0,a.jsx)("button",{className:f,disabled:m||u,"aria-busy":u||void 0,...p,children:b})}c.propTypes={children:i().node,variant:i().oneOf(Object.keys(d.Ck)),size:i().oneOf(Object.keys(d.GO)),icon:i().string,iconRight:i().string,href:i().string,disabled:i().bool,loading:i().bool,fullWidth:i().bool,className:i().string}},99013:(e,t,r)=>{Promise.resolve().then(r.bind(r,42586))}},e=>{e.O(0,[1610,2903,8441,3794,7358],()=>e(e.s=99013)),_N_E=e.O()}]);
@@ -0,0 +1 @@
1
+ (()=>{"use strict";var e,t,r,a,c,s,n,o,i={},d={};function f(e){var t=d[e];if(void 0!==t)return t.exports;var r=d[e]={exports:{}},a=!0;try{i[e].call(r.exports,r,r.exports,f),a=!1}finally{a&&delete d[e]}return r.exports}f.m=i,e=[],f.O=(t,r,a,c)=>{if(r){c=c||0;for(var s=e.length;s>0&&e[s-1][2]>c;s--)e[s]=e[s-1];e[s]=[r,a,c];return}for(var n=1/0,s=0;s<e.length;s++){for(var[r,a,c]=e[s],o=!0,i=0;i<r.length;i++)(!1&c||n>=c)&&Object.keys(f.O).every(e=>f.O[e](r[i]))?r.splice(i--,1):(o=!1,c<n&&(n=c));if(o){e.splice(s--,1);var d=a();void 0!==d&&(t=d)}}return t},f.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return f.d(t,{a:t}),t},r=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,f.t=function(e,a){if(1&a&&(e=this(e)),8&a||"object"==typeof e&&e&&(4&a&&e.__esModule||16&a&&"function"==typeof e.then))return e;var c=Object.create(null);f.r(c);var s={};t=t||[null,r({}),r([]),r(r)];for(var n=2&a&&e;"object"==typeof n&&!~t.indexOf(n);n=r(n))Object.getOwnPropertyNames(n).forEach(t=>s[t]=()=>e[t]);return s.default=()=>e,f.d(c,s),c},f.d=(e,t)=>{for(var r in t)f.o(t,r)&&!f.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},f.f={},f.e=e=>Promise.all(Object.keys(f.f).reduce((t,r)=>(f.f[r](e,t),t),[])),f.u=e=>8105===e?"static/chunks/8105-bdd81b911fed8537.js":5814===e?"static/chunks/5814-f219e250823160d0.js":9233===e?"static/chunks/9233-7c1e356386d4e864.js":4070===e?"static/chunks/4070-c76ef7302b944563.js":9671===e?"static/chunks/9671-13bf0a1dd082ad39.js":4685===e?"static/chunks/4685-8a4450325e60133c.js":7899===e?"static/chunks/7899-83edd7bbf1a98c4a.js":1863===e?"static/chunks/1863-07d1c4c60eabc139.js":5014===e?"static/chunks/5014-a5d960f4c6bc6297.js":198===e?"static/chunks/198-0c7f5eadfd257db1.js":3961===e?"static/chunks/3961-193c64b1695b33ee.js":5060===e?"static/chunks/5060-1c610ccae6241090.js":971===e?"static/chunks/971-27c4c5772ea6abeb.js":3044===e?"static/chunks/3044-ee7d162fa370dc8a.js":9284===e?"static/chunks/9284-61f162b7e4e8e29a.js":9394===e?"static/chunks/9394-ac4431dfa81224cc.js":9449===e?"static/chunks/9449-f56c6dfcfae3b50a.js":"static/chunks/"+e+"."+({270:"fca1d241965ad518",1036:"8a38d2bfc9f93236",1536:"2f931db1adf1a474",1931:"0a9b23f72463011f",2513:"07cfab564e286e41",4289:"6b78acbbff5886aa",4490:"0a9025c0609ad814",4506:"fbe8545026f1cbaa",4815:"903371440731eb11",5064:"98f2197be4baff8a",6174:"f1da2912aec81c15",6354:"7a4bb5771a8b2614",6554:"5d2fe03b263ab0ac",7198:"150be318dbc95704",7556:"0336d8b6a1abd43a",7942:"65a1310eb9394724",8046:"10d75ab56fadd8a5",8202:"1ffc6ce531e066ce",8387:"d76fed15eca7020b",8388:"699e1ab12e1565d1",8922:"3da620b68775ad61",9176:"7bca687eb6d20d48",9300:"56f8a551e86baf88",9499:"83d2d5f989f163b0"})[e]+".js",f.miniCssF=e=>{},f.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}}(),f.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),a={},f.l=(e,t,r,c)=>{if(a[e])return void a[e].push(t);if(void 0!==r)for(var s,n,o=document.getElementsByTagName("script"),i=0;i<o.length;i++){var d=o[i];if(d.getAttribute("src")==e||d.getAttribute("data-webpack")=="_N_E:"+r){s=d;break}}s||(n=!0,(s=document.createElement("script")).charset="utf-8",s.timeout=120,f.nc&&s.setAttribute("nonce",f.nc),s.setAttribute("data-webpack","_N_E:"+r),s.src=f.tu(e)),a[e]=[t];var u=(t,r)=>{s.onerror=s.onload=null,clearTimeout(b);var c=a[e];if(delete a[e],s.parentNode&&s.parentNode.removeChild(s),c&&c.forEach(e=>e(r)),t)return t(r)},b=setTimeout(u.bind(null,void 0,{type:"timeout",target:s}),12e4);s.onerror=u.bind(null,s.onerror),s.onload=u.bind(null,s.onload),n&&document.head.appendChild(s)},f.r=e=>{"u">typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},f.tt=()=>(void 0===c&&(c={createScriptURL:e=>e},"u">typeof trustedTypes&&trustedTypes.createPolicy&&(c=trustedTypes.createPolicy("nextjs#bundler",c))),c),f.tu=e=>f.tt().createScriptURL(e),f.p="/_next/",s={8068:0,3139:0},f.f.j=(e,t)=>{var r=f.o(s,e)?s[e]:void 0;if(0!==r)if(r)t.push(r[2]);else if(/^(3139|8068)$/.test(e))s[e]=0;else{var a=new Promise((t,a)=>r=s[e]=[t,a]);t.push(r[2]=a);var c=f.p+f.u(e),n=Error();f.l(c,t=>{if(f.o(s,e)&&(0!==(r=s[e])&&(s[e]=void 0),r)){var a=t&&("load"===t.type?"missing":t.type),c=t&&t.target&&t.target.src;n.message="Loading chunk "+e+" failed.\n("+a+": "+c+")",n.name="ChunkLoadError",n.type=a,n.request=c,r[1](n)}},"chunk-"+e,e)}},f.O.j=e=>0===s[e],n=(e,t)=>{var r,a,[c,n,o]=t,i=0;if(c.some(e=>0!==s[e])){for(r in n)f.o(n,r)&&(f.m[r]=n[r]);if(o)var d=o(f)}for(e&&e(t);i<c.length;i++)a=c[i],f.o(s,a)&&s[a]&&s[a][0](),s[a]=0;return f.O(d)},(o=self.webpackChunk_N_E=self.webpackChunk_N_E||[]).forEach(n.bind(null,0)),o.push=n.bind(null,o.push.bind(o))})();
@@ -2,7 +2,6 @@ const http = require("http");
2
2
  const path = require("path");
3
3
  const fs = require("fs");
4
4
  const crypto = require("crypto");
5
- const { pathToFileURL } = require("url");
6
5
 
7
6
  // Repo checkout and Docker keep the brand module beside this file; the CLI package
8
7
  // ships custom-server.js in app/ and its packed copy one level up.
@@ -75,39 +74,6 @@ function parseBodySizeLimit(value) {
75
74
  }
76
75
  const MAX_H2C_BODY_BYTES = parseBodySizeLimit(readEnv("PROXY_CLIENT_MAX_BODY_SIZE"));
77
76
 
78
- let backgroundRefreshStarted = false;
79
-
80
- function startBackgroundTokenRefreshFromCustomServer() {
81
- if (backgroundRefreshStarted) return;
82
- backgroundRefreshStarted = true;
83
- // Prefer source path (repo / standalone that still has src). Fail-open if missing
84
- // — initializeApp also starts the same scheduler when the Next app boots.
85
- const modPath = path.join(__dirname, "src", "sse", "services", "backgroundTokenRefresh.js");
86
- import(pathToFileURL(modPath).href)
87
- .then((m) => {
88
- try {
89
- m.startBackgroundTokenRefresh();
90
- } catch (e) {
91
- console.error("[BackgroundTokenRefresh] start failed:", e && e.message ? e.message : e);
92
- }
93
- const stop = () => {
94
- try {
95
- m.stopBackgroundTokenRefresh();
96
- } catch {
97
- /* ignore */
98
- }
99
- };
100
- process.once("SIGINT", stop);
101
- process.once("SIGTERM", stop);
102
- })
103
- .catch((e) => {
104
- // Expected in published CLI standalone (src/ not on disk). App bootstrap covers it.
105
- if (process.env.DEBUG_BACKGROUND_TOKEN_REFRESH) {
106
- console.error("[BackgroundTokenRefresh] import failed:", e && e.message ? e.message : e);
107
- }
108
- });
109
- }
110
-
111
77
  function rightmostForwardedIp(xff) {
112
78
  if (!xff) return "";
113
79
  const hops = String(xff)
@@ -148,9 +114,6 @@ http.createServer = (...args) => {
148
114
  return handler(req, res);
149
115
  };
150
116
  const server = origCreate(...rest, wrapped);
151
- server.once("listening", () => {
152
- startBackgroundTokenRefreshFromCustomServer();
153
- });
154
117
  const origEmit = server.emit;
155
118
  // JBR 25 sends h2c upgrades that the HTTP/1.1 server would otherwise close.
156
119
  server.emit = function (event, ...eventArgs) {
package/app/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tokenhop-app",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "tokenhop web dashboard",
5
5
  "private": true,
6
6
  "engines": {
@@ -1,4 +1,5 @@
1
1
  import fs from "node:fs";
2
+ import path from "node:path";
2
3
  import initSqlJs from "sql.js";
3
4
  import { PRAGMA_SQL } from "../schema.js";
4
5
  import { runShutdownFlushers } from "../shutdownFlushers.js";
@@ -23,8 +24,39 @@ export async function createSqlJsAdapter(filePath) {
23
24
  const SAVE_DEBOUNCE_MS = 100;
24
25
 
25
26
  function persist() {
26
- const data = db.export();
27
- fs.writeFileSync(filePath, Buffer.from(data));
27
+ const data = Buffer.from(db.export());
28
+ // Write a sibling temp file, fsync, then rename over the target so a crash mid-write
29
+ // never leaves a truncated DB. rename replaces an existing file on POSIX and Windows.
30
+ // Unique per writer so two processes on one DATA_DIR never share a temp file.
31
+ const tmpPath = `${filePath}.${process.pid}.${Math.random().toString(36).slice(2, 10)}.tmp`;
32
+ let fd = null;
33
+ try {
34
+ fd = fs.openSync(tmpPath, "wx");
35
+ fs.writeSync(fd, data, 0, data.length, 0);
36
+ fs.fsyncSync(fd);
37
+ fs.closeSync(fd);
38
+ fd = null;
39
+ fs.renameSync(tmpPath, filePath);
40
+ // Make the rename itself durable. Directories can't be fsynced on Windows.
41
+ try {
42
+ const dirFd = fs.openSync(path.dirname(filePath), "r");
43
+ try {
44
+ fs.fsyncSync(dirFd);
45
+ } finally {
46
+ fs.closeSync(dirFd);
47
+ }
48
+ } catch {}
49
+ } catch (e) {
50
+ if (fd !== null) {
51
+ try {
52
+ fs.closeSync(fd);
53
+ } catch {}
54
+ }
55
+ try {
56
+ fs.rmSync(tmpPath, { force: true });
57
+ } catch {}
58
+ throw e;
59
+ }
28
60
  dirty = false;
29
61
  }
30
62
 
@@ -110,8 +142,11 @@ export async function createSqlJsAdapter(filePath) {
110
142
 
111
143
  function close() {
112
144
  if (saveTimer) clearTimeout(saveTimer);
113
- if (dirty) persist();
114
- db.close();
145
+ try {
146
+ if (dirty) persist();
147
+ } finally {
148
+ db.close();
149
+ }
115
150
  }
116
151
 
117
152
  // Flush on shutdown (sync: repos flush before sql.js persists to disk)
@@ -152,20 +152,27 @@ export class XaiService extends OAuthService {
152
152
  /**
153
153
  * Refresh an access token using a refresh_token.
154
154
  */
155
- async refreshAccessToken(refreshToken) {
155
+ async refreshAccessToken(refreshToken, proxyOptions = null) {
156
156
  const { tokenUrl } = await discoverEndpoints();
157
- const res = await fetch(tokenUrl, {
158
- method: "POST",
159
- headers: {
160
- "Content-Type": "application/x-www-form-urlencoded",
161
- Accept: "application/json",
157
+ // Dynamic import: proxyFetch patches globalThis.fetch at load; this module is
158
+ // also imported by pure URL/discovery helpers that must not trigger that.
159
+ const { proxyAwareFetch } = await import("open-sse/utils/proxyFetch.js");
160
+ const res = await proxyAwareFetch(
161
+ tokenUrl,
162
+ {
163
+ method: "POST",
164
+ headers: {
165
+ "Content-Type": "application/x-www-form-urlencoded",
166
+ Accept: "application/json",
167
+ },
168
+ body: new URLSearchParams({
169
+ grant_type: "refresh_token",
170
+ client_id: XAI_CONFIG.clientId,
171
+ refresh_token: refreshToken,
172
+ }),
162
173
  },
163
- body: new URLSearchParams({
164
- grant_type: "refresh_token",
165
- client_id: XAI_CONFIG.clientId,
166
- refresh_token: refreshToken,
167
- }),
168
- });
174
+ proxyOptions,
175
+ );
169
176
  if (!res.ok) {
170
177
  const err = await res.text();
171
178
  throw new Error(`xAI token refresh failed: ${err}`);
@@ -104,7 +104,8 @@ function buildProxyOptions(cfg) {
104
104
  connectionProxyUrl: cfg.connectionProxyUrl || "",
105
105
  connectionNoProxy: cfg.connectionNoProxy || "",
106
106
  vercelRelayUrl: cfg.vercelRelayUrl || "",
107
- strictProxy: false,
107
+ strictProxy: cfg.strictProxy === true,
108
+ connectionProxyPoolId: cfg.proxyPoolId || null,
108
109
  };
109
110
  }
110
111
 
@@ -200,15 +201,35 @@ function shouldSkipAfterFailure(state, key, nowMs = Date.now()) {
200
201
  return failedAt && nowMs - failedAt < C.failureCooldownMs;
201
202
  }
202
203
 
204
+ // Skip reasons repeat every tick in steady state; log each one once per connection.
205
+ function logSkipOnce(state, key, reason) {
206
+ state.lastSkipLog ??= {};
207
+ if (state.lastSkipLog[key] === reason) return;
208
+ state.lastSkipLog[key] = reason;
209
+ console.log(`[AutoPing] ${key}: ${reason}`);
210
+ }
211
+
203
212
  async function pingConnection(conn, provider, providerConfig, handler, deps, state = g) {
204
213
  const key = cacheKey(provider, conn.id);
205
214
 
206
215
  // resetAt is stable for time-based windows; Codex polls every tick because inactive windows slide forward.
207
216
  const cachedReset = state.resetCache[key];
217
+ const cachedResetMs = cachedReset ? new Date(cachedReset).getTime() : NaN;
218
+ const lastPingedKey = conn.lastPingedResetKey || normalizeResetKey(conn.lastPingedResetAt);
219
+ // A missed window: the last observed reset passed and was never pinged (the
220
+ // live read may no longer report it). Recover it instead of waiting forever.
221
+ const missedReset =
222
+ !providerConfig.pingWhenResetAtSlides &&
223
+ Number.isFinite(cachedResetMs) &&
224
+ Date.now() >= cachedResetMs &&
225
+ lastPingedKey !== normalizeResetKey(cachedReset)
226
+ ? cachedReset
227
+ : null;
208
228
  if (
229
+ !missedReset &&
209
230
  !providerConfig.pingWhenResetAtSlides &&
210
231
  cachedReset &&
211
- Date.now() < new Date(cachedReset).getTime() - C.refreshAheadMs
232
+ Date.now() < cachedResetMs - C.refreshAheadMs
212
233
  )
213
234
  return;
214
235
 
@@ -231,17 +252,28 @@ async function pingConnection(conn, provider, providerConfig, handler, deps, sta
231
252
  const usage = await handler.getUsage(connection.accessToken, proxyOptions);
232
253
  const quotas = usage?.quotas || {};
233
254
  const quota = quotas?.[providerConfig.quotaKey];
234
- const resetAt = quota?.resetAt;
235
- if (!resetAt) return;
255
+ const liveReset = quota?.resetAt;
236
256
 
237
- state.resetCache[key] = resetAt;
257
+ // Prefer the missed window: the live read may already report the next reset
258
+ // (or nothing on an idle window) while the last observed one went unpinged.
259
+ const resetAt = missedReset || liveReset;
260
+ if (!resetAt) {
261
+ if (cachedReset) logSkipOnce(state, key, `no reset reported (last seen ${cachedReset})`);
262
+ return;
263
+ }
264
+ if (liveReset) state.resetCache[key] = liveReset;
238
265
 
239
266
  if (
240
267
  providerConfig.skipWhenBlockingQuotaExhausted &&
241
268
  hasExhaustedBlockingQuota(quotas, providerConfig.quotaKey)
242
- )
269
+ ) {
270
+ logSkipOnce(state, key, `skip ping (blocking quota exhausted, reset ${resetAt})`);
243
271
  return;
244
- if (isQuotaExhausted(quota)) return;
272
+ }
273
+ if (isQuotaExhausted(quota)) {
274
+ logSkipOnce(state, key, `skip ping (session quota exhausted, reset ${resetAt})`);
275
+ return;
276
+ }
245
277
 
246
278
  const now = Date.now();
247
279
  const resetKey = normalizeResetKey(resetAt);
@@ -251,7 +283,10 @@ async function pingConnection(conn, provider, providerConfig, handler, deps, sta
251
283
  // Claude waits for reset. Codex pings only when resetAt slides, which means the 5h window is inactive.
252
284
  if (!shouldPingForReset(providerConfig, cachedReset, resetAt, now)) return;
253
285
  if (wasPingedRecently(connection, providerConfig.minPingIntervalMs, now)) return;
254
- if (lastPingedResetKey === resetKey) return;
286
+ if (lastPingedResetKey === resetKey) {
287
+ logSkipOnce(state, key, `skip ping (reset ${resetAt} already pinged)`);
288
+ return;
289
+ }
255
290
 
256
291
  const ok = await handler.sendPing(connection, providerConfig, proxyOptions, deps);
257
292
  if (!ok) {
@@ -40,7 +40,8 @@ function buildProxyOptions(cfg) {
40
40
  connectionProxyUrl: cfg?.connectionProxyUrl || "",
41
41
  connectionNoProxy: cfg?.connectionNoProxy || "",
42
42
  vercelRelayUrl: cfg?.vercelRelayUrl || "",
43
- strictProxy: false,
43
+ strictProxy: cfg?.strictProxy === true,
44
+ connectionProxyPoolId: cfg?.proxyPoolId || null,
44
45
  };
45
46
  }
46
47
 
@@ -78,7 +78,19 @@ async function loadActiveConnections() {
78
78
 
79
79
  async function refreshOne(connection) {
80
80
  const { checkAndRefreshToken } = await import("./tokenRefresh.js");
81
- return checkAndRefreshToken(connection.provider, connection, { force: true });
81
+ // Resolve the connection's proxy config so refresh honours the pool's
82
+ // strictProxy flag (YAN-651): never fall back to direct when strict is on.
83
+ const { resolveConnectionProxyConfig } = await import("../../lib/network/connectionProxy.js");
84
+ const cfg = await resolveConnectionProxyConfig(connection.providerSpecificData || {});
85
+ const proxyOptions = {
86
+ connectionProxyEnabled: cfg.connectionProxyEnabled === true,
87
+ connectionProxyUrl: cfg.connectionProxyUrl || "",
88
+ connectionNoProxy: cfg.connectionNoProxy || "",
89
+ vercelRelayUrl: cfg.vercelRelayUrl || "",
90
+ strictProxy: cfg.strictProxy === true,
91
+ connectionProxyPoolId: cfg.proxyPoolId || null,
92
+ };
93
+ return checkAndRefreshToken(connection.provider, connection, { force: true, proxyOptions });
82
94
  }
83
95
 
84
96
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tokenhop",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "tokenhop CLI - Start and manage tokenhop server",
5
5
  "bin": {
6
6
  "tokenhop": "cli.js"
@@ -305,9 +305,11 @@ async function handleCreateCombo() {
305
305
  // Create combo
306
306
  showStatus("Creating combo...", "info");
307
307
 
308
+ // The API stores model id strings (alias/model, as the dashboard sends),
309
+ // not the /api/models row objects (YAN-693).
308
310
  const createResult = await api.createCombo({
309
311
  name,
310
- models: selectedModels,
312
+ models: selectedModels.map((m) => m.routedModel || `${m.provider}/${m.model}`),
311
313
  });
312
314
 
313
315
  if (!createResult.success) {