Shows the DeepSeek API account balance in the DSH Web sidebar with 30s auto-refresh, click-to-refresh, hover details, and low-balance threshold warnings.
Install
# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)
dsh plugin --profile web add github:flyingfishzxf/dsh-dsbal
Any plugin you install runs third-party code with your own permissions — it can read your files, use your credentials, and reach the network, and tool approvals don’t sandbox it. GitHub-sourced plugins also run build scripts at install time — pnpm blocks those until you allow them, so an install can stop with ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED or ERR_PNPM_IGNORED_BUILDS; dsh prints the exact key to add under allowBuilds in your profile’s pnpm-workspace.yaml, and the install works on the next run. Allowing a build is a trust decision: only install sources you trust, and pin a commit (github:owner/repo#sha).
README
A minimal, single-purpose DeepSeek API balance widget for the DSH web sidebar — it shows one number and nothing else.
- Shows your CNY balance on a button in the sidebar footer, above Settings
(wallet icon on the left,
¥xx.xxon the right), aligned with the Settings button. - 30s auto refresh; click the button to refresh immediately and reset the cycle.
- Hover opens a usage-notes card: the current balance in large type
(
¥xx.xx) at the top, then the balance warning legend (< 50 yellow · < 30 orange · < 10 red → dashed border on the button), the peak/off-peak billing rule (two rows: peak/off-peak hours), and a merged refresh rule + refresh time on one line, with the plugin version (dsh-dsbal v0.4.3) right-aligned at the bottom. The card tracks the button width: as wide as the button column when the sidebar is expanded (capped at 360px), a fixed 240px when collapsed, following live while the sidebar animates. - Balance breakdown: while both the topped-up and the granted wallet carry credit, two ledger rows sit under the total — 充值余额 (topped-up) and 赠送余额 (granted), the same wording the official Settings → Account page uses. They only restate the total when one of the two is empty, so with a single funded wallet the card keeps its current single-amount form; the total, the button and the warning tier never change.
- Collapsed sidebar: the button shrinks to a 36px circle with no room for
the amount or the badge, so peak/off-peak moves onto the icon colour
(red
#e5484dduring peak, brand blue#4d6bfeoff-peak) and the exact amount is read from the top of the hover card. Expanded, the icon stays neutral and the 梁文峰/梁文谷 pill alone carries the state. - Peak/off-peak pricing hint: periods are defined in Beijing time (peak is
Monday–Friday 09:00-12:00 & 14:00-18:00; every other hour, weekends in
full (including make-up workdays) and Chinese statutory holidays in full
are off-peak at half the peak price). A hollow badge sits at the right of the
balance — red 「梁文峰」 during peak, brand-blue 「梁文谷」 off-peak
(right-aligned, never wider than the sidebar). The holiday table is fetched
silently in the browser from
holiday-cn (jsDelivr, then GitHub
raw), cached in
localStoragefor 24h, and falls back to the bundled 2025/2026 table when offline or not yet fetched. - Balance warning borders: < 10 → red, < 30 → orange, < 50 → yellow, ≥ 50 → normal (dashed border of the tier colour; orange/yellow are kept visually distinct).
- UI language aware: all texts follow the DSH language setting (zh / en), switching live.
Install
Install directly from GitHub (currently recommended):
dsh plugin --profile web add github:flyingfishzxf/dsh-dsbal
Or, after the package is published to npm:
dsh plugin --profile web add dsh-dsbal
For local development, you can install from a local path:
dsh plugin --profile web add file:/path/to/dsh-dsbal
After installing, restart
dsh weband hard-refresh the browser so the new bundle is loaded.
How it works
- The host half registers a
dsBalanceRemote service.fetchfirst resolves the DeepSeek API key through the credential seam (DEEPSEEK_API_KEYby default) and callsGET {baseURL}/user/balancethrough the shell — theweb.fetchseam cannot carry anAuthorizationheader:- POSIX:
curlwith${DEEPSEEK_API_KEY}expansion. - Windows:
node -e(OpenSSL-based fetch). The sandboxed PowerShell shell cannot complete any schannel TLS (curl and .NET both fail withSEC_E_NO_CREDENTIALS), while Node's fetch is unaffected. The request explicitly runs unconfined (danger-full-access): the Windows ACL sandbox runner breaks for wide deployment workspaces (e.g. startingdsh webfrom a home directory), which would otherwise make balance fetching depend on the host's start directory. The command is fixed and plugin-authored (URL from settings, key from credentials), so this is safe; POSIX stays confined. - The key and URL ride the shell spec's explicit
envlayer, so the secret never appears in the command string or logs.
- POSIX:
- With no API key configured, the balance comes from the DeepSeek account
seam instead:
deepseekAccount.getBalance()asks the Platform for the same recharge and granted wallets the official Settings → Account page shows. This is what makes the plugin work on the DSH desktop app, which signs in to the DeepSeek account Platform (OAuth) and stores noDEEPSEEK_API_KEYat all — the key-only path could there only report "API key not configured". The account path runs in-process, so it needs no shell, nocurl/node, no TLS and no sandbox. A configured API key still takes precedence, so existing installs are unaffected. - The client half mounts the Remote, renders the sidebar button and the hover card, and owns the refresh loop.
Configuration
The plugin honours the llm-deepseek settings section, exactly like the
DeepSeek model adapter. That section is keyed by Loader entry id on current
hosts (include:llm-deepseek), so the lookup accepts both the entry id and the
bare namespace:
apiKeyEnv— credential reference (defaultDEEPSEEK_API_KEY).baseURL— API base (defaulthttps://api.deepseek.com).
Requirements
- POSIX:
curlon the host. Windows:nodeon the host (API-key path only). - Either a configured DeepSeek API key in DSH credentials, or a signed-in DeepSeek account (what the desktop app has).
- DSH host compatibility: the host half uses the current
shell.execute(...).result()execution surface and thesettings.describe()section lookup, and falls back to the pre-0.1.7shell.run()/settings.get()APIs, so one bundle keeps working across that host update.
Limitations
- Shows only the DeepSeek balance — the account behind the configured key
(
DEEPSEEK_API_KEYby default), queried viaGET /user/balance; with no key configured, the balance of the signed-in account, queried through the account Platform. It does not show other providers' or other accounts' balances, and it cannot combine or convert between accounts. - Read-only: it displays the balance and nothing else. No top-up, key management, or billing operations.
- The refresh interval is fixed at 30 seconds and is not configurable.
- The balance is displayed in CNY, which is how DeepSeek reports it.
- Host dependencies:
curlon POSIX,nodeon Windows for the API-key path (see Requirements); the account path has none.
Publish to the plugin market
Not listed yet. The list is maintained in awesome-dsh-plugin as one YAML file per plugin.
To add this plugin:
Make sure the repository meets the requirements:
- at least 1 day old,
- 10 or more commits,
- the
dsh-plugintopic added on GitHub (repo Settings → General → Topics; CI checks it).
Fork
awesome-dsh-plugin.Add
data/plugins/flyingfishzxf__dsh-dsbal.yml:url: https://github.com/flyingfishzxf/dsh-dsbal name: flyingfishzxf/dsh-dsbal category: usage description: en: 'Shows the DeepSeek API account balance in the DSH Web sidebar with 30s auto-refresh, click-to-refresh, hover details, and low-balance threshold warnings.' zh: '在 DSH Web 侧边栏显示 DeepSeek API 账户余额:30 秒自动刷新、点击刷新、悬停查看明细、余额不足阈值告警。'The market description must state what the plugin does without superlatives (they get sent back) — the "minimal" positioning lives in this README, not in the market entry.
Regenerate the READMEs and commit them along with the YAML file:
npm ci node scripts/generate-readme.mjsOpen a pull request.
The market (dshmarket) picks it up automatically after the PR is merged.
License
MIT
Links
More in this category
bowenliang123/dsh-context★ 2079
DSH context insight panel: Context dashboard + /context command + Context browser — one-stop context lifecycle management with categorized composition, content details, evolution trends, compaction/injection events, and stats.
Han-1413141/dsh-cost-meter★ 408
Per-session and daily API cost, budget with usage %, official balance, history dashboard, and one-click official price sync with peak/off-peak pricing.
wssfk12138/dsh-damage-pulse★ 263
Tracks DeepSeek token usage, per-call and session costs, and account balance with cache-aware charge animations in the DSH Web UI.
zh667/TokenLedger★ 202
Sidebar usage panel that attributes tokens to the relay site that served each request, read from your existing provider config: today/month/all-time totals, per-site and per-model breakdowns, a year activity heatmap, and New API / Sub2API / DeepSeek balances.
Ychris12138/dsh-usage-stats★ 172
Multi-provider usage dashboard with provider/model token breakdowns, calendar drill-downs, account balances, and OpenCode Go / Z.ai subscription quota tracking.
PolinniZhong/dsh-personal-center★ 118
Personal center for DeepSeek Harness: cross-session usage statistics, per-model cost estimation, global custom instructions, a global font-size adjuster, a data-driven desktop pet with bitmap & vector skins, and a conversation status overview, all local and offline.
Community comments
Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.