DeepSeek Harness Plugin Hub

发布与管理完整 Harness Profiles,发现适合你的插件。

探索

插件目录环境预设文档中心动态

社区

发布插件联系我们报告问题

相关链接

Plugin Hub GitHubDeepSeek Harness 官方项目系统状态隐私说明
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

独立、非官方社区项目,与 DeepSeek 官方无隶属、授权或背书关系。

Providers Hub — DeepSeek Harness 插件(DSH Plugin)
← Plugins
P

dsh-providers-hub

Providers Hub

DeepSeek Harness 插件:AI 编程服务提供商的一站式中心——账号登录、多账号池、静默凭据刷新、额度领取,以及本地兼容 OpenAI 的网关

插件会安装到这里;不确定时保持 web。

npx -y @deepseek-ai/dsh plugin --profile web add github:iJetLi/dsh-providers-hub#828037dac57761110a0f62fd0a1bfda55fd34e90
README兼容性版本

兼容性与来源证明

Providers Hub 以 dsh-providers-hub 发布,当前版本为 0.2.0-rc.11。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

DSH 兼容范围
*
运行环境
web
发布来源
github
Registry 更新时间
2026/10/14

版本

0.2.0-rc.11prerelease
2026/10/14

相关插件

正在加载相关插件…

最新版
0.2.0-rc.11
DSH
*
HMR
重启进程
Tree shaking
未声明可安全裁剪
解包体积
未提供
文件数
未提供
Surface
web
许可证
MIT
发布源
github
GitHub
★ 1
周下载
0
最近提交
2026/10/16
查看源码 ↗
README Badge

点击下方 Badge 复制 Markdown,粘贴到 README 即可。

这是你的 Plugin?认领权益 · 优先安全扫描

验证 package.json 声明的 GitHub 仓库,即可管理这个公开页面。认领后,Hub 会优先安排当前版本的安全扫描,并在通过后公开展示结果。

认领这个 Plugin →
报告问题
DeepSeek Harness Plugin Hub
ProfilesPlugins分类动态文档登录管理 Profiles
ProfilesPlugins分类动态文档登录

相关插件

继续浏览 security-access 分类下经过校验的插件。

Experimental Auto Review@deepseek-ai/dsh-experimental-auto-review针对每个工具的 LLM 授权审查,适用于 DeepSeek Harness Auto 权限预设Cc Safety Netcc-safety-net编码代理 CLI 钩子——阻止破坏性命令和访问机密文件Doctor@linxin666/dsh-doctorDSH 配置档案的事务性救援模式,配备受监督的启动器、隔离的恢复容器、确定性修复、健康监控以及本地 Web 恢复控制台Pocketdsh-pocket把 DeepSeek Harness 装进你的口袋:一个包、一个设置页,手机扫码即同步访问电脑上的 DSH(局域网 + 公网,实时同屏)。

README

dsh-codearts-auth

使用声明:本项目仅供学习研究使用,请遵守各服务提供方的服务条款。

deepseek-harness 插件:统一管理多个 AI 编程服务的账号,并把它们的模型接进 DSH 的模型选择器。支持多账号池(同一服务登录多个账号,按可用性自动选号)与 凭据静默续期(到期前自动刷新,无需再次打开浏览器)。

  • 16 个 provider 路由,外加 1 个聚合路由(见下)
  • 登录、状态、续期、积分领取全部在 Jet Hub 设置页完成,不注册任何斜杠命令
  • 附带一个本机 OpenAI 兼容网关,供其它客户端复用已登录账号

📌 本 README 只写「怎么用」。 各 provider 的协议、端点、登录流程、请求头 构造、实测数据与事故史等实现细节,统一记录在不入库的内部文档 docs/implementation-notes.md 中。需要改动实现或排查协议问题时读它。

⚠️ accio 的章节该文件里还没有(implementation-notes.md 目前零处 accio)—— 读它时不要以为 accio 没有实现笔记。accio 的实测结论与坑点当前登记在 docs/agent-notes/providers-accio.md(含三条与参考实现相反的结论、两个真缺陷、 区域选择与接线陷阱),补写 implementation-notes.md 的 accio 章节是独立任务。


目录

  • 安装
  • 用法
  • 支持的渠道
  • 聚合路由
  • 本机 OpenAI 网关
  • 用量徽标与 Token 用量
  • 配置项
  • 开发

安装

该包尚未发布到 npm registry。提供两种安装方式。

方式一:从 git 仓库安装(推荐)

add 以 git+https 方式安装,pnpm 会运行本包的 prepare 脚本自动构建 lib/, 无需手动 pnpm build。

⚠️ pnpm 10 起会拦截依赖的构建脚本,必须先在 profile 的 pnpm-workspace.yaml (路径形如 ~/.dsh/profiles/<name>/pnpm-workspace.yaml)里放行;而放行键的写法 在 pnpm 10 与 pnpm 11 之间互不兼容,写错就装不上。

1. 先跑一次安装(这一次必然失败,为的是让 pnpm 打印它期望的键):

dsh plugin --profile <name> add "https://gitee.com/iJetLi/deepseek-harness-codearts.git"

2. 按第 1 步的报错选一种写法,写进 profile 的 pnpm-workspace.yaml。

报 ERR_PNPM_INVALID_VERSION_UNION 的(pnpm 10.x)—— 只认纯包名键:

allowBuilds:
  dsh-providers-hub: true

报 ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED 的(pnpm 11.x)—— git 托管包 不认纯包名键,必须用第 1 步 pnpm 打印的完整键(含 #<commit>):

allowBuilds:
  dsh-providers-hub@git+https://gitee.com/iJetLi/deepseek-harness-codearts.git#<第 1 步打印的 commit>: true

两代通用(省事,但放宽了权限):

dangerouslyAllowAllBuilds: true

它会放行该 profile 里所有依赖的构建脚本(不止本插件)。

3. 重跑第 1 步的命令:这次会拉取、构建并安装成功。之后每次升级重新 add 即可。

⚠️ 不要写 dsh-providers-hub@git+https://gitee.com/…(不带 #<commit>)—— 这个"看起来最自然"的键在两代 pnpm 上都不工作。

⚠️ pnpm 11.x 的精确键里带 commit,因此升级(重新 add 拉到新 commit)后该键 失效,按新报错里的键替换即可;用 dangerouslyAllowAllBuilds 则不必改。

方式二:从源码目录安装(本地开发)

先在本仓库中构建 lib/,再安装为 pnpm link: 依赖:

pnpm build:all
dsh plugin --profile <name> install <path-to-this-repo>

dsh plugin install 以 link: 方式安装,pnpm 不会为 link: 依赖运行 prepare 脚本,因此必须先手动执行 pnpm build:all 生成 lib/。 注意必须用 build:all 而非 build:后者只编译宿主侧,不产出 lib/client/jet-hub.js。

每次修改 src/ 或 plugin-src/ 后都需要重新执行 pnpm build:all —— dsh 启动时 不会自动重建。

通用说明

该包声明了 dsh.bundle 补丁(cordis.patch.yml),因此 profile 的 layer 栈会 自动拾取 codearts-auth 行。插件注入由 dsh base 提供的 credentials、 commands 和 llm 服务。


用法

登录入口:Jet Hub 设置页的对应 provider 面板。

⚠️ 不注册任何斜杠命令 —— 登录、状态查看、续期与积分领取统一在 Jet Hub 完成。

基本流程:

  1. 打开 Jet Hub 设置页(侧边 rail 选择要用的渠道);
  2. 点「+ 新建账号」→ 浏览器打开授权页 → 完成登录;
  3. 需要多个账号时重复第 2 步(账号池会自动选号);
  4. 回到 dsh 的模型选择器,选中该渠道的模型即可开始对话。

「+ 新建账号」是两步式的:先返回 loginUrl 由前端弹窗打开,后台再轮询换取 令牌 —— 这样不会阻塞浏览器手势窗口,弹窗不会被拦截。

账号卡片支持:测试 / 重测 / 重置 / 停用 / 代理 / 指纹 / 删除,以及拖拽排序 (顺序即选号优先级)。停用只影响自动选号,不影响凭据续期与积分领取。


支持的渠道

16 个 provider 路由,互不覆盖,可同时使用。

id渠道登录方式积分能力
codeartsCodeArts(华为云)浏览器回调余额 + 每日签到
buddyCodeBuddy(腾讯)浏览器授权 + 轮询余额 + 每日签到 + 成长任务 + 锁定永久积分
workbuddyWorkBuddy(国际版)同上余额 + 锁定永久积分(无签到)
lobsteraiLobsterAI(有道)浏览器回调余额 + 每日签到
qoderQoder(阿里系)设备码轮询余额 + 每日领取
qodercnQoder 中国版同上(共用实现)余额 + 每日领取
traeTRAE(字节跳动)浏览器回调余额 + 签到
clineClineWorkOS 设备码轮询余额
loomyLoomy(讯飞)短信验证码余额(两个池)+ 每日额度 + 新手任务
raccoonRaccoon Work(商汤)微信扫码 / 短信余额 + 一次性登录奖励
minimaxMiniMax Code(中国版)OAuth 设备码 + PKCE余额 + 每日签到
zcodeZCode(智谱 z.ai)OAuth 设备码余额 + 每日领取
opencodeOpenCode—余额
geminiGemini Code Assist浏览器回调余额
officeaceOfficeAce(华为 MaaS / 果办)华为云 OAuth PKCE余额 + 自动领取(无手动签到入口)
accioAccio(阿里)浏览器回调余额(三类桶;无签到)

各渠道的能力与限制要点:

  • 图片输入:buddy / workbuddy / trae(逐模型)/ minimax(部分模型)支持; lobsterai、zcode 不支持;accio 未实测(面板会明确报错而不是静默丢图); 其余以模型声明为准。
  • 思考档位:多数渠道支持,档位名按各渠道自己的定义下发;未声明的渠道不发送该字段。
  • loomy 是唯一用短信验证码登录、且不能自动续期的渠道。
  • zcode 的领取路径需要一次性验证参数,由本机浏览器环境产出(web 版需要 chromium,桌面版用自带内核)。 ⚠ 推理(对话)路径是否也要它,由服务端开关决定:官方 3.14.5 起 GET /api/v1/client/configs 会下发 captcha.skip_model_request —— 当前实测是 true(不校验,故按最省的方式「先探后取」: 不带验证头先发一发,被 3007 拒了才产);一旦服务端翻成 false, 插件会自动改为首发直接带上,不再白吃那发注定失败的往返 (判据是三态:缺席 = 不知道 = 保持先探,见 requiresCaptchaUpfront)。
  • qoder / qodercn 共用同一套实现,差异仅在产品配置。
  • minimax 是唯一的 Anthropic Messages 协议族渠道。
  • accio 登录走浏览器回调。⚠️ 新建账号时必须先选登录区域(中国版 www.accio-ai.com / 国际版 zh.accio.com):两个区域的登录页域名不同, 而区域由服务端按账号下发、登录前无法自动判断 ⇒ 选错会打开打不开的登录页, 登录不会成功。区域会写进凭据,续期与推理按它选域名。 ⚠️ 它没有签到按钮 —— 每日积分由服务端在登录时发放(24 小时有效、 不累积,未登录的那天不补),没有可调用的领取接口。面板上的积分按服务端下发的 三类桶(每日 / 每月 / 推荐)分列显示,并给出每日额度的重置倒计时。 ⚠️ 「刷新每日额度」入口尚未实现:它本质是重新登录既有账号, 需要宿主侧新增一条 RPC(现有的「+ 新建账号」每次都会新造账号,拿它重登只会 多出一个空账号而原账号额度不变)。当前要刷新请删除该账号后重新登录一次。 ⚠️ 模型倍率跨度极大(0.013 ~ 2.8,215 倍),故倍率直接写进模型展示名 (模型名 · x倍率),选型时看名字即可。 ⚠️ 图片输入未实测,面板会明确报「暂不支持图片输入」而不是静默丢掉。 ⚠️ 该渠道不产生限流标记(也不会被限流探针测出东西),故「重测 / 重置」这组 按钮对它整组不渲染 —— 渲染出来只会是点不动的死控件。

一键领取积分

在对应面板标题栏点「一键领取积分」,插件会顺序处理该面板下的所有账号 (顺序执行以避免并发请求),并逐账号显示结果与原因。

⚠️ 汇总按单位分列,不跨量纲求和 —— ZCode 的额度单位是 token、其余渠道是 积分,两者不可折算,因此显示成 +100.00MToken, +100积分 而不是加成一个数。

模型列表开关

每个 provider 的面板都有「显示列表」按钮,可逐个开关模型,控制它是否出现在 对话框的模型选择器里(黑名单制,默认全部显示)。开关按 provider 隔离。

锁定永久积分

buddy / workbuddy / loomy 提供「锁定永久积分」按钮,用来保住不会马上 作废的积分。判定规则:距扣费截止不足 15 天的算临时(优先消耗),其余算永久。 锁定后只消耗临时积分,用完则明确报错而不是偷偷烧掉永久积分。


聚合路由(aggregate)

同一个真实模型往往在多个渠道都能用(例如 DeepSeek V4.1 Flash 在 buddy、 codearts、cline 等都有)。聚合路由把「同一个真实模型」在各渠道的条目归到一个 规范名下,请求时自动挑一个渠道发出去。

解决什么:各家渠道送的免费额度有到期时间,用不完就作废。聚合层按 「最快作废的额度优先用」自动排序,把临期积分先烧掉。

怎么用:

  1. 在模型选择器里选 aggregate 分组;
  2. 想不挑模型就选该分组下的 auto —— 它用全部渠道的全部模型当候选池;
  3. 想指定模型就选该分组下的具体规范名(如 Deepseek-V4.1-Flash)。

选中后模型名旁会附一个 · <渠道> 后缀,那是首选渠道(临期最早的那个)。 ⚠️ 它不是「本次实际发往的渠道」 —— 真实历史由用量徽标显示。

自动切换:某个渠道失败时会换下一个候选重试,但只在还没吐出任何可见内容 时才切换(已输出的内容收不回来,拼接会产生畸形回答)。

参与轮换的渠道:buddy / workbuddy / loomy / codearts / zcode / lobsterai / trae 七家。其余渠道暂不参与(插件对它们的额度到期时刻没有 可靠信息,宁可少一个候选,不可把未知当可用)—— 它们仍可直连正常使用。

⚠️ zcode 的额度是「按模型」分桶的,故它的可用性是逐模型判定的: 赠送的 8M 实测分成 GLM-5.3 3M 与 GLM-5.3-Flash 5M 两个专属桶 (上游在余额接口里下发 capabilities: ["model:<模型>"])。某个模型烧光而另一个 还有额度时,只会把烧光的那个模型在该账号上标记为当日用尽 —— 另一个模型照常可用,不会因为「账号整体还有额度」而误派发到已尽的模型上。 若账号另有不限定模型的通用赠送额度(如 1 亿 token),且它还有余额, 则两个模型都仍可用(通用额度能承接它们)。

上下文窗口:聚合模型声明的是候选渠道里的最大值。同一个模型在 buddy / codearts 上都是 1M,那么 aggregate 下选它也声明 1M(与直连一致)。⚠️ 若某次 请求恰好被路由到窗口更小的候选,由失败切换兜住(上游报超长 ⇒ 换下一个候选)。

思考档位:声明各渠道档位的并集(官方中文名),默认 high —— 与你选的 档位会逐候选翻译到目标渠道(精确命中就原样下发,写法不同就就近落到同族, 目标没有这一族就不下发该字段让它走自己的默认)。

聚合有自己的设置面板(Jet Hub 左侧 rail 的「聚合」项),可逐条开关 「参与轮换」。它没有账号与凭据(复用各渠道的账号)。


本机 OpenAI 网关

插件启动后会在 127.0.0.1:8326 提供两套标准 OpenAI 接口,供 Pi、Continue、 Cline、OpenCode、Codex 或其他兼容客户端使用。网关复用 Jet Hub 已登录账号和现有 provider 适配器,不把上游凭据复制到客户端。

GET  http://127.0.0.1:8326/v1/models
GET  http://127.0.0.1:8326/v1/reasoning-efforts   ← 思考档位对照表
POST http://127.0.0.1:8326/v1/chat/completions    ← OpenAI Chat Completions
POST http://127.0.0.1:8326/v1/responses           ← OpenAI Responses API

⚠️ 两个端点同时可用,没有「格式开关」:客户端用哪一套协议,由它自己请求的 路径决定。

⚠️ 上面那两个地址里的 host 与端口都可被环境变量改掉 (DSH_OPENAI_GATEWAY_HOST / DSH_OPENAI_GATEWAY_PORT);设置页里的 「API 请求地址」显示的是实际监听地址,照它抄即可。

容器化部署(Docker / Compose)

默认只绑 127.0.0.1,因此端口映射对网关无效:容器里 curl 127.0.0.1:8326 能通只是假象,docker-proxy 与同网络的其它容器走的是容器桥接 IP(eth0), 那个地址上没有监听,于是宿主侧看到 Connection reset by peer (对照:Web 端口绑的是容器 IP,所以映射可用)。

修法是让网关绑容器自身的接口地址:

environment:
  - DSH_OPENAI_GATEWAY_ENABLED=1
  - DSH_OPENAI_GATEWAY_HOST=172.21.0.8   # 容器自身 IP:hostname -i 或 ip -4 addr show eth0
  - DSH_OPENAI_GATEWAY_PORT=8326
$ docker exec dsh ss -tlnp | grep 8326
LISTEN  172.21.0.8:8326     # 绑上桥接 IP 后,端口映射才可达

⚠️ 不许填 0.0.0.0 / :: 这类通配地址:会被显式拒绝并在启动前报错 (dsh 本体的 --host 也是同一姿态)。绑通配等于把网关暴露给整个网络, 真正的隔离只剩 API Key —— 而本网关承担的是「用你已登录的账号发请求」。 容器场景填容器自身 IP 即可。

⚠️ 暴露面不止「同一容器网络内的其它容器」,还包括宿主:经端口映射(-p) 或 bridge 网关,宿主本身就能连到该端口。跨 bridge 网络的容器才被隔离。 设置页里绑了非回环地址时会显示这条提示;不打算对外提供时请保持默认 127.0.0.1(或删除该环境变量)。

拿到地址与密钥

鉴权使用 Authorization: Bearer <网关 API Key>。

⚠️ 因此在浏览器地址栏直接打开这些地址会返回 401(没有带 Bearer 头)—— 这是预期行为,不是网关没启动。请用客户端或 curl 带上传头访问。

优先从 DSH_OPENAI_GATEWAY_API_KEY 读取;未设置时,插件首次启动会在 DSH home 的 openai-gateway/api-key 生成并持久化随机密钥,重启后保持不变。

设置页里的开关状态存在 $DSH_HOME/jet-hub/state.json 的 gatewayEnabled 字段 (缺省为启用)。它不进账号备份/恢复。

关闭网关

网关是旁路功能:它启动失败或被关闭,都不影响插件其余功能(登录、积分、模型 目录照常)。三种关闭方式:

方式做法
环境变量DSH_OPENAI_GATEWAY_ENABLED=0(完全不启动,连 API Key 文件都不生成)
设置页开关关掉后不再监听
改端口DSH_OPENAI_GATEWAY_PORT 填非法值会记录错误并跳过启动,不会静默改用其它端口
改地址DSH_OPENAI_GATEWAY_HOST 填通配地址(0.0.0.0 / ::)同样记录错误并跳过启动 —— 不会静默绑到全部网卡

请求体上限与 keep-alive

项值超限时的行为
请求体300 MiBHTTP 413 + invalid_request_error / request_too_large,响应体里带上限值
空闲连接(keep-alive)120 秒服务端发 FIN;此后复用该连接会得到 Connection reset

⚠️ 每轮把全量历史重新回传的客户端(Codex 等),历史里并入大截图后可能撞上 413: 新建会话、或删掉那条带大图的回合即可恢复。

安全边界

  • 默认只绑定 127.0.0.1,且拒绝通配地址(0.0.0.0 / ::)。 只有容器/端口映射这类「客户端不在同一网络命名空间」的场景才需要改 DSH_OPENAI_GATEWAY_HOST,且应填具体接口地址(如容器自身 IP)而不是通配。 ⚠️ 改了之后暴露面包含宿主(端口映射/bridge 网关都能连到), 同机与同容器网络的其它用户或进程也能连到该端口 —— 真正的隔离靠 API Key, 不要把它配置进任何浏览器端工具或扩展。
  • 密钥以明文写在 $DSH_HOME/openai-gateway/api-key。POSIX 下的 0600 权限在 Windows 上不生效,多用户机器请改用 DSH_OPENAI_GATEWAY_API_KEY 环境变量。

用量徽标与 Token 用量

用量徽标

会话输入区右侧、模型选择器左边有一枚薄胶囊,显示当前渠道一共有多少可用额度; 点开是完整浮层(逐账号明细 / 订阅窗口 / 刷新 / 签到 / 显示偏好)。 只在选中本插件渠道的模型时渲染,非本插件的模型不渲染、不发请求。

折叠态按 渠道 • 读数 两段显示,例如:

CodeBuddy (腾讯) • 2434.96积分
CodeArts (华为云) • 9499.84积分
ZCode (智谱) • 94.54MToken
  • 默认显示余额(一共能用的额度);可在浮层里切换成「优先订阅」或「只看积分」。
  • 多账号只显示一个数字(所有启用账号的余额合计),不会变成一长串。
  • 账号读不到时合计会静默少报,故胶囊会挂一个警示角标(441.78积分 ⚠)。
  • 浮层里逐账号列表按余额降序,超过 5 个折叠成「展开其余 N 个」。

Token 用量

点 Jet Hub 页头的「Token 用量」按钮查看。数据分两份:

数据位置回答的问题重启后
实时明细 + 汇总树进程内存(上限 500 条)每一笔长什么样、这次会话花了多少清空
历史日聚合~/.dsh/jet-hub/token-ledger.json本周 / 本月用了多少保留(按 UTC+8 日界,90 天)

在历史图表中点选某一天并展开,可删除该日的历史累计。删除前会二次确认,只移除该日聚合,不影响实时明细、其他日期或账号设置;之后该日的新请求会重新累计。

  • 计数是 wire 口径:上游 usage 报什么记什么,不做本地估算。
  • 总处理量 = 未命中缓存输入 + 缓存命中输入 + 输出;输出已含思考 token,缓存写入另列且不重复计入。不同渠道价格不同,因此这里不把 token 数冒充账单金额。
  • 没收到 usage(失败 / 中断)显示 —,与真实的 0 严格区分。
  • 输出速率(tok/s)的分子含思考 token;汇总显示算术均值及完整样本的 P50/P90 估值。
  • 日聚合文件升级到 schema v2 增加 TPS 对数直方图;旧 v1 数据照常读取(计数全保留)。⚠️ 升级前已累计过「输出速率样本」的日期不会显示 P50/P90 —— 判据要求「直方图样本数 = 累计样本数」,而旧桶的 tpsCount 在升级前就已累加、直方图为空,两者之差恒定 ⇒ 该日期在 90 天保留期内一直无分位数(avgTps 均值仍照常显示)。完全在 v2 之后累计满样本的日期正常显示;升级前存在但从未有过速率样本的日期(如当天全是失败请求)也会正常显示。

配置项

项位置说明
账号池$DSH_HOME/jet-hub/state.json账号、有效期、限流标记、模型黑名单、provider 顺序
网关开关同上,gatewayEnabled缺省启用
供应商显示顺序同上,providerOrder纯展示偏好,拖动行调整
永久积分锁定$DSH_HOME/jet-hub/*.json(独立文档)不与账号池同放 —— 避免多 profile 互相覆盖
Token 账本~/.dsh/jet-hub/token-ledger.json历史日聚合

常见环境变量

变量默认说明
DSH_HIDE_MODELS_WITHOUT_ACCOUNT关闭设为真值时,没有已登录账号的渠道在模型选择器里整体隐藏
DSH_OPENAI_GATEWAY_ENABLED1设为 0 / false / off / no 时完全不启动网关
DSH_OPENAI_GATEWAY_HOST127.0.0.1网关监听地址。容器/端口映射场景填容器自身 IP(hostname -i);填 0.0.0.0 / :: 等通配地址会被拒绝并跳过启动
DSH_OPENAI_GATEWAY_PORT8326网关监听端口
DSH_OPENAI_GATEWAY_API_KEY自动生成网关 Bearer 密钥
DSH_REASONING_LOOP_GUARD开启思考死循环守卫总开关
DSH_REASONING_LOOP_AUTO_RESUME开启中止后是否自动补一句「继续」并重跑
DSH_REASONING_LOOP_AUTO_RESUME_MAX2连续自动续跑上限(最大 10)
DSH_TRAE_MAX_COMPLETION_TOKENS64000TRAE 单次输出上限(设 0 关闭收敛)

更多 provider 专属变量(如 DSH_ZCODE_INTERNAL_CARRIER、 DSH_TRAE_ROTATE_MACHINE_ID 等)见内部文档。


账号备份与迁移

Jet Hub 设置页底部的备份区提供导出 / 导入,用于两种情况:换 DSH 版本时整体迁移, 以及从别处单独搬一个账号进来。

备份文件是自包含的 JSON(账号索引 + 凭据原文 + 模型黑名单 + 永久积分锁定表), 与 DSH 版本无关 —— 导入时按当前版本的存储契约重建,因此天然跨版本。

  • 加密在浏览器侧完成(PBKDF2 + AES-GCM),RPC 只收发明文载荷,明文与口令 都不经过宿主持久化与日志。可选加密,不勾选即导出明文。
  • 账号凭据、refresh_token 都在文件里,等同于明文密钥,请自行妥善保管。
  • ⚠️ 不含的就是本机偏好:备份只搬账号与凭据,不搬本机 OpenAI 网关开关、 用量徽标偏好、自动签到记账等本机状态(导入时它们保持当前值,不会被备份覆盖)。 账号条目上的字段(含 OpenCode 的 opencodeProxy / 指纹代次)则原样随快照往返。

导出:可以只导出选中的账号

导出弹窗列出当前账号池并可逐个勾选(backup.export 的 accountIds), 默认「全部账号」。只导一个账号时文件名会带上该账号 id(dsh-codearts-backup-buddy-xxxx-日期.json), 避免被误当成整份备份收着。

⚠️ 过滤只作用于 accounts 与 credentials 两个字段:模型黑名单与永久积分锁定表 仍按全量写出。这样「只导一个账号」的产物依旧是一份可整体还原的自包含快照 —— 让过滤只承担一种语义,两条路径就不会互相污染。

导入:两种模式(replace / merge)

模式语义用于
replace(默认)整体替换账号池与模型黑名单,还原快照「恢复」按钮、换 DSH 版本后整体迁移
merge只追加:已存在的账号一律跳过,不碰模型黑名单与锁定表「单独导入一个账号」、从别人的备份里挑账号

导入弹窗可勾选要落地哪些账号,并选择模式。

⚠️ merge 下裁剪发生在发请求之前(plugin-src/client/backup-payload.js)。 判重虽然在后端,但后端只知道「这份载荷里有哪些账号」,不知道用户勾了哪几个; 不先裁剪的话,从整份备份里只勾一个账号,其余账号仍会被追加,更糟的是备份里那些 不在勾选范围内的 credentialRef 可能已被本机现有账号占用,写进去等于 覆盖现有账号的凭据,与「只增加不覆盖」的承诺相反。故裁剪必须同时裁掉 accounts、credentials 与 disabledModels 三处。

⚠️ 合并导入判重的三层口径(缺一层就会堆出重复账号)

src/backup.ts 的 importBackup({ mode: 'merge' }) 依次判:

  1. 池里已有的 id —— 账号的唯一键;
  2. 池里已有的身份(provider: + 凭据里的身份字段,见下表);
  3. 备份文件内部重复的 id —— 同一份文件手工编辑后可能出现两条同 id。

⚠️ 只按 id 判重是不够的,第 2 层才是关键:插件自己登录时 id 由 shortId() 随机生成(buddy-a1b2c3d4),而从第三方文件转换来的 id 是确定性哈希 (见下节)。同一个人因此有两套 id,只比 id 会把他重复加进池里 —— 而用户在 「从别人的备份里挑账号」时,最常见的情形恰恰是「这个号我已经手登过了」。

⚠️ 身份字段逐 provider 对齐(漏一个字段,那个 provider 的「同一个号我已手登过」 场景就必然多一条重复账号):

字段哪些 provider 的凭据里有
user_idCodeBuddy / WorkBuddy / LobsterAI / Raccoon / ZCode
uidQoder(含中国版)/ TRAE
useridLoomy
account_idCline / MiniMax
subGemini(OIDC sub;不取 email —— 它会随改邮箱而变)
api_keyOpenCode(仅账号槽)

⚠️ Gemini 只认 sub,不认 email:两者都在它的凭据里,但 sub 是 OIDC 的 稳定主体标识(换邮箱、改昵称都不变,上游就拿它当账号 id),而 email 会随用户 改邮箱而变 —— 拿它判重会让同一个账号在改邮箱后多出一条重复账号。

⚠️ OpenCode 的匿名通道要排除:它的凭据只有 api_key,而匿名通道的 api_key 恒为字面量 public —— 全部匿名槽共用一个值。若拿它当身份,用户刻意添加的 第二条匿名通道会被判成「已存在」而拒绝导入(「多条匿名通道各走各的出口」 是上游明确提供的能力)。故匿名槽不产生身份,退回按 id 判重。

⚠️ 轮换令牌(access_token / refresh_token)不能当身份:它们每次续期都会变, 拿来判重会让续期后的同一账号被判成新账号。

⚠️ id 与身份都可能判不出来:凭据缺失/损坏时按「无法判断」跳过该条, 不让一次判重失败阻断整体导入。

⚠️ 第三方账号列表可以直接导入(自动转换)

很多用户手上的是别的工具(账号池 / 卡号池脚本、IDE 本地缓存导出)产生的 CodeBuddy 账号列表,而不是本插件备份。两者结构完全不同:

第三方账号列表本插件备份
顶层裸数组 [ {...} ](或 { accounts / data / items / list: [...] })对象 { format, version, ... }
格式标记无format: 'dsh-codearts-auth/backup'
凭据账号对象里直接带 access_token / refresh_token独立 credentials 字典(ref → 凭据 JSON 原文字符串)
账号索引id 是 uid 或工具自己的编号accounts[],id 形如 buddy-a1b2c3d4

直接把它丢给「恢复」只会得到「该备份文件里没有账号」—— 因为取不到 accounts。 故选中这类文件时会自动识别并转换(plugin-src/client/backup-convert.js), 转换结果显示在弹窗里供核对,并默认落到 merge 模式(别人的新号,避免误覆盖本机账号)。

⚠️ 转换只改结构,不改写令牌:access_token / refresh_token 原样搬运。 其余字段以「本机一个真实可用的 CodeBuddy 凭据」为基准对齐:

字段来源
expires_at原值(毫秒时间戳),统一成字符串毫秒
refresh_expires_at优先 auth_raw 的 refreshExpiresIn - expiresIn 差值补算,退回 refresh_token 的 JWT exp
domainaccess_token 的 JWT iss 主机名(它会被当作 X-Domain 头发出去)
user_idaccess_token 的 JWT sub
token_type / account_type原值,缺省 Bearer / personal
enterprise_id缺省 ''(个人版为空串,与真实凭据一致)

⚠️ provider 按 JWT iss 的主机名分派:含 workbuddy → 国际版,否则 → buddy。 两套 provider 是不同路由,认错会让凭据发到错误的端点。

⚠️ 账号 id 由 uid 经 FNV-1a 哈希确定性生成(stableShortId),与插件自己登录 生成的形式一致。这样同一份文件导入两次,第二次会全部被判为「已存在」而跳过, 而不是堆出两份账号。但 id 判重挡不住「同一个人的账号已用随机 id 登录在本机」—— 那正是靠上文第 2 层的身份字段判重。

⚠️ 不写 scope:真实凭据里有它,但插件从不读取 scope 发请求 (只在续期时原样带回),而第三方文件里也没有 —— 与其猜一个可能不准的值,不如省略。

⚠️ 合并导入只写「真正要新增的账号」的凭据

merge 模式下绝不回写备份里其余凭据(含各 provider 的默认单凭据 ref)。 replace 模式才按字典逐条写入 —— 备份文件里可能含账号池之外的独立凭据 ref, 导出时一并纳入,导入时同样还原。

⚠️ 写入顺序是先凭据、后账号池:账号池写入成功后门控(hasLoggedInAccount) 与黑名单立即反映新状态;凭据写入中途失败(非法 ref 等)只跳过该条、不中断整体。

⚠️ 模式必须取白名单(req?.mode === 'merge' ? 'merge' : 'replace'), 不能把请求里的任意字符串透传下去:未知值会被 ?? 'replace' 静默当成整体替换 —— 那时用户以为只是「加一个账号」,实际账号池被清空,属于不可逆的数据损失。

测试

  • tests/unit/backup.spec.ts(44 条)—— 选择性导出、合并导入三层判重、 merge 不回写其余凭据、replace 兼容旧行为、各 provider 的身份字段覆盖度;
  • tests/unit/backup-payload.spec.ts(13 条)—— 载荷裁剪与账号摘要;
  • tests/unit/backup-convert.spec.ts(28 条)—— 第三方列表识别与转换;
  • tests/unit/account-pool.spec.ts 的 mergeAccounts 段(6 条)—— 只追加、 不改黑名单与锁定、坏条目归一化、文件内重复 id。

⚠️ 与上游同步(2026-10-02)

本章功能已随上游 62 个提交(新增 OpenCode provider、本机 OpenAI 网关、用量徽标、 自动签到、供应商开关)重新落地:只有 plugin-src/client/jet-hub.js 的 import 块 需要手工合并,BackupPanel 与 src/backup.ts 上游未改动。唯一的适配点是 OpenCode 的身份字段(见上表与匿名槽说明)。细节与反向验证记录见 AGENTS.md 的「上游同步记录」一节。

⚠️ 已做反向验证(2026-09-30):禁用身份判重 → 1 条变红;让 merge 回写全部 凭据 → 3 条变红;mergeAccounts 去掉文件内去重 → 1 条变红。

开发

pnpm test          # 单元测试(快速,无网络,全部 mock)
pnpm typecheck     # 只做类型检查
pnpm build:all     # 完整构建(宿主 tsc + 资源拷贝 + 客户端 esbuild)

构建

  • pnpm build — 用 tsc 将 src/ 编译到 lib/。插件宿主侧入口是 lib/index.js。
  • pnpm build:client — 用 esbuild 将 plugin-src/client/ 打包为 lib/client/jet-hub.js(Jet Hub 设置页的客户端 bundle)。
  • pnpm build:all — 依次执行上述步骤,是完整的构建。
  • pnpm typecheck — 只做类型检查,不产出文件。

lib/ 已被 gitignore,因此构建是安装或运行前的必需步骤。

E2E 测试

E2E 探针按 provider 分列(如 pnpm test:e2e:codearts、pnpm test:e2e:buddy、 pnpm test:e2e:loomy),均有闸门、默认全部跳过 —— 需要显式设置对应环境变量 (部分还需 ..._CONFIRM=yes)才会真正发出请求。详见 tests/e2e/README.md。

⚠️ 带 -claim / -chat / -tools 后缀的探针会真实消耗额度或领取机会; 带 -refresh 后缀的会真实轮换一次凭据(如 accio-refresh)。运行前请确认。

项目结构

路径说明
src/TypeScript 源码(宿主侧)
plugin-src/client/Jet Hub 客户端源码(esbuild 打包)
lib/编译产物(已 gitignore)
tests/unit/单元测试
tests/e2e/端到端测试(默认跳过)
docs/agent-notes/逐 provider 的事故史与约定(开发向)
docs/implementation-notes.md全部实现细节与协议笔记(不入库)。⚠️ 目前没有 accio 章节 —— accio 的实测笔记在 docs/agent-notes/providers-accio.md,补写该章节是独立任务
cordis.patch.ymlDSH bundle 补丁