Files
openclaw-config/docs/bk02-dsh-openclaw-ACP集成.md
T
yangxuan 43cd42a563 feat(acp): 接入 DSH 作为 ACP harness,打通 微信→OpenClaw→DSH 派发链路
- openclaw.json
  - plugins.allow 放行 acpx(限制性白名单,缺了后端不会加载)
  - 新增 acp 策略段:enabled/dispatch、backend=acpx、defaultAgent=dsh、
    allowedAgents=[dsh]、stream.deliveryMode=live
  - 新增 plugins.entries.acpx.config:permissionMode=approve-all、
    timeoutSeconds=900、cwd、agents.dsh = dsh --profile acp(绝对路径)
  - 新增 OpenClaw agent dsh(runtime.type=acp → harness dsh),否则
    sessions_spawn 会报 dispatch_failed: Unknown agent id "dsh"
- workspace-dsh/:该 agent 的身份文件(AGENTS/SOUL/IDENTITY/USER/BOOTSTRAP.md)。
  其中的空 .git 由 `openclaw agents add` 的标准 provisioning 生成(非任何 agent 自建),
  会让父仓库把它当 gitlink,已移除后纳入版本控制
- docs/bk02-dsh-openclaw-ACP集成.md:部署/配置/验证证据/排错/回滚全文
- docs/dsh-acp-smoke.mjs:ACP 独立冒烟(initialize→session/new→prompt→close)
- docs/dsh-lang-check.mjs:全局中文指令验证(英文提问看是否回中文)
- skills/delegate-to-dsh:让「交给 dsh」稳定走 ACP 派发;缺此技能时模型会
  静默 fallback 到内嵌 subagent(已复现「假成功」并写入判据)
- agents/main/agent/workshop-skills/acp-backend-triage:ACP 后端排查技能
- plugin-skills/acp-router:acpx 插件自带技能(symlink,与既有渠道一致)
- .gitignore:workspace-dsh 沿用 workspace/ 白名单(只版本化顶层 *.md);
  新增忽略 acpx/ 插件运行产物

验证:ACP 三条途径均通过(独立冒烟、显式 sessions_spawn、自然语言「转给 dsh」),
DSH 侧会话留痕与产物落地见 docs 文档 §5 与 §7。
2026-09-16 17:40:53 +08:00

24 KiB
Raw Blame History

bk02 · DSH × OpenClaw ACP 集成说明

用途:本机 DeepSeek Harnessdsh)的部署与「OpenClaw → DSH」ACP 协同链路的完整说明。新会话/新人接手读本文件即可,无需历史对话。 配套bk02-openclaw-系统说明.mdOpenClaw 本体)、openclaw-升级与维护.md 主机bk02 / xuan-asus-nj · Debian 12 bookworm · 首次落地 2026-09-16

⚠️ 本目录不含明文口令,凭据位置见 §8。


0. 30 秒速览

DSH 版本 @deepseek-ai/dsh 0.1.5-rc.1nvm Node v26.8.2,全局安装)
DSH ACP 入口 dsh --profile acp —— 官方 @deepseek-ai/dsh-acpACP v1 stdio server
DSH Web 服务 dsh-web.service用户级 systemd),监听 127.0.0.1:18787
Web 访问入口 https://bk02.baiji-algieba.ts.net:18787/?token=<启动时打印>tailscale serve,仅 tailnet 内可达)
OpenClaw 侧 @openclaw/acpx 插件 2026.9.4harness 别名 dsh,已注册为 OpenClaw agent dsh
链路 微信/飞书 → OpenClaw agent → sessions_spawn(runtime:"acp", agentId:"dsh")dsh --profile acp → 干活 → 结果回传
DSH 状态目录 ~/.dshprofiles/ sessions/ .env / AGENTS.md
已装插件 web profileskillhub-plugin 0.2.16 + superpowers-dsh 0.1.1acp profile:仅 superpowers-dshskillhub 的启动自检会往 stdout 打印,污染 ACP 协议流,见 §3.1)
全局指令 ~/.dsh/AGENTS.md —— 交互与思考一律中文,所有 profile / 所有会话生效

最常用的四条命令

export PATH=$HOME/.nvm/versions/node/v26.8.2/bin:$PATH        # 每次登录先做

systemctl --user status dsh-web                               # DSH Web 状态
journalctl --user -u dsh-web -f                               # DSH Web 日志(含带 token 的访问 URL)
journalctl --user -u openclaw-gateway -f                      # OpenClaw 网关日志(ACP spawn 记录在这里)
node ~/.openclaw/docs/dsh-acp-smoke.mjs                       # DSH ACP 独立冒烟(不经过 OpenClaw

1. 架构与职责边界

微信 / 飞书 / 其他渠道
        │
        ▼
┌──────────────────────────────┐
│ OpenClaw Gateway (18789)     │  ← 渠道接入、路由、会话、结果投递
│  @openclaw/acpx 插件          │  ← ACP 客户端侧(acpx 0.13.2 内嵌)
└──────────────────────────────┘
        │  ACP v1 over stdio(JSON-RPC)
        ▼
┌──────────────────────────────┐
│ dsh --profile acp            │  ← 每会话一个子进程;ACP server 侧
│  @deepseek-ai/dsh-acp        │      模型 deepseek-official / deepseek-v4-flash
│  dsh-base(工具/沙箱/持久化)  │      权限 preset workspace-write
└──────────────────────────────┘
        │
        ▼
   真实干活:读写文件、跑命令、再回传

职责分工(官方定位):

  • OpenClaw 拥有:渠道、路由、后台任务状态、投递、绑定、策略。
  • DSH 拥有:provider 登录、模型目录、文件系统行为、原生工具、会话持久化。

关键认知:ACP 是 stdio 直连,不需要任何网络暴露。DSH Web(18787)是给人用的浏览器界面,与 ACP 链路彼此独立。


2. 为什么不是「把 DSH 装成一个别的 ACP 工具」

DSH 自带官方 ACP 服务端,无需自研桥接:

  • npm 包 @deepseek-ai/dsh-acpAutomation-only Agent Client Protocol server for driving DeepSeek Harness agents over JSON-RPC stdio
  • dsh ≥0.1.5 内置 acp profile 模板(bundles = @deepseek-ai/dsh-base + @deepseek-ai/dsh-acp-app),dsh --profile acp 开箱即用。
  • 默认组合已配好 provider: deepseek-official / model: deepseek-v4-flash
  • ACP 能力:initialize / session/new / session/list / session/resume / session/close / session/prompt / session/cancel / session/set_config_optionsession/update 语义流、session/request_permission 权限询问、stdio 与 HTTP MCP。
  • 明确不支持(写代码时别指望):session/load、删除、fork、附加目录、SSE MCP、计划/终端/客户端文件系统操作、elicitation。

3. DSH 侧安装(可复现步骤)

# 1) 用 nvm 的 Node(系统 /usr/bin/node 是 22.x,不用)
export PATH=$HOME/.nvm/versions/node/v26.8.2/bin:$PATH

# 2) 全局安装 dsh(必须显式放行 install scripts,否则 node-pty / spawn helper 不生成)
npm i -g --allow-scripts=@deepseek-ai/dsh-subprocess-local,koffi,node-pty,@google/genai,protobufjs \
  @deepseek-ai/dsh@0.1.5-rc.1

# 3) 初始化 ACP profile(首次执行自动创建 ~/.dsh/profiles/acp
dsh --profile acp --help

# 4) 写入模型凭据(600 权限;凭据来源优先级见 §8)
printf 'DEEPSEEK_API_KEY=<见 §8>\n' > ~/.dsh/.env && chmod 600 ~/.dsh/.env

# 5) 独立冒烟:不经过 OpenClaw,直接与 dsh 的 ACP server 对话
node ~/.openclaw/docs/dsh-acp-smoke.mjs

~/.dsh/profiles/acp/ 由 CLI 自动生成,不要手改(除非要换模型):

{ "dsh": { "profile": { "bundles": ["@deepseek-ai/dsh-base", "@deepseek-ai/dsh-acp-app"],
                        "patchReload": "startup" } } }

要改模型/provider,在 ~/.dsh/profiles/acp/cordis.patch.yml 里按 id 覆盖 acp 行:

- id: acp
  config:
    provider: deepseek-official
    model: deepseek-v4-pro      # 默认是 deepseek-v4-flash

3.1 插件与全局中文指令(2026-09-16 追加)

前置:dsh plugin 是 pnpm 的转发器,先装 pnpm(本机原先没有):

export PATH=$HOME/.nvm/versions/node/v26.8.2/bin:$PATH
npm i -g pnpm            # → pnpm 12.4.2,落在 ~/.nvm/versions/node/v26.8.2/bin/pnpm

装插件(插件是否属于某个 profile,取决于 dsh --profile <name>,所以要分别装):

# Web 界面用的 profile:两个都装(HTTP 传输,不受 stdout 约束)
dsh plugin --profile web add skillhub-plugin superpowers-dsh

# ACP 自动化 profile:只装 superpowers-dsh —— 详见下方「stdout 纪律」
dsh plugin --profile acp add superpowers-dsh

装完 profile 的 package.json 会自动登记(dsh plugin 会按已装状态 reconcile 层列表):

{ "dependencies": { "skillhub-plugin": "^0.2.16", "superpowers-dsh": "^0.1.1" },
  "dsh": { "profile": { "bundles": ["@deepseek-ai/dsh-base", "@deepseek-ai/dsh-web-app",
                                   "skillhub-plugin", "superpowers-dsh"] } } }

校验(不需要起服务):

dsh --profile web --dump-config | grep -iE "skillhub|superpowers"

⚠️ stdout 纪律:skillhub-plugin 不能装进 acp profile

skillhub-plugin 0.2.16 在插件加载时跑一个 fire-and-forget 启动自检,console.log 往 stdout 打印

[skillhub] self-check ok: 插件分页两页零重复(5+5 条, total=2714)

而 ACP 的 stdout 只允许承载协议流量dsh-acp 文档原话:Stdout carries only protocol traffic, so keep logging off it)。该行会被 ACP 客户端当成非法 JSON 帧。实测:装进 acp profile 后,ACP 冒烟脚本每轮都会捕获到这条非 JSON 输出(脚本用宽容解析才没崩,acpx 的行为不作保证);从 acp profile 移除后立即干净:

dsh plugin --profile acp remove skillhub-plugin
node ~/.openclaw/docs/dsh-acp-smoke.mjs   # 输出里不应再出现「非 JSON 的 stdout 输出」

该输出硬编码在 lib/host.jsselfCheckPluginPaging() 里(同函数另外两处用 console.error → stderr,无害),没有配置开关。若将来非要在 ACP 侧用技能市场,需要给该行打补丁改走 stderr,而不是直接安装。

全局中文指令(交互 + 思考)

~/.dsh/AGENTS.mdDSH_HOME 级,所有 profile、所有会话生效;权限 600):

# 用户全局指令(User-Global Instructions

以下约定适用于所有 DSH 会话、所有项目目录,作为全局行为准则,优先于工具描述中的一般性提示:

## 语言

- 交互:与用户的所有交流(回复、提问、澄清、说明)一律使用中文。
- 思考:内部推理与思考过程也一律使用中文。

与 wit01 上 ~/.dsh/AGENTS.md 内容一致。验证方式(脚本 dsh-lang-check.mjs,走 ACP 提问,故意用英文):

提问 DSH 回复 判定
Answer in ONE short sentence, English only: what is 2+2? 2 + 2 = 4. 用户显式指定 English → 遵从用户(预期行为)
Reply with a single short sentence: name one benefit of unit tests. 单元测试能在改动代码时快速发现回归缺陷。 未指定语言时输出中文,指令生效

判定中文指令是否生效,要用未指定语言的英文提问;像第一行那样显式要求 English only 时,模型服从当次用户指令是正确行为,不算指令失效。


4. OpenClaw 侧配置(4 处,缺一不可)

配置全部落在 ~/.openclaw/openclaw.json(用 openclaw config patch 写入,勿手改 JSON 后不校验)。

4.1 插件清单必须放行 acpx

plugins.allow限制性白名单,不在里面 = 插件被阻止加载(/acp doctor 会报缺失 allowlist 项):

"plugins": { "allow": ["deepseek","memory-core","ollama","searxng","openclaw-weixin",
                       "dingtalk-connector","openclaw-lark","feishu", "acpx"] }

4.2 acpx 插件里注册 DSH harness

"plugins": { "entries": { "acpx": { "enabled": true, "config": {
  "permissionMode": "approve-all",     // 非交互会话必需,否则写/执行被拒(见 §9 安全)
  "timeoutSeconds": 900,
  "cwd": "/home/yangxuan/.openclaw/workspace",
  "agents": {
    "dsh": {
      "command": "/home/yangxuan/.nvm/versions/node/v26.8.2/bin/dsh",
      "args": ["--profile", "acp"]
    }
  }
} } } }

agents.<id> 是 acpx 插件自带的扩展点(schema:{ command, args? }),用绝对路径,因为网关服务的 PATH 未必包含 nvm 目录。

4.3 开启 ACP 策略

"acp": {
  "enabled": true,
  "dispatch": { "enabled": true },
  "backend": "acpx",
  "defaultAgent": "dsh",
  "allowedAgents": ["dsh"],
  "stream": { "deliveryMode": "live" }
}

4.4 把 dsh 注册成一个 OpenClaw agent(关键,易漏)

只做 4.2 + 4.3 会得到 dispatch_failed: Unknown agent id "dsh"ACP spawn 会拼出子会话键 agent:dsh:acp:<uuid>Gateway 用 listAgentIds() 校验该 agent 必须真实存在

openclaw agents add dsh --workspace /home/yangxuan/.openclaw/workspace-dsh --non-interactive
# 再用 config patch 给它接上 ACP 运行时:
# agents.entries.dsh.runtime = { type: "acp", acp: { agent: "dsh", backend: "acpx" } }

最终 agents.entries.dsh

{
  "name": "DSH",
  "workspace": "/home/yangxuan/.openclaw/workspace-dsh",
  "agentDir": "/home/yangxuan/.openclaw/agents/dsh/agent",
  "runtime": { "type": "acp", "acp": { "agent": "dsh", "backend": "acpx" } }
}

改完配置:openclaw gateway restart(插件类改动必须重启;纯 agents.entries 改动可热加载)。


5. 验证(2026-09-16 实测,均已通过)

检查 命令 结果
ACP 独立冒烟 node ~/.openclaw/docs/dsh-acp-smoke.mjs initializedeepseek-harness-acp 0.0.1session/new → sessionId + 模型下拉(deepseek-v4-flash/pro…);session/prompt → 助手回「1+1 等于 2。」;stopReason: end_turn
后端就绪 网关日志 embedded acpx runtime backend registered (cwd: /home/yangxuan/.openclaw/workspace)backend ready
端到端派发 openclaw agent --agent main --session-key acp-e2e -m "请调用 sessions_spawn(runtime=acp, agentId=dsh, task=在 /tmp/dsh-e2e/ 创建 proof2.txt …)" 子会话 agent:dsh:acp:ce3e4ea5…runId b175b303-…,约 5 秒完成
DSH 侧留痕 ~/.dsh/sessions/--home-yangxuan-.openclaw-workspace-dsh--/<uuid>/session.v3.jsonl.zstd permission/preset: workspace-writesandbox/mode: workspace-writeapproval/policy: ask 及用户消息原文
产物落地 ls /tmp/dsh-e2e/ proof2.txt / proof3.txt = dsh-acp-e2e-ok
Web 跨机访问 curl -L "https://bk02.baiji-algieba.ts.net:18787/?token=<token>" 303 → Set-Cookie → 20027724 字节 HTML
自然语言派发(部署 skill 前 openclaw agent --agent main -m "这个活我不想自己干,请转给 dsh 执行:…" 假成功:回复称「已交给 dsh」,但 DSH 侧无新会话 —— 实际是默认 subagent + exec 干完再复述(工具轨迹 10 次调用 / 4 次失败)
自然语言派发(部署 skill 后 同上措辞(用户不必知道参数) DSH 侧新增会话 332ef715-28e4-4dfb-812e-4152f3c33afdcwd=workspace-dshpermission/preset: workspace-write),任务描述被自动补全验收标准,产物 nl2.txt = skill-ok

证据判据:别只看 OpenClaw 的回复文本。回复正确可能来自 OpenClaw 内嵌运行时(executionTrace.runner="embedded")。要确认真的走了 DSH,看两处:网关日志里的 agent:dsh:acp:<uuid> 子会话,以及 ~/.dsh/sessions/--home-yangxuan-.openclaw-workspace-dsh--/ 下是否新增会话目录。


6. DSH Web 界面(给人用,与 ACP 无关)

~/.config/systemd/user/dsh-web.service

[Unit]
Description=DeepSeek Harness Web (dsh web on 18787, tailscale)
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
Environment=PATH=/home/yangxuan/.nvm/versions/node/v26.8.2/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Environment=DSH_HOME=/home/yangxuan/.dsh
ExecStart=/home/yangxuan/.nvm/versions/node/v26.8.2/bin/node \
  /home/yangxuan/.nvm/versions/node/v26.8.2/bin/dsh web \
  --host 127.0.0.1 --port 18787 --no-open \
  --trusted-host bk02.baiji-algieba.ts.net --trusted-host bk02.baiji-algieba.ts.net:18787 \
  --trusted-host localhost:18787 --trusted-host 127.0.0.1:18787
Restart=on-failure
RestartSec=5

[Install]
WantedBy=default.target

对外暴露(仅 tailnet 可达,https,复用 tailscale 证书):

sudo -n tailscale serve --bg --https=18787 http://127.0.0.1:18787
sudo -n tailscale serve status          # https://bk02.baiji-algieba.ts.net:18787 (tailnet only)

访问必须带 token(每次启动随机生成、只打印一次):

journalctl --user -u dsh-web --no-pager | grep -o 'token=[A-Za-z0-9]*' | tail -1
# → 浏览器打开 https://bk02.baiji-algieba.ts.net:18787/?token=<上面那串>

不带 token 访问返回 401 dsh web authentication required; reopen the URL printed by dsh web.;带 token 会用 303 + Set-Cookie: dsh-auth-* 落地,之后正常浏览。

两个已知坑:

  1. --host 只接受 127.0.0.10.0.0.0;写 --host 100.115.195.192 会在启动时报 ValidationError: $.host expected "127.0.0.1" | "0.0.0.0" but got "100.115.195.192"。 所以要「tailscale 上的 18787」就用 127.0.0.1 + tailscale serve(本方案),不要指望直绑 tailscale IP。
  2. 首次启动会初始化 ~/.dsh/profiles/web,约 10–40 秒才监听端口;systemd 里已在等待逻辑外,需自行 ss -ltn | grep 18787 确认。

7. 微信 → DSH 的接法(2026-09-16 实测结论)

结论:微信 / 飞书 / 钉钉只能走「助手按需派活」,渠道级 ACP 绑定在这三家都不存在。

7.1 渠道能力实测(为什么不能直接绑定会话)

OpenClaw 判定一个渠道能否「把当前会话绑到 ACP 会话」的代码是: getChannelPlugin(id)?.conversationBindings?.supportsCurrentConversationBinding === true;持久 bindings[] type="acp" 还需要适配器提供 bindings.compileConfiguredBinding / matchInboundConversation(Telegram 适配器就是这么实现的)。

体检本机三个渠道插件的结果:

渠道 插件 conversationBindings supportsCurrentConversationBinding threadBindings
微信 @tencent-weixin/openclaw-weixin 2.4.8 0 处 0 处 0 处
飞书 ~/.openclaw/extensions/openclaw-lark 0 处 0 处 0 处
钉钉 @dingtalk-real-ai/dingtalk-connector 0 处 0 处 0 处
Telegram(对照组,官方内置) dist/channel-*.mjs truebindingStore: "adapter"

因此:

  • /acp spawn dsh --bind here 在微信/飞书/钉钉不可用(会得到 "Conversation bindings are unavailable …")。
  • 持久 bindings[] type="acp" 同样不可用(适配器没有绑定钩子)。
  • 助手派活是最短可用路径(也是本机唯一路径)。

7.2 唯一可用路径:助手把活派给 DSH(已部署)

链路:微信消息 → OpenClaw main 助手 → sessions_spawn(runtime:"acp", agentId:"dsh")dsh --profile acp → 干活 → 结果回传微信

为了让它稳定,已部署技能 ~/.openclaw/skills/delegate-to-dsh/SKILL.md:触发词为「交给 dsh / 让 dsh 干 / 用 DSH 跑 / 转给 dsh」,并写明纪律(必须带 runtime:"acp"、禁止自己用 exec 或默认 subagent 兜底、派发失败要如实报错、结果原样回传)。

⚠️ 不加这个技能不可靠:实测 17:19 那次用户说「转给 dsh 执行」,main 声情并茂地回了"已交给 dsh 并执行完成",但工具轨迹里是 sessions_spawn(默认 subagent+ execDSH 侧没有任何新会话 —— 即它由 OpenClaw 内嵌运行时干完,然后复述成 dsh 的口气。技能上线后同一句话(17:21)DSH 侧新增会话 332ef715…cwd=/home/yangxuan/.openclaw/workspace-dsh,产物落地。

7.3 怎么确认真的交给了 DSH

# ① DSH 侧会话数是否 +1(最硬的证据)
ls -lt ~/.dsh/sessions/--home-yangxuan-.openclaw-workspace-dsh--/ | head

# ② 网关日志里的 ACP 子会话 / 后端就绪
journalctl --user -u openclaw-gateway --since "10 minutes ago" | grep -iE "agent:dsh:acp:|acpx runtime backend"

# ③ 会话内容(含 cwd 与 permission preset
L=$(ls -t ~/.dsh/sessions/--home-yangxuan-.openclaw-workspace-dsh--/ | head -1)
zstd -dc ~/.dsh/sessions/--home-yangxuan-.openclaw-workspace-dsh--/$L/session.v3.jsonl.zstd | head -5

判据:回复文本不算证据(见 7.2 的反例),要看 ①/③。

7.4 其他说明

  • agents.entries.dsh.runtime.type="acp" 不会让发给 dsh 的普通消息自动走 ACP(实测 openclaw agent --agent dsh 仍是 executionTrace.runner="embedded")。它的作用只有一个:让 dsh 能作为 sessions_spawn(runtime:"acp", agentId:"dsh") 的合法目标。
  • 想换成「某个微信账号的消息全量交给 DSH」,在当前渠道能力下做不到「消息直通」;可行的近似做法是把该账号绑定的 agent 换成 dsh,但那只会让 OpenClaw 内嵌运行时换个身份干活,不是 ACP。
  • 若将来 OpenClaw 侧或渠道插件补上 conversationBindings,再考虑 /acp spawn --bind here

8. 凭据位置(本项目文档不含明文)

凭据 位置 说明
DSH 模型 API Key ~/.dsh/.env600)里的 DEEPSEEK_API_KEY DSH 凭据解析优先级:继承的进程环境 > ~/.dsh/.credentials.yaml > 调用目录 .env > ~/.dsh/.env。写 .env 最省事;Web 的 Models 页写入则会落到 .credentials.yaml 并覆盖 .env
DSH Web 访问 token 运行时随机生成 见 §6,从 journalctl 取;不落盘
OpenClaw 各类密钥 ~/.openclaw/.env / ~/.openclaw/openclaw.json bk02-openclaw-系统说明.md §6

9. 排错清单(按遇到概率排序)

症状 原因 处置
dispatch_failed: Unknown agent id "dsh" 只注册了 acpx harness 别名,没建同名 OpenClaw agent 做 §4.4openclaw agents add dsh + runtime.type="acp"
ACP runtime backend is not configured @openclaw/acpx 没装 / 被 plugins.allow 拦 / 网关没重启 openclaw plugins install @openclaw/acpx;把 acpx 加进 plugins.allow;重启网关
回复看着对但 DSH 侧没有新会话 其实是 OpenClaw 内嵌运行时干的 executionTrace.runner;确认 agent:dsh:acp:<uuid> 子会话与 ~/.dsh/sessions/...-workspace-dsh--
PermissionPromptUnavailableError: Permission prompt unavailable in non-interactive mode 非交互 ACP 会话撞上写/执行门禁 plugins.entries.acpx.config.permissionMode = "approve-all"(或 nonInteractivePermissions="deny" 降级)
dsh: profile "acp" does not exist dsh 版本 < 0.1.5(无内置 acp 模板) 升级 dsh,或 dsh plugin --profile acp add @deepseek-ai/dsh-acp 后手写 profile
网关日志 security warning: dangerous config flags … permissionMode=approve-all 预期告警 approve-all 等于把 bk02 上的写/执行权限交给 DSH 会话,见下方安全说明
Web 打开 401 没带 token journalctl --user -u dsh-web 取带 token 的 URL
Web 启动即崩、日志报 $.host expected … --host 传了具体 IP 127.0.0.1+ tailscale serve
dsh 命令找不到 该 shell 没加载 nvm 的 Node export PATH=$HOME/.nvm/versions/node/v26.8.2/bin:$PATH
dsh plugin …pnpm not found on PATH 本机没装 pnpmdsh plugin 只是 pnpm 转发器) npm i -g pnpm
ACP 会话报 JSON 解析错 / 客户端把某行当非法帧 acp profile 里装了会往 stdout 打印的插件(已知:skillhub-plugin 自检行) dsh plugin --profile acp remove skillhub-plugin;装任何插件后都跑一遍冒烟脚本确认无「非 JSON 的 stdout 输出」

安全说明permissionMode=approve-all 让 DSH 会话在 bk02 上自动获得写文件/执行命令的许可(这是「让 DSH 干活」的代价)。可收紧为 approve-reads,但写/执行类任务会需要交互确认,非交互会话可能直接失败。DSH 自身仍带 workspace-write 沙箱 preset 与 approval/policy: ask 记录,可在 ~/.dsh/sessions/*/session.v3.jsonl.zstd 审计。


10. 回滚

# OpenClaw:配置回滚到接入前(备份在 ~/.openclaw/openclaw.json.bak-<ts>-pre-dsh-acp
cp ~/.openclaw/openclaw.json.bak-20260916-170416-pre-dsh-acp ~/.openclaw/openclaw.json
openclaw gateway restart

# DSH Web:停用 + 撤掉 tailscale 暴露
systemctl --user disable --now dsh-web
sudo -n tailscale serve --https=18787 off

# DSH 本体
npm rm -g @deepseek-ai/dsh        # 配置与历史留在 ~/.dsh(可整体删除)

11. 变更记录

时间 变更
2026-09-16 17:01 bk02 安装 @deepseek-ai/dsh@0.1.5-rc.1nvm v26.8.2),自动初始化 acp profile
2026-09-16 17:02 写入 ~/.dsh/.envDEEPSEEK_API_KEYACP stdio 冒烟通过
2026-09-16 17:04 安装 @openclaw/acpxplugins.allow 放行;写入 acp 段与 acpx agents.dsh;网关重启
2026-09-16 17:11 创建 OpenClaw agent dshworkspace-dsh)并接 ACP runtime
2026-09-16 17:12 端到端 ACP 派发成功(proof2/proof3 由 DSH 创建)
2026-09-16 17:15 dsh-web.service 落地(127.0.0.1:18787+ tailscale serve --https=18787;跨机访问 200
2026-09-16 17:20 查明微信/飞书/钉钉渠道均无 conversationBindings 能力(仅 Telegram 等内置渠道有)→ 排除 /acp spawn --bind here 与持久 bindings[] 两条路;部署技能 ~/.openclaw/skills/delegate-to-dsh/SKILL.md 并重启网关
2026-09-16 17:21 自然语言派发验证通过(DSH 侧新会话 332ef715…),「微信 → OpenClaw → DSH → 结果回传」链路可用
2026-09-16 17:23 装 pnpm 12.4.2web profile 增装 skillhub-plugin + superpowers-dsh;写 ~/.dsh/AGENTS.md 全局中文指令(交互 + 思考)
2026-09-16 17:24 发现 skillhub-plugin 自检用 console.log 污染 ACP stdout → 从 acp profile 移除(保留 superpowers-dsh),复测协议流干净;语言复测中文生效
2026-09-16 17:25 端到端回归:OpenClaw 派发仍正常(DSH 会话 6→7,产物 nl3.txt