dsh-safe-delete
在工具守护层拦截任何 DSH 智能体会话(GUI、自动化运行、无头桥接)发出的 `rm` 命令,并将目标移动到 macOS 废纸篓,而不是直接删除。
AI 分析
核心用途是拦截智能体执行的 `rm` 命令并移至 macOS 废纸篓以防误删。适合在 macOS 上运行 DSH 且需要安全防护的用户。
安裝
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:NattoCB/dsh-safe-delete說明文件
閱讀完整 README ↗dsh-safe-delete
A DeepSeek Harness host-side plugin that makes rm issued by any agent session recoverable: instead of deleting, targets are moved to the macOS Trash.
How it works
The plugin registers one global tools guard on the DSH tools registry. Every bash tool call — GUI sessions, scheduled automation runs, headless bridges, subagents: anything the registry serves — is scanned with a shell-aware lexer for an rm command in command position (rm, sudo rm, /bin/rm, xargs rm, after env/nice-style prefixes and VAR=x assignments).
When one is found, the plugin denies the original command, rewrites the rm invocation to /usr/bin/trash -v (flags stripped; quoting and globs survive because the rewritten command is re-executed by bash -c), runs the trash itself, and reports back to the model:
[dsh-safe-delete] intercepted `rm` — the targets were MOVED TO TRASH (recoverable),
not deleted. Original command denied. Targets: build/ dist
trash: build/ → .Trash/build/
Plain non-rm commands pass through untouched. Commands that merely mention rm (echo rm, grep "rm " log) are ignored. Constructs that could hide an rm behind a string the lexer refuses to rewrite — $(...), backticks, subshells, heredocs, eval, nested sh -c 'rm ...' — are denied with guidance to split the command into plain form; nothing is executed and nothing is deleted.
Scope and limits
- Covered: any
rm/sudo rm/absolute-pathrm/xargs rmin command position, in simple and compound commands (&&,||,;,|). - Not covered:
find -delete,unlink, language runtimes' own file APIs,git clean, and other non-rmdeletion paths. The guard is an accident-prevention net for the most common destructive verb, not a sandbox. rmflags (-f,-r, ...) are stripped rather than honored:trashmoves whole directories natively, and a failed trash (e.g. nonexistent target) is reported instead of silently ignored, sorm -f maybe-existsstyle calls surface an explicit report.sudo rmis intercepted at the guard layer (before sudo ever runs), but deleting files that require root to trash can still fail — trash errors are reported verbatim.
Install
dsh plugin --profile web add github:/dsh-safe-delete
Restart the DSH web process — host-side bundles and their patches load at process start. On boot the plugin logs rm guard active once.
Development
npm test # node --test: lexer, rewrite matrix, guard contract
The lexer/rewriter is exported as exports._internals so tests exercise the real code paths (analyzeCommand, tokenize, splitSegments).
License
MIT