@jheavenknows/bluerouter 1.0.51 → 1.0.53
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-cli-build/BUILD_ID +1 -1
- package/app/.next-cli-build/app-path-routes-manifest.json +5 -5
- 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/required-server-files.json +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_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_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_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/endpoint/page.js +1 -1
- 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 +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_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/combo/[id]/page.js +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/web/page.js +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_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/ollama-nodes/page.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/ollama-nodes/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_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/prompt-logs/page.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/prompt-logs/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/provider-health/page.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/provider-health/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/[id]/page.js +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_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_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/proxy-pools/page.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/proxy-pools/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_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_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_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_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/virtual-combos/page.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/virtual-combos/page_client-reference-manifest.js +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/_global-error.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/_global-error.segments/_index.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_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/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/_not-found.segments/_index.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/api/auth/ldap/test/route.js +1 -1
- package/app/.next-cli-build/server/app/api/auth/ldap/test/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/auth/ldap/users/route.js +1 -1
- package/app/.next-cli-build/server/app/api/auth/ldap/users/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/auth/login/route.js +1 -1
- package/app/.next-cli-build/server/app/api/auth/login/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/auth/logout/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/auth/oidc/callback/route.js +1 -1
- package/app/.next-cli-build/server/app/api/auth/oidc/callback/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/auth/oidc/start/route.js +1 -1
- package/app/.next-cli-build/server/app/api/auth/oidc/start/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/auth/oidc/test/route.js +1 -1
- package/app/.next-cli-build/server/app/api/auth/oidc/test/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/auth/status/route.js +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/all-statuses/route.js +4 -4
- 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/autostart/route.js +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/autostart/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/prompt-log-db/route.js +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/prompt-log-db/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/root-ca/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-settings/route.js +2 -2
- 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/codex-settings/route.js +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/copilot-settings/route.js +2 -2
- package/app/.next-cli-build/server/app/api/cli-tools/copilot-settings/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/cowork-mcp-registry/route.js +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/cowork-mcp-tools/route.js +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 +3 -3
- 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/hermes-settings/route.js +2 -2
- 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/kilo-settings/route.js +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/opencode-settings/route.js +2 -2
- 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/dashboard/prompt-logs/[id]/route.js +1 -1
- package/app/.next-cli-build/server/app/api/dashboard/prompt-logs/[id]/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/dashboard/prompt-logs/route.js +1 -1
- package/app/.next-cli-build/server/app/api/dashboard/prompt-logs/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/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/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/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/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/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/ollama-model-memory/route.js +1 -1
- package/app/.next-cli-build/server/app/api/ollama-nodes/[id]/install/route.js +170 -46
- package/app/.next-cli-build/server/app/api/ollama-nodes/[id]/route.js +1 -1
- package/app/.next-cli-build/server/app/api/ollama-nodes/[id]/status/route.js +1 -1
- package/app/.next-cli-build/server/app/api/ollama-nodes/route.js +1 -1
- package/app/.next-cli-build/server/app/api/ollama-routing-targets/route.js +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/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/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/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/proxy-pools/[id]/route.js +1 -1
- package/app/.next-cli-build/server/app/api/proxy-pools/[id]/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/proxy-pools/[id]/test/route.js +1 -1
- package/app/.next-cli-build/server/app/api/proxy-pools/[id]/test/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/proxy-pools/cloudflare-deploy/route.js +1 -1
- package/app/.next-cli-build/server/app/api/proxy-pools/cloudflare-deploy/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/proxy-pools/deno-deploy/route.js +1 -1
- package/app/.next-cli-build/server/app/api/proxy-pools/deno-deploy/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/proxy-pools/route.js +1 -1
- package/app/.next-cli-build/server/app/api/proxy-pools/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/proxy-pools/vercel-deploy/route.js +1 -1
- package/app/.next-cli-build/server/app/api/proxy-pools/vercel-deploy/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 +1 -1
- package/app/.next-cli-build/server/app/api/settings/require-login/route.js +1 -1
- package/app/.next-cli-build/server/app/api/settings/require-login/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/translator/console-logs/route.js +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/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/tunnel/disable/route.js +1 -1
- package/app/.next-cli-build/server/app/api/tunnel/disable/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/tunnel/enable/route.js +1 -1
- package/app/.next-cli-build/server/app/api/tunnel/enable/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/tunnel/status/route.js +1 -1
- package/app/.next-cli-build/server/app/api/tunnel/status/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/tunnel/tailscale-check/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/tunnel/tailscale-disable/route.js +1 -1
- package/app/.next-cli-build/server/app/api/tunnel/tailscale-disable/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/tunnel/tailscale-enable/route.js +1 -1
- package/app/.next-cli-build/server/app/api/tunnel/tailscale-enable/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/tunnel/tailscale-install/route.js +2 -2
- package/app/.next-cli-build/server/app/api/tunnel/tailscale-install/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/tunnel/tailscale-login/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/tunnel/tailscale-start-daemon/route.js +2 -2
- package/app/.next-cli-build/server/app/api/tunnel/tailscale-start-daemon/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/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 +1 -1
- 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/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/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/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/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/version/route.js +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/api/virtual-combos/[id]/route.js +1 -1
- package/app/.next-cli-build/server/app/api/virtual-combos/[id]/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/virtual-combos/route.js +1 -1
- package/app/.next-cli-build/server/app/api/virtual-combos/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_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/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/callback.segments/_index.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 +1 -1
- package/app/.next-cli-build/server/app/callback.segments/callback.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/basic-chat.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/basic-chat.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard/basic-chat/__PAGE__.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard/basic-chat.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_index.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/cli-tools.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/cli-tools.rsc +7 -7
- package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard/cli-tools/__PAGE__.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard/cli-tools.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_full.segment.rsc +7 -7
- package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_index.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/combos.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/combos.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard/combos/__PAGE__.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard/combos.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/combos.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/combos.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/combos.segments/_index.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/dashboard/combos.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/endpoint.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/endpoint.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard/endpoint/__PAGE__.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard/endpoint.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/endpoint.segments/_full.segment.rsc +8 -8
- package/app/.next-cli-build/server/app/dashboard/endpoint.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/endpoint.segments/_index.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/dashboard/endpoint.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/media-providers/web.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/media-providers/web.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers/web/__PAGE__.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers/web.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_index.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/mitm.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/mitm.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard/mitm/__PAGE__.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard/mitm.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/mitm.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/mitm.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/mitm.segments/_index.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/dashboard/mitm.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/ollama-nodes.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/ollama-nodes.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/ollama-nodes.segments/!KGRhc2hib2FyZCk/dashboard/ollama-nodes/__PAGE__.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/ollama-nodes.segments/!KGRhc2hib2FyZCk/dashboard/ollama-nodes.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/ollama-nodes.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/ollama-nodes.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/ollama-nodes.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/ollama-nodes.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/ollama-nodes.segments/_index.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/dashboard/ollama-nodes.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/profile.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/profile.rsc +5 -5
- package/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard/profile/__PAGE__.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard/profile.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/profile.segments/_full.segment.rsc +5 -5
- package/app/.next-cli-build/server/app/dashboard/profile.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/profile.segments/_index.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/dashboard/profile.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/prompt-logs.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/prompt-logs.rsc +5 -5
- package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/!KGRhc2hib2FyZCk/dashboard/prompt-logs/__PAGE__.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/!KGRhc2hib2FyZCk/dashboard/prompt-logs.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/_full.segment.rsc +5 -5
- package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/_index.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/provider-health.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/provider-health.rsc +5 -5
- package/app/.next-cli-build/server/app/dashboard/provider-health.segments/!KGRhc2hib2FyZCk/dashboard/provider-health/__PAGE__.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/provider-health.segments/!KGRhc2hib2FyZCk/dashboard/provider-health.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/provider-health.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/provider-health.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/provider-health.segments/_full.segment.rsc +5 -5
- package/app/.next-cli-build/server/app/dashboard/provider-health.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/provider-health.segments/_index.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/dashboard/provider-health.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/providers/new.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/providers/new.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers/new/__PAGE__.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers/new.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/providers/new.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/providers/new.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/providers/new.segments/_index.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/dashboard/providers/new.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/providers.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/providers.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard/providers/__PAGE__.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard/providers.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/providers.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/providers.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/providers.segments/_index.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/dashboard/providers.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/proxy-pools.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/proxy-pools.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard/proxy-pools/__PAGE__.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard/proxy-pools.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_index.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/quota.html +2 -2
- package/app/.next-cli-build/server/app/dashboard/quota.rsc +7 -7
- package/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard/quota/__PAGE__.segment.rsc +3 -3
- package/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard/quota.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/quota.segments/_full.segment.rsc +7 -7
- package/app/.next-cli-build/server/app/dashboard/quota.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/quota.segments/_index.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/dashboard/quota.segments/_tree.segment.rsc +2 -2
- 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_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/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_index.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 +1 -1
- package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/skills.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/skills.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/skills.segments/!KGRhc2hib2FyZCk/dashboard/skills/__PAGE__.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/skills.segments/!KGRhc2hib2FyZCk/dashboard/skills.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/skills.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/skills.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/skills.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/skills.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/skills.segments/_index.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/dashboard/skills.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/translator.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/translator.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard/translator/__PAGE__.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard/translator.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/translator.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/translator.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/translator.segments/_index.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/dashboard/translator.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/usage.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/usage.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard/usage/__PAGE__.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard/usage.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/usage.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/usage.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/usage.segments/_index.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/dashboard/usage.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/virtual-combos.html +2 -2
- package/app/.next-cli-build/server/app/dashboard/virtual-combos.rsc +5 -5
- package/app/.next-cli-build/server/app/dashboard/virtual-combos.segments/!KGRhc2hib2FyZCk/dashboard/virtual-combos/__PAGE__.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/virtual-combos.segments/!KGRhc2hib2FyZCk/dashboard/virtual-combos.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/virtual-combos.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/virtual-combos.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard/virtual-combos.segments/_full.segment.rsc +5 -5
- package/app/.next-cli-build/server/app/dashboard/virtual-combos.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/virtual-combos.segments/_index.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/dashboard/virtual-combos.segments/_tree.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard.html +1 -1
- package/app/.next-cli-build/server/app/dashboard.rsc +7 -7
- package/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk/dashboard/__PAGE__.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next-cli-build/server/app/dashboard.segments/_full.segment.rsc +7 -7
- package/app/.next-cli-build/server/app/dashboard.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard.segments/_index.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/dashboard.segments/_tree.segment.rsc +2 -2
- 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 +1 -1
- package/app/.next-cli-build/server/app/index.segments/_full.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/index.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/index.segments/_index.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 +2 -2
- 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 +5 -5
- package/app/.next-cli-build/server/app/landing.segments/_full.segment.rsc +5 -5
- package/app/.next-cli-build/server/app/landing.segments/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/landing.segments/_index.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 +2 -2
- package/app/.next-cli-build/server/app/landing.segments/landing.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/login/page.js +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/_head.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/login.segments/_index.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 +1 -1
- package/app/.next-cli-build/server/app/login.segments/login.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/page.js +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 +5 -5
- package/app/.next-cli-build/server/chunks/2769.js +1 -1
- package/app/.next-cli-build/server/chunks/3110.js +1 -1
- package/app/.next-cli-build/server/chunks/4746.js +1 -1
- package/app/.next-cli-build/server/chunks/7153.js +1 -1
- package/app/.next-cli-build/server/chunks/7197.js +1 -1
- package/app/.next-cli-build/server/chunks/7774.js +8 -8
- package/app/.next-cli-build/server/chunks/7965.js +1 -1
- package/app/.next-cli-build/server/chunks/8491.js +1 -1
- package/app/.next-cli-build/server/chunks/8520.js +1 -1
- package/app/.next-cli-build/server/chunks/8895.js +1 -1
- package/app/.next-cli-build/server/chunks/9526.js +1 -1
- package/app/.next-cli-build/server/middleware-build-manifest.js +1 -1
- package/app/.next-cli-build/server/middleware.js +1 -1
- 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-8d63c226121155a8.js → 1321-5ef553cf7914ae11.js} +1 -1
- package/app/.next-cli-build/static/chunks/app/landing/{page-70884f02f4f66d0e.js → page-7d550a4fdc74c753.js} +1 -1
- package/app/.next-cli-build/static/css/{b301b62b8274cce1.css → 0f03023a765dc337.css} +1 -1
- package/app/.next-cli-build/static/media/material-symbols-outlined.50fdf095.woff2 +0 -0
- package/app/cli/.build-home/AppData/Roaming/bluerouter/db/data.sqlite-shm +0 -0
- package/app/cli/.build-home/AppData/Roaming/bluerouter/db/data.sqlite-wal +0 -0
- package/app/cli/.build-home/AppData/Roaming/bluerouter/jwt-secret +1 -1
- package/app/cli/.build-home/AppData/Roaming/bluerouter/machine-id +1 -1
- package/app/cli/.build-home/AppData/Roaming/nextjs-nodejs/Config/config.json +3 -3
- package/app/package.json +4 -4
- package/app/public/favicon.svg +58 -58
- package/app/public/i18n/literals/ar.json +194 -194
- package/app/public/i18n/literals/bn.json +194 -194
- package/app/public/i18n/literals/cs.json +194 -194
- package/app/public/i18n/literals/da.json +194 -194
- package/app/public/i18n/literals/de.json +194 -194
- package/app/public/i18n/literals/el.json +194 -194
- package/app/public/i18n/literals/es.json +194 -194
- package/app/public/i18n/literals/fi.json +194 -194
- package/app/public/i18n/literals/fr.json +194 -194
- package/app/public/i18n/literals/he.json +194 -194
- package/app/public/i18n/literals/hi.json +194 -194
- package/app/public/i18n/literals/hu.json +194 -194
- package/app/public/i18n/literals/id.json +194 -194
- package/app/public/i18n/literals/it.json +194 -194
- package/app/public/i18n/literals/ja.json +194 -194
- package/app/public/i18n/literals/ko.json +194 -194
- package/app/public/i18n/literals/nl.json +194 -194
- package/app/public/i18n/literals/no.json +194 -194
- package/app/public/i18n/literals/pl.json +194 -194
- package/app/public/i18n/literals/pt-BR.json +194 -194
- package/app/public/i18n/literals/pt-PT.json +194 -194
- package/app/public/i18n/literals/ro.json +194 -194
- package/app/public/i18n/literals/ru.json +194 -194
- package/app/public/i18n/literals/sv.json +194 -194
- package/app/public/i18n/literals/th.json +194 -194
- package/app/public/i18n/literals/tl.json +194 -194
- package/app/public/i18n/literals/tr.json +194 -194
- package/app/public/i18n/literals/uk.json +194 -194
- package/app/public/i18n/literals/ur.json +194 -194
- package/app/public/i18n/literals/vi.json +194 -194
- package/app/public/i18n/literals/zh-CN.json +768 -768
- package/app/public/i18n/literals/zh-TW.json +194 -194
- package/app/server.js +1 -1
- package/app/src/lib/updater/updater.js +235 -235
- package/hooks/postinstall.js +22 -22
- package/hooks/sqliteRuntime.js +139 -139
- package/hooks/trayRuntime.js +107 -107
- package/package.json +3 -1
- package/src/cli/api/client.js +547 -547
- package/src/cli/menus/cliTools.js +618 -618
- package/src/cli/menus/providers.js +10 -10
- package/src/cli/menus/settings.js +207 -207
- package/src/cli/terminalUI.js +121 -121
- package/src/cli/tray/autostart.js +306 -306
- package/src/cli/tray/tray.js +322 -322
- package/app/.next-cli-build/static/media/material-symbols-outlined.acf6198a.woff2 +0 -0
- package/app/cli/.build-home/AppData/Roaming/9router/db/backups/upgrade-1.0.18-to-1.0.19-1.0.19-20260526-095516/data.sqlite +0 -0
- package/app/cli/.build-home/AppData/Roaming/9router/db/backups/upgrade-1.0.19-to-1.0.20-1.0.20-20260526-095953/data.sqlite +0 -0
- package/app/cli/.build-home/AppData/Roaming/9router/db/backups/upgrade-1.0.20-to-1.0.21-1.0.21-20260526-100915/data.sqlite +0 -0
- package/app/cli/.build-home/AppData/Roaming/9router/db/backups/upgrade-1.0.21-to-1.0.22-1.0.22-20260526-102212/data.sqlite +0 -0
- package/app/cli/.build-home/AppData/Roaming/9router/db/data.sqlite +0 -0
- package/app/cli/.build-home/AppData/Roaming/9router/db/data.sqlite-shm +0 -0
- package/app/cli/.build-home/AppData/Roaming/9router/db/data.sqlite-wal +0 -0
- package/app/cli/.build-home/AppData/Roaming/9router/jwt-secret +0 -1
- package/app/cli/.build-home/AppData/Roaming/9router/machine-id +0 -1
- package/app/cli/.build-home/AppData/Roaming/bluerouter/db/backups/upgrade-1.0.46-to-1.0.47-1.0.47-20260526-224538/data.sqlite +0 -0
- package/app/cli/.build-home/AppData/Roaming/bluerouter/db/backups/upgrade-1.0.47-to-1.0.48-1.0.48-20260526-232153/data.sqlite +0 -0
- package/app/cli/.build-home/AppData/Roaming/bluerouter/db/backups/upgrade-1.0.48-to-1.0.49-1.0.49-20260526-233719/data.sqlite +0 -0
- package/app/cli/.build-home/AppData/Roaming/bluerouter/db/backups/upgrade-1.0.49-to-1.0.50-1.0.50-20260526-234400/data.sqlite +0 -0
- package/app/cli/.build-home/AppData/Roaming/bluerouter/db/backups/upgrade-1.0.50-to-1.0.51-1.0.51-20260526-235526/data.sqlite +0 -0
- /package/app/.next-cli-build/static/{JCrst1bYxD23RuorShv5s → QSbdGxh8toy2LcHGBDqR0}/_buildManifest.js +0 -0
- /package/app/.next-cli-build/static/{JCrst1bYxD23RuorShv5s → QSbdGxh8toy2LcHGBDqR0}/_ssgManifest.js +0 -0
- /package/app/cli/.build-home/AppData/Roaming/{9router/db/backups/upgrade-1.0.17-to-1.0.18-1.0.18-20260526-095022 → bluerouter/db/backups/upgrade-1.0.52-to-1.0.53-1.0.53-20260527-171653}/data.sqlite +0 -0
|
@@ -1,618 +1,618 @@
|
|
|
1
|
-
const api = require("../api/client");
|
|
2
|
-
const { pause, confirm } = require("../utils/input");
|
|
3
|
-
const { showStatus } = require("../utils/display");
|
|
4
|
-
const { selectModelFromList } = require("../utils/modelSelector");
|
|
5
|
-
const { showMenuWithBack } = require("../utils/menuHelper");
|
|
6
|
-
const { getEndpoint } = require("../utils/endpoint");
|
|
7
|
-
|
|
8
|
-
const COLORS = {
|
|
9
|
-
reset: "\x1b[0m",
|
|
10
|
-
green: "\x1b[32m",
|
|
11
|
-
red: "\x1b[31m",
|
|
12
|
-
dim: "\x1b[2m",
|
|
13
|
-
cyan: "\x1b[36m"
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
// Claude model types with defaults (matching Web UI)
|
|
17
|
-
const CLAUDE_MODEL_TYPES = [
|
|
18
|
-
{ id: "sonnet", name: "Sonnet", envKey: "ANTHROPIC_DEFAULT_SONNET_MODEL", defaultValue: "cc/claude-sonnet-4-5-20250929" },
|
|
19
|
-
{ id: "opus", name: "Opus", envKey: "ANTHROPIC_DEFAULT_OPUS_MODEL", defaultValue: "cc/claude-opus-4-5-20251101" },
|
|
20
|
-
{ id: "haiku", name: "Haiku", envKey: "ANTHROPIC_DEFAULT_HAIKU_MODEL", defaultValue: "cc/claude-haiku-4-5-20251001" },
|
|
21
|
-
];
|
|
22
|
-
|
|
23
|
-
// ─── Shared helpers ───────────────────────────────────────────────────────────
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Get first available API key from server
|
|
27
|
-
* @returns {Promise<string|null>}
|
|
28
|
-
*/
|
|
29
|
-
async function getFirstApiKey() {
|
|
30
|
-
const result = await api.getApiKeys();
|
|
31
|
-
const keys = result.success ? (result.data.keys || []) : [];
|
|
32
|
-
return keys.length > 0 ? keys[0].key : null;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// ─── Claude Code ──────────────────────────────────────────────────────────────
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Build header showing current Claude config status
|
|
39
|
-
* @returns {Promise<string>}
|
|
40
|
-
*/
|
|
41
|
-
async function buildClaudeHeader() {
|
|
42
|
-
const result = await api.getCliToolSettings("claude");
|
|
43
|
-
if (!result.success) return ` ${COLORS.red}Failed to load settings${COLORS.reset}`;
|
|
44
|
-
|
|
45
|
-
const settings = result.data.settings;
|
|
46
|
-
const currentUrl = settings?.env?.ANTHROPIC_BASE_URL;
|
|
47
|
-
const currentKey = settings?.env?.ANTHROPIC_AUTH_TOKEN;
|
|
48
|
-
const lines = [];
|
|
49
|
-
|
|
50
|
-
if (currentUrl) {
|
|
51
|
-
lines.push(`Status: ${COLORS.green}✓ Configured${COLORS.reset}`);
|
|
52
|
-
lines.push(`Endpoint: ${COLORS.cyan}${currentUrl}${COLORS.reset}`);
|
|
53
|
-
if (currentKey) {
|
|
54
|
-
lines.push(`API Key: ${COLORS.dim}${currentKey.substring(0, 10)}...${COLORS.reset}`);
|
|
55
|
-
}
|
|
56
|
-
} else {
|
|
57
|
-
lines.push(`Status: ${COLORS.red}✗ Not configured${COLORS.reset}`);
|
|
58
|
-
lines.push(`${COLORS.dim}Run "Quick Setup" to configure${COLORS.reset}`);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
return lines.join("\n");
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Get current Claude model from settings
|
|
66
|
-
* @param {string} envKey
|
|
67
|
-
* @returns {Promise<string>}
|
|
68
|
-
*/
|
|
69
|
-
async function getClaudeModel(envKey) {
|
|
70
|
-
const result = await api.getCliToolSettings("claude");
|
|
71
|
-
return result.success ? (result.data.settings?.env?.[envKey] || "Not set") : "Not set";
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Quick setup for Claude Code — sets endpoint, key, and all default models
|
|
76
|
-
* @param {number} port
|
|
77
|
-
*/
|
|
78
|
-
async function claudeQuickSetup(port) {
|
|
79
|
-
const { endpoint } = await getEndpoint(port);
|
|
80
|
-
const apiKey = await getFirstApiKey();
|
|
81
|
-
|
|
82
|
-
if (!apiKey) {
|
|
83
|
-
showStatus("No API keys found. Create one in API Keys menu first.", "error");
|
|
84
|
-
await pause();
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const env = { ANTHROPIC_BASE_URL: endpoint, ANTHROPIC_AUTH_TOKEN: apiKey, API_TIMEOUT_MS: "600000" };
|
|
89
|
-
CLAUDE_MODEL_TYPES.forEach(t => { env[t.envKey] = t.defaultValue; });
|
|
90
|
-
|
|
91
|
-
const result = await api.applyCliToolSettings("claude", { env });
|
|
92
|
-
showStatus(result.success ? "Quick Setup completed!" : `Failed: ${result.error}`, result.success ? "success" : "error");
|
|
93
|
-
await pause();
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Select and save a specific Claude model type
|
|
98
|
-
* @param {Object} modelType
|
|
99
|
-
* @param {number} port
|
|
100
|
-
*/
|
|
101
|
-
async function claudeSelectModel(modelType, port) {
|
|
102
|
-
const current = await getClaudeModel(modelType.envKey);
|
|
103
|
-
const selected = await selectModelFromList(`Select ${modelType.name} Model`, current, { excludeCombos: true });
|
|
104
|
-
if (!selected) return;
|
|
105
|
-
|
|
106
|
-
const env = { [modelType.envKey]: selected };
|
|
107
|
-
|
|
108
|
-
// Also set base URL if not configured yet
|
|
109
|
-
const settingsResult = await api.getCliToolSettings("claude");
|
|
110
|
-
if (!settingsResult.data?.settings?.env?.ANTHROPIC_BASE_URL) {
|
|
111
|
-
const { endpoint } = await getEndpoint(port);
|
|
112
|
-
const apiKey = await getFirstApiKey();
|
|
113
|
-
env.ANTHROPIC_BASE_URL = endpoint;
|
|
114
|
-
env.API_TIMEOUT_MS = "600000";
|
|
115
|
-
if (apiKey) env.ANTHROPIC_AUTH_TOKEN = apiKey;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
const result = await api.applyCliToolSettings("claude", { env });
|
|
119
|
-
showStatus(result.success ? `${modelType.name} → ${selected} saved!` : `Failed: ${result.error}`, result.success ? "success" : "error");
|
|
120
|
-
await pause();
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Reset Claude Code settings
|
|
125
|
-
*/
|
|
126
|
-
async function claudeReset() {
|
|
127
|
-
const result = await api.resetCliToolSettings("claude");
|
|
128
|
-
showStatus(result.success ? "Settings reset successfully!" : `Failed: ${result.error}`, result.success ? "success" : "error");
|
|
129
|
-
await pause();
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Claude Code submenu
|
|
134
|
-
* @param {number} port
|
|
135
|
-
* @param {Array<string>} breadcrumb
|
|
136
|
-
*/
|
|
137
|
-
async function showClaudeCodeMenu(port, breadcrumb = []) {
|
|
138
|
-
await showMenuWithBack({
|
|
139
|
-
title: "🔧 Claude Code Settings",
|
|
140
|
-
breadcrumb,
|
|
141
|
-
headerContent: buildClaudeHeader,
|
|
142
|
-
refresh: async () => ({
|
|
143
|
-
sonnet: await getClaudeModel("ANTHROPIC_DEFAULT_SONNET_MODEL"),
|
|
144
|
-
opus: await getClaudeModel("ANTHROPIC_DEFAULT_OPUS_MODEL"),
|
|
145
|
-
haiku: await getClaudeModel("ANTHROPIC_DEFAULT_HAIKU_MODEL"),
|
|
146
|
-
}),
|
|
147
|
-
items: [
|
|
148
|
-
{
|
|
149
|
-
label: "⚡ Quick Setup (recommended)",
|
|
150
|
-
action: async () => { await claudeQuickSetup(port); return true; }
|
|
151
|
-
},
|
|
152
|
-
{
|
|
153
|
-
label: (d) => `Sonnet → ${d.sonnet}`,
|
|
154
|
-
action: async () => { await claudeSelectModel(CLAUDE_MODEL_TYPES[0], port); return true; }
|
|
155
|
-
},
|
|
156
|
-
{
|
|
157
|
-
label: (d) => `Opus → ${d.opus}`,
|
|
158
|
-
action: async () => { await claudeSelectModel(CLAUDE_MODEL_TYPES[1], port); return true; }
|
|
159
|
-
},
|
|
160
|
-
{
|
|
161
|
-
label: (d) => `Haiku → ${d.haiku}`,
|
|
162
|
-
action: async () => { await claudeSelectModel(CLAUDE_MODEL_TYPES[2], port); return true; }
|
|
163
|
-
},
|
|
164
|
-
{
|
|
165
|
-
label: "Reset to Default",
|
|
166
|
-
action: async () => { await claudeReset(); return true; }
|
|
167
|
-
}
|
|
168
|
-
]
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
// ─── Codex CLI ────────────────────────────────────────────────────────────────
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* Build header showing current Codex config status
|
|
176
|
-
* @returns {Promise<string>}
|
|
177
|
-
*/
|
|
178
|
-
async function buildCodexHeader() {
|
|
179
|
-
const result = await api.getCliToolSettings("codex");
|
|
180
|
-
if (!result.success) return ` ${COLORS.red}Failed to load settings${COLORS.reset}`;
|
|
181
|
-
|
|
182
|
-
const { installed, hasBluerouter, config } = result.data;
|
|
183
|
-
if (!installed) return `Status: ${COLORS.red}✗ Codex CLI not installed${COLORS.reset}`;
|
|
184
|
-
|
|
185
|
-
if (!hasBluerouter) {
|
|
186
|
-
return [
|
|
187
|
-
`Status: ${COLORS.red}✗ Not configured${COLORS.reset}`,
|
|
188
|
-
`${COLORS.dim}Run "Quick Setup" to configure${COLORS.reset}`
|
|
189
|
-
].join("\n");
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// Parse base_url and model from raw TOML string
|
|
193
|
-
const baseUrlMatch = config && config.match(/base_url\s*=\s*"([^"]+)"/);
|
|
194
|
-
const modelMatch = config && config.match(/^model\s*=\s*"([^"]+)"/m);
|
|
195
|
-
const baseUrl = baseUrlMatch ? baseUrlMatch[1] : "";
|
|
196
|
-
const model = modelMatch ? modelMatch[1] : "";
|
|
197
|
-
|
|
198
|
-
const lines = [`Status: ${COLORS.green}✓ Configured${COLORS.reset}`];
|
|
199
|
-
if (baseUrl) lines.push(`Endpoint: ${COLORS.cyan}${baseUrl}${COLORS.reset}`);
|
|
200
|
-
if (model) lines.push(`Model: ${COLORS.dim}${model}${COLORS.reset}`);
|
|
201
|
-
return lines.join("\n");
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
/**
|
|
205
|
-
* Quick setup for Codex CLI
|
|
206
|
-
* @param {number} port
|
|
207
|
-
*/
|
|
208
|
-
async function codexQuickSetup(port) {
|
|
209
|
-
const { endpoint } = await getEndpoint(port);
|
|
210
|
-
const apiKey = await getFirstApiKey();
|
|
211
|
-
|
|
212
|
-
if (!apiKey) {
|
|
213
|
-
showStatus("No API keys found. Create one in API Keys menu first.", "error");
|
|
214
|
-
await pause();
|
|
215
|
-
return;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
// Get model selection
|
|
219
|
-
const model = await selectModelFromList("Select Codex Model", "cx/claude-sonnet-4-5-20250929", { excludeCombos: true });
|
|
220
|
-
if (!model) return;
|
|
221
|
-
|
|
222
|
-
const result = await api.applyCliToolSettings("codex", { baseUrl: endpoint, apiKey, model });
|
|
223
|
-
showStatus(result.success ? "Codex setup completed!" : `Failed: ${result.error}`, result.success ? "success" : "error");
|
|
224
|
-
await pause();
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
/**
|
|
228
|
-
* Reset Codex CLI settings
|
|
229
|
-
*/
|
|
230
|
-
async function codexReset() {
|
|
231
|
-
const result = await api.resetCliToolSettings("codex");
|
|
232
|
-
showStatus(result.success ? "Codex settings reset!" : `Failed: ${result.error}`, result.success ? "success" : "error");
|
|
233
|
-
await pause();
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
/**
|
|
237
|
-
* Codex CLI submenu
|
|
238
|
-
* @param {number} port
|
|
239
|
-
* @param {Array<string>} breadcrumb
|
|
240
|
-
*/
|
|
241
|
-
async function showCodexMenu(port, breadcrumb = []) {
|
|
242
|
-
await showMenuWithBack({
|
|
243
|
-
title: "🤖 Codex CLI Settings",
|
|
244
|
-
breadcrumb,
|
|
245
|
-
headerContent: buildCodexHeader,
|
|
246
|
-
refresh: async () => ({}),
|
|
247
|
-
items: [
|
|
248
|
-
{
|
|
249
|
-
label: "⚡ Quick Setup",
|
|
250
|
-
action: async () => { await codexQuickSetup(port); return true; }
|
|
251
|
-
},
|
|
252
|
-
{
|
|
253
|
-
label: "Reset to Default",
|
|
254
|
-
action: async () => { await codexReset(); return true; }
|
|
255
|
-
}
|
|
256
|
-
]
|
|
257
|
-
});
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
// ─── Factory Droid ────────────────────────────────────────────────────────────
|
|
261
|
-
|
|
262
|
-
/**
|
|
263
|
-
* Build header showing current Droid config status
|
|
264
|
-
* @returns {Promise<string>}
|
|
265
|
-
*/
|
|
266
|
-
async function buildDroidHeader() {
|
|
267
|
-
const result = await api.getCliToolSettings("droid");
|
|
268
|
-
if (!result.success) return ` ${COLORS.red}Failed to load settings${COLORS.reset}`;
|
|
269
|
-
|
|
270
|
-
const { installed, hasBluerouter, settings } = result.data;
|
|
271
|
-
if (!installed) return `Status: ${COLORS.red}✗ Factory Droid not installed${COLORS.reset}`;
|
|
272
|
-
|
|
273
|
-
if (!hasBluerouter) {
|
|
274
|
-
return [
|
|
275
|
-
`Status: ${COLORS.red}✗ Not configured${COLORS.reset}`,
|
|
276
|
-
`${COLORS.dim}Run "Quick Setup" to configure${COLORS.reset}`
|
|
277
|
-
].join("\n");
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
// Extract Bluerouter custom model config
|
|
281
|
-
const custom = settings?.customModels?.find(m => m.id === "custom:Bluerouter-0");
|
|
282
|
-
const lines = [`Status: ${COLORS.green}✓ Configured${COLORS.reset}`];
|
|
283
|
-
if (custom?.baseUrl) lines.push(`Endpoint: ${COLORS.cyan}${custom.baseUrl}${COLORS.reset}`);
|
|
284
|
-
if (custom?.model) lines.push(`Model: ${COLORS.dim}${custom.model}${COLORS.reset}`);
|
|
285
|
-
return lines.join("\n");
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
/**
|
|
289
|
-
* Quick setup for Factory Droid
|
|
290
|
-
* @param {number} port
|
|
291
|
-
*/
|
|
292
|
-
async function droidQuickSetup(port) {
|
|
293
|
-
const { endpoint } = await getEndpoint(port);
|
|
294
|
-
const apiKey = await getFirstApiKey();
|
|
295
|
-
|
|
296
|
-
if (!apiKey) {
|
|
297
|
-
showStatus("No API keys found. Create one in API Keys menu first.", "error");
|
|
298
|
-
await pause();
|
|
299
|
-
return;
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
const model = await selectModelFromList("Select Droid Model", "cc/claude-sonnet-4-5-20250929", { excludeCombos: true });
|
|
303
|
-
if (!model) return;
|
|
304
|
-
|
|
305
|
-
const result = await api.applyCliToolSettings("droid", { baseUrl: endpoint, apiKey, model });
|
|
306
|
-
showStatus(result.success ? "Factory Droid setup completed!" : `Failed: ${result.error}`, result.success ? "success" : "error");
|
|
307
|
-
await pause();
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
/**
|
|
311
|
-
* Reset Factory Droid settings
|
|
312
|
-
*/
|
|
313
|
-
async function droidReset() {
|
|
314
|
-
const result = await api.resetCliToolSettings("droid");
|
|
315
|
-
showStatus(result.success ? "Factory Droid settings reset!" : `Failed: ${result.error}`, result.success ? "success" : "error");
|
|
316
|
-
await pause();
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
/**
|
|
320
|
-
* Factory Droid submenu
|
|
321
|
-
* @param {number} port
|
|
322
|
-
* @param {Array<string>} breadcrumb
|
|
323
|
-
*/
|
|
324
|
-
async function showDroidMenu(port, breadcrumb = []) {
|
|
325
|
-
await showMenuWithBack({
|
|
326
|
-
title: "🤖 Factory Droid Settings",
|
|
327
|
-
breadcrumb,
|
|
328
|
-
headerContent: buildDroidHeader,
|
|
329
|
-
refresh: async () => ({}),
|
|
330
|
-
items: [
|
|
331
|
-
{
|
|
332
|
-
label: "⚡ Quick Setup",
|
|
333
|
-
action: async () => { await droidQuickSetup(port); return true; }
|
|
334
|
-
},
|
|
335
|
-
{
|
|
336
|
-
label: "Reset to Default",
|
|
337
|
-
action: async () => { await droidReset(); return true; }
|
|
338
|
-
}
|
|
339
|
-
]
|
|
340
|
-
});
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
// ─── Open Claw ────────────────────────────────────────────────────────────────
|
|
344
|
-
|
|
345
|
-
/**
|
|
346
|
-
* Build header showing current OpenClaw config status
|
|
347
|
-
* @returns {Promise<string>}
|
|
348
|
-
*/
|
|
349
|
-
async function buildOpenClawHeader() {
|
|
350
|
-
const result = await api.getCliToolSettings("openclaw");
|
|
351
|
-
if (!result.success) return ` ${COLORS.red}Failed to load settings${COLORS.reset}`;
|
|
352
|
-
|
|
353
|
-
const { installed, hasBluerouter, settings } = result.data;
|
|
354
|
-
if (!installed) return `Status: ${COLORS.red}✗ Open Claw not installed${COLORS.reset}`;
|
|
355
|
-
|
|
356
|
-
if (!hasBluerouter) {
|
|
357
|
-
return [
|
|
358
|
-
`Status: ${COLORS.red}✗ Not configured${COLORS.reset}`,
|
|
359
|
-
`${COLORS.dim}Run "Quick Setup" to configure${COLORS.reset}`
|
|
360
|
-
].join("\n");
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
// Extract Bluerouter provider config
|
|
364
|
-
const provider = settings?.models?.providers?.["bluerouter"];
|
|
365
|
-
const primary = settings?.agents?.defaults?.model?.primary || "";
|
|
366
|
-
const model = primary.startsWith("bluerouter/") ? primary.replace("bluerouter/", "") : (provider?.models?.[0]?.id || "");
|
|
367
|
-
const lines = [`Status: ${COLORS.green}✓ Configured${COLORS.reset}`];
|
|
368
|
-
if (provider?.baseUrl) lines.push(`Endpoint: ${COLORS.cyan}${provider.baseUrl}${COLORS.reset}`);
|
|
369
|
-
if (model) lines.push(`Model: ${COLORS.dim}${model}${COLORS.reset}`);
|
|
370
|
-
return lines.join("\n");
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
/**
|
|
374
|
-
* Quick setup for Open Claw
|
|
375
|
-
* @param {number} port
|
|
376
|
-
*/
|
|
377
|
-
async function openClawQuickSetup(port) {
|
|
378
|
-
const { endpoint } = await getEndpoint(port);
|
|
379
|
-
const apiKey = await getFirstApiKey();
|
|
380
|
-
|
|
381
|
-
if (!apiKey) {
|
|
382
|
-
showStatus("No API keys found. Create one in API Keys menu first.", "error");
|
|
383
|
-
await pause();
|
|
384
|
-
return;
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
const model = await selectModelFromList("Select OpenClaw Model", "cc/claude-sonnet-4-5-20250929", { excludeCombos: true });
|
|
388
|
-
if (!model) return;
|
|
389
|
-
|
|
390
|
-
const result = await api.applyCliToolSettings("openclaw", { baseUrl: endpoint, apiKey, model });
|
|
391
|
-
showStatus(result.success ? "Open Claw setup completed!" : `Failed: ${result.error}`, result.success ? "success" : "error");
|
|
392
|
-
await pause();
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
/**
|
|
396
|
-
* Reset Open Claw settings
|
|
397
|
-
*/
|
|
398
|
-
async function openClawReset() {
|
|
399
|
-
const result = await api.resetCliToolSettings("openclaw");
|
|
400
|
-
showStatus(result.success ? "Open Claw settings reset!" : `Failed: ${result.error}`, result.success ? "success" : "error");
|
|
401
|
-
await pause();
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
/**
|
|
405
|
-
* Open Claw submenu
|
|
406
|
-
* @param {number} port
|
|
407
|
-
* @param {Array<string>} breadcrumb
|
|
408
|
-
*/
|
|
409
|
-
async function showOpenClawMenu(port, breadcrumb = []) {
|
|
410
|
-
await showMenuWithBack({
|
|
411
|
-
title: "🦞 Open Claw Settings",
|
|
412
|
-
breadcrumb,
|
|
413
|
-
headerContent: buildOpenClawHeader,
|
|
414
|
-
refresh: async () => ({}),
|
|
415
|
-
items: [
|
|
416
|
-
{
|
|
417
|
-
label: "⚡ Quick Setup",
|
|
418
|
-
action: async () => { await openClawQuickSetup(port); return true; }
|
|
419
|
-
},
|
|
420
|
-
{
|
|
421
|
-
label: "Reset to Default",
|
|
422
|
-
action: async () => { await openClawReset(); return true; }
|
|
423
|
-
}
|
|
424
|
-
]
|
|
425
|
-
});
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
// ─── OpenCode CLI ─────────────────────────────────────────────────────────────
|
|
429
|
-
|
|
430
|
-
async function buildOpenCodeHeader() {
|
|
431
|
-
const result = await api.getCliToolSettings("opencode");
|
|
432
|
-
if (!result.success) return ` ${COLORS.red}Failed to load settings${COLORS.reset}`;
|
|
433
|
-
|
|
434
|
-
const { installed, hasBluerouter, opencode } = result.data;
|
|
435
|
-
if (!installed) return `Status: ${COLORS.red}✗ OpenCode CLI not installed${COLORS.reset}`;
|
|
436
|
-
|
|
437
|
-
if (!hasBluerouter) {
|
|
438
|
-
return [
|
|
439
|
-
`Status: ${COLORS.red}✗ Not configured${COLORS.reset}`,
|
|
440
|
-
`${COLORS.dim}Run "Quick Setup" to configure${COLORS.reset}`
|
|
441
|
-
].join("\n");
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
const lines = [`Status: ${COLORS.green}✓ Configured${COLORS.reset}`];
|
|
445
|
-
if (opencode?.baseURL) lines.push(`Endpoint: ${COLORS.cyan}${opencode.baseURL}${COLORS.reset}`);
|
|
446
|
-
if (opencode?.activeModel) lines.push(`Active: ${COLORS.dim}${opencode.activeModel}${COLORS.reset}`);
|
|
447
|
-
if (Array.isArray(opencode?.models) && opencode.models.length > 0) {
|
|
448
|
-
lines.push(`Models: ${COLORS.dim}${opencode.models.join(", ")}${COLORS.reset}`);
|
|
449
|
-
}
|
|
450
|
-
return lines.join("\n");
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
async function openCodeQuickSetup(port) {
|
|
454
|
-
const { endpoint } = await getEndpoint(port);
|
|
455
|
-
const apiKey = await getFirstApiKey();
|
|
456
|
-
|
|
457
|
-
if (!apiKey) {
|
|
458
|
-
showStatus("No API keys found. Create one in API Keys menu first.", "error");
|
|
459
|
-
await pause();
|
|
460
|
-
return;
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
// Pick first model (also becomes active model by default)
|
|
464
|
-
const firstModel = await selectModelFromList("Select Active Model (OpenCode)", "", { excludeCombos: true });
|
|
465
|
-
if (!firstModel) return;
|
|
466
|
-
|
|
467
|
-
const models = [firstModel];
|
|
468
|
-
|
|
469
|
-
// Optionally add more models
|
|
470
|
-
while (true) {
|
|
471
|
-
const more = await confirm(`Add another model? (current: ${models.length})`);
|
|
472
|
-
if (!more) break;
|
|
473
|
-
const next = await selectModelFromList(`Add Model #${models.length + 1}`, models.join(", "), { excludeCombos: true });
|
|
474
|
-
if (!next) break;
|
|
475
|
-
if (!models.includes(next)) models.push(next);
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
// Optional subagent model
|
|
479
|
-
let subagentModel = firstModel;
|
|
480
|
-
const wantSubagent = await confirm(`Set a different subagent model? (default: ${firstModel})`);
|
|
481
|
-
if (wantSubagent) {
|
|
482
|
-
const picked = await selectModelFromList("Select Subagent Model", firstModel, { excludeCombos: true });
|
|
483
|
-
if (picked) subagentModel = picked;
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
const result = await api.applyCliToolSettings("opencode", {
|
|
487
|
-
baseUrl: endpoint,
|
|
488
|
-
apiKey,
|
|
489
|
-
models,
|
|
490
|
-
activeModel: firstModel,
|
|
491
|
-
subagentModel,
|
|
492
|
-
});
|
|
493
|
-
showStatus(result.success ? "OpenCode setup completed!" : `Failed: ${result.error}`, result.success ? "success" : "error");
|
|
494
|
-
await pause();
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
async function openCodeReset() {
|
|
498
|
-
const result = await api.resetCliToolSettings("opencode");
|
|
499
|
-
showStatus(result.success ? "OpenCode settings reset!" : `Failed: ${result.error}`, result.success ? "success" : "error");
|
|
500
|
-
await pause();
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
async function showOpenCodeMenu(port, breadcrumb = []) {
|
|
504
|
-
await showMenuWithBack({
|
|
505
|
-
title: "💻 OpenCode CLI Settings",
|
|
506
|
-
breadcrumb,
|
|
507
|
-
headerContent: buildOpenCodeHeader,
|
|
508
|
-
refresh: async () => ({}),
|
|
509
|
-
items: [
|
|
510
|
-
{ label: "⚡ Quick Setup", action: async () => { await openCodeQuickSetup(port); return true; } },
|
|
511
|
-
{ label: "Reset to Default", action: async () => { await openCodeReset(); return true; } }
|
|
512
|
-
]
|
|
513
|
-
});
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
// ─── Hermes Agent ─────────────────────────────────────────────────────────────
|
|
517
|
-
|
|
518
|
-
async function buildHermesHeader() {
|
|
519
|
-
const result = await api.getCliToolSettings("hermes");
|
|
520
|
-
if (!result.success) return ` ${COLORS.red}Failed to load settings${COLORS.reset}`;
|
|
521
|
-
|
|
522
|
-
const { installed, hasBluerouter, settings } = result.data;
|
|
523
|
-
if (!installed) return `Status: ${COLORS.red}✗ Hermes Agent not installed${COLORS.reset}`;
|
|
524
|
-
|
|
525
|
-
if (!hasBluerouter) {
|
|
526
|
-
return [
|
|
527
|
-
`Status: ${COLORS.red}✗ Not configured${COLORS.reset}`,
|
|
528
|
-
`${COLORS.dim}Run "Quick Setup" to configure${COLORS.reset}`
|
|
529
|
-
].join("\n");
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
const model = settings?.model || {};
|
|
533
|
-
const lines = [`Status: ${COLORS.green}✓ Configured${COLORS.reset}`];
|
|
534
|
-
if (model.base_url) lines.push(`Endpoint: ${COLORS.cyan}${model.base_url}${COLORS.reset}`);
|
|
535
|
-
if (model.default) lines.push(`Model: ${COLORS.dim}${model.default}${COLORS.reset}`);
|
|
536
|
-
return lines.join("\n");
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
async function hermesQuickSetup(port) {
|
|
540
|
-
const { endpoint } = await getEndpoint(port);
|
|
541
|
-
const apiKey = await getFirstApiKey();
|
|
542
|
-
|
|
543
|
-
if (!apiKey) {
|
|
544
|
-
showStatus("No API keys found. Create one in API Keys menu first.", "error");
|
|
545
|
-
await pause();
|
|
546
|
-
return;
|
|
547
|
-
}
|
|
548
|
-
|
|
549
|
-
const model = await selectModelFromList("Select Hermes Model", "", { excludeCombos: true });
|
|
550
|
-
if (!model) return;
|
|
551
|
-
|
|
552
|
-
const result = await api.applyCliToolSettings("hermes", { baseUrl: endpoint, apiKey, model });
|
|
553
|
-
showStatus(result.success ? "Hermes setup completed!" : `Failed: ${result.error}`, result.success ? "success" : "error");
|
|
554
|
-
await pause();
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
async function hermesReset() {
|
|
558
|
-
const result = await api.resetCliToolSettings("hermes");
|
|
559
|
-
showStatus(result.success ? "Hermes settings reset!" : `Failed: ${result.error}`, result.success ? "success" : "error");
|
|
560
|
-
await pause();
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
async function showHermesMenu(port, breadcrumb = []) {
|
|
564
|
-
await showMenuWithBack({
|
|
565
|
-
title: "⚡ Hermes Agent Settings",
|
|
566
|
-
breadcrumb,
|
|
567
|
-
headerContent: buildHermesHeader,
|
|
568
|
-
refresh: async () => ({}),
|
|
569
|
-
items: [
|
|
570
|
-
{ label: "⚡ Quick Setup", action: async () => { await hermesQuickSetup(port); return true; } },
|
|
571
|
-
{ label: "Reset to Default", action: async () => { await hermesReset(); return true; } }
|
|
572
|
-
]
|
|
573
|
-
});
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
// ─── Main CLI Tools Menu ──────────────────────────────────────────────────────
|
|
577
|
-
|
|
578
|
-
/**
|
|
579
|
-
* Main CLI Tools menu
|
|
580
|
-
* @param {number} port
|
|
581
|
-
* @param {Array<string>} breadcrumb
|
|
582
|
-
*/
|
|
583
|
-
async function showCliToolsMenu(port, breadcrumb = []) {
|
|
584
|
-
const { endpoint } = await getEndpoint(port);
|
|
585
|
-
await showMenuWithBack({
|
|
586
|
-
title: "🔧 CLI Tools",
|
|
587
|
-
breadcrumb,
|
|
588
|
-
headerContent: `Configure CLI tools to use Bluerouter\nEndpoint: ${endpoint}`,
|
|
589
|
-
items: [
|
|
590
|
-
{
|
|
591
|
-
label: "Claude Code",
|
|
592
|
-
action: async () => { await showClaudeCodeMenu(port, [...breadcrumb, "Claude Code"]); return true; }
|
|
593
|
-
},
|
|
594
|
-
{
|
|
595
|
-
label: "Codex CLI",
|
|
596
|
-
action: async () => { await showCodexMenu(port, [...breadcrumb, "Codex CLI"]); return true; }
|
|
597
|
-
},
|
|
598
|
-
{
|
|
599
|
-
label: "Factory Droid",
|
|
600
|
-
action: async () => { await showDroidMenu(port, [...breadcrumb, "Factory Droid"]); return true; }
|
|
601
|
-
},
|
|
602
|
-
{
|
|
603
|
-
label: "Open Claw",
|
|
604
|
-
action: async () => { await showOpenClawMenu(port, [...breadcrumb, "Open Claw"]); return true; }
|
|
605
|
-
},
|
|
606
|
-
{
|
|
607
|
-
label: "OpenCode",
|
|
608
|
-
action: async () => { await showOpenCodeMenu(port, [...breadcrumb, "OpenCode"]); return true; }
|
|
609
|
-
},
|
|
610
|
-
{
|
|
611
|
-
label: "Hermes",
|
|
612
|
-
action: async () => { await showHermesMenu(port, [...breadcrumb, "Hermes"]); return true; }
|
|
613
|
-
}
|
|
614
|
-
]
|
|
615
|
-
});
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
module.exports = { showCliToolsMenu };
|
|
1
|
+
const api = require("../api/client");
|
|
2
|
+
const { pause, confirm } = require("../utils/input");
|
|
3
|
+
const { showStatus } = require("../utils/display");
|
|
4
|
+
const { selectModelFromList } = require("../utils/modelSelector");
|
|
5
|
+
const { showMenuWithBack } = require("../utils/menuHelper");
|
|
6
|
+
const { getEndpoint } = require("../utils/endpoint");
|
|
7
|
+
|
|
8
|
+
const COLORS = {
|
|
9
|
+
reset: "\x1b[0m",
|
|
10
|
+
green: "\x1b[32m",
|
|
11
|
+
red: "\x1b[31m",
|
|
12
|
+
dim: "\x1b[2m",
|
|
13
|
+
cyan: "\x1b[36m"
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
// Claude model types with defaults (matching Web UI)
|
|
17
|
+
const CLAUDE_MODEL_TYPES = [
|
|
18
|
+
{ id: "sonnet", name: "Sonnet", envKey: "ANTHROPIC_DEFAULT_SONNET_MODEL", defaultValue: "cc/claude-sonnet-4-5-20250929" },
|
|
19
|
+
{ id: "opus", name: "Opus", envKey: "ANTHROPIC_DEFAULT_OPUS_MODEL", defaultValue: "cc/claude-opus-4-5-20251101" },
|
|
20
|
+
{ id: "haiku", name: "Haiku", envKey: "ANTHROPIC_DEFAULT_HAIKU_MODEL", defaultValue: "cc/claude-haiku-4-5-20251001" },
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
// ─── Shared helpers ───────────────────────────────────────────────────────────
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Get first available API key from server
|
|
27
|
+
* @returns {Promise<string|null>}
|
|
28
|
+
*/
|
|
29
|
+
async function getFirstApiKey() {
|
|
30
|
+
const result = await api.getApiKeys();
|
|
31
|
+
const keys = result.success ? (result.data.keys || []) : [];
|
|
32
|
+
return keys.length > 0 ? keys[0].key : null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// ─── Claude Code ──────────────────────────────────────────────────────────────
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Build header showing current Claude config status
|
|
39
|
+
* @returns {Promise<string>}
|
|
40
|
+
*/
|
|
41
|
+
async function buildClaudeHeader() {
|
|
42
|
+
const result = await api.getCliToolSettings("claude");
|
|
43
|
+
if (!result.success) return ` ${COLORS.red}Failed to load settings${COLORS.reset}`;
|
|
44
|
+
|
|
45
|
+
const settings = result.data.settings;
|
|
46
|
+
const currentUrl = settings?.env?.ANTHROPIC_BASE_URL;
|
|
47
|
+
const currentKey = settings?.env?.ANTHROPIC_AUTH_TOKEN;
|
|
48
|
+
const lines = [];
|
|
49
|
+
|
|
50
|
+
if (currentUrl) {
|
|
51
|
+
lines.push(`Status: ${COLORS.green}✓ Configured${COLORS.reset}`);
|
|
52
|
+
lines.push(`Endpoint: ${COLORS.cyan}${currentUrl}${COLORS.reset}`);
|
|
53
|
+
if (currentKey) {
|
|
54
|
+
lines.push(`API Key: ${COLORS.dim}${currentKey.substring(0, 10)}...${COLORS.reset}`);
|
|
55
|
+
}
|
|
56
|
+
} else {
|
|
57
|
+
lines.push(`Status: ${COLORS.red}✗ Not configured${COLORS.reset}`);
|
|
58
|
+
lines.push(`${COLORS.dim}Run "Quick Setup" to configure${COLORS.reset}`);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return lines.join("\n");
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Get current Claude model from settings
|
|
66
|
+
* @param {string} envKey
|
|
67
|
+
* @returns {Promise<string>}
|
|
68
|
+
*/
|
|
69
|
+
async function getClaudeModel(envKey) {
|
|
70
|
+
const result = await api.getCliToolSettings("claude");
|
|
71
|
+
return result.success ? (result.data.settings?.env?.[envKey] || "Not set") : "Not set";
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Quick setup for Claude Code — sets endpoint, key, and all default models
|
|
76
|
+
* @param {number} port
|
|
77
|
+
*/
|
|
78
|
+
async function claudeQuickSetup(port) {
|
|
79
|
+
const { endpoint } = await getEndpoint(port);
|
|
80
|
+
const apiKey = await getFirstApiKey();
|
|
81
|
+
|
|
82
|
+
if (!apiKey) {
|
|
83
|
+
showStatus("No API keys found. Create one in API Keys menu first.", "error");
|
|
84
|
+
await pause();
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const env = { ANTHROPIC_BASE_URL: endpoint, ANTHROPIC_AUTH_TOKEN: apiKey, API_TIMEOUT_MS: "600000" };
|
|
89
|
+
CLAUDE_MODEL_TYPES.forEach(t => { env[t.envKey] = t.defaultValue; });
|
|
90
|
+
|
|
91
|
+
const result = await api.applyCliToolSettings("claude", { env });
|
|
92
|
+
showStatus(result.success ? "Quick Setup completed!" : `Failed: ${result.error}`, result.success ? "success" : "error");
|
|
93
|
+
await pause();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Select and save a specific Claude model type
|
|
98
|
+
* @param {Object} modelType
|
|
99
|
+
* @param {number} port
|
|
100
|
+
*/
|
|
101
|
+
async function claudeSelectModel(modelType, port) {
|
|
102
|
+
const current = await getClaudeModel(modelType.envKey);
|
|
103
|
+
const selected = await selectModelFromList(`Select ${modelType.name} Model`, current, { excludeCombos: true });
|
|
104
|
+
if (!selected) return;
|
|
105
|
+
|
|
106
|
+
const env = { [modelType.envKey]: selected };
|
|
107
|
+
|
|
108
|
+
// Also set base URL if not configured yet
|
|
109
|
+
const settingsResult = await api.getCliToolSettings("claude");
|
|
110
|
+
if (!settingsResult.data?.settings?.env?.ANTHROPIC_BASE_URL) {
|
|
111
|
+
const { endpoint } = await getEndpoint(port);
|
|
112
|
+
const apiKey = await getFirstApiKey();
|
|
113
|
+
env.ANTHROPIC_BASE_URL = endpoint;
|
|
114
|
+
env.API_TIMEOUT_MS = "600000";
|
|
115
|
+
if (apiKey) env.ANTHROPIC_AUTH_TOKEN = apiKey;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const result = await api.applyCliToolSettings("claude", { env });
|
|
119
|
+
showStatus(result.success ? `${modelType.name} → ${selected} saved!` : `Failed: ${result.error}`, result.success ? "success" : "error");
|
|
120
|
+
await pause();
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Reset Claude Code settings
|
|
125
|
+
*/
|
|
126
|
+
async function claudeReset() {
|
|
127
|
+
const result = await api.resetCliToolSettings("claude");
|
|
128
|
+
showStatus(result.success ? "Settings reset successfully!" : `Failed: ${result.error}`, result.success ? "success" : "error");
|
|
129
|
+
await pause();
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Claude Code submenu
|
|
134
|
+
* @param {number} port
|
|
135
|
+
* @param {Array<string>} breadcrumb
|
|
136
|
+
*/
|
|
137
|
+
async function showClaudeCodeMenu(port, breadcrumb = []) {
|
|
138
|
+
await showMenuWithBack({
|
|
139
|
+
title: "🔧 Claude Code Settings",
|
|
140
|
+
breadcrumb,
|
|
141
|
+
headerContent: buildClaudeHeader,
|
|
142
|
+
refresh: async () => ({
|
|
143
|
+
sonnet: await getClaudeModel("ANTHROPIC_DEFAULT_SONNET_MODEL"),
|
|
144
|
+
opus: await getClaudeModel("ANTHROPIC_DEFAULT_OPUS_MODEL"),
|
|
145
|
+
haiku: await getClaudeModel("ANTHROPIC_DEFAULT_HAIKU_MODEL"),
|
|
146
|
+
}),
|
|
147
|
+
items: [
|
|
148
|
+
{
|
|
149
|
+
label: "⚡ Quick Setup (recommended)",
|
|
150
|
+
action: async () => { await claudeQuickSetup(port); return true; }
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
label: (d) => `Sonnet → ${d.sonnet}`,
|
|
154
|
+
action: async () => { await claudeSelectModel(CLAUDE_MODEL_TYPES[0], port); return true; }
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
label: (d) => `Opus → ${d.opus}`,
|
|
158
|
+
action: async () => { await claudeSelectModel(CLAUDE_MODEL_TYPES[1], port); return true; }
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
label: (d) => `Haiku → ${d.haiku}`,
|
|
162
|
+
action: async () => { await claudeSelectModel(CLAUDE_MODEL_TYPES[2], port); return true; }
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
label: "Reset to Default",
|
|
166
|
+
action: async () => { await claudeReset(); return true; }
|
|
167
|
+
}
|
|
168
|
+
]
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// ─── Codex CLI ────────────────────────────────────────────────────────────────
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Build header showing current Codex config status
|
|
176
|
+
* @returns {Promise<string>}
|
|
177
|
+
*/
|
|
178
|
+
async function buildCodexHeader() {
|
|
179
|
+
const result = await api.getCliToolSettings("codex");
|
|
180
|
+
if (!result.success) return ` ${COLORS.red}Failed to load settings${COLORS.reset}`;
|
|
181
|
+
|
|
182
|
+
const { installed, hasBluerouter, config } = result.data;
|
|
183
|
+
if (!installed) return `Status: ${COLORS.red}✗ Codex CLI not installed${COLORS.reset}`;
|
|
184
|
+
|
|
185
|
+
if (!hasBluerouter) {
|
|
186
|
+
return [
|
|
187
|
+
`Status: ${COLORS.red}✗ Not configured${COLORS.reset}`,
|
|
188
|
+
`${COLORS.dim}Run "Quick Setup" to configure${COLORS.reset}`
|
|
189
|
+
].join("\n");
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Parse base_url and model from raw TOML string
|
|
193
|
+
const baseUrlMatch = config && config.match(/base_url\s*=\s*"([^"]+)"/);
|
|
194
|
+
const modelMatch = config && config.match(/^model\s*=\s*"([^"]+)"/m);
|
|
195
|
+
const baseUrl = baseUrlMatch ? baseUrlMatch[1] : "";
|
|
196
|
+
const model = modelMatch ? modelMatch[1] : "";
|
|
197
|
+
|
|
198
|
+
const lines = [`Status: ${COLORS.green}✓ Configured${COLORS.reset}`];
|
|
199
|
+
if (baseUrl) lines.push(`Endpoint: ${COLORS.cyan}${baseUrl}${COLORS.reset}`);
|
|
200
|
+
if (model) lines.push(`Model: ${COLORS.dim}${model}${COLORS.reset}`);
|
|
201
|
+
return lines.join("\n");
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Quick setup for Codex CLI
|
|
206
|
+
* @param {number} port
|
|
207
|
+
*/
|
|
208
|
+
async function codexQuickSetup(port) {
|
|
209
|
+
const { endpoint } = await getEndpoint(port);
|
|
210
|
+
const apiKey = await getFirstApiKey();
|
|
211
|
+
|
|
212
|
+
if (!apiKey) {
|
|
213
|
+
showStatus("No API keys found. Create one in API Keys menu first.", "error");
|
|
214
|
+
await pause();
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Get model selection
|
|
219
|
+
const model = await selectModelFromList("Select Codex Model", "cx/claude-sonnet-4-5-20250929", { excludeCombos: true });
|
|
220
|
+
if (!model) return;
|
|
221
|
+
|
|
222
|
+
const result = await api.applyCliToolSettings("codex", { baseUrl: endpoint, apiKey, model });
|
|
223
|
+
showStatus(result.success ? "Codex setup completed!" : `Failed: ${result.error}`, result.success ? "success" : "error");
|
|
224
|
+
await pause();
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Reset Codex CLI settings
|
|
229
|
+
*/
|
|
230
|
+
async function codexReset() {
|
|
231
|
+
const result = await api.resetCliToolSettings("codex");
|
|
232
|
+
showStatus(result.success ? "Codex settings reset!" : `Failed: ${result.error}`, result.success ? "success" : "error");
|
|
233
|
+
await pause();
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Codex CLI submenu
|
|
238
|
+
* @param {number} port
|
|
239
|
+
* @param {Array<string>} breadcrumb
|
|
240
|
+
*/
|
|
241
|
+
async function showCodexMenu(port, breadcrumb = []) {
|
|
242
|
+
await showMenuWithBack({
|
|
243
|
+
title: "🤖 Codex CLI Settings",
|
|
244
|
+
breadcrumb,
|
|
245
|
+
headerContent: buildCodexHeader,
|
|
246
|
+
refresh: async () => ({}),
|
|
247
|
+
items: [
|
|
248
|
+
{
|
|
249
|
+
label: "⚡ Quick Setup",
|
|
250
|
+
action: async () => { await codexQuickSetup(port); return true; }
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
label: "Reset to Default",
|
|
254
|
+
action: async () => { await codexReset(); return true; }
|
|
255
|
+
}
|
|
256
|
+
]
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// ─── Factory Droid ────────────────────────────────────────────────────────────
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Build header showing current Droid config status
|
|
264
|
+
* @returns {Promise<string>}
|
|
265
|
+
*/
|
|
266
|
+
async function buildDroidHeader() {
|
|
267
|
+
const result = await api.getCliToolSettings("droid");
|
|
268
|
+
if (!result.success) return ` ${COLORS.red}Failed to load settings${COLORS.reset}`;
|
|
269
|
+
|
|
270
|
+
const { installed, hasBluerouter, settings } = result.data;
|
|
271
|
+
if (!installed) return `Status: ${COLORS.red}✗ Factory Droid not installed${COLORS.reset}`;
|
|
272
|
+
|
|
273
|
+
if (!hasBluerouter) {
|
|
274
|
+
return [
|
|
275
|
+
`Status: ${COLORS.red}✗ Not configured${COLORS.reset}`,
|
|
276
|
+
`${COLORS.dim}Run "Quick Setup" to configure${COLORS.reset}`
|
|
277
|
+
].join("\n");
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// Extract Bluerouter custom model config
|
|
281
|
+
const custom = settings?.customModels?.find(m => m.id === "custom:Bluerouter-0");
|
|
282
|
+
const lines = [`Status: ${COLORS.green}✓ Configured${COLORS.reset}`];
|
|
283
|
+
if (custom?.baseUrl) lines.push(`Endpoint: ${COLORS.cyan}${custom.baseUrl}${COLORS.reset}`);
|
|
284
|
+
if (custom?.model) lines.push(`Model: ${COLORS.dim}${custom.model}${COLORS.reset}`);
|
|
285
|
+
return lines.join("\n");
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Quick setup for Factory Droid
|
|
290
|
+
* @param {number} port
|
|
291
|
+
*/
|
|
292
|
+
async function droidQuickSetup(port) {
|
|
293
|
+
const { endpoint } = await getEndpoint(port);
|
|
294
|
+
const apiKey = await getFirstApiKey();
|
|
295
|
+
|
|
296
|
+
if (!apiKey) {
|
|
297
|
+
showStatus("No API keys found. Create one in API Keys menu first.", "error");
|
|
298
|
+
await pause();
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
const model = await selectModelFromList("Select Droid Model", "cc/claude-sonnet-4-5-20250929", { excludeCombos: true });
|
|
303
|
+
if (!model) return;
|
|
304
|
+
|
|
305
|
+
const result = await api.applyCliToolSettings("droid", { baseUrl: endpoint, apiKey, model });
|
|
306
|
+
showStatus(result.success ? "Factory Droid setup completed!" : `Failed: ${result.error}`, result.success ? "success" : "error");
|
|
307
|
+
await pause();
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Reset Factory Droid settings
|
|
312
|
+
*/
|
|
313
|
+
async function droidReset() {
|
|
314
|
+
const result = await api.resetCliToolSettings("droid");
|
|
315
|
+
showStatus(result.success ? "Factory Droid settings reset!" : `Failed: ${result.error}`, result.success ? "success" : "error");
|
|
316
|
+
await pause();
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Factory Droid submenu
|
|
321
|
+
* @param {number} port
|
|
322
|
+
* @param {Array<string>} breadcrumb
|
|
323
|
+
*/
|
|
324
|
+
async function showDroidMenu(port, breadcrumb = []) {
|
|
325
|
+
await showMenuWithBack({
|
|
326
|
+
title: "🤖 Factory Droid Settings",
|
|
327
|
+
breadcrumb,
|
|
328
|
+
headerContent: buildDroidHeader,
|
|
329
|
+
refresh: async () => ({}),
|
|
330
|
+
items: [
|
|
331
|
+
{
|
|
332
|
+
label: "⚡ Quick Setup",
|
|
333
|
+
action: async () => { await droidQuickSetup(port); return true; }
|
|
334
|
+
},
|
|
335
|
+
{
|
|
336
|
+
label: "Reset to Default",
|
|
337
|
+
action: async () => { await droidReset(); return true; }
|
|
338
|
+
}
|
|
339
|
+
]
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// ─── Open Claw ────────────────────────────────────────────────────────────────
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Build header showing current OpenClaw config status
|
|
347
|
+
* @returns {Promise<string>}
|
|
348
|
+
*/
|
|
349
|
+
async function buildOpenClawHeader() {
|
|
350
|
+
const result = await api.getCliToolSettings("openclaw");
|
|
351
|
+
if (!result.success) return ` ${COLORS.red}Failed to load settings${COLORS.reset}`;
|
|
352
|
+
|
|
353
|
+
const { installed, hasBluerouter, settings } = result.data;
|
|
354
|
+
if (!installed) return `Status: ${COLORS.red}✗ Open Claw not installed${COLORS.reset}`;
|
|
355
|
+
|
|
356
|
+
if (!hasBluerouter) {
|
|
357
|
+
return [
|
|
358
|
+
`Status: ${COLORS.red}✗ Not configured${COLORS.reset}`,
|
|
359
|
+
`${COLORS.dim}Run "Quick Setup" to configure${COLORS.reset}`
|
|
360
|
+
].join("\n");
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// Extract Bluerouter provider config
|
|
364
|
+
const provider = settings?.models?.providers?.["bluerouter"];
|
|
365
|
+
const primary = settings?.agents?.defaults?.model?.primary || "";
|
|
366
|
+
const model = primary.startsWith("bluerouter/") ? primary.replace("bluerouter/", "") : (provider?.models?.[0]?.id || "");
|
|
367
|
+
const lines = [`Status: ${COLORS.green}✓ Configured${COLORS.reset}`];
|
|
368
|
+
if (provider?.baseUrl) lines.push(`Endpoint: ${COLORS.cyan}${provider.baseUrl}${COLORS.reset}`);
|
|
369
|
+
if (model) lines.push(`Model: ${COLORS.dim}${model}${COLORS.reset}`);
|
|
370
|
+
return lines.join("\n");
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* Quick setup for Open Claw
|
|
375
|
+
* @param {number} port
|
|
376
|
+
*/
|
|
377
|
+
async function openClawQuickSetup(port) {
|
|
378
|
+
const { endpoint } = await getEndpoint(port);
|
|
379
|
+
const apiKey = await getFirstApiKey();
|
|
380
|
+
|
|
381
|
+
if (!apiKey) {
|
|
382
|
+
showStatus("No API keys found. Create one in API Keys menu first.", "error");
|
|
383
|
+
await pause();
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
const model = await selectModelFromList("Select OpenClaw Model", "cc/claude-sonnet-4-5-20250929", { excludeCombos: true });
|
|
388
|
+
if (!model) return;
|
|
389
|
+
|
|
390
|
+
const result = await api.applyCliToolSettings("openclaw", { baseUrl: endpoint, apiKey, model });
|
|
391
|
+
showStatus(result.success ? "Open Claw setup completed!" : `Failed: ${result.error}`, result.success ? "success" : "error");
|
|
392
|
+
await pause();
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* Reset Open Claw settings
|
|
397
|
+
*/
|
|
398
|
+
async function openClawReset() {
|
|
399
|
+
const result = await api.resetCliToolSettings("openclaw");
|
|
400
|
+
showStatus(result.success ? "Open Claw settings reset!" : `Failed: ${result.error}`, result.success ? "success" : "error");
|
|
401
|
+
await pause();
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
/**
|
|
405
|
+
* Open Claw submenu
|
|
406
|
+
* @param {number} port
|
|
407
|
+
* @param {Array<string>} breadcrumb
|
|
408
|
+
*/
|
|
409
|
+
async function showOpenClawMenu(port, breadcrumb = []) {
|
|
410
|
+
await showMenuWithBack({
|
|
411
|
+
title: "🦞 Open Claw Settings",
|
|
412
|
+
breadcrumb,
|
|
413
|
+
headerContent: buildOpenClawHeader,
|
|
414
|
+
refresh: async () => ({}),
|
|
415
|
+
items: [
|
|
416
|
+
{
|
|
417
|
+
label: "⚡ Quick Setup",
|
|
418
|
+
action: async () => { await openClawQuickSetup(port); return true; }
|
|
419
|
+
},
|
|
420
|
+
{
|
|
421
|
+
label: "Reset to Default",
|
|
422
|
+
action: async () => { await openClawReset(); return true; }
|
|
423
|
+
}
|
|
424
|
+
]
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// ─── OpenCode CLI ─────────────────────────────────────────────────────────────
|
|
429
|
+
|
|
430
|
+
async function buildOpenCodeHeader() {
|
|
431
|
+
const result = await api.getCliToolSettings("opencode");
|
|
432
|
+
if (!result.success) return ` ${COLORS.red}Failed to load settings${COLORS.reset}`;
|
|
433
|
+
|
|
434
|
+
const { installed, hasBluerouter, opencode } = result.data;
|
|
435
|
+
if (!installed) return `Status: ${COLORS.red}✗ OpenCode CLI not installed${COLORS.reset}`;
|
|
436
|
+
|
|
437
|
+
if (!hasBluerouter) {
|
|
438
|
+
return [
|
|
439
|
+
`Status: ${COLORS.red}✗ Not configured${COLORS.reset}`,
|
|
440
|
+
`${COLORS.dim}Run "Quick Setup" to configure${COLORS.reset}`
|
|
441
|
+
].join("\n");
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
const lines = [`Status: ${COLORS.green}✓ Configured${COLORS.reset}`];
|
|
445
|
+
if (opencode?.baseURL) lines.push(`Endpoint: ${COLORS.cyan}${opencode.baseURL}${COLORS.reset}`);
|
|
446
|
+
if (opencode?.activeModel) lines.push(`Active: ${COLORS.dim}${opencode.activeModel}${COLORS.reset}`);
|
|
447
|
+
if (Array.isArray(opencode?.models) && opencode.models.length > 0) {
|
|
448
|
+
lines.push(`Models: ${COLORS.dim}${opencode.models.join(", ")}${COLORS.reset}`);
|
|
449
|
+
}
|
|
450
|
+
return lines.join("\n");
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
async function openCodeQuickSetup(port) {
|
|
454
|
+
const { endpoint } = await getEndpoint(port);
|
|
455
|
+
const apiKey = await getFirstApiKey();
|
|
456
|
+
|
|
457
|
+
if (!apiKey) {
|
|
458
|
+
showStatus("No API keys found. Create one in API Keys menu first.", "error");
|
|
459
|
+
await pause();
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
// Pick first model (also becomes active model by default)
|
|
464
|
+
const firstModel = await selectModelFromList("Select Active Model (OpenCode)", "", { excludeCombos: true });
|
|
465
|
+
if (!firstModel) return;
|
|
466
|
+
|
|
467
|
+
const models = [firstModel];
|
|
468
|
+
|
|
469
|
+
// Optionally add more models
|
|
470
|
+
while (true) {
|
|
471
|
+
const more = await confirm(`Add another model? (current: ${models.length})`);
|
|
472
|
+
if (!more) break;
|
|
473
|
+
const next = await selectModelFromList(`Add Model #${models.length + 1}`, models.join(", "), { excludeCombos: true });
|
|
474
|
+
if (!next) break;
|
|
475
|
+
if (!models.includes(next)) models.push(next);
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
// Optional subagent model
|
|
479
|
+
let subagentModel = firstModel;
|
|
480
|
+
const wantSubagent = await confirm(`Set a different subagent model? (default: ${firstModel})`);
|
|
481
|
+
if (wantSubagent) {
|
|
482
|
+
const picked = await selectModelFromList("Select Subagent Model", firstModel, { excludeCombos: true });
|
|
483
|
+
if (picked) subagentModel = picked;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
const result = await api.applyCliToolSettings("opencode", {
|
|
487
|
+
baseUrl: endpoint,
|
|
488
|
+
apiKey,
|
|
489
|
+
models,
|
|
490
|
+
activeModel: firstModel,
|
|
491
|
+
subagentModel,
|
|
492
|
+
});
|
|
493
|
+
showStatus(result.success ? "OpenCode setup completed!" : `Failed: ${result.error}`, result.success ? "success" : "error");
|
|
494
|
+
await pause();
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
async function openCodeReset() {
|
|
498
|
+
const result = await api.resetCliToolSettings("opencode");
|
|
499
|
+
showStatus(result.success ? "OpenCode settings reset!" : `Failed: ${result.error}`, result.success ? "success" : "error");
|
|
500
|
+
await pause();
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
async function showOpenCodeMenu(port, breadcrumb = []) {
|
|
504
|
+
await showMenuWithBack({
|
|
505
|
+
title: "💻 OpenCode CLI Settings",
|
|
506
|
+
breadcrumb,
|
|
507
|
+
headerContent: buildOpenCodeHeader,
|
|
508
|
+
refresh: async () => ({}),
|
|
509
|
+
items: [
|
|
510
|
+
{ label: "⚡ Quick Setup", action: async () => { await openCodeQuickSetup(port); return true; } },
|
|
511
|
+
{ label: "Reset to Default", action: async () => { await openCodeReset(); return true; } }
|
|
512
|
+
]
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
// ─── Hermes Agent ─────────────────────────────────────────────────────────────
|
|
517
|
+
|
|
518
|
+
async function buildHermesHeader() {
|
|
519
|
+
const result = await api.getCliToolSettings("hermes");
|
|
520
|
+
if (!result.success) return ` ${COLORS.red}Failed to load settings${COLORS.reset}`;
|
|
521
|
+
|
|
522
|
+
const { installed, hasBluerouter, settings } = result.data;
|
|
523
|
+
if (!installed) return `Status: ${COLORS.red}✗ Hermes Agent not installed${COLORS.reset}`;
|
|
524
|
+
|
|
525
|
+
if (!hasBluerouter) {
|
|
526
|
+
return [
|
|
527
|
+
`Status: ${COLORS.red}✗ Not configured${COLORS.reset}`,
|
|
528
|
+
`${COLORS.dim}Run "Quick Setup" to configure${COLORS.reset}`
|
|
529
|
+
].join("\n");
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
const model = settings?.model || {};
|
|
533
|
+
const lines = [`Status: ${COLORS.green}✓ Configured${COLORS.reset}`];
|
|
534
|
+
if (model.base_url) lines.push(`Endpoint: ${COLORS.cyan}${model.base_url}${COLORS.reset}`);
|
|
535
|
+
if (model.default) lines.push(`Model: ${COLORS.dim}${model.default}${COLORS.reset}`);
|
|
536
|
+
return lines.join("\n");
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
async function hermesQuickSetup(port) {
|
|
540
|
+
const { endpoint } = await getEndpoint(port);
|
|
541
|
+
const apiKey = await getFirstApiKey();
|
|
542
|
+
|
|
543
|
+
if (!apiKey) {
|
|
544
|
+
showStatus("No API keys found. Create one in API Keys menu first.", "error");
|
|
545
|
+
await pause();
|
|
546
|
+
return;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
const model = await selectModelFromList("Select Hermes Model", "", { excludeCombos: true });
|
|
550
|
+
if (!model) return;
|
|
551
|
+
|
|
552
|
+
const result = await api.applyCliToolSettings("hermes", { baseUrl: endpoint, apiKey, model });
|
|
553
|
+
showStatus(result.success ? "Hermes setup completed!" : `Failed: ${result.error}`, result.success ? "success" : "error");
|
|
554
|
+
await pause();
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
async function hermesReset() {
|
|
558
|
+
const result = await api.resetCliToolSettings("hermes");
|
|
559
|
+
showStatus(result.success ? "Hermes settings reset!" : `Failed: ${result.error}`, result.success ? "success" : "error");
|
|
560
|
+
await pause();
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
async function showHermesMenu(port, breadcrumb = []) {
|
|
564
|
+
await showMenuWithBack({
|
|
565
|
+
title: "⚡ Hermes Agent Settings",
|
|
566
|
+
breadcrumb,
|
|
567
|
+
headerContent: buildHermesHeader,
|
|
568
|
+
refresh: async () => ({}),
|
|
569
|
+
items: [
|
|
570
|
+
{ label: "⚡ Quick Setup", action: async () => { await hermesQuickSetup(port); return true; } },
|
|
571
|
+
{ label: "Reset to Default", action: async () => { await hermesReset(); return true; } }
|
|
572
|
+
]
|
|
573
|
+
});
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
// ─── Main CLI Tools Menu ──────────────────────────────────────────────────────
|
|
577
|
+
|
|
578
|
+
/**
|
|
579
|
+
* Main CLI Tools menu
|
|
580
|
+
* @param {number} port
|
|
581
|
+
* @param {Array<string>} breadcrumb
|
|
582
|
+
*/
|
|
583
|
+
async function showCliToolsMenu(port, breadcrumb = []) {
|
|
584
|
+
const { endpoint } = await getEndpoint(port);
|
|
585
|
+
await showMenuWithBack({
|
|
586
|
+
title: "🔧 CLI Tools",
|
|
587
|
+
breadcrumb,
|
|
588
|
+
headerContent: `Configure CLI tools to use Bluerouter\nEndpoint: ${endpoint}`,
|
|
589
|
+
items: [
|
|
590
|
+
{
|
|
591
|
+
label: "Claude Code",
|
|
592
|
+
action: async () => { await showClaudeCodeMenu(port, [...breadcrumb, "Claude Code"]); return true; }
|
|
593
|
+
},
|
|
594
|
+
{
|
|
595
|
+
label: "Codex CLI",
|
|
596
|
+
action: async () => { await showCodexMenu(port, [...breadcrumb, "Codex CLI"]); return true; }
|
|
597
|
+
},
|
|
598
|
+
{
|
|
599
|
+
label: "Factory Droid",
|
|
600
|
+
action: async () => { await showDroidMenu(port, [...breadcrumb, "Factory Droid"]); return true; }
|
|
601
|
+
},
|
|
602
|
+
{
|
|
603
|
+
label: "Open Claw",
|
|
604
|
+
action: async () => { await showOpenClawMenu(port, [...breadcrumb, "Open Claw"]); return true; }
|
|
605
|
+
},
|
|
606
|
+
{
|
|
607
|
+
label: "OpenCode",
|
|
608
|
+
action: async () => { await showOpenCodeMenu(port, [...breadcrumb, "OpenCode"]); return true; }
|
|
609
|
+
},
|
|
610
|
+
{
|
|
611
|
+
label: "Hermes",
|
|
612
|
+
action: async () => { await showHermesMenu(port, [...breadcrumb, "Hermes"]); return true; }
|
|
613
|
+
}
|
|
614
|
+
]
|
|
615
|
+
});
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
module.exports = { showCliToolsMenu };
|