switchboard-router 0.6.19 → 0.6.22

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 (402) hide show
  1. package/app/.next-cli-build/BUILD_ID +1 -1
  2. package/app/.next-cli-build/app-path-routes-manifest.json +10 -10
  3. package/app/.next-cli-build/build-manifest.json +2 -2
  4. package/app/.next-cli-build/prerender-manifest.json +3 -3
  5. package/app/.next-cli-build/required-server-files.json +4 -1
  6. package/app/.next-cli-build/server/app/(dashboard)/dashboard/agent-library/page.js.nft.json +1 -1
  7. package/app/.next-cli-build/server/app/(dashboard)/dashboard/agent-library/page_client-reference-manifest.js +1 -1
  8. package/app/.next-cli-build/server/app/(dashboard)/dashboard/basic-chat/page.js.nft.json +1 -1
  9. package/app/.next-cli-build/server/app/(dashboard)/dashboard/basic-chat/page_client-reference-manifest.js +1 -1
  10. package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/[toolId]/page.js +1 -1
  11. package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/[toolId]/page.js.nft.json +1 -1
  12. package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/[toolId]/page_client-reference-manifest.js +1 -1
  13. package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/page.js +1 -1
  14. package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/page.js.nft.json +1 -1
  15. package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/page_client-reference-manifest.js +1 -1
  16. package/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/page.js +1 -1
  17. package/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/page.js.nft.json +1 -1
  18. package/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/page_client-reference-manifest.js +1 -1
  19. package/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/routing/page.js.nft.json +1 -1
  20. package/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/routing/page_client-reference-manifest.js +1 -1
  21. package/app/.next-cli-build/server/app/(dashboard)/dashboard/console-log/page.js.nft.json +1 -1
  22. package/app/.next-cli-build/server/app/(dashboard)/dashboard/console-log/page_client-reference-manifest.js +1 -1
  23. package/app/.next-cli-build/server/app/(dashboard)/dashboard/endpoint/page.js +2 -2
  24. package/app/.next-cli-build/server/app/(dashboard)/dashboard/endpoint/page.js.nft.json +1 -1
  25. package/app/.next-cli-build/server/app/(dashboard)/dashboard/endpoint/page_client-reference-manifest.js +1 -1
  26. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page.js.nft.json +1 -1
  27. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page_client-reference-manifest.js +1 -1
  28. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/page.js.nft.json +1 -1
  29. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/page_client-reference-manifest.js +1 -1
  30. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/combo/[id]/page.js.nft.json +1 -1
  31. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/combo/[id]/page_client-reference-manifest.js +1 -1
  32. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/page.js.nft.json +1 -1
  33. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/page_client-reference-manifest.js +1 -1
  34. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/web/page.js.nft.json +1 -1
  35. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/web/page_client-reference-manifest.js +1 -1
  36. package/app/.next-cli-build/server/app/(dashboard)/dashboard/mitm/page.js.nft.json +1 -1
  37. package/app/.next-cli-build/server/app/(dashboard)/dashboard/mitm/page_client-reference-manifest.js +1 -1
  38. package/app/.next-cli-build/server/app/(dashboard)/dashboard/page.js +1 -1
  39. package/app/.next-cli-build/server/app/(dashboard)/dashboard/page.js.nft.json +1 -1
  40. package/app/.next-cli-build/server/app/(dashboard)/dashboard/page_client-reference-manifest.js +1 -1
  41. package/app/.next-cli-build/server/app/(dashboard)/dashboard/profile/page.js +1 -1
  42. package/app/.next-cli-build/server/app/(dashboard)/dashboard/profile/page.js.nft.json +1 -1
  43. package/app/.next-cli-build/server/app/(dashboard)/dashboard/profile/page_client-reference-manifest.js +1 -1
  44. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/[id]/page.js.nft.json +1 -1
  45. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/[id]/page_client-reference-manifest.js +1 -1
  46. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/new/page.js.nft.json +1 -1
  47. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/new/page_client-reference-manifest.js +1 -1
  48. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/page.js +2 -2
  49. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/page.js.nft.json +1 -1
  50. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/page_client-reference-manifest.js +1 -1
  51. package/app/.next-cli-build/server/app/(dashboard)/dashboard/quota/page.js.nft.json +1 -1
  52. package/app/.next-cli-build/server/app/(dashboard)/dashboard/quota/page_client-reference-manifest.js +1 -1
  53. package/app/.next-cli-build/server/app/(dashboard)/dashboard/skills/[id]/page.js.nft.json +1 -1
  54. package/app/.next-cli-build/server/app/(dashboard)/dashboard/skills/[id]/page_client-reference-manifest.js +1 -1
  55. package/app/.next-cli-build/server/app/(dashboard)/dashboard/skills/page.js.nft.json +1 -1
  56. package/app/.next-cli-build/server/app/(dashboard)/dashboard/skills/page_client-reference-manifest.js +1 -1
  57. package/app/.next-cli-build/server/app/(dashboard)/dashboard/token-saver/page.js.nft.json +1 -1
  58. package/app/.next-cli-build/server/app/(dashboard)/dashboard/token-saver/page_client-reference-manifest.js +1 -1
  59. package/app/.next-cli-build/server/app/(dashboard)/dashboard/translator/page.js.nft.json +1 -1
  60. package/app/.next-cli-build/server/app/(dashboard)/dashboard/translator/page_client-reference-manifest.js +1 -1
  61. package/app/.next-cli-build/server/app/(dashboard)/dashboard/usage/page.js.nft.json +1 -1
  62. package/app/.next-cli-build/server/app/(dashboard)/dashboard/usage/page_client-reference-manifest.js +1 -1
  63. package/app/.next-cli-build/server/app/_global-error/page.js.nft.json +1 -1
  64. package/app/.next-cli-build/server/app/_global-error/page_client-reference-manifest.js +1 -1
  65. package/app/.next-cli-build/server/app/_global-error.html +1 -1
  66. package/app/.next-cli-build/server/app/_global-error.rsc +1 -1
  67. package/app/.next-cli-build/server/app/_global-error.segments/_full.segment.rsc +1 -1
  68. package/app/.next-cli-build/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  69. package/app/.next-cli-build/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  70. package/app/.next-cli-build/server/app/_global-error.segments/_head.segment.rsc +1 -1
  71. package/app/.next-cli-build/server/app/_global-error.segments/_index.segment.rsc +1 -1
  72. package/app/.next-cli-build/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  73. package/app/.next-cli-build/server/app/_not-found/page.js.nft.json +1 -1
  74. package/app/.next-cli-build/server/app/_not-found/page_client-reference-manifest.js +1 -1
  75. package/app/.next-cli-build/server/app/_not-found.html +1 -1
  76. package/app/.next-cli-build/server/app/_not-found.rsc +4 -4
  77. package/app/.next-cli-build/server/app/_not-found.segments/_full.segment.rsc +4 -4
  78. package/app/.next-cli-build/server/app/_not-found.segments/_head.segment.rsc +1 -1
  79. package/app/.next-cli-build/server/app/_not-found.segments/_index.segment.rsc +4 -4
  80. package/app/.next-cli-build/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  81. package/app/.next-cli-build/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  82. package/app/.next-cli-build/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  83. package/app/.next-cli-build/server/app/api/agent-library/catalog/route.js.nft.json +1 -1
  84. package/app/.next-cli-build/server/app/api/agent-library/doctor/route.js.nft.json +1 -1
  85. package/app/.next-cli-build/server/app/api/agent-library/export/route.js.nft.json +1 -1
  86. package/app/.next-cli-build/server/app/api/agent-library/mcp/route.js.nft.json +1 -1
  87. package/app/.next-cli-build/server/app/api/agent-library/route.js.nft.json +1 -1
  88. package/app/.next-cli-build/server/app/api/agent-library/skills/route.js.nft.json +1 -1
  89. package/app/.next-cli-build/server/app/api/agent-library/sync/route.js.nft.json +1 -1
  90. package/app/.next-cli-build/server/app/api/agent-library/updates/route.js.nft.json +1 -1
  91. package/app/.next-cli-build/server/app/api/auth/status/route.js.nft.json +1 -1
  92. package/app/.next-cli-build/server/app/api/cli-tools/aider-settings/route.js +2 -2
  93. package/app/.next-cli-build/server/app/api/cli-tools/aider-settings/route.js.nft.json +1 -1
  94. package/app/.next-cli-build/server/app/api/cli-tools/all-statuses/route.js +4 -4
  95. package/app/.next-cli-build/server/app/api/cli-tools/all-statuses/route.js.nft.json +1 -1
  96. package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/alias/route.js +1 -1
  97. package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/alias/route.js.nft.json +1 -1
  98. package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/route.js +1 -1
  99. package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/route.js.nft.json +1 -1
  100. package/app/.next-cli-build/server/app/api/cli-tools/claude-full-catalog/route.js +2 -2
  101. package/app/.next-cli-build/server/app/api/cli-tools/claude-full-catalog/route.js.nft.json +1 -1
  102. package/app/.next-cli-build/server/app/api/cli-tools/claude-settings/route.js.nft.json +1 -1
  103. package/app/.next-cli-build/server/app/api/cli-tools/cline-settings/route.js +1 -1
  104. package/app/.next-cli-build/server/app/api/cli-tools/cline-settings/route.js.nft.json +1 -1
  105. package/app/.next-cli-build/server/app/api/cli-tools/codex-settings/route.js +1 -1
  106. package/app/.next-cli-build/server/app/api/cli-tools/codex-settings/route.js.nft.json +1 -1
  107. package/app/.next-cli-build/server/app/api/cli-tools/cowork-mcp-registry/route.js +2 -2
  108. package/app/.next-cli-build/server/app/api/cli-tools/cowork-mcp-registry/route.js.nft.json +1 -1
  109. package/app/.next-cli-build/server/app/api/cli-tools/cowork-mcp-tools/route.js +1 -1
  110. package/app/.next-cli-build/server/app/api/cli-tools/cowork-mcp-tools/route.js.nft.json +1 -1
  111. package/app/.next-cli-build/server/app/api/cli-tools/cowork-settings/route.js +2 -2
  112. package/app/.next-cli-build/server/app/api/cli-tools/cowork-settings/route.js.nft.json +1 -1
  113. package/app/.next-cli-build/server/app/api/cli-tools/deepseek-tui-settings/route.js +1 -1
  114. package/app/.next-cli-build/server/app/api/cli-tools/deepseek-tui-settings/route.js.nft.json +1 -1
  115. package/app/.next-cli-build/server/app/api/cli-tools/droid-settings/route.js +2 -2
  116. package/app/.next-cli-build/server/app/api/cli-tools/droid-settings/route.js.nft.json +1 -1
  117. package/app/.next-cli-build/server/app/api/cli-tools/gemini-cli-settings/route.js +3 -3
  118. package/app/.next-cli-build/server/app/api/cli-tools/gemini-cli-settings/route.js.nft.json +1 -1
  119. package/app/.next-cli-build/server/app/api/cli-tools/grok-settings/route.js +2 -2
  120. package/app/.next-cli-build/server/app/api/cli-tools/grok-settings/route.js.nft.json +1 -1
  121. package/app/.next-cli-build/server/app/api/cli-tools/hermes-settings/route.js +2 -2
  122. package/app/.next-cli-build/server/app/api/cli-tools/hermes-settings/route.js.nft.json +1 -1
  123. package/app/.next-cli-build/server/app/api/cli-tools/jcode-settings/route.js +2 -2
  124. package/app/.next-cli-build/server/app/api/cli-tools/jcode-settings/route.js.nft.json +1 -1
  125. package/app/.next-cli-build/server/app/api/cli-tools/kilo-settings/route.js +2 -2
  126. package/app/.next-cli-build/server/app/api/cli-tools/kilo-settings/route.js.nft.json +1 -1
  127. package/app/.next-cli-build/server/app/api/cli-tools/openclaw-settings/route.js +1 -1
  128. package/app/.next-cli-build/server/app/api/cli-tools/openclaw-settings/route.js.nft.json +1 -1
  129. package/app/.next-cli-build/server/app/api/cli-tools/opencode-settings/route.js +2 -2
  130. package/app/.next-cli-build/server/app/api/cli-tools/opencode-settings/route.js.nft.json +1 -1
  131. package/app/.next-cli-build/server/app/api/cli-tools/pi-settings/route.js +1 -1
  132. package/app/.next-cli-build/server/app/api/cli-tools/pi-settings/route.js.nft.json +1 -1
  133. package/app/.next-cli-build/server/app/api/combos/[id]/route.js +1 -1
  134. package/app/.next-cli-build/server/app/api/combos/[id]/route.js.nft.json +1 -1
  135. package/app/.next-cli-build/server/app/api/combos/route.js +1 -1
  136. package/app/.next-cli-build/server/app/api/combos/route.js.nft.json +1 -1
  137. package/app/.next-cli-build/server/app/api/headroom/proxy/[...path]/route.js.nft.json +1 -1
  138. package/app/.next-cli-build/server/app/api/headroom/start/route.js.nft.json +1 -1
  139. package/app/.next-cli-build/server/app/api/headroom/status/route.js.nft.json +1 -1
  140. package/app/.next-cli-build/server/app/api/headroom/stop/route.js.nft.json +1 -1
  141. package/app/.next-cli-build/server/app/api/health/route.js.nft.json +1 -1
  142. package/app/.next-cli-build/server/app/api/keys/[id]/route.js.nft.json +1 -1
  143. package/app/.next-cli-build/server/app/api/keys/route.js +1 -1
  144. package/app/.next-cli-build/server/app/api/keys/route.js.nft.json +1 -1
  145. package/app/.next-cli-build/server/app/api/locale/route.js.nft.json +1 -1
  146. package/app/.next-cli-build/server/app/api/mcp/[plugin]/message/route.js.nft.json +1 -1
  147. package/app/.next-cli-build/server/app/api/mcp/[plugin]/sse/route.js.nft.json +1 -1
  148. package/app/.next-cli-build/server/app/api/media-providers/tts/deepgram/voices/route.js.nft.json +1 -1
  149. package/app/.next-cli-build/server/app/api/media-providers/tts/elevenlabs/voices/route.js.nft.json +1 -1
  150. package/app/.next-cli-build/server/app/api/media-providers/tts/inworld/voices/route.js.nft.json +1 -1
  151. package/app/.next-cli-build/server/app/api/media-providers/tts/minimax/voices/route.js.nft.json +1 -1
  152. package/app/.next-cli-build/server/app/api/media-providers/tts/voices/route.js.nft.json +1 -1
  153. package/app/.next-cli-build/server/app/api/mgmt/v1/combos/[id]/route.js +1 -1
  154. package/app/.next-cli-build/server/app/api/mgmt/v1/combos/[id]/route.js.nft.json +1 -1
  155. package/app/.next-cli-build/server/app/api/mgmt/v1/combos/[id]/strategy/route.js +1 -1
  156. package/app/.next-cli-build/server/app/api/mgmt/v1/combos/[id]/strategy/route.js.nft.json +1 -1
  157. package/app/.next-cli-build/server/app/api/mgmt/v1/combos/route.js +1 -1
  158. package/app/.next-cli-build/server/app/api/mgmt/v1/combos/route.js.nft.json +1 -1
  159. package/app/.next-cli-build/server/app/api/mgmt/v1/health/route.js +1 -1
  160. package/app/.next-cli-build/server/app/api/mgmt/v1/health/route.js.nft.json +1 -1
  161. package/app/.next-cli-build/server/app/api/mgmt/v1/providers/route.js +1 -1
  162. package/app/.next-cli-build/server/app/api/mgmt/v1/providers/route.js.nft.json +1 -1
  163. package/app/.next-cli-build/server/app/api/mgmt/v1/routing/route.js +1 -1
  164. package/app/.next-cli-build/server/app/api/mgmt/v1/routing/route.js.nft.json +1 -1
  165. package/app/.next-cli-build/server/app/api/mgmt/v1/usage/route.js +1 -1
  166. package/app/.next-cli-build/server/app/api/mgmt/v1/usage/route.js.nft.json +1 -1
  167. package/app/.next-cli-build/server/app/api/mgmt/v1/version/route.js +1 -1
  168. package/app/.next-cli-build/server/app/api/mgmt/v1/version/route.js.nft.json +1 -1
  169. package/app/.next-cli-build/server/app/api/models/alias/route.js.nft.json +1 -1
  170. package/app/.next-cli-build/server/app/api/models/availability/route.js.nft.json +1 -1
  171. package/app/.next-cli-build/server/app/api/models/custom/route.js.nft.json +1 -1
  172. package/app/.next-cli-build/server/app/api/models/disabled/route.js.nft.json +1 -1
  173. package/app/.next-cli-build/server/app/api/models/route.js.nft.json +1 -1
  174. package/app/.next-cli-build/server/app/api/models/test/route.js +1 -1
  175. package/app/.next-cli-build/server/app/api/models/test/route.js.nft.json +1 -1
  176. package/app/.next-cli-build/server/app/api/oauth/[provider]/[action]/route.js +1 -1
  177. package/app/.next-cli-build/server/app/api/oauth/[provider]/[action]/route.js.nft.json +1 -1
  178. package/app/.next-cli-build/server/app/api/oauth/codex/bulk-import/route.js +1 -1
  179. package/app/.next-cli-build/server/app/api/oauth/codex/bulk-import/route.js.nft.json +1 -1
  180. package/app/.next-cli-build/server/app/api/oauth/codex/import-token/route.js +1 -1
  181. package/app/.next-cli-build/server/app/api/oauth/codex/import-token/route.js.nft.json +1 -1
  182. package/app/.next-cli-build/server/app/api/oauth/cursor/auto-import/route.js.nft.json +1 -1
  183. package/app/.next-cli-build/server/app/api/oauth/cursor/import/route.js.nft.json +1 -1
  184. package/app/.next-cli-build/server/app/api/oauth/gitlab/pat/route.js.nft.json +1 -1
  185. package/app/.next-cli-build/server/app/api/oauth/iflow/cookie/route.js.nft.json +1 -1
  186. package/app/.next-cli-build/server/app/api/oauth/kiro/api-key/route.js +1 -1
  187. package/app/.next-cli-build/server/app/api/oauth/kiro/api-key/route.js.nft.json +1 -1
  188. package/app/.next-cli-build/server/app/api/oauth/kiro/auto-import/route.js.nft.json +1 -1
  189. package/app/.next-cli-build/server/app/api/oauth/kiro/import/route.js +1 -1
  190. package/app/.next-cli-build/server/app/api/oauth/kiro/import/route.js.nft.json +1 -1
  191. package/app/.next-cli-build/server/app/api/oauth/kiro/import-cli-proxy/route.js.nft.json +1 -1
  192. package/app/.next-cli-build/server/app/api/oauth/kiro/social-authorize/route.js +1 -1
  193. package/app/.next-cli-build/server/app/api/oauth/kiro/social-authorize/route.js.nft.json +1 -1
  194. package/app/.next-cli-build/server/app/api/oauth/kiro/social-exchange/route.js +1 -1
  195. package/app/.next-cli-build/server/app/api/oauth/kiro/social-exchange/route.js.nft.json +1 -1
  196. package/app/.next-cli-build/server/app/api/pricing/route.js.nft.json +1 -1
  197. package/app/.next-cli-build/server/app/api/provider-nodes/[id]/route.js.nft.json +1 -1
  198. package/app/.next-cli-build/server/app/api/provider-nodes/route.js.nft.json +1 -1
  199. package/app/.next-cli-build/server/app/api/provider-nodes/validate/route.js +1 -1
  200. package/app/.next-cli-build/server/app/api/provider-nodes/validate/route.js.nft.json +1 -1
  201. package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/batch/route.js +1 -1
  202. package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/batch/route.js.nft.json +1 -1
  203. package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/cache/route.js +1 -1
  204. package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/cache/route.js.nft.json +1 -1
  205. package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/prepare/route.js +1 -1
  206. package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/prepare/route.js.nft.json +1 -1
  207. package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/remove-unavailable/route.js +1 -1
  208. package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/remove-unavailable/route.js.nft.json +1 -1
  209. package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/route.js +1 -1
  210. package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/route.js.nft.json +1 -1
  211. package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/verify/cancel/route.js +1 -1
  212. package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/verify/cancel/route.js.nft.json +1 -1
  213. package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/verify/start/route.js +1 -1
  214. package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/verify/start/route.js.nft.json +1 -1
  215. package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/verify/status/route.js +1 -1
  216. package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/verify/status/route.js.nft.json +1 -1
  217. package/app/.next-cli-build/server/app/api/providers/[id]/models/route.js +1 -1
  218. package/app/.next-cli-build/server/app/api/providers/[id]/models/route.js.nft.json +1 -1
  219. package/app/.next-cli-build/server/app/api/providers/[id]/route.js.nft.json +1 -1
  220. package/app/.next-cli-build/server/app/api/providers/[id]/test/route.js +1 -1
  221. package/app/.next-cli-build/server/app/api/providers/[id]/test/route.js.nft.json +1 -1
  222. package/app/.next-cli-build/server/app/api/providers/[id]/test-models/route.js +1 -1
  223. package/app/.next-cli-build/server/app/api/providers/[id]/test-models/route.js.nft.json +1 -1
  224. package/app/.next-cli-build/server/app/api/providers/client/route.js +1 -1
  225. package/app/.next-cli-build/server/app/api/providers/client/route.js.nft.json +1 -1
  226. package/app/.next-cli-build/server/app/api/providers/kilo/free-models/route.js.nft.json +1 -1
  227. package/app/.next-cli-build/server/app/api/providers/route.js.nft.json +1 -1
  228. package/app/.next-cli-build/server/app/api/providers/suggested-models/route.js.nft.json +1 -1
  229. package/app/.next-cli-build/server/app/api/providers/test-batch/route.js +1 -1
  230. package/app/.next-cli-build/server/app/api/providers/test-batch/route.js.nft.json +1 -1
  231. package/app/.next-cli-build/server/app/api/providers/validate/route.js.nft.json +1 -1
  232. package/app/.next-cli-build/server/app/api/routing/feedback/route.js +2 -2
  233. package/app/.next-cli-build/server/app/api/routing/feedback/route.js.nft.json +1 -1
  234. package/app/.next-cli-build/server/app/api/routing/insights/route.js.nft.json +1 -1
  235. package/app/.next-cli-build/server/app/api/routing/learn/route.js.nft.json +1 -1
  236. package/app/.next-cli-build/server/app/api/routing/stats/route.js.nft.json +1 -1
  237. package/app/.next-cli-build/server/app/api/routing/versions/promote/route.js.nft.json +1 -1
  238. package/app/.next-cli-build/server/app/api/routing/versions/rollback/route.js.nft.json +1 -1
  239. package/app/.next-cli-build/server/app/api/settings/database/route.js.nft.json +1 -1
  240. package/app/.next-cli-build/server/app/api/settings/proxy-test/route.js.nft.json +1 -1
  241. package/app/.next-cli-build/server/app/api/settings/route.js +1 -1
  242. package/app/.next-cli-build/server/app/api/settings/route.js.nft.json +1 -1
  243. package/app/.next-cli-build/server/app/api/shutdown/route.js.nft.json +1 -1
  244. package/app/.next-cli-build/server/app/api/skills/[id]/route.js.nft.json +1 -1
  245. package/app/.next-cli-build/server/app/api/tags/route.js.nft.json +1 -1
  246. package/app/.next-cli-build/server/app/api/token-saver/vault-stats/route.js.nft.json +1 -1
  247. package/app/.next-cli-build/server/app/api/translator/console-logs/route.js.nft.json +1 -1
  248. package/app/.next-cli-build/server/app/api/translator/console-logs/stream/route.js.nft.json +1 -1
  249. package/app/.next-cli-build/server/app/api/translator/load/route.js.nft.json +1 -1
  250. package/app/.next-cli-build/server/app/api/translator/save/route.js.nft.json +1 -1
  251. package/app/.next-cli-build/server/app/api/translator/send/route.js +1 -1
  252. package/app/.next-cli-build/server/app/api/translator/send/route.js.nft.json +1 -1
  253. package/app/.next-cli-build/server/app/api/translator/translate/route.js +2 -2
  254. package/app/.next-cli-build/server/app/api/translator/translate/route.js.nft.json +1 -1
  255. package/app/.next-cli-build/server/app/api/usage/[connectionId]/codex-reset-credits/route.js +1 -1
  256. package/app/.next-cli-build/server/app/api/usage/[connectionId]/codex-reset-credits/route.js.nft.json +1 -1
  257. package/app/.next-cli-build/server/app/api/usage/[connectionId]/route.js +1 -1
  258. package/app/.next-cli-build/server/app/api/usage/[connectionId]/route.js.nft.json +1 -1
  259. package/app/.next-cli-build/server/app/api/usage/chart/route.js.nft.json +1 -1
  260. package/app/.next-cli-build/server/app/api/usage/history/route.js.nft.json +1 -1
  261. package/app/.next-cli-build/server/app/api/usage/logs/route.js.nft.json +1 -1
  262. package/app/.next-cli-build/server/app/api/usage/providers/route.js.nft.json +1 -1
  263. package/app/.next-cli-build/server/app/api/usage/request-details/route.js.nft.json +1 -1
  264. package/app/.next-cli-build/server/app/api/usage/request-logs/route.js.nft.json +1 -1
  265. package/app/.next-cli-build/server/app/api/usage/stats/route.js.nft.json +1 -1
  266. package/app/.next-cli-build/server/app/api/usage/stream/route.js.nft.json +1 -1
  267. package/app/.next-cli-build/server/app/api/v1/api/chat/route.js +1 -1
  268. package/app/.next-cli-build/server/app/api/v1/api/chat/route.js.nft.json +1 -1
  269. package/app/.next-cli-build/server/app/api/v1/audio/speech/route.js +1 -1
  270. package/app/.next-cli-build/server/app/api/v1/audio/speech/route.js.nft.json +1 -1
  271. package/app/.next-cli-build/server/app/api/v1/audio/transcriptions/route.js +1 -1
  272. package/app/.next-cli-build/server/app/api/v1/audio/transcriptions/route.js.nft.json +1 -1
  273. package/app/.next-cli-build/server/app/api/v1/audio/voices/route.js.nft.json +1 -1
  274. package/app/.next-cli-build/server/app/api/v1/chat/completions/route.js +1 -1
  275. package/app/.next-cli-build/server/app/api/v1/chat/completions/route.js.nft.json +1 -1
  276. package/app/.next-cli-build/server/app/api/v1/embeddings/route.js +1 -1
  277. package/app/.next-cli-build/server/app/api/v1/embeddings/route.js.nft.json +1 -1
  278. package/app/.next-cli-build/server/app/api/v1/images/generations/route.js +1 -1
  279. package/app/.next-cli-build/server/app/api/v1/images/generations/route.js.nft.json +1 -1
  280. package/app/.next-cli-build/server/app/api/v1/messages/count_tokens/route.js.nft.json +1 -1
  281. package/app/.next-cli-build/server/app/api/v1/messages/route.js +1 -1
  282. package/app/.next-cli-build/server/app/api/v1/messages/route.js.nft.json +1 -1
  283. package/app/.next-cli-build/server/app/api/v1/models/[kind]/route.js +1 -1
  284. package/app/.next-cli-build/server/app/api/v1/models/[kind]/route.js.nft.json +1 -1
  285. package/app/.next-cli-build/server/app/api/v1/models/info/route.js.nft.json +1 -1
  286. package/app/.next-cli-build/server/app/api/v1/models/route.js +1 -1
  287. package/app/.next-cli-build/server/app/api/v1/models/route.js.nft.json +1 -1
  288. package/app/.next-cli-build/server/app/api/v1/responses/compact/route.js +1 -1
  289. package/app/.next-cli-build/server/app/api/v1/responses/compact/route.js.nft.json +1 -1
  290. package/app/.next-cli-build/server/app/api/v1/responses/route.js +1 -1
  291. package/app/.next-cli-build/server/app/api/v1/responses/route.js.nft.json +1 -1
  292. package/app/.next-cli-build/server/app/api/v1/route.js +1 -1
  293. package/app/.next-cli-build/server/app/api/v1/route.js.nft.json +1 -1
  294. package/app/.next-cli-build/server/app/api/v1/search/route.js +1 -1
  295. package/app/.next-cli-build/server/app/api/v1/search/route.js.nft.json +1 -1
  296. package/app/.next-cli-build/server/app/api/v1/web/fetch/route.js +1 -1
  297. package/app/.next-cli-build/server/app/api/v1/web/fetch/route.js.nft.json +1 -1
  298. package/app/.next-cli-build/server/app/api/v1beta/models/[...path]/route.js +1 -1
  299. package/app/.next-cli-build/server/app/api/v1beta/models/[...path]/route.js.nft.json +1 -1
  300. package/app/.next-cli-build/server/app/api/v1beta/models/route.js.nft.json +1 -1
  301. package/app/.next-cli-build/server/app/api/version/route.js +1 -1
  302. package/app/.next-cli-build/server/app/api/version/route.js.nft.json +1 -1
  303. package/app/.next-cli-build/server/app/api/version/shutdown/route.js.nft.json +1 -1
  304. package/app/.next-cli-build/server/app/api/version/update/route.js.nft.json +1 -1
  305. package/app/.next-cli-build/server/app/callback/page.js.nft.json +1 -1
  306. package/app/.next-cli-build/server/app/callback/page_client-reference-manifest.js +1 -1
  307. package/app/.next-cli-build/server/app/callback.html +1 -1
  308. package/app/.next-cli-build/server/app/callback.rsc +4 -4
  309. package/app/.next-cli-build/server/app/callback.segments/_full.segment.rsc +4 -4
  310. package/app/.next-cli-build/server/app/callback.segments/_head.segment.rsc +1 -1
  311. package/app/.next-cli-build/server/app/callback.segments/_index.segment.rsc +4 -4
  312. package/app/.next-cli-build/server/app/callback.segments/_tree.segment.rsc +2 -2
  313. package/app/.next-cli-build/server/app/callback.segments/callback/__PAGE__.segment.rsc +1 -1
  314. package/app/.next-cli-build/server/app/callback.segments/callback.segment.rsc +1 -1
  315. package/app/.next-cli-build/server/app/dashboard/settings/pricing/page.js.nft.json +1 -1
  316. package/app/.next-cli-build/server/app/dashboard/settings/pricing/page_client-reference-manifest.js +1 -1
  317. package/app/.next-cli-build/server/app/dashboard/settings/pricing.html +1 -1
  318. package/app/.next-cli-build/server/app/dashboard/settings/pricing.rsc +4 -4
  319. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_full.segment.rsc +4 -4
  320. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_head.segment.rsc +1 -1
  321. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_index.segment.rsc +4 -4
  322. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_tree.segment.rsc +2 -2
  323. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing/__PAGE__.segment.rsc +1 -1
  324. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing.segment.rsc +1 -1
  325. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings.segment.rsc +1 -1
  326. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard.segment.rsc +1 -1
  327. package/app/.next-cli-build/server/app/favicon.ico/route.js.nft.json +1 -1
  328. package/app/.next-cli-build/server/app/index.html +1 -1
  329. package/app/.next-cli-build/server/app/index.rsc +4 -4
  330. package/app/.next-cli-build/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  331. package/app/.next-cli-build/server/app/index.segments/_full.segment.rsc +4 -4
  332. package/app/.next-cli-build/server/app/index.segments/_head.segment.rsc +1 -1
  333. package/app/.next-cli-build/server/app/index.segments/_index.segment.rsc +4 -4
  334. package/app/.next-cli-build/server/app/index.segments/_tree.segment.rsc +2 -2
  335. package/app/.next-cli-build/server/app/landing/page.js.nft.json +1 -1
  336. package/app/.next-cli-build/server/app/landing/page_client-reference-manifest.js +1 -1
  337. package/app/.next-cli-build/server/app/landing.html +1 -1
  338. package/app/.next-cli-build/server/app/landing.rsc +4 -4
  339. package/app/.next-cli-build/server/app/landing.segments/_full.segment.rsc +4 -4
  340. package/app/.next-cli-build/server/app/landing.segments/_head.segment.rsc +1 -1
  341. package/app/.next-cli-build/server/app/landing.segments/_index.segment.rsc +4 -4
  342. package/app/.next-cli-build/server/app/landing.segments/_tree.segment.rsc +2 -2
  343. package/app/.next-cli-build/server/app/landing.segments/landing/__PAGE__.segment.rsc +1 -1
  344. package/app/.next-cli-build/server/app/landing.segments/landing.segment.rsc +1 -1
  345. package/app/.next-cli-build/server/app/login/page.js.nft.json +1 -1
  346. package/app/.next-cli-build/server/app/login/page_client-reference-manifest.js +1 -1
  347. package/app/.next-cli-build/server/app/login.html +1 -1
  348. package/app/.next-cli-build/server/app/login.rsc +4 -4
  349. package/app/.next-cli-build/server/app/login.segments/_full.segment.rsc +4 -4
  350. package/app/.next-cli-build/server/app/login.segments/_head.segment.rsc +1 -1
  351. package/app/.next-cli-build/server/app/login.segments/_index.segment.rsc +4 -4
  352. package/app/.next-cli-build/server/app/login.segments/_tree.segment.rsc +2 -2
  353. package/app/.next-cli-build/server/app/login.segments/login/__PAGE__.segment.rsc +1 -1
  354. package/app/.next-cli-build/server/app/login.segments/login.segment.rsc +1 -1
  355. package/app/.next-cli-build/server/app/manifest.webmanifest/route.js.nft.json +1 -1
  356. package/app/.next-cli-build/server/app/page.js.nft.json +1 -1
  357. package/app/.next-cli-build/server/app/page_client-reference-manifest.js +1 -1
  358. package/app/.next-cli-build/server/app-paths-manifest.json +10 -10
  359. package/app/.next-cli-build/server/chunks/1350.js +1 -0
  360. package/app/.next-cli-build/server/chunks/1818.js +1 -0
  361. package/app/.next-cli-build/server/chunks/194.js +1 -1
  362. package/app/.next-cli-build/server/chunks/2376.js +2 -2
  363. package/app/.next-cli-build/server/chunks/2409.js +1 -0
  364. package/app/.next-cli-build/server/chunks/{4126.js → 4658.js} +2 -2
  365. package/app/.next-cli-build/server/chunks/4833.js +2 -2
  366. package/app/.next-cli-build/server/chunks/5139.js +1 -1
  367. package/app/.next-cli-build/server/chunks/{5821.js → 5305.js} +1 -1
  368. package/app/.next-cli-build/server/chunks/6182.js +1 -1
  369. package/app/.next-cli-build/server/chunks/6328.js +1 -0
  370. package/app/.next-cli-build/server/chunks/7945.js +15 -15
  371. package/app/.next-cli-build/server/chunks/8658.js +2 -2
  372. package/app/.next-cli-build/server/chunks/869.js +1 -1
  373. package/app/.next-cli-build/server/chunks/{9397.js → 8718.js} +1 -1
  374. package/app/.next-cli-build/server/chunks/8775.js +2 -2
  375. package/app/.next-cli-build/server/chunks/{8129.js → 8789.js} +1 -1
  376. package/app/.next-cli-build/server/chunks/8998.js +3 -3
  377. package/app/.next-cli-build/server/instrumentation.js +1 -1
  378. package/app/.next-cli-build/server/middleware-build-manifest.js +1 -1
  379. package/app/.next-cli-build/server/middleware.js +4 -4
  380. package/app/.next-cli-build/server/pages/404.html +1 -1
  381. package/app/.next-cli-build/server/pages/500.html +1 -1
  382. package/app/.next-cli-build/server/server-reference-manifest.js +1 -1
  383. package/app/.next-cli-build/server/server-reference-manifest.json +1 -1
  384. package/app/.next-cli-build/server/webpack-runtime.js +1 -1
  385. package/app/.next-cli-build/static/chunks/{1321-755bcf9b81c9c788.js → 1321-a98567948f8d7a2b.js} +1 -1
  386. package/app/.next-cli-build/static/chunks/{545-879fcbf4fd26bb8c.js → 545-ea5f9025a426a8b1.js} +18 -18
  387. package/app/.next-cli-build/static/css/691ada29b4dd12e3.css +1 -0
  388. package/app/node_modules/node-machine-id/dist/index.js +1 -0
  389. package/app/node_modules/node-machine-id/package.json +74 -0
  390. package/app/package.json +1 -1
  391. package/app/server.js +1 -1
  392. package/hooks/trayRuntime.js +153 -77
  393. package/package.json +7 -2
  394. package/src/cli/tray/tray.js +99 -58
  395. package/app/.next-cli-build/server/chunks/4194.js +0 -1
  396. package/app/.next-cli-build/server/chunks/4746.js +0 -1
  397. package/app/.next-cli-build/server/chunks/7250.js +0 -1
  398. package/app/.next-cli-build/server/chunks/8666.js +0 -1
  399. package/app/.next-cli-build/server/chunks/9613.js +0 -1
  400. package/app/.next-cli-build/static/css/c6541e58fb98dd9a.css +0 -1
  401. /package/app/.next-cli-build/static/{o2JUWaEf7w5j6DEc9HFGF → 2mYOb_X99XG3bUyPmT5Yf}/_buildManifest.js +0 -0
  402. /package/app/.next-cli-build/static/{o2JUWaEf7w5j6DEc9HFGF → 2mYOb_X99XG3bUyPmT5Yf}/_ssgManifest.js +0 -0
@@ -1,107 +1,183 @@
1
- // Lazy install systray2 for macOS/Linux into USER_DATA_DIR/runtime/node_modules.
2
- // Windows uses PowerShell NotifyIcon (no binary) → no systray needed.
3
- // This keeps the published npm tarball free of unsigned Go binaries that
4
- // trigger antivirus false positives (e.g. Kaspersky flagging tray_windows.exe).
5
- //
6
- // We use the maintained `systray2` fork. The original `systray@1.0.5` package
7
- // bundles a 2017 x86_64 Go binary whose Mach-O headers are rejected by modern
8
- // dyld (macOS 14+), so the tray silently fails to register on Apple Silicon.
9
- const { spawnSync } = require("child_process");
1
+ // Switchboard tray binary resolver.
2
+ // Uses platform-specific optionalDependencies (esbuild/swc pattern).
3
+ // Each platform has its own npm package containing only that architecture's binary.
4
+ // Falls back to downloading from GitHub releases if optionalDeps are missing.
10
5
  const fs = require("fs");
11
6
  const path = require("path");
12
- const { getRuntimeDir, getRuntimeNodeModules, runNpmInstall, summarizeNpmError } = require("./sqliteRuntime");
7
+ const https = require("https");
8
+ const zlib = require("zlib");
13
9
 
14
- const SYSTRAY_PKG = "systray2";
15
- const SYSTRAY_VERSION = "2.1.4";
16
- const LEGACY_SYSTRAY_PKG = "systray";
10
+ const BINARY_NAME = "switchboard-tray";
11
+ const TRAY_VERSION = "1.0.0";
12
+ const GITHUB_REPO = "Vijay-Duke/switchboard-router";
17
13
 
18
- function hasSystray() {
19
- return fs.existsSync(path.join(getRuntimeNodeModules(), SYSTRAY_PKG, "package.json"));
14
+ // Platform → package name mapping
15
+ const PLATFORM_PACKAGES = {
16
+ "darwin-arm64": "switchboard-tray-darwin-arm64",
17
+ "darwin-x64": "switchboard-tray-darwin-x64",
18
+ "linux-x64": "switchboard-tray-linux-x64",
19
+ };
20
+
21
+ /**
22
+ * Get the platform-specific package name for the current system.
23
+ */
24
+ function getPlatformPackage() {
25
+ const key = `${process.platform}-${process.arch}`;
26
+ return PLATFORM_PACKAGES[key] || null;
20
27
  }
21
28
 
22
- // Remove the legacy `systray` package from all known locations.
23
- // On Windows it was an AV false-positive risk; on macOS/Linux its bundled
24
- // binary is broken on modern OS versions.
25
- function cleanupLegacySystray({ silent = false } = {}) {
26
- // 1) Runtime dir: ~/.switchboard/runtime/node_modules/systray (or %APPDATA% on Win)
27
- // 2) npm global nested: <npm_prefix>/node_modules/switchboard/node_modules/systray
28
- // __dirname here = <pkg root>/hooks → up 1 = pkg root
29
- const targets = [
30
- path.join(getRuntimeNodeModules(), LEGACY_SYSTRAY_PKG),
31
- path.join(__dirname, "..", "node_modules", LEGACY_SYSTRAY_PKG)
32
- ];
33
- for (const dir of targets) {
34
- if (fs.existsSync(dir)) {
35
- try {
36
- fs.rmSync(dir, { recursive: true, force: true });
37
- if (!silent) console.log(`[switchboard][runtime] removed legacy systray: ${dir}`);
38
- } catch (e) {
39
- if (!silent) console.warn(`[switchboard][runtime] failed to remove ${dir}: ${e.message}`);
40
- }
29
+ /**
30
+ * Try to resolve the tray binary from the optionalDependency package.
31
+ * Returns the binary path if found, null otherwise.
32
+ */
33
+ function resolveBinaryFromPackage() {
34
+ const pkg = getPlatformPackage();
35
+ if (!pkg) return null;
36
+
37
+ try {
38
+ // resolve from the installed optionalDependency
39
+ const pkgDir = path.dirname(require.resolve(`${pkg}/package.json`));
40
+ const binPath = path.join(pkgDir, "bin", BINARY_NAME);
41
+ if (fs.existsSync(binPath)) {
42
+ return binPath;
41
43
  }
44
+ } catch {
45
+ // Package not installed (--ignore-optional or install failure)
46
+ }
47
+ return null;
48
+ }
49
+
50
+ /**
51
+ * Fallback: check if the binary was downloaded by postinstall into ~/.switchboard/runtime/bin/
52
+ */
53
+ function resolveBinaryFromCache() {
54
+ const cacheDir = path.join(
55
+ process.env.SWITCHBOARD_DATA_DIR || path.join(require("os").homedir(), ".switchboard"),
56
+ "runtime", "bin"
57
+ );
58
+ const binPath = path.join(cacheDir, BINARY_NAME);
59
+ if (fs.existsSync(binPath)) {
60
+ return binPath;
42
61
  }
62
+ return null;
43
63
  }
44
64
 
45
- // systray2's npm tarball sometimes ships the bundled Go binary without the
46
- // executable bit set on macOS, causing spawn() to fail with EACCES. Set +x
47
- // best-effort so the tray actually starts.
48
- function chmodSystrayBin({ silent = false } = {}) {
49
- if (process.platform === "win32") return;
50
- const binName = process.platform === "darwin" ? "tray_darwin_release" : "tray_linux_release";
51
- const binPath = path.join(getRuntimeNodeModules(), SYSTRAY_PKG, "traybin", binName);
52
- if (!fs.existsSync(binPath)) return;
65
+ /**
66
+ * Download the tray binary from GitHub releases as a last resort.
67
+ * Stores it in ~/.switchboard/runtime/bin/
68
+ */
69
+ async function downloadBinaryFallback({ silent = false } = {}) {
70
+ const pkg = getPlatformPackage();
71
+ if (!pkg) return null;
72
+
73
+ const cacheDir = path.join(
74
+ process.env.SWITCHBOARD_DATA_DIR || path.join(require("os").homedir(), ".switchboard"),
75
+ "runtime", "bin"
76
+ );
77
+ fs.mkdirSync(cacheDir, { recursive: true });
78
+ const destPath = path.join(cacheDir, BINARY_NAME);
79
+
80
+ // Download the platform package tarball from npm and extract the binary
81
+ const tarballUrl = `https://registry.npmjs.org/${pkg}/-/${pkg}-${TRAY_VERSION}.tgz`;
82
+ if (!silent) console.log(`⏳ Downloading tray binary from npm (${pkg})...`);
83
+
53
84
  try {
54
- fs.chmodSync(binPath, 0o755);
55
- } catch (e) {
56
- if (!silent) console.warn(`[switchboard][runtime] chmod tray bin failed: ${e.message}`);
85
+ const tarball = await httpGet(tarballUrl);
86
+ const extracted = extractFileFromTarball(zlib.gunzipSync(tarball), `package/bin/${BINARY_NAME}`);
87
+ if (!extracted) {
88
+ if (!silent) console.warn("⚠️ Failed to extract tray binary from tarball");
89
+ return null;
90
+ }
91
+ fs.writeFileSync(destPath, extracted, { mode: 0o755 });
92
+ if (!silent) console.log("✅ Tray binary downloaded");
93
+ return destPath;
94
+ } catch (err) {
95
+ if (!silent) console.warn(`⚠️ Tray binary download failed: ${err.message}`);
96
+ return null;
57
97
  }
58
98
  }
59
99
 
60
- function ensureRuntimeDir() {
61
- const dir = getRuntimeDir();
62
- if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
63
- const pkgPath = path.join(dir, "package.json");
64
- if (!fs.existsSync(pkgPath)) {
65
- fs.writeFileSync(pkgPath, JSON.stringify({
66
- name: "switchboard-runtime",
67
- version: "1.0.0",
68
- private: true
69
- }, null, 2));
100
+ function httpGet(url) {
101
+ return new Promise((resolve, reject) => {
102
+ https.get(url, (res) => {
103
+ if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
104
+ return httpGet(res.headers.location).then(resolve, reject);
105
+ }
106
+ if (res.statusCode < 200 || res.statusCode >= 300) {
107
+ return reject(new Error(`HTTP ${res.statusCode}`));
108
+ }
109
+ const chunks = [];
110
+ res.on("data", (c) => chunks.push(c));
111
+ res.on("end", () => resolve(Buffer.concat(chunks)));
112
+ res.on("error", reject);
113
+ }).on("error", reject);
114
+ });
115
+ }
116
+
117
+ function extractFileFromTarball(tarBuffer, filepath) {
118
+ let offset = 0;
119
+ while (offset < tarBuffer.length) {
120
+ const header = tarBuffer.subarray(offset, offset + 512);
121
+ offset += 512;
122
+ const fileName = header.toString("utf-8", 0, 100).replace(/\0.*/g, "");
123
+ const fileSize = parseInt(header.toString("utf-8", 124, 136).replace(/\0.*/g, ""), 8);
124
+ if (isNaN(fileSize)) break;
125
+ if (fileName === filepath) {
126
+ return tarBuffer.subarray(offset, offset + fileSize);
127
+ }
128
+ offset = (offset + fileSize + 511) & ~511;
70
129
  }
71
- return dir;
130
+ return null;
72
131
  }
73
132
 
74
- function npmInstall(pkgs, { silent = false } = {}) {
75
- const cwd = ensureRuntimeDir();
76
- if (!silent) console.log("⏳ Installing system tray (first run)...");
77
- const res = runNpmInstall({ cwd, pkgs, extraArgs: ["--no-save"], timeout: 120000 });
78
- if (!res.ok && !silent) {
79
- const reason = summarizeNpmError(res.stderr);
80
- console.warn("⚠️ System tray install failed — tray disabled");
81
- console.warn(` Reason: ${reason}`);
82
- console.warn(` Retry: cd "${cwd}" && npm install ${pkgs.join(" ")}`);
133
+ // Remove legacy systray/systray2 from runtime dir if present
134
+ function cleanupLegacySystray({ silent = false } = {}) {
135
+ const { getRuntimeNodeModules } = require("./sqliteRuntime");
136
+ const targets = [
137
+ path.join(getRuntimeNodeModules(), "systray"),
138
+ path.join(getRuntimeNodeModules(), "systray2"),
139
+ ];
140
+ for (const dir of targets) {
141
+ if (fs.existsSync(dir)) {
142
+ try {
143
+ fs.rmSync(dir, { recursive: true, force: true });
144
+ if (!silent) console.log(`[switchboard] removed legacy tray package: ${path.basename(dir)}`);
145
+ } catch {}
146
+ }
83
147
  }
84
- return res.ok;
85
148
  }
86
149
 
87
- // Public: ensure systray2 is installed on macOS/Linux only.
88
- // Windows skips entirely (uses PowerShell tray).
150
+ /**
151
+ * Resolve the tray binary path. Tries in order:
152
+ * 1. optionalDependency package (installed by npm)
153
+ * 2. Cached binary from previous download
154
+ * 3. null (caller can trigger async download fallback)
155
+ */
156
+ function getTrayBinPath() {
157
+ return resolveBinaryFromPackage() || resolveBinaryFromCache() || null;
158
+ }
159
+
160
+ /**
161
+ * Ensure the tray runtime is available. Called during postinstall or first run.
162
+ */
89
163
  function ensureTrayRuntime({ silent = false } = {}) {
90
- // Always evict the legacy `systray` package — its binary is broken on
91
- // modern macOS and an AV false-positive on Windows.
92
164
  cleanupLegacySystray({ silent });
93
165
 
94
166
  if (process.platform === "win32") {
95
167
  return { systray: false, skipped: true };
96
168
  }
97
- if (hasSystray()) {
98
- chmodSystrayBin({ silent });
169
+
170
+ const binPath = getTrayBinPath();
171
+ if (binPath) {
172
+ // Ensure executable bit
173
+ try { fs.chmodSync(binPath, 0o755); } catch {}
99
174
  if (!silent) console.log("✅ System tray ready");
100
- return { systray: true };
175
+ return { systray: true, binPath };
101
176
  }
102
- const ok = npmInstall([`${SYSTRAY_PKG}@${SYSTRAY_VERSION}`], { silent });
103
- if (ok) chmodSystrayBin({ silent });
104
- return { systray: ok && hasSystray() };
177
+
178
+ if (!silent) console.log("ℹ️ Tray binary not found (optionalDependency may have been skipped). Will download on first use.");
179
+ return { systray: false, needsDownload: true };
105
180
  }
106
181
 
107
- module.exports = { ensureTrayRuntime };
182
+ module.exports = { ensureTrayRuntime, getTrayBinPath, downloadBinaryFallback, getPlatformPackage };
183
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "switchboard-router",
3
- "version": "0.6.19",
3
+ "version": "0.6.22",
4
4
  "description": "Switchboard CLI — local AI routing gateway (install: npm i -g switchboard-router; run: switchboard)",
5
5
  "bin": {
6
6
  "switchboard": "./cli.js",
@@ -39,7 +39,12 @@
39
39
  "react-dom": "^19.2.7"
40
40
  },
41
41
  "comment_sqlite": "sql.js + better-sqlite3 are NOT bundled here. They are installed into ~/.switchboard/runtime/node_modules by hooks/postinstall.js (and re-checked at runtime by cli.js). This avoids Windows EBUSY errors when updating the global CLI, since native .node files no longer live under the locked install dir.",
42
- "comment_systray": "systray2 is NOT bundled here. It is lazy-installed into ~/.switchboard/runtime/node_modules by hooks/postinstall.js on macOS/Linux only. Windows uses PowerShell NotifyIcon (zero binary). This avoids shipping unsigned Go binaries that trigger antivirus false positives (Kaspersky). We use the systray2 fork because the legacy systray@1.0.5 ships a 2017 x86_64 binary that fails on modern macOS dyld.",
42
+ "comment_systray": "System tray uses platform-specific optionalDependencies (esbuild pattern). npm installs only the matching binary for the user's OS/arch. Windows uses PowerShell NotifyIcon (zero binary). Postinstall fallback downloads from GitHub releases if optionalDeps are skipped.",
43
+ "optionalDependencies": {
44
+ "switchboard-tray-darwin-arm64": "^1.0.0",
45
+ "switchboard-tray-darwin-x64": "1.0.0",
46
+ "switchboard-tray-linux-x64": "1.0.0"
47
+ },
43
48
  "engines": {
44
49
  "node": ">=18.0.0"
45
50
  },
@@ -156,80 +156,132 @@ function initWindowsTray(options) {
156
156
  }
157
157
 
158
158
  /**
159
- * macOS/Linux tray via systray binary
159
+ * macOS/Linux tray via our own switchboard-tray binary.
160
160
  *
161
- * Prefers `systray2` (active fork of `systray`, ships newer
162
- * getlantern/systray-portable binaries that work on macOS 14+ and Apple
163
- * Silicon under Rosetta). Falls back to legacy `systray@1.0.5` if systray2
164
- * is not available, though that binary's Mach-O headers are rejected by
165
- * modern dyld and the icon will not appear.
161
+ * Spawns the Go binary directly (no systray2 dependency).
162
+ * Binary communicates via JSON-per-line on stdin/stdout.
163
+ * Installed as optionalDependencies per platform (esbuild pattern).
166
164
  */
167
- function resolveSystray() {
168
- let runtimeDir = null;
165
+ function resolveTrayBinPath() {
169
166
  try {
170
- const { getRuntimeNodeModules } = require("../../../hooks/sqliteRuntime");
171
- runtimeDir = getRuntimeNodeModules();
172
- } catch (e) {}
167
+ const { getTrayBinPath, downloadBinaryFallback } = require("../../../hooks/trayRuntime");
168
+ return { binPath: getTrayBinPath(), downloadBinaryFallback };
169
+ } catch {
170
+ return { binPath: null, downloadBinaryFallback: null };
171
+ }
172
+ }
173
173
 
174
- // 1) systray2 in runtime dir (where ensureTrayRuntime installs it)
175
- if (runtimeDir) {
176
- try { return { mod: require(path.join(runtimeDir, "systray2")).default, isV2: true }; } catch (e) {}
174
+ /**
175
+ * Lightweight tray wrapper — spawns our binary and provides the same interface
176
+ * that the old systray2 SysTray class exposed (.onClick, .sendAction, .ready, .kill, ._process).
177
+ */
178
+ class SwitchboardTray {
179
+ constructor({ menu, binPath }) {
180
+ this._binPath = binPath;
181
+ this._menu = menu;
182
+ this._process = null;
183
+ this._rl = null;
184
+ this._onClickListeners = [];
185
+ this._readyPromise = this._start();
177
186
  }
178
- // 2) systray2 resolvable from the package's own node_modules / NODE_PATH
179
- try { return { mod: require("systray2").default, isV2: true }; } catch (e) {}
180
- // 3) Legacy systray fallback (unlikely to render on modern macOS)
181
- try { return { mod: require("systray").default, isV2: false }; } catch (e) {}
182
- if (runtimeDir) {
183
- try { return { mod: require(path.join(runtimeDir, "systray")).default, isV2: false }; } catch (e) {}
187
+
188
+ async _start() {
189
+ const { spawn } = require("child_process");
190
+ const { createInterface } = require("readline");
191
+
192
+ this._process = spawn(this._binPath, [], { windowsHide: true });
193
+
194
+ this._rl = createInterface({ input: this._process.stdout });
195
+
196
+ return new Promise((resolve, reject) => {
197
+ this._process.on("error", reject);
198
+
199
+ const onLine = (line) => {
200
+ try {
201
+ const msg = JSON.parse(line);
202
+ if (msg.type === "ready") {
203
+ // Send menu config
204
+ this._write(JSON.stringify(this._menu));
205
+ resolve();
206
+ } else if (msg.type === "clicked") {
207
+ for (const listener of this._onClickListeners) {
208
+ listener(msg);
209
+ }
210
+ }
211
+ } catch {}
212
+ };
213
+
214
+ this._rl.on("line", onLine);
215
+ });
184
216
  }
185
- return null;
186
- }
187
217
 
188
- function chmodTrayBin(pkgName) {
189
- // systray2's npm tarball occasionally lands without +x on the bundled Go
190
- // binary (observed on macOS). spawn() then fails with EACCES. Best-effort
191
- // chmod on every init avoids a hard-to-diagnose silent tray failure.
192
- try {
193
- const { getRuntimeNodeModules } = require("../../../hooks/sqliteRuntime");
194
- const binName = process.platform === "darwin" ? "tray_darwin_release" : "tray_linux_release";
195
- const candidates = [
196
- path.join(getRuntimeNodeModules(), pkgName, "traybin", binName),
197
- path.join(__dirname, "..", "..", "..", "node_modules", pkgName, "traybin", binName)
198
- ];
199
- for (const p of candidates) {
200
- if (fs.existsSync(p)) fs.chmodSync(p, 0o755);
218
+ _write(line) {
219
+ if (this._process && this._process.stdin && !this._process.stdin.destroyed) {
220
+ this._process.stdin.write(line.trim() + "\n");
201
221
  }
202
- } catch (e) {}
222
+ }
223
+
224
+ ready() {
225
+ return this._readyPromise;
226
+ }
227
+
228
+ onClick(listener) {
229
+ this._onClickListeners.push(listener);
230
+ return this._readyPromise;
231
+ }
232
+
233
+ sendAction(action) {
234
+ this._write(JSON.stringify(action));
235
+ return this;
236
+ }
237
+
238
+ kill(exitNode = false) {
239
+ if (this._process) {
240
+ this._write(JSON.stringify({ type: "exit" }));
241
+ setTimeout(() => {
242
+ try { this._process.kill("SIGTERM"); } catch {}
243
+ }, 500);
244
+ }
245
+ if (exitNode) process.exit(0);
246
+ }
203
247
  }
204
248
 
205
249
  function initUnixTray(options, {
206
- resolveSystrayImpl = resolveSystray,
207
- chmodTrayBinImpl = chmodTrayBin,
250
+ resolveTrayBinPathImpl = resolveTrayBinPath,
208
251
  getAutostartEnabledImpl = getAutostartEnabled,
209
252
  } = {}) {
210
253
  const { port } = options;
211
254
  try {
212
- const resolved = resolveSystrayImpl();
213
- if (!resolved) return null;
214
- const { mod: SysTray, isV2 } = resolved;
255
+ const { binPath, downloadBinaryFallback } = resolveTrayBinPathImpl();
256
+
257
+ if (!binPath) {
258
+ // Try async download fallback
259
+ if (downloadBinaryFallback) {
260
+ downloadBinaryFallback({ silent: true }).then((downloaded) => {
261
+ if (downloaded) {
262
+ // Binary now available — caller can retry via interface menu
263
+ process.stderr.write("[switchboard] tray binary downloaded; restart to enable tray icon\n");
264
+ }
265
+ }).catch(() => {});
266
+ }
267
+ return null;
268
+ }
215
269
 
216
- chmodTrayBinImpl(isV2 ? "systray2" : "systray");
270
+ // Ensure executable
271
+ try { fs.chmodSync(binPath, 0o755); } catch {}
217
272
 
218
273
  const autostartEnabled = getAutostartEnabledImpl();
219
274
  const items = buildMenuItems(port, autostartEnabled);
220
275
 
221
276
  const menu = {
222
277
  icon: getIconBase64(),
223
- // The bundled icon.png is a full-color RGBA logo. Don't mark it as a
224
- // template icon: macOS would then render it as a solid white square
225
- // because template mode only uses the alpha channel.
226
278
  isTemplateIcon: false,
227
279
  title: "",
228
280
  tooltip: `Switchboard - Port ${port}`,
229
281
  items
230
282
  };
231
283
 
232
- trayInstance = new SysTray({ menu, debug: false, copyDir: true });
284
+ trayInstance = new SwitchboardTray({ menu, binPath });
233
285
  isWinTray = false;
234
286
 
235
287
  const clickRegistration = trayInstance.onClick((action) => {
@@ -245,22 +297,11 @@ function initUnixTray(options, {
245
297
  });
246
298
  });
247
299
  });
248
- // systray2 waits for ready() inside onClick(). If its bundled executable
249
- // cannot run (for example x86_64 on ARM without Rosetta), this separate
250
- // promise rejects too. Observe it so Node does not promote the rejection
251
- // to uncaughtException and shut down an otherwise healthy server/TUI.
252
300
  if (clickRegistration && typeof clickRegistration.catch === "function") {
253
301
  clickRegistration.catch(() => {});
254
302
  }
255
303
 
256
- if (isV2) {
257
- // The caller awaits ready() and reports one contextual error. Observe the
258
- // source promise here as defense-in-depth for any future direct caller.
259
- trayInstance.ready().catch(() => {});
260
- } else {
261
- trayInstance.onReady(() => {});
262
- trayInstance.onError(() => {});
263
- }
304
+ trayInstance.ready().catch(() => {});
264
305
 
265
306
  return trayInstance;
266
307
  } catch (err) {
@@ -1 +0,0 @@
1
- "use strict";exports.id=4194,exports.ids=[4194],exports.modules={7866:(a,b,c)=>{c.d(b,{w$:()=>e});let d=c(39006).rE||"0.0.0";function e(a,b={}){let c,f=(c=function(a){if("string"!=typeof a)return"";let b=a.trim();return b?b.startsWith("workos:")?b:`workos:${b}`:""}(a))?`Bearer ${c}`:"",g={"HTTP-Referer":"https://cline.bot","X-Title":"Cline","User-Agent":`Switchboard/${d}`,"X-PLATFORM":process.platform||"unknown","X-PLATFORM-VERSION":process.version||"unknown","X-CLIENT-TYPE":"switchboard","X-CLIENT-VERSION":d,"X-CORE-VERSION":d,"X-IS-MULTIROOT":"false",...b};return f&&(g.Authorization=f),g}},39326:(a,b,c)=>{function d(a){return null==a?"":String(a).trim()}async function e(a={}){try{let b=function(a={}){let b=a?.connectionProxyEnabled===!0,c=d(a?.connectionProxyUrl);return{connectionProxyEnabled:b,connectionProxyUrl:c,connectionNoProxy:d(a?.connectionNoProxy)}}(a);if(b.connectionProxyEnabled&&b.connectionProxyUrl)return{source:"legacy",proxyPoolId:null,proxyPool:null,...b,strictProxy:!1,vercelRelayUrl:""};return{source:"none",proxyPoolId:null,proxyPool:null,connectionProxyEnabled:!1,connectionProxyUrl:"",connectionNoProxy:b.connectionNoProxy||"",strictProxy:!1,vercelRelayUrl:""}}catch(a){return console.error("[resolveConnectionProxyConfig] Failed to resolve proxy config:",a),{source:"error",proxyPoolId:null,proxyPool:null,connectionProxyEnabled:!1,connectionProxyUrl:"",connectionNoProxy:"",strictProxy:!1,vercelRelayUrl:""}}}c.d(b,{B:()=>e})},47293:(a,b,c)=>{c.d(b,{A:()=>f});let d=new Uint8Array(16);var e=c(50122);let f=function(a,b,c){return b||a||!crypto.randomUUID?function(a,b,c){let f=(a=a||{}).random??a.rng?.()??crypto.getRandomValues(d);if(f.length<16)throw Error("Random bytes length must be >= 16");if(f[6]=15&f[6]|64,f[8]=63&f[8]|128,b){if((c=c||0)<0||c+16>b.length)throw RangeError(`UUID byte range ${c}:${c+15} is out of buffer bounds`);for(let a=0;a<16;++a)b[c+a]=f[a];return b}return(0,e.k)(f)}(a,b,c):crypto.randomUUID()}},50122:(a,b,c)=>{c.d(b,{k:()=>e});let d=[];for(let a=0;a<256;++a)d.push((a+256).toString(16).slice(1));function e(a,b=0){return(d[a[b+0]]+d[a[b+1]]+d[a[b+2]]+d[a[b+3]]+"-"+d[a[b+4]]+d[a[b+5]]+"-"+d[a[b+6]]+d[a[b+7]]+"-"+d[a[b+8]]+d[a[b+9]]+"-"+d[a[b+10]]+d[a[b+11]]+d[a[b+12]]+d[a[b+13]]+d[a[b+14]]+d[a[b+15]]).toLowerCase()}},66328:(a,b,c)=>{c.d(b,{F:()=>w});var d=c(44776),e=c(39326),f=c(74926),g=c(40615),h=c(27335),i=c(57034),j=c(4630),k=c(18129),l=c(92990),m=c(73159),n=c(7866);let o={claude:{checkExpiry:!0,refreshable:!0},xai:{url:`${m.o.apiBaseUrl}/models`,method:"GET",authHeader:"Authorization",authPrefix:"Bearer ",extraHeaders:{"User-Agent":m.o.userAgent,Accept:"application/json"},acceptStatuses:[403],refreshable:!0},codex:{url:"https://chatgpt.com/backend-api/codex/responses",method:"POST",authHeader:"Authorization",authPrefix:"Bearer ",extraHeaders:{"Content-Type":"application/json",originator:"codex_cli_rs","User-Agent":"codex_cli_rs/0.136.0"},body:JSON.stringify({model:"gpt-5.3-codex",input:[],stream:!1,store:!1}),acceptStatuses:[400],refreshable:!0},"gemini-cli":{url:"https://www.googleapis.com/oauth2/v1/userinfo?alt=json",method:"GET",authHeader:"Authorization",authPrefix:"Bearer ",refreshable:!0},antigravity:{url:"https://www.googleapis.com/oauth2/v1/userinfo?alt=json",method:"GET",authHeader:"Authorization",authPrefix:"Bearer ",refreshable:!0},github:{url:"https://api.github.com/user",method:"GET",authHeader:"Authorization",authPrefix:"Bearer ",extraHeaders:{"User-Agent":"Switchboard",Accept:"application/vnd.github+json"}},iflow:{buildUrl:a=>`https://iflow.cn/api/oauth/getUserInfo?accessToken=${encodeURIComponent(a)}`,method:"GET",noAuth:!0},qwen:{checkExpiry:!0,refreshable:!0},kiro:{checkExpiry:!0,refreshable:!0},qoder:{url:"https://openapi.qoder.sh/api/v1/userinfo",method:"GET",authHeader:"Authorization",authPrefix:"Bearer ",refreshable:!1},"kimi-coding":{checkExpiry:!0,refreshable:!1},cursor:{tokenExists:!0},kilocode:{url:`${l.MZ.apiBaseUrl}/api/profile`,method:"GET",authHeader:"Authorization",authPrefix:"Bearer "},cline:{refreshable:!0},clinepass:{refreshable:!0},gitlab:{url:"https://gitlab.com/api/v4/user",method:"GET",authHeader:"Authorization",authPrefix:"Bearer "},"codebuddy-cn":{tokenExists:!0},kimchi:{url:l.Td.validationUrl||"https://api.cast.ai/v1/llm/openai/supported-providers",method:"GET",authHeader:"Authorization",authPrefix:"Bearer ",extraHeaders:{Accept:"application/json","User-Agent":"kimchi/0.1.40"},refreshable:!1}};async function p(a,b=null){return await u("https://api.cline.bot/api/v1/users/me",{method:"GET",headers:(0,n.w$)(a,{Accept:"application/json"})},b)}let q=JSON.stringify({metadata:{ideType:"IDE_UNSPECIFIED",platform:"PLATFORM_UNSPECIFIED",pluginType:"GEMINI"}});async function r(a,b,c=null){let d="antigravity"===a.provider?"google-api-nodejs-client/9.15.1 vscode-antigravity/1.107.0":"google-api-nodejs-client/9.15.1 gemini-cli/0.34.0",e=await u("https://cloudcode-pa.googleapis.com/v1internal:loadCodeAssist",{method:"POST",headers:{Authorization:`Bearer ${b}`,"Content-Type":"application/json","User-Agent":d},body:q},c);return e.ok?{valid:!0,error:null}:{valid:!1,error:function(a,b){if(!a)return b;try{let b=JSON.parse(a),c=b?.error?.message||b?.message||b?.error;if("string"==typeof c&&c.trim())return c.trim();if(c)return JSON.stringify(c)}catch{}return a.trim()||b}(await e.text().catch(()=>""),`API returned ${e.status}`),status:e.status}}async function s(a){let b=a.provider,c=a.refreshToken;if(!c)return null;try{if("gemini-cli"===b||"antigravity"===b){let a="gemini-cli"===b?l.LT:l.YT,d=await fetch("https://oauth2.googleapis.com/token",{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({client_id:a.clientId,client_secret:a.clientSecret,grant_type:"refresh_token",refresh_token:c})});if(!d.ok)return null;let e=await d.json();return{accessToken:e.access_token,expiresIn:e.expires_in,refreshToken:e.refresh_token||c}}if("codex"===b||"xai"===b)return await (0,k.Vq)(b,a,console);if("claude"===b){let a=await fetch(l.OV.tokenUrl,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({grant_type:"refresh_token",refresh_token:c,client_id:l.OV.clientId})});if(!a.ok)return null;let b=await a.json();return{accessToken:b.access_token,expiresIn:b.expires_in,refreshToken:b.refresh_token||c}}if("kiro"===b){let b=a.providerSpecificData||{},d=b.clientId||a.clientId,e=b.clientSecret||a.clientSecret,f=(0,i.l6)(b.region||a.region);if(d&&e){let a=`https://oidc.${f}.amazonaws.com/token`,b=await fetch(a,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({clientId:d,clientSecret:e,refreshToken:c,grantType:"refresh_token"})});if(!b.ok)return null;let g=await b.json();return{accessToken:g.accessToken,expiresIn:g.expiresIn||3600,refreshToken:g.refreshToken||c}}let g=await fetch(l.Tx.socialRefreshUrl,{method:"POST",headers:{"Content-Type":"application/json","User-Agent":"kiro-cli/1.0.0"},body:JSON.stringify({refreshToken:c})});if(!g.ok)return null;let h=await g.json();return{accessToken:h.accessToken,expiresIn:h.expiresIn||3600,refreshToken:h.refreshToken||c}}if("qwen"===b){let a=await fetch(l.Hp.tokenUrl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:new URLSearchParams({grant_type:"refresh_token",refresh_token:c,client_id:l.Hp.clientId})});if(!a.ok)return null;let b=await a.json();return{accessToken:b.access_token,expiresIn:b.expires_in,refreshToken:b.refresh_token||c}}if("cline"===b||"clinepass"===b){let a=await fetch(l.lB.refreshUrl,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({refreshToken:c,grantType:"refresh_token",clientType:"extension"})});if(!a.ok)return null;let b=await a.json(),d=b?.data||b,e=d?.expiresAt?Math.max(1,Math.floor((new Date(d.expiresAt).getTime()-Date.now())/1e3)):3600;return{accessToken:d?.accessToken,expiresIn:e,refreshToken:d?.refreshToken||c}}return null}catch(a){return console.log(`Error refreshing ${b} token:`,a.message),null}}async function t(a,b=null){let c=o[a.provider];if(!c)return{valid:!1,error:"Provider test not supported",refreshed:!1};if(!a.accessToken)return{valid:!1,error:"No access token",refreshed:!1};if(c.tokenExists)return{valid:!0,error:null,refreshed:!1,newTokens:null};let d=a.accessToken,e=!1,f=null,g=(0,k.fp)(a.provider,a);if(c.refreshable&&g&&a.refreshToken){let b=await s(a);if(!b)return{valid:!1,error:"Token expired and refresh failed",refreshed:!1};d=b.accessToken,e=!0,f=b}if(c.checkExpiry)return e?{valid:!0,error:null,refreshed:e,newTokens:f}:g?{valid:!1,error:"Token expired",refreshed:!1}:{valid:!0,error:null,refreshed:!1,newTokens:null};if("gemini-cli"===a.provider||"antigravity"===a.provider){let g=await r(a,d,b);if(g.valid)return{valid:!0,error:null,refreshed:e,newTokens:f};if(401===g.status&&c.refreshable&&!e&&a.refreshToken){let c=await s(a);if(c?.accessToken){let d=await r(a,c.accessToken,b);return d.valid?{valid:!0,error:null,refreshed:!0,newTokens:c}:{valid:!1,error:d.error,refreshed:!0,newTokens:c}}return{valid:!1,error:"Token invalid or revoked",refreshed:!1}}return{valid:!1,error:g.error,refreshed:e}}if("cline"===a.provider||"clinepass"===a.provider){let c=async a=>{let c=await p(a,b);return c.ok?{valid:!0,error:null,refreshed:e,newTokens:f}:401===c.status?{valid:!1,error:"Token invalid or revoked",refreshed:e}:403===c.status?{valid:!1,error:"Access denied",refreshed:e}:{valid:!1,error:`API returned ${c.status}`,refreshed:e}},g=await c(d);if(g.valid||"Token invalid or revoked"!==g.error||!a.refreshToken)return g;let h=await s(a);return h?.accessToken?(e=!0,f=h,d=h.accessToken,await c(d)):{valid:!1,error:"Token invalid or revoked",refreshed:!1}}try{let g=c.buildUrl?c.buildUrl(d):c.url,h=c.noAuth?{...c.extraHeaders}:{[c.authHeader]:`${c.authPrefix}${d}`,...c.extraHeaders},i={method:c.method,headers:h};c.body&&(i.body=c.body);let j=await u(g,i,b);if(j.ok||c.acceptStatuses&&c.acceptStatuses.includes(j.status))return{valid:!0,error:null,refreshed:e,newTokens:f};if(401===j.status&&c.refreshable&&!e&&a.refreshToken){let d=await s(a);if(d){let a=c.buildUrl?c.buildUrl(d.accessToken):g,e=c.noAuth?{...c.extraHeaders}:{[c.authHeader]:`${c.authPrefix}${d.accessToken}`,...c.extraHeaders},f={method:c.method,headers:e};c.body&&(f.body=c.body);let h=await u(a,f,b);if(h.ok||c.acceptStatuses&&c.acceptStatuses.includes(h.status))return{valid:!0,error:null,refreshed:!0,newTokens:d}}return{valid:!1,error:"Token invalid or revoked",refreshed:!1}}if(401===j.status)return{valid:!1,error:"Token invalid or revoked",refreshed:e};if(403===j.status)return{valid:!1,error:"Access denied",refreshed:e};return{valid:!1,error:`API returned ${j.status}`,refreshed:e}}catch(a){return{valid:!1,error:a.message,refreshed:e}}}async function u(a,b={},d=null){if(d?.vercelRelayUrl){let{proxyAwareFetch:e}=await Promise.resolve().then(c.bind(c,89843));return e(a,b,{vercelRelayUrl:d.vercelRelayUrl})}if(!d?.connectionProxyEnabled||!d?.connectionProxyUrl)return fetch(a,b);let{proxyAwareFetch:e}=await Promise.resolve().then(c.bind(c,89843));return e(a,b,{connectionProxyEnabled:!0,connectionProxyUrl:d.connectionProxyUrl,connectionNoProxy:d.connectionNoProxy||""})}async function v(a,b=null){if((0,g.mq)(a.provider)){let c=a.providerSpecificData?.baseUrl;if(!c)return{valid:!1,error:"Missing base URL"};try{let d=await u(`${c.replace(/\/$/,"")}/models`,{headers:{Authorization:`Bearer ${a.apiKey}`}},b);return{valid:d.ok,error:d.ok?null:"Invalid API key or base URL"}}catch(a){return{valid:!1,error:a.message}}}if((0,g.gb)(a.provider)){let c=a.providerSpecificData?.baseUrl;if(!c)return{valid:!1,error:"Missing base URL"};try{(c=c.replace(/\/$/,"")).endsWith("/messages")&&(c=c.slice(0,-9));let d=c.endsWith("/v1")?`${c}/messages`:`${c}/v1/messages`,e=a.defaultModel||"claude-3-haiku-20240307",f=await u(d,{method:"POST",headers:{"x-api-key":a.apiKey,"anthropic-version":"2023-06-01","content-type":"application/json",Authorization:`Bearer ${a.apiKey}`},body:JSON.stringify({model:e,max_tokens:1,messages:[{role:"user",content:"test"}]})},b),g=401!==f.status&&403!==f.status;return{valid:g,error:g?null:"Invalid API key or base URL"}}catch(a){return{valid:!1,error:a.message}}}try{switch(a.provider){case"cloudflare-ai":{let c=(a.providerSpecificData||{}).accountId;if(!c)return{valid:!1,error:"Missing Account ID"};let d=`https://api.cloudflare.com/client/v4/accounts/${c}/ai/v1/chat/completions`,e=await u(d,{method:"POST",headers:{Authorization:`Bearer ${a.apiKey}`,"Content-Type":"application/json"},body:JSON.stringify({model:(0,h.fZ)("cloudflare-ai"),messages:[{role:"user",content:"test"}],max_tokens:1})},b),f=401!==e.status&&403!==e.status&&404!==e.status;return{valid:f,error:f?null:"Invalid API token or Account ID"}}case"azure":{let c=a.providerSpecificData||{},d=(c.azureEndpoint||"").replace(/\/$/,""),e=c.deployment||"gpt-4",f=c.apiVersion||"2024-10-01-preview",g=`${d}/openai/deployments/${e}/chat/completions?api-version=${f}`,h={"api-key":a.apiKey,"Content-Type":"application/json"};c.organization&&(h["OpenAI-Organization"]=c.organization);let i=await u(g,{method:"POST",headers:h,body:JSON.stringify({messages:[{role:"user",content:"test"}],max_completion_tokens:1})},b),j=401!==i.status&&403!==i.status;return{valid:j,error:j?null:"Invalid API key or Azure configuration"}}case"openai":{let c=await u("https://api.openai.com/v1/models",{headers:{Authorization:`Bearer ${a.apiKey}`}},b);return{valid:c.ok,error:c.ok?null:"Invalid API key"}}case"vercel-ai-gateway":{let c=await u("https://ai-gateway.vercel.sh/v1/models",{headers:{Authorization:`Bearer ${a.apiKey}`}},b);return{valid:c.ok,error:c.ok?null:"Invalid API key"}}case"anthropic":{let c=await u("https://api.anthropic.com/v1/messages",{method:"POST",headers:{"x-api-key":a.apiKey,"anthropic-version":"2023-06-01","content-type":"application/json"},body:JSON.stringify({model:"claude-3-haiku-20240307",max_tokens:1,messages:[{role:"user",content:"test"}]})},b),d=401!==c.status;return{valid:d,error:d?null:"Invalid API key"}}case"gemini":{let c=await u(`https://generativelanguage.googleapis.com/v1/models?key=${a.apiKey}`,{},b);return{valid:c.ok,error:c.ok?null:"Invalid API key"}}case"openrouter":{let c=await u("https://openrouter.ai/api/v1/auth/key",{headers:{Authorization:`Bearer ${a.apiKey}`}},b);return{valid:c.ok,error:c.ok?null:"Invalid API key"}}case"glm":{let c=await u("https://api.z.ai/api/anthropic/v1/messages",{method:"POST",headers:{"x-api-key":a.apiKey,"anthropic-version":"2023-06-01","content-type":"application/json"},body:JSON.stringify({model:"glm-4.7",max_tokens:1,messages:[{role:"user",content:"test"}]})},b),d=401!==c.status&&403!==c.status;return{valid:d,error:d?null:"Invalid API key"}}case"glm-cn":{let c=await u("https://open.bigmodel.cn/api/coding/paas/v4/chat/completions",{method:"POST",headers:{Authorization:`Bearer ${a.apiKey}`,"content-type":"application/json"},body:JSON.stringify({model:"glm-4.7",max_tokens:1,messages:[{role:"user",content:"test"}]})},b),d=401!==c.status&&403!==c.status;return{valid:d,error:d?null:"Invalid API key"}}case"minimax":case"minimax-cn":{let c=await u({minimax:"https://api.minimax.io/anthropic/v1/messages","minimax-cn":"https://api.minimaxi.com/anthropic/v1/messages"}[a.provider],{method:"POST",headers:{"x-api-key":a.apiKey,"anthropic-version":"2023-06-01","content-type":"application/json"},body:JSON.stringify({model:"minimax-m2",max_tokens:1,messages:[{role:"user",content:"test"}]})},b),d=401!==c.status&&403!==c.status;return{valid:d,error:d?null:"Invalid API key"}}case"kimi":{let c=await u("https://api.kimi.com/coding/v1/messages",{method:"POST",headers:{"x-api-key":a.apiKey,"anthropic-version":"2023-06-01","content-type":"application/json"},body:JSON.stringify({model:"kimi-latest",max_tokens:1,messages:[{role:"user",content:"test"}]})},b),d=401!==c.status&&403!==c.status;return{valid:d,error:d?null:"Invalid API key"}}case"alicode":case"alicode-intl":{let c="alicode-intl"===a.provider?"https://coding-intl.dashscope.aliyuncs.com/v1/chat/completions":"https://coding.dashscope.aliyuncs.com/v1/chat/completions",d=await u(c,{method:"POST",headers:{Authorization:`Bearer ${a.apiKey}`,"content-type":"application/json"},body:JSON.stringify({model:(0,h.fZ)(a.provider),max_tokens:1,messages:[{role:"user",content:"test"}]})},b),e=401!==d.status&&403!==d.status;return{valid:e,error:e?null:"Invalid API key"}}case"volcengine-ark":case"byteplus":{let c=await u(j.xq[a.provider]?.baseUrl,{method:"POST",headers:{Authorization:`Bearer ${a.apiKey}`,"content-type":"application/json"},body:JSON.stringify({model:(0,h.fZ)(a.provider),max_tokens:1,messages:[{role:"user",content:"test"}]})},b),d=401!==c.status&&403!==c.status;return{valid:d,error:d?null:"Invalid API key"}}case"deepseek":{let c=await u("https://api.deepseek.com/models",{headers:{Authorization:`Bearer ${a.apiKey}`}},b);return{valid:c.ok,error:c.ok?null:"Invalid API key"}}case"groq":{let c=await u("https://api.groq.com/openai/v1/models",{headers:{Authorization:`Bearer ${a.apiKey}`}},b);return{valid:c.ok,error:c.ok?null:"Invalid API key"}}case"mistral":{let c=await u("https://api.mistral.ai/v1/models",{headers:{Authorization:`Bearer ${a.apiKey}`}},b);return{valid:c.ok,error:c.ok?null:"Invalid API key"}}case"xai":{let c=await u("https://api.x.ai/v1/models",{headers:{Authorization:`Bearer ${a.apiKey}`,"User-Agent":m.o.userAgent,Accept:"application/json"}},b),d=c.ok||403===c.status;return{valid:d,error:d?null:"Invalid API key"}}case"nvidia":{let c=await u("https://integrate.api.nvidia.com/v1/models",{headers:{Authorization:`Bearer ${a.apiKey}`}},b);return{valid:c.ok,error:c.ok?null:"Invalid API key"}}case"perplexity":{let c=await u("https://api.perplexity.ai/v1/models",{headers:{Authorization:`Bearer ${a.apiKey}`}},b);return{valid:c.ok,error:c.ok?null:"Invalid API key"}}case"together":{let c=await u("https://api.together.xyz/v1/models",{headers:{Authorization:`Bearer ${a.apiKey}`}},b);return{valid:c.ok,error:c.ok?null:"Invalid API key"}}case"fireworks":{let c=await u("https://api.fireworks.ai/inference/v1/models",{headers:{Authorization:`Bearer ${a.apiKey}`}},b);return{valid:c.ok,error:c.ok?null:"Invalid API key"}}case"cerebras":{let c=await u("https://api.cerebras.ai/v1/models",{headers:{Authorization:`Bearer ${a.apiKey}`}},b);return{valid:c.ok,error:c.ok?null:"Invalid API key"}}case"cohere":{let c=await u("https://api.cohere.ai/v1/models",{headers:{Authorization:`Bearer ${a.apiKey}`}},b);return{valid:c.ok,error:c.ok?null:"Invalid API key"}}case"nebius":{let c=await u("https://api.studio.nebius.ai/v1/models",{headers:{Authorization:`Bearer ${a.apiKey}`}},b);return{valid:c.ok,error:c.ok?null:"Invalid API key"}}case"siliconflow":{let c=await u("https://api.siliconflow.com/v1/models",{headers:{Authorization:`Bearer ${a.apiKey}`}},b);return{valid:c.ok,error:c.ok?null:"Invalid API key"}}case"hyperbolic":{let c=await u("https://api.hyperbolic.xyz/v1/models",{headers:{Authorization:`Bearer ${a.apiKey}`}},b);return{valid:c.ok,error:c.ok?null:"Invalid API key"}}case"ollama":{let b=await fetch("https://ollama.com/api/tags",{headers:{Authorization:`Bearer ${a.apiKey}`}});return{valid:b.ok,error:b.ok?null:"Invalid API key"}}case"ollama-local":{let b=(0,j.Ak)(a),c=await fetch(`${b}/api/tags`);return{valid:c.ok,error:c.ok?null:`Ollama not reachable at ${b}`}}case"deepgram":{let c=await u("https://api.deepgram.com/v1/projects",{headers:{Authorization:`Token ${a.apiKey}`}},b);return{valid:c.ok,error:c.ok?null:"Invalid API key"}}case"assemblyai":{let c=await u("https://api.assemblyai.com/v1/account",{headers:{Authorization:`Bearer ${a.apiKey}`}},b);return{valid:c.ok,error:c.ok?null:"Invalid API key"}}case"nanobanana":{let c=await u("https://api.nanobananaapi.ai/v1/models",{headers:{Authorization:`Bearer ${a.apiKey}`}},b);return{valid:c.ok,error:c.ok?null:"Invalid API key"}}case"fal-ai":{let c=await u("https://api.fal.ai/v1/models?limit=1",{headers:{Authorization:`Key ${a.apiKey}`}},b),d=401!==c.status&&403!==c.status;return{valid:d,error:d?null:"Invalid API key"}}case"chutes":{let c=await u("https://llm.chutes.ai/v1/models",{headers:{Authorization:`Bearer ${a.apiKey}`}},b);return{valid:c.ok,error:c.ok?null:"Invalid API key"}}case"grok-web":{let c=a.apiKey.startsWith("sso=")?a.apiKey.slice(4):a.apiKey,d=a=>Array.from(crypto.getRandomValues(new Uint8Array(a)),a=>a.toString(16).padStart(2,"0")).join(""),e=Buffer.from("e:TypeError: Cannot read properties of null (reading 'children')").toString("base64"),f=await u("https://grok.com/rest/app-chat/conversations/new",{method:"POST",headers:{Accept:"*/*","Content-Type":"application/json",Cookie:`sso=${c}`,Origin:"https://grok.com",Referer:"https://grok.com/","User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36","x-statsig-id":e,"x-xai-request-id":crypto.randomUUID(),traceparent:`00-${d(16)}-${d(8)}-00`},body:JSON.stringify({temporary:!0,modelName:"grok-4",message:"ping",fileAttachments:[],imageAttachments:[],disableSearch:!1,enableImageGeneration:!1,sendFinalMetadata:!0})},b),g=401!==f.status&&403!==f.status;return{valid:g,error:g?null:"Invalid SSO cookie"}}case"perplexity-web":{let c=a.apiKey;c.startsWith("__Secure-next-auth.session-token=")&&(c=c.slice(33));let d=await u("https://www.perplexity.ai/api/auth/session",{method:"GET",headers:{"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36",Cookie:`__Secure-next-auth.session-token=${c}`}},b);if(!d.ok)return{valid:!1,error:"Invalid session cookie"};let e=await d.json().catch(()=>null),f=!!(e&&e.user);return{valid:f,error:f?null:"Session expired — re-paste cookie"}}case"opencode-go":{let c=await u("https://opencode.ai/zen/go/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${a.apiKey}`},body:JSON.stringify({model:(0,h.fZ)("opencode-go"),messages:[{role:"user",content:"ping"}],max_tokens:1,stream:!1})},b),d=401!==c.status&&403!==c.status;return{valid:d,error:d?null:"Invalid API key"}}case"xiaomi-mimo":case"xiaomi-tokenplan":{let c=await u(`${{"xiaomi-mimo":"https://api.xiaomimimo.com/v1","xiaomi-tokenplan":"https://token-plan-sgp.xiaomimimo.com/v1"}[a.provider]}/models`,{headers:{Authorization:`Bearer ${a.apiKey}`}},b);return{valid:c.ok,error:c.ok?null:"Invalid API key"}}case"blackbox":{let c=j.xq.blackbox?.baseUrl?.replace(/\/chat\/completions$/,"")||"https://api.blackbox.ai/v1",d=await u(`${c}/models`,{headers:{Authorization:`Bearer ${a.apiKey}`}},b);return{valid:d.ok,error:d.ok?null:"Invalid API key"}}case"clinepass":{let c=await u("https://api.cline.bot/api/v1/models",{headers:{Accept:"application/json",Authorization:`Bearer ${a.apiKey}`}},b);return{valid:c.ok,error:c.ok?null:"Invalid API key"}}default:return{valid:!1,error:"Provider test not supported"}}}catch(a){return{valid:!1,error:a.message}}}async function w(a){let b,c=await (0,d.Mc)(a);if(!c)return{valid:!1,error:"Connection not found",latencyMs:0,testedAt:new Date().toISOString()};let h={...c,provider:(0,g.rs)(c.provider)},i=await (0,e.B)(c.providerSpecificData||{});if(i.connectionProxyEnabled&&i.connectionProxyUrl&&!i.vercelRelayUrl){let b=await (0,f.C)({proxyUrl:i.connectionProxyUrl});if(!b.ok){let c=b.error||`Proxy test failed with status ${b.status}`;return await (0,d.updateProviderConnection)(a,{testStatus:"error",lastError:c,lastErrorAt:new Date().toISOString()}),{valid:!1,error:c,latencyMs:0,testedAt:new Date().toISOString()}}}let j=Date.now();b="apikey"===c.authType||"cookie"===c.authType?await v(h,i):await t(h,i);let k=Date.now()-j,l={testStatus:b.valid?"active":"error",lastError:b.valid?null:b.error,lastErrorAt:b.valid?null:new Date().toISOString()};return b.refreshed&&b.newTokens&&(b.newTokens.accessToken&&(l.accessToken=b.newTokens.accessToken),b.newTokens.refreshToken&&(l.refreshToken=b.newTokens.refreshToken),b.newTokens.idToken&&(l.idToken=b.newTokens.idToken),b.newTokens.lastRefreshAt&&(l.lastRefreshAt=b.newTokens.lastRefreshAt),b.newTokens.expiresIn&&(l.expiresIn=b.newTokens.expiresIn),b.newTokens.expiresIn?l.expiresAt=new Date(Date.now()+1e3*b.newTokens.expiresIn).toISOString():b.newTokens.expiresAt&&(l.expiresAt=b.newTokens.expiresAt),b.newTokens.providerSpecificData&&(l.providerSpecificData={...c.providerSpecificData||{},...b.newTokens.providerSpecificData})),await (0,d.updateProviderConnection)(a,l),{valid:b.valid,error:b.error,refreshed:!!b.refreshed,latencyMs:k,testedAt:new Date().toISOString()}}},73159:(a,b,c)=>{c.d(b,{U:()=>k,o:()=>l});var d=c(45350);let e=d.xq.xai?.clientId,f="https://auth.x.ai",g="/oauth2/authorize",h="/oauth2/token",i="/.well-known/openid-configuration",j="/callback",k=96,l={clientId:e,issuer:f,authEndpointPath:g,tokenEndpointPath:h,discoveryPath:i,authorizeUrl:`${f}${g}`,tokenUrl:`${f}${h}`,discoveryUrl:`${f}${i}`,scope:"openid profile email offline_access grok-cli:access api:access",apiBaseUrl:"https://api.x.ai/v1",redirectUri:`http://127.0.0.1:56121${j}`,loopbackPort:56121,callbackPath:j,pkceVerifierBytes:96,refreshLeadSeconds:300,userAgent:"grok-cli/switchboard",codeChallengeMethod:"S256"}},74926:(a,b,c)=>{c.d(b,{C:()=>f});var d=c(47774);function e(a){return null==a?"":String(a).trim()}async function f({proxyUrl:a,testUrl:b,timeoutMs:c}={}){let g,h=e(a);if(!h)return{ok:!1,status:400,error:"proxyUrl is required"};let i=e(b)||"https://google.com/",j=Number(c),k=Number.isFinite(j)&&j>0?Math.min(j,3e4):8e3;try{try{g=new d.ProxyAgent({uri:h})}catch(a){return{ok:!1,status:400,error:`Invalid proxy URL: ${a?.message||String(a)}`}}let a=new AbortController,b=Date.now(),c=setTimeout(()=>a.abort(),k);try{let c=await (0,d.hd)(i,{method:"HEAD",dispatcher:g,signal:a.signal,headers:{"User-Agent":"Switchboard"}});return{ok:c.ok,status:c.status,statusText:c.statusText,url:i,elapsedMs:Date.now()-b}}catch(b){let a=b?.name==="AbortError"?"Proxy test timed out":function(a){if(!a)return"Unknown error";let b=a?.message||String(a),c=a?.cause?.code||a?.code,d=a?.cause?.message;return d&&d!==b?c?`${b}: ${d} (${c})`:`${b}: ${d}`:c&&!b.includes(c)?`${b} (${c})`:b}(b);return{ok:!1,status:500,error:a}}finally{clearTimeout(c)}}finally{try{await g?.close?.()}catch{}}}},92990:(a,b,c)=>{c.d(b,{DI:()=>i,Hp:()=>k,LT:()=>j,MZ:()=>v,Nl:()=>z,Nu:()=>p,OV:()=>h,S6:()=>s,Td:()=>A,Tx:()=>q,WN:()=>t,Ww:()=>B,YT:()=>n,ZL:()=>m,cD:()=>o,f7:()=>y,hF:()=>l,lB:()=>w,t:()=>u,w1:()=>x});var d=c(21820),e=c(92675),f=c(45350);function g(){let a=(0,d.platform)(),b=(0,d.arch)();return"darwin"===a?"arm64"===b?2:1:"linux"===a?"arm64"===b?4:3:5*("win32"===a)}let h={...f.sr.claude},i={...f.sr.codex},j={...e.w3,...f.sr["gemini-cli"]},k={...f.sr.qwen},l={...f.sr.qoder},m={...f.sr.iflow},n={...e.XP,...f.sr.antigravity,loadCodeAssistClientMetadata:JSON.stringify({ideType:9,platform:g(),pluginType:2})};function o(){return{ideType:9,platform:g(),pluginType:2}}({...f.sr.openai});let p={...f.sr.github},q={...f.sr.kiro},r=/^[a-z]{2}(?:-[a-z0-9]+)+-\d{1,2}$/;function s(a){if("string"!=typeof a||!r.test(a))throw Error("Invalid region");return a}let t={...f.sr.cursor,tokenStoragePaths:{linux:"~/.config/Cursor/User/globalStorage/state.vscdb",macos:"/Users/<user>/Library/Application Support/Cursor/User/globalStorage/state.vscdb",windows:"%APPDATA%\\Cursor\\User\\globalStorage\\state.vscdb"}},u={...f.sr["kimi-coding"],clientId:process.env.KIMI_CODING_OAUTH_CLIENT_ID||f.xq["kimi-coding"]?.clientId},v={...f.sr.kilocode},w={...f.sr.cline},x={...f.sr.clinepass},y={...f.sr.gitlab},z={...f.sr["codebuddy-cn"]},A={...f.sr.kimchi},B=3e5}};