🤖 O que é o Claude Code
Claude Code como ferramenta de engenharia — o CLI que age no seu filesystem, não só um chat. O loop de conversa, ferramentas nativas e primeiros passos.
O Claude Code é um CLI que executa o modelo Claude diretamente no seu terminal, com acesso real ao filesystem, processos e ferramentas do sistema.
Entender que o Claude Code age — não apenas responde — muda como você o instrui. É a base para usar hooks, comandos e automações.
CLI, agentic AI, ferramentas de ação, filesystem access, diferença entre chat e agente.
O modelo processa input, decide quais ferramentas chamar, recebe o resultado e decide o próximo passo — tudo em turnos síncronos.
Entender o loop explica por que hooks são executados em momentos específicos e como o Claude decide quando parar.
Turn-based execution, tool calls, tool results, context window, agentic loop.
As quatro ferramentas fundamentais que o Claude usa para agir: Bash (executar comandos), Read (ler arquivos), Edit (modificar), Write (criar).
Cada hook intercepta uma dessas ferramentas. Saber o que cada uma faz é pré-requisito para escrever hooks precisos.
Tool API, Bash, Read, Edit, Write, ToolUse events, intercepção por nome de ferramenta.
settings.json registra hooks e comandos; CLAUDE.md fornece instruções persistentes injetadas no contexto de cada sessão.
Toda automação que você criar vive nesses dois arquivos. Sem entendê-los, você não consegue registrar hooks nem instruções de projeto.
settings.json local vs global, CLAUDE.md de projeto, injeção de contexto, registro de hooks, slash commands.
O Claude Code usa o diretório atual como âncora — lê CLAUDE.md, settings.json local e passa o cwd para cada ferramenta executada.
Saber como o contexto é montado evita confusão sobre qual settings.json está ativo e por que certas instruções não aparecem.
Working directory, cascading config (local > global), context window, CLAUDE.md hierarchy.
Instalação via npm, autenticação com a API Anthropic e estrutura de um primeiro prompt que usa ferramentas de verdade.
Um ambiente funcional é o pré-requisito para todos os módulos seguintes. Erros de autenticação bloqueiam tudo.
npm install -g @anthropic-ai/claude-code, ANTHROPIC_API_KEY, claude --version, primeiro prompt de leitura de arquivo.
🎣 Hooks — o Sistema de Eventos
O que é um hook, os 4 tipos disponíveis, como o Claude Code os executa via subprocess e o protocolo de exit codes para bloquear ou aprovar ações.
Um hook é um script externo que o Claude Code executa em pontos específicos do seu loop — antes ou depois de usar uma ferramenta, ao parar, ao enviar notificações.
Hooks são o mecanismo central de automação e governança do Claude Code. Sem eles, você não tem controle sobre o que o Claude faz.
Event hook, intercepção, subprocess externo, ponto de extensão, separação de responsabilidades.
PreToolUse: antes de executar ferramenta (pode bloquear). PostToolUse: após execução (pode injetar contexto). Stop: quando o Claude finaliza. Notification: eventos assíncronos.
Cada tipo tem capacidades diferentes. Usar o tipo errado resulta em hook que não consegue bloquear ou que roda na hora errada.
PreToolUse (bloqueio), PostToolUse (observação), Stop (cleanup/log), Notification (alertas externos).
O Claude Code abre um subprocess com o comando do hook, passa um JSON via stdin com o contexto do evento e lê stdout para decisões de bloqueio.
Entender o protocolo stdin/stdout é obrigatório para debugar hooks que não funcionam como esperado.
subprocess, stdin JSON payload, stdout response, exit code protocol, timeout do subprocess.
Exit code 0 = aprovado (APPROVE), a ferramenta executa. Exit code 1 = bloqueado (BLOCK), a ferramenta não executa e o Claude recebe a mensagem de erro do hook.
O protocolo de exit code é a única forma de o hook comunicar uma decisão ao Claude Code. Errar o código quebra toda a lógica de validação.
exit 0 (approve), exit 1 (block), stderr para mensagem de erro, stdout para contexto adicional.
Fail-open significa que se o hook travar, lançar exceção ou não responder no timeout, o Claude Code ignora o hook e continua — não bloqueia.
Sem entender fail-open, você pode escrever um hook que parece funcionar mas silenciosamente falha em produção sem bloquear nada.
Fail-open vs fail-closed, timeout handling, graceful degradation, logging de falhas do hook.
Um hook mínimo em bash: lê o JSON do stdin, extrai o campo relevante com jq, toma uma decisão e retorna o exit code correto.
Ter um hook funcional do zero é o ponto de partida para todos os exemplos dos módulos seguintes.
read stdin, jq para parse JSON, condições shell, exit 0/1, chmod +x, registro no settings.json.
⚡ Slash Commands e Skills
Como criar e usar comandos personalizados — a diferença entre local e global, o que é uma skill, como passar argumentos e quando usar cada abordagem.
Um slash command é um atalho que mapeia um nome curto para um arquivo de prompt (skill). Ao digitar /meu-comando, o Claude carrega e executa as instruções desse arquivo.
Slash commands são a interface do usuário para skills reutilizáveis — permitem acionar comportamentos complexos com um único token.
Slash command, skill file, prompt injection, reutilização de instruções, interface de usuário para automações.
Comandos locais ficam em .claude/settings.json do projeto (só daquele repo). Comandos globais ficam em ~/.claude/settings.json (disponíveis em qualquer projeto).
A escolha entre local e global determina o escopo do comando — comandos de projeto não devem vazar para outros contextos.
.claude/settings.json (local), ~/.claude/settings.json (global), escopo, cascading, override de comandos.
Uma skill é um arquivo Markdown (.md) com instruções detalhadas sobre como executar uma tarefa específica — o "cérebro" por trás de um slash command.
Skills permitem encapsular expertise complexa em arquivos versionáveis, compartilháveis e iteráveis sem mudar o código.
Skill file (.md), instruções detalhadas, versionamento de prompt, encapsulamento de expertise, composição de skills.
O processo de criação: definir o nome, escrever o arquivo .md com instruções claras, registrar no settings.json e testar no Claude Code.
Criar o primeiro comando do zero solidifica o entendimento do sistema completo e produz algo imediatamente útil.
Nome do comando, arquivo .md, registro em settings.json, campo "description", campo "prompt" vs "file".
Ao usar /meu-comando texto adicional, o "texto adicional" fica disponível na skill como $args — permite comandos parametrizados.
Argumentos tornam skills genéricas e reutilizáveis. Sem eles, cada variação precisaria de um comando separado.
$args, argumentos posicionais, template de skill com placeholder, validação de argumentos na skill.
Regras para decidir: crie um comando quando a tarefa é repetida frequentemente, requer instruções longas ou precisa ser consistente entre sessões.
Criar comandos para tudo polui o settings.json e aumenta o cognitive load. Saber quando não criar é tão importante quanto saber como criar.
Frequência de uso, complexidade de instrução, consistência necessária, overhead de manutenção, YAGNI para skills.
🧠 Estado e Persistência
Como resolver o problema de memória entre sessões — estado em arquivo, escrita atômica, compare-and-swap e lockfiles para concorrência segura.
Cada sessão do Claude Code começa do zero — sem memória do que aconteceu antes. Para persistir estado entre sessões, é preciso usar arquivos externos.
Sem entender essa limitação, você vai tentar usar variáveis de ambiente ou memória em processo — ambas somem ao fim da sessão.
Stateless sessions, external state, persistent storage, arquivo como memória, CLAUDE.md como instrução persistente.
Arquivos YAML e JSON servem como banco de dados simples para hooks — legíveis por humanos, fáceis de processar com yq/jq no shell.
YAML/JSON são o padrão para estado de hooks por serem editáveis manualmente e suportados nativamente pelas ferramentas do kit (jq, yq).
YAML vs JSON, jq para JSON, yq para YAML, estrutura de estado, campos obrigatórios (version, updated_at, data).
Escrever em arquivo temporário e usar mv para substituir o original — garante que o arquivo nunca esteja em estado parcialmente escrito.
Escrita direta pode corromper o arquivo se o hook for interrompido no meio. mv é atômico no mesmo filesystem — é tudo-ou-nada.
Atomic write, mv atomicity, tmpfile, same filesystem, rename syscall, proteção contra corrupção.
CAS: lê o estado atual, verifica se ainda é o esperado antes de escrever. Se mudou entre a leitura e a escrita, aborta e retenta — evita overwrites acidentais.
Em hooks concorrentes (múltiplos processos rodando em paralelo), sem CAS você cria race conditions que corrompem o estado silenciosamente.
Compare-and-swap, optimistic locking, version field, retry on conflict, etag pattern.
Um lockfile é um arquivo temporário criado no início do hook para sinalizar exclusividade — outros processos verificam sua existência antes de executar.
Para operações que NÃO podem ser paralelas (ex: migration de banco), lockfiles garantem que apenas uma instância do hook roda por vez.
lockfile, mkdir como lock atômico, PID no lockfile, stale lock detection, cleanup no EXIT trap.
Padrões para ler campos específicos do arquivo de estado — yq para YAML tipado, jq para JSON, grep como fallback quando as ferramentas não estão disponíveis.
Leitura eficiente de estado evita carregar o arquivo inteiro na memória e permite verificações rápidas no caminho crítico do hook.
yq '.field', jq -r '.field', grep fallback, null check, default values, validação de schema no hook.
📂 O Ambiente para Construir
Estrutura de repositório, como testar hooks sem quebrar o fluxo, logs e debugging, SPEC.md como bússola e o kit de ferramentas de apoio.
A estrutura padrão: .claude/ para configs, hooks/ para scripts, skills/ para prompts, state/ para estado persistente e tests/ para testes de hooks.
Uma estrutura consistente acelera onboarding de novos desenvolvedores e evita que hooks fiquem espalhados pelo repositório.
.claude/, hooks/, skills/, state/, tests/, SPEC.md, convenções de nomenclatura, separação de responsabilidades.
Testar um hook passando JSON de exemplo via stdin manualmente, sem precisar acionar o Claude Code — permite validar a lógica em isolamento.
Testar hooks via Claude Code real é lento e inconsistente. Testes unitários com echo/pipe são 100x mais rápidos e repetíveis.
echo '{}' | ./hook.sh, mock JSON payload, exit code assertion, test fixtures, bats para shell testing.
Hooks devem escrever logs em arquivo (não stdout, que é reservado para comunicação com o Claude). O arquivo de log padrão fica em .claude/logs/hooks.log.
Sem logs, debugar hooks que falham silenciosamente é impossível. Um bom sistema de log é a diferença entre horas e minutos de diagnóstico.
stderr para erros, arquivo de log dedicado, timestamp no log, nível de log (DEBUG/INFO/ERROR), tail -f para monitoramento.
O SPEC.md documenta o que o hook deve fazer, quais inputs aceita, quais invariantes mantém e quais são os casos de borda — antes de qualquer código.
Especificar antes de implementar força decisões difíceis quando ainda é fácil mudar e evita reimplementações por requisitos não capturados.
SPEC.md, invariantes, casos de borda, contratos de interface, decisões de design explícitas, spec-driven development.
Tratar arquivos de skill e CLAUDE.md como código — cada iteração commitada com mensagem descritiva, permitindo rollback e comparação.
Prompts evoluem. Sem versionamento, você perde o histórico de por que certas instruções existem e não consegue fazer rollback quando algo quebra.
Prompt versioning, git para prompts, commit atômico, mensagem de commit descritiva, diff de prompt, blame para rastrear decisões.
jq processa JSON no terminal. yq processa YAML. shellcheck analisa scripts shell e aponta erros comuns antes de rodar em produção.
Essas três ferramentas eliminam as classes de erro mais comuns em hooks — parse incorreto de JSON, corrupção de YAML e bugs de quoting em shell.
jq -r, yq eval, shellcheck -S error, instalação via package manager, integração no CI/CD de hooks.
🎯 Seu Primeiro Hook de Validação
Projeto prático completo — um hook que bloqueia commits sem mensagem descritiva, do SPEC à implementação, testes de fail-open e iteração incremental.
Um PreToolUse hook que intercepta chamadas ao Bash contendo "git commit" e valida que a mensagem tem pelo menos 20 caracteres e não é genérica.
Este projeto aplica todos os conceitos da trilha — hooks, stdin/stdout, exit codes, fail-open — em um caso de uso real e imediatamente útil.
PreToolUse, Bash tool interception, regex matching, mensagem de commit, critérios de qualidade, bloqueio seletivo.
Documentar antes de codificar: o que é "mensagem ruim", quais flags do git commit capturar (-m, --message), o que fazer com commits de merge/WIP.
O SPEC revela edge cases cedo — o que fazer com git commit --amend? com commits assinados? Essas decisões moldam toda a implementação.
Critérios de qualidade, whitelist de padrões, edge cases de git, invariantes do hook, decisões de design documentadas.
O código completo do hook: ler JSON do stdin, extrair o comando com jq, verificar se é git commit, extrair a mensagem, validar e retornar exit code.
Ver o código completo e funcional de um hook real consolida o entendimento teórico dos módulos anteriores em algo tangível.
stdin=$(cat), jq -r, grep com regex, wc -c para comprimento, exit 1 com mensagem, estrutura completa do hook.
Testar deliberadamente cenários onde o hook falha — jq não instalado, arquivo corrompido, timeout — e verificar que o Claude Code continua sem bloquear.
Confiar em fail-open sem testá-lo é arriscado. Verificar empiricamente garante que erros no hook não travam o workflow de desenvolvimento.
Cenários de falha, set -e, error handling, graceful degradation, logging de erros do hook, comportamento esperado com fail-open.
Registrar o hook no settings.json com o evento correto (PreToolUse), o matcher de ferramenta (Bash) e o caminho do script — e verificar que o Claude Code o executa.
O registro correto no settings.json é a etapa que mais falha por erro de path ou de nome de evento. Testar end-to-end confirma que tudo está conectado.
hooks.PreToolUse, matcher, command path, permissão de execução, teste end-to-end, verificação no log do Claude Code.
Iterar sobre o hook funcional — adicionar timestamp no log, melhorar a mensagem de erro, adicionar modo DRY_RUN, commitar cada melhoria separadamente.
Hooks de produção são construídos incrementalmente. Ver o processo de iteração demonstra como evoluir um hook sem introduzir regressões.
Iteração incremental, commit atômico por melhoria, DRY_RUN mode, melhoria de UX da mensagem de erro, changelog do hook.