zevairouter 1.0.146 → 1.0.148

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 (345) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/cli/app/.next-cli-build/BUILD_ID +1 -1
  3. package/cli/app/.next-cli-build/app-path-routes-manifest.json +8 -8
  4. package/cli/app/.next-cli-build/build-manifest.json +2 -2
  5. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/automation/page_client-reference-manifest.js +1 -1
  6. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/basic-chat/page_client-reference-manifest.js +1 -1
  7. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/[toolId]/page_client-reference-manifest.js +1 -1
  8. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/page_client-reference-manifest.js +1 -1
  9. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/page_client-reference-manifest.js +1 -1
  10. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/console-log/page_client-reference-manifest.js +1 -1
  11. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/context/page_client-reference-manifest.js +1 -1
  12. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/endpoint/page_client-reference-manifest.js +1 -1
  13. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page_client-reference-manifest.js +1 -1
  14. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/page_client-reference-manifest.js +1 -1
  15. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/combo/[id]/page_client-reference-manifest.js +1 -1
  16. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/web/page_client-reference-manifest.js +1 -1
  17. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/mitm/page_client-reference-manifest.js +1 -1
  18. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/page_client-reference-manifest.js +1 -1
  19. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/playground/page_client-reference-manifest.js +1 -1
  20. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/profile/page_client-reference-manifest.js +1 -1
  21. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/[id]/page_client-reference-manifest.js +1 -1
  22. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/new/page_client-reference-manifest.js +1 -1
  23. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/page.js +1 -1
  24. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/page_client-reference-manifest.js +1 -1
  25. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/proxy-pools/page_client-reference-manifest.js +1 -1
  26. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/pxpipe/page_client-reference-manifest.js +1 -1
  27. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/quota/page.js +1 -1
  28. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/quota/page_client-reference-manifest.js +1 -1
  29. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/terminal/page_client-reference-manifest.js +1 -1
  30. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/token-saver/page_client-reference-manifest.js +1 -1
  31. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/translator/page_client-reference-manifest.js +1 -1
  32. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/usage/page_client-reference-manifest.js +1 -1
  33. package/cli/app/.next-cli-build/server/app/_global-error/page_client-reference-manifest.js +1 -1
  34. package/cli/app/.next-cli-build/server/app/_global-error.html +1 -1
  35. package/cli/app/.next-cli-build/server/app/_global-error.rsc +1 -1
  36. package/cli/app/.next-cli-build/server/app/_global-error.segments/_full.segment.rsc +1 -1
  37. package/cli/app/.next-cli-build/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  38. package/cli/app/.next-cli-build/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  39. package/cli/app/.next-cli-build/server/app/_global-error.segments/_head.segment.rsc +1 -1
  40. package/cli/app/.next-cli-build/server/app/_global-error.segments/_index.segment.rsc +1 -1
  41. package/cli/app/.next-cli-build/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  42. package/cli/app/.next-cli-build/server/app/_not-found/page_client-reference-manifest.js +1 -1
  43. package/cli/app/.next-cli-build/server/app/_not-found.html +1 -1
  44. package/cli/app/.next-cli-build/server/app/_not-found.rsc +4 -4
  45. package/cli/app/.next-cli-build/server/app/_not-found.segments/_full.segment.rsc +4 -4
  46. package/cli/app/.next-cli-build/server/app/_not-found.segments/_head.segment.rsc +1 -1
  47. package/cli/app/.next-cli-build/server/app/_not-found.segments/_index.segment.rsc +4 -4
  48. package/cli/app/.next-cli-build/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  49. package/cli/app/.next-cli-build/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  50. package/cli/app/.next-cli-build/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  51. package/cli/app/.next-cli-build/server/app/api/models/route.js +1 -1
  52. package/cli/app/.next-cli-build/server/app/api/providers/route.js +1 -1
  53. package/cli/app/.next-cli-build/server/app/api/providers/validate/route.js +1 -1
  54. package/cli/app/.next-cli-build/server/app/api/translator/console-logs/route.js +1 -1
  55. package/cli/app/.next-cli-build/server/app/api/translator/console-logs/stream/route.js +1 -1
  56. package/cli/app/.next-cli-build/server/app/api/version/route.js +1 -1
  57. package/cli/app/.next-cli-build/server/app/api/version/shutdown/route.js +1 -1
  58. package/cli/app/.next-cli-build/server/app/api/version/update/route.js +1 -1
  59. package/cli/app/.next-cli-build/server/app/callback/page_client-reference-manifest.js +1 -1
  60. package/cli/app/.next-cli-build/server/app/callback.html +1 -1
  61. package/cli/app/.next-cli-build/server/app/callback.rsc +4 -4
  62. package/cli/app/.next-cli-build/server/app/callback.segments/_full.segment.rsc +4 -4
  63. package/cli/app/.next-cli-build/server/app/callback.segments/_head.segment.rsc +1 -1
  64. package/cli/app/.next-cli-build/server/app/callback.segments/_index.segment.rsc +4 -4
  65. package/cli/app/.next-cli-build/server/app/callback.segments/_tree.segment.rsc +2 -2
  66. package/cli/app/.next-cli-build/server/app/callback.segments/callback/__PAGE__.segment.rsc +1 -1
  67. package/cli/app/.next-cli-build/server/app/callback.segments/callback.segment.rsc +1 -1
  68. package/cli/app/.next-cli-build/server/app/dashboard/automation.html +1 -1
  69. package/cli/app/.next-cli-build/server/app/dashboard/automation.rsc +6 -6
  70. package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/!KGRhc2hib2FyZCk/dashboard/automation/__PAGE__.segment.rsc +2 -2
  71. package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/!KGRhc2hib2FyZCk/dashboard/automation.segment.rsc +1 -1
  72. package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  73. package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  74. package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/_full.segment.rsc +6 -6
  75. package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/_head.segment.rsc +1 -1
  76. package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/_index.segment.rsc +4 -4
  77. package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/_tree.segment.rsc +2 -2
  78. package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.html +1 -1
  79. package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.rsc +6 -6
  80. package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard/basic-chat/__PAGE__.segment.rsc +2 -2
  81. package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard/basic-chat.segment.rsc +1 -1
  82. package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  83. package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  84. package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_full.segment.rsc +6 -6
  85. package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_head.segment.rsc +1 -1
  86. package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_index.segment.rsc +4 -4
  87. package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_tree.segment.rsc +2 -2
  88. package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.html +1 -1
  89. package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.rsc +6 -6
  90. package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard/cli-tools/__PAGE__.segment.rsc +2 -2
  91. package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard/cli-tools.segment.rsc +1 -1
  92. package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  93. package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  94. package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_full.segment.rsc +6 -6
  95. package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_head.segment.rsc +1 -1
  96. package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_index.segment.rsc +4 -4
  97. package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_tree.segment.rsc +2 -2
  98. package/cli/app/.next-cli-build/server/app/dashboard/combos.html +1 -1
  99. package/cli/app/.next-cli-build/server/app/dashboard/combos.rsc +6 -6
  100. package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard/combos/__PAGE__.segment.rsc +2 -2
  101. package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard/combos.segment.rsc +1 -1
  102. package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  103. package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  104. package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/_full.segment.rsc +6 -6
  105. package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/_head.segment.rsc +1 -1
  106. package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/_index.segment.rsc +4 -4
  107. package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/_tree.segment.rsc +2 -2
  108. package/cli/app/.next-cli-build/server/app/dashboard/context.html +1 -1
  109. package/cli/app/.next-cli-build/server/app/dashboard/context.rsc +6 -6
  110. package/cli/app/.next-cli-build/server/app/dashboard/context.segments/!KGRhc2hib2FyZCk/dashboard/context/__PAGE__.segment.rsc +2 -2
  111. package/cli/app/.next-cli-build/server/app/dashboard/context.segments/!KGRhc2hib2FyZCk/dashboard/context.segment.rsc +1 -1
  112. package/cli/app/.next-cli-build/server/app/dashboard/context.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  113. package/cli/app/.next-cli-build/server/app/dashboard/context.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  114. package/cli/app/.next-cli-build/server/app/dashboard/context.segments/_full.segment.rsc +6 -6
  115. package/cli/app/.next-cli-build/server/app/dashboard/context.segments/_head.segment.rsc +1 -1
  116. package/cli/app/.next-cli-build/server/app/dashboard/context.segments/_index.segment.rsc +4 -4
  117. package/cli/app/.next-cli-build/server/app/dashboard/context.segments/_tree.segment.rsc +2 -2
  118. package/cli/app/.next-cli-build/server/app/dashboard/endpoint.html +1 -1
  119. package/cli/app/.next-cli-build/server/app/dashboard/endpoint.rsc +6 -6
  120. package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard/endpoint/__PAGE__.segment.rsc +2 -2
  121. package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard/endpoint.segment.rsc +1 -1
  122. package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  123. package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  124. package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/_full.segment.rsc +6 -6
  125. package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/_head.segment.rsc +1 -1
  126. package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/_index.segment.rsc +4 -4
  127. package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/_tree.segment.rsc +2 -2
  128. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.html +1 -1
  129. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.rsc +6 -6
  130. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers/web/__PAGE__.segment.rsc +2 -2
  131. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers/web.segment.rsc +1 -1
  132. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers.segment.rsc +1 -1
  133. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  134. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  135. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_full.segment.rsc +6 -6
  136. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_head.segment.rsc +1 -1
  137. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_index.segment.rsc +4 -4
  138. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_tree.segment.rsc +2 -2
  139. package/cli/app/.next-cli-build/server/app/dashboard/mitm.html +1 -1
  140. package/cli/app/.next-cli-build/server/app/dashboard/mitm.rsc +6 -6
  141. package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard/mitm/__PAGE__.segment.rsc +2 -2
  142. package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard/mitm.segment.rsc +1 -1
  143. package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  144. package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  145. package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/_full.segment.rsc +6 -6
  146. package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/_head.segment.rsc +1 -1
  147. package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/_index.segment.rsc +4 -4
  148. package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/_tree.segment.rsc +2 -2
  149. package/cli/app/.next-cli-build/server/app/dashboard/playground.html +1 -1
  150. package/cli/app/.next-cli-build/server/app/dashboard/playground.rsc +6 -6
  151. package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/!KGRhc2hib2FyZCk/dashboard/playground/__PAGE__.segment.rsc +2 -2
  152. package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/!KGRhc2hib2FyZCk/dashboard/playground.segment.rsc +1 -1
  153. package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  154. package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  155. package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/_full.segment.rsc +6 -6
  156. package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/_head.segment.rsc +1 -1
  157. package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/_index.segment.rsc +4 -4
  158. package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/_tree.segment.rsc +2 -2
  159. package/cli/app/.next-cli-build/server/app/dashboard/profile.html +1 -1
  160. package/cli/app/.next-cli-build/server/app/dashboard/profile.rsc +6 -6
  161. package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard/profile/__PAGE__.segment.rsc +2 -2
  162. package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard/profile.segment.rsc +1 -1
  163. package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  164. package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  165. package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/_full.segment.rsc +6 -6
  166. package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/_head.segment.rsc +1 -1
  167. package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/_index.segment.rsc +4 -4
  168. package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/_tree.segment.rsc +2 -2
  169. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.html +1 -1
  170. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.rsc +6 -6
  171. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers/new/__PAGE__.segment.rsc +2 -2
  172. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers/new.segment.rsc +1 -1
  173. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers.segment.rsc +1 -1
  174. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  175. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  176. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/_full.segment.rsc +6 -6
  177. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/_head.segment.rsc +1 -1
  178. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/_index.segment.rsc +4 -4
  179. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/_tree.segment.rsc +2 -2
  180. package/cli/app/.next-cli-build/server/app/dashboard/providers.html +1 -1
  181. package/cli/app/.next-cli-build/server/app/dashboard/providers.rsc +6 -6
  182. package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard/providers/__PAGE__.segment.rsc +2 -2
  183. package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard/providers.segment.rsc +1 -1
  184. package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  185. package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  186. package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/_full.segment.rsc +6 -6
  187. package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/_head.segment.rsc +1 -1
  188. package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/_index.segment.rsc +4 -4
  189. package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/_tree.segment.rsc +2 -2
  190. package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.html +1 -1
  191. package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.rsc +6 -6
  192. package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard/proxy-pools/__PAGE__.segment.rsc +2 -2
  193. package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard/proxy-pools.segment.rsc +1 -1
  194. package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  195. package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  196. package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_full.segment.rsc +6 -6
  197. package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_head.segment.rsc +1 -1
  198. package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_index.segment.rsc +4 -4
  199. package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_tree.segment.rsc +2 -2
  200. package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.html +1 -1
  201. package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.rsc +6 -6
  202. package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk/dashboard/pxpipe/__PAGE__.segment.rsc +2 -2
  203. package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk/dashboard/pxpipe.segment.rsc +1 -1
  204. package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  205. package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  206. package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_full.segment.rsc +6 -6
  207. package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_head.segment.rsc +1 -1
  208. package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_index.segment.rsc +4 -4
  209. package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_tree.segment.rsc +2 -2
  210. package/cli/app/.next-cli-build/server/app/dashboard/quota.html +2 -2
  211. package/cli/app/.next-cli-build/server/app/dashboard/quota.rsc +7 -7
  212. package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard/quota/__PAGE__.segment.rsc +3 -3
  213. package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard/quota.segment.rsc +1 -1
  214. package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  215. package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  216. package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/_full.segment.rsc +7 -7
  217. package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/_head.segment.rsc +1 -1
  218. package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/_index.segment.rsc +4 -4
  219. package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/_tree.segment.rsc +2 -2
  220. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing/page_client-reference-manifest.js +1 -1
  221. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.html +1 -1
  222. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.rsc +4 -4
  223. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_full.segment.rsc +4 -4
  224. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_head.segment.rsc +1 -1
  225. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_index.segment.rsc +4 -4
  226. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_tree.segment.rsc +2 -2
  227. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing/__PAGE__.segment.rsc +1 -1
  228. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing.segment.rsc +1 -1
  229. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings.segment.rsc +1 -1
  230. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard.segment.rsc +1 -1
  231. package/cli/app/.next-cli-build/server/app/dashboard/token-saver.html +1 -1
  232. package/cli/app/.next-cli-build/server/app/dashboard/token-saver.rsc +6 -6
  233. package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk/dashboard/token-saver/__PAGE__.segment.rsc +2 -2
  234. package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk/dashboard/token-saver.segment.rsc +1 -1
  235. package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  236. package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  237. package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/_full.segment.rsc +6 -6
  238. package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/_head.segment.rsc +1 -1
  239. package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/_index.segment.rsc +4 -4
  240. package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/_tree.segment.rsc +2 -2
  241. package/cli/app/.next-cli-build/server/app/dashboard/translator.html +1 -1
  242. package/cli/app/.next-cli-build/server/app/dashboard/translator.rsc +6 -6
  243. package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard/translator/__PAGE__.segment.rsc +2 -2
  244. package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard/translator.segment.rsc +1 -1
  245. package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  246. package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  247. package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/_full.segment.rsc +6 -6
  248. package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/_head.segment.rsc +1 -1
  249. package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/_index.segment.rsc +4 -4
  250. package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/_tree.segment.rsc +2 -2
  251. package/cli/app/.next-cli-build/server/app/dashboard/usage.html +1 -1
  252. package/cli/app/.next-cli-build/server/app/dashboard/usage.rsc +6 -6
  253. package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard/usage/__PAGE__.segment.rsc +2 -2
  254. package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard/usage.segment.rsc +1 -1
  255. package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  256. package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  257. package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/_full.segment.rsc +6 -6
  258. package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/_head.segment.rsc +1 -1
  259. package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/_index.segment.rsc +4 -4
  260. package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/_tree.segment.rsc +2 -2
  261. package/cli/app/.next-cli-build/server/app/dashboard.html +1 -1
  262. package/cli/app/.next-cli-build/server/app/dashboard.rsc +6 -6
  263. package/cli/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk/dashboard/__PAGE__.segment.rsc +2 -2
  264. package/cli/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  265. package/cli/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  266. package/cli/app/.next-cli-build/server/app/dashboard.segments/_full.segment.rsc +6 -6
  267. package/cli/app/.next-cli-build/server/app/dashboard.segments/_head.segment.rsc +1 -1
  268. package/cli/app/.next-cli-build/server/app/dashboard.segments/_index.segment.rsc +4 -4
  269. package/cli/app/.next-cli-build/server/app/dashboard.segments/_tree.segment.rsc +2 -2
  270. package/cli/app/.next-cli-build/server/app/index.html +1 -1
  271. package/cli/app/.next-cli-build/server/app/index.rsc +4 -4
  272. package/cli/app/.next-cli-build/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  273. package/cli/app/.next-cli-build/server/app/index.segments/_full.segment.rsc +4 -4
  274. package/cli/app/.next-cli-build/server/app/index.segments/_head.segment.rsc +1 -1
  275. package/cli/app/.next-cli-build/server/app/index.segments/_index.segment.rsc +4 -4
  276. package/cli/app/.next-cli-build/server/app/index.segments/_tree.segment.rsc +2 -2
  277. package/cli/app/.next-cli-build/server/app/landing/page_client-reference-manifest.js +1 -1
  278. package/cli/app/.next-cli-build/server/app/landing.html +1 -1
  279. package/cli/app/.next-cli-build/server/app/landing.rsc +5 -5
  280. package/cli/app/.next-cli-build/server/app/landing.segments/_full.segment.rsc +5 -5
  281. package/cli/app/.next-cli-build/server/app/landing.segments/_head.segment.rsc +1 -1
  282. package/cli/app/.next-cli-build/server/app/landing.segments/_index.segment.rsc +4 -4
  283. package/cli/app/.next-cli-build/server/app/landing.segments/_tree.segment.rsc +2 -2
  284. package/cli/app/.next-cli-build/server/app/landing.segments/landing/__PAGE__.segment.rsc +2 -2
  285. package/cli/app/.next-cli-build/server/app/landing.segments/landing.segment.rsc +1 -1
  286. package/cli/app/.next-cli-build/server/app/login/page_client-reference-manifest.js +1 -1
  287. package/cli/app/.next-cli-build/server/app/login.html +1 -1
  288. package/cli/app/.next-cli-build/server/app/login.rsc +5 -5
  289. package/cli/app/.next-cli-build/server/app/login.segments/_full.segment.rsc +5 -5
  290. package/cli/app/.next-cli-build/server/app/login.segments/_head.segment.rsc +1 -1
  291. package/cli/app/.next-cli-build/server/app/login.segments/_index.segment.rsc +4 -4
  292. package/cli/app/.next-cli-build/server/app/login.segments/_tree.segment.rsc +2 -2
  293. package/cli/app/.next-cli-build/server/app/login.segments/login/__PAGE__.segment.rsc +2 -2
  294. package/cli/app/.next-cli-build/server/app/login.segments/login.segment.rsc +1 -1
  295. package/cli/app/.next-cli-build/server/app/page_client-reference-manifest.js +1 -1
  296. package/cli/app/.next-cli-build/server/app-paths-manifest.json +8 -8
  297. package/cli/app/.next-cli-build/server/chunks/3155.js +1 -1
  298. package/cli/app/.next-cli-build/server/chunks/412.js +2 -2
  299. package/cli/app/.next-cli-build/server/chunks/4566.js +1 -1
  300. package/cli/app/.next-cli-build/server/chunks/4746.js +1 -1
  301. package/cli/app/.next-cli-build/server/chunks/5307.js +1 -1
  302. package/cli/app/.next-cli-build/server/chunks/5469.js +1 -1
  303. package/cli/app/.next-cli-build/server/chunks/5949.js +3 -3
  304. package/cli/app/.next-cli-build/server/chunks/8242.js +2 -2
  305. package/cli/app/.next-cli-build/server/chunks/8306.js +1 -1
  306. package/cli/app/.next-cli-build/server/chunks/8371.js +1 -1
  307. package/cli/app/.next-cli-build/server/chunks/9621.js +1 -1
  308. package/cli/app/.next-cli-build/server/middleware-build-manifest.js +1 -1
  309. package/cli/app/.next-cli-build/server/pages/404.html +1 -1
  310. package/cli/app/.next-cli-build/server/pages/500.html +1 -1
  311. package/cli/app/.next-cli-build/static/chunks/523-176a0660a9383518.js +3 -0
  312. package/cli/app/.next-cli-build/static/chunks/5497-8d0ec2995dc0a392.js +7 -0
  313. package/cli/app/.next-cli-build/static/chunks/{620-cc65df39cb93df1c.js → 620-16902cd352ef1d97.js} +1 -1
  314. package/cli/app/.next-cli-build/static/chunks/9126-7d5476f17beddfb0.js +1 -0
  315. package/cli/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/providers/page-2468e6ba8d1efeec.js +1 -0
  316. package/cli/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/quota/page-579bf915396efc69.js +1 -0
  317. package/cli/app/.next-cli-build/static/css/87ffa46afc2273f4.css +1 -0
  318. package/cli/app/CHANGELOG.md +22 -0
  319. package/cli/app/cli/hooks/cloakbrowserRuntime.js +111 -4
  320. package/cli/app/package.json +1 -1
  321. package/cli/hooks/cloakbrowserRuntime.js +111 -4
  322. package/cli/package.json +1 -1
  323. package/package.json +1 -1
  324. package/src/app/(dashboard)/dashboard/basic-chat/BasicChatPageClient.js +91 -38
  325. package/src/app/(dashboard)/dashboard/endpoint/EndpointPageClient.js +45 -38
  326. package/src/app/(dashboard)/dashboard/providers/page.js +136 -36
  327. package/src/app/(dashboard)/dashboard/usage/components/ProviderLimits/QuotaTable.js +15 -9
  328. package/src/app/(dashboard)/dashboard/usage/components/ProviderLimits/index.js +188 -120
  329. package/src/app/(dashboard)/dashboard/usage/components/ProviderTopology.js +128 -3
  330. package/src/lib/oauth/services/bulkImportBrowserEngine.js +36 -0
  331. package/src/lib/oauth/services/codebuddyCnBulkImportManager.js +469 -172
  332. package/src/lib/oauth/services/codebuddyCnPhoneAutomation.js +16 -2
  333. package/src/lib/oauth/services/kiroBulkImportManager.js +7 -1
  334. package/src/shared/components/Header.js +4 -4
  335. package/src/shared/components/HeaderLanguage.js +2 -1
  336. package/src/shared/components/HeaderMenu.js +2 -1
  337. package/src/shared/components/Toggle.js +28 -12
  338. package/cli/app/.next-cli-build/static/chunks/523-078802482e95c757.js +0 -3
  339. package/cli/app/.next-cli-build/static/chunks/5497-7f6609cd427c6525.js +0 -7
  340. package/cli/app/.next-cli-build/static/chunks/9126-9e1755f122b943cd.js +0 -1
  341. package/cli/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/providers/page-847b19cd29966941.js +0 -1
  342. package/cli/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/quota/page-6050ac2547c62b54.js +0 -1
  343. package/cli/app/.next-cli-build/static/css/1472cd17dfd55a13.css +0 -1
  344. /package/cli/app/.next-cli-build/static/{DeFI037NxtdV4EpLD2ihz → kmlfntQuBCJ_ni8__OiKd}/_buildManifest.js +0 -0
  345. /package/cli/app/.next-cli-build/static/{DeFI037NxtdV4EpLD2ihz → kmlfntQuBCJ_ni8__OiKd}/_ssgManifest.js +0 -0
@@ -39,6 +39,91 @@ function hasPackage(name) {
39
39
  return fs.existsSync(path.join(getRuntimeNodeModules(), name, "package.json"));
40
40
  }
41
41
 
42
+ function parseSemver(value) {
43
+ const match = String(value || "").trim().match(
44
+ /^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/
45
+ );
46
+ if (!match) return null;
47
+ return {
48
+ major: Number.parseInt(match[1], 10),
49
+ minor: Number.parseInt(match[2], 10),
50
+ patch: Number.parseInt(match[3], 10),
51
+ prerelease: match[4] ? match[4].split(".") : [],
52
+ };
53
+ }
54
+
55
+ function comparePrerelease(left, right) {
56
+ if (left.length === 0 && right.length === 0) return 0;
57
+ if (left.length === 0) return 1;
58
+ if (right.length === 0) return -1;
59
+
60
+ const count = Math.max(left.length, right.length);
61
+ for (let i = 0; i < count; i += 1) {
62
+ if (left[i] === undefined) return -1;
63
+ if (right[i] === undefined) return 1;
64
+ if (left[i] === right[i]) continue;
65
+
66
+ const leftNumeric = /^\d+$/.test(left[i]);
67
+ const rightNumeric = /^\d+$/.test(right[i]);
68
+ if (leftNumeric && rightNumeric) {
69
+ return Number.parseInt(left[i], 10) < Number.parseInt(right[i], 10) ? -1 : 1;
70
+ }
71
+ if (leftNumeric !== rightNumeric) return leftNumeric ? -1 : 1;
72
+ return left[i] < right[i] ? -1 : 1;
73
+ }
74
+ return 0;
75
+ }
76
+
77
+ function compareSemver(left, right) {
78
+ for (const key of ["major", "minor", "patch"]) {
79
+ if (left[key] !== right[key]) return left[key] < right[key] ? -1 : 1;
80
+ }
81
+ return comparePrerelease(left.prerelease, right.prerelease);
82
+ }
83
+
84
+ function satisfiesCaretRange(version, range) {
85
+ const installed = parseSemver(version);
86
+ const rangeMatch = String(range || "").trim().match(/^\^\s*(.+)$/);
87
+ const minimum = parseSemver(rangeMatch?.[1]);
88
+ if (!installed || !minimum) return false;
89
+
90
+ // Stable runtime requirements must never accept a prerelease implicitly.
91
+ if (installed.prerelease.length > 0 && minimum.prerelease.length === 0) return false;
92
+
93
+ let upper;
94
+ if (minimum.major > 0) {
95
+ upper = { major: minimum.major + 1, minor: 0, patch: 0, prerelease: [] };
96
+ } else if (minimum.minor > 0) {
97
+ upper = { major: 0, minor: minimum.minor + 1, patch: 0, prerelease: [] };
98
+ } else {
99
+ upper = { major: 0, minor: 0, patch: minimum.patch + 1, prerelease: [] };
100
+ }
101
+
102
+ return compareSemver(installed, minimum) >= 0 && compareSemver(installed, upper) < 0;
103
+ }
104
+
105
+ function getRuntimePackageVersion(name) {
106
+ try {
107
+ const packageJson = JSON.parse(
108
+ fs.readFileSync(path.join(getRuntimeNodeModules(), name, "package.json"), "utf8")
109
+ );
110
+ return typeof packageJson.version === "string" ? packageJson.version : null;
111
+ } catch {
112
+ return null;
113
+ }
114
+ }
115
+
116
+ function isCloakbrowserRuntimeCompatible(mod, installedVersion) {
117
+ return !!mod?.launch && satisfiesCaretRange(installedVersion, CLOAKBROWSER_VERSION);
118
+ }
119
+
120
+ function clearRuntimePackageCache(name) {
121
+ const packageRoot = `${path.join(getRuntimeNodeModules(), name)}${path.sep}`;
122
+ for (const modulePath of Object.keys(require.cache)) {
123
+ if (modulePath.startsWith(packageRoot)) delete require.cache[modulePath];
124
+ }
125
+ }
126
+
42
127
  function tryRequireCloakbrowser() {
43
128
  try {
44
129
  const rreq = getRuntimeRequire();
@@ -83,7 +168,13 @@ function loadCloakbrowserModule() {
83
168
  * playwright-core is the drive peer (no stock Chromium binary download).
84
169
  */
85
170
  function ensureCloakbrowserRuntime({ silent = false } = {}) {
86
- if (cachedReady?.ok && cachedReady.module && tryRequireMmdb() && hasPackage(PLAYWRIGHT_CORE_PACKAGE)) {
171
+ let installedCloakVersion = getRuntimePackageVersion(CLOAKBROWSER_PACKAGE);
172
+ if (
173
+ cachedReady?.ok
174
+ && isCloakbrowserRuntimeCompatible(cachedReady.module, installedCloakVersion)
175
+ && tryRequireMmdb()
176
+ && hasPackage(PLAYWRIGHT_CORE_PACKAGE)
177
+ ) {
87
178
  return cachedReady;
88
179
  }
89
180
 
@@ -94,7 +185,6 @@ function ensureCloakbrowserRuntime({ silent = false } = {}) {
94
185
  process.env.NODE_PATH = env.NODE_PATH;
95
186
  // Re-init module paths for already-running process
96
187
  try {
97
- // eslint-disable-next-line no-underscore-dangle
98
188
  require("module").Module._initPaths();
99
189
  } catch {
100
190
  /* ignore */
@@ -105,7 +195,7 @@ function ensureCloakbrowserRuntime({ silent = false } = {}) {
105
195
  }
106
196
 
107
197
  let mod = tryRequireCloakbrowser();
108
- const needCloak = !mod?.launch;
198
+ const needCloak = !isCloakbrowserRuntimeCompatible(mod, installedCloakVersion);
109
199
  const needMmdb = !tryRequireMmdb() && !hasPackage(MMDB_PACKAGE);
110
200
  const needPwCore = !hasPackage(PLAYWRIGHT_CORE_PACKAGE);
111
201
 
@@ -133,9 +223,12 @@ function ensureCloakbrowserRuntime({ silent = false } = {}) {
133
223
  err.code = "CLOAKBROWSER_INSTALL_FAILED";
134
224
  return { ok: false, error: err };
135
225
  }
226
+
227
+ if (needCloak) clearRuntimePackageCache(CLOAKBROWSER_PACKAGE);
136
228
  }
137
229
 
138
230
  mod = tryRequireCloakbrowser();
231
+ installedCloakVersion = getRuntimePackageVersion(CLOAKBROWSER_PACKAGE);
139
232
  if (!mod?.launch) {
140
233
  const err = new Error(
141
234
  `cloakbrowser installed but launch() is missing. Reinstall: cd "${getRuntimeDir()}" && npm install ${CLOAKBROWSER_PACKAGE}@${CLOAKBROWSER_VERSION} ${MMDB_PACKAGE}@${MMDB_VERSION} ${PLAYWRIGHT_CORE_PACKAGE}@${PLAYWRIGHT_CORE_VERSION}`
@@ -144,6 +237,14 @@ function ensureCloakbrowserRuntime({ silent = false } = {}) {
144
237
  return { ok: false, error: err };
145
238
  }
146
239
 
240
+ if (!satisfiesCaretRange(installedCloakVersion, CLOAKBROWSER_VERSION)) {
241
+ const err = new Error(
242
+ `cloakbrowser version mismatch: installed ${installedCloakVersion || "unknown"}, required ${CLOAKBROWSER_VERSION}. Reinstall: cd "${getRuntimeDir()}" && npm install ${CLOAKBROWSER_PACKAGE}@${CLOAKBROWSER_VERSION}`
243
+ );
244
+ err.code = "CLOAKBROWSER_VERSION_MISMATCH";
245
+ return { ok: false, error: err };
246
+ }
247
+
147
248
  if (!tryRequireMmdb() && !hasPackage(MMDB_PACKAGE)) {
148
249
  const err = new Error(
149
250
  `mmdb-lib is required for geoip: true. Install: cd "${getRuntimeDir()}" && npm install ${MMDB_PACKAGE}@${MMDB_VERSION}`
@@ -152,7 +253,7 @@ function ensureCloakbrowserRuntime({ silent = false } = {}) {
152
253
  return { ok: false, error: err };
153
254
  }
154
255
 
155
- cachedReady = { ok: true, module: mod };
256
+ cachedReady = { ok: true, module: mod, version: installedCloakVersion };
156
257
  return cachedReady;
157
258
  }
158
259
 
@@ -165,4 +266,10 @@ module.exports = {
165
266
  MMDB_VERSION,
166
267
  PLAYWRIGHT_CORE_PACKAGE,
167
268
  PLAYWRIGHT_CORE_VERSION,
269
+ __test__: {
270
+ parseSemver,
271
+ compareSemver,
272
+ satisfiesCaretRange,
273
+ isCloakbrowserRuntimeCompatible,
274
+ },
168
275
  };
package/cli/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zevairouter-cli",
3
- "version": "1.0.146",
3
+ "version": "1.0.148",
4
4
  "description": "ZevaiRouter CLI - Start and manage ZevaiRouter server",
5
5
  "bin": {
6
6
  "zevai": "./cli.js"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zevairouter",
3
- "version": "1.0.146",
3
+ "version": "1.0.148",
4
4
  "description": "Self-hosted AI router: many providers, one OpenAI-compatible /v1 endpoint and dashboard",
5
5
  "bin": {
6
6
  "zevai": "./cli/cli.js"
@@ -32,6 +32,51 @@ const SUGGESTIONS = [
32
32
  "Summarize the key trade-offs",
33
33
  ];
34
34
 
35
+ // Mirrors the providers backed by /api/providers/[id]/models. Other providers
36
+ // already use the static catalog and should not trigger known-failing requests.
37
+ const LIVE_MODEL_PROVIDER_IDS = new Set([
38
+ "alicode",
39
+ "alicode-intl",
40
+ "anthropic",
41
+ "antigravity",
42
+ "assemblyai",
43
+ "byteplus",
44
+ "cerebras",
45
+ "chutes",
46
+ "claude",
47
+ "cline",
48
+ "clinepass",
49
+ "codex",
50
+ "cohere",
51
+ "deepseek",
52
+ "fireworks",
53
+ "gemini",
54
+ "gemini-cli",
55
+ "github",
56
+ "grok-cli",
57
+ "groq",
58
+ "hyperbolic",
59
+ "kimchi",
60
+ "kiro",
61
+ "mistral",
62
+ "nanobanana",
63
+ "nebius",
64
+ "nvidia",
65
+ "ollama",
66
+ "ollama-local",
67
+ "openai",
68
+ "openrouter",
69
+ "perplexity",
70
+ "perplexity-agent",
71
+ "qoder",
72
+ "qwen",
73
+ "siliconflow",
74
+ "together",
75
+ "vercel-ai-gateway",
76
+ "volcengine-ark",
77
+ "xai",
78
+ ]);
79
+
35
80
  marked.setOptions({
36
81
  gfm: true,
37
82
  breaks: true,
@@ -214,6 +259,17 @@ function finalizeProviderGroups(providerMap) {
214
259
  .sort((a, b) => a.providerName.localeCompare(b.providerName));
215
260
  }
216
261
 
262
+ function supportsLiveModelDiscovery(connection) {
263
+ const providerId = connection?.provider;
264
+ if (!providerId) return false;
265
+ if (LIVE_MODEL_PROVIDER_IDS.has(providerId)) return true;
266
+
267
+ const hasBaseUrl = Boolean(connection?.providerSpecificData?.baseUrl);
268
+ return hasBaseUrl && (
269
+ isOpenAICompatibleProvider(providerId) || isAnthropicCompatibleProvider(providerId)
270
+ );
271
+ }
272
+
217
273
  /** Fetch with hard timeout so one slow provider never blocks the UI forever. */
218
274
  async function fetchWithTimeout(url, options = {}, timeoutMs = 8000) {
219
275
  const controller = new AbortController();
@@ -245,29 +301,11 @@ export default function BasicChatPageClient() {
245
301
  const [providerGroups, setProviderGroups] = useState([]);
246
302
  const [loadingData, setLoadingData] = useState(true);
247
303
  const [loadError, setLoadError] = useState("");
248
- const [sessions, setSessions] = useState(() => {
249
- if (typeof window === "undefined") return [];
250
- try {
251
- const saved = safeParse(globalThis.localStorage.getItem(STORAGE_KEYS.sessions), []);
252
- return Array.isArray(saved) ? saved.map((session) => ({
253
- ...session,
254
- messages: Array.isArray(session.messages) ? session.messages : [],
255
- })) : [];
256
- } catch { return []; }
257
- });
258
- const [activeSessionId, setActiveSessionId] = useState(() => {
259
- if (typeof window === "undefined") return "";
260
- return globalThis.localStorage.getItem(STORAGE_KEYS.activeSessionId) || "";
261
- });
262
- const [activeProviderId, setActiveProviderId] = useState(() => {
263
- if (typeof window === "undefined") return "";
264
- return globalThis.localStorage.getItem(STORAGE_KEYS.activeProviderId) || "";
265
- });
304
+ const [sessions, setSessions] = useState([]);
305
+ const [activeSessionId, setActiveSessionId] = useState("");
306
+ const [activeProviderId, setActiveProviderId] = useState("");
266
307
  const [activeModelId, setActiveModelId] = useState("");
267
- const [draft, setDraft] = useState(() => {
268
- if (typeof window === "undefined") return "";
269
- return globalThis.localStorage.getItem(STORAGE_KEYS.draft) || "";
270
- });
308
+ const [draft, setDraft] = useState("");
271
309
  const [attachments, setAttachments] = useState([]);
272
310
  const [isSending, setIsSending] = useState(false);
273
311
  const [streamingMessageId, setStreamingMessageId] = useState("");
@@ -278,16 +316,8 @@ export default function BasicChatPageClient() {
278
316
  const [historyOpen, setHistoryOpen] = useState(false);
279
317
  const [settingsOpen, setSettingsOpen] = useState(false);
280
318
  const [copiedId, setCopiedId] = useState("");
281
- const [temperature, setTemperature] = useState(() => {
282
- if (typeof window === "undefined") return 0.7;
283
- const raw = globalThis.localStorage.getItem(STORAGE_KEYS.temperature);
284
- const n = Number(raw);
285
- return Number.isFinite(n) ? Math.min(2, Math.max(0, n)) : 0.7;
286
- });
287
- const [systemPrompt, setSystemPrompt] = useState(() => {
288
- if (typeof window === "undefined") return "";
289
- return globalThis.localStorage.getItem(STORAGE_KEYS.systemPrompt) || "";
290
- });
319
+ const [temperature, setTemperature] = useState(0.7);
320
+ const [systemPrompt, setSystemPrompt] = useState("");
291
321
  const fileInputRef = useRef(null);
292
322
  const abortRef = useRef(null);
293
323
  const initializedRef = useRef(false);
@@ -298,8 +328,27 @@ export default function BasicChatPageClient() {
298
328
  const messagesEndRef = useRef(null);
299
329
 
300
330
  useEffect(() => {
301
- // eslint-disable-next-line react-hooks/set-state-in-effect -- hydration gate: flags client mount so lazy localStorage reads (in useState initializers) only persist after hydration
302
- setIsHydrated(true);
331
+ try {
332
+ const saved = safeParse(globalThis.localStorage.getItem(STORAGE_KEYS.sessions), []);
333
+ const savedSessions = Array.isArray(saved) ? saved.map((session) => ({
334
+ ...session,
335
+ messages: Array.isArray(session.messages) ? session.messages : [],
336
+ })) : [];
337
+ const storedTemperature = globalThis.localStorage.getItem(STORAGE_KEYS.temperature);
338
+ const rawTemperature = storedTemperature === null ? Number.NaN : Number(storedTemperature);
339
+
340
+ // eslint-disable-next-line react-hooks/set-state-in-effect -- restore client-only persisted state after deterministic SSR hydration
341
+ setSessions(savedSessions);
342
+ setActiveSessionId(globalThis.localStorage.getItem(STORAGE_KEYS.activeSessionId) || "");
343
+ setActiveProviderId(globalThis.localStorage.getItem(STORAGE_KEYS.activeProviderId) || "");
344
+ setDraft(globalThis.localStorage.getItem(STORAGE_KEYS.draft) || "");
345
+ setTemperature(Number.isFinite(rawTemperature) ? Math.min(2, Math.max(0, rawTemperature)) : 0.7);
346
+ setSystemPrompt(globalThis.localStorage.getItem(STORAGE_KEYS.systemPrompt) || "");
347
+ } catch {
348
+ // Storage may be unavailable in privacy-restricted browser contexts.
349
+ } finally {
350
+ setIsHydrated(true);
351
+ }
303
352
  }, []);
304
353
 
305
354
  useEffect(() => {
@@ -353,8 +402,10 @@ export default function BasicChatPageClient() {
353
402
  .filter(Boolean);
354
403
  providerMap.get(providerId).models.push(...staticModels);
355
404
 
356
- // Live list once per provider — first active connection is enough
357
- liveFetchTargets.push(connection);
405
+ // Live list once per provider — first active connection is enough.
406
+ if (staticModels.length === 0 && supportsLiveModelDiscovery(connection)) {
407
+ liveFetchTargets.push(connection);
408
+ }
358
409
  }
359
410
 
360
411
  const group = providerMap.get(providerId);
@@ -457,16 +508,18 @@ export default function BasicChatPageClient() {
457
508
  }, []);
458
509
 
459
510
  useEffect(() => {
511
+ if (!isHydrated) return;
460
512
  try {
461
513
  globalThis.localStorage.setItem(STORAGE_KEYS.temperature, String(temperature));
462
514
  } catch { /* ignore */ }
463
- }, [temperature]);
515
+ }, [isHydrated, temperature]);
464
516
 
465
517
  useEffect(() => {
518
+ if (!isHydrated) return;
466
519
  try {
467
520
  globalThis.localStorage.setItem(STORAGE_KEYS.systemPrompt, systemPrompt);
468
521
  } catch { /* ignore */ }
469
- }, [systemPrompt]);
522
+ }, [isHydrated, systemPrompt]);
470
523
 
471
524
  const modelIndex = useMemo(() => {
472
525
  const map = new Map();
@@ -866,13 +866,13 @@ export default function APIPageClient({ machineId }) {
866
866
  <Input aria-label="Cloudflare Tunnel endpoint URL" value={`${tunnelPublicUrl || tunnelUrl}/v1`} readOnly className="w-full min-w-0 font-mono text-sm sm:flex-1" />
867
867
  <button
868
868
  onClick={() => copy(`${tunnelPublicUrl || tunnelUrl}/v1`, "tunnel_url")}
869
- className="p-2 hover:bg-black/5 dark:hover:bg-white/5 rounded text-text-muted hover:text-primary transition-colors shrink-0"
869
+ className="flex size-11 shrink-0 items-center justify-center rounded-xl text-text-muted transition-colors hover:bg-black/5 hover:text-primary dark:hover:bg-white/5 sm:size-9 sm:rounded-lg"
870
870
  >
871
871
  <span className="material-symbols-outlined text-[18px]">{copied === "tunnel_url" ? "check" : "content_copy"}</span>
872
872
  </button>
873
873
  <button
874
874
  onClick={() => setShowDisableTunnelModal(true)}
875
- className="p-2 hover:bg-red-500/10 rounded text-red-500 transition-colors shrink-0"
875
+ className="flex size-11 shrink-0 items-center justify-center rounded-xl text-red-500 transition-colors hover:bg-red-500/10 sm:size-9 sm:rounded-lg"
876
876
  title="Disable Tunnel"
877
877
  >
878
878
  <span className="material-symbols-outlined text-[18px]">power_settings_new</span>
@@ -886,7 +886,7 @@ export default function APIPageClient({ machineId }) {
886
886
  </div>
887
887
  <button
888
888
  onClick={() => setShowDisableTunnelModal(true)}
889
- className="p-2 hover:bg-red-500/10 rounded text-red-500 transition-colors shrink-0"
889
+ className="flex size-11 shrink-0 items-center justify-center rounded-xl text-red-500 transition-colors hover:bg-red-500/10 sm:size-9 sm:rounded-lg"
890
890
  title="Disable Tunnel"
891
891
  >
892
892
  <span className="material-symbols-outlined text-[18px]">power_settings_new</span>
@@ -900,7 +900,7 @@ export default function APIPageClient({ machineId }) {
900
900
  </div>
901
901
  <button
902
902
  onClick={() => { setTunnelLoading(false); setTunnelProgress(""); }}
903
- className="p-2 hover:bg-red-500/10 rounded text-red-500 transition-colors shrink-0"
903
+ className="flex size-11 shrink-0 items-center justify-center rounded-xl text-red-500 transition-colors hover:bg-red-500/10 sm:size-9 sm:rounded-lg"
904
904
  title="Stop"
905
905
  >
906
906
  <span className="material-symbols-outlined text-[18px]">power_settings_new</span>
@@ -912,7 +912,7 @@ export default function APIPageClient({ machineId }) {
912
912
  <span className="material-symbols-outlined text-sm">error</span>
913
913
  {tunnelStatus.message}
914
914
  </div>
915
- <Button size="sm" icon="cloud_upload" onClick={() => setShowEnableTunnelModal(true)}>Enable</Button>
915
+ <Button size="sm" icon="cloud_upload" className="min-h-11 sm:min-h-8" onClick={() => setShowEnableTunnelModal(true)}>Enable</Button>
916
916
  </>
917
917
  ) : tunnelChecking ? (
918
918
  <>
@@ -922,7 +922,7 @@ export default function APIPageClient({ machineId }) {
922
922
  </div>
923
923
  <button
924
924
  onClick={() => setTunnelChecking(false)}
925
- className="p-2 hover:bg-red-500/10 rounded text-red-500 transition-colors shrink-0"
925
+ className="flex size-11 shrink-0 items-center justify-center rounded-xl text-red-500 transition-colors hover:bg-red-500/10 sm:size-9 sm:rounded-lg"
926
926
  title="Stop"
927
927
  >
928
928
  <span className="material-symbols-outlined text-[18px]">power_settings_new</span>
@@ -932,6 +932,7 @@ export default function APIPageClient({ machineId }) {
932
932
  <Button
933
933
  size="sm"
934
934
  icon="cloud_upload"
935
+ className="min-h-11 sm:min-h-8"
935
936
  onClick={() => {
936
937
  if (isLoginUnsafe) {
937
938
  setTunnelStatus({ type: "error", message: `Security required: ${unsafeReason}` });
@@ -958,13 +959,13 @@ export default function APIPageClient({ machineId }) {
958
959
  <Input aria-label="Tailscale endpoint URL" value={`${tsUrl}/v1`} readOnly className="w-full min-w-0 font-mono text-sm sm:flex-1" />
959
960
  <button
960
961
  onClick={() => copy(`${tsUrl}/v1`, "ts_url")}
961
- className="p-2 hover:bg-black/5 dark:hover:bg-white/5 rounded text-text-muted hover:text-primary transition-colors shrink-0"
962
+ className="flex size-11 shrink-0 items-center justify-center rounded-xl text-text-muted transition-colors hover:bg-black/5 hover:text-primary dark:hover:bg-white/5 sm:size-9 sm:rounded-lg"
962
963
  >
963
964
  <span className="material-symbols-outlined text-[18px]">{copied === "ts_url" ? "check" : "content_copy"}</span>
964
965
  </button>
965
966
  <button
966
967
  onClick={() => setShowDisableTsModal(true)}
967
- className="p-2 hover:bg-red-500/10 rounded text-red-500 transition-colors shrink-0"
968
+ className="flex size-11 shrink-0 items-center justify-center rounded-xl text-red-500 transition-colors hover:bg-red-500/10 sm:size-9 sm:rounded-lg"
968
969
  title="Disable Tailscale"
969
970
  >
970
971
  <span className="material-symbols-outlined text-[18px]">power_settings_new</span>
@@ -978,7 +979,7 @@ export default function APIPageClient({ machineId }) {
978
979
  </div>
979
980
  <button
980
981
  onClick={() => setShowDisableTsModal(true)}
981
- className="p-2 hover:bg-red-500/10 rounded text-red-500 transition-colors shrink-0"
982
+ className="flex size-11 shrink-0 items-center justify-center rounded-xl text-red-500 transition-colors hover:bg-red-500/10 sm:size-9 sm:rounded-lg"
982
983
  title="Disable Tailscale"
983
984
  >
984
985
  <span className="material-symbols-outlined text-[18px]">power_settings_new</span>
@@ -1001,7 +1002,7 @@ export default function APIPageClient({ machineId }) {
1001
1002
  )}
1002
1003
  <button
1003
1004
  onClick={() => { setTsLoading(false); setTsConnecting(false); setTsProgress(""); clearUserAuth(); }}
1004
- className="p-2 hover:bg-red-500/10 rounded text-red-500 transition-colors shrink-0"
1005
+ className="flex size-11 shrink-0 items-center justify-center rounded-xl text-red-500 transition-colors hover:bg-red-500/10 sm:size-9 sm:rounded-lg"
1005
1006
  title="Stop"
1006
1007
  >
1007
1008
  <span className="material-symbols-outlined text-[18px]">power_settings_new</span>
@@ -1013,7 +1014,7 @@ export default function APIPageClient({ machineId }) {
1013
1014
  <span className="material-symbols-outlined text-sm">error</span>
1014
1015
  {tsStatus.message}
1015
1016
  </div>
1016
- <Button size="sm" icon="vpn_lock" onClick={handleOpenTsModal}>Enable</Button>
1017
+ <Button size="sm" icon="vpn_lock" className="min-h-11 sm:min-h-8" onClick={handleOpenTsModal}>Enable</Button>
1017
1018
  </>
1018
1019
  ) : (
1019
1020
  <Button
@@ -1026,7 +1027,7 @@ export default function APIPageClient({ machineId }) {
1026
1027
  }
1027
1028
  handleOpenTsModal();
1028
1029
  }}
1029
- className="bg-linear-to-r from-indigo-500 to-purple-500 hover:from-indigo-600 hover:to-purple-600 text-white!"
1030
+ className="min-h-11 sm:min-h-8"
1030
1031
  >
1031
1032
  Enable
1032
1033
  </Button>
@@ -1073,6 +1074,7 @@ export default function APIPageClient({ machineId }) {
1073
1074
  {(tunnelEnabled || tsEnabled) && (
1074
1075
  <div className="mt-4 pt-4 border-t border-border flex items-center gap-3">
1075
1076
  <Toggle
1077
+ touchTarget
1076
1078
  label="Allow dashboard access via tunnel"
1077
1079
  checked={tunnelDashboardAccess}
1078
1080
  onChange={() => handleTunnelDashboardAccess(!tunnelDashboardAccess)}
@@ -1099,7 +1101,7 @@ export default function APIPageClient({ machineId }) {
1099
1101
  </div>
1100
1102
  <Link
1101
1103
  href="/dashboard/token-saver"
1102
- className="inline-flex w-full shrink-0 items-center justify-center gap-1.5 rounded-lg border border-primary/25 bg-surface/80 px-3.5 py-2 text-sm font-semibold text-text-main shadow-sm transition-[border-color,color,transform] hover:translate-x-0.5 hover:border-primary/50 hover:text-primary sm:w-auto"
1104
+ className="inline-flex min-h-11 w-full shrink-0 items-center justify-center gap-1.5 rounded-xl border border-primary/25 bg-surface/80 px-3.5 py-2 text-sm font-semibold text-text-main shadow-sm transition-[border-color,color,transform] hover:translate-x-0.5 hover:border-primary/50 hover:text-primary sm:min-h-0 sm:w-auto sm:rounded-lg"
1103
1105
  >
1104
1106
  Open workspace
1105
1107
  <span className="material-symbols-outlined text-[16px]">arrow_forward</span>
@@ -1149,6 +1151,7 @@ export default function APIPageClient({ machineId }) {
1149
1151
  </div>
1150
1152
  <div className="shrink-0 self-end sm:self-auto">
1151
1153
  <Toggle
1154
+ touchTarget
1152
1155
  label="Require API key"
1153
1156
  checked={requireApiKey}
1154
1157
  onChange={() => handleRequireApiKey(!requireApiKey)}
@@ -1189,7 +1192,7 @@ export default function APIPageClient({ machineId }) {
1189
1192
  <button
1190
1193
  type="button"
1191
1194
  onClick={() => toggleKeyVisibility(key.id)}
1192
- className="p-1 hover:bg-black/5 dark:hover:bg-white/5 rounded text-text-muted hover:text-primary opacity-100 sm:opacity-0 sm:group-hover:opacity-100 transition-all shrink-0"
1195
+ className="flex size-11 shrink-0 items-center justify-center rounded-xl text-text-muted opacity-100 transition-all hover:bg-black/5 hover:text-primary dark:hover:bg-white/5 sm:size-7 sm:rounded-lg sm:opacity-0 sm:group-hover:opacity-100"
1193
1196
  title={visibleKeys.has(key.id) ? "Hide key" : "Show key"}
1194
1197
  aria-label={visibleKeys.has(key.id) ? "Hide API key" : "Show API key"}
1195
1198
  >
@@ -1200,7 +1203,7 @@ export default function APIPageClient({ machineId }) {
1200
1203
  <button
1201
1204
  type="button"
1202
1205
  onClick={() => handleCopyKey(key.id)}
1203
- className="p-1 hover:bg-black/5 dark:hover:bg-white/5 rounded text-text-muted hover:text-primary opacity-100 sm:opacity-0 sm:group-hover:opacity-100 transition-all shrink-0"
1206
+ className="flex size-11 shrink-0 items-center justify-center rounded-xl text-text-muted opacity-100 transition-all hover:bg-black/5 hover:text-primary dark:hover:bg-white/5 sm:size-7 sm:rounded-lg sm:opacity-0 sm:group-hover:opacity-100"
1204
1207
  title="Copy key"
1205
1208
  aria-label="Copy API key"
1206
1209
  >
@@ -1242,30 +1245,34 @@ export default function APIPageClient({ machineId }) {
1242
1245
  </div>
1243
1246
  </div>
1244
1247
  <div className="flex items-center gap-2">
1245
- <Toggle
1246
- size="sm"
1247
- disabled={keyPending === `toggle:${key.id}`}
1248
- checked={key.isActive ?? true}
1249
- onChange={(checked) => {
1250
- if (key.isActive && !checked) {
1251
- setConfirmState({
1252
- title: "Pause API Key",
1253
- message: `Pause API key "${key.name}"?\n\nThis key will stop working immediately but can be resumed later.`,
1254
- onConfirm: async () => {
1255
- setConfirmState(null);
1256
- handleToggleKey(key.id, checked);
1257
- }
1258
- });
1259
- } else {
1260
- handleToggleKey(key.id, checked);
1261
- }
1262
- }}
1263
- title={key.isActive ? "Pause key" : "Resume key"}
1264
- />
1248
+ <div className="flex size-11 items-center justify-center sm:size-auto">
1249
+ <Toggle
1250
+ size="sm"
1251
+ touchTarget
1252
+ disabled={keyPending === `toggle:${key.id}`}
1253
+ checked={key.isActive ?? true}
1254
+ onChange={(checked) => {
1255
+ if (key.isActive && !checked) {
1256
+ setConfirmState({
1257
+ title: "Pause API Key",
1258
+ message: `Pause API key "${key.name}"?\n\nThis key will stop working immediately but can be resumed later.`,
1259
+ onConfirm: async () => {
1260
+ setConfirmState(null);
1261
+ handleToggleKey(key.id, checked);
1262
+ }
1263
+ });
1264
+ } else {
1265
+ handleToggleKey(key.id, checked);
1266
+ }
1267
+ }}
1268
+ title={key.isActive ? "Pause key" : "Resume key"}
1269
+ />
1270
+ </div>
1265
1271
  <button
1266
1272
  disabled={keyPending === `delete:${key.id}`}
1267
1273
  onClick={() => handleDeleteKey(key.id)}
1268
- className="p-2 hover:bg-red-500/10 rounded text-red-500 opacity-100 sm:opacity-0 sm:group-hover:opacity-100 transition-all"
1274
+ className="flex size-11 items-center justify-center rounded-xl text-red-500 opacity-100 transition-all hover:bg-red-500/10 sm:size-9 sm:rounded-lg sm:opacity-0 sm:group-hover:opacity-100"
1275
+ aria-label={`Delete ${key.name}`}
1269
1276
  >
1270
1277
  <span className="material-symbols-outlined text-[18px]">delete</span>
1271
1278
  </button>
@@ -1515,7 +1522,7 @@ function EndpointRow({ label, url, copyId, copied, onCopy, badge, actions }) {
1515
1522
  <Input aria-label={`${label} endpoint URL`} value={url} readOnly className="w-full min-w-0 font-mono text-sm sm:flex-1" />
1516
1523
  <button
1517
1524
  onClick={() => onCopy(url, copyId)}
1518
- className="p-2 hover:bg-black/5 dark:hover:bg-white/5 rounded text-text-muted hover:text-primary transition-colors shrink-0"
1525
+ className="flex size-11 shrink-0 items-center justify-center rounded-xl text-text-muted transition-colors hover:bg-black/5 hover:text-primary dark:hover:bg-white/5 sm:size-9 sm:rounded-lg"
1519
1526
  aria-label={`Copy ${label} endpoint URL`}
1520
1527
  >
1521
1528
  <span className="material-symbols-outlined text-[18px]">{copied === copyId ? "check" : "content_copy"}</span>
@@ -1569,7 +1576,7 @@ function SecurityWarning({ message, action }) {
1569
1576
  {action && (
1570
1577
  <a
1571
1578
  href={action.href}
1572
- className="text-xs font-medium underline shrink-0 hover:opacity-80"
1579
+ className="inline-flex min-h-11 shrink-0 items-center text-xs font-medium underline hover:opacity-80 sm:min-h-0"
1573
1580
  onClick={action.href.startsWith("#") ? (e) => {
1574
1581
  e.preventDefault();
1575
1582
  document.getElementById(action.href.slice(1))?.scrollIntoView({ behavior: "smooth" });