跳到主要内容

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 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 (<HERMES_HOME>/pets/<slug>/), so each profile 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 activityPet state
    A tool/turn just failedfailed
    A plan finished (all todos done)jump (celebrate)
    A turn finished cleanlywave
    A tool is executingrun
    The model is thinking/readingreview
    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 happeningidle

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)

# 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

GoalCommand
Browse the galleryhermes pets list [query] [--limit N]
List installed petshermes pets list --installed
Install a pethermes pets install <slug> [--select] [--force]
Set the active pethermes pets select [slug] (omit slug for a picker)
Resize the pet everywherehermes pets scale <factor> (e.g. 0.5, clamped 0.1–3.0)
Preview/animatehermes pets show [slug] [--state <s>] [--cycle] [--once] [--mode <m>] [--scale <f>]
Disable the pethermes pets off
Remove an installed pethermes pets remove <slug>
Diagnose setuphermes 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 <factor> — resize the pet everywhere (e.g. /pet scale 0.5).
  • /pet <slug> — 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:

GestureAction
DragMove the pet anywhere on screen, even outside the app. Its spot and in/out state persist across restarts.
Single-clickOpen a mini composer to send a prompt to the most recent session — without surfacing the app.
Double-clickToggle the app window: minimize it if it's up front, restore it if it's hidden.
Shift-clickPop the pet back into the window.
Mail iconAppears 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:

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 <HERMES_HOME>/pets/ instead — install through hermes pets.

See also

  • The petdex skill lets the agent install and switch pets for you on request.