Role-based Codex / Claude Code / ACP subagent providers for the DeepSeek Harness — continuable children, durable session recovery, per-role product permissions, and delegation with a permission ceiling.
- Language
- JavaScript
- License
- MIT
- Branch
- main
Install
$ dsh plugin --profile web add dsh-plugin-product-subagentsRun the command above in your terminal to install this plugin via the dsh CLI. You can switch Profile in the top-right corner. New to dsh? Read the beginner tutorial
Install via your agent
Install the DeepSeek Harness plugin shaokeyibb/dsh-plugin-product-subagents for me: review the repository at https://github.com/shaokeyibb/dsh-plugin-product-subagents first, then run the install command and verify the plugin loads successfully.
Paste this instruction to the DSH Web GUI assistant — it will install and verify for you.
一句话定位
把 DeepSeek Harness 之外的 Agent 工具(Claude Code CLI、Codex CLI、以及任何支持 ACP 协议的客户端)接进来当"子代理"用:模型可以按角色把任务丢给它们,让它们独立完成长活,自己这边同时做别的事;中转模型本身被限制成只读,所有真正干活的是被启动起来的外部 CLI。
核心能力
- 按角色派发任务给外部 Agent:内置 general / code-review / explore / debug 四个角色,可用 product_delegate 一句话把活儿派给对应 provider 的 CLI 子代理。
- 子代理会话能续聊:派出去的子代理有持久化的远程会话 ID,多次 product_submit 走的是同一个远端 CLI 上下文,不用每次重新介绍任务背景。
- 跨进程恢复:绑定丢失或 harness 重启后,子代理能凭注册表文件(默认
~/.dsh/product-subagents-registry.json)或会话日志里的PRODUCT_SESSION:标记自动接回原会话。 - 双层权限模型:远端 CLI 跑任务时的权限由角色的
permissionMode(readonly / default / full)控制,而中继模型自身永远只读,永远拿不到写工具。 - 委派权限天花板:子代理不能派生比自己权限更高的后代(
readonly < default < full),并发生成时被product_delegate直接拒掉。 - 任意 ACP Agent 零代码接入:Cursor (
agent acp)、CodeBuddy (cbc --acp)、Gemini (gemini --acp)、opencode 等只要在 PATH 上就能被自动探测并加进 provider 列表。
技术实现
- 语言: JavaScript(纯 ES Module,
package.json:5声明"type": "module") - 关键依赖:
@deepseek-ai/dsh-tools(peer):用defineTool注册 6 个 model-facing 工具@deepseek-ai/dsh-subagent(peer):注册 subagent provider 与 continuation 入口@deepseek-ai/cordis(peer ^4.0.1):宿主插件框架@agentclientprotocol/sdk(^0.25.0):通用 ACP 协议 SDK,给 Cursor / opencode / CodeBuddy / Gemini 复用
- 架构模式: 标准 Cordis 插件;通过
package.json#dsh.bundle.patch自带cordis.patch.yml,dsh plugin add时自动作为 profile 层加载;apply()内部走 provider 注册 → tool 注册 → lifecycle 钩子(subagent/end排空闲释放、ctx.effect卸载时全释放)三段式。 - 入口文件:
lib/index.js(同时export name = 'product-subagents'、inject = ['subagents','tools','sessions'],lib/index.js:16-17)
适用场景
希望在一个 DeepSeek Harness 会话里同时调度多个不同 CLI Agent(让 Claude Code 读代码、Codex 跑修复、Cursor 接管 UI 改动),又希望它们之间能交接上下文、不会互相写穿对方的文件;或者想给一个长期任务持续追问、但又不想每次都重新把背景解释给 CLI。普通聊天、写一次性短任务的场景用不到这个插件。
前置依赖与兼容性
| 依赖 | 最低版本 | 说明 |
|---|---|---|
@deepseek-ai/dsh-subagent | ^0.1.0-rc.6 | peerDependencies,注册 provider 与 continuation 能力 |
@deepseek-ai/dsh-tools | ^0.1.0-rc.6 | peerDependencies,必须和宿主共用同一份实例(CHANGELOG 0.3.0 修复过被二次安装搞崩的问题) |
@deepseek-ai/cordis | ^4.0.1 | peerDependencies,宿主插件框架 |
| 产品 CLI | 至少 1 个在 PATH | Claude Code / Codex / opencode / Cursor agent / CodeBuddy cbc / Gemini 中任意一个;未安装时该 provider 不会被注册(lib/availability.js) |
| Node.js | >=18 | package.json#engines.node |
| 平台 | 跨平台 | Windows / macOS / Linux 都跑通;Windows 下 cmd.exe 启动 .cmd 垫片(lib/run.js:18-29) |
| 原生模块 | 无 | 只用 Node 内置 fs / os / child_process / stream |
安装方式
dsh plugin --profile web add github:shaokeyibb/dsh-plugin-product-subagents
配置项
| 配置 | 类型 | 说明 | 默认值 |
|---|---|---|---|
providers | 映射(provider 名 → 描述) | 添加或覆盖产品 CLI,每个描述含 type(claude/codex/acp)、command、args、env、timeoutMs;同名键可覆盖内置 provider;不写就用内置三件套(claude-code / codex / acp 即 opencode) | 不写 |
idleTimeoutMs | 非负整数(毫秒) | 子代理结算后闲置多久释放远端会话;0 关闭自动释放 | 600000(10 分钟) |
maxConcurrentChildren | 正整数 | 同时存在的"后台型"子代理上限;超过就拒绝新派活 | 8 |
rolesDir | 字符串路径 | 自定义角色 JSON 文件目录,每文件一个角色 | 插件自带的 roles/ |
registryPath | 字符串路径 | 远端会话 ID 的注册表文件路径,用来跨进程恢复会话 | ~/.dsh/product-subagents-registry.json |
常见问题
Q: 装好之后怎么开始用?
A: 重启 DeepSeek Harness 让插件加载,新会话里模型就会多出 6 个 product_* 工具,最常用的是 product_delegate(按角色派活)和 product_wait(等子代理返回)。要先在 PATH 上准备好至少一个产品 CLI(claude、codex 或 opencode / agent / cbc / gemini 之一)。
Q: 不配置也能用吗?
A: 可以。插件只检测 PATH 上已有的产品 CLI 并自动注册;只装了 Claude Code 就有 claude-code 这个 provider,三件套都不装就什么也跑不起来。要加 Cursor、CodeBuddy 这类自定义 ACP 客户端才需要写 config.providers。
Q: 远程子代理的会话能跨进程恢复吗?
A: 可以。子代理的远程会话 ID 会被三处冗余记录:内存绑定 → 默认 ~/.dsh/product-subagents-registry.json 注册表 → 子会话事件日志里的 PRODUCT_SESSION 标记;空闲释放或重启后下次 product_submit 会按这个顺序恢复,自动接上同一会话。
Q: 子代理可以再派自己的子代理吗?能突破我的权限吗?
A: 默认允许,角色 JSON 里写 allowDelegation: false 就能禁止。权限有天花板:readonly < default < full,子代理不能派生比自己权限更高的后代,调用会被 product_delegate 直接拒绝。
Q: 子代理里的中继模型(relay)会不会偷偷改我文件?
A: 不会。子代理里跑的"中继模型"只看得到 product_submit(必要时再加 product_delegate),永远拿不到 Bash、文件编辑这类写工具;所有实际改文件的工作都被丢给远端 Claude Code / Codex / ACP 进程做,受对应角色 permissionMode 控制。
Q: Windows 上能跑吗?
A: 能。插件在 Windows 下通过 cmd.exe /d /s /c 启动 .cmd 垫片(lib/run.js),任务文本里带空格或引号会自动转义;CI 在 macOS / Ubuntu / Windows × Node 18/20/22 全跑通过。
Q: 哪些 ACP 客户端可以直接用,不用写代码?
A: 任何走 Agent Client Protocol(ACP)的 CLI 都可以直接当 provider:opencode、Cursor 的 agent acp、CodeBuddy 的 cbc --acp、Gemini 的 gemini --acp,只要在 PATH 上能被探测到;不支持某个 ACP 能力(比如 setSessionConfigOption 改 model)会自动静默回退。
Q: 子代理空闲时会一直占着资源吗?
A: 不会。子代理每完成一轮会被排进空闲释放计时器(默认 600000 毫秒即 10 分钟,可在配置 idleTimeoutMs 改,0 禁用);下一次 product_submit 调用会取消还没触发的释放,所以快速续聊不会重新建会话。
上手难度
进阶 — 不需要写代码,但要理解"角色 = 远端 CLI 权限档位"、"中继模型和远端 CLI 不是一回事"这两个关键区分;安装后还要至少装一个产品 CLI 并登录,否则什么也跑不起来;想加自定义 ACP 客户端才需要写 cordis.patch.yml 的 config 覆盖。
已知问题与限制
- pnpm 11 默认开
minimumReleaseAge,老机器可能因为 0.3.0 还"太新"被回退到 0.2.0(0.2.0 把@deepseek-ai/dsh-tools放在 dependencies,会和宿主 peer 冲突),必要时显式 pin@0.3.0(CHANGELOG.md:21-28)。 - 角色的
permissionMode只能取readonly/default/full三个值,其它值会静默回退成default(lib/roles.js:39)。 - 角色目录里某个 JSON 坏了会被直接跳过(
lib/roles.js:46-48),插件不报警;可通过product_roles看到实际生效的列表。 - 通用 ACP 客户端遇到不支持的能力时静默降级:
readTextFile/writeTextFile一律抛错(lib/bridges/acp.js:36-39);requestPermission一律拒掉(lib/bridges/acp.js:32-34),相当于跑 unattended 模式;setSessionConfigOption失败被吞(lib/bridges/acp.js:115-119),意味着通过model参数改 model 大概率不生效。 - ACP 进程意外退出后会自动重连并尝试
session/load(lib/bridges/acp.js:87-102, 145-159);如果对端 ACP 不支持loadSession会回退成全新会话,原会话上下文就丢了。 - Codex 桥按 codex-cli 0.147+ 的点号事件名(
thread.started/item.completed/turn.completed)实现,对老版本的_下划线命名做了 fallback(lib/bridges/codex.js:11-14, 88-102);装太老的 codex CLI 会丢文本。 - 后台子代理到达
maxConcurrentChildren时product_delegate会被拒掉(lib/tools/product-delegate.js:103-105),需要先用product_wait或subagent_progress让一个子代理结束。 - 自定义
config.providers整段config会被 profile 里的 patch 替换(README.md:66-67),要保留idleTimeoutMs之类默认必须重写一遍。
English | 简体中文
Role-based Codex / Claude Code / ACP subagent providers for the DeepSeek Harness. Turns external agent CLIs into durable, continuable subagents with a declarative role library, per-role product permissions, delegation with a permission ceiling, and cross-platform process launching.
Features
- Continuable children — one-shot sync or async continuable (control with
send_message,list_agents,interrupt_agent; attach synchronously withproduct_wait). - Session continuity — a child's remote product session survives idle disposal and process restarts (durable registry + log markers; claude/codex resume by id, ACP reconnects).
- Declarative roles (
roles/*.json) —general(default),code-review,explore(never delegates),debug. Delegation defaults ON; a role can ban it. Unknown roles fall back togeneral. - Two-layer permission model — the relay model is always a read-only
pipe;
permissionMode(readonly/default/full) applies to the remote product and is mapped to each product's own CLI flags. - Permission ceiling — a child can never spawn a descendant with more permission than it has.
- Any ACP agent — add Cursor (
agent acp), CodeBuddy (cbc --acp), Gemini (gemini --acp) and more viaconfig.providers; no code needed. - Resource management — idle disposal, configurable timeouts, concurrency cap.
- Cross-platform — Windows
.cmdshims, Windows-safe path escaping; CI runs macOS / Ubuntu / Windows.
Requirements
- A DeepSeek Harness deployment (web profile).
- At least one product CLI on
PATHand authenticated:claude,codex, or an ACP CLI (opencode,agent,cbc, …). - Node ≥ 18.
Install
Recommended — dsh plugin add
dsh plugin --profile web add dsh-plugin-product-subagents
That single command installs the package and wires the host-plane row
automatically: the plugin ships a cordis.patch.yml declared via
dsh.bundle in its package.json, so dsh plugin add registers it as a
profile layer (no manual cordis.patch.yml editing needed). Restart the
harness afterwards so the plugin loads.
To customise the plugin (e.g. add ACP providers), target the product-subagents
id in your profile's own cordis.patch.yml (~/.dsh/profiles/web/cordis.patch.yml):
- id: product-subagents
config:
idleTimeoutMs: 600000
providers:
cursor: { type: acp, command: agent, args: [acp] }
codebuddy: { type: acp, command: cbc, args: [--acp] }
Note: a config override replaces the row's whole
configobject, so restate any keys you wish to keep (likeidleTimeoutMsabove).
Install via your agent (one line)
Paste this to your DeepSeek Harness agent (or any coding agent with shell access to the harness home) — it performs every step itself:
Install the
dsh-plugin-product-subagentsplugin into my DeepSeek Harness web profile: rundsh plugin --profile web add dsh-plugin-product-subagents, then tell me to restart the harness so the plugin loads.
Manual (advanced)
If you prefer to manage the profile yourself, use pnpm (not npm) inside the profile directory so peer dependencies are not auto-installed:
cd ~/.dsh/profiles/web
pnpm add dsh-plugin-product-subagents
Then add a host-plane row to your profile's cordis.patch.yml:
- insert:
- id: product-subagents
name: 'dsh-plugin-product-subagents'
config:
idleTimeoutMs: 600000
providers:
cursor: { type: acp, command: agent, args: [acp] }
codebuddy: { type: acp, command: cbc, args: [--acp] }
Quick start
In a session, the model has six tools:
| Tool | Purpose |
|---|---|
product_delegate | delegate a task under a role (sync or continuable) |
product_roles | list the role library |
product_submit | per-child bridge (continuable children only) |
subagent_progress | status + internal trace of one child |
product_wait | block until a child settles, return its answer |
product_agents | provider availability + live children |
product_delegate role=general task="Refactor demo-project/calc.js and run its tests"
product_wait subagent_id=<childId>
Configuration
config:
providers: { cursor: { type: acp, command: agent, args: [acp] } }
idleTimeoutMs: 600000 # settled children release their remote session
# after this idle period (0 disables)
maxConcurrentChildren: 8 # cap on simultaneous continuable children
rolesDir: <path> # declarative role library (default: roles/)
registryPath: <path> # durable remote-session registry
Roles and permissions
Each role file:
{
"id": "code-review",
"description": "Review code for bugs, security, maintainability (read-only).",
"provider": "claude-code",
"permissionMode": "readonly",
"allowDelegation": true,
"instructions": "You are a code reviewer. READ-ONLY: never modify files. …"
}
permissionModemaps to product flags:readonly(claude--permission-mode plan/ codex--sandbox read-only),full(claude--dangerously-skip-permissions/ codex--dangerously-bypass-approvals-and-sandbox).- The relay model never gets write-capable tools, in every role.
- Delegation is capped:
readonly < default < full; a child cannot spawn a descendant with a higher mode.
Custom ACP providers
config.providers accepts any ACP-capable CLI — the generic bridge handles a
persistent process, session/load resume, and dead-process reconnect:
providers:
cursor: { type: acp, command: agent, args: [acp] } # Cursor CLI
codebuddy: { type: acp, command: cbc, args: [--acp] } # CodeBuddy
gemini: { type: acp, command: gemini, args: [--acp] } # Gemini CLI
opencode: { type: acp, command: opencode, args: [acp] } # opencode
Providers appear in the delegation enum only when their command is detected
on PATH. Built-ins (claude-code, codex, acp) can be overridden with
the same keys.
Development
npm install
npm test # node:test — pure logic + fake bridge, no CLIs or keys
npm run lint # syntax-check every module
See docs/ARCHITECTURE.md for the bridge contract, the permission model, and how to add products. CI runs the suite on macOS / Ubuntu / Windows × Node 18/20/22.
Security
This is a configuration-as-trust-boundary tool: it spawns whatever CLIs
you configure, and full passes the products' own "bypass all permission
checks" flags. See SECURITY.md.
License
MIT
Read the usage guide →
Install steps, key points, FAQ and compatibility for this plugin — auto-derived from indexed fields.
Listing badge
[](https://deepseek-plugin.org/plugins/shaokeyibb/dsh-plugin-product-subagents)Paste this markdown into your GitHub README to link back to this listing. The badge only states the listing — not a security endorsement.