Skip to content

Add Antigravity account switching - #937

Merged
steipete merged 3 commits into
steipete:mainfrom
hhh2210:antigravity-multi-account
May 14, 2026
Merged

Add Antigravity account switching#937
steipete merged 3 commits into
steipete:mainfrom
hhh2210:antigravity-multi-account

Conversation

@hhh2210

@hhh2210 hhh2210 commented May 13, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds Antigravity to CodexBar's existing token-account quick switching system for multiple Google OAuth accounts.
  • Upserts successful Antigravity OAuth logins into token accounts while preserving the shared ~/.codexbar/antigravity/oauth_creds.json fallback when no token account is selected.
  • Passes selected account credentials to remote usage fetches through ANTIGRAVITY_OAUTH_CREDENTIALS_JSON, with invalid selected-account JSON failing closed instead of silently falling back to shared credentials.
  • Keeps selected-account refresh/project updates isolated from shared credentials and writes those updates back to the selected token account.
  • Forces the Google OAuth account chooser for "Add Google Account" so adding another account does not silently reuse the current browser session.

Review feedback addressed

  • Codex P1: selected token-account refresh/project updates were not persisted back into the token account. Fixed by threading a selected-account token updater through ProviderFetchContext into the Antigravity fetcher.
  • Codex P2: missing-email OAuth credentials could merge distinct accounts through the fallback Google Account label. Fixed by matching only non-empty email identifiers and using numbered fallback labels.
  • Copilot low-confidence note: existing token-account organizationID is no longer cleared during Antigravity account updates.
  • Follow-up local review: project ID persistence is best effort again, so a cache write failure does not fail an otherwise successful usage fetch.

Testing

  • ./Scripts/lint.sh format && ./Scripts/lint.sh lint passed, 0 violations.
  • swift test --filter AntigravityRemoteUsageFetcherTests passed, 16 tests.
  • swift test --filter SettingsStoreCoverageTests passed, 28 tests.
  • swift test --filter AntigravityLoginAlertTests passed, 5 tests.
  • swift test passed, 2356 tests in 292 suites.
  • ./Scripts/compile_and_run.sh passed, built the production app, packaged CodexBar.app, launched it, and verified OK: CodexBar is running.

Closes #936

Copilot AI review requested due to automatic review settings May 13, 2026 10:14

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 19e9365428

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +461 to +465
if let tokenValue = environment[AntigravityOAuthCredentialsStore.environmentCredentialsKey] {
guard let credentials = AntigravityOAuthCredentialsStore.credentials(fromTokenAccountValue: tokenValue) else {
throw AntigravityRemoteFetchError.parseFailed("Could not decode selected account credentials.")
}
return (credentials, nil)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Persist selected-account credential updates

When credentials come from ANTIGRAVITY_OAUTH_CREDENTIALS_JSON, this path returns store: nil, so later refresh/project updates are never persisted (refreshAccessToken only saves when a store exists). On the next fetch, the provider re-reads the same stale token-account JSON and must refresh again, which can cause repeated OAuth refresh calls every cycle after first expiry and can break account usage if the refresh token/client fields ever rotate.

Useful? React with 👍 / 👎.

Comment on lines +29 to +31
let index = data.accounts.firstIndex(where: { account in
account.externalIdentifier == email || account.label == label
})

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Avoid merging distinct accounts on fallback label

This upsert match treats account.label == "Google Account" as identity, so any login where credentials.email is missing will overwrite an existing unlabeled account instead of creating a new one. Since email is optional in the OAuth credentials model, this can collapse multiple real accounts into one entry and defeats the new quick-switching behavior for those logins.

Useful? React with 👍 / 👎.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR adds Antigravity to CodexBar’s token-account quick switching system so multiple Google OAuth accounts can be saved, selected, and used for remote usage fetching via an explicit environment override.

Changes:

  • Adds Antigravity token-account support metadata and wiring so selected accounts inject credentials via ANTIGRAVITY_OAUTH_CREDENTIALS_JSON.
  • Updates Antigravity remote usage fetching to prefer selected token-account credentials (and to fail on invalid selected-account JSON instead of silently falling back).
  • Adds/updates tests and documentation describing the multi-account OAuth flow and expected behavior.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
Tests/CodexBarTests/SettingsStoreCoverageTests.swift Adds coverage for Antigravity OAuth upsert behavior into token accounts.
Tests/CodexBarTests/AntigravityRemoteUsageFetcherTests.swift Adds tests for token-account injection, selection precedence, refresh isolation, and invalid selected-account handling.
Sources/CodexBarCore/TokenAccountSupportCatalog+Data.swift Registers Antigravity as a token-account-capable provider and defines env injection key/UX strings.
Sources/CodexBarCore/Providers/Antigravity/AntigravityRemoteUsageFetcher.swift Adds environment-driven credential selection and isolates persistence based on credential source.
Sources/CodexBarCore/Providers/Antigravity/AntigravityProviderDescriptor.swift Passes provider fetch context environment into the Antigravity remote fetcher.
Sources/CodexBarCore/Providers/Antigravity/AntigravityOAuthCredentialsStore.swift Adds env key constant and JSON (de)serialization helpers for token-account values.
Sources/CodexBar/Providers/Antigravity/AntigravitySettingsStore.swift Adds Antigravity OAuth account upsert into token accounts after login.
Sources/CodexBar/Providers/Antigravity/AntigravityProviderImplementation.swift Observes token accounts, adjusts settings action labeling, and adds a login menu override.
Sources/CodexBar/Providers/Antigravity/AntigravityLoginFlow.swift Upserts shared credentials into a token account after a successful Antigravity login flow.
docs/antigravity.md Documents OAuth multi-account switching and remote OAuth endpoints.
Comments suppressed due to low confidence (1)

Sources/CodexBar/Providers/Antigravity/AntigravitySettingsStore.swift:41

  • The upsert path always passes organizationID: .some(nil) when updating an existing Antigravity token account, which forcibly clears any previously stored organization/workspace value. If Antigravity doesn’t use organizationID, it’s safer to leave it unchanged by omitting the parameter (or only setting it when you intentionally want to change it).
            self.updateTokenAccount(
                provider: .antigravity,
                accountID: account.id,
                label: label,
                token: token,
                externalIdentifier: .some(email),
                organizationID: .some(nil))
            self.setActiveTokenAccountIndex(index, for: .antigravity)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +25 to +30
let email = credentials.email?.trimmingCharacters(in: .whitespacesAndNewlines)
let label = (email?.isEmpty == false) ? email! : "Google Account"
let data = self.tokenAccountsData(for: .antigravity)
if let data,
let index = data.accounts.firstIndex(where: { account in
account.externalIdentifier == email || account.label == label
Comment on lines +461 to +466
if let tokenValue = environment[AntigravityOAuthCredentialsStore.environmentCredentialsKey] {
guard let credentials = AntigravityOAuthCredentialsStore.credentials(fromTokenAccountValue: tokenValue) else {
throw AntigravityRemoteFetchError.parseFailed("Could not decode selected account credentials.")
}
return (credentials, nil)
}
Comment on lines +60 to 65
let accountCount = context.settings.tokenAccounts(for: .antigravity).count
let loginTitle = accountCount > 0 ? "Add Google Account" : "Login with Google"
let subtitle = """
Stores credentials in ~/.codexbar/antigravity/oauth_creds.json. Uses Antigravity.app OAuth when available, \
Stores each signed-in Google account for quick Antigravity switching. Uses Antigravity.app OAuth when available, \
or ANTIGRAVITY_OAUTH_CLIENT_ID and ANTIGRAVITY_OAUTH_CLIENT_SECRET as an override.
"""
Comment thread docs/antigravity.md
Comment on lines 31 to 32
## Data sources + fallback order

@hhh2210

hhh2210 commented May 13, 2026

Copy link
Copy Markdown
Contributor Author

Update: pushed commit 075852bd after addressing the automated review feedback and the prior CI lint failure. The PR description now lists the review items handled and the local verification results. Latest CI run is still in progress: both Linux CLI jobs have passed, and the macOS lint-build-test job has passed its lint step and is currently running Swift tests.

ChatGPT Atlas 2026-05-13 18 37 52

@steipete
steipete merged commit a15df5c into steipete:main May 14, 2026
4 checks passed
steipete added a commit that referenced this pull request May 14, 2026
* Improve Kiro credits UX

* Add provider changelog links

* Fix changelog menu test

* feat: gate provider changelog links behind setting

* Address Kiro review feedback

* Polish Kiro credit detail styling

* fix: repair stale managed Codex account removal

* fix: handle Claude enterprise web accounts (#941)

Fixes Claude Enterprise/organization web accounts by tolerating null session-window usage and exposing an optional organization ID field for Claude token accounts.

Local verification:
- swift test --filter 'ClaudeWebEnterpriseUsageTests|ProvidersPaneCoverageTests|ClaudeUsageTests'
- make check

Co-authored-by: Claude <noreply@anthropic.com>

* docs: update changelog for Claude enterprise fix

* fix: handle quota and usage edge cases

* Rebalance Kimi provider icon (#912)

* Add zh-Hans translations for Claude peak hour labels (#921)

* docs: update changelog for recent contributor fixes

* Add Tahoe menu bar visibility guidance

Co-authored-by: Piotr Durlej <pdurlej@users.noreply.github.com>

* Coalesce historical pace reset buckets

Co-authored-by: zhulijin1991 <zhulijin1991@users.noreply.github.com>

* Add Codex priority cost pricing

Co-authored-by: Bryan Font <bfont@me.com>

* fix: parse Claude web spend limits

* fix: refresh Gemini credentials without access token

* refactor: split Claude web extra usage helpers

* fix: defer account switcher menu rebuilds

Fixes #944.

Refs #946.

Co-authored-by: Jakub Hašek <kubahasek@users.noreply.github.com>

* docs: fix changelog spacing

* fix: handle unavailable Codex limits gracefully

* docs: update unreleased changelog

* fix: repair update and account menu paths

Co-authored-by: Radek Sienkiewicz <mail@velvetshark.com>

* fix: handle account-scoped usage and menu login bugs

* Add Antigravity account switching (#937)

* Add Antigravity account switching

* Force Antigravity account chooser

* Persist Antigravity selected account updates

* docs: add Antigravity account switching changelog

---------

Co-authored-by: thiagocaltoe <thiago12_fera@hotmail.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Clint Andrew Hall <clint@clintandrewhall.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Giuseppe Bisemi <giuseppe.bisemi@gmail.com>
Co-authored-by: HaiTao Wu <whtis@users.noreply.github.com>
Co-authored-by: Piotr Durlej <pdurlej@users.noreply.github.com>
Co-authored-by: zhulijin1991 <167979819+zhulijin1991@users.noreply.github.com>
Co-authored-by: zhulijin1991 <zhulijin1991@users.noreply.github.com>
Co-authored-by: iam-brain <94809115+iam-brain@users.noreply.github.com>
Co-authored-by: Bryan Font <bfont@me.com>
Co-authored-by: Jakub Hašek <kubahasek@users.noreply.github.com>
Co-authored-by: Radek Sienkiewicz <mail@velvetshark.com>
Co-authored-by: Larry Hao(郝卓远) <107194248+hhh2210@users.noreply.github.com>
LeoLin990405 pushed a commit to LeoLin990405/CodexBar that referenced this pull request Aug 6, 2026
* Add Antigravity account switching

* Force Antigravity account chooser

* Persist Antigravity selected account updates
LeoLin990405 pushed a commit to LeoLin990405/CodexBar that referenced this pull request Aug 6, 2026
* Improve Kiro credits UX

* Add provider changelog links

* Fix changelog menu test

* feat: gate provider changelog links behind setting

* Address Kiro review feedback

* Polish Kiro credit detail styling

* fix: repair stale managed Codex account removal

* fix: handle Claude enterprise web accounts (steipete#941)

Fixes Claude Enterprise/organization web accounts by tolerating null session-window usage and exposing an optional organization ID field for Claude token accounts.

Local verification:
- swift test --filter 'ClaudeWebEnterpriseUsageTests|ProvidersPaneCoverageTests|ClaudeUsageTests'
- make check

Co-authored-by: Claude <noreply@anthropic.com>

* docs: update changelog for Claude enterprise fix

* fix: handle quota and usage edge cases

* Rebalance Kimi provider icon (steipete#912)

* Add zh-Hans translations for Claude peak hour labels (steipete#921)

* docs: update changelog for recent contributor fixes

* Add Tahoe menu bar visibility guidance

Co-authored-by: Piotr Durlej <pdurlej@users.noreply.github.com>

* Coalesce historical pace reset buckets

Co-authored-by: zhulijin1991 <zhulijin1991@users.noreply.github.com>

* Add Codex priority cost pricing

Co-authored-by: Bryan Font <bfont@me.com>

* fix: parse Claude web spend limits

* fix: refresh Gemini credentials without access token

* refactor: split Claude web extra usage helpers

* fix: defer account switcher menu rebuilds

Fixes steipete#944.

Refs steipete#946.

Co-authored-by: Jakub Hašek <kubahasek@users.noreply.github.com>

* docs: fix changelog spacing

* fix: handle unavailable Codex limits gracefully

* docs: update unreleased changelog

* fix: repair update and account menu paths

Co-authored-by: Radek Sienkiewicz <mail@velvetshark.com>

* fix: handle account-scoped usage and menu login bugs

* Add Antigravity account switching (steipete#937)

* Add Antigravity account switching

* Force Antigravity account chooser

* Persist Antigravity selected account updates

* docs: add Antigravity account switching changelog

---------

Co-authored-by: thiagocaltoe <thiago12_fera@hotmail.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Clint Andrew Hall <clint@clintandrewhall.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Giuseppe Bisemi <giuseppe.bisemi@gmail.com>
Co-authored-by: HaiTao Wu <whtis@users.noreply.github.com>
Co-authored-by: Piotr Durlej <pdurlej@users.noreply.github.com>
Co-authored-by: zhulijin1991 <167979819+zhulijin1991@users.noreply.github.com>
Co-authored-by: zhulijin1991 <zhulijin1991@users.noreply.github.com>
Co-authored-by: iam-brain <94809115+iam-brain@users.noreply.github.com>
Co-authored-by: Bryan Font <bfont@me.com>
Co-authored-by: Jakub Hašek <kubahasek@users.noreply.github.com>
Co-authored-by: Radek Sienkiewicz <mail@velvetshark.com>
Co-authored-by: Larry Hao(郝卓远) <107194248+hhh2210@users.noreply.github.com>
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.

Support quick switching between multiple Antigravity Google accounts

3 participants