npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@andrecgoncalves/dsh-balance

v0.4.1

Published

Provider-aware account balance chip for the DeepSeek Harness web sidebar: DeepSeek, OpenRouter, Moonshot/Kimi, Zhipu/GLM, and MiniMax.

Readme

dsh-balance

npm 包 GitHub 发布 CI 许可证:MIT node >= 22.18 DeepSeek Harness

English | 中文

一个 DeepSeek Harness 插件:在侧边栏底部、紧挨设置按钮的右侧,显示当前活跃模型所属服务商的账户余额,并保持实时刷新。

这个余额胶囊是感知服务商的:它会读取当前会话所选的模型,显示对应服务商的余额,并在你切换模型时自动跟着切换。

在 DeepSeek 上,胶囊还会跟踪高峰 / 空闲计费时段——状态圆点在 DeepSeek 高峰时段内变红,空闲时段变绿(此时请求按半价计费)。详见 DeepSeek 高峰 / 空闲时段

目录

为什么选择 dsh-balance?

  • 感知服务商,不止 DeepSeek。 它会跟随当前活跃模型所属的服务商,覆盖 DeepSeek、OpenRouter、Moonshot/Kimi、Zhipu/GLM 与 MiniMax——切换模型时胶囊立即切换。
  • 只做一件事的最小实现。 没有设置面板、没有费用估算、没有额外服务。一条路由,一个胶囊,gzip 后约 11 kB。
  • 对核心零侵入。 一个树外包,注册到已声明的插槽,不会修改或 fork Harness 源码中的任何文件。

轻量设计

dsh-balance 刻意保持极简,不给 Harness 增加任何机制:

| | | |---|---| | 运行时依赖 | —— dependencies: {};唯一的 import 是 @deepseek-ai/* 平台模块与 React,均由运行中的 Harness 以可选 peer 提供 | | 产物体积 | 宿主端 约 8 kB(gzip 3.1 kB)+ 浏览器端 约 23 kB(gzip 8.1 kB)→ gzip 合计约 11 kB | | Harness 接触面 | 一条精确路由(GET /plugins/balance)与已声明 sidebar.footer.action 插槽中的一个组件 | | 核心补丁 | —— 不 fork 文件、不修补核心 CSS;插件只从自己的 DOM 锚点设置自己那一行底栏的样式 | | 后台任务 | 无 —— 没有数据库、没有 worker、没有遥测、没有全局状态;每个胶囊只有一个 setInterval,卸载时清除 | | 生命周期 | 路由通过 ctx.effect 注册,卸载时自动回收;模型目录订阅会取消订阅;卸载插件后不会留下任何残留 | | 故障隔离 | 缺少密钥或上游出错时降级为灰色胶囊,绝不会阻塞会话或界面 |

无需配置,也无需清理。 安装后唯一的变化是侧边栏底部多了一行;卸载后 Harness 与原来完全一致。

亮点

  • 一个胶囊,五家服务商。 DeepSeek、OpenRouter、Moonshot/Kimi、Zhipu/GLM(Z.ai)与 MiniMax——各自带有品牌图标、货币单位与悬停明细。
  • 感知服务商。 切换活跃模型,胶囊立即切换到对应服务商的余额。
  • 在 DeepSeek 上感知高峰/空闲。 状态圆点在 DeepSeek 高峰计费时段(周一至周五,北京时间 09:00–12:00 与 14:00–18:00)变红,空闲时段变绿(此时请求按半价计费)。
  • 密钥永不进入浏览器。 由宿主端解析凭证并请求服务商,浏览器只会看到归一化后的余额数据。
  • 实时更新。 每 60 秒自动刷新,点击刷新,会话变化时刷新,模型所属服务商变化时立即刷新。
  • 优雅降级。 缺少密钥或上游出错时,显示灰色的 Balance — 胶囊,原因写在悬停提示里,不会破坏布局。
  • 无需账号即可预览。 内置 mock 模式,可为任意服务商渲染出逼真的余额。

截图

支持的服务商

| 活跃模型路由 | 显示的余额 | 数据来源 | |---|---|---| | deepseekdeepseek-official | DeepSeek 账户余额(原币种) | api.deepseek.com/user/balance | | openrouter | 剩余额度(total_credits − total_usage,美元) | openrouter.ai/api/v1/credits | | moonshotaimoonshotai-cn | 可用余额(美元,现金 + 代金券) | api.moonshot.ai / api.moonshot.cn/v1/users/me/balance | | zaizai-coding-cnzhipu | 账户余额(默认人民币) | open.bigmodel.cn / api.z.ai 账户报表 | | minimaxminimax-cn | Token 套餐剩余额度(次数或百分比) | minimax.io / api.minimaxi.com/v1/token_plan/remains | | 其他任意路由 | DeepSeek 余额 | 与 deepseek 行相同 |

映射刻意保持克制:插件不认识的路由(包括自定义服务商 id)会回退到 DeepSeek 余额,而不是让胶囊报错。

胶囊显示什么

  • [品牌图标] $9.74 ● —— 服务商图标、金额,然后是状态圆点。
  • 状态圆点 —— DeepSeek 标记高峰/空闲计费时段(绿色 = 空闲,红色 = 高峰;详见 DeepSeek 高峰 / 空闲时段)。OpenRouter、Moonshot、Zhipu 和 MiniMax 标记剩余余额或额度是否为正(绿色 = 有余额,红色 = 已耗尽)。
  • 悬停提示 —— 完整明细(例如 Total $42.50 · Granted $5.00 · Topped up $37.50)。
  • 点击 —— 立即刷新。
  • 错误 —— 灰色 Balance — 胶囊;悬停查看原因,点击重试。
  • 侧边栏折叠为 56px 轨道时会隐藏该胶囊——齿轮旁边放不下。

DeepSeek 高峰 / 空闲时段

DeepSeek 的空闲时段价格为高峰时段的一半。胶囊通过状态圆点反映当前时段;判断基于 UTC 时间,因此与你的本地时区无关:

| 时段 | 时间 | |---|---| | 高峰 —— 红点 | 周一至周五,北京时间(UTC+8)09:00–12:0014:00–18:00,即 01:00–04:0006:00–10:00 UTC | | 空闲 —— 绿点 | 其余所有时间,包括整个周末,按高峰价的 5 折计费 |

来源:DeepSeek API —— 模型 & 价格 脚注 (1):「空闲时段价格为高峰时段价格的一半。高峰时段为北京时间周一至周五 9:00 - 12:00、14:00 - 18:00(其余为空闲时段)。」

在这五家服务商中,只有 DeepSeek 有固定的高峰 / 空闲时段。 其他服务商没有按时段定价,因此它们的圆点表示余额 / 额度,而不是计费时段:

| 服务商 | 按时段定价? | 实际采用的计费方式 | |---|---|---| | DeepSeek | —— 周一至周五为高峰,空闲时段半价 | —— | | OpenRouter | 无 | 透传上游价格,另加平台手续费 | | Moonshot / Kimi | 无 | 固定 token 单价,含缓存折扣 | | Zhipu / GLM(Z.ai) | 无 | 目录价,偶有限时促销 | | MiniMax | 无 | 固定 token 单价(M3 永久 5 折),另有可选的 1.5× 优先档 |

安装

前置条件:带有 web profile 的 DeepSeek Harness(dsh web)以及 Node.js ≥ 22.18。

插件是自包含的:不需要额外服务、不需要配置文件、不需要核心补丁。安装只会新增一个依赖和侧边栏中的一行。

从 npm 安装

pnpm dsh plugin --profile web add @andrecgoncalves/dsh-balance

从 GitHub 安装

pnpm dsh plugin --profile web add github:andregoncalves/dsh-balance

该包会在安装时自行构建(preparepnpm run build),因此无需把 lib/ 提交到仓库。

从本地克隆安装(开发用)

git clone https://github.com/andregoncalves/dsh-balance.git
cd dsh-balance
pnpm install
pnpm run build
pnpm dsh plugin --profile web add link:"$PWD"

请使用 link: 而不是 file::普通 file: 依赖使用硬链接,在原子化重建时会失效。

这一行是如何接入的

本包声明了 dsh.bundle,因此 dsh plugin add 会自动把它追加到 profile 的 dsh.profile.bundles,并由包内自带的 cordis.patch.yml 插入侧边栏那一行——无需手动修改补丁文件。首次安装后刷新一次浏览器,让启动清单(window.__DSH_BOOT__)识别新增的行;之后源码改动会重建并热替换。

把该 bundle 加入 ~/.dsh/profiles/web/package.json

"dsh": { "profile": { "bundles": ["@deepseek-ai/dsh-base", "@deepseek-ai/dsh-web-app", "@andrecgoncalves/dsh-balance"] } }

bundle 的补丁随后会插入该行。如果你更希望把它当作普通依赖,可以不走 dsh.bundle,而是自己在 ~/.dsh/profiles/web/cordis.patch.yml 中加入:

- insert:
    - id: dsh-balance
      name: "@andrecgoncalves/dsh-balance"

两种方式中,id 都是插件内部的 Cordis 名称,保持 dsh-balance 不变;name 是已安装的包名。

验证

curl http://127.0.0.1:3080/plugins/balance                    # DeepSeek
curl "http://127.0.0.1:3080/plugins/balance?kind=openrouter"  # OpenRouter
curl "http://127.0.0.1:3080/plugins/balance?kind=moonshot"    # Moonshot / Kimi
curl "http://127.0.0.1:3080/plugins/balance?kind=zhipu"       # Zhipu / GLM
curl "http://127.0.0.1:3080/plugins/balance?kind=minimax"     # MiniMax

每个接口返回 {"ok":true,"provider":"…","balance":{…}};当凭证缺失时返回 {"ok":false,"error":"no-key","message":"…"}

配置

DeepSeek 通过 Harness 的凭证接缝解析 DEEPSEEK_API_KEY(例如 ~/.dsh/.credentials.yaml)。其他服务商优先走凭证接缝,然后回退到启动环境(进程环境、调用项目目录下的 .env,最后是 Harness 主目录的 .env)。

| 服务商 | 依次尝试的凭证名 | |---|---| | DeepSeek | DEEPSEEK_API_KEY | | OpenRouter | OPENROUTER_API_KEY | | Moonshot / Kimi | MOONSHOT_API_KEY | | Zhipu / GLM | ZAI_API_KEYGLM_API_KEYZHIPU_API_KEY | | MiniMax | MINIMAX_API_KEYMINIMAX_CN_API_KEYMINIMAX_API_TOKEN |

若要与模型适配器共用同一套凭证,请把密钥写入 ~/.dsh/.credentials.yaml,并为该路由添加 apiKeyEnv。Zhipu 的账户接口要求密钥原样传递(不加 Bearer 前缀),宿主会自动选择正确的认证方式。Moonshot 与 Zhipu 在两个区域主机之间互为镜像,只对其中一个站点有效的密钥会先尝试另一个站点,之后才报告失败。

无需账号预览(mock 模式)

mock 模式由宿主端返回预设余额,跳过凭证解析与上游请求。它默认关闭,可通过 DSH_BALANCE_MOCK=1?mock=1 查询参数开启。

curl "http://127.0.0.1:3080/plugins/balance?kind=moonshot&mock=1"
curl "http://127.0.0.1:3080/plugins/balance?kind=zhipu&mock=1"
curl "http://127.0.0.1:3080/plugins/balance?kind=minimax&mock=1"

想在界面中查看,请带上环境变量启动服务:

DSH_BALANCE_MOCK=1 dsh web

然后在 Settings → Models 中为想预览的服务商(moonshotaizaiminimax 等)添加路由,添加一个模型并选中它。胶囊会跟随活跃模型,在没有任何真实密钥的情况下显示预设余额。mock 模式不会读取凭证,也不会请求服务商——其中的数字仅用于预览布局。

实现原理

dsh-balance 是一个双面包(dual-face Cordis package):同一个 npm 包,包含宿主端与浏览器端两个部分。

| 部分 | 文件 | 职责 | |---|---|---| | Bundle 层 | cordis.patch.yml | 由 dsh.bundle 声明;当 profile 列出本包时插入 dsh-balance 行,因此 dsh plugin add 无需手动修改补丁文件。 | | 宿主端(Node) | src/index.ts | 在宿主 Web 服务器上注册 GET /plugins/balance?kind=…。通过凭证接缝(以及新增服务商的启动环境)解析密钥,请求服务商,并转发归一化后的余额。密钥不会经过网络传到浏览器。 | | 浏览器端 | src/client/index.tsx | 将 BalanceChip 组件注册到 sidebar.footer.action 插槽。从模型目录存储(ctx.modelDirectories)读取当前会话的模型服务商,映射为 kind,并每 60 秒、点击时、会话切换时、模型切换时轮询宿主路由。每种服务的返回数据由各自的渲染器整形。 |

浏览器端产物由宿主的 client-module 流水线以 Web 外壳所需的 window.__ModuleLoader__.load({ id, factory }) 闭包格式提供;react@deepseek-ai/* 平台模块保持外部依赖,从浏览器冻结的模块表中解析。

Fork 提示。 client-module 的条目 id 就是 npm 包名。构建时会从 package.json 读取(见 tsdown.config.ts),scripts/verify-client.mjs 也会校验同一个值。若你重命名该包,还需同步 cordis.patch.yml 中的 name 以及 profile dsh.profile.bundles 中的条目;插件内部的 Cordis name 导出始终是 dsh-balance

开发

pnpm install
pnpm run build     # tsdown:lib/index.js(宿主端)+ lib/client.js(浏览器端)
pnpm run verify    # 在桩模块表上执行客户端产物并校验契约

使用 link: 安装时,重建 lib/ 会立即更新正在运行的应用,包括在已打开的浏览器标签页中热替换胶囊。宿主端改动可能需要按你的 DSH 工作流重载或重启。

@deepseek-ai/* 平台包是可选的 peer 依赖,由正在运行的 Harness 提供,因此 pnpm install 永远不会去下载它们(见 pnpm-workspace.yaml)。因此 TypeScript 类型检查需要本机的 Harness 检出并配置 tsconfig 路径;构建本身没有这个要求。

故障排查

| 现象 | 原因与处理 | |---|---| | 显示 Balance — 且提示 Set DEEPSEEK_API_KEY … | 凭证无法解析。请写入 ~/.dsh/.credentials.yaml 或启动环境。 | | 其他服务商却显示 DeepSeek 余额 | 该路由 id 不在上面的映射表中——请带上路由 id 提交 issue。 | | 重命名包之后胶囊消失 | client-module 的 id 就是包名;请确认 cordis.patch.yml 中的行与 dsh.profile.bundles 中的条目都与 package.json 一致,然后重启 dsh web。 | | 折叠侧边栏后胶囊消失 | 正常现象——56px 轨道中齿轮旁没有空间。 | | Moonshot 或 Zhipu 返回上游 401/403 | 密钥属于另一个区域主机;插件已尝试镜像站点,若仍报错说明该密钥在两个站点都无效。 |

常见问答

浏览器会看到我的 API 密钥吗? 不会。宿主端通过 Harness 的凭证接缝解析密钥并请求服务商,浏览器只会收到归一化后的余额。

卸载后会影响 Harness 吗? 不会。它只注册了一条路由和一个插槽组件,两者都归插件所有。卸载后 Harness 与原来完全一致——核心没有任何改动。

运行成本如何? 每个打开的标签页每分钟一次很小的本地 HTTP 请求,且只在侧边栏展开时发生。mock 模式完全不请求服务商。

为什么自定义服务商显示 DeepSeek 余额? 未知路由会刻意回退到 DeepSeek,而不是让胶囊报错。请带上路由 id 提交 issue,即可补充映射。

headless/CLI 会话能用吗? 胶囊是 Web 侧边栏功能;只要 profile 挂载了 Web 服务器,宿主路由在任何 profile 下都可用,但没有 Web UI 就没有胶囊可渲染。

更新日志

完整历史见 CHANGELOG.md。每次发布同时发布在 GitHub Releasesnpm

许可证

MIT © 2026 Andre Goncalves