dsh-quota-panel 是 DeepSeek HarnessDSHWeb 界面dsh web的服务商额度 /…
41/100
综合分
10
GitHub 星标
588
npm 周下载
—/5
用户评分
数据截至 2026/9/25 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add dsh-quota-panelnpm 源 · dsh-quota-panel 的发布者账号已校验与本仓库一致
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:仅索引
图例:✓ 通过! 需注意— 未判定 / 无数据· 「未判定」= 本站尚无数据,不代表插件有问题
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/dsh-client-connection@deepseek-ai/dsh-client-locale@deepseek-ai/dsh-client-ui-renderer@deepseek-ai/dsh-cordis-client-runner@deepseek-ai/dsh-credentials给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
界面预览
6 张 · 点击查看大图功能亮点
- 服务商额度余额挂件
- 胶囊卡片设置面板
- 双面结构零依赖
dsh 网页端的服务商额度/余额挂件:胶囊 + 卡片 + 设置面板,双面结构(loopback RPC 宿主半边 + shell.overlay 客户端半边),零 npm 依赖
README
由 DeepSeek 最新模型翻译生成dsh-quota-panel
dsh-quota-panel 是 DeepSeek Harness(DSH)Web 界面(dsh web)的服务商额度 / 余额状态组件。它固定在产品界面右下角,盯着你配好 API key 的每一个 AI 服务商,一眼就能看出还剩多少余额 / 额度——DeepSeek、OpenRouter、SiliconFlow、Moonshot、StepFun、xAI、Zhipu GLM、OpenCode Go、Volcengine Ark(Agent/Coding Plan),还有 one-api / new-api 风格的聚合站,以及带 5 小时 / 每周用量窗口和 MCP 月度额度的编码套餐(智谱 GLM Coding、Z.AI、Kimi Coding、MiniMax Coding 全球版 / 中国版)。xAI、Zhipu GLM、OpenCode Go、ChatGPT 订阅(通过 Codex 登录的 Plus/Pro),还有 one-api / new-api 风格的聚合站,以及带 5 小时 / 每周用量窗口和 MCP 月度额度的编码套餐(智谱 GLM Coding、Z.AI、Kimi Coding、MiniMax Coding 全球版 / 中国版)。
展开完整文档(README 剩余 1 节)
dsh-quota-panel
dsh-quota-panel 是 DeepSeek Harness(DSH)Web 界面(dsh web)的服务商额度 / 余额状态组件。它固定在产品界面右下角,盯着你配好 API key 的每一个 AI 服务商,一眼就能看出还剩多少余额 / 额度——DeepSeek、OpenRouter、SiliconFlow、Moonshot、StepFun、xAI、Zhipu GLM、OpenCode Go、Volcengine Ark(Agent/Coding Plan),还有 one-api / new-api 风格的聚合站,以及带 5 小时 / 每周用量窗口和 MCP 月度额度的编码套餐(智谱 GLM Coding、Z.AI、Kimi Coding、MiniMax Coding 全球版 / 中国版)。xAI、Zhipu GLM、OpenCode Go、ChatGPT 订阅(通过 Codex 登录的 Plus/Pro),还有 one-api / new-api 风格的聚合站,以及带 5 小时 / 每周用量窗口和 MCP 月度额度的编码套餐(智谱 GLM Coding、Z.AI、Kimi Coding、MiniMax Coding 全球版 / 中国版)。
从 v0.5 起它变成双面插件,自带服务商目录和自动发现:装上、重启 dsh web,凡是 key 能解析出来的服务商都会自动出现在面板上——零配置。它不依赖任何 npm 包,也不需要 allowBuilds 授权。
截图(真实浏览器渲染)
折叠胶囊,浅色主题:
capsule (light)
展开卡片,浅色主题:
expanded (light)
设置面板(⚙),浅色主题:
settings (light)
折叠胶囊,深色主题:
capsule (dark)
展开卡片,深色主题:
expanded (dark)
设置面板(⚙),深色主题:
settings (dark)
支持的功能
- 自动发现——宿主侧自带一份知名服务商目录;每个条目写明该服务商的标准凭据引用,凡是 key 能解析出来($DSH_HOME/.credentials.yaml / .env / 环境变量)的服务商都会自动出现在面板上,零配置。删掉 key,那一行就消失。DSH 里没有凭据枚举 API,所以每个刷新周期都会探测一遍目录。
- 编码套餐用量窗口——GLM / Z.AI / Kimi / MiniMax 编码套餐按用量行渲染:5 小时窗口、每周池,以及(GLM/Z.AI)MCP 月度通道,各自带重置倒计时;套餐里没有的窗口显示 —,而不是编一个 0% 出来。
- 两种尺寸——折叠态:极简胶囊,每个账号一对独立的「状态点 + 数值」(● ¥58.36 · ● 45%);展开态:完整卡片,每个服务商一行(状态点、名称、主数值、次要信息,用量型服务商还有进度条)。
- 自动刷新——按配置的间隔走(默认 60 s),页面隐藏时暂停;抓取期间刷新按钮转圈,连点也不会并发发请求。
- 按账号状态 — 余额行按档位分级(critical <= warn <= healthy),用量行按百分比分级(error >= warn);只有出问题的那一个圆点或数值会变色,其他保持平静。用量百分比采用电池风格的三色分级,与状态圆点相互独立。
- 设置面板(⚙) — 按服务商控制可见性、刷新间隔、按服务商设置警告阈值、按服务商设置 HTTP(S) 代理 URL、 胶囊显示模式(auto = 最高窗口 — 默认值 — / 5h 窗口 / 周窗口 / 最高),以及「恢复默认值」。所有本地设置立即生效,持久化到浏览器 localStorage,绝不写入配置档,也不会上传。
- 按行设置 HTTP(S) 代理 — 为你的网络无法直接访问的服务商配置代理(见下文)。
- One-api / new-api 聚合器 — 内置的 openai-billing 格式可适配聚合器仪表盘。
- 主题 — 完全由 Harness 设计 token 驱动(--dsw-alias-、--dsw-static-、--dsw-shadow-、 --dsw-font-),并带有合理的回退值,因此它会跟随产品主题(浅色/深色),自身不附带任何配色方案。
- 构造即安全 — API 密钥永远不会到达浏览器;浏览器只与 DSH 自身已认证的 /api 通道内本插件的方法通信,并且只接收归一化后的视图(见「工作原理」)。
尚不支持
- 只有用量的服务商 — OpenAI、Anthropic、Together、Groq、Mistral、 Cohere、DashScope、Baichuan 都不提供公开的「剩余余额」端点,只有用量/成本查询(通常需要管理员密钥加时间窗口,语义是「已花费」而不是「剩余」)。计划作为单独的用量行类型,展示月度支出(优先支持 Anthropic Admin API 和 OpenAI 用量 API)。
- 仅靠 Cookie / 命令行的编程套餐 — Qwen Token Plan (百炼控制台)、Xiaomi MiMo Token Plan 和 Qoder 的配额页面都不提供 API 密钥配额端点:它们需要网页 Cookie、arkcli 命令行,或聊天端点限流探测(依据 CodexBar 的研究)。
Volcengine Ark / Doubao Agent Plan 和 Coding Plan 现已通过 AK/SK 签名的 OpenAPI 支持(见上方目录表)。此列表中的其他服务商在出现 API 密钥端点之前无法接入。
- socks5 代理 — 只接受 HTTP/HTTPS 代理(socks URL 会被拒绝,并在对应行给出明确错误)。
- 自定义适配器 — 无法从配置档接入新的上游格式;format 值超出内置集合时会在挂载时直接报错。
- 多页面放置 — 小组件只存在于 shell.overlay 槽位(右下角),不在侧边栏、页眉或状态栏中。
请求新增服务商
缺少某个服务商?提交 issue,并附上:
1. 你想要的服务商 id(^[a-z0-9-]+$,例如 together),使用 -cn 后缀,用于双站点服务商的中国站点(参见 siliconflow / siliconflow-cn);
2. 余额 API URL —— 一个公开端点,用服务商的标准 API key 就能查到剩余余额/额度(例如 GET https://api.provider.com/v1/user/info,Bearer 认证),如果方便的话,再附上响应结构。
目录需要的就这些:一个 id,其标准凭据引用能解析;一个端点;再加一个响应格式适配器。只有 cookie/命令行 额度页面的服务商(见上文)暂时无法支持,除非它们对外暴露 API key 端点。
工作原理
┌─────────────── browser (lib/client.js) ───────────────┐
│ shell.overlay slot → capsule / card / settings panel │
│ localStorage: visibility · interval · thresholds · │ │ proxy URLs (frontend settings) │ └──────────────┬─────────────────────────────────────────┘ │ Connection /api channel (browser-session fenced): │ POST /api/dsh-quota-panel/specs (render hints) │ POST /api/dsh-quota-panel/fetch-all { proxy: {...} } ┌──────────────▼────────────── host (lib/index.js) ──────┐ │ ctx.credentials → API keys (never leave the host) │ │ catalog probe → auto discovery (15 built-in providers) │ │ per-row fetch → proxy engine (CONNECT tunnel / │ │ absolute-URI) → upstream JSON │ │ normalization → {balance | usage | info} view models │ └─────────────────────────────────────────────────────────┘
- 宿主端(lib/index.js)在 Connection 服务已认证的 /api 通道上,按端点各挂一条精确的 Fetch 路由,位于 dsh-quota-panel 方法命名空间下:
- POST /api/dsh-quota-panel/specs —— 返回解析后的行,只带渲染提示(id、label、行类型、货币、阈值档位、窗口标签、已配置的代理名)。不含凭据,不含端点。
- POST /api/dsh-quota-panel/fetch-all —— 抓取所有可见行,把每个上游响应归一化成通用视图模型(balance / usage / info),返回 {rows: [{id, view} | {id, error}], fetchedAt}。上游原始 JSON 和 key 一样留在宿主端;某一行失败不影响其他行。
- POST /api/dsh-quota-panel/chatgpt-auth-status / chatgpt-login-start / chatgpt-login-cancel / chatgpt-logout —— 可选的 ChatGPT 订阅设备登录流程。
请求由 DSH 自己的 /api 路由把关(可信主机 + 浏览器会话),所以这些端点从另一台机器访问不到,没有页面会话的客户端也访问不到。
- 自动发现 —— DSH 的凭据存储没有枚举 API,所以宿主端在每个抓取周期探测目录条目的标准引用;凡是 key 能解析的条目就加入面板,key 解析不了的条目跳过(只有通过 providers 显式配置过的条目,缺 key 时才会给出清晰的单行错误)。
- 代理引擎 —— 零依赖、手写的 proxiedGetJson: https 目标走 HTTP CONNECT 隧道(隧道上跑 TLS),http 目标走绝对 URI 转发。每行超时 15 s,响应体上限 1 MB。代理选择优先级: 前端设置面板 > 配置档配置 > 直连。
- 阈值判断在客户端完成,依据 specs 提示,所以本地阈值覆盖无需重新拉取即可生效;配置档阈值随 specs 下发,前端设置会在本地覆盖它们。
- 配置校验 —— 导出的 Config schema(内置 schemastery)声明结构与默认值;跨字段约束(id 唯一性、critical <= warn <= healthy、代理引用、catalog 覆盖键)在挂载时由宿主侧校验,出错直接报错。
- DOM 安全 —— 卡片只用 createElement/textContent 构建 DOM;API 返回值绝不碰 innerHTML;技术性错误(401、超时、凭据缺失、代理拒绝)只出现在 title 提示或行内文本里。
- 代理坏掉绝不会拖垮宿主 —— 代理引擎打开的每个 socket 和请求,其 error 事件都会汇入该行的结果,所以代理不可达(比如 clash 停了,ECONNREFUSED 127.0.0.1:7890)会显示为单行错误,而不是未处理的 EventEmitter 错误。
配置
开箱即用:什么都不用配。 安装、重启,任何密钥能解析出来的服务商都会自动出现。下表只用于调优。
所有键都是可选的 —— 结构和默认值都在导出的 Config schema 里,所以配置档补丁可以省略任何带默认值的字段。
| 键 | 含义 | 默认值 |
| auto | 探测内置 catalog;密钥可解析的服务商加入面板 | true |
| hide | 要丢弃的行 id(catalog 行和显式行都一样) | [] |
| proxies | 具名代理定义 {<name>: "http://host:port"},仅支持 HTTP(S) | {} |
| catalog | 对自动发现行的部分覆盖 {<catalog-id>: {...}} | {} |
| refreshMs | 自动刷新间隔 | 60000 |
| providers | 显式行;同 id 条目会整体替换 catalog 行 | [] |
每个 catalog 覆盖可以设置:label / endpoint / format / proxy / refs(要探测的凭据引用,UPPER_SNAKE)/ secretRefs(第二个凭据引用 —— 火山引擎 AK/SK 对必需;只有 refs 和 secretRefs 都能解析时才会发现该行)/ region(火山引擎 OpenAPI region;默认 cn-beijing)/ currency(余额行:$ 或 US$ 这类符号)/ balanceTiers / warnPercent / errorPercent / windowLabels。
显式 providers 字段:
| 字段 | 含义 | 默认值 |
| id | 行 id(RPC 行按 id 对齐),^[a-z0-9-]+$ | 必填 |
| label | 卡片上显示的服务商名称 | 必填 |
| credential | 凭据引用($DSH_HOME/.credentials.yaml 或环境变量) | 必填 |
| secretCredential | 第二个凭据引用(火山引擎 volcengine-agent-usage / volcengine-coding-usage:即 SK) | — |
| endpoint | 额度 JSON 端点;openai-billing 的基础 URL | 必填 |
| format | 行适配器(见下表) | deepseek-balance |
| proxy | proxies 中定义的代理名;不填 = 直连 | — |
| region | (volcengine-agent-usage / volcengine-coding-usage)火山引擎 OpenAPI 区域 | cn-beijing |
| currency | (余额行)货币符号,覆盖格式默认值 | 格式默认值 |
| balanceTiers | (余额行){critical, warn, healthy} | {10, 20, 50} |
| lowBalance | balanceTiers.warn 的旧别名 | — |
| windowLabels | (用量类格式)用量窗口的标签 | {滚, 周, 月} |
| warnPercent / errorPercent | (用量行)阈值 | 70 / 90 |
内置服务商目录(自动发现)
| 服务商 | 探测的凭据引用 | 端点 | 行类型 |
| DeepSeek | DEEPSEEK_API_KEY | api.deepseek.com/user/balance | ¥ 余额 |
| OpenRouter | OPENROUTER_API_KEY | openrouter.ai/api/v1/credits | $ 余额(已购 − 已用) |
| SiliconFlow(国际) | SILICONFLOW_API_KEY | api.siliconflow.com/v1/user/info | $ 余额 |
| SiliconFlow(中国) | SILICONFLOW_CN_API_KEY | api.siliconflow.cn/v1/user/info | ¥ 余额 |
| Moonshot / Kimi | MOONSHOT_API_KEY | api.moonshot.cn/v1/users/me/balance | ¥ 余额 |
| MiniMax Coding(国际) | MINIMAX_API_KEY | www.minimax.io/v1/token_plan/remains | 5 小时提示词用量 % |
| MiniMax Coding(中国) | MINIMAX_CN_API_KEY | api.minimaxi.com/v1/token_plan/remains | 5 小时提示词用量 % |
| StepFun | STEP_API_KEY / STEPFUN_API_KEY | api.stepfun.com/v1/accounts | ¥ 余额(悬停:现金/代金券) |
| xAI | XAI_API_KEY | api.x.ai/v1/billing/credits | $ 余额 |
| Zhipu GLM | ZHIPU_API_KEY / GLM_API_KEY | open.bigmodel.cn/api/monitor/usage/quota/limit | 文本行(剩余/总额度;无公开余额 API) |
| 智谱 GLM Coding | ZAI_CODING_CN_API_KEY | open.bigmodel.cn/api/monitor/usage/quota/limit | 编码套餐窗口(5 小时 token / 每周 / 搜索次数) |
| Z.AI GLM Coding | ZAI_API_KEY | api.z.ai/api/monitor/usage/quota/limit | 编码套餐窗口(5 小时 token / 每周 / 搜索次数) |
| Kimi Coding | KIMI_API_KEY | api.kimi.com/coding/v1/usages | 用量 %(5 小时速率限制 + 每周请求池) |
| OpenCode Go | OPENCODE_GO_API_KEY | opencode.ai/zen/go/v1/usage | 三窗口用量 % |
| 火山引擎方舟 Agent Plan | VOLC_ACCESS_KEY + VOLC_SECRET_KEY | open.volcengineapi.com(OpenAPI,已签名) | 用量 %(5 小时 / 每周 / 每月,GetAFPUsage) |
| 火山引擎方舟 Coding Plan | VOLC_ACCESS_KEY + VOLC_SECRET_KEY | open.volcengineapi.com(OpenAPI,已签名) | 用量 %(会话 / 每周 / 每月,GetCodingPlanUsage) |
火山引擎方舟有两个独立订阅 —— Agent Plan 和 Coding Plan ——显示为两个独立的行(就像两个服务商),它们共用同一个 AK/SK 密钥对。每一行只查询自己套餐的 API,绝不回退到另一行,所以账号没订阅的套餐会在那一行显示「未订阅」提示,而不是显示另一个套餐的数字。
火山引擎用 AccessKey ID / SecretAccessKey 密钥对做身份验证,走 HMAC-SHA256 请求签名——不是 Bearer token。推理用的 ARK_API_KEY(形如 ark-...)查不了用量;只有 AK/SK 密钥对才有 OpenAPI 权限。完整配置见下一节。
火山引擎 Ark 配置
Ark Agent Plan / Coding Plan 的用量来自控制面 OpenAPI,需要一对具备只读权限的 AK/SK。三步:
1. 创建 AccessKey
打开 https://console.volcengine.com/iam/keymanage(火山引擎控制台 → 身份与访问管理 → 访问密钥),点击新建访问密钥。建议创建一个子用户密钥专门给这个插件用,不要用主账号密钥。把 AccessKey ID 和 SecretAccessKey 存好——SecretAccessKey 只显示一次。
2. 授予 Ark 只读权限
给持有密钥的子用户(或角色)挂上 ArkReadOnlyAccess 策略:
- 打开 IAM → 用户,选中子用户,选择权限 → 添加权限;
- 在搜索策略名称和备注框里输入 ArkReadOnlyAccess;
- 结果里服务来源是「火山方舟」的那条才是你要的——勾选它。搜索结果里同名策略只有两条,两个都勾也没问题。
只用 ArkReadOnlyAccess 就够了——GetAFPUsage 和 GetCodingPlanUsage 都是只读操作;不需要 ArkFullAccess,也不需要账号级账单权限。
3. 保存凭证
往 $DSH_HOME/.credentials.yaml 里加两行(Windows 默认是 C:\Users\<you>\.dsh\.credentials.yaml,Linux/macOS 是 ~/.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 和格式 id volcengine-usage 已替换为 volcengine-agent(volcengine-agent-usage)和 volcengine-coding(volcengine-coding-usage)。自动发现的配置无需改动;手写的 catalog: 覆盖或 providers: 条目如果还引用旧 id,插件会拒绝加载,并报出校验错误、列出有效 id——把它改成两个新 id 即可。
安全提示:一对 AK/SK 可以读取账号下所有 Ark 用量数据。粘贴到聊天、工单或截图前先脱敏;不再需要时,到密钥管理页面轮换。
| ChatGPT 订阅(Plus/Pro) | 插件内登录或 ~/.codex/auth.json(不用 API key) | chatgpt.com/backend-api/wham/usage | 每周用量百分比(Pro 还包含 5 小时窗口) |
另有 openai-billing 格式,适配 one-api / new-api 风格的聚合服务:把 endpoint 设为聚合服务的基础 URL,host 侧会请求 {base}/v1/dashboard/billing/subscription(hard_limit_usd)和 {base}/v1/dashboard/billing/usage(total_usage);剩余额度 = 限额 − 已用($)。聚合服务的域名因部署而异,所以这个格式只能显式配置。
双站点服务商 id(自定义 id → 站点映射)
有些服务商分别运营国际站和中国站,端点、凭据引用和货币都不同。目录把每个站点建模为独立的 provider id,所以只要配置对应的 key 就行——而显式 providers: 条目如果复用其中一个 id,会整体替换目录行(字段相同,用你的 endpoint/label/currency):
| provider id | 站点 | 端点 | 凭据引用 | 货币 |
| siliconflow | SiliconFlow 国际站 | api.siliconflow.com/v1/user/info | SILICONFLOW_API_KEY | $ |
| siliconflow-cn | SiliconFlow 中国站 | api.siliconflow.cn/v1/user/info | SILICONFLOW_CN_API_KEY | ¥ |
| minimax | MiniMax Coding 国际站 | www.minimax.io/v1/token_plan/remains | MINIMAX_API_KEY | —(用量 %) |
| minimax-cn | MiniMax Coding 中国站 | api.minimaxi.com/v1/token_plan/remains | MINIMAX_CN_API_KEY | —(用量 %) |
| zai | Z.AI GLM Coding 国际站 | api.z.ai/api/monitor/usage/quota/limit | ZAI_API_KEY | —(用量 %) |
| zai-coding-cn | 智谱 GLM Coding 中国站 | open.bigmodel.cn/api/monitor/usage/quota/limit | ZAI_CODING_CN_API_KEY | —(用量 %) |
同一服务商的两个站点可以同时显示在面板上(两个 key 都配置);hide: ["siliconflow"] 可以单独隐藏其中一行。
余额类行的货币符号默认取自 format(siliconflow-balance 渲染 ¥),也可以按行覆盖:catalog 行带 currency(全局 SiliconFlow 行设为 $),catalog: 覆盖项可以设置它,显式 providers: 条目接受 currency 字段(例如 "US$")。
ChatGPT 订阅(Plus/Pro)
ChatGPT 订阅用量不是 API 计费——没有公开的余额/用量 API。本插件调用 Codex 使用的同一个内部用量端点,带上 ChatGPT OAuth token,把每周窗口(Pro 上还有 5 小时窗口)显示为已用百分比行。支持两种登录方式,挑你喜欢的那种:
⚠️ 实验性。 端点(chatgpt.com/backend-api/wham/usage)是 Codex CLI 使用的未公开内部 API,响应结构可能变化。插件只做只读查询。
方式 A:插件内登录(推荐——不需要安装 Codex CLI)
1. 重启 dsh web,打开面板右下角的设置(齿轮图标);
2. 在顶部「ChatGPT account」区域,点击 「Log in to ChatGPT」;
3. 插件启动 OAuth 设备码流程,显示一次性代码和登录 URL https://auth.openai.com/codex/device;
4. 在浏览器打开该 URL,用你的 ChatGPT Plus/Pro 账号登录,输入代码;
5. 授权完成后,「ChatGPT」行自动出现(无需重启)。悬停可看到 plan: plus/pro 和 weekly: N%(Pro 还会显示 5h 窗口)。
Token 存放在 $DSH_HOME/dsh-quota-panel/chatgpt-auth.json(Windows 上是 C:\Users\<you>\.dsh\dsh-quota-panel\,文件权限 0600)。access token 过期时,插件用 refresh token 刷新并写回。在同一区域点击「Log out」可删除本地 token。
方式 B:复用 Codex CLI 登录
如果你已经通过 Codex CLI 登录过(运行过 codex 并完成浏览器登录),插件会自动读取 ~/.codex/auth.json(或 $CODEX_HOME/auth.json)——无需额外配置。用这种方式,刷新后的 token 只留在插件进程内存里,绝不写回 auth.json(那个文件归 Codex CLI 所有)。
两者同时存在时,插件内登录优先。两者都不存在时,ChatGPT 行隐藏。如果 token 因为在别处登录而失效,该行会显示错误——再跑一次方式 A,或执行 codex login,即可恢复。
内置 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 }] } — 优先取 coding model 行(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 的 limits 回退到 percentage) |
| opencode-usage | 用量 % | { usage: { rolling|weekly|monthly: { percent, resetsAt } } } |
| 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 remaining/usage],声明缺失时标记为 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);已用 = limit − remaining |
| volcengine-agent-usage | 用量 % | 在 fetchRow 中内联分发(不走 adaptRow):签名并调用 Volcengine Ark OpenAPI GetAFPUsage,解析 Result.AFPFiveHour / AFPWeekly / AFPMonthly(Agent Plan 5h/周/月;按控制台说明跳过 AFPDaily)。 |
| volcengine-coding-usage | 用量 % | 在 fetchRow 中内联分发(不走 adaptRow):签名并调用 Volcengine Ark OpenAPI GetCodingPlanUsage,解析 Result.QuotaUsage[].Level ∈ {session,weekly,monthly}(Coding Plan session/周/月,仅百分比)。与 Agent 行相互独立——两者之间没有回退。 |
| chatgpt-subscription | 用量 % | { plan_type, rate_limit: { primary_window: { used_percent, reset_at, limit_window_seconds }, secondary_window? } } — 通过 ~/.codex/auth.json 里的 OAuth token 读取,请求 Codex 内部用量端点;窗口按 limit_window_seconds 分类(18000s ≈ 5h → 滚动窗口,604800s ≈ 7d → 每周窗口),无法分类时回退到常见的位置布局(primary = 5h 会话,secondary = 每周池)。实验性 |
代理(无法直连的服务商)
在前端设置面板(⚙ → 代理)里按服务商配置代理:填入 HTTP(S) 代理 URL(例如 http://127.0.0.1:7890,允许 user:pass),保存到浏览器 localStorage,立即生效——留空则回退到配置档配置或直连。请求仍在宿主侧执行:浏览器在 fetch-all 载荷里发送每一行的代理 URL,宿主校验它(仅 http/https,拒绝 socks)并通过它发起请求——密钥不会到达浏览器,但代理本身能看到它们(见 Security 下的 Known issues & risks)。
配置档的 proxies 映射 + 行级 proxy / catalog.<id>.proxy 仍可作为默认代理使用(前端字段为空时生效)。优先级:前端设置 > 配置档配置 > 直连。
example profile-level default proxy (the ⚙ panel can override per row)
- id: quota-panel
name: 'dsh-quota-panel'
config:
proxies:
home: http://127.0.0.1:7890 # local proxy http port (clash / v2rayN …)
catalog:
openrouter:
proxy: home # OpenRouter via proxy by default
providers:
- id: my-agg
label: My aggregator
credential: AGG_API_KEY
endpoint: https://agg.example # base URL for openai-billing
format: openai-billing
proxy: home
阈值默认值
DeepSeek 余额(balanceTiers {critical: 10, warn: 20, healthy: 50}):
| 余额 | 状态 | 次要信息 |
| <= 10 | error(红点 + 红色数值) | 建议充值 |
| 10 < x <= 20 | warn(琥珀色) | 余额紧张 |
| 20 < x <= 50 | ok | 余额正常 |
| > 50 | ok | 余额充足 |
OpenCode 用量(high = max(rolling, weekly, monthly)):
| 用量 | 状态 |
| < warnPercent | ok(绿点,DeepSeek 蓝条) |
| >= warnPercent | warn(琥珀色点 + 条) |
| >= errorPercent | error(红点 + 条) |
兼容性
一次只支持一条 DSH 宿主线。 本包只支持其 peerDependencies 锁定的那条宿主线——目前是 @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 服务(字典) |
这些对等依赖都锁定了精确版本,所以 DSH 0.1.7 或更新版本的主机,其插件/主机兼容性检查(evaluatePluginCompatibility)会拒绝在其他主机版本线上安装或启动这个包。这是有意为之:旧的主机版本线会
served by old plugin versions.* Keep running the release that pinned your DSH
version — its tag records which one — and upgrade the plugin together with DSH. (Host lines older than 0.1.7 have no such gate and simply ignore the declaration; they are not tested or supported.)
Verification for the current line lives in the testbed and the CI boot gate;
docs/2026-09-24-dsh-0.1.7-rc.1-assessment.md
records the seam-by-seam diff against the previous line.
Versioning and tags
The version string carries the DSH host line plus a local revision,
0.1.7-rc.1-v0.1
└────┬────┘ └┬┘
DSH line └─ local revision (this repo's counter)
(peer pin)
* package.json#version is <dsh-line>-v<local> (for example
0.1.7-rc.1-v0.1).
* The git tag is v + that version: v0.1.7-rc.1-v0.1.
* The npm channel mirrors DSH's own dist-tags. The release job reads
npm view @deepseek-ai/dsh dist-tags and publishes the plugin under the tag
that currently names the declared host line: a release for dsh latest
(today 0.1.5-rc.3) goes to npm latest; a release for dsh next
(today 0.1.7-rc.1) goes to npm next. A line no dist-tag points at falls
back to next. GitHub releases follow the same split: latest → normal
release gated by the production environment's reviewer, everything else →
pre-release.
* Releases for a maintenance line are cut from that line's branch
(release/0.1.5-rc.3) by pushing the tag by hand or dispatching the CI
workflow with release: true; main only ever auto-tags its own line.
* A human can override the mapping for a release they have confirmed:
dispatch the CI workflow with promote_tag (e.g. v0.1.7-rc.1-v0.1) to
move npm latest and the GitHub Latest flag to that release, even when its
host line is still dsh next.
Because the host line is pinned in peerDependencies, one DSH line gets one
plugin line: old host lines keep their old plugin release, and the plugin is
upgraded together with DSH.
Install
Install a released version — not the main branch. main receives unverified work-in-progress; only tagged releases have passed the CI gates (check + boot) and — for the shipped line — the human approval gate.
Recommended — the release that matches your DSH line:
dsh npm latest (0.1.5-rc.3 today) → plugin release tagged
v0.1.5-rc.3-v0.1, published as npm latest:
dsh plugin --profile web add dsh-quota-panel
dsh npm next (0.1.7-rc.1 today) → plugin release tagged
v0.1.7-rc.1-v0.1, published as npm next:
dsh plugin --profile web add dsh-quota-panel@next
Pin the tag instead (checked on the Releases page):
dsh plugin --profile web add "github:wenzetan/dsh-quota-panel#v0.1.5-rc.3-v0.1"
Restart dsh web (bundle layer and client module graph apply at boot)
Check npm view @deepseek-ai/dsh dist-tags to see which tag your DSH line
rides, then install the matching plugin channel — the version rule is in Versioning and tags.
Avoid bare github:wenzetan/dsh-quota-panel (no #tag) — it tracks main HEAD, which is the testing branch: it may carry unreleased work, fail CI, or break. Only developers iterating on the plugin itself should install from main.
Refresh the browser page once after installing. Zero npm dependencies (the
schema library — schemastery + cosmokit, both MIT — is vendored under src/vendor/ with relative-path imports), no allowBuilds authorization needed.
Release channels & npm publishing (maintainer)
The release identity and channel rules live in
Versioning and tags. In short: package.json#version
is <dsh-line>-v<local>, the tag is v<that version>, and the publish
channel mirrors @deepseek-ai/dsh's own dist-tags — latest for the shipped
line (GitHub release, production environment reviewer), that line's dist-tag
for everything else (GitHub pre-release).
| package.json version | Host line it pins | Channel | Gate | GitHub Release | npm dist-tag |
| 0.1.7-rc.1-v0.1 | dsh next | that line's tag | CI only (check + boot) | flagged pre-release | next |
| 0.1.5-rc.3-v0.1 | dsh latest | that line's tag | CI + human approval | normal release | latest |
Workflow:
1. Release the current line (automatic) — bump package.json#version (e.g. 0.1.7-rc.1-v0.1) and push main. CI runs the full gates, auto-tags v0.1.7-rc.1-v0.1 and publishes it under the dist-tag that @deepseek-ai/dsh itself currently carries for 0.1.7-rc.1 (next today). The classify job re-derives that mapping at publish time, so nothing is hardcoded.
2. Release another host line — check out that line's branch (release/0.1.5-rc.3), bump the version there (0.1.5-rc.3-v0.1), and either push the tag by hand or run the CI workflow with the release input on that branch. The release job publishes under the tag that dsh itself carries for that line — latest for 0.1.5-rc.3 — and the release-latest job waits in the production environment for a human approval before creating the GitHub Release and publishing.
3. Promote (optional, human) — once you have confirmed the newer line works for real, dispatch the CI workflow with promote_tag set to its tag (e.g. v0.1.7-rc.1-v0.1). The promote job moves npm latest and the GitHub Latest flag there, and demotes every other normal release to a pre-release — so exactly one release (the current latest) is a normal release. It runs behind the production environment.
4. Verify (human) — install the pinned tag (dsh plugin --profile web add "github:wenzetan/dsh-quota-panel#v0.1.5-rc.3-v0.1", or dsh-quota-panel@latest / @next from npm) and test it for real.
One-time setup:
- npm token — create an Automation (or granular) token with publish rights to dsh-quota-panel (name free as of this writing) and add it as the repository secret NPM_TOKEN (Settings → Secrets and variables → Actions). Without it, GitHub Releases still ship; npm steps are skipped.
- stable gate — Settings → Environments → New environment → production → Required reviewers → add yourself. This is what makes "no stable release without human confirmation" enforced rather than
conventional. (Without the reviewer configured, the stable channel
publishes without pausing — same as before.)
The package declares dsh.bundle.patch (host half auto-activates as a
profile layer) and the dsh.client manifest (browser half auto-joins the
__DSH_BOOT__ module graph, immediately: true prefetched with the shell).
Acknowledgments
This plugin builds on community work — thanks to:
- yingjunnan/dsh-deepseek-quota
— the original bottom-right DeepSeek balance card for the DSH Web page (auto-refresh + manual refresh); the capsule/card interaction model is directly inspired by it.
- Ghost011118/dsh-balance-meter
— DeepSeek account balance and session cost readout for the DSH Web GUI; its panel design informed the expanded card layout.
- 0xsline/awesome-deepseek-harness
— the community plugin catalog that surfaced the projects above and the broader DSH plugin ecosystem.
- hanmumuHL/check_balance — endpoint research (DeepSeek balance API) that informed the catalog.
- steipete/CodexBar — its provider
docs (z.ai/GLM coding-plan windows, Kimi Code usage API, MiMo / Qwen /
Qoder / Doubao auth research) shaped the coding-plan adapters and the
not-supported list.
- zwen64657/glm-plan-usage2
— Rust GLM usage tracker whose monitor-API research (docs/api-research.md real-world samples) pinned the semantic window mapping: TOKENS_LIMIT unit=3 → 5h, unit=6 → weekly, TIME_LIMIT → MCP monthly, percentage as the authoritative field; its Kimi (window.duration 300/10080, limit − remaining) and MiniMax (coding-model row, weekly lane) clients informed the matching adapters here (issue #2).
- PowerUserZ/OpenTokenUsage
— documented the MiniMax token_plan/remains response quirks and the Kimi Code usage endpoint.
- schemastery and
cosmokit (both MIT) — the schema
library vendored under src/vendor/.
Changelog
- 0.1.7-rc.1-v0.1 (and its maintenance twin 0.1.5-rc.3-v0.1) — Adopts the DSH-line version scheme: package.json#version is <dsh-line>-v<local>, the
git tag is v<that version>, and the npm channel mirrors
@deepseek-ai/dsh's own dist-tags (0.1.7-rc.1 → next, 0.1.5-rc.3 →
latest). The five seam packages are declared as exact-version peers, so a
DSH 0.1.7+ host's plugin compatibility gate only loads the release built for
its own host line (old lines keep their old plugin release). Client bundle
URLs in the boot graph are document-relative since 0.1.7 — the testbed probes accept both forms. Every release before this entry was unpublished from GitHub and deprecated on npm.
- v0.9.2-rc.4 — Fixes the swapped GLM Coding Plan 5h/weekly lanes on credit
packages (issue #7): CREDIT_LIMIT rows now share the TOKENS_LIMIT window
declaration (unit=3 → the 5h credit window, unit=6 → the weekly pool)
instead of being placed by nextResetTime order alone — the weekly pool resetting before the 5h window inverted the two lanes every time. Either row kind can now also fill a lane its sibling left empty (a lone TOKENS_LIMIT row used to discard the CREDIT_LIMIT row and lose the 5h lane entirely). Rows that declare no unit keep the reset-order fallback, and the hover title spells out the declaration and quota ([CREDIT_LIMIT u3n5 left 1900/2000], no unit when absent). Existing V1 (5h-only) and V2 (5h/weekly/MCP) shapes are unchanged.
- v0.9.2-rc.3 — Fixes a host crash in the proxy engine: the CONNECT tunnel request had no error listener, so an unreachable proxy (ECONNREFUSED 127.0.0.1:7890 — proxy not running) surfaced as Node's Emitted 'error' event on ClientRequest instance and killed dsh web. Every socket and request now funnels error into the row result, so a dead proxy degrades to a per-row message.
- v0.9.2-rc.2 — Restores the host half on @deepseek-ai/dsh@0.1.5-rc.1 and newer. connection.rpc.handle() no longer works for third-party plugins there: its route disposer reads owner.webServer, and that owner resolves to the Connection plugin's own fiber, which never holds webServer — the registration throws inside a child fiber, so boot stays silent while the channel disappears. The host half now mounts one exact Fetch route per endpoint through connection.fetch.register() (which needs only owner.effect), under DSH's own authenticated /api channel: POST /api/dsh-quota-panel/<endpoint>. This supersedes rc.1, which remains merged but must not be promoted because its RPC endpoints are missing on current DSH.
- v0.9.2-rc.1 — Volcengine Ark Agent Plan and Coding Plan are now shown as two rows at once (previously a single row queried Agent Plan first and fell back to Coding Plan). The two subscriptions render as two independent providers sharing the same AK/SK pair: the Agent row (volcengine-agent, GetAFPUsage, 5h/weekly/monthly) and the Coding row (volcengine-coding, GetCodingPlanUsage, session/weekly/monthly) each query only their own API with no cross-fallback; a plan the account has not subscribed to reports its own "not subscribed" message on that row. The Coding row's hover title labels its rolling window session: (it is a session limit, not a 5h window), and a migration note for the replaced row/format ids (volcengine / volcengine-usage) was added to the Volcengine troubleshooting section.
- v0.8.1-rc.6 — layout fixes from issue #1, reworked: the panel is now draggable — grab the collapsed capsule or the expanded card header and move it anywhere (pointer capture, 5px move threshold so click-to-expand still works, viewport-clamped so it stays grabbable, position persisted to localStorage with the other settings, restored positions re-clamped on resize, "restore defaults" clears it). The default anchor stays right/bottom 18px until the first drag. Also injects
[class="overlayLayer"]{z-index:1150 !important} so the shell overlay
layer (z-index 20) is no longer covered whole-layer by body-mounted
third-party fixed panels (z-index 1000+) — the widget stays inside the React tree, keeping event delegation intact. Both style tags are removed on plugin unload. (rc.5 was briefly auto-released with a fixed 60px bottom offset instead of dragging; its tag/release were rolled back — the npm version is an orphan pre-release.)
- v0.8.1-rc.4 — capsule display mode (issue #2 follow-up): the settings panel gains 胶囊显示 / "capsule display" (auto = highest window — the default, unchanged behavior / 5h window / weekly window / highest). In rolling/weekly modes the collapsed capsule's value, status dot, progress bar and 100% caption all follow the chosen window instead of the highest one, so a 5h capsule no longer glows warn because the weekly pool sits at 40%; a plan without the chosen window falls back to the highest. The expanded card always shows every window.
- v0.8.1-rc.3 — coding-plan adapter fixes (issue #2, cross-checked with glm-plan-usage2): zai-coding-quota maps windows semantically (TOKENS_LIMIT unit=3 → 5h,
unit=6 → weekly, TIME_LIMIT → the MCP monthly lane; unknown units fall
back to nextResetTime ordering) instead of the size heuristic that
swapped 5h/weekly on plans returning both rows, prefers the percentage
field for every window, and relabels the third slot 搜索 → 月; kimi-coding-usage matches windows by window.duration (300 = 5h, 10080 = weekly) instead of blind limits[0] and computes used as limit − remaining (the old code read a nonexistent detail.used, so the 5h window silently dropped); minimax-remains prefers the MiniMax-M coding model row over whatever comes first and adds the weekly window (current_weekly_total_count > 0, remaining-side counts).
- v0.8.1-rc.1 — first pre-release on the automatic rc pipeline: 100% usage caption appends the reset time (当前已使用 100% 等待重置 …); CI reworked (reference dsh-llm-newapi): pre-releases auto-tag + publish to npm next with a latest reclaim guard; stable versions require the manual rc_tag promote workflow.
- v0.8.0 — first stable release on the dual-channel pipeline: same code as v0.7.3 (which already passed check + boot) plus the install guidance rework (released tags / npm latest + next instead of bare main).
- v0.7.3 — no unconfigured provider rows: cordis.patch.yml no longer ships explicit example rows (deepseek / opencode-go), so the settings panel lists exactly the providers whose credential resolves (auto discovery). The CI boot gate now asserts both directions: the seeded key appears, and unconfigured providers do not.
- v0.7.2 — web i18n: the panel follows the shell's language setting (通用设置 → 语言, locale.preference; zh / en) through the ctx.locale service — all copy (capsule, card, settings panel, errors, aria labels, usage windows) ships as zh/en dictionaries registered under the quota-panel namespace; provider labels are proper nouns kept as-is (GLM, MiniMax, Kimi Coding…) with Chinese brand names romanized (智谱 → ZhiPu); host catalog labels normalized accordingly (SiliconFlow CN, MiniMax Coding CN, ZhiPu GLM). Also: usage reset times now show absolute 24h timestamps (下次重置 2026-08-15 14:00, dictionary key nextReset); usage rows drop the weekly segment when the plan has no weekly window and render the search/MCP lane as -% when it is unknown (no fabricated 0%); the usage caption reads 当前已使用 X%.
- v0.7.1 — dual-site SiliconFlow: catalog id siliconflow now maps to the global site (api.siliconflow.com, $), new id siliconflow-cn maps to the China site (api.siliconflow.cn, ¥, ref SILICONFLOW_CN_API_KEY); balance rows gained a per-row currency override (catalog rows, catalog: overrides, and explicit providers: entries); README documents the dual-site provider id → endpoint/currency mapping.
- v0.7.0 — adopted the org TypeScript tool-bundle template (dsh-plugin-check compliant, zero waivers): sources moved to src/.ts compiled into lib/ by npm run build (tsc + vendored runtime copy), committed artifacts verified current by CI; new dsh-plugin-check CI gate (any error or warning fails — currently verdict=pass, 0 error / 0 warning); CI check job now installs dev dependencies and builds before testing.
- v0.6.0 — coding-plan support: new catalog rows 智谱 GLM Coding (ZAI_CODING_CN_API_KEY), Z.AI GLM Coding (ZAI_API_KEY), Kimi Coding (KIMI_API_KEY), MiniMax Coding global/CN (MINIMAX_API_KEY / MINIMAX_CN_API_KEY); new zai-coding-quota (5h/weekly token windows + search lane) and kimi-coding-usage (5h + weekly request pool) adapters; minimax-remains rewritten for the real model_remains
response (now a usage row); zhipu-quota shows percentage when a
limit carries no remaining; usage rows render missing windows as
— (labels from windowLabels, no longer hardcoded rolling/weekly/
monthly).
- v0.5.0 — built-in provider catalog + auto discovery (probes credential refs; 9 providers on board with zero config); 8 new format
adapters (incl. one-api/new-api openai-billing); fetch-all
contract switched to host-side normalized views (balance / usage / info),
upstream JSON no longer shipped; per-row HTTP(S) proxy (CONNECT tunnel /
absolute URI, zero-dependency), configured in the ⚙ settings panel
(localStorage, takes precedence over profile proxies / proxy);
new auto / hide / proxies / catalog config keys.
- v0.4.0 — dual-face refactor: host half moved to a loopback Connection RPC channel (specs / fetch-all) + Config schema; browser half moved into the dsh.client manifest + shell.overlay slot (React); added the ⚙ settings panel (visibility / refresh interval / thresholds, localStorage-persisted).
- v0.3.0 — two sizes: collapsed minimal capsule (independent status dot + battery-style value per account), click to expand the full card.
- v0.2.0 — Harness-native card: design tokens, balance tier thresholds, usage progress bar.
- v0.1.0 — initial floating panel: server-side quota proxy + page badge.
Security
- API keys are resolved host-side via ctx.credentials and used only for
host-side requests to providers; the browser talks exclusively to the
plugin's methods on Connection's authenticated /api channel
(/api/dsh-quota-panel/<method>), the specs endpoint ships
render hints only (labels/kinds/thresholds) with no credential or
endpoint; since v0.5 fetch-all ships normalized views only — raw upstream JSON stays host-side too.
- The card builds DOM exclusively with createElement/textContent;
API values never touch innerHTML; technical errors (401, timeout,
missing credential, refused proxy) surface only in title tooltips or
inline row text, and one failing row never affects the others.
Known issues & risks (proxy path)
The per-row proxy feature has two known risk points you should weigh before
routing a provider through a proxy:
1. The upstream Authorization header is forwarded to the proxy. When a
row goes through a proxy, the host sends the request headers — including Authorization: Bearer <key> — to the proxy server itself: for https targets the key rides in the CONNECT request (outside the TLS tunnel), for http targets in the absolute-URI request. The proxy operator can therefore read every API key routed through it.
2. The plugin accepts an arbitrary proxy URL per row. The
browser-side proxy field is sent to the host in the fetch-all payload
and validated only as http/https. The endpoint itself sits behind DSH's
/api fence (trusted host + browser session), so a caller needs the page
session of the running dsh web — but anyone who does* hold that session (or a script driving the same browser profile) can POST a proxy override pointing at an arbitrary server and have the host send your provider keys to it.
Stay safe:
- Use a proxy you fully trust — ideally on your own machine (http://127.0.0.1:7890, e.g. clash / v2rayN). Never point a row at a third-party or public proxy you do not operate: its operator can read your
keys (see 1).
- Use dedicated API keys for providers queried through a proxy — separate from keys used anywhere else, with the least privilege your provider offers (billing/balance-only scopes where available), and rotate them if a proxy was ever shared or is suspected compromised.
- Run dsh web only on machines you trust. The plugin's endpoints sit
behind DSH's /api fence (trusted host + browser session), so they are not
open to the network; keep it that way by not exposing the port to other
users or the network.
- Proxy URLs are stored in browser localStorage as entered — prefer proxies without embedded credentials, or a dedicated local proxy that needs none.
TODO
- Usage-only providers (OpenAI / Anthropic / Together / Groq / Mistral /
Cohere / DashScope / Baichuan) as a separate usage row kind showing
monthly spend instead of balance (Anthropic Admin API and OpenAI usage
API first).
- socks5 proxy support (HTTP/HTTPS only today).
Local development
Sources live in src/*.ts (org tool-bundle template): tsc compiles them
into lib/ (declarations included) and scripts/build.mjs copies the
vendored schema runtime into lib/vendor/. devDependencies are build-only
— runtime stays zero-dependency.
npm install
npm run build
After editing src/, rebuild and COMMIT lib/ — github: installs run from the committed artifacts (CI's "Committed artifacts are current" step rejects a stale lib/).
Dual-face check: host RPC contract + catalog discovery/proxy engine
(exercised against real local servers) + client slot/settings surfaces
node scripts/test-page-script.mjs
Health check with @deepseek-ai/dsh-plugin-check (same gate as CI; fails
on any error or warning). One-off deps dir, then the gate script:
mkdir -p /tmp/pc-deps && cd /tmp/pc-deps && npm init -y >/dev/null
npm install --no-audit --no-fund --ignore-scripts \
github:omdsh-dev/dsh-plugin-check \
@deepseek-ai/dsh-tools @deepseek-ai/dsh-invariants @deepseek-ai/cordis
cd /path/to/dsh-quota-panel
PLUGIN_CHECK_DEPS=/tmp/pc-deps node scripts/plugin-check.mjs .
To upgrade the vendored schema library: replace the two runtime files
under src/vendor/ and rewrite the cosmokit import on line 1 of
schemastery.mjs to "./cosmokit.js", then rebuild.
Contributing
Pull requests are welcome! 🎉 Whether it is a new provider adapter
(the catalog + auto-discovery pipeline makes adding one mostly declarative
— see the [Volcengine Ark PR][pr4] for a complete reference implementation, including the first AK/SK-signed provider), a bug fix, a UI tweak, or docs improvements.
Before opening a PR:
1. Follow Local development to build and run the
dual-face checks (npm run build && npm test) — CI rejects a stale
lib/, so rebuild and commit the artifacts after editing src/;
2. Add test assertions in scripts/test-page-script.mjs covering the new
behavior (mocked upstream + normalized row view);
3. Update both README.md and README.zh.md if the change is
user-facing.
For provider requests without an OpenAPI endpoint (Cookie / CLI-only
plans), open an issue first so we can discuss feasibility.
[pr4]: https://github.com/wenzetan/dsh-quota-panel/pull/4
License
MIT预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
wenzetan/dsh-quota-panel
dsh-quota-panel 是 DeepSeek HarnessDSHWeb 界面dsh web的服务商额度 /…
相关插件 · 模型接入
API 中继安全审计toby-bridges/api-relay-audit
面向 AI API 中转与 LLM 代理的本地安全审计。
★ 897已汉化DSH
69.4
免费搜索插件DDDMUC/dsh-free-search
DeepSeek Harness 免费搜索插件 —— 无需 API key,零成本,多引擎可切换。 一个给…
★ 883已汉化DSH
68.9
免费联网搜索liustack/modsearch
在官方 App 里模型能联网,切到 API 就不能了。ModSearch 把联网补回来:网页搜索、X…
★ 863已汉化DSH
68.5
OpenCode 免费模型FishBottle7/opencode2dsh
在 DSHDeepSeek Harness里原生使用 OpenCode Zen 的免费匿名模型。
★ 387已汉化DSH
67.8
WorkBuddy 账号池XDTrees/dsh-xdpool
把你能白嫖的模型额度接进 DSH 同一个池:WorkBuddy 多账号自动容错、十三家扫码登录、76…
★ 415已汉化DSH
67.7
AI 模型网关tingly-dev/tingly-box
Tingly Box Web UI 演示
★ 373已汉化DSH
67.4
这个插件是你维护的吗?
作者本人可认领并核对本条目;认领通过后,详情页会显示「作者已认领」标记。