import * as NodeServices from "@effect/platform-node/NodeServices";import { expect, it } from "@effect/vitest";import { ANTIGRAVITY_DEFAULT_MODEL, ProviderInstanceId, type AntigravitySettings,} from "@t3tools/contracts";import { HostProcessEnvironment, HostProcessExecutablePath, HostProcessPlatform,} from "@t3tools/shared/hostProcess";import * as Effect from "effect/Effect";import * as Deferred from "effect/Deferred";import * as Fiber from "effect/Fiber";import * as FileSystem from "effect/FileSystem";import * as Layer from "effect/Layer";import * as Path from "effect/Path";import * as Schema from "effect/Schema";import * as TestClock from "effect/testing/TestClock";import * as ChildProcessSpawner from "effect/unstable/process/ChildProcessSpawner"; import * as BackgroundPolicy from "../../background/BackgroundPolicy.ts";import { ServerConfig } from "../../config.ts";import { ServerSettingsService } from "../../serverSettings.ts";import { AntigravityInstallation, AntigravityInstallationError, type AntigravityExecutable,} from "../AntigravityInstallation.ts";import { ANTIGRAVITY_AUTH_STDOUT_PREFIX, resolveAntigravityProfileDirectory,} from "../antigravityAuthSupport.ts";import { NoOpProviderEventLoggers, ProviderEventLoggers } from "../Layers/ProviderEventLoggers.ts";import * as ModelManifest from "../ModelManifest.ts";import { AntigravityDriver } from "./AntigravityDriver.ts"; const hostPlatform = HostProcessPlatform.defaultValue();const windowsHost = hostPlatform === "win32";const decodeRequest = Schema.decodeEffect( Schema.fromJsonString( Schema.Struct({ method: Schema.optional(Schema.String), params: Schema.optional(Schema.Record(Schema.String, Schema.Unknown)), }), ),);const blockedCredentialKeys = new Set([ "GEMINI_API_KEY", "GOOGLE_API_KEY", "GOOGLE_APPLICATION_CREDENTIALS", "GOOGLE_GENAI_USE_VERTEXAI",]); function shellQuote(value: string): string { return `'${value.replaceAll("'", `'"'"'`)}'`;} const makeHarness = Effect.fn("makeAntigravityDriverHarness")(function* ( options: { readonly config?: Partial<AntigravitySettings> } = {},) { const fs = yield* FileSystem.FileSystem; const path = yield* Path.Path; const config = yield* ServerConfig; const spawner = yield* ChildProcessSpawner.ChildProcessSpawner; const nodePath = yield* HostProcessExecutablePath; const baseEnv = yield* HostProcessEnvironment; const root = yield* fs.makeTempDirectoryScoped({ prefix: "t3-antigravity-driver-" }); const instanceId = ProviderInstanceId.make(path.basename(root)); const mockAgentPath = yield* path.fromFileUrl( new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), ); const requestLog = path.join(root, "requests.jsonl"); const profileDirectory = resolveAntigravityProfileDirectory(config.stateDir, instanceId); const instancePath = `${path.join(root, "instance-bin")}:${baseEnv.PATH ?? ""}`; const makeExecutable = Effect.fn("AntigravityDriverTest.makeExecutable")(function* ( name: string, loginRequired = false, ) { const directory = path.join(root, name); const executablePath = path.join(directory, "agy_acp_server.par"); const harnessPath = path.join(directory, "localharness_external"); yield* fs.makeDirectory(directory, { recursive: true }); const authorizationUrl = "https://accounts.google.com/o/oauth2/v2/auth?response_type=code&redirect_uri=http%3A%2F%2F127.0.0.1%3A51234%2F&state=fixture-state"; yield* fs.writeFileString( executablePath, [ "#!/bin/sh", ...(loginRequired ? [`printf '%s\\n' ${shellQuote(ANTIGRAVITY_AUTH_STDOUT_PREFIX + authorizationUrl)}`] : []), `exec ${shellQuote(nodePath)} ${shellQuote(mockAgentPath)} "$@"`, "", ].join("\n"), ); yield* fs.writeFileString(harnessPath, "#!/bin/sh\nexit 99\n"); yield* fs.chmod(executablePath, 0o755); yield* fs.chmod(harnessPath, 0o755); return { executablePath, harnessPath, source: "managed", version: name, managedVersionDirectory: directory, } satisfies AntigravityExecutable; }); const first = yield* makeExecutable("runtime 'one"); const second = yield* makeExecutable("runtime two"); const signedOut = yield* makeExecutable("runtime signed-out", true); const controls = { selected: first, failResolution: false, beforeAcquire: Effect.void }; const acquisitions: Array<{ binaryPath: string | undefined; path: string | undefined }> = []; const releases: Array<string | null> = []; const launches: Array<{ command: string; args: ReadonlyArray<string>; cwd: string | undefined; extendEnv: boolean | undefined; profileDirectory: string | undefined; harnessPath: string | undefined; forceFileStorage: string | undefined; credentialKeys: ReadonlyArray<string>; geminiApiKey: string | undefined; handle: ChildProcessSpawner.ChildProcessHandle; }> = []; const installation = Layer.mock(AntigravityInstallation)({ managedDirectory: root, acquire: (binaryPath, environment) => Effect.gen(function* () { acquisitions.push({ binaryPath, path: environment?.PATH }); yield* controls.beforeAcquire; if (controls.failResolution) { return yield* new AntigravityInstallationError({ operation: "resolve", detail: "Fixture resolution failed.", }); } const selected = controls.selected; yield* Effect.addFinalizer(() => Effect.sync(() => { releases.push(selected.version); }), ); return selected; }), }); const observedSpawner = ChildProcessSpawner.make((command) => Effect.gen(function* () { if (command._tag !== "StandardCommand") return yield* Effect.die("Unexpected process pipeline."); const handle = yield* spawner.spawn(command); const environment = command.options.env ?? {}; launches.push({ command: command.command, args: command.args, cwd: command.options.cwd, extendEnv: command.options.extendEnv, profileDirectory: environment.GEMINI_HOME, harnessPath: environment.ANTIGRAVITY_HARNESS_PATH, forceFileStorage: environment.AGY_ACP_FORCE_FILE_STORAGE, credentialKeys: Object.keys(environment).filter((key) => blockedCredentialKeys.has(key.toUpperCase()), ), geminiApiKey: environment.GEMINI_API_KEY, handle, }); return handle; }), ); const instance = yield* AntigravityDriver.create({ instanceId, displayName: "Google test account", enabled: false, config: { ...AntigravityDriver.defaultConfig(), ...options.config }, environment: [ { name: "PATH", value: instancePath }, { name: "T3_ACP_ANTIGRAVITY", value: "1" }, { name: "T3_ACP_REQUEST_LOG_PATH", value: requestLog }, { name: "GEMINI_API_KEY", value: "must-not-be-used" }, { name: "google_api_key", value: "must-not-be-used" }, { name: "GOOGLE_APPLICATION_CREDENTIALS", value: "/must-not-be-used.json" }, { name: "GOOGLE_GENAI_USE_VERTEXAI", value: "true" }, { name: "GEMINI_HOME", value: "/must-not-be-used" }, { name: "ANTIGRAVITY_HARNESS_PATH", value: "/must-not-be-used" }, { name: "BROWSER", value: "must-not-run" }, ].map((variable) => ({ ...variable, sensitive: false })), }).pipe( Effect.provide(installation), Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, observedSpawner), ); const refresh = instance.refreshModels; if (!refresh) return yield* Effect.die("Antigravity does not expose model refresh."); const readRequests = Effect.gen(function* () { if (!(yield* fs.exists(requestLog))) return []; const text = yield* fs.readFileString(requestLog); return yield* Effect.forEach(text.split(/\r?\n/u).filter(Boolean), (line) => decodeRequest(line), ); }); const assertClosed = Effect.gen(function* () { for (const launch of launches) { // Cancelled startup can report a signal instead of a numeric exit code. yield* launch.handle.exitCode.pipe(Effect.ignore); expect(yield* launch.handle.isRunning).toBe(false); if (launch.cwd) expect(yield* fs.exists(launch.cwd)).toBe(false); } }); return { instance, refresh, fs, profileDirectory, instancePath, first, second, signedOut, controls, acquisitions, releases, launches, readRequests, assertClosed, };}); const testLayer = ServerConfig.layerTest(process.cwd(), { prefix: "t3-antigravity-driver-config-",}).pipe( Layer.provideMerge(NodeServices.layer), Layer.provideMerge(ServerSettingsService.layerTest()), Layer.provideMerge( Layer.mock(BackgroundPolicy.BackgroundPolicy)({ shouldRunScopeWork: () => Effect.succeed(false), }), ), Layer.provideMerge(Layer.succeed(ProviderEventLoggers, NoOpProviderEventLoggers)), Layer.provideMerge(ModelManifest.layerTest),); it.layer(testLayer)("AntigravityDriver", (it) => { it.effect.skipIf(windowsHost)("does not launch a process for a disabled instance", () => Effect.gen(function* () { const h = yield* makeHarness(); const snapshot = yield* h.instance.snapshot.refresh; expect(snapshot.status).toBe("disabled"); expect(h.acquisitions).toEqual([]); expect(h.launches).toEqual([]); expect(yield* h.fs.exists(h.profileDirectory)).toBe(false); }).pipe(Effect.scoped), ); it.effect.skipIf(windowsHost)("refreshes models after slow process startup", () => Effect.gen(function* () { const h = yield* makeHarness(); const entered = yield* Deferred.make<void>(); const ready = yield* Deferred.make<void>(); h.controls.beforeAcquire = Deferred.succeed(entered, undefined).pipe( Effect.andThen(Deferred.await(ready)), ); const refresh = yield* h.refresh().pipe(Effect.forkScoped); yield* Deferred.await(entered); yield* TestClock.adjust("70 seconds"); yield* Deferred.succeed(ready, undefined); yield* Fiber.join(refresh); const snapshot = yield* h.instance.snapshot.getSnapshot; expect(snapshot.auth.status).toBe("authenticated"); expect(snapshot.models.length).toBeGreaterThan(0); yield* h.assertClosed; }).pipe(Effect.scoped), ); it.effect.skipIf(windowsHost)( "refreshes a disabled instance through the selected executable and personal Google ACP", () => Effect.gen(function* () { const h = yield* makeHarness(); yield* h.refresh(); const snapshot = yield* h.instance.snapshot.getSnapshot; expect(snapshot.status).toBe("disabled"); expect(snapshot.auth.status).toBe("authenticated"); expect(snapshot.models.map((model) => model.slug)).toEqual([ "gemini-test-low", "gemini-test-high", ]); expect(snapshot.models[0]?.aliases).toContain(ANTIGRAVITY_DEFAULT_MODEL); // The mock catalog is not in the manifest's current list, so it folds // under the legacy section like an old Codex model would. expect(snapshot.models.every((model) => model.isLegacy === true)).toBe(true); expect(snapshot.slashCommands.map((command) => command.name)).toEqual(["plan", "logout"]); expect(snapshot.supportsTextGeneration).toBe(true); h.controls.selected = h.second; yield* h.refresh(); expect(h.acquisitions).toEqual([ { binaryPath: "", path: h.instancePath }, { binaryPath: "", path: h.instancePath }, ]); const nativeLaunches = h.launches.filter((launch) => launch.harnessPath !== undefined); expect(nativeLaunches.map((launch) => launch.command)).toEqual([ h.first.executablePath, h.second.executablePath, ]); expect(nativeLaunches.map((launch) => launch.harnessPath)).toEqual([ h.first.harnessPath, h.second.harnessPath, ]); for (const launch of nativeLaunches) { expect(launch.args).toEqual(hostPlatform === "linux" ? ["--uid="] : []); expect(launch.profileDirectory).toBe(h.profileDirectory); expect(launch.forceFileStorage).toBe("1"); expect(launch.extendEnv).toBe(false); } for (const launch of h.launches) expect(launch.credentialKeys).toEqual([]); expect(h.releases).toEqual([h.first.version, h.second.version]); const requests = yield* h.readRequests; expect(requests.map((request) => request.method)).toEqual([ "initialize", "authenticate", "session/new", "initialize", "authenticate", "session/new", ]); expect( requests .filter((request) => request.method === "authenticate") .map((request) => request.params?.methodId), ).toEqual(["oauth-personal", "oauth-personal"]); expect( requests .filter((request) => request.method === "session/new") .map((request) => request.params?.mcpServers), ).toEqual([[], []]); yield* h.assertClosed; }).pipe(Effect.scoped), ); it.effect.skipIf(windowsHost)( "authenticates with the configured API key method and labels the account by method", () => Effect.gen(function* () { const h = yield* makeHarness({ config: { authMethod: "gemini-api-key", apiKey: "fixture-gemini-key" }, }); yield* h.refresh(); const snapshot = yield* h.instance.snapshot.getSnapshot; expect(snapshot.auth).toMatchObject({ status: "authenticated", type: "gemini-api-key", label: "Gemini API key", }); expect(snapshot.models.length).toBeGreaterThan(0); const nativeLaunches = h.launches.filter((launch) => launch.harnessPath !== undefined); expect(nativeLaunches.map((launch) => launch.geminiApiKey)).toEqual(["fixture-gemini-key"]); const requests = yield* h.readRequests; expect( requests .filter((request) => request.method === "authenticate") .map((request) => request.params?.methodId), ).toEqual(["gemini-api-key"]); yield* h.assertClosed; }).pipe(Effect.scoped), ); it.effect.skipIf(windowsHost)("reports the missing credential before launching a process", () => Effect.gen(function* () { const h = yield* makeHarness({ config: { authMethod: "gemini-api-key" } }); const error = yield* h.refresh().pipe(Effect.flip); expect(error.detail).toContain("API key"); expect(h.launches.filter((launch) => launch.harnessPath !== undefined)).toEqual([]); }).pipe(Effect.scoped), ); it.effect.skipIf(windowsHost)( "closes refresh processes and clears account metadata when Google sign-in is required", () => Effect.gen(function* () { const h = yield* makeHarness(); yield* h.refresh(); h.controls.selected = h.signedOut; const error = yield* h.refresh().pipe(Effect.flip); expect(error.detail).toContain("Sign in to Antigravity"); const snapshot = yield* h.instance.snapshot.getSnapshot; expect(snapshot.auth.status).toBe("unauthenticated"); expect(snapshot.models).toEqual([]); expect(snapshot.slashCommands).toEqual([]); expect(snapshot.supportsTextGeneration).toBe(false); expect(h.acquisitions).toHaveLength(2); expect(h.releases).toEqual([h.first.version, h.signedOut.version]); yield* h.assertClosed; }).pipe(Effect.scoped), ); it.effect.skipIf(windowsHost)( "clears account metadata when a text helper needs Google sign-in", () => Effect.gen(function* () { const h = yield* makeHarness(); yield* h.refresh(); h.controls.selected = h.signedOut; const error = yield* h.instance.textGeneration .generateThreadTitle({ cwd: h.profileDirectory, message: "Repair Google login", modelSelection: { instanceId: h.instance.instanceId, model: "gemini-test-low" }, }) .pipe(Effect.flip); expect(error._tag).toBe("TextGenerationError"); const snapshot = yield* h.instance.snapshot.getSnapshot; expect(snapshot.auth.status).toBe("unauthenticated"); expect(snapshot.models).toEqual([]); expect(snapshot.supportsTextGeneration).toBe(false); expect(h.releases).toEqual([h.first.version, h.signedOut.version]); yield* h.assertClosed; }).pipe(Effect.scoped), ); it.effect.skipIf(windowsHost)("keeps the previous catalog when executable resolution fails", () => Effect.gen(function* () { const h = yield* makeHarness(); yield* h.refresh(); const before = yield* h.instance.snapshot.getSnapshot; h.controls.failResolution = true; const error = yield* h.refresh().pipe(Effect.flip); expect(error.detail).toContain("previous model list is unchanged"); const after = yield* h.instance.snapshot.getSnapshot; expect(after.models).toEqual(before.models); expect(after.auth).toEqual(before.auth); expect(h.acquisitions).toHaveLength(2); expect(h.releases).toEqual([h.first.version]); yield* h.assertClosed; }).pipe(Effect.scoped), );});
import * as NodeServices from "@effect/platform-node/NodeServices";
import { expect, it } from "@effect/vitest";
import {
ANTIGRAVITY_DEFAULT_MODEL,
ProviderInstanceId,
type AntigravitySettings,
} from "@t3tools/contracts";
import {
HostProcessEnvironment,
HostProcessExecutablePath,
HostProcessPlatform,
} from "@t3tools/shared/hostProcess";
import * as Effect from "effect/Effect";
import * as Deferred from "effect/Deferred";
import * as Fiber from "effect/Fiber";
import * as FileSystem from "effect/FileSystem";
import * as Layer from "effect/Layer";
import * as Path from "effect/Path";
import * as Schema from "effect/Schema";
import * as TestClock from "effect/testing/TestClock";
import * as ChildProcessSpawner from "effect/unstable/process/ChildProcessSpawner";
import * as BackgroundPolicy from "../../background/BackgroundPolicy.ts";
import { ServerConfig } from "../../config.ts";
import { ServerSettingsService } from "../../serverSettings.ts";
import {
AntigravityInstallation,
AntigravityInstallationError,
type AntigravityExecutable,
} from "../AntigravityInstallation.ts";
import {
ANTIGRAVITY_AUTH_STDOUT_PREFIX,
resolveAntigravityProfileDirectory,
} from "../antigravityAuthSupport.ts";
import { NoOpProviderEventLoggers, ProviderEventLoggers } from "../Layers/ProviderEventLoggers.ts";
import * as ModelManifest from "../ModelManifest.ts";
import { AntigravityDriver } from "./AntigravityDriver.ts";
const hostPlatform = HostProcessPlatform.defaultValue();
const windowsHost = hostPlatform === "win32";
const decodeRequest = Schema.decodeEffect(
Schema.fromJsonString(
Schema.Struct({
method: Schema.optional(Schema.String),
params: Schema.optional(Schema.Record(Schema.String, Schema.Unknown)),
}),
),
);
const blockedCredentialKeys = new Set([
"GEMINI_API_KEY",
"GOOGLE_API_KEY",
"GOOGLE_APPLICATION_CREDENTIALS",
"GOOGLE_GENAI_USE_VERTEXAI",
]);
function shellQuote(value: string): string {
return `'${value.replaceAll("'", `'"'"'`)}'`;
}
const makeHarness = Effect.fn("makeAntigravityDriverHarness")(function* (
options: { readonly config?: Partial<AntigravitySettings> } = {},
) {
const fs = yield* FileSystem.FileSystem;
const path = yield* Path.Path;
const config = yield* ServerConfig;
const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
const nodePath = yield* HostProcessExecutablePath;
const baseEnv = yield* HostProcessEnvironment;
const root = yield* fs.makeTempDirectoryScoped({ prefix: "t3-antigravity-driver-" });
const instanceId = ProviderInstanceId.make(path.basename(root));
const mockAgentPath = yield* path.fromFileUrl(
new URL("../../../scripts/acp-mock-agent.ts", import.meta.url),
);
const requestLog = path.join(root, "requests.jsonl");
const profileDirectory = resolveAntigravityProfileDirectory(config.stateDir, instanceId);
const instancePath = `${path.join(root, "instance-bin")}:${baseEnv.PATH ?? ""}`;
const makeExecutable = Effect.fn("AntigravityDriverTest.makeExecutable")(function* (
name: string,
loginRequired = false,
) {
const directory = path.join(root, name);
const executablePath = path.join(directory, "agy_acp_server.par");
const harnessPath = path.join(directory, "localharness_external");
yield* fs.makeDirectory(directory, { recursive: true });
const authorizationUrl =
"https://accounts.google.com/o/oauth2/v2/auth?response_type=code&redirect_uri=http%3A%2F%2F127.0.0.1%3A51234%2F&state=fixture-state";
yield* fs.writeFileString(
executablePath,
[
"#!/bin/sh",
...(loginRequired
? [`printf '%s\\n' ${shellQuote(ANTIGRAVITY_AUTH_STDOUT_PREFIX + authorizationUrl)}`]
: []),
`exec ${shellQuote(nodePath)} ${shellQuote(mockAgentPath)} "$@"`,
"",
].join("\n"),
);
yield* fs.writeFileString(harnessPath, "#!/bin/sh\nexit 99\n");
yield* fs.chmod(executablePath, 0o755);
yield* fs.chmod(harnessPath, 0o755);
return {
executablePath,
harnessPath,
source: "managed",
version: name,
managedVersionDirectory: directory,
} satisfies AntigravityExecutable;
});
const first = yield* makeExecutable("runtime 'one");
const second = yield* makeExecutable("runtime two");
const signedOut = yield* makeExecutable("runtime signed-out", true);
const controls = { selected: first, failResolution: false, beforeAcquire: Effect.void };
const acquisitions: Array<{ binaryPath: string | undefined; path: string | undefined }> = [];
const releases: Array<string | null> = [];
const launches: Array<{
command: string;
args: ReadonlyArray<string>;
cwd: string | undefined;
extendEnv: boolean | undefined;
profileDirectory: string | undefined;
harnessPath: string | undefined;
forceFileStorage: string | undefined;
credentialKeys: ReadonlyArray<string>;
geminiApiKey: string | undefined;
handle: ChildProcessSpawner.ChildProcessHandle;
}> = [];
const installation = Layer.mock(AntigravityInstallation)({
managedDirectory: root,
acquire: (binaryPath, environment) =>
Effect.gen(function* () {
acquisitions.push({ binaryPath, path: environment?.PATH });
yield* controls.beforeAcquire;
if (controls.failResolution) {
return yield* new AntigravityInstallationError({
operation: "resolve",
detail: "Fixture resolution failed.",
});
}
const selected = controls.selected;
yield* Effect.addFinalizer(() =>
Effect.sync(() => {
releases.push(selected.version);
}),
);
return selected;
}),
});
const observedSpawner = ChildProcessSpawner.make((command) =>
Effect.gen(function* () {
if (command._tag !== "StandardCommand")
return yield* Effect.die("Unexpected process pipeline.");
const handle = yield* spawner.spawn(command);
const environment = command.options.env ?? {};
launches.push({
command: command.command,
args: command.args,
cwd: command.options.cwd,
extendEnv: command.options.extendEnv,
profileDirectory: environment.GEMINI_HOME,
harnessPath: environment.ANTIGRAVITY_HARNESS_PATH,
forceFileStorage: environment.AGY_ACP_FORCE_FILE_STORAGE,
credentialKeys: Object.keys(environment).filter((key) =>
blockedCredentialKeys.has(key.toUpperCase()),
),
geminiApiKey: environment.GEMINI_API_KEY,
handle,
});
return handle;
}),
);
const instance = yield* AntigravityDriver.create({
instanceId,
displayName: "Google test account",
enabled: false,
config: { ...AntigravityDriver.defaultConfig(), ...options.config },
environment: [
{ name: "PATH", value: instancePath },
{ name: "T3_ACP_ANTIGRAVITY", value: "1" },
{ name: "T3_ACP_REQUEST_LOG_PATH", value: requestLog },
{ name: "GEMINI_API_KEY", value: "must-not-be-used" },
{ name: "google_api_key", value: "must-not-be-used" },
{ name: "GOOGLE_APPLICATION_CREDENTIALS", value: "/must-not-be-used.json" },
{ name: "GOOGLE_GENAI_USE_VERTEXAI", value: "true" },
{ name: "GEMINI_HOME", value: "/must-not-be-used" },
{ name: "ANTIGRAVITY_HARNESS_PATH", value: "/must-not-be-used" },
{ name: "BROWSER", value: "must-not-run" },
].map((variable) => ({ ...variable, sensitive: false })),
}).pipe(
Effect.provide(installation),
Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, observedSpawner),
);
const refresh = instance.refreshModels;
if (!refresh) return yield* Effect.die("Antigravity does not expose model refresh.");
const readRequests = Effect.gen(function* () {
if (!(yield* fs.exists(requestLog))) return [];
const text = yield* fs.readFileString(requestLog);
return yield* Effect.forEach(text.split(/\r?\n/u).filter(Boolean), (line) =>
decodeRequest(line),
);
});
const assertClosed = Effect.gen(function* () {
for (const launch of launches) {
// Cancelled startup can report a signal instead of a numeric exit code.
yield* launch.handle.exitCode.pipe(Effect.ignore);
expect(yield* launch.handle.isRunning).toBe(false);
if (launch.cwd) expect(yield* fs.exists(launch.cwd)).toBe(false);
}
});
return {
instance,
refresh,
fs,
profileDirectory,
instancePath,
first,
second,
signedOut,
controls,
acquisitions,
releases,
launches,
readRequests,
assertClosed,
};
});
const testLayer = ServerConfig.layerTest(process.cwd(), {
prefix: "t3-antigravity-driver-config-",
}).pipe(
Layer.provideMerge(NodeServices.layer),
Layer.provideMerge(ServerSettingsService.layerTest()),
Layer.provideMerge(
Layer.mock(BackgroundPolicy.BackgroundPolicy)({
shouldRunScopeWork: () => Effect.succeed(false),
}),
),
Layer.provideMerge(Layer.succeed(ProviderEventLoggers, NoOpProviderEventLoggers)),
Layer.provideMerge(ModelManifest.layerTest),
);
it.layer(testLayer)("AntigravityDriver", (it) => {
it.effect.skipIf(windowsHost)("does not launch a process for a disabled instance", () =>
Effect.gen(function* () {
const h = yield* makeHarness();
const snapshot = yield* h.instance.snapshot.refresh;
expect(snapshot.status).toBe("disabled");
expect(h.acquisitions).toEqual([]);
expect(h.launches).toEqual([]);
expect(yield* h.fs.exists(h.profileDirectory)).toBe(false);
}).pipe(Effect.scoped),
);
it.effect.skipIf(windowsHost)("refreshes models after slow process startup", () =>
Effect.gen(function* () {
const h = yield* makeHarness();
const entered = yield* Deferred.make<void>();
const ready = yield* Deferred.make<void>();
h.controls.beforeAcquire = Deferred.succeed(entered, undefined).pipe(
Effect.andThen(Deferred.await(ready)),
);
const refresh = yield* h.refresh().pipe(Effect.forkScoped);
yield* Deferred.await(entered);
yield* TestClock.adjust("70 seconds");
yield* Deferred.succeed(ready, undefined);
yield* Fiber.join(refresh);
const snapshot = yield* h.instance.snapshot.getSnapshot;
expect(snapshot.auth.status).toBe("authenticated");
expect(snapshot.models.length).toBeGreaterThan(0);
yield* h.assertClosed;
}).pipe(Effect.scoped),
);
it.effect.skipIf(windowsHost)(
"refreshes a disabled instance through the selected executable and personal Google ACP",
() =>
Effect.gen(function* () {
const h = yield* makeHarness();
yield* h.refresh();
const snapshot = yield* h.instance.snapshot.getSnapshot;
expect(snapshot.status).toBe("disabled");
expect(snapshot.auth.status).toBe("authenticated");
expect(snapshot.models.map((model) => model.slug)).toEqual([
"gemini-test-low",
"gemini-test-high",
]);
expect(snapshot.models[0]?.aliases).toContain(ANTIGRAVITY_DEFAULT_MODEL);
// The mock catalog is not in the manifest's current list, so it folds
// under the legacy section like an old Codex model would.
expect(snapshot.models.every((model) => model.isLegacy === true)).toBe(true);
expect(snapshot.slashCommands.map((command) => command.name)).toEqual(["plan", "logout"]);
expect(snapshot.supportsTextGeneration).toBe(true);
h.controls.selected = h.second;
yield* h.refresh();
expect(h.acquisitions).toEqual([
{ binaryPath: "", path: h.instancePath },
{ binaryPath: "", path: h.instancePath },
]);
const nativeLaunches = h.launches.filter((launch) => launch.harnessPath !== undefined);
expect(nativeLaunches.map((launch) => launch.command)).toEqual([
h.first.executablePath,
h.second.executablePath,
]);
expect(nativeLaunches.map((launch) => launch.harnessPath)).toEqual([
h.first.harnessPath,
h.second.harnessPath,
]);
for (const launch of nativeLaunches) {
expect(launch.args).toEqual(hostPlatform === "linux" ? ["--uid="] : []);
expect(launch.profileDirectory).toBe(h.profileDirectory);
expect(launch.forceFileStorage).toBe("1");
expect(launch.extendEnv).toBe(false);
}
for (const launch of h.launches) expect(launch.credentialKeys).toEqual([]);
expect(h.releases).toEqual([h.first.version, h.second.version]);
const requests = yield* h.readRequests;
expect(requests.map((request) => request.method)).toEqual([
"initialize",
"authenticate",
"session/new",
"initialize",
"authenticate",
"session/new",
]);
expect(
requests
.filter((request) => request.method === "authenticate")
.map((request) => request.params?.methodId),
).toEqual(["oauth-personal", "oauth-personal"]);
expect(
requests
.filter((request) => request.method === "session/new")
.map((request) => request.params?.mcpServers),
).toEqual([[], []]);
yield* h.assertClosed;
}).pipe(Effect.scoped),
);
it.effect.skipIf(windowsHost)(
"authenticates with the configured API key method and labels the account by method",
() =>
Effect.gen(function* () {
const h = yield* makeHarness({
config: { authMethod: "gemini-api-key", apiKey: "fixture-gemini-key" },
});
yield* h.refresh();
const snapshot = yield* h.instance.snapshot.getSnapshot;
expect(snapshot.auth).toMatchObject({
status: "authenticated",
type: "gemini-api-key",
label: "Gemini API key",
});
expect(snapshot.models.length).toBeGreaterThan(0);
const nativeLaunches = h.launches.filter((launch) => launch.harnessPath !== undefined);
expect(nativeLaunches.map((launch) => launch.geminiApiKey)).toEqual(["fixture-gemini-key"]);
const requests = yield* h.readRequests;
expect(
requests
.filter((request) => request.method === "authenticate")
.map((request) => request.params?.methodId),
).toEqual(["gemini-api-key"]);
yield* h.assertClosed;
}).pipe(Effect.scoped),
);
it.effect.skipIf(windowsHost)("reports the missing credential before launching a process", () =>
Effect.gen(function* () {
const h = yield* makeHarness({ config: { authMethod: "gemini-api-key" } });
const error = yield* h.refresh().pipe(Effect.flip);
expect(error.detail).toContain("API key");
expect(h.launches.filter((launch) => launch.harnessPath !== undefined)).toEqual([]);
}).pipe(Effect.scoped),
);
it.effect.skipIf(windowsHost)(
"closes refresh processes and clears account metadata when Google sign-in is required",
() =>
Effect.gen(function* () {
const h = yield* makeHarness();
yield* h.refresh();
h.controls.selected = h.signedOut;
const error = yield* h.refresh().pipe(Effect.flip);
expect(error.detail).toContain("Sign in to Antigravity");
const snapshot = yield* h.instance.snapshot.getSnapshot;
expect(snapshot.auth.status).toBe("unauthenticated");
expect(snapshot.models).toEqual([]);
expect(snapshot.slashCommands).toEqual([]);
expect(snapshot.supportsTextGeneration).toBe(false);
expect(h.acquisitions).toHaveLength(2);
expect(h.releases).toEqual([h.first.version, h.signedOut.version]);
yield* h.assertClosed;
}).pipe(Effect.scoped),
);
it.effect.skipIf(windowsHost)(
"clears account metadata when a text helper needs Google sign-in",
() =>
Effect.gen(function* () {
const h = yield* makeHarness();
yield* h.refresh();
h.controls.selected = h.signedOut;
const error = yield* h.instance.textGeneration
.generateThreadTitle({
cwd: h.profileDirectory,
message: "Repair Google login",
modelSelection: { instanceId: h.instance.instanceId, model: "gemini-test-low" },
})
.pipe(Effect.flip);
expect(error._tag).toBe("TextGenerationError");
const snapshot = yield* h.instance.snapshot.getSnapshot;
expect(snapshot.auth.status).toBe("unauthenticated");
expect(snapshot.models).toEqual([]);
expect(snapshot.supportsTextGeneration).toBe(false);
expect(h.releases).toEqual([h.first.version, h.signedOut.version]);
yield* h.assertClosed;
}).pipe(Effect.scoped),
);
it.effect.skipIf(windowsHost)("keeps the previous catalog when executable resolution fails", () =>
Effect.gen(function* () {
const h = yield* makeHarness();
yield* h.refresh();
const before = yield* h.instance.snapshot.getSnapshot;
h.controls.failResolution = true;
const error = yield* h.refresh().pipe(Effect.flip);
expect(error.detail).toContain("previous model list is unchanged");
const after = yield* h.instance.snapshot.getSnapshot;
expect(after.models).toEqual(before.models);
expect(after.auth).toEqual(before.auth);
expect(h.acquisitions).toHaveLength(2);
expect(h.releases).toEqual([h.first.version]);
yield* h.assertClosed;
}).pipe(Effect.scoped),
);
});