@google/gemini-cli-core 0.26.0-preview.4 → 0.27.0-nightly.20260126.cb772a5b7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (325) hide show
  1. package/README.md +18 -1
  2. package/dist/docs/changelogs/index.md +87 -0
  3. package/dist/docs/changelogs/latest.md +355 -150
  4. package/dist/docs/changelogs/preview.md +318 -210
  5. package/dist/docs/cli/commands.md +0 -6
  6. package/dist/docs/cli/keyboard-shortcuts.md +32 -31
  7. package/dist/docs/cli/settings.md +16 -18
  8. package/dist/docs/cli/system-prompt.md +32 -0
  9. package/dist/docs/cli/uninstall.md +18 -0
  10. package/dist/docs/extensions/index.md +1 -1
  11. package/dist/docs/get-started/configuration.md +9 -34
  12. package/dist/docs/hooks/best-practices.md +219 -398
  13. package/dist/docs/hooks/index.md +111 -656
  14. package/dist/docs/hooks/reference.md +280 -136
  15. package/dist/docs/hooks/writing-hooks.md +202 -796
  16. package/dist/docs/sidebar.json +1 -5
  17. package/dist/docs/tools/mcp-server.md +24 -1
  18. package/dist/google-gemini-cli-core-0.27.0-nightly.20260121.97aac696f.tgz +0 -0
  19. package/dist/src/agents/agentLoader.js +10 -10
  20. package/dist/src/agents/agentLoader.js.map +1 -1
  21. package/dist/src/agents/agentLoader.test.js +16 -19
  22. package/dist/src/agents/agentLoader.test.js.map +1 -1
  23. package/dist/src/agents/cli-help-agent.js +8 -5
  24. package/dist/src/agents/cli-help-agent.js.map +1 -1
  25. package/dist/src/agents/cli-help-agent.test.js +4 -2
  26. package/dist/src/agents/cli-help-agent.test.js.map +1 -1
  27. package/dist/src/agents/codebase-investigator.d.ts +2 -1
  28. package/dist/src/agents/codebase-investigator.js +62 -41
  29. package/dist/src/agents/codebase-investigator.js.map +1 -1
  30. package/dist/src/agents/codebase-investigator.test.js +15 -8
  31. package/dist/src/agents/codebase-investigator.test.js.map +1 -1
  32. package/dist/src/agents/generalist-agent.js +9 -11
  33. package/dist/src/agents/generalist-agent.js.map +1 -1
  34. package/dist/src/agents/generalist-agent.test.js +3 -3
  35. package/dist/src/agents/generalist-agent.test.js.map +1 -1
  36. package/dist/src/agents/local-executor.js +25 -9
  37. package/dist/src/agents/local-executor.js.map +1 -1
  38. package/dist/src/agents/local-executor.test.js +74 -7
  39. package/dist/src/agents/local-executor.test.js.map +1 -1
  40. package/dist/src/agents/local-invocation.test.js +7 -3
  41. package/dist/src/agents/local-invocation.test.js.map +1 -1
  42. package/dist/src/agents/registry.d.ts +8 -5
  43. package/dist/src/agents/registry.js +31 -75
  44. package/dist/src/agents/registry.js.map +1 -1
  45. package/dist/src/agents/registry.test.js +93 -30
  46. package/dist/src/agents/registry.test.js.map +1 -1
  47. package/dist/src/agents/remote-invocation.js +2 -1
  48. package/dist/src/agents/remote-invocation.js.map +1 -1
  49. package/dist/src/agents/remote-invocation.test.js +15 -3
  50. package/dist/src/agents/remote-invocation.test.js.map +1 -1
  51. package/dist/src/agents/subagent-tool-wrapper.js +1 -3
  52. package/dist/src/agents/subagent-tool-wrapper.js.map +1 -1
  53. package/dist/src/agents/subagent-tool-wrapper.test.js +10 -25
  54. package/dist/src/agents/subagent-tool-wrapper.test.js.map +1 -1
  55. package/dist/src/agents/subagent-tool.d.ts +15 -0
  56. package/dist/src/agents/subagent-tool.js +61 -0
  57. package/dist/src/agents/subagent-tool.js.map +1 -0
  58. package/dist/src/agents/types.d.ts +6 -9
  59. package/dist/src/agents/types.js +4 -0
  60. package/dist/src/agents/types.js.map +1 -1
  61. package/dist/src/code_assist/codeAssist.js +1 -1
  62. package/dist/src/code_assist/codeAssist.js.map +1 -1
  63. package/dist/src/code_assist/codeAssist.test.js +2 -2
  64. package/dist/src/code_assist/codeAssist.test.js.map +1 -1
  65. package/dist/src/code_assist/experiments/experiments.test.js +1 -0
  66. package/dist/src/code_assist/experiments/experiments.test.js.map +1 -1
  67. package/dist/src/code_assist/experiments/experiments_local.test.js +11 -6
  68. package/dist/src/code_assist/experiments/experiments_local.test.js.map +1 -1
  69. package/dist/src/code_assist/experiments/flagNames.d.ts +2 -0
  70. package/dist/src/code_assist/experiments/flagNames.js +2 -0
  71. package/dist/src/code_assist/experiments/flagNames.js.map +1 -1
  72. package/dist/src/code_assist/oauth2.js +3 -3
  73. package/dist/src/code_assist/oauth2.test.js +1 -1
  74. package/dist/src/code_assist/server.d.ts +2 -1
  75. package/dist/src/code_assist/server.js +3 -1
  76. package/dist/src/code_assist/server.js.map +1 -1
  77. package/dist/src/code_assist/setup.d.ts +1 -0
  78. package/dist/src/code_assist/setup.js +5 -1
  79. package/dist/src/code_assist/setup.js.map +1 -1
  80. package/dist/src/code_assist/setup.test.js +10 -4
  81. package/dist/src/code_assist/setup.test.js.map +1 -1
  82. package/dist/src/config/config.d.ts +25 -18
  83. package/dist/src/config/config.js +70 -40
  84. package/dist/src/config/config.js.map +1 -1
  85. package/dist/src/config/config.test.js +48 -21
  86. package/dist/src/config/config.test.js.map +1 -1
  87. package/dist/src/confirmation-bus/message-bus.js +2 -32
  88. package/dist/src/confirmation-bus/message-bus.js.map +1 -1
  89. package/dist/src/confirmation-bus/types.d.ts +35 -21
  90. package/dist/src/confirmation-bus/types.js +8 -3
  91. package/dist/src/confirmation-bus/types.js.map +1 -1
  92. package/dist/src/core/client.js +25 -7
  93. package/dist/src/core/client.js.map +1 -1
  94. package/dist/src/core/client.test.js +52 -6
  95. package/dist/src/core/client.test.js.map +1 -1
  96. package/dist/src/core/contentGenerator.d.ts +1 -0
  97. package/dist/src/core/contentGenerator.js.map +1 -1
  98. package/dist/src/core/coreToolHookTriggers.d.ts +2 -38
  99. package/dist/src/core/coreToolHookTriggers.js +12 -159
  100. package/dist/src/core/coreToolHookTriggers.js.map +1 -1
  101. package/dist/src/core/coreToolHookTriggers.test.js +62 -94
  102. package/dist/src/core/coreToolHookTriggers.test.js.map +1 -1
  103. package/dist/src/core/coreToolScheduler.js +3 -5
  104. package/dist/src/core/coreToolScheduler.js.map +1 -1
  105. package/dist/src/core/coreToolScheduler.test.js +3 -0
  106. package/dist/src/core/coreToolScheduler.test.js.map +1 -1
  107. package/dist/src/core/fakeContentGenerator.d.ts +1 -0
  108. package/dist/src/core/fakeContentGenerator.js +1 -0
  109. package/dist/src/core/fakeContentGenerator.js.map +1 -1
  110. package/dist/src/core/geminiChat.js +1 -0
  111. package/dist/src/core/geminiChat.js.map +1 -1
  112. package/dist/src/core/geminiChat.test.js +21 -0
  113. package/dist/src/core/geminiChat.test.js.map +1 -1
  114. package/dist/src/core/geminiChat_network_retry.test.js +17 -12
  115. package/dist/src/core/geminiChat_network_retry.test.js.map +1 -1
  116. package/dist/src/core/loggingContentGenerator.d.ts +3 -0
  117. package/dist/src/core/loggingContentGenerator.js +6 -0
  118. package/dist/src/core/loggingContentGenerator.js.map +1 -1
  119. package/dist/src/core/loggingContentGenerator.test.js +11 -0
  120. package/dist/src/core/loggingContentGenerator.test.js.map +1 -1
  121. package/dist/src/core/prompts-substitution.test.js +101 -0
  122. package/dist/src/core/prompts-substitution.test.js.map +1 -0
  123. package/dist/src/core/prompts.js +115 -31
  124. package/dist/src/core/prompts.js.map +1 -1
  125. package/dist/src/core/prompts.test.js +32 -0
  126. package/dist/src/core/prompts.test.js.map +1 -1
  127. package/dist/src/core/recordingContentGenerator.d.ts +2 -1
  128. package/dist/src/core/recordingContentGenerator.js +6 -1
  129. package/dist/src/core/recordingContentGenerator.js.map +1 -1
  130. package/dist/src/core/turn.d.ts +2 -0
  131. package/dist/src/core/turn.js.map +1 -1
  132. package/dist/src/generated/git-commit.d.ts +2 -2
  133. package/dist/src/generated/git-commit.js +2 -2
  134. package/dist/src/generated/git-commit.js.map +1 -1
  135. package/dist/src/hooks/hookAggregator.js +13 -3
  136. package/dist/src/hooks/hookAggregator.js.map +1 -1
  137. package/dist/src/hooks/hookEventHandler.d.ts +1 -13
  138. package/dist/src/hooks/hookEventHandler.js +1 -289
  139. package/dist/src/hooks/hookEventHandler.js.map +1 -1
  140. package/dist/src/hooks/hookEventHandler.test.js +1 -4
  141. package/dist/src/hooks/hookEventHandler.test.js.map +1 -1
  142. package/dist/src/hooks/hookSystem.d.ts +47 -3
  143. package/dist/src/hooks/hookSystem.js +90 -6
  144. package/dist/src/hooks/hookSystem.js.map +1 -1
  145. package/dist/src/hooks/hookSystem.test.js +19 -8
  146. package/dist/src/hooks/hookSystem.test.js.map +1 -1
  147. package/dist/src/hooks/types.d.ts +23 -1
  148. package/dist/src/hooks/types.js +28 -2
  149. package/dist/src/hooks/types.js.map +1 -1
  150. package/dist/src/hooks/types.test.js +9 -1
  151. package/dist/src/hooks/types.test.js.map +1 -1
  152. package/dist/src/ide/detect-ide.d.ts +41 -0
  153. package/dist/src/ide/detect-ide.js +47 -3
  154. package/dist/src/ide/detect-ide.js.map +1 -1
  155. package/dist/src/ide/detect-ide.test.js +46 -0
  156. package/dist/src/ide/detect-ide.test.js.map +1 -1
  157. package/dist/src/ide/ide-client.d.ts +1 -0
  158. package/dist/src/ide/ide-client.js +36 -9
  159. package/dist/src/ide/ide-client.js.map +1 -1
  160. package/dist/src/ide/ide-client.test.js +154 -6
  161. package/dist/src/ide/ide-client.test.js.map +1 -1
  162. package/dist/src/index.d.ts +2 -0
  163. package/dist/src/index.js +2 -0
  164. package/dist/src/index.js.map +1 -1
  165. package/dist/src/mcp/oauth-provider.d.ts +1 -2
  166. package/dist/src/mcp/oauth-provider.js +4 -8
  167. package/dist/src/mcp/oauth-provider.js.map +1 -1
  168. package/dist/src/mcp/oauth-provider.test.js +32 -0
  169. package/dist/src/mcp/oauth-provider.test.js.map +1 -1
  170. package/dist/src/mcp/oauth-utils.d.ts +13 -4
  171. package/dist/src/mcp/oauth-utils.js +23 -19
  172. package/dist/src/mcp/oauth-utils.js.map +1 -1
  173. package/dist/src/mcp/oauth-utils.test.js +13 -8
  174. package/dist/src/mcp/oauth-utils.test.js.map +1 -1
  175. package/dist/src/policy/policy-engine.d.ts +1 -8
  176. package/dist/src/policy/policy-engine.js +1 -75
  177. package/dist/src/policy/policy-engine.js.map +1 -1
  178. package/dist/src/policy/policy-engine.test.js +0 -222
  179. package/dist/src/policy/policy-engine.test.js.map +1 -1
  180. package/dist/src/routing/modelRouterService.js +18 -8
  181. package/dist/src/routing/modelRouterService.js.map +1 -1
  182. package/dist/src/routing/modelRouterService.test.js +14 -6
  183. package/dist/src/routing/modelRouterService.test.js.map +1 -1
  184. package/dist/src/routing/strategies/classifierStrategy.js +4 -7
  185. package/dist/src/routing/strategies/classifierStrategy.js.map +1 -1
  186. package/dist/src/routing/strategies/classifierStrategy.test.js +10 -4
  187. package/dist/src/routing/strategies/classifierStrategy.test.js.map +1 -1
  188. package/dist/src/routing/strategies/numericalClassifierStrategy.d.ts +13 -0
  189. package/dist/src/routing/strategies/numericalClassifierStrategy.js +178 -0
  190. package/dist/src/routing/strategies/numericalClassifierStrategy.js.map +1 -0
  191. package/dist/src/routing/strategies/numericalClassifierStrategy.test.js +347 -0
  192. package/dist/src/routing/strategies/numericalClassifierStrategy.test.js.map +1 -0
  193. package/dist/src/scheduler/confirmation.js +2 -3
  194. package/dist/src/scheduler/confirmation.js.map +1 -1
  195. package/dist/src/scheduler/confirmation.test.js +8 -8
  196. package/dist/src/scheduler/confirmation.test.js.map +1 -1
  197. package/dist/src/scheduler/scheduler.test.js +0 -3
  198. package/dist/src/scheduler/scheduler.test.js.map +1 -1
  199. package/dist/src/scheduler/state-manager.js +4 -0
  200. package/dist/src/scheduler/state-manager.js.map +1 -1
  201. package/dist/src/scheduler/state-manager.test.js +11 -0
  202. package/dist/src/scheduler/state-manager.test.js.map +1 -1
  203. package/dist/src/scheduler/tool-executor.js +2 -4
  204. package/dist/src/scheduler/tool-executor.js.map +1 -1
  205. package/dist/src/scheduler/tool-executor.test.js +1 -1
  206. package/dist/src/scheduler/tool-executor.test.js.map +1 -1
  207. package/dist/src/services/chatRecordingService.d.ts +1 -1
  208. package/dist/src/services/chatRecordingService.js +23 -1
  209. package/dist/src/services/chatRecordingService.js.map +1 -1
  210. package/dist/src/services/chatRecordingService.test.js +111 -0
  211. package/dist/src/services/chatRecordingService.test.js.map +1 -1
  212. package/dist/src/services/sessionSummaryService.test.js +1 -1
  213. package/dist/src/services/sessionSummaryService.test.js.map +1 -1
  214. package/dist/src/telemetry/metrics.js +15 -4
  215. package/dist/src/telemetry/metrics.js.map +1 -1
  216. package/dist/src/telemetry/metrics.test.js +7 -0
  217. package/dist/src/telemetry/metrics.test.js.map +1 -1
  218. package/dist/src/telemetry/types.d.ts +3 -1
  219. package/dist/src/telemetry/types.js +19 -4
  220. package/dist/src/telemetry/types.js.map +1 -1
  221. package/dist/src/test-utils/mock-message-bus.d.ts +1 -19
  222. package/dist/src/test-utils/mock-message-bus.js +1 -65
  223. package/dist/src/test-utils/mock-message-bus.js.map +1 -1
  224. package/dist/src/tools/ask-user.d.ts +20 -0
  225. package/dist/src/tools/ask-user.js +142 -0
  226. package/dist/src/tools/ask-user.js.map +1 -0
  227. package/dist/src/{core/geminiChatHookTriggers.test.d.ts → tools/ask-user.test.d.ts} +1 -1
  228. package/dist/src/tools/ask-user.test.js +187 -0
  229. package/dist/src/tools/ask-user.test.js.map +1 -0
  230. package/dist/src/tools/confirmation-policy.test.js +1 -1
  231. package/dist/src/tools/confirmation-policy.test.js.map +1 -1
  232. package/dist/src/tools/diffOptions.d.ts +1 -1
  233. package/dist/src/tools/diffOptions.js +7 -3
  234. package/dist/src/tools/diffOptions.js.map +1 -1
  235. package/dist/src/tools/diffOptions.test.js +17 -0
  236. package/dist/src/tools/diffOptions.test.js.map +1 -1
  237. package/dist/src/tools/edit.js +1 -1
  238. package/dist/src/tools/edit.js.map +1 -1
  239. package/dist/src/tools/edit.test.js +11 -3
  240. package/dist/src/tools/edit.test.js.map +1 -1
  241. package/dist/src/tools/mcp-client-manager.d.ts +13 -4
  242. package/dist/src/tools/mcp-client-manager.js +53 -21
  243. package/dist/src/tools/mcp-client-manager.js.map +1 -1
  244. package/dist/src/tools/mcp-client-manager.test.js +1 -0
  245. package/dist/src/tools/mcp-client-manager.test.js.map +1 -1
  246. package/dist/src/tools/mcp-client.test.js +1 -2
  247. package/dist/src/tools/mcp-client.test.js.map +1 -1
  248. package/dist/src/tools/modifiable-tool.test.js +3 -3
  249. package/dist/src/tools/modifiable-tool.test.js.map +1 -1
  250. package/dist/src/tools/read-many-files.js +3 -2
  251. package/dist/src/tools/read-many-files.js.map +1 -1
  252. package/dist/src/tools/ripGrep.js +7 -2
  253. package/dist/src/tools/ripGrep.js.map +1 -1
  254. package/dist/src/tools/ripGrep.test.js +2 -2
  255. package/dist/src/tools/ripGrep.test.js.map +1 -1
  256. package/dist/src/tools/tool-names.d.ts +8 -2
  257. package/dist/src/tools/tool-names.js +14 -2
  258. package/dist/src/tools/tool-names.js.map +1 -1
  259. package/dist/src/tools/tools.d.ts +1 -0
  260. package/dist/src/tools/tools.js +2 -1
  261. package/dist/src/tools/tools.js.map +1 -1
  262. package/dist/src/tools/write-file.test.js +7 -7
  263. package/dist/src/tools/write-file.test.js.map +1 -1
  264. package/dist/src/utils/constants.d.ts +7 -0
  265. package/dist/src/utils/constants.js +8 -0
  266. package/dist/src/utils/constants.js.map +1 -0
  267. package/dist/src/utils/editCorrector.js +1 -1
  268. package/dist/src/utils/editCorrector.js.map +1 -1
  269. package/dist/src/utils/editor.js +4 -1
  270. package/dist/src/utils/editor.js.map +1 -1
  271. package/dist/src/utils/editor.test.js +6 -4
  272. package/dist/src/utils/editor.test.js.map +1 -1
  273. package/dist/src/utils/events.d.ts +2 -0
  274. package/dist/src/utils/events.js +1 -0
  275. package/dist/src/utils/events.js.map +1 -1
  276. package/dist/src/utils/extensionLoader.js +1 -0
  277. package/dist/src/utils/extensionLoader.js.map +1 -1
  278. package/dist/src/utils/extensionLoader.test.js +11 -0
  279. package/dist/src/utils/extensionLoader.test.js.map +1 -1
  280. package/dist/src/utils/googleQuotaErrors.d.ts +3 -3
  281. package/dist/src/utils/googleQuotaErrors.js +6 -17
  282. package/dist/src/utils/googleQuotaErrors.js.map +1 -1
  283. package/dist/src/utils/googleQuotaErrors.test.js +4 -22
  284. package/dist/src/utils/googleQuotaErrors.test.js.map +1 -1
  285. package/dist/src/utils/llm-edit-fixer.js +4 -7
  286. package/dist/src/utils/llm-edit-fixer.js.map +1 -1
  287. package/dist/src/utils/llm-edit-fixer.test.js +2 -2
  288. package/dist/src/utils/llm-edit-fixer.test.js.map +1 -1
  289. package/dist/src/utils/memoryImportProcessor.js +7 -24
  290. package/dist/src/utils/memoryImportProcessor.js.map +1 -1
  291. package/dist/src/utils/promptIdContext.d.ts +6 -0
  292. package/dist/src/utils/promptIdContext.js +15 -0
  293. package/dist/src/utils/promptIdContext.js.map +1 -1
  294. package/dist/src/utils/schemaValidator.d.ts +6 -0
  295. package/dist/src/utils/schemaValidator.js +12 -1
  296. package/dist/src/utils/schemaValidator.js.map +1 -1
  297. package/dist/src/utils/workspaceContext.d.ts +15 -0
  298. package/dist/src/utils/workspaceContext.js +32 -11
  299. package/dist/src/utils/workspaceContext.js.map +1 -1
  300. package/dist/src/utils/workspaceContext.test.js +55 -0
  301. package/dist/src/utils/workspaceContext.test.js.map +1 -1
  302. package/dist/tsconfig.tsbuildinfo +1 -1
  303. package/package.json +2 -3
  304. package/dist/docs/changelogs/releases.md +0 -1543
  305. package/dist/google-gemini-cli-core-0.26.0-preview.3.tgz +0 -0
  306. package/dist/src/agents/delegate-to-agent-tool.d.ts +0 -19
  307. package/dist/src/agents/delegate-to-agent-tool.js +0 -178
  308. package/dist/src/agents/delegate-to-agent-tool.js.map +0 -1
  309. package/dist/src/agents/delegate-to-agent-tool.test.js +0 -213
  310. package/dist/src/agents/delegate-to-agent-tool.test.js.map +0 -1
  311. package/dist/src/agents/schema-utils.d.ts +0 -39
  312. package/dist/src/agents/schema-utils.js +0 -57
  313. package/dist/src/agents/schema-utils.js.map +0 -1
  314. package/dist/src/agents/schema-utils.test.js +0 -144
  315. package/dist/src/agents/schema-utils.test.js.map +0 -1
  316. package/dist/src/core/clientHookTriggers.d.ts +0 -36
  317. package/dist/src/core/clientHookTriggers.js +0 -76
  318. package/dist/src/core/clientHookTriggers.js.map +0 -1
  319. package/dist/src/core/geminiChatHookTriggers.d.ts +0 -68
  320. package/dist/src/core/geminiChatHookTriggers.js +0 -158
  321. package/dist/src/core/geminiChatHookTriggers.js.map +0 -1
  322. package/dist/src/core/geminiChatHookTriggers.test.js +0 -153
  323. package/dist/src/core/geminiChatHookTriggers.test.js.map +0 -1
  324. /package/dist/src/{agents/delegate-to-agent-tool.test.d.ts → core/prompts-substitution.test.d.ts} +0 -0
  325. /package/dist/src/{agents/schema-utils.test.d.ts → routing/strategies/numericalClassifierStrategy.test.d.ts} +0 -0
@@ -1,495 +1,131 @@
1
- # Gemini CLI hooks
1
+ # Gemini CLI hooks (experimental)
2
2
 
3
3
  Hooks are scripts or programs that Gemini CLI executes at specific points in the
4
4
  agentic loop, allowing you to intercept and customize behavior without modifying
5
5
  the CLI's source code.
6
6
 
7
- > **Note: Hooks are currently an experimental feature.**
8
- >
9
- > To use hooks, you must explicitly enable them in your `settings.json`:
10
- >
11
- > ```json
12
- > {
13
- > "tools": { "enableHooks": true },
14
- > "hooks": { "enabled": true }
15
- > }
16
- > ```
17
- >
18
- > Both of these are needed in this experimental phase.
7
+ ## Availability
19
8
 
20
- See [writing hooks guide](writing-hooks.md) for a tutorial on creating your
21
- first hook and a comprehensive example.
9
+ > **Experimental Feature**: Hooks are currently enabled by default only in the
10
+ > **Preview** and **Nightly** release channels.
22
11
 
23
- See [hooks reference](reference.md) for the technical specification of the I/O
24
- schemas.
25
-
26
- See [best practices](best-practices.md) for guidelines on security, performance,
27
- and debugging.
28
-
29
- ## What are hooks?
30
-
31
- With hooks, you can:
32
-
33
- - **Add context:** Inject relevant information before the model processes a
34
- request
35
- - **Validate actions:** Review and block potentially dangerous operations
36
- - **Enforce policies:** Implement security and compliance requirements
37
- - **Log interactions:** Track tool usage and model responses
38
- - **Optimize behavior:** Dynamically adjust tool selection or model parameters
39
-
40
- Hooks run synchronously as part of the agent loop—when a hook event fires,
41
- Gemini CLI waits for all matching hooks to complete before continuing.
42
-
43
- ## Security and Risks
44
-
45
- > **Warning: Hooks execute arbitrary code with your user privileges.**
46
- >
47
- > By configuring hooks, you are explicitly allowing Gemini CLI to run shell
48
- > commands on your machine. Malicious or poorly configured hooks can:
49
-
50
- - **Exfiltrate data**: Read sensitive files (`.env`, ssh keys) and send them to
51
- remote servers.
52
- - **Modify system**: Delete files, install malware, or change system settings.
53
- - **Consume resources**: Run infinite loops or crash your system.
54
-
55
- **Project-level hooks** (in `.gemini/settings.json`) and **Extension hooks** are
56
- particularly risky when opening third-party projects or extensions from
57
- untrusted authors. Gemini CLI will **warn you** the first time it detects a new
58
- project hook (identified by its name and command), but it is **your
59
- responsibility** to review these hooks (and any installed extensions) before
60
- trusting them.
61
-
62
- > **Note:** Extension hooks are subject to a mandatory security warning and
63
- > consent flow during extension installation or update if hooks are detected.
64
- > You must explicitly approve the installation or update of any extension that
65
- > contains hooks.
66
-
67
- See [Security Considerations](best-practices.md#using-hooks-securely) for a
68
- detailed threat model and mitigation strategies.
69
-
70
- ## Core concepts
71
-
72
- ### Hook events
73
-
74
- Hooks are triggered by specific events in Gemini CLI's lifecycle. The following
75
- table lists all available hook events:
76
-
77
- | Event | When It Fires | Common Use Cases |
78
- | --------------------- | --------------------------------------------- | ------------------------------------------ |
79
- | `SessionStart` | When a session begins | Initialize resources, load context |
80
- | `SessionEnd` | When a session ends | Clean up, save state |
81
- | `BeforeAgent` | After user submits prompt, before planning | Add context, validate prompts |
82
- | `AfterAgent` | When agent loop ends | Review output, force continuation |
83
- | `BeforeModel` | Before sending request to LLM | Modify prompts, add instructions |
84
- | `AfterModel` | After receiving LLM response | Filter responses, log interactions |
85
- | `BeforeToolSelection` | Before LLM selects tools (after BeforeModel) | Filter available tools, optimize selection |
86
- | `BeforeTool` | Before a tool executes | Validate arguments, block dangerous ops |
87
- | `AfterTool` | After a tool executes | Process results, run tests |
88
- | `PreCompress` | Before context compression | Save state, notify user |
89
- | `Notification` | When a notification occurs (e.g., permission) | Auto-approve, log decisions |
90
-
91
- ### Hook types
92
-
93
- Gemini CLI currently supports **command hooks** that run shell commands or
94
- scripts:
95
-
96
- ```json
97
- {
98
- "type": "command",
99
- "command": "$GEMINI_PROJECT_DIR/.gemini/hooks/my-hook.sh",
100
- "timeout": 30000
101
- }
102
- ```
103
-
104
- **Note:** Plugin hooks (npm packages) are planned for a future release.
105
-
106
- ### Matchers
107
-
108
- For tool-related events (`BeforeTool`, `AfterTool`), you can filter which tools
109
- trigger the hook:
110
-
111
- ```json
112
- {
113
- "hooks": {
114
- "BeforeTool": [
115
- {
116
- "matcher": "write_file|replace",
117
- "hooks": [
118
- /* hooks for write operations */
119
- ]
120
- }
121
- ]
122
- }
123
- }
124
- ```
125
-
126
- **Matcher patterns:**
127
-
128
- - **Exact match:** `"read_file"` matches only `read_file`
129
- - **Regex:** `"write_.*|replace"` matches `write_file`, `replace`
130
- - **Wildcard:** `"*"` or `""` matches all tools
131
-
132
- **Session event matchers:**
133
-
134
- - **SessionStart:** `startup`, `resume`, `clear`
135
- - **SessionEnd:** `exit`, `clear`, `logout`, `prompt_input_exit`
136
- - **PreCompress:** `manual`, `auto`
137
- - **Notification:** `ToolPermission`
138
-
139
- ## Hook input/output contract
140
-
141
- ### Command hook communication
142
-
143
- Hooks communicate via:
144
-
145
- - **Input:** JSON on stdin
146
- - **Output:** Exit code + stdout/stderr
147
-
148
- ### Exit codes
149
-
150
- - **0:** Success - stdout shown to user (or injected as context for some events)
151
- - **2:** Blocking error - stderr shown to agent/user, operation may be blocked
152
- - **Other:** Non-blocking warning - logged but execution continues
153
-
154
- ### Common input fields
155
-
156
- Every hook receives these base fields:
12
+ If you are on the Stable channel, you must explicitly enable the hooks system in
13
+ your `settings.json`:
157
14
 
158
15
  ```json
159
16
  {
160
- "session_id": "abc123",
161
- "transcript_path": "/path/to/transcript.jsonl",
162
- "cwd": "/path/to/project",
163
- "hook_event_name": "BeforeTool",
164
- "timestamp": "2025-12-01T10:30:00Z"
165
- // ... event-specific fields
166
- }
167
- ```
168
-
169
- ### Event-specific fields
170
-
171
- #### BeforeTool
172
-
173
- **Input:**
174
-
175
- ```json
176
- {
177
- "tool_name": "write_file",
178
- "tool_input": {
179
- "file_path": "/path/to/file.ts",
180
- "content": "..."
17
+ "hooksConfig": {
18
+ "enabled": true
181
19
  }
182
20
  }
183
21
  ```
184
22
 
185
- **Output (JSON on stdout):**
186
-
187
- ```json
188
- {
189
- "decision": "allow|deny|ask|block",
190
- "reason": "Explanation shown to agent",
191
- "systemMessage": "Message shown to user"
192
- }
193
- ```
23
+ - **[Writing hooks guide](/docs/hooks/writing-hooks)**: A tutorial on creating
24
+ your first hook with comprehensive examples.
25
+ - **[Hooks reference](/docs/hooks/reference)**: The definitive technical
26
+ specification of I/O schemas and exit codes.
27
+ - **[Best practices](/docs/hooks/best-practices)**: Guidelines on security,
28
+ performance, and debugging.
194
29
 
195
- Or simple exit codes:
196
-
197
- - Exit 0 = allow (stdout shown to user)
198
- - Exit 2 = deny (stderr shown to agent)
199
-
200
- #### AfterTool
201
-
202
- **Input:**
203
-
204
- ```json
205
- {
206
- "tool_name": "read_file",
207
- "tool_input": { "file_path": "..." },
208
- "tool_response": "file contents..."
209
- }
210
- ```
211
-
212
- **Output:**
213
-
214
- ```json
215
- {
216
- "decision": "allow|deny",
217
- "hookSpecificOutput": {
218
- "hookEventName": "AfterTool",
219
- "additionalContext": "Extra context for agent"
220
- }
221
- }
222
- ```
223
-
224
- #### BeforeAgent
225
-
226
- **Input:**
227
-
228
- ```json
229
- {
230
- "prompt": "Fix the authentication bug"
231
- }
232
- ```
233
-
234
- **Output:**
235
-
236
- ```json
237
- {
238
- "decision": "allow|deny",
239
- "hookSpecificOutput": {
240
- "hookEventName": "BeforeAgent",
241
- "additionalContext": "Recent project decisions: ..."
242
- }
243
- }
244
- ```
245
-
246
- #### BeforeModel
247
-
248
- **Input:**
249
-
250
- ```json
251
- {
252
- "llm_request": {
253
- "model": "gemini-2.0-flash-exp",
254
- "messages": [{ "role": "user", "content": "Hello" }],
255
- "config": { "temperature": 0.7 },
256
- "toolConfig": {
257
- "functionCallingConfig": {
258
- "mode": "AUTO",
259
- "allowedFunctionNames": ["read_file", "write_file"]
260
- }
261
- }
262
- }
263
- }
264
- ```
265
-
266
- **Output:**
267
-
268
- ```json
269
- {
270
- "decision": "allow",
271
- "hookSpecificOutput": {
272
- "hookEventName": "BeforeModel",
273
- "llm_request": {
274
- "messages": [
275
- { "role": "system", "content": "Additional instructions..." },
276
- { "role": "user", "content": "Hello" }
277
- ]
278
- }
279
- }
280
- }
281
- ```
282
-
283
- #### AfterModel
284
-
285
- **Input:**
286
-
287
- ```json
288
- {
289
- "llm_request": {
290
- "model": "gemini-2.0-flash-exp",
291
- "messages": [
292
- /* ... */
293
- ],
294
- "config": {
295
- /* ... */
296
- },
297
- "toolConfig": {
298
- /* ... */
299
- }
300
- },
301
- "llm_response": {
302
- "text": "string",
303
- "candidates": [
304
- {
305
- "content": {
306
- "role": "model",
307
- "parts": ["array of content parts"]
308
- },
309
- "finishReason": "STOP"
310
- }
311
- ]
312
- }
313
- }
314
- ```
315
-
316
- **Output:**
317
-
318
- ```json
319
- {
320
- "hookSpecificOutput": {
321
- "hookEventName": "AfterModel",
322
- "llm_response": {
323
- "candidate": {
324
- /* modified response */
325
- }
326
- }
327
- }
328
- }
329
- ```
330
-
331
- #### BeforeToolSelection
332
-
333
- **Input:**
334
-
335
- ```json
336
- {
337
- "llm_request": {
338
- "model": "gemini-2.0-flash-exp",
339
- "messages": [
340
- /* ... */
341
- ],
342
- "toolConfig": {
343
- "functionCallingConfig": {
344
- "mode": "AUTO",
345
- "allowedFunctionNames": [
346
- /* 100+ tools */
347
- ]
348
- }
349
- }
350
- }
351
- }
352
- ```
30
+ ## What are hooks?
353
31
 
354
- **Output:**
32
+ Hooks run synchronously as part of the agent loop—when a hook event fires,
33
+ Gemini CLI waits for all matching hooks to complete before continuing.
355
34
 
356
- ```json
357
- {
358
- "hookSpecificOutput": {
359
- "hookEventName": "BeforeToolSelection",
360
- "toolConfig": {
361
- "functionCallingConfig": {
362
- "mode": "ANY",
363
- "allowedFunctionNames": ["read_file", "write_file", "replace"]
364
- }
365
- }
366
- }
367
- }
368
- ```
35
+ With hooks, you can:
369
36
 
370
- Or simple output (comma-separated tool names sets mode to ANY):
37
+ - **Add context:** Inject relevant information (like git history) before the
38
+ model processes a request.
39
+ - **Validate actions:** Review tool arguments and block potentially dangerous
40
+ operations.
41
+ - **Enforce policies:** Implement security scanners and compliance checks.
42
+ - **Log interactions:** Track tool usage and model responses for auditing.
43
+ - **Optimize behavior:** Dynamically filter available tools or adjust model
44
+ parameters.
371
45
 
372
- ```bash
373
- echo "read_file,write_file,replace"
374
- ```
46
+ ## Core concepts
375
47
 
376
- #### SessionStart
48
+ ### Hook events
377
49
 
378
- **Input:**
50
+ Hooks are triggered by specific events in Gemini CLI's lifecycle.
379
51
 
380
- ```json
381
- {
382
- "source": "startup|resume|clear"
383
- }
384
- ```
52
+ | Event | When It Fires | Impact | Common Use Cases |
53
+ | --------------------- | ---------------------------------------------- | ---------------------- | -------------------------------------------- |
54
+ | `SessionStart` | When a session begins (startup, resume, clear) | Inject Context | Initialize resources, load context |
55
+ | `SessionEnd` | When a session ends (exit, clear) | Advisory | Clean up, save state |
56
+ | `BeforeAgent` | After user submits prompt, before planning | Block Turn / Context | Add context, validate prompts, block turns |
57
+ | `AfterAgent` | When agent loop ends | Retry / Halt | Review output, force retry or halt execution |
58
+ | `BeforeModel` | Before sending request to LLM | Block Turn / Mock | Modify prompts, swap models, mock responses |
59
+ | `AfterModel` | After receiving LLM response | Block Turn / Redact | Filter/redact responses, log interactions |
60
+ | `BeforeToolSelection` | Before LLM selects tools | Filter Tools | Filter available tools, optimize selection |
61
+ | `BeforeTool` | Before a tool executes | Block Tool / Rewrite | Validate arguments, block dangerous ops |
62
+ | `AfterTool` | After a tool executes | Block Result / Context | Process results, run tests, hide results |
63
+ | `PreCompress` | Before context compression | Advisory | Save state, notify user |
64
+ | `Notification` | When a system notification occurs | Advisory | Forward to desktop alerts, logging |
385
65
 
386
- **Output:**
66
+ ### Global mechanics
387
67
 
388
- ```json
389
- {
390
- "hookSpecificOutput": {
391
- "hookEventName": "SessionStart",
392
- "additionalContext": "Loaded 5 project memories"
393
- }
394
- }
395
- ```
68
+ Understanding these core principles is essential for building robust hooks.
396
69
 
397
- #### SessionEnd
70
+ #### Strict JSON requirements (The "Golden Rule")
398
71
 
399
- **Input:**
72
+ Hooks communicate via `stdin` (Input) and `stdout` (Output).
400
73
 
401
- ```json
402
- {
403
- "reason": "exit|clear|logout|prompt_input_exit|other"
404
- }
405
- ```
74
+ 1. **Silence is Mandatory**: Your script **must not** print any plain text to
75
+ `stdout` other than the final JSON object. **Even a single `echo` or `print`
76
+ call before the JSON will break parsing.**
77
+ 2. **Pollution = Failure**: If `stdout` contains non-JSON text, parsing will
78
+ fail. The CLI will default to "Allow" and treat the entire output as a
79
+ `systemMessage`.
80
+ 3. **Debug via Stderr**: Use `stderr` for **all** logging and debugging (e.g.,
81
+ `echo "debug" >&2`). Gemini CLI captures `stderr` but never attempts to parse
82
+ it as JSON.
406
83
 
407
- No structured output expected (but stdout/stderr logged).
84
+ #### Exit codes
408
85
 
409
- #### PreCompress
86
+ Gemini CLI uses exit codes to determine the high-level outcome of a hook
87
+ execution:
410
88
 
411
- **Input:**
89
+ | Exit Code | Label | Behavioral Impact |
90
+ | --------- | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
91
+ | **0** | **Success** | The `stdout` is parsed as JSON. **Preferred code** for all logic, including intentional blocks (e.g., `{"decision": "deny"}`). |
92
+ | **2** | **System Block** | **Critical Block**. The target action (tool, turn, or stop) is aborted. `stderr` is used as the rejection reason. High severity; used for security stops or script failures. |
93
+ | **Other** | **Warning** | Non-fatal failure. A warning is shown, but the interaction proceeds using original parameters. |
412
94
 
413
- ```json
414
- {
415
- "trigger": "manual|auto"
416
- }
417
- ```
95
+ #### Matchers
418
96
 
419
- **Output:**
97
+ You can filter which specific tools or triggers fire your hook using the
98
+ `matcher` field.
420
99
 
421
- ```json
422
- {
423
- "systemMessage": "Compression starting..."
424
- }
425
- ```
426
-
427
- #### Notification
428
-
429
- **Input:**
430
-
431
- ```json
432
- {
433
- "notification_type": "ToolPermission",
434
- "message": "string",
435
- "details": {
436
- /* notification details */
437
- }
438
- }
439
- ```
440
-
441
- **Output:**
442
-
443
- ```json
444
- {
445
- "systemMessage": "Notification logged"
446
- }
447
- ```
100
+ - **Tool events** (`BeforeTool`, `AfterTool`): Matchers are **Regular
101
+ Expressions**. (e.g., `"write_.*"`).
102
+ - **Lifecycle events**: Matchers are **Exact Strings**. (e.g., `"startup"`).
103
+ - **Wildcards**: `"*"` or `""` (empty string) matches all occurrences.
448
104
 
449
105
  ## Configuration
450
106
 
451
- Hook definitions are configured in `settings.json` files using the `hooks`
452
- object. Configuration can be specified at multiple levels with defined
453
- precedence rules.
454
-
455
- ### Configuration layers
456
-
457
- Hook configurations are applied in the following order of execution (lower
458
- numbers run first):
459
-
460
- 1. **Project settings:** `.gemini/settings.json` in your project directory
461
- (highest priority)
462
- 2. **User settings:** `~/.gemini/settings.json`
463
- 3. **System settings:** `/etc/gemini-cli/settings.json`
464
- 4. **Extensions:** Internal hooks defined by installed extensions (lowest
465
- priority). See [Extensions documentation](../extensions/index.md#hooks) for
466
- details on how extensions define and configure hooks.
467
-
468
- #### Deduplication and shadowing
107
+ Hooks are configured in `settings.json`. Gemini CLI merges configurations from
108
+ multiple layers in the following order of precedence (highest to lowest):
469
109
 
470
- If multiple hooks with the identical **name** and **command** are discovered
471
- across different configuration layers, Gemini CLI deduplicates them. The hook
472
- from the higher-priority layer (e.g., Project) will be kept, and others will be
473
- ignored.
474
-
475
- Within each level, hooks run in the order they are declared in the
476
- configuration.
110
+ 1. **Project settings**: `.gemini/settings.json` in the current directory.
111
+ 2. **User settings**: `~/.gemini/settings.json`.
112
+ 3. **System settings**: `/etc/gemini-cli/settings.json`.
113
+ 4. **Extensions**: Hooks defined by installed extensions.
477
114
 
478
115
  ### Configuration schema
479
116
 
480
117
  ```json
481
118
  {
482
119
  "hooks": {
483
- "EventName": [
120
+ "BeforeTool": [
484
121
  {
485
- "matcher": "pattern",
122
+ "matcher": "write_file|replace",
486
123
  "hooks": [
487
124
  {
488
- "name": "hook-identifier",
125
+ "name": "security-check",
489
126
  "type": "command",
490
- "command": "./path/to/script.sh",
491
- "description": "What this hook does",
492
- "timeout": 30000
127
+ "command": "$GEMINI_PROJECT_DIR/.gemini/hooks/security.sh",
128
+ "timeout": 5000
493
129
  }
494
130
  ]
495
131
  }
@@ -498,226 +134,45 @@ configuration.
498
134
  }
499
135
  ```
500
136
 
501
- **Configuration properties:**
502
-
503
- - **`name`** (string, recommended): Unique identifier for the hook used in
504
- `/hooks enable/disable` commands. If omitted, the `command` path is used as
505
- the identifier.
506
- - **`type`** (string, required): Hook type - currently only `"command"` is
507
- supported
508
- - **`command`** (string, required): Path to the script or command to execute
509
- - **`description`** (string, optional): Human-readable description shown in
510
- `/hooks panel`
511
- - **`timeout`** (number, optional): Timeout in milliseconds (default: 60000)
512
- - **`matcher`** (string, optional): Pattern to filter when hook runs (event
513
- matchers only)
514
-
515
- ### Environment variables
516
-
517
- Hooks have access to:
518
-
519
- - `GEMINI_PROJECT_DIR`: Project root directory
520
- - `GEMINI_SESSION_ID`: Current session ID
521
- - `GEMINI_API_KEY`: Gemini API key (if configured)
522
- - All other environment variables from the parent process
523
-
524
- ## Managing hooks
525
-
526
- ### View registered hooks
527
-
528
- Use the `/hooks panel` command to view all registered hooks:
529
-
530
- ```bash
531
- /hooks panel
532
- ```
533
-
534
- This command displays:
535
-
536
- - All configured hooks organized by event
537
- - Hook source (user, project, system)
538
- - Hook type (command or plugin)
539
- - Individual hook status (enabled/disabled)
540
-
541
- ### Enable and disable all hooks at once
542
-
543
- You can enable or disable all hooks at once using commands:
544
-
545
- ```bash
546
- /hooks enable-all
547
- /hooks disable-all
548
- ```
549
-
550
- These commands provide a shortcut to enable or disable all configured hooks
551
- without managing them individually. The `enable-all` command removes all hooks
552
- from the `hooks.disabled` array, while `disable-all` adds all configured hooks
553
- to the disabled list. Changes take effect immediately without requiring a
554
- restart.
555
-
556
- ### Enable and disable individual hooks
557
-
558
- You can enable or disable individual hooks using commands:
559
-
560
- ```bash
561
- /hooks enable hook-name
562
- /hooks disable hook-name
563
- ```
564
-
565
- These commands allow you to control hook execution without editing configuration
566
- files. The hook name should match the `name` field in your hook configuration.
567
- Changes made via these commands are persisted to your settings. The settings are
568
- saved to workspace scope if available, otherwise to your global user settings
569
- (`~/.gemini/settings.json`).
570
-
571
- ### Disabled hooks configuration
572
-
573
- To permanently disable hooks, add them to the `hooks.disabled` array in your
574
- `settings.json`:
575
-
576
- ```json
577
- {
578
- "hooks": {
579
- "disabled": ["secret-scanner", "auto-test"]
580
- }
581
- }
582
- ```
583
-
584
- **Note:** The `hooks.disabled` array uses a UNION merge strategy. Disabled hooks
585
- from all configuration levels (user, project, system) are combined and
586
- deduplicated, meaning a hook disabled at any level remains disabled.
587
-
588
- ## Migration from Claude Code
589
-
590
- If you have hooks configured for Claude Code, you can migrate them:
591
-
592
- ```bash
593
- gemini hooks migrate --from-claude
594
- ```
595
-
596
- This command:
597
-
598
- - Reads `.claude/settings.json`
599
- - Converts event names (`PreToolUse` → `BeforeTool`, etc.)
600
- - Translates tool names (`Bash` → `run_shell_command`, `replace` → `replace`)
601
- - Updates matcher patterns
602
- - Writes to `.gemini/settings.json`
603
-
604
- ### Event name mapping
605
-
606
- | Claude Code | Gemini CLI |
607
- | ------------------ | -------------- |
608
- | `PreToolUse` | `BeforeTool` |
609
- | `PostToolUse` | `AfterTool` |
610
- | `UserPromptSubmit` | `BeforeAgent` |
611
- | `Stop` | `AfterAgent` |
612
- | `Notification` | `Notification` |
613
- | `SessionStart` | `SessionStart` |
614
- | `SessionEnd` | `SessionEnd` |
615
- | `PreCompact` | `PreCompress` |
616
-
617
- ### Tool name mapping
618
-
619
- | Claude Code | Gemini CLI |
620
- | ----------- | --------------------- |
621
- | `Bash` | `run_shell_command` |
622
- | `Edit` | `replace` |
623
- | `Read` | `read_file` |
624
- | `Write` | `write_file` |
625
- | `Glob` | `glob` |
626
- | `Grep` | `search_file_content` |
627
- | `LS` | `list_directory` |
628
-
629
- ## Tool and Event Matchers Reference
137
+ #### Hook configuration fields
630
138
 
631
- ### Available tool names for matchers
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. |
632
146
 
633
- The following built-in tools can be used in `BeforeTool` and `AfterTool` hook
634
- matchers:
147
+ ---
635
148
 
636
- #### File operations
637
-
638
- - `read_file` - Read a single file
639
- - `read_many_files` - Read multiple files at once
640
- - `write_file` - Create or overwrite a file
641
- - `replace` - Edit file content with find/replace
642
-
643
- #### File system
644
-
645
- - `list_directory` - List directory contents
646
- - `glob` - Find files matching a pattern
647
- - `search_file_content` - Search within file contents
648
-
649
- #### Execution
650
-
651
- - `run_shell_command` - Execute shell commands
652
-
653
- #### Web and external
654
-
655
- - `google_web_search` - Google Search with grounding
656
- - `web_fetch` - Fetch web page content
657
-
658
- #### Agent features
659
-
660
- - `write_todos` - Manage TODO items
661
- - `save_memory` - Save information to memory
662
- - `delegate_to_agent` - Delegate tasks to sub-agents
663
-
664
- #### Example matchers
665
-
666
- ```json
667
- {
668
- "matcher": "write_file|replace" // File editing tools
669
- }
670
- ```
671
-
672
- ```json
673
- {
674
- "matcher": "read_.*" // All read operations
675
- }
676
- ```
677
-
678
- ```json
679
- {
680
- "matcher": "run_shell_command" // Only shell commands
681
- }
682
- ```
683
-
684
- ```json
685
- {
686
- "matcher": "*" // All tools
687
- }
688
- ```
689
-
690
- ### Event-specific matchers
691
-
692
- #### SessionStart event matchers
149
+ ### Environment variables
693
150
 
694
- - `startup` - Fresh session start
695
- - `resume` - Resuming a previous session
696
- - `clear` - Session cleared
151
+ Hooks are executed with a sanitized environment.
697
152
 
698
- #### SessionEnd event matchers
153
+ - `GEMINI_PROJECT_DIR`: The absolute path to the project root.
154
+ - `GEMINI_SESSION_ID`: The unique ID for the current session.
155
+ - `GEMINI_CWD`: The current working directory.
156
+ - `CLAUDE_PROJECT_DIR`: (Alias) Provided for compatibility.
699
157
 
700
- - `exit` - Normal exit
701
- - `clear` - Session cleared
702
- - `logout` - User logged out
703
- - `prompt_input_exit` - Exit from prompt input
704
- - `other` - Other reasons
158
+ ## Security and risks
705
159
 
706
- #### PreCompress event matchers
160
+ > **Warning: Hooks execute arbitrary code with your user privileges.** By
161
+ > configuring hooks, you are allowing scripts to run shell commands on your
162
+ > machine.
707
163
 
708
- - `manual` - Manually triggered compression
709
- - `auto` - Automatically triggered compression
164
+ **Project-level hooks** are particularly risky when opening untrusted projects.
165
+ Gemini CLI **fingerprints** project hooks. If a hook's name or command changes
166
+ (e.g., via `git pull`), it is treated as a **new, untrusted hook** and you will
167
+ be warned before it executes.
710
168
 
711
- #### Notification event matchers
169
+ See [Security Considerations](/docs/hooks/best-practices#using-hooks-securely)
170
+ for a detailed threat model.
712
171
 
713
- - `ToolPermission` - Tool permission notifications
172
+ ## Managing hooks
714
173
 
715
- ## Learn more
174
+ Use the CLI commands to manage hooks without editing JSON manually:
716
175
 
717
- - [Writing Hooks](writing-hooks.md) - Tutorial and comprehensive example
718
- - [Best Practices](best-practices.md) - Security, performance, and debugging
719
- - [Custom Commands](../cli/custom-commands.md) - Create reusable prompt
720
- shortcuts
721
- - [Configuration](../get-started/configuration.md) - Gemini CLI configuration
722
- options
723
- - [Hooks Design Document](../hooks-design.md) - Technical architecture details
176
+ - **View hooks:** `/hooks panel`
177
+ - **Enable/Disable all:** `/hooks enable-all` or `/hooks disable-all`
178
+ - **Toggle individual:** `/hooks enable <name>` or `/hooks disable <name>`