
Security News
Deno Goes the Way of the Dinosaur
Cloudflare is acquiring Deno’s team, which will provide another year of bug fixes and security updates before ending support for the runtime.
dsh-usage-display
Advanced tools
多厂商余额/用量徽标(内置 DeepSeek 余额与智谱 GLM Coding Plan 配额):host 侧按轮次事件取数,经 SSE 同步到浏览器展示。
在 dsh Web 界面显示模型厂商余额 / 套餐用量的会话头部徽标插件。host 进程从各家 厂商官方接口取数并缓存,浏览器侧只读本地路由渲染;API key 始终留在 host, 不会下发到浏览器。
内置三家厂商,按多厂商适配器架构组织,新增厂商只需实现一个 adapter:
| 厂商 | providerId | 展示内容 |
|---|---|---|
| DeepSeek | deepseek | 多币种账户余额(granted / topped-up 拆分) |
| MiniMax | minimax | Token Plan 配额(5 小时窗口与周窗口) |
| 智谱 GLM | zhipu | Coding Plan 配额(5h、周限额、工具用量三个百分比) |
设置页(Settings → Plugins → “用量与余额”)可按通用显示 / DeepSeek / MiniMax / 智谱 GLM 分区调整展示偏好与告警阈值,保存后立即生效:

display.panelStyle),徽标可用 auto 按指标类型自动选择。turn/start 与 turn/end 各全量刷新一次,切换模型时
只定向刷新新选中的厂商。# 1. 安装依赖并构建(产出 lib/index.js 与 lib/client.js)
pnpm install
pnpm run build
# 2. 安装进 web profile(在插件目录内执行 `add .` 等价;-w 按 workspace 链接)
dsh plugin --profile web add -w D:/Code/dsh-usage-display
# 3. 验证组合层,然后启动
dsh web --dump-config
dsh web
Windows 下路径务必用正斜杠,反斜杠会被解析成非法包名(如 Codedsh-usage-display)。
-w 需要保留:profile 自带 pnpm-workspace.yaml。
卸载:dsh plugin --profile web remove dsh-usage-display。
pnpm add dsh-usage-display(或 npm i dsh-usage-display)后执行
dsh plugin --profile web add dsh-usage-display;prepare 脚本会在安装时构建。pnpm pack 后执行 dsh plugin --profile web add ./dsh-usage-display-<version>.tgz,
分发的是预构建产物,用户侧无需构建授权。dsh plugin --profile web add github:deluo/dsh-usage-display。源码包由 prepare
脚本构建;pnpm ≥ 10 默认拒绝,需按提示在该 profile 的 pnpm-workspace.yaml 中给
allowBuilds 授权后重试。默认配置见 cordis.patch.yml,用户可在 profile 或 home 级的
cordis.patch.yml 中覆盖(后应用层整行替换):
dsh-usage-display:
display:
badgeStyle: 'auto' # auto | text | ring | bar;徽标上的进度形态
panelStyle: 'ring' # text | ring | bar;面板里 percent 指标的形态
showResetCountdown: true # 徽标配额文案是否带“距重置”倒计时
providers:
deepseek:
enabled: true # 关闭后显示“已停用”,不再取数
routeIds: ['deepseek-official'] # dsh provider 路由 id → 本插件 providerId(providerId 自动补入)
apiKeyEnv: 'DEEPSEEK_API_KEY' # 凭证引用名,不是 key
baseURL: 'https://api.deepseek.com'
badgeCurrency: 'CNY' # 徽标主币种;账户无此币种时保持接口返回顺序
warnBelow: 10 # 余额低于此值 → warn;'off' 关闭
criticalBelow: 5 # 余额低于此值 → critical;'off' 关闭
minimax:
enabled: true
routeIds: ['minimax', 'minimax-cn', 'minimaxi', 'minimax-coding-plan', 'minimax-token-plan']
apiKeyEnv: 'MINIMAX_API_KEY' # 只存引用名,key 由 host 运行时解析
apiKeyAliases:
[
'MINIMAX_TOKEN_PLAN_API_KEY',
'MINIMAX_CODING_PLAN_API_KEY',
'MINIMAX_CODING_API_KEY',
'MINIMAX_CN_API_KEY',
'MINIMAX_API_KEY',
'MINIMAX_API_TOKEN',
]
baseURL: 'https://api.minimaxi.com' # 含 minimaxi.com 走国内站,否则走 api.minimax.io
badgeMetric: '5h' # 徽标主指标:5h | weekly
resetTimeStyle: 'countdown' # 重置时间:countdown 倒计时 | time 本地时间点
warnAbovePercent: 80 # 用量超过此百分比 → warn;'off' 关闭
criticalAbovePercent: 90 # 用量超过此百分比 → critical;'off' 关闭
zhipu:
enabled: true
routeIds: ['zai-coding-cn', 'zai-coding', 'zai', 'glm', 'zhipu', 'bigmodel', 'zhipuai']
apiKeyEnv: 'ZHIPU_API_KEY'
apiKeyAliases:
[
'ZAI_CODING_CN_API_KEY',
'ZAI_CODING_API_KEY',
'GLM_API_KEY',
'ZAI_API_KEY',
'BIGMODEL_API_KEY',
]
baseURL: 'https://open.bigmodel.cn'
authStyle: 'raw' # 'raw' | 'bearer'
badgeMetric: '5h' # 徽标主指标:5h | weekly | tools
resetTimeStyle: 'countdown' # 重置时间:countdown 倒计时 | time 本地时间点
warnAbovePercent: 80 # 用量超过此百分比 → warn;'off' 关闭
criticalAbovePercent: 90 # 用量超过此百分比 → critical;'off' 关闭
公共字段:
| 字段 | 类型 | 默认 | 说明 |
|---|---|---|---|
enabled | boolean | true | 关闭后徽标显示“用量已停用”,不再取数 |
routeIds | string[] | [] | dsh provider 路由 id → 本插件 providerId,用于模型切换联动;providerId 本身总会自动加入映射 |
展示偏好(插件级 display):
| 字段 | 类型 | 默认 | 说明 |
|---|---|---|---|
badgeStyle | 'auto' | 'text' | 'ring' | 'bar' | 'auto' | 徽标进度形态;auto 对 percent 指标用迷你条形图、金额保持纯文本 |
panelStyle | 'text' | 'ring' | 'bar' | 'ring' | 面板中 percent 指标的形态 |
showResetCountdown | boolean | true | 徽标配额文案是否带“距重置”倒计时 |
DeepSeek 专属:
| 字段 | 类型 | 默认 | 说明 |
|---|---|---|---|
routeIds | string[] | ['deepseek-official'] | DeepSeek 官方 harness 适配器上报的 provider 路由 id;deepseek 作为 providerId 仍会自动加入 |
apiKeyEnv | string | DEEPSEEK_API_KEY | 凭证引用名,请求 GET {baseURL}/user/balance 时使用 |
baseURL | string | https://api.deepseek.com | 余额接口前缀 |
badgeCurrency | string | CNY | 徽标主币种(按接口返回的 currency 匹配,大小写不敏感);无此币种时保持接口顺序 |
warnBelow | number | 'off' | 10 | 余额低于此值徽标变黄 |
criticalBelow | number | 'off' | 5 | 余额低于此值徽标变红 |
智谱专属:
| 字段 | 类型 | 默认 | 说明 |
|---|---|---|---|
apiKeyEnv | string | ZHIPU_API_KEY | 首选凭证引用名 |
apiKeyAliases | string[] | 见上 | 首选未配置时按顺序回退;指向模型适配器已在用的引用名即可直接复用其 key |
baseURL | string | https://open.bigmodel.cn | 实际请求 host 按域名路由:含 bigmodel.cn → open.bigmodel.cn,否则 api.z.ai |
authStyle | 'raw' | 'bearer' | 'raw' | 首选鉴权头风格;401/403 自动换另一种重试,非法值在配置层直接报错 |
badgeMetric | '5h' | 'weekly' | 'tools' | '5h' | 徽标主指标 |
resetTimeStyle | 'countdown' | 'time' | 'countdown' | 重置时间展示:countdown 显示紧凑倒计时(如 2h13m、2d3h);time 显示本地时间点(如 15:30、明天 08:30) |
warnAbovePercent | number | 'off' | 80 | 用量超过此百分比徽标变黄 |
criticalAbovePercent | number | 'off' | 90 | 用量超过此百分比徽标变红 |
MiniMax Token Plan 专属:
| 字段 | 类型 | 默认 | 说明 |
|---|---|---|---|
routeIds | string[] | ['minimax', 'minimax-cn', 'minimaxi', 'minimax-coding-plan', 'minimax-token-plan'] | dsh provider 路由 id → 本插件 providerId |
apiKeyEnv | string | MINIMAX_API_KEY | 首选凭证引用名 |
apiKeyAliases | string[] | 多个 Token Plan / Coding Plan / CN 别名 | 首选未配置时按顺序回退 |
baseURL | string | https://api.minimaxi.com | 区域识别基准地址;含 minimaxi.com 走国内站,否则走 api.minimax.io |
badgeMetric | '5h' | 'weekly' | '5h' | 徽标主指标 |
resetTimeStyle | 'countdown' | 'time' | 'countdown' | 重置时间展示形态 |
warnAbovePercent | number | 'off' | 80 | 用量超过此百分比徽标变黄 |
criticalAbovePercent | number | 'off' | 90 | 用量超过此百分比徽标变红 |
warn* / critical* 配反(如 warnBelow 小于 criticalBelow)时按更严格的方向归一;
全部设为 'off' 关闭该厂商的告警染色。
配置里从不出现 key 本身。apiKeyEnv / apiKeyAliases 都是凭证引用名,host 每次取数时
经 ctx.credentials.resolve() 解析:进程环境优先,其次 $DSH_HOME/.credentials.yaml
(Models 页 / dsh credentials set 写入),再以项目与用户的 .env 回退。模型侧已配置的
智谱 key 可以直接复用——把 apiKeyEnv 指向模型适配器所用的引用名(dsh web --dump-config
可查到);托管存储里的 key 变更下次取数即生效,进程 env 的快照在启动时冻结。
display.panelStyle 渲染为环形图、条形图或
纯数字表格。手动刷新会等待真实取数落定。countdown 显示 2h13m / 2d3h 等
倒计时,time 显示 15:30、明天 08:30、周三 08:30 等本地时间点。enabled / routeIds /
apiKeyEnv / baseURL / authStyle 等接入类字段不在此暴露,仍在
cordis.patch.yml 中维护。routeIds 未覆盖)时徽标进入中性态显示“其他厂商”,面板列出
全部已接入厂商。loading / ok / unconfigured / disabled / error;失败时展示
上次成功值并标注原更新时间。调试与二次集成用:
GET /plugins/dsh-usage-display/balance[?refresh=1] # 聚合快照;refresh=1 强制真实取数
GET /plugins/dsh-usage-display/events # SSE:balance-updated 事件 + 15s 心跳
/balance 只接受 GET,其余方法返回 405。响应示例:
{
"providers": [
{
"providerId": "deepseek",
"displayName": "DeepSeek",
"kind": "balance",
"status": "ok",
"isAvailable": true,
"metrics": [
{
"key": "cny",
"label": "CNY 余额",
"kind": "amount",
"remaining": 110.0,
"unit": "CNY",
"detail": { "granted": "10.00", "toppedUp": "100.00" },
"severity": "ok"
}
],
"fetchedAt": "2026-08-18T10:00:00.000Z",
"cached": false,
"severity": "ok"
},
{
"providerId": "minimax",
"displayName": "MiniMax Token Plan",
"kind": "quota",
"status": "ok",
"isAvailable": true,
"plan": "Max",
"metrics": [
{
"key": "5h",
"label": "5h限额",
"kind": "percent",
"used": 28,
"resetsAt": "2026-08-18T13:00:00.000Z"
},
{ "key": "weekly", "label": "周限额", "kind": "percent", "used": 45 }
],
"fetchedAt": "2026-08-18T10:00:00.000Z",
"cached": false
},
{
"providerId": "zhipu",
"displayName": "智谱 GLM",
"kind": "quota",
"status": "ok",
"isAvailable": true,
"plan": "pro",
"metrics": [
{
"key": "5h",
"label": "5h限额",
"kind": "percent",
"used": 28,
"resetsAt": "2026-08-18T13:00:00.000Z"
},
{ "key": "weekly", "label": "周限额", "kind": "percent", "used": 12 },
{ "key": "tools", "label": "工具用量", "kind": "percent", "used": 8 }
],
"fetchedAt": "2026-08-18T10:00:00.000Z",
"cached": false
}
],
"activeBySession": { "<会话id>": { "providerId": "zhipu", "model": "glm-4.7" } },
"routes": {
"deepseek-official": "deepseek",
"deepseek": "deepseek",
"minimax": "minimax",
"minimax-cn": "minimax",
"zai": "zhipu",
"glm": "zhipu"
},
"display": { "badgeStyle": "auto", "panelStyle": "ring", "showResetCountdown": true },
"providerDisplay": {
"minimax": { "resetTimeStyle": "countdown" },
"zhipu": { "resetTimeStyle": "countdown" }
}
}
普通读只返回本地缓存(cached: true),不会触发厂商 API;?refresh=1 等待取数并返回
新鲜快照(cached: false)。
dsh-usage-display/
├── package.json # 双面插件声明(dsh.bundle + dsh.client)
├── cordis.patch.yml # host loader 行与默认配置
├── tsconfig.json # 类型检查配置
├── tsdown.config.ts # host / client 双 bundle 构建
├── scripts/
│ ├── smoke-client.mjs # 客户端 bundle 冒烟测试
│ └── smoke-host.mjs # host 编排冒烟测试
└── src/
├── index.ts # host 入口:HTTP 路由 + SSE + 会话事件编排
├── types.ts # 两侧共用的快照 / 指标契约
├── settings.ts # 设置页可调子集目录(各厂商 tunable 类型聚合)
├── core/
│ ├── registry.ts # 厂商注册表:schema / tunable 抽取合并 / 展示偏好聚合
│ └── usage-service.ts # 缓存 / in-flight 去重 / 故障隔离
├── providers/
│ ├── types.ts # ProviderAdapter SPI
│ ├── deepseek.ts # DeepSeek 余额适配器
│ ├── minimax.ts # MiniMax Token Plan 配额适配器
│ └── zhipu.ts # 智谱 GLM 配额适配器
└── client/
├── index.ts # 浏览器入口:读取快照 + 注册徽标
├── routes.ts # 本地路由常量(与 host 侧对齐)
├── usage-store.ts
├── UsageBadge.tsx
└── SettingsTab.tsx # 设置页(Plugins 分区 tab)
src/providers/<id>.ts 实现 ProviderModule,fetch() 负责取数并把 wire 格式
归一化为 ProviderSnapshot(异常在内部吞掉并返回 error 快照,正常路径不 throw);
指标 kind 支持 amount / window / percent。如需设置页热更新,模块里声明
tunable(schema + extract + merge)与可选的 display 偏好,字段默认值只在模块内
维护一份。src/index.ts 的 createRegistry([deepseek, minimax, zhipu]) 中登记模块,并在
SETTINGS_SCHEMA 里补一行该厂商的 tunable.schema。src/settings.ts 补该厂商的可调类型,客户端 SettingsTab.tsx 按需要增加分区。cordis.patch.yml 补该厂商的默认配置(只写需要覆盖的字段,其余交给 schema 默认值)。pnpm run build 后按开发流程验证。最小骨架:
// src/providers/acme.ts
// (z 来自 @deepseek-ai/schemastery;withCommonConfig / ProviderModule / ProviderAdapter
// 来自 providers/types.ts,此处省略 import 语句)
export const acme: ProviderModule<AcmeConfig, AcmeTunable, 'acme'> = {
id: 'acme',
displayName: 'Acme',
kind: 'balance', // 或 'quota'
config: withCommonConfig({
apiKeyEnv: z.string().default('ACME_API_KEY'),
baseURL: z.string().default('https://api.acme.example'),
// 如需设置页热更新:把可调字段与 tunable schema 共用一份定义
}),
// tunable / display 可选,缺省即没有设置页热更新与专属展示偏好
create: (ctx, config) => new AcmeAdapter(ctx, config),
}
class AcmeAdapter implements ProviderAdapter {
readonly id = 'acme'
readonly displayName = 'Acme'
readonly kind = 'balance' as const
async fetch(): Promise<ProviderSnapshot> {
// 取数 + 归一化;错误时返回 status: 'error' 的快照
}
}
pnpm install
pnpm run build # 产出 lib/index.js(host ESM)与 lib/client.js(浏览器 loader 闭包)
pnpm run typecheck # tsc --noEmit(基于 npm 发布的 @deepseek-ai 类型)
pnpm run format # prettier 统一格式化(提交前执行;format:check 仅检查)
pnpm run smoke # 客户端 bundle 冒烟:mock 模块加载器 + mock ctx,无需浏览器
pnpm run smoke:host # host 冒烟:多厂商编排、模型切换联动、鉴权重试,无需 key
迭代循环:改 host 半 → pnpm run build → 重启 dsh web;改 client 半 → pnpm run build
→ 刷新页面。本地 node_modules 里的 @deepseek-ai/* 来自 npm 发布版本,若运行中的 dsh
版本接口有变化,请同步 peerDependencies 后重新 pnpm install。
127.0.0.1,若绑定 0.0.0.0 会把这些只读端点暴露到网络。turn/end 对空轮次(输入被拒等)也会发出,多一次无害的余额查询。MIT
FAQs
多厂商余额/用量徽标(内置 DeepSeek 余额与智谱 GLM Coding Plan 配额):host 侧按轮次事件取数,经 SSE 同步到浏览器展示。
The npm package dsh-usage-display receives a total of 30 weekly downloads. As such, dsh-usage-display popularity was classified as not popular.
We found that dsh-usage-display demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Security News
Cloudflare is acquiring Deno’s team, which will provide another year of bug fixes and security updates before ending support for the runtime.

Security News
Anthropic’s free OSS Scanner uses Mythos and other Claude models to find open source vulnerabilities and send maintainers reports with proposed fixes.

Security News
On Front Lines’ Early Adopters: CISO podcast, Andrew Becherer shares lessons from Datadog, weighs the long-term costs of AI-built tools, and explains how founders can actually gain a CISO’s trust.