mirror of
https://github.com/stablyai/orca.git
synced 2026-09-28 08:02:43 +00:00
fix(status-bar): stop gating and routing Antigravity usage through Gemini
The Antigravity status-bar slot required `geminiCliOAuthEnabled`, and its sign-in CTA opened Gemini's Accounts section. Both were artifacts of the deleted Gemini mirror. Antigravity now earns its slot from Antigravity signals alone (checked item + CLI on PATH) and renders its own explicit unavailable state; it no longer offers a CTA that would configure a different provider. Refs #14515 Refs #9122
This commit is contained in:
@@ -163,21 +163,20 @@ describe('hasUsageProviderSettingsForProvider', () => {
|
||||
expect(hasUsageProviderSettingsForProvider('grok', usageSettings())).toBe(false)
|
||||
})
|
||||
|
||||
it('requires both a checked Antigravity item and Gemini OAuth as the durable Antigravity signal', () => {
|
||||
it('treats a checked Antigravity item as durable on its own, with no Gemini opt-in', () => {
|
||||
expect(
|
||||
hasUsageProviderSettingsForProvider(
|
||||
'antigravity',
|
||||
usageSettings({ antigravityUsageConfigured: true })
|
||||
)
|
||||
).toBe(true)
|
||||
// Why: an unrelated provider's opt-in must never decide whether Antigravity's slot exists (#14515).
|
||||
expect(
|
||||
hasUsageProviderSettingsForProvider(
|
||||
'antigravity',
|
||||
usageSettings({ antigravityUsageConfigured: true, geminiCliOAuthEnabled: true })
|
||||
)
|
||||
).toBe(true)
|
||||
// Why: the snapshot mirrors the Gemini fetch — without the OAuth opt-in it
|
||||
// is permanently unavailable, so the checked item alone is not durable.
|
||||
expect(
|
||||
hasUsageProviderSettingsForProvider(
|
||||
'antigravity',
|
||||
usageSettings({ antigravityUsageConfigured: true })
|
||||
)
|
||||
).toBe(false)
|
||||
expect(
|
||||
hasUsageProviderSettingsForProvider(
|
||||
'antigravity',
|
||||
@@ -345,11 +344,11 @@ describe('getVisibleUsageProvider', () => {
|
||||
).toBe(null)
|
||||
})
|
||||
|
||||
it('keeps Antigravity visible while the snapshot is pending when checked and Gemini OAuth is on', () => {
|
||||
it('keeps Antigravity visible while the snapshot is pending when its item is checked', () => {
|
||||
const visible = getVisibleUsageProvider(
|
||||
'antigravity',
|
||||
null,
|
||||
usageSettings({ antigravityUsageConfigured: true, geminiCliOAuthEnabled: true })
|
||||
usageSettings({ antigravityUsageConfigured: true })
|
||||
)
|
||||
expect(visible).toMatchObject({
|
||||
provider: 'antigravity',
|
||||
@@ -359,26 +358,21 @@ describe('getVisibleUsageProvider', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it('hides Antigravity while Gemini OAuth is off even when its status item is checked', () => {
|
||||
// Why: without the OAuth opt-in the mirrored snapshot is permanently
|
||||
// 'unavailable'; the default-on item must not pin a dead bar.
|
||||
expect(
|
||||
getVisibleUsageProvider(
|
||||
'antigravity',
|
||||
null,
|
||||
usageSettings({ antigravityUsageConfigured: true })
|
||||
)
|
||||
).toBe(null)
|
||||
it('surfaces the unavailable Antigravity slot instead of hiding it or borrowing Gemini', () => {
|
||||
// Why: the slot is how Orca says "no readable Antigravity quota yet"; hiding it
|
||||
// leaves #9122's reporter with no explanation at all.
|
||||
expect(
|
||||
getVisibleUsageProvider(
|
||||
'antigravity',
|
||||
provider('unavailable', {
|
||||
provider: 'antigravity',
|
||||
error: 'Gemini CLI OAuth is disabled in settings'
|
||||
error: 'Antigravity usage is not available.'
|
||||
}),
|
||||
usageSettings({ antigravityUsageConfigured: true })
|
||||
)
|
||||
).toBe(null)
|
||||
).toMatchObject({ provider: 'antigravity', status: 'unavailable' })
|
||||
// Why: an unchecked or undetected CLI still hides it entirely.
|
||||
expect(getVisibleUsageProvider('antigravity', null, usageSettings())).toBe(null)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -487,13 +481,13 @@ describe('isUsageEmptyState', () => {
|
||||
grok: provider('unavailable', { provider: 'grok' }),
|
||||
minimax: provider('unavailable', { provider: 'minimax' })
|
||||
},
|
||||
usageSettings({ antigravityUsageConfigured: true, geminiCliOAuthEnabled: true })
|
||||
usageSettings({ antigravityUsageConfigured: true })
|
||||
)
|
||||
).toBe(false)
|
||||
})
|
||||
|
||||
it('still shows the setup CTA when Antigravity is checked but Gemini OAuth is off', () => {
|
||||
// Why: the default-on Antigravity item is not configured usage on its own;
|
||||
it('still shows the setup CTA once the Antigravity slot settles as unavailable', () => {
|
||||
// Why: an Antigravity slot with no readable quota is not configured usage;
|
||||
// it must not hide the teaching CTA from users who set nothing up.
|
||||
expect(
|
||||
isUsageEmptyState(
|
||||
@@ -503,7 +497,7 @@ describe('isUsageEmptyState', () => {
|
||||
gemini: provider('unavailable'),
|
||||
opencodeGo: provider('unavailable', { provider: 'opencode-go' }),
|
||||
kimi: provider('unavailable', { provider: 'kimi' }),
|
||||
antigravity: null,
|
||||
antigravity: provider('unavailable', { provider: 'antigravity' }),
|
||||
grok: provider('unavailable', { provider: 'grok' }),
|
||||
minimax: provider('unavailable', { provider: 'minimax' })
|
||||
},
|
||||
|
||||
@@ -10,9 +10,7 @@ export type UsageProviderSettings = Pick<
|
||||
> & {
|
||||
// Why: Antigravity has no separate persisted usage credential in Orca. The
|
||||
// checked status-bar item is the durable user signal; StatusBar only sets
|
||||
// this after PATH detection says the agent is available. Durability further
|
||||
// requires geminiCliOAuthEnabled — the snapshot mirrors the Gemini fetch,
|
||||
// which never yields data while that opt-in is off.
|
||||
// this after PATH detection says the agent is available.
|
||||
antigravityUsageConfigured: boolean
|
||||
// Why: MiniMax/Grok sign-in live on disk, not in settings; main sets these each poll.
|
||||
minimaxCookieConfigured: boolean
|
||||
@@ -75,8 +73,9 @@ export function hasUsageProviderSettings(
|
||||
(settings?.claudeManagedAccounts?.length ?? 0) > 0 ||
|
||||
settings?.geminiCliOAuthEnabled === true ||
|
||||
Boolean(settings?.opencodeSessionCookie?.trim()) ||
|
||||
// Antigravity's durable signal requires geminiCliOAuthEnabled, so it is
|
||||
// already covered by the gemini term above.
|
||||
// Why: Antigravity is deliberately absent — Orca has no readable Antigravity
|
||||
// quota source yet (#14515), so it can never stand in for a configured provider
|
||||
// and must not suppress the setup CTA for a user who set nothing up.
|
||||
settings?.minimaxCookieConfigured === true ||
|
||||
settings?.minimaxApiKeyConfigured === true ||
|
||||
settings?.grokAuthConfigured === true
|
||||
@@ -103,10 +102,11 @@ export function hasUsageProviderSettingsForProvider(
|
||||
return Boolean(settings.opencodeSessionCookie?.trim())
|
||||
}
|
||||
if (providerId === 'antigravity') {
|
||||
// Why: the Antigravity snapshot mirrors the Gemini fetch, which stays
|
||||
// 'unavailable' until the user opts into Gemini CLI OAuth. Without that
|
||||
// gate the default-on checked item would pin a permanently dead bar.
|
||||
return settings.antigravityUsageConfigured === true && settings.geminiCliOAuthEnabled === true
|
||||
// Why: Antigravity's slot is earned by Antigravity signals alone — a checked
|
||||
// item plus the CLI on PATH. It has no readable quota source yet (#14515), so
|
||||
// the slot renders an explicit unavailable state rather than another
|
||||
// provider's numbers.
|
||||
return settings.antigravityUsageConfigured === true
|
||||
}
|
||||
if (providerId === 'minimax') {
|
||||
return settings.minimaxCookieConfigured === true || settings.minimaxApiKeyConfigured === true
|
||||
|
||||
@@ -6,7 +6,6 @@ describe('getUsageProviderAccountsSectionId', () => {
|
||||
expect(getUsageProviderAccountsSectionId('claude')).toBe('accounts-claude')
|
||||
expect(getUsageProviderAccountsSectionId('codex')).toBe('accounts-codex')
|
||||
expect(getUsageProviderAccountsSectionId('gemini')).toBe('accounts-gemini')
|
||||
expect(getUsageProviderAccountsSectionId('antigravity')).toBe('accounts-gemini')
|
||||
expect(getUsageProviderAccountsSectionId('opencode-go')).toBe('accounts-opencode-go')
|
||||
expect(getUsageProviderAccountsSectionId('minimax')).toBe('accounts-minimax')
|
||||
expect(getUsageProviderAccountsSectionId('grok')).toBe('accounts-grok')
|
||||
@@ -15,4 +14,10 @@ describe('getUsageProviderAccountsSectionId', () => {
|
||||
it('does not invent an Accounts section for CLI-owned Kimi credentials', () => {
|
||||
expect(getUsageProviderAccountsSectionId('kimi')).toBeNull()
|
||||
})
|
||||
|
||||
it("does not route Antigravity into another provider's Accounts section", () => {
|
||||
// Why: `accounts-gemini` configures Gemini, not Antigravity — a sign-in CTA there
|
||||
// sends the user to the wrong provider (#14515).
|
||||
expect(getUsageProviderAccountsSectionId('antigravity')).toBeNull()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -9,9 +9,11 @@ export function getUsageProviderAccountsSectionId(
|
||||
case 'codex':
|
||||
return 'accounts-codex'
|
||||
case 'gemini':
|
||||
case 'antigravity':
|
||||
// Why: Antigravity usage currently shares Gemini's OAuth configuration.
|
||||
return 'accounts-gemini'
|
||||
case 'antigravity':
|
||||
// Why: Antigravity sign-in lives in the OS keyring under the `agy` CLI; Orca has no
|
||||
// Accounts section that configures it, and Gemini's would configure the wrong provider.
|
||||
return null
|
||||
case 'opencode-go':
|
||||
return 'accounts-opencode-go'
|
||||
case 'minimax':
|
||||
|
||||
Reference in New Issue
Block a user