docs: add docs for hooks + extensions (#16073)

This commit is contained in:
Abhi
2026-01-07 15:46:44 -05:00
committed by GitHub
parent 4c961df313
commit 17b3eb730a
3 changed files with 79 additions and 5 deletions

View File

@@ -263,6 +263,54 @@ Would provide these commands:
- `/deploy` - Shows as `[gcp] Custom command from deploy.toml` in help
- `/gcs:sync` - Shows as `[gcp] Custom command from sync.toml` in help
### Hooks
Extensions can provide [hooks](../hooks/index.md) to intercept and customize
Gemini CLI behavior at specific lifecycle events. Hooks provided by an extension
must be defined in a `hooks/hooks.json` file within the extension directory.
> [!IMPORTANT] Hooks are not defined directly in `gemini-extension.json`. The
> CLI specifically looks for the `hooks/hooks.json` file.
#### Directory structure
```
.gemini/extensions/my-extension/
├── gemini-extension.json
└── hooks/
└── hooks.json
```
#### `hooks/hooks.json` format
The `hooks.json` file contains a `hooks` object where keys are
[event names](../hooks/reference.md#supported-events) and values are arrays of
[hook definitions](../hooks/reference.md#hook-definition).
```json
{
"hooks": {
"before_agent": [
{
"hooks": [
{
"type": "command",
"command": "node ${extensionPath}/scripts/setup.js",
"name": "Extension Setup"
}
]
}
]
}
}
```
#### Supported variables
Just like `gemini-extension.json`, the `hooks/hooks.json` file supports
[variable substitution](#variables). This is particularly useful for referencing
scripts within the extension directory using `${extensionPath}`.
### Conflict resolution
Extension commands have the lowest precedence. When a conflict occurs with user
@@ -278,11 +326,12 @@ For example, if both a user and the `gcp` extension define a `deploy` command:
- `/gcp.deploy` - Executes the extension's deploy command (marked with `[gcp]`
tag)
## Variables
### Variables
Gemini CLI extensions allow variable substitution in `gemini-extension.json`.
This can be useful if e.g., you need the current directory to run an MCP server
using `"cwd": "${extensionPath}${/}run.ts"`.
Gemini CLI extensions allow variable substitution in both
`gemini-extension.json` and `hooks/hooks.json`. This can be useful if e.g., you
need the current directory to run an MCP server or hook script using
`"cwd": "${extensionPath}${/}run.ts"`.
**Supported variables:**
@@ -291,3 +340,4 @@ using `"cwd": "${extensionPath}${/}run.ts"`.
| `${extensionPath}` | The fully-qualified path of the extension in the user's filesystem e.g., '/Users/username/.gemini/extensions/example-extension'. This will not unwrap symlinks. |
| `${workspacePath}` | The fully-qualified path of the current workspace. |
| `${/} or ${pathSeparator}` | The path separator (differs per OS). |
| `${process.execPath}` | The path to the Node.js binary executing the CLI. |

View File

@@ -46,6 +46,11 @@ project hook (identified by its name and command), but it is **your
responsibility** to review these hooks (and any installed extensions) before
trusting them.
> [!NOTE] Extension hooks are subject to a mandatory security warning and
> consent flow during extension installation or update if hooks are detected.
> You must explicitly approve the installation or update of any extension that
> contains hooks.
See [Security Considerations](best-practices.md#using-hooks-securely) for a
detailed threat model and mitigation strategies.
@@ -444,7 +449,8 @@ numbers run first):
2. **User settings:** `~/.gemini/settings.json`
3. **System settings:** `/etc/gemini-cli/settings.json`
4. **Extensions:** Internal hooks defined by installed extensions (lowest
priority)
priority). See [Extensions documentation](../extensions/index.md#hooks) for
details on how extensions define and configure hooks.
#### Deduplication and shadowing

View File

@@ -1018,6 +1018,24 @@ const SECRET_PATTERNS = [
];
```
## Packaging as an extension
While project-level hooks are great for specific repositories, you might want to
share your hooks across multiple projects or with other users. You can do this
by packaging your hooks as a [Gemini CLI extension](../extensions/index.md).
Packaging as an extension provides:
- **Easy distribution:** Share hooks via a git repository or GitHub release.
- **Centralized management:** Install, update, and disable hooks using
`gemini extensions` commands.
- **Version control:** Manage hook versions separately from your project code.
- **Variable substitution:** Use `${extensionPath}` and `${process.execPath}`
for portable, cross-platform scripts.
To package hooks as an extension, follow the
[extensions hook documentation](../extensions/index.md#hooks).
## Learn more
- [Hooks Reference](index.md) - Complete API reference and configuration