Scarica AX Code · GratuitoDocumentazione

Questa pagina è tradotta dalla documentazione inglese. Comandi, identificatori ed esempi restano invariati. Runtime 7.24.4 · SDK 2.6.7. Testo inglese

Hook del ciclo di vita

Stato: attivo Ambito: stato attuale Ultima revisione: 2026-08-23 Responsabile: runtime di ax-code

Gli hook del ciclo di vita permettono di eseguire comandi shell sugli eventi dell’agente senza ricompilare il runtime. Completano le regole di permesso e la sandbox di isolamento: gli hook sono effetti collaterali deterministici («formatta sempre», «mai force-push»), mentre i prompt restano solo consultivi.

Eventi

Evento Quando Può bloccare?
PreToolUse Prima che uno strumento venga eseguito Sì (blockOnFailure: true)
PostToolUse Dopo il completamento di uno strumento (args: argomenti dello strumento). Lo stdout limitato o il feedback strutturato viene accodato al risultato dello strumento visto dal modello; vedi sotto No
PostToolUseFailure Dopo che uno strumento solleva un’eccezione (args: { args, error }, testo dell’errore limitato a 4,000 caratteri). Invio senza attesa; l’errore raggiunge comunque il modello invariato No
Stop Quando un turno di sessione si conclude (i pacchetti possono eseguirsi allo stop tramite automazione) No
UserPromptSubmit Quando un prompt dell’utente viene inviato, prima che il messaggio sia persistito Sì (blockOnFailure: true)
PreCompact Prima che parta la compattazione della sessione (args: { auto, overflow }) No
SubagentStop Quando un subagent task termina (args: { agent, status }) No
SessionStart Quando viene creata una sessione di primo livello (args: { sessionID, title, time }) No
SessionEnd Quando una sessione viene rimossa o archiviata (args: { sessionID, reason }, reason vale "remove" oppure "archive") No
PostCompact Dopo che una compattazione di sessione si conclude con successo (args: { sessionID, reason }, reason vale "auto" oppure "manual"; non scatta se la compattazione si interrompe, ad esempio per overflow del contesto) No
Interrupt Quando un utente o un operatore annulla in modo esplicito un turno in corso (args: { sessionID }; non scatta al termine normale del turno né durante la pulizia interna) No

I quattro eventi del ciclo di vita della sessione (SessionStart, SessionEnd, PostCompact, Interrupt) e PostToolUseFailure sono solo di osservazione: scattano e proseguono, non bloccano mai il percorso del ciclo di vita e i loro payload portano soltanto id, motivi e timestamp — mai testo della conversazione, riassunti o output degli strumenti. Le sessioni dei subagent non fanno scattare SessionStart (emergono già tramite SubagentStop). SubagentStop scatta per i processi figli avviati sia da task sia da task_parallel.

Il feedback di PostToolUse raggiunge il modello

Un hook PostToolUse può restituire testo al modello. Il testo viene accodato al risultato dello strumento dentro un blocco <hook_feedback event="PostToolUse">, dopo l’output proprio dello strumento; non sostituisce mai l’output e non blocca mai.

  • Voci legacy (senza protocol): stdout ripulito di un hook terminato con codice 0.
  • Voci protocol: "claude-code": hookSpecificOutput.additionalContext, il reason di un verdetto {"decision": "block", "reason": "..."}, oppure stderr quando l’hook termina con codice 2. Gli altri codici diversi da zero non contribuiscono nulla.

Il feedback è limitato a 4,000 caratteri per hook e a 8,000 caratteri per chiamata di strumento, così un hook rumoroso non può inondare il contesto. È questo che rende utile il pacchetto format-after-edit: il promemoria arriva ora nel turno successivo del modello, invece di restare soltanto nel log.

Questi nomi corrispondono ai trigger interni dei plugin di AX Code (tool.execute.before / tool.execute.after), più gli hook di prompt a livello di sessione, di compattazione, di subagent e di stop. I prompt di continuazione sintetici (prompt interni agentRouting: "preserve") non fanno scattare UserPromptSubmit.

Abilitare i pacchetti

Gli hook e i plugin di progetto eseguono codice controllato dal repository, quindi .ax-code/hooks.json, .ax-code/plugin/ e i plugin configurati dal progetto sono disabilitati per impostazione predefinita. Dopo averli esaminati, attiva l’adesione fuori dal repository all’avvio di AX Code:

AX_CODE_TRUST_PROJECT_CONFIG=1 ax-code

Poi crea .ax-code/hooks.json nel progetto:

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

Pacchetti ufficiali (≥5)

Pacchetto Eventi Descrizione
format-after-edit PostToolUse Ricorda all’agente di formattare dopo le modifiche
block-force-push PreToolUse Blocca git push --force / -f
require-tests-on-stop Stop Ricorda di verificare dopo le mutazioni
protect-env-files PreToolUse Avvisa quando gli strumenti toccano .env
log-bash-commands PreToolUse Registra i comandi bash per l’audit

Hook personalizzati:

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

Protocollo wire di Claude Code (opt-in)

Se hai già hook scritti per Claude Code, una voce può aderire al protocollo wire di Claude Code con "protocol": "claude-code":

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

Per gli eventi che possono bloccare (PreToolUse, UserPromptSubmit), le voci aderenti vengono decodificate con la semantica di Claude Code al posto del controllo blockOnFailure:

  • Exit 2 blocca l’azione; lo stderr dell’hook viene mostrato come motivo. Uno stdout malformato blocca comunque (a prova di errore).
  • Exit 0 con JSON sullo stdout {"permissionDecision": "allow"|"deny"|"ask", "reason"?}: allow prosegue; deny blocca con reason; ask mette in pausa la chiamata dello strumento su un prompt di permesso interattivo hook che mostra il motivo (predefinito "hook requested user confirmation"). Il prompt è soltanto interattivo: nessuna regola always, concessione con carattere jolly o approvazione automatica autonoma può rispondere, e un’esecuzione headless lo rifiuta; il modello lo vede come un ordinario rifiuto di permesso. Un hook successivo che risponde deny prevale su un ask precedente. UserPromptSubmit non ha una chiamata di strumento a cui collegare un prompt, quindi ask continua a bloccare in quel caso. La forma annidata di Claude Code {"hookSpecificOutput": {"permissionDecision": "...", "permissionDecisionReason": "..."}} è accettata come alias.
  • Qualsiasi altro exit è un errore non bloccante (viene registrato e l’azione prosegue).

Gli eventi di sola osservazione ignorano del tutto il decoder: non possono mai bloccare. Le voci prive del campo protocol si comportano esattamente come prima.

Variabili d’ambiente disponibili per i comandi degli hook:

  • HOOK_EVENT — nell’ordine: PreToolUse, PostToolUse, PostToolUseFailure, poi Stop, UserPromptSubmit, PreCompact, quindi SubagentStop, SessionStart, SessionEnd, PostCompact e Interrupt
  • HOOK_TOOL — id dello strumento
  • HOOK_SESSION_ID
  • HOOK_ARGS_JSON — argomenti dello strumento in JSON
  • HOOK_ARGS_STDIN=1 — gli argomenti JSON completi sono sempre disponibili su stdin; HOOK_ARGS_JSON è vuoto per i payload più grandi di 32 KiB
  • HOOK_PACK — nome del pacchetto, quando applicabile

I processi figli degli hook ereditano una versione ripulita dell’ambiente di AX Code. AX Code conserva le variabili ordinarie di piattaforma e degli strumenti, ma rimuove i nomi simili a segreti, gli URL che contengono credenziali, gli helper di credenziali come SSH_AUTH_SOCK e le variabili di iniezione nel processo come NODE_OPTIONS. Le variabili di protocollo HOOK_* elencate sopra vengono aggiunte dopo la ripulitura e sono sempre disponibili.

Gli hook legacy completamente fidati che richiedono credenziali già presenti nell’ambiente possono ripristinare il comportamento precedente fuori dal repository:

AX_CODE_HOOKS_FULL_ENV=1 AX_CODE_TRUST_PROJECT_CONFIG=1 ax-code

Questa via di uscita espone ogni variabile d’ambiente a ogni hook abilitato. Un repository non può richiederla tramite .ax-code/hooks.json; usala soltanto dopo aver esaminato tutti gli hook e i pacchetti.

Nota di sicurezza: la ripulitura dell’ambiente riduce l’esposizione delle credenziali ambientali, ma non isola i comandi degli hook. Gli hook restano codice shell arbitrario, in grado di leggere i file accessibili e di usare la rete dell’host. Trattali come codice fidato ed esamina ogni hook e ogni pacchetto abilitato.

Rapporto con l'isolamento

Gli hook non sostituiscono la sandbox. Usa:

  1. Isolamento dell’app per confini portabili di scrittura e di rete
  2. Isolamento del sistema operativo (il backend predefinito "auto") per la sandbox bash applicata dal kernel, quando disponibile
  3. Hook per gli effetti collaterali di policy e per i blocchi rigidi, come il force-push

Vedi Modalità sandbox e SECURITY.md.