mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-08-02 18:41:35 +08:00
feat(profiles): include Claude Desktop provider in project profiles
Claude Desktop's only dimension managed by cc-switch is its provider (MCP/Skills are hardcoded unsupported and prompts have no live file), so snapshots capture just the current desktop provider while the empty MCP/Skills sets and None prompt make apply a natural no-op for the other dimensions - no per-dimension special casing needed. - Add claude-desktop slot to PROFILE_APPS and PerApp (serde key uses the hyphenated app id); old payloads without the key deserialize to None and leave Claude Desktop untouched on apply - Gate the tray Projects submenu by iterating PROFILE_APPS instead of hardcoding Claude/Codex visibility - Show the profile switcher on the Claude Desktop tab, mirror the PerApp type, invalidate the claude-desktop providers cache on apply, and extend the switcher tooltip in all four locales - Extend the roundtrip integration test with the desktop provider dimension; the desktop switch is cfg-gated to macOS/Windows because desktop live writes error on Linux where CI runs cargo test
This commit is contained in:
@@ -29,6 +29,21 @@ fn claude_provider(id: &str, token: &str) -> Provider {
|
||||
)
|
||||
}
|
||||
|
||||
/// Claude Desktop 供应商:无 meta 时默认 Direct 模式,只要求 env 里有 token + base_url
|
||||
fn desktop_provider(id: &str, token: &str) -> Provider {
|
||||
Provider::with_id(
|
||||
id.to_string(),
|
||||
id.to_uppercase(),
|
||||
json!({
|
||||
"env": {
|
||||
"ANTHROPIC_AUTH_TOKEN": token,
|
||||
"ANTHROPIC_BASE_URL": "https://desktop.test"
|
||||
}
|
||||
}),
|
||||
None,
|
||||
)
|
||||
}
|
||||
|
||||
fn mcp_server(id: &str, claude_enabled: bool) -> McpServer {
|
||||
serde_json::from_value(json!({
|
||||
"id": id,
|
||||
@@ -105,6 +120,26 @@ fn profile_snapshot_apply_roundtrip_restores_configuration() {
|
||||
.set_current_provider(AppType::Claude.as_str(), "p1")
|
||||
.expect("set current provider p1");
|
||||
|
||||
// Claude Desktop 只有供应商一个活跃维度(MCP/Skills/Prompt 对它不适用)
|
||||
state
|
||||
.db
|
||||
.save_provider(
|
||||
AppType::ClaudeDesktop.as_str(),
|
||||
&desktop_provider("d1", "dk-1"),
|
||||
)
|
||||
.expect("save desktop provider d1");
|
||||
state
|
||||
.db
|
||||
.save_provider(
|
||||
AppType::ClaudeDesktop.as_str(),
|
||||
&desktop_provider("d2", "dk-2"),
|
||||
)
|
||||
.expect("save desktop provider d2");
|
||||
state
|
||||
.db
|
||||
.set_current_provider(AppType::ClaudeDesktop.as_str(), "d1")
|
||||
.expect("set current desktop provider d1");
|
||||
|
||||
// 让 live settings.json 与 p1 一致(switch_normal 回填需要)
|
||||
let claude_dir = home.join(".claude");
|
||||
fs::create_dir_all(&claude_dir).expect("create .claude dir");
|
||||
@@ -152,9 +187,19 @@ fn profile_snapshot_apply_roundtrip_restores_configuration() {
|
||||
"codex has no current provider"
|
||||
);
|
||||
assert!(payload.mcp.codex.is_empty());
|
||||
assert_eq!(payload.providers.claude_desktop.as_deref(), Some("d1"));
|
||||
assert!(
|
||||
payload.mcp.claude_desktop.is_empty() && payload.skills.claude_desktop.is_empty(),
|
||||
"desktop has no MCP/Skills dimension"
|
||||
);
|
||||
assert_eq!(payload.prompts.claude_desktop, None);
|
||||
|
||||
// ---- 改动全部四类配置(走真实切换路径)----
|
||||
ProviderService::switch(&state, AppType::Claude, "p2").expect("switch to p2");
|
||||
// Desktop live 写入仅 macOS/Windows 可用;其他平台不动 d1,
|
||||
// apply 时命中幂等跳过(这正是 Linux 上带 Desktop 槽的 payload 应有行为)
|
||||
#[cfg(any(target_os = "macos", windows))]
|
||||
ProviderService::switch(&state, AppType::ClaudeDesktop, "d2").expect("switch desktop to d2");
|
||||
McpService::toggle_app(&state, "m1", AppType::Claude, false).expect("disable m1");
|
||||
McpService::toggle_app(&state, "m2", AppType::Claude, true).expect("enable m2");
|
||||
SkillService::toggle_app(&state.db, "local:test-skill", &AppType::Claude, false)
|
||||
@@ -171,6 +216,16 @@ fn profile_snapshot_apply_roundtrip_restores_configuration() {
|
||||
.expect("get current provider");
|
||||
assert_eq!(current.as_deref(), Some("p1"), "provider restored to p1");
|
||||
|
||||
let current_desktop = state
|
||||
.db
|
||||
.get_current_provider(AppType::ClaudeDesktop.as_str())
|
||||
.expect("get current desktop provider");
|
||||
assert_eq!(
|
||||
current_desktop.as_deref(),
|
||||
Some("d1"),
|
||||
"desktop provider restored to d1"
|
||||
);
|
||||
|
||||
let servers = state.db.get_all_mcp_servers().expect("get mcp servers");
|
||||
assert!(servers.get("m1").expect("m1").apps.claude, "m1 re-enabled");
|
||||
assert!(!servers.get("m2").expect("m2").apps.claude, "m2 disabled");
|
||||
|
||||
Reference in New Issue
Block a user