# dsh-ssh
**Repository Path**: itopen/dsh-ssh
## Basic Information
- **Project Name**: dsh-ssh
- **Description**: No description available
- **Primary Language**: Unknown
- **License**: MIT
- **Default Branch**: main
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2026-09-14
- **Last Updated**: 2026-09-14
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# dsh-ssh
[中文](README.md) | English
[](https://www.npmjs.com/package/@dsh-ssh/dsh-ssh)
[](./LICENSE)
Run your DeepSeek Harness workspace on any remote machine over SSH — right from the DSH settings page. Configure a host, pick one of its directories as a workspace, and every bash / file / search tool call runs on that machine instead of your own.

Add SSH hosts in the settings page

Browse a remote directory and pick it as the workspace
> **Why dsh-ssh**
>
> Built entirely on DSH's official public contract for third-party plugins — purely additive, zero changes to DSH core, and zero installation on the remote (it only needs a plain `sshd`). Remove it and DSH is exactly as it was. Your local workspaces behave byte-for-byte identically to before.
## Table of Contents
- [Features](#features)
- [Install](#install)
- [Quickstart (30 seconds)](#quickstart-30-seconds)
- [What runs where](#what-runs-where)
- [Compatibility](#compatibility)
- [Known limitations](#known-limitations)
- [Troubleshooting](#troubleshooting)
- [FAQ](#faq)
- [Development](#development)
- [License](#license)
## Features
- **SSH hosts in Settings**: add / edit / delete hosts (host, port, user, key or password) right in the DSH settings page, with a one-click connection test.
- **Remote directories as workspaces**: browse the remote directory tree when creating a workspace and pick any folder. Local and remote workspaces coexist; switch the running machine any time.
- **Seven tools run remotely**: `bash`, `read`, `write`, `edit`, `read_image`, `glob`, and `grep` all execute on the remote machine — same names, same arguments, no model-visible difference.
- **Trust on first use (TOFU)**: the first connection to an unknown host shows a fingerprint confirmation; the host key is then verified on every later connection.
- **Background tasks work remotely**: `run_in_background` with the full `job_list` / `job_output` / `job_kill` chain all run on the remote.
- **Sandbox enforced remotely**: all three sandbox modes apply on the remote host exactly as they do locally.
- **Robust by default**: known-hosts verification, automatic reconnect, atomic writes (temp file + rename), and a pooled `ssh2` connection for exec + SFTP.
- **Credentials write-only**: passwords are stored through DSH's settings secret mechanism; private keys are referenced by local path.
## Install
```bash
dsh plugin --profile web add @dsh-ssh/dsh-ssh
```
If pnpm reports `ERR_PNPM_ADDING_TO_ROOT`, append `-w` (profile dirs are pnpm workspace roots and pnpm 11 requires the flag). A failed `cpu-features` build log during install is expected — it is an optional native accelerator and falls back to pure JS.
Restart DSH, then open the settings page and add your first host.
## Quickstart (30 seconds)
1. **Add a host** — Settings → SSH Hosts → add host, enter host / port / user / auth, hit *Test connection*.
2. **Trust the key** — the first connection shows a fingerprint confirmation (TOFU). Confirm to trust it.
3. **Create a remote workspace** — new conversation → create / switch workspace → browse the remote directory → pick a folder.
4. **Done** — tools are automatically routed over SSH while the workspace is remote. Nothing else to configure; the standard preset works as-is.
## What runs where
In a remote workspace, only the seven routed tools execute on the remote host:
| Capability | Runs on |
|---|---|
| `bash`, `read`, `write`, `edit`, `read_image`, `glob`, `grep` | **Remote machine (over SSH)** |
| skill tools, MCP tools, and all other host tools | **Your local machine** |
## Compatibility
| Dimension | Status |
|---|---|
| Remote OS | Ubuntu ✅ · macOS ✅ (tested against real hosts) |
| Authentication | Key-based ✅ · Password ✅ |
| Remote needs | Plain `sshd` only — no agent, service, or kernel module |
| Windows remote | Not supported (Linux / macOS only) |
| Preset | Any preset, including the standard one — independent of presets |
> **Requirements**: Node ≥ 22 · pnpm 11.21.0 · DSH peerDependencies (`@deepseek-ai/cordis@^4.0.1`, `@deepseek-ai/dsh-*@^0.1.0-rc.6`, `@deepseek-ai/schemastery@^3.18.1` — see `packages/dsh-ssh/package.json`)
## Known limitations
- No ProxyJump / multi-hop — direct single-hop connections only.
- Remote `grep` uses GNU grep; ignore rules differ slightly from `rg`.
- If SFTP is disabled on the remote, file operations automatically fall back to `exec` + base64 (works, but slower).
- Windows remote hosts are not supported.
## Troubleshooting
- **Cannot connect / Test connection fails**: check host / port / user, firewall for port 22, whether `sshd` is running, and auth (key path / password); the Settings → *Test connection* does a real handshake + `echo`, and errors include hostId and remote output.
- **Fingerprint mismatch / TOFU verification fails**: the first connection shows a fingerprint popup (TOFU) and writes to `known_hosts` once confirmed; `host key changed` means the remote was reinstalled or a MITM risk — verify and then remove the stale `known_hosts` entry or re-trust.
- **Private key permission error (UNPROTECTED PRIVATE KEY)**: OpenSSH requires `600`/`400` (no group/other read); fix file permissions and path (avoid spaces or CJK characters), and ensure DSH can read it.
- **SFTP disabled → falls back to exec + base64 (slower)**: if the remote disables SFTP, file ops still work via exec-channel base64 (ExecFs) but large / batch ops are noticeably slower — expected degradation; enable the SFTP subsystem in `sshd_config` to restore speed.
- **Placeholder directory (`~/.dsh/remote//...`)**: a remote workspace is just a local placeholder (plain workspace record, `workspaceRegistry` does `realpath` check); it holds no business data but must exist and must not be a symlink — do not delete/move it manually, switch via DSH workspace management.
- **How to collect logs**: tool failures include hostId, the exact remote command, exit code and tail output; combine with `~/.dsh/settings.yaml` (`dsh-ssh-hosts`), DSH console logs, and remote `sshd` logs (`/var/log/auth.log` or `journalctl -u sshd`) and attach sanitized info when filing an issue.
## FAQ
**Does this affect my local workspaces?**
No. The plugin is purely additive — local paths still go through DSH's own host implementation, byte-for-byte unchanged.
**Are background tasks supported?**
Yes. `run_in_background` and the whole `job_list` / `job_output` / `job_kill` chain execute on the remote machine.
**Are my credentials safe?**
Passwords are stored write-only through DSH's secret mechanism; private keys are referenced by local path and never copied. Unknown hosts are vetted by a TOFU fingerprint confirmation before anything is trusted.
**Do I need a special preset?**
No. Tool routing is independent of presets and works with the standard preset.
**How do I uninstall?**
```bash
dsh plugin --profile web remove @dsh-ssh/dsh-ssh
```
DSH is fully restored — no trace left behind.
## Development
This repository is a pnpm workspace; developer-oriented documentation lives in the root [CONTRIBUTING.md](./CONTRIBUTING.md). See [CONTRIBUTING.md](./CONTRIBUTING.md) for the package layout, tests, and live verification scripts.
> **Navigation**: Agent entry → [AGENTS.md](./AGENTS.md) · Developer handbook → [CONTRIBUTING.md](./CONTRIBUTING.md)
## License
[MIT](./LICENSE)