switchboard-router 0.9.8 → 0.9.10

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 (583) hide show
  1. package/app/.next/static/chunks/1321-a73f95036c368bd4.js +1 -0
  2. package/app/.next/static/chunks/1330-846d6a9e1497295e.js +7 -0
  3. package/app/.next/static/chunks/app/(dashboard)/dashboard/agent-library/page-65e302b698beee56.js +1 -0
  4. package/app/.next/static/chunks/app/(dashboard)/dashboard/endpoint/page-337881fe6c0cc77a.js +16 -0
  5. package/app/.next/static/chunks/app/(dashboard)/dashboard/loading-c80ac975cf0f4842.js +1 -0
  6. package/app/{.next-cli-build/static/chunks/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page-78d098f14f8cff05.js → .next/static/chunks/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page-efb20dd903e0dc94.js} +10 -10
  7. package/app/.next/static/chunks/app/(dashboard)/dashboard/media-providers/combo/[id]/page-03290d1edb08623a.js +4 -0
  8. package/app/.next/static/chunks/app/(dashboard)/dashboard/page-9bcd63bfeeac87c6.js +1 -0
  9. package/app/.next/static/chunks/app/(dashboard)/dashboard/providers/[id]/{page-97e0f7067cab0724.js → page-ca71683d9d850162.js} +3 -3
  10. package/app/.next/static/chunks/app/(dashboard)/dashboard/pxpipe/page-c5c37fbce431369b.js +1 -0
  11. package/app/.next/static/chunks/app/(dashboard)/dashboard/skills/page-b582299fa61407d9.js +1 -0
  12. package/app/.next/static/css/92ffae29025c5847.css +1 -0
  13. package/app/.next-cli-build/BUILD_ID +1 -1
  14. package/app/.next-cli-build/app-path-routes-manifest.json +8 -8
  15. package/app/.next-cli-build/build-manifest.json +2 -2
  16. package/app/.next-cli-build/prerender-manifest.json +3 -3
  17. package/app/.next-cli-build/server/app/(dashboard)/dashboard/agent-library/page.js +1 -1
  18. package/app/.next-cli-build/server/app/(dashboard)/dashboard/agent-library/page.js.nft.json +1 -1
  19. package/app/.next-cli-build/server/app/(dashboard)/dashboard/agent-library/page_client-reference-manifest.js +1 -1
  20. package/app/.next-cli-build/server/app/(dashboard)/dashboard/basic-chat/page.js +1 -1
  21. package/app/.next-cli-build/server/app/(dashboard)/dashboard/basic-chat/page.js.nft.json +1 -1
  22. package/app/.next-cli-build/server/app/(dashboard)/dashboard/basic-chat/page_client-reference-manifest.js +1 -1
  23. package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/[toolId]/page.js +1 -1
  24. package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/[toolId]/page.js.nft.json +1 -1
  25. package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/[toolId]/page_client-reference-manifest.js +1 -1
  26. package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/page.js +1 -1
  27. package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/page.js.nft.json +1 -1
  28. package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/page_client-reference-manifest.js +1 -1
  29. package/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/page.js +1 -1
  30. package/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/page.js.nft.json +1 -1
  31. package/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/page_client-reference-manifest.js +1 -1
  32. package/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/routing/page.js +1 -1
  33. package/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/routing/page.js.nft.json +1 -1
  34. package/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/routing/page_client-reference-manifest.js +1 -1
  35. package/app/.next-cli-build/server/app/(dashboard)/dashboard/console-log/page.js +1 -1
  36. package/app/.next-cli-build/server/app/(dashboard)/dashboard/console-log/page.js.nft.json +1 -1
  37. package/app/.next-cli-build/server/app/(dashboard)/dashboard/console-log/page_client-reference-manifest.js +1 -1
  38. package/app/.next-cli-build/server/app/(dashboard)/dashboard/endpoint/page.js +3 -3
  39. package/app/.next-cli-build/server/app/(dashboard)/dashboard/endpoint/page.js.nft.json +1 -1
  40. package/app/.next-cli-build/server/app/(dashboard)/dashboard/endpoint/page_client-reference-manifest.js +1 -1
  41. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page.js +10 -10
  42. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page.js.nft.json +1 -1
  43. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page_client-reference-manifest.js +1 -1
  44. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/page.js +1 -1
  45. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/page.js.nft.json +1 -1
  46. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/page_client-reference-manifest.js +1 -1
  47. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/combo/[id]/page.js +3 -3
  48. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/combo/[id]/page.js.nft.json +1 -1
  49. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/combo/[id]/page_client-reference-manifest.js +1 -1
  50. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/page.js +1 -1
  51. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/page.js.nft.json +1 -1
  52. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/page_client-reference-manifest.js +1 -1
  53. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/web/page.js +1 -1
  54. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/web/page.js.nft.json +1 -1
  55. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/web/page_client-reference-manifest.js +1 -1
  56. package/app/.next-cli-build/server/app/(dashboard)/dashboard/mitm/page.js +1 -1
  57. package/app/.next-cli-build/server/app/(dashboard)/dashboard/mitm/page.js.nft.json +1 -1
  58. package/app/.next-cli-build/server/app/(dashboard)/dashboard/mitm/page_client-reference-manifest.js +1 -1
  59. package/app/.next-cli-build/server/app/(dashboard)/dashboard/page.js +1 -1
  60. package/app/.next-cli-build/server/app/(dashboard)/dashboard/page.js.nft.json +1 -1
  61. package/app/.next-cli-build/server/app/(dashboard)/dashboard/page_client-reference-manifest.js +1 -1
  62. package/app/.next-cli-build/server/app/(dashboard)/dashboard/profile/page.js +1 -1
  63. package/app/.next-cli-build/server/app/(dashboard)/dashboard/profile/page.js.nft.json +1 -1
  64. package/app/.next-cli-build/server/app/(dashboard)/dashboard/profile/page_client-reference-manifest.js +1 -1
  65. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/[id]/page.js +2 -2
  66. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/[id]/page.js.nft.json +1 -1
  67. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/[id]/page_client-reference-manifest.js +1 -1
  68. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/new/page.js +1 -1
  69. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/new/page.js.nft.json +1 -1
  70. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/new/page_client-reference-manifest.js +1 -1
  71. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/page.js +1 -1
  72. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/page.js.nft.json +1 -1
  73. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/page_client-reference-manifest.js +1 -1
  74. package/app/.next-cli-build/server/app/(dashboard)/dashboard/pxpipe/page.js +1 -1
  75. package/app/.next-cli-build/server/app/(dashboard)/dashboard/pxpipe/page.js.nft.json +1 -1
  76. package/app/.next-cli-build/server/app/(dashboard)/dashboard/pxpipe/page_client-reference-manifest.js +1 -1
  77. package/app/.next-cli-build/server/app/(dashboard)/dashboard/quota/page.js +1 -1
  78. package/app/.next-cli-build/server/app/(dashboard)/dashboard/quota/page.js.nft.json +1 -1
  79. package/app/.next-cli-build/server/app/(dashboard)/dashboard/quota/page_client-reference-manifest.js +1 -1
  80. package/app/.next-cli-build/server/app/(dashboard)/dashboard/skills/[id]/page.js +1 -1
  81. package/app/.next-cli-build/server/app/(dashboard)/dashboard/skills/[id]/page.js.nft.json +1 -1
  82. package/app/.next-cli-build/server/app/(dashboard)/dashboard/skills/[id]/page_client-reference-manifest.js +1 -1
  83. package/app/.next-cli-build/server/app/(dashboard)/dashboard/skills/page.js +1 -1
  84. package/app/.next-cli-build/server/app/(dashboard)/dashboard/skills/page.js.nft.json +1 -1
  85. package/app/.next-cli-build/server/app/(dashboard)/dashboard/skills/page_client-reference-manifest.js +1 -1
  86. package/app/.next-cli-build/server/app/(dashboard)/dashboard/token-saver/page.js +1 -1
  87. package/app/.next-cli-build/server/app/(dashboard)/dashboard/token-saver/page.js.nft.json +1 -1
  88. package/app/.next-cli-build/server/app/(dashboard)/dashboard/token-saver/page_client-reference-manifest.js +1 -1
  89. package/app/.next-cli-build/server/app/(dashboard)/dashboard/translator/page.js +1 -1
  90. package/app/.next-cli-build/server/app/(dashboard)/dashboard/translator/page.js.nft.json +1 -1
  91. package/app/.next-cli-build/server/app/(dashboard)/dashboard/translator/page_client-reference-manifest.js +1 -1
  92. package/app/.next-cli-build/server/app/(dashboard)/dashboard/usage/page.js +1 -1
  93. package/app/.next-cli-build/server/app/(dashboard)/dashboard/usage/page.js.nft.json +1 -1
  94. package/app/.next-cli-build/server/app/(dashboard)/dashboard/usage/page_client-reference-manifest.js +1 -1
  95. package/app/.next-cli-build/server/app/_global-error/page.js.nft.json +1 -1
  96. package/app/.next-cli-build/server/app/_global-error/page_client-reference-manifest.js +1 -1
  97. package/app/.next-cli-build/server/app/_global-error.html +1 -1
  98. package/app/.next-cli-build/server/app/_global-error.rsc +1 -1
  99. package/app/.next-cli-build/server/app/_global-error.segments/_full.segment.rsc +1 -1
  100. package/app/.next-cli-build/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  101. package/app/.next-cli-build/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  102. package/app/.next-cli-build/server/app/_not-found/page.js +1 -1
  103. package/app/.next-cli-build/server/app/_not-found/page.js.nft.json +1 -1
  104. package/app/.next-cli-build/server/app/_not-found/page_client-reference-manifest.js +1 -1
  105. package/app/.next-cli-build/server/app/_not-found.html +1 -1
  106. package/app/.next-cli-build/server/app/_not-found.rsc +4 -4
  107. package/app/.next-cli-build/server/app/_not-found.segments/_full.segment.rsc +4 -4
  108. package/app/.next-cli-build/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +4 -4
  109. package/app/.next-cli-build/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  110. package/app/.next-cli-build/server/app/api/agent-library/catalog/route.js.nft.json +1 -1
  111. package/app/.next-cli-build/server/app/api/agent-library/doctor/route.js.nft.json +1 -1
  112. package/app/.next-cli-build/server/app/api/agent-library/export/route.js.nft.json +1 -1
  113. package/app/.next-cli-build/server/app/api/agent-library/mcp/route.js.nft.json +1 -1
  114. package/app/.next-cli-build/server/app/api/agent-library/route.js.nft.json +1 -1
  115. package/app/.next-cli-build/server/app/api/agent-library/skills/route.js.nft.json +1 -1
  116. package/app/.next-cli-build/server/app/api/agent-library/sync/route.js.nft.json +1 -1
  117. package/app/.next-cli-build/server/app/api/agent-library/updates/route.js.nft.json +1 -1
  118. package/app/.next-cli-build/server/app/api/auth/status/route.js.nft.json +1 -1
  119. package/app/.next-cli-build/server/app/api/cli-tools/aider-settings/route.js +2 -2
  120. package/app/.next-cli-build/server/app/api/cli-tools/aider-settings/route.js.nft.json +1 -1
  121. package/app/.next-cli-build/server/app/api/cli-tools/all-statuses/route.js +5 -5
  122. package/app/.next-cli-build/server/app/api/cli-tools/all-statuses/route.js.nft.json +1 -1
  123. package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/alias/route.js +2 -2
  124. package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/alias/route.js.nft.json +1 -1
  125. package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/route.js +1 -1
  126. package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/route.js.nft.json +1 -1
  127. package/app/.next-cli-build/server/app/api/cli-tools/claude-full-catalog/route.js +1 -1
  128. package/app/.next-cli-build/server/app/api/cli-tools/claude-full-catalog/route.js.nft.json +1 -1
  129. package/app/.next-cli-build/server/app/api/cli-tools/claude-picker-labels/route.js +1 -1
  130. package/app/.next-cli-build/server/app/api/cli-tools/claude-picker-labels/route.js.nft.json +1 -1
  131. package/app/.next-cli-build/server/app/api/cli-tools/claude-settings/route.js.nft.json +1 -1
  132. package/app/.next-cli-build/server/app/api/cli-tools/cline-settings/route.js +2 -2
  133. package/app/.next-cli-build/server/app/api/cli-tools/cline-settings/route.js.nft.json +1 -1
  134. package/app/.next-cli-build/server/app/api/cli-tools/codex-settings/route.js +1 -1
  135. package/app/.next-cli-build/server/app/api/cli-tools/codex-settings/route.js.nft.json +1 -1
  136. package/app/.next-cli-build/server/app/api/cli-tools/cowork-mcp-registry/route.js +2 -2
  137. package/app/.next-cli-build/server/app/api/cli-tools/cowork-mcp-registry/route.js.nft.json +1 -1
  138. package/app/.next-cli-build/server/app/api/cli-tools/cowork-mcp-tools/route.js +2 -2
  139. package/app/.next-cli-build/server/app/api/cli-tools/cowork-mcp-tools/route.js.nft.json +1 -1
  140. package/app/.next-cli-build/server/app/api/cli-tools/cowork-settings/route.js +2 -2
  141. package/app/.next-cli-build/server/app/api/cli-tools/cowork-settings/route.js.nft.json +1 -1
  142. package/app/.next-cli-build/server/app/api/cli-tools/deepseek-tui-settings/route.js +2 -2
  143. package/app/.next-cli-build/server/app/api/cli-tools/deepseek-tui-settings/route.js.nft.json +1 -1
  144. package/app/.next-cli-build/server/app/api/cli-tools/droid-settings/route.js +2 -2
  145. package/app/.next-cli-build/server/app/api/cli-tools/droid-settings/route.js.nft.json +1 -1
  146. package/app/.next-cli-build/server/app/api/cli-tools/gemini-cli-settings/route.js +2 -2
  147. package/app/.next-cli-build/server/app/api/cli-tools/gemini-cli-settings/route.js.nft.json +1 -1
  148. package/app/.next-cli-build/server/app/api/cli-tools/grok-settings/route.js +2 -2
  149. package/app/.next-cli-build/server/app/api/cli-tools/grok-settings/route.js.nft.json +1 -1
  150. package/app/.next-cli-build/server/app/api/cli-tools/hermes-settings/route.js +2 -2
  151. package/app/.next-cli-build/server/app/api/cli-tools/hermes-settings/route.js.nft.json +1 -1
  152. package/app/.next-cli-build/server/app/api/cli-tools/jcode-settings/route.js +2 -2
  153. package/app/.next-cli-build/server/app/api/cli-tools/jcode-settings/route.js.nft.json +1 -1
  154. package/app/.next-cli-build/server/app/api/cli-tools/kilo-settings/route.js +2 -2
  155. package/app/.next-cli-build/server/app/api/cli-tools/kilo-settings/route.js.nft.json +1 -1
  156. package/app/.next-cli-build/server/app/api/cli-tools/openclaw-settings/route.js +2 -2
  157. package/app/.next-cli-build/server/app/api/cli-tools/openclaw-settings/route.js.nft.json +1 -1
  158. package/app/.next-cli-build/server/app/api/cli-tools/opencode-settings/route.js +1 -1
  159. package/app/.next-cli-build/server/app/api/cli-tools/opencode-settings/route.js.nft.json +1 -1
  160. package/app/.next-cli-build/server/app/api/cli-tools/pi-settings/route.js +1 -1
  161. package/app/.next-cli-build/server/app/api/cli-tools/pi-settings/route.js.nft.json +1 -1
  162. package/app/.next-cli-build/server/app/api/cli-tools/picker-labels/route.js +1 -1
  163. package/app/.next-cli-build/server/app/api/cli-tools/picker-labels/route.js.nft.json +1 -1
  164. package/app/.next-cli-build/server/app/api/combos/[id]/route.js +1 -1
  165. package/app/.next-cli-build/server/app/api/combos/[id]/route.js.nft.json +1 -1
  166. package/app/.next-cli-build/server/app/api/combos/route.js +1 -1
  167. package/app/.next-cli-build/server/app/api/combos/route.js.nft.json +1 -1
  168. package/app/.next-cli-build/server/app/api/headroom/extras/route.js +1 -1
  169. package/app/.next-cli-build/server/app/api/headroom/extras/route.js.nft.json +1 -1
  170. package/app/.next-cli-build/server/app/api/headroom/proxy/[...path]/route.js +1 -1
  171. package/app/.next-cli-build/server/app/api/headroom/proxy/[...path]/route.js.nft.json +1 -1
  172. package/app/.next-cli-build/server/app/api/headroom/restart/route.js +1 -1
  173. package/app/.next-cli-build/server/app/api/headroom/restart/route.js.nft.json +1 -1
  174. package/app/.next-cli-build/server/app/api/headroom/start/route.js +1 -1
  175. package/app/.next-cli-build/server/app/api/headroom/start/route.js.nft.json +1 -1
  176. package/app/.next-cli-build/server/app/api/headroom/status/route.js +1 -1
  177. package/app/.next-cli-build/server/app/api/headroom/status/route.js.nft.json +1 -1
  178. package/app/.next-cli-build/server/app/api/headroom/stop/route.js +1 -1
  179. package/app/.next-cli-build/server/app/api/headroom/stop/route.js.nft.json +1 -1
  180. package/app/.next-cli-build/server/app/api/health/route.js +1 -1
  181. package/app/.next-cli-build/server/app/api/health/route.js.nft.json +1 -1
  182. package/app/.next-cli-build/server/app/api/keys/[id]/route.js +1 -1
  183. package/app/.next-cli-build/server/app/api/keys/[id]/route.js.nft.json +1 -1
  184. package/app/.next-cli-build/server/app/api/keys/route.js +1 -1
  185. package/app/.next-cli-build/server/app/api/keys/route.js.nft.json +1 -1
  186. package/app/.next-cli-build/server/app/api/locale/route.js.nft.json +1 -1
  187. package/app/.next-cli-build/server/app/api/mcp/[plugin]/message/route.js.nft.json +1 -1
  188. package/app/.next-cli-build/server/app/api/mcp/[plugin]/sse/route.js.nft.json +1 -1
  189. package/app/.next-cli-build/server/app/api/media-providers/tts/deepgram/voices/route.js +1 -1
  190. package/app/.next-cli-build/server/app/api/media-providers/tts/deepgram/voices/route.js.nft.json +1 -1
  191. package/app/.next-cli-build/server/app/api/media-providers/tts/elevenlabs/voices/route.js +1 -1
  192. package/app/.next-cli-build/server/app/api/media-providers/tts/elevenlabs/voices/route.js.nft.json +1 -1
  193. package/app/.next-cli-build/server/app/api/media-providers/tts/inworld/voices/route.js +1 -1
  194. package/app/.next-cli-build/server/app/api/media-providers/tts/inworld/voices/route.js.nft.json +1 -1
  195. package/app/.next-cli-build/server/app/api/media-providers/tts/minimax/voices/route.js +1 -1
  196. package/app/.next-cli-build/server/app/api/media-providers/tts/minimax/voices/route.js.nft.json +1 -1
  197. package/app/.next-cli-build/server/app/api/media-providers/tts/voices/route.js +1 -1
  198. package/app/.next-cli-build/server/app/api/media-providers/tts/voices/route.js.nft.json +1 -1
  199. package/app/.next-cli-build/server/app/api/mgmt/v1/combos/[id]/route.js +1 -1
  200. package/app/.next-cli-build/server/app/api/mgmt/v1/combos/[id]/route.js.nft.json +1 -1
  201. package/app/.next-cli-build/server/app/api/mgmt/v1/combos/[id]/strategy/route.js +1 -1
  202. package/app/.next-cli-build/server/app/api/mgmt/v1/combos/[id]/strategy/route.js.nft.json +1 -1
  203. package/app/.next-cli-build/server/app/api/mgmt/v1/combos/route.js +1 -1
  204. package/app/.next-cli-build/server/app/api/mgmt/v1/combos/route.js.nft.json +1 -1
  205. package/app/.next-cli-build/server/app/api/mgmt/v1/health/route.js +1 -1
  206. package/app/.next-cli-build/server/app/api/mgmt/v1/health/route.js.nft.json +1 -1
  207. package/app/.next-cli-build/server/app/api/mgmt/v1/metrics/route.js +2 -2
  208. package/app/.next-cli-build/server/app/api/mgmt/v1/metrics/route.js.nft.json +1 -1
  209. package/app/.next-cli-build/server/app/api/mgmt/v1/providers/route.js +1 -1
  210. package/app/.next-cli-build/server/app/api/mgmt/v1/providers/route.js.nft.json +1 -1
  211. package/app/.next-cli-build/server/app/api/mgmt/v1/routing/route.js +1 -1
  212. package/app/.next-cli-build/server/app/api/mgmt/v1/routing/route.js.nft.json +1 -1
  213. package/app/.next-cli-build/server/app/api/mgmt/v1/usage/route.js +1 -1
  214. package/app/.next-cli-build/server/app/api/mgmt/v1/usage/route.js.nft.json +1 -1
  215. package/app/.next-cli-build/server/app/api/mgmt/v1/version/route.js +1 -1
  216. package/app/.next-cli-build/server/app/api/mgmt/v1/version/route.js.nft.json +1 -1
  217. package/app/.next-cli-build/server/app/api/models/alias/route.js +1 -1
  218. package/app/.next-cli-build/server/app/api/models/alias/route.js.nft.json +1 -1
  219. package/app/.next-cli-build/server/app/api/models/availability/route.js +1 -1
  220. package/app/.next-cli-build/server/app/api/models/availability/route.js.nft.json +1 -1
  221. package/app/.next-cli-build/server/app/api/models/custom/route.js +1 -1
  222. package/app/.next-cli-build/server/app/api/models/custom/route.js.nft.json +1 -1
  223. package/app/.next-cli-build/server/app/api/models/disabled/route.js +1 -1
  224. package/app/.next-cli-build/server/app/api/models/disabled/route.js.nft.json +1 -1
  225. package/app/.next-cli-build/server/app/api/models/route.js +1 -1
  226. package/app/.next-cli-build/server/app/api/models/route.js.nft.json +1 -1
  227. package/app/.next-cli-build/server/app/api/models/test/route.js +1 -1
  228. package/app/.next-cli-build/server/app/api/models/test/route.js.nft.json +1 -1
  229. package/app/.next-cli-build/server/app/api/oauth/[provider]/[action]/route.js +1 -1
  230. package/app/.next-cli-build/server/app/api/oauth/[provider]/[action]/route.js.nft.json +1 -1
  231. package/app/.next-cli-build/server/app/api/oauth/codex/bulk-import/route.js +1 -1
  232. package/app/.next-cli-build/server/app/api/oauth/codex/bulk-import/route.js.nft.json +1 -1
  233. package/app/.next-cli-build/server/app/api/oauth/codex/import-token/route.js +1 -1
  234. package/app/.next-cli-build/server/app/api/oauth/codex/import-token/route.js.nft.json +1 -1
  235. package/app/.next-cli-build/server/app/api/oauth/cursor/auto-import/route.js.nft.json +1 -1
  236. package/app/.next-cli-build/server/app/api/oauth/cursor/import/route.js +1 -1
  237. package/app/.next-cli-build/server/app/api/oauth/cursor/import/route.js.nft.json +1 -1
  238. package/app/.next-cli-build/server/app/api/oauth/gitlab/pat/route.js +1 -1
  239. package/app/.next-cli-build/server/app/api/oauth/gitlab/pat/route.js.nft.json +1 -1
  240. package/app/.next-cli-build/server/app/api/oauth/iflow/cookie/route.js +1 -1
  241. package/app/.next-cli-build/server/app/api/oauth/iflow/cookie/route.js.nft.json +1 -1
  242. package/app/.next-cli-build/server/app/api/oauth/kiro/api-key/route.js +1 -1
  243. package/app/.next-cli-build/server/app/api/oauth/kiro/api-key/route.js.nft.json +1 -1
  244. package/app/.next-cli-build/server/app/api/oauth/kiro/auto-import/route.js.nft.json +1 -1
  245. package/app/.next-cli-build/server/app/api/oauth/kiro/import/route.js +1 -1
  246. package/app/.next-cli-build/server/app/api/oauth/kiro/import/route.js.nft.json +1 -1
  247. package/app/.next-cli-build/server/app/api/oauth/kiro/import-cli-proxy/route.js +1 -1
  248. package/app/.next-cli-build/server/app/api/oauth/kiro/import-cli-proxy/route.js.nft.json +1 -1
  249. package/app/.next-cli-build/server/app/api/oauth/kiro/social-authorize/route.js +1 -1
  250. package/app/.next-cli-build/server/app/api/oauth/kiro/social-authorize/route.js.nft.json +1 -1
  251. package/app/.next-cli-build/server/app/api/oauth/kiro/social-exchange/route.js +1 -1
  252. package/app/.next-cli-build/server/app/api/oauth/kiro/social-exchange/route.js.nft.json +1 -1
  253. package/app/.next-cli-build/server/app/api/pricing/route.js +1 -1
  254. package/app/.next-cli-build/server/app/api/pricing/route.js.nft.json +1 -1
  255. package/app/.next-cli-build/server/app/api/provider-nodes/[id]/route.js +1 -1
  256. package/app/.next-cli-build/server/app/api/provider-nodes/[id]/route.js.nft.json +1 -1
  257. package/app/.next-cli-build/server/app/api/provider-nodes/route.js +1 -1
  258. package/app/.next-cli-build/server/app/api/provider-nodes/route.js.nft.json +1 -1
  259. package/app/.next-cli-build/server/app/api/provider-nodes/validate/route.js +1 -1
  260. package/app/.next-cli-build/server/app/api/provider-nodes/validate/route.js.nft.json +1 -1
  261. package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/batch/route.js +1 -1
  262. package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/batch/route.js.nft.json +1 -1
  263. package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/cache/route.js +1 -1
  264. package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/cache/route.js.nft.json +1 -1
  265. package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/prepare/route.js +1 -1
  266. package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/prepare/route.js.nft.json +1 -1
  267. package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/remove-unavailable/route.js +1 -1
  268. package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/remove-unavailable/route.js.nft.json +1 -1
  269. package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/route.js +1 -1
  270. package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/route.js.nft.json +1 -1
  271. package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/verify/cancel/route.js +1 -1
  272. package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/verify/cancel/route.js.nft.json +1 -1
  273. package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/verify/start/route.js +1 -1
  274. package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/verify/start/route.js.nft.json +1 -1
  275. package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/verify/status/route.js +1 -1
  276. package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/verify/status/route.js.nft.json +1 -1
  277. package/app/.next-cli-build/server/app/api/providers/[id]/models/route.js +1 -1
  278. package/app/.next-cli-build/server/app/api/providers/[id]/models/route.js.nft.json +1 -1
  279. package/app/.next-cli-build/server/app/api/providers/[id]/route.js +1 -1
  280. package/app/.next-cli-build/server/app/api/providers/[id]/route.js.nft.json +1 -1
  281. package/app/.next-cli-build/server/app/api/providers/[id]/test/route.js +1 -1
  282. package/app/.next-cli-build/server/app/api/providers/[id]/test/route.js.nft.json +1 -1
  283. package/app/.next-cli-build/server/app/api/providers/[id]/test-models/route.js +1 -1
  284. package/app/.next-cli-build/server/app/api/providers/[id]/test-models/route.js.nft.json +1 -1
  285. package/app/.next-cli-build/server/app/api/providers/client/route.js +1 -1
  286. package/app/.next-cli-build/server/app/api/providers/client/route.js.nft.json +1 -1
  287. package/app/.next-cli-build/server/app/api/providers/kilo/free-models/route.js.nft.json +1 -1
  288. package/app/.next-cli-build/server/app/api/providers/route.js +1 -1
  289. package/app/.next-cli-build/server/app/api/providers/route.js.nft.json +1 -1
  290. package/app/.next-cli-build/server/app/api/providers/suggested-models/route.js.nft.json +1 -1
  291. package/app/.next-cli-build/server/app/api/providers/test-batch/route.js +1 -1
  292. package/app/.next-cli-build/server/app/api/providers/test-batch/route.js.nft.json +1 -1
  293. package/app/.next-cli-build/server/app/api/providers/validate/route.js +1 -1
  294. package/app/.next-cli-build/server/app/api/providers/validate/route.js.nft.json +1 -1
  295. package/app/.next-cli-build/server/app/api/pxpipe/health/route.js.nft.json +1 -1
  296. package/app/.next-cli-build/server/app/api/pxpipe/install/route.js.nft.json +1 -1
  297. package/app/.next-cli-build/server/app/api/pxpipe/logs/route.js.nft.json +1 -1
  298. package/app/.next-cli-build/server/app/api/pxpipe/restart/route.js.nft.json +1 -1
  299. package/app/.next-cli-build/server/app/api/pxpipe/start/route.js +2 -2
  300. package/app/.next-cli-build/server/app/api/pxpipe/start/route.js.nft.json +1 -1
  301. package/app/.next-cli-build/server/app/api/pxpipe/stats/route.js.nft.json +1 -1
  302. package/app/.next-cli-build/server/app/api/pxpipe/status/route.js +2 -2
  303. package/app/.next-cli-build/server/app/api/pxpipe/status/route.js.nft.json +1 -1
  304. package/app/.next-cli-build/server/app/api/pxpipe/stop/route.js.nft.json +1 -1
  305. package/app/.next-cli-build/server/app/api/routing/feedback/route.js +1 -1
  306. package/app/.next-cli-build/server/app/api/routing/feedback/route.js.nft.json +1 -1
  307. package/app/.next-cli-build/server/app/api/routing/insights/route.js +1 -1
  308. package/app/.next-cli-build/server/app/api/routing/insights/route.js.nft.json +1 -1
  309. package/app/.next-cli-build/server/app/api/routing/learn/route.js +1 -1
  310. package/app/.next-cli-build/server/app/api/routing/learn/route.js.nft.json +1 -1
  311. package/app/.next-cli-build/server/app/api/routing/stats/route.js +1 -1
  312. package/app/.next-cli-build/server/app/api/routing/stats/route.js.nft.json +1 -1
  313. package/app/.next-cli-build/server/app/api/routing/versions/promote/route.js +1 -1
  314. package/app/.next-cli-build/server/app/api/routing/versions/promote/route.js.nft.json +1 -1
  315. package/app/.next-cli-build/server/app/api/routing/versions/rollback/route.js +1 -1
  316. package/app/.next-cli-build/server/app/api/routing/versions/rollback/route.js.nft.json +1 -1
  317. package/app/.next-cli-build/server/app/api/settings/database/route.js +1 -1
  318. package/app/.next-cli-build/server/app/api/settings/database/route.js.nft.json +1 -1
  319. package/app/.next-cli-build/server/app/api/settings/proxy-test/route.js.nft.json +1 -1
  320. package/app/.next-cli-build/server/app/api/settings/route.js +1 -1
  321. package/app/.next-cli-build/server/app/api/settings/route.js.nft.json +1 -1
  322. package/app/.next-cli-build/server/app/api/shutdown/route.js.nft.json +1 -1
  323. package/app/.next-cli-build/server/app/api/skills/[id]/route.js.nft.json +1 -1
  324. package/app/.next-cli-build/server/app/api/tags/route.js.nft.json +1 -1
  325. package/app/.next-cli-build/server/app/api/token-saver/vault-stats/route.js.nft.json +1 -1
  326. package/app/.next-cli-build/server/app/api/translator/console-logs/route.js +1 -1
  327. package/app/.next-cli-build/server/app/api/translator/console-logs/route.js.nft.json +1 -1
  328. package/app/.next-cli-build/server/app/api/translator/console-logs/stream/route.js +1 -1
  329. package/app/.next-cli-build/server/app/api/translator/console-logs/stream/route.js.nft.json +1 -1
  330. package/app/.next-cli-build/server/app/api/translator/load/route.js.nft.json +1 -1
  331. package/app/.next-cli-build/server/app/api/translator/save/route.js.nft.json +1 -1
  332. package/app/.next-cli-build/server/app/api/translator/send/route.js +1 -1
  333. package/app/.next-cli-build/server/app/api/translator/send/route.js.nft.json +1 -1
  334. package/app/.next-cli-build/server/app/api/translator/translate/route.js +1 -1
  335. package/app/.next-cli-build/server/app/api/translator/translate/route.js.nft.json +1 -1
  336. package/app/.next-cli-build/server/app/api/usage/[connectionId]/codex-reset-credits/route.js +1 -1
  337. package/app/.next-cli-build/server/app/api/usage/[connectionId]/codex-reset-credits/route.js.nft.json +1 -1
  338. package/app/.next-cli-build/server/app/api/usage/[connectionId]/route.js +1 -1
  339. package/app/.next-cli-build/server/app/api/usage/[connectionId]/route.js.nft.json +1 -1
  340. package/app/.next-cli-build/server/app/api/usage/chart/route.js +1 -1
  341. package/app/.next-cli-build/server/app/api/usage/chart/route.js.nft.json +1 -1
  342. package/app/.next-cli-build/server/app/api/usage/history/route.js +1 -1
  343. package/app/.next-cli-build/server/app/api/usage/history/route.js.nft.json +1 -1
  344. package/app/.next-cli-build/server/app/api/usage/logs/route.js +1 -1
  345. package/app/.next-cli-build/server/app/api/usage/logs/route.js.nft.json +1 -1
  346. package/app/.next-cli-build/server/app/api/usage/providers/route.js +1 -1
  347. package/app/.next-cli-build/server/app/api/usage/providers/route.js.nft.json +1 -1
  348. package/app/.next-cli-build/server/app/api/usage/request-details/route.js +1 -1
  349. package/app/.next-cli-build/server/app/api/usage/request-details/route.js.nft.json +1 -1
  350. package/app/.next-cli-build/server/app/api/usage/request-logs/route.js +1 -1
  351. package/app/.next-cli-build/server/app/api/usage/request-logs/route.js.nft.json +1 -1
  352. package/app/.next-cli-build/server/app/api/usage/stats/route.js +1 -1
  353. package/app/.next-cli-build/server/app/api/usage/stats/route.js.nft.json +1 -1
  354. package/app/.next-cli-build/server/app/api/usage/stream/route.js +2 -6
  355. package/app/.next-cli-build/server/app/api/usage/stream/route.js.nft.json +1 -1
  356. package/app/.next-cli-build/server/app/api/v1/api/chat/route.js +1 -1
  357. package/app/.next-cli-build/server/app/api/v1/api/chat/route.js.nft.json +1 -1
  358. package/app/.next-cli-build/server/app/api/v1/audio/speech/route.js +1 -1
  359. package/app/.next-cli-build/server/app/api/v1/audio/speech/route.js.nft.json +1 -1
  360. package/app/.next-cli-build/server/app/api/v1/audio/transcriptions/route.js +1 -1
  361. package/app/.next-cli-build/server/app/api/v1/audio/transcriptions/route.js.nft.json +1 -1
  362. package/app/.next-cli-build/server/app/api/v1/audio/voices/route.js.nft.json +1 -1
  363. package/app/.next-cli-build/server/app/api/v1/chat/completions/route.js +1 -1
  364. package/app/.next-cli-build/server/app/api/v1/chat/completions/route.js.nft.json +1 -1
  365. package/app/.next-cli-build/server/app/api/v1/embeddings/route.js +1 -1
  366. package/app/.next-cli-build/server/app/api/v1/embeddings/route.js.nft.json +1 -1
  367. package/app/.next-cli-build/server/app/api/v1/images/generations/route.js +1 -1
  368. package/app/.next-cli-build/server/app/api/v1/images/generations/route.js.nft.json +1 -1
  369. package/app/.next-cli-build/server/app/api/v1/messages/count_tokens/route.js +1 -1
  370. package/app/.next-cli-build/server/app/api/v1/messages/count_tokens/route.js.nft.json +1 -1
  371. package/app/.next-cli-build/server/app/api/v1/messages/route.js +1 -1
  372. package/app/.next-cli-build/server/app/api/v1/messages/route.js.nft.json +1 -1
  373. package/app/.next-cli-build/server/app/api/v1/models/[kind]/route.js +1 -1
  374. package/app/.next-cli-build/server/app/api/v1/models/[kind]/route.js.nft.json +1 -1
  375. package/app/.next-cli-build/server/app/api/v1/models/info/route.js +1 -1
  376. package/app/.next-cli-build/server/app/api/v1/models/info/route.js.nft.json +1 -1
  377. package/app/.next-cli-build/server/app/api/v1/models/route.js +1 -1
  378. package/app/.next-cli-build/server/app/api/v1/models/route.js.nft.json +1 -1
  379. package/app/.next-cli-build/server/app/api/v1/responses/compact/route.js +1 -1
  380. package/app/.next-cli-build/server/app/api/v1/responses/compact/route.js.nft.json +1 -1
  381. package/app/.next-cli-build/server/app/api/v1/responses/route.js +1 -1
  382. package/app/.next-cli-build/server/app/api/v1/responses/route.js.nft.json +1 -1
  383. package/app/.next-cli-build/server/app/api/v1/route.js +1 -1
  384. package/app/.next-cli-build/server/app/api/v1/route.js.nft.json +1 -1
  385. package/app/.next-cli-build/server/app/api/v1/search/route.js +1 -1
  386. package/app/.next-cli-build/server/app/api/v1/search/route.js.nft.json +1 -1
  387. package/app/.next-cli-build/server/app/api/v1/videos/[id]/route.js +1 -1
  388. package/app/.next-cli-build/server/app/api/v1/videos/[id]/route.js.nft.json +1 -1
  389. package/app/.next-cli-build/server/app/api/v1/videos/edits/route.js +1 -1
  390. package/app/.next-cli-build/server/app/api/v1/videos/edits/route.js.nft.json +1 -1
  391. package/app/.next-cli-build/server/app/api/v1/videos/extensions/route.js +1 -1
  392. package/app/.next-cli-build/server/app/api/v1/videos/extensions/route.js.nft.json +1 -1
  393. package/app/.next-cli-build/server/app/api/v1/videos/generations/route.js +1 -1
  394. package/app/.next-cli-build/server/app/api/v1/videos/generations/route.js.nft.json +1 -1
  395. package/app/.next-cli-build/server/app/api/v1/web/fetch/route.js +1 -1
  396. package/app/.next-cli-build/server/app/api/v1/web/fetch/route.js.nft.json +1 -1
  397. package/app/.next-cli-build/server/app/api/v1beta/models/[...path]/route.js +1 -1
  398. package/app/.next-cli-build/server/app/api/v1beta/models/[...path]/route.js.nft.json +1 -1
  399. package/app/.next-cli-build/server/app/api/v1beta/models/route.js +1 -1
  400. package/app/.next-cli-build/server/app/api/v1beta/models/route.js.nft.json +1 -1
  401. package/app/.next-cli-build/server/app/api/version/route.js +1 -1
  402. package/app/.next-cli-build/server/app/api/version/route.js.nft.json +1 -1
  403. package/app/.next-cli-build/server/app/api/version/shutdown/route.js +1 -1
  404. package/app/.next-cli-build/server/app/api/version/shutdown/route.js.nft.json +1 -1
  405. package/app/.next-cli-build/server/app/api/version/update/route.js +1 -1
  406. package/app/.next-cli-build/server/app/api/version/update/route.js.nft.json +1 -1
  407. package/app/.next-cli-build/server/app/callback/page.js +1 -1
  408. package/app/.next-cli-build/server/app/callback/page.js.nft.json +1 -1
  409. package/app/.next-cli-build/server/app/callback/page_client-reference-manifest.js +1 -1
  410. package/app/.next-cli-build/server/app/callback.html +1 -1
  411. package/app/.next-cli-build/server/app/callback.rsc +4 -4
  412. package/app/.next-cli-build/server/app/callback.segments/_full.segment.rsc +4 -4
  413. package/app/.next-cli-build/server/app/callback.segments/_tree.segment.rsc +2 -2
  414. package/app/.next-cli-build/server/app/callback.segments/callback/__PAGE__.segment.rsc +4 -4
  415. package/app/.next-cli-build/server/app/dashboard/settings/pricing/page.js +1 -1
  416. package/app/.next-cli-build/server/app/dashboard/settings/pricing/page.js.nft.json +1 -1
  417. package/app/.next-cli-build/server/app/dashboard/settings/pricing/page_client-reference-manifest.js +1 -1
  418. package/app/.next-cli-build/server/app/dashboard/settings/pricing.html +1 -1
  419. package/app/.next-cli-build/server/app/dashboard/settings/pricing.rsc +4 -4
  420. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_full.segment.rsc +4 -4
  421. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_tree.segment.rsc +2 -2
  422. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing/__PAGE__.segment.rsc +4 -4
  423. package/app/.next-cli-build/server/app/favicon.ico/route.js.nft.json +1 -1
  424. package/app/.next-cli-build/server/app/index.html +1 -1
  425. package/app/.next-cli-build/server/app/index.rsc +4 -4
  426. package/app/.next-cli-build/server/app/index.segments/__PAGE__.segment.rsc +4 -4
  427. package/app/.next-cli-build/server/app/index.segments/_full.segment.rsc +4 -4
  428. package/app/.next-cli-build/server/app/index.segments/_tree.segment.rsc +2 -2
  429. package/app/.next-cli-build/server/app/landing/page.js +1 -1
  430. package/app/.next-cli-build/server/app/landing/page.js.nft.json +1 -1
  431. package/app/.next-cli-build/server/app/landing/page_client-reference-manifest.js +1 -1
  432. package/app/.next-cli-build/server/app/landing.html +1 -1
  433. package/app/.next-cli-build/server/app/landing.rsc +4 -4
  434. package/app/.next-cli-build/server/app/landing.segments/_full.segment.rsc +4 -4
  435. package/app/.next-cli-build/server/app/landing.segments/_tree.segment.rsc +2 -2
  436. package/app/.next-cli-build/server/app/landing.segments/landing/__PAGE__.segment.rsc +4 -4
  437. package/app/.next-cli-build/server/app/login/page.js +1 -1
  438. package/app/.next-cli-build/server/app/login/page.js.nft.json +1 -1
  439. package/app/.next-cli-build/server/app/login/page_client-reference-manifest.js +1 -1
  440. package/app/.next-cli-build/server/app/login.html +1 -1
  441. package/app/.next-cli-build/server/app/login.rsc +4 -4
  442. package/app/.next-cli-build/server/app/login.segments/_full.segment.rsc +4 -4
  443. package/app/.next-cli-build/server/app/login.segments/_tree.segment.rsc +2 -2
  444. package/app/.next-cli-build/server/app/login.segments/login/__PAGE__.segment.rsc +4 -4
  445. package/app/.next-cli-build/server/app/manifest.webmanifest/route.js.nft.json +1 -1
  446. package/app/.next-cli-build/server/app/page.js +1 -1
  447. package/app/.next-cli-build/server/app/page.js.nft.json +1 -1
  448. package/app/.next-cli-build/server/app/page_client-reference-manifest.js +1 -1
  449. package/app/.next-cli-build/server/app-paths-manifest.json +8 -8
  450. package/app/.next-cli-build/server/chunks/1158.js +1 -0
  451. package/app/.next-cli-build/server/chunks/1274.js +1 -0
  452. package/app/.next-cli-build/server/chunks/1351.js +1 -0
  453. package/app/.next-cli-build/server/chunks/1792.js +2 -0
  454. package/app/.next-cli-build/server/chunks/{159.js → 1837.js} +1 -1
  455. package/app/.next-cli-build/server/chunks/1937.js +1 -1
  456. package/app/.next-cli-build/server/chunks/1998.js +1 -1
  457. package/app/.next-cli-build/server/chunks/{3986.js → 2142.js} +2 -2
  458. package/app/.next-cli-build/server/chunks/{9508.js → 27.js} +5 -42
  459. package/app/.next-cli-build/server/chunks/3423.js +1 -0
  460. package/app/.next-cli-build/server/chunks/3446.js +1 -1
  461. package/app/.next-cli-build/server/chunks/3593.js +1 -1
  462. package/app/.next-cli-build/server/chunks/369.js +10 -10
  463. package/app/.next-cli-build/server/chunks/3735.js +2 -2
  464. package/app/.next-cli-build/server/chunks/403.js +1 -0
  465. package/app/.next-cli-build/server/chunks/4330.js +7 -0
  466. package/app/.next-cli-build/server/chunks/{940.js → 4675.js} +2 -2
  467. package/app/.next-cli-build/server/chunks/4739.js +1 -1
  468. package/app/.next-cli-build/server/chunks/4780.js +1 -1
  469. package/app/.next-cli-build/server/chunks/4803.js +1 -1
  470. package/app/.next-cli-build/server/chunks/507.js +1 -1
  471. package/app/.next-cli-build/server/chunks/5115.js +1 -0
  472. package/app/.next-cli-build/server/chunks/519.js +1 -0
  473. package/app/.next-cli-build/server/chunks/5195.js +1 -0
  474. package/app/.next-cli-build/server/chunks/5258.js +1 -1
  475. package/app/.next-cli-build/server/chunks/5717.js +9 -14
  476. package/app/.next-cli-build/server/chunks/5774.js +1 -0
  477. package/app/.next-cli-build/server/chunks/5781.js +2 -2
  478. package/app/.next-cli-build/server/chunks/5888.js +1 -1
  479. package/app/.next-cli-build/server/chunks/5920.js +2 -2
  480. package/app/.next-cli-build/server/chunks/6194.js +1 -0
  481. package/app/.next-cli-build/server/chunks/6252.js +1 -1
  482. package/app/.next-cli-build/server/chunks/6305.js +2 -0
  483. package/app/.next-cli-build/server/chunks/6328.js +1 -1
  484. package/app/.next-cli-build/server/chunks/6406.js +1 -1
  485. package/app/.next-cli-build/server/chunks/6492.js +1 -1
  486. package/app/.next-cli-build/server/chunks/{5913.js → 6757.js} +38 -1
  487. package/app/.next-cli-build/server/chunks/698.js +1 -1
  488. package/app/.next-cli-build/server/chunks/7133.js +1 -0
  489. package/app/.next-cli-build/server/chunks/7454.js +1 -1
  490. package/app/.next-cli-build/server/chunks/{3072.js → 7880.js} +2 -2
  491. package/app/.next-cli-build/server/chunks/7965.js +1 -1
  492. package/app/.next-cli-build/server/chunks/8027.js +63 -0
  493. package/app/.next-cli-build/server/chunks/8062.js +1 -1
  494. package/app/.next-cli-build/server/chunks/8400.js +12 -12
  495. package/app/.next-cli-build/server/chunks/8469.js +1 -1
  496. package/app/.next-cli-build/server/chunks/8520.js +1 -1
  497. package/app/.next-cli-build/server/chunks/869.js +1 -1
  498. package/app/.next-cli-build/server/chunks/8775.js +1 -1
  499. package/app/.next-cli-build/server/chunks/8789.js +1 -1
  500. package/app/.next-cli-build/server/chunks/8942.js +2 -2
  501. package/app/.next-cli-build/server/chunks/8976.js +1 -1
  502. package/app/.next-cli-build/server/chunks/8998.js +33 -38
  503. package/app/.next-cli-build/server/chunks/9059.js +1 -0
  504. package/app/.next-cli-build/server/chunks/9091.js +3 -3
  505. package/app/.next-cli-build/server/chunks/9261.js +2 -2
  506. package/app/.next-cli-build/server/chunks/9264.js +2 -2
  507. package/app/.next-cli-build/server/chunks/9421.js +2 -2
  508. package/app/.next-cli-build/server/chunks/static/media/versions.4155c5ec.json +24 -0
  509. package/app/.next-cli-build/server/middleware-build-manifest.js +1 -1
  510. package/app/.next-cli-build/server/middleware.js +11 -16
  511. package/app/.next-cli-build/server/pages/404.html +1 -1
  512. package/app/.next-cli-build/server/pages/500.html +1 -1
  513. package/app/.next-cli-build/server/server-reference-manifest.js +1 -1
  514. package/app/.next-cli-build/server/server-reference-manifest.json +1 -1
  515. package/app/.next-cli-build/static/chunks/1321-a73f95036c368bd4.js +1 -0
  516. package/app/.next-cli-build/static/chunks/1330-846d6a9e1497295e.js +7 -0
  517. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/agent-library/page-65e302b698beee56.js +1 -0
  518. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/endpoint/page-337881fe6c0cc77a.js +16 -0
  519. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/loading-c80ac975cf0f4842.js +1 -0
  520. package/app/{.next/static/chunks/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page-78d098f14f8cff05.js → .next-cli-build/static/chunks/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page-efb20dd903e0dc94.js} +10 -10
  521. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/media-providers/combo/[id]/page-03290d1edb08623a.js +4 -0
  522. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/page-9bcd63bfeeac87c6.js +1 -0
  523. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/providers/[id]/{page-97e0f7067cab0724.js → page-ca71683d9d850162.js} +3 -3
  524. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/pxpipe/page-c5c37fbce431369b.js +1 -0
  525. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/skills/page-b582299fa61407d9.js +1 -0
  526. package/app/.next-cli-build/static/css/92ffae29025c5847.css +1 -0
  527. package/app/open-sse/identity/snapshots/versions.json +9 -5
  528. package/app/open-sse/identity/tls/bin/darwin/arm64/switchboard-claude-tls +0 -0
  529. package/app/open-sse/identity/tls/bin/darwin/x64/switchboard-claude-tls +0 -0
  530. package/app/open-sse/identity/tls/bin/linux/arm64/switchboard-claude-tls +0 -0
  531. package/app/open-sse/identity/tls/bin/linux/x64/switchboard-claude-tls +0 -0
  532. package/app/open-sse/identity/tls/bin/win32/arm64/switchboard-claude-tls.exe +0 -0
  533. package/app/open-sse/identity/tls/bin/win32/x64/switchboard-claude-tls.exe +0 -0
  534. package/app/package.json +1 -1
  535. package/app/public/i18n/literals/zh-CN.json +17 -1
  536. package/app/src/lib/updater/updater.js +7 -2
  537. package/cli.js +85 -33
  538. package/hooks/trayRuntime.js +72 -17
  539. package/package.json +1 -1
  540. package/src/cli/api/client.js +9 -3
  541. package/src/cli/cliOptions.js +1 -1
  542. package/src/cli/processManager.js +61 -1
  543. package/src/cli/serverStatus.js +66 -4
  544. package/src/cli/terminalUI.js +5 -2
  545. package/src/cli/tray/autostart.js +20 -4
  546. package/src/cli/tray/tray.js +4 -1
  547. package/src/cli/utils/display.js +20 -0
  548. package/app/.next/static/chunks/1321-0003ef56aef2b3ab.js +0 -1
  549. package/app/.next/static/chunks/1330-56405eca78b12fee.js +0 -7
  550. package/app/.next/static/chunks/app/(dashboard)/dashboard/agent-library/page-40f3ca16440f8e17.js +0 -1
  551. package/app/.next/static/chunks/app/(dashboard)/dashboard/endpoint/page-ca47b09e6ed6ae7b.js +0 -16
  552. package/app/.next/static/chunks/app/(dashboard)/dashboard/media-providers/combo/[id]/page-ff13a39fb7744f5e.js +0 -4
  553. package/app/.next/static/chunks/app/(dashboard)/dashboard/page-86cd6523dcd61f1b.js +0 -1
  554. package/app/.next/static/chunks/app/(dashboard)/dashboard/pxpipe/page-1805f993834a1adb.js +0 -1
  555. package/app/.next/static/chunks/app/(dashboard)/dashboard/skills/page-645e7c5ec034fe8c.js +0 -1
  556. package/app/.next/static/css/196a6347b9104610.css +0 -1
  557. package/app/.next-cli-build/server/chunks/1350.js +0 -1
  558. package/app/.next-cli-build/server/chunks/1656.js +0 -2
  559. package/app/.next-cli-build/server/chunks/194.js +0 -1
  560. package/app/.next-cli-build/server/chunks/3026.js +0 -1
  561. package/app/.next-cli-build/server/chunks/5616.js +0 -1
  562. package/app/.next-cli-build/server/chunks/6052.js +0 -2
  563. package/app/.next-cli-build/server/chunks/6182.js +0 -63
  564. package/app/.next-cli-build/server/chunks/6274.js +0 -1
  565. package/app/.next-cli-build/server/chunks/6347.js +0 -1
  566. package/app/.next-cli-build/server/chunks/849.js +0 -1
  567. package/app/.next-cli-build/server/chunks/8658.js +0 -1
  568. package/app/.next-cli-build/server/chunks/8834.js +0 -7
  569. package/app/.next-cli-build/server/chunks/9617.js +0 -1
  570. package/app/.next-cli-build/server/chunks/static/media/versions.401d57e8.json +0 -20
  571. package/app/.next-cli-build/static/chunks/1321-0003ef56aef2b3ab.js +0 -1
  572. package/app/.next-cli-build/static/chunks/1330-56405eca78b12fee.js +0 -7
  573. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/agent-library/page-40f3ca16440f8e17.js +0 -1
  574. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/endpoint/page-ca47b09e6ed6ae7b.js +0 -16
  575. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/media-providers/combo/[id]/page-ff13a39fb7744f5e.js +0 -4
  576. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/page-86cd6523dcd61f1b.js +0 -1
  577. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/pxpipe/page-1805f993834a1adb.js +0 -1
  578. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/skills/page-645e7c5ec034fe8c.js +0 -1
  579. package/app/.next-cli-build/static/css/196a6347b9104610.css +0 -1
  580. /package/app/.next/static/{Kxe3gixpS84MCzX8yohZb → pVi5nGAVrNaYdEp0c24Nk}/_buildManifest.js +0 -0
  581. /package/app/.next/static/{Kxe3gixpS84MCzX8yohZb → pVi5nGAVrNaYdEp0c24Nk}/_ssgManifest.js +0 -0
  582. /package/app/.next-cli-build/static/{Kxe3gixpS84MCzX8yohZb → pVi5nGAVrNaYdEp0c24Nk}/_buildManifest.js +0 -0
  583. /package/app/.next-cli-build/static/{Kxe3gixpS84MCzX8yohZb → pVi5nGAVrNaYdEp0c24Nk}/_ssgManifest.js +0 -0
package/cli.js CHANGED
@@ -9,8 +9,8 @@ const { openBrowser: openBrowserWithoutShell } = require("./src/shared/openBrows
9
9
  const pkg = require("./package.json");
10
10
  const { DEFAULT_HOST, DEFAULT_PORT, formatHelp, isLoopbackHost, parseCliArgs } = require("./src/cli/cliOptions");
11
11
  const processTools = require("./src/cli/processManager");
12
- const { findListeningPids } = processTools;
13
- const { probeSwitchboard, probeTcp, waitForSwitchboard } = require("./src/cli/serverStatus");
12
+ const { findListeningPids, observeChildExit } = processTools;
13
+ const { probeSwitchboard, probeTcp, startHealthWatchdog, waitForSwitchboard } = require("./src/cli/serverStatus");
14
14
 
15
15
  // Subcommands (`switchboard xai video …`) run against an already-running
16
16
  // gateway and skip the launcher flow (no arg parsing, no server spawn).
@@ -629,8 +629,8 @@ async function showInterfaceMenu(latestVersion, { trayAvailable = true } = {}) {
629
629
  return menuItems[selected]?.action || "exit";
630
630
  }
631
631
 
632
- const MAX_RESTARTS = 2;
633
- const RESTART_RESET_MS = 30000; // Reset counter if alive > 30s
632
+
633
+ const RESTART_RESET_MS = 30000;
634
634
 
635
635
  function startServer(latestVersion) {
636
636
  const displayHost = getDisplayHost();
@@ -641,15 +641,20 @@ function startServer(latestVersion) {
641
641
  if (reachableHost) console.log(`\x1b[33m⚠ Network-exposed: reachable at http://${reachableHost}:${port} (bound ${host}). Use --host 127.0.0.1 for local-only. Non-loopback /v1 requires an API key by default.\x1b[0m`);
642
642
  }
643
643
 
644
- let restartCount = 0;
644
+ let consecutiveCrashes = 0;
645
+ let everHealthy = false;
645
646
  let serverStartTime = Date.now();
646
647
 
647
648
  const CRASH_LOG_LINES = 50;
648
649
  let crashLog = [];
650
+ let lastPrintedCrashLog = "";
649
651
 
650
652
  function spawnServer() {
651
653
  serverStartTime = Date.now();
652
654
  crashLog = [];
655
+ // A restarted child must prove itself healthy again before it earns
656
+ // unbounded restarts.
657
+ everHealthy = false;
653
658
  const child = spawn(RUNTIME, ["--max-old-space-size=6144", serverPath], {
654
659
  cwd: standaloneDir,
655
660
  stdio: ["ignore", "pipe", "pipe"],
@@ -683,6 +688,42 @@ function startServer(latestVersion) {
683
688
  let isShuttingDown = false;
684
689
  let shutdownPromise = null;
685
690
  let restartTimer = null;
691
+ let watchdogRestarting = false;
692
+ const stopHealthWatchdog = startHealthWatchdog({
693
+ port,
694
+ hostname: getProbeHost(),
695
+ onHealthy: () => {
696
+ everHealthy = true;
697
+ if (!isShuttingDown && server?.pid) writeOwnedProcessState(server.pid);
698
+ },
699
+ onUnhealthy: async () => {
700
+ // A child that already exited belongs to the crash-restart path (its
701
+ // respawn timer is pending); signalling its PID could hit an unrelated
702
+ // process if the OS reused it, so leave it alone without touching
703
+ // restartTimer.
704
+ if (isShuttingDown || watchdogRestarting || !processTools.childIsLive(server)) return;
705
+ watchdogRestarting = true;
706
+ const unhealthyServer = server;
707
+ clearTimeout(restartTimer);
708
+ restartTimer = null;
709
+ console.error("\nServer health checks failed repeatedly; restarting the owned server process.");
710
+ try {
711
+ const terminated = await processTools.terminatePid(unhealthyServer.pid, { timeoutMs: 2500, processGroup: true });
712
+ if (!terminated || isShuttingDown || server !== unhealthyServer) return;
713
+ try {
714
+ server = spawnServer();
715
+ attachServerEvents();
716
+ } catch (error) {
717
+ // The watchdog swallows callback errors, so a failed respawn must
718
+ // exit here instead of leaving a launcher with no server.
719
+ console.error("Failed to restart server:", error.message);
720
+ void shutdown(1);
721
+ }
722
+ } finally {
723
+ watchdogRestarting = false;
724
+ }
725
+ },
726
+ });
686
727
 
687
728
  async function cleanup() {
688
729
  if (isCleaningUp) return;
@@ -695,9 +736,12 @@ function startServer(latestVersion) {
695
736
  } catch (e) { }
696
737
  killProxyByPidFile();
697
738
  killTunnelByPidFile();
698
- const serverCleanup = server?.pid
739
+ // An exited child is never signalled (its PID may be reused), but its
740
+ // process group can still hold grandchildren (MCP stdio bridges, MITM
741
+ // proxy) that must not outlive the launcher.
742
+ const serverCleanup = processTools.childIsLive(server)
699
743
  ? processTools.terminatePid(server.pid, { timeoutMs: 2500, processGroup: true })
700
- : Promise.resolve(true);
744
+ : processTools.terminateOrphanedGroup(server?.pid, { timeoutMs: 2500 });
701
745
  const [, serverResult] = await Promise.allSettled([trayCleanup, serverCleanup]);
702
746
  if (serverResult.status === "fulfilled" && serverResult.value === true) clearOwnedProcessState();
703
747
  } catch (e) { }
@@ -707,6 +751,7 @@ function startServer(latestVersion) {
707
751
  if (shutdownPromise) return shutdownPromise;
708
752
  isShuttingDown = true;
709
753
  if (restartTimer) clearTimeout(restartTimer);
754
+ stopHealthWatchdog();
710
755
  if (message) console.log(message);
711
756
  shutdownPromise = cleanup().finally(() => process.exit(exitCode));
712
757
  return shutdownPromise;
@@ -757,6 +802,9 @@ function startServer(latestVersion) {
757
802
  // Ignore SIGHUP so macOS terminal close doesn't kill the background tray process
758
803
  process.removeAllListeners("SIGHUP");
759
804
  process.on("SIGHUP", () => {});
805
+ // The terminal may close while we keep running; a later console write to
806
+ // the dead pty would wedge the process, so fail those writes safely.
807
+ require("./src/cli/utils/display").detachTerminalOutput();
760
808
 
761
809
  console.log(`\n🚀 ${pkg.name} v${pkg.version}`);
762
810
  console.log(`Starting server at http://${displayHost}:${port}...`);
@@ -773,6 +821,7 @@ function startServer(latestVersion) {
773
821
  }
774
822
  return;
775
823
  }
824
+ everHealthy = true;
776
825
  const trayReady = await initTrayIcon();
777
826
  if (trayReady) {
778
827
  console.log("\nSwitchboard is ready in the system tray.");
@@ -801,6 +850,7 @@ function startServer(latestVersion) {
801
850
  }
802
851
  return;
803
852
  }
853
+ everHealthy = true;
804
854
  let trayReady = await initTrayIcon();
805
855
  if (!trayReady) {
806
856
  console.warn(`Tray icon unavailable. You can stop safely with Ctrl+C or "${APP_NAME} stop".`);
@@ -826,7 +876,7 @@ function startServer(latestVersion) {
826
876
  } else if (choice === "terminal") {
827
877
  // Start Terminal UI - it will return when user selects Back
828
878
  const { startTerminalUI } = require("./src/cli/terminalUI");
829
- await startTerminalUI(port, { networkExposed: isNetworkExposed() });
879
+ await startTerminalUI(port, { networkExposed: isNetworkExposed(), host: getProbeHost() });
830
880
  // Loop continues, show menu again
831
881
  } else if (choice === "hide") {
832
882
  const { clearScreen } = require("./src/cli/utils/display");
@@ -850,6 +900,9 @@ function startServer(latestVersion) {
850
900
  // it outside the login session so NSStatusItem silently fails.
851
901
  process.removeAllListeners("SIGHUP");
852
902
  process.on("SIGHUP", () => {});
903
+ // The user may now close this terminal; detach output first so a
904
+ // later console write to the dead pty cannot wedge the launcher.
905
+ require("./src/cli/utils/display").detachTerminalOutput();
853
906
 
854
907
  console.log(`\n⏳ Switching to tray mode... (icon already visible in menu bar)`);
855
908
  console.log(`🔔 Switchboard is running in tray (PID: ${process.pid})`);
@@ -892,11 +945,8 @@ function startServer(latestVersion) {
892
945
 
893
946
  function attachServerEvents() {
894
947
  const observedServer = server;
895
- let terminalEventHandled = false;
896
- const handleTerminalEvent = (code, signal, error) => {
897
- if (terminalEventHandled) return;
898
- terminalEventHandled = true;
899
- if (isShuttingDown) return;
948
+ observeChildExit(observedServer, (code, signal, error) => {
949
+ if (isShuttingDown || watchdogRestarting || observedServer !== server) return;
900
950
  if (error) console.error("Failed to start server:", error.message);
901
951
  if (error?.code === "EADDRINUSE" || isPortConflict()) {
902
952
  void stopForPortConflict();
@@ -908,14 +958,6 @@ function startServer(latestVersion) {
908
958
  return;
909
959
  }
910
960
  tryRestart(code, signal);
911
- };
912
-
913
- observedServer.on("error", (err) => {
914
- handleTerminalEvent(null, null, err);
915
- });
916
-
917
- observedServer.on("close", (code, signal) => {
918
- handleTerminalEvent(code, signal, null);
919
961
  });
920
962
  }
921
963
 
@@ -937,11 +979,16 @@ function startServer(latestVersion) {
937
979
  return;
938
980
  }
939
981
  const aliveMs = Date.now() - serverStartTime;
940
- // Reset counter if last run was stable
941
- if (aliveMs >= RESTART_RESET_MS) restartCount = 0;
982
+ // Stable runs reset backoff. Repeated crashes keep retrying at a bounded
983
+ // cadence so a transient runtime fault never leaves the gateway dead.
984
+ if (aliveMs >= RESTART_RESET_MS) {
985
+ consecutiveCrashes = 0;
986
+ lastPrintedCrashLog = "";
987
+ }
942
988
 
943
- if (restartCount >= MAX_RESTARTS) {
944
- console.error(`\nServer crashed ${MAX_RESTARTS} times. Giving up without changing your settings.`);
989
+ consecutiveCrashes++;
990
+ if (processTools.shouldAbandonRestarts({ consecutiveCrashes, everHealthy })) {
991
+ console.error(`\nServer crashed ${consecutiveCrashes} times without ever becoming healthy. Giving up without changing your settings.`);
945
992
  console.error(`Data directory: ${getAppDataDir()}`);
946
993
  console.error(`Retry with server logs: ${commandFor()} --log`);
947
994
  if (crashLog.length) {
@@ -952,15 +999,19 @@ function startServer(latestVersion) {
952
999
  void shutdown(1);
953
1000
  return;
954
1001
  }
955
-
956
- restartCount++;
957
- const delay = Math.min(1000 * restartCount, 10000);
1002
+ const delay = processTools.nextRestartDelay(consecutiveCrashes - 1);
958
1003
  const reason = signal ? `signal=${signal}` : `code=${code ?? "unknown"}`;
959
- console.error(`\nServer exited (${reason}). Restarting in ${delay / 1000}s... (${restartCount}/${MAX_RESTARTS})`);
960
- if (crashLog.length) {
961
- console.error("\n--- Server crash log ---");
962
- crashLog.forEach(l => console.error(l));
963
- console.error("--- End crash log ---\n");
1004
+ console.error(`\nServer exited (${reason}). Restarting in ${delay / 1000}s... (attempt ${consecutiveCrashes})`);
1005
+ const logText = crashLog.join("\n");
1006
+ if (processTools.shouldPrintCrashLog(consecutiveCrashes, crashLog, lastPrintedCrashLog)) {
1007
+ if (crashLog.length) {
1008
+ console.error("\n--- Server crash log ---");
1009
+ crashLog.forEach(l => console.error(l));
1010
+ console.error("--- End crash log ---\n");
1011
+ }
1012
+ lastPrintedCrashLog = logText;
1013
+ } else if (consecutiveCrashes === 11 && logText) {
1014
+ console.error(`suppressing repeated crash log; run \`${commandFor()} --log\` for full output`);
964
1015
  }
965
1016
 
966
1017
  restartTimer = setTimeout(() => {
@@ -971,5 +1022,6 @@ function startServer(latestVersion) {
971
1022
  }, delay);
972
1023
  }
973
1024
 
1025
+
974
1026
  attachServerEvents();
975
1027
  }
@@ -2,14 +2,19 @@
2
2
  // Uses platform-specific optionalDependencies (esbuild/swc pattern).
3
3
  // Each platform has its own npm package containing only that architecture's binary.
4
4
  // Falls back to downloading from GitHub releases if optionalDeps are missing.
5
+ const crypto = require("crypto");
5
6
  const fs = require("fs");
6
7
  const path = require("path");
7
8
  const https = require("https");
8
9
  const zlib = require("zlib");
10
+ const { getDataDir } = require("../src/shared/dataDir");
9
11
 
10
12
  const BINARY_NAME = "switchboard-tray";
11
13
  const TRAY_VERSION = "1.0.0";
12
14
  const GITHUB_REPO = "Vijay-Duke/switchboard-router";
15
+ // Upper bound for any single registry response body we buffer in memory.
16
+ const TARBALL_MAX_BYTES = 32 * 1024 * 1024;
17
+ const METADATA_MAX_BYTES = 1024 * 1024;
13
18
 
14
19
  // Platform → package name mapping
15
20
  const PLATFORM_PACKAGES = {
@@ -48,13 +53,10 @@ function resolveBinaryFromPackage() {
48
53
  }
49
54
 
50
55
  /**
51
- * Fallback: check if the binary was downloaded by postinstall into ~/.switchboard/runtime/bin/
56
+ * Fallback: check if the binary was downloaded by postinstall into <DATA_DIR>/runtime/bin/
52
57
  */
53
58
  function resolveBinaryFromCache() {
54
- const cacheDir = path.join(
55
- process.env.SWITCHBOARD_DATA_DIR || path.join(require("os").homedir(), ".switchboard"),
56
- "runtime", "bin"
57
- );
59
+ const cacheDir = path.join(getDataDir(), "runtime", "bin");
58
60
  const binPath = path.join(cacheDir, BINARY_NAME);
59
61
  if (fs.existsSync(binPath)) {
60
62
  return binPath;
@@ -63,17 +65,50 @@ function resolveBinaryFromCache() {
63
65
  }
64
66
 
65
67
  /**
66
- * Download the tray binary from GitHub releases as a last resort.
67
- * Stores it in ~/.switchboard/runtime/bin/
68
+ * Fetch the registry-recorded sha512 integrity for the platform tarball.
69
+ * Returns null when the metadata is missing or unusable (fail closed).
70
+ */
71
+ async function fetchTarballIntegrity(pkg) {
72
+ const metaUrl = `https://registry.npmjs.org/${pkg}/${TRAY_VERSION}`;
73
+ const body = await module.exports.httpGet(metaUrl, { maxBytes: METADATA_MAX_BYTES });
74
+ let meta;
75
+ try {
76
+ meta = JSON.parse(body.toString("utf8"));
77
+ } catch {
78
+ return null;
79
+ }
80
+ const integrity = meta && meta.dist && meta.dist.integrity;
81
+ if (typeof integrity !== "string" || !integrity.startsWith("sha512-")) return null;
82
+ return integrity;
83
+ }
84
+
85
+ /**
86
+ * Verify the downloaded tarball against the registry-recorded integrity
87
+ * (`sha512-<base64>`). Throws on mismatch — the bytes must never be executed.
88
+ */
89
+ function verifyTarballIntegrity(tarball, integrity) {
90
+ let expected;
91
+ try {
92
+ expected = Buffer.from(integrity.slice("sha512-".length), "base64");
93
+ } catch {
94
+ throw new Error("tray tarball has an unparseable integrity value");
95
+ }
96
+ const actual = crypto.createHash("sha512").update(tarball).digest();
97
+ if (expected.length !== actual.length || !crypto.timingSafeEqual(expected, actual)) {
98
+ throw new Error("tray tarball integrity mismatch; refusing to install");
99
+ }
100
+ }
101
+
102
+ /**
103
+ * Download the tray binary from the npm registry as a last resort.
104
+ * Stores it in <DATA_DIR>/runtime/bin/. The tarball is verified against the
105
+ * registry metadata integrity before anything is written or executed.
68
106
  */
69
107
  async function downloadBinaryFallback({ silent = false } = {}) {
70
108
  const pkg = getPlatformPackage();
71
109
  if (!pkg) return null;
72
110
 
73
- const cacheDir = path.join(
74
- process.env.SWITCHBOARD_DATA_DIR || path.join(require("os").homedir(), ".switchboard"),
75
- "runtime", "bin"
76
- );
111
+ const cacheDir = path.join(getDataDir(), "runtime", "bin");
77
112
  fs.mkdirSync(cacheDir, { recursive: true });
78
113
  const destPath = path.join(cacheDir, BINARY_NAME);
79
114
 
@@ -82,7 +117,13 @@ async function downloadBinaryFallback({ silent = false } = {}) {
82
117
  if (!silent) console.log(`⏳ Downloading tray binary from npm (${pkg})...`);
83
118
 
84
119
  try {
85
- const tarball = await httpGet(tarballUrl);
120
+ const integrity = await fetchTarballIntegrity(pkg);
121
+ if (!integrity) {
122
+ if (!silent) console.warn("⚠️ Tray metadata has no usable integrity; refusing download");
123
+ return null;
124
+ }
125
+ const tarball = await module.exports.httpGet(tarballUrl, { maxBytes: TARBALL_MAX_BYTES });
126
+ verifyTarballIntegrity(tarball, integrity);
86
127
  const extracted = extractFileFromTarball(zlib.gunzipSync(tarball), `package/bin/${BINARY_NAME}`);
87
128
  if (!extracted) {
88
129
  if (!silent) console.warn("⚠️ Failed to extract tray binary from tarball");
@@ -97,18 +138,32 @@ async function downloadBinaryFallback({ silent = false } = {}) {
97
138
  }
98
139
  }
99
140
 
100
- function httpGet(url) {
141
+ function httpGet(url, { maxBytes = TARBALL_MAX_BYTES } = {}) {
101
142
  return new Promise((resolve, reject) => {
102
143
  https.get(url, (res) => {
103
144
  if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
104
- return httpGet(res.headers.location).then(resolve, reject);
145
+ return module.exports.httpGet(res.headers.location, { maxBytes }).then(resolve, reject);
105
146
  }
106
147
  if (res.statusCode < 200 || res.statusCode >= 300) {
107
148
  return reject(new Error(`HTTP ${res.statusCode}`));
108
149
  }
109
150
  const chunks = [];
110
- res.on("data", (c) => chunks.push(c));
111
- res.on("end", () => resolve(Buffer.concat(chunks)));
151
+ let size = 0;
152
+ let rejected = false;
153
+ res.on("data", (c) => {
154
+ if (rejected) return;
155
+ size += c.length;
156
+ if (size > maxBytes) {
157
+ rejected = true;
158
+ try { res.destroy(); } catch { /* best effort */ }
159
+ reject(new Error(`response exceeds ${maxBytes} bytes`));
160
+ return;
161
+ }
162
+ chunks.push(c);
163
+ });
164
+ res.on("end", () => {
165
+ if (!rejected) resolve(Buffer.concat(chunks));
166
+ });
112
167
  res.on("error", reject);
113
168
  }).on("error", reject);
114
169
  });
@@ -179,5 +234,5 @@ function ensureTrayRuntime({ silent = false } = {}) {
179
234
  return { systray: false, needsDownload: true };
180
235
  }
181
236
 
182
- module.exports = { ensureTrayRuntime, getTrayBinPath, downloadBinaryFallback, getPlatformPackage };
237
+ module.exports = { ensureTrayRuntime, getTrayBinPath, downloadBinaryFallback, getPlatformPackage, httpGet };
183
238
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "switchboard-router",
3
- "version": "0.9.8",
3
+ "version": "0.9.10",
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",
@@ -50,10 +50,14 @@ function loadCliSecret() {
50
50
  }
51
51
 
52
52
  function getCliToken() {
53
- if (cachedCliToken !== null) return cachedCliToken;
53
+ if (cachedCliToken) return cachedCliToken;
54
+ // Never cache an empty token: the long-lived launcher probes before the
55
+ // server has written machine-id, and machineIdSync can fail (e.g. no
56
+ // /usr/sbin on PATH under launchd). Retry until the file exists.
54
57
  const raw = loadRawMachineId();
58
+ if (!raw) return "";
55
59
  const secret = loadCliSecret();
56
- cachedCliToken = raw ? crypto.createHash("sha256").update(raw + CLI_TOKEN_SALT + secret).digest("hex").substring(0, 16) : "";
60
+ cachedCliToken = crypto.createHash("sha256").update(raw + CLI_TOKEN_SALT + secret).digest("hex").substring(0, 16);
57
61
  return cachedCliToken;
58
62
  }
59
63
 
@@ -481,7 +485,9 @@ async function disableTunnel() {
481
485
 
482
486
  module.exports = {
483
487
  configure,
484
-
488
+ getCliToken,
489
+ CLI_TOKEN_HEADER,
490
+
485
491
  // Providers
486
492
  getProviders,
487
493
  getProviderById,
@@ -102,6 +102,7 @@ function formatHelp({ version = "unknown", defaultPort = DEFAULT_PORT, defaultHo
102
102
  Usage:
103
103
  switchboard [start] [options] Start Switchboard (default)
104
104
  switchboard status [options] Show server, version, PID, and ownership status
105
+ Exit codes: 0 running, 1 port conflict, 3 not running
105
106
  switchboard stop [options] Stop the owned Switchboard instance gracefully
106
107
  switchboard restart [options] Gracefully stop, then start Switchboard
107
108
  switchboard xai video [options] Generate a Grok Imagine video (MP4)
@@ -129,7 +130,6 @@ Examples:
129
130
  switchboard restart --port ${defaultPort}
130
131
  switchboard xai video --prompt "a neon city" --output video.mp4
131
132
  switchboard stop
132
- switchboard xai video --prompt "a neon city" --output video.mp4
133
133
  `;
134
134
  }
135
135
 
@@ -3,7 +3,8 @@ const path = require("path");
3
3
  const { execFileSync, execSync } = require("child_process");
4
4
 
5
5
  function normalizePath(value) {
6
- try { return path.resolve(value); } catch { return ""; }
6
+ try { return fs.realpathSync(path.resolve(value)); }
7
+ catch { try { return path.resolve(value); } catch { return ""; } }
7
8
  }
8
9
 
9
10
  function tokenizeCommand(command) {
@@ -171,16 +172,75 @@ async function terminatePid(pid, { timeoutMs = 2000, processGroup = false } = {}
171
172
  process.kill(unixTarget, "SIGKILL");
172
173
  }
173
174
  } catch { /* best effort */ }
175
+ const killDeadline = Date.now() + Math.min(timeoutMs, 1000);
176
+ while (targetIsAlive() && Date.now() < killDeadline) await sleep(25);
174
177
  return !targetIsAlive();
175
178
  }
176
179
 
180
+ // After a detached child has exited, its process group may still hold
181
+ // grandchildren. Sweep the group only while the leader PID itself is gone: a
182
+ // live PID means the OS reused it, and that process's group is not ours.
183
+ async function terminateOrphanedGroup(pid, { timeoutMs = 2000 } = {}) {
184
+ const numericPid = Number(pid);
185
+ if (process.platform === "win32" || !Number.isInteger(numericPid) || numericPid <= 1) return true;
186
+ if (isPidAlive(numericPid) || !isPidAlive(-numericPid)) return true;
187
+ return terminatePid(numericPid, { timeoutMs, processGroup: true });
188
+ }
189
+
190
+ function observeChildExit(child, onTerminal) {
191
+ let handled = false;
192
+ const finish = (code, signal, error) => {
193
+ if (handled) return;
194
+ handled = true;
195
+ onTerminal(code, signal, error);
196
+ };
197
+ child.once("error", (error) => finish(null, null, error));
198
+ child.once("exit", (code, signal) => finish(code, signal, null));
199
+ }
200
+
201
+ function nextRestartDelay(attempt) {
202
+ const exponent = Math.min(Math.max(Number(attempt) || 0, 0), 5);
203
+ return Math.min(1000 * (2 ** exponent), 30000);
204
+ }
205
+
206
+ // Give up on deterministic boot failures: a child that never served a healthy
207
+ // probe after maxBootFailures consecutive crashes will never recover by
208
+ // retrying. Once a child has been healthy, restarts stay unbounded.
209
+ function shouldAbandonRestarts({ consecutiveCrashes, everHealthy, maxBootFailures = 5 } = {}) {
210
+ return !everHealthy && Number(consecutiveCrashes) >= Number(maxBootFailures);
211
+ }
212
+
213
+ // True only for a child that the OS may still deliver signals to. A crashed
214
+ // child keeps its pid property after exit, so signalling it risks hitting an
215
+ // unrelated process if the OS has reused the PID.
216
+ function childIsLive(child) {
217
+ return !!child?.pid && child.exitCode === null && child.signalCode === null;
218
+ }
219
+
220
+ // Echo the crash log on the first attempt of a backoff cycle and whenever it
221
+ // changes; after 10 consecutive crashes the launcher keeps restarting at the
222
+ // 30 s cap but stays quiet (the log is still available via --log).
223
+ function shouldPrintCrashLog(attempt, log, lastPrinted) {
224
+ if (Number(attempt) > 10) return false;
225
+ const text = Array.isArray(log) ? log.join("\n") : String(log ?? "");
226
+ if (!text) return false;
227
+ if (Number(attempt) <= 1) return true;
228
+ return text !== String(lastPrinted ?? "");
229
+ }
230
+
177
231
  module.exports = {
178
232
  acquireLifecycleLock,
233
+ childIsLive,
179
234
  findListeningPids,
180
235
  getProcessCommand,
181
236
  getProcessCwd,
182
237
  isPidAlive,
238
+ observeChildExit,
239
+ nextRestartDelay,
240
+ shouldAbandonRestarts,
241
+ shouldPrintCrashLog,
183
242
  matchesRecordedProcess,
184
243
  processMatchesRecordedPath,
244
+ terminateOrphanedGroup,
185
245
  terminatePid,
186
246
  };
@@ -3,6 +3,11 @@ const net = require("net");
3
3
  const MAX_RESPONSE_BYTES = 64 * 1024;
4
4
 
5
5
  function requestJson({ hostname = "127.0.0.1", port, path, timeoutMs = 1000 }) {
6
+ // Lazily required so the data-dir resolution (and its tests) can point
7
+ // DATA_DIR at a temp dir before this module is first used. The CLI token
8
+ // lets probes authenticate against local-only routes from any peer, which
9
+ // keeps health and version probes working on explicit LAN binds.
10
+ const { CLI_TOKEN_HEADER, getCliToken } = require("./api/client");
6
11
  return new Promise((resolve) => {
7
12
  let settled = false;
8
13
  const finish = (value) => {
@@ -15,7 +20,7 @@ function requestJson({ hostname = "127.0.0.1", port, path, timeoutMs = 1000 }) {
15
20
  port,
16
21
  path,
17
22
  method: "GET",
18
- headers: { Accept: "application/json" },
23
+ headers: { Accept: "application/json", [CLI_TOKEN_HEADER]: getCliToken() },
19
24
  }, (res) => {
20
25
  let body = "";
21
26
  res.setEncoding("utf8");
@@ -61,14 +66,18 @@ function probeTcp(port, timeoutMs = 1000, hostname = "127.0.0.1") {
61
66
  });
62
67
  }
63
68
 
69
+ async function probeHealth(port, timeoutMs = 1000, hostname = "127.0.0.1") {
70
+ const response = await requestJson({ hostname, port, path: "/api/health", timeoutMs });
71
+ return response?.statusCode === 200 && response?.body?.ok === true;
72
+ }
73
+
64
74
  async function probeSwitchboard(port, timeoutMs = 1000, hostname = "127.0.0.1") {
65
75
  const response = await requestJson({ hostname, port, path: "/api/mgmt/v1/version", timeoutMs });
66
76
  const data = response?.body?.data;
67
77
  if (response?.statusCode === 200 && data?.name === "switchboard-app") return data;
68
78
 
69
79
  // Compatibility with older bundles that predate the management version API.
70
- const health = await requestJson({ hostname, port, path: "/api/health", timeoutMs });
71
- if (health?.statusCode === 200 && health?.body?.ok === true) {
80
+ if (await probeHealth(port, timeoutMs, hostname)) {
72
81
  return { name: "switchboard-app", version: null, startedAt: null, legacyHealth: true };
73
82
  }
74
83
  return null;
@@ -87,4 +96,57 @@ async function waitForSwitchboard(port, { timeoutMs = 20000, intervalMs = 250, h
87
96
  return null;
88
97
  }
89
98
 
90
- module.exports = { probeSwitchboard, probeTcp, waitForSwitchboard };
99
+ function startHealthWatchdog({
100
+ port,
101
+ hostname = "127.0.0.1",
102
+ graceMs = 60_000,
103
+ intervalMs = 10_000,
104
+ timeoutMs = 2_000,
105
+ maxFailures = 3,
106
+ probe = probeHealth,
107
+ onUnhealthy,
108
+ onHealthy,
109
+ } = {}) {
110
+ let stopped = false;
111
+ let timer = null;
112
+ let failures = 0;
113
+
114
+ const tick = async () => {
115
+ if (stopped) return;
116
+ try {
117
+ const status = await probe(port, timeoutMs, hostname).catch(() => null);
118
+ if (status) {
119
+ failures = 0;
120
+ try {
121
+ await onHealthy?.();
122
+ } catch (error) {
123
+ console.error("[watchdog] onHealthy failed:", error?.message || error);
124
+ }
125
+ } else failures++;
126
+
127
+ if (failures >= maxFailures) {
128
+ failures = 0;
129
+ try {
130
+ await onUnhealthy?.();
131
+ } catch (error) {
132
+ console.error("[watchdog] onUnhealthy failed:", error?.message || error);
133
+ }
134
+ if (stopped) return;
135
+ }
136
+ } catch (error) {
137
+ // A probe that throws synchronously must not become an unhandled
138
+ // rejection (the launcher would treat it as fatal).
139
+ console.error("[watchdog] probe failed:", error?.message || error);
140
+ } finally {
141
+ if (!stopped) timer = setTimeout(tick, intervalMs);
142
+ }
143
+ };
144
+
145
+ timer = setTimeout(tick, graceMs);
146
+ return () => {
147
+ stopped = true;
148
+ clearTimeout(timer);
149
+ };
150
+ }
151
+
152
+ module.exports = { probeHealth, probeSwitchboard, probeTcp, startHealthWatchdog, waitForSwitchboard };
@@ -52,10 +52,13 @@ function getHeader(port, networkExposed) {
52
52
  /**
53
53
  * Start Terminal UI
54
54
  * @param {number} port - Server port number
55
+ * @param {Object} [options] - UI options
56
+ * @param {boolean} [options.networkExposed] - Whether the bind is reachable from the LAN
57
+ * @param {string} [options.host] - Probe/bind host so API requests reach a specific-IP bind
55
58
  */
56
- async function startTerminalUI(port, { networkExposed = false } = {}) {
59
+ async function startTerminalUI(port, { networkExposed = false, host } = {}) {
57
60
  // Configure API client
58
- api.configure({ port });
61
+ api.configure(host ? { port, host } : { port });
59
62
 
60
63
  const basePath = ["Switchboard"];
61
64