Goal
Answer the question every Claude Code user has but nobody can: which tool calls and which files actually cost me the most?
At session / workflow / repo granularity. This is the feature that distinguishes burn from every other token tracker — none of them keep tool-call content at ingest, so none of them can do this.
Approach
Two cost components per tool_use:
1. Initial cost — the turn right after the tool call. When the user turn carrying this tool's tool_result is sent back to the model, turn N+1 charges for those tokens as either fresh_input, cacheCreate_5m, or cacheCreate_1h. Allocate turn N+1's (fresh + cacheCreate) across the blocks that entered context between N and N+1, proportional to their size.
2. Persistence cost — the same tool_result stays in context for turn N+2, N+3, … until the session ends or the cache tier evicts. It shows up in those turns' cacheRead. Allocate each subsequent turn's cacheRead across the blocks still in its context by size share.
Total cost of a tool call = initial + sum(persistence). Priced per-tier using the existing @relayburn/analyze pricing loader.
Output (MVP)
burn waste [--since 7d] [--project <path>] [--session <id>] [--workflow <id>]
Three tables:
- Top files by cumulative cost — columns: path, first-read turn, initial tokens, persistence tokens, riding-along-turns, total USD, % of session.
- Top Bash commands by cost — grouped by
argsHash so repeated commands aggregate.
- Top subagent calls by cost —
Agent/Task tool uses with their subagent_type.
Default output: top 10 per table. --all for full. --json for programmatic consumption.
Depends on
#1 (user-turn block sizes).
Acceptance
- Synthetic session test: session containing one 8k-token Read followed by 20 turns that each touch the cache.
burn waste ranks that file first and its reported total cost is within ±10% of hand-computed truth.
- Reported per-tool-call USD totals sum to the session's grand total within ±2% (some overhead — system prompt, tool definitions — won't attribute cleanly; budget for it and report an "unattributed" line).
- Handles edge cases: sidechain subagent turns (separate session context), cache tier transitions (5m → 1h), session resumption after cache eviction.
Stretch
burn waste --suggest — heuristics over the output: "file X was read twice, second read was identical; skipping would have saved $Y." "Bash command Z was run 11 times for the same args; could have been cached." Out of scope for MVP, good follow-up.
Goal
Answer the question every Claude Code user has but nobody can: which tool calls and which files actually cost me the most?
At session / workflow / repo granularity. This is the feature that distinguishes burn from every other token tracker — none of them keep tool-call content at ingest, so none of them can do this.
Approach
Two cost components per
tool_use:1. Initial cost — the turn right after the tool call. When the user turn carrying this tool's
tool_resultis sent back to the model, turn N+1 charges for those tokens as eitherfresh_input,cacheCreate_5m, orcacheCreate_1h. Allocate turn N+1's (fresh + cacheCreate) across the blocks that entered context between N and N+1, proportional to their size.2. Persistence cost — the same tool_result stays in context for turn N+2, N+3, … until the session ends or the cache tier evicts. It shows up in those turns'
cacheRead. Allocate each subsequent turn'scacheReadacross the blocks still in its context by size share.Total cost of a tool call = initial + sum(persistence). Priced per-tier using the existing
@relayburn/analyzepricing loader.Output (MVP)
Three tables:
argsHashso repeated commands aggregate.Agent/Tasktool uses with theirsubagent_type.Default output: top 10 per table.
--allfor full.--jsonfor programmatic consumption.Depends on
#1 (user-turn block sizes).
Acceptance
burn wasteranks that file first and its reported total cost is within ±10% of hand-computed truth.Stretch
burn waste --suggest— heuristics over the output: "file X was read twice, second read was identical; skipping would have saved $Y." "Bash command Z was run 11 times for the same args; could have been cached." Out of scope for MVP, good follow-up.