@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,178 +1,322 @@
1
- # Hooks Reference
1
+ # Hooks reference
2
2
 
3
3
  This document provides the technical specification for Gemini CLI hooks,
4
- including the JSON schemas for input and output, exit code behaviors, and the
5
- stable model API.
4
+ including JSON schemas and API details.
6
5
 
7
- ## Communication Protocol
6
+ ## Global hook mechanics
8
7
 
9
- Hooks communicate with Gemini CLI via standard streams and exit codes:
8
+ - **Communication**: `stdin` for Input (JSON), `stdout` for Output (JSON), and
9
+ `stderr` for logs and feedback.
10
+ - **Exit codes**:
11
+ - `0`: Success. `stdout` is parsed as JSON. **Preferred for all logic.**
12
+ - `2`: System Block. The action is blocked; `stderr` is used as the rejection
13
+ reason.
14
+ - `Other`: Warning. A non-fatal failure occurred; the CLI continues with a
15
+ warning.
16
+ - **Silence is Mandatory**: Your script **must not** print any plain text to
17
+ `stdout` other than the final JSON.
10
18
 
11
- - **Input**: Gemini CLI sends a JSON object to the hook's `stdin`.
12
- - **Output**: The hook sends a JSON object (or plain text) to `stdout`.
13
- - **Exit Codes**: Used to signal success or blocking errors.
19
+ ---
20
+
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**. |
14
33
 
15
- ### Exit Code Behavior
34
+ ### Hook configuration
16
35
 
17
- | Exit Code | Meaning | Behavior |
18
- | :-------- | :----------------- | :---------------------------------------------------------------------------------------------- |
19
- | `0` | **Success** | `stdout` is parsed as JSON. If parsing fails, it's treated as a `systemMessage`. |
20
- | `2` | **Blocking Error** | Interrupts the current operation. `stderr` is shown to the agent (for tool events) or the user. |
21
- | Other | **Warning** | Execution continues. `stderr` is logged as a non-blocking warning. |
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. |
22
43
 
23
44
  ---
24
45
 
25
- ## Input Schema (`stdin`)
26
-
27
- Every hook receives a base JSON object. Extra fields are added depending on the
28
- specific event.
29
-
30
- ### Base Fields (All Events)
31
-
32
- | Field | Type | Description |
33
- | :---------------- | :------- | :---------------------------------------------------- |
34
- | `session_id` | `string` | Unique identifier for the current CLI session. |
35
- | `transcript_path` | `string` | Path to the session's JSON transcript (if available). |
36
- | `cwd` | `string` | The current working directory. |
37
- | `hook_event_name` | `string` | The name of the firing event (e.g., `BeforeTool`). |
38
- | `timestamp` | `string` | ISO 8601 timestamp of the event. |
39
-
40
- ### Event-Specific Fields
41
-
42
- #### Tool Events (`BeforeTool`, `AfterTool`)
43
-
44
- - `tool_name`: (`string`) The internal name of the tool (e.g., `write_file`,
45
- `run_shell_command`).
46
- - `tool_input`: (`object`) The arguments passed to the tool.
47
- - `tool_response`: (`object`, **AfterTool only**) The raw output from the tool
48
- execution.
49
- - `mcp_context`: (`object`, **optional**) Present only for MCP tool invocations.
50
- Contains server identity information:
51
- - `server_name`: (`string`) The configured name of the MCP server.
52
- - `tool_name`: (`string`) The original tool name from the MCP server.
53
- - `command`: (`string`, optional) For stdio transport, the command used to
54
- start the server.
55
- - `args`: (`string[]`, optional) For stdio transport, the command arguments.
56
- - `cwd`: (`string`, optional) For stdio transport, the working directory.
57
- - `url`: (`string`, optional) For SSE/HTTP transport, the server URL.
58
- - `tcp`: (`string`, optional) For WebSocket transport, the TCP address.
59
-
60
- #### Agent Events (`BeforeAgent`, `AfterAgent`)
61
-
62
- - `prompt`: (`string`) The user's submitted prompt.
63
- - `prompt_response`: (`string`, **AfterAgent only**) The final response text
64
- from the model.
65
- - `stop_hook_active`: (`boolean`, **AfterAgent only**) Indicates if a stop hook
66
- is already handling a continuation.
67
-
68
- #### Model Events (`BeforeModel`, `AfterModel`, `BeforeToolSelection`)
69
-
70
- - `llm_request`: (`LLMRequest`) A stable representation of the outgoing request.
71
- See [Stable Model API](#stable-model-api).
72
- - `llm_response`: (`LLMResponse`, **AfterModel only**) A stable representation
73
- of the incoming response.
74
-
75
- #### Session & Notification Events
76
-
77
- - `source`: (`startup` | `resume` | `clear`, **SessionStart only**) The trigger
78
- source.
79
- - `reason`: (`exit` | `clear` | `logout` | `prompt_input_exit` | `other`,
80
- **SessionEnd only**) The reason for session end.
81
- - `trigger`: (`manual` | `auto`, **PreCompress only**) What triggered the
82
- compression event.
83
- - `notification_type`: (`ToolPermission`, **Notification only**) The type of
84
- notification being fired.
85
- - `message`: (`string`, **Notification only**) The notification message.
86
- - `details`: (`object`, **Notification only**) Payload-specific details for the
87
- notification.
46
+ ## Base input schema
47
+
48
+ All hooks receive these common fields via `stdin`:
49
+
50
+ ```typescript
51
+ {
52
+ "session_id": string, // Unique ID for the current session
53
+ "transcript_path": string, // Absolute path to session transcript JSON
54
+ "cwd": string, // Current working directory
55
+ "hook_event_name": string, // The firing event (e.g. "BeforeTool")
56
+ "timestamp": string // ISO 8601 execution time
57
+ }
58
+ ```
88
59
 
89
60
  ---
90
61
 
91
- ## Output Schema (`stdout`)
62
+ ## Common output fields
92
63
 
93
- If the hook exits with `0`, the CLI attempts to parse `stdout` as JSON.
64
+ Most hooks support these fields in their `stdout` JSON:
94
65
 
95
- ### Common Output Fields
66
+ | Field | Type | Description |
67
+ | :--------------- | :-------- | :----------------------------------------------------------------------------- |
68
+ | `systemMessage` | `string` | Displayed immediately to the user in the terminal. |
69
+ | `suppressOutput` | `boolean` | If `true`, hides internal hook metadata from logs/telemetry. |
70
+ | `continue` | `boolean` | If `false`, stops the entire agent loop immediately. |
71
+ | `stopReason` | `string` | Displayed to the user when `continue` is `false`. |
72
+ | `decision` | `string` | `"allow"` or `"deny"` (alias `"block"`). Specific impact depends on the event. |
73
+ | `reason` | `string` | The feedback/error message provided when a `decision` is `"deny"`. |
74
+
75
+ ---
96
76
 
97
- | Field | Type | Description |
98
- | :------------------- | :-------- | :------------------------------------------------------------------------------------- |
99
- | `decision` | `string` | One of: `allow`, `deny`, `block`, `ask`, `approve`. |
100
- | `reason` | `string` | Explanation shown to the **agent** when a decision is `deny` or `block`. |
101
- | `systemMessage` | `string` | Message displayed in Gemini CLI terminal to provide warning or context to the **user** |
102
- | `continue` | `boolean` | If `false`, immediately terminates the agent loop for this turn. |
103
- | `stopReason` | `string` | Message shown to the user when `continue` is `false`. |
104
- | `suppressOutput` | `boolean` | If `true`, the hook execution is hidden from the CLI transcript. |
105
- | `hookSpecificOutput` | `object` | Container for event-specific data (see below). |
77
+ ## Tool hooks
78
+
79
+ ### Matchers and tool names
80
+
81
+ For `BeforeTool` and `AfterTool` events, the `matcher` field in your settings is
82
+ compared against the name of the tool being executed.
83
+
84
+ - **Built-in Tools**: You can match any built-in tool (e.g., `read_file`,
85
+ `run_shell_command`). See the [Tools Reference](/docs/tools) for a full list
86
+ of available tool names.
87
+ - **MCP Tools**: Tools from MCP servers follow the naming pattern
88
+ `mcp__<server_name>__<tool_name>`.
89
+ - **Regex Support**: Matchers support regular expressions (e.g.,
90
+ `matcher: "read_.*"` matches all file reading tools).
91
+
92
+ ### `BeforeTool`
93
+
94
+ Fires before a tool is invoked. Used for argument validation, security checks,
95
+ and parameter rewriting.
96
+
97
+ - **Input Fields**:
98
+ - `tool_name`: (`string`) The name of the tool being called.
99
+ - `tool_input`: (`object`) The raw arguments generated by the model.
100
+ - `mcp_context`: (`object`) Optional metadata for MCP-based tools.
101
+ - **Relevant Output Fields**:
102
+ - `decision`: Set to `"deny"` (or `"block"`) to prevent the tool from
103
+ executing.
104
+ - `reason`: Required if denied. This text is sent **to the agent** as a tool
105
+ error, allowing it to respond or retry.
106
+ - `hookSpecificOutput.tool_input`: An object that **merges with and
107
+ overrides** the model's arguments before execution.
108
+ - `continue`: Set to `false` to **kill the entire agent loop** immediately.
109
+ - **Exit Code 2 (Block Tool)**: Prevents execution. Uses `stderr` as the
110
+ `reason` sent to the agent. **The turn continues.**
111
+
112
+ ### `AfterTool`
113
+
114
+ Fires after a tool executes. Used for result auditing, context injection, or
115
+ hiding sensitive output from the agent.
116
+
117
+ - **Input Fields**:
118
+ - `tool_name`: (`string`)
119
+ - `tool_input`: (`object`) The original arguments.
120
+ - `tool_response`: (`object`) The result containing `llmContent`,
121
+ `returnDisplay`, and optional `error`.
122
+ - `mcp_context`: (`object`)
123
+ - **Relevant Output Fields**:
124
+ - `decision`: Set to `"deny"` to hide the real tool output from the agent.
125
+ - `reason`: Required if denied. This text **replaces** the tool result sent
126
+ back to the model.
127
+ - `hookSpecificOutput.additionalContext`: Text that is **appended** to the
128
+ tool result for the agent.
129
+ - `continue`: Set to `false` to **kill the entire agent loop** immediately.
130
+ - **Exit Code 2 (Block Result)**: Hides the tool result. Uses `stderr` as the
131
+ replacement content sent to the agent. **The turn continues.**
106
132
 
107
- ### `hookSpecificOutput` Reference
133
+ ---
108
134
 
109
- | Field | Supported Events | Description |
110
- | :------------------ | :----------------------------------------- | :-------------------------------------------------------------------------------- |
111
- | `additionalContext` | `SessionStart`, `BeforeAgent`, `AfterTool` | Appends text directly to the agent's context. |
112
- | `llm_request` | `BeforeModel` | A `Partial<LLMRequest>` to override parameters of the outgoing call. |
113
- | `llm_response` | `BeforeModel` | A **full** `LLMResponse` to bypass the model and provide a synthetic result. |
114
- | `llm_response` | `AfterModel` | A `Partial<LLMResponse>` to modify the model's response before the agent sees it. |
115
- | `toolConfig` | `BeforeToolSelection` | Object containing `mode` (`AUTO`/`ANY`/`NONE`) and `allowedFunctionNames`. |
135
+ ## Agent hooks
136
+
137
+ ### `BeforeAgent`
138
+
139
+ Fires after a user submits a prompt, but before the agent begins planning. Used
140
+ for prompt validation or injecting dynamic context.
141
+
142
+ - **Input Fields**:
143
+ - `prompt`: (`string`) The original text submitted by the user.
144
+ - **Relevant Output Fields**:
145
+ - `hookSpecificOutput.additionalContext`: Text that is **appended** to the
146
+ prompt for this turn only.
147
+ - `decision`: Set to `"deny"` to block the turn and **discard the user's
148
+ message** (it will not appear in history).
149
+ - `continue`: Set to `false` to block the turn but **save the message to
150
+ history**.
151
+ - `reason`: Required if denied or stopped.
152
+ - **Exit Code 2 (Block Turn)**: Aborts the turn and erases the prompt from
153
+ context. Same as `decision: "deny"`.
154
+
155
+ ### `AfterAgent`
156
+
157
+ Fires once per turn after the model generates its final response. Primary use
158
+ case is response validation and automatic retries.
159
+
160
+ - **Input Fields**:
161
+ - `prompt`: (`string`) The user's original request.
162
+ - `prompt_response`: (`string`) The final text generated by the agent.
163
+ - `stop_hook_active`: (`boolean`) Indicates if this hook is already running as
164
+ part of a retry sequence.
165
+ - **Relevant Output Fields**:
166
+ - `decision`: Set to `"deny"` to **reject the response** and force a retry.
167
+ - `reason`: Required if denied. This text is sent **to the agent as a new
168
+ prompt** to request a correction.
169
+ - `continue`: Set to `false` to **stop the session** without retrying.
170
+ - `clearContext`: If `true`, clears conversation history (LLM memory) while
171
+ preserving UI display.
172
+ - **Exit Code 2 (Retry)**: Rejects the response and triggers an automatic retry
173
+ turn using `stderr` as the feedback prompt.
116
174
 
117
175
  ---
118
176
 
119
- ## Stable Model API
177
+ ## Model hooks
178
+
179
+ ### `BeforeModel`
180
+
181
+ Fires before sending a request to the LLM. Operates on a stable, SDK-agnostic
182
+ request format.
183
+
184
+ - **Input Fields**:
185
+ - `llm_request`: (`object`) Contains `model`, `messages`, and `config`
186
+ (generation params).
187
+ - **Relevant Output Fields**:
188
+ - `hookSpecificOutput.llm_request`: An object that **overrides** parts of the
189
+ outgoing request (e.g., changing models or temperature).
190
+ - `hookSpecificOutput.llm_response`: A **Synthetic Response** object. If
191
+ provided, the CLI skips the LLM call entirely and uses this as the response.
192
+ - `decision`: Set to `"deny"` to block the request and abort the turn.
193
+ - **Exit Code 2 (Block Turn)**: Aborts the turn and skips the LLM call. Uses
194
+ `stderr` as the error message.
195
+
196
+ ### `BeforeToolSelection`
197
+
198
+ Fires before the LLM decides which tools to call. Used to filter the available
199
+ toolset or force specific tool modes.
200
+
201
+ - **Input Fields**:
202
+ - `llm_request`: (`object`) Same format as `BeforeModel`.
203
+ - **Relevant Output Fields**:
204
+ - `hookSpecificOutput.toolConfig.mode`: (`"AUTO" | "ANY" | "NONE"`)
205
+ - `"NONE"`: Disables all tools (Wins over other hooks).
206
+ - `"ANY"`: Forces at least one tool call.
207
+ - `hookSpecificOutput.toolConfig.allowedFunctionNames`: (`string[]`) Whitelist
208
+ of tool names.
209
+ - **Union Strategy**: Multiple hooks' whitelists are **combined**.
210
+ - **Limitations**: Does **not** support `decision`, `continue`, or
211
+ `systemMessage`.
212
+
213
+ ### `AfterModel`
214
+
215
+ Fires immediately after an LLM response chunk is received. Used for real-time
216
+ redaction or PII filtering.
217
+
218
+ - **Input Fields**:
219
+ - `llm_request`: (`object`) The original request.
220
+ - `llm_response`: (`object`) The model's response (or a single chunk during
221
+ streaming).
222
+ - **Relevant Output Fields**:
223
+ - `hookSpecificOutput.llm_response`: An object that **replaces** the model's
224
+ response chunk.
225
+ - `decision`: Set to `"deny"` to discard the response chunk and block the
226
+ turn.
227
+ - `continue`: Set to `false` to **kill the entire agent loop** immediately.
228
+ - **Note on Streaming**: Fired for **every chunk** generated by the model.
229
+ Modifying the response only affects the current chunk.
230
+ - **Exit Code 2 (Block Response)**: Aborts the turn and discards the model's
231
+ output. Uses `stderr` as the error message.
232
+
233
+ ---
120
234
 
121
- Gemini CLI uses a decoupled format for model interactions to ensure hooks remain
122
- stable even if the underlying Gemini SDK changes.
235
+ ## Lifecycle & system hooks
123
236
 
124
- ### `LLMRequest` Object
237
+ ### `SessionStart`
125
238
 
126
- Used in `BeforeModel` and `BeforeToolSelection`.
239
+ Fires on application startup, resuming a session, or after a `/clear` command.
240
+ Used for loading initial context.
127
241
 
128
- > 💡 **Note**: In v1, model hooks are primarily text-focused. Non-text parts
129
- > (like images or function calls) provided in the `content` array will be
130
- > simplified to their string representation by the translator.
242
+ - **Input fields**:
243
+ - `source`: (`"startup" | "resume" | "clear"`)
244
+ - **Relevant output fields**:
245
+ - `hookSpecificOutput.additionalContext`: (`string`)
246
+ - **Interactive**: Injected as the first turn in history.
247
+ - **Non-interactive**: Prepended to the user's prompt.
248
+ - `systemMessage`: Shown at the start of the session.
249
+ - **Advisory only**: `continue` and `decision` fields are **ignored**. Startup
250
+ is never blocked.
251
+
252
+ ### `SessionEnd`
253
+
254
+ Fires when the CLI exits or a session is cleared. Used for cleanup or final
255
+ telemetry.
256
+
257
+ - **Input Fields**:
258
+ - `reason`: (`"exit" | "clear" | "logout" | "prompt_input_exit" | "other"`)
259
+ - **Relevant Output Fields**:
260
+ - `systemMessage`: Displayed to the user during shutdown.
261
+ - **Best Effort**: The CLI **will not wait** for this hook to complete and
262
+ ignores all flow-control fields (`continue`, `decision`).
263
+
264
+ ### `Notification`
265
+
266
+ Fires when the CLI emits a system alert (e.g., Tool Permissions). Used for
267
+ external logging or cross-platform alerts.
268
+
269
+ - **Input Fields**:
270
+ - `notification_type`: (`"ToolPermission"`)
271
+ - `message`: Summary of the alert.
272
+ - `details`: JSON object with alert-specific metadata (e.g., tool name, file
273
+ path).
274
+ - **Relevant Output Fields**:
275
+ - `systemMessage`: Displayed alongside the system alert.
276
+ - **Observability Only**: This hook **cannot** block alerts or grant permissions
277
+ automatically. Flow-control fields are ignored.
278
+
279
+ ### `PreCompress`
280
+
281
+ Fires before the CLI summarizes history to save tokens. Used for logging or
282
+ state saving.
283
+
284
+ - **Input Fields**:
285
+ - `trigger`: (`"auto" | "manual"`)
286
+ - **Relevant Output Fields**:
287
+ - `systemMessage`: Displayed to the user before compression.
288
+ - **Advisory Only**: Fired asynchronously. It **cannot** block or modify the
289
+ compression process. Flow-control fields are ignored.
290
+
291
+ ---
292
+
293
+ ## Stable Model API
294
+
295
+ Gemini CLI uses these structures to ensure hooks don't break across SDK updates.
296
+
297
+ **LLMRequest**:
131
298
 
132
299
  ```typescript
133
300
  {
134
301
  "model": string,
135
302
  "messages": Array<{
136
303
  "role": "user" | "model" | "system",
137
- "content": string | Array<{ "type": string, [key: string]: any }>
304
+ "content": string // Non-text parts are filtered out for hooks
138
305
  }>,
139
- "config"?: {
140
- "temperature"?: number,
141
- "maxOutputTokens"?: number,
142
- "topP"?: number,
143
- "topK"?: number
144
- },
145
- "toolConfig"?: {
146
- "mode"?: "AUTO" | "ANY" | "NONE",
147
- "allowedFunctionNames"?: string[]
148
- }
306
+ "config": { "temperature": number, ... },
307
+ "toolConfig": { "mode": string, "allowedFunctionNames": string[] }
149
308
  }
150
- ```
151
309
 
152
- ### `LLMResponse` Object
310
+ ```
153
311
 
154
- Used in `AfterModel` and as a synthetic response in `BeforeModel`.
312
+ **LLMResponse**:
155
313
 
156
314
  ```typescript
157
315
  {
158
- "text"?: string,
159
316
  "candidates": Array<{
160
- "content": {
161
- "role": "model",
162
- "parts": string[]
163
- },
164
- "finishReason"?: "STOP" | "MAX_TOKENS" | "SAFETY" | "RECITATION" | "OTHER",
165
- "index"?: number,
166
- "safetyRatings"?: Array<{
167
- "category": string,
168
- "probability": string,
169
- "blocked"?: boolean
170
- }>
317
+ "content": { "role": "model", "parts": string[] },
318
+ "finishReason": string
171
319
  }>,
172
- "usageMetadata"?: {
173
- "promptTokenCount"?: number,
174
- "candidatesTokenCount"?: number,
175
- "totalTokenCount"?: number
176
- }
320
+ "usageMetadata": { "totalTokenCount": number }
177
321
  }
178
322
  ```