Overview
Hooks are scripts or programs that execute at specific points in the Gemini CLI lifecycle, allowing you to intercept and customize behavior without modifying the CLI source code. Hooks run synchronously—when a hook event fires, Gemini CLI waits for all matching hooks to complete before continuing.Hook Events
Hooks are triggered by specific lifecycle events.SessionStart
When: Session begins (startup, resume, or clear) Use Cases: Initialize resources, load context, set up environment Input Schema:Unique identifier for the session
Path to the conversation transcript file
Current working directory
Event name:
"SessionStart"ISO 8601 timestamp
Session start trigger:
"startup", "resume", or "clear"If
false, stops execution with error message from stopReasonError message shown if
continue is falseAdvisory message displayed to user
SessionEnd
When: Session ends (exit or clear) Use Cases: Clean up resources, save state, log summary Input Schema: Same base fields as SessionStart, plus:Session end trigger:
"exit" or "clear"BeforeAgent
When: After user submits prompt, before agent planning begins Use Cases: Add context, validate prompts, block turns Input Schema:The user’s prompt text
Array of conversation turns (formatted for LLM)
If
false, blocks the turnContext to inject into the model’s prompt (sanitized for safety)
Message displayed to the user
AfterAgent
When: When agent loop completes Use Cases: Review output, force retry, halt execution Input Schema:The agent’s final response text
If
false, halts executionIf
true, forces the agent to retryReason for retry (added to context)
Advisory message
BeforeModel
When: Before sending request to LLM Use Cases: Modify prompts, swap models, mock responses Input Schema:If
false, blocks the LLM requestModified LLM request (replaces original if provided)
Mock LLM response (skips actual LLM call if provided)
AfterModel
When: After receiving LLM response Use Cases: Filter/redact responses, log interactions Input Schema:The request that was sent
If
false, blocks the responseModified response (replaces original if provided)
If
true, indicates content was redactedBeforeToolSelection
When: Before LLM selects tools Use Cases: Filter available tools, optimize selection Input Schema:Array of tool declarations
Tool configuration (mode, allowed functions)
Modified tools list (filters available tools)
BeforeTool
When: Before a tool executes Use Cases: Validate arguments, block dangerous operations Matcher: Regular expression matching tool names (e.g.,"write_.*", "shell_tool")
Input Schema:
Name of the tool being called
Tool arguments as key-value pairs
Human-readable description of what the tool will do
Tool execution decision:
"allow"or"approve"- Proceed without confirmation"ask"- Request user confirmation"block"or"deny"- Block execution
Reason for the decision (shown to user)
Modified tool arguments (replaces original if provided)
AfterTool
When: After a tool executes Use Cases: Process results, run tests, hide sensitive output Matcher: Regular expression matching tool names Input Schema:Name of the tool that executed
Arguments that were passed
Result handling decision:
"allow"- Use the result as-is"block"- Hide result from LLM and user
Modified tool result (replaces original if provided)
Additional context to inject after the tool result
If
true, hides output from user (but sends to LLM)PreCompress
When: Before context compression Use Cases: Save state, notify user Input Schema:Current context size in tokens
Maximum context size
Notification
When: System notification occurs Use Cases: Forward to desktop alerts, logging Matcher: Exact string matching notification types (e.g.,"error", "warning", "info")
Input Schema:
Notification category
Notification message
Additional notification details
Hook Configuration
HookConfig
Defines a single hook implementation.Command Hook
Hook type (command-based hook)
Shell command to execute. Use
$GEMINI_PROJECT_DIR and other environment variables.Friendly name for logs and CLI commands
Brief explanation of the hook’s purpose
Execution timeout in milliseconds (default: 60000)
Additional environment variables
Runtime Hook
Hook type (programmatic hook)
Unique identifier for the runtime hook
Function to execute when hook is triggered
HookDefinition
Groups hooks by matcher and execution strategy.Filter pattern:
- Tool events: Regular expression (e.g.,
"write_.*","shell_.*") - Lifecycle events: Exact string (e.g.,
"startup","error") - Wildcard:
"*"or empty string matches all
If
true, hooks run sequentially. If false (default), hooks run in parallel.Array of hook configurations to execute
Configuration Example
Exit Codes
Gemini CLI uses exit codes to determine hook execution outcomes:Preferred code for all logic. The
stdout is parsed as JSON. Use this even for intentional blocks (set {"decision": "deny"} in output).Critical block. The target action (tool, turn, or stop) is aborted.
stderr is used as the rejection reason. High severity for security stops or script failures.Non-fatal failure. A warning is shown, but execution proceeds using original parameters.
Environment Variables
Hooks execute with these environment variables:Absolute path to the project root
Unique ID for the current session
Current working directory
Alias for
GEMINI_PROJECT_DIR (compatibility)JSON Communication
The Golden Rule
Your hook script MUST NOT print any text tostdout except the final JSON object.
Input (stdin)
JSON object with event-specific fields:Output (stdout)
JSON object with decision and context:Hook Examples
Block Dangerous Commands
Inject Git Context
Validate File Paths
Run Tests After Tool
Mock LLM Response
Managing Hooks
Use CLI commands to manage hooks:Security Considerations
Hook Trust System
Gemini CLI fingerprints project hooks. If a hook’s name or command changes (e.g., viagit pull), it’s treated as a new, untrusted hook and you’ll be warned before it executes.
Best Practices
- Review project hooks before trusting them
- Use user-level hooks for personal automation
- Validate all inputs in hook scripts
- Log hook activity for auditing
- Set appropriate timeouts to prevent hangs
- Use stderr for debugging to avoid breaking JSON output
- Test hooks thoroughly before deploying to teams
Configuration Sources
Hooks are merged from multiple layers in precedence order (highest to lowest):- Project settings -
.gemini/settings.jsonin current directory - User settings -
~/.gemini/settings.json - System settings -
/etc/gemini-cli/settings.json - Extensions - Hooks from installed extensions