zevairouter 1.0.146 → 1.0.147

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 (336) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/cli/app/.next-cli-build/BUILD_ID +1 -1
  3. package/cli/app/.next-cli-build/app-path-routes-manifest.json +11 -11
  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 +11 -11
  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/4746.js +1 -1
  300. package/cli/app/.next-cli-build/server/chunks/5307.js +1 -1
  301. package/cli/app/.next-cli-build/server/chunks/5469.js +1 -1
  302. package/cli/app/.next-cli-build/server/chunks/8242.js +2 -2
  303. package/cli/app/.next-cli-build/server/chunks/8306.js +1 -1
  304. package/cli/app/.next-cli-build/server/chunks/9621.js +1 -1
  305. package/cli/app/.next-cli-build/server/middleware-build-manifest.js +1 -1
  306. package/cli/app/.next-cli-build/server/pages/404.html +1 -1
  307. package/cli/app/.next-cli-build/server/pages/500.html +1 -1
  308. package/cli/app/.next-cli-build/static/chunks/523-176a0660a9383518.js +3 -0
  309. package/cli/app/.next-cli-build/static/chunks/5497-8d0ec2995dc0a392.js +7 -0
  310. package/cli/app/.next-cli-build/static/chunks/{620-cc65df39cb93df1c.js → 620-375754e53341e85b.js} +1 -1
  311. package/cli/app/.next-cli-build/static/chunks/9126-7d5476f17beddfb0.js +1 -0
  312. package/cli/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/providers/page-2468e6ba8d1efeec.js +1 -0
  313. package/cli/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/quota/page-579bf915396efc69.js +1 -0
  314. package/cli/app/.next-cli-build/static/css/87ffa46afc2273f4.css +1 -0
  315. package/cli/app/CHANGELOG.md +10 -0
  316. package/cli/app/package.json +1 -1
  317. package/cli/package.json +1 -1
  318. package/package.json +1 -1
  319. package/src/app/(dashboard)/dashboard/basic-chat/BasicChatPageClient.js +91 -38
  320. package/src/app/(dashboard)/dashboard/endpoint/EndpointPageClient.js +45 -38
  321. package/src/app/(dashboard)/dashboard/providers/page.js +136 -36
  322. package/src/app/(dashboard)/dashboard/usage/components/ProviderLimits/QuotaTable.js +15 -9
  323. package/src/app/(dashboard)/dashboard/usage/components/ProviderLimits/index.js +188 -120
  324. package/src/app/(dashboard)/dashboard/usage/components/ProviderTopology.js +128 -3
  325. package/src/shared/components/Header.js +4 -4
  326. package/src/shared/components/HeaderLanguage.js +2 -1
  327. package/src/shared/components/HeaderMenu.js +2 -1
  328. package/src/shared/components/Toggle.js +28 -12
  329. package/cli/app/.next-cli-build/static/chunks/523-078802482e95c757.js +0 -3
  330. package/cli/app/.next-cli-build/static/chunks/5497-7f6609cd427c6525.js +0 -7
  331. package/cli/app/.next-cli-build/static/chunks/9126-9e1755f122b943cd.js +0 -1
  332. package/cli/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/providers/page-847b19cd29966941.js +0 -1
  333. package/cli/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/quota/page-6050ac2547c62b54.js +0 -1
  334. package/cli/app/.next-cli-build/static/css/1472cd17dfd55a13.css +0 -1
  335. /package/cli/app/.next-cli-build/static/{DeFI037NxtdV4EpLD2ihz → y-U4C09T7DItXT7CZZV41}/_buildManifest.js +0 -0
  336. /package/cli/app/.next-cli-build/static/{DeFI037NxtdV4EpLD2ihz → y-U4C09T7DItXT7CZZV41}/_ssgManifest.js +0 -0
@@ -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" });
@@ -95,6 +95,12 @@ function getConnectionErrorTag(connection) {
95
95
 
96
96
  const PROVIDERS_DEFAULT_PAGE_SIZE = 20;
97
97
  const PROVIDERS_FETCH_TIMEOUT_MS = 8000;
98
+ const PROVIDER_STATUS_FILTERS = [
99
+ { value: "all", label: "All" },
100
+ { value: "connected", label: "Connected" },
101
+ { value: "ready", label: "Ready" },
102
+ { value: "setup", label: "Needs setup" },
103
+ ];
98
104
 
99
105
  async function fetchJsonWithTimeout(url) {
100
106
  const controller = new AbortController();
@@ -129,6 +135,13 @@ export default function ProvidersPage() {
129
135
  useState(false);
130
136
  const [testingMode, setTestingMode] = useState(null);
131
137
  const [testResults, setTestResults] = useState(null);
138
+ const [statusFilter, setStatusFilter] = useState("all");
139
+ const [collapsedSections, setCollapsedSections] = useState({
140
+ custom: false,
141
+ oauth: false,
142
+ free: true,
143
+ apikey: true,
144
+ });
132
145
  const notify = useNotificationStore();
133
146
  const searchQuery = useHeaderSearchStore((s) => s.query);
134
147
  const registerSearch = useHeaderSearchStore((s) => s.register);
@@ -142,7 +155,7 @@ export default function ProvidersPage() {
142
155
  useEffect(() => {
143
156
  // eslint-disable-next-line react-hooks/set-state-in-effect -- pagination reset: returns to page 1 when search query or page size changes
144
157
  setApikeyPage(1);
145
- }, [searchQuery, apikeyPageSize]);
158
+ }, [searchQuery, apikeyPageSize, statusFilter]);
146
159
 
147
160
  const matchSearch = (name) =>
148
161
  !searchQuery.trim() ||
@@ -158,16 +171,6 @@ export default function ProvidersPage() {
158
171
  return (a.name || "").localeCompare(b.name || "");
159
172
  });
160
173
 
161
- const sortItemsByPriority = (items, authType) =>
162
- [...items].sort((a, b) => {
163
- const sa = getProviderStats(a.id, authType);
164
- const sb = getProviderStats(b.id, authType);
165
- const ca = sa.connected > 0 ? 1 : 0;
166
- const cb = sb.connected > 0 ? 1 : 0;
167
- if (ca !== cb) return cb - ca;
168
- return (a.name || "").localeCompare(b.name || "");
169
- });
170
-
171
174
  useEffect(() => {
172
175
  const fetchData = async () => {
173
176
  try {
@@ -266,6 +269,21 @@ export default function ProvidersPage() {
266
269
  return { connected, error, total, errorCode, errorTime, allDisabled };
267
270
  };
268
271
 
272
+ const matchesStatusFilter = (providerId, provider, authType) => {
273
+ if (statusFilter === "all") return true;
274
+ const stats = getProviderStats(providerId, authType);
275
+ if (statusFilter === "connected") return stats.connected > 0;
276
+ if (statusFilter === "ready") return stats.connected === 0 && provider.noAuth === true;
277
+ return stats.connected === 0 && provider.noAuth !== true;
278
+ };
279
+
280
+ const toggleSection = (section) => {
281
+ setCollapsedSections((current) => ({
282
+ ...current,
283
+ [section]: !current[section],
284
+ }));
285
+ };
286
+
269
287
  // Toggle all connections for a provider on/off
270
288
  const handleToggleProvider = async (providerId, authType, newActive) => {
271
289
  const providerConns = connections.filter(
@@ -323,7 +341,7 @@ export default function ProvidersPage() {
323
341
  textIcon: "OC",
324
342
  apiType: node.apiType,
325
343
  }))
326
- .filter((p) => matchSearch(p.name));
344
+ .filter((p) => matchSearch(p.name) && matchesStatusFilter(p.id, p, "apikey"));
327
345
 
328
346
  const anthropicCompatibleProviders = providerNodes
329
347
  .filter((node) => node.type === "anthropic-compatible")
@@ -333,23 +351,28 @@ export default function ProvidersPage() {
333
351
  color: "#D97757",
334
352
  textIcon: "AC",
335
353
  }))
336
- .filter((p) => matchSearch(p.name));
354
+ .filter((p) => matchSearch(p.name) && matchesStatusFilter(p.id, p, "apikey"));
337
355
 
338
356
  const oauthEntries = Object.entries(OAUTH_PROVIDERS).filter(
339
- ([, info]) => !info.hidden && matchSearch(info.name),
357
+ ([key, info]) => !info.hidden && matchSearch(info.name) && matchesStatusFilter(key, info, "oauth"),
340
358
  );
341
359
  const freeEntries = Object.entries(FREE_PROVIDERS).filter(
342
- ([, info]) => !info.hidden && matchSearch(info.name),
360
+ ([key, info]) => {
361
+ const hasApiKeyMode = Array.isArray(info?.authModes) && info.authModes.includes("apikey");
362
+ const authTypes = hasApiKeyMode ? ["oauth", "apikey"] : "oauth";
363
+ return !info.hidden && matchSearch(info.name) && matchesStatusFilter(key, info, authTypes);
364
+ },
343
365
  );
344
366
  const freeTierEntries = Object.entries(FREE_TIER_PROVIDERS).filter(
345
- ([, info]) => !info.hidden && matchSearch(info.name),
367
+ ([key, info]) => !info.hidden && matchSearch(info.name) && matchesStatusFilter(key, info, "apikey"),
346
368
  );
347
369
  const apikeyEntries = sortByPriority(
348
370
  Object.entries(APIKEY_PROVIDERS).filter(
349
- ([, info]) =>
371
+ ([key, info]) =>
350
372
  !info.hidden &&
351
373
  (info.serviceKinds ?? ["llm"]).includes("llm") &&
352
- matchSearch(info.name),
374
+ matchSearch(info.name) &&
375
+ matchesStatusFilter(key, info, "apikey"),
353
376
  ),
354
377
  "apikey",
355
378
  );
@@ -376,6 +399,10 @@ export default function ProvidersPage() {
376
399
  apikeyEntries.length > 0 ||
377
400
  compatibleProviders.length > 0 ||
378
401
  anthropicCompatibleProviders.length > 0;
402
+ const showCustomSection =
403
+ compatibleProviders.length > 0 ||
404
+ anthropicCompatibleProviders.length > 0 ||
405
+ (statusFilter === "all" && !searchQuery.trim());
379
406
 
380
407
  return (
381
408
  <div className="flex min-w-0 flex-col gap-6 px-1 sm:px-0">
@@ -415,28 +442,54 @@ export default function ProvidersPage() {
415
442
  </div>
416
443
  )}
417
444
 
445
+ <div className="overflow-x-auto pb-0.5 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden">
446
+ <div className="inline-flex min-w-full items-center gap-1.5 rounded-xl border border-border-subtle bg-surface/70 p-1.5 sm:min-w-0">
447
+ {PROVIDER_STATUS_FILTERS.map((option) => (
448
+ <button
449
+ key={option.value}
450
+ type="button"
451
+ onClick={() => {
452
+ setStatusFilter(option.value);
453
+ setApikeyPage(1);
454
+ setCollapsedSections({ custom: false, oauth: false, free: false, apikey: false });
455
+ }}
456
+ aria-pressed={statusFilter === option.value}
457
+ className={`flex h-11 flex-1 items-center justify-center whitespace-nowrap rounded-lg px-3 text-xs font-medium transition-colors sm:h-8 sm:flex-none sm:px-3 ${statusFilter === option.value ? "bg-primary text-white shadow-sm" : "text-text-muted hover:bg-black/5 hover:text-text-main dark:hover:bg-white/5"}`}
458
+ >
459
+ {option.label}
460
+ </button>
461
+ ))}
462
+ </div>
463
+ </div>
464
+
418
465
  {!hasAnyResult && (
419
466
  <div className="text-center py-8 border border-dashed border-border rounded-xl">
420
467
  <span className="material-symbols-outlined text-[32px] text-text-muted mb-2">
421
468
  search_off
422
469
  </span>
423
- <p className="text-text-muted text-sm">No providers match your search</p>
470
+ <p className="text-text-muted text-sm">
471
+ {searchQuery.trim() ? "No providers match your search" : "No providers match this filter"}
472
+ </p>
424
473
  </div>
425
474
  )}
426
475
 
427
476
  {/* Custom Providers (OpenAI/Anthropic Compatible) — dynamic */}
477
+ {showCustomSection && (
428
478
  <div className="flex flex-col gap-4">
429
479
  <ProviderSectionHeader
430
480
  icon="extension"
431
481
  title="Custom Providers"
432
482
  description="OpenAI and Anthropic-compatible endpoints"
483
+ count={compatibleProviders.length + anthropicCompatibleProviders.length}
484
+ collapsed={collapsedSections.custom && !searchQuery.trim()}
485
+ onToggle={() => toggleSection("custom")}
433
486
  >
434
487
  <div className="grid grid-cols-1 gap-2 sm:flex sm:w-auto">
435
488
  <Button
436
489
  size="sm"
437
490
  icon="add"
438
491
  onClick={() => setShowAddAnthropicCompatibleModal(true)}
439
- className="w-full sm:w-auto"
492
+ className="min-h-11 w-full sm:min-h-0 sm:w-auto"
440
493
  >
441
494
  Add Anthropic Compatible
442
495
  </Button>
@@ -445,12 +498,13 @@ export default function ProvidersPage() {
445
498
  variant="secondary"
446
499
  icon="add"
447
500
  onClick={() => setShowAddCompatibleModal(true)}
448
- className="w-full sm:w-auto"
501
+ className="min-h-11 w-full sm:min-h-0 sm:w-auto"
449
502
  >
450
503
  Add OpenAI Compatible
451
504
  </Button>
452
505
  </div>
453
506
  </ProviderSectionHeader>
507
+ <div className={collapsedSections.custom && !searchQuery.trim() ? "hidden sm:block" : ""}>
454
508
  {compatibleProviders.length === 0 &&
455
509
  anthropicCompatibleProviders.length === 0 ? (
456
510
  <div className="flex items-center gap-3 rounded-xl border border-dashed border-border bg-surface/45 px-4 py-3 text-text-muted">
@@ -477,7 +531,9 @@ export default function ProvidersPage() {
477
531
  )}
478
532
  </div>
479
533
  )}
534
+ </div>
480
535
  </div>
536
+ )}
481
537
 
482
538
  {/* OAuth Providers */}
483
539
  {oauthEntries.length > 0 && (
@@ -486,13 +542,16 @@ export default function ProvidersPage() {
486
542
  icon="passkey"
487
543
  title="OAuth Providers"
488
544
  description="Connect existing provider accounts securely"
545
+ count={oauthEntries.length}
546
+ collapsed={collapsedSections.oauth && !searchQuery.trim()}
547
+ onToggle={() => toggleSection("oauth")}
489
548
  >
490
549
  <div className="flex w-full flex-col gap-2 sm:w-auto sm:flex-row sm:items-center">
491
550
  <ModelAvailabilityBadge />
492
551
  <button
493
552
  onClick={() => handleBatchTest("oauth")}
494
553
  disabled={!!testingMode}
495
- className={`flex w-full items-center justify-center gap-1.5 rounded-lg border px-3 py-2 text-xs font-medium transition-colors sm:w-auto sm:py-1.5 ${
554
+ className={`flex h-11 w-full items-center justify-center gap-1.5 rounded-xl border px-3 text-xs font-medium transition-colors sm:h-8 sm:w-auto sm:rounded-lg ${
496
555
  testingMode === "oauth"
497
556
  ? "bg-primary/20 border-primary/40 text-primary animate-pulse"
498
557
  : "bg-bg border-border text-text-muted hover:text-text-main hover:border-primary/40"
@@ -509,7 +568,7 @@ export default function ProvidersPage() {
509
568
  </button>
510
569
  </div>
511
570
  </ProviderSectionHeader>
512
- <div className="grid grid-cols-1 gap-2.5 sm:grid-cols-2 sm:gap-3 lg:grid-cols-3 xl:grid-cols-4">
571
+ <div className={`${collapsedSections.oauth && !searchQuery.trim() ? "hidden sm:grid" : "grid"} grid-cols-1 gap-2.5 sm:grid-cols-2 sm:gap-3 lg:grid-cols-3 xl:grid-cols-4`}>
513
572
  {oauthEntries.map(([key, info]) => (
514
573
  <ProviderCard
515
574
  key={key}
@@ -530,11 +589,14 @@ export default function ProvidersPage() {
530
589
  icon="savings"
531
590
  title="Free Tier Providers"
532
591
  description="Ready-to-use and free-tier routing options"
592
+ count={freeEntries.length + freeTierEntries.length}
593
+ collapsed={collapsedSections.free && !searchQuery.trim()}
594
+ onToggle={() => toggleSection("free")}
533
595
  >
534
596
  <button
535
597
  onClick={() => handleBatchTest("free")}
536
598
  disabled={!!testingMode}
537
- className={`flex w-full items-center justify-center gap-1.5 rounded-lg border px-3 py-2 text-xs font-medium transition-colors sm:w-auto sm:py-1.5 ${
599
+ className={`flex h-11 w-full items-center justify-center gap-1.5 rounded-xl border px-3 text-xs font-medium transition-colors sm:h-8 sm:w-auto sm:rounded-lg ${
538
600
  testingMode === "free"
539
601
  ? "bg-primary/20 border-primary/40 text-primary animate-pulse"
540
602
  : "bg-bg border-border text-text-muted hover:text-text-main hover:border-primary/40"
@@ -550,7 +612,7 @@ export default function ProvidersPage() {
550
612
  {testingMode === "free" ? "Testing..." : "Test All"}
551
613
  </button>
552
614
  </ProviderSectionHeader>
553
- <div className="grid grid-cols-1 gap-2.5 sm:grid-cols-2 sm:gap-3 lg:grid-cols-3 xl:grid-cols-4">
615
+ <div className={`${collapsedSections.free && !searchQuery.trim() ? "hidden sm:grid" : "grid"} grid-cols-1 gap-2.5 sm:grid-cols-2 sm:gap-3 lg:grid-cols-3 xl:grid-cols-4`}>
554
616
  {freeEntries.map(([key, info]) => {
555
617
  const hasApiKeyMode = Array.isArray(info?.authModes) && info.authModes.includes("apikey");
556
618
  const statAuthTypes = hasApiKeyMode ? ["oauth", "apikey"] : "oauth";
@@ -584,11 +646,14 @@ export default function ProvidersPage() {
584
646
  icon="key"
585
647
  title="API Key Providers"
586
648
  description="Bring your own provider credentials"
649
+ count={apikeyEntries.length}
650
+ collapsed={collapsedSections.apikey && !searchQuery.trim()}
651
+ onToggle={() => toggleSection("apikey")}
587
652
  >
588
653
  <button
589
654
  onClick={() => handleBatchTest("apikey")}
590
655
  disabled={!!testingMode}
591
- className={`flex w-full items-center justify-center gap-1.5 rounded-lg border px-3 py-2 text-xs font-medium transition-colors sm:w-auto sm:py-1.5 ${
656
+ className={`flex h-11 w-full items-center justify-center gap-1.5 rounded-xl border px-3 text-xs font-medium transition-colors sm:h-8 sm:w-auto sm:rounded-lg ${
592
657
  testingMode === "apikey"
593
658
  ? "bg-primary/20 border-primary/40 text-primary animate-pulse"
594
659
  : "bg-bg border-border text-text-muted hover:text-text-main hover:border-primary/40"
@@ -604,7 +669,7 @@ export default function ProvidersPage() {
604
669
  {testingMode === "apikey" ? "Testing..." : "Test All"}
605
670
  </button>
606
671
  </ProviderSectionHeader>
607
- <div className="grid grid-cols-1 gap-2.5 sm:grid-cols-2 sm:gap-3 lg:grid-cols-3 xl:grid-cols-4">
672
+ <div className={`${collapsedSections.apikey && !searchQuery.trim() ? "hidden sm:grid" : "grid"} grid-cols-1 gap-2.5 sm:grid-cols-2 sm:gap-3 lg:grid-cols-3 xl:grid-cols-4`}>
608
673
  {visibleApikeyEntries.map(([key, info]) => (
609
674
  <ApiKeyProviderCard
610
675
  key={key}
@@ -616,6 +681,7 @@ export default function ProvidersPage() {
616
681
  ))}
617
682
  </div>
618
683
  {apikeyEntries.length > 0 && (
684
+ <div className={collapsedSections.apikey && !searchQuery.trim() ? "hidden sm:block" : ""}>
619
685
  <Pagination
620
686
  currentPage={activeApikeyPage}
621
687
  pageSize={apikeyPageSize}
@@ -626,6 +692,7 @@ export default function ProvidersPage() {
626
692
  setApikeyPage(1);
627
693
  }}
628
694
  />
695
+ </div>
629
696
  )}
630
697
  </div>
631
698
  )}
@@ -698,19 +765,47 @@ export default function ProvidersPage() {
698
765
  );
699
766
  }
700
767
 
701
- function ProviderSectionHeader({ icon, title, description, children }) {
768
+ function ProviderSectionHeader({
769
+ icon,
770
+ title,
771
+ description,
772
+ count,
773
+ collapsed,
774
+ onToggle,
775
+ children,
776
+ }) {
702
777
  return (
703
778
  <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
704
- <div className="flex min-w-0 items-center gap-2.5">
705
- <span aria-hidden="true" className="material-symbols-outlined flex size-8 shrink-0 items-center justify-center rounded-lg bg-primary/[0.08] text-[17px] text-primary">
706
- {icon}
707
- </span>
708
- <div className="min-w-0">
709
- <h2 className="text-lg font-semibold leading-tight">{title}</h2>
710
- <p className="mt-0.5 text-[11px] text-text-muted sm:text-xs">{description}</p>
779
+ <div className="flex w-full min-w-0 items-center gap-2.5 sm:w-auto">
780
+ <div className="flex min-w-0 flex-1 items-center gap-2.5 sm:flex-none">
781
+ <span aria-hidden="true" className="material-symbols-outlined flex size-8 shrink-0 items-center justify-center rounded-lg bg-primary/[0.08] text-[17px] text-primary">
782
+ {icon}
783
+ </span>
784
+ <div className="min-w-0">
785
+ <div className="flex items-center gap-2">
786
+ <h2 className="truncate text-lg font-semibold leading-tight">{title}</h2>
787
+ <span className="rounded-full bg-surface-2 px-2 py-0.5 text-[10px] font-semibold tabular-nums text-text-muted">
788
+ {count}
789
+ </span>
790
+ </div>
791
+ <p className="mt-0.5 truncate text-[11px] text-text-muted sm:text-xs">{description}</p>
792
+ </div>
711
793
  </div>
794
+ <button
795
+ type="button"
796
+ onClick={onToggle}
797
+ className="flex size-11 shrink-0 items-center justify-center rounded-xl border border-border text-text-muted transition-colors hover:border-primary/30 hover:text-primary sm:hidden"
798
+ aria-expanded={!collapsed}
799
+ aria-label={`${collapsed ? "Expand" : "Collapse"} ${title}`}
800
+ >
801
+ <span className="material-symbols-outlined text-[20px]">
802
+ {collapsed ? "expand_more" : "expand_less"}
803
+ </span>
804
+ </button>
712
805
  </div>
713
- {children}
806
+ {children && (
807
+ <div className={collapsed ? "hidden sm:block" : "block"}>{children}</div>
808
+ )}
714
809
  </div>
715
810
  );
716
811
  }
@@ -719,6 +814,9 @@ ProviderSectionHeader.propTypes = {
719
814
  icon: PropTypes.string.isRequired,
720
815
  title: PropTypes.string.isRequired,
721
816
  description: PropTypes.string.isRequired,
817
+ count: PropTypes.number.isRequired,
818
+ collapsed: PropTypes.bool.isRequired,
819
+ onToggle: PropTypes.func.isRequired,
722
820
  children: PropTypes.node,
723
821
  };
724
822
 
@@ -782,6 +880,7 @@ function ProviderCard({ providerId, provider, stats, onToggle }) {
782
880
  >
783
881
  <Toggle
784
882
  size="sm"
883
+ touchTarget
785
884
  checked={!allDisabled}
786
885
  onChange={() => {}}
787
886
  title={allDisabled ? "Enable provider" : "Disable provider"}
@@ -900,6 +999,7 @@ function ApiKeyProviderCard({
900
999
  >
901
1000
  <Toggle
902
1001
  size="sm"
1002
+ touchTarget
903
1003
  checked={!allDisabled}
904
1004
  onChange={() => {}}
905
1005
  title={allDisabled ? "Enable provider" : "Disable provider"}