From 26554234df9bf89cc465e06d16d14dbdde33a496 Mon Sep 17 00:00:00 2001 From: OrcaWin Date: Sun, 18 Oct 2026 11:08:47 -0700 Subject: [PATCH] fix(rate-limits): run the Antigravity usage probe with agy's auto-update off (#30387) A due update check makes agy start --bg-updater, whose own console child opens a visible window on Windows and takes focus, so stepping away from Orca for 15+ minutes and coming back flashed a terminal (#27390). Set AGY_CLI_DISABLE_AUTO_UPDATE=true on both probes; a background quota read should not update the user's CLI anyway. Only 'true' is honoured (agy 1.4.2). Co-authored-by: Orca Worker --- .../rate-limits/antigravity-usage-command.ts | 9 +++++++ .../antigravity-usage-fetcher.test.ts | 27 ++++++++++--------- .../rate-limits/antigravity-usage-fetcher.ts | 3 ++- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/src/main/rate-limits/antigravity-usage-command.ts b/src/main/rate-limits/antigravity-usage-command.ts index 133f92fc593..039c387d79f 100644 --- a/src/main/rate-limits/antigravity-usage-command.ts +++ b/src/main/rate-limits/antigravity-usage-command.ts @@ -36,6 +36,15 @@ export const ANTIGRAVITY_USAGE_ARGS: readonly string[] = [ */ export const ANTIGRAVITY_USAGE_TIMEOUT_MS = 30_000 +/** + * Added to every probe's environment. + * + * Why: a due update check makes agy start `--bg-updater`, whose own console child opens a visible + * window on Windows and takes focus (#27390); a background quota read must not update the CLI + * either. Verified on agy 1.4.2: only `true` disables it (`1` still spawns the updater). + */ +export const ANTIGRAVITY_PROBE_ENV = { AGY_CLI_DISABLE_AUTO_UPDATE: 'true' } as const + // Before agy 1.1.11, `/usage` in print mode spends a model turn (agy's bundled changelog). export const ANTIGRAVITY_MIN_USAGE_VERSION = '1.1.11' diff --git a/src/main/rate-limits/antigravity-usage-fetcher.test.ts b/src/main/rate-limits/antigravity-usage-fetcher.test.ts index ca7ef170d5b..c1003316784 100644 --- a/src/main/rate-limits/antigravity-usage-fetcher.test.ts +++ b/src/main/rate-limits/antigravity-usage-fetcher.test.ts @@ -115,21 +115,24 @@ describe('fetchAntigravityRateLimits', () => { }) it('probes the version, then runs the quota read with the resolved path and login-shell env', async () => { - const h = harness({ result: processResult({ stdout: USAGE_ENVELOPE }) }) + const loginShellEnv = { PATH: '/Users/x/.local/bin:/usr/bin' } + const h = harness({ result: processResult({ stdout: USAGE_ENVELOPE }), env: loginShellEnv }) await h.fetch() - expect(h.runCommand).toHaveBeenCalledTimes(2) - expect(h.runCommand.mock.calls[0]![0].args).toEqual(ANTIGRAVITY_VERSION_ARGS) - const spec = h.runCommand.mock.calls[1]![0] - expect(spec.program).toBe('/Users/x/.local/bin/agy') - expect(spec.args).toEqual(ANTIGRAVITY_USAGE_ARGS) // Why the login-shell PATH: agy installs to ~/.local/bin, which Electron's inherited PATH omits. - expect(spec.env).toEqual({ PATH: '/Users/x/.local/bin:/usr/bin' }) - expect(spec.timeoutMs).toBeGreaterThan(0) - expect(h.resolveCommand).toHaveBeenCalledWith('agy', { - platform: 'darwin', - env: { PATH: '/Users/x/.local/bin:/usr/bin' } - }) + // Why auto-update off: a due check spawns agy's updater, whose child flashes a Windows console. + const probeEnv = { PATH: '/Users/x/.local/bin:/usr/bin', AGY_CLI_DISABLE_AUTO_UPDATE: 'true' } + expect(h.runCommand).toHaveBeenCalledTimes(2) + const [versionSpec, usageSpec] = h.runCommand.mock.calls.map(([spec]) => spec) + expect(versionSpec.args).toEqual(ANTIGRAVITY_VERSION_ARGS) + expect(versionSpec.env).toEqual(probeEnv) + expect(usageSpec.program).toBe('/Users/x/.local/bin/agy') + expect(usageSpec.args).toEqual(ANTIGRAVITY_USAGE_ARGS) + expect(usageSpec.env).toEqual(probeEnv) + expect(usageSpec.timeoutMs).toBeGreaterThan(0) + expect(h.resolveCommand).toHaveBeenCalledWith('agy', { platform: 'darwin', env: probeEnv }) + // The login-shell env is a shared cache entry; the probe must not write into it. + expect(loginShellEnv).toEqual({ PATH: '/Users/x/.local/bin:/usr/bin' }) }) it('reports an absent CLI as unavailable and never spawns', async () => { diff --git a/src/main/rate-limits/antigravity-usage-fetcher.ts b/src/main/rate-limits/antigravity-usage-fetcher.ts index 2980d9b9603..e021f84c9a3 100644 --- a/src/main/rate-limits/antigravity-usage-fetcher.ts +++ b/src/main/rate-limits/antigravity-usage-fetcher.ts @@ -5,6 +5,7 @@ import { resolveLoginShellEnvironment } from '../startup/login-shell-environment import type { ProviderRateLimits, UsageRateLimitFailureKind } from '../../shared/rate-limit-types' import { ANTIGRAVITY_MIN_USAGE_VERSION, + ANTIGRAVITY_PROBE_ENV, ANTIGRAVITY_USAGE_ARGS, ANTIGRAVITY_USAGE_MAX_OUTPUT_BYTES, ANTIGRAVITY_USAGE_TIMEOUT_MS, @@ -121,7 +122,7 @@ export async function fetchAntigravityRateLimits( // Why the login shell's env: agy installs to ~/.local/bin, which is on the user's PATH but not on // the PATH an Electron app inherits from the window server or a desktop launcher. - const env = await resolveEnvironment() + const env = { ...(await resolveEnvironment()), ...ANTIGRAVITY_PROBE_ENV } const command = antigravityCommandName() const program = await resolve(command, { platform, env }) if (!program) {