Back to home

devloom1024

dsh-acp-gateway

Third-party complete DeepSeek Harness agent over the Agent Client Protocol (ACP) — a superset of the official automation-only @deepseek-ai/dsh-acp. npx one-command, offline archive, works with Zed / VS Code ACP / Claude Code.

Stars
0
Language
TypeScript
Created
Aug 15, 2026
Updated
Aug 15, 2026

Introduction

dsh-acp-gateway

An independent, third-party DeepSeek Harness agent over the Agent Client Protocol (ACP v1) — a complete ACP agent over stdio that any ACP-compatible client (Zed, VS Code ACP, Claude Code, ...) can launch directly. It is a superset of the official automation-only @deepseek-ai/dsh-acp: every ACP session is a real DSH agent with the same tool access, presets, sessions, and settings as the Web GUI.

Registry-style entry (see the ACP Registry):

FieldValue
Namedsh-acp-gateway
Version3.10.0
Transportstdio (JSON-RPC 2.0, newline-delimited)
ProtocolACP v1
Commandnpx -y dsh-acp-gateway
Capabilitiesstreaming, tool calls, sessions (list/load/delete), image/audio, slash commands, session modes (agent presets), config options (model / thought level / permission)

Quick Start

# One command — the package brings the full @deepseek-ai/dsh runtime, so no
# separate server, no global install. First launch downloads ~330 MB once.
npx -y dsh-acp-gateway

Zedsettings.json:

{
  "agent": {
    "acp": {
      "command": "npx",
      "args": ["-y", "dsh-acp-gateway"]
    }
  }
}

First boot takes ~15-20s (a full DSH instance boots); each agent window is its own process that exits with the window. Sessions persist in ~/.dsh (DSH_ACP_HOME isolates), so session/load resumes them later. Set the model provider's API key env var (e.g. OPENCODE_GO_API_KEY or DEEPSEEK_API_KEY).

Features

CapabilityDetail
✅ Token-level streamingassistant/chunk text deltas → agent_message_chunk
✅ Tool-call notificationstool_call (pending) → tool_call_update (completed/failed)
✅ Full tool accessmounts the selected agent preset: bash, fs, web, skills, subagents, ...
session/list / session/load / session/deleteresume persisted sessions with history replay
usage_updatetoken usage from assistant/message
✅ Image / audio prompt contentimage → DSH attachment; audio → textual reference
✅ Slash commandsavailable_commands_update + /cmd execution (incl. /plan, /plan off — the same channel the web GUI's Plan chip uses)
✅ Session modesthe agent presets (the web GUI's modes: Standard / Code(PTC) / Minimal / Creator / your custom presets), session/set_mode re-composes the agent, current_mode_update
user_message_chunkecho accepted prompts
✅ Embedded resource contentresource blocks expand into prompt text
✅ Session config optionsACP v1 configOptions (select) for mode (the agent presets), model (provider/model), thought_level, permission (read-only / workspace-write / danger-full-access)
✅ Permission approval flowworkspace-write asks the client through session/request_permission for mutating tools (edit/delete/move/execute)
✅ ElicitationDSH ask_user_question surfaces as an ACP elicitation/create form; answers feed back as the tool result
✅ Thinking streamagent_thought_chunk from DSH reasoning chunks
✅ Agent planexit_plan_mode markdown → ACP plan notification (entries)
✅ Session infosession_info_update on title changes

Architecture

ACP client (Zed / VS Code ACP / ...)
   │  stdio  (launches `dsh-acp-gateway` / `dsh-acp-agent` / `dsh-acp-server`)
   ▼
dsh-acp-gateway process (full DSH instance)
   │  agents.create() → real DSH agent (selected preset, full tools)
   ▼
DSH agent engine (same as the Web GUI)
  • Direct mode (default for editors): the client launches the server itself over stdio — stdio is the ACP channel, and the process exits when the client closes (1:1 lifecycle, no orphans).
  • Bridge mode: dsh-acp-agent is a thin stdio bridge to a long-running dsh-acp-server (endpoint discovery: DSH_ACP_URL~/.dsh/acp/endpointhttp://127.0.0.1:3080); one server can serve many clients/sessions.
  • Each ACP session maps to a real DSH agent/session (durable, resumable via session/load).

Installation

1. Zero-install: npx (recommended for editors)

See Quick Start. The package depends on the full @deepseek-ai/dsh runtime, so it is self-contained — no globally installed dsh app, no separate server process, no manual lifecycle.

2. Offline archive (no npm, no network)

Build a self-contained tarball with the full dependency closure, the shipped presets, and a portable vendor anchor. It expects a system node >= 20 (--embed-node bundles a Node binary instead):

bash scripts/package-offline.sh               # → dist-offline/dsh-acp-gateway-<ver>.tar.gz
bash scripts/package-offline.sh out --embed-node   # embed a Node runtime (~156 MB)

Extract anywhere and point an ACP client at the bundled launcher:

{
  "agent": { "acp": { "command": "/path/to/extracted/dsh-acp", "args": [] } }
}

The closure contains platform-specific native prebuilds (node-pty etc.), so build the archive on each target platform.

3. Deploy as a plugin inside a DSH deployment

npm install dsh-acp-gateway
# or clone this repo and: npm link

Add to your deployment cordis.yml (host plane):

- id: acp-gateway
  name: 'dsh-acp-gateway'
  config: {}

Requires the standard host services (agents, webServer, fs, shell, agentDefaultModel, approval, agentPresets, commands, attachments, sessionQuery). On start the plugin writes the stdio bridge to ~/.dsh/acp/dsh-acp-agent.js (endpoint embedded).

Client setup

Zedsettings.json:

{
  "agent": {
    "acp": {
      "command": "npx",
      "args": ["-y", "dsh-acp-gateway"]
    }
  }
}

VS Code (vscode-acp)settings.json:

{
  "acp.agent": {
    "command": "npx",
    "args": ["-y", "dsh-acp-gateway"]
  }
}

Any other ACP client — point it at npx -y dsh-acp-gateway, or at a local install (npm i -g ./dsh-acp-gateway-<ver>.tgz then dsh-acp-gateway), or at the extracted offline launcher (/path/to/dsh-acp).

Usage

Commands

CommandPurpose
dsh-acp-gatewaythe ACP agent itself (stdio direct mode)
dsh-acp-serveralias of the above
dsh-acp-agentstdio bridge to a long-running server (bridge mode)
dsh-acp-clienta scripted test client
npx dsh-acp-gateway
# --provider opencode-go --model deepseek-v4-flash (defaults, env-overridable)

By default the server shares your deployment home (~/.dsh): presets (including locally authored ones like anchored-standard), settings (default model, default preset, permission), sessions, and credentials are exactly the ones the web GUI uses. Set DSH_ACP_HOME (e.g. ~/.dsh-acp) for a fully isolated instance.

Session modes = agent presets

ACP session modes are the agent presets — the same "modes" the web GUI offers (Standard / Code / Minimal / Creator, plus your custom presets). The current mode follows the deployment default (agent-presets.default in settings); session/set_mode or the mode config option switches the preset, re-composing the agent at the next prompt. Plan mode is not a mode: it is toggled through the /plan and /plan off slash commands, exactly like the web GUI's Plan chip.

Test client

npx dsh-acp-client                        # interactive, via the bridge
npx dsh-acp-client --endpoint http://127.0.0.1:56045
echo 'init
new /tmp
prompt 运行 pwd 并报告' | npx dsh-acp-client   # scripted

Commands: init, new [cwd], prompt <text>, mode <preset-id>, set <configId> <value> (mode/provider/model/thought_level/permission), cancel, list, load <id>, delete <id>.

Protocol coverage

Implemented methods (Agent side): initialize, authenticate (no-op), session/new, session/prompt, session/cancel, session/list, session/load, session/delete, session/set_mode, session/set_config_option.

Notifications: agent_message_chunk, user_message_chunk, tool_call, tool_call_update, usage_update, available_commands_update, current_mode_update, config_option_update.

Session config options: mode (the agent presets — standard / code(PTC) / minimal / creation / your custom presets), model (provider/model — one selector across every provider), thought_level (minimal/low/medium/high/max), permission (sandbox file access: read-only / workspace-write / danger-full-access). Changing mode, model, or thought_level rebuilds the live agent from its persisted session; permission applies immediately and sets the approval policy (workspace-write asks the client via session/request_permission for mutating tools). Both configOptions and the modes field are returned (transition period per the spec).

Notifications additionally include agent_thought_chunk (reasoning stream), plan (from exit_plan_mode), and session_info_update (title changes). DSH ask_user_question maps to an ACP elicitation/create form.

Content: text, resource (embedded context), resource_link, image, audio.

Not implemented (by design): client-cooperative capabilities (fs/*, terminal/*, elicitation/*), MCP server connection, HTTP transport.

Troubleshooting

SymptomCause / fix
Editor stuck on "loading"The bridge could not reach any endpoint. Check ~/.dsh/acp/endpoint points at a live server (DSH_ACP_URL overrides), or use direct mode (npx -y dsh-acp-gateway). The bridge now answers with a JSON-RPC error and re-reads the endpoint file instead of hanging
Typing / shows no slash commandsZed drops available_commands_update sent before the session/new response (zed#60199); this gateway holds notifications until after the response — restart the agent and create a fresh session
session/delete leaves sessions behindFixed: persisted session dirs are removed with direct fs
Multiple ACP instancesMultiple clients can share one server (bridge mode); each direct-mode process is its own full DSH instance (~30-60 MB RSS each, 15-20s boot)
Plan mode does nothingPlan is toggled via /plan / /plan off slash commands, not a session mode

Development

The package is TypeScript compiled to ESM in dist/ (NodeNext). Logic lives in src/*.ts; bin/ artifacts are emitted to dist/src/bin/.

npm run check   # tsc --noEmit (type-check)
npm run build   # tsc (emit dist/)
npm test        # build + run unit tests against the build

Publishing

The package is self-contained for npx: it depends on @deepseek-ai/dsh (which brings the whole runtime closure), ships the preset roster in config/agent-presets, and carries the portable vendor anchor in vendor/ (regenerate after any dependency change):

npm install     # fetch the closure
npm run vendor  # regenerate vendor/dsh-app/package.json
npm run build
npm test
npm publish

Offline archive (for machines without npm/Node):

npm run pack-offline   # → dist-offline/dsh-acp-gateway-<ver>.tar.gz (~119 MB)

The runtime depends on the dsh installation's packages (resolved through the @deepseek-ai/* symlink farm in node_modules/). After any npm install, restore the links with:

./scripts/link-deps.sh

License

MIT