bowenliang123/dsh-context
bowenliang123/dsh-contextDSH 上下文洞察面板:Context 仪表盘 + /context命令 + Context 浏览器,查看 Context的分类组成、内容详情、演进趋势、压缩/注入事件、统计等一站式 Context 全生命周期管理。
dsh 网页端 CC Switch 风格 Token 消耗统计:按请求的用量日志、真实消耗 Hero、按请求提交时间分桶的趋势图、按模型峰谷牌价计费、项目/模型统计与账户余额。
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-viewerRestart 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.2.0-rc.2 (and 0.1.6+ — slot names, projection APIs, and service contracts are unchanged between those releases; v0.3.0 switches to the loader-applied plugin Config export, the sanctioned config channel since the settings service became SettingsForms). 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. v0.4.2 re-verified on the 0.2.0-rc.2 dependency tree: node test/smoke.cjs and 48 component tests (vitest, 5 specs) pass, and node scripts/build-client.mjs rebuilds lib/ byte-identically.
shell.overlay, a faithful port of CC Switch's usage-dashboard method):
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. The projection retains the newest 10,000 entries per session (stateVersion 2), so long-lived sessions stop growing the fold and the wire payload at that point.GET /api/billing/pricing (fetched by the statistics drawer; the browser mirrors the built-in table as a fallback), and PRICING_FALLBACK in the host half holds the current list prices (see below).GET /api/billing/balance proxies DeepSeek's /user/balance through the harness credentials service; the API key never leaves the server. The credential reference (apiKeyRef, default DEEPSEEK_API_KEY) and provider base URL (baseURL) ride the plugin entry's config in the profile (defaults apply when unset).


Six registrations, all in stock slots (see src/client/index.ts):
| Slot | Surface | Id |
|---|---|---|
sidebar.panellist | panel row + icon | token |
main | panel page (its key must equal the row's id) | token |
sidebar.footer.action | balance chip | token-viewer-balance |
conversation.input.dock | live token strip | token-viewer |
shell.overlay | statistics drawer | token-viewer-detail |
shell.overlay | whale-maid pet | token-viewer-pet |
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.
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 statistics drawer installs the route's rows as its active billing table and re-folds its costs when they land; the browser carries the same rows as MODEL_PRICING_FALLBACK in src/client/derive.ts, so an unreachable route degrades to the same prices instead of inventing any. The per-session list and the composer dock keep billing at the flash off-peak floor — those figures are aggregate estimates without per-request times.
MIT, except src/client/assets/whale-maid.png (embedded into lib/client.js): the community's chibi DeepSeek whale-maid, from yefeng7531/dsh-whale-maid-mascot, originally published at bilibili opus/1231977657712771073, licensed CC BY-NC-SA 4.0 (non-commercial use only, share-alike; only rescaled to 135×240). See src/client/assets/SOURCE.md.