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.

Mux — DSH Plugin for DeepSeek Harness
DeepSeek Harness Plugin Hub
ProfilesPluginsCategoriesNewsDocsSign inManage Profiles
ProfilesPluginsCategoriesNewsDocsSign in
← Plugins
M

@freepeak/dsh-mux

Mux

DeepSeek Harness plugin: talk to coding CLIs (Claude Code, Cursor, …) from the GUI and keep the thread.

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

npx -y @deepseek-ai/dsh plugin --profile web add github:FreePeak/dsh-mux#5c13e253042bbe3b65e0052e5e93bdacb4e3f54c
READMECompatibilityVersions
Mux panel with discovery strip

Compatibility and provenance

Mux is published as @freepeak/dsh-mux and currently resolves to version 0.2.0. 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/23/2026

Versions

0.2.0stable
9/23/2026

Related plugins

Loading related plugins…

Latest
0.2.0
DSH
*
HMR
Process restart
Tree shaking
Safe tree shaking not declared
Unpacked size
Unavailable
Files
Unavailable
Surface
web
License
MIT
Source
github
GitHub
★ 4
Weekly downloads
0
Last push
9/24/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

Related plugins

More verified plugins in developer-tools.

Web App@deepseek-ai/dsh-web-appThe dsh browser-surface bundle: the web patch layer over dsh-base plus the runtime glue plugin (frontend dist serving, web-surface prompt, bash runtime variables, URL line)Sdk App@deepseek-ai/dsh-sdk-appThe dsh SDK profile bundle: stdio JSON-RPC serving and process lifecycle over dsh-baseExperimental Inspector@deepseek-ai/dsh-experimental-inspectorExperimental cross-realm CDP hub for Host debugging and Client Runtime inspectionExperimental Inspector Profile@deepseek-ai/dsh-experimental-inspector-profileOptional Web bundle for raw Session logs and Chat node inspection

README

dsh-mux

Talk to other coding CLIs from inside the DeepSeek Harness GUI — and keep the thread.

Install · CLIs · Architecture · Docker · Dev · License


What it is

dsh-mux is a DeepSeek Harness external bundle: a sidebar page, slash commands, a host tool, and a remote service that let you talk to other coding CLIs — Claude Code, OMP, Pi, Cursor, Agy, Command Code, opencode — from the DSH web GUI, with each conversation kept alive as a thread.

Instead of switching terminals, open Mux, pick a CLI, type a follow-up, and the same CLI session continues where it left off (resume by the CLI's own session id). Stream output in real time, stop a turn in progress, or hand a session id to the model with the mux tool.

This is not a standalone server, not a HarnessRouter deployment, and not a live bidirectional PTY. It runs one CLI process per turn, resumed by session id.

Mux panel with discovery strip

Table of contents

  • Installation
  • First run
  • Run in Docker
  • Validation (container)
  • Supported CLIs
  • Architecture
  • How it works
  • Configuration
  • Development
  • Brand assets
  • Security
  • Contributing
  • Changelog
  • License

Installation

# from a clone or release checkout
dsh plugin install /path/to/dsh-mux

Installed into the active web profile (patch reload is live on that profile, so later edits to the bundle are picked up without a full restart).

Put the target CLI binaries (claude, omp, pi, cursor, agy, command-code) on your PATH. opencode is tracked but reported as missing until its binary appears.

Requirements

Node.js≥ 22 (build + tests)
HostDeepSeek Harness web profile (dsh web)
OptionalPlaywright (container drive script)

First run

  1. Start the GUI (dsh web prints http://127.0.0.1:3081/?token=...).
  2. Click Mux in the sidebar — the discovery strip shows which CLIs are installed.
  3. Type a message and hit Send. The CLI runs non-interactively (accept mode) and streams its reply into the panel and the DSH transcript.
  4. Type a follow-up — it resumes the same CLI session id rather than starting fresh.

From the composer:

/mux                  # open the Mux panel
/mux claude say hi    # start a thread; result goes to the transcript
/ask omp explain this # same thing, shorter name

Run in Docker

A self-contained container boots DSH with dsh-mux installed, including a fixture claude CLI (docker/fixtures/claude) that validates the full spawn → stdin → session-id → resume pipeline without model credentials:

docker compose -f docker/docker-compose.yml up --build -d
docker compose -f docker/docker-compose.yml logs -f   # `dsh web:` line has the token

Open http://127.0.0.1:3101/?token=... (host loopback only — the harness refuses a wildcard bind, so an in-container relay forwards to its private 127.0.0.1:3099).

Re-seed profileFORCE_REINIT=1 docker compose -f docker/docker-compose.yml up -d
Full resetdocker compose -f docker/docker-compose.yml down -v

Validation (container)

scripts/drive.py walks the container end-to-end over the harness wire API (workspace → session → commands.execute → panel) and captures:

ScreenshotProves
01 · boot / sidebarContainer boots; client bundle loads; Mux entry renders
02 · commands/mux + /ask claude execute; fixture returns mux · claude · exit 0
03 · discoveryPanel + discovery strip via remote.mux.discover()
04 · thread turnsStored thread shows prompt / answer turns

Full transcript (including the resume proof — a second send on the same thread passes cliSessionId to --resume and the fixture echoes it back): docs/screenshots/drive.log.

python3 scripts/drive.py "http://127.0.0.1:3101/?token=..."   # needs Playwright
python3 scripts/shot.py  "http://127.0.0.1:3101/?token=..."    # onboarding walkthrough

Supported CLIs

Every adapter keeps the prompt on stdin, never in argv, and runs in non-interactive accept mode so a turn can never block on a prompt nobody can see.

CLIFirst turnResume turnStatus
Claude Code-p --output-format stream-json--resume <id> -pready
OMP-p --mode json--resume <id> -pready
Pi-p --mode json--resume <id> -pready
Cursoragent -p --output-format stream-jsonagent --resume <id> -pready
Agy-p --output-format stream-json--conversation <id> -pready
Command Code-p --output-format json --skip-onboarding--resume <id> -pready
opencode(binary missing)(n/a)missing

Architecture

 You ──► DSH Web GUI
            │
     ┌──────┴──────────┐
     ▼                  ▼
 Mux page            DSH agent
 (thread list,       (/mux, /ask,
  composer,          tool mux)
  Send / Stop)
     │                  │
     └────────┬─────────┘
              ▼
         dsh-mux host ──► Thread store (cliSessionId)
              │
              ▼
   Coding CLIs (one process per turn)

Interactive diagrams:

  • Architecture
  • One-turn workflow
  • Resume sequence

Design decisions

  • One CLI process per turn. Resume is driven by the CLI's own session id — uniform across all seven targets without a long-lived RPC pipe.
  • Fail-closed. Timeouts, empty stdout, or unknown IDs produce clear errors. Stop kills the running process (SIGTERM → SIGKILL).
  • Threads persist in JSON under the profile data dir. Deletion removes the mux record only — the CLI's own session files are untouched.
  • The model can drive it. Tool mux accepts { tool, prompt, threadId } so an agent can start or continue a thread inside a larger task.
  • Host remote + browser mount. The page mounts a hand-authored typert contribution (ctx.remote.$mount) and reads via ctx.get('remote.mux').

How it works

  1. runTurn spawns the chosen CLI with print args + permission-mode flag.
  2. The prompt is written on stdin; stdin is closed; stdout/stderr stream.
  3. A session id is parsed from the CLI output and stored on the thread.
  4. The next turn feeds that id through the CLI's resume flag.
  5. Every result carries a header: mux · claude · 4.2s · exit 0.

Default ceilings: 10 minutes per turn, 1 MiB combined output.

Configuration

Host config (schemastery) — all fields are .default(...) (no .optional()):

KeyDefaultMeaning
turn timeout600000 msWall clock per spawn
output cap1048576 bytesCombined stdout + stderr
(empty string fields)''Reserved / path overrides

See src/plugin.ts for the live schema.

Development

npm install
npm test          # 28 tests, offline
npm run build     # tsdown → lib/*.mjs
ScriptPurpose
testnode --experimental-strip-types --test test/*.test.ts
buildBundle src/index.ts + src/remote.ts into lib/

CI

Every push and pull request to main runs .github/workflows/ci.yml: npm ci → unit tests → build → artifact gates. While the repository is private, jobs run on a self-hosted macOS runner labelled dsh-mux (~/actions-runners/dsh-mux, launchd service) so they do not burn the org's limited hosted Actions minutes. If the repository is made public, switch runs-on back to ubuntu-latest before opening it — fork PR code must never execute on a maintainer machine.

Project layout

dsh-mux/
├── assets/              # logo, mark, favicon, social card
├── package.json         # dsh.bundle + dsh.client, exports (./, ./remote, ./client)
├── cordis.patch.yml     # rows: dsh-mux + dsh-mux-remote
├── client.js            # browser: sidebar + panel + remote contribution
├── docker/              # Dockerfile, compose, entrypoint, fixture claude
├── scripts/drive.py     # container validation + screenshots
├── src/
│   ├── adapters.ts      # seven CLI specs
│   ├── discovery.ts     # PATH strip
│   ├── run.ts           # spawn / stream / cap / kill
│   ├── threads.ts       # JSON thread store
│   ├── commands.ts      # /mux + /ask parser
│   ├── plugin.ts        # host tool + commands (no default export)
│   ├── remote.ts        # host remote (hand-applied @Remote markers)
│   └── index.ts         # cordis entry (named exports only)
├── test/                # 28 tests + artifacts gates
└── docs/                # PRD, diagrams, screenshots, UI sketch

Hard-won constraints (also in CONTRIBUTING.md):

  • Function plugin must not export default (inject would be stripped).
  • No raw @Remote in shipped JS — hand-apply markers.
  • schemastery: .default(), not .optional().
  • Browser: ctx.get('remote.mux'), not ctx.remote.mux.

Brand assets

Asset
markmark.svg · favicon.svg
logo.svg · logo-dark.svg
mark-light.svg · mark-mono.svg
social-card.svg (1280×640)

Two inbound strokes join at a mux node and leave as one outbound trunk with a green continuity dot — many CLIs in, one resumed thread out. Details: assets/README.md.

Security

Spawning local CLIs is intentional and constrained: prompt on stdin (never argv), fail-closed turns, real time/output ceilings. See SECURITY.md for the supported versions line and how to report vulnerabilities privately.

Contributing

Contributions are welcome. Please open an issue before large changes. Read CONTRIBUTING.md and the Code of Conduct.

PR checklist (short form):

  • npm test green (28)
  • npm run build if host/remote sources changed
  • No new runtime dependency without justification
  • CHANGELOG.md updated when behaviour changes

Changelog

See CHANGELOG.md.

License

MIT © FreePeak


Built for the DeepSeek Harness ecosystem. Not affiliated with Anthropic, OpenAI, Cursor, or any of the supported CLIs.