Polydesk-logotype
Polydesk.ai — Header

Claude Code Hooks : automatiser et sécuriser votre workflow de développement

Les hooks de Claude Code sont des scripts qui s’exécutent automatiquement à des moments précis du cycle de vie de l’agent : avant chaque action (PreToolUse), après chaque modification (PostToolUse), à la fin d’une tâche (Stop) et à 9 autres points clés. Ils transforment les bonnes pratiques en règles exécutées systématiquement.

Contrairement aux instructions dans CLAUDE.md que l’agent peut interpréter avec flexibilité, les hooks s’exécutent de façon déterministe. Un hook PreToolUse qui bloque rm -rf le bloquera à chaque fois, sans exception. C’est la différence entre une recommandation et une garantie.

Ce guide couvre les 12 événements principaux, les trois types de handlers, la configuration dans settings.json, et des exemples prêts à copier pour les cas d’usage les plus courants.

Hooks Claude Code en un coup d’œil
Configuration
.claude/settings.json (partagé) ou settings.local.json (perso)
Événements clés
PreToolUse, PostToolUse, Stop, Notification, SessionStart
Types de handlers
command, prompt, agent
Blocage
Exit code 2 = bloquer l’action (PreToolUse uniquement)
Matcher
Regex sur le nom de l’outil (Bash, Edit, Write, etc.)
Gestion interactive
/hooks dans Claude Code

Comment fonctionnent les hooks

Les hooks s’insèrent dans le cycle de vie de l’agent Claude Code. À chaque point du cycle, un ou plusieurs hooks peuvent se déclencher si leur matcher correspond à l’action en cours.

Le cycle principal :

1. UserPromptSubmit : l’utilisateur envoie un prompt.
2. Claude analyse et planifie.
3. PreToolUse : avant chaque utilisation d’outil (Bash, Edit, Write, Read, etc.).
4. PermissionRequest : si une permission est demandée à l’utilisateur.
5. L’outil s’exécute.
6. PostToolUse : après l’exécution réussie de l’outil.
7. PostToolUseFailure : si l’outil a échoué.
8. Retour à l’étape 2 (boucle jusqu’à la fin de la tâche).
9. Stop : Claude a terminé sa réponse.

Les hooks des subagents fonctionnent de la même façon : vos hooks PreToolUse et PostToolUse s’exécutent aussi pour les actions des subagents. Un subagent ne peut pas contourner vos gardes de sécurité.

Codes de sortie

Exit codeSignificationComportement
0SuccèsL’action continue. La sortie JSON sur stdout est parsée pour un contrôle fin.
2BlocageL’action est bloquée (PreToolUse uniquement). Le message stderr est transmis à Claude.
AutreErreur non bloquanteAffiché en mode verbose, l’action continue quand même.
Exit 2, pas exit 1, pour bloquer C’est le piège le plus fréquent : exit 1 ne bloque PAS l’action. Seul exit 2 bloque. Un hook de sécurité qui utilise exit 1 ne fournit aucune protection réelle. Tout hook de sécurité critique doit utiliser exit 2.

Configuration dans settings.json

Les hooks sont définis dans .claude/settings.json à la racine de votre projet :

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": ".claude/hooks/block-dangerous.sh"
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Edit|Write|MultiEdit",
        "hooks": [
          {
            "type": "command",
            "command": "npx prettier --write "$CLAUDE_TOOL_INPUT_FILE_PATH""
          }
        ]
      }
    ]
  }
}

Le matcher est une regex qui filtre sur le nom de l’outil. Les noms d’outils disponibles sont : Bash, Edit, MultiEdit, Write, Read, Glob, Grep, Agent, WebFetch, WebSearch, et tous les noms d’outils MCP (format mcp__*). Le matcher est case-sensitive.

Utilisez .claude/settings.json pour les hooks partagés avec l’équipe (committés dans Git). Utilisez .claude/settings.local.json pour les hooks personnels (notifications, formatage local). Le fichier local n’est pas versionné.

Pour gérer les hooks de façon interactive sans éditer le JSON à la main, tapez /hooks dans une session Claude Code.

Les trois types de handlers

Command (le plus courant)

Exécute un script shell. Rapide, déterministe, idéal pour le formatage, la validation et les gardes de sécurité.

{
  "type": "command",
  "command": ".claude/hooks/auto-format.sh"
}

Le script reçoit les données en JSON sur stdin (pas en variables d’environnement). Utilisez jq pour extraire les champs. La variable $CLAUDE_PROJECT_DIR donne le chemin absolu du projet.

Prompt (évaluation par LLM)

Envoie un prompt à un modèle Claude pour une évaluation single-turn. Utile pour les décisions contextuelles qu’un script ne peut pas prendre (évaluation d’impact sur la production, review de sécurité).

{
  "type": "prompt",
  "prompt": "Analyse cette commande Bash et détermine si elle est sûre pour un environnement de développement. Commande : $ARGUMENTS"
}

Agent (vérification approfondie)

Spawne un subagent avec accès aux outils (Read, Grep, Glob) pour une vérification en profondeur. Plus lent mais plus puissant.

{
  "type": "agent",
  "prompt": "Vérifie que les modifications ne cassent aucun test existant. Lance les tests, analyse les résultats, et bloque si des tests échouent."
}

Recommandation : commencez par des hooks command pour le formatage, graduez vers les hooks prompt pour la sécurité, puis les hooks agent pour la vérification approfondie.


Les 12 événements de hooks

ÉvénementQuand il se déclenchePeut bloquer ?Usage principal
PreToolUseAvant chaque utilisation d’outilOui (exit 2)Sécurité, validation, modification d’input
PostToolUseAprès exécution réussie d’un outilNonFormatage, linting, commits auto
PostToolUseFailureAprès échec d’un outilNonLogging, alertes d’erreur
StopQuand Claude finit sa réponseOui (exit 2 = continue)Vérification finale, push Git
UserPromptSubmitQuand l’utilisateur envoie un promptOuiValidation d’input, logging
NotificationQuand Claude envoie une notificationNonAlertes Slack, notifications desktop
SessionStartDébut de sessionNonSetup d’environnement, chargement de contexte
SessionEndFin de sessionNonNettoyage, rapports
PermissionRequestQuand une permission est demandéeOuiAuto-approval de commandes sûres
SubagentStartDébut d’un subagentNonConfiguration, notifications
SubagentStopFin d’un subagentOuiValidation des résultats du subagent
PreCompactAvant la compaction du contexteNonSauvegarder des infos avant résumé

PreToolUse est l’événement le plus puissant parce qu’il peut bloquer des actions et modifier les inputs des outils avant exécution. C’est votre mécanisme principal de sécurité et de contrôle qualité.

5 hooks prêts à copier

1. Auto-formatage après chaque édition

Le hook le plus utilisé. Prettier passe automatiquement sur chaque fichier modifié par Claude.

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit|MultiEdit",
        "hooks": [{
          "type": "command",
          "command": "jq -r '.tool_input.file_path' | xargs npx prettier --write 2>/dev/null || true"
        }]
      }
    ]
  }
}

2. Garde de sécurité : bloquer les commandes dangereuses

Bloque rm -rf, git reset --hard, git push --force et les curls réseau.

#!/bin/bash
# .claude/hooks/block-dangerous.sh
set -euo pipefail
CMD=$(cat | jq -r '.tool_input.command // empty')

# Patterns dangereux
if echo "$CMD" | grep -qE 'rms+-rf|gits+resets+--hard|gits+pushs+--force|DROPs+TABLE'; then
  echo "Commande dangereuse bloquée : $CMD" >&2
  exit 2
fi

exit 0
{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Bash",
      "hooks": [{
        "type": "command",
        "command": ".claude/hooks/block-dangerous.sh"
      }]
    }]
  }
}

3. Lancer les tests et lint après les modifications

#!/bin/bash
# .claude/hooks/post-edit-quality.sh
set -euo pipefail

if [ -f package.json ]; then
  npx prettier -w . || true
  if ! pnpm -s lint; then
    echo "Lint failed. Please fix lint errors."
  fi
  if ! pnpm -s typecheck; then
    echo "Typecheck failed. Please resolve TS errors."
  fi
fi

exit 0

4. Notification quand Claude a terminé

{
  "hooks": {
    "Notification": [{
      "matcher": "",
      "hooks": [{
        "type": "command",
        "command": "osascript -e 'display notification "Claude Code a terminé" with title "Claude Code"'"
      }]
    }]
  }
}

5. Auto-approval des commandes sûres

Approuve automatiquement les commandes de test et de lint sans demander la permission.

#!/bin/bash
# .claude/hooks/auto-approve-safe.sh
CMD=$(cat | jq -r '.tool_input.command // empty')

if echo "$CMD" | grep -qE '^(npm run (test|lint|build)|npx (prettier|eslint|tsc)|pnpm (test|lint))'; then
  echo '{"hookSpecificOutput":{"hookEventName":"PermissionRequest","decision":{"behavior":"allow"}}}'
  exit 0
fi

# Ne pas décider, laisser la permission normale
exit 0

Fonctionnalité avancée : modifier les inputs

Depuis la version 2.0.10, les hooks PreToolUse peuvent modifier les paramètres d’un outil avant son exécution. Au lieu de bloquer et forcer une nouvelle tentative, le hook intercepte, corrige et laisse l’exécution se poursuivre.

Cas d’usage : ajouter automatiquement le flag --dry-run aux commandes de déploiement, rediriger les chemins de fichiers vers un sandbox, formater les messages de commit selon votre convention, injecter du contexte additionnel pour Claude.

{
  "hookSpecificOutput": {
    "hookEventName": "PreToolUse",
    "permissionDecision": "allow",
    "updatedInput": {
      "command": "npm run deploy -- --dry-run"
    },
    "additionalContext": "Le flag --dry-run a été ajouté par le hook de sécurité."
  }
}

Les modifications sont invisibles pour Claude. L’agent pense avoir exécuté la commande originale, mais le hook a silencieusement ajouté les gardes de sécurité.

Bonnes pratiques

Performance. Chaque hook s’exécute de façon synchrone. Gardez les hooks sous 500 ms pour éviter de ralentir l’agent. Un développeur a rapporté utiliser 95 hooks sans latence perceptible parce que chacun complète en moins de 200 ms.

Structure de fichiers. Placez les scripts dans .claude/hooks/ avec des noms explicites. Rendez-les exécutables (chmod +x). Utilisez $CLAUDE_PROJECT_DIR pour les chemins absolus.

Hooks et subagents. Les hooks s’exécutent aussi pour les actions des subagents. C’est un avantage de sécurité : un subagent ne peut pas contourner vos gardes PreToolUse.

Stop hook et boucle infinie. Quand un hook Stop retourne exit 2, Claude continue de travailler. Cela peut créer une boucle infinie. Vérifiez le champ stop_hook_active dans l’input JSON et laissez passer (exit 0) si le hook est déjà actif.

Debug. Activez le mode verbose avec Ctrl+O pour voir les stdout/stderr de vos hooks en temps réel. Testez vos scripts manuellement en leur passant du JSON sur stdin avant de les configurer comme hooks.

Hooks en équipe : standardiser la qualité

Les hooks sont le meilleur moyen de garantir que chaque membre de l’équipe, humain ou IA, respecte les mêmes standards. Voici une configuration d’équipe complète que vous pouvez adapter :

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [{
          "type": "command",
          "command": ".claude/hooks/block-dangerous.sh"
        }]
      },
      {
        "matcher": "Write|Edit",
        "hooks": [{
          "type": "command",
          "command": ".claude/hooks/protect-critical-paths.sh"
        }]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Write|Edit|MultiEdit",
        "hooks": [{
          "type": "command",
          "command": ".claude/hooks/auto-format.sh"
        }]
      }
    ],
    "Stop": [
      {
        "matcher": "",
        "hooks": [{
          "type": "command",
          "command": ".claude/hooks/final-quality-check.sh"
        }]
      }
    ]
  }
}

Le script protect-critical-paths.sh est un hook PreToolUse qui bloque les modifications dans les répertoires sensibles (authentification, paiement, migrations de base de données) sauf si le prompt le mentionne explicitement :

#!/bin/bash
# .claude/hooks/protect-critical-paths.sh
set -euo pipefail

FILE_PATH=$(cat | jq -r '.tool_input.file_path // empty')
PROTECTED_PATHS="src/core/auth|src/services/payment|prisma/migrations"

if echo "$FILE_PATH" | grep -qE "$PROTECTED_PATHS"; then
  echo "Modification d'un fichier protégé ($FILE_PATH). Review manuelle requise." >&2
  exit 2
fi

exit 0

Committez .claude/settings.json et le dossier .claude/hooks/ dans Git. Chaque développeur qui clone le repo obtient automatiquement les mêmes gardes de sécurité. Pour les hooks personnels (notifications macOS, formatage spécifique), chaque développeur utilise .claude/settings.local.json qui reste hors du versioning.

Hooks et CI/CD

Les hooks Claude Code et les hooks Git (pre-commit, pre-push) sont complémentaires. Les hooks Claude Code interviennent pendant la session de développement (en temps réel). Les hooks Git interviennent au moment du commit ou du push (en différé).

La stratégie recommandée :

Hooks Claude Code (temps réel) : auto-formatage PostToolUse, blocage des commandes dangereuses PreToolUse, vérification de types après édition. Ces hooks assurent que le code est propre au moment où il est écrit.

Hooks Git (commit/push) : suite de tests complète, vérification de lint, scan de sécurité, vérification des messages de commit. Ces hooks assurent que le code est prêt à être partagé.

Les deux couches se renforcent mutuellement. Les hooks Claude Code réduisent le nombre d’erreurs qui atteignent le commit. Les hooks Git attrapent ce qui a pu passer à travers.

Hooks et mode –dangerously-skip-permissions

Point critique : les hooks s’exécutent toujours, même quand Claude Code tourne avec le flag --dangerously-skip-permissions (l’équivalent du YOLO mode). C’est intentionnel et c’est ce qui rend les hooks essentiels pour les sessions autonomes.

Quand vous lancez Claude Code en mode headless (CI/CD, scripts automatisés, Background Agents), les hooks PreToolUse sont votre dernier filet de sécurité. Ils bloquent les commandes destructrices que l’agent pourrait tenter sans supervision humaine. Sans hooks, le mode skip-permissions est réellement dangereux. Avec des hooks bien configurés, il devient un outil de productivité maîtrisé.

Configuration minimale pour le mode autonome :

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [{
          "type": "command",
          "command": ".claude/hooks/block-dangerous.sh"
        }]
      },
      {
        "matcher": "Write|Edit",
        "hooks": [{
          "type": "command",
          "command": ".claude/hooks/protect-critical-paths.sh"
        }]
      }
    ]
  }
}

Avec ces deux hooks, même un agent totalement autonome ne peut pas exécuter de commandes destructrices ni modifier les fichiers critiques sans votre approbation explicite.

Hooks Claude Code vs hooks Cursor

Les deux outils supportent des hooks déclenchés par événements, mais avec des différences significatives :

AspectClaude Code HooksCursor Hooks
Types de handlerscommand, prompt, agent (3 types)command uniquement
Événements12+ (PreToolUse, PostToolUse, Stop, Session, Subagent, etc.)Moins d’événements, centré sur les éditions
Blocage d’actionsOui (exit 2 sur PreToolUse)Oui (limité)
Modification d’inputsOui (updatedInput depuis v2.0.10)Non
SubagentsHooks récursifs sur les subagentsNon applicable
Distribution équipe.claude/settings.json (Git) + Enterprise dashboardVia plugins ou paramètres Teams
Évaluation par LLMOui (handler type prompt/agent)Non

Claude Code offre un système de hooks plus mature et plus flexible, notamment grâce aux handlers prompt et agent qui permettent des vérifications contextuelles impossibles avec de simples scripts shell. La modification d’inputs PreToolUse est aussi un avantage unique : au lieu de bloquer et forcer une nouvelle tentative, le hook peut corriger silencieusement les paramètres avant exécution.

Si vous utilisez les deux outils, maintenez une cohérence dans vos gardes de sécurité. Les scripts de validation (block-dangerous.sh, protect-critical-paths.sh) peuvent être partagés entre les deux environnements avec des adaptations mineures de configuration.


Questions fréquentes

Quelle est la différence entre un hook et une instruction dans CLAUDE.md ?

Une instruction dans CLAUDE.md est une recommandation que Claude interprète avec flexibilité : il peut l’oublier ou la réinterpréter. Un hook est un script qui s’exécute de façon déterministe à chaque occurrence de l’événement correspondant. Pour le formatage de code, un hook PostToolUse qui lance Prettier est 100 % fiable, tandis qu’une instruction « formate toujours le code » dans CLAUDE.md sera parfois ignorée. Utilisez CLAUDE.md pour les décisions de design et les hooks pour les actions automatisables.

Comment bloquer une action dangereuse avec un hook ?

Créez un hook PreToolUse sur le matcher Bash qui analyse la commande et retourne exit 2 si elle est dangereuse. Le message écrit sur stderr est transmis à Claude, qui ajuste sa stratégie. Seul exit 2 bloque : exit 1 signale une erreur non bloquante et l’action continue. Tout hook de sécurité critique doit impérativement utiliser exit 2.

Les hooks fonctionnent-ils avec les subagents ?

Oui. Les hooks PreToolUse et PostToolUse s’exécutent pour chaque action de chaque subagent. Si un subagent tente une commande dangereuse, votre hook de sécurité la bloquera. L’événement SubagentStop se déclenche quand un subagent termine, permettant de valider ses résultats. Cette exécution récursive garantit que vos gardes de sécurité s’appliquent à tous les niveaux d’agents.

Combien de hooks peut-on configurer sans impacter les performances ?

La contrainte est la performance individuelle de chaque hook, pas leur nombre. Des développeurs utilisent jusqu’à 95 hooks sans latence perceptible parce que chacun complète en moins de 200 ms. La règle : si un hook PostToolUse ajoute plus de 500 ms à chaque édition de fichier, la session devient lente. Profilez vos hooks avec time avant de les déployer. Dix hooks rapides sont meilleurs que deux hooks lents.

Comment partager les hooks avec mon équipe ?

Placez la configuration dans .claude/settings.json (committable dans Git) et les scripts dans .claude/hooks/. Toute l’équipe obtient les mêmes gardes de sécurité et vérifications qualité automatiquement. Pour les hooks personnels (notifications, formatage local), utilisez .claude/settings.local.json qui n’est pas versionné. Sur les plans Enterprise, les administrateurs peuvent distribuer des hooks via le dashboard web.

Polydesk.ai — Footer