4bf7481f9b
The vision prompt now returns {titles, unidentified}: boxes that look
like games but can't be confidently titled are reported (location
relative to identified neighbors, partial text, art notes) instead of
silently omitted. They land in data/unidentified.json keyed by photo,
and the end-of-run summary lists them — plus low-confidence reads —
with instructions to retake a closer photo and re-run. New --force flag
re-extracts everything; pre-feature raw caches (bare arrays) still
parse. Live run on IMG_4499 confirmed the flow and the low-confidence
list correctly flags the known "Hebarceos" misread.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3.1 KiB
3.1 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project
bggpipe — a resumable, idempotent CLI pipeline: shelf photos → Claude vision title + edition-cue extraction → BoardGameGeek ID and version matching → human review → collection diff → upload to BGG via Playwright → metadata enrichment (games.json). Full design: @bgg-shelf-pipeline-spec.md. The repo is greenfield — no code exists yet. Follow the spec's "Suggested Build Order" when scaffolding; re-run /init once code exists.
Stack (decided, not yet scaffolded)
- Python 3.12+, deps via uv (
uv add,uv run), CLI framework typer, tests pytest, lint/format ruff. - Browser automation: Playwright (not Selenium). Needs
uv run playwright install chromiumafter install. - Vision: Anthropic API, latest Sonnet model.
Hard rules (from spec — never violate)
- ≤1 request every 2 seconds to any BGG endpoint; jittered backoff on 429/503. Upload stage: 2–4 s randomized delay between games.
- Credentials never touch disk or logs.
ANTHROPIC_API_KEY,BGG_USERNAME,BGG_PASSWORD,BGG_API_TOKENcome from env vars only. Playwright storage state is credential-adjacent — keep it gitignored. - The XML API requires a registered app token (
Authorization: Bearer, fromBGG_API_TOKEN) — unregistered requests get 401. Until Eric's registration at boardgamegeek.com/applications is approved, tests run on the stub fixtures intests/fixtures/bgg_cache/; re-record them withscripts/record_fixtures.pyonce the token exists. - Every stage is idempotent and resumable — killing mid-run and restarting must lose no work; re-runs skip already-processed items.
- Use only the XML API2 and the public website — no undocumented BGG endpoints (BGG tightened access policies in 2025).
- BGG has no write API: writes drive the real website with a logged-in Playwright session.
Domain gotchas
- Base game vs. expansion vs. new edition is the top failure mode — bias matching toward
ambiguousover auto-match ("Wingspan Europe" must not match base Wingspan). - Editions/versions matter: Eric owns multiple editions of some games — each is a separate collection entry (keyed by
collidon BGG). Never guess a version: no legible cues →version_unknownand a version-less collection entry. - Normalize titles (casefold, strip punctuation/articles, special chars like é/&/:) identically on both sides of a match; dedupe across photos but keep
source_photosprovenance. - Detailed BGG API behavior (202 queueing, collection-endpoint quirks, endpoints): use the
bgg-apiskill. If the spec's BGG behavior changes, update thebgg-apiskill to match — they must not drift.
Git
- Remote is self-hosted Gitea 1.26 (
git.kestrelsnest.social), not GitHub —ghCLI does not work here. - Commit
data/matches.csv,data/to_add.csv,data/upload_log.csv,data/titles.json,data/unidentified.json,data/games.json. Never commitdata/bgg_cache/,photos/, Playwright storage state, or.env.