`~/.cc-switch/` 里有什么:一个库、一份设置、两种备份与一批软链

2026-08-10

CC Switch 把自己的数据都放在 ~/.cc-switch/ 下。README 的 FAQ「我的数据存储在哪里」列了五条(README_ZH.md:304-308):数据库、本地设置、备份、SKILLS、技能备份。看上去是很平的一张清单,但真正值得花时间的不是这五个名字,而是这一句:这个目录下同时存在三套互不相干的备份保留策略,一个可配置、两个是硬编码常量,而 README FAQ 只用「保留最近 10 个 / 保留最近 20 个」两行带过。

以下全部基于我们本地 clone 的 cc-switch 仓库快照 c39c903(提交日期 2026-08-10),仓库内版本号 3.19.2。我们只读源码文本,没有安装也没有运行过这个桌面应用

先把五条路径钉到代码行上

FAQ 的五条,在 src-tauri/src/ 下都能找到对应的路径拼接,值得逐条对一遍:

FAQ 里的名字路径代码侧拼接位置
数据库~/.cc-switch/cc-switch.dbsrc-tauri/src/database/mod.rs:99-101
本地设置~/.cc-switch/settings.jsonsrc-tauri/src/settings.rs:559-563
备份~/.cc-switch/backups/src-tauri/src/services/env_manager.rs:71
SKILLS~/.cc-switch/skills/src-tauri/src/services/skill.rs:512-514
技能备份~/.cc-switch/skill-backups/src-tauri/src/services/skill.rs:521-523

这张表的读法是:左边是文档说法,右边是你可以自己打开去核的那一行。根目录本身来自 get_home_dir().join(".cc-switch")src-tauri/src/config.rs:208),也就是说所有子项都是从同一个函数派生出来的,不是各写各的绝对路径。

还有一条 FAQ 没写、但同样落在这个目录下的东西:panic 日志目录也挂在 .cc-switch 下(src-tauri/src/panic_hook.rs:28)。你要是排查过崩溃日志找不到地方,这一行值得记住。顺带一提,src-tauri/Cargo.toml:110-117 的 release profile 里 panic = "unwind",注释写明保留 unwind 就是为了让 panic hook 能抓到 backtrace——这和日志目录是配套的两件事。

反直觉的那一处:三套备份,三个不同的数

这是本文的重点。~/.cc-switch/ 底下和”备份”沾边的机制有三套,它们的保留数分别由不同的东西决定:

第一套,配置目录备份,硬编码 10。 src-tauri/src/services/config.rs:10 定义了 const MAX_BACKUPS: usize = 10;,写完备份文件后直接调用 Self::cleanup_old_backups(&backup_dir, MAX_BACKUPS)src-tauri/src/services/config.rs:36)。这个 10 写在常量里,没有设置项能改它。

第二套,数据库备份,可配置。 设置结构里有 backup_retain_count 这个字段,注释原文是 “Maximum number of backup files to retain (default 10)“(src-tauri/src/settings.rs:476-478);取值走 effective_backup_retain_count(),口径是默认 10、下限 1——读不到设置值时取 10,读到的值会被钳到不小于 1(src-tauri/src/settings.rs:1076-1087)。数据库备份清理时读的正是这个值(src-tauri/src/database/backup.rs:415)。

第三套,技能卸载备份,硬编码 20。 src-tauri/src/services/skill.rs:267 定义 const SKILL_BACKUP_RETAIN_COUNT: usize = 20;,在 cleanup_old_skill_backups 里比对(src-tauri/src/services/skill.rs:285428662871)。

三套机制凑在同一个目录下,于是”保留几个”这个问题在不同文档层上得到了不同答案:

  • README FAQ 写的是「备份:自动轮换,保留最近 10 个」(README_ZH.md:306),是一个写死的数;
  • 用户手册的自动备份设置写的是保留数量可选 3 / 5 / 10 / 15 / 20 / 30 / 50,默认 10 个,备份间隔可选禁用 / 6h / 12h / 24h / 48h / 7d,默认 24 小时(docs/user-manual/zh/1-getting-started/1.5-settings.md:197-200);
  • 代码里则是上面那三套并存。

README 的「10」与手册的「可选 3-50、默认 10」是两处不同的写法,代码里可配置的那一路与硬编码的那两路也是三种不同的约束。说完差异就停——哪一处「才算数」、为什么会这样,本文不做推断,也不拿它去评价这个项目。技能备份的 20 这一项,README(README_ZH.md:308)与代码常量(src-tauri/src/services/skill.rs:267)倒是对得上。

你要自己核这件事,动作很短:打开 src-tauri/src/services/config.rs 看第 10 行的常量,打开 src-tauri/src/settings.rs 看第 476-478 行与 1076-1087 行这两段,再回头读一遍 README_ZH.md:306 和手册 1.5 那张表,三处并排放着看就清楚了。

需要提醒的是:这些都是代码里的默认配置,不是”你的备份一定会留住几份”的保证。备份实际生成多少份还取决于触发时机,而触发时机本身也有例外——CHANGELOG 记录 3.19.2 没有做数据库 schema 迁移,因此不触发升级前备份CHANGELOG.md:56,同段还写明 “SCHEMA_VERSION stays at 16”,与 src-tauri/src/database/mod.rs:56SCHEMA_VERSION: i32 = 16 一致)。别把”有备份机制”直接理解成”每次升级都有一份”。

一个库配一份设置:为什么 settings.json 不进数据库

第二件容易被跳过的事是双层存储。README 的架构表述里写了 SSOT(所有数据在 SQLite)与双层存储(SQLite 存可同步数据 + JSON 存设备级设置)(README_ZH.md:424-429),而代码注释把这条分界讲得更直白:src-tauri/src/settings.rs:339 的注释写明,这份设置是「存储设备级别设置,保存在本地 ~/.cc-switch/settings.json,不随数据库同步」。

所以判断一个配置该去哪儿找,规则是:跟着人走的东西在库里,跟着这台机器走的东西在 JSON 里。 路径拼接处还有一句补充注释——settings.json「保留用于旧版本迁移和无数据库场景」(src-tauri/src/settings.rs:559-563)。

顺着这条线还有一个实用的点:用户手册 1.5 列了各 CLI 工具目录的默认值——~/.claude/~/.codex/~/.gemini/~/.config/opencode/~/.openclaw/~/.hermes/,应用自身数据默认目录则是 ~/.cc-switch/docs/user-manual/zh/1-getting-started/1.5-settings.md:117123-132)。手册在这张表下面明确写了改目录后需要重启应用。也就是说 ~/.cc-switch/ 是 CC Switch 自己的家,~/.claude/ 这些是它要去读写的别人的家——两者不是一回事,排查问题时别混。

「一批软链」这四个字得拆开看

FAQ 对 SKILLS 那条的原话是「默认通过软链接连接到对应应用」(README_ZH.md:307)。代码里这个存储位置是有分支的:SkillStorageLocation::CcSwitch 落到 get_app_config_dir().join("skills"),也就是 ~/.cc-switch/skills/;另一个分支落到 ~/.agents/skillssrc-tauri/src/services/skill.rs:512-514src-tauri/src/services/skill.rs:397)。所以”我的技能文件到底在哪”这个问题,答案取决于存储位置设置选的是哪一支,不能只按 FAQ 那一行去找。技能装成软链还是复制、两种策略差在哪,我们另有一篇专门讲,这里只锁定路径这一层。

这个目录里装着敏感数据,请照这个前提处理

必须说清楚一件事:CC Switch 会读写 ~/.claude~/.codex 这些真实 CLI 配置文件,并在本机保存 API Key。~/.cc-switch/cc-switch.db 与它的备份文件因此属于本机敏感数据。我们没有读过它的加密实现,也不会写”这样就安全了”这类话——是否同步到网盘、是否随仓库带走、备份文件怎么处置,请按你自己的环境评估。

仓库里有一处旁证能说明这个目录的权限边界。flatpak/README.md 讨论权限时提到,当前 manifest 默认用 --filesystem=home(图的是”下载即用”的便利),文中同时给出了可替换的最小权限清单:~/.cc-switch:create~/.claude:create~/.claude.json~/.codex:create~/.gemini:create~/.config/opencode:create~/.openclaw:createflatpak/README.md:4954-61)。同一份文档还注明 Flatpak 的 :create 修饰符只对目录生效,~/.claude.json 不能用 :create;该文件不存在时,受限权限下应用可能无法创建,文中建议先跑一次 Claude Code 或手工建一个内容为 {} 的空 JSON(flatpak/README.md:63)。这份清单本身就是这个应用需要触达哪些目录的一份说明书。

搬家与卸载:带走什么,删掉什么

如果要把数据搬到另一台机器上,手册给的导出格式是 SQL 备份文件,文件名形如 cc-switch-export-{timestamp}.sqldocs/user-manual/zh/1-getting-started/1.5-settings.md:138-146)。按前面的双层存储逻辑,设备级的 settings.json 本来就不参与同步,新机器上重新配一遍是预期内的。

卸载这一侧,手册的指引是:Windows 走系统「设置 → 应用」;macOS 移入废纸篓,并可选删除 ~/.cc-switch/;Linux 用 sudo apt remove cc-switchparu -R cc-switch-bindocs/user-manual/zh/1-getting-started/1.2-installation.md:220-240)。注意 macOS 那条里的「可选」二字——删应用不会顺手删数据目录,你不动手它就一直在。这和 README FAQ 里那句设计原则是配套的:「本软件的设计原则是’最小侵入性’,即使卸载本软件,也不会影响应用的正常使用」(README_ZH.md:288),英文版同义(README.md:287)。反过来读就是:卸载之后 ~/.cc-switch/ 里那个含密钥的库还在原地,处置它是你自己的事。

复核清单

想把本文的说法自己验一遍,四个动作就够,全部只需读文本:

  1. src-tauri/src/config.rs:208 确认根目录来源;
  2. src-tauri/src/services/config.rs:10src-tauri/src/settings.rs:476-4781076-1087src-tauri/src/services/skill.rs:267 三处并排,确认三套保留数;
  3. README_ZH.md:304-308docs/user-manual/zh/1-getting-started/1.5-settings.md:197-200 并排,确认文档两层的写法差异;
  4. src-tauri/src/services/skill.rs:512-514:397,确认 skills 目录有两个落点。

什么情况说明你遇到的问题不在本文范围内:如果你的现象是切换供应商不生效、代理连不上、某个 CLI 读不到配置,那多半和 ~/.cc-switch/ 的落盘无关,得去看对应工具目录(~/.claude/ 这一层)与生效方式,那是另一条线上的事。本文只解决”东西存在哪、留几份、卸载后还剩什么”这四个问题。

最后把分寸重复一遍:以上数字与路径都是 2026-08-10 我们读到的 c39c903 快照里的内容,常量与默认值随版本变动,请以你自己 clone 到的仓库为准。


本文依据 CC Switch 官方仓库(github.com/farion1231/cc-switch)的 README、docs/ 下的用户手册与发布说明、 src/config/ 的预设定义与 src-tauri/src/ 的后端源码整理,核对日 2026-08-10,对应仓库快照 c39c903。 本文内容为仓库源码与文档口径,我们没有安装或运行过这个桌面应用, 因此不涉及界面外观、操作手感与切换速度的任何描述。 文中出现的阈值与默认值均为源码中的默认配置,不构成对实际运行结果的保证。 该项目仍在快速迭代,版本与默认值随时可能变动,请以仓库最新内容为准。 安全相关做法请结合自身环境评估,本文不构成安全方案建议。

想系统学会用 AI?报名体系课或加入会员,照着学、照着用。