# dsh-digipet **Hatch a digital creature in your DeepSeek Harness — it feeds on your real work and evolves, raising-game style.** Write code and it becomes a dragon; read docs and it becomes a sage; keep shipping errors… and it becomes something that lives in ten million processes at once. [![license](https://img.shields.io/badge/license-MIT-green)](LICENSE) ![dsh-plugin](https://img.shields.io/badge/dsh-plugin-1f6feb) ![deps](https://img.shields.io/badge/deps-0-lightgrey) ![tokens](https://img.shields.io/badge/token%20cost-0-orange) ![tests](https://img.shields.io/badge/tests-42%20✓-brightgreen) [中文](README.md) | English
``` The shell cracks open — ▗▄▚▚▄▖ ▐ ◉ ◉ ▌ ▝▚▄▄▞▘ 。o ✨ DigiEgg evolved into Bitpop (Baby Ⅰ) "A single bit that just raised its flag, not yet sure what it wants to become." ``` ![Evolution ceremony](docs/ceremony.png) ## 30 seconds to a pet ```sh dsh plugin --profile web add github:swaylq/dsh-digipet # restart dsh, then in any session: /pet hatch ``` Then **just work**. Every completed turn +5 XP, each of your messages +2, every tool call +3, even every error +4. `/pet` to check on it, `/pet evolve` for the ceremony. ## What it becomes depends on how you work The life cycle follows classic V-pet canon in full: **Egg → Baby Ⅰ → Baby Ⅱ → Child → Adult → Perfect → Ultimate**. From Child onward, every evolution re-reads how you actually worked that stage to pick a lineage: | Lineage | What feeds it | Ultimate form | |---|---|---| | 🐉 Dragon | writing files, running commands | Wardrake Sovereign | | 📜 Sage | reading code, searching docs | Codex Deva | | 🕊️ Angel | plain conversation | Seraph Prime | | 👾 Virus | errors and mishaps survived | Doomweaver — `kill -9` only makes it split | 3 shared baby forms + 4 lineages × 4 stages + **3 hidden forms** = a 22-slot dex. Lineages are never locked in — a Dragon-line pet that spends a stage drowning in stack traces respecs into the Virus line. What it finally becomes is a mirror of how you actually worked. As for the hidden forms, the dex offers only a rumor: > "Rumor: evolving on a stuffed belly ends badly." Veterans know exactly what that means. Some mistakes can be redeemed by love; others pile up, layer upon inherited layer, into something *ancestral* (the last line of its art reads `// don't touch.`). ![Dex](docs/dex.png) ## Commands | Command | Does | |---|---| | `/pet` | status card: art, XP, fullness, mood, four stats, lifetime counters | | `/pet hatch` | lay the egg (one pet per DSH home; also triggers a ready egg's ceremony) | | `/pet evolve` | the evolution ceremony | | `/pet name ` | name it (≤16 chars) | | `/pet dex` | the collection (unseen forms show as ???; hidden forms get only a rumor) | | `/pet story` | its life journal | | `/pet about` | mechanics and trust stance | **Upgrading from 0.1.x**: old saves (the sea-creature roster) migrate automatically and losslessly on next boot — stage, XP, stats, dex and journal all carry over, with historical forms mapped onto the new roster. ## Why The DSH ecosystem already has twenty-plus desktop pets ([whale-girl](https://github.com/vlln/whale-girl), assorted whales, a revived Clippy, Live2D companions…). Nearly all of them are **state mirrors**: agent thinks, pet thinks; task done, pet cheers. The deepest one, whale-girl, has XP levels and titles — but its body never changes, and it lives only in the Web GUI. None of them is a **raising game**: no hatching, no evolution stages, no "how you work decides what it becomes." dsh-digipet fills that square — a first-generation-V-pet growth loop hosted in your harness and fed by your actual work. Overfeeding makes it drowsy (above 90% fullness, XP gain drops to 15%) — a thematically honest anti-grind valve. **But veterans know: never press evolve on a stuffed belly.** ## How it works The whole plugin is **four event taps and one slash command**: | Hook | Feeds | |---|---| | `agent/turn-stopping` | +5 XP per completed turn | | `agent/inbox/claimed` | +2 XP per user message (feeds Bond) | | `tools/result` | +3 XP per tool call, classified by tool name into Forge or Lore; failures feed Grit | | `agent/error` | +4 XP per error (feeds Grit) | Thresholds: 30 / 120 / 500 / 1800 / 6000 / 16000 XP. Evolution takes the dominant stat of the window since the last evolution; the window then resets. The save lives at `$DSH_HOME/digipet/state.json`, written the same way the official JSON storage backend persists (temp file + fsync + atomic rename), throttled to one write per 1.5 s no matter how busy the agent gets. **DSH's core invariant is "model-visible means logged" — this plugin's answer is to show the model nothing at all.** No registered tool (tool schemas are a per-request token tax), no `agent.inject()`, no session events. The pet exists only in command result cards and contributes zero bytes to every model request. ## Trust stance - **Reads**: only its own save file. It never reads your code or your conversation — the event taps use only *what kind of thing happened*; message and tool contents never touch the save. - **Writes**: only `$DSH_HOME/digipet/state.json`. - **Network**: none. - **Model surface**: none. Zero token overhead; provider KV caches are untouched. - **Blast radius**: every listener body is wrapped in try/catch and the command handler has its own error floor — a stumbling pet cannot veto, rewrite, or delay real work. All hooked events are notification-mode (`emit`/`serial`). ## Known limitations - One pet per DSH home; every profile, session, and subagent on the machine shares and feeds it (feature and limitation). - Concurrent dsh processes race the save last-writer-wins — the same single-process stance as the official JSON backend. - Tool classification is a name heuristic (`write`/`edit`/`shell` → Forge; `read`/`grep`/`search` → Lore); oddly named third-party tools count as neutral chow. - The collapsed conversation row flattens the art to one line — click the card for the full monospace version (same interaction as DSH's tool rows). - Thresholds and the diet are deliberately not configurable: changed numbers would leave the dex and old saves speaking different languages. ## Verification record Verified on dsh `0.1.0-rc.6` (macOS, web profile): 1. Installed via `dsh plugin --profile web add `; the digipet layer appears in `--dump-config`; 2. `dsh web` boots clean; 3. In a real browser: `/pet hatch` renders the egg card (monospace, newlines preserved) → real events feed it to 30 XP → `/pet evolve` hatches Bitpop; 4. With no API key, plain messages still produce real events — the save matches the diet line by line; 5. A crafted 0.1.x save (glitch-line junior) was loaded across a restart: it migrated automatically onto the new roster with name, stats and journal intact; 6. 42 unit/integration tests (`node --test`) covering the pure logic core, a faked Cordis context, the stray-evolution arc, and migration. ## Homage and boundaries The roster's silhouettes honor first-generation V-pet raising canon — the skull-helmed dino arc, the cyborg retrofit, the winged guardians, the network virus, and *that slug you get for raising it wrong*. "Digimon" is a trademark of Bandai Namco; this project is unaffiliated, and all names, art and copy are original with no official assets. ## License MIT