Vault Change Feed 2.0:实现根据设备各自记录日志
Vault Change Feed 2.0 replaces a shared log with per-device event streams. This post explains reader cursors, deduplication, and when incremental reading must fall back to a full scan.
最开始写Vault Change Feed的时候,就是为了让AI每次对话前不用说明我修改过的文件。但是在使用云同步的情况下,我发现文档内容和日志之间可能会存在覆盖的情况。
一份共享日志遇到多台设备
早期版本把事件写进日志,而日志文档也进行云同步。为了避免两个实例同时写,1.2 加过心跳写者锁;1.3 又补了抢占后的回读验证和写前检查,失去写入权的实例退到待机。
这些改动有用,但它们的前提是同一时间只能有一个写者。云同步有延迟,两台设备对谁正在写可能有不同判断。重复序列、重复事件,都需要处理。
9 月 8 日记录的 2.0.0 ,我对结构进行了修改,每台设备只追加自己的日志,读取时再合并。
日志怎么分开
现在每台设备有自己的日志文件:
hljs textvault-change-feed/ ├── devices.json ├── events/ │ ├── device-a.jsonl │ └── device-b.jsonl └── cursors/ ├── codex.json └── claude-code.json
电脑写电脑的,手机写手机的。即使两边都写到了第 100 条,也不会因为编号一样就混在一起。
AI 读取时再把这些文件合起来。它的游标也要跟着改,分别记住每台设备读到了哪里。比如电脑读到 100,手机读到 30,下次就各自从这个位置往后读。
Codex 和 Claude Code 也各有自己的游标文件。Codex 看过的内容,Claude 不一定看过,不能共用一个进度。
同一次修改记了两遍怎么办
我在电脑上改一篇笔记,同步到手机后,手机也可能记下这次变化。这样合并日志时就会出现两条。
所以事件里增加了内容哈希。读取时先按时间、设备和序列排序;创建和修改事件如果路径、操作、内容哈希都相同,就只留第一条。
同一篇笔记改了两次,内容不同,还是要保留。没有哈希的事件也不能直接套这个去重规则,删除和重命名另外处理。这个顺序用于整理日志,不能靠它判断两台设备上所有操作的严格先后。
太久没读,还是得重新扫描
日志不会一直无限保存。如果 AI 上次读到第 100 条,回来时日志已经从 150 开始,中间那部分就没了,不能跳过去当作什么都没发生。
这种情况,或者插件发出了 resync 事件,就需要重新扫描知识库。读完多少条,游标就记到多少条,不能提前把后面的也标成已读。
2.0 的读取方式变了,旧的读取脚本也要更新。迁移前会自动备份旧日志,但新格式不向后兼容。
这次主要改的就是这一块。原来不断补“谁可以写”的判断,现在让设备分开写,把合并放到读取的时候处理。插件只记变更,笔记的同步还是交给 iCloud 等原有工具。