Skip to content

Show one meter for spend-only Claude accounts - #882

Merged
Finesssee merged 6 commits into
mainfrom
feat/claude-spend-only
Oct 15, 2026
Merged

Finesssee merged 6 commits into
mainfrom
feat/claude-spend-only

Conversation

@Finesssee

@Finesssee Finesssee commented Oct 15, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Port of upstream steipete#4480 (2e19c92, v0.75.0; fixes upstream steipete#4381). Claude accounts with no session/weekly/model lanes but a positive monthly spend cap now show one "Monthly" meter instead of an empty card.

  • claude/spend_window.rs (new): projects the used share of the cap into primary; reset is the observed cost.resets_at, else midnight UTC on the 1st of next month; window = the calendar month ending at the reset.
  • OAuth (apply_spend_only_extra_usage) and web (build_usage_and_cost) paths apply the projection only for spend-only accounts; quota accounts unchanged.
  • CostSnapshot.folded_into_primary (+ bridge foldedIntoPrimary): the card shows the cap as a caption (spend / limit, balance) without a second bar.
  • Pace: Claude now uses a calendar-month pace capability; session/weekly lanes keep per-lane pace.
  • CHANGELOG line.

Deviations: Windows keeps RateWindow::no_active_session() and projects inside the Claude module (upstream made primary optional); label is the existing "Monthly" key; the CLI /usage spend-cap parser is not ported.

Commands

  • cargo test --manifest-path rust/Cargo.toml (4503 lib pass after merging main)
  • cargo test --manifest-path apps/desktop-tauri/src-tauri/Cargo.toml (721 pass)
  • cargo clippy both manifests --all-targets -- -D warnings, cargo fmt --all
  • pnpm test (1259 pass), pnpm exec tsc --noEmit -p ., pnpm run build

UI proof

Not run: the CODEXBAR_SEED_USAGE_JSON seed hook is Codex-only, so there is no synthetic Claude source to render a spend-only card. The caption change is covered by cardCost.test.ts. Upstream rendering was captured on the Mac rig (Claude-SpendOnly pack: "Extra usage 75% left", "Spend limit $12.50/$50.00").

Summary by CodeRabbit

  • New Features
    • Claude accounts that rely on a monthly spending cap now see it as their primary usage meter, with calendar-month pacing and a reset date when available. If Claude doesn’t provide a reset date, the meter resets at the start of the next month.
    • Accounts with session or weekly quotas keep their existing meters and Extra usage details.
  • Bug Fixes
    • Avoids showing a duplicate percentage meter when a spending cap is already included in the primary meter.

Factory Agent added 5 commits October 15, 2026 17:12
A Claude account whose only limit is a monthly spend cap has no session or
weekly lane. A positive cap now becomes the primary meter: the used share of
the cap, scored over the calendar month it resets in (midnight UTC on the 1st,
inferred when Claude reports no reset). Quota accounts and uncapped balances
keep their lanes and cost unchanged. Upstream steipete#4480, fixes steipete#4381.
The cost bridge carries folded_into_primary so the card can drop the duplicate
bar. Pace test uses Codex as the unsupported provider now that Claude opts in.
When the primary meter already shows the cap, the Extra usage block keeps the
spend, limit and balance as a caption and omits its bar. Other cost blocks are
unchanged.
@coderabbitai

coderabbitai Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration
  • Configuration used: Repository: nesszer/Win-CodexBar/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: b29e224f-84e7-4e6e-a2a7-0c0222989e50
📥 Commits

Reviewing files that changed from the base of the PR and between 5fec033 and aaa49be.

📒 Files selected for processing: 1
  • CHANGELOG.md
+---------------------------------------------------------------------------------------+
| Analyze workflow to improve concurrency. Exploit concurrency in your user's workflow. |
+---------------------------------------------------------------------------------------+
  \
   \     /)/)
        ( '')
        /  |
      o(___)

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: nesszer/Win-CodexBar/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: c1756611-b564-49bd-97d4-fee5233c9514
📥 Commits

Reviewing files that changed from the base of the PR and between 22a6589 and 5fec033.

📒 Files selected for processing: 17
  • CHANGELOG.md
  • apps/desktop-tauri/src-tauri/src/commands/bridge.rs
  • apps/desktop-tauri/src-tauri/src/commands/bridge/pace.rs
  • apps/desktop-tauri/src-tauri/src/tray_bridge.rs
  • apps/desktop-tauri/src-tauri/src/tray_presentation_tests.rs
  • apps/desktop-tauri/src-tauri/src/usage_metric.rs
  • apps/desktop-tauri/src/lib/cardCost.test.ts
  • apps/desktop-tauri/src/lib/cardCost.ts
  • apps/desktop-tauri/src/types/bridge.ts
  • rust/src/core/pace_capability.rs
  • rust/src/core/provider_factory.rs
  • rust/src/core/usage_snapshot.rs
  • rust/src/providers/claude/mod.rs
  • rust/src/providers/claude/oauth/mod.rs
  • rust/src/providers/claude/oauth/tests.rs
  • rust/src/providers/claude/spend_window.rs
  • rust/src/providers/claude/web_api.rs

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 1 remain after this review.

📝 Walkthrough

Claude Extra usage caps now populate a monthly primary meter for spend-only accounts. Accounts with quota lanes retain those lanes. A folded-cost flag passes through the bridge so the cost display does not repeat the cap percentage.

Changes: Claude spend-only usage

Layer / File(s) Summary
Monthly meter projection
rust/src/core/usage_snapshot.rs, rust/src/core/provider_factory.rs, rust/src/core/pace_capability.rs, rust/src/providers/claude/mod.rs, rust/src/providers/claude/spend_window.rs
Claude gains calendar-month pace capability and projection logic for eligible spend-only accounts. The monthly meter uses a reported reset when available, or the next UTC month start. Tests cover calendar boundaries and quota-lane exclusions.
OAuth and Web API integration
rust/src/providers/claude/oauth/*, rust/src/providers/claude/web_api.rs
OAuth and Web API usage paths build Extra usage cost snapshots and attempt spend-only projection. Tests cover capped and uncapped spend-only usage, existing quota lanes, and disabled Extra usage.
Bridge and cost display
apps/desktop-tauri/src-tauri/src/commands/bridge.rs, apps/desktop-tauri/src/types/bridge.ts, apps/desktop-tauri/src/lib/cardCost.ts, apps/desktop-tauri/src/lib/cardCost.test.ts, apps/desktop-tauri/src-tauri/src/{commands/bridge/pace.rs,tray_bridge.rs,tray_presentation_tests.rs,usage_metric.rs}, CHANGELOG.md
The bridge carries the folded-cost flag. The cost section omits its percentage when the cap is already shown in the primary meter. Fixtures, a bridge pace test, and the Windows Unreleased changelog are updated.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant ClaudeWebAPI
  participant SpendWindow as spend_window::project_spend_only
  participant Bridge as CostSnapshotBridge
  participant CostDisplay as cardCostSection
  ClaudeWebAPI->>SpendWindow: project eligible monthly cap into primary meter
  SpendWindow-->>ClaudeWebAPI: projected usage and folded cost
  ClaudeWebAPI->>Bridge: return usage and cost snapshot
  Bridge->>CostDisplay: pass foldedIntoPrimary flag
  CostDisplay-->>Bridge: omit cost percentage and bar
Loading

Suggested reviewers: xuelongmu

Merge Risk: ⚪ Minimal · up to 5fec0

The reviewed change has no identified issue requiring correction before merge.

Caution

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

  • Ignore

Failed Failed checks: 1 error · 1 warning

Check name Status Explanation Resolution
Provider Data Stays Siloed Error The provider data paths stay isolated, but the PR adds provider-specific branching in shared code. In rust/src/core/pace_capability.rs, the shared test mappings now match ProviderId::Claude at lin… Remove the new ProviderId::Claude arms from shared rust/src/core/pace_capability.rs. Move Claude-specific capability assertions into rust/src/providers/claude/ or refactor the shared tests to use provider-owned capability data without…
Ui Changes Include Windows Proof Warning The PR changes visible Windows UI. apps/desktop-tauri/src/lib/cardCost.ts now removes the cost bar and percentage caption when foldedIntoPrimary is true, and ExtraUsageBlock.tsx renders those fi… Run a fresh Windows build with a spend-only Claude account or suitable fixture. Attach screenshots or add a proof note that records the Windows build and shows the single Monthly meter, spend/limit caption, and absence of a duplicate cost b…
Passed Passed checks: 6 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title is a short imperative summary that accurately describes the main change: displaying one meter for spend-only Claude accounts.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Secrets Handled Safely Passed No changed code sends tokens, cookies, API keys, OAuth credentials, or authorization headers to logs, user-facing errors, test snapshots, or credential files. The new OAuth tests use only the syntheti…
No Unapproved Dependencies Passed The pull request changes no Cargo.toml, package.json, npm lockfile, yarn.lock, or pnpm-lock.yaml. It also does not change a pinned pnpm packageManager version. Therefore, it adds no dependency or lock…
Full details: Provider Data Stays Siloed

Explanation

The provider data paths stay isolated, but the PR adds provider-specific branching in shared code. In rust/src/core/pace_capability.rs, the shared test mappings now match ProviderId::Claude at lines 505–514 and 524–533. This is outside the permitted provider directories and rust/src/core/provider_factory.rs, so it matches the explicit cross-provider branching condition.

Resolution

Remove the new ProviderId::Claude arms from shared rust/src/core/pace_capability.rs. Move Claude-specific capability assertions into rust/src/providers/claude/ or refactor the shared tests to use provider-owned capability data without matching specific ProviderId values. Keep the runtime dispatch in rust/src/core/provider_factory.rs, which is permitted.

Full details: Ui Changes Include Windows Proof

Explanation

The PR changes visible Windows UI. apps/desktop-tauri/src/lib/cardCost.ts now removes the cost bar and percentage caption when foldedIntoPrimary is true, and ExtraUsageBlock.tsx renders those fields directly. The description states that UI proof was not run and reports rendering only from a Mac rig. It includes no screenshots or proof note from a fresh Windows build.

Resolution

Run a fresh Windows build with a spend-only Claude account or suitable fixture. Attach screenshots or add a proof note that records the Windows build and shows the single Monthly meter, spend/limit caption, and absence of a duplicate cost bar.

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai 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.

Pre-merge checks failed. Please resolve the failing checks before merging.

@Finesssee
Finesssee merged commit 0ba9017 into main Oct 15, 2026
1 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant