gitgotchi
v0.1.1
Published
A codebase Tamagotchi that lives in your terminal.
Downloads
345
Maintainers
Readme
🥚 Gitgotchi
A codebase Tamagotchi that lives in your terminal. Its health, mood, and looks are a direct reflection of the git repo it lives in. Fresh commits feed it. Failing CI makes it sick. Stale branches make it lonely. Climbing coverage makes it grow up.
It is an ambient status toy, not a linter. It never blocks, never exits non-zero, never nags. The pet's face is the only feedback.
npx gitgotchiContents
Quick start
npx gitgotchi # meet your pet (one-shot status)
npx gitgotchi watch # live view, refreshes every 60s (min 10 via -i)
npx gitgotchi card # export a share card SVG (add --png if you have sharp)
npx gitgotchi init # name your pet
npx gitgotchi rename Pixel
npx gitgotchi --json # machine-readable state, for status barsZero config. Runs in any git repo using only local signals (git + grep) in a few seconds. CI and coverage are automatic bonuses when they're available.
Install options: npx gitgotchi needs no install. To keep it around,
npm i -g gitgotchi (then gitgotchi anywhere) or npm i -D gitgotchi in a
project. Requires Node ≥ 20.
How your repo maps to your pet
Four vitals, each a pure function of one kind of repo signal:
| Vital | Goes up when… | Goes down when… | | -------------- | ------------------------------------- | ----------------------------------------- | | ❤ health | CI is green, coverage is high | CI keeps failing, coverage is low | | 🍖 hunger | you commit often ("commits are food") | the repo goes quiet (starving at ~7 days) | | ✨ hygiene | few TODO/FIXME/HACK markers | markers pile up | | 👥 social | branches are fresh, work is pushed | branches go stale, work sits unpushed |
The lowest vital sets the mood — thriving, content, hungry, grubby,
lonely, sick, or critical — and the mood is the face Byte wears:
╭╮ ╭╮ ╭╮ ╭╮ ╭╮ ╭╮ ╭╮ ╭╮
╭┴┴──┴┴╮ ╭┴┴──┴┴╮ ╭┴┴──┴┴╮ ╭┴┴──┴┴╮
│ ^ ^ │ │ ◕ ◕ │ │ ◔ ◔ │ │ x x │
│ ◡ │ │ o │ │ ~ │ │ ~ │
╰─┬──┬─╯ ╰─┬──┬─╯ ╰─┬──┬─╯ ╰─┬──┬─╯
╵ ╵ ╵ ╵ ╵ ╵ ╵ ╵
thriving hungry grubby criticalLife stages
The pet grows as you keep showing up:
| Stage | Reached at | | ----- | ----------------------------------------- | | egg | birth | | baby | 3 check-ins | | kid | 20 check-ins and best coverage ≥ 50% | | adult | 100 check-ins and a green streak ≥ 10 | | elder | 365 days old |
Stages never regress. A "check-in" is any time you run gitgotchi.
How it works
One-directional data flow, with a hard wall between I/O and game logic:
collectors (I/O) → RepoSignals → engine (pure) → PetState → store + render- Collectors (
src/collectors/) gather signals — commit recency, dirty tree, branches, TODO grep, coverage files, optional CI. They never throw: any failure degrades tonullor a safe default. - The engine (
src/engine/) is 100% pure functions. The clock and RNG seed are injected, so the same repo state in produces byte-identical creature state out. This is why the whole game is testable without a filesystem. - State (
src/state/) is zod-validated and saved atomically (temp file + rename). Corrupt state is backed up to.bakand the pet starts fresh — never a crash, never a silent overwrite. - UI (
src/ui/) is Ink (React for the terminal); sprites are plain data, snapshot-tested. Non-TTY output falls back to a plain text block.
See docs/ARCHITECTURE.md for the full tour and docs/manual-tests.md for a hands-on walkthrough of every mood and stage.
The share card
gitgotchi card renders a 1200×630 SVG of your pet + stats — the thing you post.
It's deterministic (same state → identical bytes) and needs no browser. Add
--png to rasterize via sharp if you have it installed; otherwise you get the
SVG and a friendly note.
FAQ
Does it send my data anywhere? No. No account, no server, no telemetry.
State lives in .gitgotchi/state.json (added to your .gitignore automatically).
Can it block or fail my build? Never, by design. It always exits 0 and never lectures. Guilt is delivered exclusively through sad eyes.
Does it need a GitHub token? No. CI status is a progressive enhancement — if
a token is available (gh auth token or GITHUB_TOKEN) it reads Actions status;
otherwise it just uses local signals.
Why is my pet already grubby? It counts TODO/FIXME/HACK markers in tracked files. That's not a judgment — Byte just notices.
Development
npm install
npm test # vitest
npm run typecheck
npm run lintTDD is the workflow and the engine holds a 100% line-coverage gate. See CONTRIBUTING.md for conventions and the milestone process.
License
MIT © David Sellam
