DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

satan9394 /

satan9394/dsh-usage-unified

Verified

Machine-wide DeepSeek Harness (dsh) token usage statistics — trends, a custom date range, per-model bucket splits, call details, CSV/JSON export. 全机 DSH 用量统计:趋势 / 自定义区间 / 模型四桶 / 调用明细 / 导出,中英双语、浅深色。

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@df8f179a

dsh-usage-unified

English | 中文

One DeepSeek Harness (dsh) plugin that is the union of two upstream plugins, so no feature lives in one and not the other:

Upstream What it contributed
lanlandeli/dsh-usage-stats The rich dashboard: sidebar + full-screen overlay, per-day token trend, model donut, token-composition card, per-call detail table with filters and pagination, CSV/JSON export, workspace/task-scope filters, zh/en i18n, theme-adaptive styling.
zoyluoblue/deepseek-harness-token The machine-wide core: discovery of every dsh home (~/.dsh, ~/.dsh_desktop/<version>, $DSH_HOME), raw session-log reading (zstd container frames), the pure resumable fold, an incremental durable index, all-time / 7d / 30d ranges, current + longest streaks, peak hour, per-model disjoint-bucket split, coverage disclosure, and a Settings section.

The two were merged at the data layer, not bolted together: one machine-wide index now feeds one dashboard, so the numbers agree everywhere.

Feature matrix (after the merge)

Feature Upstream #1 Upstream #2 Unified
Machine-wide (all dsh homes / old Desktop versions) ✗ ✓ ✓
Both session-log formats (session.jsonl.zstd, session.v3.jsonl.zstd) n/a ✗ (v0 only) ✓
Sidebar entry + full-screen overlay ✓ ✗ ✓
Settings → Usage section ✗ ✓ ✓
Token totals incl. cache reads ✓ ✓ ✓
7d / 30d / all-time trend ✓ ✓ ✓
Custom date range ✗ ✗ ✓
Smooth multi-series trend (total / input / output / cache read) ✗ ✗ ✓
Current streak ✓ ✓ ✓
Longest streak ✗ ✓ ✓
Peak hour ✗ ✓ ✓
Cache-hit-rate + model-call cards ✗ ✗ ✓
Per-model donut + share ✓ ✗ ✓
Per-model input/cacheRead/cacheWrite/output split ✗ ✓ ✓
Per-call detail table (time, duration, tokens, cache %, model, effort) ✓ ✗ ✓
Workspace + main/subtask scope filters ✓ ✗ ✓
CSV / JSON export ✓ ✗ ✓
Coverage + homes + skipped-log disclosure ✗ ✓ ✓
zh/en, light/dark ✓ ✓ ✓

The activity heatmap both upstreams shipped was dropped here as redundant with the trend chart.

Install

# straight from GitHub (runtime files are committed — no install-time build):
dsh plugin --profile web add github:satan9394/dsh-usage-unified

# from an npm release, once published:
dsh plugin --profile web add dsh-usage-unified

# from a local checkout:
dsh plugin --profile web add E:\path\to\dsh-usage-unified

Restart the Web profile. The dashboard appears as a 使用统计 / Usage Stats item in the sidebar footer, and as a section under Settings. All data stays local; the routes answer loopback callers only.

See docs/COMPATIBILITY.md for the declared Node/DSH ranges and docs/SECURITY.md for permissions, dependencies, and failure bounds.

Architecture

src/
  index.ts          host entry: Config, mount index + routes + refresh loop
  homes.ts          discover every dsh home (deduped by sessions realpath)
  reader.ts         walk session logs; decode both on-disk formats (no private API)
  zstd-frames.ts    scan concatenated zstd frames (resume cursor is frame-aligned)
  fold.ts           pure resumable fold: session → totals, day/hour slices, calls
  aggregate.ts      snapshot + call rows + streaks/peak hour + CSV
  index-store.ts    incremental index, file-backed cache under DSH_HOME
  transport.ts      /snapshot, /calls, /export.csv, /export.json (loopback only)
  types.ts          the wire contract shared by both halves
  client/
    index.tsx       sidebar + overlay + settings registrations, dashboard
    i18n.ts         merged zh/en dictionaries
    source.ts       the one transport seam
    styles.ts       dashboard stylesheet

Key design decisions (full rationale in PLAN.md):

  • The reader is harness-version-agnostic. Legacy logs are JSONL storage records where streaming content is packed (text-chunks, …) with no seq; versioned logs are plain events. Token accounting only needs the sequenced events (assistant/message carries the final usage), so the reader keeps any line with a string type and numeric seq and skips the packed runs — no dependency on the harness's private decodeStorageRecord, which has moved between releases.
  • One row per (turn, step). A usage report arrives twice per step (a streaming assistant/chunk and the final assistant/message); the fold replaces rather than accumulates, and stores one call row per step for the detail table. Compaction summaries are their own rows.
  • All-time vs bounded range. All-time reads authoritative per-session counters (so tokens with rejected timestamps are still counted); a bounded range is summed from day slices (so it can be smaller — the honest behaviour).
  • File-backed cache. The index persists to $DSH_HOME/usage-unified/index-v1.json atomically, rather than depending on ctx.storageDomain, so the panel always loads.

Development

npm install          # .npmrc sets legacy-peer-deps for the dsh peer tree
npm run typecheck    # tsc --noEmit
npm run test         # vitest (45 tests)
npm run build        # tsdown → lib/index.js + lib/client.js
npm run check        # all three
npm run verify:realdata   # read-only pass over this machine's real dsh homes
npm run smoke:local       # local HTTP self-test against real ~/.dsh (no install)
npm run smoke:serve       # keep the local viewer up (prints the URL)
npm run report            # static self-contained report (30d) → opens in browser
npm run report:all        # same, all-time range

smoke:local is the "run it in the workspace, point at the real data" path: it does not touch the DSH profile. It mounts the same host routes over a plain Node server on a free loopback port, points the index at the real ~/.dsh, runs seven HTTP assertions (snapshot 7d/all, main scope, calls, CSV, JSON, 404), and — with smoke:serve — serves a small built-in viewer so the real numbers are visible without the DSH UI. The first cold scan takes minutes; the index is cached in .smoke-cache/ (gitignored), so later runs are seconds.

verify:realdata walks every real session log, folds it, and cross-checks the folded tokens against an independently coded reconstruction of provider usage; it prints the discovery, both formats, totals, models, workspaces, coverage, the call endpoint and a persistence round-trip.

Compatibility

  • Targets the dsh 0.1.5-rc.1 plugin API (peerDependencies), and reads both the legacy and the current session-log layouts, so it is not limited to one harness generation.
  • The browser half declares its own minimal structural types for the injected runtime seam (src/client/runtime.d.ts) instead of importing @deepseek-ai/dsh-client-runtime, whose published line has diverged from the one the harness ships. The @deepseek-ai/* client modules remain peerDependencies, provided by the harness at load time.

Cross-agent leaderboard (optional, opt-in)

The dashboard here is DSH-only and works entirely offline — installing the plugin never contacts the network and never uploads anything. Aggregating every agent on the machine (DSH, Claude Code, Codex, OpenCode, …) into one number and posting it to the tokscale leaderboard is opt-in and only happens if you run the guided setup from a clone of this repo (the plugin itself never needs it):

git clone https://github.com/satan9394/dsh-usage-unified && cd dsh-usage-unified
npm install
npm run leaderboard:setup     # guided: install/login tokscale, export, first submit
npm run leaderboard:off       # undo: remove the daily task, stop submitting

leaderboard:setup follows docs/LEADERBOARD.md, which states exactly what leaves the machine and asks before anything is uploaded. That document also covers the exporters (scripts/tokscale-export.mjs for DSH's versioned logs, scripts/ccswitch-export.mjs for CC Switch's proxy-side Claude usage), the pricing table (scripts/custom-pricing.mjs), and the daily refresh task.

Privacy at a glance

A submit carries aggregates only — token buckets per day, estimated cost, message counts, client and model names, MCP server names, session timing metrics, a random dev_… device key, and the CLI version. It never carries prompts, responses, source code, or workspace/file paths. Two items cannot be redacted at upload: model/provider names and MCP server names (rename your MCP servers if those are sensitive). Set TOKSCALE_USERNAME before npm run report to embed your own profile card; leave it unset and the report stays anonymous.

License

MIT — see LICENSE. Derived from two MIT-licensed plugins; see _upstream/ for their sources.

—/ 5

No ratings yet

Verified DSH bundle

Commit df8f179ad343

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout