wuwuzhige-sudo/dsh-terminal-panel ↗★ 1
dsh-terminal-panel
A manual 'Terminal' tab in the DeepSeek Harness (dsh) web conversation view — run commands on the harness host machine, with persistent cwd, sudo password prompt, and command history.
安装
此插件尚未提供可验证的 bundle,或兼容性检查未通过。请先阅读仓库说明。 阅读完整 README ↗
说明文档
阅读完整 README ↗dsh-terminal-panel
A manual Terminal tab in the DeepSeek Harness (dsh) web conversation view. Run commands on the harness host machine directly from the browser — green-on-black classic terminal look, persistent cwd, sudo password prompt, command history.

Features
- Terminal tab in every conversation view (
对话 · 轨迹 · 终端ordering) - Manual command execution on the host machine via the harness
subprocessservice - Persistent working directory — plain
cdworks across commands (cd ..,cd ~/x, relative paths, error messages for bad targets) - sudo support — commands starting with
sudorun withsudo -S; the panel masks the password field while sudo is waiting (type it at the bottom line and press Enter) - Command history (↑/↓), Ctrl+C to interrupt the running command, clear screen, reset directory
- Two themes — classic green-on-black and modern black-on-white, toggled by a button next to the panel controls; the choice persists across reloads (localStorage)
- ANSI escape cleanup — raw escape sequences never reach the panel
- Output cap — 512 KiB rolling buffer, so long-running output cannot blow up memory
Install
The plugin ships as a dsh profile plugin. On the machine running dsh web:
# 1. Install the package into the web profile (git dependency; pnpm resolves it)
dsh plugin --profile web add /dsh-terminal-panel
# 2. Register the plugin in the profile patch layer
cat >> ~/.dsh/profiles/web/cordis.patch.yml ⚠️ **This plugin executes arbitrary commands on the harness host.** Anyone who can reach the `/sxec/*` endpoints can run commands as the harness user.
- Requests are accepted **only** from loopback hosts or hosts listed in `trustedHosts` (DNS-rebinding defence).
- There is **no built-in authentication** — protect the web server itself with a reverse-proxy auth layer (e.g. Caddy `basic_auth`) when exposing it beyond localhost.
- The endpoint inherits the exposure of whatever fronts the dsh web server: bind it to loopback only, or put an authenticated proxy in front.
## How it works
- **Host half** (`lib/index.js`): a dsh plugin that registers a `/sxec/*` route family on the harness webserver (`term-init`, `term-run`, `term-send`, `term-signal`, `term-reset`, `term-read`). Commands run either locally via `node:child_process` (bypassing the harness subprocess sandbox) or through `ssh -T` when `sshTarget` is configured; output is ANSI-sanitised and buffered.
- **Client half** (`lib/client.js`): registers the Terminal slot in `conversation.view` and talks to the host via same-origin `fetch('/sxec/*')` calls (no WebSocket, no extra ports).
## Configuration
| Field | Type | Default | Description |
|---|---|---|---|
| `trustedHosts` | `string[]` | `[]` | Extra hostnames (besides loopback) allowed to call the terminal RPC. Required when the web UI is served through a reverse proxy / Tailscale Serve with a real hostname. |
| `sshTarget` | `string` | `''` | SSH target for command execution, e.g. `ql@127.0.0.1` or `ql@my-server`. Empty = run commands locally. |
| `sshIdentity` | `string` | `~/.ssh/dsh-terminal` | SSH identity file used for `sshTarget`. |
### SSH mode (why you want it)
When dsh runs sandboxed (bwrap/user namespace — the default on Linux), the
process cannot `setuid`, so **sudo is unusable** in local mode. Point the
panel at SSH instead — commands then execute in the **host namespace** of the
sshd server, where sudo works normally. The same mechanism turns the panel
into a remote terminal for **any** SSH host:
```yaml
- insert:
- id: dsh-terminal-panel
name: 'dsh-terminal-panel'
config:
trustedHosts:
- myhost.tailXXXX.ts.net
sshTarget: ql@127.0.0.1 # localhost: sudo works
# sshTarget: ql@100.67.174.12 # or any SSH host
sshIdentity: /home/ql/.ssh/dsh-terminal