Skip to content
dsh.fish
Bundle

dsh-agent-whale-girl

An unofficial whale-girl companion for the DSH Web GUI: a sidebar brand mark plus a draggable, collapsible floating mascot that follows the cursor, reacts to pats and clicks, reads the agent state, and reports the current session's real token usage.

Source
Turanbuturan
License
MIT
Updated
Updated 7 days ago

Readme

# dsh-agent-whale-girl

An unofficial **whale-girl (鲸鱼娘) companion** for the DeepSeek Harness Web GUI.
She replaces the sidebar brand mark and floats over the page as a draggable,
collapsible mascot: her head follows your cursor, she reacts to pats and clicks,
she follows what the agent is doing, and her speech bubble reports the current
session's real token usage.

![whale-girl](assets/whale-girl-768.webp)

> The character is community fan art, not an official DeepSeek asset — see
> [Source & attribution](#source--attribution). Chinese docs: [README.zh.md](README.zh.md).

## What she does

| Area | Behaviour |
| --- | --- |
| Sidebar brand mark (`sidebar.brand.mark`) | Replaces the stock fish logo with a close-up of her face (`avatar-face.png`). Registered with `priority: -1` so it wins the single-value slot. |
| Floating companion (`shell.overlay`) | A 220×298 paper doll over the frame, with a token card above her and speech bubbles. Drag her anywhere inside the frame (position kept in `localStorage['whale-girl:position']`); double-click returns her to the bottom-right corner and forgets the position; when the window shrinks she is folded back into view. |
| Gaze | Her head turns towards the pointer (up to ±7°) and her tail counter-swings (±4.8°); both settle back to centre 0.22 s after the pointer leaves. The pivot is measured from the eyes/lashes in the art, not from the bounding box. |
| Pat | Press and hold ≥ 350 ms: a one-shot squash-and-return animation plus a dedicated line. She does **not** fold away. |
| Click and combo | A quick click (< 350 ms) folds or unfolds her, with an answering line; 3–4 fast clicks get a counted complaint; the 5th click fires a one-shot easter egg. |
| Mood | `data-mood` follows context occupancy: `<50%` `calm`, `≥50%` `tense`, `≥85%` `crit`. Each crossing drops a 💦 in her corner for 2.6 s. |
| Speech | Lines are triggered by state and filled with real numbers from DSH's own session projections (`tokenUsage`, `contextPressure`): a greeting on mount, an answer on click, live progress while the turn is producing output, a context warning at 80 %, and a "done" line 2.5 s after output stops. She never calls the network or the model. |
| Token card | Context occupancy (bar plus `tokens / window`) and output / input / cache-read counts for the current session — the same projections the composer's own indicator uses. Hidden when there is no session; it yields when the window is narrower than 900 px. |
| Three-layer puppet | Her body, head and tail are separate layers that are pixel-identical to the still illustration at rest, so they are invisible until she moves. |

Animations run only while she is being interacted with: exactly three one-shot
`@keyframes` (`wg-pat` / `wg-egg` / `wg-emote`), no `infinite`, no `alternate`,
no `will-change`; `getAnimations()` is empty when idle.

## Install

The package declares a `dsh.bundle` patch, so installing it mounts both halves —
no profile editing, no manual copy:

```sh
dsh plugin --profile desktop add github:Turanbuturan/dsh-agent-whale-girl
```

`--profile desktop` is the DSH desktop app; use `--profile web` for a plain web
profile. A release tarball or a local checkout works the same way:

```sh
dsh plugin --profile desktop add ./dsh-agent-whale-girl
```

Reload the page afterwards. Host-side changes need a full app restart (Node's ESM
cache pins the module path), but this plugin's host half is empty — a page
refresh is enough.

### Manual drop-in

Copy the folder into `<profile>/plugins/` and add the row to the profile's
`cordis.patch.yml`:

```yaml
- insert:
    - id: whale-girl
      name: "./plugins/dsh-agent-whale-girl/index.js"
```

The path resolves against the profile directory. Removing the `insert` row (and
refreshing) removes her; the folder may stay in place.

### Uninstall

```sh
dsh plugin --profile desktop remove dsh-agent-whale-girl
```

If you used the manual drop-in instead, delete the `insert` row and refresh.

## Build and verify

`lib/client.js` and `lib/client.css` are committed, so installing needs no build
step. To rebuild after changing the art or the skeleton:

```sh
node build.mjs            # regenerates lib/client.js + lib/client.css from the PNGs and layers.json
node verify-bundle.cjs lib/client.js
```

`verify-bundle.cjs` is a structural and behavioural self-check (registrations,
injected CSS, layer geometry, gaze maths, click/pat/combo timing, mood values).
Use absolute paths — the script resolves the bundle relative to the working
directory.

## Files

| File | Purpose |
| --- | --- |
| `package.json` | Declares `dsh.bundle.patch` (installable bundle) and `dsh.client.platform = "web"` (browser half). |
| `index.js` | Host half: an intentionally empty `apply()` so the loader can mount the package. |
| `cordis.patch.yml` | The mount declaration read at install time. |
| `lib/client.js` / `lib/client.css` | Build output: the client bundle that registers both slots, and the stylesheet it injects. |
| `build.mjs` | Builds the two files above from the PNGs and `layers.json` (inlines the art, writes the skeleton geometry into CSS). |
| `layers.json` | Puppet skeleton: crop boxes, rotation origins in the 414×560 art space, amplitudes, measured pivots. |
| `verify-bundle.cjs` | Self-check. |
| `avatar-body.png` / `avatar-head.png` / `avatar-tail.png` | The three puppet layers. |
| `avatar-face.png` | 96×96 face crop used by the 24 px mark and the folded bubble. |
| `avatar.png` | The full-body illustration before cutting. |
| `assets/` | Source art. |

## Source & attribution

The code is MIT. The character art is community fan art and keeps the terms of
the repositories it came from:

- [`Neko3000/deepseek-whalechan`](https://github.com/Neko3000/deepseek-whalechan) — MIT — **the art used now**; cut into layers and background-removed here.
- [`TreapGoGo/deepseek-whale-girl`](https://github.com/TreapGoGo/deepseek-whale-girl) — MIT — the earlier chibi avatar (`assets/whale-girl-avatar-512.png`).
- [`fornarwhal/deepseek-whale-girl-icon`](https://github.com/fornarwhal/deepseek-whale-girl-icon) — custom terms — reviewed as a candidate icon source, not shipped.

See [NOTICE](NOTICE) for the file-by-file mapping. "DeepSeek" and the DeepSeek
whale logo belong to their respective owners; this plugin is an unofficial
community project.

## License

MIT — see [LICENSE](LICENSE).

Install

dsh plugin --profile web add github:Turanbuturan/dsh-agent-whale-girl

Profile: web

  • This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.
Source