DeepSeek Harness Remote Workspace

DeepSeek Harness Remote Workspace

Work on a remote server as if it were local

Connect a host over SSH, pick a folder there, and work in it. The agent reads, writes, edits, lists, searches, and runs shell commands on the far side with every tool it already has. The connection is shared by every session, several servers can be connected at once, and the whole thing is switched on from Settings → Plugins.

What it does

Requirements

Install

curl -fsSL https://raw.githubusercontent.com/cmukanisa/dsh-remote-ssh/main/install.sh | sh

Or from a clone: git clone https://github.com/cmukanisa/dsh-remote-ssh && cd dsh-remote-ssh && node install.mjs

Installing activates the plugin, and the run is a transaction

It checks every requirement first, installs, verifies, and rolls back to the exact previous state if anything does not pass — a half-installed plugin would leave a harness booting a composition that disables the shipped providers without registering the replacements.

  checking
  ✓ node        ·························· v24.14.0 (the harness requires >= 22.19)
  ✓ ssh         ···································· OpenSSH_10.3p1, LibreSSL 3.3.6
  ✓ tailscale   ················ 1.102.3 — the Tailscale SSH transport is available
  ✓ harness     ················································· /Users/you/.dsh
  ✓ writable    ··································· profiles/plugins accepts writes
  ✓ modules     ················· profiles/node_modules/@deepseek-ai/cordis present

  installing
  ✓ copied      ········ dsh-remote-ssh → profiles/plugins/dsh-remote-ssh (8 files)
  ✓ patched     ···································· cordis.patch.yml (8 rows)
  ✓ enabled     ····························· settings.yaml remote-ssh.enabled = true

  verifying
  ✓ files       ······················································ 12 files in place
  ✓ composition ·············································· 8 expected rows
  ✓ setting     ····································· remote-ssh.enabled = true
  ✓ module      ············· registry.js imports and exports RemoteRegistry

  ──────────────────────────────────────────────────────────────────────────────
  Done in 0.1s. Reload the harness page, then workspace "+" → "Serveur distant (SSH)".
FlagEffect
--keep-offinstall dormant — for a rollout where activation is audited separately
--enableactivate even if a previous run left it switched off
--linksymlink the packages instead of copying them (development)
--dry-runrun the checks, report the changes, write nothing
--no-colorplain output (also honours NO_COLOR)
--uninstallremove the packages, the composition rows, and the setting
--dsh-home DIRtarget a different harness home

Use

  1. Reload the harness page.
  2. Click + in the sidebar's workspace header — or the 🖥 button in the sidebar foot, which opens the same dialog.
  3. Choose Remote server (SSH).
  4. Click + Server and fill in the connection: name, host, port, user, private key path, or a password.
  5. Browse to the folder, then Use this folder.

The folder appears as a normal workspace. Sessions opened there reach the server, and the profile stays available for every other session.

The interface follows your browser's language: English, French, or Chinese.

Tailscale

Two different things are called "connecting over Tailscale", and the plugin keeps them apart.

The connect form lists your tailnet's peers; one click fills in the MagicDNS name, the user, and the transport when the peer runs the Tailscale SSH server. A peer reported as offline is named before the attempt, instead of surfacing as a connect timeout.

Work that outlives the harness

The agent loop runs inside the harness, so closing it ends the turn. What can keep working is the command, and detaching it is the whole trick: the plugin writes a small launcher on the server, starts it under its own session, and sends its output to a log file there.

Nothing to configure: work started in a remote workspace is detached by default, and one durable record per run lives in $DSH_HOME/remotes-sessions.json, shared by every session.

Updating

Re-run the installer. It rewrites its own composition block, and its closing line says which of two things the running harness needs:

node install.mjs       # or the curl one-liner again

Troubleshooting

SymptomCause and fix
does not answer as a POSIX hostA Windows SSH server. Use a Linux/macOS host, or expose that machine's WSL sshd on its own port.
Permission denied (publickey)Run ssh <host> by hand first; the plugin uses the same client, agent, and config.
Host key changedThe plugin refuses, correctly. Remove the stale line from known_hosts once you are sure.
glob/grep say a program is missingInstall ripgrep on the server (apt-get install ripgrep, dnf install ripgrep, apk add ripgrep).
A tailnet peer times outTailscale reported it offline; the connect form says so in advance.
The workspace shows no files in a local-only toolThat tool bypasses the filesystem seam, so it sees the empty local mirror. Use the workspace file tree.
Failed to load plugins … loaded without registering "…dsh-remote-ssh-ui" after an updateThe running harness still holds the package identity it read at boot. Restart dsh web; reloading the page is not enough.

Limits worth knowing

Links