{"slug": "oh-my-pi-enable-antigravity", "title": "oh my pi enable antigravity", "summary": "A developer published an extension for oh-my-pi (version 18.18.4 and later) that re-enables Google Antigravity logins and models after upstream PR #18622 added a `disabled` rule to the google-antigravity catalog entry. The extension strips the restrictive auth policy hooks, wraps the provider definition to bypass the free-tier eligibility check, and resolves a project ID via the loadCodeAssist endpoint, falling back to \"aicode-consumers\" when none is found.", "body_md": "|  | /** | \n|  | * Extension to re-enable Google Antigravity logins and models in oh-my-pi >= 18.18.4, | \n|  | * and bypass the artificial \"ineligible account\" location/free-tier block. | \n|  | * | \n|  | * Upstream PR #18622 added a `disabled` rule to google-antigravity in the catalog, | \n|  | * and google-antigravity-project has a rigid check that throws if free-tier is | \n|  | * flagged as ineligible, even when the user has valid OAuth credentials, paid tier, | \n|  | * or an active cloudaicompanionProject. | \n|  | */ | \n|  | import * as compatAuth from \"@oh-my-pi/pi-catalog/compat/auth\"; | \n|  | import { getProviderDefinition, registerOAuthProvider } from \"@oh-my-pi/pi-ai\"; | \n|  | import { Database } from \"bun:sqlite\"; | \n|  | import { getAgentDbPath } from \"@oh-my-pi/pi-utils\"; | \n|  | // 1. Clear paused status and remove restrictive built-in hooks | \n|  | const policy = compatAuth.authPolicyFor(\"google-antigravity\"); | \n|  | if (policy) { | \n|  | delete (policy as any).disabled; | \n|  | if (policy.login) { | \n|  | delete (policy.login as any).afterExchange; | \n|  | } | \n|  | if (policy.refresh) { | \n|  | delete (policy.refresh as any).afterRefresh; | \n|  | } | \n|  | } | \n|  | // 2. Wrap provider definition to bypass the eligibility check | \n|  | const def = getProviderDefinition(\"google-antigravity\"); | \n|  | const formatApiKey = (creds: any) => | \n|  | JSON.stringify({ | \n|  | token: creds.access, | \n|  | projectId: creds.projectId, | \n|  | refreshToken: creds.refresh, | \n|  | expiresAt: creds.expires, | \n|  | email: creds.email, | \n|  | accountId: creds.accountId, | \n|  | }); | \n|  | if (def && def.login) { | \n|  | const originalLogin = def.login; | \n|  | const originalRefreshToken = def.refreshToken; | \n|  | const resolveProjectId = async ( | \n|  | accessToken: string, | \n|  | onProgress?: (msg: string) => void, | \n|  | signal?: AbortSignal | \n|  | ): Promise<string> => { | \n|  | let projectId = | \n|  | process.env.GOOGLE_CLOUD_PROJECT \\|\\| process.env.GOOGLE_CLOUD_PROJECT_ID; | \n|  | if (!projectId) { | \n|  | onProgress?.(\"Checking Antigravity project status...\"); | \n|  | try { | \n|  | const res = await fetch( | \n|  | \"https://daily-cloudcode-pa.googleapis.com/v1internal:loadCodeAssist\", | \n|  | { | \n|  | method: \"POST\", | \n|  | headers: { | \n|  | Authorization: `Bearer ${accessToken}`, | \n|  | \"Content-Type\": \"application/json\", | \n|  | \"User-Agent\": \"antigravity\", | \n|  | }, | \n|  | body: JSON.stringify({ metadata: { ideType: \"ANTIGRAVITY\" } }), | \n|  | signal, | \n|  | } | \n|  | ); | \n|  | if (res.ok) { | \n|  | const data = (await res.json()) as any; | \n|  | projectId = | \n|  | typeof data.cloudaicompanionProject === \"string\" | \n|  | ? data.cloudaicompanionProject | \n|  | : data.cloudaicompanionProject?.id; | \n|  | } | \n|  | } catch {} | \n|  | } | \n|  | return projectId \\|\\| \"aicode-consumers\"; | \n|  | }; | \n|  | const customLogin = async (ctrl: any) => { | \n|  | // def.login handles local callback server and OAuth token exchange with Google | \n|  | const creds = await originalLogin(ctrl); | \n|  | // Resolve project without the artificial free-tier location eligibility block | \n|  | const projectId = | \n|  | creds.projectId \\|\\| | \n|  | (await resolveProjectId(creds.access, ctrl.onProgress, ctrl.signal)); | \n|  | return { | \n|  | ...creds, | \n|  | projectId, | \n|  | }; | \n|  | }; | \n|  | const customRefreshToken = async (creds: any, signal?: AbortSignal) => { | \n|  | const refreshed = await originalRefreshToken(creds, signal); | \n|  | return { | \n|  | ...refreshed, | \n|  | projectId: creds.projectId \\|\\| refreshed.projectId \\|\\| \"aicode-consumers\", | \n|  | }; | \n|  | }; | \n|  | registerOAuthProvider({ | \n|  | id: \"google-antigravity\", | \n|  | name: def.name, | \n|  | login: customLogin, | \n|  | refreshToken: customRefreshToken, | \n|  | getApiKey: formatApiKey, | \n|  | }); | \n|  | registerOAuthProvider({ | \n|  | id: \"antigravity\", | \n|  | name: def.name, | \n|  | storeCredentialsAs: \"google-antigravity\", | \n|  | login: customLogin, | \n|  | refreshToken: customRefreshToken, | \n|  | getApiKey: formatApiKey, | \n|  | }); | \n|  | } | \n|  | // 3. Bump auth_change_revision so CredentialPool picks up credentials | \n|  | try { | \n|  | const db = new Database(getAgentDbPath()); | \n|  | db.run(\"UPDATE auth_change_revision SET revision = revision + 1 WHERE id = 1\"); | \n|  | db.close(); | \n|  | } catch {} | \n|  | export default function (api: any) { | \n|  | if (api.extension) { | \n|  | api.extension.registersProviders = true; | \n|  | } | \n|  | api.on(\"session_start\", async (_event: any, ctx: any) => { | \n|  | if (ctx.model && ctx.model.provider !== \"google-antigravity\") { | \n|  | const target = ctx.modelRegistry.find(\"google-antigravity\", \"gemini-3.8-flash\"); | \n|  | if (target) { | \n|  | await api.runtime.setModel(target); | \n|  | } | \n|  | } | \n|  | }); | \n|  | } |", "url": "https://wpnews.pro/news/oh-my-pi-enable-antigravity", "canonical_source": "https://gist.github.com/XSilverTH/6519a09b6d57966cc4d107c966c18c4f", "published_at": "2026-11-10 09:33:55+00:00", "updated_at": "2026-11-10 17:27:19.883219+00:00", "lang": "en", "topics": ["ai-tools", "developer-tools", "ai-agents"], "entities": ["Google", "oh-my-pi", "Google Antigravity", "Bun"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/oh-my-pi-enable-antigravity", "markdown": "https://wpnews.pro/news/oh-my-pi-enable-antigravity.md", "text": "https://wpnews.pro/news/oh-my-pi-enable-antigravity.txt", "jsonld": "https://wpnews.pro/news/oh-my-pi-enable-antigravity.jsonld"}}