
Claude Code Hooks : Le Guide Complet du Développeur avec des Exemples Prêts pour la Production
Claude Code est excellent pour écrire du code, mais c'est toujours un système probabiliste. Vous pouvez lui demander d'exécuter Prettier après chaque modification de fichier. Vous pouvez mettre cette instruction dans votre CLAUDE.md. Et parfois, il va simplement... l'oublier. Les hooks Claude Code résolvent ce problème en vous donnant un contrôle déterministe et garanti sur ce qui se passe avant, pendant et après chaque action que Claude effectue.
Je configure des hooks sur des dizaines de projets depuis quelques mois, et ils sont devenus discrètement la partie la plus importante de ma configuration Claude Code. Ce guide couvre tout, des bases jusqu'à un kit de démarrage prêt pour la production que vous pouvez intégrer à n'importe quel projet aujourd'hui. Si vous avez utilisé Claude Code aux côtés d'outils comme Cursor ou Copilot, vous connaissez déjà la valeur de la personnalisation -- les hooks vont encore plus loin.
Que Sont les Hooks Claude Code (et Pourquoi S'en Soucier) ?
Les hooks Claude Code sont des commandes shell définies par l'utilisateur, des endpoints HTTP ou des prompts LLM qui s'exécutent automatiquement à des points spécifiques du cycle de vie de Claude Code. Selon la documentation officielle d'Anthropic, contrairement aux instructions de prompt que Claude peut ignorer, les hooks se déclenchent de manière déterministe à chaque fois -- vous donnant un contrôle garanti sur le formatage, la sécurité, les notifications et l'automatisation des workflows.
Le Problème Probabiliste
Voilà le truc avec les instructions CLAUDE.md : ce sont des suggestions, pas des contrats. Vous pouvez écrire "toujours exécuter npx prettier --write après avoir modifié des fichiers TypeScript" dans votre contexte de projet, et Claude le suivra la plupart du temps. Mais "la plupart du temps" ne suffit pas quand vous appliquez un formatage de code à une équipe, ou que vous bloquez des push en production, ou que vous journalisez chaque commande shell pour un audit de sécurité.
C'est la tension centrale de tout outil de codage IA. Claude est un modèle de langage -- il fonctionne sur des probabilités. Votre context engineering peut orienter le comportement, mais il ne peut pas le garantir.
Comment les Hooks Résolvent Ce Problème
Les hooks contournent entièrement le LLM. Ce sont des scripts shell, des appels HTTP ou des évaluations IA qui se déclenchent à des événements spécifiques du cycle de vie -- avant l'exécution d'un outil (PreToolUse), après sa complétion (PostToolUse), quand une notification apparaît, quand une session démarre, ou quand Claude s'arrête. Pensez-y comme des hooks Git, mais pour votre assistant de codage IA.
Il existe quatre types de hooks : command (scripts shell), HTTP (requêtes POST de webhook), prompt (évaluations oui/non par Claude en un seul tour), et agent (lance un sous-agent avec accès aux outils). Nous détaillerons chacun plus tard -- les hooks command couvrent environ 90 % de vos besoins.
Comment Fonctionnent les Hooks Claude Code : Le Flux du Cycle de Vie
Les hooks Claude Code s'exécutent selon un cycle de vie défini : un événement se déclenche (ex. PreToolUse), le matcher vérifie si le hook s'applique, le script de hook s'exécute et reçoit du JSON sur stdin, et le code de sortie détermine ce qui se passe ensuite. Exit code 0 signifie continuer, exit code 2 signifie bloquer l'action. Ce flux est identique quel que soit le type de hook utilisé.
Événement -> Matcher -> Hook -> Code de Sortie (Le Flux en 4 Étapes)
Voici comment chaque exécution de hook fonctionne :
1. ÉVÉNEMENT SE DÉCLENCHE ex., PreToolUse(Write)
|
2. MATCHER VÉRIFIE "Write" correspond-il au pattern du matcher du hook ?
|
3. HOOK S'EXÉCUTE Le script shell tourne, reçoit du JSON via stdin
|
4. CODE DE SORTIE DÉCIDE 0 = continuer | 2 = bloquer | autre = erreurLe JSON qui arrive sur stdin contient tout sur l'événement : le tool_name, le tool_input (chemin de fichier, contenu, commande), et les métadonnées de session. Votre script lit ce JSON, applique la logique nécessaire, et sort avec le code approprié.
Pour les hooks PreToolUse, l'exit code 2 est le plus puissant -- il bloque l'action entièrement et renvoie votre message stdout à Claude comme feedback. Claude voit votre message et peut ajuster son approche.
Portées de Configuration : User, Project et Local
Les hooks résident dans settings.json à trois niveaux :
| Portée | Fichier | Versionné dans Git ? | Cas d'utilisation |
|---|---|---|---|
| User | ~/.claude/settings.json | Non | Préférences personnelles (notifications, formatage) |
| Project | .claude/settings.json | Oui | Hooks partagés en équipe (protection de fichiers, tests, linting) |
| Local | .claude/settings.local.json | Non (gitignored) | Surcharges personnelles pour ce projet |
Les paramètres de projet sont les plus utiles pour les équipes. Mettez vos hooks dans .claude/settings.json, commitez, et chaque développeur de l'équipe bénéficie automatiquement des mêmes garde-fous.
Le Champ if : Filtrage Fin
Depuis Claude Code v2.1.85, les hooks supportent un champ if qui permet de filtrer par arguments d'outil -- pas seulement par noms d'outils. Comme documenté dans la référence des hooks Anthropic, vous pouvez écrire un hook qui se déclenche uniquement sur les commandes Bash correspondant à git push, au lieu de se déclencher sur chaque invocation de Bash.
{
"matcher": "Bash",
"if": "tool_input.command matches 'git push'",
"hooks": [{ "type": "command", "command": "./scripts/check-branch.sh" }]
}C'était un vrai tournant. Avant if, il fallait soit matcher trop largement (toutes les commandes Bash) soit faire le filtrage dans le script (peu élégant).
Tous les Événements de Hooks Claude Code : Tableau de Référence Rapide
Claude Code propose plus de 20 événements de hooks sur l'ensemble de son cycle de vie, comme documenté dans la référence officielle des hooks et le changelog Claude Code. Les plus utilisés sont PreToolUse, PostToolUse, Notification et Stop -- mais les événements plus récents comme ConfigChange et FileChanged ouvrent des patterns d'automatisation avancés.
Voici la référence complète :
| Événement | Quand il se déclenche | Peut bloquer ? | Cas d'utilisation courant |
|---|---|---|---|
| PreToolUse | Avant l'exécution d'un outil | Oui (exit 2) | Bloquer les commandes dangereuses, protéger les fichiers |
| PostToolUse | Après la complétion d'un outil | Non | Auto-format, lancer les tests, journaliser les actions |
| Notification | Quand Claude envoie une notification | Non | Alertes bureau, messages Slack |
| Stop | Quand Claude termine une réponse | Non | Nettoyage, génération de résumés |
| SessionStart | À l'initialisation de la session | Non | Injecter du contexte, configurer l'environnement |
| UserPromptSubmit | Quand l'utilisateur soumet un prompt | Oui (exit 2) | Validation des entrées, filtrage de contenu |
| PreCompact | Avant la compaction du contexte | Non | Sauvegarder l'état avant la réduction mémoire |
| PostCompact | Après la compaction du contexte | Non | Réinjecter le contexte critique |
| ConfigChange | Quand les paramètres changent | Non | Recharger les variables d'environnement à chaud |
| FileChanged | Quand un fichier surveillé change | Non | Déclencher des rebuilds, invalider les caches |
| TaskCreated | Quand une nouvelle tâche est créée | Non | Suivi des tâches, allocation de ressources |
| PermissionDenied | Quand une vérification de permission échoue | Non | Journalisation d'audit, alerte sur actions bloquées |
| WorktreeCreate | Quand un nouveau worktree Git est créé | Non | Initialiser les paramètres spécifiques au worktree |
| SubagentStart | Quand un sous-agent démarre | Non | Surveiller l'activité des sous-agents |
| SubagentStop | Quand un sous-agent se termine | Non | Valider la sortie du sous-agent |
Conseil pro : Vous utiliserez PreToolUse et PostToolUse pour 80 % de vos hooks. SessionStart est le suivant le plus utile -- parfait pour injecter le contexte du projet dont Claude a besoin au début de chaque session.
Les 4 Types de Hooks Claude Code Expliqués
Claude Code supporte quatre types de handlers : les hooks command exécutent des scripts shell, les hooks HTTP envoient des POST vers des URLs, les hooks prompt posent une question oui/non à Claude, et les hooks agent lancent un sous-agent avec accès aux outils. D'expérience, les hooks command couvrent 90 % des cas. Utilisez HTTP pour les intégrations externes, et prompt/agent pour les décisions nuancées nécessitant un jugement IA.
| Type | Vitesse | Complexité | Idéal pour | Exemple |
|---|---|---|---|---|
| Command | Rapide | Faible | Formatage, blocage, journalisation | Exécuter Prettier après édition de fichier |
| HTTP | Moyen | Moyen | Services externes, webhooks | POST vers Slack à la complétion |
| Prompt | Lent | Moyen | Décisions subjectives | "Ce code est-il sûr à exécuter ?" |
| Agent | Le plus lent | Élevé | Vérification complexe avec accès aux fichiers | Vérifier si le nouveau code suit les patterns du projet |
Hooks Command (Le Cheval de Labour)
Les hooks command exécutent une commande shell et utilisent le code de sortie pour déterminer le résultat. Ils reçoivent les données JSON de l'événement sur stdin.
{
"hooks": {
"PreToolUse": [{
"matcher": "Bash",
"hooks": [{
"type": "command",
"command": "jq -r '.tool_input.command' | grep -q 'rm -rf /' && exit 2 || exit 0"
}]
}]
}
}C'est ce que vous utiliserez pour le formatage, la protection de fichiers, les notifications et la plupart des automatisations. Rapide, simple et prévisible.
Hooks HTTP (Intégrations Externes)
Les hooks HTTP envoient une requête POST vers une URL avec le JSON de l'événement comme corps. Le code de statut de la réponse détermine le résultat (200 = continuer, 403 = bloquer).
{
"hooks": {
"Stop": [{
"matcher": "",
"hooks": [{
"type": "http",
"url": "https://your-api.com/claude-webhook"
}]
}]
}
}Idéal pour envoyer des événements vers Slack, Discord, PagerDuty, ou un dashboard personnalisé. Vous pouvez également utiliser cela pour interroger un moteur de politique externe avant d'autoriser une exécution d'outil.
Hooks Prompt (Décisions Pilotées par l'IA)
Les hooks prompt transmettent les données de l'événement à Claude lui-même pour une évaluation oui/non en un seul tour. Claude renvoie une réponse JSON avec "decision": "allow" ou "decision": "block" accompagnée d'un raisonnement.
{
"hooks": {
"PreToolUse": [{
"matcher": "Bash",
"hooks": [{
"type": "prompt",
"prompt": "Is this bash command safe to run in a production environment? Consider: does it modify system files, delete data, or access sensitive credentials?"
}]
}]
}
}Utilisez-les avec parcimonie. Ils ajoutent de la latence (un appel LLM complet par exécution de hook) et un coût. Mais pour des vérifications de sécurité genuinement subjectives -- comme "cette migration de base de données semble-t-elle destructive ?" -- ils sont difficiles à battre. Si vous vous intéressez à changer le modèle utilisé par Claude Code, le modèle utilisé pour les hooks prompt suit votre modèle de session actuel.
Hooks Agent (Vérification Assistée par Outils)
Les hooks agent lancent un sous-agent avec accès aux outils Read, Grep et Glob. Le sous-agent peut inspecter des fichiers avant de prendre sa décision.
{
"hooks": {
"PreToolUse": [{
"matcher": "Write",
"hooks": [{
"type": "agent",
"prompt": "Check if the file being written follows the project's naming conventions and import patterns. Read .claude/CONVENTIONS.md for the rules."
}]
}]
}
}C'est le type de hook le plus puissant, mais aussi le plus lent. Réservez-le aux vérifications à enjeux élevés où vous avez besoin du contexte des fichiers pour prendre une bonne décision.
7 Exemples de Hooks Claude Code Prêts pour la Production (Copiez-Collez)
Les hooks Claude Code les plus utiles incluent l'auto-formatage avec Prettier ou Black après les modifications de fichiers, le blocage des écritures vers des fichiers protégés, l'envoi de notifications bureau à la complétion des tâches, l'injection de contexte de projet au démarrage de session, l'exécution automatique des tests après modifications du code, l'application de la protection des branches, et l'audit de toutes les utilisations d'outils. J'ai utilisé des variantes de ces exemples sur chaque projet depuis trois mois.
Chaque exemple ci-dessous est un extrait complet de settings.json que vous pouvez intégrer dans votre .claude/settings.json. Les collections communautaires comme awesome-claude-code proposent encore plus de patterns.
1. Auto-Format à l'Enregistrement
{
"hooks": {
"PostToolUse": [{
"matcher": "Write|Edit",
"hooks": [{
"type": "command",
"command": "FILE=$(jq -r '.tool_input.file_path // .tool_input.file' /dev/stdin); case \"$FILE\" in *.ts|*.tsx|*.js|*.jsx) npx prettier --write \"$FILE\" 2>/dev/null;; *.py) black \"$FILE\" 2>/dev/null;; esac; exit 0"
}]
}]
}
}Ce hook se déclenche après chaque Write ou Edit, extrait le chemin du fichier depuis le JSON stdin, et exécute le formateur approprié. Le exit 0 à la fin garantit que le hook ne bloque jamais -- les échecs de formatage ne doivent pas arrêter Claude.
Conseil pro : Ajoutez *.go avec gofmt et *.rs avec rustfmt si vous travaillez dans plusieurs langages.
2. Bloquer les Écritures vers les Fichiers Protégés
{
"hooks": {
"PreToolUse": [{
"matcher": "Write|Edit",
"if": "tool_input.file_path matches '(\\.env|\\.env\\.local|package-lock\\.json|yarn\\.lock|pnpm-lock\\.yaml)'",
"hooks": [{
"type": "command",
"command": "echo '{\"message\": \"BLOCKED: This file is protected. Edit it manually.\"}' && exit 2"
}]
}]
}
}L'exit code 2 bloque l'action et renvoie le message JSON à Claude. Claude voit le feedback et s'adapte -- en général, il vous dira qu'il voulait modifier le fichier et vous demandera de le faire manuellement. Le champ if évite que ce hook se déclenche sur chaque Write.
3. Notification Bureau à la Complétion
{
"hooks": {
"Notification": [{
"matcher": "",
"hooks": [{
"type": "command",
"command": "MSG=$(jq -r '.message // \"Claude Code task finished\"' /dev/stdin); if [ \"$(uname)\" = 'Darwin' ]; then osascript -e \"display notification \\\"$MSG\\\" with title \\\"Claude Code\\\"\"; else notify-send 'Claude Code' \"$MSG\"; fi; exit 0"
}]
}]
}
}Fonctionne sur macOS (osascript) et Linux (notify-send). Le matcher vide signifie qu'il se déclenche sur toutes les notifications. Vraiment utile quand vous lancez une longue tâche et passez à une autre fenêtre.
4. Injection de Contexte au Démarrage de Session
{
"hooks": {
"SessionStart": [{
"matcher": "",
"hooks": [{
"type": "command",
"command": "echo '{\"message\": \"Project: '\"$(basename $(pwd))\"' | Branch: '\"$(git branch --show-current 2>/dev/null || echo none)\"' | Last commit: '\"$(git log --oneline -1 2>/dev/null || echo none)\"'\"}'; exit 0"
}]
}]
}
}Cela injecte le nom du projet actuel, la branche Git et le dernier commit dans chaque session. Claude reçoit ce contexte automatiquement -- pas besoin de lui dire sur quelle branche vous êtes.
5. Exécution Automatique des Tests après Modification du Code
{
"hooks": {
"PostToolUse": [{
"matcher": "Write|Edit",
"if": "tool_input.file_path matches '\\.(ts|tsx|js|jsx|py)$'",
"hooks": [{
"type": "command",
"command": "FILE=$(jq -r '.tool_input.file_path' /dev/stdin); TEST_FILE=$(echo \"$FILE\" | sed 's/\\.[^.]*$/.test&/'); if [ -f \"$TEST_FILE\" ]; then npx jest \"$TEST_FILE\" --no-coverage 2>&1 | tail -5; fi; exit 0",
"timeout": 30000
}]
}]
}
}Si un fichier de test correspondant existe, il s'exécute automatiquement après que Claude a modifié le source. Le tail -5 garde la sortie concise, et le timeout évite les suites de tests incontrôlées. Cela se combine bien avec un workflow de revue de code assistée par IA.
6. Application de la Protection des Branches (Avancé)
{
"hooks": {
"PreToolUse": [{
"matcher": "Bash",
"if": "tool_input.command matches 'git push.*(main|master|production)'",
"hooks": [{
"type": "command",
"command": "echo '{\"message\": \"BLOCKED: Direct push to protected branch. Use a feature branch and open a PR.\"}' && exit 2"
}]
}]
}
}Ce hook bloque tout git push ciblant les branches main, master ou production. Claude reçoit le feedback et suggèrera de créer une branche de fonctionnalité à la place.
7. Journalisation d'Audit de Sécurité (Avancé)
{
"hooks": {
"PostToolUse": [{
"matcher": "Bash",
"hooks": [{
"type": "command",
"command": "INPUT=$(cat /dev/stdin); CMD=$(echo \"$INPUT\" | jq -r '.tool_input.command'); echo \"[$(date -u +%Y-%m-%dT%H:%M:%SZ)] BASH: $CMD\" >> .claude/audit.log; exit 0"
}]
}]
}
}Enregistre chaque commande Bash exécutée par Claude dans un fichier d'audit avec un horodatage UTC. Inestimable pour les revues de sécurité et pour comprendre ce que Claude a réellement fait pendant une session. Gardez .claude/audit.log dans votre .gitignore.
Hooks vs MCP vs Skills vs CLAUDE.md : Quand Utiliser Quoi
Utilisez les hooks pour l'automatisation déterministe qui doit toujours s'exécuter (formatage, blocage, notifications). Utilisez MCP pour donner à Claude accès à des outils et données externes. Utilisez les Skills pour les packages de prompts réutilisables. Utilisez CLAUDE.md pour les directives comportementales et le contexte du projet. Les hooks sont garantis ; tout le reste est probabiliste. C'est la distinction la plus importante, et je reviens toujours dessus quand je conseille des équipes.
La Matrice de Décision
| Mécanisme | Déterministe ? | Quand il s'exécute | Idéal pour | Exemple |
|---|---|---|---|---|
| Hooks | Oui | Automatiquement sur les événements du cycle de vie | Application, automatisation, notifications | Auto-format, bloquer les écritures de fichiers |
| MCP | Non (Claude décide) | Quand Claude appelle l'outil MCP | Nouvelles capacités, accès à des données externes | Interroger une base de données, chercher dans Notion |
| Skills | Non (l'utilisateur déclenche) | Quand l'utilisateur invoque une commande slash | Ensembles d'instructions réutilisables | /review pour le workflow de revue de code |
| CLAUDE.md | Non (directive) | Lu au démarrage de session | Contexte du projet, standards de codage | "Utiliser Tailwind, écrire des tests pour tout nouveau code" |
Pour une analyse approfondie de MCP, consultez notre guide MCP. Si vous venez de Cursor, le système de règles de Cursor est grosso modo analogue à CLAUDE.md -- mais Cursor n'a rien de comparable aux hooks.
Quand ils Se Chevauchent (et Comment Choisir)
Voici l'organigramme que j'utilise :
- "Est-ce que cela DOIT se produire à chaque fois, sans exception ?" -- Hook. Formatter le code, bloquer les fichiers protégés, envoyer des notifications. Zéro ambiguïté.
- "Claude a-t-il besoin d'une nouvelle CAPACITÉ qu'il n'a pas ?" -- Serveur MCP. Accéder à une base de données, appeler une API, chercher dans des docs externes.
- "Est-ce que je veux des INSTRUCTIONS réutilisables pour un workflow spécifique ?" -- Skill (commande slash). Templates de revue de code, checklists de déploiement.
- "Est-ce que je veux façonner le COMPORTEMENT de Claude dans ce projet ?" -- CLAUDE.md. Standards de codage, décisions d'architecture, bibliothèques préférées.
Des exemples concrets qui clarifient la frontière :
- "Toujours formater avec Prettier" = Hook (doit se produire à chaque fois)
- "Utiliser Prettier pour le formatage" dans CLAUDE.md = Directive (Claude peut oublier)
- "Chercher dans nos docs internes" = MCP (nouvelle capacité)
- "Suivre notre guide de style lors des revues de code" = Skill ou CLAUDE.md
Comme décrit dans l'annonce des plugins Anthropic, les hooks font partie d'un écosystème de plugins plus large qui inclut également MCP et les Skills. Ils sont conçus pour se compléter, pas pour se concurrencer.
Le Kit de Démarrage : Configuration de Hooks Claude Code Clé en Main pour N'importe Quel Projet
Une configuration de hooks de démarrage pour Claude Code devrait inclure l'auto-format à l'édition de fichier, la notification à la complétion de tâche, la protection de fichiers sensibles, l'injection de contexte de session, et un hook Stop pour le nettoyage. C'est exactement la configuration que j'intègre à chaque nouveau projet -- adaptée à la stack, mais la structure reste identique.
La Configuration
{
"hooks": {
"SessionStart": [{
"matcher": "",
"hooks": [{
"type": "command",
"command": "echo '{\"message\": \"Project: '\"$(basename $(pwd))\"' | Branch: '\"$(git branch --show-current 2>/dev/null)\"' | Node: '\"$(node -v 2>/dev/null)\"'\"}'; exit 0"
}]
}],
"PreToolUse": [{
"matcher": "Write|Edit",
"if": "tool_input.file_path matches '(\\.env|\\.env\\..+|.*lock\\.json|.*lock\\.yaml)'",
"hooks": [{
"type": "command",
"command": "echo '{\"message\": \"Protected file. Edit manually.\"}' && exit 2"
}]
}],
"PostToolUse": [{
"matcher": "Write|Edit",
"hooks": [{
"type": "command",
"command": "FILE=$(jq -r '.tool_input.file_path // .tool_input.file' /dev/stdin); case \"$FILE\" in *.ts|*.tsx|*.js|*.jsx) npx prettier --write \"$FILE\" 2>/dev/null;; *.py) black \"$FILE\" 2>/dev/null;; *.go) gofmt -w \"$FILE\" 2>/dev/null;; esac; exit 0"
}]
}],
"Notification": [{
"matcher": "",
"hooks": [{
"type": "command",
"command": "MSG=$(jq -r '.message // \"Done\"' /dev/stdin); osascript -e \"display notification \\\"$MSG\\\" with title \\\"Claude Code\\\"\" 2>/dev/null || notify-send 'Claude Code' \"$MSG\" 2>/dev/null; exit 0"
}]
}],
"Stop": [{
"matcher": "",
"hooks": [{
"type": "command",
"command": "echo '[STOP] '\"$(date +%H:%M:%S)\"'' >> .claude/session.log; exit 0"
}]
}]
}
}Comment Personnaliser pour Votre Stack
| Stack | Commande de format | Commande de test | Extensions surveillées |
|---|---|---|---|
| Node/TypeScript | npx prettier --write | npx jest --no-coverage | .ts, .tsx, .js, .jsx |
| Python | black | pytest -x | .py |
| Go | gofmt -w | go test ./... | .go |
| Rust | rustfmt | cargo test | .rs |
Remplacez les commandes de format et de test dans la configuration ci-dessus pour correspondre à votre stack. La structure reste identique.
Vérifier que Vos Hooks Fonctionnent
Trois façons de confirmer que les hooks sont actifs :
- Commande
/hooks-- Tapez/hooksdans Claude Code pour voir tous les hooks enregistrés, leurs matchers et leur statut. - Inspection de la transcription -- Après le déclenchement d'un hook, vérifiez la transcription de session. Les exécutions de hooks apparaissent avec leur sortie et leur code de sortie.
- Bascule rapide -- Ajoutez
"disableAllHooks": trueà votre settings.json pour désactiver temporairement tous les hooks sans supprimer la configuration. Supprimez-le (ou mettezfalse) pour les réactiver.
Intégration CI/CD : Les Hooks Claude Code en Mode Headless
Les hooks Claude Code fonctionnent en mode headless (claude -p) avec quelques différences : les hooks Notification se déclenchent toujours mais vous devriez rediriger vers des logs plutôt que des alertes bureau. Les hooks PreToolUse avec exit code 2 peuvent mettre en pause les sessions headless pour une revue humaine. GitHub Actions utilise anthropics/claude-code-action@v1 en parallèle des hooks pour des workflows automatisés.
Comportement en Mode Headless
| Événement hook | Mode interactif | Mode headless (-p) | Recommandation CI |
|---|---|---|---|
| PreToolUse (exit 2) | Bloque, affiche le message | Met en pause pour --resume | Utiliser pour les approbations humaines obligatoires |
| PostToolUse | S'exécute normalement | S'exécute normalement | Garder les formateurs et loggers |
| Notification | Alerte bureau | Se déclenche toujours (sans UI) | Rediriger vers un fichier log ou un webhook Slack |
| Stop | Lance le nettoyage | Lance le nettoyage | Bien pour la collecte d'artefacts CI |
| SessionStart | Injecte le contexte | Injecte le contexte | Injecter les variables d'environnement CI |
La grande surprise en mode headless : les hooks PreToolUse qui sortent avec le code 2 ne se contentent pas d'échouer silencieusement. Ils mettent la session en pause et permettent de reprendre avec --resume, ce qui donne un pattern human-in-the-loop pour les pipelines CI.
Intégration GitHub Actions
Voici un workflow GitHub Actions minimal qui utilise Claude Code avec des hooks. Comme documenté dans le guide officiel GitHub Actions :
- name: Run Claude Code
uses: anthropics/claude-code-action@v1
with:
prompt: "Review this PR and suggest improvements"
allowed_tools: "Read,Grep,Glob"
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}Vos hooks .claude/settings.json voyagent avec le dépôt, donc ils se déclencheront en CI exactement comme en local. Assurez-vous simplement que les hooks qui reposent sur des outils spécifiques au bureau (comme osascript) ont des alternatives ou des conditions.
Gestion des Hooks en Équipe
Un pattern qui fonctionne bien pour les équipes :
.claude/settings.json(commité) -- Hooks partagés en équipe : protection de fichiers, formateurs, protection des branches. Tout le monde les reçoit..claude/settings.local.json(gitignored) -- Hooks personnels : préférences de notification, logging personnalisé, hooks expérimentaux.~/.claude/settings.json(global utilisateur) -- Vos défauts pour tous les projets : style de notification, préférences de formatage personnelles.
Cela ressemble à la façon dont .editorconfig (commité) et les paramètres IDE locaux (personnels) fonctionnent. Comme le note le guide CI/CD d'Angelo Lima, les équipes qui standardisent sur des hooks partagés voient moins de problèmes "ça marche sur ma machine" avec Claude Code.
Dépannage des Hooks Claude Code et Erreurs Courantes
Les problèmes courants avec les hooks Claude Code incluent : les hooks qui ne se déclenchent pas (vérifiez l'orthographe du matcher et l'emplacement du settings.json), les hooks qui s'exécutent mais ne bloquent pas (mauvais code de sortie -- utilisez 2 pas 1), les boucles infinies (le hook Stop se déclenche lui-même), et les démarrages lents (trop de hooks synchrones). L'erreur la plus courante que je vois est la confusion sur les codes de sortie -- les développeurs utilisent exit 1 quand ils veulent dire exit 2.
Le Hook Ne Se Déclenche Pas
Symptômes : Vous avez ajouté un hook mais rien ne se passe quand l'événement se produit.
Solutions :
- Faute de frappe dans le matcher -- Les matchers sont sensibles à la casse.
"write"ne correspondra pas à l'outilWrite. Vérifiez les noms exacts des outils avec/hooks. - Mauvais fichier de paramètres -- Les hooks dans
~/.claude/settings.jsonn'apparaîtront pas dans la sortie de/hookspour la portée du projet. Essayez.claude/settings.jsonà la racine du projet. - Erreur de syntaxe JSON -- Une virgule parasite ou un crochet manquant désactive silencieusement toute la configuration des hooks. Passez votre settings.json dans
jq .pour valider. disableAllHooks: true-- Vérifiez si quelqu'un (ou une session de debug précédente) a laissé ce flag activé.
Le Hook S'exécute mais Ne Bloque Pas
Symptômes : Votre hook PreToolUse s'exécute, mais l'action continue quand même.
Solutions :
- Mauvais code de sortie -- L'exit code 1 signifie "erreur" (le hook a échoué), pas "bloquer". Utilisez
exit 2pour bloquer une action. Cela piège presque tout le monde, comme noté dans la doc officielle. - JSON stdout manquant -- Pour les hooks bloquants, affichez un message JSON pour que Claude sache pourquoi l'action a été bloquée :
echo '{"message": "Blocked: reason"}'
Boucles Infinies
Symptômes : Claude continue de retenter la même action, ou votre machine chauffe de façon suspecte.
Solutions :
- Le hook Stop déclenche des actions -- Si votre hook Stop écrit un fichier ou exécute une commande qui pousse Claude à répondre, vous avez créé une boucle. Les hooks Stop ne devraient faire que des choses passives : logger, notifier, nettoyer.
- Le hook PostToolUse cause des modifications -- Un hook PostToolUse qui modifie un fichier déclenche un autre événement PostToolUse. Protégez-vous contre cela avec des matchers spécifiques ou le champ
if.
Problèmes de Performance
Symptômes : Claude prend notablement plus de temps à démarrer ou à exécuter des outils.
Solutions :
- Trop de hooks SessionStart -- Chacun s'exécute de manière synchrone au démarrage. Gardez-les légers (moins d'une seconde chacun).
- Scripts lourds dans les chemins critiques -- Les hooks sur PreToolUse et PostToolUse se déclenchent fréquemment. Si votre script fait des requêtes réseau ou des calculs lourds, ajoutez un champ
timeout(en millisecondes) et demandez-vous si ce devrait être un hook HTTP à la place. - Pas de mise en cache -- Si vous vérifiez la même chose de manière répétée (comme "est-ce une branche protégée ?"), mettez le résultat en cache dans un fichier temporaire plutôt que d'exécuter des commandes Git à chaque invocation de hook.
Foire Aux Questions
Que sont les hooks Claude Code et comment fonctionnent-ils ?
Les hooks Claude Code sont des scripts d'automatisation définis par l'utilisateur qui s'exécutent à des événements spécifiques du cycle de vie pendant une session Claude Code. Vous les configurez dans settings.json avec un pattern de matcher et un handler (commande shell, endpoint HTTP, prompt ou agent). Quand l'événement correspondant se déclenche, le hook s'exécute automatiquement et utilise les codes de sortie pour contrôler le résultat.
Comment configurer les hooks dans settings.json de Claude Code ?
Ajoutez un objet "hooks" à l'un des trois emplacements de configuration : ~/.claude/settings.json (global utilisateur), .claude/settings.json (partagé en projet), ou .claude/settings.local.json (personnel au projet). Chaque type d'événement correspond à un tableau de définitions de hooks avec matcher, le champ if optionnel, et un tableau hooks contenant des objets handler avec type et command ou url.
Quelle est la différence entre les hooks PreToolUse et PostToolUse ?
PreToolUse se déclenche avant l'exécution d'un outil, vous donnant le pouvoir de le bloquer avec exit code 2. PostToolUse se déclenche après la complétion de l'exécution, utile pour le formatage, les tests ou la journalisation. PreToolUse sert à la prévention et au contrôle d'accès. PostToolUse sert à la validation et au nettoyage. Les deux reçoivent le nom de l'outil et son entrée sous forme de JSON sur stdin.
Les hooks Claude Code peuvent-ils bloquer des commandes dangereuses ?
Oui. Les hooks PreToolUse avec exit code 2 bloquent n'importe quelle exécution d'outil. Vous pouvez protéger les fichiers sensibles de toute écriture, bloquer les commandes shell correspondant à des patterns dangereux comme rm -rf ou git push main, et empêcher l'accès aux bases de données de production. Le message de blocage est renvoyé à Claude comme feedback, afin qu'il puisse ajuster son approche.
Quels événements de hooks sont disponibles dans Claude Code ?
Claude Code propose 15+ événements : PreToolUse et PostToolUse pour l'exécution des outils, Notification pour les alertes, Stop pour la fin de session, SessionStart pour l'initialisation, UserPromptSubmit pour le filtrage des entrées, PreCompact et PostCompact pour la gestion du contexte, et les événements plus récents comme ConfigChange, FileChanged, TaskCreated et PermissionDenied. Voir le tableau de référence complet dans la section des événements de hooks ci-dessus.
En quoi les hooks diffèrent-ils des outils MCP et des Skills ?
Les hooks sont déterministes -- ils se déclenchent toujours sur les événements correspondants quel que soit ce que Claude décide. Les outils MCP étendent les capacités de Claude (accès aux bases de données, appels API) mais Claude choisit quand les utiliser. Les Skills sont des packages d'instructions réutilisables invoqués par des commandes slash. CLAUDE.md fournit des directives comportementales. Utilisez les hooks quand quelque chose doit se produire à chaque fois, MCP quand Claude a besoin de nouvelles capacités.
Les hooks Claude Code fonctionnent-ils en mode headless ?
Oui, avec des nuances. Les hooks se déclenchent normalement en mode headless (claude -p), mais les hooks spécifiques au bureau comme les notifications macOS nécessitent des alternatives. Surtout, les hooks PreToolUse qui sortent avec le code 2 peuvent mettre en pause les sessions headless pour une approbation humaine via --resume. Cela permet des pipelines CI/CD human-in-the-loop où certaines actions nécessitent une validation manuelle.
Combien de hooks est trop ? Les hooks ralentissent-ils Claude Code ?
Il n'y a pas de limite stricte, mais chaque hook synchrone ajoute de la latence. Les hooks SessionStart s'exécutent au démarrage, donc gardez-les rapides (moins d'une seconde chacun). Les hooks PreToolUse et PostToolUse se déclenchent à chaque appel d'outil correspondant -- les scripts lourds ici s'accumulent rapidement. Je recommande de garder le nombre total de hooks en dessous de 10-15, d'utiliser le champ if pour restreindre la portée, et d'ajouter des valeurs timeout pour éviter les scripts incontrôlés.
Puis-je utiliser des hooks pour auto-formater le code avec Prettier ou Black ?
Oui -- c'est le cas d'utilisation de hook le plus populaire. Créez un hook PostToolUse correspondant à Write|Edit, extrayez le chemin du fichier depuis le JSON stdin, et exécutez le formateur approprié selon l'extension du fichier. Voir l'exemple numéro un dans la section des exemples de production pour une configuration complète prête à copier-coller qui gère les fichiers TypeScript, JavaScript et Python.
Les hooks Claude Code sont-ils sûrs ? Quels sont les risques de sécurité ?
Les hooks s'exécutent avec vos permissions utilisateur complètes -- il n'y a pas de sandbox. Un hook malveillant pourrait lire vos clés SSH, supprimer des fichiers ou exfiltrer des données. N'utilisez que des hooks provenant de sources fiables, vérifiez tout .claude/settings.json partagé avant de l'accepter dans votre projet, et utilisez .claude/settings.local.json pour les hooks personnels qui ne devraient pas être partagés. Pour des patterns de sécurité IA plus larges, consultez notre guide sur les guardrails LLM.