Lab 2.5 : Construire des Garde-fous avec les Hooks
Module : 2.5 - Hooks | ← SlidesDurée : 30 minutes Projet Exemple : node-express-mongoose-demo
⭐ Lab Optionnel/Bonus
Objectifs d'Apprentissage
À la fin de ce lab, vous serez capable de :
- Configurer des hooks déterministes dans
.claude/settings.json - Créer des hooks de rapport qui fournissent un retour non bloquant (Niveau 1)
- Implémenter des hooks de garde-fou qui bloquent les motifs de code interdits (Niveau 2)
- Construire des portes d'approbation pour les opérations à haut risque (Niveau 3)
- Parser l'entrée JSON des hooks en utilisant
jqdans des scripts shell
Prérequis
jqinstallé sur votre système (brew install jqousudo apt install jq)- Labs 2.1-2.4 complétés (ou familiarité avec les bases de Claude Code)
- Le projet exemple
node-express-mongoose-democonfiguré
Comment Fonctionnent les Hooks
Les hooks sont des commandes shell configurées dans .claude/settings.json. Ils s'exécutent automatiquement lorsque Claude déclenche des événements spécifiques.
- Entrée : Les hooks reçoivent du JSON sur stdin avec
tool_name,tool_input, et le contexte de session. - Sortie : Code de sortie
0= autoriser, code de sortie2= bloquer. Les hooks peuvent également produire du JSON structuré sur stdout. - STDERR : Les messages d'erreur écrits sur stderr sont affichés à Claude lorsqu'un hook bloque.
Configuration
# Naviguer vers le projet exemple
cd sample-projects/node-express-mongoose-demo
# Vérifier que jq est installé
jq --version
# Créer un répertoire pour vos scripts de hook
mkdir -p .claude/hooks
# Démarrer Claude Code
claudeTâche 1 : Créer un Hook de Rapport PostToolUse
Durée : 8 minutes
Niveau 1 : Rapport. Créer un hook qui détecte les commentaires TODO dans les fichiers que Claude écrit. Il avertit mais ne bloque pas — l'action a déjà eu lieu.
Étape 1 : Créer le script du hook
Créer un fichier à .claude/hooks/check-todos.sh :
#!/bin/bash
# Read JSON from stdin
INPUT=$(cat)
# Extract file_path from tool input
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
if [ -n "$FILE_PATH" ] && [ -f "$FILE_PATH" ]; then
if grep -q "TODO" "$FILE_PATH"; then
echo "WARNING: File $FILE_PATH contains TODO comments. Track these in the backlog." >&2
fi
fi
# PostToolUse: action already happened, exit 0
exit 0Le rendre exécutable :
chmod +x .claude/hooks/check-todos.shÉtape 2 : Configurer le hook dans .claude/settings.json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": ".claude/hooks/check-todos.sh"
}
]
}
]
}
}Étape 3 : Redémarrer Claude et tester
Create a file called todo-test.js with a function that adds two numbers.
Include a TODO comment about adding input validation later.Claude écrit le fichier. Le hook s'exécute après l'écriture et affiche l'avertissement TODO.
Critères de réussite :
- [ ] Script du hook créé et exécutable
- [ ]
settings.jsonconfiguré avec le hook PostToolUse - [ ] L'avertissement apparaît après que Claude a écrit un fichier contenant "TODO"
- [ ] L'écriture n'est PAS bloquée (PostToolUse ne peut pas bloquer)
Tâche 2 : Créer un Hook de Garde-fou PreToolUse
Durée : 10 minutes
Niveau 2 : Garde-fous. Créer un hook qui BLOQUE les écritures contenant des instructions console.log. Claude voit l'erreur et s'adapte automatiquement.
Étape 1 : Créer le script de garde-fou
Créer .claude/hooks/block-console-log.sh :
#!/bin/bash
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')
# Only check Write tool (content is available in tool_input)
if [ "$TOOL_NAME" != "Write" ]; then
exit 0
fi
CONTENT=$(echo "$INPUT" | jq -r '.tool_input.content // empty')
if echo "$CONTENT" | grep -q "console.log"; then
echo "BLOCKED: console.log statements are forbidden. Use a proper logger instead." >&2
exit 2 # Exit code 2 = block the action
fi
exit 0Le rendre exécutable :
chmod +x .claude/hooks/block-console-log.shÉtape 2 : Mettre à jour .claude/settings.json
Ajouter la section PreToolUse à côté du PostToolUse existant :
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": ".claude/hooks/check-todos.sh"
}
]
}
],
"PreToolUse": [
{
"matcher": "Write",
"hooks": [
{
"type": "command",
"command": ".claude/hooks/block-console-log.sh"
}
]
}
]
}
}Étape 3 : Redémarrer Claude et tester
Create a file called debug-test.js that logs "hello world" using console.log.Observez ce qui se passe : Claude essaie d'écrire -> le hook le bloque (exit 2) -> Claude voit le message d'erreur -> Claude réécrit sans console.log.
Critères de réussite :
- [ ] Script du hook créé et exécutable
- [ ] L'écriture d'un fichier avec
console.logest bloquée - [ ] Claude voit le message stderr et s'adapte automatiquement
- [ ] Le fichier réécrit évite
console.log
Tâche 3 : Créer une Porte d'Approbation PreToolUse
Durée : 7 minutes
Niveau 3 : Porte d'approbation. Exiger une confirmation humaine explicite avant que Claude ne modifie les modèles de base de données ou les migrations.
Étape 1 : Créer le script de la porte
Créer .claude/hooks/db-approval-gate.sh :
#!/bin/bash
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
# Check if the file path touches database-related code
if [[ "$FILE_PATH" == *"models/"* ]] || [[ "$FILE_PATH" == *"migration"* ]] || [[ "$FILE_PATH" == *"schema"* ]]; then
# Output JSON to request human approval
cat <<'GATE'
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "ask",
"permissionDecisionReason": "This modifies database-related code. Please review and approve."
}
}
GATE
exit 0
fi
exit 0Le rendre exécutable :
chmod +x .claude/hooks/db-approval-gate.shÉtape 2 : Ajouter à la section PreToolUse dans .claude/settings.json
"PreToolUse": [
{
"matcher": "Write",
"hooks": [
{
"type": "command",
"command": ".claude/hooks/block-console-log.sh"
}
]
},
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": ".claude/hooks/db-approval-gate.sh"
}
]
}
]Étape 3 : Redémarrer Claude et tester
Add a new field called 'lastLogin' of type Date to the User model in app/models/user.js.Claude tente l'écriture -> le hook détecte un chemin models/ -> on vous demande d'approuver ou de refuser.
Critères de réussite :
- [ ] Script du hook créé et exécutable
- [ ] La modification d'un fichier dans
app/models/déclenche une demande d'approbation humaine - [ ] Vous pouvez approuver ou refuser le changement
Tâche 4 : Tester les Trois Niveaux
Durée : 5 minutes
Passez en revue les trois garde-fous en séquence pour vérifier qu'ils fonctionnent ensemble.
Test 1 : Rapporteur (Niveau 1)
Create a file utils/helpers.js with a helper function. Add a TODO comment.Attendu : Le fichier est écrit. L'avertissement concernant le TODO apparaît.
Test 2 : Garde-fou (Niveau 2)
Add console.log debugging to utils/helpers.js.Attendu : L'écriture est bloquée. Claude réessaie sans console.log.
Test 3 : Porte d'Approbation (Niveau 3)
Add a 'createdAt' timestamp field to the Article model.Attendu : On vous demande d'approuver le changement de modèle.
Critères de réussite :
- [ ] Les trois hooks sont déclenchés dans l'ordre attendu
- [ ] Le rapporteur avertit mais autorise
- [ ] Le garde-fou bloque et Claude récupère
- [ ] La porte demande une approbation humaine
Dépannage des Hooks
Si un hook ne fonctionne pas, vérifiez ces problèmes courants :
| Problème | Cause | Correction |
|---|---|---|
| Le hook ne se déclenche pas | JSON invalide dans settings.json | Valider avec `cat .claude/settings.json |
| Le hook ne se déclenche pas | Script non exécutable | Lancer chmod +x .claude/hooks/votre-script.sh |
| Le hook ne se déclenche pas | Mauvais matcher | Vérifier que le nom de l'outil correspond (ex: Write et non write) |
| L'analyse JSON échoue | jq non installé | Installer : brew install jq ou apt install jq |
| Le blocage ne fonctionne pas | Mauvais code de sortie | Utiliser exit 2 (pas exit 1) pour les blocages PreToolUse |
| Aucune erreur affichée | Écriture sur stdout au lieu de stderr | Utiliser >&2 pour les messages d'erreur dans les hooks bloquants |
Conseil pour le test manuel : Vous pouvez tester un script de hook directement :
echo '{"tool_name":"Write","tool_input":{"file_path":"test.js","content":"console.log(1)"}}' | .claude/hooks/block-console-log.sh
echo $? # Devrait afficher 2Conseils
- Gardez les hooks rapides. Des hooks lents rendent Claude poussif.
- Utilisez stderr pour les messages d'erreur (
>&2) — Claude lit stderr lorsqu'un hook bloque. - Utilisez stdout pour le JSON structuré — pour des décisions comme
permissionDecision: "ask". - Testez les scripts manuellement d'abord avant de les ajouter à settings.json.
- Commencez par le Niveau 1 (rapport). Passez au Niveau 2/3 uniquement si nécessaire.
Objectifs Bonus
Si vous finissez en avance :
- Auto-formateur : Créer un hook PostToolUse qui lance
npx prettier --writesur chaque fichier touché par Claude. - Scanner de secrets : Créer un hook PreToolUse qui bloque les écritures contenant des motifs comme
AKIA(clés AWS) ou-----BEGIN.*PRIVATE KEY. - Garde de branche : Créer un hook PreToolUse sur l'outil
Bashqui bloquegit pushversmain.
Livrables
À la fin de ce lab, vous devriez avoir :
- Trois scripts de hook dans
.claude/hooks/(rapporteur, garde-fou, porte) - Un fichier
.claude/settings.jsonavec les trois niveaux configurés - La preuve que chaque niveau fonctionne : avertissements, blocages et demandes d'approbation
Prochaines Étapes
Après avoir terminé ce lab, passez au Lab 2.7 : Mini-Projet de Modernisation - le projet final du Jour 2.