bowenliang123/dsh-context
bowenliang123/dsh-contextDSH 上下文洞察面板:Context 仪表盘 + /context命令 + Context 浏览器,查看 Context的分类组成、内容详情、演进趋势、压缩/注入事件、统计等一站式 Context 全生命周期管理。
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.
Adds a 「余额与高峰」/ “Balance & Peak” card to the harness settings page:
GET /user/balance endpoint.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.
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.
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.
| 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.
fetch, Intl, node:test. The client bundle is a plain-JS __ModuleLoader__ factory — install is instantaneous and there is nothing to compile.Intl.DateTimeFormat; the host's own timezone is irrelevant. No tz database package.NO_KEY, INVALID_KEY, RATE_LIMITED, TIMEOUT, NETWORK, BAD_SHAPE).webServer, settings, credentials or schemastery? Each piece quietly skips itself; the rest keeps working.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.
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.
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
MIT