dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
dsh-acp-v1 is, at heart, a dsh plugin: it supplies the ACP capabilities missing from dsh's built-in ACP, and serves the DeepSeek Harness to the Zed editor as a custom ACP agent-server extension (an interactive ACP v1 server).
Run DeepSeek Harness agents inside Zed's Agent Panel over the Agent Client Protocol (v1): create/close threads, stream text + reasoning, live tool cards, plan updates, slash commands and installed agent skills, session history, permissions, model/thought-level/preset selects, elicitation forms — while every tool runs inside the dsh sandbox with dsh's own model route.
dsh CLI (tested on 0.2.0-rc.2) — install globally first:
npm install -g @deepseek-ai/dsh@0.2.0-rc.2
dsh --version # → 0.2.0-rc.2
pnpm (the dsh plugin command delegates to pnpm)
Zed with the Agent Panel (ACP v1)
A DeepSeek API key: DEEPSEEK_API_KEY env var, or configured once in dsh
Web (Models settings → writes ~/.dsh/.credentials.yaml)
The plugin is installed as a profile bundle. Pick a profile name (the
examples use acp); the boot command is then dsh --profile acp.
# HTTPS (public repository; use a credentialed URL for a private one)
dsh plugin --profile acp add https://github.com/dangpangch/dsh-acp.git
The repository ships its prebuilt bundle (lib/), so the install is a plain
fetch — no build scripts, no extra allowlist. Repeat add (or remove +
add) after pulling new commits to upgrade the installed copy.
dsh plugin --profile acp add /path/to/dsh-acp
This installs a pnpm link to the local checkout. After changing the source code, rebuild and the running profile picks it up on next boot:
pnpm build # tsdown -> lib/
dsh plugin --profile acp add seeds a fresh profile with the CLI's template,
which also bundles the official automation-only
@deepseek-ai/dsh-acp-app. In that composition the official bridge answers
the client (agentInfo.name = deepseek-harness-acp, no session/close, no
live deltas) and this plugin never gets the connection.
Remove it from the profile's own package.json so the bundle list is exactly
base + this plugin, then restart the profile:
// ~/.dsh/profiles/acp/package.json
"dsh": {
"profile": {
"bundles": ["@deepseek-ai/dsh-base", "dsh-acp-v1"]
}
}
Verify the running bridge with dsh --profile acp + initialize:
agentInfo.name must be dsh-acp-v1.
Add a Custom Agent to Zed's settings.json
(~/.config/zed/settings.json on Linux; Cmd+, → "Open Zed Settings" from
the agent panel otherwise):
{
"agent_servers": {
"DeepSeek Harness (acp)": {
"type": "custom",
"command": "dsh",
"args": ["--profile", "acp"]
}
}
}
Notes:
command: "dsh" assumes dsh is on PATH (npm global install). If a
GUI-launched Zed cannot find it, start Zed from a terminal that has dsh
on PATH, or set command to the absolute path of the dsh binary.DeepSeek Harness (acp). The thread toolbar offers Preset (while the session
is still blank), plus the Model / Thought Level / Write permission selects.DEEPSEEK_API_KEY is optional in agent_servers[].env — without it dsh uses
the credentials already stored by dsh Web.stdout must contain only JSON-RPC; EOF must exit 0:
printf '%s\n%s\n' \
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":1,"clientCapabilities":{}}}' \
'{"jsonrpc":"2.0","id":2,"method":"session/new","params":{"cwd":"/tmp","mcpServers":[]}}' |
dsh --profile acp
Expect two result frames (initialize → protocolVersion 1, session/new →
sessionId), then exit 0.
session/new · list · load · resume · close · delete with durable
history (session-query/persistence); load replays committed content per
ACP semantics.agent_message_chunk, streamed reasoning, tool cards
(execute cards carry the concrete command line in their title), plan/todo
updates, usage_update, available_commands_update slash catalog = dsh
command plane + user-invocable skills (~/.agents/skills,
<project>/.agents/skills, .dsh/skills). Skills follow the pi-acp naming
convention: announced as skill:<name> (/skill:find-skills in the /
popup), commands keep plain names; picking one loads the skill body through
dsh's tool-skill pre-step.tool_call_update, folding with
the card. Commands run under dsh's own sandbox/approval; nothing is ever
executed inside the client.session/request_permission (allow-once /
reject-once). A pending escalation is announced in the conversation stream
before the request, so the wait is visible even when you are not looking at
that session.authenticate via DEEPSEEK_API_KEY or dsh Web credentials;
AUTH_REQUIRED with a sign-in method when missing.ask_user_question → ACP form (when the client declares
elicitation.form).Honestly not implemented (never advertised): session fork, delegated
terminal/fs execution (commands run only in the dsh sandbox — the client
renders captured output as card content, it never executes the agent's
command), additionalDirectories,
audio/embeddedContext, MCP mounting (non-empty mcpServers is accepted and
ignored — no MCP tools are mounted, noted on stderr), fine-grained diff
cards, Windows.
The agent preset and the default model route are deployment fields, read from the environment once at boot (changing them means restarting the agent):
DSH_ACP_PRESET — the preset every ACP session is composed from (default
standard; the roster this bundle ships: standard, ptc, minimal,
cordis). A value no installed preset supplies fails session/new with a
readable error listing the available presets. This bundle ships the host rows
the non-standard presets need (cordis-host-runner +
cordis-inspect-providers for creator mode; the terminal / tool-presentation
packages are devDependencies), so a base-only profile — and the standalone
dev boot — mounts all four.DSH_ACP_PROVIDER / DSH_ACP_MODEL — the shipped default route
(deepseek-official / deepseek-v4-flash); the per-session Model config
option still overrides.Presets are a deployment default and a blank-session session option. A new
thread advertises a Preset selector: while the session has produced no
turn, picking another preset recomposes the agent — tool set, prompt sections,
skills — the same switch dsh Web performs. dsh fixes the composition at the
first turn (agent-preset/locked), so the bridge drops the selector at
turn/start: after that the preset is a property of the session and only a new
thread can change it. A reloaded session re-mounts the preset its log last
selected, not the one DSH_ACP_PRESET names now.
On dsh 0.2.0 the preset roster is declarative: the registry scans no
directories, so this bundle ships the four compositions as
presets/<id>.patch.yml (@deepseek-ai/dsh-agent-preset rows, listed in
package.json dsh.bundle.patch) and disables dsh-base's agent-plane rows so
each session's preset owns its tool surface. Add a preset the same way a
deployment does: insert a @deepseek-ai/dsh-agent-preset row from your
profile's own cordis.patch.yml. A preset whose composition cannot mount is
not offered (and a direct pick fails with a readable error).
pnpm install
pnpm typecheck # tsc --noEmit
pnpm build # tsdown -> lib/
pnpm test # vitest (175 tests incl. spawned frame-purity + history probes)
node scripts/conformance.mjs # ACP v1 wire conformance + mount audit
node scripts/preset-smoke.mjs # deployment env fields (preset/provider/model)
node scripts/history-probe.mjs # session history end-to-end (isolated DSH_HOME)
The dev/probe boot composes @deepseek-ai/dsh-base + every dsh.bundle.patch
layer of this package (cordis.patch.yml then presets/*.patch.yml). Set
DSH_ACP_DEV_PATCH=<patch.yml> to append one more layer — the way the probes
author a preset, since the 0.2.0 registry scans no directories.
Layout: src/bridge/index.ts (plugin entry), catalog.ts (slash catalog),
replay.ts (history → ACP frames), tool-cards.ts (card titles/kinds),
{codec,updates,content,config-options,session-store}.ts (wire builders /
decision tables), src/dev-bin.ts (isolated dev/test boot),
cordis.patch.yml + presets/*.patch.yml (bundle patch).
docs/design.zh.mddocs/design-summary.en.md