Skip to content

Commit cb772a5

Browse files
authored
docs(hooks): clarify mandatory 'type' field and update hook schema documentation (#17499)
1 parent dcd949b commit cb772a5

File tree

5 files changed

+77
-12
lines changed

5 files changed

+77
-12
lines changed

docs/extensions/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ The `hooks.json` file contains a `hooks` object where keys are
324324
```json
325325
{
326326
"hooks": {
327-
"before_agent": [
327+
"BeforeAgent": [
328328
{
329329
"hooks": [
330330
{

docs/hooks/best-practices.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ spawning a process for irrelevant events.
9191
"hooks": [
9292
{
9393
"name": "validate-writes",
94+
"type": "command",
9495
"command": "./validate.sh"
9596
}
9697
]
@@ -584,6 +585,7 @@ defaults to 60 seconds, but you should set stricter limits for fast hooks.
584585
"hooks": [
585586
{
586587
"name": "fast-validator",
588+
"type": "command",
587589
"command": "./hooks/validate.sh",
588590
"timeout": 5000 // 5 seconds
589591
}

docs/hooks/index.md

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,8 @@ You can filter which specific tools or triggers fire your hook using the
104104

105105
## Configuration
106106

107-
Hook definitions are configured in `settings.json`. Gemini CLI merges
108-
configurations from multiple layers in the following order of precedence
109-
(highest to lowest):
107+
Hooks are configured in `settings.json`. Gemini CLI merges configurations from
108+
multiple layers in the following order of precedence (highest to lowest):
110109

111110
1. **Project settings**: `.gemini/settings.json` in the current directory.
112111
2. **User settings**: `~/.gemini/settings.json`.
@@ -126,8 +125,7 @@ configurations from multiple layers in the following order of precedence
126125
"name": "security-check",
127126
"type": "command",
128127
"command": "$GEMINI_PROJECT_DIR/.gemini/hooks/security.sh",
129-
"timeout": 5000,
130-
"sequential": false
128+
"timeout": 5000
131129
}
132130
]
133131
}
@@ -136,6 +134,18 @@ configurations from multiple layers in the following order of precedence
136134
}
137135
```
138136

137+
#### Hook configuration fields
138+
139+
| Field | Type | Required | Description |
140+
| :------------ | :----- | :-------- | :------------------------------------------------------------------- |
141+
| `type` | string | **Yes** | The execution engine. Currently only `"command"` is supported. |
142+
| `command` | string | **Yes\*** | The shell command to execute. (Required when `type` is `"command"`). |
143+
| `name` | string | No | A friendly name for identifying the hook in logs and CLI commands. |
144+
| `timeout` | number | No | Execution timeout in milliseconds (default: 60000). |
145+
| `description` | string | No | A brief explanation of the hook's purpose. |
146+
147+
---
148+
139149
### Environment variables
140150

141151
Hooks are executed with a sanitized environment.

docs/hooks/reference.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,31 @@ including JSON schemas and API details.
1818

1919
---
2020

21+
## Configuration schema
22+
23+
Hooks are defined in `settings.json` within the `hooks` object. Each event
24+
(e.g., `BeforeTool`) contains an array of **hook definitions**.
25+
26+
### Hook definition
27+
28+
| Field | Type | Required | Description |
29+
| :----------- | :-------- | :------- | :-------------------------------------------------------------------------------------- |
30+
| `matcher` | `string` | No | A regex (for tools) or exact string (for lifecycle) to filter when the hook runs. |
31+
| `sequential` | `boolean` | No | If `true`, hooks in this group run one after another. If `false`, they run in parallel. |
32+
| `hooks` | `array` | **Yes** | An array of **hook configurations**. |
33+
34+
### Hook configuration
35+
36+
| Field | Type | Required | Description |
37+
| :------------ | :------- | :-------- | :------------------------------------------------------------------- |
38+
| `type` | `string` | **Yes** | The execution engine. Currently only `"command"` is supported. |
39+
| `command` | `string` | **Yes\*** | The shell command to execute. (Required when `type` is `"command"`). |
40+
| `name` | `string` | No | A friendly name for identifying the hook in logs and CLI commands. |
41+
| `timeout` | `number` | No | Execution timeout in milliseconds (default: 60000). |
42+
| `description` | `string` | No | A brief explanation of the hook's purpose. |
43+
44+
---
45+
2146
## Base input schema
2247

2348
All hooks receive these common fields via `stdin`:

docs/hooks/writing-hooks.md

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ main().catch((err) => {
194194
"hooks": [
195195
{
196196
"name": "intent-filter",
197+
"type": "command",
197198
"command": "node .gemini/hooks/filter-tools.js"
198199
}
199200
]
@@ -234,7 +235,13 @@ security.
234235
"SessionStart": [
235236
{
236237
"matcher": "startup",
237-
"hooks": [{ "name": "init", "command": "node .gemini/hooks/init.js" }]
238+
"hooks": [
239+
{
240+
"name": "init",
241+
"type": "command",
242+
"command": "node .gemini/hooks/init.js"
243+
}
244+
]
238245
}
239246
],
240247
"BeforeAgent": [
@@ -243,6 +250,7 @@ security.
243250
"hooks": [
244251
{
245252
"name": "memory",
253+
"type": "command",
246254
"command": "node .gemini/hooks/inject-memories.js"
247255
}
248256
]
@@ -252,39 +260,59 @@ security.
252260
{
253261
"matcher": "*",
254262
"hooks": [
255-
{ "name": "filter", "command": "node .gemini/hooks/rag-filter.js" }
263+
{
264+
"name": "filter",
265+
"type": "command",
266+
"command": "node .gemini/hooks/rag-filter.js"
267+
}
256268
]
257269
}
258270
],
259271
"BeforeTool": [
260272
{
261273
"matcher": "write_file",
262274
"hooks": [
263-
{ "name": "security", "command": "node .gemini/hooks/security.js" }
275+
{
276+
"name": "security",
277+
"type": "command",
278+
"command": "node .gemini/hooks/security.js"
279+
}
264280
]
265281
}
266282
],
267283
"AfterModel": [
268284
{
269285
"matcher": "*",
270286
"hooks": [
271-
{ "name": "record", "command": "node .gemini/hooks/record.js" }
287+
{
288+
"name": "record",
289+
"type": "command",
290+
"command": "node .gemini/hooks/record.js"
291+
}
272292
]
273293
}
274294
],
275295
"AfterAgent": [
276296
{
277297
"matcher": "*",
278298
"hooks": [
279-
{ "name": "validate", "command": "node .gemini/hooks/validate.js" }
299+
{
300+
"name": "validate",
301+
"type": "command",
302+
"command": "node .gemini/hooks/validate.js"
303+
}
280304
]
281305
}
282306
],
283307
"SessionEnd": [
284308
{
285309
"matcher": "exit",
286310
"hooks": [
287-
{ "name": "save", "command": "node .gemini/hooks/consolidate.js" }
311+
{
312+
"name": "save",
313+
"type": "command",
314+
"command": "node .gemini/hooks/consolidate.js"
315+
}
288316
]
289317
}
290318
]

0 commit comments

Comments
 (0)