Plugin directory / Browser / deepseek-peak
deepseek-peak
Verified · install-tested on dsh YMRYMR
What it does
Live DeepSeek V4 API peak/off-peak status widget — drop-in dsh-plugin for deepseek-ai/deepseek-harness, plus a standalone browser widget.
Works — verified, early-stage project
Live DeepSeek V4 API peak/off-peak status widget — drop-in dsh-plugin for deepseek-ai/deepseek-harness, plus a standalone browser widget. It installs cleanly and boots without issues in our testing. It's early-stage but functional.
“Verified” means our automated CI actually ran dsh plugin add in a clean profile and it booted — nothing more. Feature descriptions and version compatibility are the author’s claims. This is not a security audit and not an endorsement of third-party code.
README
deepseek-peak
A drop-in dsh-plugin for thedeepseek-ai/deepseek-harness
web UI that shows the DeepSeek V4 API's current peak / off-peak pricing
state, lets you pause the LLM during peak hours with a queue that drains
on its own, watches your account balance, and warns you when the
balance drops below a threshold you set.

The PEAK pill in the session header, the BALANCE row with the
REFRESH and TOP UP actions, and the per-model 30-day peak/off-peak
bar charts (v4-pro and v4-flash). The pill is amber when the
balance drops below the configured lowBalanceWarningUsd
threshold.
What it does
Pill (always visible, in the session header next to the Session
log button). Reads the current phase from the browser clock against a
baked-in UTC schedule:- Green during off-peak windows
- Red during peak windows (2× the off-peak rate)
- A
PRE-CUTOVERbadge while the new schedule is being previewed - A live countdown to the next phase boundary
- A
→ livetarget arrow while pre-cutover, or a→ next phase HH:MM
arrow after the cutover - A pause toggle at the right edge of the pill: when on AND the phase
is peak, the LLM stream is gated and user messages queue instead of
running - Amber border + dot + label when the account balance drops below
the configuredlowBalanceWarningUsdthreshold (default $1.00).
Overrides the phase color so a low balance is visible at a glance.
Tooltip (on hover, while the pill is open). Expands under the
pill:- A BALANCE row showing the current DeepSeek account balance
(host-routed through/api/peak-hours/balanceso the API key never
leaves the harness process). Two action pills on the right:- REFRESH — bypasses the 5-min host cache AND the browser cache
so a user who just topped up sees the new number without waiting
for the natural refresh tick. - TOP UP — opens
https://platform.deepseek.com/top_upin a
new tab.
- REFRESH — bypasses the 5-min host cache AND the browser cache
- A per-model chart card for each model the user has run in the
trailing 30 days (v4-pro, v4-flash). Each card has a tiny inline
SVG daily bar chart, 30 days wide, with peak (red) on top of
off-peak (green). The split is computed from each event's UTC
timestamp against the schedule. - A small legend so the peak/off-peak split is legible without a
tooltip. - When the LLM is gated and the queue has items, a queue card
appears under the chart with one row per queued message and a
per-row send arrow that dispatches that single message
immediately (bypasses the global pause).
- A BALANCE row showing the current DeepSeek account balance
Settings (registered on the existing
peak-hoursnamespace in
the host's settings plane, exposed throughSettings → Plugins → Plugin configuration → Peak hours):paused— boolean, the same value the pill toggle writes. Two
write paths into the same field; last write wins.lowBalanceWarningUsd— number, the threshold below which the
pill switches to amber. Default$1.00. Zero is allowed (always
warn); negatives are rejected by the schema.
Background refresh:
- The state poll runs every 2 s on the browser (Pill's
usePeakHoursState
hook), so toggle / threshold / queue / balance changes propagate
in under two ticks. - The balance is fetched server-side and cached for 5 min, with a
30-s fast retry on transient errors so a brief blip doesn't poison
the cache. - The chart's per-day buckets come from the host's
/api/peak-hours/usageroute, which walks the session persistence
log. The in-browser trajectory walk is a fallback for the
harness-not-running case.
- The state poll runs every 2 s on the browser (Pill's
Source of truth:
api-docs.deepseek.com/quick_start/pricing/.
The schedule windows and the cutover date are baked in as constants
insrc/client/domain.ts. ThePRE-CUTOVERwindow is the period
between "the new schedule is announced" and "the new schedule is
enforced"; the pill shows it for the duration and the gate is
engaged wheneverpaused && peakregardless of cutover state.
This repo ships two things:
harness-plugin/— adsh-pluginCordis client package for the
harness web UI. This is the real integration.widget.html+serve.js— a self-contained browser widget
you can pin as a tab in any browser, no harness required. Useful as a
fallback for users who don't run the harness. It does NOT include the
pause / queue / balance features; it's a phase + countdown display
only.
The harness plugin is the rich one. The standalone widget is a
"schedule on a second monitor" display.
Install (harness plugin)
Requires:
- A checked-out
deepseek-harnessworking tree (any recent commit) node≥ 22.19pnpm≥ 11 (install once withnpm i -g pnpm)
# Clone this repo
git clone https://github.com/YMRYMR/deepseek-peak.git
cd deepseek-peak
# One-liner installer: takes your harness clone as the argument
./install.sh /path/to/deepseek-harness
What the installer does (each step is idempotent and skipped if already done):
- Copies
harness-plugin/→<harness>/packages/client/ui-peak-hours/ - Adds the
ui-peak-hoursrow topackages/bundle/web-app/cordis.patch.yml - Adds the workspace dep to
packages/bundle/web-app/package.json - Adds the project reference to
tsconfig.client.json - Adds the path mapping to
tsconfig.base.json - Runs
pnpm installin the harness - Runs
pnpm run build:lib:host(required for the generated Typert contracts) - Runs
pnpm --filter @deepseek-ai/dsh-client-ui-peak-hours run bundle - Runs the harness verification gates (warnings only)
Then start the harness:
cd /path/to/deepseek-harness
pnpm dsh web
Open http://127.0.0.1:3080/. The pill appears in the top-right of the
session header, left of the Session log button.
Hard-refresh the browser (Ctrl+Shift+R) the first time so the new__DSH_BOOT__ roster loads.
What you should see
A compact pill, ~180 px wide, with this shape (left to right):
[●] PEAK PRE-CUTOVER 08h 11m → live [pause-switch]
[●]is the colored dot — green for off-peak, red for peak, amber
when the balance is below the configured threshold (overrides the
phase color)- The phase label and the
PRE-CUTOVERbadge (only during the
pre-cutover window) - The countdown to the next phase boundary (1 Hz tick)
- The target arrow:
→ livewhile pre-cutover,→ next phase HH:MM
after the cutover - The pause switch at the right edge (red when on, gray when off)
Hover the pill
The card expands under the pill:
- BALANCE row — your DeepSeek account balance, with the REFRESH
and TOP UP actions on the right - Per-model chart card for each model you've used in the trailing
30 days (typically v4-pro and v4-flash). Tiny inline-SVG daily bar
chart, 30 days wide, peak (red) on top of off-peak (green). Day totals
shown in the top-right of each card. - A small legend under the chart: red = peak, green = off-peak
- If the queue has items, a queue card with one row per queued
message and a per-row send arrow for manual dispatch
Pause-during-peak workflow
- Click the pill's pause switch to the right of the countdown.
- While the switch is on AND the phase is peak, the next LLM stream
(user message or subagent tool call) is gated. The harness shows
the request as queued, and the tooltip expands to show the queue
card. - The queue is FIFO. Each item is dispatched the moment the switch
flips off or the phase leaves peak. - To dispatch a single item without flipping the global pause, click
the row's per-row send arrow in the queue card.
Low-balance warning
Open Settings → Plugins → Plugin configuration → Peak hours and setlowBalanceWarningUsd to your preferred floor (default 1.00). The
pill switches to amber the moment the live account balance drops below
the value. Override the same field directly in ~/.dsh/settings.yaml:
peak-hours:
paused: false
lowBalanceWarningUsd: 1.5
The next 2 s state poll picks up the new value automatically.
Uninstall
./uninstall.sh /path/to/deepseek-harness
The script removes the plugin directory and prints the four small
wire-up entries you need to delete by hand (one line each incordis.patch.yml, package.json, and the two tsconfig files).
Install (standalone widget)
No harness needed. Just a Node server that serves a static HTML page.
cd deepseek-peak
node serve.js
Opens http://127.0.0.1:3737/ in your default browser. Pin the tab.
Press Ctrl+C in the terminal to stop.
The standalone widget includes a 24-hour timeline of peak windows, a
V4-Flash / V4-Pro model selector, and the actual $/1M-token rate for
each tier. Useful on a screen that doesn't have the harness open.
Pause / queue / balance features are NOT in the standalone widget —
they live in the harness plugin only.
Why a plugin AND a standalone
The harness pill is the right answer inside the harness. The standalone
is the right answer everywhere else (a second monitor, a tablet, a
phone browser). Both compute the same numbers from the same
authoritative schedule, so they never disagree.
Host routes exposed by the plugin
| Route | Method | Purpose |
|---|---|---|
/api/peak-hours/state |
GET |
Current pause / phase / queue / balance / threshold (2 s polled by the browser) |
/api/peak-hours/state |
POST |
Toggle the global pause (writes through the host's settings service) |
/api/peak-hours/balance |
GET |
Live DeepSeek account balance (5 min host cache) |
/api/peak-hours/balance?fresh=1 |
GET |
Force a fresh upstream fetch (bypasses both the host and the browser cache; the in-tooltip REFRESH button calls this) |
/api/peak-hours/usage?rangeDays=N |
GET |
Per-day, per-model token / cost buckets for the trailing N days (default 30, max 365; 5 min host cache) |
/api/peak-hours/usage?fresh=1&rangeDays=N |
GET |
Force a fresh host walk of the session persistence log |
/api/peak-hours/queue/dispatch |
POST |
Manually dispatch the front queued item (the per-row send arrow in the queue card calls this) |
The API key is held by the host's credentials seam and never reaches
the browser — the host routes read the key, fetch fromapi.deepseek.com, and return the parsed JSON envelope.
Verified
The plugin passes every harness gate I could run on a Windows dev tree:
| Check | Result |
|---|---|
pnpm run constraints |
220/220 packages conform |
pnpm run verify-cordis-config |
120/120 config files passed |
pnpm run verify-package-invariants |
220/220 hand-owned companions conform |
tsc -b tsconfig.client.json |
clean |
pnpm --filter ... run bundle |
~78 kB client.js |
pnpm run build (host + client + web) |
clean |
Live runtime smoke (curl /plugins/.../client.js) |
200, ~78 kB, slot registered |
What the source layout looks like
deepseek-peak/
├── README.md # this file
├── LICENSE # MIT
├── .gitignore
├── install.sh # one-line installer for the harness plugin
├── uninstall.sh # rollback helper
├── package.json # standalone-widget package
├── serve.js # standalone-widget Node server
├── smoke.js # standalone-widget self-test (5/5 passes)
├── widget.html # the standalone widget
├── docs/
│ └── pill-preview.png # the screenshot at the top of this README
└── harness-plugin/ # the in-harness plugin (copied to a harness
# clone by install.sh)
├── package.json
├── tsconfig.json
├── tsdown.config.ts
├── README.md
└── src/
├── index.ts # host face — routes, settings,
│ # LLM gate, 1 Hz phase ticker
├── invariant.ts
├── css-modules.d.ts
└── client/
├── index.ts # browser apply() — registers the pill
├── domain.ts # pure peak/off-peak math, schedule,
│ # pre-cutover computation
├── phase.ts # phase types, currentPhase(), labels
├── peakHoursState.ts # state hook — 2 s poll, paused toggle
├── balance.ts # balance fetch + 5 min cache, REFRESH support
├── usage.ts # host usage fetch with host-side fallback
├── pricing.ts # model display names
├── PeakHoursPill.tsx # the always-visible React component
├── PeakHoursPill.module.css
├── PeakHoursHost.tsx # hover-state host; renders the tooltip + queue
├── PeakHoursHost.module.css
├── UsageTooltip.tsx # the tooltip card (balance + chart + queue)
├── UsageTooltip.module.css
├── QueueCard.tsx # per-row dispatch card
├── QueueCard.module.css
├── PauseSwitch.tsx # the pill's right-edge toggle
├── PauseSwitch.module.css
├── PeakHoursDock.tsx # legacy input.dock variant, kept for
│ # reference; the current pill lives
│ # in the session header instead
└── PeakHoursDock.module.css
Notes
- The schedule and the pre-cutover date are baked in as constants in
src/client/domain.ts. If DeepSeek changes the windows or the
cutover date, edit the constants there and re-bundle. - All times are computed in UTC; only the display is localized to
the browser's IANA zone. - The pill trusts the browser clock against the baked-in UTC
schedule. A user with a mis-set system clock will see a misleading
status. A future iteration can sanity-check viaworldtimeapi.org. - The pause toggle on the pill and the
pausedfield in the
Plugin configuration page are two write paths into the same
persisted setting. The 2 s state poll reconciles whichever wrote
last. - The pill's REFRESH button invalidates the browser cache (so a
rapid second click still reaches the host) and calls the host with?fresh=1(so the host bypasses its own 5 min cache and re-fetches
fromapi.deepseek.com). Both must be running the latest code for
REFRESH to work end-to-end; the host change requires a dsh web
restart.
License
MIT. See LICENSE.
Install
Install the catalog once, then DeepSeek Harness can find and install any plugin from this site automatically:
dsh plugin add dshbase-catalog Then say "install deepseek-peak for me" — your agent finds it in the directory and installs it. Docs: dshbase-catalog · verified packs.
This plugin is GitHub source (not published to npm) — install it straight from the repo:
Web profile:
dsh plugin --profile web add github:YMRYMR/deepseek-peak Headless (CLI) profile:
dsh plugin --profile headless add github:YMRYMR/deepseek-peak Test report
Verified: L1 install + L2 load + L3 runtime from GitHub source on dsh 0.1.0-rc.6.
When to use it
Let the agent drive a real browser — navigate, click, fill, and read pages — for research or UI testing.
Who it's for
Users who want browser automation done by the agent rather than a separate scraper or test script.
For developers — extending it
Browser actions are the seam — expose more tool calls (form fill, downloads, tab management) to the model.