DeepSeek Harness Plugin

gejiaju/dsh-balance

Stars ★ 0 Category Usage & Billing Added 2026-09-02

Shows DeepSeek API balance and tells whether the current moment is peak or off-peak pricing time, with a live countdown to the next switch.

Install

# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)

dsh plugin --profile web add github:gejiaju/dsh-balance

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

DeepSeek API balance & peak-hour indicator for DeepSeek Harness (DSH) — see your account balance and know at a glance whether the current moment is peak or off-peak pricing time.

中文文档

What it does

Adds a 「余额与高峰」/ “Balance & Peak” card to the harness settings page:

  • Balance — DeepSeek account balance (total / granted / topped-up, per currency), fetched from the official GET /user/balance endpoint.
  • Peak hours — whether the current moment is in a peak (高峰) or off-peak (空闲/低谷) pricing window, with a live countdown to the next switch and the upcoming schedule.

Defaults mirror DeepSeek's current published policy:

Peak windows (Beijing time) 09:00–12:00, 14:00–18:00 (start inclusive, end exclusive)
Off-peak price 50% of the peak price
Weekends Saturday & Sunday priced as off-peak all day (rule since 2026-08-23)

Everything above is configurable — timezone, windows, weekend rule — so a future policy change needs a config edit, not a release.

Install

dsh plugin --profile web add dsh-balance

Restart dsh web (or the desktop app), then open Settings → 余额与高峰. No API key configuration is needed on a normal profile: the plugin reuses the DeepSeek key already stored through the harness credentials service (the web Models page) or the DEEPSEEK_API_KEY environment variable.

Requires dsh web ≥ 0.1.0-rc.6 (the settings-section primitive). On older hosts the card simply does not appear — nothing else changes.

Configuration

All fields are optional; defaults are shown. Edit them on the Settings → Plugins → Plugin configuration page, or in cordis.patch.yml:

- id: dsh-balance
  name: dsh-balance
  config:
    # apiKey: ""                      # explicit key; otherwise credentials/env
    # baseUrl: https://api.deepseek.com
    # timezone: Asia/Shanghai         # IANA zone the windows are defined in
    # refreshSeconds: 300             # balance cache TTL (min 10)
    # weekendOffPeak: true            # weekends priced as off-peak all day
    # peakWindows: [[9,12],[14,18]]   # [startHour,endHour] or [sh,sm,eh,em]
    # offpeakRatio: 0.5               # display only: off-peak / peak price

The GUI configuration page exposes timezone, weekendOffPeak, refreshSeconds and peakWindows. apiKey is deliberately left to the plugin config: the harness's own credentials page is the better home for a secret, and it is picked up automatically.

HTTP API

Route Description
GET /dsh-balance/status Full status: balance (cached), peak state, next switch, key source (masked).
POST /dsh-balance/refresh Force a balance refetch, bypassing the cache TTL.

Same-origin only. The response never contains the API key — only a masked hint like sk-…abcd.

How it's built (and why it's fast)

  • Zero runtime dependencies, zero build step. Pure Node built-ins: fetch, Intl, node:test. The client bundle is a plain-JS __ModuleLoader__ factory — install is instantaneous and there is nothing to compile.
  • Timezone-aware peak math in pure JS. Wall-clock time and weekday are read in the configured IANA zone via Intl.DateTimeFormat; the host's own timezone is irrelevant. No tz database package.
  • Balance caching + single-flight. TTL cache (default 5 min) means a busy UI never hammers the API; concurrent callers share one in-flight request; a failed refresh keeps the last good value (shown as stale) instead of blanking the card.
  • No background polling. The client polls status on the server-side cache TTL (minimum 30 s) and ticks the countdown locally; the server never touches the balance API unless asked. The client polls status every 30 s (server-side cached) and ticks the countdown locally; the server never touches the balance API unless asked.
  • Secure by default. Keys never appear in logs, routes, or error messages; errors are classified (NO_KEY, INVALID_KEY, RATE_LIMITED, TIMEOUT, NETWORK, BAD_SHAPE).
  • Graceful degradation. Missing webServer, settings, credentials or schemastery? Each piece quietly skips itself; the rest keeps working.

Security

See SECURITY.md for how the API key is handled (never logged, never returned, masked in responses). A ready-to-copy configuration lives in examples/cordis.patch.yml.

Tests

npm test          # or: node --test
npm run check     # syntax-check everything + run the tests

41 tests cover the peak window edges (window boundaries, weekends, timezone independence, custom windows), the balance client (error classification, caching, single-flight, stale-on-failure), and the routes end-to-end against a stubbed host.

Repository layout

lib/index.js      cordis plugin entry (apply, config wiring)
lib/peak.js       pure peak/off-peak + next-switch logic (tz-aware)
lib/balance.js    DeepSeek balance client (TTL cache, single-flight)
lib/keys.js       API key resolution: config → credentials → env
lib/routes.js     HTTP routes + status assembly
lib/settings.js   optional settings namespace (GUI config fields)
lib/config.js     defaults, validation, package version
client/client.js  settings-section UI (plain JS, no build)
test/             node:test unit + integration suites

License

MIT

Content from the project README on GitHub ↗

Links

More in this category

View the whole category →

Community comments

Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.