dsh-ssh-manager
Manage SSH identity keys and per-host ssh config from the web settings page, so git-over-ssh works in headless server mode.
andreasseidl
@andreasseidl
⬇ 2
★ 0
main
安装
dsh plugin --profile web add github:andreasseidl/dsh-ssh-manager
需要可复现安装时,可在仓库后追加 #commit 固定提交。
Manage SSH identity keys and per-host ssh config from the web settings page, so git-over-ssh works in headless server mode.
该插件未提供要点说明,请参考仓库 README。
- 安装并启动 DeepSeek Harness:
npx @deepseek-ai/dsh web - 在终端执行上面的安装命令(CLI 会解析插件并核验来源)
- 用 dsh plugins list 确认已安装,必要时重启 Harness 生效
插件以当前 dsh 进程的权限运行,安装时可能执行代码。请先通读仓库源码与许可证,确认无破坏性命令与越权访问;本站只做索引,不对第三方插件安全性作担保。
| 代码仓库 | github.com/andreasseidl/dsh-ssh-manager |
| 许可证 | MIT |
| 主要语言 | main |
| 下载量 | 2 |
| GitHub 星标 | 0 |
| 最近推送 | 2026-09-04 |
| 收录日期 | 2026-09-19 |
| 分类 | 开发与运行时 |
事实信息来自公开插件目录快照(2026-10-01),介绍文案由本站再加工。
以下为插件仓库 README 全文(原始内容,由公开目录抓取整理)。
# dsh-ssh-manager
A [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) plugin for
managing SSH identities **from the web settings page**, so an unattended agent
can `git clone git@host:user/repo` in headless server mode.
It adds one card to **Plugins → Plugin configuration → SSH** and turns
what you enter there into real ssh files under `$DSH_HOME/.ssh` (`~/.dsh/.ssh`
when `DSH_HOME` is unset) — always separate from your own `~/.ssh`.
## Install
Requires Node ≥ 20 and pnpm (which `dsh plugin` forwards to).
```bash
dsh plugin --profile web add dsh-ssh-manager # from npm
dsh plugin --profile web add /path/to/dsh-ssh-manager # or a local checkout
```
That installs the package into the profile and appends it to
`dsh.profile.bundles`; the plugin's own `cordis.patch.yml` inserts its loader
row from there. **Restart the harness** and the card appears — no web-app
rebuild, and nothing to build in this package (`lib/` ships prebuilt and
self-contained).
Don't *also* add a `- insert: - id: dsh-ssh-manager` row to the profile's user
patch: two rows with the same id are a fatal duplicate-entry error.
Alternative: symlink + user patch (for a checkout you edit in place)
```bash
ln -s /abs/path/to/dsh-ssh-manager "$DSH_HOME/profiles//node_modules/dsh-ssh-manager"
```
then add the row to the profile's `cordis.patch.yml`:
```yaml
- insert:
- id: dsh-ssh-manager
name: 'dsh-ssh-manager'
```
Profiles with `patchReload: live` pick the patch up without a restart; write it
atomically (`write tmp` + `rename`) if so.
## Using it
1. Open **Plugins → Plugin configuration → SSH**.
2. First time only: the card shows a warning and greys out **Add SSH host**
until `~/.ssh/config` imports the managed dir. **Add the Include line**
appends that one line for you, preserving your existing config and its file
mode.
3. **Add SSH host** → fill in host, URL/HostName, user, paste the private key,
add any extra ssh-config options → **Save**.
4. `git clone git@github.com:you/repo` now works from the agent. The public key
is derived to `.pub`, ready to paste into GitHub/GitLab.
**Fields.** *Host* is the ssh `Host` alias, *URL / HostName* the machine to
connect to, *User* the ssh user (`git` for GitHub/GitLab), *Extra ssh-config
options* one directive per line (e.g. `ProxyJump jump-host`).
**The private key** behaves like a provider API key: write-only, never shown
back or sent to the browser. A **new** host must carry one before it can be
saved; editing an existing host shows *Configured — paste a new key to replace*
and keeps the stored key if you leave the field blank. Renaming counts as new,
since the old entry's key leaves with it.
**Validation.** A key must start with a PEM header (`-----BEGIN OPENSSH PRIVATE
KEY-----`, `-----BEGIN RSA PRIVATE KEY-----`, …). Host names must start with a
letter or digit and use only letters, digits, `.`, `_`, `-` — they double as
directory and file names on disk.
## What it writes
```
$DSH_HOME/.ssh/
config flat ssh_config; only a managed Include region is
added, everything else is preserved
config.d//
config the Host block, fenced with managed markers (0600)
the private key (0600)
.pub the derived public key (0644)
```
Each host owns its files, so concurrent editors never contend on one file.
Removing a host deletes its whole `config.d//` directory. Anything the
plugin did not write — a seeded default config, `known_hosts`, manually placed
keys — is never touched. In the DSH container,
`/etc/ssh/ssh_config.d/99-dsh-container.conf` already `Include`s
`$DSH_HOME/.ssh/config`, so the managed blocks take effect for git.
Keys live in the settings document as `role('secret')`: never serialized into a
describing response, and written to disk with mode 0600.
## Development
```bash
npm install # tsdown + schemastery, build inputs only
npm run build # host bundle (tsdown) + client wrap
```
- `src/index.js` → `lib/index.js` — host half: schema, validation, and the
reconcile that writes and cleans the ssh files. Bundled **self-contained**
(schemastery inlined): the harness imports it with plain Node resolution from
wherever it is installed, so a non-bundled copy fails to load. `build.mjs`
refuses to emit one that isn't.
- `src/client/index.js` → `lib/client.js` — browser half: the settings card in
plain `React.createElement` (no JSX), wrapped into the loader's
closure-factory artifact. `package.json`'s `dsh.client` declares it.
- `cordis.patch.yml` — the patch inserting the loader row.
The card talks to the harness through `ctx.settingsScope` (revision-fenced
writes), the built-in client modules (`react`, `@deepseek-ai/dsh-client-*`), and
one host route for the Include check: `GET|POST /dsh-ssh-manager/ssh-import`
(loopback-guarded, same-origin).
Both halves are committed prebuilt, so keep `lib/` in step with `src/` — the
`prepublishOnly` hook rebuilds and refuses to publish if that changes anything
under `lib/`. **Host-side changes need a harness restart**; client-only changes
apply on a page refresh.
## License
MIT — see [LICENSE](LICENSE).
数据来源:公开的 DeepSeek Harness 插件目录与各插件 GitHub 仓库。本站为独立第三方目录,与 DeepSeek、幻方(High-Flyer)及插件作者均无隶属或背书关系。