跳到主要内容

Pets

VibeOS 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 (<VIBEOS_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), VibeOS 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)
vibeos pets list
vibeos pets list cat

# Install a pet and make it active in one step
vibeos pets install boba --select

# Preview / animate it in your terminal (Ctrl+C to stop)
vibeos pets show

# Check your setup
vibeos pets doctor

vibeos pets commands​

GoalCommand
Browse the galleryvibeos pets list [query] [--limit N]
List installed petsvibeos pets list --installed
Install a petvibeos pets install <slug> [--select] [--force]
Set the active petvibeos pets select [slug] (omit slug for a picker)
Resize the pet everywherevibeos pets scale <factor> (e.g. 0.5, clamped 0.1–3.0)
Preview/animatevibeos pets show [slug] [--state <s>] [--cycle] [--once] [--mode <m>] [--scale <f>]
Disable the petvibeos pets off
Remove an installed petvibeos pets remove <slug>
Diagnose setupvibeos pets doctor

vibeos 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 VibeOS 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).

The popped-out pet shows a speech bubble with status lines (working…, thinking…, your turn, …) and — after you message it from the mini composer — a truncated preview of the assistant's text reply (full answer stays in the chat transcript). In-window the pet stays quiet for status chatter, but the same reply preview appears above the mascot once an answer lands.

Selecting a pet also creates a matching Avatar profile under <VIBEOS_HOME>/avatars/ (id defaults to the pet slug). Avatars are the conversational binding — full guide: Avatars (persona, voice, soft memory, talking-head, /avatar commands).

Short summary: optional persona overlay + pet visual + TTS voice preset + soft memory_scope (avatar:<id> by default; shared to opt out). display.avatar.auto_speak gates TTS / talking-head while the pet is visible.

Quick switch

SurfaceHow
Desktop Cmd+KAvatars… — browse and select
Desktop / CLI / gateway/avatar, /avatar list, /avatar <id>, /avatar none
SettingsAppearance → Pet — bind persona + voice + talking-head mode

Create or patch from chat (same on desktop, CLI, and messaging):

/avatar create boba pet=boba personality=concise voice=edge:en-US-AriaNeural
/avatar update boba talking-head=skill memory=shared
/avatar boba
/avatar none

On messaging platforms, /avatar also updates the live session: soft memory_scope on the running agent, ephemeral persona when the avatar has one, and a one-shot note on the next turn (same cache-safe pattern as /model). Classic CLI does the same for memory scope (and rebuilds the agent when the persona overlay changes).

Fields: pet=, name=, personality=, voice=, memory= (shared or leave default), talking-head= (off | wave | skill), portrait=.

From the popped-out pet, open the mini composer and use the mic to speak; completed replies are spoken back (using the avatar voice when set) while the overlay is active.

Talking-head render (optional)​

display.avatar.talking_head controls the optional render layer (not a core tool):

ModeBehavior
wave (default)Pet plays a celebrate/jump animation while avatar TTS speaks
offNo extra render
skillLocal talking-photo: TTS + ffmpeg still mux (avatar.talking_head.render); escalate to video_generate via the optional skill when you want motion

In skill mode, leave the portrait path blank to auto-crop the pet's idle frame into avatars/<id>-portrait.png. Set an explicit local image path when you want a custom face. Settings → Pet also has Regenerate from pet (avatar.portrait.regenerate) after you change the spritesheet.

Install the skill when you want clips:

vibeos skills install official/creative/talking-head

Vendor lip-sync SaaS (HeyGen, D-ID, …) stays out of the VibeOS core tree — publish as a standalone plugin under ~/.vibeos/plugins/ if you need those APIs. Scaffold:

bash scripts/scaffold-talking-head-vendor-plugin.sh

See the optional skill reference optional-skills/creative/talking-head/references/standalone-vendor-plugin.md.

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 vibeos 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; VibeOS uses its own profile-scoped <VIBEOS_HOME>/pets/ instead — install through vibeos pets.

See also​

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