# Hooks no Claude Code para iniciantes: automatizando ações repetitivas

> Guia prático completo sobre a configuração de Hooks no Claude Code: linting automático, formatação, verificações de segurança antes do commit, notificações e automação headless.

## 1. O que são Hooks no Claude Code e por que eles são necessários

Ao trabalhar com um assistente de IA no terminal, os desenvolvedores frequentemente se veem repetindo as mesmas rotinas: *"agora execute o ESLint"*, *"formate o código com Prettier"*, *"verifique os tipos antes do commit"*. Mesmo que essas regras sejam definidas nas instruções do sistema `CLAUDE.md`, o modelo de linguagem pode ocasionalmente esquecer de executá-las ou ignorá-las para economizar tokens.

**Hooks** no Claude Code resolvem esse problema radicalmente: são gatilhos determinísticos que chamam automaticamente comandos do sistema ou scripts em momentos precisos do ciclo de vida da operação do assistente.

A lógica dos hooks é simples:
> **Se o Claude executou o evento X → o sistema operacional garante a execução da ação Y.**

```mermaid
flowchart LR
    subgraph Текстова_інструкція["CLAUDE.md (Ймовірнісна)"]
        A["Промпт: 'Завжди запускай лінтер'"] --> B{"Модель пам'ятає?"}
        B -->|Іноді| C["Запуск перевірки"]
        B -->|Пропустила| D["Помилки накопичуються"]
    end
    subgraph Нативний_Hook["Hooks у settings.json (Детермінована)"]
        E["Подія: Редагування файлу"] --> F["Автоматичний тригер ОС"]
        F --> G["Гарантоване виконання npx eslint"]
    end
```

### Comparação das abordagens de automação

| Característica | Prompts manuais | Instruções no CLAUDE.md | Hooks nativos |
| :--- | :--- | :--- | :--- |
| **Confiabilidade de execução** | Baixa (depende da memória humana) | Média (comportamento probabilístico do LLM) | 100% (interceptação determinística de eventos) |
| **Consumo de tokens** | Alto (tokens gastos a cada solicitação) | Médio (a regra é carregada em cada contexto) | Zero (executado localmente no shell) |
| **Velocidade de resposta** | Lenta (entrada manual de comandos) | Requer uma rodada adicional de geração | Instantânea (chamada nativa de processo) |
| **Capacidade de bloqueio** | Inexistente | Inexistente | Sim (exit code não-zero interrompe a ação) |

> [!NOTE]
> Os Hooks do Claude Code são configurados em formato JSON no arquivo `.claude/settings.json` no nível do repositório individual ou globalmente em `~/.claude/settings.json`.

---

## 2. Ciclo de vida de eventos: PreToolUse, PostToolUse, Notification, Stop

O Claude Code oferece quatro pontos fundamentais de interceptação (eventos) aos quais você pode vincular comandos automatizados.

```mermaid
sequenceDiagram
    autonumber
    actor Dev as Розробник
    participant Agent as Claude Code
    participant Hook as Система Hooks
    participant Tool as Інструмент (Bash/Edit/Write)

    Dev->>Agent: Запит на модифікацію коду
    Agent->>Hook: Спроба виклику інструмента
    Note over Hook: PreToolUse Hook
    Hook-->>Agent: Перевірка пройдена (Exit Code 0)
    Agent->>Tool: Виконання операції
    Tool-->>Agent: Результат успішний
    Agent->>Hook: Подія завершення операції
    Note over Hook: PostToolUse Hook
    Hook-->>Agent: Результат лінтингу / форматування
    Agent->>Hook: Завершення відповіді моделі
    Note over Hook: Stop Hook (Сповіщення)
    Agent-->>Dev: Фінальна відповідь
```

### Principais pontos de disparo

1. **`PreToolUse` (Antes do uso da ferramenta):** dispara *antes* que o agente execute uma ação. Se o comando do hook retornar um erro (exit code diferente de 0), a execução da ação é bloqueada. Este é o lugar ideal para verificações de segurança antes de commits ou pushes.
2. **`PostToolUse` (Após o uso da ferramenta):** dispara *imediatamente após* a execução bem-sucedida da ferramenta. É o gatilho mais popular para formatação automática de código (Prettier) ou linting do arquivo modificado (ESLint).
3. **`Notification` (Notificação):** ativa-se quando o assistente precisa enviar uma mensagem importante do sistema ou solicitar autorização adicional.
4. **`Stop` (Fim da resposta):** dispara no momento em que o Claude Code termina completamente a geração da resposta e aguarda a próxima mensagem do usuário. Usado para reproduzir sinais sonoros e notificações desktop.

![Pontos de disparo dos Hooks no ciclo de vida](/api/guides-media/automation/hooks-automation-guide-for-beginners/images/hooks-automation-guide-for-beginners-extra-02.webp)

---

## 3. Estrutura de configuração no settings.json e sintaxe do Matcher

A configuração dos hooks é armazenada no arquivo `.claude/settings.json`. Se este arquivo ainda não existir na raiz do seu projeto, crie-o.

### Sintaxe básica de configuração

```json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Edit",
        "hooks": [
          {
            "type": "command",
            "command": "echo 'Починається редагування файлу...'"
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "echo 'Bash-команда завершена успішно'"
          }
        ]
      }
    ]
  }
}
```

### Como funciona o campo Matcher

O campo `matcher` define a qual ferramenta específica do agente o hook deve reagir:

- `"Edit"` — intercepta a modificação de arquivos já existentes.
- `"Write"` — dispara ao criar um novo arquivo ou sobrescrevê-lo totalmente.
- `"Bash"` — reage à execução de qualquer comando de console.
- `"Bash(git commit*)"` — template preciso que filtra chamadas Bash iniciadas pelo comando `git commit`.
- `"*"` — seletor universal (wildcard), que dispara para qualquer ferramenta do agente.

> [!TIP]
> Os templates `matcher` são sensíveis a maiúsculas/minúsculas. Use os nomes padrão das ferramentas do Claude Code: `Edit`, `Write`, `Bash`, `Glob`, `Grep`.

---

## 4. Linting e formatação automáticos (ESLint + Prettier)

O cenário diário mais prático é delegar a formatação e a verificação primária de estilo às utilitários `Prettier` e `ESLint`. Isso garante que o código seja sempre salvo no repositório em estado perfeito.

### Configuração do PostToolUse para ESLint e Prettier

```json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit",
        "hooks": [
          {
            "type": "command",
            "command": "npx eslint --fix \"$CLAUDE_FILE_PATH\" 2>/dev/null || true"
          }
        ]
      },
      {
        "matcher": "Write",
        "hooks": [
          {
            "type": "command",
            "command": "npx prettier --write \"$CLAUDE_FILE_PATH\" 2>/dev/null || true"
          }
        ]
      }
    ]
  }
}
```

### Análise das flags de segurança no comando

- `"$CLAUDE_FILE_PATH"` — variável de ambiente dinâmica onde o Claude insere automaticamente o caminho completo do arquivo recém-modificado pelo agente.
- `2>/dev/null` — suprime a saída excessiva de erros do fluxo stderr para não sobrecarregar o terminal.
- `|| true` — construção bash crucial. Garante que, mesmo se o linter encontrar erros irreparáveis e retornar código `1`, o hook termine com código `0` e não pare o trabalho subsequente do agente.

```mermaid
flowchart TD
    A["Claude викликає Edit"] --> B["Файл збережено на диску"]
    B --> C["PostToolUse тригер"]
    C --> D["npx eslint --fix $CLAUDE_FILE_PATH"]
    D --> E{"Успішно або || true"}
    E --> F["Агент продовжує вирішувати задачу"]
```

---

## 5. Barreiras de proteção antes do git commit (TypeCheck + Testes)

Se usamos hooks "suaves" com `|| true` para formatação, para fixar mudanças no controle de versão é necessário um controle rigoroso de qualidade (Quality Gate).

Usando `PreToolUse`, você pode bloquear a criação de um commit se houver erros de compilação TypeScript ou falhas nos testes unitários no projeto.

### Configuração do hook Pre-commit bloqueador

```json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash(git commit*)",
        "hooks": [
          {
            "type": "command",
            "command": "npm run typecheck && npm run lint"
          }
        ]
      }
    ]
  }
}
```

### O que acontece quando erros são detectados

1. O Claude formula o comando `git commit -m "..."`.
2. Antes de sua execução, o sistema ativa o `PreToolUse`.
3. Os comandos de validação são executados: `npm run typecheck` e `npm run lint`.
4. **Se um erro for encontrado:** o processo retorna um código de saída não-zero (exit code 1).
5. O Claude Code intercepta a saída do erro do compilador diretamente em seu contexto.
6. Em vez de um commit quebrado, o assistente analisa o texto do erro, corrige automaticamente os tipos no código e faz uma nova tentativa limpa de commit.

> [!IMPORTANT]
> Atenção: nas verificações bloqueadoras de `PreToolUse`, **nunca** use `|| true`, caso contrário, a verificação será sempre considerada bem-sucedida e a barreira de proteção deixará de funcionar.

---

## 6. Notificações de áudio e desktop ao concluir tarefas (Stop Hook)

Refatorações complexas ou a execução de suítes completas de testes podem levar de 2 a 10 minutos. Em vez de ficar olhando fixamente para o terminal, configure notificações através do evento `Stop`.

:::tabs
@tab macOS
```json
{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "afplay /System/Library/Sounds/Glass.aiff && osascript -e 'display notification \"Завдання виконано!\" with title \"Claude Code\"'"
          }
        ]
      }
    ]
  }
}
```
@tab Linux (Ubuntu / Debian)
```json
{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "paplay /usr/share/sounds/freedesktop/stereo/complete.oga 2>/dev/null || notify-send 'Claude Code' 'Завдання успішно виконано!'"
          }
        ]
      }
    ]
  }
}
```
@tab Windows (WSL / PowerShell)
```json
{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "powershell.exe -c \"[System.Media.SystemSounds]::Asterisk.Play(); [System.Console]::Beep(800, 250)\""
          }
        ]
      }
    ]
  }
}
```
:::

> [!TIP]
> A notificação dispara apenas quando o agente conclui completamente a geração da resposta final, e não entre chamadas intermediárias de ferramentas.

---

## 7. Passagem de contexto através de variáveis de ambiente

Para que os scripts de automação sejam flexíveis e adaptativos, o Claude Code exporta automaticamente metadados da operação atual para variáveis de ambiente do sistema (Environment Variables).

![Variáveis de ambiente do Claude Code para hooks](/api/guides-media/automation/hooks-automation-guide-for-beginners/images/hooks-automation-guide-for-beginners-extra-01.webp)

### Referência das variáveis de sistema do Claude Code

| Variável de ambiente | Tipo de valor | Descrição e exemplo de conteúdo |
| :--- | :--- | :--- |
| **`$CLAUDE_FILE_PATH`** | Caminho absoluto | Caminho para o arquivo específico sendo criado ou editado (`/Users/dev/project/src/index.ts`) |
| **`$CLAUDE_TOOL_NAME`** | Identificador textual | Nome da ferramenta que iniciou o evento (`Edit`, `Write`, `Bash`) |
| **`$CLAUDE_PROJECT_DIR`** | Caminho absoluto | Diretório raiz do projeto onde a sessão atual do Claude Code está rodando |

### Exemplo de script Bash contextual para um hook

Crie o script `.claude/hooks/smart-validator.sh`:

```bash
#!/usr/bin/env bash
set -e

# Перевіряємо, чи існує файл і яке у нього розширення
if [[ -f "$CLAUDE_FILE_PATH" ]]; then
  case "$CLAUDE_FILE_PATH" in
    *.ts|*.tsx)
      echo "⚡ Валідація TypeScript файлу: $CLAUDE_FILE_PATH"
      npx eslint --fix "$CLAUDE_FILE_PATH" || true
      ;;
    *.json)
      echo "🔍 Перевірка валідності JSON..."
      jq empty "$CLAUDE_FILE_PATH" 2>/dev/null || echo "Помилка формату JSON!"
      ;;
    *.md)
      echo "📝 Оновлено документацію: $(basename "$CLAUDE_FILE_PATH")"
      ;;
  esac
fi
```

Agora, no `.claude/settings.json`, basta indicar a chamada deste script:

```json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "*",
        "hooks": [
          {
            "type": "command",
            "command": "bash .claude/hooks/smart-validator.sh"
          }
        ]
      }
    ]
  }
}
```

---

## 8. Padrão «CI-in-a-Loop»: feedback contínuo

No desenvolvimento tradicional sem hooks, surge um padrão de ruptura: o agente altera dezenas de arquivos, depois inicia-se uma build do projeto que gera uma avalanche de 40 erros de tipo. É difícil para o agente descobrir qual alteração específica causou a quebra.

**CI-in-a-Loop (Curto ciclo de feedback)** inverte esse processo:

```mermaid
flowchart TD
    A["Claude вносить правку в код"] --> B["Миттєвий запуск tsc"]
    B --> C{"Є помилка?"}
    C -->|Так| D["Claude бачить 1 точкову помилку"]
    D --> E["Миттєвий фікс за 5 секунд"]
    E --> B
    C -->|Ні| F["Перехід до наступного рядка/файлу"]
```

### Configuração da auditoria cíclica de TypeScript

```json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit",
        "hooks": [
          {
            "type": "command",
            "command": "npx tsc --noEmit 2>&1 | head -n 20 || true"
          }
        ]
      }
    ]
  }
}
```

### Por que usar obrigatoriamente `head -n 20`

Se a saída do compilador retornar centenas de linhas de log, elas entram no contexto do modelo e podem estourar o limite de tokens. Limitar via `head -n 20` mostra os primeiros erros mais críticos, dando ao modelo um guia preciso para correção imediata sem sobrecarregar a sessão.

---

## 9. Automação Headless: modo -p, Cron e Git Hooks

Os hooks podem ser combinados com o modo autônomo (headless) do Claude Code — a flag `-p` (print/prompt). Isso permite automatizar a execução de tarefas totalmente sem intervenção humana.

```mermaid
flowchart LR
    A["Розклад Cron (02:00)"] --> B["Скрипт nightly-audit.sh"]
    B --> C["claude -p 'Run test suite, fix bugs, commit'"]
    C --> D["Хуки PostToolUse контролюють код"]
    D --> E["Автоматичний Push результату"]
```

### Script autônomo de auditoria noturna (nightly-audit.sh)

```bash
#!/usr/bin/env bash
cd /var/www/my-project

# Запуск Claude Code в автономному режимі з фіксованим завданням
claude -p "Run full test suite. If any tests fail, inspect the stack trace and fix them. Ensure typecheck passes. Finally, commit all fixes with a conventional commit." >> /var/log/claude-audit.log 2>&1
```

### Configuração do agendamento via Cron

Abra o planejador de tarefas (`crontab -e`) e configure a execução toda noite às 03:00:

```text
0 3 * * * /usr/local/bin/nightly-audit.sh
```

### Execução da verificação em um Git Hook nativo (.git/hooks/post-merge)

Para que, após cada atualização via `git pull`, seja iniciado automaticamente uma análise de compatibilidade:

```bash
#!/usr/bin/env bash
# .git/hooks/post-merge
echo "🚀 Запуск автоматичної перевірки залежностей через Claude..."
claude -p "Check if package.json was updated. If so, run npm install, verify build, and report summary."
```

Não esqueça de dar permissão de execução ao script: `chmod +x .git/hooks/post-merge`.

---

## 10. Melhores práticas de engenharia e regras de segurança para Hooks

Hooks mal configurados podem causar loops infinitos ou travar o terminal. Siga estas quatro regras fundamentais de higiene de engenharia.

### Quatro regras para design seguro de hooks

1. **Desempenho extremo:** Hooks com evento `PostToolUse` rodam após cada modificação de arquivo. Se o hook demorar mais de 1-2 segundos, o trabalho interativo com o Claude ficará lento e desconfortável. Execute testes E2E pesados apenas em `PreToolUse` antes do commit, mas não após cada `Edit`.
2. **Logging obrigatório da saída:** Sempre redirecione a saída de scripts de diagnóstico para um arquivo de log temporário:
   ```bash
   "command": "bash .claude/hooks/check.sh >> /tmp/claude-hooks.log 2>&1 || true"
   ```
   Se o hook parar de disparar, você poderá abrir imediatamente `/tmp/claude-hooks.log` e encontrar a causa.
3. **Teste isolado em terminal limpo:** Antes de adicionar qualquer comando ao `settings.json`, execute-o manualmente em um shell comum. Se o comando gerar erro no console, ele garantidamente quebrará a sessão do Claude Code.
4. **Prevenção de recursão infinita:** Nunca configure um comando em `PostToolUse` que modifique os arquivos do projeto por si só sem flags de ignorância (por exemplo, um script externo que chama outro `Edit`), caso contrário, o agente entrará em um loop infinito de chamadas.

> [!WARNING]
> Não execute comandos via hooks que esperem entrada interativa do usuário (como confirmações `read -p` ou `sudo` pedindo senha). Isso resultará no travamento do processo do terminal.

---

## 11. Workshop prático, cheat sheet e checklist final

Para começar rapidamente em seu próprio projeto, use esta referência consolidada pronta e uma configuração production testada.

![Cheat sheet para escolher o tipo de Hook para automação](/api/guides-media/automation/hooks-automation-guide-for-beginners/images/hooks-automation-guide-for-beginners-extra-03.webp)

### Arquivo de configuração pronto `.claude/settings.json`

Copie esta configuração de referência para a pasta `.claude` do seu projeto:

```json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash(git commit*)",
        "hooks": [
          {
            "type": "command",
            "command": "npm run typecheck && npm test"
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Edit",
        "hooks": [
          {
            "type": "command",
            "command": "npx prettier --write \"$CLAUDE_FILE_PATH\" 2>/dev/null || true"
          }
        ]
      },
      {
        "matcher": "Write",
        "hooks": [
          {
            "type": "command",
            "command": "npx prettier --write \"$CLAUDE_FILE_PATH\" 2>/dev/null || true"
          }
        ]
      }
    ],
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "osascript -e 'display notification \"Роботу завершено!\" with title \"Claude Code\"' 2>/dev/null || true"
          }
        ]
      }
    ]
  }
}
```

### Autoavaliação rápida

> **1. Qual a diferença fundamental entre `PreToolUse` e `PostToolUse`?**
>
> > [!TIP]
> > **Resposta:** `PreToolUse` roda *antes* da execução da ação da ferramenta e pode bloqueá-la com exit code não-zero. `PostToolUse` roda *após* a conclusão bem-sucedida da operação e é usado para formatação ou linting.

> **2. Por que adicionar `|| true` nos hooks de formatação?**
>
> > [!TIP]
> > **Resposta:** Para que erros do linter ou formatador não retornem status crítico e parem o processo de geração da resposta do agente.

> **3. Qual variável de ambiente contém o caminho do arquivo recém-editado?**
>
> > [!TIP]
> > **Resposta:** A variável `$CLAUDE_FILE_PATH`.

### Checklist final de implementação de Hooks

- [ ] Criado o diretório `.claude/` e o arquivo `settings.json` na raiz do projeto.
- [ ] Configurada a formatação automática de arquivos modificados via `PostToolUse` + `Prettier`.
- [ ] Implementada a verificação de tipos/testes em `PreToolUse` para bloquear commits ruins.
- [ ] Adicionadas notificações de som/desktop no evento `Stop`.
- [ ] Testados todos os scripts de hook manualmente no terminal antes de integrar.