插件目录 / Developer / dsh-ssh-plugin
dsh-ssh-plugin
已验证 · 实测可装 YOLO-LZL
功能简介
Developer 类别的 DeepSeek Harness 插件。
可用 — 实测通过,早期项目
Developer 类别的 DeepSeek Harness 插件。 实测能干净安装、正常启动。早期项目,但功能可用。
「已验证」表示我们的自动化 CI 在干净 profile 里实际执行了 dsh plugin add 并启动成功——仅此而已。功能描述与版本兼容性均为作者声明。这不是安全审计,也不代表对第三方代码的背书。
README
dsh-ssh-plugin
A DeepSeek Harness plugin that adds the ssh_exec model tool — run commands on a remote Linux server over the system ssh client — plus persisted SSH connections: save connections once, bind them to a workspace, and let ssh_exec use them by default.
- Key-based auth only (
BatchMode=yes) — no password/passphrase prompts, so a missing or unauthorized key fails fast instead of hanging. - No remote-shell quoting layer — the remote command travels through ssh stdin to
bash -s. - Session sandbox aware — runs the client under the calling session's standing policy;
danger-full-accessruns it unconfined. - Recognizes your local
~/.ssh/config— hosts defined there need no manualssh_connections save; pass the alias asssh_exechostand ssh resolves it, andssh_connections listshows them read-only. - Dual-face package — the host half registers the
ssh-connectionssettings namespace and thessh_connectionstool; the browser half registers the "SSH Connections" card in Settings → Plugins. - All harness services except
tools/shellare optional — profiles withoutsettingsorworkspaceRegistrydegrade gracefully (see below).
Install
dsh plugin --profile <name> add dsh-ssh-plugin # from npm
dsh plugin --profile <name> add github:you/dsh-ssh-plugin # from git
dsh plugin --profile <name> add ./dsh-ssh-plugin # from a local checkout
A local checkout must be built first: pnpm install && pnpm bundle (git installs build automatically through prepare).
Then boot with dsh --profile <name>.
The plugin declares the harness packages as peer dependencies; @deepseek-ai/dsh-base (the first bundle of every profile) provides them.
Usage
ssh_exec
The model gains an ssh_exec tool. Ask in natural language (e.g. "ssh to [email protected] and show disk usage"), or pass explicit arguments:
| Arg | Required | Notes |
|---|---|---|
host |
yes* | Remote host as [user@]host, e.g. [email protected], or any alias defined in ~/.ssh/config. |
command |
yes | Bash command(s) run on the remote host via bash -s. |
port |
no | SSH port. Default 22. |
key_path |
no | Absolute path to the private key. Omit for ~/.ssh defaults and ssh-agent. |
timeout_ms |
no | Foreground timeout in ms. Default 30000. |
connection |
no | Label of a saved connection; fills in host/port/user/keyPath. |
* host is required in the schema, but at execution the effective host resolves as explicit host → explicit connection → workspace default. Explicit port/key_path always win over the resolved connection's values. A host that is a ~/.ssh/config alias is handed to ssh unchanged — ssh applies the config's HostName/User/Port/IdentityFile itself, so no ssh_connections save is needed for config hosts.
ssh_connections
The model also gains an ssh_connections tool for durable connection management (persisted through the harness settings store, so it survives restarts):
save— persist a connection (label,host, optionalport/user/keyPath). Labels are unique.list— show saved connections plus hosts discovered from the local~/.ssh/config(read-only; pass the alias asssh_exechost, no save needed).delete— remove one by label (also unbinds workspaces that pointed at it).use— bind the current workspace to a connection label sossh_execmay omithost; omitlabelto clear the workspace default.
SSH config discovery
On every call the plugin reads the local OpenSSH client config (~/.ssh/config, or sshConfigPath when configured) and parses it:
- Concrete
Hostaliases become visible to the model inssh_connections listand are suggested inssh_execerror messages. - Per ssh semantics, the first obtained value wins: global directives and
Host *blocks provide defaults, later matching blocks cannot override them.HostName/User/Port/IdentityFileare resolved;Matchblocks andIncludedirectives are not expanded — hosts must live in the file itself. - Discovery is best-effort: a missing/unreadable config yields an empty list, never an error. Config hosts are never persisted — they exist only in your
~/.ssh/config.
Settings card
With a web profile, Settings → Plugins shows an "SSH Connections" card styled like the built-in plugin cards (Bash/Terminal, Agent loop, Web search): a collapsible card with an unsaved badge and discard/save actions. Edit the same connections list (add/remove rows, save). The card only writes the connections field; workspace bindings are managed by ssh_connections use.
Data model
The ssh-connections settings namespace (schemastery schema, validated for duplicate labels):
{
connections: [{
label: string // unique, non-empty
host: string // [user@]host, non-empty
port?: number // 1..65535, default 22
user?: string // optional; prepended to host when host has no user part
keyPath?: string // absolute private-key path; omit for ~/.ssh + ssh-agent
}],
workspaceDefaults: { [workspaceId: string]: string } // workspaceId → label
}
Only key paths are stored — key content never leaves disk (role('secret') is reserved for a future keyContent field).
Configuration
Set row-level defaults in a later patch layer (profile cordis.patch.yml or --patch):
- id: tool-ssh
name: dsh-ssh-plugin
config:
timeoutMs: 30000
connectTimeout: 15
sshConfigPath: C:\Users\me\.ssh\config # optional; defaults to ~/.ssh/config
Degradation matrix
| Composition | Behavior |
|---|---|
No ctx.settings (e.g. TUI) |
No namespace, no ssh_connections tool; ssh_exec works with explicit args only. |
No ctx.workspaceRegistry |
use and the workspace-default resolution report "workspace registry unavailable"; everything else works. |
No ~/.ssh/config (or unreadable) |
ssh_connections list shows saved connections only; ssh_exec suggestions omit config aliases. |
| Namespace not exposed to the browser | The card renders an "unavailable" placeholder. |
Requirements
- A reachable Linux target with bash and key-based SSH access set up (
~/.ssh/authorized_keys). - On Windows, a session whose standing sandbox policy is
danger-full-access; the restricted token otherwise refuses to startssh.exe.
Development
pnpm install
pnpm bundle # tsdown → lib/index.js (host) + lib/client.js (browser bundle)
pnpm types # tsc --emitDeclarationOnly → lib/types/**/*.d.ts
pnpm test # vitest (model + wiring)
安装
装一次目录插件,之后本站所有插件都能让 DeepSeek Harness 自动找、自动装:
dsh plugin add dshbase-catalog 然后对 agent 说「帮我装 dsh-ssh-plugin」,它会在目录里找到并自动安装。文档:dshbase-catalog · 已验证场景包。
该插件是 GitHub 源码(未发 npm)——直接从仓库装:
Web profile:
dsh plugin --profile web add github:YOLO-LZL/dsh-ssh-plugin Headless(CLI)profile:
dsh plugin --profile headless add github:YOLO-LZL/dsh-ssh-plugin 实测报告
验证通过:从 GitHub 源码完成 L1 安装 + L2 加载 + L3 运行(dsh 0.1.0-rc.6)。