DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

765199214 /

765199214/dsh-remote-sandbox

Verified

This plugin has no description yet.

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: master@3e038c3e

dsh-remote-sandbox

Run a DeepSeek Harness turn inside a remote OpenSandbox container: type /dsh-sandbox <message> and that message — and everything the agent does while answering it — executes in an isolated Linux sandbox instead of on your machine. Files the sandbox produces are copied back into your workspace automatically.

Nothing changes until you type the command. Other sessions, other turns, and every tool this plugin does not own keep their ordinary behaviour.

What it does

/dsh-sandbox <message> Attach a sandbox to this session, mirror the workspace into it, and answer the message there
/dsh-sandbox on / off Enter or leave sandbox mode without sending a message
/dsh-sandbox status Show the container, its state, and both mirror roots
/dsh-sandbox sync Copy sandbox changes back into the workspace immediately
/dsh-sandbox destroy Leave sandbox mode and delete the container
/dsh-sandbox help Usage

While a session is in sandbox mode:

  • pwsh and bash commands run inside the container, through its own shell (bash). The model is told to write POSIX commands rather than PowerShell cmdlets.
  • read, write, edit, glob, and grep read and write the container's copy of the workspace.
  • After every operation, new and modified files are copied back into the workspace, so generated output lands where you expect it. Local copies of write/edit results are updated immediately.
  • Tools that never touch the workspace (web_search, web_fetch, todo_write, skill, subagent and job surfaces, …) keep running on the host and are unaffected.

Fail closed: nothing silently runs locally

While a session is in sandbox mode, a workspace-touching call either runs inside the sandbox or it fails. The failure is an ordinary tool error the model sees:

沙箱处理失败:<what failed>
本次调用没有在本地工作区执行任何操作。

There is no fallback path. Specifically:

Situation Behaviour
The container answers 502/503 (paused, restarting, proxy blip) The client forgets the cached endpoint, asks the server to resume, retries up to 3 times; if it still fails, the call fails
The sandbox handle was lost (host restart) The plugin reattaches to the session's sandbox by metadata; if that fails, the call fails
The tool is workspace-touching but not routed Refused with SANDBOX_TOOL_UNSUPPORTED, never delegated
A command ran but its files could not be pulled out The call fails and says so — a file left in the container was not delivered

Local execution happens only when the session never invoked /dsh-sandbox. The mode flag — not the presence of a live container — is what gates every call, so a lost handle can never quietly turn sandboxed work into host work.

Verify it yourself: /dsh-sandbox status prints the server's reachability and probes the container (container: usable — Linux 6.8.0-… x86_64, pwd /workspace). Inside a sandboxed turn, uname -s reports Linux and /etc/os-release exists, while the host is Windows.

Install

The plugin is a DSH bundle: its cordis.patch.yml declares one row, and the package's lib/index.js is the host plugin. There is no build step — the shipped files are the sources DSH loads.

From a tarball (what to hand to someone else)

# the recipient, inside their own profile:
dsh plugin --profile web add ./dsh-remote-sandbox-0.1.0.tgz
# then restart DSH once

npm pack / pnpm pack in this directory produces exactly that tarball; the files field keeps it to lib/, cordis.patch.yml, README.md, and LICENSE.

With the dsh CLI, from a checkout

dsh plugin --profile web add link:/absolute/path/to/dsh-remote-sandbox

A linked package resolves through this checkout, so after any code change the plugin must be restarted: module roots are not watched.

By hand

  1. Make the package resolvable from the profile, e.g. a directory junction from %DSH_HOME%\profiles\<profile>\node_modules\dsh-remote-sandbox to this checkout.
  2. Add one row to the profile's cordis.patch.yml:
- id: remote-sandbox
  name: dsh-remote-sandbox
  config:
    baseUrl: 192.10.50.139:9999
    apiKey: replace-with-a-random-secret

With HMR active the row loads immediately; otherwise restart DSH.

Configure

Two places, same schema:

  • the row's config in the profile patch (shown above), and
  • Plugins → dsh-remote-sandbox → Configuration in the Web client, which renders the plugin's exported Schemastery Config as a form and writes the override back into the profile patch.
Field Default Meaning
baseUrl 192.10.50.139:9999 OpenSandbox server (host:port or an http(s):// URL)
apiKey replace-with-a-random-secret Sent as OPEN-SANDBOX-API-KEY
image ubuntu:24.04 Image used when a sandbox is created
execdPort 44772 Sandbox-side execd port, resolved through the lifecycle API
sandboxTimeoutSeconds 3600 Container lifetime; expired sandboxes are recreated on demand
requestTimeoutMs 60000 One lifecycle or file-transfer request
commandTimeoutMs 300000 Default command timeout inside the sandbox
remoteWorkspace /workspace Directory that mirrors the session workspace
syncOnStart true Upload the workspace when sandbox mode starts
pullBack true Copy new/changed files back after every operation
pullBackDeletes false Also delete local files the sandbox lost
maxUploadBytes / maxPullBytes 8388608 Per-file size caps for either direction
exclude node_modules, .git, … Never uploaded
pullBackExclude node_modules, .git Never copied back
systemPrompt true Tell the model it is inside the sandbox

How it works

  • Activation. /dsh-sandbox is a human command (ctx.commands.register), so the command line never reaches the model as text. The handler creates or reattaches a sandbox, then submits the remaining message with agent.steer() — an ordinary user message, so the normal turn runs.
  • Identity. Sandboxes carry metadata dsh-session-id; a restart or a later /dsh-sandbox reattaches to the same container and its files. The server's own timeout reclaims stale ones.
  • Tool routing. The plugin wraps the registry's tools/execute waterfall. For a session in sandbox mode it routes pwsh, bash, read, write, edit, glob, and grep to the container, returns a result built to each tool's own output.schema, and refuses anything else that could touch the workspace. Only sessions with the mode flag set are affected.
  • Mirroring. The workspace is uploaded once (find-based manifest + per-file upload), then each operation is followed by a manifest diff that downloads only what changed. The sandbox manifest is re-read after any upload, so a file is never uploaded and downloaded again in the same turn.
  • Model guidance. A system-prompt section (order 550, only while sandbox mode is on) explains the container, the path mapping, POSIX commands, the failure contract, and that files are copied back.

Handing it to someone else

  1. Pack it: npm pack (or pnpm pack) in this directory → dsh-remote-sandbox-0.1.0.tgz.
  2. They install it into their own profile: dsh plugin --profile <profile> add ./dsh-remote-sandbox-0.1.0.tgz, then restart DSH once.
  3. They set their own baseUrl and apiKey — on Plugins → dsh-remote-sandbox → Configuration, or in their profile's cordis.patch.yml. The built-in defaults point at the documented test server and will not reach their environment.
  4. They confirm the wiring with /dsh-sandbox status: it prints whether the server answers, the container's state, and a live probe of the container.

Two notes for recipients:

  • @deepseek-ai/schemastery is a peer dependency: the harness supplies it, and it is what renders the Configuration form. A profile that cannot resolve it will not show the form.
  • Nothing else is needed — no build step, no runtime dependencies, plain ESM. If they prefer a checkout, add link:<dir> works too, but then every code change needs a restart.

Requirements

  • DSH with ctx.commands, ctx.tools, and ctx.systemPrompt (any base-backed profile), >= 0.2.x.
  • An OpenSandbox server reachable from the DSH host, with an image whose execd exposes the /command, /files/*, and /directories* routes.
  • Node 22.19+ or 24+ (uses the global fetch, FormData, and Blob).

Tests

# against a live server: create/list/exec/upload/download/delete, timeouts, exit codes
node test/smoke-opensandbox.mjs

# the fail-closed contract, with no server needed: every sandboxed call either runs
# remotely or fails, and never falls through to the host
node test/isolation.mjs

# the plugin under the real Cordis runtime with stand-in services
node test/cordis-load.mjs

# the whole plugin (command → tools → sync) with a stand-in host context
node test/e2e-plugin.mjs

The last three run offline except e2e-plugin.mjs, which drives a real sandbox; that one and the smoke test read SANDBOX_URL and SANDBOX_KEY from the environment, defaulting to the documented test environment.

Known limits

  • Paths outside the workspace are refused in sandbox mode; only the workspace is mirrored.
  • Commands run in the foreground; run_in_background is rejected with a clear message.
  • read_image is not routed, so it is refused in sandbox mode; images the container produces are copied back first, then can be read after leaving the mode.
  • Local edits made while sandbox mode is on are uploaded before the next remote command, but not pushed continuously. A failed upload warns instead of failing the command.
  • Sandbox mode is bound to the session that ran the command. Subagents started from that session have their own sessions and therefore still run on the host. If that matters, ask the model to do the work in the main session rather than in a subagent, or set systemPrompt: false and instruct it yourself.
  • Sandboxes outlive the host on purpose (they are reattached by dsh-session-id metadata) and are reclaimed by the server's timeout unless /dsh-sandbox destroy removes them.
  • A new bundle needs the host to recompose. With HMR active the row loads as soon as the profile changes; otherwise restart DSH once after installing. A linked package's code changes always need a restart, because module roots are not watched.
—/ 5

No ratings yet

Verified DSH bundle

Commit 3e038c3ebf0a

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout