deepseek-harness-acp

by openma-ai

6 通知与集成npm 检测到 manifest package.json#dsh 社区精选 收录于 08-14

ACP profile 插件与独立 stdio server,可从 Zed 等 ACP 客户端使用完整 DSH agent,并共享 DSH 凭据与会话。

ACP profile plugin and standalone stdio server for using the full DSH agent from Zed and other ACP clients while sharing DSH credentials and sessions.

安装

dsh plugin --profile web add @openma/deepseek-harness-acp

从 npm 安装预构建包

安装与环境配置指引、插件开发教程见 DSH 中文社区文档 ↗

安装即在你的机器上以你的权限运行第三方代码——它可读写文件、使用凭据、访问网络,DSH 的工具审批不会为插件代码加沙箱。「检测到 manifest」仅代表发现 dsh.bundle / dsh.plugin 清单,不构成兼容性或安全审查;安装前请审阅源码,不熟悉的插件先在不含密钥的环境试用。

README

目录

The adapter composes the harness in-process and maps its session-event log onto the full ACP vocabulary: streamed text and reasoning, tool calls with diffs and display terminals, plans, permission requests, session modes, config options, slash commands, skills, and MCP servers. Credentials never touch your editor config — it reuses the key you saved in the dsh Web UI, or dsh-acp login saves one to the same store.

Two entry points, one embeddable plugin

A · dsh profile plugin (recommended) B · Standalone server
Best for Normal installation and upgrades Connecting an ACP client without managing a dsh profile
Install dsh plugin --profile acp add @openma/deepseek-harness-acp@latest npm i -g @openma/deepseek-harness-acp
Zed runs dsh --profile acp dsh-acp
Harness The dsh that owns the profile Your installed dsh — or the npm-installed peer when none exists
Composition dsh-base + this bundle + your profile's own patches dsh-base + this bundle (profile machinery booted in-process)

Both shapes share $DSH_HOME: the same credential store, settings, presets, and session logs as dsh web — conversations started in the Web UI can be listed and loaded from the editor.

Other dsh surfaces can mount the transport-independent @openma/deepseek-harness-acp/plugin on their Base Host tree and own the transport adapter. The TUI profile uses this path: it starts a separate TUI Client process and connects ACP over that process's standard stdin/stdout; it does not start dsh-acp or use an in-process Client stream.

The package is therefore not only a CLI wrapper. It is also the ACP surface plugin used by other dsh applications: one Host composition can expose the same sessions, tools, presets, skills, and persistence through a transport chosen by the surface.

npm install -g @deepseek-ai/dsh
dsh web                                                    # save your API key once
dsh plugin --profile acp add @openma/deepseek-harness-acp@latest
// Zed settings.json
{
  "agent_servers": {
    "DeepSeek Harness": { "command": "dsh", "args": ["--profile", "acp"] }
  }
}

The plugin command creates $DSH_HOME/profiles/acp, installs or upgrades the adapter, and registers its dsh.bundle patch. The bridge mounts over @deepseek-ai/dsh-base — the same product baseline as dsh web, with the module-reload watcher off. Extend the profile in $DSH_HOME/profiles/acp/cordis.patch.yml like any other dsh profile. A global dsh-acp installation is not required for this path.

B · Standalone server

npm install -g @openma/deepseek-harness-acp
dsh-acp login        # interactive; or save the key in the dsh Web UI
// Zed settings.json
{
  "agent_servers": {
    "DeepSeek Harness": { "command": "dsh-acp" }
  }
}

The standalone binary finds DeepSeek Harness via --dsh-path / DSH_PATH, its own tree, ./node_modules, dsh on PATH, or npm root -g. It ships an npm-installed harness peer as the last candidate, so it still prefers the dsh you installed. When a real $DSH_HOME/profiles/acp exists, that profile owns the composition.

Plugin and extension model

There are two independent ways to extend an ACP-backed surface.

To use portable Agent Plugins, Codex plugins, Claude Code plugins, or Pi packages through an ACP client, add the Agent Plugins Bridge to the same profile:

dsh plugin --profile acp add @openma/dsh-agents-plugins-bridge@latest

The Bridge contributes ordinary Host rows. Imported commands, skills, tools, hooks, MCP connections, agents, and Pi extensions therefore reach ACP through this adapter's existing projections; there is no ACP-specific plugin import runtime. The Bridge's Web management panel and MCP Apps HTML renderer remain Web surfaces and are not sent over ACP.

For extensions that need a session-owned background lifecycle without an open terminal UI, use Martty owner. It is a generic ACP rpc client: this package remains the server/transport, while Martty owns the long-lived Session and explicit startup/shutdown slash commands.

Extend the Host composition

The ACP adapter rides the Cordis tree that the profile already owns. Add dsh plugins to that profile to change the agent composition instead of forking the ACP server: providers and models join the live catalog, commands and skills join the advertised session surface, tools and subagents appear through standard session/update, and the same session persistence remains available to every surface.

For applications embedding ACP, the public package entries are:

Export Role
@openma/deepseek-harness-acp/plugin Complete Host-side surface plugin. It fills the ACP-required Host services that Base leaves to a surface and provides ctx.acpServer. It does not claim a transport.
@openma/deepseek-harness-acp/server Lower-level transport-independent acpServer provider for a Host tree that already supplies the injected composition services.
@openma/deepseek-harness-acp/stdio Standard profile adapter: connects ctx.acpServer to process stdin/stdout.
@openma/deepseek-harness-acp/bridge Node stream adapter and compatibility entry for older profile patches.

ctx.acpServer.connect(stream) creates a connection-owned bridge fiber over the existing Host composition. The transport owner retains process, stream, and TTY lifecycle; the ACP plugin retains session and agent semantics. This is the shape used by @openma/deepseek-harness-tui: ACP stays on the Base Host tree while a separate TUI Client process owns its own Cordis tree.

Adding a Cordis service does not automatically invent a wire method. Prefer a standard ACP capability or event projection whenever one exists; add an adapter only for behavior that must cross the client boundary.

Extend ACP without breaking ordinary clients

Optional wire behavior follows ACP's extension conventions:

  1. Advertise support in initialize metadata, with a namespaced and versioned capability such as _meta.dsh.cordis.protocol.
  2. Carry annotations on standard messages in namespaced _meta fields when no new request is needed.
  3. Name custom JSON-RPC requests and notifications with a leading underscore, and send them only after both peers negotiated the matching capability.
  4. Keep the standard ACP path complete. A client that does not advertise an extension must still get normal sessions, prompts, updates, cancellation, auth, and config options.

The current package applies this pattern to the built-in _dsh/cordis/* family used by the TUI for Client capability discovery, dynamic Package lifecycle, and package-private Host/Client RPC. It is an explicit, versioned extension—not a synchronization of Cordis plugin ids, fibers, or inject across processes. The bridge's internal method registry is not currently a public arbitrary-extension API; new extension families should first define a stable capability, ownership, lifecycle, and fallback contract.

Authentication

No keys in editor config, no secrets pasted into chat. ACP clients follow the protocol: initialize advertises three Agent Auth methods.

  1. API key — api-key, or api-key:<provider> when more than one route is live. The client may pass _meta["api-key"].apiKey.
  2. Browser — browser. The adapter opens a localhost sign-in page; the secret never travels over ACP. Hidden when NO_BROWSER is set.
  3. Custom gateway — gateway, only when the client opts in with clientCapabilities.auth._meta.gateway === true. The client sends _meta.gateway { baseUrl, headers, providerName? }.

The adapter writes credentials to the harness store. Missing credentials fail session/new and session/prompt with auth_required (-32000). Logout is the ACP logout method.

  1. Harness credential store — $DSH_HOME/.credentials.yaml (mode 600), the file the dsh Web UI writes; hot-reloaded. Save a key with dsh-acp login [--provider <route>], or the Web UI (Settings → Models).
  2. Process environment — DEEPSEEK_API_KEY / DEEPSEEK_BASE_URL (and the matching ANTHROPIC_API_KEY / OPENAI_API_KEY for those routes) in the environment that launches the agent.

The credential gate is the current provider route. An Anthropic-only store is enough for an Anthropic session; a DeepSeek key does not unlock another provider.

Features

  • Streaming — assistant text and reasoning deltas; assembled-message fallback.
  • Images — promptCapabilities.image is advertised when the composition mounts ctx.attachments (dsh-base does). ACP image blocks are validated, stored with saveImage, and kept in wire order with surrounding text. resource_link stays a textual file pointer.
  • Tool calls — ACP kinds, human titles, file locations, real diffs from fs-tool hunks, raw input/output; command output on a display terminal when the client supports one, fenced output otherwise.
  • Permission presets as session modes — read-only / workspace-write / danger-full-access, each a named {sandbox, approval} pair recorded as a durable session fact (also exposed as a config option for clients that only render those).
  • Agent composition — when the profile mounts agentPresets, an uncategorized config option id: "agent" lists the roster (standard / code / minimal / cordis, plus user copies). Switching rebuilds the agent live with history preserved. Authoring (copy/rm) stays on the Web settings page; there is no /preset slash.
  • Live model catalog — providers × models from the running composition (third-party providers added in the Web UI appear immediately), plus reasoning-effort selection that follows your product default.
  • Slash commands — adapter built-ins (/status, /model) plus the harness command registry (/compact, /goal, /permission, /plan, …) executed without a model turn, plus skills (/skill-name — the harness's own invocation gesture). Login and logout are ACP methods, not chat commands.
  • Plans & usage — todo_write snapshots as ACP plans; token accounting as usage_update and per-turn usage.
  • Sessions — session/load with full history replay, session/list, silent restore when a client prompts an old session after an agent restart, titles as session_info_update.
  • MCP servers — per-session mcpServers mount @deepseek-ai/dsh-mcp-client instances (stdio + streamable HTTP); tools join as mcp__<server>__<tool>; a failing server never takes the session down.
  • Real cancellation — session/cancel interrupts the live turn through the harness agent.

Configuration

Flags win over environment variables, which win over defaults. All optional — with no flags, sessions follow your product defaults (settings.yaml).

Flag Env Default Purpose
--dsh-path DSH_PATH auto-detect DeepSeek Harness installation
--provider DSH_PROVIDER product default Provider route override
--model DSH_MODEL product default Model override
--max-tokens DSH_MAX_TOKENS provider default Per-request output-token cap
--permission-mode DSH_PERMISSION_MODE workspace-write Initial permission preset
--reasoning-effort DSH_REASONING_EFFORT product default off / high / max
— DEEPSEEK_API_KEY — API credential (fallback to the credential store)
— DEEPSEEK_BASE_URL DeepSeek endpoint OpenAI-compatible endpoint override
— DSH_ACP_DEBUG off Verbose stderr diagnostics

Subcommands: dsh-acp login [api-key] (interactive when omitted; input never echoes), dsh-acp update (self-update via npm).

Permissions and sandboxing

Sessions start in workspace-write: bash and file mutations are confined to the session's cwd (plus shared temp roots), and a model retry requesting wider access raises an ACP permission request. Always allow (this session) flips the approval policy to never for that session. danger-full-access disables both the sandbox and the prompts — use it only in disposable checkouts or containers. Each level is one durable preset (sandbox + approval together), the same three the Web UI offers.

Architecture

ACP client (Zed, …)
   │  ACP JSON-RPC over stdio
   ▼
dsh-acp
   ├─ src/profile-boot.ts     boots the harness's own profile machinery
   │                          (dsh-base + this bundle + $DSH_HOME layers)
   ├─ src/harness.ts          host discovery (DSH_PATH → cwd → PATH → npm -g → npm peer)
   └─ src/bridge/             the ACP bridge (a cordis plugin)
        ├─ index.ts           sessions, prompts, cancel, modes, options,
        │                     commands, credentials, MCP mounts
        ├─ translate.ts       session-event → ACP update projection (pure)
        ├─ history.ts         stored-log replay for session/load (pure)
        └─ prompt.ts          ACP prompt blocks → harness content blocks (pure)
   ▼
your @deepseek-ai/dsh installation   (agent spine, llm, persistence, sandbox,
                                      tools, presets, skills, compaction, …)

When embedded by another surface, only the transport edge changes:

dsh Base Host Cordis tree
   ├─ product plugins (agents, tools, skills, persistence, …)
   └─ @openma/deepseek-harness-acp/plugin
         └─ acpServer.connect(Stream)
                │ standard ACP + negotiated extensions
                ▼
          surface-owned Client process

The bridge consumes the harness session/event firehose — the same append-only log persistence stores — so live streaming, history replay, and session/list agree by construction. All harness modules, including cordis itself, load from one host tree: plugin and service identity is never split across copies.

Development

npm install         # dev deps include the harness packages (types + tests)
npm run typecheck   # tsc --noEmit
npm test            # vitest: unit + e2e smoke (boots the real composition; no model calls)
npm run build       # esbuild → dist/

To also run the e2e suite against a standalone host install:

npm install --prefix /tmp/dsh-host @deepseek-ai/dsh
DSH_ACP_TEST_HOST=/tmp/dsh-host npm test

Live iteration: paired profiles

Keep the profile your editor uses on the published package, and point a second profile at this worktree via a pnpm symlink:

dsh plugin --profile acp add -w @openma/deepseek-harness-acp   # stable
dsh plugin --profile acp-test add -w "link:$PWD"               # dev (symlink)

The dev loop is npm run build + restart — dist/ and cordis.patch.yml are read through the link. (pnpm treats file: as a copy install and caches same-version tarballs; link: avoids both.)

{
  "agent_servers": {
    "DeepSeek Harness": { "command": "dsh", "args": ["--profile", "acp"] },
    "DeepSeek Harness (dev)": { "command": "dsh", "args": ["--profile", "acp-test"] }
  }
}

License

Apache-2.0.

原始 README: https://github.com/openma-ai/deepseek-harness-acp/blob/main/README.md ↗

同类插件

查看全部 →
通知与集成alvinunreal

dsh

将 DeepSeek Harness 的生命周期状态、错误与审批请求,桥接到本地运行的 OpenPets 桌面伙伴。

查看详情
1081github+08-21
通知与集成tencent-connect

dsh-qqbot

让 QQ Bot 接入 DeepSeek Harness(dsh)的官方插件

查看详情
55github+08-17
通知与集成omdsh-dev

dsh-open-in-vscode

从 Web GUI 一键在 VS Code 中打开工作区目录。

查看详情
39github+08-13
通知与集成omdsh-dev

dsh-notification

回合完成桌面通知,按结果分控 + 关键词过滤。

查看详情
38github+08-13
通知与集成THEWOLFWALKER

dsh-notifier

DSH 统一通知推送与远程控制:一个 `notify()` API 打通 25+ 渠道(Telegram / 钉钉 / 飞书 / 企业微信 / QQ 机器人 / WxPusher / PushPlus / Server 酱 / Bark / Discord / Slack / ntfy / webhook 等),timeSensitive / active / passive 分级路由并重试;五通道反向审批(Telegram 按钮 / 飞书卡片 / QQ / WxPusher / 微信 iLink);QQ/钉钉/飞书官方扫码登录;本地 Web 管理台;多 agent 路由;系统桌面通知——以及**手机指挥中心**:在手机上发 `!status` / `!stop` / `!retry` 遥控 agent,通知带可操作按钮(查看结果 / 重试 / 日志,点击回调 agent)。密钥脱敏、工具限流、零运行时依赖。

查看详情
27github+08-16
通知与集成wzj998

chatccc

飞书(Lark)或微信(WeChat)聊天控制 DeepSeek Harness / Claude Code / Cursor / Codex / CCC Agent

查看详情
22github+08-23