← Back to home@qwert702

dsh-token-viewer

Developer tool: live token usage & cost monitoring for DeepSeek Harness - consumed tokens for the current session and across all sessions, read from token-meter projections. No model calls.

Stars
7
Language
TypeScript
Created
Aug 14, 2026
Updated
Sep 19, 2026

Introduction

dsh-token-viewer

CC Switch-style token consumption statistics for the DeepSeek Harness Web GUI. Read-only surfaces over the harness's host-computed projections plus one balance read; the plugin adds no prompt content, tools, or provider requests.

Install (one command):

dsh plugin add qwert702/dsh-token-viewer

Restart the harness, refresh the web page, then click the Token icon in the sidebar panel list; the account balance also shows up as a chip at the bottom of the sidebar.

Targets harness 0.1.6-alpha.2. Earlier versions of this plugin disabled the official ui-sidebar plugin and forked its sidebar.workspaces.header slot; that slot is gone in 0.1.6, so v0.2.1 and later no longer override any official plugin — it registers into the stock slots instead. On an older harness, pin v0.2.0.

Features

  • Sidebar panel — a Token row in the sidebar's global panel list; clicking it opens the plugin's page in the main area: DeepSeek account balance (with refresh; error-retry when the host proxy fails) and aggregate consumption across all sessions, expandable to a per-conversation list.
  • Balance chip — the sidebar footer carries the live account balance (full amount when the sidebar is wide, a bare currency mark on the collapsed rail); clicking it opens the statistics drawer.
  • TokenDock — a slim live strip above the composer showing the current session's billed input (uncached + cache read + cache write), output, cache hit rate, and approximate context occupancy.
  • Usage statistics panel (drawer in shell.overlay, a faithful port of CC Switch's usage-dashboard method):
    • Per-request statistics — the host usageLog projection records one timestamped entry per reported assistant step (commit time, model, four token buckets); every figure folds these records, never cumulative session totals.
    • Hero — real consumption (fresh input + output + cache write + cache read), request count, total cost, over a five-card breakdown row with a cache-hit-rate progress bar.
    • Trend chart — requests bucketed by their own commit time (hourly for the day, daily otherwise, empty buckets zero-filled), four token series plus a dashed cost line.
    • Three tabs — request log (newest first; clicking a row opens that session), per-project statistics, and per-model statistics with average cost.
    • Range presets — today / 7d / 14d / 30d / all, resolved exactly like CC Switch (local midnight of N−1 days back).
  • Per-model peak/off-peak list pricing — every request bills under its own model's provider list price (V4-Flash / V4-Pro, CNY per 1M tokens, cache writes at the cache-miss rate), split by the provider's Beijing peak windows (09:00–12:00 and 14:00–18:00, double the off-peak rate); versioned model ids match by prefix, unknown models fall back to the V4-Flash off-peak table. Prices live in PRICING_FALLBACK in the host half (see below).
  • Balance route — GET /api/billing/balance proxies DeepSeek's /user/balance through the harness credentials service; the API key never leaves the server.

Screenshots

Usage statistics panel overview

Per-model statistics tab

Per-project statistics tab

Slot layout

Five registrations, all in stock slots (see src/client/index.ts):

SlotSurfaceId
sidebar.panellistpanel row + icontoken
mainpanel page (its key must equal the row's id)token
sidebar.footer.actionbalance chiptoken-viewer-balance
conversation.input.docklive token striptoken-viewer
shell.overlaystatistics drawertoken-viewer-detail

Repo layout

  • src/index.ts — host half source (balance + pricing routes, modelUsage / usageLog session projections, all with wire views so the browser can read them). src is the single source of truth.
  • src/client/** — browser half source: the five slot entries above, their components, and their CSS Modules.
  • lib/index.js, lib/client.js — the built artifacts the harness actually loads. Committed on purpose so dsh plugin add works with no build step.
  • scripts/build-client.mjs — node scripts/build-client.mjs: esbuild builds both halves (src/index.ts → lib/index.js, src/client/index.ts → lib/client.js). react and the harness's other static browser modules stay external; .module.css goes through a small built-in CSS Modules plugin that scopes class names and injects a <style data-plugin data-plugin-css> tag at materialization.
  • test/smoke.cjs — node test/smoke.cjs: harness-free smoke test. It stubs window.__ModuleLoader__ in a vm sandbox, runs apply() against a recording slot registry, renders every component against a stub kit, and imports the host half for real.

The TypeScript monorepo source (extracted from deepseek-ai/deepseek-harness) lives on the archive/monorepo-src branch.

Model pricing

PRICING_FALLBACK in src/index.ts (built into lib/index.js) holds the current DeepSeek list prices; the panel fetches GET /api/billing/pricing, which prefers the provider's official pricing page when reachable and falls back to the built-in table otherwise. The browser half carries no pricing table of its own — it bills purely from what the route returns.

License

MIT