Skip to content

fix(dashboard): always show balances at $0 and hide disabled Extra Usage - #1557

Merged
robinebers merged 1 commit into
mainfrom
capy/always-show-balances-at
Nov 3, 2026
Merged

robinebers merged 1 commit into
mainfrom
capy/always-show-balances-at

Conversation

@robinebers

@robinebers robinebers commented Nov 3, 2026 •

Copy link
Copy Markdown
Owner

TL;DR

Balances now always show, even at $0. Extra Usage hides while the provider has it off and shows while it's on, even at $0 used or $0 left. This replaces #1555's "disabled Extra Usage reads $0 spent".

What was happening

What this changes

Each provider now decides enabled or disabled from its own API fields:

Provider Row Field used Enabled at $0 Disabled
Claude Extra Usage extra_usage.is_enabled shows $0 spent, or a $0 bar with a monthly limit hidden
ChatGPT Extra Usage (credits) credits.has_credits (header x-codex-credits-has-credits as fallback) shows $0 hidden
Cursor Extra Usage (on-demand) spendLimitUsage.individualLimit/pooledLimit (no flag, so a missing or $0 limit = off); usage-summary onDemand.enabled shows a $0 bar hidden
Copilot Extra Usage premium_interactions.overage_permitted shows 0 hidden
Grok Extra Usage (pay as you go) config.onDemandCap.val (no flag, proto3 omits 0, so missing or $0 cap = off) shows the cap hidden (no more Disabled row)
Devin Extra Usage (balance) planStatus.overageBalanceMicros (no flag) shows $0 left when reported hidden when Windsurf leaves it out
Ollama Extra Usage (purchased credits) purchased.balance_usd (every plan can buy credits, no flag) shows $0 left n/a
OpenRouter Balance /credits total_credits − total_usage shows $0 left n/a
Cursor Credits credit-grants read succeeded (hasCreditGrants, totalCents) plus Stripe balance shows $0 left hidden only when the credit-grants read failed

Where I looked the fields up (read):

  • ChatGPT: openai/codex codex-rs/tui/src/status/rate_limits.rs:121-126 ("has_credits: Whether credits tracking is enabled for the account"), and credit_status_row returns no row when !has_credits (:401).
  • Grok: xai-org/grok-build crates/codegen/xai-grok-pager/src/app/effects/helpers.rs:1608-1610, pay_as_you_go = on_demand_val > 0.
  • Devin: Windsurf PlanStatus has no overage on/off field in any public reader (cubezhao/ai-tools-mng, Meow-Calculations/Windsurf_To_API_Go internal/cloud/cloud.go:100).
  • Ollama: docs.ollama.com/api/balance and ollama.com/pricing ("Every plan, including Pay as you go, can buy usage credits").

Heads-up

  • Priority effect (rules unchanged): a balance at exactly $0 lists under Used Up (existing emptyBalance rule). New entrants: ChatGPT credits when credits are on at 0, and Cursor Credits at $0 left, which now shows for every Cursor account with no credits. OpenRouter, Devin, and Ollama $0 balances already listed there. Claude/Cursor Extra Usage on at $0 is not a balance, so it doesn't enter Priority.
  • Cursor Credits now appears for accounts with no credits ($0 left), in its existing place after Requests. Robin, please confirm you want that default.
  • Devin: Windsurf gives no flag and proto3 leaves out a zero, so a left-out overageBalanceMicros is either "$0" or "no extra usage". I keep it hidden; a reported "0" shows $0 left.
  • CLI: ChatGPT with has_credits: false no longer exports a credits: 0 resource; Grok with no cap no longer has a pay-as-you-go line.

Tests

On the Mac mini (macOS 15.7.7), nice -n 10, script/test_quiet.sh --filter, one run at a time:

  • Red with the test changes only, on main 16d35bc: 9 failures across ZeroBalanceAndExtraUsageTests and CodexUsageClientAndMapperTests (Claude, Cursor, Copilot, Grok, ChatGPT off still shown; Claude/ChatGPT on at $0 hidden; Cursor Credits $0 hidden). The OpenRouter, Ollama, and Devin zero-balance asserts pass on main too; they guard the rule.
  • Green: focused 16/16; full suite 755 tests, 3 skipped, 0 failures.

Screenshots

Rendered offscreen on the Mac mini from the same fixtures, before (main) and after.

Claude, Extra Usage off: hidden (before left, after right)

claude-extra-off light
claude-extra-off dark

Claude, Extra Usage on at $0: shown (before left, after right)

claude-extra-on-zero light
claude-extra-on-zero dark

ChatGPT, credits off: hidden (unchanged) (before left, after right)

chatgpt-credits-off light
chatgpt-credits-off dark

ChatGPT, credits on at $0: shown (before left, after right)

chatgpt-credits-on-zero light
chatgpt-credits-on-zero dark

Ollama, purchased credits at $0: shown (unchanged) (before left, after right)

ollama-purchased-zero light
ollama-purchased-zero dark

Devin, extra-usage balance at $0: shown (unchanged) (before left, after right)

devin-balance-zero light
devin-balance-zero dark

OpenRouter, Balance at $0: shown (unchanged) (before left, after right)

openrouter-balance-zero light
openrouter-balance-zero dark

Grok, pay-as-you-go off: Disabled row hidden (before left, after right)

grok-payg-off light
grok-payg-off dark

Cursor, on-demand off and no credits: Extra Usage hidden, Credits $0 left shown (before left, after right)

cursor-ondemand-off-no-credits light
cursor-ondemand-off-no-credits dark

Open in Capy


Note

Medium Risk
Touches many provider mappers and dashboard visibility rules, which changes what users and CLI exports see for credits and Extra Usage without altering auth or billing APIs.

Overview
Replaces the prior behavior where disabled Extra Usage rows still appeared as $0 spent (via showingWhenUnreported). Each provider now omits or emits Extra Usage from its mapper using that API’s own on/off signals—Claude is_enabled, ChatGPT has_credits, Copilot overage_permitted, Grok only when onDemandCap > 0, and similar—so enabled-at-zero still shows (bar or $0 spent) while disabled is hidden (including Grok’s old Disabled badge).

Balances (ChatGPT credits, Cursor Credits, OpenRouter, etc.) stay visible at $0 left by dropping the dashboard filter that hid zero ChatGPT credits and adjusting Codex/Cursor credit parsing. WidgetDescriptor.showingWhenUnreported is removed for Extra Usage; time ranges still default to zero when unreported.

Docs, CHANGELOG, and tests (ZeroBalanceAndExtraUsageTests, updated Codex tests) reflect the new rules.

Reviewed by Cursor Bugbot for commit 48f6986. Bugbot is set up for automated code reviews on this repo. Configure here.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
@cursor

cursor Bot commented Nov 3, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: cadaaf62-af93-4fdb-892e-6ec70bb3fc6c)

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

No new issues found.

Reviewed changes Reviewed the full PR, including provider mapping, dashboard visibility, Priority classification, CLI export effects, regression tests, and documentation.

  • Extra Usage visibility. Removes synthetic zero rows for disabled usage while retaining enabled zero-spend rows and positive Grok caps.
  • Zero balances. Keeps reported zero Codex and Cursor balances visible; Codex's disabled-credit handling matches OpenAI's own finite-credit display logic. Newly visible zero balances follow the existing Used Up rule.
  • Regression coverage. Tests cover enabled/disabled usage and reported zero balances across providers; documentation reflects the new behavior.
  • Validation. All changed Swift files passed syntax parsing, and GitHub's Build and Test check passed. Full macOS tests were not rerun locally on this Linux runner.

Pullfrog  | View workflow run | Using gpt-6-astra | 𝕏

@robinebers
robinebers merged commit 88e4261 into main Nov 3, 2026
6 of 7 checks passed
@robinebers
robinebers deleted the capy/always-show-balances-at branch November 3, 2026 08:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant