dshbase

插件目录 / Developer / dsh-trash

dsh-trash

已验证 · 实测可装 LeonSone

✓ 持续维护

查看 GitHub ↗ ← 返回插件目录

0Stars
0Forks
0未关闭 issue
—语言
2026-08-22最近推送
跨平台平台

功能简介

A DeepSeek Harness (DSH) plugin: every delete operation goes through a recoverable trash store — accidental deletes are one restore away.

✅
我们的评价
可用 — 实测通过,早期项目

A DeepSeek Harness (DSH) plugin: every delete operation goes through a recoverable trash store — accidental deletes are one restore away. 实测能干净安装、正常启动。早期项目,但功能可用。

「已验证」表示我们的自动化 CI 在干净 profile 里实际执行了 dsh plugin add 并启动成功——仅此而已。功能描述与版本兼容性均为作者声明。这不是安全审计,也不代表对第三方代码的背书。

README

dsh-trash

English | 中文

A DeepSeek Harness plugin that turns every delete operation into a recoverable trash move — even under the highest permission (danger-full-access). Accidentally deleted something? Restore it in one call.

  • Intercepts delete commands in the pwsh / bash / run_code tools (Remove-Item, rm, del, rd, rmdir, unlink, [System.IO.*]::Delete, fs.unlink/rm/rmdir, os.remove, shutil.rmtree, …) at the tool pipeline's tools/pre-execute gate, denies them, and guides the model to the trash tools.
  • Ships 4 tools: trash (delete = move to trash), trash-list (inspect), trash-restore (recover), trash-purge (confirmed permanent cleanup — the only path that truly deletes).
  • Zero runtime dependencies (Node built-ins only), installable from anywhere (registry / file: / link: / GitHub).

How it works

Layer What happens
Interceptor A tools/pre-execute listener (prepended, so it runs first) scans pwsh.command, bash.command, and run_code.code for delete patterns. On a hit it returns { kind: "deny" } — denials are monotonic, so no later stage (approval, guard, dispatch) can let the call through. The model sees an actionable message telling it to use trash instead.
Trash store Each "delete" becomes one entry under the trash root (default $DSH_HOME/trash): data/ keeps the original names, meta.json records original paths, timestamps, sizes, and an optional reason. Cross-volume moves degrade to copy-then-clean.
Tools trash / trash-list / trash-restore / trash-purge — see below.
<trashRoot>/
  <entryId>/
    data/...        the "deleted" files & directories (original names preserved)
    meta.json       original path, deleted-at, size, reason

Installation

# From a local checkout (dev / link mode — edits to the source take effect immediately)
dsh plugin --profile web add link:D:/path/to/dsh-trash

# Or straight from GitHub (requires git + a GitHub token on this machine)
dsh plugin --profile web add github:LeonSone/dsh-trash

dsh plugin add adds the package to the profile's dependencies; because the package declares dsh.bundle, it is automatically appended to dsh.profile.bundles. Restart dsh web (or the headless runner) for the plugin to load.

Headless profile: dsh plugin --profile headless add <spec> — same flow.

Usage

Once installed, the model's behavior changes automatically:

Scenario Behavior
Model runs Remove-Item / rm / del / … Blocked with a message explaining the trash workflow
Model calls trash(paths=[...]) Files/dirs move into the trash (recoverable)
Accidental delete trash-restore(entry_id=...) restores to the original path; or trash-restore(path="<substring of original path>") finds the newest matching entry
Permanent cleanup trash-purge(confirm: true) — optionally scoped to specific entry_ids

Tool reference

Tool Purpose
trash(paths, reason?) Move files/directories into the trash. Returns entry_id, trash_root, moved.
trash-list(path?) List trash entries (deleted-at, size, reason, original paths). Optional substring filter on the original path.
trash-restore(entry_id? | path?, target_path?, overwrite?) Restore an entry to its original location (or target_path for single-item entries). If the target exists, it refuses unless overwrite: true — in which case the existing content is first moved to the trash itself, then the restore proceeds. Nothing is ever lost.
trash-purge(entry_ids?, confirm: true) Permanently delete trash entries. The only real deletion in the whole plugin.

Configuration (optional)

Append to your profile's cordis.patch.yml:

- id: dsh-trash
  config:
    location: D:/data/dsh-trash   # trash root; same drive as the workspace = instant renames
    interceptPwsh: true           # intercept deletes in pwsh (default true)
    interceptBash: true           # intercept deletes in bash (default true)
    interceptRunCode: true        # intercept fs.* deletes in run_code (default true)

Security notes

  • Fail-safe by design: the detector prefers false positives over letting a real delete through (e.g. a tutorial string mentioning Remove-Item is blocked too; the denial message explains why). Short aliases (rm/del/rd/ri) only match in command position, so cat /tmp/rm, Test-Path C:\rd, or grep 'rm -rf' docs are not flagged.
  • One true delete path: only trash-purge(confirm: true), and it only touches the trash root.
  • Restore safety: entry_id is strictly validated (no path traversal); target_path may not point inside the trash root.
  • Overwrite safety: restoring over an existing file first backs that file up into the trash — every step is reversible.

Development

node test/unit.test.mjs   # 48 cases: detector hit/miss matrix + full trash-store workflow

Uninstall

dsh plugin --profile web remove dsh-trash

The trash directory itself is left untouched; move it away first if you want to keep the data.

License

MIT

安装

🧩 让 Agent 自动装(推荐)

装一次目录插件,之后本站所有插件都能让 DeepSeek Harness 自动找、自动装:

dsh plugin add dshbase-catalog

然后对 agent 说「帮我装 dsh-trash」,它会在目录里找到并自动安装。文档:dshbase-catalog · 已验证场景包。

该插件是 GitHub 源码(未发 npm)——直接从仓库装:

Web profile:

dsh plugin --profile web add github:LeonSone/dsh-trash

Headless(CLI)profile:

dsh plugin --profile headless add github:LeonSone/dsh-trash

实测报告

验证通过:从 GitHub 源码完成 L1 安装 + L2 加载 + L3 运行(dsh 0.1.0-rc.6)。

安全:尚未扫描——我们的每日静态扫描将很快覆盖它。

分享徽章

Developer 里更多

浏览全部 7819 个插件 →