> ## Documentation Index
> Fetch the complete documentation index at: https://code.claude.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Reagir a eventos com um mod

> Manipule eventos do Claude Code a partir de um mod: observe, reescreva ou responda chamadas de ferramentas, prompts e turnos, filtre quais eventos um hook manipula e planeje para outros mods.

Um hook é um manipulador de eventos: uma função que Claude Code executa quando um evento nomeado acontece. Claude Code dispara um evento em cada ponto onde está prestes a agir, como quando executa uma ferramenta, envia um prompt, faz uma solicitação ao modelo ou inicia ou encerra uma sessão. Seu hook é executado antes de Claude Code agir, portanto pode observar o evento, reescrevê-lo ou respondê-lo no lugar de Claude Code. Você registra um hook com [`on(eventName, handler)`](/docs/pt/plugins/mods/reference#the-hook-function).

Construa seu [primeiro mod](/docs/pt/plugins/mods/create) antes de começar aqui. Para cada evento e seus campos exatos, consulte a [referência](/docs/pt/plugins/mods/reference#events) ou leia [os tipos para sua compilação](/docs/pt/plugins/mods/create#get-the-types-for-your-build).

<h2 id="how-a-hook-handles-an-event">
  Como um hook manipula um evento
</h2>

Um hook fica entre um evento e o que Claude Code faria sobre ele, portanto pode observar o evento, reescrevê-lo ou respondê-lo por si mesmo. Ele recebe três argumentos: a [API de mods](/docs/pt/plugins/mods/api) como `$`, o evento como `e` e o próximo manipulador como `next`. Os manipuladores de um evento formam uma cadeia de middleware. `next(e)` chama o próximo manipulador, que é o hook de outro mod ou, no final da cadeia, o comportamento próprio de Claude Code, e é resolvido para o resultado. O que seu hook faz com `next` decide qual dos três ele faz.

<h3 id="observe-an-event">
  Observe um evento
</h3>

Para observar um evento sem alterá-lo, faça seu trabalho e retorne `next(e)`. Este hook registra cada ferramenta que Claude está prestes a usar:

```javascript theme={null}
on('tool.call', async ($, e, next) => {
  // Executa antes da ferramenta
  $.ui.log('Claude is about to use ' + e.tool)
  // Passe o evento adiante inalterado
  return next(e)
})
```

Antes de cada ferramenta ser executada, uma linha fraca como `● my-mod: Claude is about to use Bash` aparece na transcrição, onde `my-mod` é o nome do seu plugin. A ferramenta é executada como seria sem o mod.

Para agir após o evento, `await next(e)`, faça seu trabalho e retorne o resultado. Este hook registra cada ferramenta após sua execução:

```javascript theme={null}
on('tool.call', async ($, e, next) => {
  // Deixe a ferramenta ser executada e aguarde seu resultado
  const result = await next(e)
  // Executa após a ferramenta
  $.ui.log(e.tool + ' finished')
  // Devolva o resultado inalterado
  return result
})
```

A linha agora aparece após cada ferramenta terminar. Claude lê o mesmo resultado de qualquer forma, porque o hook retorna o que `next(e)` foi resolvido.

<h3 id="rewrite-an-event">
  Reescreva um evento
</h3>

Para alterar o que Claude Code age, como o texto de um prompt, chame `next` com uma cópia modificada do evento. O evento em si é imutável: é congelado em cada profundidade e atribuir a um campo lança um erro. Este hook corta cada prompt antes de ser enviado:

```javascript theme={null}
on('prompt.submit', async ($, e, next) => {
  // Passe uma cópia do evento com seu texto alterado
  return next({ ...e, text: e.text.trim() })
})
```

Manipuladores posteriores e Claude Code recebem o prompt cortado e nunca veem o original. Você também pode alterar o resultado: `await next(e)`, depois retorne uma cópia do resultado com um campo substituído.

<h3 id="answer-an-event">
  Responda a um evento
</h3>

Para manipular um evento você mesmo, retorne um resultado sem chamar `next`. Isso interrompe a cadeia, portanto mods posteriores e o comportamento próprio de Claude Code não são executados. Este hook recusa cada comando Bash:

```javascript theme={null}
on('tool.call', { tool: 'Bash' }, async () => {
  // Nenhuma chamada para next, portanto o comando nunca é executado
  return { deny: 'Bash is turned off in this project. Use the file tools.' }
})
```

Quando Claude tenta um comando Bash, o comando não é executado e Claude lê o texto `deny` como o resultado da ferramenta. Cada evento tem sua própria forma de resultado, que a [referência de eventos](/docs/pt/plugins/mods/reference#events) lista.

<h3 id="filter-which-events-a-hook-handles">
  Filtre quais eventos um hook manipula
</h3>

Para executar um hook apenas para alguns eventos, passe um filtro como o segundo argumento para `on`. Claude Code chama o filtro de matcher. É um objeto cujos campos são comparados com os do evento, e o hook é executado apenas quando cada campo corresponde. Um campo pode ser um valor, uma matriz de valores permitidos ou uma expressão regular.

Cada linha neste exemplo registra a mesma função, `hook`, para um conjunto mais estreito de chamadas de ferramentas:

```javascript theme={null}
// Uma string corresponde a um valor: apenas chamadas Bash
on('tool.call', { tool: 'Bash' }, hook)
// Uma matriz corresponde a qualquer valor nela: chamadas Edit e Write
on('tool.call', { tool: ['Edit', 'Write'] }, hook)
// Uma expressão regular corresponde por padrão: cada ferramenta de um servidor MCP
on('tool.call', { tool: /^mcp__github__/ }, hook)
```

`hook` é executado uma vez para uma chamada Bash, Edit ou Write, e uma vez para uma chamada a uma ferramenta cujo nome começa com `mcp__github__`. Uma chamada para qualquer outra ferramenta, como Read, não corresponde a nenhuma das três, portanto `hook` não é executado para ela.

O nome do evento pode ser um wildcard. `'classic.*'` corresponde a cada [evento de hook de configurações](#hook-the-settings-hook-events). `'*'` corresponde a cada evento exceto os [eventos de telemetria](/docs/pt/plugins/mods/reference#telemetry), que você conecta por nome ou como `'telemetry.*'`.

Registre cada evento uma vez por matcher. Se você chamar `on` duas vezes para `session.start` sem um matcher, o módulo falhará ao carregar com `on("session.start") is registered twice without a matcher`. Coloque tudo o que seu mod faz no início da sessão em um hook.

<h2 id="hook-what-claude-is-doing">
  Hook o que Claude está fazendo
</h2>

Conecte esses eventos para ver ou alterar uma chamada de ferramenta, um prompt ou um turno conforme acontece. Para cada evento e o que um hook pode retornar, consulte a [referência de eventos](/docs/pt/plugins/mods/reference#events).

<h3 id="guard-or-change-a-tool-call">
  Guarde ou altere uma chamada de ferramenta
</h3>

Um hook `tool.call` vê cada ferramenta que Claude está prestes a usar, portanto pode recusar a chamada, alterar seus argumentos ou deixá-la passar. `tool.call` dispara quando Claude Code está prestes a executar uma ferramenta, incluindo chamadas que um subagenteaz e chamadas para ferramentas MCP. `e.tool` é o nome da ferramenta e os argumentos da ferramenta são campos de `e`, como `e.command` para Bash. Quando você chama `next(e)`, Claude Code executa a verificação de permissão e depois a ferramenta.

Este hook recusa um comando Bash que força um push e diz a Claude por quê:

```javascript theme={null}
// O matcher limita o hook a chamadas Bash, portanto e.command é o comando do shell
on('tool.call', { tool: 'Bash' }, async ($, e, next) => {
  if (/git push .*--force/.test(e.command)) {
    // Retornar sem chamar next responde ao evento, portanto o comando nunca é executado
    return { deny: 'Force pushes are not allowed in this repository. Push to a new branch instead.' }
  }
  // Cada outro comando passa para a verificação de permissão e depois para Bash
  return next(e)
})
```

Quando Claude tenta `git push --force`, o comando não é executado e nenhum prompt de permissão aparece, porque o hook nunca chama `next`. Claude lê o texto `deny` como o resultado da ferramenta, portanto escreva-o como uma instrução que Claude pode agir. Cada outro comando Bash é executado como seria sem o mod.

Para agir após uma ferramenta ter sido executada, `await next(e)`, faça seu trabalho e retorne o que `next` lhe deu. Este hook registra cada arquivo `.mdx` que Claude altera, com [`$.ui.log`](/docs/pt/plugins/mods/api#show-something-without-starting-a-turn), que adiciona uma linha fraca à transcrição que Claude não lê:

```javascript theme={null}
on('tool.call', { tool: ['Edit', 'Write'] }, async ($, e, next) => {
  // Aguarde a verificação de permissão e a ferramenta, e mantenha o que produziram
  const result = await next(e)
  // Uma chamada recusada volta como { deny }, e uma falhada tem isError definido
  const changed = !result.deny && !result.isError
  if (changed && e.file_path.endsWith('.mdx')) $.ui.log('Claude changed ' + e.file_path)
  // Retorne o resultado como veio, portanto Claude lê o que a ferramenta retornou
  return result
})
```

Depois que Claude edita ou escreve um arquivo `.mdx`, uma linha fraca na transcrição nomeia o arquivo. Nada é registrado para outro tipo de arquivo ou para uma chamada que foi recusada ou falhou. A visualização de Claude da chamada não muda, porque o hook retorna o resultado que recebeu.

Para alterar uma chamada, passe argumentos alterados para `next`. Para tentar novamente uma chamada, chame `next(e)` novamente: um hook que vê `isError` no primeiro resultado pode executar a ferramenta uma segunda vez e retornar esse resultado. Para responder a uma chamada você mesmo, retorne um objeto com um campo `result`, como `{ result: 'Skipped by my-mod' }`, sem chamar `next`. Quando você faz isso, nenhum prompt de permissão aparece e a ferramenta não é executada, portanto o resultado que você retorna é tudo que Claude aprende sobre o que aconteceu.

Hooks nas [configurações gerenciadas](/docs/pt/server-managed-settings) de sua organização são executados antes de qualquer hook `tool.call` de mod, e um bloqueio de um deles é final.

<h4 id="hold-a-tool-call-until-the-user-decides">
  Mantenha uma chamada de ferramenta até o usuário decidir
</h4>

Um hook pode pausar uma chamada de ferramenta e perguntar ao usuário o que fazer antes de prosseguir. Um hook `tool.call` pode `await` antes de chamar `next` ou retornar, e a chamada de ferramenta permanece pendente até então. Para fazer a pergunta ao usuário, chame `$.ui.ask`. Ele mostra sua pergunta acima de uma lista numerada de suas opções, no diálogo que Claude usa para lhe fazer uma pergunta, e é resolvido para o rótulo que o usuário escolhe. Após suas opções, o diálogo adiciona uma linha para digitar uma resposta diferente e uma linha **Chat about this**.

O padrão `RISKY` neste exemplo corresponde a `rm -r`, `rm -rf`, `git reset --hard` e `git push` com `--force`, e perde outras grafias como `git push -f`. Este módulo pergunta antes de executar um comando Bash que corresponde ao padrão:

```javascript theme={null}
const RISKY = /\brm\s+-rf?\b|\bgit\s+reset\s+--hard\b|\bgit\s+push\b.*--force/

export function register(on) {
  on('tool.call', { tool: 'Bash' }, async ($, e, next) => {
    // Deixe cada outro comando passar sem uma pergunta
    if (!RISKY.test(e.command)) return next(e)
    // Comece a partir da resposta segura, portanto uma pergunta que ninguém responde recusa o comando
    let answer = 'Refuse'
    try {
      // A chamada de ferramenta aguarda aqui até o usuário escolher um dos dois rótulos
      answer = await $.ui.ask('Run this command? ' + e.command, ['Run it', 'Refuse'])
    } catch {
      // O usuário descartou a pergunta ou esta é uma execução claude -p sem ninguém para perguntar
    }
    if (answer !== 'Run it') {
      // Responda sem chamar next, portanto o comando não é executado
      return { deny: 'The user declined this command. Ask before trying a different approach.' }
    }
    return next(e)
  })
}
```

Quando Claude tenta um comando como `rm -rf build`, a pergunta aparece com o comando nela, e o comando aguarda a resposta:

* **O usuário escolhe Run it**: o hook chama `next(e)` e a verificação de permissão usual ainda é executada após ele
* **O usuário escolhe Refuse**: o comando não é executado e Claude lê o texto `deny`
* **O usuário digita uma resposta**: `$.ui.ask` é resolvido para o texto digitado. O hook o compara com `Run it`, portanto qualquer outro texto recusa o comando.
* **Ninguém responde**: `$.ui.ask` rejeita quando o usuário descarta a pergunta ou escolhe **Chat about this**, e em uma execução `claude -p`, portanto o bloco `catch` deixa a resposta em `Refuse`

Mantenha a espera dentro de uma chamada de API de mods como `$.ui.ask`, porque esse tempo não conta contra o [limite de tempo de 10 segundos](/docs/pt/plugins/mods/reference#limits) do hook. O tempo gasto aguardando uma promessa sua conta. Claude Code pula um hook que expira, portanto o comando mantido seria executado.

<h3 id="rewrite-or-add-to-a-prompt">
  Reescreva ou adicione a um prompt
</h3>

Um hook `prompt.submit` vê cada prompt antes do turno começar, portanto pode reescrever o texto ou adicionar a ele. `e.text` é o que foi digitado.

| Para fazer isso | Retorne isto |
| :- | :- |
| Reescreva o prompt. A mensagem na transcrição mostra o novo texto. | `next({ ...e, text: newText })` |
| Adicione texto apenas que Claude lê, após o prompt | `next({ ...e, context: [...(e.context ?? []), extraText] })` |
| Impeça que o prompt seja enviado | `{ drop: 'the reason' }` |

Este hook adiciona o nome da ramificação atual para Claude sempre que um prompt menciona uma solicitação de pull:

```javascript theme={null}
on('prompt.submit', async ($, e, next) => {
  // Passe um prompt que não menciona uma solicitação de pull como está
  if (!/\bPR\b|pull request/i.test(e.text)) return next(e)
  const git = await $.process.run(['git', 'branch', '--show-current'])
  // Fora de um repositório git o comando falha, portanto não há ramificação para adicionar
  if (git.exitCode !== 0) return next(e)
  // Mantenha qualquer contexto que um hook anterior adicionou e adicione mais uma linha para Claude
  return next({ ...e, context: [...(e.context ?? []), 'Current branch: ' + git.stdout.trim()] })
})
```

Quando você envia um prompt como `open a PR for this change`, sua mensagem parece a mesma na transcrição e Claude também lê uma linha como `Current branch: feature/auth` após ela. Um prompt que não menciona uma solicitação de pull passa inalterado e `git` não é executado.

[Outros eventos](/docs/pt/plugins/mods/reference#prompts-and-what-claude-reads) cobrem o resto do que Claude lê: `prompt.section` para cada seção do prompt do sistema, `prompt.context` para o contexto enviado com a primeira mensagem e `skill.prompt` para o texto de uma skill. Texto desses hooks que muda entre solicitações [invalida o cache de prompt](/docs/pt/prompt-caching).

<h3 id="follow-a-turn">
  Siga um turno
</h3>

Um turno é tudo o que Claude faz em resposta a um prompt. Conecte `turn.start`, `turn.step` e `turn.complete` para seguir um:

| Evento | Quando dispara | O que um hook pode fazer |
| :- | :- | :- |
| `turn.start` | Um turno começa | Observe. `e.turnId` identifica o turno nos outros dois eventos. |
| `turn.step` | Claude Code está prestes a enviar uma solicitação ao modelo. Um turno com chamadas de ferramentas tem várias. `e.agentId` é definido para uma solicitação de um subagenteaz. | Leia o uso de token de cada solicitação, envie-o para um modelo diferente com `next({ ...e, model })` ou responda sem chamar o modelo |
| `turn.complete` | O turno terminou, incluindo um turno que o usuário interrompeu, onde `e.isAborted` é `true`. `e.answer` é o texto final de Claude, `e.durationMs` quanto tempo levou e `e.usage` os totais de token do turno. Um turno de um subagenteaz dispara com `e.agentId` definido. | Observe ou retorne um objeto com um campo `text`, como `{ text: 'Done in 12 seconds' }`, para mostrar uma linha sob a resposta |

Escreva um hook `turn.step` como um gerador assíncrono, porque o evento flui. `yield* next(e)` encaminha a resposta conforme flui e é avaliado para o resultado terminado. Este hook registra quanto de cada solicitação a API Claude serviu do [cache de prompt](/docs/pt/prompt-caching):

```javascript theme={null}
// function* torna o hook um gerador, que pode passar a resposta adiante pedaço por pedaço
on('turn.step', async function* ($, e, next) {
  // Envie a solicitação, encaminhe cada pedaço conforme chega e mantenha o resultado terminado
  const result = yield* next(e)
  // Pule um resultado que não relata contagens de token
  if (result.usage) {
    $.ui.log('cache read ' + result.usage.cache_read_input_tokens + ' · wrote ' + result.usage.cache_creation_input_tokens)
  }
  // Retorne o resultado inalterado, portanto o turno continua como usual
  return result
})
```

A resposta de Claude flui para a tela como faria sem o mod. Após cada solicitação terminar, uma linha fraca na transcrição fornece o número de tokens lidos do cache e o número escrito nele. Um turno com chamadas de ferramentas tem várias solicitações, portanto adiciona várias linhas.

`result.usage` contém as quatro contagens de token que a API Claude relata para uma solicitação, mais o `model` que respondeu: `input_tokens`, `output_tokens`, `cache_read_input_tokens` e `cache_creation_input_tokens`. O hook é executado para solicitações de subagenteaz também, portanto verifique `e.agentId` quando você quer apenas a conversa principal.

<h3 id="hook-the-settings-hook-events">
  Hook os eventos de hook de configurações
</h3>

Hooks de configurações são os hooks de comando, HTTP, prompt e agente que você configura em arquivos de configurações. Cada [evento de hook de configurações](/docs/pt/hooks#hook-events), como `Stop`, `SessionEnd` ou `PostToolUse`, também é um evento nomeado `classic.` seguido pelo nome do evento de hook de configurações, como `classic.Stop`. `e` é o JSON que um hook de configurações recebe em stdin, incluindo `transcript_path`.

Este hook usa `Stop`, que dispara quando Claude termina de responder, para registrar onde a transcrição da sessão é salva:

```javascript theme={null}
on('classic.Stop', async ($, e, next) => {
  // e tem os mesmos campos que um hook Stop em um arquivo de configurações lê de stdin
  $.ui.log('Transcript saved at ' + e.transcript_path)
  // Passe o evento adiante, portanto hooks Stop em seus arquivos de configurações ainda são executados
  return next(e)
})
```

Cada vez que Claude termina de responder, uma linha fraca na transcrição fornece o caminho do arquivo de transcrição. O hook retorna `next(e)`, portanto observa o evento e não muda nada sobre como o turno termina.

<h2 id="run-alongside-other-mods">
  Execute ao lado de outros mods
</h2>

Vários mods podem conectar o mesmo evento e qualquer um deles pode falhar. Se seu mod bloqueia chamadas de ferramentas, verifique sua posição na cadeia e o que acontece quando seu hook falha.

<h3 id="the-order-mods-run-in">
  A ordem em que os mods são executados
</h3>

Hooks no mesmo evento formam uma cadeia de middleware. Cada `next` de um mod chama o hook do mod seguinte, e o último `next` atinge o comportamento próprio de Claude Code. O primeiro mod é o mais externo: vê o evento antes dos outros e o resultado após eles, e decide se os outros são executados. Um mod posterior não pode impedir que um anterior veja um evento.

Claude Code ordena a cadeia por onde cada mod vem:

1. O guard integrado `sec-default@builtin`, um mod integrado em Claude Code que `/plugin` lista como `cc-plugin-sec-default`, onde [ele carrega](/docs/pt/plugins/mods/admin#know-what-happens-by-default), mods que sua organização lista em [`prependPlugins`](/docs/pt/plugins/mods/admin#install-your-organizations-mods) e depois qualquer outro mod que conta como de sua organização e não está em `appendPlugins`
2. Mods que você instala
3. Mods que sua organização lista em `appendPlugins`
4. Outros mods integrados em Claude Code

Entre os mods que você instala, um mod é executado antes dos mods que lista em `dependencies` em seu manifesto. Dentro de um módulo, hooks são executados na ordem em que `register` chamou `on`.

<h4 id="where-settings-hooks-run-in-the-order">
  Onde hooks de configurações são executados na ordem
</h4>

Os hooks `PreToolUse` configurados em arquivos de configurações também são executados durante uma chamada de ferramenta, em pontos fixos na cadeia de mods:

* **Hooks `PreToolUse` de configurações gerenciadas**: são executados antes do hook `tool.call` do primeiro mod, e um bloqueio de um deles é final, portanto nenhum mod vê a chamada.
* **Hooks `PreToolUse` de cada outro arquivo de configurações e de `hooks/hooks.json` de plugins**: são executados após o último mod chamar `next`, como parte do comportamento próprio de Claude Code. Um mod que responde `tool.call` sem chamar `next` os impede de serem executados, e um mod que chama `next` vê sua decisão no resultado que retorna.

[`tool.check`](/docs/pt/plugins/mods/reference#tools) é o evento onde Claude Code decide se uma chamada de ferramenta pode ser executada. Dispara após esses hooks e as regras de permissão terem decidido, e `next(e)` é resolvido para sua decisão. Um hook em `tool.check` pode retornar uma decisão diferente, como `{ decision: 'allow' }`, portanto pode aprovar uma chamada que um hook no segundo grupo bloqueou. [Estenda permissões com hooks](/docs/pt/permissions#extend-permissions-with-hooks) lista quais decisões prevalecem sobre um mod.

<h3 id="handle-a-hook-that-fails">
  Manipule um hook que falha
</h3>

Um hook que falha não quebra a sessão e você pode decidir o que acontece em seu lugar. Quando um hook sem um manipulador `.catch` lança, expira ou retorna um resultado da forma errada, o que acontece a seguir depende se ele tinha chamado `next`:

* **Falhou antes de chamar `next`**: Claude Code o pula e o próximo manipulador é executado em seu lugar
* **Falhou após `next` ser resolvido**: esse resultado permanece e nada é executado uma segunda vez

Uma linha nomeia o mod, o evento e o motivo, como `my-mod: tool.call hook skipped: threw Error: boom`. Onde você o lê depende da sessão, como [Descubra por que um mod não faz nada](/docs/pt/plugins/mods/troubleshoot#find-out-why-a-mod-does-nothing) lista. Um hook `ui.render` cujo desenho não valida é relatado diferentemente, como [Construa uma árvore a partir de elementos](/docs/pt/plugins/mods/interface#build-a-tree-from-elements) descreve.

Para fazer um hook que bloqueia chamadas falhar fechado, adicione um manipulador de erro `.catch` que responda em seu lugar. Aqui, `guard` é sua função de hook:

```javascript theme={null}
// on retorna um registro e .catch anexa um manipulador a esse hook
on('tool.call', { tool: 'Bash' }, guard).catch(async ($, e, next) => {
  // next.error.kind é 'throw' ou 'timeout', que diz como guard falhou
  return { deny: 'The command guard failed, so this command was not run: ' + next.error.kind }
})
```

Enquanto `guard` funciona, o manipulador nunca é executado. Quando `guard` lança ou expira em uma chamada Bash, Claude Code chama o manipulador com o mesmo evento. O manipulador retorna `{ deny }`, portanto o comando não é executado e Claude lê o texto com `throw` ou `timeout` no final. Sem o manipulador, Claude Code pularia `guard` e executaria o comando. O manipulador tem [um segundo](/docs/pt/plugins/mods/reference#limits) para responder.

<h2 id="next-steps">
  Próximos passos
</h2>

* [Use a API de mods](/docs/pt/plugins/mods/api): adicione comandos e ferramentas, chame um modelo e execute trabalho em um temporizador
* [Desenhe na interface](/docs/pt/plugins/mods/interface): mostre o que seus hooks coletam em um painel ou acima do prompt
* [Teste um mod](/docs/pt/plugins/mods/test): levante qualquer um desses eventos de um teste
* [Referência de mods](/docs/pt/plugins/mods/reference): cada evento, cada método de API de mods e os limites
