Skip to content

feat(opencode): show quota usage toast after quota refresh#36

Merged
ualtinok merged 2 commits into
cortexkit:mainfrom
iceteaSA:feat/quota-toast
Jun 5, 2026
Merged

feat(opencode): show quota usage toast after quota refresh#36
ualtinok merged 2 commits into
cortexkit:mainfrom
iceteaSA:feat/quota-toast

Conversation

@iceteaSA
Copy link
Copy Markdown
Contributor

@iceteaSA iceteaSA commented May 21, 2026

Rebased onto upstream/main (v1.5.0) now that #34 (QuotaManager) is merged — this branch no longer depends on feat/quota-manager.

Displays quota-usage bar notifications via client.tui.showToast after quota data is refreshed.

  • Shows main and enabled fallback account usage with visual bars (█░).
  • Padded percentage and reset time per account; formatResetIn handles sub-1-minute (<1m), "now", and invalid-date inputs.
  • Toast variant reflects severity: info (<70%), warning (≥70%), error (≥90%).
  • Clamped bar rendering prevents RangeError on >100% utilization.
  • Reads main/fallback quota from the shared, token-aware QuotaManager cache (not the request-start snapshot).
  • The "active" account label mirrors actual routing: the first fallback that passes quota policy, otherwise main — never a failing fallback.
  • Fires on a synchronous cold-start cache miss and on the resolved .then() of each periodic background refresh; never blocks the request.

Single file change: packages/opencode/src/index.ts.


Summary by cubic

Shows a quota usage toast after quota refresh, matching the TUI sidebar. Keeps the sidebar correct during async refreshes by preserving the active account and re-rendering when background fallback storage changes via @cortexkit/anthropic-auth-core.

  • New Features

    • Quota toast via client.tui.showToast after cold-start refreshMain and background refresh; shows main + enabled fallbacks with shared-width █░ bars, padded %, 5h/7d, “resets <1m/now”, and active/idle status; clamps >100%; severity by max usage; reads token-aware data from the shared QuotaManager cache and marks the first account that passes policy.
  • Bug Fixes

    • Preserve the active fallback in the sidebar after async main refresh by remembering the last routing and only refreshing numbers.
    • Auto-refresh the sidebar when background fallback storage changes (token refresh, quota update, error) by wiring onFallbackStorageChanged in FallbackAccountManager.

Written for commit 4b7a88c. Summary will update on new commits.

Review in cubic

Greptile Summary

This PR adds a quota-usage toast notification after main quota refreshes (both cold-start and periodic background) and fixes the bug where async background refreshes would clobber the active fallback account back to main in the sidebar. It also wires onFallbackStorageChanged in FallbackAccountManager so the sidebar updates automatically when background fallback quota refreshes persist storage changes.

  • Introduces showQuotaToast / showQuotaToastFromCache with quotaBar, quotaLine, and formatResetIn helpers; toast variant (info/warning/error) reflects the highest usedPercent across all shown accounts.
  • Adds lastSidebarRouting state and refreshSidebarQuota() to preserve the actual active-account label across quota-only sidebar refreshes, specifically targeting the async background-refresh clobber race.
  • Adds onFallbackStorageChanged callback to FallbackAccountManager (fired from refreshQuotaForDueAccounts when storage changes) and wires it to refreshSidebarQuota().

Confidence Score: 4/5

Safe to merge; the core logic is correct and well-tested, with one minor interaction between the new lastSidebarRouting mechanism and the pre-existing /claude-quota command handler.

The async-clobber fix is solid and covered by integration tests. The one notable rough edge is that the pre-existing /claude-quota command handler still calls writeSidebarState with a hardcoded activeId:'main', which now also resets lastSidebarRouting — so a background refresh landing after a quota command continues showing 'main' as active even when a fallback is serving, until the next real request corrects it. It doesn't affect routing correctness, only display accuracy.

packages/opencode/src/index.ts around the CLAUDE_QUOTAS_COMMAND_NAME handler (lines 847–863)

Important Files Changed

Filename Overview
packages/opencode/src/index.ts Adds showQuotaToast, formatResetIn, quotaBar/quotaLine helpers; wires toast after cold-start and background main quota refresh; adds lastSidebarRouting + refreshSidebarQuota to prevent the async-refresh clobber bug. Pre-existing /claude-quota command handler still hard-codes activeId:'main' which now also resets lastSidebarRouting.
packages/core/src/accounts.ts Adds onFallbackStorageChanged callback to AccountManagerOptions and FallbackAccountManager; fires it after refreshQuotaForDueAccounts persists changes. Minimal, well-scoped change.
packages/opencode/src/tests/accounts.test.ts New test verifying onFallbackStorageChanged fires exactly once when refreshQuotaForDueAccounts changes storage. Well-structured.
packages/opencode/src/tests/index.test.ts Two new integration tests: one for the async-main-refresh-clobber regression, one for sidebar updating on background fallback quota changes. Both cover the key scenarios introduced by this PR.

Reviews (5): Last reviewed commit: "Merge branch 'fix/sidebar-fallback-quota..." | Re-trigger Greptile

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

3 issues found across 6 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/opencode/src/index.ts">

<violation number="1" location="packages/opencode/src/index.ts:428">
P2: Fallback quota command output drops fresh per-account refresh errors by always passing an empty error map.</violation>
</file>

<file name="packages/core/src/quota-manager.ts">

<violation number="1" location="packages/core/src/quota-manager.ts:88">
P2: Persisted main quota cache uses interval-only staleness instead of policy-aware `getQuotaNextRefreshAt`, causing premature refreshes.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

Comment thread packages/opencode/src/index.ts Outdated
Comment thread packages/core/src/quota-manager.ts Outdated
Comment thread packages/core/src/quota-manager.ts
@iceteaSA iceteaSA force-pushed the feat/quota-toast branch 5 times, most recently from 4ad7d49 to b20b6c0 Compare May 22, 2026 17:08
@iceteaSA iceteaSA force-pushed the feat/quota-toast branch 9 times, most recently from 95a1614 to 58f05a8 Compare June 3, 2026 18:21
Comment thread packages/opencode/src/index.ts
Comment thread packages/opencode/src/index.ts Outdated
Comment thread packages/opencode/src/index.ts
@iceteaSA iceteaSA force-pushed the feat/quota-toast branch 2 times, most recently from f4bee10 to 617634b Compare June 3, 2026 19:51
@iceteaSA
Copy link
Copy Markdown
Contributor Author

iceteaSA commented Jun 4, 2026

Updated: this branch now carries the sidebar quota fix (#57), merged in to keep the sidebar-touching branches consistent. #57's commits appear in this PR's diff until #57 merges to main, after which the diff reduces to this PR's own changes. Merge order: #57 first.

iceteaSA added 2 commits June 4, 2026 10:01
Displays quota usage bar notifications via client.tui.showToast after
quota data is refreshed. Shows main and fallback account usage with
visual bars, percentage, and reset time. Toast variant reflects
severity (info < 70%, warning >= 70%, error >= 90%).
Align the quota refresh toast with the sidebar's visual language:

- Replace the emoji status dots with status words (active/idle)
- Use the shared bar width and a padded percentage via a quotaLine helper
- Rename the seven-day label from 1w to 7d to match the sidebar
- Keep severity-driven variant color (info/warning/error)
@iceteaSA iceteaSA force-pushed the feat/quota-toast branch from e21de9f to 4b7a88c Compare June 4, 2026 08:02
Copy link
Copy Markdown

@greptile-apps greptile-apps Bot left a comment

Choose a reason for hiding this comment

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

iceteaSA has reached the 50-review limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@ualtinok ualtinok merged commit 4a70492 into cortexkit:main Jun 5, 2026
3 checks passed
@iceteaSA iceteaSA deleted the feat/quota-toast branch June 5, 2026 16:43
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