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/codebuddy-intl/codebuddy-en/workbuddy)+ 设置面板(偏好 CLI/默认模型/国际版凭据) | ✅ 是(落盘为 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 安装(推荐)
v1.2.0 起推荐方式 B 一并安装(dsh plugin --profile web add codebuddy-first-bridge):
方式 A 的注册通道已并入状态灯插件——新 DSH(≥ 0.1.7-alpha.1)上 preset 由 indicator 自动向
agentPresets 注册表登记(声明制),旧 DSH(≤ 0.1.6-alpha.2)上沿用目录式安装。两种 DSH
都是装完方式 B 后开箱即用;下面的目录复制步骤仅旧 DSH 需要。
方式 A1 — npm 安装(v1.1.6 起支持):
npm install -g codebuddy-first-bridge
包内 preset/codebuddy-first/ 即为完整 preset(含 agent.cordis.yml、preset.yml 与自包含的 bridge 模块)。把该目录复制到你的 DSH 用户 preset 根目录后即可选择(仅 dsh ≤ 0.1.6-alpha.2 需要;0.1.7-alpha.1 起目录式 preset 不再被读取,preset 由方式 B 的 indicator 插件自动注册):
$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 默认后端不受影响。
- 可选:国际版账号。两个国际面是两个独立选项(v1.4.0 起):
backend="codebuddy-intl"(显示名「CodeBuddy 国际版(npm CLI · 国际面)」,别名 codebuddy-ioa / codebuddy-international / codebuddy-oversea):与 codebuddy 是同一个 npm CLI,走它的国际产品面(product.ioa.json 目录:claude-sonnet-5、claude-opus-5、gemini-3.1-pro、gpt-6-astra、hy3-ioa …)。注意:国际面模型由服务端按账号授权放行——真机实测 --model claude-sonnet-5 返回 400 model [...] is only available for authorized users,而 --model hy4-preview(国内面)正常返回 PONG。国内账号选它会拿到明确的授权错误提示,而不是配置错误。
backend="codebuddy-en"(显示名「WorkBuddy 国际版(WorkBuddyAI 桌面 CLI)」,别名 workbuddy-en / workbuddy-ai):WorkBuddy 国际版是独立安装包——WorkBuddyAI 桌面版自带 CLI(C:\Program Files\WorkBuddyAI\resources\app.asar.unpacked\cli\bin\codebuddy,可用 CODEBUDDY_EN_BIN 覆盖;v1.3.0 曾误认为「复用同一个 npm CLI」,已由真机 product.json 推翻)。凭据自动复用,通常无需配置:国际版自己的登录 token 被桌面 App 的 protector key 加密,该密钥只经 sidecar 通道下发、不落盘,headless CLI 读不到(CLI 自身报 category:"missing-key");但桥接按 设置面板 codebuddyEnToken → 环境变量 CODEBUDDY_AUTH_TOKEN → DSH 凭据库(dsh-home 的 .credentials.yaml / .env 里指向 的 ,即你为 DSH 的 workbuddy provider 配过的那个 key)依次取用。真机实测:只要 DSH 里配过 workbuddy key, 即开箱可用;三条通道皆空时才返回 + 指引,不会静默 401。办公场景也可直接用 (国内版桌面 CLI,同样免配置)。
工具用法
codebuddy_run(prompt, mode?, model?, effort?, maxTurns?, cwd?, addDirs?, timeoutSec?, background?, backend?)
-
backend:四后端选择。codebuddy(默认,CodeBuddy 国内版 npm CLI,product 端点 www.codebuddy.ai,编码场景)、codebuddy-intl(= CodeBuddy 国际版,同一个 npm CLI 的国际产品面 product.ioa.json;别名 codebuddy-ioa / codebuddy-international / codebuddy-oversea;国际面模型由服务端按账号授权放行)、codebuddy-en(= WorkBuddy 国际版,WorkBuddyAI 桌面自带 CLI C:\Program Files\WorkBuddyAI,product 端点 www.workbuddy.ai,需填 codebuddyEnToken;亦接受别名 workbuddy-en / workbuddy-ai)、workbuddy(WorkBuddy 国内版桌面自带 CLI,product 端点 copilot.tencent.com,免配置;办公场景:文档/幻灯/表格、知识库、图片视频生成、微信/企微回复)。会话按后端归档(各产品面登录互斥);codebuddy_continue 续接时按 sessionId 自动路由回所属后端,显式传 backend 最优先;无历史会话的新调用按用户偏好默认后端(设置面板)调度。注意 codebuddy-intl 与 codebuddy-en 是两个不同选项:前者是 CodeBuddy 的国际面(同一 npm CLI),后者是 WorkBuddy 国际版(WorkBuddyAI 桌面 CLI)。
-
mode:auto(默认,跟随 DSH plan 状态自动选 plan/accept-edits)、plan、accept-edits。
-
model:可选,指定模型;不传时用用户偏好默认模型(设置面板,若设置过),否则用 CLI 配置的默认。每个模型后方会挂倍率与限时优惠(hy3 · 免费 · 限时免费、hy4-preview · x0.29 · 夜间免费),设置面板里另有「免费 ×N / 计费 / 未标倍率 / 限时优惠 ×N / 未授权 ×N」五行一览,便于精确判断成本。
数据来自哪一层(v1.6.1 修正 —— 这是反复「模型获取错误」的真正根因):模型数据有三层,此前一直只读了第①层。
| 层 | 位置 | 说明 |
|---|
| ① 产品面默认值 | 安装目录 product.${env}.json / product.json | 只是出厂默认目录,不含促销信息 |
| ② 账号级配置 | ~/.workbuddy、~/.workbuddy-ai 的 cache/acc-product-config-v3.json | 带 modelPromotions,账号专属 |
| ③ 客户端实时快照 | 同目录 local_storage/entry_*.info | 用户菜单看到的就是这一层 |
按 ②→③→① 依次回退,且逐字段独立取值(倍率与促销可来自不同文件)。两个易踩的坑:entry_*.info 顶层是 [{userId, data}, …] 数组(同一文件可能有多个账号,取末尾最新一份),而 里是裸对象;国际版 可能(本机为 37 项、无促销、且没有 / ),却排在链首会遮蔽更新的 快照 —— 故候选链改为「按字段各自取第一个有内容的文件」,而非「第一个能读到的文件」。
:如「夜间免费」为每晚 23:00–次日 8:00、(即该时段内真免费),白天只挂角标不折扣;「限时免费」无时段限制。面板与下拉只显示的促销,与 CLI 菜单一致。促销价的写法是 (数字在前),与 字段的 (x 在前),两者都要认。
:真机实测目录里的 命名(、、)(),而未带后缀的 、 正常可用——两者不是同一套 id。
,给 CLI 传一个故意不存在的 model,服务端会在报错里回一行 后跟逐行 (core 里的 就是解析它的)。v1.6.0 起该解析已在真实调用路径上自动生效( → 缓存),;面板据此把型号分成「已授权(可用)」与「未授权(选中必报 400)」两类,下拉只列前者。
: 让账号清单的 挂上目录里 的 ;另有别名表(→、→、→)。
两种 400 要分清: = 该账号清单里没有这个 id; = 在目录里但你这个账号没授权(、、 均属此类——)。
本机实测(2026-09-25,四后端):
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,自动适配明暗。
可视化配置界面(v1.3.2)
DSH 设置里新增「CodeBuddy 桥接」分区(浏览器半注册官方 settings.section 列表槽,与 dsh-dream-skin / dsh-mobile-companion 同款机制),四项用户偏好在同一面板编辑:
| 设置项 | 字段 | 说明 |
|---|
| 首选 CLI | preferredBackend | codebuddy / codebuddy-intl / codebuddy-en / workbuddy 下拉。只影响缺省派发;会话里显式传 backend 参数仍以参数为准 |
| 默认模型 | defaultModel | 输入框带所选后端的实测模型候选(datalist)。留空 = 各 CLI 自身默认 |
| 端点覆盖 | endpointOverride | 一般留空(按登录域自动推导)。仅调试用 |
| 国际版凭据 | codebuddyEnToken | 密码框,页面只显示尾 4 位掩码、明文永不回传浏览器;勾选「清除」可显式清空。留空保存 = 保持现值 |
面板下方是逐后端诊断表:每个后端的生效端点(含来源:覆盖 / 登录域 / product)、auth 库登录域、凭据来源(设置面板 / 环境变量 / DSH 凭据库自动复用)、可能 401 的警示与可操作提示。
保存即对三种形态同时生效,无需重启:面板经 POST /codebuddy-indicator/settings 写入 <dsh-home>/codebuddy-bridge-settings.json(单一事实源),preset 桥接、动态插件与 MCP 子进程在每次调用时现读该文件(MCP 有 5s 缓存)。优先级:设置文件 > preset 行 config > 默认值。
为什么不用 DSH 官方自动表单:官方 Config 投影只覆盖 include 条目,而 preset 桥接行经 PresetTree 组合挂载、不是 include → 永远进不了表单(dsh-config-editor 源码逐行核实)。自绘面板 + 自家读写路由是唯一能让一次保存抵达全部三形态的路径,且能展示诊断信息。
目录结构
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 ↔ indicator package.json ↔ MCP VERSION ↔ CHANGELOG)+ YAML/结构断言
├─ test/ # node:test 套件(125 例:纯函数/沙箱模拟/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 路由(status + v1.3.2 settings GET/POST)
│ ├─ client-entry.mjs # 裸名行占位入口(防二次加载 index.mjs 崩溃)
│ └─ client.js # 浏览器半:轮询渲染每项目灯 + v1.3.2 可视化配置界面(settings.section)
├─ 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 上全部 26 个已发布 @deepseek-ai/dsh 版本(0.0.1-rc.1 → 0.1.7-rc.1)做过探测/回测,完整矩阵与证据见 docs/COMPATIBILITY.md。结论速览:
- preset 形态(方式 A):全版本可用(v1.2.0 修复)——dsh ≤ 0.1.6-alpha.2 走目录制 preset(
dsh ≥ 0.1.3-alpha.2 起强制 persona prefix:/suffix: schema);dsh ≥ 0.1.7-alpha.1 起目录式 preset 不再被读取(目录制 → 声明制切换),preset 由状态灯插件(方式 B)向 agentPresets 注册表自动登记。新 DSH 上方式 A 需与方式 B 一并安装。
- 家级状态灯 bundle 安装(方式 B):
dsh plugin --profile web add codebuddy-first-bridge 全 26 个版本可用(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.4.0 | dsh 0.1.7-rc.1 真机实测 / 全版本 | 模型清单改为运行时读取 + CodeBuddy 国际版独立成选项。用户反馈「四个产品面的模型获取错误」——逐安装核实属实:旧清单里 codebuddy-en/workbuddy 两份抄的是国内版 product.internal.json(含本机不存在的型号),codebuddy 一份也与 --help 不符。① 新增 readBackendModelCatalog()/extractModelIds(),运行时从各安装自己的 product 描述文件现读(agents.cli.models 与顶层 models 取更完整的那份——WorkBuddyAI 的 agents.cli.models 只有 4 个角色别名,37 个真实 id 在顶层 models),读不到回退内置实测清单,永不抛错/为空。实测项数:codebuddy=22、codebuddy-intl=53、codebuddy-en=37、workbuddy=23。② 新增后端 codebuddy-intl(CodeBuddy 国际版),与「WorkBuddy 国际版」(codebuddy-en)在面板上区分为两个独立选项:同一个 npm CLI 的国际面(product.ioa.json:claude-sonnet-5/claude-opus-5/gemini-3.1-pro/gpt-6-astra/hy3-ioa…),别名 codebuddy-ioa/codebuddy-international/codebuddy-oversea 归一;规范 id 只增不改(历史会话归档键不变)。③ 实测结论:国际面模型被同一个 npm CLI 接受,但由服务端按账号授权放行——--model claude-sonnet-5 返回 400 model [...] is only available for authorized users,--model hy4-preview 返回 PONG;codebuddy-intl 诊断提示专述此点,避免误改端点/凭据。④ policy 文案、六处 schema enum/描述、面板模型提示同步。测试 128→132 例 |
| v1.6.2 | dsh 0.1.7-rc.1 真机实测 / 全版本 | 「默认模型」候选只剩一个,看起来像模型列表丢了。你反馈「所有的模型列表只有 deepseek-v4.1-flash 一个」——核查后确认数据完整(live 接口实测 codebuddy 53 / codebuddy-intl 53 / codebuddy-en 26 / workbuddy 53 项,一条没少),问题在渲染方式:原用 <input list> + <datalist>,这是自由文本框,浏览器会按输入框当前文字做前缀过滤;而你的 defaultModel 正是 deepseek-v4.1-flash,它又恰好排在候选第 1 位(带 Free now 促销、实付 x0.00,落在免费段最前),于是展开下拉只剩它自己。改用显式 列出全部可用型号,候选不再受输入文字影响;另加「自定义…」一项切到手动输入框,保留手输任意 model id 的能力。note 文案改为显示(如「共 26 项」),一眼可验。顺带修掉 与 被并到同一行的样式拼接故障(后者缺尾逗号会中断 CSS 解析,橙色促销标签不生效) |
详见 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