Skip to content

fix(usage): show Claude credit usage when a login has no rate-limit windows - #295

Closed
BigWebstas wants to merge 2 commits into
johannesjo:mainfrom
BigWebstas:fix/claude-credit-usage
Closed

BigWebstas wants to merge 2 commits into
johannesjo:mainfrom
BigWebstas:fix/claude-credit-usage

Conversation

@BigWebstas

Copy link
Copy Markdown
Contributor

Description

Shows Claude credit usage in the status bar for logins that are billed per use instead of a Pro/Max subscription.

For those logins, the Claude usage endpoint returns no five_hour or seven_day window, only an extra_usage block with the spend and the monthly limit. The parser ignored that block, so it reported "no rate-limit windows" and the status bar stayed hidden even though the user had a dollar limit set.

  • Parser (electron/ipc/claude-usage.ts): reads extra_usage, plus the newer spend block, into a new optional creditUsage field with used, limit, currency and percent used. Amounts arrive in minor units and are converted using decimal_places or the exponent field, which default to 2.
  • Status bar: when a login has no rate-limit windows, credits become the headline, e.g. Credits $12.34 / $50.00 (25%). The hover popover always lists them. The meter turns amber at the usual 80% threshold.
  • Store and types: creditUsage is carried through UsageResult and UsageState, and cleared on logout along with the windows. Codex is unaffected.

Issues Resolved

None filed.

Check List

  • New functionality includes testing. (Parser, formatter, store and status bar tests.)
  • New functionality has been documented in the README if applicable. (Not applicable: no new setting or command.)

🤖 Generated with Claude Code

…indows

Logins billed per use get no five-hour or weekly window from the Claude
usage endpoint, only an extra_usage block, so the parser returned
nothing and the status bar stayed hidden. Parse extra_usage (and the
newer spend block) into creditUsage and show it as "$used / $limit":
inline in the bar when there are no windows, and in the popover.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@johannesjo

Copy link
Copy Markdown
Owner

🔧 Needs changes – labelled needs work; ping me once the items below are addressed and I'll re-review.

Thanks for the PR! This lets the status bar show credit spend for Claude logins whose usage response carries only extra_usage, and it has good parser and formatter coverage. One rendering bug needs fixing before merge.

Should fix before merge

  • src/components/UsageStatusBar.tsx:76 and :107 – both <Show when={percent()}> blocks test for a truthy value, so a usedPercent of 0 hides the progress bar and the (0%) readout even when a limit is set. For example, a subscriber with extra usage enabled (is_enabled: true, monthly_limit: 5000, used_credits: 0) or a pay-per-use login at the start of the month sees Credits $0.00 / $50.00 with no meter. The meter then appears and the entry widens once spend goes above zero. Check for null instead, e.g. when={percent() !== null} and read props.credit.usedPercent ?? 0 inside, and add a test with usedPercent: 0.

Nits

  • src/components/UsageStatusBar.tsx:97 – CreditMeter fills as credits are spent, while UsageMeter drains (its comment says filled means budget still available). The popover shows both together, so a nearly full bar means plenty left on the 5h row and almost exhausted on the credits row. The text makes the meaning clear, but draining the credit bar too, or a comment explaining the difference, would avoid the mismatch.
  • src/components/UsageStatusBar.client.test.tsx:96 – saved = { ...usage.claude } has no creditUsage key, so Object.assign(usage.claude, saved) leaves creditUsage on the shared fixture. Nothing breaks today because this is the last test, but any later test would inherit it. Delete the key in finally, or add creditUsage: null to the hoisted fixture.
  • src/components/usage-format.ts:32 – formatCurrency hardcodes 'en-US', but the other formatters in this file pass undefined and use the user's locale. A de-DE user sees €12.34 rather than 12,34 €. The fallback in the catch block also prints $ for any malformed currency code (e.g. 'dollars'); ${amount.toFixed(2)} ${currency} would be safer.
  • src/components/UsageStatusBar.tsx:114, :188, :244 – these doc comments still describe the old behavior: "both windows", "just the five-hour window", and hidden "permanently when no agent has a subscription login". Each could mention the credit fallback.

Questions

  • The spend branch in parseCreditUsage (electron/ipc/claude-usage.ts) handles amount_minor/exponent, and the extra_usage branch reads currency/decimal_places. I couldn't tell where those shapes come from. Are they in a response you've seen, or anticipated? If you have a captured (redacted) response, a fixture from it would make the tests document the real contract.

Automated review pass (Claude Code). Anything unclear or wrong – say so and I'll take a look.

@johannesjo johannesjo left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

🔁 Superseded by main, so closing is the likely next step. No new code issues at 77e536a.

Thanks again for this fix. Since the last review, the same change has landed on main through #297 (97e6d3c0, "refactor(usage): adopt the creditUsage shape from fork/extras" and "fix(usage): draw the credit meter at 0% used"). This head only merges main from before that point (e9db9a7). The PR's own code has not changed since 901021a.

  • Already on main: electron/ipc/claude-usage.ts, claude-usage.test.ts, src/components/usage-format.ts, usage-format.test.ts, src/store/usage.ts and usage.test.ts match origin/main byte for byte. CreditUsage and the creditUsage fields in shared-types.ts, src/ipc/types.ts, src/store/types.ts and src/store/core.ts are on main too.

  • Merge conflicts: git merge-tree origin/main HEAD conflicts in src/components/UsageStatusBar.tsx and UsageStatusBar.client.test.tsx. Main's version of both is a superset of this one. It has the percent() !== null fix for the 0% meter from the earlier review, a test for it, and the new ResourcesPanel. Resolving the conflicts in main's favour leaves this PR with an empty diff.

  • Still open, now on main rather than here (follow-ups, not blockers for this PR): these nits from the previous review still apply to main's copy:

    • formatCurrency hardcodes 'en-US', and its catch falls back to $ for any currency code.
    • The UsageStatusBar doc comments still describe only the rate-limit windows.
    • It's still unconfirmed where the spend / decimal_places response shapes come from.

    A small follow-up PR against main, ideally with a captured and redacted extra_usage response as a fixture, would be welcome.


Generated by Claude Code

Copy link
Copy Markdown
Owner

Thanks a lot for this, @BigWebstas! 🙏 Your credit-usage work landed on main through #297 (which adopted the creditUsage shape and added the 0% meter fix), so this PR has nothing left to add, and I'm closing it as superseded. The small follow-ups from the review (en-US-only formatCurrency, the $ fallback, the stale UsageStatusBar doc comments) now apply to the code on main. A small follow-up PR for those is very welcome if you feel like it.


Generated by Claude Code

@johannesjo johannesjo closed this Oct 10, 2026
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.

2 participants