Tapoo is an AI agent behavior profiler built as a maze runner hide-and-seek game. Two interfaces share one codebase: a browser SPA, where a configured AI agent plays the maze and what it does is recorded, and a Go terminal game with the same terminal-inspired feel. Profiling is browser-only - the terminal build is the game by itself. Its companion Tapoo Oracle application analyzes exported AI-agent gameplay logs against the Tapoo Agentic Behavior Rubric.
Objective: Guide the blue player to the red destination before the score drops to zero.
go install github.com/dmigwi/tapoo@latest
tapoogo run .make frontend-install
make frontend-buildThen serve public/ and open /index.html.
Gameplay And Controls
Tapoo increases maze area as levels rise. Progress continues until the current terminal window or browser viewport can no longer fit the next maze cleanly.
Arrow keys: move the playerCtrl+B: cycle maze wall weightSpaceorEsc: pause the current runEnter: proceed after pause, win, or failureCtrl+C: quit
- Keyboard controls mirror the terminal controls
Ctrl+Alt+R: reset browser progress- On touch devices, on-screen controls are shown automatically
Highlights
- Terminal-first maze gameplay
- Browser SPA with the same black-and-green terminal feel
- Adjustable wall weights with live cycling during play
- Per-level scoring and progression
- Pause, resume, retry, and next-level flow
- HTTP-driven AI agent play against Ollama, OpenAI-compatible, and Anthropic APIs, with up to 6 (configurable) agent seats
- Agent behavior analysis through the companion Tapoo Oracle application
- Best-effort persistence for terminal and browser sessions
- Manual GitHub Pages deployment for the web build
- Go and TypeScript test coverage in CI
Browser App
The browser build emits versioned JS/CSS bundles under public/js and public/css, then serves the SPA from public/index.html.
This compiles frontend/tapoo.ts with esbuild into a minified browser bundle.
Available pages:
/index.htmlfor the game/agents.htmlfor configuring and running HTTP-driven AI agents/prompts.htmlfor previewing the exact prompts and tool definitions sent to an agent/privacy.htmlfor the browser storage and agent data privacy notice
AI Agents
Instead of (or alongside) a human player, up to 6 agent seats can each be configured to play the maze by calling an HTTP chat-completions endpoint every turn.
- Ollama - native
/api/chatshape - OpenAI-compatible -
/v1/chat/completions(also covers self-hosted servers such as vLLM, LM Studio, and llama.cpp, and routers such as Hugging Face's Inference Providers) - Anthropic -
/v1/messages
Each seat is configured independently from the /agents.html overlay:
- player name, model, endpoint, and API provider
- credential (bearer token or API key) and custom extra headers, e.g.
anthropic-version - reasoning effort - how hard the model reasons before replying; the available levels and default depend on the provider, since reasoning support varies by model (e.g. Kimi K3 handles heavy reasoning well, Gemma 4 does not)
- echo back reasoning - whether prior reasoning content is replayed on the next request, off by default since guidance on this conflicts across reasoning models; locked off automatically whenever reasoning effort is set to
none, and has no effect for Anthropic agents
The /prompts.html page mirrors the exact system prompt, tool definitions, and required response format an agent receives, so its behavior can be inspected without capturing live traffic.
Tapoo produces downloadable agent-api gameplay logs. Tapoo Oracle
owns the log contract, behavior rubric, and analysis engine that turn those exports into capability
and violation profiles. Oracle is included in this repository as the tapoo-oracle
git submodule and can be initialized with:
git submodule update --init --recursivePersistence
Tapoo carries a semantic version (MAJOR.MINOR.PATCH), shown in the terminal intro banner and in the browser footer. Browser storage additionally carries its own separate schema version, independent of the app version above - see the browser storage note below.
The terminal version stores best-effort runtime state in a local file:
.tapoo.store
It keeps track of:
- current level
- selected wall weight
- last game progress state
If the persisted state cannot be read or validated, Tapoo falls back to default startup behavior.
The SPA stores gameplay state in browser storage:
localStoragefor durable preferences such as level and wall weight, and for configured agent seats (including credentials, endpoints, and per-agent reasoning settings)sessionStoragefor the active round snapshot, per-tab agent session metrics, and the tab-session ID used to scope Tapoo LogsIndexedDBfor Tapoo Logs when available; logs remain on the current device and are scoped to the current tab session for download/reset
Every stored entry is tagged with the current storage schema version. On startup, Tapoo detects entries left over from an older schema version and asks for acknowledgement before removing them rather than attempting to migrate them.
Privacy note: browser storage stays on the current device unless the user clears it, resets progress, removes configured agent data, or downloads/shares Tapoo Logs. Browser storage is lightly obfuscated to discourage casual tampering, but it should not be treated as strong encryption for personal data. When AI Agent play is configured, gameplay context such as player name, current cell, destination cell, submitted moves, score, level, and traversal history may be sent to the configured agent API endpoint. If IndexedDB is unavailable, Tapoo falls back to smaller sessionStorage logs and may limit higher AI Agent levels.
The deployed browser pages include a short privacy notice at privacy.html.
Development
- Go
1.25+ - pnpm
11.25.0 - Node.js
24LTS golangci-lint v2.12.2
make help
make frontend-install
make frontend-quality
make frontend-build
make test
make ciGo and TypeScript carve mazes independently from different random sources, so parity-harness/bench-report.mjs runs both ports' benchmark suites (maze/bench and frontend/bench) and checks that the two generators produce identical per-sample maze structures rather than merely eyeballing the numbers. A flagged case means a reproducible behavioral gap between the ports, not just run-to-run noise.
make go-bench # Go maze generation only
make frontend-bench # TypeScript maze generation only
make ci-bench # both, with the cross-port parity checkEach run also writes parity-harness/bench-report.json with the full comparison and SVG charts.
Contributing
Contributions are welcome, but contributors should install the repository pre-commit hook before creating commits.
- Install the required toolchains:
Go 1.25+,Node.js 24 LTS,pnpm 11.25.0, andgolangci-lint v2.12.2 - Install frontend dependencies:
make frontend-install- Install the repository git hooks:
./scripts/install-hooks.shThe hook installer copies scripts/hooks/pre-commit into .git/hooks/pre-commit.
The pre-commit hook runs:
golangci-lint runThis is required so commits are checked locally before they are pushed. If golangci-lint is not installed, the hook installation script will warn you and show installation options.
make ciAt minimum, contributors should make sure:
- Go tests pass
- frontend typecheck, lint, and tests pass
golangci-lint runpassesgovulncheckpasses
make lint: rungolangci-lintmake govulncheck: rungovulncheckmake frontend-quality: run frontend typecheck, lint, and testsmake frontend-build: build the minified SPA bundlemake test: run frontend checks plus Go race tests with coveragemake ci: run the local equivalent of the main CI pipeline
Testing And Quality
go test ./...
go test -race -covermode=atomic -coverprofile=coverage.out ./...
golangci-lint runpnpm run typecheck:frontend
pnpm run lint:frontend
pnpm run test:frontend
pnpm run coverage:frontendCI And Deployment
The main CI workflow lives at .github/workflows/go.yml and runs:
- Go linting
govulncheck- frontend typecheck, lint, tests, and build
- Go race tests with coverage
- coverage uploads for Go and frontend reports
The Pages workflow lives at .github/workflows/pages.yml.
Pages deployment is manual-only.
To deploy:
- Open the repository on GitHub.
- Go to
Actions. - Choose
Deploy Pages Manually. - Click
Run workflow. - Select the branch you want to deploy.
Important:
- GitHub Pages should be configured to use
GitHub Actionsas the publishing source. - Since the workflow is manual, it deploys the branch selected at run time.
maze/ Go gameplay, rendering, persistence, and tests
frontend/app/ TypeScript SPA logic and tests
public/ Static site assets, HTML, CSS, images, and built JS
scripts/ Frontend build and hook helpers
tapoo-oracle/ Companion agent-log analyzer (git submodule)
This project is licensed under the Apache License 2.0. See LICENSE.
Tapoo is distributed on an AS IS basis, without warranties or guaranteed support.
