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.
- package/app/.next/static/chunks/1321-a73f95036c368bd4.js +1 -0
- package/app/.next/static/chunks/1330-846d6a9e1497295e.js +7 -0
- package/app/.next/static/chunks/app/(dashboard)/dashboard/agent-library/page-65e302b698beee56.js +1 -0
- package/app/.next/static/chunks/app/(dashboard)/dashboard/endpoint/page-337881fe6c0cc77a.js +16 -0
- package/app/.next/static/chunks/app/(dashboard)/dashboard/loading-c80ac975cf0f4842.js +1 -0
- 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
- package/app/.next/static/chunks/app/(dashboard)/dashboard/media-providers/combo/[id]/page-03290d1edb08623a.js +4 -0
- package/app/.next/static/chunks/app/(dashboard)/dashboard/page-9bcd63bfeeac87c6.js +1 -0
- package/app/.next/static/chunks/app/(dashboard)/dashboard/providers/[id]/{page-97e0f7067cab0724.js → page-ca71683d9d850162.js} +3 -3
- package/app/.next/static/chunks/app/(dashboard)/dashboard/pxpipe/page-c5c37fbce431369b.js +1 -0
- package/app/.next/static/chunks/app/(dashboard)/dashboard/skills/page-b582299fa61407d9.js +1 -0
- package/app/.next/static/css/92ffae29025c5847.css +1 -0
- package/app/.next-cli-build/BUILD_ID +1 -1
- package/app/.next-cli-build/app-path-routes-manifest.json +8 -8
- package/app/.next-cli-build/build-manifest.json +2 -2
- package/app/.next-cli-build/prerender-manifest.json +3 -3
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/agent-library/page.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/agent-library/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/agent-library/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/basic-chat/page.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/basic-chat/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/basic-chat/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/[toolId]/page.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/[toolId]/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/[toolId]/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/page.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/page.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/routing/page.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/routing/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/routing/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/console-log/page.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/console-log/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/console-log/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/endpoint/page.js +3 -3
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/endpoint/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/endpoint/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page.js +10 -10
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/page.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/combo/[id]/page.js +3 -3
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/combo/[id]/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/combo/[id]/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/page.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/web/page.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/web/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/web/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/mitm/page.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/mitm/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/mitm/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/page.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/profile/page.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/profile/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/profile/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/[id]/page.js +2 -2
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/[id]/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/[id]/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/new/page.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/new/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/new/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/page.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/pxpipe/page.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/pxpipe/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/pxpipe/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/quota/page.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/quota/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/quota/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/skills/[id]/page.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/skills/[id]/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/skills/[id]/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/skills/page.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/skills/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/skills/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/token-saver/page.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/token-saver/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/token-saver/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/translator/page.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/translator/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/translator/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/usage/page.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/usage/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/usage/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/_global-error/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/_global-error.html +1 -1
- package/app/.next-cli-build/server/app/_global-error.rsc +1 -1
- package/app/.next-cli-build/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/_not-found/page.js +1 -1
- package/app/.next-cli-build/server/app/_not-found/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/_not-found.html +1 -1
- package/app/.next-cli-build/server/app/_not-found.rsc +4 -4
- package/app/.next-cli-build/server/app/_not-found.segments/_full.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/api/agent-library/catalog/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/agent-library/doctor/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/agent-library/export/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/agent-library/mcp/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/agent-library/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/agent-library/skills/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/agent-library/sync/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/agent-library/updates/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/auth/status/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/aider-settings/route.js +2 -2
- package/app/.next-cli-build/server/app/api/cli-tools/aider-settings/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/all-statuses/route.js +5 -5
- package/app/.next-cli-build/server/app/api/cli-tools/all-statuses/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/alias/route.js +2 -2
- package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/alias/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/route.js +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/claude-full-catalog/route.js +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/claude-full-catalog/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/claude-picker-labels/route.js +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/claude-picker-labels/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/claude-settings/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/cline-settings/route.js +2 -2
- package/app/.next-cli-build/server/app/api/cli-tools/cline-settings/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/codex-settings/route.js +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/codex-settings/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/cowork-mcp-registry/route.js +2 -2
- package/app/.next-cli-build/server/app/api/cli-tools/cowork-mcp-registry/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/cowork-mcp-tools/route.js +2 -2
- package/app/.next-cli-build/server/app/api/cli-tools/cowork-mcp-tools/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/cowork-settings/route.js +2 -2
- package/app/.next-cli-build/server/app/api/cli-tools/cowork-settings/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/deepseek-tui-settings/route.js +2 -2
- package/app/.next-cli-build/server/app/api/cli-tools/deepseek-tui-settings/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/droid-settings/route.js +2 -2
- package/app/.next-cli-build/server/app/api/cli-tools/droid-settings/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/gemini-cli-settings/route.js +2 -2
- package/app/.next-cli-build/server/app/api/cli-tools/gemini-cli-settings/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/grok-settings/route.js +2 -2
- package/app/.next-cli-build/server/app/api/cli-tools/grok-settings/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/hermes-settings/route.js +2 -2
- package/app/.next-cli-build/server/app/api/cli-tools/hermes-settings/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/jcode-settings/route.js +2 -2
- package/app/.next-cli-build/server/app/api/cli-tools/jcode-settings/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/kilo-settings/route.js +2 -2
- package/app/.next-cli-build/server/app/api/cli-tools/kilo-settings/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/openclaw-settings/route.js +2 -2
- package/app/.next-cli-build/server/app/api/cli-tools/openclaw-settings/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/opencode-settings/route.js +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/opencode-settings/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/pi-settings/route.js +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/pi-settings/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/picker-labels/route.js +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/picker-labels/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/combos/[id]/route.js +1 -1
- package/app/.next-cli-build/server/app/api/combos/[id]/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/combos/route.js +1 -1
- package/app/.next-cli-build/server/app/api/combos/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/headroom/extras/route.js +1 -1
- package/app/.next-cli-build/server/app/api/headroom/extras/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/headroom/proxy/[...path]/route.js +1 -1
- package/app/.next-cli-build/server/app/api/headroom/proxy/[...path]/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/headroom/restart/route.js +1 -1
- package/app/.next-cli-build/server/app/api/headroom/restart/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/headroom/start/route.js +1 -1
- package/app/.next-cli-build/server/app/api/headroom/start/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/headroom/status/route.js +1 -1
- package/app/.next-cli-build/server/app/api/headroom/status/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/headroom/stop/route.js +1 -1
- package/app/.next-cli-build/server/app/api/headroom/stop/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/health/route.js +1 -1
- package/app/.next-cli-build/server/app/api/health/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/keys/[id]/route.js +1 -1
- package/app/.next-cli-build/server/app/api/keys/[id]/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/keys/route.js +1 -1
- package/app/.next-cli-build/server/app/api/keys/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/locale/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/mcp/[plugin]/message/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/mcp/[plugin]/sse/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/media-providers/tts/deepgram/voices/route.js +1 -1
- package/app/.next-cli-build/server/app/api/media-providers/tts/deepgram/voices/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/media-providers/tts/elevenlabs/voices/route.js +1 -1
- package/app/.next-cli-build/server/app/api/media-providers/tts/elevenlabs/voices/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/media-providers/tts/inworld/voices/route.js +1 -1
- package/app/.next-cli-build/server/app/api/media-providers/tts/inworld/voices/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/media-providers/tts/minimax/voices/route.js +1 -1
- package/app/.next-cli-build/server/app/api/media-providers/tts/minimax/voices/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/media-providers/tts/voices/route.js +1 -1
- package/app/.next-cli-build/server/app/api/media-providers/tts/voices/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/mgmt/v1/combos/[id]/route.js +1 -1
- package/app/.next-cli-build/server/app/api/mgmt/v1/combos/[id]/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/mgmt/v1/combos/[id]/strategy/route.js +1 -1
- package/app/.next-cli-build/server/app/api/mgmt/v1/combos/[id]/strategy/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/mgmt/v1/combos/route.js +1 -1
- package/app/.next-cli-build/server/app/api/mgmt/v1/combos/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/mgmt/v1/health/route.js +1 -1
- package/app/.next-cli-build/server/app/api/mgmt/v1/health/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/mgmt/v1/metrics/route.js +2 -2
- package/app/.next-cli-build/server/app/api/mgmt/v1/metrics/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/mgmt/v1/providers/route.js +1 -1
- package/app/.next-cli-build/server/app/api/mgmt/v1/providers/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/mgmt/v1/routing/route.js +1 -1
- package/app/.next-cli-build/server/app/api/mgmt/v1/routing/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/mgmt/v1/usage/route.js +1 -1
- package/app/.next-cli-build/server/app/api/mgmt/v1/usage/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/mgmt/v1/version/route.js +1 -1
- package/app/.next-cli-build/server/app/api/mgmt/v1/version/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/models/alias/route.js +1 -1
- package/app/.next-cli-build/server/app/api/models/alias/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/models/availability/route.js +1 -1
- package/app/.next-cli-build/server/app/api/models/availability/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/models/custom/route.js +1 -1
- package/app/.next-cli-build/server/app/api/models/custom/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/models/disabled/route.js +1 -1
- package/app/.next-cli-build/server/app/api/models/disabled/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/models/route.js +1 -1
- package/app/.next-cli-build/server/app/api/models/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/models/test/route.js +1 -1
- package/app/.next-cli-build/server/app/api/models/test/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/oauth/[provider]/[action]/route.js +1 -1
- package/app/.next-cli-build/server/app/api/oauth/[provider]/[action]/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/oauth/codex/bulk-import/route.js +1 -1
- package/app/.next-cli-build/server/app/api/oauth/codex/bulk-import/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/oauth/codex/import-token/route.js +1 -1
- package/app/.next-cli-build/server/app/api/oauth/codex/import-token/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/oauth/cursor/auto-import/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/oauth/cursor/import/route.js +1 -1
- package/app/.next-cli-build/server/app/api/oauth/cursor/import/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/oauth/gitlab/pat/route.js +1 -1
- package/app/.next-cli-build/server/app/api/oauth/gitlab/pat/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/oauth/iflow/cookie/route.js +1 -1
- package/app/.next-cli-build/server/app/api/oauth/iflow/cookie/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/oauth/kiro/api-key/route.js +1 -1
- package/app/.next-cli-build/server/app/api/oauth/kiro/api-key/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/oauth/kiro/auto-import/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/oauth/kiro/import/route.js +1 -1
- package/app/.next-cli-build/server/app/api/oauth/kiro/import/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/oauth/kiro/import-cli-proxy/route.js +1 -1
- package/app/.next-cli-build/server/app/api/oauth/kiro/import-cli-proxy/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/oauth/kiro/social-authorize/route.js +1 -1
- package/app/.next-cli-build/server/app/api/oauth/kiro/social-authorize/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/oauth/kiro/social-exchange/route.js +1 -1
- package/app/.next-cli-build/server/app/api/oauth/kiro/social-exchange/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/pricing/route.js +1 -1
- package/app/.next-cli-build/server/app/api/pricing/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/provider-nodes/[id]/route.js +1 -1
- package/app/.next-cli-build/server/app/api/provider-nodes/[id]/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/provider-nodes/route.js +1 -1
- package/app/.next-cli-build/server/app/api/provider-nodes/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/provider-nodes/validate/route.js +1 -1
- package/app/.next-cli-build/server/app/api/provider-nodes/validate/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/batch/route.js +1 -1
- package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/batch/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/cache/route.js +1 -1
- package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/cache/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/prepare/route.js +1 -1
- package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/prepare/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/remove-unavailable/route.js +1 -1
- package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/remove-unavailable/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/route.js +1 -1
- package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/verify/cancel/route.js +1 -1
- package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/verify/cancel/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/verify/start/route.js +1 -1
- package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/verify/start/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/verify/status/route.js +1 -1
- package/app/.next-cli-build/server/app/api/providers/[id]/model-probes/verify/status/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/providers/[id]/models/route.js +1 -1
- package/app/.next-cli-build/server/app/api/providers/[id]/models/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/providers/[id]/route.js +1 -1
- package/app/.next-cli-build/server/app/api/providers/[id]/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/providers/[id]/test/route.js +1 -1
- package/app/.next-cli-build/server/app/api/providers/[id]/test/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/providers/[id]/test-models/route.js +1 -1
- package/app/.next-cli-build/server/app/api/providers/[id]/test-models/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/providers/client/route.js +1 -1
- package/app/.next-cli-build/server/app/api/providers/client/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/providers/kilo/free-models/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/providers/route.js +1 -1
- package/app/.next-cli-build/server/app/api/providers/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/providers/suggested-models/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/providers/test-batch/route.js +1 -1
- package/app/.next-cli-build/server/app/api/providers/test-batch/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/providers/validate/route.js +1 -1
- package/app/.next-cli-build/server/app/api/providers/validate/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/pxpipe/health/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/pxpipe/install/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/pxpipe/logs/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/pxpipe/restart/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/pxpipe/start/route.js +2 -2
- package/app/.next-cli-build/server/app/api/pxpipe/start/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/pxpipe/stats/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/pxpipe/status/route.js +2 -2
- package/app/.next-cli-build/server/app/api/pxpipe/status/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/pxpipe/stop/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/routing/feedback/route.js +1 -1
- package/app/.next-cli-build/server/app/api/routing/feedback/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/routing/insights/route.js +1 -1
- package/app/.next-cli-build/server/app/api/routing/insights/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/routing/learn/route.js +1 -1
- package/app/.next-cli-build/server/app/api/routing/learn/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/routing/stats/route.js +1 -1
- package/app/.next-cli-build/server/app/api/routing/stats/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/routing/versions/promote/route.js +1 -1
- package/app/.next-cli-build/server/app/api/routing/versions/promote/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/routing/versions/rollback/route.js +1 -1
- package/app/.next-cli-build/server/app/api/routing/versions/rollback/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/settings/database/route.js +1 -1
- package/app/.next-cli-build/server/app/api/settings/database/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/settings/proxy-test/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/settings/route.js +1 -1
- package/app/.next-cli-build/server/app/api/settings/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/shutdown/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/skills/[id]/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/tags/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/token-saver/vault-stats/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/translator/console-logs/route.js +1 -1
- package/app/.next-cli-build/server/app/api/translator/console-logs/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/translator/console-logs/stream/route.js +1 -1
- package/app/.next-cli-build/server/app/api/translator/console-logs/stream/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/translator/load/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/translator/save/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/translator/send/route.js +1 -1
- package/app/.next-cli-build/server/app/api/translator/send/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/translator/translate/route.js +1 -1
- package/app/.next-cli-build/server/app/api/translator/translate/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/usage/[connectionId]/codex-reset-credits/route.js +1 -1
- package/app/.next-cli-build/server/app/api/usage/[connectionId]/codex-reset-credits/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/usage/[connectionId]/route.js +1 -1
- package/app/.next-cli-build/server/app/api/usage/[connectionId]/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/usage/chart/route.js +1 -1
- package/app/.next-cli-build/server/app/api/usage/chart/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/usage/history/route.js +1 -1
- package/app/.next-cli-build/server/app/api/usage/history/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/usage/logs/route.js +1 -1
- package/app/.next-cli-build/server/app/api/usage/logs/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/usage/providers/route.js +1 -1
- package/app/.next-cli-build/server/app/api/usage/providers/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/usage/request-details/route.js +1 -1
- package/app/.next-cli-build/server/app/api/usage/request-details/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/usage/request-logs/route.js +1 -1
- package/app/.next-cli-build/server/app/api/usage/request-logs/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/usage/stats/route.js +1 -1
- package/app/.next-cli-build/server/app/api/usage/stats/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/usage/stream/route.js +2 -6
- package/app/.next-cli-build/server/app/api/usage/stream/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/api/chat/route.js +1 -1
- package/app/.next-cli-build/server/app/api/v1/api/chat/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/audio/speech/route.js +1 -1
- package/app/.next-cli-build/server/app/api/v1/audio/speech/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/audio/transcriptions/route.js +1 -1
- package/app/.next-cli-build/server/app/api/v1/audio/transcriptions/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/audio/voices/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/chat/completions/route.js +1 -1
- package/app/.next-cli-build/server/app/api/v1/chat/completions/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/embeddings/route.js +1 -1
- package/app/.next-cli-build/server/app/api/v1/embeddings/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/images/generations/route.js +1 -1
- package/app/.next-cli-build/server/app/api/v1/images/generations/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/messages/count_tokens/route.js +1 -1
- package/app/.next-cli-build/server/app/api/v1/messages/count_tokens/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/messages/route.js +1 -1
- package/app/.next-cli-build/server/app/api/v1/messages/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/models/[kind]/route.js +1 -1
- package/app/.next-cli-build/server/app/api/v1/models/[kind]/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/models/info/route.js +1 -1
- package/app/.next-cli-build/server/app/api/v1/models/info/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/models/route.js +1 -1
- package/app/.next-cli-build/server/app/api/v1/models/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/responses/compact/route.js +1 -1
- package/app/.next-cli-build/server/app/api/v1/responses/compact/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/responses/route.js +1 -1
- package/app/.next-cli-build/server/app/api/v1/responses/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/route.js +1 -1
- package/app/.next-cli-build/server/app/api/v1/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/search/route.js +1 -1
- package/app/.next-cli-build/server/app/api/v1/search/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/videos/[id]/route.js +1 -1
- package/app/.next-cli-build/server/app/api/v1/videos/[id]/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/videos/edits/route.js +1 -1
- package/app/.next-cli-build/server/app/api/v1/videos/edits/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/videos/extensions/route.js +1 -1
- package/app/.next-cli-build/server/app/api/v1/videos/extensions/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/videos/generations/route.js +1 -1
- package/app/.next-cli-build/server/app/api/v1/videos/generations/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/web/fetch/route.js +1 -1
- package/app/.next-cli-build/server/app/api/v1/web/fetch/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1beta/models/[...path]/route.js +1 -1
- package/app/.next-cli-build/server/app/api/v1beta/models/[...path]/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1beta/models/route.js +1 -1
- package/app/.next-cli-build/server/app/api/v1beta/models/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/version/route.js +1 -1
- package/app/.next-cli-build/server/app/api/version/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/version/shutdown/route.js +1 -1
- package/app/.next-cli-build/server/app/api/version/shutdown/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/version/update/route.js +1 -1
- package/app/.next-cli-build/server/app/api/version/update/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/callback/page.js +1 -1
- package/app/.next-cli-build/server/app/callback/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/callback/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/callback.html +1 -1
- package/app/.next-cli-build/server/app/callback.rsc +4 -4
- package/app/.next-cli-build/server/app/callback.segments/_full.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/callback.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/callback.segments/callback/__PAGE__.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/dashboard/settings/pricing/page.js +1 -1
- package/app/.next-cli-build/server/app/dashboard/settings/pricing/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/dashboard/settings/pricing/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/dashboard/settings/pricing.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/settings/pricing.rsc +4 -4
- package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_full.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing/__PAGE__.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/favicon.ico/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/index.html +1 -1
- package/app/.next-cli-build/server/app/index.rsc +4 -4
- package/app/.next-cli-build/server/app/index.segments/__PAGE__.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/index.segments/_full.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/index.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/landing/page.js +1 -1
- package/app/.next-cli-build/server/app/landing/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/landing/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/landing.html +1 -1
- package/app/.next-cli-build/server/app/landing.rsc +4 -4
- package/app/.next-cli-build/server/app/landing.segments/_full.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/landing.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/landing.segments/landing/__PAGE__.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/login/page.js +1 -1
- package/app/.next-cli-build/server/app/login/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/login/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/login.html +1 -1
- package/app/.next-cli-build/server/app/login.rsc +4 -4
- package/app/.next-cli-build/server/app/login.segments/_full.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/login.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/login.segments/login/__PAGE__.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/manifest.webmanifest/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/page.js +1 -1
- package/app/.next-cli-build/server/app/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app-paths-manifest.json +8 -8
- package/app/.next-cli-build/server/chunks/1158.js +1 -0
- package/app/.next-cli-build/server/chunks/1274.js +1 -0
- package/app/.next-cli-build/server/chunks/1351.js +1 -0
- package/app/.next-cli-build/server/chunks/1792.js +2 -0
- package/app/.next-cli-build/server/chunks/{159.js → 1837.js} +1 -1
- package/app/.next-cli-build/server/chunks/1937.js +1 -1
- package/app/.next-cli-build/server/chunks/1998.js +1 -1
- package/app/.next-cli-build/server/chunks/{3986.js → 2142.js} +2 -2
- package/app/.next-cli-build/server/chunks/{9508.js → 27.js} +5 -42
- package/app/.next-cli-build/server/chunks/3423.js +1 -0
- package/app/.next-cli-build/server/chunks/3446.js +1 -1
- package/app/.next-cli-build/server/chunks/3593.js +1 -1
- package/app/.next-cli-build/server/chunks/369.js +10 -10
- package/app/.next-cli-build/server/chunks/3735.js +2 -2
- package/app/.next-cli-build/server/chunks/403.js +1 -0
- package/app/.next-cli-build/server/chunks/4330.js +7 -0
- package/app/.next-cli-build/server/chunks/{940.js → 4675.js} +2 -2
- package/app/.next-cli-build/server/chunks/4739.js +1 -1
- package/app/.next-cli-build/server/chunks/4780.js +1 -1
- package/app/.next-cli-build/server/chunks/4803.js +1 -1
- package/app/.next-cli-build/server/chunks/507.js +1 -1
- package/app/.next-cli-build/server/chunks/5115.js +1 -0
- package/app/.next-cli-build/server/chunks/519.js +1 -0
- package/app/.next-cli-build/server/chunks/5195.js +1 -0
- package/app/.next-cli-build/server/chunks/5258.js +1 -1
- package/app/.next-cli-build/server/chunks/5717.js +9 -14
- package/app/.next-cli-build/server/chunks/5774.js +1 -0
- package/app/.next-cli-build/server/chunks/5781.js +2 -2
- package/app/.next-cli-build/server/chunks/5888.js +1 -1
- package/app/.next-cli-build/server/chunks/5920.js +2 -2
- package/app/.next-cli-build/server/chunks/6194.js +1 -0
- package/app/.next-cli-build/server/chunks/6252.js +1 -1
- package/app/.next-cli-build/server/chunks/6305.js +2 -0
- package/app/.next-cli-build/server/chunks/6328.js +1 -1
- package/app/.next-cli-build/server/chunks/6406.js +1 -1
- package/app/.next-cli-build/server/chunks/6492.js +1 -1
- package/app/.next-cli-build/server/chunks/{5913.js → 6757.js} +38 -1
- package/app/.next-cli-build/server/chunks/698.js +1 -1
- package/app/.next-cli-build/server/chunks/7133.js +1 -0
- package/app/.next-cli-build/server/chunks/7454.js +1 -1
- package/app/.next-cli-build/server/chunks/{3072.js → 7880.js} +2 -2
- package/app/.next-cli-build/server/chunks/7965.js +1 -1
- package/app/.next-cli-build/server/chunks/8027.js +63 -0
- package/app/.next-cli-build/server/chunks/8062.js +1 -1
- package/app/.next-cli-build/server/chunks/8400.js +12 -12
- package/app/.next-cli-build/server/chunks/8469.js +1 -1
- package/app/.next-cli-build/server/chunks/8520.js +1 -1
- package/app/.next-cli-build/server/chunks/869.js +1 -1
- package/app/.next-cli-build/server/chunks/8775.js +1 -1
- package/app/.next-cli-build/server/chunks/8789.js +1 -1
- package/app/.next-cli-build/server/chunks/8942.js +2 -2
- package/app/.next-cli-build/server/chunks/8976.js +1 -1
- package/app/.next-cli-build/server/chunks/8998.js +33 -38
- package/app/.next-cli-build/server/chunks/9059.js +1 -0
- package/app/.next-cli-build/server/chunks/9091.js +3 -3
- package/app/.next-cli-build/server/chunks/9261.js +2 -2
- package/app/.next-cli-build/server/chunks/9264.js +2 -2
- package/app/.next-cli-build/server/chunks/9421.js +2 -2
- package/app/.next-cli-build/server/chunks/static/media/versions.4155c5ec.json +24 -0
- package/app/.next-cli-build/server/middleware-build-manifest.js +1 -1
- package/app/.next-cli-build/server/middleware.js +11 -16
- package/app/.next-cli-build/server/pages/404.html +1 -1
- package/app/.next-cli-build/server/pages/500.html +1 -1
- package/app/.next-cli-build/server/server-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/server-reference-manifest.json +1 -1
- package/app/.next-cli-build/static/chunks/1321-a73f95036c368bd4.js +1 -0
- package/app/.next-cli-build/static/chunks/1330-846d6a9e1497295e.js +7 -0
- package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/agent-library/page-65e302b698beee56.js +1 -0
- package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/endpoint/page-337881fe6c0cc77a.js +16 -0
- package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/loading-c80ac975cf0f4842.js +1 -0
- 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
- package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/media-providers/combo/[id]/page-03290d1edb08623a.js +4 -0
- package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/page-9bcd63bfeeac87c6.js +1 -0
- package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/providers/[id]/{page-97e0f7067cab0724.js → page-ca71683d9d850162.js} +3 -3
- package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/pxpipe/page-c5c37fbce431369b.js +1 -0
- package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/skills/page-b582299fa61407d9.js +1 -0
- package/app/.next-cli-build/static/css/92ffae29025c5847.css +1 -0
- package/app/open-sse/identity/snapshots/versions.json +9 -5
- package/app/open-sse/identity/tls/bin/darwin/arm64/switchboard-claude-tls +0 -0
- package/app/open-sse/identity/tls/bin/darwin/x64/switchboard-claude-tls +0 -0
- package/app/open-sse/identity/tls/bin/linux/arm64/switchboard-claude-tls +0 -0
- package/app/open-sse/identity/tls/bin/linux/x64/switchboard-claude-tls +0 -0
- package/app/open-sse/identity/tls/bin/win32/arm64/switchboard-claude-tls.exe +0 -0
- package/app/open-sse/identity/tls/bin/win32/x64/switchboard-claude-tls.exe +0 -0
- package/app/package.json +1 -1
- package/app/public/i18n/literals/zh-CN.json +17 -1
- package/app/src/lib/updater/updater.js +7 -2
- package/cli.js +85 -33
- package/hooks/trayRuntime.js +72 -17
- package/package.json +1 -1
- package/src/cli/api/client.js +9 -3
- package/src/cli/cliOptions.js +1 -1
- package/src/cli/processManager.js +61 -1
- package/src/cli/serverStatus.js +66 -4
- package/src/cli/terminalUI.js +5 -2
- package/src/cli/tray/autostart.js +20 -4
- package/src/cli/tray/tray.js +4 -1
- package/src/cli/utils/display.js +20 -0
- package/app/.next/static/chunks/1321-0003ef56aef2b3ab.js +0 -1
- package/app/.next/static/chunks/1330-56405eca78b12fee.js +0 -7
- package/app/.next/static/chunks/app/(dashboard)/dashboard/agent-library/page-40f3ca16440f8e17.js +0 -1
- package/app/.next/static/chunks/app/(dashboard)/dashboard/endpoint/page-ca47b09e6ed6ae7b.js +0 -16
- package/app/.next/static/chunks/app/(dashboard)/dashboard/media-providers/combo/[id]/page-ff13a39fb7744f5e.js +0 -4
- package/app/.next/static/chunks/app/(dashboard)/dashboard/page-86cd6523dcd61f1b.js +0 -1
- package/app/.next/static/chunks/app/(dashboard)/dashboard/pxpipe/page-1805f993834a1adb.js +0 -1
- package/app/.next/static/chunks/app/(dashboard)/dashboard/skills/page-645e7c5ec034fe8c.js +0 -1
- package/app/.next/static/css/196a6347b9104610.css +0 -1
- package/app/.next-cli-build/server/chunks/1350.js +0 -1
- package/app/.next-cli-build/server/chunks/1656.js +0 -2
- package/app/.next-cli-build/server/chunks/194.js +0 -1
- package/app/.next-cli-build/server/chunks/3026.js +0 -1
- package/app/.next-cli-build/server/chunks/5616.js +0 -1
- package/app/.next-cli-build/server/chunks/6052.js +0 -2
- package/app/.next-cli-build/server/chunks/6182.js +0 -63
- package/app/.next-cli-build/server/chunks/6274.js +0 -1
- package/app/.next-cli-build/server/chunks/6347.js +0 -1
- package/app/.next-cli-build/server/chunks/849.js +0 -1
- package/app/.next-cli-build/server/chunks/8658.js +0 -1
- package/app/.next-cli-build/server/chunks/8834.js +0 -7
- package/app/.next-cli-build/server/chunks/9617.js +0 -1
- package/app/.next-cli-build/server/chunks/static/media/versions.401d57e8.json +0 -20
- package/app/.next-cli-build/static/chunks/1321-0003ef56aef2b3ab.js +0 -1
- package/app/.next-cli-build/static/chunks/1330-56405eca78b12fee.js +0 -7
- package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/agent-library/page-40f3ca16440f8e17.js +0 -1
- package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/endpoint/page-ca47b09e6ed6ae7b.js +0 -16
- package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/media-providers/combo/[id]/page-ff13a39fb7744f5e.js +0 -4
- package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/page-86cd6523dcd61f1b.js +0 -1
- package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/pxpipe/page-1805f993834a1adb.js +0 -1
- package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/skills/page-645e7c5ec034fe8c.js +0 -1
- package/app/.next-cli-build/static/css/196a6347b9104610.css +0 -1
- /package/app/.next/static/{Kxe3gixpS84MCzX8yohZb → pVi5nGAVrNaYdEp0c24Nk}/_buildManifest.js +0 -0
- /package/app/.next/static/{Kxe3gixpS84MCzX8yohZb → pVi5nGAVrNaYdEp0c24Nk}/_ssgManifest.js +0 -0
- /package/app/.next-cli-build/static/{Kxe3gixpS84MCzX8yohZb → pVi5nGAVrNaYdEp0c24Nk}/_buildManifest.js +0 -0
- /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
|
-
|
|
633
|
-
const RESTART_RESET_MS = 30000;
|
|
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
|
|
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
|
-
|
|
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
|
-
:
|
|
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
|
-
|
|
896
|
-
|
|
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
|
-
//
|
|
941
|
-
|
|
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
|
-
|
|
944
|
-
|
|
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... (${
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
crashLog.
|
|
963
|
-
|
|
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
|
}
|
package/hooks/trayRuntime.js
CHANGED
|
@@ -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
|
|
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
|
-
*
|
|
67
|
-
*
|
|
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
|
|
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
|
-
|
|
111
|
-
|
|
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
package/src/cli/api/client.js
CHANGED
|
@@ -50,10 +50,14 @@ function loadCliSecret() {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
function getCliToken() {
|
|
53
|
-
if (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 =
|
|
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,
|
package/src/cli/cliOptions.js
CHANGED
|
@@ -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); }
|
|
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
|
};
|
package/src/cli/serverStatus.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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 };
|
package/src/cli/terminalUI.js
CHANGED
|
@@ -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
|
|