Local-first. MIT. Zero dependencies.

The cost of every pull request.

TokenFlow prices the coding-agent logs already on your machine. A receipt for every branch, a brake for the session that blows the budget.

AI cost receipt
PR #476 +6,269 / -99 lines
$1,291estimated spend, up to the merge
92% re-sent context8% fresh work
Sessions
4
Turns
5,488
Subagent turns
62%
Models
Opus 5, Fable 5
Cost per 100 lines
$20.28
vs median branch
87×
Largest prompt
1.11M tokens
A real receipt from the author's own logs, priced with the shipped table. Branch and repository names withheld. No prompt or code content was read.

Three findings from nine weeks of agent logs

86%

of $26.7K went to re-sending context. Cache reads and writes are the cheap path per token, so this is the price of long sessions, not waste.

Nine weeks, one developer, priced with the shipped table.
93%

of spend sat in the top 1% of sessions. Across 22,698 sessions the median cost two cents.

Spend follows a power law. Averages hide it.
15×

The median turn costs $0.01 for the first fifty turns and $0.15 after that.

Per-request sources only.

A turn gets fifteen times dearer after turn fifty.

Every turn re-sends the conversation so far. Past a point, most of what you pay for is the conversation, not the answer. That step is where a brake belongs.

Median cost of a turn, by how deep into the session it runs

146,373 priced turns from Claude Code, Codex and OpenCode. Hermes reports whole sessions and is excluded.

Median cost per turn by turn index Turns one to fifty: one cent. Fifty-one to two hundred: fifteen cents. Two hundred one to one thousand: fourteen cents. Over one thousand: twelve cents. $0.01 $0.15 $0.14 $0.12 turns 1 to 50 51 to 200 201 to 1,000 over 1,000 n = 55,939 n = 15,717 n = 31,152 n = 43,565

Turns carrying more than 200K prompt tokens were 34% of turns and 75% of their spend. Reproduce with tokenflow receipt --sessions.

Receipts

What did this branch cost?

Every turn is attributed to the branch checked out when it ran. Branches join to merged pull requests by name. The result is a number your team can argue with.

1

A PR owns the turns up to its merge, including the work done before it was opened. That work is how the PR came to exist.

2

Turns after the merge sit beside the receipt, never inside it. They are follow-up on a checkout that kept the old branch name.

3

Long-lived branches are flagged. A receipt for main is a receipt for a period, not for one change.

Rule two came from a mistake. The first draft of this page said a 102-line fix cost $2,499. It cost $16. The other $2,483 ran on the same branch over the six days after it merged, and no console showed the difference. The receipt does now.
PRLinesTo mergePer 100 linesSessionsTurnsSubagentAfter merge
#476+6,269 / -99$1,291$20.2845,48862%$7
#430+11,649 / -256$596$5.0114,35687%$12
#300+5,910 / -343$366$5.8511,66384%$2
#389+11,298 / -813$203$1.6816386%$17
#478+101 / -1$16$16.072320%$2,483
#339943$0.41$0.04130%none

Six of 86 merged pull requests from one repository. Median PR $16.20. Across all of them, 46% of what those branches cost was spent after the merge and belongs to no PR. The $0.41 row is more likely under-attributed than cheap: Codex sessions carry no branch yet.

The Receipts view of the TokenFlow dashboard: spend per repository and branch with context share, sessions, turns, subagent share and rank against the repository median
The Receipts view on synthetic demo data. Click a branch for its receipt and copy it as a pull-request comment.
Guard

A brake that works while the session is still running.

A Claude Code hook reads the live transcript, prices it with the same table, and warns or blocks against caps you declared. Nothing is invented: with no caps set it only informs.

# declare what you want guarded
tokenflow guard --set warnCostUsd=25,maxCostUsd=200
tokenflow guard --set warnContextTokens=200000

# then, mid-session, the hook says:
TokenFlow guard: session spend $61.48 passed the
warning level of $25.00; the prompt now carries
492K tokens (warning level 200K).
Most of each turn now pays to re-send earlier
context. Compact, or start a fresh session with a
short brief, and the per-turn cost drops.

Runs once per prompt and before each subagent is spawned, the two moments a session's cost curve bends. A cap that is reached blocks the next tool call with the reason on screen.

$5082 sessions over the cap$18.8K70% of spend above it
$10052 sessions$15.6K58%
$20032 sessions$11.4K43%
$50012 sessions$5.7K21%

Dollars above each per-session cap in the author's nine weeks. An upper bound on what a guard could have held back, not a saving: some of that work would have happened anyway in a fresh session.

Three commands. No account, no key, no upload.

Detect

Each adapter looks in the conventional place for its own logs: Claude Code, Codex, OpenCode, Hermes, Cline, Cursor, gateways, git. Nothing scans your disk.

tokenflow setup

Ingest

Every file resumes at its byte offset. Streaming re-reports collapse to their maximum, cache buckets stay exclusive, and a missing field stays missing instead of becoming zero.

tokenflow refresh

Read

A dashboard at loopback, a native menu bar app, receipts per branch, a guard for the session you are in, and one self-contained HTML file that opens anywhere, offline.

tokenflow up

Privacy by construction, not by policy.

The receipts need your transcripts and your repository on the same disk. That is exactly why nothing leaves it.

Install in one line.

macOS gets the menu bar app. Everything else gets the CLI and the dashboard. Both are the same engine.

macOS, Homebrew
brew tap vimoxshah/tap https://github.com/vimoxshah/tokenflow
brew install --cask tokenflow
Any platform, npm
npx @vimoxshah/tokenflow@latest setup
macOS, direct
TokenFlow.dmg from the latest release

Needs Node 22.5 or later. The app is unsigned, so macOS asks once: right-click, Open, Open.

Everything else it already does.

Twenty-one dashboard views
Overview with the three insights that matter, receipts, tickets, session anatomy, live, providers, models, interfaces, time patterns, peaks, efficiency, cache health, cost with coverage, what-if, productivity, rhythm, compare, compare branches, explorer, annotations, data health. In a left sidebar grouped by topic, because twenty-one no longer fit a tab strip.
A budget check on every pull request
The receipt a push already attached as a git note becomes one PR comment and a status check. Run it as a GitHub Action, or host your own GitHub App on your own tokenflow team serve. We host nothing and store nothing.
Cost per ticket
Every branch that named the same Jira, Linear or GitHub key, added up across repositories. A branch that names no key stays unattributed rather than guessed into a ticket.
A FOCUS-shaped export
export --focus writes the FinOps FOCUS column names, so these estimates can sit beside a real cloud bill in a tool that already reads FOCUS. Still an estimate at list price, and every row says so.
An MCP server
Four read-only tools over stdio, so the agent spending the money can read its own bill: what this branch has cost, the caps in force here, recent totals, the monthly budget. No socket, no network.
Org policy
A cap your team publishes on a server you run, cached locally and applied as a ceiling: it can lower a cap, never raise one. The guard reads the cache and never waits on the network.
Two controls, not eighteen
A date button that reads the range it applied, a + Filter button, and removable chips for whatever is actually on. Pick a dimension and its values arrive with a search box and each value's share. Twenty-one views in a sidebar grouped by topic, collapsible to a rail of icons. A command palette with grouped commands and your recents. Hover any chart for a crosshair and every series at that point.
A native menu bar app
Spend today, capacity meters with reset countdowns, forecasts with stated confidence, anomaly alerts, per-provider and per-model rows. Swift, not Electron.
Honest cost
A versioned price table with a source for every rate. Service tiers applied as multipliers. Unpriced models show as unknown, never as $0.
Three skins, both modes
Aurora, Terminal and Editorial in dark and light. Series colours belong to the mode, so switching skin never changes what a colour means.
Digests and budgets
A weekly digest to your own Telegram, inbox or webhook. A monthly budget with projected-overrun alerts that fire once.
One-file export
The whole dashboard, receipts included, in a single HTML file that opens from disk with no server.
The TokenFlow dashboard filtered to two models: a date button, a Filter button and one removable chip reading Model: claude-sonnet-4-20250514 +1, with every figure on the page narrowed to that slice
Filtering, on synthetic demo data. A date button, a + Filter button, and a chip for whatever is actually on. Pick two models and every number narrows, including the plain-language insight at the top.

Fair questions.

Is my data sent anywhere?

Not unless you send it. There is no telemetry and no hosted service. Adapters read token counts and metadata and discard prompt text, source code and file contents, and everything lives in ~/.tokenflow, which you can back up or delete. The paths that can leave the machine are all opt-in and all point at an address you chose: a folder you already sync, a team server you run, your own git remote for receipt notes, and a policy pull from that same team server. The MCP server is local stdio with no socket at all.

How is a receipt bounded?

By branch and by merge. A pull request owns the turns on its branch up to the merge, including work done before it was opened. Turns after the merge are reported beside it. Sessions on a detached HEAD are reported as unattributed, never guessed.

Can I trust the cost estimates?

Every built-in rate records its source URL and fetch date. Service tiers are applied as multipliers per request. Models without a published rate show blank with a reason, and every total states how many turns it priced.

Does the guard need anything installed on a server?

No. It is a Claude Code hook that runs on your machine, reads the live transcript incrementally, and prints its verdict. With no thresholds declared it never blocks.

Why does macOS warn on first launch?

The app is unsigned because there is no Apple Developer account behind this free project. Right-click the app, choose Open, then Open again. The gate appears once.

Point it at your logs. Know what a pull request costs.

Free and open source under MIT. Your tokens never leave your machine.