最近我在用 WorkBuddy 干活,发现了一个挺有意思的细节。
它产生的临时文件,用完删掉之后,文件不会消失——而是进了废纸篓。而且它的临时文件都就近放在当前工作目录里,不像我平时用的 opencode,动不动就在 /tmp 下面拉一堆东西。
整个流程很干净。这个 Harness 在”删除”这件事上做得挺讲究。
这个细节让我为之点赞。
我平时的主力是 opencode,配着 Paseo 一起用。Agent 干活时删文件是家常便饭——清中间产物、重跑一遍、删掉不再需要的脚本。但Agent 删文件和人删文件是两回事:
人删之前会看一眼路径,会犹豫一下。Agent 不会。它的路径是拼出来的,变量是从上下文里猜的。路径一旦拼错,rm -rf 下去的瞬间东西就没了,没有第二次机会。
所以真正的问题不是”该不该让 Agent 删文件”,而是”能不能让删除变得可撤销“。
WorkBuddy 用的是废纸篓。那 opencode 这边能不能也这么干?
顺手一查,答案比我想的简单:macOS 15 起,系统自带了一个 trash 命令。
系统自带的trash命令
/usr/bin/trash
这个二进制是 Apple 签名的(com.apple.trash),受 SIP 保护,挂在只读系统卷上——你删不掉它,也不需要维护它。手册页在 man trash。
只有一个前提:macOS 15 Sequoia 及以上才有。
这里有个坑:trash 的 man page 在 HISTORY 里写的是 First appeared in macOS 14.0,这是 Apple 自己写错的。社区实测 Sonoma 14.6.1 和 14.8 上并不存在这个命令,Tahoe 的 man page 已经改口说是 Sequoia 加入的。所以如果你的 Mac 上没有 trash,先 sw_vers 看一眼版本,大概率是系统比 15 老。
用法
语法极简:
trash 文件或目录...
目前实测下来它的行为和Finder里的删除行为一致,可以删文件、删目录、删替身、删软链接。
给 Agent 配上
在项目的 AGENTS.md 或 CLAUDE.md 里写一句就行:
## 文件删除安全
- 删除操作一律使用 `trash` 命令把文件移入废纸篓,不要用 `rm` 永久删除。
- 仅当明确要求永久删除时,才使用 `rm`。
我自己的全局配置里就是这么写的。
好消息是这套规则跟 harness 无关——trash 就是个普通 Unix 命令,任何能跑 shell 的 Agent 都能用,区别只在规则往哪个文件里写。
不过要清醒一点:规则文件是软约束。 写”禁止用 rm”,靠的是模型自觉。上下文一长,或者模型自己判断”这就是个临时文件”,照样可能直接 rm。要硬保证,得在 harness 的权限层再拦一道,把 rm 类命令设成需要确认。软规则管习惯,硬拦截兜底。
两点提醒
废纸篓不是”不删除”,只是”延后删除”。 Agent 跑批量任务时可能删掉成百上千个文件,废纸篓会在你没注意的时候膨胀到几十 GB。定期清空它,或者跑完任务后扫一眼。
找回靠 Finder。 打开废纸篓 → 选中文件 → 右键”放回原处”。注意如果原目录已经不存在,这个选项会失效,得手动拖回去。
老系统怎么办
如果 Mac 停在 Sonoma 或更早,两个选择:
brew install trash(Ali Rantakari 那个版本)。注意它是 keg-only,而且和macos-trash、osx-trash、trash-cli三个包冲突——它们都占trash这个名字。- 或者用
osascript让 Finder 代劳,不用装任何东西:
osascript -e 'tell application "Finder" to delete POSIX file "/path/to/file"'
总之就一句话:能用 trash 的地方,别用 rm。 尤其当对面敲命令的是个 AI。