Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 49 additions & 2 deletions open-sse/services/antigravityHeaders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,51 @@ import {
getCachedAntigravityIdeVersion,
} from "./antigravityVersion.ts";

// loadCodeAssist/onboardUser's `metadata` body is a protobuf-JSON-shaped
// object — ideType/pluginType are int32 enums on the wire, not strings, and
// platform is required. Values mirror the sibling 9router project's
// LOAD_CODE_ASSIST_METADATA (open-sse/config/appConstants.js).
//
// Live comparison (same Google account, same host, 2026-08-25): 9Router
// (this exact metadata shape, including a Linux platform enum) succeeded
// against loadCodeAssist/onboardUser; OmniRoute (ideType as the bare string
// "ANTIGRAVITY", no platform/pluginType) got 403 on both from the identical
// account. Sending an incomplete client identity reads to Google's backend
// as untrusted and gets rejected.
//
// NOTE: a prior version of this function carried the comment "Matches
// Antigravity-Manager quota.rs: only ideType (no platform — LINUX is
// rejected)" — the opposite conclusion, presumably true when it was
// written. Trusting the fresh live comparison over that stale claim here;
// if this regresses Linux specifically, that old note is why.
const ANTIGRAVITY_IDE_TYPE_ENUM = 9;
const ANTIGRAVITY_PLUGIN_TYPE_GEMINI_ENUM = 2;
const ANTIGRAVITY_PLATFORM_ENUM = {
UNSPECIFIED: 0,
DARWIN_AMD64: 1,
DARWIN_ARM64: 2,
LINUX_AMD64: 3,
LINUX_ARM64: 4,
WINDOWS_AMD64: 5,
} as const;

function resolveAntigravityPlatformEnum(): number {
const platform = process.platform;
const arch = process.arch;
if (platform === "darwin") {
return arch === "arm64"
? ANTIGRAVITY_PLATFORM_ENUM.DARWIN_ARM64
: ANTIGRAVITY_PLATFORM_ENUM.DARWIN_AMD64;
}
if (platform === "linux") {
return arch === "arm64"
? ANTIGRAVITY_PLATFORM_ENUM.LINUX_ARM64
: ANTIGRAVITY_PLATFORM_ENUM.LINUX_AMD64;
}
if (platform === "win32") return ANTIGRAVITY_PLATFORM_ENUM.WINDOWS_AMD64;
return ANTIGRAVITY_PLATFORM_ENUM.UNSPECIFIED;
}

export const ANTIGRAVITY_IDE_NODE_API_CLIENT = "google-api-nodejs-client/10.3.0";
export const ANTIGRAVITY_IDE_NODE_X_GOOG_API_CLIENT = "gl-node/22.21.1";

Expand Down Expand Up @@ -68,8 +113,10 @@ export function getAntigravityIdeNodeHeaders(accessToken?: string | null): Recor
}

/** Native loadCodeAssist body metadata captured from both official clients. */
export function getAntigravityLoadCodeAssistMetadata(): Record<string, string> {
export function getAntigravityLoadCodeAssistMetadata(): Record<string, number> {
return {
ideType: "ANTIGRAVITY",
ideType: ANTIGRAVITY_IDE_TYPE_ENUM,
platform: resolveAntigravityPlatformEnum(),
pluginType: ANTIGRAVITY_PLUGIN_TYPE_GEMINI_ENUM,
};
}
13 changes: 9 additions & 4 deletions tests/unit/antigravity-headers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,13 @@ test("OAuth User-Agent selection keeps IDE and CLI identities independent", () =
assert.match(getAntigravityOAuthUserAgent("cli"), /^antigravity\/cli\/1\.2\.0 /);
});

test("loadCodeAssist body metadata remains ideType only", () => {
assert.deepEqual(getAntigravityLoadCodeAssistMetadata(), { ideType: "ANTIGRAVITY" });
assert.equal("platform" in getAntigravityLoadCodeAssistMetadata(), false);
assert.equal("pluginType" in getAntigravityLoadCodeAssistMetadata(), false);
test("loadCodeAssist body metadata sends numeric protobuf-JSON enums, not a bare ideType string", () => {
// Google's backend 403s loadCodeAssist/onboardUser when ideType is sent as
// the string "ANTIGRAVITY" with platform/pluginType omitted — verified via
// a live side-by-side against 9router (same account, same host) using the
// full enum shape below, which succeeded. See antigravityHeaders.ts for
// the full incident note.
const metadata = getAntigravityLoadCodeAssistMetadata();
assert.deepEqual(metadata, { ideType: 9, platform: metadata.platform, pluginType: 2 });
assert.equal(typeof metadata.platform, "number");
});
Loading