实时按任务追踪 token 成本的小部件:高峰/低谷定价时段、涨价后预测成本、可排序的每任务成本表、多币种(默认 COP/USD/CNY,另有 40 余种)与汇率,以及一键流式解释高成本任务。
安装
# GitHub 源码(首次需按提示配置 allowBuilds 构建授权后重试)
dsh plugin --profile web add github:mov-eax-eax/dsh-token-anxiety
装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络,工具审批管不到它。GitHub 来源的插件还会在安装时执行构建脚本。请只安装可信来源,并尽量锁定 commit(github:owner/repo#sha)。
README
The Token Anxiety widget tracks the cost of every task in your conversation in real time. It runs in the band under the chat composer and shows DeepSeek pricing status (peak/valley), per-task token usage and cost, and a one-click analysis of where tokens were spent. It is installed as a bundle with no additional dependencies.
Install (from any directory; the path is absolute):
# from npm (published package)
dsh plugin --profile web add dsh-token-anxiety
# or from a local checkout
dsh plugin --profile web add /path/to/dsh-token-anxiety
Then restart dsh web and refresh the page — done.

- Live pricing status — peak/valley windows for your timezone, plus local time
- Cost overview — current cost and the projected post-hike figure in red
- Per-task breakdown — a sortable table of every task with its total cost and token usage; hover any row for details
- Currency support — COP / USD / CNY by default, plus ~40 more with regional formatting (¥, €, £, ₩…) and live FX rates
- One-click explain — a short, streamed analysis of why a task cost what it did, written in your language
- Dark & light, English & Chinese — follows your harness theme and locale
It is packaged as an installable bundle for DeepSeek Harness (composed through your profile, so it survives restarts).
Requirements
- DeepSeek Harness with a
webprofile (dsh web) — the bundle is composed through the profile'sdsh.profile.bundleslist. - Node.js 22+ (the harness's own runtime; the bundle itself adds zero dependencies — node builtins only).
Usage
Hover or click the widget in the composer band to open the popup.
Overview — headline cost in a big hero number (current, plus the projected post-hike figure in red when Projected is on), tasks / requests / tokens, and the pricing table: current vs projected rates per model, with the projected peak/valley values colored green when cheaper than the current rate and red when more expensive.
Tasks — a sortable per-task table (
#or share %). Each row shows its total cost; with Projected on, the cost column adds the projected peak/valley split on two rows. Hover a row for a details tooltip; click a bar to select the task and run Explain.Currency — pick any enabled currency (defaults COP / USD / CNY); open the chooser to see FX rates, add more (flags + search), or remove them.
Explain — one small LLM call per task; the analysis streams in as it is generated and is written in the conversation's language (a tiny LLM call detects the ISO 639-1 code of the task's user prompt). The result is a compact ~60-100 word report in four labeled lines —
Wanted:/Happened:/Avoid:/Next time:— rendered as rich text with bold accent labels.
Security
See SECURITY.md for the full review. Summary: the three HTTP
routes are POST-only, cap request bodies, validate all input, and apply the same
browser-trust fence as the harness /api prefix (loopback/trustedHosts Host,
same-origin Origin, sec-fetch-site); the explain route has an anti-abuse
throttle and hard timeouts so a stalled model can never wedge it; nothing is
written to the session log; zero runtime dependencies.
How it works
cordis.patch.ymlinserts one plugin row (token-anxiety) into the profile.- The node half (
index.js) registers thetokenAnxietysession projection: a pure fold over the ROOT session log that accumulates per-turn token usage, cost, tool signals and waste flags. No network, no model calls. - The same node half registers
POST /token-anxiety/explainon the harness webserver (ctx.webServer): the widget's Explain button fetch()es it and the handler runs the LLM analysis. The response streams back as NDJSON ({"delta": …}lines) so the widget renders the answer as it is generated; a 60s host timeout aborts stalled LLM streams (the client aborts at 70s and shows a visible error). The language is detected with one tiny LLM call returning an ISO 639-1 code. Nothing is appended to the session log, so sessions stay loadable. POST /token-anxiety/pricing-sync(same trust fence) fetches the official DeepSeek pricing page, turns it into readable text, and sends it with a strict JSON schema to an LLM call — no layout scraping in code. The model returns CNY-per-1M prices (current, peak, valley), the Beijing peak windows and the effective date; the host validates, converts CNY→USD at a fixed 7.0 rate, and writespricing.override.jsonnext to the bundle with an explicit schema/currency/unit shape. A restart loads the override over the embedded defaults (the model list derives from the active pricing, so new models surface automatically), and the pricing-derivedstateVersiondiscards stale projection caches.- The browser half (
lib/client.js) is a hand-written client bundle registered throughwindow.__ModuleLoader__.load({ id, factory })— no bundler, no minification. It reads the projection withuseProjection('tokenAnxiety')and computes peak/valley status, local time and the hour strip in the browser from the projection's embedded pricing config.
Install
# from any directory; the path is absolute
dsh plugin --profile web add /path/to/dsh-token-anxiety
Then restart the web server (dsh web / however you launch it). A restart is
required because the bundle row and the client boot graph are composed at boot.
Update after editing
The bundle is pnpm-linked into the profile, so editing files here is enough for a HOST-half change; the client graph only picks up a changed bundle after a restart. After changing files, restart the web server. To remove:
dsh plugin --profile web remove dsh-token-anxiety
Configuration
Currencies
Defaults are COP / USD / CNY. Add or remove currencies from the chooser
(any code in the ~40-currency catalog); the enabled list persists to
pricing.override.json via POST /token-anxiety/currencies (a restart loads
it). Rates are USD-base, refreshed by the pricing sync and cached for 24 h.
Pricing
Prices are embedded in PRICING (index.js) as the fallback and can be
refreshed from the official DeepSeek pricing page:
curl -X POST http://127.0.0.1:3080/token-anxiety/pricing-sync -H "Content-Type: application/json" -d '{}'
The route fetches the page, asks a model to extract the current and peak/valley
rates (CNY → USD at a fixed 7.0 rate; the Beijing peak windows and the
effective date are parsed too) and writes pricing.override.json. FX rates
(open.er-api.com, keyless) ride along, cached daily. A restart merges the
override over the defaults; the pricing-derived stateVersion discards stale
projection caches.
Language
When the harness locale is zh, the whole UI renders in Chinese and the
currency defaults to CNY. It follows the harness locale.preference setting.
Known limitations
- Root-session tasks only. The projection fold is per-session and
synchronous, so the subagent tree the old dynamic plugin aggregated on demand
cannot be folded here. Subagent conversations do not appear in the widget. (The
explain_tasktool itself aggregates the full subagent tree, so its conversation context is complete.) - Explain is a direct host route, not an agent turn. The widget's button
fetch()es
/token-anxiety/explain(registered by the host half on the harness webserver), and the host runs the analysis LLM call inline. The analysis lives in the widget's component state, so it does not survive a page reload and it is not part of the session log (deliberately: it never writes a custom session event, so sessions stay loadable). Theexplain_tasktool is kept for conversational asks ("why did this cost so much?"). The route sits outside the harness/apiprefix, so it applies the same browser-trust predicate itself (loopback ortrustedHostsHost, same-origin Origin,sec-fetch-site); the deployment still binds loopback-only. - Pricing is embedded and dated. The embedded
PRICINGis the fallback; refreshing it is a host-side action (POST /token-anxiety/pricing-sync, see Configuration) that writespricing.override.json; a restart merges it over the defaults. EditingPRICINGby hand still works;stateVersionderives from the active pricing, so any change discards persisted projection-cache rows.
Files
dsh-token-anxiety/
├── package.json # dsh.bundle + dsh.client manifests, exports["./client"]
├── cordis.patch.yml # one plugin row
├── index.js # host half: projection fold + explain_task tool + /token-anxiety/explain + /token-anxiety/pricing-sync + /token-anxiety/currencies routes
├── lib/client.js # browser half: the widget (hand-written bundle)
├── SECURITY.md # security review
├── shots/ # UI screenshots (chat area, overview, tasks, explain — dark/light)
└── LICENSE # MIT
pricing.override.jsonis runtime state (gitignored): it stores the synced pricing, FX rates and the enabled-currency list.
License
MIT © mov-eax-eax
链接
同类插件
strukto-ai/mirage#dsh★ 3447
把文件系统与 bash 提供者换成 mirage 虚拟工作区:文件工具与 shell 命令作用于挂载的资源(RAM、S3、Redis、Slack、Gmail、Notion、Postgres)而非宿主磁盘,支持按挂载点设置读/写/执行模式、按命令选择沙箱(进程内 monty、pyodide、quickjs;远程 docker、e2b、daytona),并可在虚拟终端中安装 CLI(git、gh、slack、linear、ntn、gws,或自行注册的程序树)作为命令头词。
hust-open-atom-club/oh-dsh★ 196
社区发行版:TUI、桌面端与 Web UI 统一体验,分层安装、一步到位。
Jayden-X-L/forkprobe★ 66
同一任务并行试跑多个技能,对比结果选出最优。
vlln/plugin-registry★ 43
插件生态基建:浏览器面板管理官方 repository 插件(0 patch)+ make-dsh-plugin 插件开发引导技能。
forrestchang/dsh-multica-runtime★ 37
让 dsh 运行时跑在 Multica 上。
omdsh-dev/dsh-plugin-check★ 20
插件健康检查:扫描清单协议/patch 格式/构建陷阱,零依赖只读。