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 outRemove the package dependency:
npm uninstall dsh-secret-balance-widgetRestart/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
还没有评论,来写第一条。