Burnfolio collects local AI coding-agent usage data and summarizes token burn by date, CLI type, and model.
The hosted app runs on Cloudflare Workers at https://burnfolio.ai, with D1 for
storage and Cloudflare Email Service for optional magic-link sign-in.
Current collectors:
- Claude Code:
~/.config/claude/projectsand~/.claude/projects - Codex:
${CODEX_HOME:-~/.codex}/sessionsandarchived_sessions - OpenCode:
${OPENCODE_DATA_DIR:-~/.local/share/opencode} - Pi:
${PI_AGENT_DIR:-~/.pi/agent/sessions} - Amp:
${AMP_DATA_DIR:-~/.local/share/amp} - Droid:
${DROID_SESSIONS_DIR:-~/.factory/sessions} - Codebuff:
${CODEBUFF_DATA_DIR}or~/.config/manicode* - Hermes Agent:
${HERMES_HOME:-~/.hermes}/state.db - Goose: local
sessions.dbroots orGOOSE_PATH_ROOT - Kilo:
${KILO_DATA_DIR:-~/.local/share/kilo}/kilo.db - Kimi:
${KIMI_DATA_DIR:-~/.kimi} - OpenClaw:
~/.openclaw,~/.clawdbot,~/.moltbot,~/.moldbot - Qwen Code:
${QWEN_DATA_DIR:-~/.qwen} - GitHub Copilot CLI:
~/.copilot/otel/*.jsonlorCOPILOT_OTEL_FILE_EXPORTER_PATH - Gemini CLI:
${GEMINI_DATA_DIR:-~/.gemini/tmp}
curl -fsSL https://raw.githubusercontent.com/nbitslabs/burnfolio/main/install.sh | bashBurnfolio publishes pre-built pyro binaries for every release tag on GitHub:
- Linux:
amd64,arm64 - macOS:
amd64,arm64 - Windows:
amd64,arm64
Release assets are available at
https://github.com/nbitslabs/burnfolio/releases.
The installer downloads the latest release binary, installs it to
/usr/local/bin or ~/.local/bin, writes ~/.pyro/config.json, and can
optionally run an immediate sync.
If you already have a Burnfolio machine token, you can either pass it with
--profile and --machine or let the interactive installer prompt for it.
For a new machine token from the dashboard, copy the generated one-liner:
curl -fsSL https://raw.githubusercontent.com/nbitslabs/burnfolio/main/install.sh | bash -s -- --profile <account-number-or-username> --machine <machine-token>The dashboard keeps a copy-ready install command on each machine row. Burnfolio stores machine tokens hashed server-side and shows the full token only once, at creation or rotation — the row action rotates the token (the previous token stops working) and copies a fresh install command.
The installer asks whether to set up automatic sync with cron: none, hourly,
or daily. Cron sync output is logged to ~/.pyro/sync.log. For non-interactive
setup, pass the schedule explicitly:
curl -fsSL https://raw.githubusercontent.com/nbitslabs/burnfolio/main/install.sh | bash -s -- \
--profile <account-number-or-username> \
--machine <machine-token> \
--schedule dailyUseful installer flags:
--profile <account-or-username>
--machine <machine-token>
--schedule <none|hourly|daily>
--providers amp,claude,codebuff,codex,copilot,droid,gemini,goose,hermes,kilo,kimi,openclaw,opencode,pi,qwen
--openrouter-key <management-key>
--openrouter-profile <account-or-org>
--openrouter-since 2020-01-01
--server https://burnfolio.ai
--install-dir ~/.local/bin
--version v0.1.2Uninstall disables Burnfolio cron sync and marks the local install as
uninstalled in ~/.pyro/config.json. It leaves the .pyro folder and saved
machine config in place so you can reinstall or inspect status later:
curl -fsSL https://raw.githubusercontent.com/nbitslabs/burnfolio/main/uninstall.sh | bashUseful uninstaller flags:
--profile <account-or-username>
--install-dir ~/.local/bin
--remove-binary
--keep-cron
--yesShow local install state:
pyro statusRun a local summary and automatically sync when ~/.pyro/config.json has an
active profile and machine token:
pyroUseful CLI flags:
pyro --providers claude,codex,opencode,pi
pyro --json
pyro --no-sync
pyro --home /path/to/home
pyro --profile bf_ab12cd34 --machine bfm_...
pyro --profile bf_ab12cd34 --machine bfm_... --openrouter-key sk-or-v1-... --openrouter-profile bf_ab12cd34
pyro install --profile bf_ab12cd34 --machine bfm_...
pyro uninstallThe first time you sync with --profile/--machine outside of pyro install,
pyro prints a one-line notice that it saved those credentials to
~/.pyro/config.json so future runs sync automatically.
Build from source for local development:
make build
./bin/pyro
go install ./cmd/pyro
pyroThe table output is grouped by date, CLI, and model. JSON output includes provider totals plus the same date/CLI/model segments for the server API.
When --profile and --machine are provided, the CLI uploads all local history to
Burnfolio as one idempotent total per day, broken down by CLI and model.
Re-running the same command replaces each machine/day row instead of
double-counting it. Only counts leave your machine — no prompts, code, or
transcripts are ever uploaded. Each synced day carries the date, a record
count, six token counters (input, cache read, cache write, output, reasoning,
total), and the same six counters split out per CLI and model.
Total token counts are input + cache_read + cache_write + output. Reasoning
tokens are reported separately but are informational only and never added
into the total, since providers already include them in the output count.
OpenRouter imports use the same definition.
Burnfolio can import OpenRouter account usage from an OpenRouter management key. Management keys are not inference keys, but they can read account analytics.
Local import keeps the OpenRouter key on your machine and uploads only daily token totals:
pyro install \
--profile <account-or-username> \
--machine <machine-token> \
--openrouter-key <openrouter-management-key> \
--openrouter-profile <account-or-org>
pyroYou can also connect a management key in the Burnfolio dashboard for your personal profile or from an organization management page. Server-side connections are encrypted and fetched hourly.
OpenRouter data is stored separately from local machine inference data and is deduplicated by target profile, OpenRouter key fingerprint, and day. If the same key is synced from multiple machines or from both Pyro and the dashboard, the same daily rows are updated instead of added twice.
Create an account at https://burnfolio.ai with an email magic link — no
password. After signing in, the dashboard provides machine tokens and
ready-to-run install + sync commands. Accounts created before magic-link-only
signup can still sign in with their account number and key.
Run the generated install + sync command locally:
curl -fsSL https://raw.githubusercontent.com/nbitslabs/burnfolio/main/install.sh | bash -s -- --profile <account-number-or-username> --machine <machine-token>From the dashboard you can claim a username, create personal or organization
machine tokens, create the nbitslabs org, and invite users as members or
admins. Public user and org pages expose the same burn graph plus iframe and
SVG embed snippets.
scripts/smoke-live.sh is retired: it relied on anonymous signup, which has
been removed. Use scripts/verify-account.sh with a pre-provisioned account
instead.
For a real account acceptance pass, set the profile and machine token generated by the dashboard:
BURNFOLIO_PROFILE=<account-or-username> \
BURNFOLIO_MACHINE=<machine-token> \
scripts/verify-account.shOptional checks can verify a fresh second machine and an org profile:
BURNFOLIO_PROFILE=<account-or-username> \
BURNFOLIO_MACHINE=<machine-token> \
BURNFOLIO_SECOND_MACHINE=<second-machine-token> \
BURNFOLIO_EXPECT_SECOND_INCREASE=1 \
BURNFOLIO_ORG=nbitslabs \
BURNFOLIO_EXPECT_ORG_MATCH=1 \
scripts/verify-account.shProfiles expose both iframe and SVG embeds:
<script src="https://burnfolio.ai/embed/<profile>/script.js"></script>
<img src="https://burnfolio.ai/embed/<profile>.svg" alt="Burnfolio token burn graph">See examples/embed.html for a complete third-party page template.
The Cloudflare Worker keeps its UI code in worker/index.js and its stylesheet
in worker/styles.css. Tailwind processes and minifies the stylesheet, then the
build step writes the deployable Worker to dist/worker/index.js.
npm install
npm run build:uimake deploy runs the UI build before wrangler deploy, so production deploys
use the generated Worker bundle.