| summary | Gemini CLI OAuth quotas and opt-in Gemini app web usage limits. | |||
|---|---|---|---|---|
| read_when |
|
Choose Gemini CLI (the default) or Gemini app under Settings → Providers → Gemini → Usage source. They measure different quotas and may use different Google accounts. Changing the source clears the previous quota display. Antigravity remains a separate provider.
- Gemini CLI uses local CLI OAuth credentials and the quota API described below.
autoandapiselect this path; they never fall back to a browser account. API-key and Vertex AI auth types are unsupported here. - Gemini app is an explicit
websource for the 5-hour and weekly limits shown at gemini.google.com/usage. Select Automatic cookies to use the shared browser order, or Manual to paste a Cookie header. Login opens that usage page. The app source does not require Gemini CLI. - Legacy CLI parsing remains available to parser callers through
GeminiStatusProbe.parse(text:); the fetch pipeline does not scrape/stats.
The bundled gemini-web plugin sends a cookie-authenticated GET to
https://gemini.google.com/_/BardChatUi/graphql/schemas/GEMINI_WEB_GRAPHQL/executeQuery.
The public UsagePageSurface JavaScript bundle identifies the persisted UsagePageQuery signature as
2/dWbCvkVB0X16r9NPnxifeOAAqdCqMf0xeWvau9yPy7g= and its variables as:
{"g1Request":{"entrypoints":["GEMINI_USAGE_SETTINGS_UPGRADE_BANNER"]},"workspaceRequest":{"recommendationsForSurfaceRequests":[]}}The response's data.viewer.rpcs.getUsageInfo.pools contains GXU_FIVE_HOURLY and GXU_WEEKLY entries.
percentageUsed is a fraction; gxu.windowRefreshesAt supplies the reset time. Missing or invalid values remain
unavailable, while a reported zero stays zero. The app's subscription tier comes from this response; CLI account
identity and plan data are never copied into the app result.
Cookie values stay opaque to the plugin and are scoped to the Gemini request URL. Imported browser sessions are not written to a cookie cache; a manually entered Cookie header follows the existing local settings storage policy. The shared browser gate forbids prompts during background or settings refreshes, checks matching cookie rows before Safe Storage access, and applies the manual-action prompt budget and denial cooldown. Signed-out candidates can be skipped; the first validated account ends traversal, even when it reports no supported quota windows. Query drift fails visibly instead of silently switching accounts or reusing CLI quotas.
codexbar usage --provider gemini --source web --json- File:
~/.gemini/oauth_creds.json. - Required fields:
access_token,refresh_token(optional),id_token,expiry_date. - If access token is expired, we refresh via Google OAuth using client ID/secret extracted from the Gemini CLI install (see below).
- Resolution order:
GEMINI_OAUTH_CLIENT_ID+GEMINI_OAUTH_CLIENT_SECRETenvironment override.GEMINI_OAUTH2_JS_PATHpointing at a readableoauth2.jsfile.- Installed Gemini CLI package (
oauth2.js/ bundle regex extraction). - Known global Gemini CLI install paths (Homebrew npm prefix layouts, then
Homebrew Cellar/
optlibexecpackage roots when the GUI cannot resolve thegeminibinary).
- We locate the installed
geminibinary, then search for:- Homebrew nested path:
.../libexec/lib/node_modules/@google/gemini-cli/node_modules/@google/gemini-cli-core/dist/src/code_assist/oauth2.js
- Homebrew Cellar/opt package root (no-binary fallback):
/opt/homebrew/Cellar/gemini-cli/<version>/libexec/lib/node_modules/@google/gemini-cli/opt/homebrew/opt/gemini-cli/libexec/lib/node_modules/@google/gemini-cli- same under
/usr/local
- Bun/npm sibling path:
.../node_modules/@google/gemini-cli-core/dist/src/code_assist/oauth2.js
- Homebrew nested path:
- Regex extraction:
OAUTH_CLIENT_IDandOAUTH_CLIENT_SECRETfromoauth2.jsor Homebrew bundle chunks.
- Quota:
POST https://cloudcode-pa.googleapis.com/v1internal:retrieveUserQuota- Body:
{ "project": "<projectId>" }(or{}if unknown) - Header:
Authorization: Bearer <access_token>
- Project discovery (quota project ID):
- Primary:
cloudaicompanionProjectfromloadCodeAssist. - Fallback:
GET https://cloudresourcemanager.googleapis.com/v1/projects- Picks
gen-lang-client*or labelgenerative-language.
- Picks
- Primary:
- Tier detection:
POST https://cloudcode-pa.googleapis.com/v1internal:loadCodeAssist- Body:
{ "metadata": { "ideType": "GEMINI_CLI", "pluginType": "GEMINI" } }
- Token refresh:
POST https://oauth2.googleapis.com/token- Form body:
client_id,client_secret,refresh_token,grant_type=refresh_token. - Values are form-encoded so literal plus signs, separators, and percent escapes remain intact.
- Quota buckets:
remainingFraction,resetTime,modelId.- For each model, lowest
remainingFractionwins. percentLeft = remainingFraction * 100.
- Reset:
resetTimeparsed as ISO-8601, formatted as "Resets in Xh Ym".
- UI mapping:
- Primary: Pro models (lowest percent left).
- Secondary: Flash models (lowest percent left).
- Tertiary: Flash Lite models (lowest percent left).
- Automatic shows the first exhausted tier when present; otherwise it prefers Pro, then Flash, then Flash Lite, even when a later tier has a higher used percentage.
- Missing model tiers remain absent. The shared menu-bar metric fallback uses Flash Lite when both Pro and Flash are unavailable, including Automatic, Pro, Flash, and Average. Average still combines Pro and Flash when both exist.
- Tier from
loadCodeAssist:paidTier.name→ paid subscription label from Google, preferred whenever presentstandard-tier→ "Paid" (fallback whenpaidTier.nameis absent)free-tier+hdclaim → "Workspace" (fallback whenpaidTier.nameis absent)free-tier→ "Free"legacy-tier→ "Legacy"
- Email from
id_tokenJWT claims.
- Google stopped serving Gemini CLI OAuth for individual, AI Pro, and Ultra accounts on 2026-06-18. Standard and Enterprise subscriptions remain supported; paid API-key access is outside CodexBar's OAuth-backed Gemini provider.
- When quota,
loadCodeAssist, or token-refresh responses include Google's unsupported-client migration signal (UNSUPPORTED_CLIENT,IneligibleTierError, or Antigravity migration copy), CodexBar surfacesconsumerTierDeprecatedwith guidance to use the Antigravity provider. - Google's live shape is an HTTP 200
loadCodeAssistbody with nocurrentTierand the consumer tier listed underineligibleTiers[].reasonCode == "UNSUPPORTED_CLIENT"; the follow-upretrieveUserQuotacall then fails with HTTP 403SUBSCRIPTION_REQUIREDand no migration wording. CodexBar reads the 200 body'sineligibleTiersdirectly, and maps that 403 toconsumerTierDeprecatedonly when the same fetch saw the unsupported-client flag and the account is not onstandard-tier— a licensed account's 403 staysHTTP 403. - The unsupported-client flag itself is suppressed for accounts the shutdown does not cover: a named
paidTier.name(authoritative even withoutcurrentTier) and anhdclaim (Workspace/education, whichresolveAccountPlanreads as Workspace when paired withfree-tier). Both would otherwise be pre-empted by the earlierloadCodeAssistbranch, which runs before the plan resolver. UsageStore.geminiMigrationObservationrecords which sentinel the last refresh produced (none/localAntigravityHandoff/googleConsumerTierShutdown); a later local-tooling failure never downgrades a shutdown already seen.geminiObservedConsumerTierDeprecation(either sentinel) drives the settings action; the narrowergeminiObservedGoogleConsumerTierShutdowndrives the login guard. While the narrow one is set for this session, the Gemini login action stops clearing~/.gemini/oauth_creds.jsonand launching Gemini CLI — whose OAuth step fails with the same message — and shows the Antigravity guidance instead. The localoauthCredentialsUnavailableWithAntigravityhandoff deliberately does not guard login: there, reinstalling or relaunching Gemini CLI is the fix, and Workspace accounts must keep that path.- The guard warns rather than blocks: its alert offers Switch Account… next to Cancel (Cancel is the default, since confirming clears credentials). Confirming re-runs the ordinary login without the guard, which is how a user moves from a shut-down consumer account to a Workspace, education, or Code Assist Standard/Enterprise one. The observation is not cleared by confirming, so the settings action stays put and the next attempt warns again.
- Settings shows an Enable Antigravity provider action only after CodexBar observes
consumerTierDeprecatedduring a Gemini refresh (typed sentinel state, not user-facing text matching). - The action is explicit: CodexBar never automatically enables Antigravity or falls back to it.
- Ordinary Gemini login,
notLoggedIn, and Antigravity setup errors remain unchanged. CodexBar does not capture TerminalgeminiOAuth output, so Terminal-only failures cannot activate the migration action. - Workspace and education Google accounts are outside the June 2026 consumer shutdown; keep using the Gemini provider. Antigravity remains the consumer replacement path for individual, AI Pro, and Ultra.
Sources/CodexBarCore/Providers/Gemini/GeminiStatusProbe.swift