Loomi Pet Helper

Helper to manage Loomi Pet state and appearance in Claude Code.

Sby Skills Guide Bot
DevelopmentIntermediate
007/22/2026
Claude Code
#openloomi#pet#state#sprite#customization

Recommended for


name: openloomi-pet description: "OpenLoomi Pet sprite & state helper for Claude Code. Use when the user wants to change their Loomi Pet state, switch theme, drop in a custom character, override individual sprites, or ask Claude to mirror its lifecycle onto the pet. Triggers: pet state, /openloomi:pet, set pet, loomi pet, pet to happy, pet to working, pet to thinking, fox sprite, capybara sprite, custom pet theme, pet-custom, pet-config, override pet sprite." allowed-tools: Bash(node ${CLAUDE_PLUGIN_ROOT}/scripts/loomi-bridge.mjs *)

OpenLoomi Pet Sub-skill

The Loomi Pet has 9 universal state names. The plugin ships the fox (loomi-*) sprite set for branding; the OpenLoomi runtime's state-resolution watcher renders the matching sprite for whichever theme you have active (fox or capybara, or any folder under ~/.openloomi/pet-custom/). State set:

| State | When to use | |---|---| | happy | A task just completed successfully | | idle | Loomi is waiting for the next loop tick (watcher-only — do not set from Claude) | | juggling | Multiple sub-agents are running | | needsinput | Permission prompt / elicitation dialog visible | | presenting | Fresh decision requires the user's review (watcher-only — do not set from Claude) | | sleeping | Local hour outside 6–22 with no pending work (watcher-only — do not set from Claude) | | sweeping | User dismissed a card just now (watcher-only) | | thinking | Between steps, awaiting LLM response | | working | A tool call is in progress (PreToolUse hook fires this) |

Available commands

  • node ${CLAUDE_PLUGIN_ROOT}/scripts/loomi-bridge.mjs pet <state> — synchronous, returns JSON; use only when the user explicitly asks.
  • Hooks call state <name> automatically (fire-and-forget, 2s timeout).

Sprite set is hardcoded in the bridge — invalid state names are rejected before any HTTP call. The endpoint POST /api/pet/state may not yet exist in the target OpenLoomi runtime; the bridge falls back to "would have set state to X — pending OpenLoomi endpoint" without raising an error.


Help the user customize their pet's appearance

The bridge only drives the state — sprite overrides and theme folders are file-based and live outside the plugin. When the user asks to "change the pet's look" or "add a custom character", walk them through the file system. Do not try to write pet-config.json from the bridge; the bridge has no such command and the runtime's file watcher does the work.

Decision tree

  1. "I just want the other built-in" → right-click Loomi → Theme → Fox / Theme → Capybara. Persisted in ~/.openloomi/pet-config.json under activeTheme. Long-press (~600 ms) is the fallback if contextmenu is swallowed by the host.
  2. "I want my own character" → drop a folder at ~/.openloomi/pet-custom/<name>/ with PNGs named after the states. The watcher auto-discovers it within ~250 ms and the theme appears in the menu.
  3. "I want to change just one sprite" → edit ~/.openloomi/pet-config.json's overrides map. Wins over both built-ins and custom-theme sprites for the matching (theme, state) pair.
  4. "I want to make my theme the default" → set activeTheme to the custom theme's folder name.

What the bridge can and can't do

| User intent | Bridge role | | ------------------------------------------ | -------------------------------------------------------------------------- | | Flip to happy mid-task | /openloomi:pet happy — yes | | Switch fox ↔ capybara | No — that's a menu action or pet-config.json edit; do not try the bridge | | Add a custom character | No — direct them to ~/.openloomi/pet-custom/<name>/ and the file watcher | | Override a single sprite | No — direct them to ~/.openloomi/pet-config.json's overrides map | | Diagnose "the pet isn't switching themes" | Direct them to the troubleshooting section in pet docs | | Drive the pet from their own tool | Direct them to POST /api/pet/state — see Pet API |

Filename conventions to communicate

When guiding the user through a custom theme, surface these conventions up-front:

  • PNG only. .gif, .webp, .apng, .lottie are silently ignored.
  • Bare or prefixed names both work. idle.png, loomi-idle.png, capybara-thinking.png, my-pack-sweeping.png all normalize correctly (case-insensitive).
  • One recognizable state PNG is enough. The folder is registered as a theme as soon as it has ≥1 normalized state stem; missing states fall through to the active theme's idle sprite.
  • Hidden / dot-prefixed folders are ignored. .git, .DS_Store etc.

Override JSON shape to communicate

The overrides map is camelCase on the wire — activeTheme, customThemesDir. Snake_case keys silently no-op the assignment (a unit test in the runtime pins the contract). Use the exact shape:

{
  "version": 1,
  "activeTheme": "fox",
  "customThemesDir": "~/.openloomi/pet-custom",
  "overrides": {
    "fox": {
      "idle": "/absolute/path/to/my-fox-idle.png"
    }
  }
}

Absolute paths only — the runtime routes them through tauri::convertFileSrc, so relative paths and ~/ prefixes will not resolve.

Common pitfalls to surface

  • The folder doesn't show up — usually a missing or mis-named state PNG. Run them through the filename convention table.
  • Override doesn't apply — host log line [loomi-pet/theme] failed to parse ~/.openloomi/pet-config.json means the JSON itself is malformed and defaults loaded. Host log line [loomi-pet/theme] failed to read <path>: <io error> means the path doesn't resolve.
  • Theme menu tick is wrong / stuck — almost always a camelCase vs snake_case wire-format mismatch. The widget reads activeTheme, not active_theme.
  • sleeping / sweeping rejected by /api/pet/state — those are watcher-only vocabulary; the runtime returns 400 invalid_state. Do not POST them from your tool.

What NOT to do from Claude

  • Do not try to call POST /api/pet/state with sleeping or sweeping. The API rejects them; the watcher owns them.
  • Do not try to write pet-config.json from the bridge. The bridge has no command for it; the file watcher owns updates.
  • Do not invent new state names. CAPYBARA_STATES rejects them before any HTTP call.
  • Do not claim support for non-PNG sprite formats. The asset pipeline is static PNG only.
  • Do not say "I'll set up your custom theme for you" if you can only walk them through the file system. The watcher does the work; you guide.

See also

Related skills