dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
DSH 插件:ZCode 派发台 —— 在 DeepSeek Harness 面板里派发/监视 ZCode 无头进程(agent 工具 + 悬浮面板:单写者互斥 / 用量聚合 / 套餐通道 / 降级链)
一个 DeepSeek Harness(DSH)插件:
把任务派发给本机 四个 AI 编程 CLI(ZCode / OpenCode / Qoder / WorkBuddy)的无头进程,
并在 DSH 页面右下角的悬浮面板里监视它们。
DSH 自带的 subagent 跑的是 DSH 自己的 agent;本插件跑的是你自己的 CLI —— 独立进程、 独立额度、独立会话,任务行出现在「DSH 派发台」面板里,可查输出、可终止、可续跑、可换通道重跑。
全部走官方 CLI:不反代、不模拟 OpenAI/Anthropic 兼容接口、不读写任何凭据内容 —— 插件只负责"起进程 / 传参数 / 读 stdout"。"通道即执行目标"是 core 的模型 (zcode / opencode/ / qoder/ / codebuddy/)。
引擎 · 官方 CLI · 登录 · 额度 / 积分 · 备注 ZCode · zcode.cjs(桌面客户端自带) · 读 ~/.zcode/v2/credentials.json · ✅ 能查(客户端日志里的 balance 行) · 支持「套餐」与「免费额度 Start Plan」两条路由 OpenCode · opencode(PATH) · 免费模型无需凭据 · 免费(无额度概念) · 十几个免费模型;并发上限默认 2(实测依据) Qoder · qoderclicn(PATH) · ⚠️ 需单独登录 · ⚠️ 积分制,无余额查询接口;单次消耗可查(credits) · 与桌面应用登录不共享;并发默认 3(实测) WorkBuddy · codebuddy(WorkBuddy 客户端内置) · ⚠️ 需单独登录 · ⚠️ 积分制,CLI 完全不暴露 · 见下节「积分可得性」;并发默认 2(保守默认,未实测)
引擎自动发现:四引擎都走 collab-kit/engine-discover.mjs 的五级探测 (env → 配置 → PATH → 已知安装位置 → 跨盘符扫描),不需要手填路径; 面板「引擎」行显示形态 / 版本 / 登录态,点悬浮看探测依据。
引擎 · 余额 · 单次消耗 · 依据 ZCode · ✅ giftQuota · token · 读客户端日志(只读,零网络) OpenCode · — · token · 免费模型 Qoder · ❌ 官方无接口 · ✅ credits · result.total_credits 恒 0,真值在每条 assistant 的 message.usage.credits(需按 message.id 去重累加) WorkBuddy · ❌ 官方无接口 · ❌ · stream-json 只有 token;total_cost_usd 恒 0;/cost /stats 无头不支持;--serve REST 无 usage 端点;本地存储无数值
⇒ 面板与 agent 工具只显示真拿得到的数:拿不到就不显示(不编数字、不猜汇率折算)。 「哪个引擎查不到」这种元数据仍完整保留在 action=channels 的 creditSummary 里给 agent 读。
社区有把 WorkBuddy / Qoder 的账号登录态反代成 OpenAI/Anthropic 兼容接口的做法。 本项目刻意不做:
走官方 CLI 是产品自身入口,不受这类限制影响。
从不读内容、不写、不删。修复动作一律交给用户或官方 /login。
DSH 的工具层反而用不上。
代价:只能拿到 CLI 愿意暴露的数据 —— 比如 WorkBuddy 的积分就查不到(见上表)。 本项目的态度是如实标注"查不到",不编数字。
长任务在看守进程那侧还会被温和终止(3 秒后才兜底强杀)—— 因为真机发现强杀 WorkBuddy CLI
会留下.logged-out标记,导致之后一直判"未登录"(详见pitfalls.md)。
本项目不发布 npm(不提供裸包名安装)。唯一安装路径 = 从 GitHub 仓库安装;
改代码的场景用本地绝对路径挂载。
从 GitHub 仓库安装(推荐)——git 规格 + #path: 子目录定位:
dsh plugin --profile web add "github:Shuffle-1992/dsh-dispatch#path:dispatch"把web换成你的 profile 名(dsh plugin list可查)。装完重启 DSH 生效。
`#path:dispatch` 不能省:本仓库是 monorepo,插件本体在 dispatch/ 子目录;DSH 实际执行 pnpm add ,而 pnpm 对 git 仓库默认取仓库根 —— 根目录没有插件package.json,装出来只会得到占位包(实测{"_pnpmPlaceholder":"...did not contain a package.json."})。
本地开发挂载(源码就在本机时):profile 的 dependencies 加 "dsh-dispatch": "link:/dispatch"、bundles 加 "dsh-dispatch", 并在 profile 的 node_modules/dsh-dispatch 建 junction 指向该目录。
包名 =dsh-dispatch;bundle 资格由仓库根package.json的dsh.bundle.patch
(→dispatch/cordis.patch.yml)声明;插件本体清单在dispatch/package.json。
能力 · 说明 派发(四引擎) · 把 prompt / 任务文件 / 目标描述交给 ZCode / OpenCode / Qoder / WorkBuddy 跑;build / edit / plan / yolo 四种模式仅 ZCode 支持(其它引擎按各自 CLI 能力剔除) 单写者互斥 · repo / 文件锁 + 进程内 FIFO 队列:同锁任务串行,冲突只排队不报错(多会话并发也不会互相踩) 实时监视 · 每个 job 的状态、耗时、Token 用量、上下文占用、积分/费用、退出码、锁持有者;可拉最近输出(tail) 续跑 / 重跑 · 同会话 --resume 重发原提示词,或在同一会话里发一条新指令(仅 ZCode 支持 resume) 通道与降级链 · 切换通道 / 模型 / 思考强度;额度耗尽或未开通时按降级链自动交接重跑到下一个可用通道 分流模式 · 主通道名额满时把新任务自动改派到降级通道(两条通道并发名额叠加);显式指定 provider 时不生效 思考强度核对 · 记录请求档位 vs 实际生效档位;Qoder 用 thinking 内容块有无判定,不符时给出向上改档建议 引擎登录助手 · WorkBuddy 登录态常显(●已登录 / ◐凭据在 / ○未登录 / ⚠标记残留)+ 一键登录(临时 --serve);登录服务温和终止、残留标记自动诊断 免费额度通道 · ZCode Start Plan:托管官方 app-server 走逐请求签名;account:-start-plan;与付费套餐复用同一条面板 / 台账 / 暂停 / 降级流水线 积分/额度视图 · 按引擎汇总(creditSummary:有余额 / 取不到 / 官方无接口)+ 本进程内消耗聚合(creditConsumption);拿不到的就不显示 用量聚合 · 本地台账 5 小时滚动 / 本周 / 今日,外加套餐剩余额度(数据源不可用时如实标注,不猜) 派发总开关 · 一个跨会话真值文件:false = 任何会话都不得派发(runner / 插件 / 桥接三处强制生效) agent 工具 · 注册 dispatch,与面板同一套动作实现(一操作两调用方) 落地自动唤醒 · 任务落地(done/failed/killed/paused)时唤醒发起会话,与 DSH 后台任务同款
dispatch/
├─ dispatch/ ★ 插件本体(cordis bundle:Host 半边 + Client 半边)
│ ├─ index.js Host 入口:apply(ctx, config)、dispatcher 单例、注册 agent 工具、激活信标
│ ├─ wire.host.mjs Host 接线 + 动作唯一实现 createActionHandler + 派发总开关读写
│ ├─ wire.client.mjs Client 接线 + 轮询 / demo 降级
│ ├─ client.js UI 半边:悬浮面板(React.createElement,无构建步骤)
│ ├─ core/ 派发核心(零 npm 依赖):dispatch-core / quota / gift-quota / appserver-rpc …
│ ├─ bin/dispatch.mjs 独立 CLI(与插件同 core,用来对照排查)
│ ├─ locale/{zh,en}.json 中英文案(key 一一对应,有测试锁)
│ ├─ test/ 69 个可复跑自测文件
│ └─ cordis.patch.yml bundle 层 patch(**只放 demo/maxConcurrent**,机器路径见「配置」)
├─ collab-kit/ ★ 四个执行器(与插件 core 共用行协议,也可单独当 CLI 用)
│ ├─ zcode-run.mjs ZCode 执行器
│ ├─ opencode-run.mjs OpenCode 执行器
│ ├─ qoder-run.mjs Qoder 执行器(credits 计量)
│ ├─ codebuddy-run.mjs WorkBuddy / CodeBuddy 执行器(官方 CLI + 登录助手)
│ ├─ engine-discover.mjs 四引擎自动发现(env → 配置 → PATH → 已知安装位置 → 跨盘符扫描)
│ └─ appserver-gift*.mjs ZCode Start Plan 免费额度托管
├─ tools/ 常驻证据脚本(见「复跑证据」,17 个)
├─ bridge/ 客户端自动化桥(inbox/outbox 收发任务文件)
├─ tasks/ 开发留档:每轮任务书与交付记录(含原始输出与未决项)
├─ refs/ 参考资料(**含第三方材料,见文末声明**)
├─ profile-backup/ DSH profile 配置的三态留档与恢复说明
├─ pitfalls.md ★ 踩坑总账(每个真机坑的现场、根因、修法)
└─ dispatch/teaching.md ★ 教学文档(引擎细节 / 登录 / 额度 / 验收清单)四引擎的差异不会被"抹平":每个引擎在 validateSpec 里剔除自己不支持的参数 (如 Qoder/WorkBuddy 不支持 mode / memoryBench),并在面板"引擎提示"行如实说明, 而不是静默忽略。
要求:DSH 桌面版(在 0.2.1-rc.2 上开发验证)+ 至少一个本机 AI CLI (ZCode / OpenCode / Qoder / WorkBuddy 任一;四个都在则全部自动发现)。
link:):# 例:把本包挂进 profile 的 node_modules
New-Item -ItemType Junction `
-Path "$env:USERPROFILE\.dsh\profiles\desktop\node_modules\@local\dispatch" `
-Target "<本仓库>\dispatch"plugin_manager 的 install_bundle 安装(target = 插件绝对路径),并读返回的 `application` 与 `warnings`(applied 才算生效)。
本包无构建步骤、无 npm 依赖;Host 半边(index.js/wire.host.mjs/core/*)改动
需要重启 DSH 才生效,Client 半边(client.js)改动刷新页面即可。字段 · 默认 · 说明 demo · false · UI 演示模式:用内置假数据渲染面板,不触达 dispatcher maxConcurrent · 3 · 全局同时运行上限(各引擎实际并发 = min(全局, 该引擎上限)) maxConcurrentOpenCode · 2 · OpenCode 独立并发(实测:并发 opencode 进程会零输出 exit 1,故默认 2 不建议调高) maxConcurrentQoder · 3 · Qoder 独立并发(实测:3/5 个 qoderclicn 并发全部 exit=0 且结果正确) maxConcurrentCodebuddy · 2 · WorkBuddy 独立并发(保守默认,未实测;该 CLI 是 Electron 内置 bundle,比纯 CLI 重) runnerPath · '' · ZCode 执行器绝对路径(collab-kit/zcode-run.mjs);留空则不创建 dispatcher opencodeRunnerPath · '' · OpenCode 执行器(留空自动推断:env DSP_OPENCODE_RUNNER → 仓库内) codebuddyRunnerPath · '' · WorkBuddy 执行器(留空自动推断:env DSP_CODEBUDDY_RUNNER → 仓库内) ledgerPath · '' · 台账 dispatch-runs.jsonl 绝对路径;留空则跳过用量聚合 workRoot · '' · 派发器工作根目录(locks/、state/jobs.json、logs/);留空则不创建 dispatcher runnerCwd · '' · runner 子进程工作目录(通常设为宿主项目根);留空 = DSH 进程 cwd switchPath · 内置默认 · 派发总开关真值文件;留空则开关不可写 notifyOnSettle · true · 任务落地时自动唤醒发起会话(与 DSH 后台任务同款) maxConsecutiveWakes · 0 · 连续唤醒次数上限;0 = 不限 systemPromptHint · true · 向 system prompt 注入「派发台优先于 subagent」提示段
Qoder 执行器路径通过options.qoderRunnerPath/ envDSP_QODER_RUNNER注入,默认推断到仓库内。
runnerPath 与 workRoot 任一为空则不创建 dispatcher:面板走 demo 降级,agent 工具返回可读错误。 这是刻意设计——不猜一个位置静默跑错。
「引擎自动发现」在 dispatcher 存在时默认开启,不需要额外配置;
它只读取环境/文件系统/CLI 版本,不消耗任何额度。
上面的路径都指向某个具体宿主项目,属部署配置。请在 ~/.dsh/profiles//cordis.patch.yml 里按 id 覆盖:
- id: dispatch
name: "dsh-dispatch"
config:
demo: false
maxConcurrent: 3
runnerPath: '<宿主项目>\scripts\collab\zcode-run.mjs'
ledgerPath: '<宿主项目>\collab\logs\dispatch-runs.jsonl'
workRoot: '<本插件目录>\.data'
switchPath: '<宿主项目>\collab\dispatch.switch.json'(cordis.patch.yml 的 patch 层按 id 覆盖是 DSH 的标准机制——同文件里 ui-theme / ui-chat 等条目就是这么覆盖 bundle 内置条目的。)
本插件不自己存凭据,而是读 ZCode 自己的 ~/.zcode/v2/config.json (provider["builtin:bigmodel-coding-plan"].options.apiKey)—— 与 ZCode CLI 同源。
已知上游缺陷:ZCode 在 OAuth 重新登录后,把新 Key **只写进加密凭据库
credentials.json、不回写config.json,导致 `config.json` 里留着失效的旧 Key**
⇒ 一切读它的程序集体 401(连 `zcode.cjs -p …` 也一样)。
💡 处理办法:把有效 Key 保存(写回)到 `config.json` —— 一次修好所有工具:
credentials.json 解出有效 Key(enc:v1 = AES-256-GCM,密钥 sha256(secret));{"code":1000,"msg":"身份验证失败。","success":false} —— 不能只看状态码);
config.json,把有效 Key 填回 options.apiKey;回读校验。详细步骤、解密参考实现、验活判定代码与完整踩坑记录见
`dispatch/README.md` 的「凭据从哪来 + 报 401 怎么办」一节。
现成恢复工具见姊妹项目 dsh-connect-zcode的 scripts/sync-key-to-config.mjs(自动备份 + 验活 + 原子替换 + 回读校验)。派发台支持 ZCode Start Plan(活动赠送额度):通道 id account:-start-plan (本机实测 account:bigmodel-start-plan),面板下拉里显示为「免费额度(Start Plan)」, 也可直接当 --provider 用:
zcd dispatch --kind prompt --prompt "只回复 OK" --provider start-plan
zcd dispatch --kind task --task <任务包> --provider account:bigmodel-start-plan --mode yolo原理:该端点要求逐请求的官方客户端证明(直连 HTTP 会被 405 / code 3012 拦), 所以由 runner 托管 zcode.cjs app-server、自己注入套餐账户并把 token 递给它签名。 实现在 collab-kit/appserver-gift.mjs(回合驱动)+ collab-kit/appserver-gift-job.mjs (产物 / 输出行 / 台账,与既有 print 模式同形)—— 因此面板、暂停分类、重试/交接、降级链、 台账聚合全部复用,台账按 billing=zcode-plan-gift 与付费套餐分账。
和姊妹项目 `dsh-connect-zcode` 的 provider 通道怎么选?
派发台的语义是「独立 ZCode 进程 + 它自己的工具 + 独立会话/额度」—— 所以在这里
「工具由 ZCode 自己执行」是设计,不是缺陷;而那边把同一个免费额度接成 DSH 的模型对话通道,