Back to home@LWLAymh

dsh-edit-guardian

No description

Stars
0
Language
JavaScript
Created
Aug 28, 2026
Updated
Aug 29, 2026
GitHub repo

Introduction

dsh-edit-guardian

中文

A DeepSeek Harness Web plugin that adds file-change visibility, keep/undo controls, and a command safety gate to the browser UI:

  1. File-change bar — when the agent modifies a file through write, edit, or str_replace_editor, the tool row renders as file +N lines -M lines [show diff]. Clicking the button expands a context-aware diff inline.
  2. Change summary + keep/undo — a persistent, collapsible summary bar above the composer lists every changed file that has not been kept yet, even while the agent is working. Each file has 保留 / 撤销 buttons; the header has 全部保留 and 全部撤销 (backed by the host-side /undo command).
  3. Dangerous-command approval + red highlight — before bash / pwsh executes a command that matches a destructive pattern (rm, Remove-Item, format, git reset --hard, git push --force, curl|sh, …), the execution is routed through the DSH approval seam and the Web UI asks the user to approve or reject it. In the shell tool row, the matched dangerous text is highlighted in red. When a tool call requests sandbox escalation (sandbox_permissions), the affected path / workdir is highlighted in red with a “需要权限” badge.

Features

1. File-change bar

ToolBehavior
writeShows the created/updated file with added/removed line counts and a show diff toggle.
editWhile running, shows the intended change from the call arguments; once settled, shows the applied hunks from the real before/after result.
str_replace_editorShows the call-time diff card and keeps it visible after the result (the stock UI only shows it while running).

Line counts are computed with a line-level diff over the per-hunk diff payloads. For very large hunks the summary falls back to an approximate count; the expanded diff is always the authoritative one.

2. Change summary + keep/undo

A persistent conversation.input.dock entry above the composer renders the summary whenever there are unkept file changes, including while the agent is still working. The header shows the file count and a collapse toggle. Each file row shows:

  • openable path
  • +N行 -M行 line stats
  • 显示 diff / 隐藏 diff toggle (per file, context-aware diff)
  • 保留 — marks that change as accepted and removes it from the summary
  • 撤销 — runs /undo <path> and removes it from the summary after success

Header actions:

  • 全部保留 — marks all currently listed changes as accepted
  • 全部撤销 — runs /undo --all and clears the summary

Resolution is tracked per tool-call id, so if a file changes again after being kept, the new change reappears in the summary.

Undo is handled by the host half, which records the pre-edit before content of every successful write / edit result. Reverting writes the recorded before back to disk; files created by write (before: null) are removed. Changes made through str_replace_editor or shell commands are not restorable by /undo.

3. Dangerous-command approval + red highlight

The host half listens on tools/pre-execute and inspects bash / pwsh command strings. When a command matches a dangerous pattern, the plugin returns an ask decision with a human-readable reason. The DSH tool registry then resolves that decision through ctx.approval, so the standard Web approval prompt is shown before anything executes.

Trust everything in advance — switch the session to the Full access permission preset in the Web UI (danger-full-access sandbox mode). dsh-edit-guardian then lets dangerous commands through without prompting, matching DSH's existing "full access" semantics.

Fail-closed: if the user rejects, cancels, or no approval channel is available, the command does not run.

Dangerous patterns

PatternMeaning
rmdeletes files or directories
rmdir / rdremoves directories
Remove-ItemPowerShell file/directory deletion
delWindows file deletion
format / mkfs / diskpart / dd of=destructive disk/volume operations
git clean / git reset --hard / git push --forcedestructive Git operations
shutdown / reboot / halt / poweroff / Restart-Computer / Stop-Computershutdown/reboot
Clear-ContentPowerShell content erasure
curl|sh / wget|shexecutes a remote script through the shell

Patterns are simple regular expressions, so harmless commands that merely mention rm (for example echo "rm -rf") may also prompt. This is intentional: when in doubt, ask. Use the Full access preset to skip prompts.

Screenshots

File-change summaryDangerous-command approval
File-change summaryDangerous-command approval

Installation

Install into your web profile:

# from a local checkout
dsh plugin --profile web add file:./dsh-edit-guardian

# or from a GitHub repository
dsh plugin --profile web add git+https://github.com/<your-name>/dsh-edit-guardian.git

# or, once published to npm
dsh plugin --profile web add dsh-edit-guardian

Then restart the web profile:

dsh --profile web

The plugin does not hot-reload into an already-running Web process.

Uninstall:

dsh plugin --profile web remove dsh-edit-guardian

How it works

dsh-edit-guardian/
├── lib/
│   ├── index.js      # host half: dangerous-command gate, undo recorder, /undo command
│   └── client.js     # web client half: file rows, shell rows, change summary
├── cordis.patch.yml  # bundle patch inserting the host row
├── dsh.plugin.json   # plugin metadata
├── scripts/          # local smoke tests
│   ├── smoke-host.mjs
│   └── smoke-client.cjs
├── package.json
└── README.md / README.zh.md
  • Host half — registers a tools/pre-execute listener. Returning { kind: "ask", reason } from the waterfall short-circuits the built-in tool pipeline into serviceAsk, which calls ctx.approval.request(...). The existing dsh-host-apiproxy approval answerer then shows the prompt in the browser. When the session's sandbox mode is danger-full-access, the listener delegates to next() instead of asking. It also records successful write / edit results and registers the /undo command.
  • Client half — registers keyed tool.call.toolview entries with a negative shadowing priority:
    • write, edit, str_replace_editor → the compact +N / -M [show diff] row with a context-aware collapsible diff, and a red “需要权限” badge when the call requests sandbox_permissions.
    • bash, pwsh → the danger-aware shell row that highlights matched dangerous text in red, shows the requested sandbox mode + workdir in red for escalation calls, and expands to the terminal output.
    • It also registers a conversation.input.dock entry that renders the persistent change summary with per-file keep/undo and header keep-all/undo-all actions, plus a collapse toggle.

Development

Smoke tests do not require a running DSH instance:

node scripts/smoke-host.mjs
node scripts/smoke-client.cjs

After changing source files, reinstall the local package into the profile and restart the web profile:

dsh plugin --profile web add file:./dsh-edit-guardian
dsh --profile web

Publishing

GitHub

cd dsh-edit-guardian
git init
git add .
git commit -m "dsh-edit-guardian: file-change summary with keep/undo and command safety gate"
git branch -M main
git remote add origin https://github.com/<your-name>/dsh-edit-guardian.git
git push -u origin main

Then add the repository topic dsh-plugin in the GitHub repo settings so DSH plugin search (find_dsh_plugin) can discover it.

If you publish to npm, fill in the real "repository" field in package.json first:

npm publish

npm

After publishing, users can install with:

dsh plugin --profile web add dsh-edit-guardian

Limitations

  • Dangerous-pattern matching is regex-based and deliberately conservative; false positives are possible.
  • Line counts are approximate for very large diffs.
  • Undo restores files recorded from write / edit only; str_replace_editor and shell-command modifications are not restorable by /undo yet.
  • Undo records are in-memory and per-session: they disappear when the web process restarts.
  • The shell row for bash / pwsh is replaced by the danger-aware renderer; its collapsed summary shows the command instead of the description.
  • The plugin is Web-profile oriented; headless/TUI profiles have no approval UI or toolview surface, so only the host-side gate and /undo are relevant there.
  • Approval policy semantics are inherited from DSH: in a custom workspace-write + never approval-policy combination, ask decisions are rejected instead of prompting.

License

MIT