DeepSeek Harness Plugin Hub

Publish and manage complete Harness Profiles. Discover Plugins for your next setup.

Explore

PluginsPresetsDocsNews

Community

Publish a pluginContactReport an issue

Resources

Plugin Hub on GitHubDeepSeek HarnessSystem statusPrivacy notice
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

Independent and unofficial. Not affiliated with, authorized by, or endorsed by DeepSeek.

Remote Workspace — DSH Plugin for DeepSeek Harness
← Plugins
R

@yujyf/dsh-remote-workspace

Remote Workspace

Local/WSL remote-workspace execution routing for DeepSeek Harness: a profile bundle plus the sidebar workspace selector

The plugin will be installed here. Keep web if you are unsure.

npx -y @deepseek-ai/dsh plugin --profile web add github:Yujyf/dsh-remote-workspace#8c3c3534e6ac1c3dbe752252190dd8c5b08288b8
READMECompatibilityVersions

Compatibility and provenance

Remote Workspace is published as @yujyf/dsh-remote-workspace and currently resolves to version 0.1.5. The Hub verifies its manifest and preserves the exact installation source for reproducible installs.

DSH compatibility
*
Runtime surfaces
web
Release source
github
Registry updated
9/10/2026

Versions

0.1.5stable
9/10/2026
0.1.1stable
9/9/2026

Related plugins

Loading related plugins…

Latest
0.1.5
DSH
*
HMR
Process restart
Tree shaking
Safe tree shaking not declared
Unpacked size
Unavailable
Files
Unavailable
Surface
web
License
MIT
Source
github
GitHub
★ 0
Weekly downloads
0
Last push
9/10/2026
View source ↗
README badge

Click the badge to copy Markdown for your README.

Do you maintain this Plugin?Claim benefit · Priority security scan

Verify the GitHub repository declared in package.json to manage this listing. After you claim it, Hub will prioritize a security scan of the current version and publish the result when it passes.

Claim this Plugin →
Report an issue
DeepSeek Harness Plugin Hub
ProfilesPluginsCategoriesNewsDocsSign inManage Profiles
ProfilesPluginsCategoriesNewsDocsSign in

Related plugins

More verified plugins in productivity-workflow.

Acp App@deepseek-ai/dsh-acp-appThe dsh ACP profile bundle: automation-only JSON-RPC stdio and process lifecycle over dsh-baseClient Ui Task Board@linxin666/dsh-client-ui-task-boardHost-authoritative task board for the DSH Web GUI with real session execution, Host cron scheduling, and optional cross-platform idle-sleep protection; mounted without DSH source changes.Web All@linxin666/dsh-web-allDSH Web UI 全家桶聚合插件:一键安装全部功能插件(task-board / git-graph / pet / remote-web-ui / web-ui-settings / skin-center / community-plugins / compat shim)。compat 桥接层已并入本包(src/client),无需独立 compat npm 包。Agent Teams@nanmicoder/dsh-agent-teamsAgentTeams for DeepSeek Harness: multi-agent team collaboration (captain, members, tasks with dependencies, messaging) driven by natural language, with a tree monitor in the web GUI

README

@yujyf/dsh-remote-workspace

Run one DSH session inside a Local or WSL execution world, chosen per session from the Web GUI, without forking DSH and without adding a single wsl_* model tool.

简体中文

What it does

DSH ships one filesystem backend and one subprocess backend per profile. This package replaces both with routers: every existing model tool (bash, read_file, write_file, edit_file, …) keeps its name and schema, while the backend underneath resolves the session's current workspace binding and delegates to the right execution world.

  • No binding — the shipped sandboxed local backend, unchanged. This is what every session uses until it is bound.
  • WSL target — a distribution reached through wsl.exe; file and process operations run inside that distribution with POSIX paths, its own home, and its own toolchain.

One sidebar entry registers the selector: pick a target, browse to a folder, register it as a workspace, and bind it to the open session. From the next model request on, that session's shell commands, file reads and writes, and file searches execute there, with the bound directory as their working directory, and a runtime-context note tells the model which world it is in and to use bash.

The selector lists remote worlds only. The host's own world is never offered, because a session with nothing bound already runs there; on a Windows host the list is one row per WSL distribution. DSH's own workspaces appear beside them under Local, and the world filter narrows the list to a single execution world.

Every remote workspace is also registered as a DSH workspace, under the distribution's UNC view of its directory (\\wsl.localhost\Ubuntu-26.04\home\me\project) and titled <name> · WSL <distro>. That entry is what puts the workspace into DSH's own workspace list and in front of every other plugin reading ctx.workspaceRegistry, instead of living only in this package's registry; removing the registration removes it again. A session created in that workspace from DSH's own surface runs in the distribution without any binding, because the session directory already names the world.

Run on the host again releases the binding: the session goes back to running on the host, and nothing is deleted.

Requirements

DSH>=0.1.0 <0.2; verified on 0.1.2-rc.1 (the version the desktop app ships) and built against the 0.1.5-alpha.2 type surface
Node^22.19 || >=24
OSWindows 10/11 for WSL targets; on macOS and Linux the selector has no remote world to offer
WSLwsl.exe on PATH, with at least one registered distribution

WSL targets are only enumerated on Windows (process.platform === 'win32'). On every other platform the remote target list is empty, and sessions keep running in the host world.

Install

dsh plugin --profile web add github:Yujyf/dsh-remote-workspace

The command forwards to pnpm inside the profile directory and then reconciles dsh.profile.bundles, so this package's cordis.patch.yml joins the profile's patch layer automatically. Restart the profile (or reload the Web GUI) to compose it.

Prebuilt lib/ is committed, so the install runs no build step. Removing it:

dsh plugin --profile web remove @yujyf/dsh-remote-workspace

Use

  1. Open a session in the Web GUI.
  2. Click Remote workspace at the bottom of the sidebar. The list shows Local (DSH's own workspaces) plus every WSL distribution; the filter row above it narrows the list to one world.
  3. Pick a WSL distribution. The status dot shows Available, Starting, Stopped, or Unavailable; connecting a Stopped distribution starts it.
  4. Browse folders…, navigate to the project directory, and choose Use this folder. The folder is registered as a workspace, connected, and added to DSH's own workspace list as <name> · WSL <distro>.
  5. Click Use in this session on a workspace row. The panel header then reads This session runs here · Ubuntu-26.04 · /home/me/project, and bash, file reads, and file writes for that session execute in that directory. Relative paths resolve there, and the next request tells the model its world, directory, and to use bash instead of pwsh.
  6. Run on the host again releases the binding; Remove deletes the registration only — the folder and its files stay untouched.

A session with no binding keeps running on the host. Binding is per session, so two open sessions can execute in two different worlds at the same time.

How it is wired

Five Cordis plugins, one capability seam each:

EntryServiceRole
.ctx.remoteWorkspaceOwner: targets, workspace registrations, connect/disconnect, session binding, health, directory listing, canonical URI resolution
./fsctx.fsFilesystem router: local binding → isolated sandboxed backend; WSL binding → helper-backed WslFileSystem
./subprocessctx.subprocessProcess router: local binding → isolated local backend; WSL binding → wsl.exe argv translation
./controllerctx.webServer routeJSON API the browser half calls: POST /remote-workspace/api/<verb>
./ui + ./clientsidebar slotSelector entry, panel, folder browser

cordis.patch.yml disables the shipped subprocess and fs-sandbox rows and inserts these five, so exactly one provider serves ctx.fs and ctx.subprocess in the composed tree.

The browser half talks to the Host over a plain JSON route rather than a Remote namespace. DSH mounts Remote namespaces from a fixed list compiled into @deepseek-ai/dsh-api-remotes, so a package outside that assembly cannot contribute one; the client fiber would then wait forever for remote.<namespace> and the Web shell would never finish booting. The route applies the same browser-trust fence as the /api gateway: the request's Host authority must be loopback, or an authority the deployment declares in webRuntime.trustedHosts.

Design constraints this package holds to:

  • No wsl_* tools. Execution worlds are selected by the backend, not by the model's choice of tool name.
  • No fake cwd. A WSL workspace is never presented to Windows as \\wsl.localhost\… or /mnt/c/…; paths stay native to the world that executes them.
  • No daemon, no runtime install. The WSL bridge starts a helper process inside the distribution on demand and speaks a line protocol over stdio; no HTTP server, no Node or Python requirement inside WSL.
  • No DSH core changes. Everything composes through the published plugin and patch-layer contracts.

How a bound session works in its world

DSH fixes a session's working directory when the session is created, and that header is immutable. Binding therefore does not rewrite the session; the routers translate each request instead:

  • The session's own host directory (E:\work\project) becomes the bound workspace directory (/home/me/project), which is where a defaulted or relative tool path lands.
  • Any other host path keeps its drive mapping (C:\Users\me is /mnt/c/Users/me), so an explicit workdir still reaches the host file it names.
  • A runtime-context entry, emitted only while the session is bound, states the distribution, the working directory, and that bash is the shell to use — PowerShell does not exist inside WSL.

The session's recorded directory is read from the live session; the binding stays durable, so a restart rebinds the same world.

Configuration

Set on the inserted remote-workspace row in the profile's cordis.yml (defaults shown):

- id: remote-workspace
  name: '@yujyf/dsh-remote-workspace'
  config:
    autoStart: true             # start a stopped distribution when one of its workspaces connects
    shutdownOnDisconnect: false # never terminate a distribution another session may be using
    commandTimeoutMs: 30000     # ceiling for one wsl.exe invocation

Known limitations

  • Windows + WSL only for remote worlds. SSH, Docker, and Podman targets are reserved by the target-type abstraction but not implemented.
  • The DSH workspace entry carries the UNC path. DSH's workspace registry only accepts a directory the harness process resolves, so the registered workspace is \\wsl.localhost\<distro>\…; that is also what a session created there records as its directory. Registering one therefore needs the distribution running (the flow connects first), and a distribution stopped afterwards leaves that workspace's directory unresolvable to DSH.
  • One binding per session. Rebinding mid-session is allowed; the previous world's processes are not migrated.
  • The session header keeps its host directory. DSH exposes no way to rewrite it, so the model's prompt still names the host path while the tools resolve in the bound world; the runtime-context note is what keeps the two consistent.
  • pwsh cannot run in a bound session. PowerShell does not exist inside WSL; the note directs the model to bash. The tool stays in the schema because DSH selects tools by host platform.
  • WSL file operations are per-call. There is no persistent in-guest filesystem handle; each call crosses the bridge.
  • Distribution termination is never automatic unless you set shutdownOnDisconnect: true.

Development

pnpm install
pnpm run typecheck   # host face + client face
pnpm run test        # behavior tests for the pure workspace-identity helpers
pnpm run build       # tsc (host face, client declarations) + esbuild browser bundle

lib/ is committed on purpose: a git install must not need a build step, and pnpm blocks dependency build scripts until they are allowlisted. Rebuild and commit lib/ together with any source change.

Layout:

src/                 host face: owner, fs router, subprocess router, controller, wire types
src/client/          browser half: slot entry, panel component, store, dictionaries
tests/               behavior tests, run against the built lib/
cordis.patch.yml     the profile layer this package contributes
scripts/build.mjs    tsc + esbuild closure-factory bundle for the browser half

The two compiler faces stay separate because the host face pulls in @deepseek-ai/dsh-session's Host ctx.sessions merge, which conflicts with the Client Session object layer's merge of the same member.