mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-24 21:30:17 +08:00
feat: add project profiles for snapshot-based config switching
Add a profile feature that captures the current provider, MCP, skills and prompt state for Claude Code and Codex as a named snapshot, and re-applies it in one click from the header switcher or the tray Projects submenu. - New profiles table (schema v12) with current marker in settings - ProfileService orchestrates the four existing switch primitives (provider first, then MCP diff, skills diff, prompt enable) - Best-effort apply: dangling references become warnings, no rollback - Header combobox switcher + snapshot-style manage dialog - Tray Projects submenu shared with the UI apply/event pipeline - i18n for zh/en/ja/zh-TW under the new profiles domain - Integration tests covering roundtrip, dangling refs and clear
This commit is contained in:
@@ -3,6 +3,7 @@ export { providersApi, universalProvidersApi } from "./providers";
|
||||
export { settingsApi } from "./settings";
|
||||
export { backupsApi } from "./settings";
|
||||
export { mcpApi } from "./mcp";
|
||||
export { profilesApi } from "./profiles";
|
||||
export { promptsApi } from "./prompts";
|
||||
export { skillsApi } from "./skills";
|
||||
export { usageApi } from "./usage";
|
||||
@@ -17,6 +18,7 @@ export * as authApi from "./auth";
|
||||
export * as copilotApi from "./copilot";
|
||||
export type { ProviderSwitchEvent } from "./providers";
|
||||
export type { Prompt } from "./prompts";
|
||||
export type { Profile, ProfilePayload, ProfilesResponse } from "./profiles";
|
||||
export type {
|
||||
CopilotDeviceCodeResponse,
|
||||
CopilotAuthStatus,
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
|
||||
/**
|
||||
* 按 app 分槽的载荷容器(与后端 services/profile.rs 的 PerApp<T> 严格对应)
|
||||
*/
|
||||
export interface PerApp<T> {
|
||||
claude: T;
|
||||
codex: T;
|
||||
}
|
||||
|
||||
/**
|
||||
* 项目 Profile 的配置快照(与后端 ProfilePayload 严格对应)
|
||||
*/
|
||||
export interface ProfilePayload {
|
||||
providers: PerApp<string | null>;
|
||||
mcp: PerApp<string[]>;
|
||||
skills: PerApp<string[]>;
|
||||
prompts: PerApp<string | null>;
|
||||
}
|
||||
|
||||
export interface Profile {
|
||||
id: string;
|
||||
name: string;
|
||||
payload: ProfilePayload;
|
||||
createdAt?: number;
|
||||
updatedAt?: number;
|
||||
}
|
||||
|
||||
export interface ProfilesResponse {
|
||||
profiles: Profile[];
|
||||
currentId: string | null;
|
||||
}
|
||||
|
||||
export const profilesApi = {
|
||||
/**
|
||||
* 获取所有项目及当前激活项目 id
|
||||
*/
|
||||
async list(): Promise<ProfilesResponse> {
|
||||
return await invoke("list_profiles");
|
||||
},
|
||||
|
||||
/**
|
||||
* 以当前配置状态创建新项目
|
||||
*/
|
||||
async create(name: string): Promise<Profile> {
|
||||
return await invoke("create_profile", { name });
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新项目(重命名和/或以当前状态重拍快照)
|
||||
*/
|
||||
async update(
|
||||
id: string,
|
||||
options: { name?: string; resnapshot?: boolean },
|
||||
): Promise<Profile> {
|
||||
return await invoke("update_profile", {
|
||||
id,
|
||||
name: options.name,
|
||||
resnapshot: options.resnapshot,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除项目
|
||||
*/
|
||||
async delete(id: string): Promise<void> {
|
||||
return await invoke("delete_profile", { id });
|
||||
},
|
||||
|
||||
/**
|
||||
* 应用项目快照,返回 warnings(best-effort,部分失败不中断)
|
||||
*/
|
||||
async apply(id: string): Promise<string[]> {
|
||||
return await invoke("apply_profile", { id });
|
||||
},
|
||||
|
||||
/**
|
||||
* 不使用项目:仅清除激活标记,不改动任何配置
|
||||
*/
|
||||
async clearCurrent(): Promise<void> {
|
||||
return await invoke("clear_current_profile");
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user