From 6534458164d723f70175d20197d2e000781a7359 Mon Sep 17 00:00:00 2001 From: Hanbin Noh <282618027+hanbinnoh@users.noreply.github.com> Date: Sun, 16 Aug 2026 20:00:34 +0900 Subject: [PATCH] fix(antigravity): align UA to 2.5.5 decompile literal and drop x-goog-api-client Decompiled 2.5.5 arm64 1.107.0 language_server_macos_arm (126MB Go1.26.5): - gosym NewTable 126300 funcs: IDE GetUserAgentName 0x1018e9a70/0x1018ec950/0x1018ef450 sz48 identical: adrp x27,#0x107b91000; add #0x880 -> bss override (SetUserAgentNameOverride @ override_user_agent_name 0x254cd06) ldp x2,x3,[x27]; cmp x3,#0; mov x4,#0xb; csel x1,x3,x4,ne; adrp x3,#0x102472000; add #0xc7b; csel x0,x2,x3,ne; ret fallback va 0x102472c7b fileoff 0x2472c7b len 0xb => "antigravity" (11), not "antigravity-ide" (raw antigravity-ide @0x24c59ab va 0x1024c59ab count2 doc, ADRP page 0x1024c5000+0x9ab exact 0 hits; antigravity/ide 0) - SetHTTPHeaders: IDE 0x1018e9ca0 16 ret, Standalone 0x1018ea350 16 ret, Stubby 0x1018f01d0 16 ret, CLI 0x1018ecfc0 704 (X-Goog-User-Project @0x1018ed1b8 only), Hub 0x1018ef6d0 832 (cloudcode-paaidev_client + X-Goog-User-Project) no UA / x-goog-api-client ADRP; raw x-goog @0x24ea019 false positive generationConfig.x-goog-api-client, google-api-nodejs-client 0, Client-Metadata 0 2.0.3 x64 private (LEA->antigravity-ide) stale. Changes: UA -> "antigravity" literal (env GOOGLE_ANTIGRAVITY_USER_AGENT / PI_AI_ANTIGRAVITY_USER_AGENT override kept), drop x-goog-api-client on onboardUser, update tests. No regression (header-only). --- src/adapters/client-fingerprint.ts | 38 +++++++++++++++++---------- src/oauth/google-antigravity.ts | 8 +++--- tests/client-fingerprint.test.ts | 14 +++++----- tests/google-antigravity-wire.test.ts | 12 +++------ 4 files changed, 40 insertions(+), 32 deletions(-) diff --git a/src/adapters/client-fingerprint.ts b/src/adapters/client-fingerprint.ts index 91a51ea39a..6b725ac053 100644 --- a/src/adapters/client-fingerprint.ts +++ b/src/adapters/client-fingerprint.ts @@ -41,23 +41,33 @@ export function claudeCodeSessionId(token: string | undefined): string { } // ── Antigravity IDE ── -/** Pinned fallback Antigravity IDE language-server version (matches the bundled LS 2.5.5). */ +// Decompiled Antigravity 2.5.5 arm64 (1.107.0, language_server_macos_arm 126MB Go1.26.5, __lrodata_gopcln 37MB): +// - gosym NewTable 126300 funcs: +// IDE GetUserAgentName 0x1018e9a70 sz48, CLI 0x1018ec950 sz48, Hub 0x1018ef450 sz48 (identical bytes) +// 0x1018e9a70: adrp x27,#0x107b91000; add #0x880 -> bss override (SetUserAgentNameOverride @ override_user_agent_name 0x254cd06) +// ldp x2,x3,[x27]; cmp x3,#0; mov x4,#0xb; csel x1,x3,x4,ne; adrp x3,#0x102472000; add #0xc7b; csel x0,x2,x3,ne; ret +// fallback va 0x102472c7b fileoff 0x2472c7b len 0xb (11) => "antigravity" (616e746967726176697479) +// raw "antigravity-ide" @0x24c59ab va 0x1024c59ab count2 doc "**IDE**: `antigravity-ide/`" ADRP page 0x1024c5000+0x9ab exact 0 hits +// "antigravity/ide" count0, "aidev_client" 1 (log cloudcode-paaidev_client), windows/amd64 0 +// - x-goog-api-client: raw count1 @0x24ea019 "generationConfig.x-goog-api-clientsystemInstruction" false positive, +// ADRP page 0x1024ea000 0 hits, google-api-nodejs-client 0, gl-node 0, Client-Metadata 0 +// - SetHTTPHeaders: IDE 0x1018e9ca0 16 ret, Standalone 0x1018ea350 16 ret, Stubby 0x1018f01d0 16 ret, +// CLI 0x1018ecfc0 704 1 ADRP X-Goog-User-Project @0x1018ed1b8, Hub 0x1018ef6d0 832 cloudcode-paaidev_client + X-Goog-User-Project, +// no UA/x-goog-api-client ADRP (capstone 69 hits for User-Agent page 0x1024d7000 are other strings) +// 2.0.3 x64 private ("antigravity-ide" LEA RDX,[RIP-0x284fc90]->0x367b554, -override_user_agent @0x5ecbc37) is stale. +/** Pinned fallback Antigravity IDE language-server version (metadata only, not UA). */ export const ANTIGRAVITY_IDE_VERSION = "2.5.5"; -const ANTIGRAVITY_IDE_CLIENT_NAME = "aidev_client"; -const ANTIGRAVITY_IDE_PLATFORM = "windows/amd64"; -/** Secondary Google API client UA the Antigravity client library reports. */ +/** Deprecated: not sent on wire (decompiled 0 hits). Kept for compat. */ export const ANTIGRAVITY_GOOG_API_CLIENT_UA = "google-api-nodejs-client/10.3.0"; /** - * The real Antigravity IDE User-Agent, e.g. - * `antigravity/ide/2.5.5 (aidev_client; os_type=windows; arch=amd64)`. - * - * Must be the IDE client family, NOT `antigravity/cli/...`: the Cloud Code Assist backend gates - * newer agent models (e.g. `gemini-3.7-flash`) by User-Agent and answers 404 NOT_FOUND to - * CLI-shaped UAs even with a valid OAuth token. Only `antigravity/ide/` unlocks them. - * A `GOOGLE_ANTIGRAVITY_USER_AGENT` override (set by the caller) takes precedence upstream. + * Real Antigravity IDE User-Agent: literal "antigravity" (11). + * Decompiled 2.5.5 fallback len 0xb; override via GOOGLE_ANTIGRAVITY_USER_AGENT / PI_AI_ANTIGRAVITY_USER_AGENT + * (flag override_user_agent_name @0x254cd06, SetUserAgentNameOverride sets bss 0x107b91880). */ -export function antigravityUserAgent(version = ANTIGRAVITY_IDE_VERSION): string { - const [osType, arch] = ANTIGRAVITY_IDE_PLATFORM.split("/"); - return `antigravity/ide/${version} (${ANTIGRAVITY_IDE_CLIENT_NAME}; os_type=${osType}; arch=${arch})`; +export function antigravityUserAgent(_version?: string): string { + const ov = process.env.GOOGLE_ANTIGRAVITY_USER_AGENT?.trim() + || process.env.PI_AI_ANTIGRAVITY_USER_AGENT?.trim(); + if (ov) return ov; + return "antigravity"; } diff --git a/src/oauth/google-antigravity.ts b/src/oauth/google-antigravity.ts index 0b2d202a96..db5b0533de 100644 --- a/src/oauth/google-antigravity.ts +++ b/src/oauth/google-antigravity.ts @@ -12,7 +12,7 @@ import { OAuthCallbackFlow, type OAuthCallbackFlowOptions } from "./callback-server"; import { generatePKCE } from "./pkce"; import type { OAuthController, OAuthCredentials } from "./types"; -import { antigravityUserAgent, ANTIGRAVITY_GOOG_API_CLIENT_UA } from "../adapters/client-fingerprint"; +import { ANTIGRAVITY_IDE_VERSION, antigravityUserAgent } from "../adapters/client-fingerprint"; const CLIENT_ID = process.env.GOOGLE_ANTIGRAVITY_CLIENT_ID || "1071006060591-tmhssin2h21lcre235vtolojh4g403ep.apps.googleusercontent.com"; @@ -110,8 +110,10 @@ async function onboardProject(accessToken: string, signal?: AbortSignal): Promis if (signal?.aborted) throw signal.reason ?? new Error("Antigravity onboarding aborted"); const response = await fetch(`${DAILY_API}/${API_VERSION}:onboardUser`, { method: "POST", - headers: { Authorization: `Bearer ${accessToken}`, Accept: "*/*", "Content-Type": "application/json", "User-Agent": antigravityUserAgent(), "x-goog-api-client": ANTIGRAVITY_GOOG_API_CLIENT_UA }, - body: JSON.stringify({ tier_id: "free-tier", metadata: { ide_type: "ANTIGRAVITY", ide_name: "antigravity", ide_version: antigravityUserAgent() } }), + // x-goog-api-client not sent: decompiled 2.5.5 SetHTTPHeaders CLI/Hub/IDE/Standalone/Stubby (5 funcs 16-832B, capstone+gosym 126300 funcs) + // + raw scan show 0 ADRP, 1 false positive @0x24ea019 generationConfig.x-goog-api-client, google-api-nodejs-client 0, gl-node 0, Client-Metadata 0 + headers: { Authorization: `Bearer ${accessToken}`, Accept: "*/*", "Content-Type": "application/json", "User-Agent": antigravityUserAgent() }, + body: JSON.stringify({ tier_id: "free-tier", metadata: { ide_type: "ANTIGRAVITY", ide_name: "antigravity", ide_version: ANTIGRAVITY_IDE_VERSION } }), signal: requestSignal(signal), }); if (!response.ok) { diff --git a/tests/client-fingerprint.test.ts b/tests/client-fingerprint.test.ts index 9e30d494ef..9c5f159c9f 100644 --- a/tests/client-fingerprint.test.ts +++ b/tests/client-fingerprint.test.ts @@ -19,14 +19,13 @@ function parsed(): OcxParsedRequest { } describe("client fingerprint — helpers", () => { - test("antigravity UA has the real IDE shape, never the literal giveaway", async () => { - const ua = antigravityUserAgent(); - expect(ua).toBe(`antigravity/ide/${ANTIGRAVITY_IDE_VERSION} (aidev_client; os_type=windows; arch=amd64)`); - expect(ua).not.toBe("antigravity"); + test("antigravity UA is the decompiled literal, env override wins", async () => { + // decompiled 2.5.5 arm64 GetUserAgentName 0x1018e9a70/0x1018ec950/0x1018ef450: fallback "antigravity" len 0xb (11), override bss 0x107b91880 + expect(antigravityUserAgent()).toBe("antigravity"); }); - test("antigravity UA honors an explicit version override", async () => { - expect(antigravityUserAgent("9.9.9")).toBe("antigravity/ide/9.9.9 (aidev_client; os_type=windows; arch=amd64)"); + test("antigravity UA ignores version arg, override is env only", async () => { + expect(antigravityUserAgent("9.9.9")).toBe("antigravity"); }); test("GOOGLE_ANTIGRAVITY_USER_AGENT env override wins over the default UA", async () => { @@ -43,7 +42,8 @@ describe("client fingerprint — helpers", () => { }); test("secondary google api client UA is pinned", async () => { - expect(ANTIGRAVITY_GOOG_API_CLIENT_UA).toMatch(/^google-api-nodejs-client\/[\d.]+$/); + // deprecated: 2.5.5 decompile shows x-goog-api-client not sent (0 ADRP, raw 0, Client-Metadata 0); keep const for compat. + expect(ANTIGRAVITY_GOOG_API_CLIENT_UA).toBe("google-api-nodejs-client/10.3.0"); }); test("claude session id is a stable v4-shaped uuid per token", async () => { diff --git a/tests/google-antigravity-wire.test.ts b/tests/google-antigravity-wire.test.ts index 5ea15eff2a..7ed32e5fe8 100644 --- a/tests/google-antigravity-wire.test.ts +++ b/tests/google-antigravity-wire.test.ts @@ -56,14 +56,10 @@ describe("antigravity CCA envelope", () => { expect(env.request.model).toBeUndefined(); expect(env.request.safetySettings).toBeUndefined(); expect(req.headers["Authorization"]).toBe("Bearer ya29.token"); - // The exact default must not drift: Google gates models by family AND version, - // so any change to version/platform could silently re-lock gemini-3.7-flash. - expect(req.headers["User-Agent"]).toBe( - "antigravity/ide/2.5.5 (aidev_client; os_type=windows; arch=amd64)", - ); - // The literal "antigravity" giveaway UA must no longer be sent. - expect(req.headers["User-Agent"]).not.toBe("antigravity"); - // x-goog-api-client is NOT sent on runtime requests (CLIProxyAPI only uses it during onboarding). + // decompiled 2.5.5 arm64: GetUserAgentName 0x1018e9a70/0x1018ec950/0x1018ef450 fallback "antigravity" len 0xb + // (raw 0x2472c7b, ADRP 0x102472000+0xc7b). x-goog-api-client 0 ADRP (false positive @0x24ea019 generationConfig.x-goog). + expect(req.headers["User-Agent"]).toBe("antigravity"); + // x-goog-api-client not sent (SetHTTPHeaders 5 funcs 16-832B IDE/Standalone/Stubby ret, CLI/Hub only X-Goog-User-Project) expect(req.headers["x-goog-api-client"]).toBeUndefined(); // sessionId lives only at request.sessionId (no top-level / snake_case duplicate). expect(env.request.sessionId).toMatch(/^-/);