Skip to content

About

A public leaderboard of the tokens AI builders burn.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Repository files navigation

tokenmaxer.quest

A public leaderboard of the tokens AI builders burn with Claude Code, Codex, opencode, pi, Cursor and Grok Bot. Pick a username, paste a couple of snippets, and your coding sessions self-report their token usage to the board. No email, no PII — just token counts.

It's a TanStack Start + React app on Cloudflare Workers with a Hono JSON/API layer, backed by one D1 database.

How it works

These tools don't hand token counts to hooks — they only point at local session files. So the installed reporter (reporter/src/* → bundled tokentally.mjs, a zero-dependency Node script published on npm as tokenmaxer) reads those files, sums usage per model, and POSTs the totals — the same files ccusage parses.

What leaves the machine: per-session token counts, model names, session ids, and timestamps — never prompts, code, file paths, or credentials. Append --dry-run to any reporter command to print the exact payloads instead of sending them.

  • Claude Code — ~/.claude/projects/**/<session>.jsonl → message.usage.*
  • Codex — ~/.codex/sessions/**/rollout-*.jsonl → last token_count event
  • opencode — ~/.local/share/opencode/storage/message/<session>/*.json → tokens.* on each assistant message
  • pi — ~/.pi/agent/sessions/**/*.jsonl → usage on each assistant record (deduped by id, since pi stores a branching tree)
  • Cursor — dashboard API fetch via local auth (reporter calls cursor-sync)
  • Grok Bot — same Cursor dashboard fetch; its grok-bot-* rows are stored as their own source

Each row is your usage for one tool, session, model and day, where day is the calendar day on the machine that reported it. Leaderboard windows are whole calendar days (today is your local date; 7d is that date plus the six before it), so a long-running session contributes to every day it touched instead of booking its lifetime total to the day it opened.

Reporting fires on Claude Code / Codex SessionStart / SessionEnd hooks (no cron, no daemon). opencode and pi have no shell hooks, so a small shell wrapper function runs the reporter each time they exit. Each row is scoped to one user, tool, session, model, and day, and re-reporting a session replaces every row it owns rather than adding to them, so reporting the same session twice never double-counts — which is what makes combining start + end (and the start-only catch-ups) safe.

Token counts are self-reported — this is an honor system with light guardrails (bearer auth, rate limits, sanity caps). See /about.

Project layout

src/
  server.ts          # Worker entry: Hono (API/agent/OG) vs TanStack Start (HTML)
  index.tsx          # Hono app: JSON API, agent markdown, OG, reporter, cookie routes
  routes/            # TanStack file routes (React pages)
  pages/             # Shared React page components
  api/               # Hono JSON/API route modules
  core/api/          # createServerFn loaders for TanStack routes
  lib/               # auth, pricing, ratelimit, validate, aggregate, format
  drizzle/           # D1 migrations
  __tests__/         # vitest unit tests
reporter/src/        # reporter modules (strict TS; esbuild → tokentally.mjs for npm + /tokentally.mjs)

API

Method Path Auth Purpose
POST /api/register — {username} → {id, username, token}
POST /api/token/rotate Bearer rotate your token
GET /api/whoami Bearer {username} for the token
POST /api/ingest Bearer upsert {source, sessions[], replace_sessions?} (live reporting)
POST /api/history Bearer bulk backfill {source, sessions[], replace_sessions?} (past history)
POST /api/profile Bearer set/clear {url} (https public profile link)
GET /api/leaderboard — ?window=&metric=&source=&model=&limit=
GET /api/u/:username — profile totals + breakdown
GET /api/health — {name, version}

window ∈ today|7d|30d|all, metric ∈ total|input|output|cached|cost, source ∈ claude_code|codex|opencode|pi|cursor|grok_bot.

Agent-readable pages

Non-browser clients (e.g. curl) get Markdown by default on /, /about, /start, and /u/:username. Browsers still get HTML. Explicit twins:

  • /llms.txt, /llms-full.txt
  • /index.md, /about.md, /start.md, /u/:username.md

/start.md requires the invite session cookie when INVITE_KEY is set.

Development

pnpm install
pnpm db:migrate:local           # apply migrations to local D1
pnpm dev                        # Vite + TanStack Start (Cloudflare plugin) on :3000
pnpm test                       # vitest
pnpm typecheck
pnpm build && pnpm preview      # production build + Workers preview

Deploy

wrangler d1 create tokentally                       # paste database_id into wrangler.toml
wrangler kv namespace create RATE_LIMIT             # paste id into wrangler.toml
pnpm db:migrate                                     # apply migrations to remote D1
# optionally set PUBLIC_BASE_URL in wrangler.toml [vars]
pnpm deploy

Onboarding (what users paste)

Username claims are invite-only via a shared invite link at /invite?token=<KEY> (sets a session cookie, then redirects home; claim the username at /start).

After claiming a username at /start, users get a personalized version of:

npm install -g tokenmaxer && \
  mkdir -p ~/.tokenmaxer && \
  printf '%s' '{"apiBase":"https://<host>","token":"tt_..."}' > ~/.tokenmaxer/config.json

Claude Code — merge into ~/.claude/settings.json:

{
    "hooks": {
        "SessionStart": [
            {
                "type": "shell",
                "command": "tokenmaxer claude-sessionstart"
            }
        ],
        "SessionEnd": [
            {
                "type": "shell",
                "command": "tokenmaxer claude-sessionend"
            }
        ]
    }
}

Codex — add to ~/.codex/config.toml (Codex has no SessionEnd hook, so the latest session reports on the next launch):

[[hooks.session_start]]
type = "command"
command = "tokenmaxer codex-sessionstart"

opencode — opencode has no shell hooks, so add a wrapper to ~/.bashrc/~/.zshrc that reports your latest sessions each time opencode exits:

opencode() { command opencode "$@"; tokenmaxer opencode-sessionstart; }

pi — same idea for pi:

pi() { command pi "$@"; tokenmaxer pi-sessionstart; }

The token lives only in ~/.tokenmaxer/config.json, never in shared settings files. (Legacy ~/.tokentally/config.json and TOKENTALLY_* env vars still work as fallbacks.)

Backfilling past history

The hooks only report sessions going forward (SessionStart catch-up scans the last TOKENMAXER_DAYS, default 3). To load everything you ran before installing tokenmaxer, run the one-time backfill — it computes token-count summaries from all local Claude Code / Codex / opencode / pi / Cursor transcripts and uploads only those summaries:

tokenmaxer backfill --dry-run    # print payloads, send nothing
tokenmaxer backfill              # all tools
tokenmaxer backfill claude      # Claude Code only (same for codex|opencode|pi|cursor)
tokenmaxer set-profile-url https://github.com/YOU   # optional public link on /u/YOU
tokenmaxer set-profile-url --clear
tokenmaxer rotate                 # replace your token (needs the current one)
tokenmaxer whoami                 # print the username for that token

Backfill posts to a dedicated POST /api/history endpoint (Bearer auth) rather than /api/ingest. It's a separate route with its own rate-limit bucket and a larger per-request cap, so a big one-time upload doesn't eat into the live reporting budget. Uploads use the same idempotent upsert as /api/ingest — each row scoped to one user, tool, session, model, and day — so it's safe to run backfill while the hooks are active and safe to re-run.

If you were reporting before local-day attribution shipped, run tokenmaxer backfill once — existing data keeps its old day attribution until you do. Cursor backfill only reaches back 90 days (reporter/src/commands.ts), so Cursor days older than that can't be re-derived at all.

Pricing

Estimated USD cost uses a hardcoded per-model table in src/lib/pricing.ts — update it and redeploy when prices change. Values are estimates, not billing truth.

About

A public leaderboard of the tokens AI builders burn.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages