🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

Token 方块墙 ChinRinhan/dsh-token-wall

DeepSeek Harness
ChinRinhan13 天前有提交已提供中文文档扫描:含敏感能力

把模型调用消耗的 Token 累积成可视化方块墙

30/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/23 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add ChinRinhan/dsh-token-wall
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么[目录]—
dsh 原生插件 · platform
暂无时间戳·判据 →
装得上吗[实装验证]✓
本站已在 dsh 0.2.1-rc.2 下真实安装成功
非静态推断
L4 · 真实安装等级说明 →
数据截至 2026/10/23·判据 →
安全吗[自动扫描]—
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
数据截至 2026/11/04·判据 →
还在维护吗[仓库]✓
活跃:最近一次提交在 13 天前
暂无时间戳·判据 →
图例:✓ 通过! 需注意— 未判定 / 无数据· 「未判定」= 本站尚无数据,不代表插件有问题
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →

可信度证据

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

读写/删除本地文件发起外部网络请求
查看扫描证据(共 14 处,展示前 14 条)
  • 发起网络请求
    client.js:1047
    fetch(path, { signal: controller?.signal, cache: 'no-store' })
  • 发起网络请求
    client.js:1287
    fetch(`${ROUTE_PREFIX}/prefs`, {
  • 发起网络请求
    client.js:2776
    fetch(todayPath(), { cache: 'no-store' })
  • 发起网络请求
    client.js:2782
    fetch(todayPath(), { cache: 'no-store' })
  • 读取本地文件
    lib/store.js:199
    if (!existsSync(this.path)) return { days: new Map(), watermarks: new Map() }
  • 读取本地文件
    lib/store.js:200
    return parseDocument(readFileSync(this.path, 'utf-8'))
  • 写入本地文件
    lib/store.js:254
    mkdirSync(dirname(this.path), { recursive: true })
  • 写入本地文件
    lib/store.js:299
    writeFileSync(tmp, JSON.stringify(payload, null, 2), 'utf-8')
  • 写入本地文件
    lib/store.js:300
    renameSync(tmp, this.path)
  • 读取本地文件
    lib/prefs.js:120
    if (!existsSync(this.path)) return { ...DEFAULT_PREFS }
  • 读取本地文件
    lib/prefs.js:121
    const raw = JSON.parse(readFileSync(this.path, 'utf-8'))
  • 写入本地文件
    lib/prefs.js:137
    mkdirSync(dirname(this.path), { recursive: true })
  • 写入本地文件
    lib/prefs.js:139
    writeFileSync(tmp, JSON.stringify({ schema: PREFS_SCHEMA, ...next }, null, 2), 'utf-8')
  • 写入本地文件
    lib/prefs.js:140
    renameSync(tmp, this.path)
扫描于 2026/11/4(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

社区实装还没有人打卡 · 装过的第一个就是你
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

GitHub 仓库 ChinRinhan/dsh-token-wall:统计并展示 token 用量。

README

由 DeepSeek 最新模型翻译生成
dsh-token-wall Token 用量看板插件,用于 DSH(DeepSeek Harness)。 按本机时区记录每次模型调用的 token 消耗,并把「攒了多少」做成看得见的方块墙。 方块墙主面板与桌宠 - 方块墙:每 10M tokens 填一格,100 格一页,累计只增不减 - 桌宠:常驻角落里的小面板,一个充能块 + 一个池,可拖动 - 消耗分布:按工作区 / 模型 / 厂商三档切换 - 设置页:区间汇总表,支持按天 / 周 / 月 / 渠道 / 模型 / 类型分组 - 历史回填:从已有会话日志补齐历史,不是装上才开始记 - 实时捕获:之后每次模型调用即时入账 npm 包名是 dsh-token-wall(dsh-token-usage 已被另一个同类插件占用)。 插件内部的标识(路由前缀 /dsh-token-usage、存储目录、localStorage key)都保持不变,所以升级不会丢历史数据。 安装 本插件以 Cordis bundle 形式发布,宿主是 DSH 的 Web profile。
展开完整文档(README 剩余 1 节)
dsh-token-wall

Token 用量看板插件,用于 DSH(DeepSeek Harness)。

按本机时区记录每次模型调用的 token 消耗,并把「攒了多少」做成看得见的方块墙。

方块墙主面板与桌宠

- 方块墙:每 10M tokens 填一格,100 格一页,累计只增不减
- 桌宠:常驻角落里的小面板,一个充能块 + 一个池,可拖动
- 消耗分布:按工作区 / 模型 / 厂商三档切换
- 设置页:区间汇总表,支持按天 / 周 / 月 / 渠道 / 模型 / 类型分组
- 历史回填:从已有会话日志补齐历史,不是装上才开始记
- 实时捕获:之后每次模型调用即时入账

npm 包名是 dsh-token-wall(dsh-token-usage 已被另一个同类插件占用)。
插件内部的标识(路由前缀 /dsh-token-usage、存储目录、localStorage key)都保持不变,所以升级不会丢历史数据。

安装

本插件以 Cordis bundle 形式发布,宿主是 DSH 的 Web profile。

方式一:从 npm 安装(推荐)

cd ~/.dsh/profiles/<profile>
npm install dsh-token-wall

然后在 profile 的 cordis.patch.yml 里插入 bundle:

- insert:
- id: dsh-token-usage # ⚠️ 用这个 id,不是包名 name: 'dsh-token-wall' config: keepDays: 400

⚠️ id 与 name 不同是有意的:id 是插件内部标识(决定路由前缀与存储目录),必须保持 dsh-token-usage 才能沿用已有数据;name 才是 npm 包名。

方式二:从源码克隆

<profile> 通常是 ~/.dsh/profiles/<名字> Windows: %USERPROFILE%\.dsh\profiles\<名字>
cd ~/.dsh/profiles/<profile>/node_modules
git clone https://github.com/ChinRinhan/dsh-token-wall.git dsh-token-wall

方式三:用 DSH 的插件管理

在 DSH 会话里执行:

plugin_manager install_bundle target=dsh-token-wall
plugin_manager set_bundle target=dsh-token-usage enabled=true

验证装上

启用后宿主会注册四条路由。把 <port> 换成你的 Web GUI 端口:

curl http://127.0.0.1:<port>/dsh-token-usage/today

返回 {"ok":true,"totals":{...},"allTime":{...},...} 就说明装好了。

界面上应该能看到三样东西:侧栏多出一个方块图标、右下角出现桌宠、设置页多出「Token 用量」一节。

首次启动会回填历史

backfillOnStart(默认开启)会扫描 $DSH_HOME/sessions 下的会话日志,把装上之前的用量补进来。

参考量级:本机 116 个会话、22 天、8,410 条记录,回填耗时数秒。

从源码安装迁移到 npm 安装

如果你之前是 clone 到 node_modules/dsh-token-usage 的,改成 npm 安装后要注意目录名变了(dsh-token-usage → dsh-token-wall):

cd ~/.dsh/profiles/<profile>
rm -rf node_modules/dsh-token-usage # 旧目录(如果不是软链)
npm install dsh-token-wall

历史数据不需要迁移:存储路径由插件内部标识决定,与包名无关,仍是 $DSH_HOME/token-usage/daily.json。

界面

方块墙(主面板)

点侧栏的方块图标进入。

总消耗 684,561,075 tokens 已获得 68 块 · 第 1 页 ████ ████ ████ ████ ████ ████ ████ ████ ████ ████ ████ ████ ████ ████ ████ ████ ████ ████ ████ ████ ... ████ ████ ████ ████ ████ ██▓░ ░░░░ ░░░░ ░░░░ ░░░░ ░░░░ ░░░░ ░░░░ ░░░░ ░░░░ ░░░░ ░░░░ ░░░░ ░░░░ ░░░░

- 每 10M tokens 一格:已填 / 正在填(按比例渐进)/ 空白,三态一眼分清
- 每 10 格一道里程碑竖线(= 1 亿 tokens),首末行标出该行的量级,看颜色密度就能判断这一段是 2 亿还是 200 亿
- 100 格一页(= 10 亿 tokens),自动停在第 N 页
- 累计 / 今日 可切换:累计是只增不减的历史总量,今日是午夜归零的当天量
- 页面下方是消耗分布与诊断信息

为什么是 10M:按真实数据量过,单轮对话中位 1.41M、p90 10.4M,典型活跃日 2–3 块、重度日 7–9 块。快慢都合适。

桌宠

常驻在窗口任意位置,也可以拖走。

┌─ Token 方块墙 ● alpha ────┐ │ 累计 2.98B │ │ ▓▓▓▓▓▓▓▓▓▓▓▓▓░░ 94% │ ← 充能块:当前这块填了多少 │ ■ 297 块 │ ← 池:已攒下的整块数 │ 今日 31.44M 1.1% · │ │ 速度 4.0K/s 昨日 127.79M │ └─────────────────────────────┘

- 拖动:按住标题栏拖,指针移出窗口也继续跟手
- 单击标题栏:折叠 / 展开(折叠后只剩一行数字,仍可拖动)
- 位置记忆:位置存在 localStorage,窗口缩放时自动钳制在可视范围内
- 窄屏隐藏:≤768px 不显示(拖拽手势会和页面滚动打架)

动效很克制:充能到 90% 以上时充能块轻微呼吸,攒到新的一块时池弹一下。系统开了「减少动态效果」时会全部关掉。

消耗分布

同一块区域,三个视角切换:

| 维度 | 回答的问题 |
| 工作区 | 我在哪个项目花得多 |
| 模型 | 我在用哪个模型花 |
| 厂商 | 我在给哪家公司送钱 |

「模型」视角会自动归并同一模型的不同写法。比如这四行其实是同一个模型:

deepseek-v4.1-flash 1.54B ← 主名 workbuddy/deepseek-v4.1-flash 25.6M ← 带渠道前缀 deepseek-ai/deepseek-v4.1-flash 52K ← 另一种前缀 deepseek-v4.1-flash-free 23.1M ← 带 free 后缀

归并后合成一行:1.62B · 4 个变体。

按模型分布,deepseek-v4.1-flash 合并了 4 个变体

⚠️ 但不同代际不合并。deepseek-flash、deepseek-v4-flash、deepseek-v4.1-flash 是三个版本,合并会掩盖「还在用旧模型」这件事。

⚠️ 认不出厂商的模型归入「其他」,不猜。可以用配置里的 modelAliases 显式声明,见下。

当前在用的工作区 / 模型会高亮。

设置页

「Token 用量」一节包含:

- 运行时开关(5 个,点完立即生效):桌宠、方块墙面板、输入框上方横幅,以及两个统计口径——含子会话、含辅助调用
- 今日与累计卡片
- 区间汇总表:按天 / 周 / 月 / 工作区 / 渠道 / 模型 / 渠道+模型 / 类型分组
- 时长预设(近 7 天 / 30 天 / 90 天)+ 自定义起止日期
- 过滤开关:含子会话、含辅助调用
- 诊断区:已跟踪会话数、实时入账数、回填状态、存储位置

配置

在 profile 的 cordis.patch.yml 里覆盖,插件升级不会丢:

- id: dsh-token-usage # 内部标识,不要改(决定路由前缀与存储目录) name: 'dsh-token-wall' # npm 包名 config: keepDays: 400 # 保留天数(落盘时淘汰更早的日键) includeSubagents: true # 计入子代理 / 团队 / workflow 子会话 includeAuxiliary: true # 计入压缩等辅助调用 statusBarEnabled: true # 是否允许显示输入框上方的横幅 statusBarRefreshMs: 1000 # 轮询间隔,最小 1000 backfillOnStart: true # 启动时回填历史

可选:手动声明模型别名(认不出的模型可以在这里归类) modelAliases: dfmodel: vendor: deepseek model: deepseek-v4.1-flash

开关有两层,分别管什么

| | 位置 | 生效方式 | 用途 |
| config.statusBarEnabled | cordis.patch.yml | 重启 DSH | 部署期的硬开关 |
| 设置页五个开关 | $DSH_HOME/token-usage/prefs.json | 立即生效 | 日常调整 |

设置页那五个开关存在独立文件里,是因为改 Cordis config 要重启,而「我想把桌宠关掉」显然不该重启。

其中两个是统计口径(includeSub / includeAux,对应「含子会话」「含辅助调用」)。它们会影响所有读数——方块墙、桌宠、横幅、设置页表格共用同一份口径,改完下一拍轮询就生效。放在这里而不是 Cordis config 里,是为了能随时切换并立即看到差别。

HTTP 接口

启用后宿主注册四条路由,默认绑定 Web GUI 的端口。

| 路径 | 说明 |
| GET /dsh-token-usage/today | 今日 + 昨日 + 累计 + 本次运行平均速度 + 当前工作区/模型 + 运行时开关 + 诊断。接受 includeSub / includeAux,与 /summary 同一口径 |
| GET /dsh-token-usage/summary | 区间汇总。groupBy 可取 day week month provider model providerModel kind workspace modelNorm vendor |
| GET /dsh-token-usage/workspaces | 工作区分布,只回 top N(limit / from / to) |
| GET / PUT /dsh-token-usage/prefs | 运行时开关(statusBar / pet / wallPanel)。唯一可写的端点 |

/summary 还支持 from / to / includeSub / includeAux / workspace 参数。

数据口径

这一节讲清楚「数字是怎么算出来的」,因为它决定了你看到的数字意味着什么。

来源

会话日志里 assistant/message 事件的 usage 字段。它是持久化的,所以「历史回填」和「实时捕获」读的是同一份数据,不存在两套口径。

| 事件 | 类型 | 说明 |
| assistant/message | 对话调用 | 主力来源 |
| compaction/summary | 辅助调用 | 压缩摘要也是真实模型调用,计入 |

⚠️ 标题生成走的 session/title-llm-request 不带 usage,因此那部分开销无法从日志恢复。这是已知限制,不是遗漏。

合计口径

totalTokens = inputTokens + cacheReadTokens + cacheWriteTokens + outputTokens

也就是「这次调用实际过了一遍的 token 总量」。它跟服务商上报的 totalTokens(通常只是 input+output)不是一回事,所以本插件不读那个字段,自己按上式算。

outputTokens 已含思考 token,reasoningTokens 只作拆分展示,不重复计入。

「没测到」≠「用了 0」

没带 usage 的调用(中断、上游提前断开、失败)不写 0,而是根本不入桶。覆盖率在设置页诊断区如实展示。

时区

按本机时区切日,不是 UTC。午夜归零。

存储位置

$DSH_HOME/token-usage/daily.json(日聚合)与 $DSH_HOME/token-usage/prefs.json(开关)。

只落日聚合、不落明细;增量合并写,多实例并存不互相覆盖;默认 2 秒防抖落盘。

更多实现细节见 docs/DESIGN.md。

开发

npm test # 全部不依赖本机数据的测试
npm run test:data # 需要本机会话日志:交叉校验 + 存储端到端
npm run visual # 生成视觉验证 HTML,再用浏览器截图
npm run check # 语法检查 + 落单反引号检查

测试文件

node --test test/fold.test.mjs # 日界、周月归属、合计口径、水位线去重、fork 前缀
node --test test/blocks.test.mjs # 方块换算:整除、跨页、当前块、进度、异常输入
node --test test/models.test.mjs # 模型归并:归一化、代际不合并、别名
node --test test/adapter.test.mjs # 宿主接口:新旧两代形状必须同一读数;认不出来要报 degraded
node --test test/store.retention.test.mjs # 保留期:内存与盘同时淘汰,且淘汰后不复活
node --test test/prefs.test.mjs # 运行时开关存储:缺省、原子写、脏输入、损坏回退
node test/client.smoke.mjs # 四个 slot 注册、样式真进 DOM、主题 token
node test/odometer.text.mjs # 桌宠可见文案逐条断言
node test/sparkline.test.mjs # 上升曲线几何:左低右高、不除零
node test/blocks-cross.test.mjs # 主面板/桌宠 与 lib/blocks.js 的跨端一致性
node test/distribution.test.mjs # 消耗分布:形状守卫、列宽预算、当前项高亮
node test/host.routes.test.mjs # 四条路由的 JSON 契约

需要本机数据的两个(不在 npm test 里):

node test/cross-validate.mjs "$DSH_HOME/sessions" # 与独立实现交叉校验真实日志
node test/store.e2e.mjs "$DSH_HOME/sessions" # 回填 → 落盘 → 重开 → 幂等 → 并发

辅助工具

node tools/usage-cli.mjs --sessions "$DSH_HOME/sessions" --group-by provider
node tools/rehearse.mjs # 用真实 home 跑一遍完整回填
node tools/preview-blocks.mjs # 字符画方块墙
node tools/analyze-blocks.mjs # 分析「10M 一格」的填充速度
node tools/migrate-workspace.mjs --home "$DSH_HOME" # 桶键 4 段 → 5 段(dry-run)
node tools/visual-check.mjs # 生成视觉验证 HTML

tools/visual-check.mjs 把真实组件装进真实 React 18,在浏览器里渲染(effect / fetch 全真),主题 token 从宿主的真实 CSS 里读。截图用 Windows 自带的 Edge 就行:

"/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe" \
--headless=new --disable-gpu --hide-scrollbars --virtual-time-budget=6000 \
--window-size=1000,1400 --screenshot=tools/out/light.png \
"file:///$(pwd)/tools/out/visual-check.html"

改代码后怎么生效

| 改动 | 生效方式 |
| client.js | 约 500ms 内热更新(HMR 轮询文件),不用重启、不用构建 |
| cordis.patch.yml / package.json | 热重载 |
| index.js / lib/** | 禁用→重新启用该 bundle 即可,不用重启 DSH |

已知限制

- 标题生成的开销不可见:日志里没有 usage,无法恢复
- 两个真实进程密集并发写时,后写者可能基于陈旧快照覆盖。桌面场景通常单进程单配置档,影响面有限;根治需要文件锁
- 视觉验证的边界:tools/visual-check.mjs 用的是真实组件 + 真实 CSS + 真实数据,但宿主外壳是模拟的(侧栏、设置面板外框、composer 布局)。驱动真实页面需要 launch token,没有也不该去取
- ≤768px 时桌宠隐藏,窄屏只剩侧栏面板可用
- 保留期到期的那一天,更早的日聚合会从盘上和内存里一起消失(默认 400 天)。这是设计行为,不是 bug;不想要就设 keepDays: 0

宿主接口兼容性

历史回填依赖 ctx.sessionPersistence。这个服务在不同 DSH 版本里换过形状:

| 能力 | 旧版 | 0.1.0-rc.6 起 |
| 列举会话 | list() → {header, revision}[] | listSnapshots();list() 改为直接返回 SessionHeader[] |
| 读事件 | open(id,'read') → 句柄 | load(id) / inspect(id) / readFrom(id, seq) |
| fork 继承前缀 | handle.inheritedEventCount | header.seedLength / session.firstLiveSeq / session/end-seed 事件 |

插件通过 lib/adapter.js 同时支持两代。认不出来时不会假装成功:设置页「诊断」区会显示 宿主接口: list=… read=…,以及红色的「回填降级」提示——看到它就说明累计数可能偏低,请把这一行连同 DSH 版本一起反馈。

文档

- CHANGELOG.md — 版本变更:每一版修了什么、为什么、怎么验证的
- docs/DESIGN.md — 架构与关键设计:数据流、水位线去重、fork 前缀、桶键、模型归并
- docs/NOTES.md — 开发笔记:踩过的坑、验证器失效的四种方式、视觉问题清单

许可证

MIT
预览分享卡片长什么样 ↓ChinRinhan/dsh-token-wall
分享 · DeepSeek Harness Hub
ChinRinhan/dsh-token-wall

把模型调用消耗的 Token 累积成可视化方块墙

这个插件是你维护的吗?
作者本人可认领并核对本条目;认领通过后,详情页会显示「作者已认领」标记。
认领条目 →
回到顶部