Commit graph

11 commits

Author SHA1 Message Date
Resham Joshi
039a4e483e
fix(overview): group thousands in the integer part of costs only (#1714)
The comma-grouping regex in overview and devices also matched the fraction,
so $0.0028 rendered as $0.0,028. A lookbehind now skips digits after the
decimal point.
2026-10-10 07:05:12 +02:00
ozymandiashh
878eba25e7
Mark local Cursor dollars in overview as estimates, not the bill (#1615)
Local Cursor rows are priced from IDE composer bubbles, which never see
the context Cursor re-sends on every request, so the figure can sit far
below the dashboard bill (about 2% on the account that reported #1545),
yet overview printed it like any exact total. The import from #1558
answers this for the time an export covers; outside it nothing said the
number was not the bill.

overview now prints one dim line under the bottom line whenever the
period still holds local cursor/cursor-agent dollars that no import
covers — covered local calls are already dropped at serve time, so any
non-imported Cursor call that survives the walk is an uncovered
estimate. The line names the amount and points at
codeburn import cursor <file.csv>.
2026-10-05 11:36:18 +02:00
iamtoruk
df38e63849 fix(usage): fold Windows case in spend identity, qualify --json counts, drop scratch tests 2026-09-07 14:56:32 -07:00
Aditya Vikram Singh
f5fd47e83d fix(usage): preserve project identity and qualify incomplete session counts 2026-09-07 22:02:54 +05:30
Aditya Vikram Singh
4228c87595 fix(models): treat subscription SKUs as honestly $0
Unpriced warnings were firing on flat-rate product ids and telling
users to model-alias them, which invents spend.
2026-08-20 01:35:39 +05:30
ozymandiashh
057de97360
feat(budget): spend budgets with overview display and scriptable --check (#562)
Ported onto current main after the locale-grouping change in overview.ts;
review follow-ups included:
- explicit note: budgets count the full would-be API cost including
  subscription-proxied spend, consistent with the overview Cost total
- percent display floors the raw value on both surfaces, so 99.6 percent
  renders as 99 percent in warn state and 100 percent appears only when the
  state is over; regression tests cover the boundary on overview and --check
- overview keeps main's en-US locale-grouped formatting and the
  unpriced-model warning block; the budget line renders after it
2026-07-16 11:10:16 -07:00
Resham Joshi
3163ccb5c4
fix(report): surface estimated costs distinctly (#688)
* fix(report): surface estimated costs distinctly

Providers that estimate tokens or price (kiro, cursor, warp, copilot,
grok, hermes, codewhale, and the codex proxy path) set costIsEstimated
on their parsed calls, but the flag died at the parser boundary: it was
never carried onto ParsedApiCall or into the session aggregates, so a
figure whose tokens were synthesized from content length rendered with
the same authority as a metered one.

Plumb the truth through, mirroring the savingsUSD/isLocalSavings pattern:
a call-level boolean (ParsedApiCall.isEstimated, CachedCall.isEstimated,
persisted so it survives the session-cache round trip) and an additive
aggregate amount (estimatedCostUSD on the model breakdown, session, and
project totals, plus PeriodData and the menubar payload). The amount is
carried rather than a bare boolean so a row that is mostly metered with a
small estimated slice is not indistinguishable from a fully guessed one.

Display: report (TUI) and overview per-model rows prefix the cost with a
tilde and print one legend line; the MCP tables carry the same marker and
legend, and the machine surfaces (report --json, MCP get_usage, menubar /
web payload) expose estimatedCostUSD. Totals math is unchanged; the flag
is display/metadata only.

Bump PROVIDER_PARSE_VERSIONS for every provider that sets the flag so
already-cached sessions reparse once and pick it up. Copilot is excluded:
it is a durable provider, so changing its env fingerprint would discard
OTel cache entries whose source rows may already be pruned.

Also fix the cross-provider project merge, which summed totalCostUSD but
dropped merged-in projects' totalEstimatedCostUSD, undercounting the
project/period estimated total (the same latent gap still affects
totalSavingsUSD, left untouched here).

* test(parser): pin estimated dollars through the cross-provider merge

The merge fix for dropped totalEstimatedCostUSD was not covered: deleting
the summing line left every test green. Extract the merge into an exported
mergeProjectsByCrossProviderKey (no behavior change) and pin both the
measured-plus-estimated and both-estimated merge cases.

* docs(parser): honest merge-comment scope and load-bearing overwrite note

Re-review nits: the merge doc claimed all additive totals are summed there
while totalSavingsUSD still is not (pre-existing gap, tracked separately)
and totalProxiedCostUSD is re-derived post-merge; say so. Mark the
buildPeriodData overwrite in usage-aggregator as load-bearing for the
estimated marker so nobody optimizes it away trusting the daily cache.
2026-07-16 10:46:21 -07:00
AgentSeal
231e7cc0d4 feat(report): surface unpriced models across overview, JSON, dashboard, and MCP
Models missing from the pricing tables silently contributed $0 to every
total with no indication anywhere (the warning was gated behind
CODEBURN_VERBOSE). Add render-time detection that flags aggregated model
rows with usage but $0 cost whose pricing lookup fails right now, and
surface it in overview, report/today/month JSON (unpricedModels), the
TUI By Model panel, and the MCP get_usage summary.

Render-time detection covers cached sessions (cost is computed at parse
time) and heals as soon as pricing data, an alias, or a price override
arrives. Rows with real cost are never flagged: aggregation keys rows by
display name, which the pricing lookup misses; $0 display-name rows are
reverse-resolved to their raw id before flagging so sessions cached
before their model's pricing landed don't get a misleading alias hint.
Local models and model-savings mappings stay excluded: $0 is correct
for them.

Fixes #638
2026-07-09 21:04:56 +02:00
ozymandiashh
a12db6e549
Show real Claude project leaf names; stop stray-.git over-grouping (#540)
The 'By Project' panel collapsed sibling Claude Code projects to a parent
folder in two cases:

1) resolveCanonicalProjectPath walked up to ANY ancestor .git and used it as
   the canonical project. A stray .git in a parent of several projects (a
   dotfiles bare repo, an accidental git init) made every sibling resolve to
   that parent ('Projects'/'home'). Now only a real linked worktree (.git is a
   FILE pointing at <main>/.git/worktrees/<name>) canonicalizes to its main
   repo; an ordinary repo or a stray ancestor .git keeps the session's own cwd
   as the project. Genuine worktree grouping is preserved.

2) When a Claude session has no cwd metadata, the dir slug was unsanitized by
   replacing every '-' with '/', inventing path segments that overview then
   split on, so 'Projects-Content-OS' rendered as 'os'. The lossy slug is now
   kept intact, and overview only basenames ABSOLUTE paths.

Fixes #493
2026-06-21 22:42:19 +02:00
Resham Joshi
98befc1c8b
feat(overview): cache in/out tokens table, roomier tables (#535)
* feat(overview): cache in/out tokens table, roomier tables

Add a Tokens breakdown table (Input / Output / Cache in / Cache out /
Total with share %) so cache write/read are shown clearly instead of
crammed into the Totals line, and widen table cell padding to 2 spaces so
columns aren't congested.

* feat(overview): full comma-grouped numbers for a precise, spacious look

Render token counts as full thousands-grouped integers (e.g.
3,926,923,819) instead of abbreviated M/B, so the roomy tables read like
a precise statement. Update the overview test to match.
2026-06-20 19:22:59 +02:00
Resham Joshi
c55dba2dd2
feat(overview): plain-text monthly usage overview command (#528)
* feat(overview): plain-text monthly usage overview command

Add 'codeburn overview', a copy-pasteable text report. Defaults to the
current month, with --from/--to to filter and --no-color for plain
output. Renders Totals, By tool, Top models, Highest-value days, Top
projects, a daily table, By activity, and Tools, with colored section
headings (stripped under --no-color or when piped).

Reuses the existing session aggregation. Cost gains thousands
separators and tokens roll up to a B unit for readability via
display-only wrappers, without changing the shared formatters. Project
names use the path basename instead of the sanitized full path.

* fix(cli): exit cleanly on EPIPE when the stdout pipe closes early

Piping output to a reader that closes early (| head, quitting less, a
missing command) made stdout writes throw EPIPE and crash with an
unhandled error event. Handle EPIPE on process.stdout and exit 0 so
piping the overview and other commands behaves normally.

* docs(readme): document and highlight the overview command

Add a 'Your month at a glance' section featuring codeburn overview with
examples and sample output, a Commands-table entry, and the provider
flag note.
2026-06-20 11:46:45 +02:00