All plugins

DSH / BUNDLE / CLIENT-UI

dsh-budget-watcher

v0.7.2NeutronStar714 / dsh-budget-watchere7a251f24e

InstallableBundlesUI & client pluginsCommunity · Topic auto-analysisWeb UI

Overview

dsh-budget-watcher

DeepSeek Harness plugin: a small floating window over the conversation showing the balance left on your API account, and what recent turns actually cost.

README / EN

Package documentation

Registry summary

DeepSeek Harness plugin: a small floating window over the conversation showing the balance left on your API account, and what recent turns actually cost.

dsh.pub verifies the pinned bundle contract, runtime facts, and distribution semantics. The complete README remains in the source repository.

Read the full README on GitHub

LIMITATIONS

Known limitations

Recorded honestly, because each one is a decision rather than an oversight. 1. **DeepSeek only.** `provider` exists and the request path is written per provider, but `PROVIDERS` in `index.js` holds a single entry. Any other provider is currently a code change, not a config change. 2. **The API-key balance, not the signed-in account balance.** The widget reads `https://api.deepseek.com/user/balance`, which needs an API key and returns `topped_up_balance`. DSH's own Settings → Account reads a different figure from the DeepSeek Platform web API through an OAuth grant. The two can disagree, and this plugin deliberately does not mix them. A user who signs in with an account but has no API key sees "no API key configured" rather than the platform number. 3. **No `is_available` for the platform account**, and no expiry information for granted credit. The public API does not expose them. 4. **One currency is featured.** `balance_infos` is an array and an account may hold more than one currency. All wallets are returned to the client, but the panel draws the one `currency` selects (`auto` prefers CNY, then whatever came first). The rest are not shown. 5. **Amounts are strings and are never arithmetic.** DeepSeek documents all three amounts as decimal strings. The widget prints what it received, so `total` is displayed as returned rather than recomputed. 6. **Polling, not push.** There is no SSE stream, so the panel polls. Two different intervals are involved and they are deliberately separate: the **panel** polls its own local host route every few seconds (2 s while a turn runs, 3 s when idle) so a prompt is noticed promptly, while `refreshIntervalMs` — 15 s minimum, 60 s default — is how long the **host** reuses one balance answer before calling DeepSeek. Conflating the two was the `0.6.3` bug: the panel inherited a 60 s poll and looked frozen until the refresh button was pressed. 7. **The route is unauthenticated beyond its fence.** It is not on DSH's authenticated `/api` prefix, so the plugin applies its own loopback + same-origin checks. It returns a balance figure and never a credential. If your deployment sets a non-loopback bind host, the route answers to that network unless you leave `allowNonLoopback` off — in which case the widget will simply report a 403. 8. **Config validation is optional.** With `@deepseek-ai/schemastery` importable, config is validated and defaulted by Cordis, producing proper errors. Without it, config is read defensively and a typo is silently ignored rather than reported. 9. **Web profiles only.** `dsh.client.platform` is `web`. A `tui` or `headless` profile loads the host half and serves the route, but there is no window to draw in. 10. **No web server, no data.** In a profile without `webServer` the plugin loads and does nothing, rather than failing the profile. 11. **The overlay cell id is not namespaced.** The entry registers as `budget-watcher` in `shell.overlay`. It is a fresh id today; another plugin choosing the same id would land in the same cell. 12. **Proxy support is inherited, not implemented.** Requests use plain `fetch`, so DSH's process-wide proxy dispatcher routes them. A proxy configured only in operating-system settings, or a SOCKS URL, is not honoured — the same boundary `dsh-http-proxy` documents for every outbound call in the harness. 13. **`dsh.engines.dsh` and `dsh.compatibility` are declarative only.** The real compatibility gate in this build reads `peerDependencies` on `@deepseek-ai/dsh*` names; this package declares none, so it is never refused — and never verified either. 14. **A host half is only ever loaded once.** Adding the bundle needs a profile restart, and so does **editing it afterwards**: Node caches an imported ES module for the life of the DSH process, so changing `index.js` on disk has no effect on a running profile. The client half is re-served from disk on every request,