A whale girl desktop pet floats in the bottom right corner of the DSH webpage. It accompanies tasks and conversations, accumulating experience and memories. Users can feed, play with, and drag the pet.
- Language
- JavaScript
- License
- MIT
- Branch
- main
Install
$ dsh plugin --profile web add whale-girlRun the command above in your terminal to install this plugin via the dsh CLI. You can switch Profile in the top-right corner. New to dsh? Read the beginner tutorial
Install via your agent
Install the DeepSeek Harness plugin vlln/whale-girl for me: review the repository at https://github.com/vlln/whale-girl first, then run the install command and verify the plugin loads successfully.
Paste this instruction to the DSH Web GUI assistant — it will install and verify for you.
At a Glance
A whale-girl desk pet hovers in the bottom-right corner of the DSH Web GUI, accompanying you through completing tasks, meetings, accumulating seniority, and creating shared memories. It's a lightweight companionship plugin in the "QQ Pet" style, driven by accumulation rather than cultivation pressure.
Core Capabilities
- Floating Window Rendering: Displays a draggable character in the bottom-right corner of the DSH web page, supporting click interaction menus (feed/play/switch character)
- State Machine Driven: Automatically switches between 15 state animations (idle, nap, welcome, celebrate, scared, disappointed, thinking, waiting, walking, etc.) based on events like tasks/sessions/idle
- Seniority Accumulation: Complete tasks +10 XP, new session +5 XP, active companionship time accumulates; zero negative feedback (failures only count, no point deduction)
- Titles & Memories: Unlock titles automatically upon reaching milestones; cumulative shared events between you and the pet are written into a memoir
- Experience Layer Hot-Reload: Pet size, transparency, wandering interval, idle time before napping, interaction reply text, etc. take effect without restart after modifying
settings.yaml - Multi-Character Switching: Built-in multiple character assets (each character must provide all 15 states), menu supports cyclic switching or persistent selection via localStorage
Technical Implementation
- Language: JavaScript (Node half) + ES Modules; client bundle packaged with esbuild
- Key Dependencies: schemastery (config schema), esbuild (build client bundle); no other runtime third-party dependencies
- Architecture Pattern: Official bundle plugin format — repository root
package.jsondeclaresdsh.bundle.patch+dsh.client.platform=web; Node half is a complete Cordis plugin (depends onjobs/agents/sessions/settings/webServer), client mounted via__ModuleLoader__kernel - Entry Files:
lib/index.mjs(Node half) +lib/client/index.mjs(client source; productlib/client.jsgenerated byscripts/build-client.mjs)
Use Cases
For people who use DSH for long periods running tasks or sessions, wanting a moving "companion" at their workstation to relieve monotony. The pet provides real feedback to task/session events (celebrates upon completion, accompanies during thinking, naps when idle), better demonstrating a "working together" atmosphere compared to purely decorative add-ons. Also suitable for users wanting to experience the QQ pet nostalgia, and as a reference for official bundle plugin development patterns.
Prerequisites & Compatibility
| Dependency | Min Version | Description |
|---|---|---|
| DSH | Not declared | Official bundle plugin, does not declare engines in package.json; requires DSH supporting bundle format (profile web management) |
| Node | Not declared | Source uses ES Modules and top-level await; runtime provided by host |
| Platform | Cross-platform | Node half cross-platform; asset path sanitization handles Windows backslash traversal |
| Native modules | None | Pure JS dependency only on schemastery, no native binding introduced |
Installation
dsh plugin --profile web add github:vlln/whale-girl
Configuration Options
| Config | Type | Description | Default |
|---|---|---|---|
enabled | Boolean | Master switch for web pet rendering; recommend setting to false when desktop companion is running to avoid dual pets | true |
size | Number (64–160) | Pet display size (pixels) | 110 |
opacity | Number (0.2–1) | Normal transparency (interaction has separate 0.25 temporary low transparency, not in this config) | 1 |
walk.enabled | Boolean | Whether to allow pet to periodically auto-wander | true |
walk.minWaitMs / maxWaitMs | Number (0–300000) | Random wait bounds between two wanders (ms) | 18000 / 40000 |
walk.minMs / maxMs | Number (0–60000) | Single wander duration bounds (ms) | 3000 / 6000 |
walk.speedPxPerSec | Number (10–300) | Wander speed (pixels/sec) | 45 |
sleepAfterMs | Number (5000–600000) | Idle duration before entering nap state (ms) | 60000 |
pollMs | Number (1000–30000) | State polling interval (ms) | 3000 |
bubbleMs | Number (500–10000) | Interaction reply bubble display duration (ms) | 2500 |
welcomeMs / celebrateMs | Number (0–30000) | Welcome/celebrate state window duration (ms) | 6000 / 6000 |
errorMs / disappointedMs | Number (0–15000) | Scared/disappointed state window duration (ms) | 4000 / 6000 |
replies.feed / replies.play | String array | Reply text pools for feed/play interactions (custom additions allowed) | Built-in 3 sentences each |
The semantic layer (XP thresholds/level curves/title sets/memory limits) is not in the schema and cannot be overridden in configuration.
FAQ
Q: Why don't I see the pet after installation?
A: Bundle plugins are synthesized when DSH starts, so you need to restart DSH Web after installation. On first install, you'll also enter the onboarding guide page where the pet is hidden by default; it appears after completing the guide.
Q: Can it run simultaneously with the desktop companion?
A: Yes. When running the desktop companion under desktop/, the web pet will automatically hide via presence heartbeat (restores after companion exits or crashes with 45s TTL expiration). If you don't want dual-display, set whale-girl.enabled to false in settings.yaml to disable the web pet.
Q: Can I adjust seniority/titles/level curves?
A: No. These are code-level sealed semantic layer constants (XP formula 50·L·(L−1)/2, title sets, memory limits, etc.), schema intentionally doesn't expose them, guarded by the gate so config surface cannot reference them — only the visual/timing parameters in the experience layer table above are adjustable.
Q: Where is data stored? Will it be lost on uninstall?
A: State file is written to <DSH_HOME>/data/whale-girl/state.json, not in the plugin directory, so uninstalling the plugin won't delete seniority or memories; they continue accumulating after reinstallation.
Q: Updates didn't take effect, what to do?
A: Most changes (config surface, client behavior) require refreshing the page or restarting DSH Web to take effect; after modifying Node half source code, you must restart web because ESM secondary import to the same URL returns the old module.
Q: How to add custom characters?
A: Provide 15-state sprite sheets and manifest entries according to the asset full contract in docs/adding-a-character.md and docs/sprites-spec.md; character id limited to [a-z0-9-] (must be URL-path safe), locally run node scripts/gates/verify-assets.mjs for acceptance verification before plugin release.
Difficulty Level
Beginner — install with one command to use; all experience layer parameters have defaults; enter advanced level only when wanting to customize characters or participate in development (requires understanding schemastery, Cordis plugin structure, and sprite asset specifications).
Known Issues & Limitations
- After bundle format initial release, plugin path/export name cannot be renamed (public ref consumed), changing structure breaks installed environments
- Character id allows only
[a-z0-9-]characters (URL path injection defense), naming needs attention - Desktop companion is not within
dsh plugininstallation scope; requires selfnpm install+ starting Tauri/headless engine indesktop/subdirectory - After modifying Node half source code, ESM cache causes disable/enable to not take effect, must restart DSH Web (
plugin tree failed to loadis a clear signal of this issue) - Although config modifications support hot-reload, initial injection still depends on synthesis at host startup; changing schema field names/defaults requires restart for old settings to re-normalize
中文 | English
whale-girl
A desktop pet in the DSH Web GUI (QQ-pet style)
A persistent companion floating bottom-right: draggable, feedable, playable —
completed tasks, sessions, and companionship time accrue into seniority levels,
titles, and memories.
Installation
Official bundle plugin (dsh.bundle + dsh.client in root package.json), managed via the official profile:
dsh plugin --profile web add "github:vlln/whale-girl#main" # single-line git source (build artifacts committed)
# or npm source: dsh plugin --profile web add [email protected]
# or local directory: dsh plugin --profile web add <path-to-whale-girl>
Restart web after installing (bundle layers compose at startup); the pet appears bottom-right: click for its menu (🍗 feed / 🎾 play), drag to move, hover for the status bar (seniority level / task count / recent shared memories). Hidden on onboarding pages.
Update via dsh plugin --profile web update whale-girl (or switch the git ref), then restart.
Usage
| You / event | Pet behavior |
|---|---|
| Drag the pet | Stretched diagonally (drag) |
| Menu 🍗 feed / 🎾 play | Chomping / ball toss (eat/play) → joy (joy) |
| Idle ≥60s | Naps (sleep); wakes on interaction (wake) |
| Task done / level-up / title / round done | Cheers (celebrate) |
| Task failed / request error | Startled (error) → disappointed (disappointed) |
| New session | Waves welcome (welcome) |
| Session running / thinking | Pensive company (think, occasional working) |
| Awaiting approval | Expectant waiting (wait) |
| Periodic wandering | Walking (walk) |
| Default | Idle standby (idle, random blinks / turns) |
Full state machine (priorities / transitions / triggers): docs/state-machine.md.
Desktop Companion (Optional)
desktop/ is a standalone companion app (Node engine + Tauri shell, zero runtime deps) that keeps the whale girl resident on your OS desktop. Not installed via dsh plugin — enable it yourself:
# Prereqs: Node ≥18; the rendering shell needs Rust (cargo)
npm install -g whale-girl-desktop # npm install (engine + Tauri shell source included)
whale-girl-desktop --headless # headless: presence heartbeat + state polling + SSE
cd "$(npm root -g)/whale-girl-desktop/src-tauri" && cargo build --release # first build ~5-15 min; artifact target/release/whale-girl-desktop (~12MB)
./target/release/whale-girl-desktop # transparent always-on-top desktop pet (defaults to local DSH on 3080)
# WHALE_GIRL_BASE_URL=http://IP:PORT points at a non-local DSH
# or from source: cd desktop && npm install && cd src-tauri && cargo build --release
- Uses whale-girl's public endpoints (
/state,/events,/presence,/interact,/config,/assets) without touching the plugin; the in-page pet hides while it runs (presence contract) and returns after exit/crash (TTL 45s). - Shell: Tauri v2 (recommended, ~12MB); legacy Electron shell kept (
npm i -D electron). - Design & contracts:
desktop/DESIGN.md,desktop/BUILD-RUN.md.
State Preview
| State | Trigger | Preview |
|---|---|---|
idle | Default standby | ![]() |
working | Random work spell while session thinks | ![]() |
celebrate | Task done / level-up / title / round done | ![]() |
error | Task failed / request error | ![]() |
disappointed | Brief dejection after failure | ![]() |
joy | Happy after feeding / playing | ![]() |
eat | Click to feed | ![]() |
play | Click to play | ![]() |
drag | While dragging | ![]() |
walk | Periodic wandering | ![]() |
sleep | Idle ≥60s | ![]() |
wake | Wake-up transition | ![]() |
welcome | New session | ![]() |
think | Company while session thinks | ![]() |
wait | Awaiting approval | ![]() |
Configuration
Edit the whale-girl: section in <dshHome>/settings.yaml (or the settings UI); changes apply live, no restart:
whale-girl:
enabled: true # web render toggle (false disables the in-page pet while a desktop companion runs)
size: 110 # pet size px (64–160)
opacity: 1 # default opacity (0.2–1)
walk:
enabled: true # wandering toggle
sleepAfterMs: 60000
Full option list and why the semantic layer (XP / titles) is sealed: lib/src/config.mjs. Not configurable (changing XP / title thresholds would break the accumulation ledger).
Characters
🎭 "Switch Character" cycles characters (or set whale-girl:character in localStorage); the button is greyed out when the manifest has a single character ("No other characters available"). Every character ships all 15 states (full contract: docs/sprites-spec.md); new characters: docs/adding-a-character.md.
Reference Implementation
whale-girl is a complete bundle plugin format exemplar (dsh.bundle + cordis.patch.yml + lib/, evolving with the official mechanism) — model new plugins on it:
- Structure:
lib/(entry / logic / client / assets) separate from docs, decisions, scripts — root AGENTS.md - Conventions: gates (
scripts/gates/run.mjs) + decision records + full asset contracts; guidance: plugin-registry's make-dsh-plugin skill, cookbook, gotchas
Contributing
Issues and suggestions welcome — your feedback shapes the pet's next steps:
- 🐛 Bug: file an issue with repro steps, browser & dsh versions; console errors for client issues
- 💡 Feature ideas: see docs/state-machine.md and docs/growth-system.md, describe the expected effect
- 🎨 New characters: docs/adding-a-character.md §quick guide — read-only contract, 15 sheets + manifest entries, validated by
verify-assets - 🔧 Code: every non-trivial change needs a decision record (
decisions/), gate self-checks, single-purpose commits (docs/AGENTS.md, root AGENTS.md)
Acknowledgements
Character by ZipZipPipe (the "Whale Girl" sticker character); sprites generated from their design.
License
MIT License
Read the usage guide →
Install steps, key points, FAQ and compatibility for this plugin — auto-derived from indexed fields.
Listing badge
[](https://deepseek-plugin.org/plugins/vlln/whale-girl)Paste this markdown into your GitHub README to link back to this listing. The badge only states the listing — not a security endorsement.














