From be4b51458c71d6673d57d2ee6127a1b4d9767df9 Mon Sep 17 00:00:00 2001 From: Yaacov Date: Mon, 19 Oct 2026 17:01:33 +0300 Subject: [PATCH 1/6] fix(antigravity): no console window on Windows; say when the runtime check runs out of time On Windows, agents that own their process tree were spawned detached. A detached process has no console, so each console program it starts gets a new visible one; Antigravity's launcher starts its inner process that way, so every install check and Antigravity session opened a Windows Terminal window. Windows already stops the tree with taskkill /T, so the agent now stays attached there and shares Effect's hidden console (marked seam in AcpSessionRuntime). A runtime check that outlived its 90-second limit fell through to the install's catch-all "Check free disk space and directory access". It now says the agent didn't respond in time. Co-Authored-By: Claude Opus 5.5 --- UPSTREAM.md | 8 ++++++ .../provider/AntigravityInstallation.test.ts | 24 +++++++++++++++++- .../src/provider/AntigravityInstallation.ts | 25 ++++++++++++------- .../src/server/AcpSessionRuntime.ts | 9 ++++++- 4 files changed, 55 insertions(+), 11 deletions(-) diff --git a/UPSTREAM.md b/UPSTREAM.md index 2dceb2e0d1..79fd2eaf8a 100644 --- a/UPSTREAM.md +++ b/UPSTREAM.md @@ -1102,6 +1102,14 @@ presentation comes from a Scient hook (its import and its call), so a sign-in st as starting from the click, and a failed sign-in or setup takes the error status dot. See [provider lifecycle](docs/internals/provider-lifecycle.md#opening-sign-in-pages). +One marked seam in `packages/provider-acp/src/server/AcpSessionRuntime.ts` keeps an agent that owns +its process tree attached on Windows: `ownDetachedProcessGroup` spawns detached only off Windows, +where `taskkill /T` already stops the tree. A detached agent has no console, so every console +program it starts opens a visible window; Antigravity's own inner process is one. This is an +upstream bug (T3's Grok uses the same path) worth proposing. In Scient's retained +`AntigravityInstallation.ts`, a runtime check that runs out of time reports that instead of the +install's catch-all disk-space advice. + Antigravity reasoning presentation is a narrow client-side divergence. The shared `packages/client-runtime/src/antigravityModelPresentation.ts` groups recognized Google Gemini effort variants for the existing model and reasoning controls. diff --git a/apps/server/src/provider/AntigravityInstallation.test.ts b/apps/server/src/provider/AntigravityInstallation.test.ts index fe957ec96f..80e0f67cb0 100644 --- a/apps/server/src/provider/AntigravityInstallation.test.ts +++ b/apps/server/src/provider/AntigravityInstallation.test.ts @@ -491,6 +491,27 @@ it.layer(NodeServices.layer)("Antigravity installation", (it) => { }), ); + it.effect("reports a runtime check that runs out of time, not a disk problem", () => + Effect.gen(function* () { + const enteredValidation = yield* Deferred.make(); + const { installation, stagingReleased } = yield* makeHarness({ + previous: true, + validate: () => + Deferred.succeed(enteredValidation, undefined).pipe(Effect.andThen(Effect.never)), + }); + yield* installation.start; + yield* Deferred.await(enteredValidation); + yield* TestClock.adjust("90 seconds"); + expect(yield* terminalState(installation)).toMatchObject({ + phase: "failed", + message: + "Antigravity didn't respond within 90 seconds while Scient was checking it. Try again when your computer is less busy.", + }); + yield* Deferred.await(stagingReleased); + yield* expectPreviousRelease(installation); + }), + ); + it.effect.each( [ { @@ -622,7 +643,8 @@ it.layer(NodeServices.layer)("Antigravity installation", (it) => { Effect.asVoid, ); if (!helper) { - expect(command.options.detached).toBe(true); + // Windows owns the tree with taskkill; detaching would show a console. + expect(command.options.detached).toBe(platform !== "win32"); stopNative = terminate; } yield* Effect.addFinalizer(() => diff --git a/apps/server/src/provider/AntigravityInstallation.ts b/apps/server/src/provider/AntigravityInstallation.ts index 15b3c9098a..da8f81ab64 100644 --- a/apps/server/src/provider/AntigravityInstallation.ts +++ b/apps/server/src/provider/AntigravityInstallation.ts @@ -151,6 +151,19 @@ const installationError = (operation: string, detail: string, cause?: unknown) = const wrapFailure = (operation: string, detail: string) => (cause: unknown) => isInstallationError(cause) ? cause : installationError(operation, detail, cause); +// SCIENT-FORK: a check that runs out of time says so, instead of the install's +// catch-all advice to check disk space. +const validationTimeout = Effect.timeoutOrElse({ + duration: VALIDATION_TIMEOUT, + orElse: () => + Effect.fail( + installationError( + "verify", + "Antigravity didn't respond within 90 seconds while Scient was checking it. Try again when your computer is less busy.", + ), + ), +}); + function executableNames(platform: NodeJS.Platform) { return platform === "win32" ? { executable: "agy_acp_server.exe", harness: "localharness_external.exe" } @@ -519,10 +532,7 @@ export const makeAntigravityInstallation = Effect.fn("AntigravityInstallation.ma return yield* installationError("verify", "The managed release has the wrong version."); } yield* report("verifying", "Checking the installed runtime."); - yield* validate(existing, asset.version).pipe( - Effect.scoped, - Effect.timeout(VALIDATION_TIMEOUT), - ); + yield* validate(existing, asset.version).pipe(Effect.scoped, validationTimeout); return existing; }).pipe(Effect.result); if (verified._tag === "Success") { @@ -712,7 +722,7 @@ export const makeAntigravityInstallation = Effect.fn("AntigravityInstallation.ma managedVersionDirectory: pairDirectory, }, asset.version, - ).pipe(Effect.scoped, Effect.timeout(VALIDATION_TIMEOUT)); + ).pipe(Effect.scoped, validationTimeout); const record: InstalledRelease = { releaseId: asset.sha256, version: asset.version, @@ -772,10 +782,7 @@ export const makeAntigravityInstallation = Effect.fn("AntigravityInstallation.ma completedRelease(asset.sha256).pipe( Effect.flatMap((existing) => existing.version === asset.version - ? validate(existing, asset.version).pipe( - Effect.scoped, - Effect.timeout(VALIDATION_TIMEOUT), - ) + ? validate(existing, asset.version).pipe(Effect.scoped, validationTimeout) : Effect.fail( installationError( "activate", diff --git a/packages/provider-acp/src/server/AcpSessionRuntime.ts b/packages/provider-acp/src/server/AcpSessionRuntime.ts index cbc012dd3c..87809fc0e3 100644 --- a/packages/provider-acp/src/server/AcpSessionRuntime.ts +++ b/packages/provider-acp/src/server/AcpSessionRuntime.ts @@ -1554,9 +1554,16 @@ export const make = ( ...(options.spawn.cwd ? { cwd: options.spawn.cwd } : {}), ...(spawnEnvironment ? { env: spawnEnvironment } : {}), extendEnv: options.spawn.extendEnv ?? true, + // SCIENT-FORK:START — Windows owns the tree with taskkill /T, not a group. + // A detached agent has no console, so every console program it starts + // (Antigravity's own inner process included) opens a visible window. ...(options.ownDetachedProcessGroup === undefined ? {} - : { detached: options.ownDetachedProcessGroup }), + : { + detached: + options.ownDetachedProcessGroup && options.processGroupPlatform !== "win32", + }), + // SCIENT-FORK:END shell: containedSpawnCommand.shell, }), ) From 9a65ddccaa5129008fab958784185e9103557d13 Mon Sep 17 00:00:00 2001 From: Yaacov Date: Mon, 19 Oct 2026 17:40:36 +0300 Subject: [PATCH 2/6] fix(antigravity): mark the check-timeout seam and prove its teardown Review follow-up. Only the check after a fresh download shows its error; the other two checks either fall back to a fresh download or report the publication failure, so they return to upstream's exact text. The remaining seam is in paired markers, and its message no longer blames a busy machine: the agent unpacks about 320 MiB on every start, which is slow on quiet machines too. The timeout is now proven through the real check, including stopping the process tree before the disposable profile is removed. Co-Authored-By: Claude Opus 5.5 --- .../provider/AntigravityInstallation.test.ts | 41 +++++++++---------- .../src/provider/AntigravityInstallation.ts | 24 ++++++++--- 2 files changed, 37 insertions(+), 28 deletions(-) diff --git a/apps/server/src/provider/AntigravityInstallation.test.ts b/apps/server/src/provider/AntigravityInstallation.test.ts index 80e0f67cb0..2550dcf63f 100644 --- a/apps/server/src/provider/AntigravityInstallation.test.ts +++ b/apps/server/src/provider/AntigravityInstallation.test.ts @@ -491,27 +491,6 @@ it.layer(NodeServices.layer)("Antigravity installation", (it) => { }), ); - it.effect("reports a runtime check that runs out of time, not a disk problem", () => - Effect.gen(function* () { - const enteredValidation = yield* Deferred.make(); - const { installation, stagingReleased } = yield* makeHarness({ - previous: true, - validate: () => - Deferred.succeed(enteredValidation, undefined).pipe(Effect.andThen(Effect.never)), - }); - yield* installation.start; - yield* Deferred.await(enteredValidation); - yield* TestClock.adjust("90 seconds"); - expect(yield* terminalState(installation)).toMatchObject({ - phase: "failed", - message: - "Antigravity didn't respond within 90 seconds while Scient was checking it. Try again when your computer is less busy.", - }); - yield* Deferred.await(stagingReleased); - yield* expectPreviousRelease(installation); - }), - ); - it.effect.each( [ { @@ -567,6 +546,15 @@ it.layer(NodeServices.layer)("Antigravity installation", (it) => { cancel: true, valid: false, }, + { + name: "a Windows ARM verification that runs out of time with locked child processes", + platform: "win32" as const, + arch: "arm64" as const, + agentName: "antigravity-acp", + version: "fixture-new", + timeout: true, + valid: false, + }, ].flatMap((testCase) => { const cleanupErrorTags = testCase.platform === "win32" @@ -674,7 +662,7 @@ it.layer(NodeServices.layer)("Antigravity installation", (it) => { Effect.orDie, ); methods.push(request.method); - if (testCase.cancel) { + if (testCase.cancel || testCase.timeout) { yield* Deferred.succeed(initializationStarted, undefined); return; } @@ -762,6 +750,10 @@ it.layer(NodeServices.layer)("Antigravity installation", (it) => { Effect.forkChild, ) : undefined; + if (testCase.timeout) { + yield* Deferred.await(initializationStarted); + yield* TestClock.adjust("90 seconds"); + } if (platform === "win32") { yield* Effect.raceFirst( Deferred.await(cleanupRetryStarted).pipe(Effect.andThen(TestClock.adjust("100 millis"))), @@ -772,6 +764,11 @@ it.layer(NodeServices.layer)("Antigravity installation", (it) => { expect((yield* terminalState(installation)).phase).toBe( testCase.cancel ? "cancelled" : testCase.valid ? "succeeded" : "failed", ); + if (testCase.timeout) { + expect((yield* terminalState(installation)).message).toBe( + "Antigravity didn't finish starting within 90 seconds while Scient was checking it. Starting it can take a while on some computers. Try again.", + ); + } yield* Deferred.await(stagingReleased); expect(methods).toEqual(["initialize"]); expect(closedRuntimes).toBe(1); diff --git a/apps/server/src/provider/AntigravityInstallation.ts b/apps/server/src/provider/AntigravityInstallation.ts index da8f81ab64..c80e7d0c33 100644 --- a/apps/server/src/provider/AntigravityInstallation.ts +++ b/apps/server/src/provider/AntigravityInstallation.ts @@ -151,18 +151,19 @@ const installationError = (operation: string, detail: string, cause?: unknown) = const wrapFailure = (operation: string, detail: string) => (cause: unknown) => isInstallationError(cause) ? cause : installationError(operation, detail, cause); -// SCIENT-FORK: a check that runs out of time says so, instead of the install's -// catch-all advice to check disk space. +// SCIENT-FORK:START — a check that runs out of time says so, instead of the +// install's catch-all advice to check disk space. const validationTimeout = Effect.timeoutOrElse({ duration: VALIDATION_TIMEOUT, orElse: () => Effect.fail( installationError( "verify", - "Antigravity didn't respond within 90 seconds while Scient was checking it. Try again when your computer is less busy.", + `Antigravity didn't finish starting within ${VALIDATION_TIMEOUT} while Scient was checking it. Starting it can take a while on some computers. Try again.`, ), ), }); +// SCIENT-FORK:END function executableNames(platform: NodeJS.Platform) { return platform === "win32" @@ -532,7 +533,10 @@ export const makeAntigravityInstallation = Effect.fn("AntigravityInstallation.ma return yield* installationError("verify", "The managed release has the wrong version."); } yield* report("verifying", "Checking the installed runtime."); - yield* validate(existing, asset.version).pipe(Effect.scoped, validationTimeout); + yield* validate(existing, asset.version).pipe( + Effect.scoped, + Effect.timeout(VALIDATION_TIMEOUT), + ); return existing; }).pipe(Effect.result); if (verified._tag === "Success") { @@ -722,7 +726,12 @@ export const makeAntigravityInstallation = Effect.fn("AntigravityInstallation.ma managedVersionDirectory: pairDirectory, }, asset.version, - ).pipe(Effect.scoped, validationTimeout); + ).pipe( + Effect.scoped, + // SCIENT-FORK:START + validationTimeout, + // SCIENT-FORK:END + ); const record: InstalledRelease = { releaseId: asset.sha256, version: asset.version, @@ -782,7 +791,10 @@ export const makeAntigravityInstallation = Effect.fn("AntigravityInstallation.ma completedRelease(asset.sha256).pipe( Effect.flatMap((existing) => existing.version === asset.version - ? validate(existing, asset.version).pipe(Effect.scoped, validationTimeout) + ? validate(existing, asset.version).pipe( + Effect.scoped, + Effect.timeout(VALIDATION_TIMEOUT), + ) : Effect.fail( installationError( "activate", From b8d6b0984c4086a40c9b6878d32cc205d5e0432c Mon Sep 17 00:00:00 2001 From: Yaacov Date: Mon, 19 Oct 2026 19:25:09 +0300 Subject: [PATCH 3/6] fix(antigravity): allow 5 minutes for the agent to start The official Windows agent unpacks about 7,300 files (320 MiB) into a fresh folder on every start: about 35 s on a development machine, and longer than T3's 90-second limits on slower disks, even with free memory. The install check, health check, model refresh and sign-out now allow 5 minutes, each in a marked line. Sign-in already allowed 5 minutes. A start that really hangs now takes longer to report; the install check can still be cancelled. Co-Authored-By: Claude Opus 5.5 --- UPSTREAM.md | 4 ++++ apps/server/src/provider/AntigravityAuth.test.ts | 2 +- apps/server/src/provider/AntigravityAuth.ts | 4 +++- apps/server/src/provider/AntigravityInstallation.test.ts | 4 ++-- apps/server/src/provider/AntigravityInstallation.ts | 4 +++- apps/server/src/provider/AntigravityProvider.test.ts | 4 ++-- apps/server/src/provider/AntigravityProvider.ts | 4 +++- apps/server/src/provider/Drivers/AntigravityDriver.test.ts | 2 +- apps/server/src/provider/Drivers/AntigravityDriver.ts | 4 +++- docs/user/providers-antigravity.md | 2 +- 10 files changed, 23 insertions(+), 11 deletions(-) diff --git a/UPSTREAM.md b/UPSTREAM.md index 79fd2eaf8a..6c74c8b4a1 100644 --- a/UPSTREAM.md +++ b/UPSTREAM.md @@ -1109,6 +1109,10 @@ program it starts opens a visible window; Antigravity's own inner process is one upstream bug (T3's Grok uses the same path) worth proposing. In Scient's retained `AntigravityInstallation.ts`, a runtime check that runs out of time reports that instead of the install's catch-all disk-space advice. +The install check, health check, model refresh (`AntigravityDriver.ts`) and sign-out +(`AntigravityAuth.ts`) allow 5 minutes instead of T3's 90 seconds, each in a marked line: the +official Windows agent unpacks about 7,300 files (320 MiB) into a fresh folder on every start, which +took about 35 s on a development machine and can exceed 90 s on slower disks. Antigravity reasoning presentation is a narrow client-side divergence. The shared `packages/client-runtime/src/antigravityModelPresentation.ts` groups recognized diff --git a/apps/server/src/provider/AntigravityAuth.test.ts b/apps/server/src/provider/AntigravityAuth.test.ts index be6d61557e..0d62269aec 100644 --- a/apps/server/src/provider/AntigravityAuth.test.ts +++ b/apps/server/src/provider/AntigravityAuth.test.ts @@ -780,7 +780,7 @@ it.layer(NodeServices.layer)("AntigravityAuth", (it) => { .logout(Effect.void) .pipe(Effect.exit, Effect.forkScoped); yield* Deferred.await(entered); - yield* TestClock.adjust("90 seconds"); + yield* TestClock.adjust("5 minutes"); assert.isTrue(Exit.isFailure(yield* Fiber.join(logout))); yield* Deferred.await(harness.closed); assert.notInclude(harness.events, "logout"); diff --git a/apps/server/src/provider/AntigravityAuth.ts b/apps/server/src/provider/AntigravityAuth.ts index af50b1f0b0..0c2ee35a24 100644 --- a/apps/server/src/provider/AntigravityAuth.ts +++ b/apps/server/src/provider/AntigravityAuth.ts @@ -501,7 +501,9 @@ export const makeAntigravityAuth = Effect.fn("makeAntigravityAuth")(function* < }).pipe( Effect.scoped, Effect.timeoutOrElse({ - duration: "90 seconds", + // SCIENT-FORK:START — Antigravity unpacks itself (~320 MiB) on every start; slow disks need minutes. + duration: "5 minutes", + // SCIENT-FORK:END orElse: () => Effect.fail(setupError("logout", "Antigravity sign-out timed out.")), }), ), diff --git a/apps/server/src/provider/AntigravityInstallation.test.ts b/apps/server/src/provider/AntigravityInstallation.test.ts index 2550dcf63f..e3fc9b7611 100644 --- a/apps/server/src/provider/AntigravityInstallation.test.ts +++ b/apps/server/src/provider/AntigravityInstallation.test.ts @@ -752,7 +752,7 @@ it.layer(NodeServices.layer)("Antigravity installation", (it) => { : undefined; if (testCase.timeout) { yield* Deferred.await(initializationStarted); - yield* TestClock.adjust("90 seconds"); + yield* TestClock.adjust("5 minutes"); } if (platform === "win32") { yield* Effect.raceFirst( @@ -766,7 +766,7 @@ it.layer(NodeServices.layer)("Antigravity installation", (it) => { ); if (testCase.timeout) { expect((yield* terminalState(installation)).message).toBe( - "Antigravity didn't finish starting within 90 seconds while Scient was checking it. Starting it can take a while on some computers. Try again.", + "Antigravity didn't finish starting within 5 minutes while Scient was checking it. Starting it can take a while on some computers. Try again.", ); } yield* Deferred.await(stagingReleased); diff --git a/apps/server/src/provider/AntigravityInstallation.ts b/apps/server/src/provider/AntigravityInstallation.ts index c80e7d0c33..a4e1ec0ea8 100644 --- a/apps/server/src/provider/AntigravityInstallation.ts +++ b/apps/server/src/provider/AntigravityInstallation.ts @@ -47,7 +47,9 @@ import { const DRIVER = ProviderDriverKind.make("antigravity"); const DOWNLOAD_TIMEOUT = "45 minutes"; -const VALIDATION_TIMEOUT = "90 seconds"; +// SCIENT-FORK:START — Antigravity unpacks itself (~320 MiB) on every start; slow disks need minutes. +const VALIDATION_TIMEOUT = "5 minutes"; +// SCIENT-FORK:END const FREE_SPACE_MARGIN = 256 * 1024 * 1024; const RECORD_MAX_BYTES = 8 * 1024; const RELEASE_RECORD = ".install-complete.json"; diff --git a/apps/server/src/provider/AntigravityProvider.test.ts b/apps/server/src/provider/AntigravityProvider.test.ts index d292212cf0..084b143212 100644 --- a/apps/server/src/provider/AntigravityProvider.test.ts +++ b/apps/server/src/provider/AntigravityProvider.test.ts @@ -551,11 +551,11 @@ it.layer(layerTest)("Antigravity provider snapshots", (it) => { ); const refresh = yield* harness.provider.snapshot.refresh.pipe(Effect.forkChild); yield* Deferred.await(entered); - yield* TestClock.adjust("90 seconds"); + yield* TestClock.adjust("5 minutes"); const snapshot = yield* Fiber.join(refresh); yield* Deferred.await(closed); expect(snapshot.status).toBe("error"); - expect(snapshot.message).toContain("90 seconds"); + expect(snapshot.message).toContain("5 minutes"); }), ), ); diff --git a/apps/server/src/provider/AntigravityProvider.ts b/apps/server/src/provider/AntigravityProvider.ts index 05f4ff44f0..7cc8ff5b73 100644 --- a/apps/server/src/provider/AntigravityProvider.ts +++ b/apps/server/src/provider/AntigravityProvider.ts @@ -38,7 +38,9 @@ import { resolveUsageLimitsAfterProbe } from "@t3tools/provider-core/server/usag const EMPTY_MODEL_CAPABILITIES = createModelCapabilities({ optionDescriptors: [] }); const MAX_WORKSPACE_SNAPSHOTS = 32; -const HEALTH_CHECK_TIMEOUT = "90 seconds"; +// SCIENT-FORK:START — Antigravity unpacks itself (~320 MiB) on every start; slow disks need minutes. +const HEALTH_CHECK_TIMEOUT = "5 minutes"; +// SCIENT-FORK:END type SessionSetupResult = Pick< AcpSessionRuntime.AcpSessionRuntimeStartResult["sessionSetupResult"], diff --git a/apps/server/src/provider/Drivers/AntigravityDriver.test.ts b/apps/server/src/provider/Drivers/AntigravityDriver.test.ts index 73802d218a..7416570711 100644 --- a/apps/server/src/provider/Drivers/AntigravityDriver.test.ts +++ b/apps/server/src/provider/Drivers/AntigravityDriver.test.ts @@ -847,7 +847,7 @@ it.layer(testLayer)("AntigravityDriver", (it) => { yield* Deferred.await(spawned); expect(nativeLaunches(h)).toHaveLength(2); expect(yield* nativeLaunches(h)[1]!.handle.isRunning).toBe(true); - yield* TestClock.adjust("90 seconds"); + yield* TestClock.adjust("5 minutes"); expect(Exit.isFailure(yield* Fiber.join(logout))).toBe(true); yield* assertProcessesClosed(h, oldLaunches); yield* assertProcessesClosed(h); diff --git a/apps/server/src/provider/Drivers/AntigravityDriver.ts b/apps/server/src/provider/Drivers/AntigravityDriver.ts index eadff9e770..e461d806a8 100644 --- a/apps/server/src/provider/Drivers/AntigravityDriver.ts +++ b/apps/server/src/provider/Drivers/AntigravityDriver.ts @@ -533,7 +533,9 @@ export const AntigravityDriver: ScientProviderDriver< }, Effect.scoped, Effect.timeoutOrElse({ - duration: "90 seconds", + // SCIENT-FORK:START — Antigravity unpacks itself (~320 MiB) on every start; slow disks need minutes. + duration: "5 minutes", + // SCIENT-FORK:END orElse: () => Effect.fail( new ProviderDriverError({ diff --git a/docs/user/providers-antigravity.md b/docs/user/providers-antigravity.md index f35513a899..cb0cd7fb8a 100644 --- a/docs/user/providers-antigravity.md +++ b/docs/user/providers-antigravity.md @@ -191,7 +191,7 @@ longer want that credential method available. ## Troubleshooting -Health checks, model refresh, and sign-out allow up to 90 seconds for the official +Health checks, model refresh, and sign-out allow up to 5 minutes for the official runtime to start, which can be slow on some computers. Explicit refresh uses saved credentials and does not launch a login page. Automatic checks verify installation only. Google controls account eligibility and limits; Scient does not silently From d9bd5d8d72c8deee2b5ff88f4ccf450cb82d194a Mon Sep 17 00:00:00 2001 From: Yaacov Date: Mon, 19 Oct 2026 19:31:10 +0300 Subject: [PATCH 4/6] fix(antigravity): keep the health check at upstream's 90 seconds Review follow-up. The health check never starts the agent (it only resolves installation metadata), so the unpacking time doesn't apply to it, and a longer limit would only hold its refresh slot longer. The docs now name the installation check instead. Co-Authored-By: Claude Opus 5.5 --- UPSTREAM.md | 4 ++-- apps/server/src/provider/AntigravityProvider.test.ts | 4 ++-- apps/server/src/provider/AntigravityProvider.ts | 4 +--- docs/user/providers-antigravity.md | 2 +- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/UPSTREAM.md b/UPSTREAM.md index 6c74c8b4a1..81ea5b1797 100644 --- a/UPSTREAM.md +++ b/UPSTREAM.md @@ -1109,8 +1109,8 @@ program it starts opens a visible window; Antigravity's own inner process is one upstream bug (T3's Grok uses the same path) worth proposing. In Scient's retained `AntigravityInstallation.ts`, a runtime check that runs out of time reports that instead of the install's catch-all disk-space advice. -The install check, health check, model refresh (`AntigravityDriver.ts`) and sign-out -(`AntigravityAuth.ts`) allow 5 minutes instead of T3's 90 seconds, each in a marked line: the +The install check, model refresh (`AntigravityDriver.ts`) and sign-out (`AntigravityAuth.ts`) +allow 5 minutes instead of T3's 90 seconds, each in a marked line: the official Windows agent unpacks about 7,300 files (320 MiB) into a fresh folder on every start, which took about 35 s on a development machine and can exceed 90 s on slower disks. diff --git a/apps/server/src/provider/AntigravityProvider.test.ts b/apps/server/src/provider/AntigravityProvider.test.ts index 084b143212..d292212cf0 100644 --- a/apps/server/src/provider/AntigravityProvider.test.ts +++ b/apps/server/src/provider/AntigravityProvider.test.ts @@ -551,11 +551,11 @@ it.layer(layerTest)("Antigravity provider snapshots", (it) => { ); const refresh = yield* harness.provider.snapshot.refresh.pipe(Effect.forkChild); yield* Deferred.await(entered); - yield* TestClock.adjust("5 minutes"); + yield* TestClock.adjust("90 seconds"); const snapshot = yield* Fiber.join(refresh); yield* Deferred.await(closed); expect(snapshot.status).toBe("error"); - expect(snapshot.message).toContain("5 minutes"); + expect(snapshot.message).toContain("90 seconds"); }), ), ); diff --git a/apps/server/src/provider/AntigravityProvider.ts b/apps/server/src/provider/AntigravityProvider.ts index 7cc8ff5b73..05f4ff44f0 100644 --- a/apps/server/src/provider/AntigravityProvider.ts +++ b/apps/server/src/provider/AntigravityProvider.ts @@ -38,9 +38,7 @@ import { resolveUsageLimitsAfterProbe } from "@t3tools/provider-core/server/usag const EMPTY_MODEL_CAPABILITIES = createModelCapabilities({ optionDescriptors: [] }); const MAX_WORKSPACE_SNAPSHOTS = 32; -// SCIENT-FORK:START — Antigravity unpacks itself (~320 MiB) on every start; slow disks need minutes. -const HEALTH_CHECK_TIMEOUT = "5 minutes"; -// SCIENT-FORK:END +const HEALTH_CHECK_TIMEOUT = "90 seconds"; type SessionSetupResult = Pick< AcpSessionRuntime.AcpSessionRuntimeStartResult["sessionSetupResult"], diff --git a/docs/user/providers-antigravity.md b/docs/user/providers-antigravity.md index cb0cd7fb8a..965e691255 100644 --- a/docs/user/providers-antigravity.md +++ b/docs/user/providers-antigravity.md @@ -191,7 +191,7 @@ longer want that credential method available. ## Troubleshooting -Health checks, model refresh, and sign-out allow up to 5 minutes for the official +Installation checks, model refresh, and sign-out allow up to 5 minutes for the official runtime to start, which can be slow on some computers. Explicit refresh uses saved credentials and does not launch a login page. Automatic checks verify installation only. Google controls account eligibility and limits; Scient does not silently From 833f0eac8a4e10ff064797ad3f6a9a6c0ff61590 Mon Sep 17 00:00:00 2001 From: Yaacov Date: Mon, 19 Oct 2026 20:19:49 +0300 Subject: [PATCH 5/6] fix(acp): let the real host, not a simulated teardown platform, decide detaching CI follow-up. The seam keyed the detached flag on `processGroupPlatform`, which tests set to "win32" on Linux to simulate Windows teardown. On the Linux runner the agent then lost its own process group, and AcpAdapterV2's simulated hard teardown could no longer reap its Bash and sleep children. Whether a detached spawn opens a console window depends on the OS that spawns it, so the flag now follows `HostProcess.Platform`; real Windows still spawns attached, and Linux simulations keep the group. Co-Authored-By: Claude Opus 5.5 --- packages/provider-acp/src/server/AcpSessionRuntime.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/provider-acp/src/server/AcpSessionRuntime.ts b/packages/provider-acp/src/server/AcpSessionRuntime.ts index 87809fc0e3..701cc167ca 100644 --- a/packages/provider-acp/src/server/AcpSessionRuntime.ts +++ b/packages/provider-acp/src/server/AcpSessionRuntime.ts @@ -1557,11 +1557,12 @@ export const make = ( // SCIENT-FORK:START — Windows owns the tree with taskkill /T, not a group. // A detached agent has no console, so every console program it starts // (Antigravity's own inner process included) opens a visible window. + // The host decides, not the teardown platform a test may simulate. ...(options.ownDetachedProcessGroup === undefined ? {} : { detached: - options.ownDetachedProcessGroup && options.processGroupPlatform !== "win32", + options.ownDetachedProcessGroup && (yield* HostProcess.Platform) !== "win32", }), // SCIENT-FORK:END shell: containedSpawnCommand.shell, From 9bcf037efacb8fa760a3de7f8f7bf2bcaeea7630 Mon Sep 17 00:00:00 2001 From: Yaacov Date: Mon, 19 Oct 2026 21:54:06 +0300 Subject: [PATCH 6/6] test(antigravity): expect the real host to decide detaching CI follow-up to 833f0eac8a. The install harness simulates a platform only while building the installation; the validation runs in the caller's context, where the host platform is the real one. On the Linux runner the simulated Windows ARM cases therefore spawn detached, as intended, but the mock spawner still expected the simulated platform's value and rejected the spawn. It now expects the real host's, matching the seam. Co-Authored-By: Claude Opus 5.5 --- apps/server/src/provider/AntigravityInstallation.test.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/server/src/provider/AntigravityInstallation.test.ts b/apps/server/src/provider/AntigravityInstallation.test.ts index e3fc9b7611..5caecef955 100644 --- a/apps/server/src/provider/AntigravityInstallation.test.ts +++ b/apps/server/src/provider/AntigravityInstallation.test.ts @@ -631,8 +631,9 @@ it.layer(NodeServices.layer)("Antigravity installation", (it) => { Effect.asVoid, ); if (!helper) { - // Windows owns the tree with taskkill; detaching would show a console. - expect(command.options.detached).toBe(platform !== "win32"); + // The real host decides, not the simulated platform: Windows owns the + // tree with taskkill, and detaching there would show a console. + expect(command.options.detached).toBe(hostPlatform !== "win32"); stopNative = terminate; } yield* Effect.addFinalizer(() =>