ARCaptcha is a daily browser puzzle built on top of ARC-AGI-3. The repo has two main parts:
- A Python backend that serves one daily puzzle at a time, keeps live environments in memory, evicts stale sessions, and can download missing daily environments from the ARC servers on demand.
- A React and Vite frontend that renders the handheld console UI and stores anonymous browser identity, replay actions, and same-day run state in
localStorage.
Warning
Parts of this codebase are pretty scuffed and need some tidying. At the moment, my goal is just to get a v1 out there.
arcaptcha/backend Flask app, CLI, config, catalog logic, and an alternate fuller Dockerfile.web/frontend source, Vite config, and built static assets.Dockerfileroot-level container build for a minimal API image.
- The backend no longer exposes the generic ARC scorecard or
/api/cmd/*routes. - The browser uses an anonymous
X-API-Keystored inlocalStorageas a lightweight per-browser identity. - The primary gameplay transport is Socket.IO on namespace
/arcaptcha, withbootstrap,action, andunloadevents. - The backend still exposes
/api/arcaptcha/*HTTP routes for health and compatibility, but the UI gameplay path is socket-based. - The browser selects one edition date from its local calendar day and sends that
edition_dateon bootstrap, action, and unload requests. - The backend accepts only the latest globally available edition date relative to
UTC+14and the immediately previous one, so all local timezones map onto a valid playable edition. bootstrapreturns both the selected daily metadata and the current game frame, and it keeps the environment warm by reusing or creating the live in-memory session for that edition date.- When a socket closes or is idle longer than the session TTL, the associated environment session is destroyed.
- If the current daily environment is not present under
environment_files/, the backend downloads its metadata and source code from the ARC servers during bootstrap. - No backend user accounts or durable user progress are stored. Refresh and restart recovery comes from the browser replay log in
localStorage.
- Python 3.12
- Node.js 20+
uvnpm
uv syncThe current backend entrypoints use module-local imports, so run backend commands from the arcaptcha/ directory.
cd arcaptcha
uv run python cli.py serve --debug --host 127.0.0.1 --port 8000The backend defaults to http://127.0.0.1:8000.
The daily schedule is frozen from the checked-in arcaptcha/content/games.json. The backend does not refetch or rewrite the catalog at startup, but it still downloads a specific environment on demand when bootstrap needs a missing daily.
cd web
npm install
npm run devThe frontend defaults to http://127.0.0.1:5173 and proxies relative /api requests to http://127.0.0.1:8000.
The frontend dev proxy also forwards /socket.io websocket traffic to http://127.0.0.1:8000.
Print the currently scheduled puzzle:
cd arcaptcha
uv run python cli.py dailyInspect a specific currently playable edition:
cd arcaptcha
uv run python cli.py daily --edition-date 2026-04-07Print the current season as one JSON document:
cd arcaptcha
uv run python cli.py seasonBuild the frontend for Flask to serve:
cd web
npm run buildAfter a successful frontend build, the backend serves web/dist at /.
ARC_BASE_URLconfigures the upstream ARC API origin. Defaults tohttps://three.arcprize.org.ARC_API_KEYconfigures the upstream ARC API key. If unset, the backend requests an anonymous key when it needs one.ARCAPTCHA_SESSION_TTL_SECONDScontrols how long an idle in-memory daily session stays warm before cleanup. Defaults to900.ARCAPTCHA_ARC_REQUEST_TIMEOUT_SECONDScontrols ARC metadata and source download timeouts. Defaults to10.VITE_API_ROOTchanges the frontend backend origin at build or dev time. If unset, the frontend uses relative URLs for both/apiand/socket.io.
Example frontend override:
cd web
VITE_API_ROOT=http://localhost:5000 npm run devThe root Dockerfile builds a minimal API image and starts the backend with the Socket.IO-enabled CLI runtime on port 5000.
docker build -t arcaptcha/api .
docker run --rm -p 5000:5000 arcaptcha/api