Repository navigation
feat(desktop): add Antigravity CLI (agy) as a first-class agent - #5772
thebrownproject wants to merge 3 commits into
Conversation
Google deprecated the Gemini CLI (Homebrew disables the formula on 2026-12-18, and the individual-account client is already rejected at sign-in) and points users at the Antigravity CLI. This registers 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 it until Google pulls it. Two things differ from the other agent integrations: - The agent id is `agy`, not `antigravity`. SUPERSET_MANAGED_BINARIES derives the shell shim name directly from the agent id, so the id has to match the binary that Antigravity actually installs. - Antigravity's hook payload carries no event-name field (the common fields are conversationId/workspacePaths/transcriptPath/modelName), so hooks.json passes the Superset event as argv rather than the hook deriving it from stdin. Hook config lives at ~/.gemini/config/hooks.json -- Antigravity's global customization root -- not the ~/.gemini/settings.json the Gemini CLI used. Hooks are namespaced by name, so we own a single "superset" key and leave user- and plugin-defined hooks alone. PreInvocation and PostToolUse map to Start, Stop maps to Stop. PreToolUse is deliberately not registered: its contract requires a `decision` field, and emitting an empty object risks gating the user's own tool calls.
Also flag the gemini preset as deprecated upstream so users know why a second Google agent is listed.
|
Ready to review this PR? Stage has broken it down into 6 individual chapters for you: Chapters generated by Stage for commit 2929c5b on Jul 19, 2026 8:30am UTC. |
📝 WalkthroughWalkthroughAdds the ChangesAntigravity agent integration
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant AntigravityCLI
participant HookScript
participant Superset
AntigravityCLI->>HookScript: Send event argv and JSON stdin
HookScript->>Superset: POST lifecycle notification
Superset-->>HookScript: Return hook response
HookScript->>Superset: GET /hook/complete
Possibly related issues
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Greptile SummaryThis PR adds Antigravity CLI (
Confidence Score: 4/5Safe to merge; the change is purely additive and follows the established agent-integration pattern throughout the codebase. The integration is well-structured and the test coverage is thorough. The one open question is whether Pay extra attention to
|
| Filename | Overview |
|---|---|
| apps/desktop/src/main/lib/agent-setup/agent-wrappers-antigravity.ts | New integration module: writes the hook script, hooks.json block, and shell wrapper for the Antigravity CLI. Merge logic preserves foreign hook keys and handles corrupt JSON. |
| apps/desktop/src/main/lib/agent-setup/templates/antigravity-hook.template.sh | Shell hook template that reads the Superset event from argv instead of stdin. Emits {} before network dispatch; follows the same v2-then-v1 fallback pattern as gemini/cursor/copilot hooks. |
| packages/shared/src/builtin-terminal-agents.ts | Adds agy builtin agent with includeInDefaultTerminalPresets: true. nonInteractiveCommand omits --mode accept-edits, which may affect headless invocations. |
| apps/desktop/src/main/lib/agent-setup/desktop-agent-capabilities.ts | Adds three new setup actions and an agy target with managedBinary: true. Wiring is correct and consistent with other managed-binary agents. |
| apps/desktop/src/main/lib/agent-setup/agent-wrappers.test.ts | Adds comprehensive test suite covering agent-id stamping, config path, argv event contract, PreToolUse exclusion, idempotency, foreign-hook preservation, and corrupted-file recovery. |
| apps/desktop/src/main/lib/agent-setup/desktop-agent-setup.ts | Registers the three Antigravity setup runners in the action dispatch table. Purely additive. |
| packages/ui/src/assets/icons/preset-icons/index.ts | Adds antigravity.svg and maps it under the agy key in PRESET_ICONS. |
| apps/desktop/src/main/lib/agent-setup/notify-hook.test.ts | Adds antigravity-hook.template.sh to the shared v2-first, v1-fallback contract test. |
| apps/desktop/src/renderer/routes/_authenticated/settings/agents/components/V2AgentsSettings/components/AgentIconPicker/agent-icon-options.ts | Adds {id: 'agy', label: 'Antigravity'} to the icon picker options list. |
| apps/docs/content/docs/terminal-presets.mdx | Documents agy preset and marks gemini as deprecated upstream. |
Sequence Diagram
%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant A as Antigravity CLI (agy)
participant H as antigravity-hook.sh
participant S as Superset (v2 host-service)
participant S1 as Superset (v1 local)
A->>H: "PreInvocation payload (stdin), argv=$1=Start"
H->>H: "INPUT=$(cat) - read stdin"
H-->>A: "printf '{}' (hook response, no-op)"
H->>S: "POST SUPERSET_HOST_AGENT_HOOK_URL {Start}"
alt v2 success (2xx)
S-->>H: 200 OK
else v2 fail / missing
H->>S1: "GET /hook/complete?eventType=Start"
end
A->>H: "PostToolUse payload (stdin), argv=$1=Start"
H->>H: "INPUT=$(cat)"
H-->>A: "printf '{}' (expected exactly {})"
H->>S: "POST {Start}"
A->>H: "Stop payload (stdin), argv=$1=Stop"
H->>H: "INPUT=$(cat)"
H-->>A: "printf '{}' (decision omitted = no block)"
H->>S: "POST {Stop}"
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant A as Antigravity CLI (agy)
participant H as antigravity-hook.sh
participant S as Superset (v2 host-service)
participant S1 as Superset (v1 local)
A->>H: "PreInvocation payload (stdin), argv=$1=Start"
H->>H: "INPUT=$(cat) - read stdin"
H-->>A: "printf '{}' (hook response, no-op)"
H->>S: "POST SUPERSET_HOST_AGENT_HOOK_URL {Start}"
alt v2 success (2xx)
S-->>H: 200 OK
else v2 fail / missing
H->>S1: "GET /hook/complete?eventType=Start"
end
A->>H: "PostToolUse payload (stdin), argv=$1=Start"
H->>H: "INPUT=$(cat)"
H-->>A: "printf '{}' (expected exactly {})"
H->>S: "POST {Start}"
A->>H: "Stop payload (stdin), argv=$1=Stop"
H->>H: "INPUT=$(cat)"
H-->>A: "printf '{}' (decision omitted = no block)"
H->>S: "POST {Stop}"
Prompt To Fix All With AI
Fix the following 3 code review issues. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 3
packages/shared/src/builtin-terminal-agents.ts:109
The `nonInteractiveCommand` for `agy` omits `--mode accept-edits`, while both `command` and `promptCommand` include it. If Antigravity requires the mode flag to operate without a TTY (i.e., to suppress interactive prompts during headless runs), the current `agy -p` invocation may stall or error in non-interactive task mode. Gemini's equivalent is `gemini --skip-trust -p`, which also drops the approval flag — but it's worth confirming that `--mode accept-edits` is not required for `agy`'s `-p` path before shipping.
```suggestion
nonInteractiveCommand: "agy --mode accept-edits -p",
```
### Issue 2 of 3
apps/desktop/src/main/lib/agent-setup/templates/antigravity-hook.template.sh:21-31
**`{}` is emitted after stdin is fully consumed, not before**
`INPUT=$(cat)` at line 21 blocks until Antigravity closes the hook's stdin writer. `printf '{}\n'` (line 31) only fires after that. The comment on line 27 — "Emit before dispatching" — refers to dispatching to Superset, not to providing the Antigravity response early. This ordering is intentional and matches the Gemini hook pattern exactly, so it's fine as long as Antigravity closes stdin before reading stdout. Worth clarifying the comment so future reviewers don't mistake it for an early-response guarantee.
### Issue 3 of 3
apps/desktop/src/main/lib/agent-setup/agent-wrappers-antigravity.ts:110-130
**`fs.readFileSync` inside the `try` block can throw independently of `JSON.parse`**
If `fs.existsSync` returns `true` but the file becomes unreadable between the check and `readFileSync` (e.g., a permission change or race with another writer), the `catch` block silently swallows the I/O error and proceeds with an empty `existing` object — wiping every foreign hook block previously written. This is a pre-existing pattern in the codebase, but it's more consequential here since `hooks.json` is shared with IDE and user-defined hooks.
Reviews (1): Last reviewed commit: "docs(terminal-presets): list the Antigra..." | Re-trigger Greptile
| "Google's terminal agent harness for reasoning, editing, and running code from the terminal.", | ||
| command: "agy --mode accept-edits", | ||
| promptCommand: "agy --mode accept-edits", | ||
| nonInteractiveCommand: "agy -p", |
There was a problem hiding this comment.
The
nonInteractiveCommand for agy omits --mode accept-edits, while both command and promptCommand include it. If Antigravity requires the mode flag to operate without a TTY (i.e., to suppress interactive prompts during headless runs), the current agy -p invocation may stall or error in non-interactive task mode. Gemini's equivalent is gemini --skip-trust -p, which also drops the approval flag — but it's worth confirming that --mode accept-edits is not required for agy's -p path before shipping.
| nonInteractiveCommand: "agy -p", | |
| nonInteractiveCommand: "agy --mode accept-edits -p", |
Does agy -p behave correctly in headless/non-TTY mode without --mode accept-edits, or does the mode flag need to be present for non-interactive prompts to run unattended?
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/shared/src/builtin-terminal-agents.ts
Line: 109
Comment:
The `nonInteractiveCommand` for `agy` omits `--mode accept-edits`, while both `command` and `promptCommand` include it. If Antigravity requires the mode flag to operate without a TTY (i.e., to suppress interactive prompts during headless runs), the current `agy -p` invocation may stall or error in non-interactive task mode. Gemini's equivalent is `gemini --skip-trust -p`, which also drops the approval flag — but it's worth confirming that `--mode accept-edits` is not required for `agy`'s `-p` path before shipping.
```suggestion
nonInteractiveCommand: "agy --mode accept-edits -p",
```
Does `agy -p` behave correctly in headless/non-TTY mode without `--mode accept-edits`, or does the mode flag need to be present for non-interactive prompts to run unattended?
How can I resolve this? If you propose a fix, please make it concise.| INPUT=$(cat) | ||
|
|
||
| # Payload keys are camelCase (protojson). conversationId is Antigravity's | ||
| # session identifier. | ||
| HOOK_SESSION_ID=$(printf '%s' "$INPUT" | grep -oE '"conversationId"[[:space:]]*:[[:space:]]*"[^"]*"' | grep -oE '"[^"]*"$' | tr -d '"') | ||
|
|
||
| # Emit before dispatching. An empty object is the no-op result for every event | ||
| # we register: PreInvocation/PostInvocation treat injectSteps as optional, | ||
| # PostToolUse expects exactly {}, and Stop only blocks termination when | ||
| # decision is "continue". | ||
| printf '{}\n' |
There was a problem hiding this comment.
{} is emitted after stdin is fully consumed, not before
INPUT=$(cat) at line 21 blocks until Antigravity closes the hook's stdin writer. printf '{}\n' (line 31) only fires after that. The comment on line 27 — "Emit before dispatching" — refers to dispatching to Superset, not to providing the Antigravity response early. This ordering is intentional and matches the Gemini hook pattern exactly, so it's fine as long as Antigravity closes stdin before reading stdout. Worth clarifying the comment so future reviewers don't mistake it for an early-response guarantee.
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop/src/main/lib/agent-setup/templates/antigravity-hook.template.sh
Line: 21-31
Comment:
**`{}` is emitted after stdin is fully consumed, not before**
`INPUT=$(cat)` at line 21 blocks until Antigravity closes the hook's stdin writer. `printf '{}\n'` (line 31) only fires after that. The comment on line 27 — "Emit before dispatching" — refers to dispatching to Superset, not to providing the Antigravity response early. This ordering is intentional and matches the Gemini hook pattern exactly, so it's fine as long as Antigravity closes stdin before reading stdout. Worth clarifying the comment so future reviewers don't mistake it for an early-response guarantee.
How can I resolve this? If you propose a fix, please make it concise.Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
| export function getAntigravityHooksJsonContent(hookScriptPath: string): string { | ||
| const globalPath = getAntigravityHooksJsonPath(); | ||
|
|
||
| let existing: AntigravityHooksJson = {}; | ||
| try { | ||
| if (fs.existsSync(globalPath)) { | ||
| const parsed: unknown = JSON.parse(fs.readFileSync(globalPath, "utf-8")); | ||
| if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) { | ||
| existing = parsed as AntigravityHooksJson; | ||
| } | ||
| } | ||
| } catch { | ||
| console.warn( | ||
| "[agent-setup] Could not parse existing ~/.gemini/config/hooks.json, rewriting Superset block only", | ||
| ); | ||
| } | ||
|
|
||
| existing[ANTIGRAVITY_HOOK_NAME] = buildSupersetHookBlock(hookScriptPath); | ||
|
|
||
| return JSON.stringify(existing, null, 2); | ||
| } |
There was a problem hiding this comment.
fs.readFileSync inside the try block can throw independently of JSON.parse
If fs.existsSync returns true but the file becomes unreadable between the check and readFileSync (e.g., a permission change or race with another writer), the catch block silently swallows the I/O error and proceeds with an empty existing object — wiping every foreign hook block previously written. This is a pre-existing pattern in the codebase, but it's more consequential here since hooks.json is shared with IDE and user-defined hooks.
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop/src/main/lib/agent-setup/agent-wrappers-antigravity.ts
Line: 110-130
Comment:
**`fs.readFileSync` inside the `try` block can throw independently of `JSON.parse`**
If `fs.existsSync` returns `true` but the file becomes unreadable between the check and `readFileSync` (e.g., a permission change or race with another writer), the `catch` block silently swallows the I/O error and proceeds with an empty `existing` object — wiping every foreign hook block previously written. This is a pre-existing pattern in the codebase, but it's more consequential here since `hooks.json` is shared with IDE and user-defined hooks.
How can I resolve this? If you propose a fix, please make it concise.…ites Two defects found reviewing the preceding commit. 1. Register PostInvocation, not PostToolUse. Antigravity dispatches a trailing PostToolUse for the final step roughly a second AFTER the Stop hook on any turn that ends without a tool call. Since PostToolUse mapped to Start, the last event Superset received for such a turn was Start, and terminal status is last-write-wins with no staleness gate on the Start branch -- so the pane stayed pinned to "working" indefinitely after the agent had finished replying, with only the manual clear-status escape hatch to recover. Reproduced against agy 1.1.4 with a probe hook logging argv and epoch. A no-tool turn emits: 307.589 PreInvocation 307.630 PostToolUse stepIdx:1 toolCall:null 309.117 PostInvocation 309.157 Stop terminationReason:NO_TOOL_CALL 310.026 PostToolUse stepIdx:3 toolCall:null <- 0.87s after Stop PostInvocation fires once per loop iteration and always precedes Stop, so it serves the same "stay busy across long tool loops" purpose without the trailing Start. Two incidental corrections to the previous reasoning: matcher "*" matches every step type rather than only tool calls (tool names are derived from the step type with the CORTEX_STEP_TYPE_ prefix stripped), and those trailing steps carry toolCall:null -- so PostToolUse was never really a tool-loop keepalive to begin with. 2. Never rewrite a hooks.json we could not read. getAntigravityHooksJsonContent seeded an empty object and fell through on parse failure, so an unreadable or non-object hooks.json was replaced wholesale by our block alone, discarding the user's and any plugin's hooks. ~/.gemini/config/ is shared by the CLI, Antigravity 2.0 and the IDE, so that took out every surface at once. It now returns null and the writer skips, matching the readExistingClaudeSettings / readExistingCodexHooks / readExistingDroidSettings contract the newer sibling integrations already use. The unparseable-file test asserted only that our own key existed, so it passed either way; it now covers unparseable, top-level-array and null files and asserts the file is left byte-identical.
|
Ran an adversarial review over this branch (5 reviewers by dimension, every finding handed to an independent agent tasked with refuting it). Two defects survived, both now fixed in 08d0772. 1. A verifier installed the exact Since Two of my original assumptions were also just wrong: Now registers Worth flagging for the other integrations: 2. Unreadable The test for that path was also theatre — it asserted only that our own key existed, so it passed whether or not user hooks survived. It now covers unparseable, top-level-array and Everything else checked out against the binary's embedded docs: the
|
08d0772 to
2929c5b
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/shared/src/builtin-terminal-agents.ts`:
- Around line 99-111: Remove includeInDefaultTerminalPresets from the
createBuiltinTerminalAgent registration for the agy Antigravity agent. Keep the
agent available without adding it to DEFAULT_TERMINAL_PRESET_AGENT_TYPES or
newly initialized users’ default terminal presets.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: cea7cd95-f36a-42f4-a1c2-1259e0be920d
⛔ Files ignored due to path filters (1)
packages/ui/src/assets/icons/preset-icons/antigravity.svgis excluded by!**/*.svg
📒 Files selected for processing (11)
apps/desktop/src/main/lib/agent-setup/agent-wrappers-antigravity.tsapps/desktop/src/main/lib/agent-setup/agent-wrappers.test.tsapps/desktop/src/main/lib/agent-setup/agent-wrappers.tsapps/desktop/src/main/lib/agent-setup/desktop-agent-capabilities.tsapps/desktop/src/main/lib/agent-setup/desktop-agent-setup.tsapps/desktop/src/main/lib/agent-setup/notify-hook.test.tsapps/desktop/src/main/lib/agent-setup/templates/antigravity-hook.template.shapps/desktop/src/renderer/routes/_authenticated/settings/agents/components/V2AgentsSettings/components/AgentIconPicker/agent-icon-options.tsapps/docs/content/docs/terminal-presets.mdxpackages/shared/src/builtin-terminal-agents.tspackages/ui/src/assets/icons/preset-icons/index.ts
🚧 Files skipped from review as they are similar to previous changes (8)
- apps/desktop/src/renderer/routes/_authenticated/settings/agents/components/V2AgentsSettings/components/AgentIconPicker/agent-icon-options.ts
- apps/desktop/src/main/lib/agent-setup/notify-hook.test.ts
- apps/desktop/src/main/lib/agent-setup/desktop-agent-capabilities.ts
- packages/ui/src/assets/icons/preset-icons/index.ts
- apps/desktop/src/main/lib/agent-setup/agent-wrappers.ts
- apps/desktop/src/main/lib/agent-setup/desktop-agent-setup.ts
- apps/docs/content/docs/terminal-presets.mdx
- apps/desktop/src/main/lib/agent-setup/agent-wrappers.test.ts
| createBuiltinTerminalAgent({ | ||
| // Google's replacement for the deprecated Gemini CLI. The id matches the | ||
| // binary name (`agy`) because SUPERSET_MANAGED_BINARIES derives the shell | ||
| // shim name from the agent id. | ||
| id: "agy", | ||
| label: "Antigravity", | ||
| description: | ||
| "Google's terminal agent harness for reasoning, editing, and running code from the terminal.", | ||
| command: "agy --mode accept-edits", | ||
| promptCommand: "agy --mode accept-edits", | ||
| nonInteractiveCommand: "agy -p", | ||
| includeInDefaultTerminalPresets: true, | ||
| }), |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Do not add Antigravity to default terminal presets.
includeInDefaultTerminalPresets: true causes agy to flow into DEFAULT_TERMINAL_PRESET_AGENT_TYPES and be seeded into new users’ terminal presets, contradicting the PR objective that Antigravity should not be included by default.
Proposed fix
nonInteractiveCommand: "agy -p",
- includeInDefaultTerminalPresets: true,
}),Based on the PR objective and the downstream preset initialization contract, this flag must remain unset for agy.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| createBuiltinTerminalAgent({ | |
| // Google's replacement for the deprecated Gemini CLI. The id matches the | |
| // binary name (`agy`) because SUPERSET_MANAGED_BINARIES derives the shell | |
| // shim name from the agent id. | |
| id: "agy", | |
| label: "Antigravity", | |
| description: | |
| "Google's terminal agent harness for reasoning, editing, and running code from the terminal.", | |
| command: "agy --mode accept-edits", | |
| promptCommand: "agy --mode accept-edits", | |
| nonInteractiveCommand: "agy -p", | |
| includeInDefaultTerminalPresets: true, | |
| }), | |
| createBuiltinTerminalAgent({ | |
| // Google's replacement for the deprecated Gemini CLI. The id matches the | |
| // binary name (`agy`) because SUPERSET_MANAGED_BINARIES derives the shell | |
| // shim name from the agent id. | |
| id: "agy", | |
| label: "Antigravity", | |
| description: | |
| "Google's terminal agent harness for reasoning, editing, and running code from the terminal.", | |
| command: "agy --mode accept-edits", | |
| promptCommand: "agy --mode accept-edits", | |
| nonInteractiveCommand: "agy -p", | |
| }), |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/shared/src/builtin-terminal-agents.ts` around lines 99 - 111, Remove
includeInDefaultTerminalPresets from the createBuiltinTerminalAgent registration
for the agy Antigravity agent. Keep the agent available without adding it to
DEFAULT_TERMINAL_PRESET_AGENT_TYPES or newly initialized users’ default terminal
presets.
Adds Google's Antigravity CLI (`agy`) to BUILTIN_TERMINAL_AGENTS, with the official mark as its preset icon, README row, docs bullet, and marketing demo entry. Rebased by hand from #5772 onto the current manifest shape. The agent id is `agy` to match the binary. Prompt launches seed the interactive session positionally, resume uses `--conversation <id>`, and `agy -p` is the headless form. The lifecycle-hook wrapper from #5772 (hooks.json under ~/.gemini/config) targets the old desktop agent-setup location and is left for a follow-up now that agent setup lives in packages/agent-setup; agy ships here as a plain terminal agent like Pi / Cursor Agent. Co-authored-by: Fraser Brown <173673575+thebrownproject@users.noreply.github.com> Claude-Session: https://claude.ai/code/session_01DuAhw6Ao5Cru3acdkrzx9f
Adds Google's Antigravity CLI (`agy`) to BUILTIN_TERMINAL_AGENTS, with the official mark as its preset icon, README row, docs bullet, and marketing demo entry. Rebased by hand from #5772 onto the current manifest shape. The agent id is `agy` to match the binary. Prompt launches seed the interactive session positionally, resume uses `--conversation <id>`, and `agy -p` is the headless form. The lifecycle-hook wrapper from #5772 (hooks.json under ~/.gemini/config) targets the old desktop agent-setup location and is left for a follow-up now that agent setup lives in packages/agent-setup; agy ships here as a plain terminal agent like Pi / Cursor Agent. Co-authored-by: Fraser Brown <173673575+thebrownproject@users.noreply.github.com> Claude-Session: https://claude.ai/code/session_01DuAhw6Ao5Cru3acdkrzx9f
Adds Google's Antigravity CLI (agy) to BUILTIN_TERMINAL_AGENTS, with the official mark as its preset icon, README row, docs bullet, and marketing demo entry. Rebased from #5772; prompt launches use -i (positional prompts are rejected by the CLI), resume uses --conversation <id>, agy -p is the headless form. Verified against an installed agy 1.1.19. Co-authored-by: Fraser Brown <173673575+thebrownproject@users.noreply.github.com> Claude-Session: https://claude.ai/code/session_01DuAhw6Ao5Cru3acdkrzx9f
…6767) * feat(shared): add Antigravity CLI (agy) as a built-in terminal agent Adds Google's Antigravity CLI (agy) to BUILTIN_TERMINAL_AGENTS, with the official mark as its preset icon, README row, docs bullet, and marketing demo entry. Rebased from #5772; prompt launches use -i (positional prompts are rejected by the CLI), resume uses --conversation <id>, agy -p is the headless form. Verified against an installed agy 1.1.19. Co-authored-by: Fraser Brown <173673575+thebrownproject@users.noreply.github.com> Claude-Session: https://claude.ai/code/session_01DuAhw6Ao5Cru3acdkrzx9f * feat(desktop): expose Antigravity in the icon picker, settings search, and preset docs Claude-Session: https://claude.ai/code/session_01DuAhw6Ao5Cru3acdkrzx9f
|
Antigravity is now on main — landed via #6767 (squash 10527b6) with your Co-authored-by credit. Thank you again @thebrownproject; the hooks.json lifecycle wrapper from this PR remains a welcome follow-up now that agent setup lives in packages/agent-setup. This PR can be closed whenever you like. |
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:
Homebrew's
gemini-cliformula is marked deprecated withbrew install --cask antigravity-clias 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
geminientry 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, notantigravity.SUPERSET_MANAGED_BINARIESderives 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 asantigravitywould generate a shim namedantigravitywhile the wrapper file was written asagy, and the two would never line up — the agent would launch unwrapped and no hook would ever fire.The alternative is adding a
binaryNamefield toDesktopAgentSetupTargetand 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/modelNameonly (camelCase, protojson). Every other agent's hook derives the event from stdin; this one can't, sohooks.jsonpasses 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.jsonthe 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
PreInvocationStartPostToolUseStartStopStopPreToolUseis deliberately not registered. Its contract requires adecisionfield (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 (PreInvocationtreatsinjectStepsas optional,PostToolUseexpects exactly{}, andStoponly blocks termination whendecisionis"continue").Testing
bun run typecheck— 35/35 tasksbun test apps/desktop/src/main/lib/agent-setup/— 79 passbun test packages/shared/src— 704 passbun run lint— exit 0New tests cover the wrapper's agent-id stamping, the
~/.gemini/configpath, 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
apps/mobile/store.config.json— happy to add if you want them in this PR.DEFAULT_V2_TERMINAL_PRESET_IDS, matching howgeminiis treated. Seeding a preset for a CLI the user hasn't installed shows a broken-looking entry.AGENT_MODEL_SUPPORTentry. Antigravity exposes--model, but the model names are display strings (e.g."Gemini 3.5 Flash (Low)") resolved per-account viaagy 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.
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 existinggeminiagent remains unchanged.New Features
agyagent with a managed wrapper, preset, and icon.~/.gemini/config/hooks.jsonunder a dedicated key; preserves other user/plugin hooks.PreInvocation/PostInvocation→Start,Stop→Stop; skipsPreToolUseandPostToolUse(the latter can fire afterStop).agy); docs updated to list the Antigravity preset and notegeminiis deprecated upstream.Bug Fixes
PostInvocation(notPostToolUse) to prevent panes from getting stuck in a “working” state.hooks.jsonwhen the existing file is unparseable or not an object, avoiding clobbering other hooks.Written for commit 2929c5b. Summary will update on new commits.
Summary by CodeRabbit
agy) as a built-in terminal agent with default presets, settings support, and a dedicated preset icon.hooks.jsonwhen it can’t be parsed.