# OS .DS_Store Thumbs.db # Editors .vscode/ .idea/ *.swp # Dependencies / build output # # NO TRAILING SLASH on node_modules, deliberately. `node_modules/` matches a directory and not a # SYMLINK of that name — so one pointing at a shared install was committed in v0.4.7, and because it # pointed at a path that does not exist, a fresh checkout had no TypeScript: `npm run typecheck` said # "tsc: not found" and 20 tests failed for a reason that had nothing to do with the code. node_modules dist/ build/ target/ __pycache__/ *.pyc # Claude Code's own state — session checkpoints and the git worktrees it works in. # # NOT ignored until now, so `git add -A` in the repo root would have staged # `.claude/worktrees/`: a whole second checkout of this repository, committed into itself. Nothing # in here is a source file and none of it should travel with the package. .claude/ # Env .env .env.local # Logs *.log # Generated replays — ANCHORED to the repo root on purpose. # # Unanchored, `replay*.html` also matched `src/web/replays.html`, which is a SOURCE file: the # website's replay viewer. It was therefore never committed, and a fresh clone was missing a page # the build copies unconditionally. Only the throwaway files this directory collects are ignored. /replay*.html # Playtest saves — somebody's game, attached to a bug report. # # ANCHORED, and this is the line those saves actually arrive on. A save is a seed plus the moves # made: it belongs to whoever sent it, and it goes stale the moment the rules move. Nothing that # lands here is ever committed. `public/replays/` is the place for a game worth publishing. # # The README exemption mirrors `main`, so a `playtests/README.md` would still be committable if this # line ever wants one; today the directory is simply created when the first save arrives. /playtests/* !/playtests/README.md