diff --git a/docs/extensions/index.md b/docs/extensions/index.md index 8f71d1c184..a2b0598388 100644 --- a/docs/extensions/index.md +++ b/docs/extensions/index.md @@ -324,7 +324,7 @@ The `hooks.json` file contains a `hooks` object where keys are ```json { "hooks": { - "before_agent": [ + "BeforeAgent": [ { "hooks": [ { diff --git a/docs/hooks/best-practices.md b/docs/hooks/best-practices.md index 559f3f18bb..316aacbc29 100644 --- a/docs/hooks/best-practices.md +++ b/docs/hooks/best-practices.md @@ -91,6 +91,7 @@ spawning a process for irrelevant events. "hooks": [ { "name": "validate-writes", + "type": "command", "command": "./validate.sh" } ] @@ -584,6 +585,7 @@ defaults to 60 seconds, but you should set stricter limits for fast hooks. "hooks": [ { "name": "fast-validator", + "type": "command", "command": "./hooks/validate.sh", "timeout": 5000 // 5 seconds } diff --git a/docs/hooks/index.md b/docs/hooks/index.md index 24c843128a..dc1c036ade 100644 --- a/docs/hooks/index.md +++ b/docs/hooks/index.md @@ -104,9 +104,8 @@ You can filter which specific tools or triggers fire your hook using the ## Configuration -Hook definitions are configured in `settings.json`. Gemini CLI merges -configurations from multiple layers in the following order of precedence -(highest to lowest): +Hooks are configured in `settings.json`. Gemini CLI merges configurations from +multiple layers in the following order of precedence (highest to lowest): 1. **Project settings**: `.gemini/settings.json` in the current directory. 2. **User settings**: `~/.gemini/settings.json`. @@ -126,8 +125,7 @@ configurations from multiple layers in the following order of precedence "name": "security-check", "type": "command", "command": "$GEMINI_PROJECT_DIR/.gemini/hooks/security.sh", - "timeout": 5000, - "sequential": false + "timeout": 5000 } ] } @@ -136,6 +134,18 @@ configurations from multiple layers in the following order of precedence } ``` +#### Hook configuration fields + +| Field | Type | Required | Description | +| :------------ | :----- | :-------- | :------------------------------------------------------------------- | +| `type` | string | **Yes** | The execution engine. Currently only `"command"` is supported. | +| `command` | string | **Yes\*** | The shell command to execute. (Required when `type` is `"command"`). | +| `name` | string | No | A friendly name for identifying the hook in logs and CLI commands. | +| `timeout` | number | No | Execution timeout in milliseconds (default: 60000). | +| `description` | string | No | A brief explanation of the hook's purpose. | + +--- + ### Environment variables Hooks are executed with a sanitized environment. diff --git a/docs/hooks/reference.md b/docs/hooks/reference.md index 2feeedf940..a86474ea85 100644 --- a/docs/hooks/reference.md +++ b/docs/hooks/reference.md @@ -18,6 +18,31 @@ including JSON schemas and API details. --- +## Configuration schema + +Hooks are defined in `settings.json` within the `hooks` object. Each event +(e.g., `BeforeTool`) contains an array of **hook definitions**. + +### Hook definition + +| Field | Type | Required | Description | +| :----------- | :-------- | :------- | :-------------------------------------------------------------------------------------- | +| `matcher` | `string` | No | A regex (for tools) or exact string (for lifecycle) to filter when the hook runs. | +| `sequential` | `boolean` | No | If `true`, hooks in this group run one after another. If `false`, they run in parallel. | +| `hooks` | `array` | **Yes** | An array of **hook configurations**. | + +### Hook configuration + +| Field | Type | Required | Description | +| :------------ | :------- | :-------- | :------------------------------------------------------------------- | +| `type` | `string` | **Yes** | The execution engine. Currently only `"command"` is supported. | +| `command` | `string` | **Yes\*** | The shell command to execute. (Required when `type` is `"command"`). | +| `name` | `string` | No | A friendly name for identifying the hook in logs and CLI commands. | +| `timeout` | `number` | No | Execution timeout in milliseconds (default: 60000). | +| `description` | `string` | No | A brief explanation of the hook's purpose. | + +--- + ## Base input schema All hooks receive these common fields via `stdin`: diff --git a/docs/hooks/writing-hooks.md b/docs/hooks/writing-hooks.md index 7b66a90a65..33357fccb2 100644 --- a/docs/hooks/writing-hooks.md +++ b/docs/hooks/writing-hooks.md @@ -194,6 +194,7 @@ main().catch((err) => { "hooks": [ { "name": "intent-filter", + "type": "command", "command": "node .gemini/hooks/filter-tools.js" } ] @@ -234,7 +235,13 @@ security. "SessionStart": [ { "matcher": "startup", - "hooks": [{ "name": "init", "command": "node .gemini/hooks/init.js" }] + "hooks": [ + { + "name": "init", + "type": "command", + "command": "node .gemini/hooks/init.js" + } + ] } ], "BeforeAgent": [ @@ -243,6 +250,7 @@ security. "hooks": [ { "name": "memory", + "type": "command", "command": "node .gemini/hooks/inject-memories.js" } ] @@ -252,7 +260,11 @@ security. { "matcher": "*", "hooks": [ - { "name": "filter", "command": "node .gemini/hooks/rag-filter.js" } + { + "name": "filter", + "type": "command", + "command": "node .gemini/hooks/rag-filter.js" + } ] } ], @@ -260,7 +272,11 @@ security. { "matcher": "write_file", "hooks": [ - { "name": "security", "command": "node .gemini/hooks/security.js" } + { + "name": "security", + "type": "command", + "command": "node .gemini/hooks/security.js" + } ] } ], @@ -268,7 +284,11 @@ security. { "matcher": "*", "hooks": [ - { "name": "record", "command": "node .gemini/hooks/record.js" } + { + "name": "record", + "type": "command", + "command": "node .gemini/hooks/record.js" + } ] } ], @@ -276,7 +296,11 @@ security. { "matcher": "*", "hooks": [ - { "name": "validate", "command": "node .gemini/hooks/validate.js" } + { + "name": "validate", + "type": "command", + "command": "node .gemini/hooks/validate.js" + } ] } ], @@ -284,7 +308,11 @@ security. { "matcher": "exit", "hooks": [ - { "name": "save", "command": "node .gemini/hooks/consolidate.js" } + { + "name": "save", + "type": "command", + "command": "node .gemini/hooks/consolidate.js" + } ] } ]