Skip to main content

dsh-ui-web/packages/dsh-usage-dashboard

34Stars2Forks0Issues0Watchers

Provides a colored usage dashboard for DSH Web: automatically records token usage per response, aggregates and displays 14-day trends, model distribution, and session rankings by session/day/model, with cost estimation based on DeepSeek pricing. Data is stored locally at ~/.dsh/usage.json.

Evidence5/5methodologySourceInstallMaintenanceDSH versionSecurity scan
Machine-auditedInstall commandRepo verifieddsh-plugin topicLicenseREADMEAI wiki

ⓘ This plugin is a sub-package of the CAPTAIN1275/dsh-ui-web monorepo — stars and activity count the whole repository.

Language
TypeScript
License
Apache-2.0
Branch
main
dsh-plugindsh-plugin-marketdsh-plugins

Install

cmdweb profile
$ dsh plugin --profile web add @captain1275/dsh-usage-dashboard

Run the command above in your terminal to install this plugin via the dsh CLI. You can switch Profile in the top-right corner. New to dsh? Read the beginner tutorial

Install via your agent

Install the DeepSeek Harness plugin CAPTAIN1275/dsh-ui-web/packages/dsh-usage-dashboard for me: review the repository at https://github.com/CAPTAIN1275/dsh-ui-web first, then run the install command and verify the plugin loads successfully.

Paste this instruction to the DSH Web GUI assistant — it will install and verify for you.

One-Line Description

Provides a colorful usage dashboard for DSH Web that automatically records token usage for each model response and persists it to ~/.dsh/usage.json. Displays 14-day trend bar charts, model distribution ring charts, and top 20 session rankings, with cost estimation based on DeepSeek's official pricing.

Core Capabilities

  • Automatic Token Usage Collection: Attaches an invisible recording seat to the conversation footer that monitors token usage projected in real-time streaming. After 2 seconds of silence, the cumulative session snapshot is reported to the host (historical data before refresh is not counted as new)
  • Colorful Statistics Dashboard: Click the sidebar entry to pop up a full-screen overlay, rendering four gradient cards (cumulative tokens / call count / cache hits / estimated cost) with three dimensions: 14-day trends, model distribution, and session rankings
  • Cost Estimation: Matches model names against DeepSeek's public pricing tiers (v4-flash, v4-pro, reasoner, legacy). Cache hits separately use cache tier unit pricing to avoid double billing
  • Session Snapshot Replacement Semantics: The host only keeps the latest snapshot for the same session. Multiple reports are accumulated as "increments" to day/model/total buckets. Refresh and session switching won't result in duplicate entries
  • LAN QR Code Entry: The "View on Phone" button in sidebar calls the host interface to enumerate local IPv4 addresses, prioritizes 192.168 / 10 / 172.x, and renders a QR code with a copyable link combined with the current port
  • Check for Updates Entry: Reuses the same glass-style popup, calls host /api/web-ui/version to display current and latest version numbers
  • Settings Panel Info Card: A pure description card (no config fields) in the Web UI plugin group's settings page that explains the dashboard's record location and data landing point

Technical Implementation

  • Language: TypeScript (peer dependency React 18.2, dsh.client.platform="web")
  • Key Dependencies: @deepseek-ai/dsh-host-webserver (route host), @deepseek-ai/dsh-token-meter (token usage projection types), @deepseek-ai/dsh-client-connection (pull session model), qrcode-generator (QR code for phone view)
  • Architecture Pattern: Cordis bidirectional plugin. The Host half injects prefix routes /api/usage/{record,lan,summary} into webServer and writes aggregated data back to ~/.dsh/usage.json; the Client half attaches an invisible recording seat in the conversation.composer.dock slot, uses DOM injection to insert three buttons into the sidebar, and mounts a description card in the web-ui.plugin.item slot
  • Entry Files: Host side src/index.ts (exports name/USAGE_API_PREFIX/apply and aggregation pure functions), client side src/client/index.ts; cost tiers are centralized in src/cost.ts, UI rendering is centralized in src/client/DashboardPanel.tsx and src/client/UsageEntry.tsx

Use Cases

When you want to know "how many tokens I used in the past two weeks, which models cost the most, and which sessions ran the most," this plugin presents all data in visualization charts with local archiving and no server upload. Suitable for heavy users sensitive to call costs, developers needing reconciliation within teams, and ops/PMs doing long-term review of model rate/call distribution.

Prerequisites & Compatibility

DependencyMin VersionDescription
DSH Web0.1.0-rc.6peerDependencies pinned to ^0.1.0-rc.6 (includes @deepseek-ai/dsh-client-connection, @deepseek-ai/dsh-host-webserver), cordis patch ui-usage-dashboard needs to be resolved by host
React18.2.0Client cards, dashboard overlay, and sidebar DOM injection all depend on React 18
PlatformCross-platform (macOS / Windows / Linux)Runtime is OS-agnostic; dashboard only renders on Web host, persistence file goes to host-side ~/.dsh directory
Native ModulesNoneAll logic in TypeScript / React, QR code uses pure browser qrcode-generator, no node-gyp dependencies
NodeNot declaredNo engines field in package, but runtime needs Node built-in node:fs, node:os, node:http modules

Installation

dsh plugin --profile web add github:CAPTAIN1275/dsh-ui-web/packages/dsh-usage-dashboard

After installation, restart dsh web for the host routes /api/usage/{record,lan,summary} to be registered. The sidebar will automatically have three additional buttons: "Usage / View on Phone / Check Updates" (same source DOM injection mode as the task dashboard, self-heals during React re-renders).

Optional: Change the persistence directory via DSH_HOME environment variable (e.g., export DSH_HOME=/path/to/dir), data will go to $DSH_HOME/usage.json instead of default ~/.dsh/usage.json.

Configuration

This plugin requires no additional configuration. All three behavior parameters are hardcoded in the source code:

BehaviorValueSource
Recording silence threshold (per response end detection)2 secondssrc/client/UsageRecorder.tsx:36 (SETTLE_MS = 2000)
Model polling interval (fetch current session model name)5 secondssrc/client/index.ts:95 (window.setInterval(..., 5000))
Dashboard review days14 dayssrc/index.ts:304 (recentDays(store, 14))

The card mounted under the "Web UI Plugins" group in settings is a pure description card, exposing no toggles or input fields.

FAQ

Q: Do I need to restart DSH Web after installation?

A: Yes. The host half registers routes through ctx.inject(['webServer']); the host process won't invoke apply without restart. Browser hard refresh only remounts the recording seat and sidebar DOM, it cannot bring /api/usage/* routes online.

Q: Where is data stored? How to clear it?

A: Defaults to ~/.dsh/usage.json. Can change directory via DSH_HOME environment variable (process.env.DSH_HOME ?? join(homedir(), '.dsh'), src/index.ts:86). Deleting that file completely clears history; the plugin won't automatically migrate or back up. Next restart will start accumulating from an empty file.

Q: What unit price is used for cost estimation? Is it accurate?

A: Matches model names against DeepSeek's official public tiers: flash → v4-flash, reasoner / r1 → reasoning tier, pro / v4-pro → v4-pro, deepseek → legacy tier, others fall back to generic tier (src/cost.ts:39-46). This is an estimation for dashboard display, not a billing reference; cache hits separately use cache tier unit pricing, input tokens don't include cache portion, won't be calculated with cache tier separately.

Q: Will billing double-count tokens from a single session?

A: No. The client uses session cumulative snapshot replacement semantics: the recording component's first mount only records baseline without reporting (src/client/UsageRecorder.tsx:106-110), subsequent reports only happen after token usage "actually increases" and 2 seconds of silence (flush function). The host only keeps the latest snapshot for the same session, writes increment to day/model/total buckets using "new value minus old value"; when projection resets to zero (e.g., refreshing session), it uses Math.max(0, ...) to clamp and prevent decrement (src/index.ts:148-151).

Q: What time zone does "Today" in the dashboard correspond to?

A: Local time zone. dayKey uses Date.getFullYear/getMonth/getDate to construct YYYY-MM-DD (src/index.ts:90-95), so new day's bar chart appears only after local midnight. Server time zone and browser time zone don't affect aggregation.

Q: Anything to do after uninstall?

A: Just uninstall the plugin and restart dsh web. The host-side dispose will unregister /api/usage/* routes, the client-side mountUsageEntry returned disposer will remove the three sidebar buttons and stop MutationObserver. The historical JSON file won't be automatically deleted, staying in place for review or manual backup.

Q: How does the sidebar's "View on Phone" work?

A: Clicking it calls /api/usage/lan to have the host enumerate all non-internal IPv4 addresses on the machine, prioritizes them in four tiers: "192.168 → 10. → 172.16-31 → others" (src/index.ts:274-287), and renders a QR code with a copyable link combined with the browser's current port for easy scanning on phone under the same Wi-Fi. Requires browser to allow navigator.clipboard.writeText for copying (silently fails in insecure contexts).

Q: Supports TUI, desktop, or mobile?

A: Not currently supported. The client half's UI is entirely based on DSH Web's sidebar shell and composer dock slots; TUI, desktop, and mobile have no equivalent mounting positions. The host-side /api/usage/* routes also have no UI rendering in non-Web forms, but the host-side persistence logic itself is platform-agnostic and still writes to ~/.dsh/usage.json.

Difficulty Level

Beginner — One-line install command, restart DSH Web to see effect, all behavior parameters are hardcoded and require no adjustment. Only need to touch environment variables when wanting to change persistence directory or reconcile unit prices.

Known Issues & Limitations

  • Zero-config but non-adjustable: Recording silence threshold, model polling interval, and dashboard review days are all hardcoded (2s / 5s / 14 days), no settings provided; must modify source code and rebuild to adjust
  • Single-step recording: The recording component only watches the current session's tokenUsage projection cumulative, won't distinguish multiple round-trips within the same session; multiple concurrent sessions are independent and don't interfere, but after switching models in the same session, old model's usage stays under old model name
  • Session title backfill: The recording component only writes currentTitle as session title into snapshot on first increase (src/client/UsageRecorder.tsx:118-124). If the session is renamed on client, the next response will refresh the title on dashboard
  • Estimated unit price lag: The cost tier table is hardcoded in source code from August 2026 (src/cost.ts:18-27). After DeepSeek adjusts prices, cost.ts needs modification and rebuild; the dashboard won't automatically fetch the latest official prices
  • QR code copy permission: The "Copy Address" button for View on Phone uses navigator.clipboard.writeText, browsers may silently fail under non-https / non-localhost, but the QR code and address text remain visible
  • Model name "unknown": If the model field is missing when reported by host-side /api/usage/record, it's normalized to string unknown and bucketed under byModel.unknown (src/index.ts:244), won't cause entire record to be discarded

Read the usage guide →

Install steps, key points, FAQ and compatibility for this plugin — auto-derived from indexed fields.

Listing badge

Listed on deepseek-plugin.org
[![Listed on deepseek-plugin.org](https://img.shields.io/badge/listed_on-deepseek--plugin.org-007EC6)](https://deepseek-plugin.org/plugins/CAPTAIN1275/dsh-ui-web/packages/dsh-usage-dashboard)

Paste this markdown into your GitHub README to link back to this listing. The badge only states the listing — not a security endorsement.

← Back to plugin directory