Utilisez PostToolUse Hooks pour déclencher le lint automatiquement après chaque écriture. Le code de sortie 2 renvoie les erreurs à Claude pour correction automatique.
Claude Code écrit du code rapidement, mais il n'exécute pas toujours le lint. Vous lui demandez de "vérifier pendant qu'il écrit" et parfois il le fait, parfois non. Les Hooks résolvent ce problème en transférant la responsabilité de la vérification du code de Claude au système.
Cet article se concentre sur une seule chose : utiliser les PostToolUse Hooks pour déclencher automatiquement des vérifications après que Claude a écrit du code, afin que chaque modification de fichier respecte vos standards.
La logique d'un Hook de vérification de code est simple :
Write ou Edit pour écrire un fichierLe code de sortie 2 est essentiel — il permet à Claude de recevoir l'erreur et de la corriger automatiquement, formant une boucle "écrire→vérifier→corriger".
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "bash -c 'file=$(echo \"$CLAUDE_TOOL_INPUT\" | jq -r .file_path 2>/dev/null); [[ \"$file\" == *.rb ]] && rubocop -A \"$file\" --no-color -q || true'"
}
]
}
]
}
}
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "bash -c 'file=$(echo \"$CLAUDE_TOOL_INPUT\" | jq -r .file_path 2>/dev/null); [[ \"$file\" =~ \\.(js|ts|jsx|tsx)$ ]] && npx eslint --fix \"$file\" || true'"
}
]
}
]
}
}
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "bash -c 'file=$(echo \"$CLAUDE_TOOL_INPUT\" | jq -r .file_path 2>/dev/null); [[ \"$file\" == *.py ]] && ruff check --fix \"$file\" && ruff format \"$file\" || true'"
}
]
}
]
}
}
Déplacer la logique de vérification dans un script indépendant est bien plus maintenable que d'accumuler des commandes dans le JSON.
Créer .claude/hooks/lint.sh :
#!/bin/bash
set -e
input=$(cat)
file=$(echo "$input" | jq -r '.tool_input.file_path // empty')
[[ -z "$file" ]] && exit 0
[[ ! -f "$file" ]] && exit 0
ext="${file##*.}"
case "$ext" in
rb) rubocop -A "$file" --no-color -q ;;
js|ts|jsx|tsx) npx eslint --fix "$file" --quiet ;;
py) ruff check --fix "$file"; ruff format "$file" ;;
go) gofmt -w "$file"; golangci-lint run "$file" 2>&1 ;;
*) exit 0 ;;
esac
Référencer le script dans settings.json :
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [{ "type": "command", "command": "bash .claude/hooks/lint.sh" }]
}
]
}
}
Code de sortie 2 + stderr est ce qui déclenche la correction automatique de Claude :
run_lint() {
local output exit_code
output=$(rubocop "$file" --no-color 2>&1)
exit_code=$?
if [[ $exit_code -ne 0 ]]; then
echo "$output" >&2
exit 2
fi
rubocop -A "$file" --no-color -q
}
skip_patterns=("vendor/" "node_modules/" "db/schema.rb" ".min.js" "_test.go")
for pattern in "${skip_patterns[@]}"; do
[[ "$file" == *"$pattern"* ]] && exit 0
done
Une fois configuré, le flux de travail devient :
Writerubocop -A automatiquement — trouve 3 problèmesVous n'avez jamais besoin d'exécuter une commande de vérification manuellement.
Global (~/.claude/settings.json) : Quand vous utilisez les mêmes règles dans tous vos projets.
Niveau projet (.claude/settings.json dans git) : Recommandé pour les équipes. Quiconque ouvre le dépôt obtient automatiquement la bonne configuration.
Les deux coexistent ; les hooks de projet fusionnent avec les globaux et les deux s'exécutent.
La vérification automatique du code avec les Hooks se résume à trois étapes :
PostToolUse + matcher "Write|Edit" pour intercepter les écritures de fichiersCommencez avec un langage. Une fois fonctionnel, ajoutez-en d'autres. Committez les scripts dans .claude/hooks/ pour les partager avec l'équipe.