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

@zoytown/dsh-billing

v0.1.3

Published

DeepSeek Harness (dsh) plugin for DeepSeek API account balance — a ctx.billing capability seam, a /balance command, and a sidebar balance indicator with a Settings page for the Web UI.

Readme

@zoytown/dsh-billing

English | 中文

@zoytown/dsh-billing 是一个用于查看 DeepSeek API 账户余额的 DeepSeek Harness(dsh)插件。它读取平台的 GET /user/balance 端点,并以三种方式呈现结果:侧边栏底部的余额胶囊、设置里的「余额」页、以及 /balance 命令。它不注册任何面向模型的工具,也不追加任何 session 事件,因此挂载它对会话零成本。

| 侧边栏 | 设置 → 余额 | |---|---| | dsh 侧边栏底部显示 DeepSeek 余额胶囊 ¥25.00,位于「设置」行旁边 | DeepSeek Harness 设置弹窗中选中「余额」栏,显示 ¥25.00 CNY 及充值/赠金拆分 |

平台实际提供了什么

只有当前余额。没有用量或消费明细端点——/usage 与 /dashboard/billing/usage 均返回 404——所以本包报告的是还剩多少,而非花了多少。任何「本次会话花费」都只能是基于 token 数的本地估算,那是另一件事,刻意不在本包范围内。

{
  "is_available": true,
  "balance_infos": [
    { "currency": "CNY", "total_balance": "25.00", "granted_balance": "0.00", "topped_up_balance": "25.00" }
  ]
}

balance_infos 是数组——一个账户可能同时持有 CNY 和 USD——本包所有消费者都完整渲染,而不是只取第一项。

安装

dsh plugin --profile web add @zoytown/dsh-billing

从 npm 安装拿到的是预构建产物,无需任何构建授权。从 git 安装(github:zoyluoblue/deepseek-harness-billing)只会拉到源码而不会触发构建,暂不支持,见已知限制。

bundle 插入三行配置——服务(同时也是浏览器行)、/balance 命令、以及 UI 的数据路由。三者互不依赖;在自己 profile 的 cordis.patch.yml 里按 id 禁用任意一行即可。

配置

| 键 | 默认值 | 含义 | |---|---|---| | apiKey | 省略 | 字面量密钥。优先用 apiKeyEnv,避免密钥进入配置文件;非空字面量优先级更高。带 role('secret'),因此永不随 describe() 响应外泄。 | | apiKeyEnv | DEEPSEEK_API_KEY | 凭据引用,每次读取时经 ctx.credentials 解析;该接缝不存在时回退到启动环境。复用 LLM 适配器的同一个密钥——本包不新增密钥。 | | baseURL | https://api.deepseek.com | 余额端点基址,会追加 /user/balance。回退到 $DEEPSEEK_BILLING_BASE_URL。 | | cacheTtlMs | 60000 | 一次成功快照的保鲜时长。 | | timeoutMs | 10000 | 单次请求的中止上限。 | | lowBalanceThreshold | 10 | 低于此值告警。0 关闭该下限,仅保留平台自身的 is_available 判定。 |

为什么不复用 $DEEPSEEK_BASE_URL

那个变量用于引导 chat-completions 适配器,而用户完全有正当理由把它指向网关或自建端点。/user/balance 仅存在于官方平台,复用它会让一套正常工作的代理配置在侧边栏里变成永久 404。因此该端点使用独立变量——这与 dsh-web-search-deepseek 为搜索单独设变量的处理一致。

若 baseURL 不提供该路径,失败会归类为 ENDPOINT_UNAVAILABLE,并在文案中点明这个原因,而不是抛出一个泛化的 HTTP 错误。

缓存

策略集中在一处,因为三个界面可能同时发问,而这是一个账户端点、官方未文档化其限流:

  • 一次成功快照在 cacheTtlMs 内直接复用;
  • 并发请求共享同一个在途请求,且任一调用方的取消不会取消其他人共同等待的那次读取;
  • 失败永不进缓存——下次询问会重试,同时保留上一次成功的快照,供界面在错误旁一并展示;
  • 本引用的 credentials/updated 提交后立即失效缓存。

不做后台轮询。新鲜度由消费者的询问驱动。

错误

BillingError.code 是界面的分支依据。失败绝不能渲染成余额为零:「没钱了」和「查不到」是两件不同的事。

| Code | 触发原因 | |---|---| | CREDENTIAL_MISSING | 无任何来源提供该引用;不会发出请求。 | | UNAUTHORIZED | HTTP 401/403。 | | ENDPOINT_UNAVAILABLE | HTTP 404——几乎总是 baseURL 指向了网关。 | | RATE_LIMITED | HTTP 429。 | | HTTP_ERROR | 其它非 2xx。 | | MALFORMED_RESPONSE | HTTP 200 但响应体不是余额文档。 | | NETWORK_ERROR | 传输失败、超时、基址无法解析,或重定向被拒。 | | ABORTED | 调用方取消。 |

两个朴素客户端会踩、而本包已处理的细节:密钥无效时端点返回 JSON error.message,但完全没有 Authorization 头时返回的是纯文本,因此响应体不会被无条件按 JSON 解析;以及使用 redirect: 'error' 在联系 Location 目标之前拒绝重定向,因为跟随重定向会把 bearer token 带到另一个主机。

命令

| 命令 | 效果 | |---|---| | /balance | 渲染余额,使用缓存。 | | /balance refresh | 同上,但忽略未过期的缓存。 |

Web UI

两个浏览器界面,共用同一个控制器:在胶囊已经在读取时打开设置页,会加入那次读取而不是再发一个请求。

| 界面 | 挂载点 | 展示内容 | |---|---|---| | 侧边栏胶囊 | sidebar.footer.action | 设置按钮旁的金额;56px 折叠轨下退为 32px 图标 + 状态角标 | | 设置 → 余额 | settings.section | 全部币种、充值/赠金拆分、当前阈值 |

胶囊区分五种状态,整个设计的支点是:失败渲染破折号,绝不渲染数字——「没钱了」和「查不到」不能长得一样。unconfigured 用虚线轮廓且完全不出数字;low 是唯一允许抢注意力的状态,且琥珀色始终与警告三角同时出现,颜色永不是唯一信号。折叠轨的角标只在 low 和 error 出现:余额健康时没有理由在余光里闪。

样式只使用 --dsw-alias-* 语义 token——本插件不定义主题、不写任何明暗选择器,两套主题都由 ui-theme 继承而来。

数据通道

浏览器半边读取 billing-route 行提供的 GET /billing/balance。之所以用普通的 webserver 路由而非 Typert Remote:Remote 需要主仓代码生成的调用描述符,仓外的包无法产出。

该路由返回的是账户数据,因此自带浏览器信任围栏,防御本地 HTTP API 会打开的两条「代理人混淆」路径——DNS rebinding(页面把自己的域名解析到 127.0.0.1,套接字打到本服务而 Host 写的是攻击者域名)与普通的跨站读取。Host 必须是 loopback 或列在 trustedHosts 中,且浏览器附带的 Fetch-Metadata 必须表明同源。它比主仓自己的 /api 围栏更严格:不推导任何 LAN IP 授权,loopback 之外的一切都必须显式声明。

- id: billing-route
  config:
    trustedHosts: []   # 仅当部署到本机之外时,填入 "host" 或 "host:port"

这不是身份认证。它阻止浏览器被当作通往 loopback 的代理,但不识别调用方。

常见问题

DeepSeek 余额怎么查?

调用 GET https://api.deepseek.com/user/balance,带 Authorization: Bearer <DEEPSEEK_API_KEY> 请求头。返回 is_available 和一个 balance_infos 数组,每个币种一条。本插件把这个端点接进 DeepSeek Harness,让余额出现在侧边栏、设置页和 /balance 命令里。

dsh 插件怎么安装?

dsh plugin --profile <名称> add <包名>。本插件:

dsh plugin --profile web add @zoytown/dsh-billing

该命令会把包装进 profile,并把它的 bundle 追加到 profile 的 dsh.profile.bundles 列表。卸载用 dsh plugin --profile web remove @zoytown/dsh-billing。

为什么余额显示的是「—」而不是数字?

因为这次读取失败了——插件绝不会显示一个它并不掌握的数字。破折号表示「查不到」,这与「余额为零」是刻意区分开的两种状态。打开 设置 → 余额 可以看到分类后的具体原因(密钥无效、端点不存在、被限流、网络错误)。

这个插件能看花了多少钱吗?

不能。DeepSeek 平台没有提供用量或消费明细端点——/usage 与 /dashboard/billing/usage 均返回 404——所以本插件只报告剩余余额。任何「本次会话花费」都只能是基于 token 数的本地估算,本包刻意不做。

能配合网关或自建 DeepSeek 端点用吗?

聊天补全可以,余额查询不行。/user/balance 只存在于官方平台,因此本插件使用独立的 baseURL(回退到 $DEEPSEEK_BILLING_BASE_URL),绝不复用 $DEEPSEEK_BASE_URL。若 baseURL 不提供该路径,会失败为 ENDPOINT_UNAVAILABLE 并在文案里点明这个原因。

需要单独再配一个 API key 吗?

不需要。它通过 ctx.credentials 解析的是 LLM 适配器用的同一个 DEEPSEEK_API_KEY 凭据引用。在「模型」页轮换密钥后,下一次余额查询即刻生效,无需重启。

会消耗 token 吗?

不会。它不注册面向模型的工具、不贡献 system prompt 段落、不追加 session 事件。命令结果由 UI 适配器直接渲染,永不进入模型历史。

Model Experience

无。本包不注册工具、不贡献 system prompt 段落、不追加 session 事件。命令结果由 UI 适配器直接渲染,永不进入模型历史。

Token effect

零。注册与调用都不会到达任何模型请求。

KV Cache effect

无;本包不向请求前缀写入任何内容。

已知限制

  • 告警下限是一个裸数字,按每币种、以该币种自身单位比较。 在 CNY/USD 混合账户上,一个按 CNY 设定的 10 也会把 $8.40 标记为告警。正确解法是 per-currency 映射,推迟到真有多币种账户需要时再做;在此之前可用 lowBalanceThreshold: 0 关闭下限。
  • 不提供消费/用量报告。 平台未暴露此类端点,见上文。
  • 不支持 git 安装。 本包未提供 prepare 脚本,dsh plugin add github:… 只会装到未构建的源码。请从 npm 安装,或使用 pnpm pack 产出的 tarball——两者都是预构建产物,无需构建授权。
  • 胶囊点击是刷新,不是跳转。 点它会重新读取余额;从它直接打开「余额」设置页需要设置外壳暴露一个「打开设置」服务,而目前没有。
  • 胶囊只显示一个币种。 侧边栏胶囊放不下多个,因此显示平台列出的第一个币种,完整列表在设置页。它绝不跨币种求和——把 CNY 加到 USD 上是个凭空捏造的数字。
  • 浏览器半边假定同源服务。 它请求相对路径,Web 应用满足这一点;以 file:// 加载并通过 IPC 桥接 fetch 的 Electron 外壳需要另外的传输方式。
  • 余额新鲜度由拉取驱动。 没有轮询,两次询问之间发生的余额下降不会被察觉,直到下一次有人询问。
  • 金额不做二次格式化。 平台返回的十进制字符串原样透传到展示层,因此平台若以非预期形态报告某币种,界面就照该形态呈现。

本仓库的工程约定与可发现性(SEO / GEO / AEO)规范见 DEVELOPMENT.md。

许可

MIT