feat(desktop): add Antigravity CLI (agy) as a first-class agent

TH
4mo ago
+439-1

Why

Google has deprecated the Gemini CLI and is pointing users at the Antigravity CLI. The individual-account client is already rejected at sign-in:

This client is no longer supported for Gemini Code Assist for individuals. To continue using Gemini, please migrate to the Antigravity suite of products.

Homebrew's gemini-cli formula is marked deprecated with brew install --cask antigravity-cli as the replacement, and disables on 2026-12-18.

This adds Antigravity as its own builtin terminal agent so Superset's lifecycle notifications work with it.

The existing gemini entry is left untouched. Enterprise Code Assist users can still run the Gemini CLI until Google pulls it, so this is purely additive — no preset migration, nothing breaks for existing users.

Two things that differ from the other agent integrations

1. The agent id is agy, not antigravity. SUPERSET_MANAGED_BINARIES derives the shell shim name directly from the agent id (shell-wrappers.ts), so the id has to match the binary Antigravity actually installs. Registering it as antigravity would generate a shim named antigravity while the wrapper file was written as agy, and the two would never line up — the agent would launch unwrapped and no hook would ever fire.

The alternative is adding a binaryName field to DesktopAgentSetupTarget and mapping it in both prelude builders. Happy to switch to that if you'd rather keep ids human-readable — it's a small change, but it touches plumbing shared by all 11 agents, so I went with the id that needs no core changes.

2. The hook takes its event from argv. Antigravity's hook payload carries no event-name field — the common fields are conversationId / workspacePaths / transcriptPath / artifactDirectoryPath / modelName only (camelCase, protojson). Every other agent's hook derives the event from stdin; this one can't, so hooks.json passes the Superset event as $1.

Config location

Hook config goes to ~/.gemini/config/hooks.json — Antigravity's global customization root, shared with Antigravity 2.0 and the IDE — not the ~/.gemini/settings.json the Gemini CLI used. Antigravity namespaces hooks by name and merges every named block for an event, so Superset owns a single "superset" key and leaves user- and plugin-defined hooks untouched. That makes the merge considerably simpler than the Gemini per-event reconciliation.

Event mapping

Antigravity eventSuperset eventWhy
PreInvocationStartFires before each model call
PostToolUseStartKeeps the terminal marked busy across long tool loops
StopStopFires when the execution loop terminates

PreToolUse is deliberately not registered. Its contract requires a decision field (allow / deny / ask / force_ask), and emitting an empty object there risks gating the user's own tool calls. There's a test asserting we never register it.

Antigravity runs hooks synchronously and blocks the agent loop on them, so the hook prints its JSON result before doing any network work, and every event we register treats {} as a safe no-op (PreInvocation treats injectSteps as optional, PostToolUse expects exactly {}, and Stop only blocks termination when decision is "continue").

Testing

  • bun run typecheck — 35/35 tasks
  • bun test apps/desktop/src/main/lib/agent-setup/ — 79 pass
  • bun test packages/shared/src — 704 pass
  • bun run lint — exit 0

New tests cover the wrapper's agent-id stamping, the ~/.gemini/config path, the argv event contract for all three registered events, the PreToolUse exclusion, idempotency, foreign-hook preservation, and recovery from an unparseable existing file. The Antigravity template is also added to the shared "dispatches to v2 first, falls back to v1" contract test.

Not included

  • Marketing compatibility surfaces and apps/mobile/store.config.json — happy to add if you want them in this PR.
  • Not added to DEFAULT_V2_TERMINAL_PRESET_IDS, matching how gemini is treated. Seeding a preset for a CLI the user hasn't installed shows a broken-looking entry.
  • No AGENT_MODEL_SUPPORT entry. Antigravity exposes --model, but the model names are display strings (e.g. "Gemini 3.5 Flash (Low)") resolved per-account via agy models, so a static catalog would go stale. Worth a follow-up if you want model selection in the picker.

The icon is the official Antigravity mark.


Open in Stage

Summary by cubic

Add Antigravity CLI (agy) as a first-class terminal agent so Superset can track lifecycle events for Google’s replacement to the deprecated Gemini CLI. The existing gemini agent remains unchanged.

  • New Features

    • Added agy agent with a managed wrapper, preset, and icon.
    • Hook config at ~/.gemini/config/hooks.json under a dedicated key; preserves other user/plugin hooks.
    • Events passed via argv; maps PreInvocation/PostInvocation → Start, Stop → Stop; skips PreToolUse and PostToolUse (the latter can fire after Stop).
    • Wrapper id matches the binary name (agy); docs updated to list the Antigravity preset and note gemini is deprecated upstream.
  • Bug Fixes

    • Use PostInvocation (not PostToolUse) to prevent panes from getting stuck in a “working” state.
    • Skip writing hooks.json when the existing file is unparseable or not an object, avoiding clobbering other hooks.

Summary by CodeRabbit

  • New Features
    • Added Antigravity (agy) as a built-in terminal agent with default presets, settings support, and a dedicated preset icon.
    • Introduced Antigravity setup for generating the wrapper, lifecycle hook script, and hooks configuration.
    • Added Antigravity to the terminal “quick-add” preset list and agent icon picker.
  • Bug Fixes
    • Preserves existing hook configuration and avoids clobbering hooks.json when it can’t be parsed.
  • Tests
    • Expanded coverage for wrapper behavior, hook event dispatching, hooks merging/idempotency, and template fallback.
  • Documentation
    • Updated terminal preset docs to include Antigravity and note Gemini CLI status.