# Hermes Digital Pet Plugin

`digital-pet` is an optional Hermes dashboard companion. It mounts a small bottom-right overlay named Signal, persists only minimal pet state, and observes Hermes activity without changing core agent behavior.

## Enable it

Copy the plugin into a Hermes profile, enable it, then start or restart the dashboard:

```bash
mkdir -p ~/.hermes/plugins
cp -a digital-pet ~/.hermes/plugins/digital-pet
hermes plugins enable digital-pet
HERMES_PLUGINS_DEBUG=1 hermes plugins list --plain
hermes dashboard --host 127.0.0.1 --port 9119 --no-open
```

Verification target: `hermes plugins list --plain` should include an enabled `digital-pet` row. The dashboard plugin manifest mounts the companion in the global `overlay` slot; it does not add a visible sidebar tab.

## Summon, hide, and inspect Signal

Use the `/pet` slash command from a Hermes session:

```text
/pet
/pet summon
/pet hide
/pet wake
/pet sleep
/pet status
/pet click
```

Command aliases:

- `/pet`, `/pet summon`, `/pet show`, `/pet on` summon the pet.
- `/pet hide` and `/pet off` hide it.
- `/pet sleep` and `/pet quiet` put it in sleep mode.
- `/pet wake` wakes a sleeping pet or summons a hidden one.
- `/pet click` simulates the dashboard click interaction.
- `/pet status` returns the public state as JSON.

The dashboard also shows a small summon glyph when the pet is hidden. Click the glyph to summon Signal.

## Dashboard interactions

Signal has deliberately simple interactions:

- Click while hidden: summon Signal.
- Click while sleeping: wake Signal.
- Click while awake: trigger a short reaction message and mood/energy update.
- Hover over the pet for about one second: enter sleep mode.
- Move the pointer away before one second: cancel the hover-to-sleep timer.

Temporary modes such as `reacting`, `prompting`, and `waking` auto-complete back to `idle` after a short dashboard timer. The dashboard polls state every 30 seconds and sends events through `/api/plugins/digital-pet/event`.

## Sleep and off modes

Sleep and off are different states:

- Sleep mode (`sleeping`) keeps the pet enabled but quiet. Signal is visible, dimmed, recovers a little energy over time, and can be woken by click or `/pet wake`.
- Off/hidden mode (`hidden`, `enabled: false`) removes the companion from the overlay except for the small summon glyph. It suppresses messages and activity reactions until summoned again.

Use sleep when the operator wants Signal present but silent. Use hide/off when the operator wants the companion out of the way.

## What it stores

State is stored at:

```text
$HERMES_HOME/digital-pet/state.json
```

The file contains only bounded companion state: enabled flag, mode, previous mode, name, mood, energy, interaction timestamps, temporary message, message expiry, and revision. It must not store user prompts, model responses, tool outputs, secrets, tokens, private paths, or PII.

For isolated tests, override the path with:

```bash
export HERMES_DIGITAL_PET_STATE=/tmp/digital-pet-state.json
```

## Extension points

Future maintainers can safely adjust basic behavior in these files:

- `state.py`
  - `DEFAULT_NAME`: default companion name.
  - `MODES` and `MOODS`: allowed state labels.
  - `MESSAGE_COOLDOWN_SECONDS`: minimum time between automatic messages.
  - `CLICK_LINES` and `PROMPT_LINES`: built-in message text used by the current state machine.
  - `apply_event(...)`: transitions for summon, hide, hover-hold, sleep, wake, click, idle ticks, prompt ticks, session start, and tool-call results.
  - `state_path()`: state location and `HERMES_DIGITAL_PET_STATE` override.

- `commands.py`
  - `_COMMAND_EVENTS`: slash command aliases and their mapped state-machine events.
  - `handle_pet_command(...)`: command JSON response shape and usage text.

- `__init__.py`
  - Registered slash command: `/pet`.
  - Registered observer hooks: `on_session_start` and `post_tool_call`.
  - Tool result failure detection. Keep this fail-open and non-invasive.

- `dashboard/plugin_api.py`
  - FastAPI routes mounted under `/api/plugins/digital-pet/`.
  - Current routes: `GET /state` and `POST /event`.

- `dashboard/dist/index.js`
  - Overlay component, polling interval, click behavior, hover-to-sleep timer, transition auto-complete timer, face selection, and button labels.

- `dashboard/dist/styles.css`
  - Position, size, colors, motion, sleeping opacity, speech bubble, mobile placement, and reduced-motion behavior.

- `dashboard/manifest.json`
  - Dashboard plugin metadata, hidden tab declaration, `overlay` slot registration, JS entry, CSS entry, and API file.

- `digital-pet-content.json`
  - Machine-readable personality/content source from the design task. It contains additional message buckets, tone rules, cooldown rules, state-effect notes, and the lightweight visual placeholder. The current implementation does not yet consume the full file automatically; copy selected lines or wire it into `state.py` deliberately.

Proceed carefully when changing state names or API response fields. The dashboard, tests, and persisted state all depend on those contracts.

## Known limitations

- The companion is a lightweight dashboard overlay, not a full animated character system.
- Message selection in `state.py` currently uses small hard-coded line sets; it does not yet load all buckets from `digital-pet-content.json`.
- Hover-to-sleep is pointer-based. Keyboard users can use `/pet sleep`; focus does not start the sleep timer.
- State is local to one Hermes profile through `$HERMES_HOME`.
- The pet reacts only to `on_session_start` and `post_tool_call` hooks today.
- Automatic activity reactions are rate-limited and intentionally sparse.
- Dashboard changes require a dashboard refresh or restart after plugin updates.

## Suggested next enhancements

Keep enhancements within the lightweight companion concept:

1. Load message buckets from `digital-pet-content.json` with id-based last-message suppression.
2. Add a small settings route for name, enabled-by-default, and reduced chatter frequency.
3. Add keyboard-accessible sleep/wake controls in the overlay.
4. Add a simple idle/prompt tick from the dashboard or a safe Hermes hook without creating noisy background work.
5. Add tests for dashboard API route behavior and command aliases.
6. Add a privacy guard test proving persisted state never includes tool arguments, outputs, prompts, or secrets.
7. Replace the placeholder face with a slightly richer CSS-only avatar while preserving reduced-motion support.

## Safety rules for maintainers

- Keep the hooks observer-only. The pet must not block or mutate Hermes tool execution.
- Fail open on plugin errors. A broken companion must not break the station.
- Persist only companion state. Never persist raw Hermes content or credentials.
- Prefer small, deterministic transitions over hidden background automation.
- Verify with `hermes plugins enable digital-pet`, `hermes plugins list --plain`, and the plugin tests after modifying behavior.
