Chapitre 7.1 — Anatomie d’un hook
⏱️ TL;DR — Un hook se déclare dans
settings.json: un événement (quand), un matcher (sur quel outil/cas), une commande (quoi lancer). Le harness l’exécute tout seul — d’où sa force : c’est déterministe, pas soumis à l’attention du modèle. Certains événements peuvent même bloquer l’action (unPreToolUsequi refuse une édition interdite). Comprendre les événements, c’est savoir où accrocher ton automatisme.
🎯 Objectifs
- Situer les événements de hook (avant/après outil, à l’arrêt…).
- Lire la structure d’un hook dans
settings.json. - Comprendre le mécanisme de blocage.
- Savoir que le hook vit hors du contexte (coût nul en tokens).
Le principe : le harness, pas le modèle
Rappel de la carte des briques (1.4) : le hook est la seule brique qui se déclenche sans invocation. Quand l’événement survient, le harness lance ta commande — que le modèle « y pense » ou non. C’est ce qui en fait une garantie. Et comme la config vit dans settings.json (pas dans le contexte), un hook ne coûte rien en tokens : il n’alourdit aucune tâche.
Les événements principaux
Un hook s’accroche à un moment du cycle de vie de la session. Les plus utiles :
| Événement | Se déclenche… | Usage typique |
|---|---|---|
| PreToolUse | avant qu’un outil s’exécute | bloquer une action (édition d’un fichier interdit, commande dangereuse) |
| PostToolUse | après un outil (ex. une édition) | formater/linter le fichier modifié |
| Stop | quand l’agent s’apprête à conclure | lancer les tests et refuser de finir s’ils échouent |
| UserPromptSubmit | à l’envoi de ton message | injecter du contexte, journaliser |
| SessionStart | au démarrage de session | préparer l’environnement |
💡 Réflexe d’architecte — Choisis l’événement selon le moment où l’automatisme a du sens : formater → après l’édition (
PostToolUse) ; empêcher une bêtise → avant (PreToolUse) ; garantir la qualité de fin → à la conclusion (Stop). Le bon hook au bon moment fait tout le travail ; le mauvais moment le rend inutile ou pénible.
La structure dans settings.json
Un hook se déclare sous la clé hooks, groupé par événement, avec un matcher (sur quel outil) et une ou plusieurs commandes :
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{ "type": "command", "command": "npx prettier --write ." }
]
}
]
}
}Lecture : « après un Edit ou un Write, lance prettier ». Le matcher filtre les outils concernés (ici les éditions) ; la commande est ce que le harness exécute. Le hook reçoit sur son entrée des informations sur l’événement (l’outil, les fichiers touchés) que ta commande/ton script peut exploiter.
📚 Aller plus loin — Les noms exacts des événements, la forme du matcher et le format des données reçues par le hook sont dans la doc officielle (
code.claude.com/docs) et peuvent évoluer. Considère les exemples de cette partie comme des patrons pédagogiques : vérifie la syntaxe précise dans la doc au moment de les écrire (ou fais-la générer par la skillupdate-config, voir 7.4).
Le blocage : le super-pouvoir du PreToolUse
Un hook PreToolUse peut empêcher l’action de se produire (typiquement en renvoyant un code de sortie d’échec). C’est ce qui transforme une consigne « ne touche pas à ce fichier » (molle) en interdiction dure :
Le message d’erreur du hook revient à l’agent : il comprend pourquoi c’est bloqué et s’adapte (« ah, je ne dois pas éditer les migrations à la main »). Le hook n’est pas qu’un mur : c’est un mur qui explique.
⚠️ Piège — Vouloir tout garantir par des hooks bloquants, au point de rendre le travail pénible (chaque action se heurte à un mur). Les hooks bloquants sont pour les vrais interdits (destructeur, fichiers protégés). Pour le reste, préfère les hooks informatifs/correctifs (
PostToolUsequi formate) : ils aident sans frustrer.
Où vivent les hooks
Comme le reste de settings.json, les hooks existent à plusieurs niveaux : projet (.claude/settings.json, versionné, partagé — l’idéal pour une équipe) et utilisateur (~/.claude/settings.json, tes automatismes perso). Un hook de projet garantit que tout le monde (et tout agent) qui travaille sur le repo hérite des mêmes automatismes — cohérence d’équipe, pas seulement la tienne.
🧭 Sur TaskFlow — Ta config actuelle n’a aucun hook (c’est le cas le plus courant, et le plus gros gisement d’amélioration). En 7.4, on ajoutera au projet TaskFlow une petite chaîne : prettier après édition, et les tests à la conclusion. À partir de là, « le code est formaté et les tests passent » ne dépend plus de personne — c’est mécanique.
✏️ Exercices
Exercice 1 — Range par événement. Prends 4 automatismes que tu voudrais (formater, bloquer un commit sur main, lancer les tests avant de finir, empêcher d’éditer un fichier généré). Associe à chacun le bon événement (Pre/Post/Stop).
✅ Solution
Formater → PostToolUse (après édition). Bloquer commit sur main → PreToolUse (avant la commande git, blocage). Tests avant de finir → Stop (à la conclusion). Empêcher d’éditer un fichier généré → PreToolUse (blocage). Le bon événement découle de « quand l’automatisme a du sens ».
Exercice 2 — Lis un hook. Écris (sur papier) la config d’un hook « après une édition, lance npm run lint». Identifie l’événement, le matcher, la commande.
✅ Solution
Événement PostToolUse, matcher sur les outils d’édition (Edit|Write), commande npm run lint. La forme exacte des clés se vérifie dans la doc, mais la structure « événement → matcher → commande » est constante. (Vérifier la syntaxe précise avant de l’appliquer.)
🧠 Quiz de révision
1. Pourquoi un hook est-il une « garantie » là où le CLAUDE.md ne l’est pas ?
Parce que c’est le harness qui l’exécute automatiquement sur un événement, indépendamment de l’attention du modèle. Le CLAUDE.md est du texte qui peut être oublié ; le hook, non.
2. Quel événement pour formater après une édition ? Pour bloquer une action ?
Formater → PostToolUse (après l’outil d’édition). Bloquer → PreToolUse (avant l’outil, peut refuser l’action).
3. Que contient la déclaration d’un hook ?
Un événement (quand), un matcher (sur quel outil/cas), et une commande (quoi lancer). Groupés sous la clé hooks de settings.json.
4. Un hook coûte-t-il du contexte ?
Non : sa config vit dans settings.json, hors de la fenêtre de contexte. Il n’alourdit aucune tâche — contrairement au CLAUDE.md.
5. Pourquoi ne pas tout garantir par des hooks bloquants ?
Parce que trop de murs rendent le travail pénible. Les hooks bloquants sont pour les vrais interdits (destructeur, fichiers protégés) ; pour le reste, des hooks correctifs/informatifs (formater) aident sans frustrer.
Chapitre suivant : Les hooks utiles — les recettes que tu voudras dès aujourd’hui.