一个自用剪贴板工具的两天:先找现成的,再自己造
我们想要一个能固定、能拖拽排序、Mac 和 Windows 都能用的剪贴板历史工具。先核对现成方案,再选型,一个晚上做出能用的版本并在真机上验收;第二天边用边提,又连加了五项功能。本文写这两天里的分工和体会。
先说结论
- 我们先核对了现成方案:CopyQ 功能上满足全部要求,但 macOS 包每次安装和升级都要手动解除隔离、重新签名,Windows 上的固定功能要另装插件;逐条拍板后,我们决定用 Tauri 2 自己做,一份代码覆盖 Mac 和 Windows。
- 9 月 28 日 20:30 拍板,21:04 在真机上验收通过;第二天边用边提,又加了截图图片、悬停显示大图、多列展示、固定窗口、记住窗口大小和位置五项。
- 分工是三个角色:我们提需求、拍板、真机验收;Claude Code 作为执行器写代码;APSer-Atelier 作为主控负责组织,登记每件事、挂起待拍板的问题、记下每一条要求,两天里用钩子当场拦下 7 次出错。
- 自己做一个小工具的门槛低了,核对的功夫省不了:人在界面上说「好了」,和产物里真的存对了,是两件事,要分开核对。
我们每天复制粘贴的东西很杂:命令、路径、客户资料里的一段原文、聊天里的截图。其中有几条会反复用,希望它们固定在最上面、不被新内容挤走,顺序也能自己排。
9 月 28 日晚上,我们决定解决这件事;到 29 日傍晚,一个叫「智能剪贴板」的自用小工具已经装在 Mac 上每天在用。本文写这两天:先核对要不要自己做,再选技术路线,一个晚上做出能用的版本,第二天按使用中的感受连续改了几轮。
这件事里有三个角色。我们负责提需求、拍板和在真机上验收;AI 编程工具 Claude Code 作为执行器,负责查资料、写选型文档和写代码;我们自研的工作平台 APSer-Atelier 作为主控,负责组织:建项目、登记、把每件事从提出到验收串成一条记录、挂起待拍板的问题、记下每一条要求,并用钩子在出错的当下拦住。主控只做组织,代码由执行器写。平台的来历见《APSer-Atelier 的场景锚定与价值定位,以及实践总结》,钩子的做法见《从记忆、规则到钩子》。
这里说的 APSer-Atelier 主控包括两部分:面对我们的主控会话(一段 Claude Code 或 Codex 对话),负责组织和派出;Atelier 平台,负责登记每一件事、挂起待拍板、记下要求、按规矩放行并留下记录。
一、该找现成的,还是自己造?
需求只有几句:保存多条剪贴板历史,能固定、能删除、能拖拽排序;Mac(macOS 27,Apple 芯片)和 Windows 11 都要能用;自己用,不对外发布。
28 日 19:01,Atelier 作为主控,建好项目并登记。Claude Code 作为执行器,先做的一件事是核对现成方案,把结果写成一份选型文档,19:08 提交:
| 方案 | 平台 | 固定 | 拖拽排序 | 核对结果 |
|---|---|---|---|---|
| macOS 聚焦搜索里的剪贴板历史 | Mac | 否 | 否 | 最多保留 7 天 |
| Windows 11 的 Win+V | Windows | 是 | 否 | 系统自带 |
| Paste | 仅苹果平台 | 是 | 是 | 付费订阅,不覆盖 Windows |
| Maccy | 仅 Mac | 是 | 文档中未找到 | 开源 |
| CopyQ | Mac、Windows、Linux | 是 | 是 | 开源,功能上完全满足 |
CopyQ 功能上满足全部要求,文档把它作为一个正式选项写了出来。当时核对到的情况是:它的 macOS 包没有通过系统的安全检查,Homebrew 已于 2026 年 9 月 1 日停止提供,安装和每次升级都要手动解除隔离、重新签名;Windows 上的固定功能要另装插件;界面面向通用场景,配置项较多。
对照我们的用法:我们只想要「固定 + 拖拽」这一个场景,希望两台机器上的体验一致,也不想每次升级都手动处理签名。文档最后列了八个待拍板的问题,每个都写了选项和代价:用现成的还是自己造、技术路线、Windows 包怎么构建、选中后是否自动粘贴、先支持哪些内容类型、历史保留多少条、快捷键、存储是否加密。
20:30,我们逐条拍板:自己做;用 Tauri 2;选中后只写回剪贴板,由自己按粘贴;先只做纯文本;未固定的保留最近 500 条;Mac 用 ⌥⌘V 呼出;数据用本机数据库文件,只有本人可读。Windows 包怎么构建先不定,先把 Mac 做出来。
二、技术路线怎么选,才能一份代码覆盖两个平台?
Tauri 2 用系统自带的网页引擎显示界面,底层用 Rust。选它的理由写在文档里,归结为一条:这个工具的主体(历史列表、固定、删除、拖拽、清空、存储)两个平台完全一样,真正要分平台写的只有三小块:监听剪贴板、识别密码类敏感内容、写回剪贴板。一份代码覆盖两端,常驻后台的包体和内存也小。
安全要求在动手前就定了:不联网,界面用到的字体和图标全部放在本地;密码管理器复制的内容带有约定的「机密」标记,看到标记就不读内容、不入库;清空后压缩数据库,不留可恢复的残页;日志只记时间、类型和长度,不记内容。
三、一个晚上,怎样从拍板走到真机验收?
20:30 拍板,21:04 我们在真机上回复「验证通过」,21:07 提交。这一版有:多条历史、固定、删除、拖拽排序、搜索、全局快捷键、敏感内容跳过、一键清空、菜单栏常驻、开机自启开关。现在的代码量是 Rust 约 1100 行、前端约 750 行。
这一晚有几件事值得记下来。
真机上才发现的问题。 剪贴板监听本来放在后台线程里,每半秒读一次系统剪贴板的变更计数;实测后台线程读到的计数不刷新,复制了新内容也察觉不到。改成后台线程只负责计时、到点投递到主线程去读,才正常。另一处是窗口:失焦就收起的弹窗,第一次点击只会激活窗口,要点两次才生效,打开对应的窗口选项后解决。这两件事在文档里都查不到结论,只能靠真机试出来。
敏感内容用真的密码管理器验证。 验收时我们用日常使用的密码管理器复制了一次密码,确认它没有进历史。测试工具模拟的标记只能说明代码按标记判断了;真实的密码管理器会不会写这个标记,要用真的去复制一次才知道。
界面验收交给人。 验收过程中,Claude Code 为了测界面,用桌面自动化接管了我们的屏幕去点击。我们当场反对。此后定下一条规矩:需要点界面的验收项列出来由我们自己点;AI 只读数据库和日志做核对,不再接管桌面。分工因此更清楚:AI 核对入库、去重、敏感跳过、清空后数据库文件里有没有残留、文件权限、进程有没有网络连接;我们在界面上核对固定、删除、拖拽、重启后顺序是否保持、选中后能不能粘贴。
21:10 前后,Windows 包的构建方式作为一个待拍板的问题登记在 Atelier 里,两个选项各写了代价。我们的答复是「先记录,不动」,当晚就先在 Mac 上用起来。
四、用了一天,又提出了哪些改动?
用了一天,问题自己冒出来了。29 日 17:2x,我们提出:截图复制之后,历史里没有。
Claude Code 没有先写代码,先实测:在后台记录每次复制时剪贴板里有哪些类型,只记类型名,不读内容。结果是,我们实际唯一使用的截图方式(微信截图)只提供 TIFF 格式的图片,不带 PNG。据此定下判定顺序:带敏感标记的一律跳过;有文字就按文字;带文件地址的不入库(在访达里复制文件时附带的图片其实是文件图标);最后才按图片处理,TIFF 转成 PNG 保存。实测 4 次截图,0.3–5.0 MB 的 TIFF 转成 54–318 KB 的 PNG。系统截图、浏览器「拷贝图像」等其他来源没有实测,文档里明写「未实测,按默认规则处理」。
图片功能 18:06 提交,旧数据库原地升级,已有的 34 条历史和顺序都保留。之后半小时里,我们一边用一边提:
- 18:09 看到缩略图偏小:「悬停显示大图」。鼠标在缩略图上停 300 毫秒,窗口里铺满显示原图。
- 窗口拉宽后希望多列展示:列表改成按列宽自动加列。
- 点选一条后窗口就收起,连续取几条不方便:加一个固定窗口的开关,开着时选中不收起、窗口置顶。
- 这三项 18:14 提交。18:20 又提出「加上记住窗口大小和位置」,18:23 提交。
18:37,我们回复「都测试ok」。
五、说了「都测试ok」之后,还要核对什么?
回复「都测试ok」之后,Claude Code 照例去查数据库,发现窗口位置并没有存下来。原因是:窗口位置只在窗口收起和退出时保存,而我们一直开着固定窗口,窗口从不收起,一旦进程被结束或者重启机器,位置就丢了。
界面上看不出这个问题:窗口就在我们刚拖到的位置。改成拖动或缩放停下后就保存,18:40 提交;AI 连续两次重启应用,日志里两次都恢复到了我们拉宽后的位置。
这件事让我们更确定一点:人在界面上说「好了」,和产物里真的存对了,是两件事,要分开核对。
六、钩子拦下了哪 7 次?
两天里,钩子在当下拦住了 7 次,都是 AI 自己没有察觉的:
| 时间 | 拦下了什么 | 为什么要拦 |
|---|---|---|
| 28 日 20:50 | 手写循环等待后台任务 | 等待时间长了会被转入后台,再开一个就成了重复等待;改用有上限的等待脚本 |
| 28 日 21:08 | 工具调用之间的叙述写成了英文 | 我们要求思考和叙述一律用中文 |
| 29 日 17:29 | 还没登记这件事,就要改代码仓 | 改仓之前必须先在平台上持有一件事,谁在改什么才看得见 |
| 29 日 17:30 | 我们提了要求,收尾时要求记录还是空的(两次) | 每一条要求都登记一笔,状态随进展更新,免得做着做着漏掉 |
| 29 日 18:06 | 提交时「全部添加」 | 只能逐个写明本次改过的文件,免得把别处的半成品带进提交 |
| 29 日 18:23 | 收尾登记没有串在提交成功之后 | 提交失败时也会照样登记「已完成」 |
这些要求都早就写在说明文件里。7 次里有几次即使没拦也不会出事,例如「全部添加」那次,仓里并没有别处的改动;拦下的好处是不用事后逐条去查。写下来的要求只能提醒;拦截点放在出错的那一刻,才管得住。
七、主控在这两天做了什么?
写代码的是 Claude Code;这两天里没有写一行代码、却一直在场的,是作为主控的 APSer-Atelier:
- 建项目、登记。 28 日 19:01,项目在 Atelier 里建好并登记,之后每件事都挂在这条记录上:什么时候提出、交给谁做、做到哪一步、验收结果如何。
- 挂起待拍板的问题。 Windows 包怎么构建,登记成一条待拍板的问题,两个选项各写了代价;我们答复「先记录,不动」,它就一直挂在那里,不会被忘掉,也不会被执行器自己替我们定了。
- 记下每一条要求。 我们在对话里提的每一条要求,都要登记一笔,状态随进展更新;漏了登记,收尾时就会被钩子拦下(见上一节)。
- 管住谁能改。 改代码仓之前,必须先在 Atelier 上持有这件事;同一个项目同一时间只允许一路在改。
- 当场拦下出错。 上一节那 7 次,都是 Atelier 登记在案的钩子拦下的,拦在出错的那一刻,而不是事后翻记录。
执行器可以换,这件事的记录、要求、待拍板的问题和规矩都留在 Atelier 和项目仓库里;下次换一个执行器接着做 Windows 端,从同一条记录往下走即可。
八、还有哪些没做?
- Windows 端:暂停。构建方式的问题还挂着没拍板,监听与敏感格式识别的 Windows 部分还没写。
- 开机自启:开关做了,还没有单独登出再登录验证过。
- 常驻内存:窗口隐藏时占多少内存,还没实测。
- 不联网:做过进程网络连接的快照检查,还没有全程抓包。
- 图标:还是框架默认图标。
选型文档当时估的自研代价是一个开发周期左右,包括两端验收。Mac 端实际一个晚上就能用了,Windows 端还没开始,这个估算现在还验证不了。
以下是我们的看法
自己做一个小工具的门槛低了,核对的功夫省不了。 两天里写代码花的时间很短,查现成方案、定安全要求、实测剪贴板里到底有什么、确认存下来的数据对不对,这些才是占时间的部分。先找现成的这一步我们没有省:现成方案能满足的话,用现成的更省心。
需求在用的过程中长出来。 第二天加的五项,没有一项是动手前想到的。一个晚上先做出能用的版本,装上用起来,比先把需求想全更快接近真正要的东西。
主控让执行器的速度落在秩序里。 一个晚上从拍板到真机验收,快的是执行器;要求有记录、待拍板的问题不被悄悄替我们定掉、出错当场被拦下,靠的是主控。执行器越快,越需要一个只做组织、不写代码的主控。
人把时间花在拍板和验收上。 八个问题逐条拍板、在真机上点一遍界面、看数据有没有存对,这几件事 AI 替代不了。反过来,核对资料、写代码、查库、读日志,交给 AI 连续做完,我们只在关键时点介入。
如果您也在考虑让 AI 帮您做一个自用的小工具,可以先问自己三件事:现成的真的不能用吗?做出来之后,怎么证明它存下来的东西是对的?哪些验收必须您自己在真机上点?