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, ilreasondi 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"?}:allowprosegue;denyblocca conreason;askmette in pausa la chiamata dello strumento su un prompt di permesso interattivohookche mostra il motivo (predefinito"hook requested user confirmation"). Il prompt è soltanto interattivo: nessuna regolaalways, 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 rispondedenyprevale su unaskprecedente.UserPromptSubmitnon ha una chiamata di strumento a cui collegare un prompt, quindiaskcontinua 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 InterruptHOOK_TOOL— id dello strumentoHOOK_SESSION_IDHOOK_ARGS_JSON— argomenti dello strumento in JSONHOOK_ARGS_STDIN=1— gli argomenti JSON completi sono sempre disponibili su stdin;HOOK_ARGS_JSONè vuoto per i payload più grandi di 32 KiBHOOK_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:
- Isolamento dell’app per confini portabili di scrittura e di rete
- Isolamento del sistema operativo (il backend predefinito
"auto") per la sandbox bash applicata dal kernel, quando disponibile - Hook per gli effetti collaterali di policy e per i blocchi rigidi, come il force-push
Vedi Modalità sandbox e SECURITY.md.