codebuddy-first-bridge
简体中文 · English
一个用于 DeepSeek Harness (DSH) 的 Cordis 插件:把编码/构建/调试/排查等实际工作优先派发给本机的 codebuddy CLI(腾讯 CodeBuddy Code),DSH 全程掌控 codebuddy(--permission-mode bypassPermissions,codebuddy 全程无提示),并在 codebuddy 流量受限 / 网络不通 时弹窗让用户选择是否回退到 DSH 本地 API 配置;同时在会话标题栏提供一个 实时状态灯,清晰显示 codebuddy 是否正在工作。
codebuddy 状态灯的几种状态
这是什么
codebuddy-first-bridge 给运行中的 DSH 会话注入两样东西:
- 三个模型工具 ——
codebuddy_run、codebuddy_continue 与 codebuddy_status,把任务转交给本机 codebuddy CLI 执行;
- 一段 codebuddy 优先策略提示 —— 让模型在所有模式(普通 / plan / accept-edits / 子代理 / workflow / ralph / goal 轮次)下都优先调用 codebuddy 做实际工作,原生工具只用于只读查询和最终验证。
在此基础上,本插件还实现了用户要求的几项关键能力:
- 回退机制(弹窗确认):当 codebuddy 疑似被限流或网络不通时,自动弹出确认框,让用户选择「使用 DSH 本地 API 配置(回退)」/「重试 codebuddy 一次」/「不回退」。
- 实时状态灯(按项目,随软件启动):浏览器会话标题栏右侧的彩色指示灯为每个项目(工作目录)分别显示一盏,随该项目 codebuddy 活动实时变化(工作中 / 成功 / 失败 / 本地回退),悬停可查看该项目当前正在执行的步骤。状态灯是家级插件(
home-plugin/codebuddy-indicator/,经 cordis.patch.yml 注册),随 DSH 启动自动加载、所有会话自动显示、无需审批。
- 实时观察与用量统计(codebuddy_status):
codebuddy_status 工具随时返回各项目 codebuddy 此刻在干什么 —— 每个项目当前步骤(工具名 + 参数或思考/打字中)、最近步骤轨迹、最近完成运行,以及按项目累计的调用次数(runs)与 token 用量(totalTokens)(codebuddy 无套餐额度 API,以 token 计量作替代观察)。支持 cwd 参数只看某个项目。运行中即可调用,无需等待结束。
四种形态
同一套逻辑提供四种落地形态,按需选择:
| 形态 | 位置 | 能力 | 是否随进程重启保留 | 状态灯 |
|---|
| 持久 Agent Preset(DSH 内推荐) | preset/codebuddy-first/ | 工具 + 优先策略 + 回退弹窗 + codebuddy_status + 双后端(codebuddy/workbuddy) | ✅ 是(落盘为 preset) | ❌ 无(Host 面组合不含浏览器 UI) |
| 家级状态灯插件(随软件启动) | home-plugin/codebuddy-indicator/ | 状态灯(所有会话自动显示,无需审批) | ✅ 是(cordis.patch.yml 注册) | ✅ 有 |
| 动态 Cordis 插件(当前会话) | dynamic/ | 工具 + 优先策略 + 回退弹窗 + 状态灯 + codebuddy_status + 双后端 | ❌ 否(进程内临时) | ✅ 有(需一次性审批) |
| MCP 服务器(任何 MCP 宿主) | mcp/ | codebuddy_run / codebuddy_continue / codebuddy_status 通过 tools/list 被 Claude Code、Codex、Cherry Studio 等自动发现,由宿主代理自主决定是否调用;支持双后端 | ✅ 是(注册进客户端配置) | ❌ 无 |
状态灯为什么需要家级插件? Agent Preset 是 Host 面 组合(agent.cordis.yml 挂载 Host 插件),其中的 .mjs 只在 Node 侧运行,天然不含浏览器 UI;而实时状态灯是 Client 面(浏览器 Slot)组件。家级插件(cordis.patch.yml 注册,如 home-plugin/codebuddy-indicator/)同时提供 Host 半(收集各会话推送的 codebuddy 状态 + HTTP 路由)与 Client 半(浏览器轮询渲染),随 DSH 启动自动加载、所有会话自动显示、无需审批。动态插件形态(首次运行需 GUI 一次性审批)与家级形态的灯可并存:两种形态都把快照汇入家级收集器(动态形态经 codebuddyCollector.mergeSnapshot,preset 形态经 ctx.emit('codebuddy/status') 事件)。
回退弹窗是 Host 侧能力,preset 与动态两种形态都具备;MCP 形态没有 UI,限流时改为在结果文本中附加「勿循环重试」提示,由调用方代理决定回退。
详见 docs/ARCHITECTURE.md。
快速开始
方式 A:作为持久 Agent Preset 安装(推荐)
方式 A1 — npm 安装(v1.1.6 起支持):
npm install -g codebuddy-first-bridge
包内 preset/codebuddy-first/ 即为完整 preset(含 agent.cordis.yml、preset.yml 与自包含的 bridge 模块)。把该目录复制到你的 DSH 用户 preset 根目录后即可选择:
$presetDir = (Get-ChildItem (npm root -g) -Recurse -Directory -Filter codebuddy-first | Select-Object -First 1).FullName
Copy-Item -Recurse "$presetDir" "$env:DSH_HOME\.agent-presets\codebuddy-first"
方式 A2 — 从仓库复制:
把 preset/codebuddy-first/ 整个目录复制到你的 DSH 用户 preset 根目录下:
${DSH_HOME:-$HOME/.dsh}/.agent-presets/codebuddy-first/
Windows 示例(本仓库开发环境):
Copy-Item -Recurse .\preset\codebuddy-first "$env:DSH_HOME\.agent-presets\codebuddy-first"
然后新开一个 DSH 会话,选择名为 CodeBuddy-First 执行代理(id:codebuddy-first)的 preset 即可。它继承 standard preset 的全部能力,额外提供 codebuddy_run / codebuddy_continue / codebuddy_status 工具、codebuddy 优先策略与限流/网络回退弹窗。
⚠️ 不要编辑随部署一起发行的 agent-presets 安装目录(升级会覆盖)。始终安装到用户 preset 根目录下的独立子目录。
完整步骤与校验方法见 docs/INSTALL.md。
方式 B:安装家级状态灯插件(随软件启动、所有会话可见)
标准安装(推荐,v1.1.7 起)——家级灯已并入主包 codebuddy-first-bridge(dsh.bundle.patch 指向其 bundle 补丁层),一条命令即可:
dsh plugin --profile web add codebuddy-first-bridge
DSH 插件系统安装主包后自动挂载家级灯:host 半经裸包名解析到 main → lib/index.mjs,client 半靠 dsh.client 声明自动纳入浏览器花名册,无需手动复制、无需 junction、无需改 cordis.patch.yml。
旧式手动安装(留档):
# 1) 复制插件源码
$dshHome = "$env:APPDATA\DSH Desktop\dsh-home"
Copy-Item -Recurse .\home-plugin\codebuddy-indicator "$dshHome\plugins\codebuddy-indicator"
# 2) 建 junction(host 解析与浏览器花名册都需要;共 3 条)
New-Item -ItemType Junction -Path "$dshHome\node_modules\codebuddy-indicator" -Target "$dshHome\plugins\codebuddy-indicator"
New-Item -ItemType Junction -Path "$dshHome\profiles\node_modules\codebuddy-indicator" -Target "$dshHome\plugins\codebuddy-indicator"
New-Item -ItemType Junction -Path "$dshHome\profiles\web\node_modules\codebuddy-indicator" -Target "$dshHome\plugins\codebuddy-indicator"
# 3) 在 cordis.patch.yml 追加一行(裸包名经 junction 解析到 lib/index.mjs):
# - insert:
# - id: codebuddy-indicator
# name: codebuddy-indicator
配合 preset 形态(方式 A)使用:preset 里的 codebuddy-first-bridge.mjs 每次状态变化会 ctx.emit('codebuddy/status') 推送到家级收集器,灯随之实时更新;改 lib/index.mjs 后重启 DSH 生效(或临时改成 name: codebuddy-indicator?v=N 热载),改 lib/client.js 后刷新浏览器即生效。
方式 C:作为动态 Cordis 插件运行(含状态灯)
在一个已加载 Cordis 能力的 DSH 会话里,用 cordis_define + cordis_run 定义并激活插件,Host 半用 dynamic/host.js,Client 半用 dynamic/client.js。首次运行 Client 半时,DSH GUI 会请求一次性审批,批准后状态灯即出现在会话标题栏。
方式 D:作为 MCP 服务器注册(任何 MCP 宿主可发现)
不需要 DSH 时,把 mcp/codebuddy-mcp-server.mjs 注册为 MCP 服务器,Claude Code / Codex / Cherry Studio 等宿主即可通过 tools/list 自动发现 codebuddy_run / codebuddy_continue / codebuddy_status 并自主决定调用:
# Claude Code 示例(路径换成你本机的仓库位置)
claude mcp add codebuddy -- node "<repo>/mcp/codebuddy-mcp-server.mjs"
Codex / 通用 JSON 配置、环境变量与自检见 mcp/README.md。
依赖前提
- DeepSeek Harness (DSH),且会话已挂载所需 Host 服务:
tools、subprocess、systemPrompt、timer(可选 jobs、planMode、sandboxPolicy、userQuestions)。
- 本机已安装
codebuddy CLI(CodeBuddy Code,npm i -g @tencent-ai/codebuddy-code;开发时验证版本 v2.143.0)。不要求在 PATH 里:桥接会依次尝试 subprocess.resolveExecutable('codebuddy') → node + CODEBUDDY_BIN → node + %APPDATA%\npm\node_modules\@tencent-ai\codebuddy-code\bin\codebuddy,npm 全局安装即可被找到。
- 可选:腾讯 WorkBuddy 桌面版(办公任务
backend="workbuddy" 派发用;CLI 随桌面版安装于 C:\Program Files\WorkBuddy\resources\app.asar.unpacked\cli\bin\codebuddy,可用 WORKBUDDY_BIN 覆盖)。未安装时该后端返回带安装指引的错误,codebuddy 默认后端不受影响。
- 状态灯还需 DSH 的 Web GUI(Client 面)。
工具用法
codebuddy_run(prompt, mode?, model?, effort?, maxTurns?, cwd?, addDirs?, timeoutSec?, background?, backend?)
backend:双后端选择(v1.1.0)。codebuddy(默认,CodeBuddy Code,编码场景)或 workbuddy(腾讯 WorkBuddy——CodeBuddy 的同引擎孪生产品,主打办公场景:文档/幻灯/表格、知识库、图片视频生成、微信/企微回复)。两者各自维护独立会话存储;codebuddy_continue 续接时按 sessionId 自动路由回所属后端,显式传 backend 最优先。
mode:auto(默认,跟随 DSH plan 状态自动选 plan/accept-edits)、plan、accept-edits。
model:可选,指定模型(如 hy4-preview(默认)、hy3、glm-5.3、kimi-k3-1、deepseek-v4-pro 等,完整清单见工具描述);不传用 CLI 配置的默认模型。effort:minimal / low / medium / high / xhigh / max;maxTurns(1-500,默认不限)可选。
background: true:作为后台任务运行,立即返回 jobId,用 job_output 收结果;后台路径同样有 timeoutSec+60s 挂起守卫。
- 返回:
{ ok, status, response, sessionId, durationSeconds, numTurns, totalTokens, exitCode, mode, backend, stderr };回退时为 { ok:false, fallback:true, status:'FALLBACK_TO_DSH', ... }。
codebuddy_continue(prompt, sessionId? | latest?, ...) —— 复用某个会话上下文继续对话(--resume <sessionId> / --continue),其余参数同上;不带 backend 时按 sessionId 自动路由到该会话所属的 CLI。
codebuddy_status(cwd?) —— 实时观察 + 用量统计:返回各项目 codebuddy 此刻在干什么({ state, running, current, trail, lastStatus, lastSessionId, runs, totalTokens, updatedAt, projects[] })。projects[] 按项目(工作目录)分节:current 为该项目当前正在执行的步骤(工具名 + 参数,或 thinking/typing 思考/打字中),trail 为最近步骤轨迹,runs/totalTokens 为按项目累计的调用次数与 token 用量(codebuddy 无套餐额度 API,以 token 计量作替代观察)。可选 cwd 只查某个项目。codebuddy_run/codebuddy_continue 运行期间即可调用,无需等待结束。
DSH 完全控制 codebuddy
每次调用 codebuddy 都强制带 -p、--output-format stream-json 与 --permission-mode bypassPermissions(plan 模式则 --permission-mode plan),因此 codebuddy 从不弹权限提示,改文件也不询问;模式、模型、effort、工作目录、超时、是否后台、能否中止全部由 DSH 侧决定,可通过 exec.signal + handle.terminate() 取消。codebuddy 无 --print-timeout,超时由 DSH 侧挂起守卫兜底(timeoutSec+60s 强杀并报 HUNG_TIMEOUT)。stream-json 的每个事件(assistant 的 tool_use/thinking/text、user 的 tool_result)实时喂给 codebuddy_status 快照。
回退与状态灯
见 docs/FALLBACK-AND-INDICATOR.md。要点:
- 失败识别:非零退出,或
stderr/status 命中 rate limit / 429 / quota / ECONN* / 网络 / 超时 / 限流 / 配额 … 等特征(只匹配 stderr 与 status,不匹配回复全文——排查网络类任务的答复里几乎必现 connection/dns/timeout 字样,会误判限流;数字码带词边界,"1500" 不会命中 500)。
- 弹窗通过 DSH 的
userQuestions.ask() 实现;被子代理调用(无真人应答者)时自动跳过弹窗、按错误返回,避免永久阻塞。
- 每次限流/网络失败弹一次三选一;「重试」仅在还有重试次数(最多 2 次尝试)时提供;后台任务失败不弹窗(前台重跑才提示)。
- 状态灯每 1.2s 轮询家级插件暴露的 HTTP 路由
GET /codebuddy-indicator/status,颜色取自主题 token,自动适配明暗。
目录结构
codebuddy-first-bridge/
├─ README.md
├─ README.en.md
├─ LICENSE
├─ .gitignore
├─ package.json # 版本元数据(v1.1.0,Node ≥18)+ scripts(build/test/check)
├─ MCP-POLICY.md / MCP-POLICY.zh.md # 外部代理「披露并优先」策略(安装到 ~/.claude/CLAUDE.md 与 ~/.codex/AGENTS.md)
├─ .github/workflows/ci.yml # node --check + 测试套件 + 版本/YAML 结构校验(Node 18/20/22)
├─ assets/indicator-states.svg
├─ core/
│ └─ codebuddy-core.mjs # ★ 共享核心(单一事实来源):纯函数 + 状态引擎 + 行流 + 执行编排 + 文案
├─ scripts/
│ ├─ build.mjs # 生成派生产物(dynamic/host.js 文本注入 + preset 侧 core 副本)
│ └─ verify.mjs # 版本三处锁死(package.json ↔ MCP VERSION ↔ CHANGELOG)+ YAML 结构断言
├─ test/ # node:test 套件(44 例:纯函数/沙箱模拟/preset/MCP e2e/同步锁定)
│ ├─ helpers/mockdsh.mjs # DSH 宿主形状替身(ctx/harness/subprocess/userQuestions)
│ ├─ fixtures/fake-codebuddy.mjs # 伪 codebuddy CLI(MCP e2e 夹具)
│ └─ *.test.mjs
├─ preset/
│ └─ codebuddy-first/ # 持久 Agent Preset(DSH 内推荐形态)
│ ├─ preset.yml # 名称/描述
│ ├─ agent.cordis.yml # 组合:standard + 一行 codebuddy 插件
│ ├─ codebuddy-first-bridge.mjs # 宿主适配层(工具注册/事件发布/env 解析)
│ └─ codebuddy-core.mjs # 【生成物】core 副本——preset 安装目录自包含
├─ home-plugin/
│ └─ codebuddy-indicator/ # 家级状态灯插件(随软件启动、所有会话可见)
│ ├─ package.json # dsh.client 声明(浏览器花名册)
│ └─ lib/
│ ├─ index.mjs # Host 半:收集 codebuddy/status 事件 + HTTP 路由
│ ├─ client-entry.mjs # 裸名行占位入口(防二次加载 index.mjs 崩溃)
│ └─ client.js # 浏览器半:轮询渲染每项目灯
├─ dynamic/ # 动态 Cordis 插件形态
│ ├─ host.template.mjs # 适配层模板(含 /*__CORE__*/ 注入点)
│ ├─ host.js # 【生成物】code.host 函数体(core 文本注入,勿手改)
│ └─ client.js # code.client 函数体(空骨架:UI 由家级灯统一呈现)
├─ mcp/ # MCP 服务器(任何 MCP 宿主可发现)
│ ├─ codebuddy-mcp-server.mjs # 零依赖 stdio MCP 服务器(宿主适配层)
│ └─ README.md # 注册方法(Claude Code/Codex/DSH/通用)+ 安全护栏
└─ docs/
├─ INSTALL.md
├─ ARCHITECTURE.md
├─ FALLBACK-AND-INDICATOR.md
├─ CHANGELOG.md # 版本历史(从 1.0.0 起)
└─ en/ # 英文文档
派生产物约定:dynamic/host.js 与 preset/codebuddy-first/codebuddy-core.mjs 是生成物。修改共享逻辑改 core/,修改动态适配改 host.template.mjs,然后 npm run build 重新生成(npm test 的同步锁定会拦住忘记重生成的提交)。
兼容性与支持声明
对 npm 上全部 20 个已发布 @deepseek-ai/dsh 版本(0.0.1-rc.1 → 0.1.5-rc.2)做过回测,完整矩阵与证据见 docs/COMPATIBILITY.md。结论速览:
- preset 形态(方式 A):要求 dsh ≥ 0.1.3-alpha.2(dsh-persona 的
prefix:/suffix: schema 从该版本起强制;更早版本用旧 text: 字段会拒绝挂载)。
- 家级状态灯 bundle 安装(方式 B):
dsh plugin --profile web add codebuddy-first-bridge 全 20 个版本可用(plugin CLI / pnpm 转发 / dsh.bundle.patch / bundles 对账自 0.0.1-rc.1 即存在)。要求 codebuddy-first-bridge ≥ 1.1.8(1.1.7 的 client 注册 id 失配会在所有 dsh 版本上触发启动致命屏)。
- MCP server(方式 D):零依赖独立进程,与 dsh 版本无关。
- 新 dsh 版本发布后可用
npm run compat:dsh 重新回测(详见 docs/RELEASE-SOP.md §3)。
版本与发布
版本管理遵循语义化版本(package.json + Git tag + GitHub Release;npm↔git 逐版本内容审计见 npm run audit:npm,CI 已接入):
| 版本 | 适配 DSH | 内容 |
|---|
| v1.1.12 | 见支持声明(22 版本回测) | 工程化修补:dsh 全版本回测基线修复 + 矩阵扩展至 22 版本(不涉及插件运行时行为)——① 移除 --legacy-peer-deps(会跳过 dsh-app-boot 运行时必需的 peerDependencies,导致沙箱 dsh 环境缺 peer 无法 boot);② 加 --before=<发布时间> 时间锚定(防内部组件 caret 范围把 0.1.6-alpha.x 拉进历史版本形成混合树);③ PROBE_VER 对齐 1.1.11。docs/COMPATIBILITY.md 新增 0.1.6-alpha.1/.2 两行并重跑矩阵 |
| v1.1.11 | 见支持声明(全版本回测) | 工程化修补:两个发布/回测工具的观测准确性(不涉及插件运行时行为)——① audit-npm-sync.mjs 取版本列表加 --prefer-online:npm view <pkg> versions 会命中 npm 本地元数据缓存,导致刚 npm publish 完立刻审计仍只见旧版本列表(实测;CI 新 tag 刚推时同理);② dsh-compat.mjs 汇总单列 功能失败:此前 functional.ok === false 的真实失败被算进 untested,与「根本没跑过」混为一谈(20 版本回测中 7 个「CLI 环境不兼容」行口径不准),现在 untested = 总数 − pass − failed − skip − pending 并与 COMPATIBILITY §3.1 分档对齐 |
| v1.1.10 | 见支持声明(全版本回测) | 工程化:一致性审计 + 全版本回测 + 支持声明 + 交接文档:新增 audit-npm-sync.mjs(npm 每个已发布版本 ↔ git tag 树逐文件 sha256 比对,git -c core.autocrlf=false 取原始字节;审计结论 1.1.6–1.1.9 内容零漂移)与 dsh-compat.mjs(20 个 dsh 版本 7 契约点静态探测 + 沙箱真实安装回测);docs/COMPATIBILITY.md 支持声明、docs/RELEASE-SOP.md 发布维护 SOP、docs/HANDOVER.md 交接文档;CI 增 npm↔git audit job;CRLF 归一化 + .gitattributes(* text=auto eol=lf),1.1.10 起 tarball 与 tag 字节级一致 |
| v1.1.9 | dsh 0.1.5-rc.1 实测 / 0.1.2-alpha.4+ | 发布闸门加固(防 v1.1.8 事故复发):verify.mjs 新增 client 注册 id 静态检查——从 exports["./client"] 解析 client 文件、提取 __ModuleLoader__.load({ id }),强制其与包名 codebuddy-first-bridge 严格一致(id 不匹配会触发 client-modules 的 loaded without registering "<packageName>",整个 combo 崩屏);prepack 加强为 verify + npm test,发布前跑完整测试套件,热修时的版本断言漂移也不再可能漏到 npm |
详见 docs/CHANGELOG.md。
安全说明
--permission-mode bypassPermissions 表示 codebuddy 会在不再询问的情况下改动文件、执行命令。这是「DSH 完全控制 codebuddy」这一需求的直接实现,请仅在你信任 codebuddy 执行环境时使用。MCP 形态可用 CODEBUDDY_MCP_ALLOWED_ROOTS 限定允许的工作目录白名单(见 mcp/README.md)。
- 插件只向 Host 的
tools / systemPrompt 注册、并暴露一个包私有的 codebuddy_status 只读 JSON 方法,不发布任何跨会话服务,因此可安全放入 preset 面(无需 isolate realm)。
- 所有副作用(工具注册、提示段、样式、定时器)都通过
ctx.effect / ctx.tools.register / ctx.timeout 挂到当前 Fiber,插件停止/更新/卸载时自动清理。
English summary
codebuddy-first-bridge is a Cordis plugin for the DeepSeek Harness (DSH). It registers model tools (codebuddy_run, codebuddy_continue, codebuddy_status) that dispatch real work to the local codebuddy CLI (Tencent CodeBuddy Code) under full DSH control (--permission-mode bypassPermissions, so codebuddy never prompts), and injects a codebuddy-first policy so the model prefers codebuddy across every mode. When codebuddy is rate-limited or the network is down, it pops a confirmation dialog offering the DSH local API config as a fallback, and it renders a live status light in the session header showing whether codebuddy is currently working.
Four forms are shipped: a persistent agent preset (preset/codebuddy-first/, survives restart, host-side fallback included), a home-level status-light plugin (home-plugin/codebuddy-indicator/, registered via cordis.patch.yml, the light appears in every session with no approval), a dynamic Cordis plugin (dynamic/, adds the browser status light, needs a one-time approval), and mcp/, a zero-dependency MCP server that exposes codebuddy_run / codebuddy_continue to any MCP-capable host (Claude Code, Codex, Cherry Studio, …), where the agent discovers the tools itself and decides when to call them — even without any codebuddy-first preset.
👉 Full English documentation: README.en.md — with English guides under docs/en/ (install, architecture, fallback & indicator).
License
MIT © 2026 chenglong