diff --git a/packages/cli/src/ui/components/views/HooksList.tsx b/packages/cli/src/ui/components/views/HooksList.tsx index 1fe3ca71d5..c2b8d8a7d7 100644 --- a/packages/cli/src/ui/components/views/HooksList.tsx +++ b/packages/cli/src/ui/components/views/HooksList.tsx @@ -6,6 +6,7 @@ import type React from 'react'; import { Box, Text } from 'ink'; +import { theme } from '../../semantic-colors.js'; interface HooksListProps { hooks: ReadonlyArray<{ @@ -24,79 +25,105 @@ interface HooksListProps { }>; } -export const HooksList: React.FC = ({ hooks }) => { - if (hooks.length === 0) { - return ( - - No hooks configured. - - ); - } +export const HooksList: React.FC = ({ hooks }) => ( + + + Hooks are scripts or programs that Gemini CLI executes at specific points + in the agentic loop, allowing you to intercept and customize behavior. + - // Group hooks by event name for better organization - const hooksByEvent = hooks.reduce( - (acc, hook) => { - if (!acc[hook.eventName]) { - acc[hook.eventName] = []; - } - acc[hook.eventName].push(hook); - return acc; - }, - {} as Record>, - ); - - return ( - - Configured Hooks: - - {Object.entries(hooksByEvent).map(([eventName, eventHooks]) => ( - - - {eventName}: - - - {eventHooks.map((hook, index) => { - const hookName = - hook.config.name || hook.config.command || 'unknown'; - const statusColor = hook.enabled ? 'green' : 'gray'; - const statusText = hook.enabled ? 'enabled' : 'disabled'; - - return ( - - - - {hookName} - {` [${statusText}]`} - - - - {hook.config.description && ( - {hook.config.description} - )} - - Source: {hook.source} - {hook.config.name && - hook.config.command && - ` | Command: ${hook.config.command}`} - {hook.matcher && ` | Matcher: ${hook.matcher}`} - {hook.sequential && ` | Sequential`} - {hook.config.timeout && - ` | Timeout: ${hook.config.timeout}s`} - - - - ); - })} - - - ))} - - - - Tip: Use `/hooks enable {''}` or `/hooks disable{' '} - {''}` to toggle hooks - - + + + ⚠️ Security Warning: + + + Hooks can execute arbitrary commands on your system. Only use hooks from + sources you trust. Review hook scripts carefully. + - ); -}; + + + + Learn more:{' '} + https://geminicli.com/docs/hooks + + + + + {hooks.length === 0 ? ( + No hooks configured. + ) : ( + <> + + Registered Hooks: + + + {Object.entries( + hooks.reduce( + (acc, hook) => { + if (!acc[hook.eventName]) { + acc[hook.eventName] = []; + } + acc[hook.eventName].push(hook); + return acc; + }, + {} as Record>, + ), + ).map(([eventName, eventHooks]) => ( + + + {eventName}: + + + {eventHooks.map((hook, index) => { + const hookName = + hook.config.name || hook.config.command || 'unknown'; + const statusColor = hook.enabled ? 'green' : 'gray'; + const statusText = hook.enabled ? 'enabled' : 'disabled'; + + return ( + + + + {hookName} + {` [${statusText}]`} + + + + {hook.config.description && ( + + {hook.config.description} + + )} + + Source: {hook.source} + {hook.config.name && + hook.config.command && + ` | Command: ${hook.config.command}`} + {hook.matcher && ` | Matcher: ${hook.matcher}`} + {hook.sequential && ` | Sequential`} + {hook.config.timeout && + ` | Timeout: ${hook.config.timeout}s`} + + + + ); + })} + + + ))} + + + )} + + + + + Tip: Use `/hooks enable {''}` or `/hooks disable{' '} + {''}` to toggle hooks + + + +);