工具快照
AI 每执行一次可能碰文件的工具 —— Edit、Write、Bash 命令、Task 子代理、MCP 工具 —— Cockpit 都会给项目拍一张快照。于是每条回复都有一条 git 历史式的时间线:一次工具调用一个条目,每个条目展示这次调用产生的真实磁盘 diff。
打开查看器
鼠标停在任何执行过文件类工具的 AI 回复上,点工具栏里的文件变更图标("查看所有文件变更")。实时对话和重新打开的历史会话都可用 —— 快照是按工具调用本身关联的。
在这个功能之前,diff 是从工具的参数里重建出来的,有两个盲区:Bash 的改动完全不可见(sed -i、代码生成器、会改文件的 npm install,全都看不到);同一文件被多次编辑时,重建结果可能和磁盘实际落下的内容有出入。快照把这两个洞都堵上了:你看到的就是磁盘上真实发生的。
读懂时间线
查看器的布局与 Explorer 的历史 tab一致:
- 左侧:一次工具调用一个条目,按执行顺序排列 —— 短 hash、时间、
[Write] nebula/codes.py这样的主题行。这是 AI 的编辑时序,不是揉在一起的一坨:你可以一步步回放这个改动是怎么搭出来的。 - 右侧:选中调用的详情 —— 工具名、带每文件
+/-行数的文件树、左右分栏 diff。精简/全文切换可以把未变更段折叠起来(GitHub 式)或展开全部行。 - 工具没有声明、但在同一窗口内变化的文件会带一个紫色圆点 —— 见多会话并发。
如果某条消息查不到快照(历史超出保留期、或快照功能刚启用),查看器会回退到参数重建,并标注 "参数重建" —— 你永远知道自己看的是磁盘真值还是尽力重建。
快照的工作方式
Cockpit 在 <数据目录>/snapshots/(默认 ~/.cockpit/snapshots/)下为每个项目维护一个影子 git 仓库:
- 项目自己的
.git完全不被触碰 —— 影子仓库有独立的对象存储,只读取你的工作区。 - 继承项目的
.gitignore,node_modules/、构建产物等永远不会进快照。常见敏感文件(.env*、*.pem、SSH 密钥)即使项目没有.gitignore也会被内置排除。 - 一切都在本地。快照永远不会离开你的机器。
- 覆盖全部引擎 —— Claude、Codex、DeepSeek、Kimi、Ollama —— 快照挂在所有引擎工具事件的唯一必经路径上。
- 只读工具(
Read、Grep、联网搜索等)直接跳过;没改任何文件的调用不会产生条目。
保留与磁盘占用
快照被有意设计成短生命周期 —— 它是审阅辅助,不是备份:
- 历史保留 7 天(按天分支;过期的天被删除、对象立即回收)。
- 30 天没有动静的项目,影子仓库整个移除;项目目录已不存在的同样移除。
- 体积守卫防失控:超过 2 MB 的单文件跳过;一次变更超过 5 万文件或 1 GB 时暂停该项目的快照(写日志告警),不吃掉你的磁盘。
- 实际开销很小:一个 13 GB 的 monorepo(可跟踪源码约 100 MB)压缩后影子仓库约 74 MB,之后每次快照只存变化的文件(每次工具调用约 80 ms)。
需要调参的话用环境变量 —— 见 CLI 参考:COCKPIT_SNAPSHOT_KEEP_DAYS、COCKPIT_SNAPSHOT_REPO_TTL_DAYS、COCKPIT_SNAPSHOT_MAX_FILE_KB。
多会话并发
同一项目目录可以同时跑多个会话。快照按目录共享一条时间线,归因是尽力而为:工具明确声明过的文件(如 Edit 的目标)正常展示;同一窗口内变化但未被声明的文件带紫色同期变更标记 —— 多半来自另一个会话或外部进程。Bash 不声明任何文件,窗口内的全部变化都记给这次调用。