wanwulizhi/dsh-claude-code-sdk

wanwulizhi/dsh-claude-code-sdk

需本机已安装并登录 Claude Code。通过 Claude Agent SDK 把编码任务委派给本机 Claude Code,报告改动文件、支持一键回退,并在输入框旁提供「Claude 模式」开关。

도구 및 기능agent-sdkanthropicclaude-code

dsh-claude-code-sdk

把自包含的编码任务委派给本机 Claude Code 执行,结果回传给 DSH。DSH 当 leader,Claude Code 当 worker。

走官方 Claude Agent SDK(@anthropic-ai/claude-agent-sdk 的 query()),不是简单 shell 调用,因此能拿到结构化的执行结果:最终文本、sessionId、token 用量,以及 worker 实际调用过的工具列表。

目标宿主是 DSH 0.2.x。

它解决什么问题

DSH 自己有一套工具循环,适合"边聊边做"。但有些任务更适合交给一个独立 agent 整段跑完:

  • 一次要改十几个文件、需要反复读代码再改的重构
  • 需要自己跑测试、看失败、再修的长循环
  • 你希望"派出去干完再回来",而不是每一步都在主对话里来回确认

这类任务交给 Claude Code 更合适:它有自己的 Read/Edit/Bash/Grep/Glob 工具链和完整 agent 循环。插件负责把任务交出去、把结果收回来。

关键特性:内层 Claude Code 的工具调用不会进入外层 DSH 会话的上下文。它读了二十个文件、跑了十次命令,回给 DSH 的只有一段最终结论。主对话不会被中间过程撑爆。

工作原理

┌──────────────────────────────────────────┐
│ DSH(leader)                            │
│  用户:「让 Claude 去把 xxx 重构了」      │
│         ↓ 模型决定调用 claude_code 工具  │
│  ┌────────────────────────────────────┐  │
│  │ dsh-claude-code-sdk                │  │
│  │  1. 从 exec.agent.session 读历史    │  │
│  │  2. 拼成 transcript + 任务文本      │  │
│  │  3. query() 交给 Claude Agent SDK  │  │
│  └────────────────────────────────────┘  │
└──────────────────┬───────────────────────┘
                   │ stdio
┌──────────────────▼───────────────────────┐
│ Claude Code(worker)                    │
│  自己的 agent 循环:Read → Edit → Bash   │
│  → 看测试结果 → 再改 → …                 │
│  这些中间过程 DSH 看不到                  │
└──────────────────┬───────────────────────┘
                   │ 只回一段最终文本 + 用量
┌──────────────────▼───────────────────────┐
│ DSH 拿到 { output, sessionId, tokens }   │
│  leader 负责 review 和验收                │
└──────────────────────────────────────────┘

插件内部对消息流的处理:

  • msg.type === "assistant" → 累加 text 块、把 tool_use 的工具名收进集合
  • msg.type === "result" → 取 total_cost_usd 与 usage.input_tokens / usage.output_tokens;正文为空时回退 msg.result
  • 失败时按 msg.result ?? msg.error ?? msg.subtype 提取原因

与 zhangjunjesse/dsh-claude-code 的区别

实现思路来自 dsh-claude-code。核心逻辑(消息流处理、Config 字段、输出 schema、技能文案结构)与之等价,以下五点是有意改动:

差异 · 原因 peer 范围是 >=0.2.0-rc.2 <0.3.0-0 · 上游钉在 ^0.1.0-rc.6,在 DSH 0.2.x 上装不进去 allowedTools 有默认白名单,含 Bash / PowerShell · 上游留空时,acceptEdits 下所有 shell 命令会被拒,worker 实际干不了活(见「权限模型」) 注入当前 DSH 对话历史 · 让 worker 知道前面聊了什么,不必每次重述背景 不内置可执行文件路径 · 由 SDK 解析自带的 CLI,跨平台可用;需要时可显式指定 技能里补充了权限与成本的实操说明 · 上游文案假设的是订阅计费,对第三方中转不成立

两个插件都注册 `claude_code` 这个工具名,同时安装会冲突(tool "claude_code" is already registered)。二选一。

安装

前提

  • DSH 0.2.x(@deepseek-ai/dsh-tools >= 0.2.0-rc.2)
  • 本机已安装并登录 Claude Code(claude 能跑起来)
  • Node.js >= 22.19.0

方式

收录到 awesome-dsh-plugin 后,可在 DSH 的 设置 → 插件 里搜索安装,或:

dsh plugin --profile web add dsh-claude-code-sdk

安装顺序是「npm 包 → 作者提供的 GitHub Release tarball → 整仓 GitHub 源码」。本包目前只提供源码,因此走最后一条:克隆仓库后安装依赖。

首次安装需要拉取对应平台的 Claude Agent SDK 二进制,约 280 MB,耗时取决于到 GitHub 与 npm 的网络。

验证装好了

在 DSH 里发一句:

用 claude_code 工具执行:task = "只回复两个字:正常"

返回「正常」即通。

如果工具没出现,先确认 DSH 是否真的重启了——插件在启动时装载,改完配置不重启不生效。

快速开始

不需要特殊语法。工具注册后,DSH 的模型会在合适的时候自己调用;你也可以直接点名。

点名调用

用 claude_code 工具执行:task = "在 D:\proj 下把 utils.js 里的 callback 写法改成 async/await,改完跑 npm test 确认通过"

只说意图,让技能接管

让 Claude Code 去重构 src/parser.js,拆成三个函数,保持现有测试全绿

插件注册的 claude-code-delegation 技能会告诉模型什么时候该派活、任务该怎么写、结果怎么质检。

多轮迭代

第一次调用返回里有 sessionId。第二轮把它作为 resume 传回去,Claude Code 记得上一轮读过的文件,不用重新读一遍:

用 claude_code 继续上次 sessionId=76ab34e8-... 的工作,把刚才那两个测试失败修掉

Claude 模式(输入框开关)

输入框右侧、模型选择器旁边有一个 「Claude 模式」 开关。点一下开启:

  • 草稿里会自动写入 /claude-mode ,你接着写任务即可
  • 之后每一条消息都会带上这个技能,模型据此把所有任务都委派给 claude_code
  • 再点一下关闭,前缀会被摘掉

开关状态按会话独立保存(写在浏览器 localStorage 的 dsh-claude-mode 键下),关掉浏览器再回来还在。

开启后 leader 的行为约定:

该做 · 不该做 理解意图、澄清歧义 · 用 read / write / edit / bash 自己动手 把任务描述写清楚(目标、路径、约束、验收) · 跳过委派直接给答案 review worker 产出、必要时带反馈再派一轮 · 直接采信 worker 的自述

如果你在开启状态下想让 leader 自己做某件事,直接说「这次你自己来」,它会照做并提示这偏离了模式。

实现细节:技能被选中时,DSH 插入的是纯文本 /{skill-name} (不是特殊组件)。所以开关本质上就是往草稿里维护这个前缀——这也是为什么关掉开关时能把前缀干净地摘掉。

任务描述怎么写

Claude Code 只能看到任务文本 + 注入的对话历史,看不到文件内容、也看不到 DSH 的工具输出。所以任务里要写清四件事:

  1. 目标:一句话说清交付什么
  2. 文件:相关文件的绝对路径(派活前先自己 grep 摸清结构,把结论写进去)
  3. 约束:构建/验证命令、禁止事项、风格要求
  4. 验收:做到什么算完成

对比:

❌ 把上面那个文件改一下
   (不知道"上面"是哪个,也不知道要改成什么)

✅ 把 D:\proj\src\utils.js 里的 debounce 函数改写成支持 cancel 方法。
   要求:保持现有导出名不变,不引入新依赖,改完执行 npx vitest run utils 确认通过。

工具 claude_code

参数

参数 · 类型 · 必填 · 说明 task · string · ✅ · 完整、自包含的任务描述 context · string · · leader 自己写的背景摘要,取代自动注入的历史。比注入原文省得多 cwd · string · · 工作目录。默认取配置值,再退到会话工作区,最后 DSH 进程目录 model · string · · 本次覆盖模型(sonnet / opus / haiku 或完整 id) permissionMode · string · · default / acceptEdits / bypassPermissions / plan / dontAsk maxTurns · integer · · 本次最大 agentic 轮数 allowedTools · string[] · · 预授权的内置工具(白名单放行,不是限制) resume · string · · 上次返回的 sessionId,续接同一会话 effort · string · · 思考强度 low / medium / high / xhigh / max maxThinkingTokens · integer · · 思考 token 预算 includeHistory · boolean · · 是否注入 DSH 对话历史,默认取配置值 trackChanges · boolean · · 是否拍快照并报告改动,默认取配置值(true)。只读任务可以关掉省开销

返回

{
  "ok": true,
  "output": "最终文本",
  "sessionId": "76ab34e8-0069-4c2c-9a5b-33ee5ac8c812",
  "costUsd": 0.0700,
  "inputTokens": 12020,
  "outputTokens": 2,
  "toolsUsed": ["Write", "PowerShell"]
}

toolsUsed 是 worker 实际调用过的工具名集合,可以用来判断它有没有真的动手(而不是只回了一段话)。

渲染到对话里时只显示 output,不显示金额和 token 数。

变更追踪与回退

每次委派前后各扫一次工作区,比对得出改动,并保留可还原的快照。

为什么需要它:dsh-rewind-plugin 挂在 DSH 自己的 write / edit 工具上,而 worker 是在 Claude Code 内部改文件,绕过了这一层。实测本机 ~/.dsh/rewind-snapshots/ 里最新快照停在 10-16,之后大量委派改文件都没留下快照。所以 worker 的改动原本既看不见、也退不回。

返回里多出来的字段

字段 · 含义 filesChanged · 改动过的文件路径(相对 cwd) added / modified / removed · 三类改动的数量 snapshotId · 这次委派的快照 id,回退时用它

正文末尾还会附一段摘要:

---
改动 2 个文件(快照 mvoo963a-ksfsiv)
新增 1:created.txt
修改 1:keep.txt

委派中途失败也会报告已改动的文件——半途而废的改动最需要知道。

回退

用户:把刚才 Claude 改的东西撤回
  → 模型调用 claude_code_revert(snapshotId, dryRun: true) 给用户看清单
  → 确认后 claude_code_revert(snapshotId) 真正执行

行为:改过的文件写回快照内容、被删的恢复、worker 新建的删除。

安全边界

  • 只处理快照里记录过的路径,不会碰你没让动的东西
  • 每条路径都重新校验是否仍在快照 root 之内(防 ../ 越界,已测试拒绝)
  • 只删单个文件,不递归删目录
  • 快照 id 有格式校验,非法值直接拒绝
  • 超出备份预算的大文件:能报告改动,但回退时会跳过并说明原因

开销

扫描会跳过 node_modules、.git、dist、build、__pycache__ 等非源码目录。实测:12 个文件约 6 ms、175 个文件约 34 ms。

有文件数与耗时双重预算(默认 8000 个文件 / 1000 ms)。超预算时直接放弃追踪,而不是给出半截的 diff——因为前后两次截断的子集可能不同,会凭空报出「新增」和「删除」。放弃时正文末尾会说明原因,你可以调大 maxTrackedFiles / maxTrackedMs。

备份另有字节预算(单文件 512 KiB、总计 64 MiB),超了就退化为「只报告不可回退」。

只读任务(审计、查代码)建议传 trackChanges: false。

成本

  • 响应时间:正常项目增加几十毫秒;超预算的大目录最多约 1 秒(扫描 + 放弃)。
  • token:改动摘要会进对话历史,每次委派约 50~150 tokens。工具定义本身(含 claude_code_revert 的完整描述)会出现在每个请求里,约 300~400 tokens,这部分被 prompt 缓存覆盖。