dsh-usage-stats
Verified@hwfee/dsh-usage-stats · v0.1.4 · MIT · Web UI
DeepSeek Harness 的用量统计插件:在新对话页的标题下方显示一张「用量」面板,包含会话数、消息数、总 token、活跃天数、高峰时段、常用模型、活跃度热力图,以及一句按中文字数折算的趣味对比。数据从 ~/.dsh/sessions 的会话日志聚合而来。 / Usage statistics panel for DeepSeek Harness: a stats card on the blank-session hero with sessions, messages, total toke
Install
dsh plugin add @hwfee/dsh-usage-stats Confirm the layer applied with dsh --profile default --dump-config — see the install guide.
Source
Published to npm without a public repository. Inspect the package contents before installing.
Tags
Readme
@hwfee/dsh-usage-stats
DeepSeek Harness (DSH) 的本地会话用量看板插件。
装上之后,每次打开新对话空白页,问候语下方会多出一张统计卡片:看看你一共开了多少次会话、发了多少条消息、烧了多少 Token、最常在几点干活、最爱用哪个模型,外加一张活跃度热力图和一句按经典小说字数折算的对比。
所有数据都从你本机 ~/.dsh/sessions 下的会话日志里聚合,纯本地计算,不发任何外部请求。
安装与卸载
在命令行运行,或在 DSH 的 设置 → 插件 → 添加插件 里直接输入 @hwfee/dsh-usage-stats:
dsh plugin --profile desktop add @hwfee/dsh-usage-stats
装完或卸完后必须彻底退出并重开 DSH。
卸载:
dsh plugin --profile desktop remove @hwfee/dsh-usage-stats
看板里有什么
- 两个标签页 + 三个时间范围
- 左上角切换 「总览」 和 「模型」(按 Token 消耗从高到低列出每个模型的用量和占比条)。
- 右上角切换 「全部 / 30 天 / 7 天」,实时重算六张卡片和模型列表的数字。
- 六张核心指标卡
- 会话数(只算真正发过
user/message的会话,空会话不算;已删除的会话仍然算,见下文第 3 条)、消息总数、总 Token、活跃天数、高峰时段(12 小时制)、最常用模型。
- 会话数(只算真正发过
- 活跃度热力图
- 7 行 × N 列,右下角那一格永远锚定「今天」,从今天往前回溯填满整周,不会出现缺半截的尾列或未来日期。鼠标悬停在格子上会显示当天的日期与消息数。
- 小说字数折算
- 底部每次打开新会话随机抽一本书(《红楼梦》73 万字、《三国演义》63 万字、《围城》23 万字、《活着》12 万字、《骆驼祥子》10 万字),算算你用掉的 Token 大概能印几本。挂载后固定,切换时间范围不会乱跳。
设置项(高度与数字单位)
如果同时装了 dsh-cds-theme,下面这两行设置会自动出现在 设置 → 主题定制 最底部;没装主题插件时,它们会自动落回 设置 → 通用设置:
- 用量面板高度:滑块
240–520 px(步进 4px,默认 344px)。调小高度时,总览页会按「先缩热力图格子 → 再收间距 → 最后微调卡文字号」的顺序等比缩放,绝不会出现竖向滚动条;总览和模型两个标签页共用同一个高度,切换标签时底下的输入框不会上下乱跳。 - 数字单位:开关切换 万/亿(
1.2万、1.23亿)或 K/M/B(1.2K、123M),默认跟随界面语言(中文用万/亿,英文用 K/M/B)。
几个容易踩坑的实现细节
1. 为什么要自己按魔数切 zstd 帧
DSH 的会话日志(*.zstd)是多个 zstd 压缩帧首尾直接拼接写进去的。如果直接拿 Node 自带的 zlib.zstdDecompressSync 去解整个文件,它只会解出第一帧,后面追加的所有对话都会被静默丢掉,算出来的 Token 少一大截。
lib/usage-store.js 的做法是按 zstd 帧魔数(28 B5 2F FD)把文件切开,逐帧解压后再按行解析 JSON。
2. 为什么第一次打开要 2 秒,之后只要 20 毫秒
百来个会话文件大约有 50 MB 压缩数据、两万多个 zstd 帧。第一次冷启动全量解压需要约 2 秒;解析完后,每个文件的摘要会按 (路径, mtimeMs, size) 持久化写进 ~/.dsh/cache/usage-stats/(故意不放系统临时目录,防止被 Windows 存储感知定期清掉)。之后每次重启 DSH 并在后台分批预热,打开新会话几乎是瞬开。
3. 为什么删了会话,统计不会变少
看板的数字不是「磁盘上现在有什么」,而是一本累计账本:每个会话一行,存在 ~/.dsh/cache/usage-stats/ledger-<哈希>.json。会话继续写的时候整行替换,日志被删掉时行不删。
- 归档:只往宿主的
workspace.json里加一个 id,日志原地不动——有没有账本都会被统计。 - 删除:真的删掉
~/.dsh/sessions/.../<会话>/session.v4.jsonl.zstd,只有账本还记得它。 - 数字因此只增不减。想清零就删掉
ledger-<哈希>.json(下一次打开会从现存日志重建);?refresh=1只重读日志,不动账本。 - 账本只存计数(消息数、Token、按天/小时/模型),不存提示词、不存路径。
4. 为什么完全跟随宿主令牌
面板样式全部使用 --dsw-alias-* 和 --dsw-radius-* 宿主变量,不写死任何色值。不管你用 DSH 原生明暗主题,还是装了 dsh-cds-theme 切陶土橙、调圆角,看板都会自动跟着变。
面板的每一层都是半透明的,空白页的海面动画能从面板、卡片和热力图后面透出来:外壳 52%、热力图底 20%,热力格按活跃度 12/22/32/42% 递进(最热的一格也仍然透光)。六张指标卡只铺 6% 的淡色底纹,靠内描边(.5px border-l2,用 inset 阴影画,不占布局)区分彼此——六格清清楚楚分得开,同时不挡后面的画面。文字不跟着变淡:只是底色透,字还是宿主原色。
本地开发与测试
npm ci # 仅安装开发期打包工具 esbuild,零运行时依赖
npm run build # 编译客户端产物:client/src/* -> client/client.js
npm test # 产物新鲜度检查 + 清单契约 + 8 个测试文件(条数以输出为准)
详细的接口与缓存设计契约见仓库根目录的 docs/usage-stats-contract.md。