Baisbt
dsh-api-balance
A lightweight DeepSeek Harness plugin for monitoring API balance and session token usage.
- Stars
- 0
- Language
- JavaScript
- Created
- Aug 17, 2026
- Updated
- Aug 17, 2026
Introduction
dsh-secret-balance-widget
A floating plugin for DeepSeek Harness that shows your DeepSeek API balance and the current session's real token usage in a small, draggable, translucent chip.
| Minimized | Expanded |
|---|---|
| Just the balance, as a tiny floating pill. | Balance + current session input/output tokens, a manual refresh, and a Pin control. |
The plugin reuses the harness' own data sources instead of reinventing them:
- Tokens are read straight from the harness'
tokenUsagesession projection produced by@deepseek-ai/dsh-token-meter— the exact source the built-in stats line under the input box uses. There is no re-tokenization and no custom tokenizer. - Theme is the harness' own DSW CSS-variable token set, so Light / Dark are matched automatically.
- The API key is stored with the harness'
credentialsservice (the same official secret store the Models page writes to) and is never returned to the browser or rendered. - Network (the balance call) happens on the Host half and is exposed to the Client over the official Package-private JSON RPC (
harness.handle/host.call).
1. What it is
A single Cordis plugin with two halves:
| Half | Runs in | What it does |
|---|---|---|
Host (src/host.js) | the DSH Node process | stores the API key via credentials, fetches GET https://api.deepseek.com/user/balance via the subprocess service + curl, and exposes dsh-balance:* RPC methods |
Client (src/client.js) | the browser | renders the floating widget into the root-scoped shell.overlay slot, reads the active session's tokenUsage projection, and calls the Host for balance data |
Features
- Minimized by default — shows only the current balance; no other stats.
- Expand for details — click to reveal API balance, current-session input and output tokens (formatted
K / M). - Real token data — from the
tokenUsageprojection (uncachedInputTokens + cacheReadTokens + cacheWriteTokensfor input,outputTokensfor output), the same source the built-in input stats line reads. - Auto-refresh every 60 s plus a manual refresh button.
- Draggable — the chip moves freely by its own handle and stays inside the viewport.
- Smart panel direction — the expanded panel opens toward the side with more free space (never hard-coded), and is clamped to remain fully visible.
- Pin / outside-click-to-collapse — clicking outside collapses unless pinned; pinning keeps it open and is visually highlighted.
- Light / Dark adaptive through the harness' own theme tokens.
2. Installation
DeepSeek Harness loads plugins from its Cordis composition. This plugin is a Cordis plugin, so installation is two steps: get the package onto your install, and reference a row for it in your composition.
Step 1 — add the package as a dependency
In the directory of your DeepSeek Harness deployment's package.json:
npm install <this-repo-as-a-git-url>
or, from a local checkout of this repository:
npm install /path/to/dsh-secret-balance-widget
Step 2 — add a row to your cordis.yml
Open the composition file that lists your plugins (shipped plugins live in rows such as - name: '@deepseek-ai/dsh-token-meter') and add:
- name: 'dsh-secret-balance-widget'
The Host half needs the credentials and subprocess services and the curl executable. On a default Harness deployment these are provided by dsh-credentials-local, dsh-subprocess-local (both usually already composed) and a system curl (present on most platforms). If curl is missing on PATH, install it or point the deployment at one.
The plugin ships two source forms.
src/host.jsandsrc/client.jsare verbatim Cordis plugin bodies — the exact format the Harness plugin authoring / dynamic loader consumes (each half is an async function body that returns a Cordis plugin). Runningnpm run buildalso emits identicallib/host.body.jsandlib/client.body.js, pluslib/host.js/lib/client.jsfor loaders that expect a module. Both shapes are the same logic.If you prefer to load it through the Harness GUI's plugin mechanism instead of a composed row, use the Host code = verbatim contents of
src/host.js, Client code = verbatim contents ofsrc/client.js, in the plugin authoring UI. After that, approve/run the plugin request.
Verify the client module
Client UI for composed @deepseek-ai/dsh-client-* packages is discovered from the dsh.client field in package.json. This package declares that field too. If your deployment scans dsh.client modules, rebuild/refresh the web bundle as your deployment requires so the new client module is picked up. The plugin does not fork or extend Harness Core — it only uses public slots/services.
3. Entering your API key
- Click the floating chip to expand it.
- If no key is set, click 设置 API Key, paste your DeepSeek API key (starts with
sk-), and click 保存. - The balance is fetched immediately and every 60 s afterwards.
The key is saved through the harness' credentials service into the deployment's credential store (e.g. $DSH_HOME/.credentials.yaml, 0600). It is treated as an opaque secret: the client never receives it, and the credential reference used is DSH_BALANCE_API_KEY.
To replace it, open the panel again and re-save. To clear it, click 移除 Key in the expanded panel.
4. Upgrading
Upgrades are normal npm dependency bumps:
npm install <this-repo-as-a-git-url>@<new-tag-or-ref>
Then restart/rerun your Harness deployment so the row reloads. Your stored API key (kept in the credential store, not in the package) survives the upgrade.
5. Uninstalling
-
Remove the row from your
cordis.yml:# - name: 'dsh-secret-balance-widget' # delete or comment out -
Remove the package dependency:
npm uninstall dsh-secret-balance-widget -
Restart/rerun the deployment. The widget disappears.
Your API key is not removed by uninstalling — it lives in the shared credential store. If you also want to remove it, clear the reference DSH_BALANCE_API_KEY from your credentials document, or reinstall and click 移除 Key first.
Development
npm install
npm run build # emits lib/
npm run typecheck # tsc --noEmit over src/
npm test # node --test
src/util.js holds the framework-free pure helpers (token formatting, balance parsing, panel placement) and is unit-tested. src/host.js and src/client.js embed small inline copies of the same helpers so each half stays self-contained for the dynamic loader; keep them in sync with src/util.js.
License
MIT