Skip to content

feat: generalize Usage & Spend across tools and model providers - #2322

Closed
Yuxin-Qiao wants to merge 30 commits into
steipete:mainfrom
Yuxin-Qiao:feat/model-centric-usage-spend
Closed

feat: generalize Usage & Spend across tools and model providers#2322
Yuxin-Qiao wants to merge 30 commits into
steipete:mainfrom
Yuxin-Qiao:feat/model-centric-usage-spend

Conversation

@Yuxin-Qiao

@Yuxin-Qiao Yuxin-Qiao commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Summary

Generalizes Usage & Spend into a tool- and provider-agnostic reporting pipeline.

This is not a MiniMax-only integration or a Claude Code-only workflow. MiniMax and Claude Code are regression fixtures for a broader requirement: users can run the same model through different IDEs, desktop apps, and CLIs, while billing still belongs to the real subscription or API provider.

What changed

Generic source architecture

  • Provider descriptors declare whether they can supply token/cost history.
  • Local history uses stable adapter identifiers instead of a closed dashboard switch.
  • Built-in local adapters cover Antigravity, Gemini CLI, Kimi Code, MiniMax Code, OpenCode, and Qwen Code; existing Codex/Pi/Claude histories continue through the shared snapshot model.
  • New tools can register a parser/descriptor without adding tool-specific business logic to every dashboard view.
  • Scans are bounded, cancellable, and run off the main actor; SQLite-backed tools use WAL-safe reads.

Billing attribution based on evidence

  • A model name is no longer treated as proof of who billed a request.
  • Third-party usage moves away from its harness only when the source retained explicit billing-provider/routing evidence.
  • Bundled models remain with the tool subscription that supplied them.
  • Separate credential/account scopes remain separate subscription rows.
  • Subscription labels reject API balance, credit, and raw spend labels.

Honest partial-data behavior

  • Unknown pricing, unknown currency, missing token dimensions, and incomplete model breakdowns remain partial/unpriced.
  • Missing values are never converted to $0.
  • Unpriced groups preserve their token and model history while omitting fabricated cost series.
  • Multi-currency totals are not silently combined.
  • MiniMax has an official-price fallback; Qwen pricing uses the correct Alibaba route instead of an unrelated vendor rate.

Dashboard and interaction

  • “By subscription” rows use compact provider/plan presentation.
  • “By model” and “By tool” share consistent semantic typography, icons, currency formatting, ranking controls, and compact charts.
  • Token and spend modes drive both the chart scale and the ranking metric.
  • Cumulative charts frame the active metric’s observed range instead of reserving months of empty space.
  • Dense charts use stable nearest-day selection and a pinned detail state.
  • Tool groups show model hierarchy without repeated full-width “zebra” bars and expose same-model tool comparisons only when the evidence is comparable.
  • Startup performs a delayed utility-priority warmup so the first visit is useful without aggressive polling.

Reliability

  • Quota-depleted notifications are persisted by provider, source, account, and reset cycle to avoid firing on every launch.
  • Transient missing quota data does not clear the durable notification state.
  • Registry replacement is synchronized and deterministic.
  • Arithmetic and cost aggregation guard overflow and non-finite values.

Scope and extension boundary

The dashboard automatically handles any provider that emits the shared structured token/cost snapshot. A tool with a new proprietary on-disk format still needs one bounded local adapter; until that exists, the UI reports unavailable/partial data rather than guessing. This keeps adding ZCode, Qoder, Zed, or another tool localized to its parser and descriptor instead of duplicating dashboard logic.

Visual proof

These screenshots exercise the implemented dashboard with local-history data across priced, partially priced, and fully unpriced states. They verify presentation and state handling; local estimated spend can differ from provider invoices.

Subscription ownership and tool grouping

Subscription rollup Models grouped by tool
Usage and Spend subscription rollup with six priced subscriptions and one explicitly unpriced Cursor subscription Models grouped by tool, including a same-model comparison between Kimi Code CLI and Cursor
Known estimates are summed by subscription while unpriced sources remain visible instead of becoming $0. Each tool keeps its observed model hierarchy; the same-model comparison surfaces comparable Kimi K3 activity across Kimi Code CLI and Cursor without inventing Cursor pricing.

Model analysis: tokens and estimated spend

Ranked by tokens Ranked by estimated spend
By-model token history with a selected-day token bucket breakdown and token ranking By-model estimated-spend history with a selected-day pricing-completeness indicator and spend ranking
Token mode drives the chart, selected-day bucket breakdown, percentages, and ranking. Spend mode switches the chart scale and ranking metric; the selected unpriced Kimi K3 row is explicitly Unavailable, not zero.

Daily source and model drill-down

Daily estimated-spend chart with an August 1 drill-down from Codex Desktop into individual models

The daily view preserves source ownership, then drills into per-model estimates. A known zero-cost model remains $0.00, which is distinct from missing pricing.

Token activity modes

Daily Weekly Cumulative
Daily token activity heatmap Weekly token activity heatmap Cumulative token activity heatmap
Calendar-style daily intensity. One column per week. Running-total intensity.

Fully unpriced history

Unpriced-only usage state that keeps token and subscription history visible while spend is unavailable

When every contributing source lacks pricing, the dashboard still shows 33K tracked tokens and both subscriptions, while the headline and chart explicitly report Pricing unavailable / Spend unavailable.

Evidence boundary

  • The screenshots cover subscription, tool, model, day-detail, activity, partial-pricing, and no-pricing presentation states.
  • They show that unavailable prices remain unavailable instead of being fabricated as zero.
  • They are UI evidence, not proof that a local estimate equals an external provider bill.

Validation

  • make check
  • make test
  • focused dashboard, attribution, scanner, notification-persistence, Groq menu, Qwen Code, and date/currency tests
  • release build and code-sign verification through ./Scripts/compile_and_run.sh

The release app launches successfully. The visual proof above covers the implemented priced, partially priced, and fully unpriced dashboard states; it does not claim equality with external provider bills.

Split status

This umbrella PR is being split into independently mergeable pieces. Land in order, then close this PR:

  1. feat(core): local real-usage data layer — unified event engine + registerable scanners + pricing foundation #2527 — local real-usage data layer (unified event engine, registerable scanners, pricing foundation)
  2. feat: add standalone token activity heatmap #2548 — standalone token activity heatmap
  3. feat(spend): model-centric Models view with per-tool breakdown and billing attribution #2569 — model-centric Models view with per-tool breakdown and billing attribution

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0bb85adb5a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Sources/CodexBar/PreferencesSpendDashboardPane.swift
@clawsweeper clawsweeper Bot added proof: sufficient Contributor real behavior proof is sufficient. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. P2 Normal priority bug or improvement with limited blast radius. merge-risk: 🚨 other 🚨 Merging this PR has meaningful risk outside the owned taxonomy. labels Jul 19, 2026
@clawsweeper

clawsweeper Bot commented Jul 19, 2026

Copy link
Copy Markdown

Codex review: needs real behavior proof before merge. Reviewed August 2, 2026, 12:22 PM ET / 16:22 UTC.

ClawSweeper review

What this changes

This branch generalizes Usage & Spend with local tool-history ingestion, provider-aware billing attribution, model and tool analysis, a token-activity heatmap, dashboard UI changes, and quota-notification persistence.

Merge readiness

Blocked until stronger real behavior proof is added - 8 items remain

Keep this PR open for maintainer direction rather than closing it: current main does not contain its new local-scanner, heatmap, or Models-view capability, but the branch duplicates three explicitly declared, still-open split PRs. The safer path is to choose one authoritative landing plan before any merge; likely related person: Peter Steinberger (high confidence) from the current Usage & Spend history.

Priority: P2
Reviewed head: a31620793ca62c50727aa8b84b82cfb2e1dd53ae
Owner decision: Required. See Decision needed.

Review scores

Measure Result What it means
Overall readiness 🦐 gold shrimp (3/6) The implementation and UI evidence are substantial, but current-head proof is incomplete and the split plan leaves the merge path unresolved.
Proof confidence 🦐 gold shrimp (3/6) Needs stronger real behavior proof before merge: The four prepared screenshots visibly demonstrate earlier UI states but target commit 7dc8a0b rather than current head a316207 and do not prove current-head local scanning, attribution, or quota persistence; provide redacted current-head runtime output, logs, or a recording. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Patch quality 🦐 gold shrimp (3/6) 2 actionable review findings remain.

Verification

Check Result Evidence
Real behavior Needs proof Needs stronger real behavior proof before merge: The four prepared screenshots visibly demonstrate earlier UI states but target commit 7dc8a0b rather than current head a316207 and do not prove current-head local scanning, attribution, or quota persistence; provide redacted current-head runtime output, logs, or a recording. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed 5 items Current main baseline: Current main has the existing SpendDashboard controller, model, and preferences pane, but searches found no activity-heatmap, billing-attribution, local-scanner-registry, or Models-view implementation from this PR.
Feature-history owner: The existing preferences dashboard lines trace to the v0.46.0 baseline, and recent main history includes follow-up Usage & Spend fixes by Peter Steinberger.
Release/current-main provenance: v0.46.0 points at the dashboard baseline commit; current main is later at 1fd7ec8. Neither establishes that this PR's new local scanner, heatmap, or Models feature has landed.
Findings 2 actionable findings [P1] Remove heatmap code now owned by the split PR
[P1] Remove scanner and attribution work owned by split PRs
Security None None.

How this fits together

CodexBar gathers provider API data and local tool-history snapshots, aggregates them into usage and cost records, and renders them in the Usage & Spend preferences dashboard. This PR changes both the local-data/attribution path and the dashboard surfaces that present the resulting history.

flowchart LR
A[Provider APIs and local tool histories] --> B[Usage and cost snapshots]
B --> C[Scanning and billing attribution]
C --> D[Usage and Spend aggregation]
D --> E[Preferences dashboard]
D --> F[Quota notification state]
Loading

Decision needed

Question Recommendation
Should this umbrella branch remain the repository's integration path, or should the three declared split PRs be the sole landing path for the Usage & Spend feature? Use the focused split PRs: Review and land the data layer, heatmap, and Models scopes independently, then close the umbrella branch as superseded.

Why: The split PRs and the umbrella branch intentionally cover the same central capability; only maintainers can choose the preferred merge, review, and rollback boundary.

Before merge

  • Add real behavior proof - Needs stronger real behavior proof before merge: The four prepared screenshots visibly demonstrate earlier UI states but target commit 7dc8a0b rather than current head a316207 and do not prove current-head local scanning, attribution, or quota persistence; provide redacted current-head runtime output, logs, or a recording. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
  • Remove heatmap code now owned by the split PR (P1) - This branch still adds the standalone activity heatmap even though its own split plan assigns that implementation to feat: add standalone token activity heatmap #2548. Keeping both landing paths would create duplicate ownership and divergent behavior; remove it here or explicitly abandon the split plan.
  • Remove scanner and attribution work owned by split PRs (P1) - This umbrella still includes scanner/pricing and Models/attribution implementation that its body assigns to separate open PRs. Preserve one authoritative path before merge; otherwise future fixes and review must be duplicated across branches.
  • Resolve merge risk (P1) - Merging this 127-file umbrella branch while the same work remains in three open split PRs would create competing ownership, review, and revert paths for scanners, pricing, heatmap, and Models behavior.
  • Resolve merge risk (P1) - The persistent quota-notification changes and altered billing/subscription attribution can affect existing provider/account behavior; current-head real-machine proof does not cover those paths.
  • Resolve merge risk (P1) - The prepared screenshots are from an earlier commit and cannot establish current-head behavior for local scanning, billing attribution, or notification persistence.
  • Complete next step (P2) - Maintainers must select a single landing path before a safe automated repair can remove duplicated feature scopes.

Findings

  • [P1] Remove heatmap code now owned by the split PR — Sources/CodexBar/SpendActivityHeatmap.swift:1
  • [P1] Remove scanner and attribution work owned by split PRs — Sources/CodexBar/SpendBillingAttribution.swift:1
Agent review details

Security

None.

Review metrics

Metric Value Why it matters
Patch size 18,350 added, 645 removed, 127 files The branch combines core ingestion, persistent state, dashboard UI, resource assets, localization, and tests in one merge unit.
Declared split scopes 3 open PRs The PR body assigns its data layer, heatmap, and Models/attribution functionality to separate open landing paths.

Merge-risk options

Maintainer options:

  1. Remove split-owned implementation (recommended)
    If this PR remains open, reduce it to an integration-only remainder by removing work already assigned to the focused split PRs.
  2. Adopt the umbrella branch
    Maintainers may intentionally accept the broader merge surface, but should first close the three competing split PRs to restore one implementation path.
  3. Pause this branch
    Pause the umbrella PR until the split landing plan is resolved, avoiding parallel fixes for the same feature surfaces.

Technical review

Best possible solution:

Use one focused landing sequence: review the data layer, heatmap, and Models work in their declared split PRs, then close this umbrella branch once no unique, necessary remainder remains.

Do we have a high-confidence way to reproduce the issue?

Not applicable: this is a feature PR rather than a report of broken established behavior. The available screenshots show earlier UI states, but not current-head live scanner, attribution, or notification behavior.

Is this the best way to solve the issue?

No: the umbrella branch is not the best landing path while it duplicates the three focused, still-open PRs named in its own body. One authoritative split sequence is more reviewable and reversible.

Full review comments:

  • [P1] Remove heatmap code now owned by the split PR — Sources/CodexBar/SpendActivityHeatmap.swift:1
    This branch still adds the standalone activity heatmap even though its own split plan assigns that implementation to feat: add standalone token activity heatmap #2548. Keeping both landing paths would create duplicate ownership and divergent behavior; remove it here or explicitly abandon the split plan.
    Confidence: 0.99
  • [P1] Remove scanner and attribution work owned by split PRs — Sources/CodexBar/SpendBillingAttribution.swift:1
    This umbrella still includes scanner/pricing and Models/attribution implementation that its body assigns to separate open PRs. Preserve one authoritative path before merge; otherwise future fixes and review must be duplicated across branches.
    Confidence: 0.99

Overall correctness: patch is incorrect
Overall confidence: 0.97

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 1fd7ec83b5d9.

Labels

Label justifications:

  • P2: This is a substantial reporting feature with normal user impact, but no demonstrated urgent regression or outage.
  • merge-risk: 🚨 compatibility: The branch changes existing dashboard semantics and persists quota-alert state across upgrades.
  • merge-risk: 🚨 auth-provider: It changes how provider, account, subscription, and billing-owner data are attributed and displayed.
  • merge-risk: 🚨 availability: New local scans and asynchronous dashboard refresh paths can make a provider's usage history unavailable or stale if they fail.
  • rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦐 gold shrimp and patch quality is 🦐 gold shrimp.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs stronger real behavior proof before merge: The four prepared screenshots visibly demonstrate earlier UI states but target commit 7dc8a0b rather than current head a316207 and do not prove current-head local scanning, attribution, or quota persistence; provide redacted current-head runtime output, logs, or a recording. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
  • proof: 📸 screenshot: Contributor real behavior proof includes screenshot evidence. The four prepared screenshots visibly demonstrate earlier UI states but target commit 7dc8a0b rather than current head a316207 and do not prove current-head local scanning, attribution, or quota persistence; provide redacted current-head runtime output, logs, or a recording.

Evidence

What I checked:

Likely related people:

  • Peter Steinberger: Current-main blame assigns the existing dashboard baseline to Peter Steinberger, and recent history includes related Usage & Spend fixes. (role: recent area contributor; confidence: high; commits: b1170d83, 27a314f3, e1e2cc20; files: Sources/CodexBar/PreferencesSpendDashboardPane.swift, Sources/CodexBar/SpendDashboardController.swift, Sources/CodexBar/SpendDashboardModel.swift)

Rank-up moves

Optional improvements that raise the rating; they are not merge blockers.

  • Choose one authoritative landing path for the three declared split scopes.
  • Remove split-owned code from this umbrella branch or close the competing split PRs.
  • Add redacted current-head runtime proof for scanning, attribution, and quota-persistence behavior.

Rating scale

Score Internal tier Crab rank Meaning
6/6 S 🦀 challenger crab Exceptional readiness
5/6 A 🦞 diamond lobster Very strong readiness
4/6 B 🐚 platinum hermit Good normal PR; ordinary maintainer review
3/6 C 🦐 gold shrimp Useful, but confidence is limited
2/6 D 🦪 silver shellfish Proof or implementation needs work
1/6 F 🧂 unranked krab Not merge-ready
N/A NA 🌊 off-meta tidepool Rating does not apply

Overall follows the weaker of proof and patch quality.
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

Workflow

  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

History

Review history (40 earlier review cycles; latest 8 shown)
  • reviewed 2026-08-01T21:41:06.044Z sha 1c765c1 :: needs real behavior proof before merge. :: [P1] Remove components now owned by the split PRs
  • reviewed 2026-08-01T21:48:43.695Z sha 1c765c1 :: needs real behavior proof before merge. :: [P1] Remove components now owned by the split PRs
  • reviewed 2026-08-01T22:36:26.821Z sha 5478f2f :: needs real behavior proof before merge. :: [P1] Remove components now owned by the split PRs
  • reviewed 2026-08-01T22:46:12.043Z sha 5478f2f :: needs real behavior proof before merge. :: [P1] Remove components now owned by the split PRs
  • reviewed 2026-08-02T02:11:30.816Z sha a316207 :: needs real behavior proof before merge. :: [P1] Remove the heatmap implementation now owned by the split PR | [P1] Remove scanner and pricing foundation now owned by the data-layer split
  • reviewed 2026-08-02T02:20:03.306Z sha a316207 :: needs real behavior proof before merge. :: [P1] Remove the heatmap implementation now owned by the split PR | [P1] Remove scanner and pricing work now owned by the data-layer split
  • reviewed 2026-08-02T03:58:56.312Z sha a316207 :: needs real behavior proof before merge. :: [P1] Remove the heatmap implementation owned by the split PR | [P1] Remove scanner and pricing work owned by the data-layer split
  • reviewed 2026-08-02T11:30:46.773Z sha a316207 :: needs real behavior proof before merge. :: [P1] Remove heatmap code now owned by the split PR | [P1] Remove scanner and attribution work owned by the split PRs

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 18a58d70fb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Sources/CodexBar/SpendDashboardController.swift Outdated
@Yuxin-Qiao
Yuxin-Qiao force-pushed the feat/model-centric-usage-spend branch 2 times, most recently from 811bc6f to 92714de Compare July 19, 2026 08:36

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 92714def17

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Sources/CodexBar/PreferencesSpendModelsView.swift Outdated
@Yuxin-Qiao
Yuxin-Qiao force-pushed the feat/model-centric-usage-spend branch 2 times, most recently from 37f7807 to fe82c42 Compare July 19, 2026 09:25

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 37f78075d2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Sources/CodexBarCore/Providers/Kimi/KimiCodeSessionScanner.swift Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fe82c42ca0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Sources/CodexBarCore/Providers/Kimi/KimiCodeSessionScanner.swift Outdated
@Yuxin-Qiao
Yuxin-Qiao force-pushed the feat/model-centric-usage-spend branch from fe82c42 to ff057d5 Compare July 19, 2026 09:32

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ff057d5869

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Sources/CodexBar/SpendDashboardController.swift
Implements Scope B from steipete#2257.

- Replace per-currency "model breakdown unavailable" panel with an
  embedded Models card showing daily stacked usage bars and a full
  model ranking.
- Merge models across providers by trimmed, case-insensitive exact
  name matching; keep token aggregation separate from cost to avoid
  cross-currency sums.
- Add independent 7d / 30d / All range control for the model card
  without affecting the existing Overview 30d spend semantics.
- Add Kimi Code session scanner so Kimi token-only history can
  contribute to the cross-provider model analysis.
- Localize new UI strings across all supported languages.
- Adopt upstream completeModelSummaries filtering for models list while
  keeping modelAnalysis built from all summaries for partial coverage.
- Regenerate CodexParserHash for merged Vendored/CostUsage sources.

Tests: SpendModelsPresentationTests, SpendDashboardModelTests,
SpendDashboardKimiModelTests, KimiCodeSessionScannerTests,
CostUsageDailyReportMergeTests, ShareStatsTests,
UserFacingLocalizationCoverageTests (63 tests).

Co-authored-by: Cursor <cursoragent@cursor.com>
@Yuxin-Qiao
Yuxin-Qiao force-pushed the feat/model-centric-usage-spend branch from ff057d5 to 7321949 Compare July 19, 2026 09:57
@clawsweeper clawsweeper Bot added status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Jul 19, 2026
… activity heatmap

Spend accuracy:
- Expand Codex pricing fingerprint to all third-party providers routed through the
  Codex/Claude-compatible endpoints (deepseek, minimax, moonshotai, kimi-for-coding)
  so stale caches invalidate when models.dev pricing lands — fixes "Spend unavailable".
- Daily-sum cost fallback: when a provider's aggregate cost figure diverges from the
  local per-day logs, sum per-day costs instead of voiding the whole provider.

New tool coverage (by-tool / by-model):
- OpenCode: read opencode.db (SQLite) in addition to JSONL messages, extracting
  model/tokens/cost via json_extract; cross-source dedup by id + fingerprint.
- Add MiniMax, Gemini session scanners and provider registration.

Token activity heatmap:
- GitHub/ChatGPT-style 52-week grid with hover tooltip (date + token count).
- Cache SpendActivitySeries; binary-search nearest day in models chart hover/click.

Refactor & quality:
- Extract LocalSnapshotSource to dedupe per-provider load blocks; ScanContext to
  thread shared scan state; split third-party Claude pricing into its own file.
- Complete i18n: fill the new dashboard keys across all 22 locales.

Co-authored-by: Cursor <cursoragent@cursor.com>
@Yuxin-Qiao Yuxin-Qiao changed the title feat: model-centric usage & spend view across providers (Scope B from #2257) feat: a best-in-class Usage & Spend dashboard — model/tool views, accurate spend, token activity heatmap Jul 26, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 208945060f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Sources/CodexBarCore/Providers/OpenCode/OpenCodeSessionScanner.swift Outdated
Comment thread Sources/CodexBarCore/Providers/OpenCode/OpenCodeSessionScanner.swift Outdated
Comment thread Sources/CodexBar/SpendClientsView.swift Outdated
Comment thread Sources/CodexBar/SpendClientsView.swift Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3d1b64f16f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Sources/CodexBar/SpendBillingAttribution.swift
Comment thread Sources/CodexBar/SpendClientsView.swift Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cd94199770

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Sources/CodexBar/SpendBillingAttribution.swift Outdated
Comment thread Sources/CodexBarCore/Providers/Gemini/GeminiSessionScanner.swift
Comment thread Sources/CodexBarCore/Providers/Antigravity/AntigravitySessionScanner.swift Outdated
@Yuxin-Qiao
Yuxin-Qiao force-pushed the feat/model-centric-usage-spend branch from cd94199 to 2cf1d84 Compare July 26, 2026 17:49
@Yuxin-Qiao
Yuxin-Qiao force-pushed the feat/model-centric-usage-spend branch from 48fdd0e to acb9821 Compare August 1, 2026 18:55

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: acb98219e8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Sources/CodexBarCore/Providers/Kimi/KimiCodeSessionScanner.swift Outdated
Comment thread Sources/CodexBarCore/Providers/Gemini/GeminiSessionScanner.swift Outdated
@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. labels Aug 1, 2026
… scan-limit signaling

Addresses the re-review batch: OpenCode provider routing evidence, MiniMax/Qwen/OpenCode/Kimi partial-pricing aggregates, Antigravity SQLITE_BUSY and protobuf bounds, Qwen oversized records, Kimi/OpenCode file limits, and billing-attribution merged costs.
@Yuxin-Qiao
Yuxin-Qiao force-pushed the feat/model-centric-usage-spend branch from acb9821 to d41f830 Compare August 1, 2026 19:37
@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. labels Aug 1, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d41f830058

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Sources/CodexBar/SessionQuotaNotifications.swift Outdated
Comment thread Sources/CodexBarCore/CostUsageModels.swift Outdated
Comment thread Sources/CodexBarCore/Providers/Gemini/GeminiSessionScanner.swift Outdated
@Yuxin-Qiao
Yuxin-Qiao force-pushed the feat/model-centric-usage-spend branch from 92ec223 to 0a487b3 Compare August 1, 2026 20:24

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

let entryDerivedTotalTokens = (entry.inputTokens ?? 0)
+ (entry.cacheReadTokens ?? 0)
+ (entry.cacheCreationTokens ?? 0)
+ (entry.outputTokens ?? 0)

P2 Badge Use checked arithmetic for merged entry totals

Fresh evidence beyond the earlier model-breakdown overflow fix is that the top-level EntryAccumulator still adds accepted buckets with trapping arithmetic. An entry with inputTokens == Int.max and any positive output/cache bucket crashes immediately while evaluating entryDerivedTotalTokens—even when it already supplies an explicit totalTokens—so merging native and Pi reports can terminate the usage scan instead of marking the aggregate unavailable.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Sources/CodexBar/SpendBillingAttribution.swift Outdated
Comment thread Sources/CodexBarCore/Providers/QwenCloud/QwenCodeSessionScanner.swift Outdated
Comment thread Sources/CodexBarCore/Providers/OpenCode/OpenCodeSessionScanner.swift Outdated
Comment thread Sources/CodexBarCore/Providers/OpenCode/OpenCodeSessionScanner.swift Outdated
@Yuxin-Qiao
Yuxin-Qiao force-pushed the feat/model-centric-usage-spend branch from 0a487b3 to dfc9b43 Compare August 1, 2026 20:48

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: dfc9b4301b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Sources/CodexBar/UsageStore+SessionQuotaTransition.swift
Comment thread Sources/CodexBarCore/Providers/Kimi/KimiCodeSessionScanner.swift Outdated
@Yuxin-Qiao
Yuxin-Qiao force-pushed the feat/model-centric-usage-spend branch from dfc9b43 to 1c765c1 Compare August 1, 2026 21:37

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1c765c1b61

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Sources/CodexBar/SpendDashboardModel.swift Outdated
Comment thread Sources/CodexBarCore/Providers/Antigravity/AntigravitySessionScanner.swift Outdated
@Yuxin-Qiao
Yuxin-Qiao force-pushed the feat/model-centric-usage-spend branch from 1c765c1 to 5478f2f Compare August 1, 2026 22:32

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5478f2fdc9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Sources/CodexBar/SpendDashboardModel.swift Outdated
Comment thread Sources/CodexBarCore/Providers/OpenCode/OpenCodeSessionScanner.swift Outdated
Comment thread Sources/CodexBarCore/Providers/Gemini/GeminiSessionScanner.swift Outdated
Comment thread Sources/CodexBarCore/Providers/QwenCloud/QwenCodeSessionScanner.swift Outdated
@Yuxin-Qiao
Yuxin-Qiao force-pushed the feat/model-centric-usage-spend branch from 5478f2f to a316207 Compare August 2, 2026 02:07

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a31620793c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

input: input,
identity: identity,
tokens: 0)
tool.cost += entryCost

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Convert costs in daily spend details

When a preferred-currency conversion produces summary.costMultiplier != 1, the chart and provider totals are converted, but this accumulator keeps the source-currency amount; the model costs added below are likewise unscaled. Fresh evidence beyond the fixed model-analysis path is that clicking a converted chart bar therefore shows raw USD tool/model values formatted as the target currency. Apply summary.costMultiplier to both the entry and breakdown costs before accumulating the daily detail.

Useful? React with 👍 / 👎.

else {
return false
}
let uncachedInput = max(0, promptTotal - cacheRead)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reject Qwen cache counts above prompt totals

When a malformed or changed Qwen record reports cachedContentTokenCount > promptTokenCount, this clamp accepts the record with zero uncached input and then adds the full cache count, even though the preceding invariant states that cached tokens are a subset of the prompt. The established snapshot consequently overcounts input and estimates cost from an impossible token split; reject such a record by requiring cacheRead <= promptTotal rather than clamping the subtraction.

Useful? React with 👍 / 👎.

Comment on lines +892 to +894
} else {
self.overflowingTokenBuckets = true
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Withhold merged costs after floating-point overflow

When two same-day reports contain individually finite costs whose sum overflows—for example two Double.greatestFiniteMagnitude values—this branch marks the token buckets as overflowed but leaves the previous finite costUSD and sawCost intact. build then emits that first report's cost as the merged day's complete subtotal while only making its tokens unavailable; track cost overflow separately and make the merged cost nil.

Useful? React with 👍 / 👎.

Comment on lines +217 to +219
let resourceValues = try? url.resourceValues(
forKeys: [.isRegularFileKey, .fileSizeKey, .contentModificationDateKey])
guard resourceValues?.isRegularFile == true else { continue }

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Propagate Qwen metadata read failures

When an enumerated Qwen transcript cannot be stat'ed because of a transient filesystem or permissions error, this try? and guard silently skip it before the now-propagating CostUsageJsonl read path is reached. Fresh evidence beyond the fixed transcript-read failure is this separate metadata-read path: remaining files can still produce an established partial snapshot, so propagate the metadata error rather than treating the transcript as non-regular.

Useful? React with 👍 / 👎.

Yuxin-Qiao added a commit to Yuxin-Qiao/CodexBar that referenced this pull request Aug 2, 2026
…dels PR

The daily estimated spend chart (SpendDailyChart) and its model-side
DailyPoint/DailySpendDetail aggregation were split out of steipete#2322 but are
not ready for review yet. Withhold them from this PR; the code remains
in steipete#2322 for a follow-up PR.
Yuxin-Qiao added a commit to Yuxin-Qiao/CodexBar that referenced this pull request Aug 2, 2026
The Models PR adds dashboard strings to every catalog; the Italian catalog
keeps them in English (same choice as steipete#2322), so the language catalog test
needs the same allowlist entries to stay green in CI.
Yuxin-Qiao added a commit to Yuxin-Qiao/CodexBar that referenced this pull request Aug 2, 2026
coveredDayCount measures the coverage window, not the number of spend days,
so the replacements used during the daily-card removal were wrong. The
heatmap assertion now checks the 30-day window stays unwidened; the
rollover and mutation cases already prove window behavior through totals.
The localization coverage test follows steipete#2322 and reads the embedded model
card from PreferencesSpendModelsView instead of the dashboard pane.
@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. labels Aug 2, 2026
@steipete

steipete commented Aug 3, 2026

Copy link
Copy Markdown
Owner

Maintainer decision on the Usage & Spend program (applies to #2322, #2527, #2548, #2569, #2575, #2577 — closing together):

We want the ideas — the token-activity view and the cross-provider cost overview in particular are genuinely good, and we're adopting them. What we can't absorb is the delivery shape: 8k–20k-line PRs bundling scanners, pricing, identity, and UI can't be reviewed honestly, and live testing of the current heads surfaced the kind of defects that big surfaces hide (duplicate token-activity cards in the Models view; the unified Overview rendering no chip for an enabled provider; the account-attribution issue flagged earlier).

So we're taking this work as a base in-house and rebuilding it in small, individually landable slices — first the token-activity view rebuilt on the shared scan cache (no separate annual scan), then the cost overview aligned with the #2578 design discussion. Your commits will be cherry-picked where they fit, and every slice that draws on this work will credit you in the changelog, as today's merges already do.

@Yuxin-Qiao — you're this repo's most prolific contributor and much of today's release is your work. Focused PRs the size of #2574 land same-day; that's the shape that serves both of us.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature: ✨ showcase ClawSweeper spotlight: unusually compelling feature idea for maintainer attention. merge-risk: 🚨 auth-provider 🚨 Merging this PR could break OAuth, tokens, provider routing, model choice, or credentials. merge-risk: 🚨 availability 🚨 Merging this PR could cause crashes, hangs, restart loops, stalls, or process outages. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. P2 Normal priority bug or improvement with limited blast radius. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants