Chronicle 的 Logo 叠在模糊的 Immich 时间线截图上

2026年3月6日 • 更新于 2026年3月7日

Chronicle:为 Linux + Immich 打造我自己的 Recall

从一个随便写的 shell 脚本,到注重隐私的 Rust 时间线工具。

技术: Rust, Linux, Immich, Systemd, CLI
Link: 源代码

我为什么要做 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(比如为了去重),但那是个大得多的项目。


Immich 中的 Chronicle 时间线
Immich 中的 Chronicle 时间线

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 设置向导
Chronicle 设置向导


设置流程也从"改个脚本然后祈祷"发展成了基于向导的体验,以引导的方式处理重要的部分。我最喜欢的升级之一是安全方面:Chronicle 现在使用 keyring 的 API 密钥处理器和更安全的认证流程,而不是在脚本里硬编码凭据。


这听起来理所当然,但我是先做了错误的版本,才真正在乎把事情做对。

暂停、恢复与控制

当我需要离开电脑好几个小时,比如渲染 3D 动画的时候,我不希望 Chronicle 记录那段时间的每一分钟。为此,Chronicle 提供了暂停/恢复功能,让你可以在需要时主动停止截图。


Chronicle 中的暂停与恢复
Chronicle 中的暂停与恢复


同样,状态和健康命令让整个系统保持透明。如果这个工具整天在后台运行,你应该能够核实它在做什么,而不用靠猜。


状态命令输出
状态命令输出


健康命令输出
健康命令输出

为更大的 Rust 项目做准备

Chronicle 是一个技术项目,但对我来说它也是个人基础设施。它能帮助解决一些实际问题,比如证明学校作业的时间线、在被打断后找回上下文,或者弄清楚在某个感觉很混乱的日子里时间究竟是怎么花掉的。


但它也代表了一个我最近越来越看重的原则:如果一个工具处理敏感的行为数据,那么所有权和信任边界就不是可有可无的细节。我最初把这次重写定位为 Hyprcontact 之前的 Rust 练习,但 Chronicle 本身成了一个严肃的项目,也成了比任何玩具应用都好得多的 Rust 老师。

结语

Chronicle 的存在,是因为我想要一个有用的记忆工具,而不必把信任外包出去。如果这引起了你的共鸣,尤其是你已经在运行 Immich 并且重视本地控制,那么 Chronicle 也许同样适合你的环境。


源代码与发布:


微信联系

扫一扫,添加我的微信

扫描二维码添加我的微信
微信号