我为什么要做 Chronicle
Chronicle 始于一个简单的想法:Windows 的 Copilot Recall 其实是个很有用的点子。
能够核实我在某个特定时间点正在做什么,听起来很棒。我可以证明我提交或做过某份学校作业,找回某个随机下午的上下文,总体上让自己对数字生活的记忆比平时好得多。但是……我用的是 Linux。不仅如此,即使微软最终把 Recall 带到了 Linux,我也不想用。我不信任微软能掌握这种程度的数据,也不想让他们对我的行为有那么多洞察。
所以我决定打造我自己的版本:精神上是本地优先,存储自托管,从头到尾都在我的掌控之下。
朴素的开端
最初的项目叫"Recall"(没错,命名非常有创意),是一个典型的"先跑起来再说"的 MVP:
- 一个 shell 脚本
- 用
scrot截图(我当时在 Mint 上用 X11) - 固定的截图设置
- 用
curl直接上传到 Immich - 还有一个硬编码的 API 密钥(天哪)
我给它配了一个小小的 systemd 上传服务和定时器,就算大功告成了。
它很粗糙,但很管用:定期截取屏幕,每小时把结果上传到 Immich,剩下的交给 Immich 去处理。
为什么 Immich 是愿景的重要组成部分
从第一天起,一个关键的动机就是 Immich。
我已经信任它,也已经喜欢它的自托管模式,而且我真的很想借助它的机器学习功能来做搜索和整理。我不必从零构建一个庞大的时间线后端,可以让 Chronicle 专注于采集、元数据和可靠性,而把媒体管理和发现交给 Immich。
这个架构决策现在看来依然正确。将来,我其实更愿意开发自己的时间线后端,而不依赖 Immich(比如为了去重),但那是个大得多的项目。
X11 很简单,但 Wayland 让我低头认输。
当时我用的是 X11,所以 MVP 很快就跑起来了。后来,在我无穷的"智慧"驱使下,我切换到了 Wayland 上的 TuxedoOS,然后一切都坏掉了。
我当然还是想要 Recall,而且我计划在不久的将来启动一个大得多的 Rust 项目,于是我把它当作练兵场:用 Rust 重写 Recall,把它做好,并学习这个生态。
我低估了这件事的工作量。我不得不深入研究显示服务器之间的差异、备用的截图策略、系统集成细节、IPC 模式,以及所有那些让长期运行的工具变得可靠的"小"边界情况。我还得把 Rust 学得足够深,才能不再与它对抗,而是真正用好它(感谢你,rustfmt!)。
这很不容易,但这份挑战正是意义所在。
从脚本到真正的产品
如今的 Chronicle 远不止最初那个脚本。
它支持多种截图途径,因此可以在现代 Linux 环境中运行:
- 可用时使用 Wayland 原生截图
- XDG portal 备用方案
- 为较旧或特殊的环境提供 X11 备用方案。
此外,它还包含自适应截图逻辑,避免保存/上传几乎相同的画面,这对长时间线的存储和带宽来说意义重大。不过实际上,即使我的四显示器配置会产生巨大的图片,.webp 压缩也让它们变得很轻:每天 8 小时、每 30 秒截一次图,整整一年在 Immich 里只占大约 60 GB,对我的自托管环境来说完全可控。
然后是我在 v0 里没有的可靠性工作:本地队列、重试,以及通过 CLI 健康/状态命令提供的运行可见性。
设置流程也从"改个脚本然后祈祷"发展成了基于向导的体验,以引导的方式处理重要的部分。我最喜欢的升级之一是安全方面:Chronicle 现在使用 keyring 的 API 密钥处理器和更安全的认证流程,而不是在脚本里硬编码凭据。
这听起来理所当然,但我是先做了错误的版本,才真正在乎把事情做对。
暂停、恢复与控制
当我需要离开电脑好几个小时,比如渲染 3D 动画的时候,我不希望 Chronicle 记录那段时间的每一分钟。为此,Chronicle 提供了暂停/恢复功能,让你可以在需要时主动停止截图。
同样,状态和健康命令让整个系统保持透明。如果这个工具整天在后台运行,你应该能够核实它在做什么,而不用靠猜。
为更大的 Rust 项目做准备
Chronicle 是一个技术项目,但对我来说它也是个人基础设施。它能帮助解决一些实际问题,比如证明学校作业的时间线、在被打断后找回上下文,或者弄清楚在某个感觉很混乱的日子里时间究竟是怎么花掉的。
但它也代表了一个我最近越来越看重的原则:如果一个工具处理敏感的行为数据,那么所有权和信任边界就不是可有可无的细节。我最初把这次重写定位为 Hyprcontact 之前的 Rust 练习,但 Chronicle 本身成了一个严肃的项目,也成了比任何玩具应用都好得多的 Rust 老师。
结语
Chronicle 的存在,是因为我想要一个有用的记忆工具,而不必把信任外包出去。如果这引起了你的共鸣,尤其是你已经在运行 Immich 并且重视本地控制,那么 Chronicle 也许同样适合你的环境。
源代码与发布: