Watch your AI coding sessions grow a peaceful pixel-art realm.
Every Claude Code, Codex, OpenCode or Koda session becomes a settler walking out of the keep. The tool it runs decides which workshop it visits, subagents become workers, and tokens fill the storehouse — a calm, Age-of-Empires-style kingdom of your work. No combat, just a quiet realm you can watch at a glance.
▶ Live site · Quick start · How it works · Architecture
Age of Agents (npm package age-of-agents) runs as a small local web app
alongside your normal CLI workflow. It watches your agent session transcripts and
renders them as a calm, real-time strategy realm:
- Each session → a settler. Start a Claude Code, Codex, OpenCode or Koda session and a settler walks out of the keep, carrying your prompt as its task.
- Tools → workshops. The settler heads to the building that matches the work — the forge for code edits, the mage tower for web research, the mine for the terminal.
- Subagents → workers. When a session spawns subagents (e.g. the Task tool), they appear as little workers around their settler.
- Tokens → harvest. Tokens read and produced fill the storehouse. Settlers ponder while thinking, rest when waiting, and stroll home when the day's work is done.
- Two worlds. Switch between a fantasy (top-down) and a sci-fi (isometric) realm on the fly.
- Many projects → cities. Each project becomes a city you can switch between; open one for an optional peek at Beads tasks and a Graphify code map (see Project intel).
A glanceable, second-monitor view of what your agents are quietly up to.
| Fantasy | Sci-Fi |
|---|---|
![]() |
![]() |
Session detail — click a settler to inspect its task, token economy and live activity:
Install — npm i -g. Install it globally for the short aoa command; update with npm update -g age-of-agents when new versions ship:
npm i -g age-of-agents
aoa # watches ~/.claude, ~/.codex, ~/.opencode & ~/.koda sessions (+ Claude in local Docker), prints the URL
aoa --demo # calm demo mode (fake sessions)
aoa --open # also open the browserThe server binds to
127.0.0.1only and never writes your transcripts anywhere — it just reads them locally and broadcasts game state over a local WebSocket. See Privacy.
git clone https://github.com/agentsmill/age-of-agents
cd age-of-agents && npm install
npm run demo # server (demo) + client (Vite) → http://localhost:5173
npm run dev # visualize your real sessionsFor focused local testing you can limit which session sources are watched:
AOA_SOURCES=codex npm run dev
AOA_SOURCES=claude,codex npm run dev
AOA_CODEX_LOOKBACK_DAYS=3 npm run devAOA_SOURCES accepts claude, codex, opencode, and koda.
Codex watches recent date folders by default instead of the entire historical
~/.codex/sessions tree.
Local engines don't write transcripts, so Age of Agents captures them through a small logging proxy. Two ways in:
Ollama (terminal):
aoa local llama3 # wraps `ollama run llama3` and logs it as a heroThe session shows up on the battlefield; the model appears in the Modele tab, where you can assign a sprite (context window is read automatically from Ollama).
Any OpenAI-compatible backend (llama.cpp / vLLM / oMLX / coding agents):
LLM_BASE_URL=http://localhost:8000/v1 aoa local-proxy # prints a proxy URLPoint your client's base URL at the printed proxy URL. Default backend base URLs:
| Backend | Default base URL |
|---|---|
| Ollama | http://localhost:11434/v1 |
| llama.cpp | http://localhost:8080/v1 |
| vLLM | http://localhost:8000/v1 |
| oMLX | http://localhost:10240/v1 |
Overrides: LLM_BASE_URL, LLM_MODEL, LLM_API_KEY.
agent session transcript ──▶ server (watcher + state machine) ──▶ WebSocket ──▶ client (PixiJS realm + HUD)
- The server tails JSONL transcripts, turns each line into a
Fact, and runs a small per-session state machine (thinking / working / resting / idle / returning). - It broadcasts a
HeroSnapshotfor every session over a WebSocket. The snapshot carries what the session is doing (currentTool, recent actions, tokens) — never raw coordinates. - The client decides where each settler goes and renders the pixel-art realm, the HUD, the minimap and the side panel.
- Running agents in Docker? Local containers are auto-discovered (zero-config) and their Claude sessions read straight out of the container via
docker exec— no image changes, no host bind-mounts required. Containerized settlers carry a 🐳 badge in the side panel. Disable withAGENTCRAFT_DOCKER=0.
Run several projects at once and each becomes its own city in the top bar — switch between them, or pick All to see every settler together. A city shows how many agents are active and which kind (Claude, Codex, OpenCode, Koda).
Select a city to open the Architect's Hall, a side panel that surfaces two optional, third-party signals about that project — read-only and entirely opt-in:
- 📜 Beads — open tasks from Beads, an AI-native issue tracker that lives in your repo. Age of Agents reads
.beads/issues.jsonl(falling back tobd list --json). Turn it on in a project withbd init. - 🌳 Graph — a code knowledge graph: symbol, edge and community counts plus the most-connected "god-nodes". Age of Agents reads
graphify-out/graph.json. Generate it with the bundled, dependency-free generator — runnpm run graphifyin a project (ornode scripts/graphify.mjs <dir>) to scan relative imports and writegraphify-out/graph.json. You can also use the external Graphify tool; the schema is the same.
Neither tool is bundled or required. If a project has no .beads/ or graphify-out/, the panel just reads "not initialized"; it polls every few seconds, so intel appears as soon as the files do.
Two full art sets, switchable from the top bar:
- Fantasy — top-down: keep, mage tower, library, guild, market, mine, orchard & ponds.
- Sci-Fi — isometric: command center, hangars, drone factory, ore refinery, research lab on a calm Martian colony.
A small npm-workspaces monorepo, published as the single age-of-agents CLI:
| Package | Stack | Responsibility |
|---|---|---|
packages/shared |
TypeScript | WebSocket protocol types (GameEvent, snapshots) |
packages/server |
Node + Fastify + ws + SQLite |
transcript watcher, state machine, hooks endpoint, demo generator, CLI |
packages/client |
Vite + React 19 + PixiJS v8 | the game realm, HUD, minimap, side panel |
npm test # unit tests (server + client)
npm run build # production client + bundled CLI (dist/cli.js)- The server listens on
127.0.0.1only — nothing is exposed to your network. - Transcripts are read locally and read-only; their contents are never written to disk by Age of Agents or sent anywhere.
- Installing the optional Claude Code hooks modifies
~/.claude/settings.json(a fast event channel). Demo mode touches nothing of yours. - Optional interactive mode (off by default). You can let the panel answer Claude Code permission prompts and plan approvals via the local hooks. It stays
127.0.0.1-only; with the mode off, Age of Agents remains a passive read-only observer. When on, an unanswered prompt (timeout or app closed) always falls back to the terminal — the app never auto-allows. "Always allow" rules live in~/.age-of-agents/permission-policy.json; the app never edits the permission rules in~/.claude/settings.json. - Optional: launch agents from the app (BETA — setup guide). With the Claude Agent SDK installed (
npm i @anthropic-ai/claude-agent-sdk), a 🚀 Launch agent button lets you start a Claude Code session from the panel — pick a folder, type a prompt, choose a permission mode. These app-owned sessions are real Claude Code runs (they use your account and tokens) and you answer their permission prompts, plan approvals and multiple-choice questions (a centered "agent question" modal) directly in the panel. The SDK is an optional dependency; without it the button is hidden and nothing changes.- Auth for launching: the Agent SDK authenticates from environment variables only — it does not read your interactive Claude Code login. To use your subscription, generate a long-lived token once with
claude setup-token, then start the app from a shell whereCLAUDE_CODE_OAUTH_TOKENis set (andANTHROPIC_API_KEYis unset, or it takes precedence). Without it, launches fail with401 Invalid authentication credentials; the launch dialog warns when no auth is present.
- Auth for launching: the Agent SDK authenticates from environment variables only — it does not read your interactive Claude Code login. To use your subscription, generate a long-lived token once with
All pixel-art assets in packages/client/public/assets/ were generated by the author with PixelLab and are the author's own work — released here under the same MIT license as the code. Without any assets the game still runs on procedurally generated placeholders.
assets-manifest.json + scripts/download-assets.mjs are an optional helper for swapping in alternative third-party packs locally; those packs are never committed (some forbid redistribution) and are not needed to run the game.
Issues and PRs are welcome. To get going: npm install, then npm run demo to see the realm, and npm test before opening a PR.
MIT © Mateusz Pawelczuk. Art assets generated with PixelLab, redistributed under MIT per PixelLab's Terms of Service.
Inspired by AgentCraft. Built with PixiJS, React, Fastify and PixelLab.

