--- sidebar_position: 11 title: "Pets (Petdex Mascots)" description: "Adopt an animated mascot that reacts to agent activity across the CLI, TUI, and desktop app" --- # Pets Hermes can show an animated **pet** — a small mascot sprite that reacts to what the agent is doing (idle, running a tool, thinking, finishing, failing) across the **CLI**, **TUI**, and **desktop app**. Pets come from the public [petdex](https://github.com/crafter-station/petdex) gallery. Pets are purely cosmetic. They have **no effect on prompt caching, tokens, or the agent's behavior** — the sprite is a display concern only. The feature is **off by default** and stays dormant until you install and select a pet. ## How it works - Pets are installed into your profile's `pets/` directory (`/pets//`), so each [profile](../profiles.md) keeps its own set. - Selecting a pet writes `display.pet.slug` and `display.pet.enabled` to `config.yaml` — nothing is stored as a secret or env var. - Each surface watches the activity it already tracks and maps it to one of six animation states. The mapping lives in one place so every surface behaves the same: | Agent activity | Pet state | | --- | --- | | A tool/turn just failed | `failed` | | A plan finished (all todos done) | `jump` (celebrate) | | A turn finished cleanly | `wave` | | A tool is executing | `run` | | The model is thinking/reading | `review` | | Turn in flight (unspecified) | `run` | | Blocked on you (a clarify/approval prompt is open) | `waiting` (falls back to `idle` on legacy 8-row sheets) | | Nothing happening | `idle` | ## Rendering In the terminal (CLI/TUI), Hermes renders the sprite at full fidelity when your terminal supports a graphics protocol (**kitty**, **Ghostty**, **WezTerm**, **iTerm2**, or **sixel**). Otherwise it falls back automatically to a truecolor Unicode **half-block** rendering. Inside a pipe or redirect (no TTY), terminal rendering is disabled by design. The desktop app draws the pet as a floating sprite on a canvas and toggles it from **Settings → Appearance**. ## Quick start (CLI) ```bash # Browse the gallery (filter by substring) hermes pets list hermes pets list cat # Install a pet and make it active in one step hermes pets install boba --select # Preview / animate it in your terminal (Ctrl+C to stop) hermes pets show # Check your setup hermes pets doctor ``` ## `hermes pets` commands | Goal | Command | | --- | --- | | Browse the gallery | `hermes pets list [query] [--limit N]` | | List installed pets | `hermes pets list --installed` | | Install a pet | `hermes pets install [--select] [--force]` | | Set the active pet | `hermes pets select [slug]` (omit slug for a picker) | | Resize the pet everywhere | `hermes pets scale ` (e.g. `0.5`, clamped 0.1–3.0) | | Preview/animate | `hermes pets show [slug] [--state ] [--cycle] [--once] [--mode ] [--scale ]` | | Disable the pet | `hermes pets off` | | Remove an installed pet | `hermes pets remove ` | | Diagnose setup | `hermes pets doctor` | `hermes pets show` flags: - `--state` — play a single state (`idle`, `wave`, `run`, `failed`, `review`, `jump`). - `--cycle` — cycle through every state. - `--once` — play once instead of looping. - `--mode` — override the render protocol (`kitty`, `iterm`, `sixel`, `unicode`, `auto`). - `--scale` — override the on-screen scale (`0` = use config). ## `/pet` slash command Inside the CLI and TUI you can manage the pet without leaving the session: - `/pet` — toggle the pet on/off (adopts the first installed pet if none is active). - `/pet list` — browse the gallery. - `/pet scale ` — resize the pet everywhere (e.g. `/pet scale 0.5`). - `/pet ` — adopt a specific pet. - `/pet off` — disable the pet. In the TUI, `/pet list` opens an interactive picker overlay; in the desktop app it opens the Cmd+K pet palette. ## Desktop app In the desktop app you can manage the pet two ways: - **Cmd+K → "Pets…"** — browse, search, adopt, and toggle pets without leaving the keyboard (mirrors the theme picker). - **Settings → Appearance** — the same gallery plus a **size slider** that resizes the floating mascot live as you drag. Both adopt/toggle/resize the floating mascot in place — size changes apply instantly; adopting a new pet lights it up within a moment. ### Pop-out overlay **Shift-click** the floating pet to pop it out into its own transparent, always-on-top desktop window. Out there it stays visible while Hermes is minimized (Codex-style), so a glance tells you what the agent is doing. Gestures once it's popped out: | Gesture | Action | | --- | --- | | **Drag** | Move the pet anywhere on screen, even outside the app. Its spot and in/out state persist across restarts. | | **Single-click** | Open a mini composer to send a prompt to the most recent session — without surfacing the app. | | **Double-click** | Toggle the app window: minimize it if it's up front, restore it if it's hidden. | | **Shift-click** | Pop the pet back into the window. | | **Mail icon** | Appears only when a turn finished while you were away; click to raise the app on the most recent thread (and mark it read). | Only the popped-out pet shows a **speech bubble** (`working…`, `thinking…`, `your turn`, …) — in-window the app itself is the surface, so the pet stays quiet there. The overlay is a pure puppet of the in-app pet — it carries no separate gateway connection and never appears in the dock or app switcher. ## Configuration All settings live under `display.pet` in `config.yaml`: ```yaml display: pet: enabled: false # master on/off (true once you select a pet) slug: "" # active pet; empty = first installed render_mode: auto # auto | kitty | iterm | sixel | unicode | off scale: 0.33 # master size knob (relative to native 192x208 frames) unicode_cols: 0 # hard override for terminal width (0 = derive from scale) ``` - **`scale`** is the single master size knob. One number shrinks every surface: the desktop canvas scales its pixels by it, and the CLI/TUI derive their terminal column width from it. The half-block fallback clamps to a legibility floor — it can't shrink as far as true-pixel kitty/GUI rendering without turning to mush, so the same `scale` looks crisp under kitty but is floored in half-blocks. - **`render_mode: auto`** detects kitty/iTerm2/sixel and falls back to unicode half-blocks. Set it explicitly to force a protocol or `off` to disable terminal rendering while keeping the pet on the desktop. - **`unicode_cols`** pins the terminal column width independently of `scale`; leave it at `0` to derive width from `scale`. ## Troubleshooting Run `hermes pets doctor` — it reports: - the pets directory and which pets are installed, - `display.pet.enabled`, `display.pet.slug`, and the resolved active pet, - the configured `render_mode`, the detected terminal graphics protocol, and the effective mode for a TTY, - whether Pillow (used for sprite decoding) is importable. It prints `✓ ready` once a pet is installed, selected, enabled, and Pillow is available. Common gotchas: - A pet only shows once one is **installed AND selected** (`enabled: true`). - Inside a pipe/redirect (no TTY), terminal rendering is disabled by design. - The petdex npm CLI installs to `~/.codex/pets`; Hermes uses its own profile-scoped `/pets/` instead — install through `hermes pets`. ## See also - The [`petdex` skill](../skills/bundled/productivity/productivity-petdex.md) lets the agent install and switch pets for you on request.