01
Built in a day, by conversation
Every commit in the first version is dated 2 December 2025, and 0.1.0 was on PyPI the same day. It started in Kiro and was built entirely through conversation, working from written specs: five documents, including a master spec of more than a thousand lines, plus a “steering” document that fixed the voice (warm and encouraging, never critical) and the look.
Most of the decisions were made in that conversation. The theme moved from spooky to cozy, more Stardew Valley than horror: a “companion”, not a pet, with moods like “tired” instead of “dying”. Evolution was sped up so you see a change within two or three commits instead of ten. Windows needed its own fixes for emoji in the terminal and backslashes in hook paths.
02
It worked, until I read it
The core loop worked from day one: commit, the companion eats, the box redraws. That's exactly why the rest went unnoticed. When I came back to it ten months later and reviewed it properly, the list of things that were quietly wrong was long:
When you delegate, comprehension becomes a separate task you have to deliberately choose to do.
- The package installed into Python as a module literally named `src`. Any project with its own `src/` package broke the hook with an import error.
- `gitgotchi uninstall` removed a comment line from the hook and left the command behind, so the companion kept eating after you'd removed it.
- The angel form was unreachable. Quality went up by one point per commit, whatever the commit was like, so the score that decides angel or demon never meant anything.
- Running a command from a subfolder created a second, empty companion there, and the companion's database sat in the repository, ready to be committed by accident.
- Stories used a Claude model that had been retired, `.env` files were never loaded although python-dotenv was a dependency, mood only updated when you committed, the same commit could be counted twice, and `gitgotchi version` didn't report the real version.
03
Rebuilt for the commits agents write
These days AI agents write a lot of the commits, so 0.3.0 rebuilt GitGotchi around that. It recognises agent commits from their Co-Authored-By trailers, “Generated with” footers and bot accounts. They feed the companion like any other commit, but they also fill a possession meter, and once agents have written at least half of six or more commits, your companion becomes a Poltergeist.
Every form became a real 3D model: a signed distance field, raymarched with NumPy, cel-shaded and outlined into pixel art, and drawn in the terminal with true-color half blocks. `gitgotchi haunt` is a live pane you keep open next to the terminal where you or your agent are working. Every commit gets a reaction, agent commits glitch the screen, and evolutions play out as they happen.
One detail came straight from working with agents: when git isn't attached to a terminal, which is how an agent runs `git commit`, the hook prints one line instead of the whole pet, so it doesn't flood the agent's context. `gitgotchi adopt` raises a companion on the history a repo already has, reading the whole log in one git call, and `gitgotchi card` draws a shareable 1200×630 image entirely in NumPy, pixel font included.
04
The audit after the release
0.3.0 shipped, and the next thing I did was review it the way I'd reviewed version one. 0.3.1, published the same day as the review, fixed what it found. Two of the findings mattered most:
A .env file in a repository you just cloned is somebody else's input.
- A security hole. GitGotchi loaded every variable from a repository's `.env` file, so a repository you'd just cloned could inject git settings and run commands during `gitgotchi seance`. It now reads only `ANTHROPIC_API_KEY`.
- It accused people of being AI agents. Anyone with a co-author at an Anthropic, OpenAI or Gemini address, anyone named Cline, and any message that merely mentioned ChatGPT counted as an agent commit. Detection now matches agent noreply addresses and bot accounts, and a footer only counts when a line starts with “Generated with”.
- Agents often commit from git worktrees, so the companion moved into `.git/gitgotchi/`, where every worktree of a repository shares one. Every write now takes the lock up front, so the hook, `adopt` and `haunt` can't lose each other's updates.
- The hook is quoted for paths with spaces, sits before any `exit` in a hook you already had, refuses to edit hooks that aren't shell scripts, and doesn't count an amended commit twice.
05
Living in someone else's repository
A tool that installs itself into other people's repositories has to leave them as it found them. The hook is a clearly marked block that sits alongside any hook you already have, follows git's `core.hooksPath` setting and worktrees, and upgrades older hooks in place. Uninstalling removes only GitGotchi's block, and the companion's database lives inside `.git/`, where it can never be committed.
Shipping is automated now: 116 tests run on five Python versions on Linux plus macOS and Windows, and a version tag publishes to PyPI after checking that the tag matches the code.
0.4.0 made it fit around how people already work. `gitgotchi-statusline` puts one line about your companion in Claude Code's status line, tmux or Starship, using only the standard library so it runs in about 50 ms. `gitgotchi config` chooses how much the hook prints after each commit, `gitgotchi doctor` checks git, the hook, the database and the terminal and suggests a fix for each problem, and there's a README badge and an animated card.
Reviewing 0.3.2's sharper sprites, I found that its new pixel cleanup filled one-pixel notches in each silhouette, and then a new inner-line pass inked most of them dark again (251 of 271 filled pixels on the Angel, across 48 frames), because a filled pixel kept the depth of a ray that had missed. The fix, borrowing a neighbour's depth, is written and tested but not merged yet.