Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Antigravity CLI

Antigravity (agy) is Google's successor to the Gemini CLI. tool-gates supports it through a single PreToolUse hook with its own wire format: a payload that nests the tool under toolCall, a flat {decision, reason} output, and a hooks.json keyed by hook name. This page covers what tool-gates gates on Antigravity and how the pieces map.

Selection

Antigravity is chosen by a flag, not auto-detected.

Antigravity's hook payload carries no hook_event_name, so tool-gates cannot tell it apart from Claude by inspection. The installer bakes --client antigravity into the hook command; that flag selects the wire format. Without it, an Antigravity payload would be misread as Claude.

Payload

tool-gates normalizes the Antigravity shape.

Antigravity sends a camelCase envelope where the tool lives under toolCall.name and its arguments use PascalCase keys (the command is at toolCall.args.CommandLine, a write target at toolCall.args.TargetFile). tool-gates rewrites this into its canonical internal shape so the same engine that serves Claude, Codex, and Gemini runs unchanged. The original args are preserved alongside the canonical command / file_path / content keys.

Antigravity toolMaps toCommand / path source
run_commandBashargs.CommandLine
view_fileReadargs.AbsolutePath
write_to_fileWriteargs.TargetFile + args.CodeContent
replace_file_contentEditargs.TargetFile + args.ReplacementContent
multi_replace_file_contentEditargs.TargetFile + concatenated args.ReplacementChunks[].ReplacementContent
grep_searchGrepargs.Query
find_by_nameGlobargs.Pattern

Decision

A flat decision, and "no opinion" defers to Antigravity.

The PreToolUse hook returns a flat JSON object on stdout. decision is required and is one of allow, ask, deny, or force_ask. Antigravity resolves a tool call as the strictest of all candidate decisions (rank order: allow lowest, then ask, force_ask, deny highest), so the hook can only tighten: deny/ask/force_ask win when they outrank agy's native decision, but a hook allow (the floor) never suppresses a prompt agy's own rules would show. Stopping the prompt for safe commands is done with agy's native permissions.allow list (see Allowlisting safe commands).

tool-gates resultAntigravity outputEffect
No opinionempty stdoutAntigravity's own fine-grained permission engine decides. tool-gates never speaks for a command it does not recognize. (decision is required by the schema; this relies on the currently-undocumented behavior that emitting none defers to Antigravity's engine.)
Allow (known-safe)empty stdouttool-gates recognizes the command as safe, but a hook allow is the lowest rank and inert on agy, so it emits nothing and lets agy's engine decide. The native permissions.allow list is what stops the prompt.
Ask (soft){"decision":"ask"}Prompts, respecting the user's "Always Allow" grants. Used for routine mutations and unknown commands.
Ask (hard floor){"decision":"force_ask"}Pipe-to-shell, eval, and dangerous substitution. Always prompts, ignoring any "Always Allow" grant, so the floor can never be permanently granted away.
Deny{"decision":"deny"}Hard block. Remediation text is folded into reason since the Pre output has no additionalContext field. A confirmed source-file recovery names Antigravity's native view_file tool; streamed output never receives file-reader advice.

The hard-ask safety floor maps to force_ask, not ask: pipe-to-shell and eval are ask-tier (never deny), and Antigravity's plain ask honors a prior "Always Allow" grant, which would let a granted command silently bypass the floor. force_ask always prompts. tool-gates does not emit permissionOverrides: a hook's permissionOverrides does not suppress the current call's prompt, so it would buy nothing.

Scope

One hook does the whole gate.

PreToolUse only

Antigravity also exposes PostToolUse, PreInvocation, PostInvocation, and Stop, but its post payload carries no tool name or input and it has no PermissionRequest event. The single PreToolUse hook is the entire gate.

Named-hook hooks.json

Antigravity's hooks.json is a top-level object keyed by hook name, so tool-gates owns one entry, tool-gates, and leaves any other named hooks untouched: {"tool-gates": {"PreToolUse": [...]}}.

Secrets and file guards

Write content arrives in the PreToolUse args, so Tier 1 secret scanning runs on the write before it lands. File guards apply on both reads (view_file) and writes for symlinked AI-config files.

MCP not wired yet

Antigravity's MCP tool-name format for hook matchers is not documented, so MCP block rules are not yet applied for Antigravity. Shell, file, grep, and glob tools are all gated.

Install

~/.gemini/config/hooks.json
# shared user/global path (recommended, default)
$ tool-gates hooks add --antigravity
# preview without writing
$ tool-gates hooks add --antigravity --dry-run
# project scope
$ tool-gates hooks add --antigravity -s project

Antigravity user hooks live at ~/.gemini/config/hooks.json, which is the installer default and the path shared by the CLI backend. Project hooks live at .agents/hooks.json and are available with -s project. The matcher covers run_command, view_file, write_to_file, replace_file_content, multi_replace_file_content, grep_search, and find_by_name.

Plugin-packaged hooks are useful for distribution, but they are not required for hook installs. Treat plugin support as a separate global-install path that should be verified with agy plugin validate and a deny probe before relying on it.

Confirm with tool-gates hooks status, which lists the Antigravity shared user and project hook paths alongside the other clients.

Allowlisting safe commands

~/.gemini/antigravity-cli/settings.json
# print a permissions.allow block for safe commands
$ tool-gates agy allowlist
# merge it into agy's settings (backs up first), then restart agy
$ tool-gates agy allowlist --apply
# preview the merge without writing
$ tool-gates agy allowlist --apply --dry-run

Because a hook allow is inert, the only thing that stops Antigravity prompting for a read-only command is its native permissions.allow list in ~/.gemini/antigravity-cli/settings.json (a different file from the hooks path). tool-gates agy allowlist generates that list from tool-gates' own unconditionally-safe command set, one command(<prog>) rule per program (command(rg), command(cat), command(jq), …).

The tool-gates hook still runs on every call and tightens (deny/ask/force_ask) over any dangerous form, so a native command(find) does not let find . -delete through: the hook asks and the stricter decision wins. Interpreters (bash/sh/zsh), curl, and conditionally-gated programs are excluded from the list. Antigravity reads settings at startup, so restart agy after applying.

tool-gates · permission gate hook for Claude Code, Codex CLI, and Antigravity CLI, with deprecated Gemini CLI support. github.com/camjac251/tool-gates

13 gates · 400+ commands · built from rules/*.toml