The Gemini Command Line Interface (CLI) is a powerful tool, and with the introduction of its "hooks" feature, users can now significantly extend and customise its behaviour without ever touching the core source code.
Hooks are essentially scripts or programs that the Gemini CLI executes at specific, predefined points within its agentic loop, offering unparalleled control and flexibility.
Use Cases
Imagine being able to inject crucial context before your AI model even sees a request, validate potentially risky actions before they execute, or even enforce company-wide compliance policies directly within your development workflow. This is precisely the power that Gemini CLI hooks bring to the table. By running synchronously as part of the agent loop, hooks ensure that the CLI waits for their completion before proceeding, guaranteeing that your custom logic is always applied.
Getting Started
Hooks communicate with the CLI via strict JSON requirements over stdin and stdout – the "Golden Rule" dictates that your script must only print the final JSON object to stdout, reserving stderr for all debugging and logging. Exit codes play a crucial role, with 0 signifying success and allowing stdout to be parsed, while 2 indicates a "System Block," aborting the target action and using stderr as the rejection reason. Hooks can also be selectively triggered using "matchers," which are regular expressions for tool events and exact strings for lifecycle events.
Real Case Scenario
Consider a scenario where you want to prevent the delete_file tool from being executed if a specific environment variable isn't set. You could configure an hook with a matcher for delete_file. This hook script would check for the environment variable. If it's missing, the script would print a JSON object like {"decision": "deny", "reason": "Environment variable 'ALLOW_DELETIONS' not set."} to stdout and exit with code 0. The Gemini CLI would then parse this and block the delete operation.
Configuration
Here is the official announcement with all the possibile configurations.
The configuration is handled in settings.json, with a clear hierarchy of precedence from project to system settings. This allows for granular control, from project-specific security checks to global compliance policies. The configuration schema defines fields like type (currently only "command" is supported), the command to execute, a friendly name, and an optional timeout.
e.g.
{
"hooks": {
"BeforeTool": [
{
"matcher": "write_file|replace",
"hooks": [
{
"name": "security-check",
"type": "command",
"command": "$GEMINI_PROJECT_DIR/.gemini/hooks/security.sh",
"timeout": 5000
}
]
}
]
}
}
Hooks execute arbitrary code with your user privileges. Therefore, caution is advised, especially with project-level hooks in untrusted projects.
Mastering these hooks means gaining control over your AI interactions, ensuring that the Gemini CLI operates exactly as you intend, securely and efficiently, across all your projects.
You can follow me on GitHub, where I'm creating cool projects.
I hope you enjoyed this article, until next time 👋
Top comments (0)