这是 GrapeClip 官方博客的第一篇文章。趁着项目开源发布,我想把「为什么要做这样一个工具」记录下来——既是给未来的自己一个交代,也希望能让你了解这个项目背后的想法。
Universal Clipboard 很好,但它有边界
我平时会在多台设备之间切换:写代码的 Mac、桌上的另一台电脑、口袋里的手机。跨设备搬运一段文本,是每天都会发生几十次的事情。
如果你的所有设备都在 Apple 生态里,Universal Clipboard(通用剪贴板)确实很方便:在 Mac 上复制,在 iPhone 上直接粘贴,几乎无感。但用久了,它的边界也很清楚:
- 必须登录同一个 Apple ID。 工作机和个人机账号不同?公司电脑不让登私人账号?那这个功能就与你无关了。
- 它时不时会失效。 用过的人大概都遇到过:复制了半天,另一台设备上粘出来的还是旧内容。它失效时不报错、不提示,你只能反复重试,或者干脆放弃,把内容发到聊天软件里再自己复制一遍。
- Android 完全被排除在外。 只要你的设备组合里有一台 Android 手机,整个体验就断裂了。跨生态的用户没有选择。
所以我想要的第一件事很朴素:一个不挑账号、不挑系统、行为可预期的剪贴板同步。macOS、Windows、Linux、Android,复制即同步,粘贴即到达。
剪贴板不起眼,但它值得被记录
第二个原因,是我一直希望有一个持续记录剪贴板历史的工具。
剪贴板大概是操作系统里最不起眼的组件之一:没有界面,没有历史,只保留最后一次复制的内容。可仔细想想,它承载的东西一点都不轻——临时记下的一段话、改到一半的代码、别人发来的地址、一个再也找不回来的 token。系统默认「复制一次就覆盖上一次」,意味着这些内容随时都在无声地丢失。
对我来说,剪贴板历史不是锦上添花,而是基础设施:它应该像 Shell 的 history 一样,默默地、完整地存在着,需要的时候随手可查。
Atuin 给我的启发
真正让这个想法落地的,是 Atuin。
Atuin 是一个 Shell 历史同步工具:它在后台默默记录你敲下的每一条命令,把历史存进本地 SQLite,再通过端到端加密同步到你的其他设备。用了一段时间之后,我意识到一件事:
如果 CLI 命令历史可以这样被记录和同步,剪贴板不也是一样的吗?
两者的形态几乎是同构的:都是一条条按时间产生的小记录,都需要在后台无感地采集,都涉及隐私所以必须端到端加密,都要在多设备之间增量同步。Atuin 已经把这套机制打磨得很成熟——客户端加密、服务端只存密文、按记录(Record)增量上传下载。
所以 GrapeClip 的同步层直接借鉴了 Atuin 的机制:服务端抽取自 Atuin 的 Record Store 模型,客户端用本地主密钥(只存在设备的 Keychain / SecureStore 里)经 HKDF 派生数据密钥,逐条用 XChaCha20-Poly1305 加密后上传。服务端是零知识的——它只见密文,不可能读到你的剪贴板内容。
就像 Atuin 在后台默默记录 Shell 命令一样,GrapeClip 在后台默默记录你的剪贴板历史,并把它安全地带到你的每一台设备上。
所以,GrapeClip 是什么
把上面三个动机合起来,就是 GrapeClip:
- 跨平台:macOS / Windows / Linux 桌面端(Tauri),Android 移动端(React Native),iOS 在规划中;
- 端到端加密:主密钥只存在你的设备里,服务端零知识,且服务端开源、可自托管;
- 历史完整:不只同步「最后一次复制」,而是持续记录你的剪贴板历史,随时可搜可翻。
项目已经在 GitHub 上开源。如果你也被 Universal Clipboard 的边界困扰过,或者也觉得剪贴板这个不起眼的工具值得更好的对待,欢迎试用,也欢迎提 Issue 和 PR。
这是第一篇,之后我会在这里继续记录 GrapeClip 的设计取舍与开发进展。