Cette page est traduite de la documentation anglaise. Les commandes, identifiants et exemples sont inchangés. Runtime 7.24.4 · SDK 2.6.7. Source anglaise
Hooks du cycle de vie
Statut : Actif
Portée : état actuel
Dernière revue : 2026-08-23
Responsable : runtime ax-code
Les hooks du cycle de vie permettent d’exécuter des commandes shell sur les événements de l’agent sans reconstruire le runtime. Ils complètent les règles de permission et le bac à sable d’isolation : les hooks sont des effets de bord déterministes (« toujours formater », « jamais de force-push »), tandis que les invites restent consultatives.
Événements
| Événement | Moment | Peut bloquer ? |
|---|---|---|
| PreToolUse | Avant l’exécution d’un outil | Oui (blockOnFailure: true) |
| PostToolUse | Après l’achèvement d’un outil (args : les arguments de l’outil). La sortie standard bornée ou le retour structuré est ajouté au résultat d’outil vu par le modèle ; voir plus bas |
Non |
| PostToolUseFailure | Après qu’un outil a levé une erreur (args : { args, error }, texte d’erreur plafonné à 4,000 caractères). Émission sans attente ; l’erreur atteint encore le modèle inchangée |
Non |
| Stop | Lorsqu’un tour de session s’achève (les paquets peuvent s’exécuter à l’arrêt via l’automatisation) | Non |
| UserPromptSubmit | Lorsqu’une invite utilisateur est soumise, avant la persistance du message | Oui (blockOnFailure: true) |
| PreCompact | Avant l’exécution du compactage de session (args : { auto, overflow }) |
Non |
| SubagentStop | Lorsqu’un sous-agent task se termine (args : { agent, status }) |
Non |
| SessionStart | Lorsqu’une session de premier niveau est créée (args : { sessionID, title, time }) |
Non |
| SessionEnd | Lorsqu’une session est retirée ou archivée (args : { sessionID, reason }, reason vaut "remove" ou "archive") |
Non |
| PostCompact | Après qu’un compactage de session s’est achevé avec succès (args : { sessionID, reason }, reason vaut "auto" ou "manual" ; non émis lorsque le compactage abandonne, par exemple en cas de débordement de contexte) |
Non |
| Interrupt | Lorsqu’un utilisateur ou un opérateur annule explicitement un tour en cours (args : { sessionID } ; non émis à l’achèvement normal d’un tour ni lors du nettoyage interne) |
Non |
Les quatre événements de cycle de vie de session (SessionStart, SessionEnd, PostCompact, Interrupt) et PostToolUseFailure sont seulement observateurs : ils s’émettent sans attente, ne bloquent jamais le chemin du cycle de vie, et leurs charges ne portent que des identifiants, des raisons et des horodatages — jamais le texte de conversation, les résumés ou la sortie d’outil. Les sessions de sous-agent n’émettent pas SessionStart (elles apparaissent déjà via SubagentStop). SubagentStop s’émet pour les enfants démarrés à la fois par task et par task_parallel.
Le retour PostToolUse atteint le modèle
Un hook PostToolUse peut renvoyer du texte au modèle. Il est ajouté au résultat d’outil dans un bloc <hook_feedback event="PostToolUse">, après la sortie propre de l’outil ; il ne remplace jamais la sortie et ne bloque jamais.
- Entrées héritées (sans
protocol) : sortie standard tronquée d’un hook qui s’est terminé avec le code 0. - Entrées
protocol: "claude-code":hookSpecificOutput.additionalContext, lereasond’un verdict{"decision": "block", "reason": "..."}, ou stderr lorsque le hook se termine avec le code 2. Les autres codes non nuls ne contribuent rien.
Le retour est plafonné à 4,000 caractères par hook et à 8,000 caractères par appel d’outil, afin qu’un hook bruyant ne puisse pas inonder le contexte. C’est ce qui rend le paquet format-after-edit utile : son rappel arrive désormais dans le tour suivant du modèle au lieu de rester seulement dans le journal.
Ces noms correspondent aux déclencheurs internes de plugins d’AX Code (tool.execute.before / tool.execute.after), plus les hooks d’invite, de compactage, de sous-agent et d’arrêt au niveau de la session. Les invites de continuation synthétiques (invites internes agentRouting: "preserve") n’émettent pas UserPromptSubmit.
Activer les paquets
Les hooks et plugins de projet exécutent du code contrôlé par le dépôt, donc .ax-code/hooks.json, .ax-code/plugin/ et les plugins configurés par le projet sont désactivés par défaut. Après les avoir examinés, activez-les hors du dépôt au démarrage d’AX Code :
AX_CODE_TRUST_PROJECT_CONFIG=1 ax-code
Puis créez .ax-code/hooks.json dans votre projet :
{
"packs": ["format-after-edit", "block-force-push", "require-tests-on-stop", "protect-env-files", "log-bash-commands"]
}
Paquets officiels (≥5)
| Paquet | Événements | Description |
|---|---|---|
format-after-edit |
PostToolUse | Rappelle à l’agent de formater après les modifications |
block-force-push |
PreToolUse | Bloque git push --force / -f |
require-tests-on-stop |
Stop | Rappelle de vérifier après les mutations |
protect-env-files |
PreToolUse | Avertit lorsque des outils touchent .env |
log-bash-commands |
PreToolUse | Journalise les commandes bash pour l’audit |
Hooks personnalisés :
{
"hooks": [
{
"event": "PreToolUse",
"matcher": "bash",
"command": "echo running bash",
"blockOnFailure": false
}
]
}
Protocole de liaison Claude Code (activation explicite)
Si vous avez déjà des hooks écrits pour Claude Code, une entrée peut adopter le protocole de liaison Claude Code avec "protocol": "claude-code" :
{
"hooks": [
{
"event": "PreToolUse",
"matcher": "bash",
"command": "my-claude-code-hook.sh",
"protocol": "claude-code"
}
]
}
Pour les événements bloquants (PreToolUse, UserPromptSubmit), les entrées activées sont décodées avec la sémantique Claude Code à la place du contrôle blockOnFailure :
- Code de sortie 2 bloque l’action ; le stderr du hook est présenté comme la raison. Une sortie standard mal formée bloque encore (sécurité par défaut).
- Code de sortie 0 avec un JSON de sortie standard
{"permissionDecision": "allow"|"deny"|"ask", "reason"?}:allowpoursuit ;denybloque avecreason;askmet l’appel d’outil en pause sur une invite de permission interactivehookqui montre la raison (défaut"hook requested user confirmation"). L’invite est seulement interactive : aucune règlealways, aucun octroi par joker ni aucune approbation automatique du mode autonome ne peut y répondre, et une exécution sans interface la rejette, ce que le modèle voit comme un rejet de permission ordinaire. Un hook ultérieur qui réponddenyl’emporte sur unaskantérieur.UserPromptSubmitn’a pas d’appel d’outil auquel attacher une invite, doncaskbloque encore là. La forme imbriquée Claude Code{"hookSpecificOutput": {"permissionDecision": "...", "permissionDecisionReason": "..."}}est acceptée comme alias. - Tout autre code de sortie est une erreur non bloquante (journalisée, l’action continue).
Les événements seulement observateurs ignorent entièrement le décodeur — ils ne peuvent jamais bloquer. Les entrées sans le champ protocol se comportent exactement comme avant.
Variables d’environnement disponibles pour les commandes de hook :
HOOK_EVENT— PreToolUse, PostToolUse, PostToolUseFailure, Stop, UserPromptSubmit, PreCompact, SubagentStop, SessionStart, SessionEnd, PostCompact et InterruptHOOK_TOOL— identifiant d’outilHOOK_SESSION_IDHOOK_ARGS_JSON— arguments d’outil JSONHOOK_ARGS_STDIN=1— les arguments JSON complets sont toujours disponibles sur stdin ;HOOK_ARGS_JSONest vide pour les charges plus grandes que 32 KiBHOOK_PACK— nom du paquet lorsque cela s’applique
Les processus enfants des hooks héritent d’une version assainie de l’environnement AX Code. AX Code conserve les variables ordinaires de plateforme et d’outillage, mais retire les noms qui ressemblent à des secrets, les URL porteuses d’identifiants, les assistants d’identifiants tels que SSH_AUTH_SOCK, et les variables d’injection de processus telles que NODE_OPTIONS. Les variables de protocole HOOK_* ci-dessus sont ajoutées après l’assainissement et sont toujours disponibles.
Les hooks hérités pleinement fiables qui exigent des identifiants ambiants peuvent rétablir le comportement précédent hors du dépôt :
AX_CODE_HOOKS_FULL_ENV=1 AX_CODE_TRUST_PROJECT_CONFIG=1 ax-code
Cette échappatoire expose chaque variable d’environnement à chaque hook activé. Un dépôt ne peut pas la demander via .ax-code/hooks.json ; ne l’utilisez qu’après avoir examiné tous les hooks et paquets.
Note de sécurité : l’assainissement de l’environnement réduit l’exposition des identifiants ambiants, mais n’isole pas les commandes de hook. Les hooks restent du code shell arbitraire qui peut lire les fichiers accessibles et utiliser le réseau de l’hôte. Traitez-les comme du code de confiance et examinez chaque hook et paquet activé.
Lien avec l'isolation
Les hooks ne remplacent pas le bac à sable. Utilisez :
- L’isolation de l’application pour des frontières portables d’écriture et de réseau
- L’isolation du système (le moteur par défaut
"auto") pour un bac à sable bash appliqué par le noyau lorsqu’il est disponible - Les hooks pour les effets de bord de politique et les blocages fermes comme le force-push
Voir Mode bac à sable et SECURITY.md.