mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-08-02 10:21:16 +08:00
feat(skills): auto-backup skill files before uninstall
Create a local backup under ~/.cc-switch/skill-backups/ before removing skill directories. The backup includes all skill files and a meta.json with original skill metadata. Old backups are pruned to keep at most 20. The backup path is returned to the frontend and shown in the success toast. Bump version to 3.12.3.
This commit is contained in:
@@ -80,9 +80,12 @@ const UnifiedSkillsPanel = React.forwardRef<
|
||||
message: t("skills.uninstallConfirm", { name: skill.name }),
|
||||
onConfirm: async () => {
|
||||
try {
|
||||
await uninstallMutation.mutateAsync(skill.id);
|
||||
const result = await uninstallMutation.mutateAsync(skill.id);
|
||||
setConfirmDialog(null);
|
||||
toast.success(t("skills.uninstallSuccess", { name: skill.name }), {
|
||||
description: result.backupPath
|
||||
? t("skills.backup.location", { path: result.backupPath })
|
||||
: undefined,
|
||||
closeButton: true,
|
||||
});
|
||||
} catch (error) {
|
||||
|
||||
@@ -1564,9 +1564,12 @@
|
||||
"noUnmanagedFound": "No skills to import found. All skills are already managed by CC Switch.",
|
||||
"foundIn": "Found in",
|
||||
"local": "Local",
|
||||
"uninstallConfirm": "Are you sure you want to uninstall \"{{name}}\"? This will remove the skill from all apps.",
|
||||
"uninstallConfirm": "Are you sure you want to uninstall \"{{name}}\"? This will remove the skill from all apps and create a local backup first.",
|
||||
"uninstallInMainPanel": "Please uninstall skills from the main panel",
|
||||
"notFound": "Skill not found",
|
||||
"backup": {
|
||||
"location": "Backup location: {{path}}"
|
||||
},
|
||||
"apps": {
|
||||
"claude": "Claude",
|
||||
"codex": "Codex",
|
||||
|
||||
@@ -1564,9 +1564,12 @@
|
||||
"noUnmanagedFound": "インポートするスキルが見つかりませんでした。すべてのスキルは CC Switch で管理されています。",
|
||||
"foundIn": "発見場所",
|
||||
"local": "ローカル",
|
||||
"uninstallConfirm": "「{{name}}」をアンインストールしますか?すべてのアプリからこのスキルが削除されます。",
|
||||
"uninstallConfirm": "「{{name}}」をアンインストールしますか?すべてのアプリからこのスキルが削除され、削除前にローカルバックアップが自動作成されます。",
|
||||
"uninstallInMainPanel": "メインパネルからスキルをアンインストールしてください",
|
||||
"notFound": "スキルが見つかりません",
|
||||
"backup": {
|
||||
"location": "バックアップ場所: {{path}}"
|
||||
},
|
||||
"apps": {
|
||||
"claude": "Claude",
|
||||
"codex": "Codex",
|
||||
|
||||
@@ -1564,9 +1564,12 @@
|
||||
"noUnmanagedFound": "未发现需要导入的技能。所有技能已在 CC Switch 统一管理中。",
|
||||
"foundIn": "发现于",
|
||||
"local": "本地",
|
||||
"uninstallConfirm": "确定要卸载技能 \"{{name}}\" 吗?这将从所有应用中移除该技能。",
|
||||
"uninstallConfirm": "确定要卸载技能 \"{{name}}\" 吗?这将从所有应用中移除该技能,并在删除前自动创建本地备份。",
|
||||
"uninstallInMainPanel": "请在主面板中卸载技能",
|
||||
"notFound": "未找到技能",
|
||||
"backup": {
|
||||
"location": "备份位置: {{path}}"
|
||||
},
|
||||
"apps": {
|
||||
"claude": "Claude",
|
||||
"codex": "Codex",
|
||||
|
||||
@@ -27,6 +27,10 @@ export interface InstalledSkill {
|
||||
installedAt: number;
|
||||
}
|
||||
|
||||
export interface SkillUninstallResult {
|
||||
backupPath?: string;
|
||||
}
|
||||
|
||||
/** 可发现的 Skill(来自仓库) */
|
||||
export interface DiscoverableSkill {
|
||||
key: string;
|
||||
@@ -94,7 +98,7 @@ export const skillsApi = {
|
||||
},
|
||||
|
||||
/** 卸载 Skill(统一卸载) */
|
||||
async uninstallUnified(id: string): Promise<boolean> {
|
||||
async uninstallUnified(id: string): Promise<SkillUninstallResult> {
|
||||
return await invoke("uninstall_skill_unified", { id });
|
||||
},
|
||||
|
||||
@@ -139,7 +143,10 @@ export const skillsApi = {
|
||||
},
|
||||
|
||||
/** 卸载技能(兼容旧 API) */
|
||||
async uninstall(directory: string, app: AppId = "claude"): Promise<boolean> {
|
||||
async uninstall(
|
||||
directory: string,
|
||||
app: AppId = "claude",
|
||||
): Promise<SkillUninstallResult> {
|
||||
if (app === "claude") {
|
||||
return await invoke("uninstall_skill", { directory });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user