Skip to content

Hooks allow you to run custom scripts or shell commands at specific points during Antigravity’s execution loop. This is powerful for enforcing custom rules, running linters, or capturing diagnostics automatically.

Hooks are configured in a hooks.json file located in your customization directory (e.g., .agents/ in your workspace or ~/.gemini/config/).

The hooks.json file maps hook names to their event configurations.

{
  "my-linter-hook": {
    "PostToolUse": [
      {
        "matcher": "run_command",
        "hooks": [
          {
            "type": "command",
            "command": "./scripts/lint.sh",
            "timeout": 10
          }
        ]
      }
    ]
  },
  "safety-gate": {
    "enabled": false,
    "PreToolUse": [
      {
        "matcher": "run_command",
        "hooks": [
          {
            "command": "./scripts/safety-check.sh"
          }
        ]
      }
    ]
  },
  "reminder": {
    "PreInvocation": [
      {
        "type": "command",
        "command": "./scripts/reminder.sh"
      }
    ]
  }
}
FieldTypeDescription
enabledbooleanOptional. Set to false to disable the hook without removing it. Defaults to true.
PreToolUsearrayHandlers that run before a tool is executed.
PostToolUsearrayHandlers that run after a tool completes.
PreInvocationarrayHandlers that run before Antigravity calls the model.
PostInvocationarrayHandlers that run immediately after each model invocation completes.
StoparrayHandlers that run when the execution loop terminates.
EventDescriptionMatcher Target
PreToolUseFires before a tool is executed.Tool name (e.g., run_command)
PostToolUseFires after a tool completes.Tool name
PreInvocationFires before the model is called.N/A (matcher ignored)
PostInvocationFires immediately after each model invocation completes.N/A (matcher ignored)
StopFires when execution terminates.N/A (matcher ignored)

For PreToolUse and PostToolUse, you can use a regular expression in the matcher field to specify which tools trigger the hook:

  • "" or "*": Match all tools.
  • "run_command": Match exactly run_command.
  • "run_command|view_file": Match either tool.
  • "browser_.*": Match any tool starting with browser_.

For PreToolUse and PostToolUse matchers, you can match against standard tool names, grouped by category:

  • view_file: View the contents of a file.
    • Arguments: AbsolutePath, StartLine (optional), EndLine (optional), IsSkillFile (optional)
  • write_to_file: Create new files.
    • Arguments: TargetFile, Overwrite, CodeContent, Description, IsArtifact (optional), ArtifactMetadata (optional)
  • replace_file_content: Edit a single contiguous block of text in a file.
    • Arguments: TargetFile, Instruction, Description, AllowMultiple, TargetContent, ReplacementContent, StartLine, EndLine, TargetLintErrorIds (optional)
  • multi_replace_file_content: Make multiple, non-contiguous edits to the same file.
    • Arguments: TargetFile, Instruction, Description, ReplacementChunks (array of chunks), TargetLintErrorIds (optional), ArtifactMetadata (optional)
  • list_dir: List the contents of a directory.
    • Arguments: DirectoryPath
  • find_by_name: Search for files and directories using glob patterns.
    • Arguments: SearchDirectory, Pattern, Type (optional), Excludes (optional), Extensions (optional), FullPath (optional), MaxDepth (optional)
  • grep_search: Fast text searches within specific paths.
    • Arguments: SearchPath, Query, IsRegex (optional), CaseInsensitive (optional), Includes (optional), MatchPerLine (optional)
  • search_web: Perform a general web search.
    • Arguments: query, domain (optional)
  • read_url_content: Fetch text content of a public URL.
    • Arguments: Url
  • run_command: Propose a bash command to run.
    • Arguments: CommandLine, Cwd, WaitMsBeforeAsync, RunPersistent (optional), RequestedTerminalID (optional)
  • manage_task: Interact with background tasks.
    • Arguments: Action ('list', 'kill', 'status', 'send_input'), TaskId (optional), Input (optional)
  • schedule: Set timers or recurring cron jobs.
    • Arguments: DurationSeconds (optional), CronExpression (optional), MaxIterations (optional), Prompt
  • list_permissions: View current resource access grants.
    • Arguments: None
  • ask_permission: Request additional scoped permissions.
    • Arguments: Action, Target, Reason
  • invoke_subagent: Spawn specialized sub-agents.
    • Arguments: Subagents (array of specs with Prompt, Role, TypeName, Workspace (optional))
  • define_subagent: Create a custom sub-agent.
    • Arguments: name, description, system_prompt, enable_mcp_tools (optional), enable_write_tools (optional), enable_subagent_tools (optional)
  • send_message: Communicate with other agents.
    • Arguments: Recipient, Message
  • manage_subagents: List or terminate active sub-agents.
    • Arguments: Action ('list', 'kill', 'kill_all'), ConversationIds (optional)
  • ask_question: Ask multiple-choice questions.
    • Arguments: questions (array of questions with question, options, is_multi_select)
  • generate_image: Create or edit images.
    • Arguments: Prompt, ImageName, ImagePaths (optional)

Each item in the hooks array supports:

FieldTypeDescription
typestringOptional. Currently only "command" is supported. Defaults to "command".
commandstringRequired. The shell command to execute.
timeoutintegerOptional. Timeout in seconds. Defaults to 30.

Hooks receive input via stdin as JSON and should return output via stdout as JSON. Field names use camelCase.

All hooks receive the following system metadata fields in their input payload on stdin:

FieldTypeDescription
conversationIdstringThe unique UUID of the active agent conversation.
workspacePathsarray of stringsAbsolute directory paths representing the user’s mounted workspaces.
transcriptPathstringThe absolute path to the persistent transcript.jsonl conversation logs.
Note: This file lives in: <app_data_dir>/brain/<conversationId>/.system_generated/logs/transcript.jsonl where <app_data_dir> is:
  • ~/.gemini/antigravity for Antigravity 2.0
  • ~/.gemini/antigravity-cli for CLI
artifactDirectoryPathstringThe absolute path to the directory containing all conversation artifacts and screenshots.
modelNamestringThe name/identifier of the model handling the invocation (e.g., gemini-3.6-flash-medium).

Fires before a tool is executed.

Schema

Input Fields (stdin):

FieldTypeDescription
toolCallobjectDetails of the proposed tool call.
toolCall.namestringThe name of the tool being executed (e.g., run_command).
toolCall.argsobjectArguments passed to the tool call.
stepIdxintegerThe 0-based index of the current step in the trajectory.
(Common Fields)Includes conversationId, workspacePaths, transcriptPath, artifactDirectoryPath, modelName.

Output Fields (stdout):

FieldTypeDescription
decisionstringRequired. Controls how the tool call is gated:
- "allow": Automatically allows the tool execution.
- "deny": Hard blocks execution immediately.
- "ask": Prompts the user, but respects “Always Allow” settings.
- "force_ask": Always prompts the user, ignoring cached permissions.
- "deny_unless_prior_grant": Denies execution unless the resource was previously approved in a prior user grant.
reasonstringOptional. The explanation shown to the agent or user for the decision.
permissionOverridesarray of stringsOptional. A list of resource strings (e.g. ["read_file(/path)", "command(args)"]) to override default tool permissions.

Example

  • Input (stdin):
{
  "toolCall": {
    "name": "run_command",
    "args": {
      "CommandLine": "npm test",
      "Cwd": "/workspace/project",
      "WaitMsBeforeAsync": 5000
    }
  },
  "stepIdx": 19,
  "conversationId": "ec33ebf9-0cba-4100-8142-c61503f6c587",
  "workspacePaths": ["/workspace/project"],
  "transcriptPath": "~/.gemini/antigravity/brain/ec33ebf9-0cba-4100-8142-c61503f6c587/.system_generated/logs/transcript.jsonl",
  "artifactDirectoryPath": "~/.gemini/antigravity/brain/ec33ebf9-0cba-4100-8142-c61503f6c587",
  "modelName": "gemini-3.6-flash-medium"
}
  • Output (stdout):
{
  "decision": "ask",
  "reason": "Requires confirmation for test execution.",
  "permissionOverrides": ["command(npm test)"]
}

Fires after a tool completes.

Schema

Input Fields (stdin):

FieldTypeDescription
toolCallobjectDetails of the executed tool call (name and args).
stepIdxintegerThe 0-based index of the completed step.
errorstringOptional. The detailed runtime error message if the tool call failed. Empty if successful.
(Common Fields)Includes conversationId, workspacePaths, transcriptPath, artifactDirectoryPath, modelName.

Output Fields (stdout): Returns an empty JSON object {}.

Example

  • Input (stdin):
{
  "toolCall": {
    "name": "run_command",
    "args": {
      "CommandLine": "npm test",
      "Cwd": "/workspace/project",
      "WaitMsBeforeAsync": 5000
    }
  },
  "stepIdx": 5,
  "error": "exit status 1",
  "conversationId": "ec33ebf9-0cba-4100-8142-c61503f6c587",
  "workspacePaths": ["/workspace/project"],
  "transcriptPath": "~/.gemini/antigravity/brain/ec33ebf9-0cba-4100-8142-c61503f6c587/.system_generated/logs/transcript.jsonl",
  "artifactDirectoryPath": "~/.gemini/antigravity/brain/ec33ebf9-0cba-4100-8142-c61503f6c587",
  "modelName": "gemini-3.6-flash-medium"
}
  • Output (stdout): {}

Fires before the model is called.

Schema

Input Fields (stdin):

FieldTypeDescription
invocationNumintegerThe 0-indexed sequence number of the current model invocation (the first invocation is 0).
initialNumStepsintegerThe number of steps currently in the trajectory.
(Common Fields)Includes conversationId, workspacePaths, transcriptPath, artifactDirectoryPath, modelName.

Output Fields (stdout):

FieldTypeDescription
injectStepsarray of objectsOptional. List of steps to inject into the conversation trajectory before the model is called.

Injected Step Schema: Each object in the injectSteps array can have one of the following fields:

  • toolCall (object): A tool call to execute.
  • userMessage (string): A message from the user.
  • ephemeralMessage (string): A transient system message.

Example

  • Input (stdin):
{
  "invocationNum": 3,
  "initialNumSteps": 10,
  "conversationId": "ec33ebf9-0cba-4100-8142-c61503f6c587",
  "workspacePaths": ["/workspace/project"],
  "transcriptPath": "~/.gemini/antigravity/brain/ec33ebf9-0cba-4100-8142-c61503f6c587/.system_generated/logs/transcript.jsonl",
  "artifactDirectoryPath": "~/.gemini/antigravity/brain/ec33ebf9-0cba-4100-8142-c61503f6c587",
  "modelName": "gemini-3.6-flash-medium"
}
  • Output (stdout):
{
  "injectSteps": [{"ephemeralMessage": "Remember to lint"}]
}

Fires immediately after each model invocation completes.

Schema

Input Fields (stdin): Same as PreInvocation input fields (invocationNum and initialNumSteps).

Output Fields (stdout):

FieldTypeDescription
injectStepsarray of objectsOptional. List of steps to inject after the invocation completes (same schema as PreInvocation inject steps).
terminationBehaviorstringOptional. Controls the execution flow after injection:
- "force_continue": Forces the loop to continue.
- "terminate": Forces the loop to terminate.
- "" (or omitted): Default behavior.

Example

  • Input (stdin): Same as PreInvocation
  • Output (stdout):
{
  "injectSteps": [],
  "terminationBehavior": ""
}

Fires when the execution loop terminates.

Schema

Input Fields (stdin):

FieldTypeDescription
executionNumintegerThe sequence number of the execution attempt.
terminationReasonstringThe reason why the execution is stopping (e.g., "model_stop", "max_steps_exceeded", "error").
errorstringOptional. The error message if termination was caused by a system error.
fullyIdlebooleanRequired. true if the agent is completely finished and all background commands or asynchronous tasks have completed. false if active background tasks are still running.
(Common Fields)Includes conversationId, workspacePaths, transcriptPath, artifactDirectoryPath, modelName.

Output Fields (stdout):

FieldTypeDescription
decisionstringRequired. Set to "continue" to prevent the agent from stopping and re-enter the execution loop. Any other value allows the stop.
reasonstringOptional. If decision is "continue", this message is injected as a system message into the conversation.

Example

  • Input (stdin):
{
  "executionNum": 1,
  "terminationReason": "model_stop",
  "error": "",
  "fullyIdle": true,
  "conversationId": "ec33ebf9-0cba-4100-8142-c61503f6c587",
  "workspacePaths": ["/workspace/project"],
  "transcriptPath": "~/.gemini/antigravity/brain/ec33ebf9-0cba-4100-8142-c61503f6c587/.system_generated/logs/transcript.jsonl",
  "artifactDirectoryPath": "~/.gemini/antigravity/brain/ec33ebf9-0cba-4100-8142-c61503f6c587",
  "modelName": "gemini-3.6-flash-medium"
}
  • Output (stdout):
{
  "decision": "continue",
  "reason": "Not done yet"
}