DeepSeek Harness 的余额与会话消费 HUD,带预算提醒、高峰时段警告和可选官方价格同步。
31.4/100
综合分
2
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/25 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
自动兼容检查有告警:未发布到 npm registry,仅可从源码安装。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add LinHyu-2006/dsh-balance-hud该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
是什么
dsh 原生插件 · model
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 8 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查⚠ 装前注意未发布到 npm registry,仅可从源码安装
展开查看检查明细 ↓
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✗npm 包dsh-balance-hud(未发布到 npm,仅可源码安装)
✓Node 引擎未声明 engines.node
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明
验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/14 13:14:49
安全扫描自动 · 静态分析源码v2.7.0🟢 扫描:未发现敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描未发现敏感能力:最多只发网络请求、读取自身元数据或只读文件,未发现执行命令、文件写入或敏感信息读取。
发起外部网络请求
查看扫描证据(共 6 处,展示前 6 条)
- 请求外部主机zh-cnlib/index.js:166
response = await fetch(`https://${PRICING_HOST}/zh-cn/quick_start/pricing`, { headers }); - 发起网络请求lib/index.js:166
response = await fetch(`https://${PRICING_HOST}/zh-cn/quick_start/pricing`, { headers }); - 发起网络请求lib/client.js:105
response = await fetch(`${PRICING_ROUTE}${suffix}`, { - 发起网络请求lib/client.js:155
const response = await fetch(MODELS_ROUTE, { - 发起网络请求lib/client.js:1248
response = await fetch(BALANCE_ROUTE, { - 发起网络请求lib/client.js:1287
const response = await fetch(BONUS_ROUTE, {
扫描于 2026/10/31(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
涉及外部主机:zh-cn
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
README
由 DeepSeek 最新模型翻译生成dsh-balance-hud
DSH(DeepSeek Harness) Web GUI 右下角的常驻 HUD:一眼看到 DeepSeek 账户余额和本会话花费。
English · 设计说明 · Design notes · LICENSE
HUD 的两种状态:折叠角标与展开明细面板
关于这些图片:它们不是运行中 DSH 窗口的真实截图,而是按插件自身的布局与配色渲染出来的图(用的是真实样式取值与真实数字)—— 制作时没有可用的实时界面截图工具。
请把它们当作如实的布局参考,而不是"已装好并正在运行"的证据。
欢迎用真实截图替换。
Windows —— 双击 tools\install.cmd,或在命令行里: tools\install.cmd
macOS / Linux: sh tools/install.sh
两个启动器都会替你找 Node,包括 DSH 自带的那份运行时(它不在 PATH 上)。
如果你的机器完全没装 Node,它会明确告诉你怎么办,而不是丢一句 node: command not found。
换个 profile 用 --profile <目录>,只看不改用 --dry-run,卸掉用 --uninstall。
展开完整文档(README 剩余 1 节)
dsh-balance-hud
DSH(DeepSeek Harness) Web GUI 右下角的常驻 HUD:一眼看到 DeepSeek 账户余额和本会话花费。
English · 设计说明 · Design notes · LICENSE
HUD 的两种状态:折叠角标与展开明细面板
关于这些图片:它们不是运行中 DSH 窗口的真实截图,而是按插件自身的布局与配色渲染出来的图(用的是真实样式取值与真实数字)—— 制作时没有可用的实时界面截图工具。
请把它们当作如实的布局参考,而不是"已装好并正在运行"的证据。
欢迎用真实截图替换。
Windows —— 双击 tools\install.cmd,或在命令行里: tools\install.cmd
macOS / Linux: sh tools/install.sh
两个启动器都会替你找 Node,包括 DSH 自带的那份运行时(它不在 PATH 上)。
如果你的机器完全没装 Node,它会明确告诉你怎么办,而不是丢一句 node: command not found。
换个 profile 用 --profile <目录>,只看不改用 --dry-run,卸掉用 --uninstall。
想自己跑也行 —— 下面这条假定 Node 已经在 PATH 上:
node tools/install.mjs # 安装到 ~/.dsh/profiles/desktop,然后重启 DSH
node tools/smoke.mjs # 离线冒烟套件(83 条断言),不需要装 DSH
装完必须重启 DSH。 装插件会改 profile 的 bundle 列表,那个列表不热加载 ——只刷新页面不会生效。
- 账户余额 —— 充值余额 + 赠金余额,走的是「设置 → 账号与余额」同一个服务
(ctx.deepseekAccount.getBalance())。
- 两条花费口径 —— 按官方价格表算的 token 预估,以及由真实余额减少量累计出的实际值。
- 付充值无感 —— 充值只抬高余额,不会打断花费计数。
- 按会话独立 —— 基线与计数按会话 id 分槽存储;刷新页面或切换会话都不会覆盖别的会话。
- 不碰凭据,默认不外联 —— 插件从头到尾不接触你的 API key;只有你开启价格同步后才会联网(见 价格与同步),在此之前不产生任何外部请求。
- 前后各半、一条中继 —— 浏览器半边负责渲染,Host 半边开只读回环路由(余额、赠金信号、价格同步、模型列表),浏览器本身只跟回环地址说话。
- 可配置、有预算 —— 「设置 → 通用」里有一行偏好,可改模型、轮询间隔、预算与提醒;花费接近预算时卡片会亮起彩色描边,面板还会倒计时到下一次峰谷切换。
界面
┌──────────────────────────────┐
│ 账户余额 ¥43.42 │ │ 本会话预估 ¥0.59 │ └──────────────────────────────┘
把鼠标移到卡片上会展开明细面板:余额分项(充值 / 赠金 / 合计)、预估花费的三个计价分项、实际值、token 用量,以及并行会话时的分摊行(本会话占比、其它会话、跟踪会话、 账户级合计)。展开面板用 4 位小数,小卡片用 2 位。
| 字段 | 含义 |
| 账户余额 | 账户合计(充值 + 赠金),2 位小数 |
| 本会话预估 | 本会话的预估花费;卡片 2 位、面板 4 位;会话还没有 token 用量时显示 — |
| 实际扣费 | 本会话累计的真实花费(单会话时;并行时改叫 本会话分摊) |
金额小于可显示的最小单位时,卡片显示 <¥0.01、面板显示 <¥0.0001 —— 花了钱就绝不会被抹成 0。
交互
- 悬停卡片展开明细面板。
- 卡片与面板是两个独立元素,中间留了 8 px 的视觉间隔。悬停判定挂在卡片和面板自己身上(各自有 enter / leave),不挂在外层定位容器上;并用一个 140 ms 的待关闭定时器,让指针落进那段间隔时面板的 mouseenter 能取消卡片的 mouseleave。
- 从卡片左边或面板左边滑出即收起。这是刻意的:容器在四周预留了空白,把收起判定挂在容器盒子上会让面板停在"其实已经离开"的空白处不消失。
- 点击卡片折叠成角标(2 格:标签 + 余额),再点恢复。
- 键盘:卡片是 role="button" + tabIndex=0,Enter / 空格 切换折叠;面板是 role="dialog"。
- 面板里有 刷新 按钮(点击立刻显示忙碌文案,完成后给一个 更新于 HH:MM:SS 时间戳),以及手动兜底的 我刚充值了 按钮(处理中显示查询状态)。
- HUD 里刻意没有任何 title 属性。 原生浏览器 tooltip 会在悬停约一秒后弹出黑色方块盖住面板,所以摘要写在 aria-label 里。冒烟测试把这条当回归守卫断言。
设置
插件往 DSH 的 settings.general.item 槽位注册一行偏好 —— 余额与花费 HUD。DSH 对这个槽位的定义是「General 区里的一行偏好 —— 单个设置专用的增量座位,不需要独占一整页」(要整页请用 settings.section;DSH 自己的 Language、link-opening、performance-usage 几行也注册在这里)。
位置:设置 → 通用 → 余额与花费 HUD。它不会占用整个设置页。
| 设置项 | 取值 | 默认 | 作用 |
| 计价模型 | deepseek-flash、deepseek-v4-pro | deepseek-flash | 预估与分摊权重所用的价格表 |
| 自动同步价格 | 不自动(只手动) / 每 6 小时 / 每 1 天 / 每 3 天 / 每 7 天 | 不自动(只手动) | 官方价格表的自动同步节奏;不选就永远不会自动跑(见 价格与同步) |
| 前台刷新间隔 | 30 / 60 / 120 / 300 秒 | 60 秒 | 页面可见时的余额轮询节奏 |
| 后台(页面隐藏) | 30 / 60 / 120 / 300 秒 | 300 秒 | 标签页隐藏时的轮询节奏 |
| 峰前提醒 | 5 / 10 / 15 / 30 分钟 | 10 分钟 | 峰谷切换提醒提前多久出现 |
| 本会话预算(元) | 元,0 = 不设 | 0 | 本会话预估花费的预算 |
| 每日预算(元) | 元,0 = 不设 | 0 | 北京自然日确认花费的预算 |
| 显示账户级合计 | 开 / 关 | 开 | 并行会话时面板里的 账户级合计 行 |
| 峰时提醒 | 开 / 关 | 开 | 面板里的峰谷提醒行 |
| 预算超限发系统通知 | 开 / 关 | 关 | 首次达到某个预算档位时的可选系统通知 |
持久化。 这一行写的是 localStorage 的 dsh-balance-hud:settings:v1,与记账键(dsh-balance-hud:tracker:v4)刻意分开,两者不可能互相干扰。
两个注册点,一个容器。 设置行(settings.general.item)与浮层(shell.overlay)是 两个独立的槽位注册,没有共同的 React 祖先,因此无法共享 React state。它们改用一个小的订阅容器 —— createSettingsStore → get / set / subscribe:set 合并一份部分补丁、落盘、广播,所以在任一处改动,另一处立刻同步 —— 不需要刷新,也不需要共享父组件。useSettings 是架在同一个容器上的 React 绑定。
配置永不被信任。 normalizeSettings 逐字段对白名单校验:未知模型、不在选项内的间隔、负数预算、非布尔开关,一律回落默认值,而不是传进界面;localStorage 里的 JSON 损坏时同样回落默认、不抛错。配置是用户可写、且随版本变化的,所以每次读取都重新校验。
预算
在设置行里可以设本会话预算和/或每日预算(单位元;0 表示不设)。
evaluateBudget(spent, budget) 返回 { level, ratio, remaining },level 为
none | warn | critical | over:
| 使用率 | 档位 |
| < 75 % | none |
| ≥ 75 % | warn |
| ≥ 90 % | critical |
| ≥ 100 % | over |
remaining 夹在 0 以上,"超限"不会报出负数余额。worstBudgetLevel 再取"本会话"与"每日"两条预算里更严重的一条,所以「今天已经用爆、但本会话还很便宜」同样会告警。
视觉。 预算达到或超过阈值时,卡片左侧出现 3 px 彩色描边 —— warn / critical 用主题的警告色、over 用错误色。它刻意不是网格里多出来的一格:卡片网格必须保持 2 列 × 2 行,冒烟测试用断言钉住了这一点。展开面板会多一行预算,显示「已用 / 预算」以及剩余金额或 已超限。
可选系统通知。 打开 预算超限发系统通知(默认关)后,每个档位在本次挂载内最多只发一次,所以不会变成骚扰。它走浏览器 Notification API,只在权限已授权时才发;没有授权时静默降级为只有描边变色,不影响其它功能。
每日预算用按天台账。 localStorage 键 dsh-balance-hud:daily:v1,内容是 { date, total },其中 date 是北京自然日(beijingDateKey)—— 官方计费与峰谷窗口都按北京时间,日界跟着同一个口径才不会错位。台账只累加确认花费(某次余额读数确认的那部分),不用递推显示值,因此同一笔钱不会被重复计入。读到新的一天时台账归零。
峰时提醒
峰时 = 北京时间周一至周五 09:00–12:00 与 14:00–18:00;峰时价恰好是闲时价的 2 倍。
minutesUntilTierChange(now) 返回 { minutes, to },to 为 'peak'(即将进入贵的那档)
或 'off'(即将回到便宜的那档)。
当"下一次切换"落在配置的提前量以内时,面板显示一行提醒:
- 约 N 分钟后进入峰时,价格翻倍
- 约 N 分钟后回到闲时价
一个 60 秒的滴答同时驱动倒计时与跨天重置,所以数字是活的。午休、跨夜、跨周末都算得对 ——例如周五 18:30 → 周一 09:00 是 870 分钟 —— 冒烟测试断言了这些用例。
两条花费口径
| 口径 | 算法 | 性质 |
| 预估 | 会话 tokenUsage 投影 × 官方价格表 | 精确可算,但只覆盖模型 token |
| 实际 | 观测到的余额减少量累计求和,按会话存在 localStorage | 平台真实扣费,但有结算延迟 |
预估把用量拆成四类 token —— 未命中输入、缓存命中、缓存写、输出 —— 各自按峰谷两档价计价。
缓存写按未命中输入价计,与平台扣费口径一致。实际值是一个计数器,不是做减法:每一次观测到的余额下降都加进当前会话的计数器,所以充值无法干扰它。
充值识别
原则:外部变动改变余额,但绝不能改变花费计数。
判据用的是 token 估算上界,而且它双向都成立:平台扣掉的钱不可能超过这段时间消耗的 token 所值的钱;反过来,余额减少的量如果超过这个上界,多出来的部分也不可能来自消费。
余额升幅 > 全部会话 token 估算之和 + 0.02 → 外部加钱:充值 / 赠金到账 / 账单修正余额降幅 > 全部会话 token 估算之和 + 0.02 → 外部减钱:赠金过期回收 / 退款 / 账单修正其余 → 普通消费,照常累计
这样既不会因为"充值和消费同时发生"漏判,也不会因为正常消费波动误判。
为什么必须处理"减钱"那个方向:赠金会过期
赠金有有效期。到期未用完的部分会被平台回收,表现为余额凭空下降、却没有任何消费。
早期版本把任何余额下降都算成消费(delta < 0 → spend),于是 5 元赠金过期会被记成 5 元"本会话花费";而计数器只增不减,这个错误会一直留在记录里直到 30 天后被淘汰。
现在两个方向走同一条路径:只移动账户级字段(baseline / lastBalance), spent 原封不动,并在 topups[] 里记下是哪一类变动。
多会话时,applyExternalChange 会把所有会话的账户级字段一起移动,但刻意不动 lastRead (会话私有的"上次真正观测到的余额")。于是每个会话都会自愈:还没观测到这次变动的会话,下次读数时仍能看到完整落差,从而自己判出这是外部变动,而不会把它摊到自己的消费上。
三层,按权威度排序
1. token 上界判据 —— 纯客户端、始终生效,是权威判据(两个方向都是它说了算)。
2. 官方赠金印证 —— GET /api/balance-hud/bonuses 读
ctx.deepseekAccount.getUnnotifiedBonuses()。它是只读且刻意不回执的
(不调 ackBonusNotified),因此不会消费掉 DSH 自己的赠金通知;数据保持可读,客户端按 orderId 去重。即使这条路由不通,变动仍会被识别 —— 这一层只是印证。
注意:它只能印证"发放",官方没有"过期"的推送,所以减钱那个方向完全靠第 1 层。
顺带把官方给的 expiresAt 透出来,提示里会带上"最早到期"日期。
3. 手动兜底 —— 我刚充值了 按钮走同一条重锚路径,处理期间显示"查询中…"。
面板会显示约 12 秒的提示,两类都有:
- 加钱:已识别充值 ¥50.00,花费继续累计(官方赠金 ¥5.00 印证),最早到期 2025-12-31。
- 减钱:检测到 ¥5.00 非消费性扣减(赠金过期回收等),未计入花费。
并行会话与分摊
账户余额是账户级的:它不携带"这笔钱是哪个会话花的",所以单个会话的真实花费 在本地不可观测。插件用比例分摊:
本会话分摊 = 本会话累计花费 × (本会话 token 成本 / 全部会话 token 成本)
所有会话的 token 成本都用同一套四类计价 + 峰谷价,权重才可比。只有一个会话时权重恒为 1,数值就退化成精确值。
这是估算。 两个会话的 token 消耗与平台结算并不同步,比例会漂移;有新会话加入分母时,数字会下跳一次。面板里有 本会话占比、其它会话、跟踪会话 几行,能看到当时的权重是多少。
持久化
记录在 localStorage 的 dsh-balance-hud:tracker:v4 下,按会话 id 分槽:
{ "sessions": { "<会话id>": { "baseline": 43.42, "lastBalance": 43.12, "spent": 0.3, "ts": 0 } } }
| 情况 | 行为 |
| 刷新页面 / 重新挂载 | 从 localStorage 读回,计数器继续累计 |
| 切换会话 | 各会话有自己的记录,互不覆盖、互不清零 |
| 识别到充值 | 只移动基线,spent 不动 |
| 记录超过 30 天 | 写回时淘汰 |
| 超过 30 个会话 | 保留最近 30 个 |
| localStorage 不可用 | 降级为仅内存,HUD 照常工作 |
页面存活期间,内存里的 store 还带着一个 topups[] 历史和一个 lastObservedBalance;但当前写盘只持久化 sessions。老数据会自动迁移 —— v3 是 { sessions: { … } }、 v2 是扁平的 { [会话id]: { … } } 字典、v1 是单条 { sessionId, … } —— 迁完会删掉旧键。
余额默认每 60 秒拉一次(页面隐藏时 5 分钟),页面回到前台立刻补读,失败按 1s → 2s → 5s → 10s → 20s 退避重试。未登录不算错误,也不会走快速重试。两个间隔都可以在设置行里改(见 设置)。
除了记账键,还有三个互相独立的键:dsh-balance-hud:settings:v1(设置行,见设置)、dsh-balance-hud:daily:v1(北京自然日台账,见 预算)和 dsh-balance-hud:prices:v1(同步来的价格表与它的 HTTP 校验器,见 价格与同步)。
清理或写坏其中一个,都不会影响其它几个。
架构
浏览器(客户端半边 lib/client.js) Host(Host 半边 lib/index.js)注册 shell.overlay 槽位 inject: [deepseekAccount, webServer] 每 60 秒轮询一次 │ fetch ──────────────────────────────────────► GET /api/balance-hud/balance (只读) GET /api/balance-hud/bonuses (只读) GET /api/balance-hud/pricing (价格同步,需主动开启) GET /api/balance-hud/models (模型列表,仅回环) └─► ctx.deepseekAccount.getBalance()
ctx.deepseekAccount.getUnnotifiedBonuses()
└─► 官方 account platform
fetch(PRICING_DOC_URL) ← 仅主动开启同步时
└─► 官方价格文档页
为什么需要这条中继。 浏览器半边无法直接调 ctx.remote.account.getBalance:不声明就访问会抛 cannot get property "remote.account" without inject;而在客户端半边声明 inject = ["remote"] 又无法满足 —— fiber 永久挂起,插件根本不激活。
两条都在真实 @deepseek-ai/cordis 4.0.4 上复现过。所以由 Host 半边读余额,再经仅回环、只读的路由交给浏览器。所有路由都只接受回环来源
(127.0.0.1、::1、IPv4 映射回环形式),其它一律 403;只支持 GET,
不改任何状态,不返回凭据,并带 cache-control: no-store。其中一条在用户主动开启后才会产生对外请求 —— 价格同步。
| 返回 | 含义 | HUD 显示 |
| { kind: 'ready', currency, rechargeTotal, bonusTotal, total } | 已登录且有钱包 | ¥xx.xx |
| { kind: 'unavailable', reason } | 未登录 / 凭据在查询期间变更 | 未登录 |
| { kind: 'error', reason } | 查询失败、路由不可达、响应不合法 | 读取失败(原因在面板里) |
价格口径
单位 元 / 百万 tokens,取自官方 模型 & 价格;闲时价恰好是峰时价的一半。
| 模型 | 缓存命中输入 | 缓存未命中输入 | 输出 |
| deepseek-flash | 闲 0.02 / 峰 0.04 | 闲 1 / 峰 2 | 闲 4 / 峰 8 |
| deepseek-v4-pro | 闲 0.15 / 峰 0.30 | 闲 4.5 / 峰 9 | 闲 13.5 / 峰 27 |
- 峰时 = 北京时间周一至周五 09:00–12:00 与 14:00–18:00。其余时段(含周末与法定节假日)按闲时计;只取本地时间的「星期 + 小时」换算,不引入时区库。
- 缓存写按未命中输入价计费。
- 价格表里两个模型都有;模型是一个设置项(默认 deepseek-flash),预估与分摊权重都跟着它走。
未知模型回落到 flash 价格(而不是归零),面板会说明这一点。
- 官方调价后,可以同步价格表(见 价格与同步),或者改 PRICES 再刷新页面。
- 上表是内置快照,日期为 2026-09-29(BUILTIN_PRICES_DATE);同步成功后就改用官方的新表。
价格与同步
预估所用的价格表内置在插件里,是一份有日期的快照(内置表日期 2026-09-29);除非你主动要求,插件一直用它。官方随时可能调价,所以插件也可以同步官方价格表 —— 来源是官方价格页,这也是它唯一会访问的外部主机。
两种触发方式,都必须由你主动选择:
- 设置行里的 同步价格 按钮(英文名 Sync prices):点一次,立刻同步一次;
- 自动同步价格 下拉:选项是 不自动(只手动) / 每 6 小时 / 每 1 天 / 每 3 天 / 每 7 天 (即 off / 6 小时 / 24 小时 / 3 天 / 7 天)。不选间隔就不会自动跑,出厂状态是「不自动」(syncHours: 0)—— 装上插件后不碰这些控件,插件一个外部请求都不会发。
开启自动同步后,默认节奏是 24 小时(DEFAULT_SYNC_HOURS),理由是:官方调价会先在 changelog 里预告,价格页随后才改,所以这是「几个月一次」的事件,不是每天的事。价格页是 CDN 资源,会回 ETag 与 Last-Modified,同步时带上 If-None-Match,页面没变就回 304 Not Modified 且没有响应体 —— 每次轮询只有几百字节。24 小时把「过期窗口」压到一天,代价几乎为零。
抓取由 Host 半边执行,不是浏览器。 浏览器从不直接访问价格页,它调两条只读回环路由: GET /api/balance-hud/pricing(同步价格)与 GET /api/balance-hud/models(DSH 已注册的模型)。
只有前者可能产生对外请求;后者完全不需要网络 —— 它读 DSH 自己的 llm 服务
(listProviders() / listModels()),设置行用它填充「计价模型」下拉,拿不到 llm 时回落内置选项。
算错价,比用旧价更糟。 页面由一个纯函数解析,它的每个判断都与页面编码无关 (抓取链路可能把 UTF-8 字节按 Latin-1 解开,中文标签会变成乱码),并且做语义校验:官方规则是「闲时价 = 峰时价的一半」,所以峰时价必须严格大于闲时价。任何一项校验不过,整次同步整体作废,插件继续用上一份好表 —— 内置表或上次同步成功的表。
半解析出来的表永远不会被用来算钱。
存在哪里、行里显示什么。 同步结果缓存在 localStorage 的 dsh-balance-hud:prices:v1,一起存的还有 ETag、Last-Modified 与抓取时间戳;收到 304 时只刷新检查时间,不动价格表。
设置行会显示当前用的是哪一份、是哪天的 —— 当前价格:内置表(2026-09-29),同步成功后变成 当前价格:已同步(YYYY-MM-DD)。
安装
这是一个本地 profile 插件,不发布到 npm。
node tools/install.mjs # 安装到 ~/.dsh/profiles/desktop
node tools/install.mjs --dry-run # 预览,不写任何文件
node tools/install.mjs --uninstall # 卸载
node tools/install.mjs --profile <dir> # 指定别的 profile
手工安装等价于:
1. 把目录放到 ~/.dsh/profiles/<profile>/plugins/dsh-balance-hud (客户端 bundle 是从 profile 提供的,所以必须真的在 profile 目录里)。
2. 在 profile 的 dependencies 加 "dsh-balance-hud": "file:./plugins/dsh-balance-hud",并在 dsh.profile.bundles 里加 "dsh-balance-hud"。
3. 把它链接进 profile 的 node_modules(Windows 用 junction,其它平台用符号链接)。
4. 重启 DSH。
注意:profile 的 package.json 不能带 UTF-8 BOM。带 BOM 时插件管理器会以 Unexpected token '\ufeff' 失败。tools/install.mjs 会把清单重写成不带 BOM 的版本,并保留一份 package.json.bak-balance-hud 备份。
改客户端半边(lib/client.js)只需刷新页面。改 Host 半边(lib/index.js,例如赠金路由或价格抓取)需要重启 DSH,因为 profile bundles 不热加载。
开发
node tools/smoke.mjs # 离线冒烟套件,不需要装 DSH
node tools/verify-install.mjs --package # 打包自检,不需要装 DSH
node tools/verify-install.mjs # 校验真实安装
tools/smoke.mjs 会在假的 React 运行时、假 Host 响应、假 localStorage 和假 document 上求值真实的 lib/client.js,然后驱动组件走完整个 hook 周期。每项检查打印一行 ✓ (共 83 条),首个失败即非零退出;覆盖模块/槽位注册、卡片布局、悬停与折叠交互、余额协议与全部路由失败模式、价格算术、显示精度、充值/过期两类外部变动判据、持久化与迁移链,以及可见性驱动的补读。A1–A3 三个新功能各有守卫:两个槽位注册(浮层 和 设置行)、设置默认值、脏配置的逐字段收敛、配置落盘往返、容器广播 + 部分合并 + 取消订阅、配置损坏回落、四档预算与剩余夹 0、两条预算取最严重、每日台账(累加 / 忽略 0 与负数 / 跨天归零 / 损坏回落),以及峰谷倒计时在峰时、闲时、跨午休与跨周末的正确性。价格同步也各有一条守卫:解析器对真实页面的固定用例、以及对「UTF-8 被误按 Latin-1 解码」的乱码副本给出同一张表;页面结构损坏或档位反常时整条放弃;resolvePrices 的来源可分辨;缓存落盘往返保留条件请求头;以及默认零外联 —— 非法间隔收敛为关闭、24 小时 是默认档。
CI(.github/workflows/ci.yml)在 ubuntu / windows 上用 Node 22 跑这两个离线脚本(macOS 每周单独跑一次)—— node tools/smoke.mjs 与 node tools/verify-install.mjs --package。两个脚本都完全离线:不依赖 DSH 安装、不联网、不需要构建,所以能在干净容器里跑,也顺带证明行尾(.gitattributes 锁 LF)、路径派生与 import.meta 用法都不依赖 Windows。
它不覆盖 Host 半边(lib/index.js 从未被加载,因此回环过滤、对外价格抓取、 If-None-Match/304 路径与模型列表路由都没有离线测试)、真实浏览器、真实 Cordis 注入和真实平台。
lib/client.js 是手写的 CJS 风格 bundle,格式就是官方的
window.__ModuleLoader__.load({ id, factory }),所以没有构建步骤。
| 文件 | 作用 |
| package.json | 声明 dsh.bundle.patch(profile 条目树)与 dsh.client(platform: web,导出 ./client) |
| cordis.patch.yml | 把插件作为一行插入 profile 条目树 |
| lib/index.js | Host 半边:只读回环路由(余额、赠金信号、可选的价格同步、模型列表) |
| lib/client.js | 浏览器半边:shell.overlay HUD、settings.general.item 设置行、价格表解析与全部记账逻辑 |
| tools/ | 安装脚本、安装校验、离线冒烟套件 |
| .github/workflows/ci.yml | 离线冒烟 + 打包自检,跑 ubuntu / windows;macOS 每周跑 |
| docs/DESIGN.zh-CN.md | 贡献者设计说明 —— 记账模型的完整推导 |
隐私与安全
- 默认:零外部请求。 装上插件后不碰价格同步的控件,插件新增的网络流量就只有到 /api/balance-hud/… 的回环 HTTP;它用内置价格表,不接触任何第三方。
- 唯一的例外是可选的价格同步。 只有你点了 同步价格,或主动选了自动同步间隔之后,插件才会按你选的节奏去抓 https://api-docs.deepseek.com/zh-cn/quick_start/pricing —— 官方的公开价格文档页。
这是它涉及的唯一外部主机,而且抓取由 Host 半边执行,不由浏览器发起(见 架构)。
- 永远不会发送的东西: 凭据、API key、账号 id、会话数据、cookie,以及任何能识别你的查询参数。
它只是对一个公开文档页发一个普通 GET;同步既不读取、也不上传你的余额。
- 本插件从不接触官方 API key。 涉及账号数据时,Host 半边只调 getBalance 和 getUnnotifiedBonuses,从不调 resolveToken 或 getPlatformSession,凭据始终留在 @deepseek-ai/dsh-deepseek-account-platform 内部。
- 仓库里、localStorage 里、HUD 上都没有密钥、令牌或账号 id。同步价格缓存(dsh-balance-hud:prices:v1)里只有价格、HTTP 校验器和时间戳,没有账号数据。
- 余额、赠金与模型列表三条路由都是仅回环、只读:对非回环调用者一律 403,只返回余额数字或已注册的模型名。插件对平台的调用走的是 DSH 本来就用的账号服务。
- 赠金路由既只读又不回执,因此不可能吞掉 DSH 自己的赠金通知。
已知边界
- 预估只覆盖模型 token。 任何非 token 计费项(插件、检索等)都会让它偏低。
- 价格表是有日期的快照。 如果你一直不同步,官方调价后预估会继续用内置的 2026-09-29 表,直到你同步、或改 PRICES 再刷新。解析器读的是当前页面结构,文档改版可能让解析失败 ——那时同步整体作废、继续用上一份好表:宁可用旧价,也不会用错价。
- 分摊是估算;凡是拿不到用量投影的会话在分母里权重为 0,会让占比失真。
- 赠金"部分过期"可能被算成消费。 判据是"降幅是否超过 token 上界":如果某笔赠金只有一部分过期,且这笔降幅恰好落在上界以内,就会被当成消费。要彻底解决需要按钱包分项的余额明细(哪个钱包、多少、何时过期),而 getBalance() 返回的 AccountWallet 只有 { currency, balance },不含过期时间。所以这是"把误差压到不超过 token 估值",不是消除。
- 拿不到 token 数据时判据会变紧。 上界退化为 0 附近,此时较大的真实消费有可能被误判为外部减钱。实际运行中 token 用量每 5 秒读一次,这种情况罕见。
- 平台结算有延迟。 刚跑完任务时实际值可能还停在原处,而预估已经动了;两者会在几十秒内收敛。
- 第一个基线略晚于会话开始,更早的花费由 token 预估覆盖。
- 账户级合计只是参照,不是某个会话的数字。
- 未登录是正常状态:卡片会说明,登录后下一次轮询自动恢复。
许可
MIT,见 LICENSE。预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
LinHyu-2006/dsh-balance-hud
DeepSeek Harness 的余额与会话消费 HUD,带预算提醒、高峰时段警告和可选官方价格同步。
相关插件 · 模型接入
API 中继安全审计toby-bridges/api-relay-audit
面向 AI API 中转与 LLM 代理的本地安全审计。
★ 897已汉化DSH
69.4
免费搜索插件DDDMUC/dsh-free-search
DeepSeek Harness 免费搜索插件 —— 无需 API key,零成本,多引擎可切换。 一个给…
★ 761已汉化DSH
68.7
免费联网搜索liustack/modsearch
在官方 App 里模型能联网,切到 API 就不能了。ModSearch 把联网补回来:网页搜索、X…
★ 863已汉化DSH
68.5
OpenCode 免费模型FishBottle7/opencode2dsh
在 DSHDeepSeek Harness里原生使用 OpenCode Zen 的免费匿名模型。
★ 379已汉化DSH
67.8
AI 模型网关tingly-dev/tingly-box
Tingly Box Web UI 演示
★ 373已汉化DSH
67.4
WorkBuddy 账号池XDTrees/dsh-xdpool
把你能白嫖的模型额度接进 DSH 同一个池:WorkBuddy 多账号自动容错、十三家扫码登录、76…
★ 359已汉化DSH
67.1