Hooks
Hooks são handlers executados automaticamente em resposta a eventos do ciclo de vida do agente. Com hooks você pode:
- Formatar código após edições
- Bloquear operações perigosas antes de executar
- Enviar notificações quando o agente termina
- Fazer recovery automático em caso de falhas
- Auditar todas as ferramentas chamadas
Configurar hooks
Hooks são definidos em settings.json ou settings.local.json:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write|FileWrite",
"hooks": [
{
"type": "command",
"command": "prettier --write {{file}}"
}
]
}
]
}
}Use /update-config para configurar hooks com verificação automática em 7 passos.
Eventos disponíveis
| Evento | Quando dispara |
|---|---|
PermissionRequest |
Antes de solicitar permissão ao usuário para uma ferramenta |
PreToolUse |
Imediatamente antes de executar qualquer ferramenta |
PostToolUse |
Imediatamente após a ferramenta retornar (sucesso ou falha) |
PreCompact |
Antes de compactar o contexto da conversa |
PostCompact |
Após compactação concluída |
Stop |
Quando o agente termina a resposta |
Notification |
Quando o agente precisa notificar o usuário |
SessionStart |
No início de uma nova sessão |
UserPromptSubmit |
Quando o usuário envia um prompt |
Tipos de hook
`command` — shell script
Executa um comando shell. O hook recebe um JSON via stdin e pode retornar um JSON via stdout para influenciar o comportamento do agente.
{
"type": "command",
"command": "bash /home/user/.verboo/hooks/lint-on-edit.sh"
}Formato de entrada (stdin):
{
"event": "PostToolUse",
"tool_name": "Edit",
"tool_input": { "file_path": "/src/main.ts", "... " },
"tool_result": { "... " }
}Formato de saída (stdout) — opcional:
{
"continue": true,
"decision": "approve",
"reason": "Arquivo formatado com sucesso"
}`prompt` — avaliação por LLM
Usa um modelo de linguagem para avaliar se a operação deve continuar:
{
"type": "prompt",
"prompt": "O comando abaixo é seguro de executar? Responda apenas 'allow' ou 'deny'.\n\nComando: {{command}}"
}`http` — POST para URL
Faz um POST HTTP para uma URL externa:
{
"type": "http",
"url": "https://hooks.slack.com/services/XXX/YYY/ZZZ",
"headers": {
"Content-Type": "application/json",
"Authorization": "Bearer ${SLACK_TOKEN}"
},
"body": {
"text": "Agente finalizou: {{TASK_SUBJECT}}"
}
}Variáveis de ambiente são expandidas com ${VAR}. Template variables do contexto são expandidas com {{VAR}}.
`agent` — verificação agêntica
Invoca um sub-agente para verificar a operação:
{
"type": "agent",
"prompt": "Verifique se a edição em {{file_path}} não introduz vulnerabilidades de segurança."
}Campos do hook
| Campo | Tipo | Descrição |
|---|---|---|
type |
string | command, prompt, http, agent |
command |
string | Comando shell (apenas command) |
url |
string | URL do endpoint (apenas http) |
prompt |
string | Prompt do modelo (apenas prompt, agent) |
headers |
object | Headers HTTP (apenas http) |
body |
object | Body da requisição (apenas http) |
timeout |
number | Timeout em ms (padrão: 10000) |
statusMessage |
string | Mensagem exibida enquanto o hook roda |
once |
bool | Executa apenas uma vez por sessão |
async |
bool | Executa em background sem bloquear o agente |
asyncRewake |
bool | Rewake o agente quando o hook async terminar |
if |
string | Condição para execução (sintaxe de permission rule) |
Hook matchers
O campo matcher é um padrão que filtra em qual ferramenta o hook dispara:
{
"matcher": "Bash|Edit|Write",
"hooks": [...]
}Padrões suportados:
- Nome exato:
"Edit" - Alternância:
"Edit|Write|FileWrite" - Wildcard:
"*"(todos os tools) - Negação com
if:"if": "not tool_name:Bash"
Saída do hook (decisão)
Hooks do tipo command podem retornar um JSON para controlar o agente:
{
"continue": false,
"decision": "block",
"reason": "Operação bloqueada: destino fora do diretório autorizado",
"stopReason": "Política de segurança violada"
}| Campo | Valores | Descrição |
|---|---|---|
continue |
true/false |
Se false, aborta a operação |
decision |
approve, deny, block |
Decisão explícita |
reason |
string | Explicação exibida ao usuário |
stopReason |
string | Mensagem de parada (quando continue: false) |
Exemplos práticos
Formatar código após edição
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "prettier --write \"{{tool_input.file_path}}\" 2>/dev/null || true",
"async": true
}
]
}
]
}
}Bloquear comandos rm perigosos
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "bash -c 'echo $HOOK_INPUT | jq -r .tool_input.command | grep -qE \"rm -rf /\" && echo \\'{ \"continue\": false, \"reason\": \"rm -rf / bloqueado\" }\\' || echo \\'{ \"continue\": true }\\''"
}
]
}
]
}
}Notificação Slack ao finalizar
{
"hooks": {
"Stop": [
{
"matcher": "*",
"hooks": [
{
"type": "http",
"url": "https://hooks.slack.com/services/T.../B.../XXX",
"body": {
"text": "Verboo Code finalizou: {{TASK_SUBJECT}}"
}
}
]
}
]
}
}Auditoria de comandos bash
{
"hooks": {
"PostToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "echo \"$(date): $HOOK_INPUT\" >> ~/.verboo-audit.log",
"async": true
}
]
}
]
}
}Hook Chains
Hook Chains são regras de recovery automático disparadas por outcomes de ferramentas ou tarefas.
Configuração
{
"hookChains": {
"version": 1,
"enabled": true,
"maxChainDepth": 2,
"defaultCooldownMs": 30000,
"rules": [
{
"id": "retry-on-bash-fail",
"enabled": true,
"trigger": {
"event": "PostToolUse",
"outcome": "failed"
},
"condition": {
"toolNames": ["Bash"],
"errorIncludes": "ECONNREFUSED"
},
"actions": [
{
"type": "spawn_fallback_agent",
"prompt": "O comando falhou com ECONNREFUSED. Verifique se o serviço está rodando e tente novamente."
}
]
}
]
}
}Campos da regra
| Campo | Descrição |
|---|---|
id |
Identificador único da regra |
enabled |
Liga/desliga a regra |
trigger.event |
Evento que dispara (ex: PostToolUse, TaskCompleted) |
trigger.outcome |
success, failed, timeout, unknown |
condition.toolNames |
Lista de ferramentas que ativam a regra |
condition.errorIncludes |
Substring no erro |
cooldownMs |
Mínimo de ms entre disparos (padrão: 30000) |
dedupWindowMs |
Janela de deduplicação (padrão: 30000) |
maxDepth |
Profundidade máxima de chains (padrão: 2, máx: 10) |
actions |
Array de ações a executar |
Tipos de ação
| Tipo | Descrição |
|---|---|
spawn_fallback_agent |
Dispara um agente de recuperação |
notify_team |
Notifica o time configurado |
warm_remote_capacity |
Pré-aquece capacidade remota |
Template variables nas ações
| Variável | Valor |
|---|---|
{{EVENT_NAME}} |
Nome do evento |
{{OUTCOME}} |
Outcome do evento |
{{RULE_ID}} |
ID da regra |
{{TASK_SUBJECT}} |
Assunto da tarefa |
{{ERROR}} |
Mensagem de erro |
{{PAYLOAD_JSON}} |
JSON completo do evento |
Hook Chains são desabilitados por padrão. Habilite gradualmente por ambiente após validar o comportamento.