Obter AX Code · GrátisDocumentação

Esta página é uma tradução da documentação em inglês. Comandos, identificadores e exemplos permanecem iguais. Runtime 7.24.4 · SDK 2.6.7. Original em inglês

Hooks de ciclo de vida

Status: Ativo
Escopo: estado atual
Última revisão: 2026-08-23 Responsável: runtime do ax-code

Os hooks de ciclo de vida permitem executar comandos de shell em eventos do agente sem recompilar o runtime. Eles complementam as regras de permissão e o sandbox de isolamento: os hooks são efeitos colaterais determinísticos (“sempre formatar”, “nunca force-push”), enquanto os prompts permanecem consultivos.

Eventos

Evento Quando Pode bloquear?
PreToolUse Antes de uma ferramenta executar Sim (blockOnFailure: true)
PostToolUse Depois que uma ferramenta conclui (args: os argumentos da ferramenta). Stdout limitado ou retorno estruturado é anexado ao resultado da ferramenta que o modelo vê; veja abaixo Não
PostToolUseFailure Depois que uma ferramenta lança uma exceção (args: { args, error }, texto de erro limitado a 4.000 caracteres). Disparo e esquecimento; o erro ainda chega ao modelo sem alteração Não
Stop Quando um turno de sessão conclui (os pacotes podem rodar ao parar, via automação) Não
UserPromptSubmit Quando um prompt do usuário é enviado, antes de a mensagem ser persistida Sim (blockOnFailure: true)
PreCompact Antes da compactação da sessão (args: { auto, overflow }) Não
SubagentStop Quando um subagente task termina (args: { agent, status }) Não
SessionStart Quando uma sessão de nível superior é criada (args: { sessionID, title, time }) Não
SessionEnd Quando uma sessão é removida ou arquivada (args: { sessionID, reason }, reason é "remove" ou "archive") Não
PostCompact Depois que uma compactação de sessão conclui com sucesso (args: { sessionID, reason }, reason é "auto" ou "manual"; não dispara quando a compactação desiste, por exemplo em estouro de contexto) Não
Interrupt Quando um usuário ou operador cancela de forma explícita um turno em execução (args: { sessionID }; não dispara na conclusão normal do turno nem na limpeza interna) Não

Os quatro eventos de ciclo de vida da sessão (SessionStart, SessionEnd, PostCompact, Interrupt) e PostToolUseFailure são apenas de observação: disparam e esquecem, nunca bloqueiam o caminho do ciclo de vida, e as cargas levam apenas ids, motivos e marcas de tempo — nunca texto de conversa, resumos ou saída de ferramenta. Sessões de subagente não disparam SessionStart (elas já aparecem via SubagentStop). SubagentStop dispara para filhos iniciados tanto por task quanto por task_parallel.

O retorno de PostToolUse chega ao modelo

Um hook PostToolUse pode devolver texto ao modelo. Ele é anexado ao resultado da ferramenta dentro de um bloco <hook_feedback event="PostToolUse">, depois da própria saída da ferramenta; nunca substitui a saída e nunca bloqueia.

  • Entradas legadas (sem protocol): stdout aparado de um hook que saiu com 0.
  • Entradas protocol: "claude-code": hookSpecificOutput.additionalContext, o reason de um veredito {"decision": "block", "reason": "..."}, ou stderr quando o hook sai com 2. Outras saídas diferentes de zero não contribuem nada.

O retorno é limitado a 4.000 caracteres por hook e 8.000 caracteres por chamada de ferramenta, para que um hook ruidoso não inunde o contexto. É isso que torna útil o pacote format-after-edit: o lembrete agora chega ao turno seguinte do modelo, em vez de ficar apenas no log.

Estes nomes mapeiam para os gatilhos internos de plugin do AX Code (tool.execute.before / tool.execute.after) mais os hooks de prompt, compactação, subagente e parada no nível da sessão. Prompts sintéticos de continuação (prompts internos agentRouting: "preserve") não disparam UserPromptSubmit.

Ativar pacotes

Hooks e plugins de projeto executam código controlado pelo repositório, então .ax-code/hooks.json, .ax-code/plugin/ e plugins configurados pelo projeto ficam desativados por padrão. Depois de revisá-los, aceite-os fora do repositório ao iniciar o AX Code:

AX_CODE_TRUST_PROJECT_CONFIG=1 ax-code

Em seguida, crie .ax-code/hooks.json no projeto:

{
  "packs": ["format-after-edit", "block-force-push", "require-tests-on-stop", "protect-env-files", "log-bash-commands"]
}

Pacotes oficiais (≥5)

Pacote Eventos Descrição
format-after-edit PostToolUse Lembra o agente de formatar depois das edições
block-force-push PreToolUse Bloqueia git push --force / -f
require-tests-on-stop Stop Lembra de verificar depois de mutações
protect-env-files PreToolUse Avisa quando ferramentas tocam .env
log-bash-commands PreToolUse Registra comandos bash para auditoria

Hooks personalizados:

{
  "hooks": [
    {
      "event": "PreToolUse",
      "matcher": "bash",
      "command": "echo running bash",
      "blockOnFailure": false
    }
  ]
}

Protocolo wire do Claude Code (adesão opcional)

Se você já tem hooks escritos para o Claude Code, uma entrada pode aderir ao protocolo wire do Claude Code com "protocol": "claude-code":

{
  "hooks": [
    {
      "event": "PreToolUse",
      "matcher": "bash",
      "command": "my-claude-code-hook.sh",
      "protocol": "claude-code"
    }
  ]
}

Para os eventos bloqueáveis (PreToolUse, UserPromptSubmit), as entradas que aderiram são decodificadas com a semântica do Claude Code em vez da verificação blockOnFailure:

  • Saída 2 bloqueia a ação; o stderr do hook aparece como o motivo. Stdout malformado ainda bloqueia (falha segura).
  • Saída 0 com JSON de stdout {"permissionDecision": "allow"|"deny"|"ask", "reason"?}: allow prossegue; deny bloqueia com reason; ask pausa a chamada de ferramenta em um prompt interativo de permissão hook que mostra o motivo (padrão "hook requested user confirmation"). O prompt é somente interativo: nenhuma regra always, concessão por curinga ou aprovação automática autônoma pode respondê-lo, e uma execução sem interface o rejeita, o que o modelo vê como uma rejeição comum de permissão. Um hook posterior que responde deny vence um ask anterior. UserPromptSubmit não tem chamada de ferramenta à qual anexar um prompt, então ask ainda bloqueia ali. A forma aninhada do Claude Code {"hookSpecificOutput": {"permissionDecision": "...", "permissionDecisionReason": "..."}} é aceita como alias.
  • Qualquer outra saída é um erro que não bloqueia (registrado; a ação prossegue).

Eventos apenas de observação ignoram o decodificador por completo — eles nunca podem bloquear. Entradas sem o campo protocol se comportam exatamente como antes.

Variáveis de ambiente disponíveis para os comandos de hook:

  • HOOK_EVENT — PreToolUse, PostToolUse, PostToolUseFailure, Stop, UserPromptSubmit, PreCompact, SubagentStop, SessionStart, SessionEnd, PostCompact e Interrupt
  • HOOK_TOOL — id da ferramenta
  • HOOK_SESSION_ID
  • HOOK_ARGS_JSON — argumentos JSON da ferramenta
  • HOOK_ARGS_STDIN=1 — os argumentos JSON completos estão sempre disponíveis em stdin; HOOK_ARGS_JSON fica vazio para cargas maiores que 32 KiB
  • HOOK_PACK — nome do pacote quando aplicável

Processos filhos de hook herdam uma versão higienizada do ambiente do AX Code. O AX Code preserva variáveis comuns de plataforma e de ferramentas, mas remove nomes com cara de segredo, URLs que carregam credencial, auxiliares de credencial como SSH_AUTH_SOCK e variáveis de injeção de processo como NODE_OPTIONS. As variáveis de protocolo HOOK_* acima são acrescentadas depois da higienização e estão sempre disponíveis.

Hooks legados totalmente confiáveis que precisam de credenciais do ambiente podem restaurar o comportamento anterior fora do repositório:

AX_CODE_HOOKS_FULL_ENV=1 AX_CODE_TRUST_PROJECT_CONFIG=1 ax-code

Esta saída de emergência expõe cada variável de ambiente a cada hook ativado. Um repositório não pode pedi-la por .ax-code/hooks.json; use-a apenas depois de revisar todos os hooks e pacotes.

Nota de segurança: a higienização do ambiente reduz a exposição de credenciais do ambiente, mas não isola os comandos de hook em sandbox. Os hooks continuam sendo código de shell arbitrário, que pode ler arquivos acessíveis e usar a rede do host. Trate-os como código confiável e revise cada hook e pacote ativado.

Relação com o isolamento

Os hooks não substituem o sandbox. Use:

  1. Isolamento do aplicativo para limites portáteis de escrita e de rede
  2. Isolamento do sistema operacional (o backend padrão "auto") para sandbox de bash imposto pelo kernel quando disponível
  3. Hooks para efeitos colaterais de política e bloqueios rígidos como force-push

Veja Modo sandbox e SECURITY.md.