Description
Add support for defining hooks within Gemini CLI extensions. This will allow extensions to automatically react to CLI events (like PreToolUse, PostToolUse, SessionStart) and execute commands or scripts.
Motivation
Currently, hooks can only be defined in user or project-level settings.json. This limits the shareability and reusability of powerful automation workflows. By enabling extensions to bundle hooks, we allow developers to create extensions that can:
- Enforce security policies (e.g., "prevent
rm -rf").
- Automate workflows (e.g., "run linter after
WriteFile").
- Integrate with external systems (e.g., "notify Slack on
SessionEnd").
Proposed Implementation
We will adopt a file-based convention similar to how custom commands are currently handled in extensions (commands/*.toml).
- Convention: Extensions can include a
hooks/hooks.json file.
- Structure: The JSON structure will match the existing
hooks configuration in settings.json.
- Loading: The
ExtensionManager will automatically discover and load this file when loading an extension.
- Variable Substitution: We will support
${extensionPath} in hook commands to allow referencing scripts bundled within the extension (e.g., ${extensionPath}/scripts/my-hook.sh).
- Registration: Extension hooks will be registered with
ConfigSource.Extensions priority, ensuring they integrate correctly with user and project hooks.
Example Usage
An extension my-linter-extension could have the following structure:
my-linter-extension/
├── gemini-extension.json
├── hooks/
│ └── hooks.json
└── scripts/
└── lint.sh
hooks/hooks.json:
{
"hooks": {
"PostToolUse": [
{
"matcher": "WriteFile",
"hooks": [
{
"type": "command",
"command": "${extensionPath}/scripts/lint.sh"
}
]
}
]
}
}
Description
Add support for defining hooks within Gemini CLI extensions. This will allow extensions to automatically react to CLI events (like
PreToolUse,PostToolUse,SessionStart) and execute commands or scripts.Motivation
Currently, hooks can only be defined in user or project-level
settings.json. This limits the shareability and reusability of powerful automation workflows. By enabling extensions to bundle hooks, we allow developers to create extensions that can:rm -rf").WriteFile").SessionEnd").Proposed Implementation
We will adopt a file-based convention similar to how custom commands are currently handled in extensions (
commands/*.toml).hooks/hooks.jsonfile.hooksconfiguration insettings.json.ExtensionManagerwill automatically discover and load this file when loading an extension.${extensionPath}in hook commands to allow referencing scripts bundled within the extension (e.g.,${extensionPath}/scripts/my-hook.sh).ConfigSource.Extensionspriority, ensuring they integrate correctly with user and project hooks.Example Usage
An extension
my-linter-extensioncould have the following structure:hooks/hooks.json:{ "hooks": { "PostToolUse": [ { "matcher": "WriteFile", "hooks": [ { "type": "command", "command": "${extensionPath}/scripts/lint.sh" } ] } ] } }