The export path that actually exists
whoburnedmore does not currently expose --json or --csv flags. Use --dry-run to print the exact aggregate JSON payload without submitting it, extract that JSON, and transform its entries array to CSV with jq.
Reproducible workflow
From local agent logs to analysis-ready files
Supported local logs
The installed CLI discovers supported coding agents and groups their readable records by local date, tool, and model.
Aggregate JSON
--dry-run prints the exact payload that would otherwise be submitted, including required daily entries and optional rollups.
Flat CSV
A deterministic jq transform adds a derived total and protects text cells that spreadsheet apps could otherwise treat as formulas.
Choose the command for the outcome you need
1. Create a private JSON export
The CLI writes progress and a short explanation before the JSON. Capturing stdout directly into a .json file therefore produces invalid JSON. This workflow keeps the raw audit output, starts copying at the first top-level opening brace, applies owner-only permissions to new files, and validates the result.
set -euo pipefail
umask 077
npx whoburnedmore --dry-run > whoburnedmore-dry-run.txt
awk '/^\{/{json=1} json' whoburnedmore-dry-run.txt > whoburnedmore-usage.json
jq empty whoburnedmore-usage.json
echo "Wrote $(jq '.entries | length' whoburnedmore-usage.json) rows"Keep whoburnedmore-dry-run.txt until the validation succeeds, then remove it according to your own retention policy. Do not add --org, --pass, or a friends-board flag to an archival dry run; those scope fields are unrelated to usage analysis and can make the payload less portable.
2. Convert the daily entries to spreadsheet-safe CSV
Install jq from your operating system package manager, then run the transform below. It preserves the four token buckets instead of collapsing away cache behavior, adds totalTokens as a transparent sum, and prefixes model, tool, or origin values that begin with spreadsheet formula characters.
jq -r '
def sheet_safe:
tostring | if test("^[=+@-]") then "\u0027" + . else . end;
["date", "tool", "model", "inputTokens", "outputTokens",
"cacheCreationTokens", "cacheReadTokens", "totalTokens",
"costUSD", "origin", "verified", "requestCount"],
(.entries[] | [
(.date | sheet_safe),
(.tool | sheet_safe),
(.model | sheet_safe),
.inputTokens,
.outputTokens,
.cacheCreationTokens,
.cacheReadTokens,
(.inputTokens + .outputTokens + .cacheCreationTokens + .cacheReadTokens),
.costUSD,
((.origin // "cli") | sheet_safe),
(.verified // false),
(.requestCount // "")
])
| @csv
' whoburnedmore-usage.json > whoburnedmore-usage.csvLossless source
Retain the JSON file for optional rollups and future schema fields.
Portable table
Open the CSV in Excel, Numbers, Sheets, DuckDB, or a notebook.
Safer cells
The transform neutralizes leading formula characters in text columns.
Daily-entry field glossary
Each row represents one local calendar day, source tool, and reported model. Token counts are non-negative integers; cost is an API-equivalent estimate, not a provider invoice or subscription-credit balance.
- date
- The usage day in
YYYY-MM-DDform, bucketed in the collector's local calendar. - tool
- The normalized coding-agent source, such as Claude, Codex, or OpenClaw.
- model
- The model identifier reported by the readable local source. Treat unknown labels as data, not as a pricing guarantee.
- inputTokens
- Non-cached input tokens attributed to this day, tool, and model row.
- outputTokens
- Tokens generated by the model for the grouped row.
- cacheCreationTokens
- Input tokens charged for creating or writing a prompt cache when the source reports that bucket.
- cacheReadTokens
- Tokens served from prompt cache when the source reports them separately.
- costUSD
- Estimated API-equivalent USD cost derived from public model pricing; provider billing is authoritative.
- origin
- Where the aggregate came from, defaulting to
cli; provider-imported rows can use another declared origin. - verified
- Whether the row came from an authoritative provider usage API rather than local self-reported logs.
- requestCount
- Optional structural count of distinct provider requests used as an integrity signal. Older or fallback readers may omit it.
- totalTokens (derived)
- The CSV-only sum of input, output, cache-creation, and cache-read tokens. It is not a native JSON field.
What else can appear in the JSON payload?
3. Validate before automating
Validate the required structure first, then produce a compact grouped summary. A zero exit status from the first command means the export contains a CLI version, at least one daily row, text identifiers, and numeric usage fields.
jq -e '
(.cliVersion | type == "string") and
(.entries | type == "array" and length > 0) and
all(.entries[];
(.date | type == "string") and
(.tool | type == "string") and
(.model | type == "string") and
([.inputTokens, .outputTokens, .cacheCreationTokens,
.cacheReadTokens, .costUSD] | all(type == "number"))
)
' whoburnedmore-usage.json
jq -r '
.entries
| group_by(.tool)
| map({
tool: .[0].tool,
rows: length,
tokens: map(.inputTokens + .outputTokens
+ .cacheCreationTokens + .cacheReadTokens) | add,
costUSD: map(.costUSD) | add
})
' whoburnedmore-usage.json- Compare the grouped token and cost totals with the local or hosted dashboard for the same collection run.
- Store the raw JSON beside the derived CSV so optional and future fields are not discarded.
- Record the CLI version and export time in your report or pipeline log for reproducibility.
- Treat estimated cost as analysis data; reconcile actual spend against the provider invoice.
Useful analyses without inventing precision
Weekly spreadsheet review
Pivot by date and tool, chart totalTokens, and keep costUSD labeled as an API-equivalent estimate.
Budget anomaly alert
Compare each day with a trailing median. Alert on a ratio or absolute threshold, not on an unexplained model-label change alone.
Cache-efficiency review
Track cacheReadTokens against the four-bucket total while preserving cacheCreationTokens as a separate investment.
Warehouse or notebook import
Load JSON directly when you need nested tool, skill, block, or agent rollups; use CSV for the flat daily fact table.
Troubleshooting failed or surprising exports
- The CLI says no usage was found
- Confirm that a supported coding agent has readable local history on this machine. Provider dashboards and encrypted or cloud-only histories are not automatically local logs.
- jq reports a parse error
- Run the two-stage capture exactly as shown. Redirecting
--dry-runstraight to JSON retains the CLI's preface and does not create a valid JSON document. - jq is not installed
- Install it with your operating system package manager and rerun only the conversion. The validated JSON remains the source file, so collection does not need to be repeated.
- A model or token bucket is missing
- Collectors can only preserve what a supported local source exposes. Do not replace an absent model with a guessed one or infer cache buckets from total usage.
- The numbers changed after upgrading
- Record
cliVersion, run a fresh export, and compare rows by date, tool, and model. Reader fixes can change deduplication or source coverage. - CSV totals differ from an invoice
- The file contains API-equivalent cost estimates based on recognized pricing. A subscription, credit plan, promotion, tax, or provider adjustment can bill differently.
Privacy, retention, and reproducibility notes
The export contains aggregate usage, not prompts, source code, tool arguments, or file names. Aggregates can still reveal working patterns and estimated spend, so the commands create owner-readable files with umask 077. Apply your organization's retention and access rules before uploading either file to a spreadsheet service.
--dry-run is the correct machine-readable audit surface because the current CLI prints the exact payload and returns before submission. --local is the stronger privacy choice when you only need to inspect an HTML dashboard on the machine. There is no native fully offline JSON export in the current command set.
This recipe intentionally exports entries as one flat table. Optional block, tool, skill, and agent rollups have different grains; mixing them into daily rows would duplicate totals and make downstream analysis unreliable.
Sources
- whoburnedmore CLI source
Canonical CLI commands and export behavior; use --local when no aggregate upload is wanted.
- Data collection and privacy methodology
Explains what the CLI aggregates, what it does not collect, and the limits of the public cohort.