dsh-whale-usage

August 23, 2026 · View on GitHub

Practical notes for working on this plugin. For user-facing setup see README.md.

Plugin architecture

dsh-whale-usage is a single self-contained DSH plugin that bridges two upstream plugins:

  • Whale widget host (lib/whale-host.js): the bottom-right DeepSeek balance whale widget (balance, peak/off-peak pricing, sounds, ledger/token usage modes) — absorbed from dsh-whale-widget.
  • Usage data engine (lib/usage-host.js): per-session app-usage stats (token trends, model breakdown, activity) — absorbed from dsh-usage-stats.
  • Bridge config panel (lib/client.js): the "Little Whale · Usage" overlay where you pick the accounting / real-time-token / app-usage mode and see today's usage.
  • Host entry (lib/index.js): wires the host half + /dsh-whale-usage/* routes + agent-facing pieces.

Nothing here changes the upstream packages; the bridge copies their source logic in, so it is immune to upstream updates.

Install (normal package — never a junction)

# from this repo (or after cloning it on the target machine)
dsh plugin --profile web add <absolute path to this folder>
# or install the built tarball:
dsh plugin --profile web add <path>/dsh-whale-usage-0.1.2.tgz
# or use the provided convenience scripts:
bash scripts/install.sh                 # POSIX
powershell -ExecutionPolicy Bypass -File scripts/install.ps1   # Windows

The plugin ships dsh.bundle.patch (cordis.patch.yml), so the DSH CLI auto-registers it in dsh.profile.bundles; a restart (and a browser hard-refresh) mounts it.

⚠️ No junction. Linking the plugin directory into the profile with a junction breaks Node's dependency resolution (deps such as schemastery/react can't resolve upward from the junction target path) and can desync the package name from cordis.patch.yml — both cause DSH boot to fail.

Building the tarball

The repo ships the built artifact (lib/) plus a pre-built dsh-whale-usage-<version>.tgz. To regenerate it after editing lib/:

npm pack         # or: pnpm pack
# produces dsh-whale-usage-<version>.tgz

Re-syncing upstream fixes

This plugin is self-contained and does not follow upstream automatically. To pick up an upstream fix:

  1. Clone / update the upstream repo (e.g. lanlandeli/dsh-usage-stats, or the whale widget source in zhu1090093659/dsh-web-ui).
  2. Copy the corresponding updated source into lib/usage-host.js (usage engine) or lib/whale-host.js (whale widget).
  3. Bump the version in package.json (+ dsh.plugin.json), npm pack, then re-install and restart DSH.

Runtime data

  • Whale accounting / config: ~/.dsh/.dshw-*.json
  • App-usage index: ${DSH_HOME}/usage-stats

Config (cordis.patch.yml / settings)

config:
  indexConcurrency: 2      # usage engine concurrency for reading historical sessions
  cacheWriteDelayMs: 1000  # debounce before writing local stats
  apiPath: /usage-stats/v1 # app-usage API prefix

Hard constraints

  • Never modify DeepSeek Harness source (~/.dsh/source/current).
  • Keep the package name (dsh-whale-usage) in sync with cordis.patch.yml's name.
  • Keep dsh.plugin.json (id / version / main / client.main) in sync with package.json and lib/.

Intentional omissions

This repo ships a built artifact (not a TS source tree), so it deliberately does not carry a source build/test/CI stack (tsconfig / tsdown / vitest / .github/workflows). Add those only once a source tree is introduced.