All plugins

DSH / BUNDLE / CLIENT-UI

dsh-guardian

v0.1.0LWLAymh / dsh-guardian4cbe3174f9

InstallableBundlesUI & client pluginsCommunity · Topic auto-analysisWeb UI

Overview

dsh-guardian

DSH plugin: file-change diff bar for write/edit/str_replace_editor, and a dangerous-command approval gate for bash/pwsh

README / EN

Package documentation

dsh-guardian

中文

A DeepSeek Harness Web plugin that adds two safety/visibility features 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 the real diff inline.
  2. Dangerous-command approval — 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.

Features

1. File-change bar

Tool Behavior
write Shows the created/updated file with added/removed line counts and a show diff toggle.
edit While running, shows the intended change from the call arguments; once settled, shows the applied hunks from the real before/after result.
str_replace_editor Shows 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. Dangerous-command approval

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-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

Pattern Meaning
rm deletes files or directories
rmdir / rd removes directories
Remove-Item PowerShell file/directory deletion
del Windows file deletion
format / mkfs / diskpart / dd of= destructive disk/volume operations
git clean / git reset --hard / git push --force destructive Git operations
shutdown / reboot / halt / poweroff / Restart-Computer / Stop-Computer shutdown/reboot
Clear-Content PowerShell content erasure
curl|sh / wget|sh executes 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.

Installation

Install into your web profile:

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

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

# or, once published to npm
dsh plugin --profile web add dsh-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-guardian

How it works

dsh-guardian/
├── lib/
│   ├── index.js      # host half: tools/pre-execute dangerous-command gate
│   └── client.js     # web client half: file-change toolview
├── 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.
  • Client half — registers a keyed tool.call.toolview entry for write, edit, and str_replace_editor with a negative shadowing priority so it wins the slot over the stock file-mutation row. The component reads the same callView / resultView diff payloads the built-in diff card consumes and renders the compact +N / -M [show diff] bar with a collapsible DiffBlock.

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-guardian
dsh --profile web

Publishing

GitHub

cd dsh-guardian
git init
git add .
git commit -m "dsh-guardian: file-change diff bar + dangerous-command approval"
git branch -M main
git remote add origin https://github.com/<your-name>/dsh-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-guardian

Limitations

  • Dangerous-pattern matching is regex-based and deliberately conservative; false positives are possible.
  • Line counts are approximate for very large diffs.
  • The plugin is Web-profile oriented; headless/TUI profiles have no approval UI or toolview surface, so only the host-side gate is 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

LIMITATIONS

Known limitations

- Dangerous-pattern matching is regex-based and deliberately conservative; false positives are possible. - Line counts are approximate for very large diffs. - The plugin is Web-profile oriented; headless/TUI profiles have no approval UI or toolview surface, so only the host-side gate is 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.