NattoCB/dsh-safe-delete0

dsh-safe-delete

Intercepts `rm` commands issued by any DSH agent session (GUI, automation runs, headless bridges) at the tools guard layer and moves the targets to the macOS Trash instead of deleting them.

AI 分析

核心用途是拦截智能体执行的 `rm` 命令并移至 macOS 废纸篓以防误删。适合在 macOS 上运行 DSH 且需要安全防护的用户。

パッケージ
dsh-safe-delete
バージョン
0.1.0
ライセンス
MIT
最終更新
2026/09/01

インストール

$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-path rm/xargs rm in command position, in simple and compound commands (&&, ||, ;, |).
  • Not covered: find -delete, unlink, language runtimes' own file APIs, git clean, and other non-rm deletion paths. The guard is an accident-prevention net for the most common destructive verb, not a sandbox.
  • rm flags (-f, -r, ...) are stripped rather than honored: trash moves whole directories natively, and a failed trash (e.g. nonexistent target) is reported instead of silently ignored, so rm -f maybe-exists style calls surface an explicit report.
  • sudo rm is 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