Hooks & automation
Section intitulée « Hooks & automation »Les skills encapsulent ce qu’on fait. Les hooks automatisent ce qui doit toujours se passer — avant ou après une action, quoi qu’il arrive.
Les hooks sont des scripts shell exécutés automatiquement en réponse à des événements Claude Code. Ils ne dépendent pas de Claude — c’est le harness qui les lance.
Cycle de vie
Section intitulée « Cycle de vie »Les 5 événements
Section intitulée « Les 5 événements »| Événement | Déclenché quand |
|---|---|
UserPromptSubmit | L’utilisateur envoie un message |
PreToolUse | Claude est sur le point d’utiliser un outil |
PostToolUse | Claude vient d’utiliser un outil |
Stop | Claude a terminé sa réponse |
SubagentStop | Un sous-agent a terminé |
Configuration
Section intitulée « Configuration »Deux emplacements, deux portées différentes :
| Fichier | Portée |
|---|---|
~/.claude/settings.json | Personnel — s’applique à tous tes projets, non versionné |
.claude/settings.json | Projet — versionné dans le repo, s’applique à toute l’équipe |
Un hook dans .claude/settings.json du repo = un garde-fou imposable à l’équipe. Un hook dans ~/.claude/settings.json = une préférence personnelle.
Hook personnel (dans ~/.claude/settings.json) — chemin absolu vers un script local :
{ "hooks": { "Stop": [ { "hooks": [ { "type": "command", "command": "/home/user/.claude/hooks/notify.sh" } ] } ] }}Hook d’équipe (dans .claude/settings.json du repo, versionné) — le script doit lui aussi être dans le repo pour exister sur toutes les machines :
{ "hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [ { "type": "command", "command": ".claude/hooks/check-dangerous-cmd.sh" } ] } ] }}matcher filtre sur le nom de l’outil (Bash, Edit, Write…). Omis = tous les outils.
Codes de sortie
Section intitulée « Codes de sortie »| Code | Effet |
|---|---|
0 | Continue normalement |
1 | Bloque l’action + affiche stderr à Claude |
2 | Bloque + injecte stdout dans la conversation |
Exemple concret de exit 2 : le hook écrit Build échoué : erreur ligne 42 dans src/index.ts sur stdout → Claude voit ce message dans la conversation et peut corriger directement, sans que tu aies à copier-coller l’erreur manuellement.
Exemples
Section intitulée « Exemples »Bloquer rm -rf :
#!/bin/bash# .claude/hooks/check-dangerous-cmd.sh (versionné dans le repo)cmd=$(echo "$CLAUDE_TOOL_INPUT" | jq -r '.command // empty')if echo "$cmd" | grep -q "rm -rf"; then echo "Commande destructrice détectée — confirmation requise." >&2 exit 1fiNotification quand Claude a fini :
#!/bin/bashnotify-send "Claude Code" "Tâche terminée"# ou : curl ... pour Slack/DiscordVérifier le build à chaque fin de tâche :
#!/bin/bash# .claude/hooks/post-task-build-check.sh (déclenché sur Stop)npm run build || { echo "Build failed" >&2; exit 1; }Un repo configuré avec quelques hooks ciblés — validation pré-commit, notification de fin de tâche — te permet d’arriver sur les agents et multi-agents avec des garde-fous déjà en place. Tu peux alors te concentrer sur l’incrémentation, pas sur la surveillance.
Débugger un hook
Section intitulée « Débugger un hook »Vérifier que le hook est chargé
Section intitulée « Vérifier que le hook est chargé »Tape /permissions dans l’interface Claude Code (pas dans le terminal) :
> /permissionsAffiche la config active — vérifie que tes hooks apparaissent dans la liste.
Variables d’environnement disponibles dans le script
Section intitulée « Variables d’environnement disponibles dans le script »CLAUDE_TOOL_NAME # nom de l'outil (Bash, Edit, Read…)CLAUDE_TOOL_INPUT # input de l'outil au format JSON — utilise jq pour le parserCLAUDE_SESSION_ID # identifiant de la sessionPattern de logging
Section intitulée « Pattern de logging »#!/bin/bashecho "[hook] déclenchement : $CLAUDE_TOOL_NAME" >> /tmp/claude-hooks.logecho "[hook] input : $CLAUDE_TOOL_INPUT" >> /tmp/claude-hooks.logErreurs courantes
Section intitulée « Erreurs courantes »| Problème | Cause probable | Fix |
|---|---|---|
| Hook ignoré silencieusement | Chemin relatif au lieu d’absolu | Utiliser le chemin absolu (/home/user/.claude/hooks/...) |
Permission denied | Script non exécutable | chmod +x ~/.claude/hooks/mon-hook.sh |
| Hook ne se déclenche pas | Mauvais matcher | Vérifier le nom exact de l’outil avec /permissions |
exit 2 sans injection | stdout vide | S’assurer que stdout contient du texte avant exit 2 |
| Shebang manquant | Le script ne s’exécute pas | Ajouter #!/bin/bash en première ligne |
Tester manuellement sans passer par Claude
Section intitulée « Tester manuellement sans passer par Claude »# Simuler un appel PreToolUseCLAUDE_TOOL_NAME="Bash" CLAUDE_TOOL_INPUT='{"command":"rm -rf /"}' bash ~/.claude/hooks/check-dangerous-cmd.shecho "Exit code : $?"