mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-27 16:26:16 +08:00
8b3ad9caf9
Adds a new ClaudeDesktop AppType that writes Claude Desktop's third-party
inference profile under configLibrary/, sharing _meta.json with other
launchers (Ollama-compatible) so cc-switch can coexist with them.
Two switch modes:
- direct: provider already exposes claude-* / anthropic/claude-* model
ids on Anthropic Messages, Claude Desktop connects to it directly.
- proxy: cc-switch's local proxy acts as the inference gateway,
presenting only claude-* route names to Claude Desktop and mapping
them to real upstream models. Required after Anthropic restricted
Claude Desktop to claude-family ids.
Backend:
- New module claude_desktop_config with snapshot/rollback, official seed
bypass, /claude-desktop/v1/{models,messages} routes, and a single
source of truth for default proxy routes.
- Gateway token persisted in SQLite, validated on every proxied request.
- get_claude_desktop_status surfaces drift signals (stale models,
missing routes, proxy stopped, base URL mismatch, missing token).
Frontend:
- Slim ClaudeDesktopProviderForm independent from ProviderForm,
controlled by a top-level appId guard.
- ProviderList banner consumes the status query (5s polling) and
renders actionable diagnostics.
- ClaudeDesktopRouteToggle in the header to start/stop the local
gateway without touching takeover state.
- Three-locale i18n synchronised.
112 lines
3.2 KiB
TypeScript
112 lines
3.2 KiB
TypeScript
import React from "react";
|
|
import type { AppId } from "@/lib/api/types";
|
|
import {
|
|
ClaudeIcon,
|
|
CodexIcon,
|
|
GeminiIcon,
|
|
OpenClawIcon,
|
|
} from "@/components/BrandIcons";
|
|
import { ProviderIcon } from "@/components/ProviderIcon";
|
|
|
|
export interface AppConfig {
|
|
label: string;
|
|
icon: React.ReactNode;
|
|
activeClass: string;
|
|
badgeClass: string;
|
|
}
|
|
|
|
export const APP_IDS: AppId[] = [
|
|
"claude",
|
|
"claude-desktop",
|
|
"codex",
|
|
"gemini",
|
|
"opencode",
|
|
"openclaw",
|
|
"hermes",
|
|
];
|
|
|
|
/** App IDs shown in Skills panels (excludes OpenClaw — it doesn't support Skills) */
|
|
export const SKILLS_APP_IDS: AppId[] = [
|
|
"claude",
|
|
"codex",
|
|
"gemini",
|
|
"opencode",
|
|
"hermes",
|
|
];
|
|
|
|
/** App IDs shown in MCP panels (excludes OpenClaw) */
|
|
export const MCP_APP_IDS: AppId[] = [...SKILLS_APP_IDS];
|
|
|
|
export const APP_ICON_MAP: Record<AppId, AppConfig> = {
|
|
claude: {
|
|
label: "Claude",
|
|
icon: <ClaudeIcon size={14} />,
|
|
activeClass:
|
|
"bg-orange-500/10 ring-1 ring-orange-500/20 hover:bg-orange-500/20 text-orange-600 dark:text-orange-400",
|
|
badgeClass:
|
|
"bg-orange-500/10 text-orange-700 dark:text-orange-300 hover:bg-orange-500/20 border-0 gap-1.5",
|
|
},
|
|
"claude-desktop": {
|
|
label: "Claude Desktop",
|
|
icon: <ClaudeIcon size={14} />,
|
|
activeClass:
|
|
"bg-amber-500/10 ring-1 ring-amber-500/20 hover:bg-amber-500/20 text-amber-700 dark:text-amber-300",
|
|
badgeClass:
|
|
"bg-amber-500/10 text-amber-700 dark:text-amber-300 hover:bg-amber-500/20 border-0 gap-1.5",
|
|
},
|
|
codex: {
|
|
label: "Codex",
|
|
icon: <CodexIcon size={14} />,
|
|
activeClass:
|
|
"bg-green-500/10 ring-1 ring-green-500/20 hover:bg-green-500/20 text-green-600 dark:text-green-400",
|
|
badgeClass:
|
|
"bg-green-500/10 text-green-700 dark:text-green-300 hover:bg-green-500/20 border-0 gap-1.5",
|
|
},
|
|
gemini: {
|
|
label: "Gemini",
|
|
icon: <GeminiIcon size={14} />,
|
|
activeClass:
|
|
"bg-blue-500/10 ring-1 ring-blue-500/20 hover:bg-blue-500/20 text-blue-600 dark:text-blue-400",
|
|
badgeClass:
|
|
"bg-blue-500/10 text-blue-700 dark:text-blue-300 hover:bg-blue-500/20 border-0 gap-1.5",
|
|
},
|
|
opencode: {
|
|
label: "OpenCode",
|
|
icon: (
|
|
<ProviderIcon
|
|
icon="opencode"
|
|
name="OpenCode"
|
|
size={14}
|
|
showFallback={false}
|
|
/>
|
|
),
|
|
activeClass:
|
|
"bg-indigo-500/10 ring-1 ring-indigo-500/20 hover:bg-indigo-500/20 text-indigo-600 dark:text-indigo-400",
|
|
badgeClass:
|
|
"bg-indigo-500/10 text-indigo-700 dark:text-indigo-300 hover:bg-indigo-500/20 border-0 gap-1.5",
|
|
},
|
|
openclaw: {
|
|
label: "OpenClaw",
|
|
icon: <OpenClawIcon size={14} />,
|
|
activeClass:
|
|
"bg-rose-500/10 ring-1 ring-rose-500/20 hover:bg-rose-500/20 text-rose-600 dark:text-rose-400",
|
|
badgeClass:
|
|
"bg-rose-500/10 text-rose-700 dark:text-rose-300 hover:bg-rose-500/20 border-0 gap-1.5",
|
|
},
|
|
hermes: {
|
|
label: "Hermes",
|
|
icon: (
|
|
<ProviderIcon
|
|
icon="hermes"
|
|
name="Hermes"
|
|
size={14}
|
|
showFallback={false}
|
|
/>
|
|
),
|
|
activeClass:
|
|
"bg-violet-500/10 ring-1 ring-violet-500/20 hover:bg-violet-500/20 text-violet-600 dark:text-violet-400",
|
|
badgeClass:
|
|
"bg-violet-500/10 text-violet-700 dark:text-violet-300 hover:bg-violet-500/20 border-0 gap-1.5",
|
|
},
|
|
};
|