dsh-client-ui-whale

August 14, 2026 · View on GitHub

English | 中文

A tiny DeepSeek Harness (DSH) client plugin that puts a DeepSeek-logo whale at the right edge of the conversation column. It idles with a small periodic spurt, and as the session's token consumption rate climbs, the spurt fires more often and grows bigger — the faster tokens stream, the harder it sprays.

The whale is the official DeepSeek logo shape (from the shipped favicon), recolored in the brand blue. DeepSeek is a trademark of DeepSeek; this plugin is an independent, unofficial fan project.

Demo

Whale spray demo: a DeepSeek-logo whale sits to the right of the chat dialog, spraying water that grows with the token consumption rate

The whale lives just to the right of the conversation column (the highlighted "NEW" area in the demo). While idle it gives a small spurt every ~2.5s; when tokens stream, the spurt fires more often (interval shortens) and its height, droplet count, and droplet size scale with the token rate.

Features

  • Floating whale pinned just right of the conversation column (falls back to the viewport corner when there is no room).
  • Rate-driven spurt: idle gives a small spurt every ~2.5s. As the token rate (tokens/second) rises, the spurt interval shortens (down to ~0.3s) and its height, droplet count, and droplet size scale up — sampled every 400ms and exponential-smoothed from the session's tokenUsage projection.
  • Live token badge under the whale so you can verify the correlation.
  • Debug panel: a small ⚙ toggle under the whale opens a panel to manually override spurt size (level) and rate (tokens/s) — handy for tuning the animation without generating tokens.
  • Dark-mode aware badge, zero build step, no runtime dependencies.

How it works

DSH composes its UI from client plugins. This package is a dual-face plugin:

  • lib/index.js — the Node half: an empty apply() that makes the package an enabled Loader entry.
  • lib/client.js — the browser half, loaded by the client module system (window.__ModuleLoader__.load). It registers one entry into the conversation.session.header.actions slot (session scope, so the standard kit carries useProjection), reads useProjection("tokenUsage"), and portals the whale into document.body for viewport-relative positioning.

Token accounting comes from @deepseek-ai/dsh-token-meter's tokenUsage projection (the disjoint buckets uncachedInputTokens, outputTokens, cacheReadTokens, cacheWriteTokens).

Install

A DSH client plugin must be resolvable from the target profile's node_modules and registered as a Loader row in cordis.patch.yml.

1. Add the plugin

From npm (recommended):

dsh plugin --profile web add @allen0118/dsh-client-ui-whale

This runs pnpm add in the profile directory, installing the published package. (Equivalent: cd "$DSH_HOME/profiles/web" && pnpm add @allen0118/dsh-client-ui-whale.)

From source (symlink — for hacking on the plugin):

PROFILE="$DSH_HOME/profiles/web"          # or your profile dir
mkdir -p "$PROFILE/node_modules/@allen0118"
ln -sfn "$(pwd)" "$PROFILE/node_modules/@allen0118/dsh-client-ui-whale"

From a local checkout (file dependency):

Add to the profile's package.json, then run pnpm install in the profile directory:

"dependencies": { "@allen0118/dsh-client-ui-whale": "file:/path/to/dsh-client-ui-whale" }

2. Register the Loader row

Append to $PROFILE/cordis.patch.yml:

- insert:
    - id: ui-whale
      name: '@allen0118/dsh-client-ui-whale'

3. Restart

Restart dsh web and refresh — plugin-set changes only take effect on restart.

Configuration

There is no config surface yet; edit lib/client.js directly:

  • Position / gap: useWhalePosition() (gap is 16, fallback corner is right: 28, narrow-viewport fallback is right: 12).
  • Spout curve: the level expression in TokenWhale — idle 0.12, else Math.min(1, Math.sqrt(rate / 50)), saturating near 50 tokens/second. The rate is sampled every 400ms and exponential-smoothed in useTokenRate().
  • Spurt interval: idle 2500ms, shrinking as 2500 × 0.5^(rate/12), clamped to 300ms.
  • Sizes: spoutH (4–80px), dropCount (2–10), dropSize (3–6px).
  • Colors: the .whale-drop / .whale-svg / .whale-count CSS rules.

To disable, add disabled: true to the ui-whale row (or delete the row) and restart.

Development

npm run check   # node --check on both halves

lib/client.js is hand-maintained plain JavaScript in the exact shape the DSH client module loader expects; there is intentionally no build step.

License

MIT. The DeepSeek logo is used for identification only.