Skip to content

GitGotchi

A companion that lives in your git repository and grows with how you commit, including the commits AI agents write for you. The first version was built by an AI IDE in a day. Every release since has started by reading what the last one got wrong.

Case studyUpdated October 18, 20265 min read

All seven forms, each a real 3D model raymarched into pixel art. Where your companion ends up depends on how you, and your AI agents, commit.
Role
Solo project: specs, the AI-assisted build, then the reviews, the 0.3 redesign and the fixes
When
December 2025 – October 2026
Stack
Python, NumPy (raymarched 3D), Typer, Rich, SQLAlchemy, Git hooks, Claude API, GitHub Actions, PyPI

The problem

How far can an AI IDE get building a complete developer tool in a day, and what is that code like to live with once other people install it?

What I built

A companion for your repo. A git hook feeds it every commit, a quality score decides how it evolves, and commits written by AI agents slowly possess it. It's drawn as 3D pixel art right in the terminal.

What happened

On PyPI the day it was started. Reviews since found nine shipped bugs in version one and a security hole in 0.3.0. 0.4.0 is current, with 116 tests where there were none.

  • 1 day

    from first commit to PyPI

  • 200+

    downloads on PyPI

  • 0 → 116

    tests, on Linux, macOS and Windows

  • 7

    forms, one of them only AI agents unlock

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.
The same seven well-described commits through both versions, in a demo repository. 0.1.3 stays a ghost at 57 and leaves its database in git status; 0.2.0 reaches angel at 77.4 and stays out of git.

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.

The haunt pane reacting to commits as they land. Agent commits glitch the screen.

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.

A sample from `gitgotchi card`: a 1200×630 share image, sized for link previews and drawn without an image library.

What I'd carry forward

  1. 1Shipping isn't reading. Generated code needs a review pass that someone actually does, and so does every release after it.
  2. 2Treat anything a cloned repository contains as someone else's input.
  3. 3Detection that accuses people needs as much care as detection that misses them.
  4. 4Test the paths nobody looks at: uninstall, a subfolder, a worktree, someone else's src/.

Get in touch

Questions about my work, a role, or a project idea. Send a message here or email me directly.

Srikarmks@gmail.com