Hooks : des garde-fous qui se déclenchent tout seuls
Un hook est une action lancée automatiquement à un moment précis : empêcher une bêtise, formater, journaliser. Les moments de déclenchement, la configuration par fichiers, et un dossier rendu intouchable. Module 9.
- Distinguer une consigne écrite, que Claude suit souvent, d'un hook, qui s'exécute à coup sûr
- Choisir le moment de déclenchement adapté et écrire le hook correspondant dans les fichiers de réglages
- Bloquer une action indésirable avec le code de sortie 2, et vérifier que le garde-fou tient
Au module 6, vous avez écrit vos règles dans la mémoire du projet. Claude les lit, les comprend, et les suit — la plupart du temps. Une consigne en langage naturel reste une probabilité. Un hook en fait une certitude : une commande que le logiciel exécute lui-même, à un moment précis, sans rien demander à personne. Ce module se configure dans des fichiers : on sort de l’application.
Ce que vous allez apprendre
- Pourquoi un hook est plus fiable qu’une consigne écrite
- Les moments de déclenchement disponibles, et les deux qui servent vraiment
- Où et comment ça se configure — hors de l’application
- Le code de sortie qui bloque une action, et celui qui ne bloque rien
- Un cas pratique : rendre un dossier de documents importants intouchable
Consigne ou hook
| Consigne dans la mémoire du projet | Hook | |
|---|---|---|
| Nature | Une phrase lue par Claude | Une commande exécutée par Claude Code |
| Fiabilité | Suivie souvent, pas toujours | Systématique |
| Peut bloquer une action | Non | Oui |
| Se configure | Dans l’application | Dans un fichier de réglages |
Le mot anglais hook signifie « crochet » : un point d’accroche dans le cycle de vie d’une session — démarrage, demande, outils, réponse, fin. Sur chacun, on branche une commande. Trois usages couvrent presque tous les besoins réels :
- Empêcher une bêtise : refuser une écriture dans un dossier sensible.
- Faire une corvée à votre place : reformater un fichier après chaque modification.
- Journaliser : garder une trace de ce qui a été fait, et quand.
Les moments de déclenchement
| Moment | Quand il survient | Usage typique |
|---|---|---|
| PreToolUse | Juste avant qu’un outil s’exécute — peut bloquer | Interdire une écriture |
| PostToolUse | Juste après qu’un outil a réussi | Formater, vérifier, journaliser |
| UserPromptSubmit | Quand vous validez une demande | Ajouter du contexte, filtrer |
| Notification | Quand Claude Code réclame votre attention | Notification sur le bureau |
| Stop | Quand Claude a fini de répondre | Prévenir que c’est terminé |
| SubagentStop | Quand un sous-agent termine (module 10) | Journaliser le travail délégué |
| PreCompact | Avant le résumé de la conversation | Sauvegarder la transcription |
| SessionStart | Au démarrage ou à la reprise d’une session | Charger l’état du dossier |
| SessionEnd | À la fermeture | Nettoyage, journal de bord |
Retenez le duo de tête. PreToolUse est un vigile : il peut barrer la route à l’action. PostToolUse est un concierge : il passe derrière et remet en ordre. Le reste sert au confort.
Où ça se configure
Les hooks se déclarent dans un fichier settings.json. Cette partie n’a pas d’équivalent dans l’application : il faut éditer le fichier — ce que Claude peut faire pour vous, si vous le lui demandez. Trois emplacements, du plus large au plus étroit :
| Fichier | Portée |
|---|---|
~/.claude/settings.json | Vos réglages personnels, tous vos dossiers |
.claude/settings.json | Le dossier de travail, partagé avec ceux qui l’ouvrent |
.claude/settings.local.json | Le dossier de travail, pour vous seul |
La structure a trois étages : le moment, le matcher — un filtre qui précise quels outils déclenchent le hook —, puis la commande.
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{ "type": "command", "command": "votre-commande-ici" }
]
}
]
}
}
Edit|Write se lit « Edit ou Write » : les deux outils qui écrivent dans les fichiers. Un nom seul cible un outil précis ; un matcher vide cible tout.
Au moment de s’exécuter, votre commande reçoit une description de la situation au format JSON — du texte structuré — sur son entrée standard :
{
"session_id": "abc123",
"cwd": "/home/vous/papiers",
"hook_event_name": "PreToolUse",
"tool_name": "Write",
"tool_input": { "file_path": "/home/vous/papiers/originaux/piece.pdf" }
}
Quel outil, quel fichier, quelle session : tout y est. La commande dispose de 60 secondes par défaut.
💡 Astuce — Pour lire ce JSON dans un script, l’utilitaire
jqextrait n’importe quel champ en une ligne :jq -r '.tool_input.file_path'renvoie le chemin du fichier concerné.
Le contrat des codes de sortie
Le code de sortie est le nombre qu’un programme renvoie en se terminant. C’est par lui que votre hook répond à Claude Code.
| Code | Effet |
|---|---|
| 0 | Tout va bien, l’action suit son cours |
| 2 | L’action est bloquée, et la sortie d’erreur du hook est transmise à Claude |
| tout le reste | Erreur signalée, mais l’action n’est pas empêchée |
Le code 2 n’est pas qu’un mur : le message que votre script écrit sur la sortie d’erreur arrive à Claude, qui comprend le refus et cherche une autre voie.
⚠️ Piège courant — Le code 1, réflexe classique pour dire « erreur », ne bloque rien. Si votre garde-fou laisse passer ce qu’il devait interdire, vérifiez ce point d’abord : seul
exit 2bloque.
Pour les cas plus fins, un hook peut aussi imprimer un JSON qui autorise, refuse ou demande confirmation explicitement. Les codes de sortie couvrent l’immense majorité des besoins.
Cas pratique : un dossier de documents intouchable
Reprenons le dossier de papiers de famille. Un sous-dossier contient les scans d’origine, irremplaçables. La mémoire du projet le dit déjà (module 6) : « ne touche jamais à ce dossier ». On veut la certitude.
1. Le script. Dans .claude/hooks/protege-originaux.sh :
#!/bin/bash
# Refuse toute écriture dans le dossier des originaux
FICHIER=$(jq -r '.tool_input.file_path // empty')
if echo "$FICHIER" | grep -q 'originaux'; then
echo "Refusé : le dossier des originaux est en lecture seule. Travaille sur une copie." >&2
exit 2
fi
exit 0
Rendez-le exécutable avec chmod +x. Sous Windows, ce script s’exécute via Git Bash ou WSL.
2. Le brancher sur PreToolUse, dans .claude/settings.json :
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{ "type": "command",
"command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/protege-originaux.sh" }
]
}
]
}
}
CLAUDE_PROJECT_DIR pointe vers la racine du dossier de travail : le hook fonctionne quel que soit l’endroit d’où la session est lancée.
3. Le test. Demandez : « renomme les fichiers du dossier des originaux selon nos règles ». L’écriture est bloquée avant de commencer, et Claude, ayant reçu votre message, propose de travailler sur une copie. Le refus vient du logiciel, pas de sa bonne volonté.
4. Vérifier. La commande /hooks, tapée dans la session, liste les hooks actifs, leur matcher et leur provenance. Et claude --debug les montre vivre : le JSON reçu, le code renvoyé. Neuf fois sur dix, un hook qui ne se déclenche pas a un matcher mal orthographié ou un script non exécutable.
Le module 4 vous donnait le pouvoir de dire non. Le hook dit non à votre place, y compris quand vous ne regardez pas l’écran.
⚠️ Piège courant — Un hook branché sur
Edit|Writene se déclenche pour aucun autre outil. Le matcher décide, littéralement, quels outils passent devant le vigile : vérifiez qu’il couvre bien ceux que vous visez.
Rester prudent
Un hook est une commande arbitraire, exécutée avec vos droits. Elle peut lire vos fichiers, en supprimer, appeler Internet : c’est sa force et son risque.
⚠️ Piège courant — Vous ouvrez un dossier de projet récupéré en ligne : les hooks de son
.claude/settings.jsonont été écrits par quelqu’un d’autre et tourneront chez vous. Trente secondes de relecture avant de commencer.
Deuxième prudence : un hook mal écrit bloque tout. Un motif trop large — un mot présent dans la moitié de vos chemins — et plus rien ne passe. Testez sur une copie, et retenez où se trouve le fichier de réglages : c’est là qu’on retire la ligne fautive.
À vous de jouer
- Choisissez le dossier que vous ne voulez jamais voir modifié. C’est lui que le hook va protéger.
- Faites écrire le script : demandez à Claude, en français, un hook PreToolUse qui refuse toute écriture dont le chemin contient le nom de ce dossier, avec un message clair et
exit 2. - Relisez-le avant d’accepter. Un garde-fou que vous n’avez pas lu n’est pas un garde-fou.
- Testez le refus : demandez explicitement une modification dans ce dossier, et observez le blocage puis la réaction de Claude.
- Tapez /hooks pour voir votre hook listé avec sa provenance, puis relancez l’essai avec
claude --debugpour le voir recevoir son JSON.
En résumé
- Une consigne écrite est une probabilité ; un hook est une commande exécutée par le logiciel, systématiquement.
- Deux moments font l’essentiel : PreToolUse avant l’outil — le seul qui puisse bloquer — et PostToolUse après.
- La configuration sort de l’application :
settings.jsonpersonnel, partagé ou local, avec moment, matcher et commande. - Le hook reçoit sur son entrée standard un JSON décrivant l’action, et dispose de 60 secondes par défaut.
- Codes de sortie : 0 tout va bien, 2 bloque et transmet votre message à Claude, tout le reste signale sans empêcher.
/hooksliste les hooks actifs,claude --debugles montre en action.- Prudence double : on relit les hooks d’un dossier qu’on n’a pas créé, et on teste les siens sur une copie.
Module 10 : déléguer pour de bon — des sous-agents spécialisés, et vos propres skills pour rendre une procédure reproductible.
Testen Sie Ihr Wissen
Vous avez écrit dans la mémoire du projet : « ne touche jamais au dossier des originaux ». Qu'apporte un hook en plus ?
La mémoire du projet est lue et interprétée : elle influence Claude sans le contraindre. Le hook, lui, est exécuté par Claude Code avant l'action, indépendamment de ce que le modèle a compris. Les deux se complètent : la règle explique, le hook garantit.
Vous voulez qu'une vérification tourne avant chaque écriture de fichier, avec la possibilité de bloquer l'action. Quel moment de déclenchement choisissez-vous ?
PreToolUse est le seul moment où l'action n'a pas encore eu lieu : c'est donc le seul qui puisse l'empêcher. PostToolUse intervient après, quand il n'y a plus rien à bloquer — c'est le bon choix pour formater ou vérifier, pas pour interdire.
Votre garde-fou détecte le problème et se termine avec le code de sortie 1. Que se passe-t-il ?
Le contrat est strict : 0 signifie que tout va bien, 2 bloque, et tous les autres codes — dont le 1, réflexe habituel en shell — sont traités comme des erreurs non bloquantes. Un garde-fou qui renvoie 1 laisse passer ce qu'il voulait interdire.
Dans le cas pratique du module, comment Claude apprend-il pourquoi son écriture a été refusée ?
Avec le code 2, tout ce que le hook a écrit sur la sortie d'erreur est renvoyé à Claude, qui comprend le refus et propose autre chose — ici, travailler sur une copie. D'où l'intérêt d'écrire un message explicite plutôt qu'un simple « interdit ».
Vous ouvrez avec Claude Code un dossier de projet récupéré en ligne. Pourquoi relire son fichier de réglages avant de travailler ?
Un hook est une commande arbitraire lancée sur votre machine, avec vos droits : elle peut lire, supprimer, appeler Internet. Dans un dossier que vous n'avez pas créé, ces commandes viennent d'un inconnu. On les relit comme on relirait un script avant de le lancer.