From 3522d072dcf15914ca833e77bc095f0ac9f41912 Mon Sep 17 00:00:00 2001 From: Jinwoo Hong <73622457+Jinwoo-H@users.noreply.github.com> Date: Wed, 17 Jun 2026 15:23:44 -0700 Subject: [PATCH] Fix usage CTA while provider snapshots load (#5637) Co-authored-by: Orca --- .../status-bar-provider-visibility.test.ts | 46 +++++++++++++++---- .../status-bar-provider-visibility.ts | 16 +++++++ 2 files changed, 54 insertions(+), 8 deletions(-) diff --git a/src/renderer/src/components/status-bar/status-bar-provider-visibility.test.ts b/src/renderer/src/components/status-bar/status-bar-provider-visibility.test.ts index 29f4b763b..790a4dbfa 100644 --- a/src/renderer/src/components/status-bar/status-bar-provider-visibility.test.ts +++ b/src/renderer/src/components/status-bar/status-bar-provider-visibility.test.ts @@ -210,15 +210,45 @@ describe('getVisibleUsageProvider', () => { }) describe('isUsageEmptyState', () => { + it('waits for provider snapshots before showing the setup CTA', () => { + expect( + isUsageEmptyState( + { + claude: null, + codex: null, + gemini: null, + opencodeGo: null, + kimi: null + }, + usageSettings() + ) + ).toBe(false) + }) + + it('does not show the setup CTA while system-default usage snapshots are fetching', () => { + expect( + isUsageEmptyState( + { + claude: provider('fetching', { provider: 'claude' }), + codex: provider('fetching', { provider: 'codex' }), + gemini: provider('unavailable'), + opencodeGo: provider('unavailable', { provider: 'opencode-go' }), + kimi: provider('unavailable', { provider: 'kimi' }) + }, + usageSettings() + ) + ).toBe(false) + }) + it('does not show the setup CTA when persisted accounts exist but snapshots have no usage data', () => { expect( isUsageEmptyState( { claude: provider('unavailable', { provider: 'claude' }), - codex: provider('fetching', { provider: 'codex' }), - gemini: null, - opencodeGo: null, - kimi: null + codex: provider('unavailable', { provider: 'codex' }), + gemini: provider('unavailable'), + opencodeGo: provider('unavailable', { provider: 'opencode-go' }), + kimi: provider('unavailable', { provider: 'kimi' }) }, usageSettings({ codexManagedAccounts: [ @@ -255,11 +285,11 @@ describe('isUsageEmptyState', () => { expect( isUsageEmptyState( { - claude: null, - codex: null, + claude: provider('unavailable', { provider: 'claude' }), + codex: provider('unavailable', { provider: 'codex' }), gemini: provider('unavailable'), - opencodeGo: null, - kimi: null + opencodeGo: provider('unavailable', { provider: 'opencode-go' }), + kimi: provider('unavailable', { provider: 'kimi' }) }, usageSettings() ) diff --git a/src/renderer/src/components/status-bar/status-bar-provider-visibility.ts b/src/renderer/src/components/status-bar/status-bar-provider-visibility.ts index 3309dc431..bd2c5c1dc 100644 --- a/src/renderer/src/components/status-bar/status-bar-provider-visibility.ts +++ b/src/renderer/src/components/status-bar/status-bar-provider-visibility.ts @@ -28,6 +28,10 @@ function hasUsageData(provider: ProviderRateLimits): boolean { ) } +function isProviderSnapshotPending(provider: ProviderRateLimits | null): boolean { + return provider === null || (provider.status === 'fetching' && !hasUsageData(provider)) +} + // Why: a provider that returns `unavailable` is explicitly not configured // (Gemini OAuth off, OpenCode Go cookie unset, Claude on API-key billing). Its // fetch object is non-null, so a bare `!== null` check still renders a "--" @@ -115,6 +119,18 @@ export function isUsageEmptyState( if (!settings) { return false } + // Why: system-default Claude/Codex accounts have no persisted account row; + // their first durable signal is the usage snapshot, so wait for snapshots to + // settle before teaching the user to connect an account. + if ( + isProviderSnapshotPending(providers.claude) || + isProviderSnapshotPending(providers.codex) || + isProviderSnapshotPending(providers.gemini) || + isProviderSnapshotPending(providers.opencodeGo) || + isProviderSnapshotPending(providers.kimi) + ) { + return false + } return ( !hasUsageProviderSettings(settings) && !isProviderConfigured(providers.claude) &&