DSH Plugins Marketplace

DSH Plugins

Plugins

/

dsh-balance-guard

m

dsh-balance-guard

Discovered

DSH plugin: your DeepSeek account balance as a colour-banded bar on the right edge, with per-turn cost prediction and a quiet low-balance warning.

dsh-balance-guard

A DeepSeek Harness plugin that pins your DeepSeek account balance to the right edge of the GUI as a colour-banded vertical bar, and projects what the current task will cost before the balance runs out.

Nothing else changes hands: the balance comes from the DSH account you are already signed into, the API key is never read, and no message content leaves the Host.

                                                       ┌──┐
                                       ¥12.34  ●       │░░│ ← balance chip (horizontal) + warning dot
                                                       │▓▓│
                                       ┌─────────────┐ │▓▓│
                                       │ 账户余额     │ │▓▓│
                                       │ ¥12.34      │ └──┘
                                       │ 本任务已花   │
                                       │ ¥0.42       │  ← hover card
                                       │ 预计还需     │
                                       │ ¥0.90 – 2.30│
                                       │ ⚠ 预计不足…  │
                                       │      去充值 →│
                                       └─────────────┘
Balance (account currency)BandMeaning
< 10redabout to run dry
10 – 30orangetop up soon
30 – 50greenfine
> 50blue, plus a light blue-violet wave above the 50 markplenty

The bar keeps its scale at 50; > 50 fills it and draws the overflow as a moving wave (disabled under prefers-reduced-motion: reduce).

中文速览

  • 在界面最右侧贴边显示一根账户余额竖条,颜色:<10 红、10–30 橙、30–50 绿、>50 蓝 (超出 50 的部分画成浅蓝紫波纹)。
  • 数字是横向的金额胶囊(¥12.34),贴着竖条左侧;鼠标悬停竖条或胶囊弹出卡片。
  • 卡片里给出本轮任务已经花了多少、预计还要花多少(区间);预计余额不够跑完时, 胶囊上出现一个静态红点,卡片里一行红字说明缺口(不弹窗、不发声、竖条不变色)。
  • 余额来自你已登录的 DSH 账号(平台登录态),不读 API Key;API Key 和账号令牌都不进浏览器。
  • 以 50 元为满刻度;卡片里还有「去充值」入口、模型、峰谷价、缓存命中率、数据新鲜度。

What it predicts

「当前任务」= the running turn of the current root session (turn/start → turn/end).

  • Already spent is provider truth: the four billed buckets of the turn (uncachedInputTokens, cacheReadTokens, cacheWriteTokens, outputTokens) read as a delta against the cumulative tokenUsage session projection, priced by the current model and period.
  • Still to come is projected per step: the next prompt size comes from the provider-anchored contextPressure.projectedTokens, output and prompt growth come from this turn's samples (falling back to configured defaults), and the cache-hit ratio is measured from the turn so far.
  • How many steps are left is the mean steps-per-turn of this session's completed turns (default 8 when there is no history). The card reports a minimum / expected / maximum: one more step, the expected remaining steps, and twice the expected steps with a 10-point-worse cache hit and peak prices.
  • Verdict: required = expectedRemaining × 1.2 + reserve, compared against the balance minus spend that landed after the balance reading (Platform balance lags by minutes). Balance at or below the line is "insufficient".

When no turn is running, the same card estimates the next task from the last three turns instead of pretending to know the future.

Requirements

  • A DSH client with the DeepSeek account signed in. The guard reads the balance through ctx.deepseekAccount; the account token never reaches the renderer, and no API key is read.
  • Node 20+ only for the test/install scripts; the plugin itself has no build step.

Where the number comes from

ctx.deepseekAccount.getState() and getBalance() — the same service the client's account menu uses, so the bar always agrees with what the client reports. getState() is async; reading it synchronously once made every signed-in account look signed out, which is why the account section of this file points that out twice.

The card names the source (余额来源:DSH 账号). A reading that fails after a successful one stays on screen, clearly labelled with the error; an explicit sign-out clears the figure and the bar turns grey.

Install

The plugin is not published to npm; it loads straight from a checkout.

git clone https://github.com/marksimZ/dsh-balance-guard.git dsh-balance-guard

Then either pass the overlay for one run:

dsh web --patch /absolute/path/to/dsh-balance-guard/cordis.patch.yml

…or make it permanent by appending the row to a profile's own patch layer, which reloads live (no restart, just reload the page). The installer picks desktop when that profile exists and web otherwise:

node scripts/install.mjs            # writes $DSH_HOME/profiles/<profile>/cordis.patch.yml
node scripts/install.mjs --dry-run  # show the exact result first
node scripts/install.mjs --profile web

cordis.patch.yml ships a machine-specific absolute path. Edit that line (or let install.mjs write it) to point at wherever you cloned this repository.

Verify the running GUI actually serves it:

node scripts/verify-deployed.mjs --url http://127.0.0.1:<GUI 端口>

Configuration

Every key is optional; defaults live in cordis.patch.yml.

KeyDefaultMeaning
safetyRatio0.2Multiplier over the expected remaining cost
minReserveCny2Amount that must stay untouched (account-currency units)
balanceTtlMs25000How long a balance reading is served
balancePollMs30000Background balance refresh cadence
balanceTimeoutMs30000Timeout for one balance read
runningPollHintMs1000Browser poll hint while a turn runs
idlePollMs15000Browser poll cadence while idle
cnyPerUsd7.2CNY per USD for the USD-quoted price catalog
assumedSteps8Remaining steps when the session has no history
assumedOutputTokens1200Output tokens per step without a sample
assumedGrowthTokens4000Prompt growth per step without a sample
assumedCacheHit0.85Cache-hit ratio without a prompt sample
holidays[]UTC dates DeepSeek bills at off-peak all day
balanceLagCompensationtrueSubtract spend that landed after the reading
clientVersion""Client version used when the page cannot report one

Prices live in src/policy.js as PRICE_TABLE (USD per 1M tokens, peak and off-peak rows for deepseek-flash and deepseek-v4-pro), with the fetch date and source URL in the file header. Peak is Monday–Friday 01:00–04:00 and 06:00–10:00 UTC, excluding the dates listed in holidays; everything else is off-peak. Changing a price is a two-file change: policy.js plus the value pinned in scripts/policy-spec.mjs.

Architecture

Two halves, one plugin.

Host half (src/index.ts)
  ctx.deepseekAccount.getState() / getBalance(metadata)   → the balance, token stays Host-side
  ctx.on('session/event')                                 → per-turn billed-token folding
  ctx.sessionProjections.stateOf(...)                     → tokenUsage / contextPressure / modelSelection
  src/policy.js                                           → bands, prices, estimator, verdict (pure)
  ├─ GET /dsh-balance-guard/state                         → same-origin read-only JSON
  └─ globalThis.__DSH_BALANCE_GUARD__                     → index injection for first paint

Browser half (src/client.js)
  window.__ModuleLoader__.load({ id, factory })           → the whole transport contract
  require('react')                                        → the shell's platform seed
  ctx.slots.inject('shell.overlay')                       → the fixed bar, chip, dot and card

Why a Host half? The account token never reaches the renderer; per-turn billing lives in the Host's session log; and the shell.overlay entry does not receive useProjection, so the page cannot read session projections by itself.

Why an HTTP route instead of @Remote? Remote methods are generated from Host decorations by the Typert build pipeline. A plugin outside the Harness build must describe its own wire protocol, so it publishes on ctx.webServer with an exact named route — deliberately not under /api, which belongs to the Connection plugin and authenticates. Only aggregates cross the wire: no tokens, no message text. The shipped Web composition binds loopback only.

Why is every threshold on the Host? So the product rules exist once (in policy.js), are tested once with plain Node, and a cached browser bundle can never disagree with the Host.

Tests

Plain Node, no test framework:

npm test          # policy spec + client spec + bundle smoke + theme tokens
npm run test:host # mounts the Host half on a mock context and drives the real route
npm run verify    # read-only probe of a running GUI
ScriptWhat it pins
scripts/policy-spec.mjsband boundaries (9.99 red, 10 orange, 30 green, 50 green, 50.01 blue), the peak/off-peak calendar, the official price table, the estimator arithmetic (including the worked example in DESIGN.md), the ×1.2 + reserve verdict and wallet projection
scripts/client-spec.mjsthe snapshot → pixels projection: chip copy, marker rule, warning levels, range formatting, poll cadence, wave closure
scripts/client-smoke.mjsthe bundle registers through __ModuleLoader__, require('react'), installs one stylesheet and mounts into shell.overlay
scripts/host-smoke.mjssigned in → running turn → short balance → settled turn → failing read keeps the last figure → signed out, over the real route
scripts/theme-tokens.mjsevery var(--dsw-*) is declared by the shipped theme; the chip is horizontal; the four tones, marker and top-up link survive
scripts/verify-deployed.mjsthe running GUI serves the bundle and the state route

theme-tokens exists because a missing custom property fails silently: the declaration is dropped and the hardcoded fallback paints, which reads as a design choice rather than a bug. The previous balance plugin shipped exactly that.

Limitations

  • The projection is not a bill. Remaining steps, cache-hit ratio and tool-output size are estimates; the min/expected/max range is the honest error bar.
  • Platform balance lags by tens of seconds to minutes. The guard subtracts measured spend that landed after the reading, but that compensation is itself measured.
  • Holidays are offline. Without a holidays list, weekday peak windows are priced as peak (a conservative over-estimate).
  • Sub-agents are not in the projection. Their spend is real and shows up in the balance; the card only notes that they are running.
  • One task at a time. With several sessions running, the Host tracks the most recently active running turn; the card names the session title.
  • Prices may change. The catalog carries a fetch date; a price change is one constant plus one test.
  • USD accounts display in USD; the price catalog is converted with cnyPerUsd only for CNY accounts.
  • The account service must be composed. The plugin declares deepseekAccount and sessionProjections as required services, so a profile without them loads no bar at all rather than a broken one. Both ship with the Desktop client and dsh web.
  • The in-app top-up page is not ours. DSH's native Platform page belongs to the account settings package, so the card's 去充值 opens the Platform top-up URL in the system browser.

License

MIT — see LICENSE.

Comments

Loading…

Similar plugins

dsh-balance-bar

by hfdsdfgr

DeepSeek Harness Web plugin: live account balance as a colour-banded vertical progress bar on the right edge of the GUI, with an animated wave above the threshold.

Manifest valid

★ 0

MIT

JavaScript

Sep 19, 2026

dsh plugin --profile web add dsh-balance-bar

by dsh-plugin-lab

DSH plugin: shows your DeepSeek account balance at the bottom of the left sidebar (native UI)

Tools & CapabilitiesManifest valid

★ 4

↓ 362/wk

MIT

TypeScript

Oct 20, 2026

dsh plugin --profile web add dsh-ds-balance

by btbxbob

DeepSeek Harness side-bar balance badge: show DeepSeek account balance and estimated depletion time (dual-half cordis plugin)

Manifest valid

★ 0

JavaScript

Sep 14, 2026

dsh plugin --profile web add dsh-balance

by lxy7747-hash

A DeepSeek Harness plugin that pins the signed-in DeepSeek account balance (recharge + bonus) to the Web sidebar foot.

Manifest valid

★ 0

MIT

JavaScript

Oct 20, 2026

dsh plugin --profile web add dsh-balance-badge

by HugePaint

A DSH (DeepSeek Harness) client plugin: live account balance plus the current DeepSeek billing window (peak / off-peak) in the sidebar footer.

Manifest valid

★ 0

MIT

JavaScript

Oct 20, 2026

dsh plugin --profile web add dsh-balance-chip

by lnetrit-alt

DSH web plugin: sidebar-embedded DeepSeek balance readout with a black minimalist full-shutdown button.

Manifest valid

★ 0

MIT

JavaScript

Aug 26, 2026

dsh plugin --profile web add dsh-system-control