fix(rate-limits): refresh Antigravity usage and show quota groups#8735
fix(rate-limits): refresh Antigravity usage and show quota groups#8735leomleao wants to merge 4 commits into
Conversation
📝 WalkthroughWalkthroughAdds Antigravity local quota discovery through CLI and desktop logs, quota-summary parsing, and platform-specific OAuth keyring access. Gemini rate-limit fetching now prefers local Antigravity data and credentials before legacy sources. Shared rate-limit types support grouped windows, and the status bar renders them with updated tests and localized settings copy. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
src/main/rate-limits/antigravity-oauth-keyring.ts (1)
17-98: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueWindows target name is hardcoded separately from the shared constants.
The PowerShell script hardcodes
'gemini:antigravity'(Line 47) instead of deriving it fromKEYRING_SERVICE/KEYRING_ACCOUNT, which are used for the macOS/Linux commands. If either constant ever changes, the Windows lookup will silently target the wrong credential (verifiedservice:usernameis the correct zalando/go-keyring Windows format, so today's value is correct — but the duplication is a latent drift risk).♻️ Derive the Windows target from the shared constants
const WINDOWS_CREDENTIAL_SCRIPT = String.raw` $signature = @' ... '@ Add-Type -TypeDefinition $signature $pointer = [IntPtr]::Zero -if ([OrcaCredentialReader]::CredRead('gemini:antigravity', 1, 0, [ref]$pointer)) { +if ([OrcaCredentialReader]::CredRead('__TARGET__', 1, 0, [ref]$pointer)) { ... } -`.trim() +`.trim() + +function buildWindowsCredentialScript(target: string): string { + return WINDOWS_CREDENTIAL_SCRIPT.replace('__TARGET__', target) +}Then call
getAntigravityKeyringCommandwithargs: ['-NoProfile', '-NonInteractive', '-Command', buildWindowsCredentialScript(${KEYRING_SERVICE}:${KEYRING_ACCOUNT})].src/main/rate-limits/antigravity-oauth-keyring.test.ts (1)
1-66: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd coverage for
readAntigravityCredentials.Only the pure helper functions are tested; the exported
readAntigravityCredentials(execFile call, timeout/maxBuffer options, base64-decode branch for Windows output, and catch-to-nullfallback) has no direct test. Mockingnode:child_process'sexecFilewould let you assert the base64-decode path and the swallow-on-error behavior that the rest of the fetch chain depends on.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 69d2dc49-5978-4ce0-8c89-e78456bbbc63
📒 Files selected for processing (21)
src/main/rate-limits/antigravity-local-quota.test.tssrc/main/rate-limits/antigravity-local-quota.tssrc/main/rate-limits/antigravity-oauth-keyring.test.tssrc/main/rate-limits/antigravity-oauth-keyring.tssrc/main/rate-limits/antigravity-quota-summary.test.tssrc/main/rate-limits/antigravity-quota-summary.tssrc/main/rate-limits/gemini-usage-fetcher.fallback.test.tssrc/main/rate-limits/gemini-usage-fetcher.test.tssrc/main/rate-limits/gemini-usage-fetcher.tssrc/renderer/src/components/settings/AccountsPane.test.tsxsrc/renderer/src/components/settings/AccountsPane.tsxsrc/renderer/src/components/settings/accounts-search.tssrc/renderer/src/components/status-bar/tooltip.test.tssrc/renderer/src/components/status-bar/tooltip.tsxsrc/renderer/src/i18n/locales/en.jsonsrc/renderer/src/i18n/locales/es.jsonsrc/renderer/src/i18n/locales/ja.jsonsrc/renderer/src/i18n/locales/ko.jsonsrc/renderer/src/i18n/locales/zh.jsonsrc/shared/rate-limit-types.tssrc/shared/types.ts
👮 Files not reviewed due to content moderation or server errors (6)
- src/renderer/src/components/status-bar/tooltip.tsx
- src/renderer/src/components/status-bar/tooltip.test.ts
- src/renderer/src/i18n/locales/es.json
- src/renderer/src/i18n/locales/ja.json
- src/renderer/src/i18n/locales/ko.json
- src/renderer/src/i18n/locales/zh.json
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/main/rate-limits/antigravity-oauth-keyring.ts (1)
174-175: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low valueUnconditionally trim
stdoutto remove trailing newlines.Command-line tools like macOS
securitytypically append a trailing newline to their output. IfparseAntigravityKeyringCredentialsuses strict equality checks or prefix matching, the trailing newline could cause valid credentials to be rejected. Trimmingstdoutfor all output types ensures the parser receives a clean value.💡 Proposed tweak
const keyringValue = - command.output === 'base64' ? Buffer.from(stdout.trim(), 'base64').toString('utf8') : stdout + command.output === 'base64' ? Buffer.from(stdout.trim(), 'base64').toString('utf8') : stdout.trim()
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 7d453817-5955-4b7d-96d9-d3b54350fb20
📒 Files selected for processing (7)
src/main/rate-limits/antigravity-local-quota.tssrc/main/rate-limits/antigravity-oauth-keyring-read.test.tssrc/main/rate-limits/antigravity-oauth-keyring.tssrc/main/rate-limits/antigravity-quota-summary.tssrc/main/rate-limits/gemini-usage-fetcher.test.tssrc/main/rate-limits/gemini-usage-fetcher.tssrc/renderer/src/components/status-bar/tooltip.tsx
🚧 Files skipped from review as they are similar to previous changes (3)
- src/main/rate-limits/antigravity-quota-summary.ts
- src/renderer/src/components/status-bar/tooltip.tsx
- src/main/rate-limits/antigravity-local-quota.ts
| case 'win32': | ||
| return { | ||
| command: 'powershell.exe', | ||
| args: ['-NoProfile', '-NonInteractive', '-Command', buildWindowsCredentialScript()], | ||
| output: 'base64' | ||
| } |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Use -EncodedCommand for robust PowerShell execution.
Passing a multi-line script containing a here-string (@'...'@) directly via -Command is fragile. Depending on how the environment handles command-line newlines, it can easily lead to PowerShell syntax errors (e.g., "The string is missing the terminator").
It is a standard best practice to pass complex scripts as a Base64-encoded UTF-16LE string using -EncodedCommand. Additionally, adding -ExecutionPolicy Bypass ensures the script runs reliably even in environments with restrictive execution policies.
🛠️ Proposed fix
case 'win32':
+ const script = buildWindowsCredentialScript()
+ const encodedCommand = Buffer.from(script, 'utf16le').toString('base64')
return {
command: 'powershell.exe',
- args: ['-NoProfile', '-NonInteractive', '-Command', buildWindowsCredentialScript()],
+ args: ['-ExecutionPolicy', 'Bypass', '-NoProfile', '-NonInteractive', '-EncodedCommand', encodedCommand],
output: 'base64'
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| case 'win32': | |
| return { | |
| command: 'powershell.exe', | |
| args: ['-NoProfile', '-NonInteractive', '-Command', buildWindowsCredentialScript()], | |
| output: 'base64' | |
| } | |
| case 'win32': | |
| const script = buildWindowsCredentialScript() | |
| const encodedCommand = Buffer.from(script, 'utf16le').toString('base64') | |
| return { | |
| command: 'powershell.exe', | |
| args: ['-ExecutionPolicy', 'Bypass', '-NoProfile', '-NonInteractive', '-EncodedCommand', encodedCommand], | |
| output: 'base64' | |
| } |
🧰 Tools
🪛 ast-grep (0.44.1)
[warning] Importing child_process exposes a command-execution surface; ensure any command/argument built from input is validated, and prefer execFile/spawn with an argument array over exec.
Context: import { execFile } from 'node:child_process'
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').
(detect-child-process-typescript)

Summary
Fix Antigravity usage refreshes and show the quota structure reported by Antigravity itself.
agyCLI's loopback quota service, then the Antigravity desktop language server, native OS keyring credentials, and existing Gemini OAuth sources.Refresh failedwhile Antigravity remains signed in.The root cause was twofold: Antigravity moved its current OAuth state into the native OS keyring, while Orca still preferred an expired legacy Gemini credential; the legacy per-model quota endpoint also does not expose Antigravity's current grouped five-hour/weekly limits.
Screenshots
Verified in a running Orca build: the Antigravity popover refreshes successfully and renders Gemini models plus Claude and GPT models, each with five-hour and weekly usage.

Testing
pnpm lintpnpm typecheckpnpm test— 2,802 files / 29,651 tests passed; 7 files / 43 tests skippedpnpm buildCoverage includes native keyring command selection and credential parsing, current/expired credential precedence, grouped quota parsing, missing reset metadata, CLI-first fetch precedence, stale-newer-log fallback to a live older AGY session, localized settings copy, and grouped popover rendering.
AI Review Report
Reviewed the complete diff against the recurring feedback on #8132 and the current rate-limit/status-bar PRs.
updatedAt; no assertion depends on wall-clock time.translate(...)entries with catalog parity for en/es/ja/ko/zh. The audit caught and fixed the AccountsPane runtime-label contract before publication.execFileargument arrays for macOSsecurity, Linux/BSDsecret-tool, and Windows Credential Manager via a constant PowerShell script. Paths use Node path utilities; no shortcut, shell interpolation, or separator assumptions were added. Usage remains scoped to the desktop host, including when worktrees are reached over SSH.Relevant open-PR review: #8669 touches the same generic tooltip, shared rate-limit types, and locale catalogs for Cursor usage. There is no behavioral dependency, but whichever PR merges second may need a straightforward rebase in those files. #8717 and #8643 are in the same rate-limit domain without file overlap.
Security Audit
127.0.0.1, sends no OAuth credentials to the CLI service, uses a 3-second timeout and 1 MiB response cap, and validates the returned quota schema.Notes
agydoes not expose a public/usagecommand. Orca reads the already-running CLI's local quota service instead of launching an interactive login flow. The Antigravity desktop app is optional and serves only as a fallback.stablyai/orcamainat9d5173252.