DeepSeek Harness plugin

dsh-token-stats

Token usage statistics for DeepSeek Harness: cumulative and peak tokens with a live HUD.

Jump to install

Source facts

Repository
huantian1223/dsh-token-stats
Latest update
Aug 22, 2026
Category
Usage & Billing
GitHub stars
1
Format
plugin
Catalog evidence
Upstream dsh.bundle evidence
Evidence path
package.json#dsh.bundle
Checked against
0.1.0-rc.8
Upstream check date
2026-08-20

This evidence comes from the upstream catalog. This site has not installed, run, or security-reviewed the plugin.

Install

Start with a prompt that asks an agent to review the GitHub repository and source. Switch to the command if you want to install it yourself.

Copy this prompt into DSH, Codex, or another agent and ask it to review the GitHub repository and source first.

Do not install or run any commands yet. Read this plugin's GitHub repository, README, and relevant source code. Then answer the questions below clearly and directly so I can decide whether it fits my needs:

1. What is this plugin, and what problem does it solve?
2. Who is it for, and what are its typical use cases?
3. How is it used after installation? Include one minimal example.
4. What known limitations or privacy, security, compatibility, or maintenance risks does it have?
5. Give a clear recommendation: recommend, conditionally recommend, or do not recommend, with reasons.

Distinguish statements documented by the repository, inferences from source code, and unknowns. If evidence is insufficient, say so explicitly. Do not guess or simply repeat the README.

GitHub: https://github.com/huantian1223/dsh-token-stats
Plugin: dsh-token-stats
Author: huantian1223

Check the source files

Read the README and other files from this plugin directory before installing.

File explorer4 files
README.en.mdSource · read only
README language

dsh-token-stats

Token usage statistics plugin for DeepSeek Harness (DSH). It parses real provider usage data from DSH session logs (session.jsonl.zstd) and provides complete usage statistics inside the Web GUI: cumulative / today / peak tokens, longest chat duration, streak days, and a 12-month activity heatmap (daily / weekly / cumulative), broken down by model and workspace.

![Token usage statistics](docs/screenshot.png)

Features

Stat cards (6 cards, 3×2 grid)

The page opens with six key figures in a symmetric 3-column × 2-row grid (2 columns on narrow screens):

CardMeaning
Cumulative tokensFull total of input + output + cache read + cache write
Today's tokensUsage so far today, with the call count and its share of the cumulative total
Peak tokensHighest single-session consumption, with the date it happened
Longest chatLongest continuous chat session (sessions are split after 30 minutes of inactivity)
Current streakConsecutive active days ending today (or yesterday)
Longest streakBest consecutive-active-days run on record

An "active day" is any day with at least one token-consuming call.

Activity heatmap

A GitHub-style 7-row calendar grid (Mon–Sun) over a rolling 12-month window, with two freely combinable dimensions:

  • Three views:

- Daily: each cell is that day's usage - Weekly: each cell is its week's total (the whole 7-cell column lights up, so an active week reads at a glance) - Cumulative: each cell is the running total up to that day (a left-to-right gradient ramp)

  • Time range: 12 months / 3 months / 30 days, 3 months by default (so sparse data does not leave the calendar mostly empty)
  • Hover preview: a bubble shows "8月13日 使用了 6391.7万个 Token(58 次调用)"; empty days show "无使用"
  • Click to drill down: in the daily view, clicking a day cell opens that day's detail dialog — every session's tokens and calls for the day, labeled with the session title (so you can tell which session it is), repeated titles auto-merged with a ×N count, paginated 10 rows per page; with the dialog open you can click other dates to switch directly
  • CSV export: one-click export of the current range as per-day rows (date / tokens / calls), with a UTF-8 BOM so Excel opens it without garbled text

Consumption breakdown

Input / output / cache read / cache write / reasoning with full-precision numbers (thousand separators, no 万/亿 abbreviation) — exact figures when you need them. (Cache read is DeepSeek's prefix-cache hits; it usually dominates the total but bills far below input.)

By model / workspace

Per-model and per-workspace consumption rankings with full-precision numbers, so you can see at a glance which model and which project directory consume the most.

Live session badge

Two pills sit in the conversation header, always visible:

  • 本会话 X: the current session's token usage, polled every 10 seconds; click for the session detail dialog (total / input / output / cache / reasoning, a per-model breakdown, and the session title), with a one-click shortcut to the full statistics
  • ¥ balance: the DeepSeek account balance, polled every 15 minutes; clicking force-refreshes the balance and opens the dedicated balance dialog

DeepSeek account balance

The balance appears in three places, each with its own purpose:

1. Header balance pill: next to the session badge, visible at all times 2. Dedicated balance dialog: opened by clicking the pill — a large amount with availability status, topped-up / granted breakdown, a refresh button, and the data source / last-updated time 3. Balance panel on the full stats page: a compact full-width strip below the heatmap, with its own refresh button

Refresh behavior: clicking refresh forces a live query to the DeepSeek open platform (/user/balance) via ?force=1, with a "刷新中…" state on the button; the balance is near-realtime — whenever new tokens are burned (session usage advances or the cumulative total moves) it auto-refreshes (5s throttle), with a 60-second poll as the idle baseline; on failure the last cached value is kept (no flicker). The API key is resolved through the DSH credentials service and stays in the host process — it is never sent to the browser.

Standalone stats page

http://127.0.0.1:3080/token-stats: the same dark-themed full statistics page as the GUI, directly accessible without opening the GUI, auto-refreshing every 15 seconds, with heatmap / balance / breakdowns / export / drill-down all working.

Balance warning: when the balance drops below the configured threshold (¥5 by default, balanceWarnThreshold, 0 disables it), the header pill dot turns red and the balance dialog / stats-page panel show a red "余额不足" state with a top-up reminder, so calls never fail silently on an exhausted balance.

Data source

All figures come from real provider usage recorded in DSH session logs (inputTokens / outputTokens / cacheReadTokens / cacheWriteTokens / reasoningTokens) — no estimation, no traffic interception. On startup the plugin replays historical session logs, captures new usage live via session/event, and reconciles incrementally every 30 seconds.

Data is stored at $DSH_HOME/token-stats/usage.jsonl ($DSH_HOME is the DSH data root; it defaults to ~/.dsh or the DSH_HOME environment variable).

Configuration

Tunables are overridden through $DSH_HOME/token-stats/config.json (defaults apply when absent):

{
  "gapMs": 1800000,
  "rescanIntervalMs": 30000,
  "balanceCacheMs": 15000,
  "windowMonths": 12,
  "defaultRange": "3m",
  "balanceWarnThreshold": 5
}
KeyDefaultMeaning
gapMs1800000 (30 min)Inactivity gap that splits a session into separate chats
rescanIntervalMs30000 (30 s)Session-log reconciliation interval
balanceCacheMs15000 (15 s)Balance query cache TTL (for the near-realtime, usage-driven refresh)
windowMonths12Full heatmap window in months
defaultRange3mDefault heatmap range (12m/3m/30d)
balanceWarnThreshold5 (¥)Red balance warning below this amount (0 disables)

Restart DSH after editing; the effective config is exposed at GET /token-stats/api/config.

Tests

pnpm test

Vitest suite covering zstd multi-frame decoding, log parsing, aggregation, store dedupe/merge, config merging and the balance service (24 cases, fixture data, no live logs).

Installation

The plugin mounts through DSH's profile plugin mechanism (managed by dsh plugin, the same mechanism as @liustack/modlens):

1. Add the dependency and bundle entry in the web profile's package.json:

// data/profiles/web/package.json
{
  "dependencies": {
    "dsh-token-stats": "link:../../path/to/dsh-token-stats"   // or file:, or a version once published to npm
  },
  "dsh": {
    "profile": {
      "bundles": ["@deepseek-ai/dsh-base", "@deepseek-ai/dsh-web-app", "dsh-token-stats"]
    }
  }
}

2. Run pnpm install in the profile directory 3. Restart DSH (exit and relaunch)

HTTP API

EndpointDescription
GET /token-stats/api/statsFull stats snapshot (everything the cards / heatmap / breakdowns need)
GET /token-stats/api/balanceDeepSeek account balance (15-minute cache; ?force=1 to bypass)
GET /token-stats/api/day?date=YYYY-MM-DDPer-session usage for one date (heatmap drill-down)
GET /token-stats/api/session/<sessionId>Single-session usage summary (used by the badge / dialog)
GET /token-statsStandalone stats page (HTML)

Package structure

dsh-token-stats/
├── package.json          # dsh.bundle.patch (host mount) + dsh.client (browser half)
├── cordis.patch.yml      # plugin loading config
├── dsh/                  # host half: log scanning, aggregation, HTTP routes
│   ├── index.js          # apply(ctx): boot backfill + live capture + routes
│   ├── scan.js           # session-log scanning and usage extraction
│   ├── stats.js          # aggregation (cumulative / peak / heatmap / streaks / today / sessions)
│   ├── zstd.js           # multi-frame zstd decoding (session logs are frame-appended)
│   ├── store.js          # usage.jsonl persistence and migration
│   ├── home.js           # DSH data root resolution
│   └── page.js           # standalone stats page
└── client/               # browser half: settings page + session badge + dialogs
    └── bundle.js         # web shell loader format, hand-written, no build step

License

[MIT](LICENSE)