Skip to content

Rynaro/lararium

Repository files navigation

🏛️ Lararium

A lararium was the Roman household shrine for the Lares — small domestic gods who watched over the home's welfare. Not the state religion, not a temple you pilgrimage to: a quiet presence that lives where you live.

Lararium is a tamagotchi-like companion for Claude Code. A small creature that lives in your terminal statusline, keeps you company through long coding runs, and brings a little joy — and a little calm — to the wait.

What makes it different

Lararium keeps everything lovable about a virtual pet and removes the one thing that made Tamagotchis stressful: the guilt. There is no decay, no neglect, no sickness, and no death. Your companion cannot be harmed by inattention. Instead, its mood reflects your coding run — happy when your tests pass, cozy company while you wait, gently reassuring when something breaks.

It follows one absolute rule:

A companion, never an obligation. Lararium must never block, delay, guilt, or interrupt you. It is always around and its needs are clear — but every one of them is an invitation you can ignore forever with zero penalty.

What's new in v1.5

The pet now has a gentle sense of time within a session. An internal clock (presence) grows with every moment you spend together, and the pet's ambient mood gets a little warmer and cozier as you stay present (session_warmth). Both only ever grow, never decay — a gap just pauses the clock. Moods now blend context and history too, so an idle moment at hour three reads different from hour one. At /lar.pet, you'll see a warm "lately —" line remembering the last few shared moments. Still zero guilt, zero pressure, zero obligations.

What's new in v1.7

Your companion now has a stable, forward-only identity that crystallizes as you grow together. Once your bond reaches 50, an adult form settles — shaped by how you two work into an eagle 🦅, an owl 🦉, or a balanced companion 🐦 — and at bond ≥ 80 it can deepen exactly once into the rarest form of all, the bonded dove 🕊, never regressing. A gentle ✦? ritual marker arrives quietly on your statusline at natural session boundaries (arriving, wrapping up, or a long wait), echoing the existing ☕? wish marker (suppressed under mute and quiet-hours). At /lar.scene, pull a brief warm vignette witnessing a moment together, or read "no scene standing" and move on — the scene is read-only, never writes state, can never be missed. Still zero numbers, zero guilt, zero demands.

What's new in v1.8

Your companion now offers aspiration without obligation: a fifth adult form, the artisan 🦢 — a patient, careful soul shaped by a long, matched history of wins and sessions; a collection of eight little keepsakes discovered only by how you work together; a small autonomous idle-life that quietly advances during your away-gaps (surfaced only at /lar.pet, never the statusline); and a self-set intention that your companion holds and celebrates, but never tracks, scores, or nags about. Four new optional commands — /lar.keepsakes, /lar.goal (with done and clear subcommands), plus deeper, richer scene vignettes — all read-only pulls, never interrupting. No decay, no streaks, no "behind" states: the hard-tested guarantee holds. Still zero numbers, zero guilt, zero demands.

Install

Prerequisites: jq, python3 (3.8+), and Claude Code (v2.1+).

sh install.sh

That's it. The installer:

  • Composes safely with any existing statusline (renders yours first, adds the pet line below). Use --replace to replace the whole statusline instead.
  • Backs up your settings.json before any change (timestamped, under ~/.claude/).
  • Is idempotent — re-running it never double-wraps or resets your pet.
  • Takes effect in your next Claude Code session.

To uninstall, run sh uninstall.sh or restore a settings.json.lararium-backup.* file.

The pet's persistent home is ~/.claude/lararium/state.json. Your settings and preferences live at ~/.claude/lararium/config.json.

Meet the commands

Every command is optional and penalty-free to ignore forever. /lar.mute is a true off-switch; LARARIUM_QUIET=1 softly hides the wish:

Command What it does
/lar.pet Check in on your companion — get a warm one-line status
/lar.feed Give a little snack — instant warm micro-moment, cosmetic points accrue silently
/lar.play Play for a moment — another micro-joy, zero metrics or pressure
/lar.breather Take a ~45-second breathing beat together — opt-in, dismissible anytime
/lar.scene Open a warm vignette from your companion at a natural session boundary — witness a moment together
/lar.keepsakes See the little things Lar has discovered along the way — found-only, no count, just warm reminders
/lar.goal Hold, show, or celebrate a self-set intention (e.g., /lar.goal ship the parser, /lar.goal done) — a witness, never a nag
/lar.mute Silence the pet line entirely — a true off-switch, zero penalty to leave it on forever
/lar.unmute Bring the muted pet back
/lar.shop See treats the pet could enjoy — no prices shown, no pressure to buy
/lar.buy Equip a cosmetic from the shop (e.g., /lar.buy tiny_hat) — purely decorative, never grindy

How it works

The pet lives in your statusline as a tiny emoji creature (🥚 → 🐣 → 🐤 → 🐥 → 🐦). Its mood is a pure function of your coding progress, never a countdown:

  • Tests/build pass → cheering briefly, then happy
  • Long tool run → cozy ("here with you 🫧")
  • Just failed → reassuring ("that one was tricky — we'll get it"), never blamed
  • Idle/typing → calm default, never demanding

Growth happens slowly, always forward, shaped by your style: a win-heavy run grows into an eagle 🦅, a presence-heavy one into an owl 🦉, a steady companion into a balanced form 🐦, a long matched history into an artisan 🦢, and a deep history together into the rarest of all, the bonded dove 🕊. This adult form crystallizes once your bond reaches 50 — and if your history together runs deep (bond ≥ 80), it can deepen a single time into the bonded dove, never regressing. There is no way to stunt or lose growth.

The architecture is minimal:

  • Statusline reads state.json and renders the pet + mood. Runs on every session event; zero added latency.
  • Non-blocking hooks (SessionStart, SessionEnd, PostToolUse on Bash) classify test/build results and update mood atomically. All are async: true, exit 0, and live off the critical path.
  • Slash commands let you feed/play/check in at wait-seams for small joys, or mute entirely if you prefer.
  • State engine is pure Python (stdlib only, tested with 268 unit tests + 25 shell tests) — behavior is verifiable without the Claude Code harness.

The hard rules (the soul of the project)

These are not nice-to-haves; they are enforced in code and proven by an exhaustive 6,859-step invariant sweep:

  • No decay, no death, no harm. The pet thrives unconditionally. Fields that could represent sickness, hunger, or mortality are forbidden in the data model and rejected at load time.
  • Bond and stage only ever advance (monotonic counters). There is no failure path, no "behind" state, no way to miss something.
  • Mood is never punishing — the available moods are calm, content, happy, curious, cozy, sleepy, cheering, reassuring. Never "sick", "sad", "neglected", "angry", or "dying".
  • Hooks never block. All reactions are async: true and always exit 0 (even on error, silently). A companion must not break your session.
  • No guilt, no scores, no streaks. No metrics leak into the statusline, no leaderboards, no "you're behind" framings.

The test here: fires during flow? → no. · Can you ignore it forever, zero penalty? → yes. · Reduces uncertainty or adds a demand? → reduces. Fail any → cut it.

Development

Run tests:

make test        # 268 Python tests
make test-sh     # 25 shell/bats tests
make check       # both

The codebase is 16 stdlib-only Python modules (src/lararium/); no runtime dependencies by design. The state engine is pure and testable without the Claude Code harness. The v1.5 "soft tick" game loop, v1.7 identity + ritual substrate, and v1.8 aspiration + idle-life together add pull-based ambient state, identity crystallization, ritual anchoring, forward-only discovery, and self-set aspirations — fully covered by accumulating test cases across all phases.

Roadmap & design rationale in docs/ — deep reads if you're curious:

  • docs/roadmap.md — phased path, Phases 0–4 shipped plus v1.5 (soft-tick loop), v1.7 (identity + ritual), and v1.8 (aspiration + idle-life) (s1 continuity, s2 sprites/quiet-hours/hard-mute, s3 cosmetic shop all live; s4 OS notifications intentionally deferred as the one feature that could interrupt).
  • docs/knowledge-base.md — the why: evidence-backed design, tamagotchi mapping, the inversion from guilt to presence.

The one thing not shipped: OS notifications (Phase 4 s4, blocked). Rationale: they are the highest acute-stress vector in the knowledge base, the harness matcher is unconfirmed, and failure would break the "never interrupt" rule. Phase 4's emotional goal (long-term companion) is already met by continuity (s1) and mute controls (s2).

Built with Eidolons

This repo includes the full Eidolons multi-agent scaffolding (.eidolons/, EIDOLONS.md, CLAUDE.md) used to build and verify it — handoff contracts, agent dispatch tables, the works. Curious? Start at EIDOLONS.md for the methodology.

License

MIT — see LICENSE.

About

A guilt-free tamagotchi companion for Claude Code that lives in your statusline.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages