dsh-usage-stats

96Star15Fork6Issue0Watching

为 DSH 网页端提供多供应商账户余额、Token Plan 额度与每日 Token 用量热图,统一展示在侧边栏浮层面板里。

机审证据安装命令仓库已核验dsh-plugin Topic许可证READMEAI 百科
语言
JavaScript
License
MIT
分支
main
deepseekdeepseek-harnessdeepseek-harness-plugindeepseek-harness-plugin-devdeepseek-harness-pluginsdshdsh-plugindsh-plugins

安装

$ dsh plugin --profile web add github:Ychris12138/dsh-usage-stats

在终端中运行以上命令,通过 dsh CLI 安装此插件。可在右上角切换 Profile。 第一次用 dsh?看这篇新手教程

对话式安装

帮我安装 DeepSeek Harness 插件 Ychris12138/dsh-usage-stats:先查看仓库 https://github.com/Ychris12138/dsh-usage-stats.git 确认安全性,然后执行安装命令并验证插件加载成功。

把这段指令粘贴给 DSH Web GUI 里的助手,由它代你完成安装与验证。

一句话定位

为 DeepSeek Harness 网页端补充多供应商账户余额、订阅 / Token Plan 额度窗口、按天按 provider/model 聚合的 Token 用量与缓存命中率,统一收口在侧边栏底部一个浮层面板里。普通用户在 dsh web 里就能看到今天烧了多少 Token、当前账户还能用多久,而不用切到每个供应商自己的控制台。

核心能力

  • 在侧边栏底部新增"用量/余额"入口:点开后是浮层面板,一次只显示当前选中的 provider,标题栏可手动刷新(同时刷新 Token、provider 列表、当前账户)
  • 每日 Token 用量统计:今日、本月、累计、缓存命中率、按日期/provider/model 下钻;同模型来自不同 provider 会分别归集(例如 deepseek-official · deepseek-chatark · deepseek-chat
  • 类 Codex 蓝色月历热图:方格按当月最大值的平方根连续映射(零是中性灰"空"),点击日期展开当天的 provider/model 明细与命中条
  • 多供应商余额统一卡片:DeepSeek、OpenRouter、Moonshot、Z.ai、New API、Sub2API、Passion、通用余额模板,按"normal/warning/critical"剩余比例上色(默认 30%/10% 阈值)
  • 订阅 / Token Plan 额度窗口:OpenCode Go 滚动用量、Z.ai Coding Plan(支持中国区 bigmodel-cn)、Kimi For Coding、MiniMax Coding Plan(支持 cn 区域),每窗口显示剩余比例与重置时间
  • 后台自动监测:服务端启动即刷新一次,之后每 5 分钟刷新所有已配置账户与本地 Token 聚合;浏览器只请求当前 provider,刷新频率与面板是否打开无关

技术实现

  • 语言: JavaScript(ESM;lib/ 下 5 个 .js 文件,客户端 bundle 单文件 1464 行手写,无构建步骤)
  • 关键依赖: 纯 Node.js 内置模块——node:fs/promises(缓存原子写)、node:http/node:https/node:dns/node:net(上游请求 + DNS 解析 + IP 过滤)、node:path/node:os(DSH_HOME 解析)。客户端用宿主 bundle 提供的 React 18 与 @deepseek-ai/dsh-client-ui-primitives
  • 架构模式: dual-half 宿主插件。cordis.patch.yml 在 web profile 插入 1 行 Loader(id: usage-stats, name: dsh-usage-stats);package.json#dsh.bundle.patch 指向 patch;服务端 apply(ctx, rawConfig) 注册 5 个 exact GET 路由并启动 5 分钟定时器;客户端通过 __ModuleLoader__ 注入 sidebar.footer.action 插槽,用 React.createPortal 把浮层挂到 document.body 避免侧边栏主题变量泄漏
  • 入口文件: 服务端 lib/index.jsapply / name = "usage-stats" / Config = { ~standard: ... });客户端 lib/client.js;账户适配器 lib/accounts.js;Token 聚合 lib/usage.js;余额方案 lib/balance.js;订阅窗口 lib/subscriptions.js

适用场景

DSH 用户希望把多个 LLM 供应商的"还剩多少钱/多少额度/今天烧了多少 Token"集中在一处查看,特别是同时使用 DeepSeek 官方 + 几家 Coding Plan + 自建 New API/Sub2API 中转的开发者。本插件不展示模型本身或对话历史,只在原有的侧边栏新增一个独立的浮层面板,对工作流零侵入。

前置依赖与兼容性

依赖最低版本说明
DeepSeek Harness (DSH)>=0.1.0-rc.6README 明确要求 @deepseek-ai/dsh >= 0.1.0-rc.6,使用 web profile
Node.js未声明package.jsonengines 字段;脚本使用 node:fs/promisesnode:dns/promises 等内置模块,安装器为单文件 .mjs
平台跨平台全部为纯 JS,无原生模块;缓存走 node:fs 原子写,DNS 解析与 HTTP 请求使用内置模块
原生模块第三方依赖仅有 react/react-dom devDependency,运行时无任何 *.node
网络需访问上游账户接口(可选)余额端点按 provider 配置:DeepSeek api.deepseek.com、OpenRouter openrouter.ai、OpenCode Go opencode.ai、Z.ai api.z.aiopen.bigmodel.cn、Kimi api.kimi.com、MiniMax www.minimax.io/www.minimaxi.com;本地 Token 聚合无需外网

安装方式

dsh plugin --profile web add github:Ychris12138/dsh-usage-stats

也可走 npx 兼容安装:npx --yes github:Ychris12138/dsh-usage-stats,支持 --dry-run / --check / --no-enable。安装或更新后必须重启已运行的 dsh web,并在浏览器硬刷新加载新的客户端 bundle。

配置项

插件开箱即用——无需任何 config 也能在侧边栏看到 Token 用量热图;下面所有字段均为可选,仅当你想让面板显示某个 provider 的余额/Token Plan 时才需要填。配置写在 ~/.dsh/profiles/web/cordis.patch.yml 中已有的 name: dsh-usage-stats entry 的 config.monitors 下(不要新开第二个插件 entry,否则会重复挂载)。

配置类型说明默认值
monitors.<providerId>object启用某个 provider 的余额/订阅监测;key 必须是 Harness 中真实存在的 provider id,未知 provider/adapter/非法映射会在路由注册前阻止插件启动不填则只显示 Token 热图
monitors.<providerId>.adapterenum适配器:deepseek-balance / openrouter-balance / moonshot-balance / zai-balance / new-api / sub2api / general / opencode-go / zai-token-plan / kimi-token-plan / minimax-token-plan / declarative。不填时按 baseURL 域名自动判别(passionapi.com → sub2api),其余走内置余额方案按域名自动判别
monitors.<providerId>.credentialRefstring凭据引用名(如 OPENROUTER_MANAGEMENT_KEY);插件不存 Key 值,只在请求时通过 Harness credentials seam 解析余额型 adapter 用对应 provider 的 apiKeyEnv
monitors.<providerId>.usageBaseURLURL覆盖 provider 的账户接口基地址;禁止内嵌 username/password,默认要求 HTTPSprovider 配置的 baseURL
monitors.<providerId>.allowInsecureboolean允许 usageBaseURL 使用 http://(仅在你控制的内网且显式同意时)false
monitors.<providerId>.fallbackCredentialRef / .fallbackUserIdRefstringNew API 在 /api/usage/token/ 返回 404/405 时回退到 /api/user/self 的管理 PAT 与 User ID(不会拿推理 Token 当管理凭据)不启用 fallback
monitors.<providerId>.warning.warnBelow / .warning.criticalBelownumber余额绝对值阈值;剩余 ≤ criticalBelow 标红、≤ warnBelow 标黄(criticalBelow 必须 ≤ warnBelow)。具有总额度的余额 / Token Plan 也会自动按 30%/10% 比例上色不启用自定义阈值
monitors.<providerId>.mode"balance" / "subscription"仅 declarative adapter 需要,指定解析后的视图类型必填
monitors.<providerId>.request.pathstring同源相对路径(如 /account/balance),不支持绝对 URL 或 protocol-relative 路径;method 仅接受 GET;body 上限 1 MiB必填
monitors.<providerId>.request.auth.type"bearer" / "raw" / "x-api-key"凭据注入方式,credentialRef 指向 ~/.dsh/.credentials.yaml 中的变量名;Authorization/X-API-Key/API-Key 等敏感 header 不能在 request.headers 里直接覆盖,必须由 credential 引用注入bearer
monitors.<providerId>.request.headersobject额外 HTTP header(仅放非敏感 header);插件默认手动 redirect、仅 JSON 响应、1 MiB body 上限
monitors.<providerId>.extract.<field>JSON Pointer从上游响应里抽取字段(root / remaining / used / total / currency / items / kind / usedPercent / remainingPercent / resetsAt …);仅执行受限 GET + JSON Pointer,不执行 JavaScript;subscription 模式 items 必填按 adapter 内置
monitors.<providerId>.extract.divisornumber对应字段除以该数值再展示(如把"分"换算成"元");必须非零

常见问题

Q: 安装后侧边栏没看到"用量/余额"入口怎么办?

A: 安装或更新插件后必须重启已运行的 dsh web,并在浏览器硬刷新(Ctrl/Cmd+Shift+R)。插件的服务端路由与客户端 bundle 都在 dsh web 启动时挂载,只刷新浏览器不会重新装载。安装器在 cordis.patch.yml 写入一条 - insert: id: usage-stats, name: dsh-usage-stats,重复运行是幂等的,不会重复追加。

Q: 不配置 Key 能用吗?能看到什么?

A: Token 用量热图与缓存命中率完全无需任何凭据,会自动汇总所有 session 的事件流。没有公开余额端点的 provider 在账户卡片显示"不支持",插件不会乱猜余额;缺 Key 的 provider 显示"未配置"。OpenRouter 是唯一例外:官方账户 credits 必须用独立的 OPENROUTER_MANAGEMENT_KEY,插件不会拿普通推理 OPENROUTER_API_KEY 去试探 /api/v1/key

Q: 数据存在哪里?会不会上传?

A: 服务端聚合缓存只保存按 provider/model 折叠后的 Token 数、会话 id、不透明 revision 与折叠游标,写入 $DSH_HOME/storages/usage-stats-cache.json,采用临时文件 + 原子 rename 写入。API Key、OpenCode auth.json、Cookie、管理 PAT 与上游原始响应永远不会进入浏览器响应、插件缓存或日志。validate:live 脚本会逐会话对比插件端点与官方 token projection,结果不一致会返回非零退出码——但脚本可能输出真实余额,不要把输出贴到公开 issue。

Q: 能接入自己的私有供应商吗?

A: 可以,用 declarative adapter:在 monitor 下设置 mode: balancemode: subscriptionrequest.path(HTTPS 同源相对路径)、request.auth.type(bearer/raw/x-api-key)、extract.* JSON Pointer 字段。仅执行受限 GET + JSON Pointer,不执行 JavaScript。凭据只能通过 credential 引用注入,usageBaseURL 不允许内嵌 username/password;敏感 header(Authorization/X-API-Key/API-Key/Cookie 等)必须在 request.headers 里被插件拒绝直接覆盖。发凭据前会筛选域名的 IPv4/IPv6 解析结果并固定一个允许的连接地址,优先使用公网地址。

Q: OpenCode Go 额度突然不可用 / 接口变 401 怎么办?

A: OpenCode Go 的 Bearer usage 端点(opencode.ai/zen/go/v1/usage)不是官方公开 API,上游可能随时调整结构;接口变化时面板会显示具体错误信息。可在 monitors.opencode-go 下显式设置 credentialRef: OPENCODE_GO_API_KEY,或回退到 OPENCODE_GO_AUTH_COOKIE + OPENCODE_GO_WORKSPACE_ID 的 cookie 兼容方案(plugin 会优先用 Harness credential,其次读 ~/.local/share/opencode/auth.json,最后才用 cookie)。不想用时直接从 Cordis entry 里删掉对应 monitor 即可停用。

Q: 反向代理能否把这五个端点暴露到公网?

A: 不建议。五个端点(/api/usage-stats/{usage,providers,balance,subscriptions,account})只校验 peer socket 是否回环 + Host header,不做身份认证;如果挂在反代后面,插件看到的 peer 会是代理自身的回环地址,等同绕过安全边界。README 与 SECURITY.md 都明确"不要把端点经反向代理暴露到局域网或公网;确需代理时必须在代理层增加可靠认证与访问控制"。安全问题请按 SECURITY.md 描述私下报告。

Q: 如何卸载?

A: dsh plugin --profile web remove dsh-usage-stats 重启 dsh web 即可。缓存文件 $DSH_HOME/storages/usage-stats-cache.json 留在磁盘上,需要时手动删除;安装器写入的 cordis patch 也会被一并清理。安装器不会动 ~/.dsh/.credentials.yaml

上手难度

入门 — 一条 dsh plugin --profile web add + 重启 dsh web 即在侧边栏看到"用量/余额"入口,Token 用量统计自动可用。进阶处在于阅读 README 里 monitors.<providerId> 的 YAML 配置示例,给 OpenRouter、OpenCode Go、各家 Coding Plan 与自建中转(New API / Sub2API / Passion / declarative)配上对应的 adapter 与 credential 引用。

已知问题与限制

  • OpenCode Go 的 Bearer usage 端点(opencode.ai/zen/go/v1/usage)为非官方公开 API:上游调整结构时额度面板会显示错误信息;可用 OPENCODE_GO_AUTH_COOKIE + OPENCODE_GO_WORKSPACE_ID cookie 兼容回退,不愿用可直接删 monitor 关闭
  • DSH 客户端侧边栏布局是 ROW 排布:本插件作为第二个 footer action 会触发宿主布局把后面条目挤出可视区——插件通过把宿主容器临时切到 column 布局规避(见 client.js 中 flexDirection 切换 effect,issue #21 已记录)
  • 部分第三方 Coding Plan 仅余额可用:Kimi Code 5 小时 / 周窗、Z.ai 部分接口若上游结构变化需等适配;Anthropic OAuth、OpenAI Codex、Gemini Code Assist、GitHub Copilot 个人版暂无 API-Key 化用量端点
  • DSH 重启后会以压缩摘要恢复活跃会话:插件发现内存事件游标低于折叠游标时会整会话重新折叠统计(issue #23 已记录),重启后短时间内用量数字会先"回滚"再追平
  • 账户卡片在 panel 容器内 portal 到 document.body:避免侧边栏主题变量泄漏进浮层(issue #17 已记录),但因此与侧边栏的视觉层级完全独立
  • 自定义 monitor 默认要求 HTTPS + 同源相对路径 + 手动 redirect + JSON + 1 MiB 上限:allowInsecure 必须显式开启才能用 HTTP;198.18.0.0/15 区间仅作为 Clash/Mihomo 风格 fake-IP 的合成地址接受(仅 HTTPS 域名),字面 IP 与其它私网地址默认拒绝,防止 DNS rebinding 绕过
  • 安装 / 更新插件后必须重启 dsh web:服务端 exact 路由、5 分钟定时器与客户端 bundle 均在 dsh web 启动时挂载,只刷新浏览器不会重新装载
  • dsh pluginnpx 是两条独立的安装路径:不要同时保留手工 cordis entry 与 bundle 注册,否则会重复挂载;安装器在写入前会校验 YAML 根节点不为空 [],历史版本留下的 [] 残根会被自动清理

收录徽章

Listed on deepseek-plugin.org
[![Listed on deepseek-plugin.org](https://img.shields.io/badge/listed_on-deepseek--plugin.org-007EC6)](https://deepseek-plugin.org/plugins/Ychris12138/dsh-usage-stats)

把这段 markdown 粘贴到你的 GitHub README,链接回本插件详情页。徽章只声明已被本站收录,不代表安全认证。

返回插件目录