wenzetan/dsh-quota-panel

wenzetan/dsh-quota-panel

右下角额度胶囊:自动发现所有已配置 Key 的供应商(DeepSeek、OpenRouter、SiliconFlow、GLM、one-api/new-api、各类 Coding 套餐),显示余额或 5 小时/周滚动用量,支持按供应商设置可见性、告警阈值与代理;另支持火山方舟 Agent Plan / Coding Plan 用量查询(AK/SK 签名 OpenAPI)与 ChatGPT Plus/Pro 订阅用量(插件内设备码登录,或读取 Codex CLI 登录态)。

用量与计费balancedeepseek-harnessquota

dsh-quota-panel

English | 中文

dsh-quota-panel 是 DeepSeek Harness(DSH)网页端(dsh web)的供应商额度/余额状态组件。 它驻留在产品界面右下角,监控你配置过 API Key 的每一个 AI 供应商, 一眼看清还剩多少余额/额度——DeepSeek、OpenRouter、SiliconFlow、Moonshot、 StepFun、xAI、智谱 GLM、OpenCode Go、火山方舟(Agent/Coding Plan),one-api / new-api 风格的聚合站, 以及各家 Coding Plan(智谱 GLM Coding、Z.AI、Kimi Coding、MiniMax Coding 国际/国内):5 小时窗口、周配额与 MCP 月度额度一目了然。 StepFun、xAI、智谱 GLM、OpenCode Go、ChatGPT 订阅(Plus/Pro,经 Codex 登录), one-api / new-api 风格的聚合站,以及各家 Coding Plan(智谱 GLM Coding、Z.AI、 Kimi Coding、MiniMax Coding 国际/国内、火山方舟 Agent/Coding Plan):5 小时窗口、 周配额与 MCP 月度额度一目了然。

v0.5 起为双面插件 + 内置供应商目录自动发现:安装并重启 dsh web 后, 凡是 key 能解析的供应商都会自动出现在面板上——零配置。 它零 npm 依赖,也不需要 allowBuilds 构建授权。

效果图(真实浏览器渲染)

收起胶囊,浅色:

胶囊(浅色)

展开卡片,浅色:

展开(浅色)

设置面板(⚙),浅色:

设置(浅色)

收起胶囊,深色:

胶囊(深色)

展开卡片,深色:

展开(深色)

设置面板(⚙),深色:

设置(深色)

支持的功能

  • 自动发现 —— 宿主侧内置常见供应商目录,每项声明该供应商标准的 credential 引用名;key 能解析($DSH_HOME/.credentials.yaml / .env / 环境变量)的供应商 自动出现在面板上,零配置;删除 key 行即消失。DSH 没有凭据枚举 API, 因此每个刷新周期都会探测一次目录。
  • 两种尺寸 —— 收起:极简胶囊,每个账户一个「独立状态点 + 数值」对 (● ¥58.36 · ● 45%);展开:完整卡片,每个供应商一行(状态点、名称、主数值、 次级信息,用量型供应商还有进度条)。
  • 自动刷新 —— 跟随配置间隔(默认 60 秒),页面隐藏时暂停;刷新按钮请求期间旋转, 重复点击不会触发并发请求。
  • 逐账户状态 —— 余额行按分级阈值(critical <= warn <= healthy), 用量行按百分比(error >= warn);只有异常的点和数值变色,其余保持平静。 用量百分比使用手机电量式三色着色,与状态点独立。
  • 设置面板(⚙) —— 逐供应商显示开关、刷新间隔、逐供应商预警阈值、 逐供应商 HTTP(S) 代理 URL、胶囊显示模式(自动 = 最高窗口(默认)/ 5h 窗口 / 周窗口 / 最高窗口)、「恢复默认」。全部本地设置即时生效, 保存在浏览器 localStorage,绝不写入 profile 或上传。
  • 按行 HTTP(S) 代理 —— 为无法直连的供应商配置代理(见下)。
  • Coding Plan 用量窗口 —— 智谱 / Z.AI / Kimi / MiniMax 套餐渲染为用量行: 5 小时窗口、周配额与(GLM/Z.AI)MCP 月度车道,各带重置倒计时; 套餐没有的窗口显示 —,绝不伪造 0%。
  • one-api / new-api 聚合站 —— 内置 openai-billing 格式适配聚合站仪表盘。
  • 主题跟随 —— 完全使用 Harness 设计 Token(--dsw-alias-*、--dsw-static-*、 --dsw-shadow-*、--dsw-font-*)驱动,token 缺失时有合理 fallback, 自动跟随产品主题(浅色/深色),不携带自己的配色。
  • 构架即安全 —— API Key 绝不进入浏览器;浏览器只与本插件在 DSH 自带 /api 鉴权通道(受信任主机 + 浏览器会话围栏)中的方法通信,只接收归一化视图(见「实现逻辑」)。

不支持的功能(规划中)

  • usage-only 供应商 —— OpenAI、Anthropic、Together、Groq、Mistral、Cohere、 DashScope、百川没有公开的「剩余余额」接口,只有 usage/cost 类查询 (通常需要 admin key 与时间窗参数,语义是「已花多少」而非「还剩多少」)。 计划作为独立的 usage 型行接入,显示月度花费(首选 Anthropic Admin API 与 OpenAI usage API)。
  • 仅 Cookie / CLI 的 Coding Plan —— 通义 Token Plan(百炼控制台)、小米 MiMo Token Plan 与 Qoder 的配额页没有 API-key 查询端点:需要网页 Cookie、 arkcli 命令行或聊天接口限频探测(依据 CodexBar 的调研)。 火山方舟(豆包)的 Agent Plan / Coding Plan 已通过 AK/SK OpenAPI 接入(见上表)。 本插件其余供应商只使用 API key/Bearer 认证。
  • socks5 代理 —— 仅接受 HTTP/HTTPS 代理(socks URL 会被拒绝并给出清晰的单行错误)。
  • 自定义适配器 —— 无法从 profile 扩展新的上游格式;format 值超出内置集合时 在挂载时 fail loud。
  • 多位置挂载 —— 组件只存在于 shell.overlay 槽位(右下角), 不支持侧边栏、顶栏或状态栏位置。

申请新增供应商

缺少你想监控的供应商?欢迎提 issue,附上:

  1. provider id(^[a-z0-9-]+$,如 together);双站点供应商的国内站用 -cn 后缀(参考 siliconflow / siliconflow-cn);
  2. 获取余额的 API URL —— 用该供应商的标准 API key 即可查询剩余 余额/额度的公开端点(如 GET https://api.provider.com/v1/user/info, Bearer 认证);能贴一段响应 JSON 结构更好。

目录接入只需要这些:一个标准凭据引用可解析的 id、一个端点、一个响应 格式适配器。只有 Cookie/CLI 配额页的供应商(见上)在官方提供 API-key 端点前无法支持。

实现逻辑

┌─────────────── browser (lib/client.js) ───────────────┐
│  shell.overlay 槽位 → 胶囊 / 卡片 / 设置面板           │
│  localStorage: 显示开关 · 间隔 · 阈值 ·               │
│                代理 URL(前端设置)                   │
└──────────────┬─────────────────────────────────────────┘
               │ Connection /api 通道(浏览器会话围栏):
               │   POST /api/dsh-quota-panel/specs(渲染提示)
               │   POST /api/dsh-quota-panel/fetch-all { proxy }
┌──────────────▼────────────── host (lib/index.js) ──────┐
│  ctx.credentials → API Key(绝不离开宿主)              │
│  目录探测 → 自动发现(15 个内置供应商)                 │
│  逐行请求 → 代理引擎(CONNECT 隧道 / 绝对 URI)→ 上游 JSON │
│  归一化 → {balance | usage | info} 视图模型            │
└─────────────────────────────────────────────────────────┘
  • 宿主侧(lib/index.js)注册一条仅限回环的 Connection RPC 通道 /dsh-quota-panel,两个端点:
    • specs —— 解析后的行,只含渲染提示(id、label、行类型、货币、阈值分级、 窗口标签、已配置的代理名)。不含凭据,不含 endpoint。
    • fetch-all —— 拉取每个可见行,把上游响应归一化为通用视图模型 (balance / usage / info),返回 {rows: [{id, view} | {id, error}], fetchedAt}。 上游原始 JSON 与 key 一样留在宿主侧;单行失败不影响其他行。
  • 自动发现 —— DSH 的凭据库没有枚举 API,因此宿主侧在每个刷新周期探测目录项 的标准引用名;key 能解析的条目加入面板,解析不到的跳过(只有通过 providers 显式配置的行,key 缺失才会给出清晰的单行错误)。
  • 代理引擎 —— 零依赖手写 proxiedGetJson:https 目标走 HTTP CONNECT 隧道 (TLS over 隧道),http 目标走绝对 URI 转发。每行独立 15 秒超时、1 MB 响应上限。 代理选择优先级:前端设置面板 > profile 配置 > 直连。
  • 阈值判断发生在客户端 —— 基于 specs 提示,因此本地阈值覆盖无需重新拉取; profile 阈值随 specs 下发,前端设置在其之上本地覆盖。
  • 配置校验 —— 导出的 Config schema(vendor 的 schemastery)声明结构与默认值; 跨字段约束(id 唯一、critical <= warn <= healthy、代理引用存在、catalog 覆盖键合法) 由宿主侧在挂载时校验,失败即报错(fail loud)。
  • DOM 安全 —— 卡片只用 createElement/textContent 构建 DOM,API 返回值绝不 经过 innerHTML;技术错误(401、超时、凭据缺失、代理拒绝)只写入 title 悬停提示 或行内错误文案。
  • 代理故障绝不会带崩宿主 —— 代理引擎打开的每个 socket 与请求都会把 error 事件汇入该行结果,因此代理不可达(例如 clash 没开、ECONNREFUSED 127.0.0.1:7890) 只显示为该行的错误,而不是未处理的 EventEmitter error。

需要的配置

开箱即用:什么都不用配。 安装、重启,key 能解析的供应商自动出现。 下表只用于调优。

所有键都可选——结构与默认值在导出的 Config schema 里,profile patch 可省略一切 带默认值的字段。

键含义默认值
auto探测内置目录,key 已配置的供应商自动上板true
hide要隐藏的行 id 列表(目录行与显式行都生效)[]
proxies代理定义 {<名称>: "http://host:port"},仅 HTTP(S){}
catalog对自动行的局部覆盖 {<目录id>: {...}}{}
refreshMs自动刷新间隔60000
providers显式行;同 id 整体替换目录行[]

catalog 每项可覆盖:label / endpoint / format / proxy / refs(探测的 credential 引用名,UPPER_SNAKE)/ secretRefs(第二凭据引用,火山方舟 AK/SK 场景使用, 必须与 refs 同时可解析才上板)/ region(火山方舟 OpenAPI 区域,默认 cn-beijing)/ currency(余额行:币种符号,如 $、US$)/ balanceTiers / warnPercent / errorPercent / windowLabels。

显式 providers 字段:

字段含义默认值
id行标识(RPC 行按 id 对齐),^[a-z0-9-]+$必填
label卡片上的提供方名称必填
credential凭据引用($DSH_HOME/.credentials.yaml 或环境变量)必填
secretCredential第二凭据引用(火山方舟 volcengine-agent-usage / volcengine-coding-usage 需要:SK)—
endpoint额度 JSON 接口;openai-billing 格式时为聚合站 base URL必填
format行适配器(见下表)deepseek-balance
proxyproxies 中定义的代理名;缺省直连—
region(volcengine-agent-usage / volcengine-coding-usage)OpenAPI 区域,默认 cn-beijingcn-beijing
currency(余额型)币种符号,覆盖 format 默认值format 默认
balanceTiers(余额型){critical, warn, healthy} 分级阈值{10, 20, 50}
lowBalance旧版别名,等价于 balanceTiers.warn—
windowLabels(usage 类格式)用量窗口的标签{滚, 周, 月}
warnPercent / errorPercent(用量型)阈值70 / 90

内置供应商目录(自动发现)

供应商探测的 credential 引用查询端点行类型
DeepSeekDEEPSEEK_API_KEYapi.deepseek.com/user/balance¥余额
OpenRouterOPENROUTER_API_KEYopenrouter.ai/api/v1/credits$余额(购入 − 已用)
SiliconFlow(国际)SILICONFLOW_API_KEYapi.siliconflow.com/v1/user/info$余额
SiliconFlow(国内)SILICONFLOW_CN_API_KEYapi.siliconflow.cn/v1/user/info¥余额
Moonshot / KimiMOONSHOT_API_KEYapi.moonshot.cn/v1/users/me/balance¥余额
MiniMax Coding(国际)MINIMAX_API_KEYwww.minimax.io/v1/token_plan/remains5h + 周提示词用量%
MiniMax Coding(国内)MINIMAX_CN_API_KEYapi.minimaxi.com/v1/token_plan/remains5h + 周提示词用量%
StepFun 阶跃STEP_API_KEY / STEPFUN_API_KEYapi.stepfun.com/v1/accounts¥余额(悬停看现金/赠金)
xAIXAI_API_KEYapi.x.ai/v1/billing/credits$余额
智谱 GLMZHIPU_API_KEY / GLM_API_KEYopen.bigmodel.cn/api/monitor/usage/quota/limit文本行(配额剩余/总数;智谱无公开余额接口)
智谱 GLM CodingZAI_CODING_CN_API_KEYopen.bigmodel.cn/api/monitor/usage/quota/limit套餐窗口(5h tokens / 周 / MCP 月度)
Z.AI GLM CodingZAI_API_KEYapi.z.ai/api/monitor/usage/quota/limit套餐窗口(5h tokens / 周 / MCP 月度)
Kimi CodingKIMI_API_KEYapi.kimi.com/coding/v1/usages用量%(5h 限频 + 周请求池)
OpenCode GoOPENCODE_GO_API_KEYopencode.ai/zen/go/v1/usage三窗口用量%
火山方舟 Agent PlanVOLC_ACCESS_KEY + VOLC_SECRET_KEYopen.volcengineapi.com(OpenAPI 签名)用量%(5h / 周 / 月,GetAFPUsage)
火山方舟 Coding PlanVOLC_ACCESS_KEY + VOLC_SECRET_KEYopen.volcengineapi.com(OpenAPI 签名)用量%(会话 / 周 / 月,GetCodingPlanUsage)

火山方舟有 Agent Plan 和 Coding Plan 两个相互独立的套餐,插件把它们作为两行同时显示(就像两个供应商),共享同一对 AK/SK:每行只查询自己的套餐接口,互不回落——未订阅的那个套餐会显示一行「未订阅」提示,而不是显示另一个套餐的数字。火山方舟使用两组凭据(AccessKey ID + SecretAccessKey)做 HMAC-SHA256 签名,不是 Bearer Token;推理用的 ARK_API_KEY(形如 ark-...)不能用于此查询,只有 AK/SK 有 OpenAPI 权限。完整接入步骤见下一节。

火山方舟(Volcengine Ark)接入教程

火山方舟的 Agent Plan / Coding Plan 用量通过控制面 OpenAPI 查询,需要一对带只读权限的 AK/SK。配置只需要三步:

1. 创建 AccessKey

打开 https://console.volcengine.com/iam/keymanage(火山引擎控制台 → 访问控制 → 访问密钥),点「新建访问密钥」。建议为这个用途单独创建一对子用户密钥而不是主账号密钥;完成后把 AccessKey ID 和 SecretAccessKey 保存好(SecretAccessKey 只在创建时显示一次)。

2. 授予方舟只读权限

在密钥所属的子用户(或角色)上挂 ArkReadOnlyAccess 策略:

  • 进入 访问控制 → 用户,找到该子用户,点「权限」→「添加权限」;
  • 在「搜索策略名和备注」输入框里输入 ArkReadOnlyAccess;
  • 结果里服务来源为「火山方舟」的那一条就是所需策略,勾上它即可(搜索结果中同名策略只有两条,都勾上也不会有副作用)。

只挂 ArkReadOnlyAccess 即可——GetAFPUsage / GetCodingPlanUsage 都是只读动作,不需要 ArkFullAccess 或账户级计费权限。

3. 写入凭据文件

在 $DSH_HOME/.credentials.yaml(默认 C:\Users\<你>\.dsh\.credentials.yaml 或 ~/.dsh/.credentials.yaml)加两行:

VOLC_ACCESS_KEY: AKLTxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
VOLC_SECRET_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

或者用环境变量 VOLC_ACCESS_KEY / VOLC_SECRET_KEY(DSH 凭据解析支持环境变量回退)。重启 dsh web 后,右下角面板会自动出现「Volcengine Agent」和「Volcengine Coding」两行(订阅了哪个套餐,哪一行就有数据;两行共享同一对 AK/SK),无需在插件配置里加 providers:。

怎么验证权限是否正确

重启后看面板:

  • Agent 行出现 5h / 周 / 月三条百分比、Coding 行出现会话 / 周 / 月三条 → AK/SK 与 ArkReadOnlyAccess 都生效(只订阅了其中一个套餐时,另一个套餐那一行会显示「未订阅」提示);
  • 显示 volcengine SignatureDoesNotMatch: ... → SK 复制错了(注意尾部的 =);
  • 显示 volcengine AccessDenied: ... → 策略没挂上或挂错了来源;
  • 显示 No active Volcengine Ark Agent/Coding Plan subscription → 签名通过但该账号没有订阅对应套餐(按量付费账号就会这样;两行各自独立提示,可在 ⚙ 设置里隐藏未订阅的那一行)。

迁移说明(≤ 0.9.1,仅影响手动固定过旧行的用户): 原来的单一目录行 id volcengine 与 format id volcengine-usage 已被替换为 volcengine-agent (volcengine-agent-usage)与 volcengine-coding(volcengine-coding-usage)。 走自动发现的用户无需任何改动;若你的配置里手写过引用旧 id 的 catalog: 覆盖或 providers: 条目,插件会校验失败并拒绝加载(错误信息会列出全部合法 id)—— 把旧 id 改成两个新 id 即可。

安全建议:AK/SK 一旦泄露他人可以读你方舟账号的所有用量数据,贴到聊天/工单/截图前先打码;不再用时去 密钥管理页 禁用并轮换。 | ChatGPT 订阅(Plus/Pro) | 插件内登录 或 ~/.codex/auth.json(无需 API Key) | chatgpt.com/backend-api/wham/usage | 周用量%(Pro 含 5h 窗口) |

另内置 openai-billing 格式,适配 one-api / new-api 等聚合站:endpoint 配 聚合站 base URL,宿主侧请求 {base}/v1/dashboard/billing/subscription (hard_limit_usd)与 {base}/v1/dashboard/billing/usage(total_usage); 剩余 = 上限 − 已用($)。聚合站域名各不相同,因此只支持显式配置行。

双站点 provider id(自定义 id → 站点映射)

部分供应商同时运营国际站与国内站,端点、凭据引用和币种各不相同。 目录把每个站点建模为独立的 provider id:配置对应 key 即自动上板; 显式 providers: 里复用这些 id 之一会整体替换目录行(同样的字段, 换成你的 endpoint/label/currency):

provider id站点查询端点credential 引用币种
siliconflowSiliconFlow 国际api.siliconflow.com/v1/user/infoSILICONFLOW_API_KEY$
siliconflow-cnSiliconFlow 国内api.siliconflow.cn/v1/user/infoSILICONFLOW_CN_API_KEY¥
minimaxMiniMax Coding 国际www.minimax.io/v1/token_plan/remainsMINIMAX_API_KEY—(用量%)
minimax-cnMiniMax Coding 国内api.minimaxi.com/v1/token_plan/remainsMINIMAX_CN_API_KEY—(用量%)
zaiZ.AI GLM Coding 国际api.z.ai/api/monitor/usage/quota/limitZAI_API_KEY—(用量%)
zai-coding-cn智谱 GLM Coding 国内open.bigmodel.cn/api/monitor/usage/quota/limitZAI_CODING_CN_API_KEY—(用量%)

同一供应商的两个站点可以同时在板(两个 key 都配置即可); hide: ["siliconflow"] 可单独隐藏某一行。

余额行的币种符号默认来自 format(siliconflow-balance 默认 ¥), 可按行覆盖:目录行自带 currency(SiliconFlow 国际行设为 $), catalog: 覆盖可设置,显式 providers: 条目接受 currency 字段 (如 "US$")。

ChatGPT 订阅(Plus/Pro)接入

ChatGPT 订阅用量不是 API 计费,没有公开的余额/用量 API。本插件通过 ChatGPT OAuth 令牌调用 Codex 同款的内部用量端点,把 Plus/Pro 套餐的周窗口 (及 Pro 的 5 小时窗口)已用百分比显示在面板上。支持两种登录方式, 任选其一:

⚠️ 实验性(experimental):该端点(chatgpt.com/backend-api/wham/usage) 是 Codex CLI 内部使用的未公开接口,响应字段可能随官方调整而变化。本插件 只做只读查询。

方式 A:插件内登录(推荐,无需安装 Codex CLI)

  1. 重启 dsh web,打开右下角面板的设置(齿轮图标);
  2. 在最上方「ChatGPT 账号」一栏点「登录 ChatGPT」;
  3. 插件会调起设备码(device-code)流程,设置里显示一个一次性验证码和 登录链接 https://auth.openai.com/codex/device;
  4. 在浏览器打开链接、登录你的 ChatGPT Plus/Pro 账号并输入验证码;
  5. 授权完成后面板自动出现「ChatGPT」行(无需重启),悬停可见 plan: plus/pro 与 weekly: N%(Pro 还会有 5h 窗口)。

令牌保存在 $DSH_HOME/dsh-quota-panel/chatgpt-auth.json(Windows 即 C:\Users\<你>\.dsh\dsh-quota-panel\,文件权限 0600),access token 过期时 插件用 refresh token 自动刷新并回写。点同一栏的「退出登录」即可删除本地令牌。

方式 B:复用 Codex CLI 登录

如果你已经用 Codex CLI 登录过(运行 codex 完成浏览器授权),插件会自动读取 ~/.codex/auth.json(或 $CODEX_HOME/auth.json),无需任何额外配置。此方式下刷新后的令牌只留在 插件进程内存,不会回写 auth.json(该文件归 Codex CLI 所有)。

两种方式同时存在时,插件内登录的令牌优先;都没有时 ChatGPT 行不显示。 若令牌在别处被重新登录而失效,面板会提示,重新走一次方式 A 或 codex 登录即可恢复。

内置 format

format行类型上游响应形态
deepseek-balance¥余额{ balance_infos: [{ currency, total_balance, granted_balance, topped_up_balance }] }
openrouter-credits$余额{ data: { total_credits, total_usage } }
siliconflow-balance余额(默认 ¥,可按行覆盖币种){ data: { balance, chargeBalance, totalUsage } }
moonshot-balance¥余额{ data: { total_balance } }
minimax-remains用量%{ base_resp, model_remains: [{ model_name, current_interval_total_count, current_interval_usage_count, current_interval_remaining_percent, end_time, current_weekly_total_count, current_weekly_usage_count, weekly_end_time }] } —— 优先取 MiniMax-M* 编码模型行;计数均为剩余侧(已用 = 总量 − 计数);current_weekly_total_count > 0 时才有周窗口
stepfun-accounts¥余额{ balance, total_cash_balance, total_voucher_balance }
xai-credits$余额{ total: { val } }(分 → 元)
openai-billing$余额聚合站 dashboard/billing 两接口
zhipu-quota文本{ code: 200, data: { limits: [{ remaining, number }] } }(无 remaining 的条目回退显示 percentage)
opencode-usage用量%`{ usage: { rolling
zai-coding-quota用量%{ code: 200, data: { limits: [{ type: TOKENS_LIMIT | TIME_LIMIT | CREDIT_LIMIT, unit, number, percentage, currentValue, usage, remaining, nextResetTime }] } } —— 语义映射(glm-plan-usage2,issue #2):TOKENS_LIMIT unit=3 → 5h 窗口、unit=6 → 周、TIME_LIMIT → MCP 月度车道;未知 unit 回退按 nextResetTime 排序;各窗口百分比优先取 percentage 字段。积分套餐(issue #7)返回的 CREDIT_LIMIT 行带有同一套 unit/number 声明,因此两类行共用一次 unit 匹配(unit=3 → 5h 积分窗口,如 2000 积分;unit=6 → 周池,如 10000 积分),任一类行都可补上另一类留空的泳道;只有未声明 unit 的行才回退 nextResetTime 顺序。积分泳道在悬停标题中标注为 [CREDIT_LIMIT u3n5 left 剩余/总量],缺声明时显示 no unit
kimi-coding-usage用量%{ usage: { limit, used, remaining, resetTime }, limits: [{ window: { duration, timeUnit }, detail: { limit, used, remaining, resetTime } }] } —— 5h = duration=300 的窗口、周 = duration=10080(缺失时回退顶层 usage);used = limit − remaining
volcengine-agent-usage用量%不走 adaptRow:fetchRow 内部以 AK/SK HMAC-SHA256 签名调用火山引擎 OpenAPI GetAFPUsage,解析 Result.AFPFiveHour/AFPWeekly/AFPMonthly(Agent Plan 的 5h/周/月,AFPDaily 按控制台惯例跳过)
volcengine-coding-usage用量%不走 adaptRow:fetchRow 内部以 AK/SK HMAC-SHA256 签名调用火山引擎 OpenAPI GetCodingPlanUsage,解析 Result.QuotaUsage[].Level ∈ {session,weekly,monthly}(Coding Plan 的会话/周/月,仅百分比)。与 Agent 行相互独立、互不回落
chatgpt-subscription用量%{ plan_type, rate_limit: { primary_window: { used_percent, reset_at, limit_window_seconds }, secondary_window? } } —— 经 ~/.codex/auth.json 的 OAuth 令牌读取 Codex 内部用量端点;按 limit_window_seconds 判别窗口(18000s≈5h → 滚动,604800s≈7天 → 周),字段缺失时按典型布局回退(primary = 5h 会话窗,secondary = 周池)。实验性接口

代理(部分供应商无法直连时)

在**前端设置面板(⚙ → 代理)**逐供应商配置:填一个 HTTP(S) 代理 URL (如 http://127.0.0.1:7890,可带 user:pass),保存在浏览器 localStorage,即时生效—— 留空即回到 profile 配置或直连。请求仍由宿主侧执行:浏览器把每行的代理 URL 随 fetch-all payload 发给宿主,宿主校验(仅 http/https,socks 拒绝)后经该代理请求 上游——key 不进入浏览器(代理本身能看到,见安全中的「已知问题与风险(代理路径)」)。

profile 配置里的 proxies + 行级 proxy / catalog.<id>.proxy 仍可用, 作为默认代理(前端留空时生效)。优先级:前端设置 > profile 配置 > 直连。

# profile 级默认代理示例(前端 ⚙ 面板可逐行覆盖)
- id: quota-panel
  name: 'dsh-quota-panel'
  config:
    proxies:
      home: http://127.0.0.1:7890     # clash / v2rayN 等本地代理的 http 端口
    catalog:
      openrouter:
        proxy: home                    # OpenRouter 默认经代理(前端可覆盖)
    providers:
      - id: my-agg
        label: 我的聚合站
        credential: AGG_API_KEY
        endpoint: https://agg.example  # openai-billing 用 base URL
        format: openai-billing
        proxy: home

阈值默认值

DeepSeek 余额(balanceTiers {critical: 10, warn: 20, healthy: 50}):

余额状态次级信息
<= 10error(红点 + 红数值)建议充值
10 < x <= 20warn(琥珀色)余额紧张
20 < x <= 50ok余额正常
> 50ok余额充足

OpenCode 用量(high = max(滚动, 每周, 每月)):

用量状态
< warnPercentok(绿点,DeepSeek 蓝进度条)
>= warnPercentwarn(琥珀点 + 进度条)
>= errorPercenterror(红点 + 进度条)

兼容性

一次只支持一条宿主线。 本包只支持它 peerDependencies 精确 pin 的宿主线—— 当前为 @deepseek-ai/dsh@0.1.7-rc.1(npm next)。实际接触的五个接缝包都以精确 版本声明为 peer:

接缝包(peer,精确版本)用途
@deepseek-ai/dsh-client-connection宿主 connection.fetch RPC 路由 + 浏览器 connection.rpc
@deepseek-ai/dsh-credentials宿主侧 credentials.resolve
@deepseek-ai/dsh-client-ui-renderer浏览器 slots 服务(shell.overlay 注册)
@deepseek-ai/dsh-cordis-client-runner浏览器 timer 服务(ctx.interval)
@deepseek-ai/dsh-client-locale浏览器 locale 服务(词典)

由于这些 peer 是精确版本,0.1.7 及更新宿主的插件/宿主版本门禁 (evaluatePluginCompatibility)会拒绝把本包装到其它宿主线上。这是有意为之: 旧宿主线由旧插件版本服务——继续跑当初 pin 了你那条 DSH 线的插件版本(它的 tag 记录了是哪一条),并与 DSH 同步升级插件。(比 0.1.7 更旧的宿主没有该门禁, 会直接忽略这份声明;它们不在支持与验证范围内。)

当前宿主线的验证在 testbed 与 CI boot 门禁里; docs/2026-09-24-dsh-0.1.7-rc.1-assessment.md 记录了相对上一条宿主线的逐接缝 diff。

版本与 tag 约定

版本串同时携带 DSH 宿主线和本地修订号:

0.1.7-rc.1-v0.1
└────┬────┘ └┬┘
DSH 线        └─ 本地修订号(本仓库自己的计数器)
(peer pin)
  • package.json#version = <dsh线>-v<本地号>(例如 0.1.7-rc.1-v0.1)。
  • git tag = v + 该版本号:v0.1.7-rc.1-v0.1。
  • npm 通道跟随 DSH 自己的 dist-tag。 发布任务读取 npm view @deepseek-ai/dsh dist-tags,把插件发到"当前指向该宿主线"的那个 tag 下: 面向 dsh latest(当前 0.1.5-rc.3)的版本发 npm latest;面向 dsh next (当前 0.1.7-rc.1)的版本发 npm next;没有任何 dist-tag 指向的宿主线回退到 next。GitHub Release 同样分流:latest 走正式 release(由 production 环境的审批人确认),其余走 pre-release。
  • 维护线的版本从该线自己的分支(release/0.1.5-rc.3)手工推 tag 或 workflow_dispatch 时传 release: true 来发;main 只自动打自己这条线的 tag。
  • 人工已确认的版本可以覆盖上述映射:workflow_dispatch 时传 promote_tag (如 v0.1.7-rc.1-v0.1),把 npm latest 与 GitHub Latest 标记移到该版本—— 即使它的宿主线还是 dsh next。

宿主线 pin 在 peerDependencies 里,所以一条 DSH 线对应一条插件线:旧宿主线保留 它当年的插件版本,插件与 DSH 一起升级。

安装

请安装已发布版本,而不是 main 分支。 main 承载未经人工确认的 开发中内容;只有打了 tag 的版本才通过了 CI 门禁(check + boot),正式版 还经过了人工审批门禁。

推荐——安装与你的 DSH 线匹配的那一版:

# dsh npm `latest`(当前 0.1.5-rc.3)→ 插件 tag v0.1.5-rc.3-v0.1,
# 以 npm `latest` 发布:
dsh plugin --profile web add dsh-quota-panel

# dsh npm `next`(当前 0.1.7-rc.1)→ 插件 tag v0.1.7-rc.1-v0.1,
# 以 npm `next` 发布:
dsh plugin --profile web add dsh-quota-panel@next

# 也可以直接锁 tag(以 Releases 页面为准):
dsh plugin --profile web add "github:wenzetan/dsh-quota-panel#v0.1.5-rc.3-v0.1"

# 重启 `dsh web`(bundle 层与 client 模块图在启动时生效)

用 npm view @deepseek-ai/dsh dist-tags 看你的 DSH 线挂在哪个 tag 下,再装对应的 插件通道——版本规则见《版本与 tag 约定》。

避免裸 github:wenzetan/dsh-quota-panel(不带 #tag)——它跟踪 main HEAD,即测试分支:可能携带未发布的功能、未过 CI 甚至坏掉的 代码。只有自己迭代该插件的开发者才应该从 main 安装。

安装后建议刷新一次浏览器页面。零 npm 依赖(schema 库 schemastery + cosmokit, 均 MIT,已 vendor 进 src/vendor/ 并以相对路径导入),无需 allowBuilds 构建授权。

发布通道与 npm 发布(维护者)

发布身份与通道规则见上面的《版本与 tag 约定》。简言之:package.json#version = <dsh线>-v<本地号>,tag = v + 该版本号,发布通道跟随 @deepseek-ai/dsh 自己的 dist-tag——latest 线走正式 release(production 环境审批人确认), 其余线走该线自己的 dist-tag(GitHub pre-release)。

package.json 版本对应的 dsh 线通道门禁GitHub Releasenpm dist-tag
0.1.7-rc.1-v0.1dsh next该线的 dist-tag仅 CI(check + boot)标记 pre-releasenext
0.1.5-rc.3-v0.1dsh latest该线的 dist-tagCI + 人工审批正式 releaselatest

流程:

  1. 发布当前线(自动) —— bump package.json#version(例如 0.1.7-rc.1-v0.1)推 main。CI 全门禁通过后自动打 tag v0.1.7-rc.1-v0.1,并按 @deepseek-ai/dsh 当前给 0.1.7-rc.1 挂的 dist-tag(今天是 next)发布。classify 任务在发布时重新推导 这个映射,没有任何硬编码。
  2. 发布其它宿主线 —— 切到该线的分支(release/0.1.5-rc.3),把版本 bump 成 0.1.5-rc.3-v0.1,然后手工推 tag,或在该分支上运行 CI 工作流 并传 release: true。发布任务会按 dsh 自己给该线挂的 tag 发布—— 0.1.5-rc.3 是 latest——且 release-latest 任务停在 production 环境等待人工审批后才创建 GitHub Release 并发布。
  3. 提升(可选,人工) —— 确认新线实测没问题后,workflow_dispatch 传 promote_tag(如 v0.1.7-rc.1-v0.1)。promote 任务会移动 npm latest 与 GitHub Latest 标记,并把其余普通 release 降级为 pre-release——保证有且只有 一个普通 release(即当前 latest)。该任务停在 production 环境。
  4. 验证(人工) —— 安装所锁定的 tag 实测 (dsh plugin --profile web add "github:wenzetan/dsh-quota-panel#v0.1.5-rc.3-v0.1",或 npm 的 dsh-quota-panel@latest / @next)。

一次性配置:

  • npm 令牌 —— 创建 Automation(或细粒度)令牌,对 dsh-quota-panel 有发布权限(该包名目前未被占用),添加为仓库 secret NPM_TOKEN(Settings → Secrets and variables → Actions)。 未配置时 GitHub Release 照常发布,仅跳过 npm 步骤。
  • 正式版门禁 —— Settings → Environments → New environment → production → Required reviewers → 加上你自己。这是把 「未经人工确认不发正式版」从约定变成强制的关键。 (不配置审批人时,稳定通道会直接发布不暂停——与之前行为一致。)

包声明了 dsh.bundle.patch(宿主侧自动激活为 profile 层)和 dsh.client manifest(浏览器侧自动进入 __DSH_BOOT__ 模块图,immediately: true 随壳预取)。

致谢

本插件站在社区工作的肩膀上——感谢:

  • yingjunnan/dsh-deepseek-quota —— DSH 网页端右下角 DeepSeek 余额卡片的原作(自动刷新 + 手动刷新); 胶囊/卡片的交互模型直接受它启发。
  • Ghost011118/dsh-balance-meter —— DSH 网页端的 DeepSeek 账户余额与会话花费读数;其面板设计启发了展开卡片的布局。
  • 0xsline/awesome-deepseek-harness —— 社区插件目录,让我们发现了上面这些项目以及更广阔的 DSH 插件生态。
  • hanmumuHL/check_balance —— DeepSeek 余额 API 端点调研,为目录条目提供了依据。
  • steipete/CodexBar —— 其供应商文档 (z.ai/GLM 套餐窗口语义、Kimi Code 用量接口、MiMo / 通义 / Qoder / 豆包的认证调研)直接塑造了本插件的套餐适配器与不支持清单。
  • zwen64657/glm-plan-usage2 —— Rust 版 GLM 用量工具,其监控接口调研(docs/api-research.md 实测 响应样本)确认了语义窗口映射:TOKENS_LIMIT unit=3 → 5h、unit=6 → 周、TIME_LIMIT → MCP 月度、percentage 为权威百分比字段;其 Kimi (window.duration 300/10080、limit − remaining)与 MiniMax(编码 模型行、周窗口)客户端逻辑为对应适配器的修复提供了参照(issue #2)。
  • PowerUserZ/OpenTokenUsage —— 记录了 MiniMax token_plan/remains 的响应怪癖与 Kimi Code 用量端点。
  • schemastery 与 cosmokit(均 MIT)—— vendor 在 src/vendor/ 下的 schema 库。

更新日志