最近我在用 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.mdCLAUDE.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-trashosx-trashtrash-cli 三个包冲突——它们都占 trash 这个名字。
  • 或者用 osascript 让 Finder 代劳,不用装任何东西:
osascript -e 'tell application "Finder" to delete POSIX file "/path/to/file"'

总之就一句话:能用 trash 的地方,别用 rm 尤其当对面敲命令的是个 AI。