Aller au contenu
Structuré avec Claude

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.

100%
ÉvénementDéclenché quand
UserPromptSubmitL’utilisateur envoie un message
PreToolUseClaude est sur le point d’utiliser un outil
PostToolUseClaude vient d’utiliser un outil
StopClaude a terminé sa réponse
SubagentStopUn sous-agent a terminé
100%

Deux emplacements, deux portées différentes :

FichierPortée
~/.claude/settings.jsonPersonnel — s’applique à tous tes projets, non versionné
.claude/settings.jsonProjet — 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.

CodeEffet
0Continue normalement
1Bloque l’action + affiche stderr à Claude
2Bloque + 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.

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 1
fi

Notification quand Claude a fini :

~/.claude/hooks/notify.sh
#!/bin/bash
notify-send "Claude Code" "Tâche terminée"
# ou : curl ... pour Slack/Discord

Vé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.


Tape /permissions dans l’interface Claude Code (pas dans le terminal) :

> /permissions

Affiche 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 parser
CLAUDE_SESSION_ID # identifiant de la session
#!/bin/bash
echo "[hook] déclenchement : $CLAUDE_TOOL_NAME" >> /tmp/claude-hooks.log
echo "[hook] input : $CLAUDE_TOOL_INPUT" >> /tmp/claude-hooks.log
ProblèmeCause probableFix
Hook ignoré silencieusementChemin relatif au lieu d’absoluUtiliser le chemin absolu (/home/user/.claude/hooks/...)
Permission deniedScript non exécutablechmod +x ~/.claude/hooks/mon-hook.sh
Hook ne se déclenche pasMauvais matcherVérifier le nom exact de l’outil avec /permissions
exit 2 sans injectionstdout videS’assurer que stdout contient du texte avant exit 2
Shebang manquantLe script ne s’exécute pasAjouter #!/bin/bash en première ligne
Fenêtre de terminal
# Simuler un appel PreToolUse
CLAUDE_TOOL_NAME="Bash" CLAUDE_TOOL_INPUT='{"command":"rm -rf /"}' bash ~/.claude/hooks/check-dangerous-cmd.sh
echo "Exit code : $?"