Build This Now
Build This Now
Atalhos de TecladoGuia da Status Line
Guia de HooksHooks Multiplataforma para o Claude CodeHooks de Setup do Claude CodeStop HooksAgentes Claude Code Auto-ValidantesHooks de Ciclo de Vida de Sessão do Claude CodeHooks de Backup de Contexto para o Claude CodeHook de Ativação de SkillsHook de Permissões do Claude Code
speedy_devvkoen_salo
Blog/Toolkit/Hooks/Stop Hooks

Stop Hooks

Stop hooks impedem o Claude Code de encerrar uma resposta enquanto os testes falham, o build quebra ou o lint está vermelho. Quatro padrões de imposição mais proteções contra loops infinitos.

Pare de configurar. Comece a construir.

Templates SaaS com orquestração de IA.

Published Feb 25, 2026Toolkit hubHooks index

Problema: O Claude termina uma resposta, mas o trabalho não está de fato concluído. Os testes ainda falham. Arquivos estão pela metade. Você pergunta "terminou?" e recebe um sim, enquanto o build está vermelho.

Solução rápida: Adicione este Stop hook e o Claude não pode encerrar o turno enquanto os testes não estiverem verdes:

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "python .claude/hooks/test-gate.py"
          }
        ]
      }
    ]
  }
}
#!/usr/bin/env python3
import json
import sys
import subprocess
 
input_data = json.load(sys.stdin)
 
# CRITICAL: Prevent infinite loops
if input_data.get('stop_hook_active', False):
    sys.exit(0)
 
# Run tests
result = subprocess.run(['npm', 'test'], capture_output=True, timeout=60)
 
if result.returncode != 0:
    output = {
        "decision": "block",
        "reason": "Tests are failing. Fix them before completing."
    }
    print(json.dumps(output))
    sys.exit(0)
 
sys.exit(0)

A partir daqui, o Claude literalmente não consegue fechar um turno com uma suite com falhas.

Como o Stop Hook Funciona

Cada vez que o Claude vai terminar uma resposta, este hook dispara. Três coisas podem acontecer:

  1. Permitir parada - Sair com código 0 e o turno termina normalmente.
  2. Bloquear parada - Retornar {"decision": "block", "reason": "..."} e o Claude continua.
  3. Executar validações - Disparar testes, verificações ou qualquer script que você quiser.

O Payload

{
  "session_id": "uuid-string",
  "stop_hook_active": false,
  "transcript_path": "/path/to/transcript.jsonl"
}

Preste atenção em stop_hook_active. Um valor verdadeiro significa que o Claude já está em estado de continuação forçada por um bloqueio anterior. Ignorar esse flag gera um loop sem fim.

Padrão 1: Gate de Testes

Mantém o turno aberto até todos os testes passarem:

#!/usr/bin/env python3
import json
import sys
import subprocess
 
input_data = json.load(sys.stdin)
 
if input_data.get('stop_hook_active', False):
    sys.exit(0)
 
result = subprocess.run(
    ['npm', 'test', '--passWithNoTests'],
    capture_output=True,
    timeout=120
)
 
if result.returncode != 0:
    # Extract last 10 lines of test output for context
    stderr = result.stderr.decode()[-500:] if result.stderr else ""
    print(json.dumps({
        "decision": "block",
        "reason": f"Tests failing. Output: {stderr}"
    }))
    sys.exit(0)
 
sys.exit(0)

Padrão 2: Validação de Build

Bloqueia até o projeto compilar:

#!/usr/bin/env python3
import json
import sys
import subprocess
 
input_data = json.load(sys.stdin)
 
if input_data.get('stop_hook_active', False):
    sys.exit(0)
 
result = subprocess.run(
    ['npm', 'run', 'build'],
    capture_output=True,
    timeout=180
)
 
if result.returncode != 0:
    print(json.dumps({
        "decision": "block",
        "reason": "Build failed. Fix compilation errors before completing."
    }))
    sys.exit(0)
 
sys.exit(0)

Padrão 3: Verificação de Lint

Sem sair do turno com erros de lint na fila:

#!/usr/bin/env python3
import json
import sys
import subprocess
 
input_data = json.load(sys.stdin)
 
if input_data.get('stop_hook_active', False):
    sys.exit(0)
 
result = subprocess.run(
    ['npx', 'eslint', 'src/', '--max-warnings=0'],
    capture_output=True,
    timeout=60
)
 
if result.returncode != 0:
    print(json.dumps({
        "decision": "block",
        "reason": "Lint errors detected. Run eslint --fix or resolve manually."
    }))
    sys.exit(0)
 
sys.exit(0)

Padrão 4: Marcador de Conclusão de Tarefa

Controla o turno com base em um flag de tarefa específico:

#!/usr/bin/env python3
import json
import sys
from pathlib import Path
 
input_data = json.load(sys.stdin)
 
if input_data.get('stop_hook_active', False):
    sys.exit(0)
 
# Check for incomplete task marker
marker = Path('.claude/incomplete-task')
if marker.exists():
    task_info = marker.read_text().strip()
    print(json.dumps({
        "decision": "block",
        "reason": f"Task incomplete: {task_info}. Finish it before stopping."
    }))
    sys.exit(0)
 
sys.exit(0)

Crie o marcador ao iniciar o trabalho:

echo "Implement user authentication" > .claude/incomplete-task

Remova quando o trabalho estiver concluído:

rm .claude/incomplete-task

Prevenindo Loops Infinitos

É por isso que o flag stop_hook_active importa. Sem ele você tem isto:

Claude responds → Stop hook fires → "block" → Claude continues
                                            ↓
Claude responds → Stop hook fires → INFINITE LOOP (without flag check)

Sempre verifique o flag primeiro:

if input_data.get('stop_hook_active', False):
    sys.exit(0)  # Allow stopping, break the loop

Combinando Múltiplas Verificações

Um hook pode encadear vários gates:

#!/usr/bin/env python3
import json
import sys
import subprocess
 
input_data = json.load(sys.stdin)
 
if input_data.get('stop_hook_active', False):
    sys.exit(0)
 
checks = [
    (['npm', 'run', 'lint'], "Lint errors"),
    (['npm', 'run', 'typecheck'], "Type errors"),
    (['npm', 'test'], "Test failures"),
]
 
for cmd, error_msg in checks:
    result = subprocess.run(cmd, capture_output=True, timeout=120)
    if result.returncode != 0:
        print(json.dumps({
            "decision": "block",
            "reason": f"{error_msg} detected. Fix before completing."
        }))
        sys.exit(0)
 
sys.exit(0)

Quando Usar Stop Hooks

Bons casos de uso:

  • Controlar um suite de testes verde antes de "tarefa concluída"
  • Garantir que o build ainda compila
  • Capturar erros de lint e de tipo
  • Qualquer regra personalizada do que "pronto" significa para você

Maus casos de uso:

  • Qualquer coisa que rode mais do que o timeout de 60 segundos
  • Verificações que acessam a rede e falham intermitentemente
  • Prompts que precisam de uma resposta humana (sem interação aqui)

Configuração

Configure em .claude/settings.json:

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "python .claude/hooks/stop-validation.py"
          }
        ]
      }
    ]
  }
}

Vários hooks podem rodar ao mesmo tempo, em paralelo. Um block de qualquer um deles mantém o Claude em andamento.

Depuração

Preso em um loop?

  • Verifique duas vezes se você lê stop_hook_active no início do script
  • Registre: echo "stop_hook_active: $stop_hook_active" >> ~/.claude/stop-debug.log

Bloqueio não está funcionando?

  • O JSON deve ser {"decision": "block", "reason": "..."}
  • Use código de saída 0, não 2. Código de saída 2 é para um caminho de bloqueio diferente.

Testes demorando muito?

  • O timeout do hook é 60 segundos
  • Execute um subconjunto menor, ou acelere a suite

O Padrão "Ralph Wilgum"

Este vem de uma técnica da comunidade e usa Stop hooks para forçar um loop de tarefa persistente:

  1. Crie um marcador de tarefa no início da sessão
  2. Faça o Stop hook bloquear enquanto o marcador está presente
  3. Exija que o Claude delete o marcador como prova de conclusão
  4. Sem mais "estou pronto" acidental com trabalho ainda aberto

O resultado: o Claude passa de melhor esforço para conclusão garantida.

Próximos Passos

  • Leia o Guia de Hooks principal para ver todos os tipos de hook
  • Configure o Context Recovery para que as sessões sobrevivam à compactação
  • Configure o Skill Activation para carregamento automático de skills
  • Veja os Permission Hooks para fluxos de aprovação automática

Continue in Hooks

  • Hooks de Setup do Claude Code
    Combina scripts, agentes e documentação em hooks de setup do Claude Code. Um comando corre um script determinístico, passa o output para um agente de diagnóstico, e regista documentação viva.
  • Hooks de Backup de Contexto para o Claude Code
    Um hook de backup de contexto do Claude Code baseado em StatusLine. Escreve snapshots estruturados a cada 10K tokens para que a compactação automática nunca apague erros, assinaturas nem decisões.
  • Hooks Multiplataforma para o Claude Code
    Hooks do Claude Code multiplataforma: elimina wrappers .cmd, .sh e .ps1 e invoca node diretamente para que um único ficheiro .mjs corra em macOS, Linux e Windows por toda a equipa.
  • Guia de Hooks
    Hooks do Claude Code do princípio ao fim: exit codes, output JSON, comandos assíncronos, endpoints HTTP, matchers PreToolUse e PostToolUse, padrões para produção.
  • Hook de Permissões do Claude Code
    Instala um hook de permissões em três camadas para o Claude Code: aprovação instantânea para chamadas seguras, recusa instantânea para as perigosas, e verificação LLM para a zona cinzenta. Sem flag de skip.
  • Agentes Claude Code Auto-Validantes
    Agentes Claude Code auto-validantes: liga hooks PostToolUse de lint, hooks Stop e sub-agentes revisores em modo só-leitura às definições dos agentes para que output de má qualidade nunca seja entregue.

More from Toolkit

  • Atalhos de Teclado
    Configure o keybindings.json do Claude Code: 17 contextos, sintaxe de teclas, sequências de acordes, combinações de modificadores e como desvincular qualquer atalho padrão instantaneamente.
  • Guia da Status Line
    Configure uma status line no Claude Code para ver o nome do modelo, branch do git, custo da sessão e uso do contexto. Configuração via settings.json, input JSON, scripts em bash, Python e Node.js.
  • Otimização de SEO e GEO com IA
    Um resumo sobre Generative Engine Optimization: como fazer com que o teu conteúdo seja citado dentro das respostas do ChatGPT, Claude e Perplexity, em vez de apenas aparecer no Google.
  • Claude Code vs Cursor em 2026
    Uma comparação lado a lado entre Claude Code e Cursor em 2026: modelos de agente, janelas de contexto, planos de preço e como cada ferramenta se encaixa em diferentes fluxos de trabalho.

Pare de configurar. Comece a construir.

Templates SaaS com orquestração de IA.

On this page

Como o Stop Hook Funciona
O Payload
Padrão 1: Gate de Testes
Padrão 2: Validação de Build
Padrão 3: Verificação de Lint
Padrão 4: Marcador de Conclusão de Tarefa
Prevenindo Loops Infinitos
Combinando Múltiplas Verificações
Quando Usar Stop Hooks
Configuração
Depuração
O Padrão "Ralph Wilgum"
Próximos Passos

Pare de configurar. Comece a construir.

Templates SaaS com orquestração de IA.