Les hooks sont des commandes externes qui s’exécutent à des points de cycle de vie spécifiques pendant une session, ce qui permet l’automatisation personnalisée, les contrôles de sécurité et les intégrations. Les fichiers de configuration de "hook" sont chargés automatiquement depuis .github/hooks/*.json de votre référentiel.
Format de configuration des hooks
Les fichiers de configuration de hook utilisent le format JSON avec la version 1.
Crochets de commande
Les commandes hook exécutent des scripts shell et sont prises en charge pour tous les types de hook.
{
"version": 1,
"hooks": {
"preToolUse": [
{
"type": "command",
"bash": "your-bash-command",
"powershell": "your-powershell-command",
"cwd": "optional/working/directory",
"env": { "VAR": "value" },
"timeoutSec": 30
}
]
}
}
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
bash | string | L'un de bash/powershell | Commande Shell pour Unix. |
cwd | string | Non | Répertoire de travail de la commande (par rapport à la racine du référentiel ou absolu). |
env | Objet | Non | Variables d’environnement à définir (prend en charge l’expansion des variables). |
powershell | string | L'un de bash/powershell | Commande Shell pour Windows. |
timeoutSec | nombre | Non | Délai d’expiration en secondes. Valeur par défaut : 30. |
type | "command" | Oui | Doit être "command". |
Points d’accroche d’invite
Les déclencheurs automatiques soumettent le texte comme si l'utilisateur l'avait tapé. Elles ne sont prises en charge que sur sessionStart et elles ne s'activent que pour les nouvelles sessions interactives. Ils ne se déclenchent pas lors de la reprise et ne se déclenchent pas en mode d’invite non interactif (-p). Le texte peut être une invite en langage naturel ou une commande slash.
{
"version": 1,
"hooks": {
"sessionStart": [
{
"type": "prompt",
"prompt": "Your prompt text or /slash-command"
}
]
}
}
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
type | "prompt" | Oui | Doit être "prompt". |
prompt | string | Oui | Texte à soumettre : il peut s'agir d'un message en langage naturel ou d'une commande slash. |
Événements de hook
| Événement | Se déclenche quand | Sortie traitée |
|---|---|---|
agentStop | L’agent principal termine un tour. | Oui : peut bloquer et forcer la continuation. |
errorOccurred | Une erreur se produit pendant l’exécution. | Non |
notification | Se déclenche de façon asynchrone lorsque l’interface CLI émet une notification système (complétion du shell, complétion de l’agent ou état inactif, invites d'autorisations, dialogues de sollicitation). Fire-and-forget : ne bloque jamais la session. Prend en charge matcher regex sur notification_type. | Facultatif — possibilité d'injecter additionalContext dans la session. |
permissionRequest | Se déclenche avant que le service d’autorisation ne s'exécute (moteur de règles, approbations de session, autorisation automatique/refus automatique et invitation de l'utilisateur). Si la sortie du hook fusionnée retourne behavior: "allow" ou "deny", cette décision court-circuite le flux d’autorisation normal. Prend en charge matcher regex sur toolName. | Oui : peut autoriser ou refuser par programme. |
postToolUse | Après que chaque outil ait terminé avec succès. | Oui : peut remplacer le résultat réussi (hooks programmatiques sdk uniquement). |
postToolUseFailure | Une fois qu’un outil rencontre une défaillance. | Oui : peut fournir des conseils de récupération via additionalContext (code 2 de sortie pour les hooks de commande). |
preCompact | Le compactage de contexte est sur le point de commencer (manuel ou automatique). Prend en charge le filtrage matcher par déclencheur ("manual" ou "auto"). | Non : notification uniquement. |
preToolUse | Avant l’exécution de chaque outil. | Oui : peut autoriser, refuser ou modifier. |
sessionEnd | La session se termine. | Non |
sessionStart | Une session nouvelle ou reprise commence. | Non |
subagentStart | Un sous-agent est lancé (avant qu'il ne s'exécute). Retourne additionalContext préfixé à l’invite du sous-agent. Prend en charge matcher pour filtrer par nom de l’agent. | Non : impossible de bloquer la création. |
subagentStop | Un sous-agent s'achève. | Oui : peut bloquer et forcer la continuation. |
userPromptSubmitted | L’utilisateur envoie une invite. | Non |
Charges utiles d'entrée des événements hook
Chaque événement de hook remet une charge utile JSON au gestionnaire de hooks. Deux formats de charge utile sont pris en charge, sélectionnés par le nom d’événement utilisé dans la configuration de hook :
- Format camelCase : configurez le nom de l’événement dans camelCase (par exemple,
sessionStart). Les champs utilisent la convention de dénomination camelCase (commençant par une minuscule et chaque mot suivant avec une majuscule).
VS Code format compatible** : configurez le nom de l’événement dans PascalCase (par exemple, `SessionStart`). Les champs utilisent snake_case pour correspondre au format d’extension VS CodeCopilot .
sessionStart / SessionStart
**entrée camelCase :**
{
sessionId: string;
timestamp: number; // Unix timestamp in milliseconds
cwd: string;
source: "startup" | "resume" | "new";
initialPrompt?: string;
}
**
VS Code entrée compatible :**
{
hook_event_name: "SessionStart";
session_id: string;
timestamp: string; // ISO 8601 timestamp
cwd: string;
source: "startup" | "resume" | "new";
initial_prompt?: string;
}
sessionEnd / SessionEnd
**entrée camelCase :**
{
sessionId: string;
timestamp: number;
cwd: string;
reason: "complete" | "error" | "abort" | "timeout" | "user_exit";
}
**
VS Code entrée compatible :**
{
hook_event_name: "SessionEnd";
session_id: string;
timestamp: string; // ISO 8601 timestamp
cwd: string;
reason: "complete" | "error" | "abort" | "timeout" | "user_exit";
}
userPromptSubmitted / UserPromptSubmit
**entrée camelCase :**
{
sessionId: string;
timestamp: number;
cwd: string;
prompt: string;
}
**
VS Code entrée compatible :**
{
hook_event_name: "UserPromptSubmit";
session_id: string;
timestamp: string; // ISO 8601 timestamp
cwd: string;
prompt: string;
}
preToolUse / PreToolUse
**entrée camelCase :**
{
sessionId: string;
timestamp: number;
cwd: string;
toolName: string;
toolArgs: unknown;
}
**
VS Code entrée compatible :**
Lorsqu’elle est configurée avec le nom PreToolUse de l’événement PascalCase, la charge utile utilise des noms de champs en snake_case afin de correspondre au format d’extension VS CodeCopilot :
{
hook_event_name: "PreToolUse";
session_id: string;
timestamp: string; // ISO 8601 timestamp
cwd: string;
tool_name: string;
tool_input: unknown; // Tool arguments (parsed from JSON string when possible)
}
postToolUse / PostToolUse
**entrée camelCase :**
{
sessionId: string;
timestamp: number;
cwd: string;
toolName: string;
toolArgs: unknown;
toolResult: {
resultType: "success";
textResultForLlm: string;
}
}
**
VS Code entrée compatible :**
{
hook_event_name: "PostToolUse";
session_id: string;
timestamp: string; // ISO 8601 timestamp
cwd: string;
tool_name: string;
tool_input: unknown;
tool_result: {
result_type: "success" | "failure" | "denied" | "error";
text_result_for_llm: string;
}
}
postToolUseFailure / PostToolUseFailure
**entrée camelCase :**
{
sessionId: string;
timestamp: number;
cwd: string;
toolName: string;
toolArgs: unknown;
error: string;
}
**
VS Code entrée compatible :**
{
hook_event_name: "PostToolUseFailure";
session_id: string;
timestamp: string; // ISO 8601 timestamp
cwd: string;
tool_name: string;
tool_input: unknown;
error: string;
}
agentStop / Stop
**entrée camelCase :**
{
sessionId: string;
timestamp: number;
cwd: string;
transcriptPath: string;
stopReason: "end_turn";
}
**
VS Code entrée compatible :**
{
hook_event_name: "Stop";
session_id: string;
timestamp: string; // ISO 8601 timestamp
cwd: string;
transcript_path: string;
stop_reason: "end_turn";
}
subagentStart
**Entrée :**
{
sessionId: string;
timestamp: number;
cwd: string;
transcriptPath: string;
agentName: string;
agentDisplayName?: string;
agentDescription?: string;
}
subagentStop / SubagentStop
**entrée camelCase :**
{
sessionId: string;
timestamp: number;
cwd: string;
transcriptPath: string;
agentName: string;
agentDisplayName?: string;
stopReason: "end_turn";
}
**
VS Code entrée compatible :**
{
hook_event_name: "SubagentStop";
session_id: string;
timestamp: string; // ISO 8601 timestamp
cwd: string;
transcript_path: string;
agent_name: string;
agent_display_name?: string;
stop_reason: "end_turn";
}
errorOccurred / ErrorOccurred
**entrée camelCase :**
{
sessionId: string;
timestamp: number;
cwd: string;
error: {
message: string;
name: string;
stack?: string;
};
errorContext: "model_call" | "tool_execution" | "system" | "user_input";
recoverable: boolean;
}
**
VS Code entrée compatible :**
{
hook_event_name: "ErrorOccurred";
session_id: string;
timestamp: string; // ISO 8601 timestamp
cwd: string;
error: {
message: string;
name: string;
stack?: string;
};
error_context: "model_call" | "tool_execution" | "system" | "user_input";
recoverable: boolean;
}
preCompact / PreCompact
**entrée camelCase :**
{
sessionId: string;
timestamp: number;
cwd: string;
transcriptPath: string;
trigger: "manual" | "auto";
customInstructions: string;
}
**
VS Code entrée compatible :**
{
hook_event_name: "PreCompact";
session_id: string;
timestamp: string; // ISO 8601 timestamp
cwd: string;
transcript_path: string;
trigger: "manual" | "auto";
custom_instructions: string;
}
`preToolUse` contrôle de décision
Le preToolUse hook peut contrôler l’exécution de l’outil en écrivant un objet JSON dans stdout.
| Champ | Valeurs | Description |
|---|---|---|
permissionDecision |
`"allow"`, `"deny"`, `"ask"` | Indique si l’outil s’exécute. La sortie vide utilise le comportement par défaut. |
| permissionDecisionReason | string | Raison indiquée à l’agent. Obligatoire lorsque la décision est "deny". |
| modifiedArgs | Objet | Remplacez les arguments de l’outil à utiliser au lieu des arguments d’origine. |
`agentStop`
/
`subagentStop` contrôle de décision
| Champ | Valeurs | Description |
|---|---|---|
decision |
`"block"`, `"allow"` |
`"block"` oblige un autre agent à réagir en utilisant `reason` comme invite. |
| reason | string | Demander le tour suivant quand decision est "block". |
`permissionRequest` contrôle de décision
Le permissionRequest hook se déclenche avant l'exécution du service de permission : avant les vérifications de règles, les approbations de session, l'acceptation automatique/le refus automatique, et l'interpellation de l'utilisateur. Si les hooks retournent behavior: "allow" ou "deny", cette décision court-circuite le flux de permis normal. Le fait de ne retourner aucune valeur laisse place à la gestion normale des autorisations. Utilisez-le pour approuver ou refuser des appels d’outils par programmation, particulièrement utiles en mode canal (-p) et environnements CI où aucune invite interactive n’est disponible.
Tous les hooks configurés permissionRequest s’exécutent pour chaque requête (sauf les types d’autorisations read``hook, qui court-circuitent avant les hooks). Les sorties de hook sont fusionnées avec les sorties de hook ultérieures substituant les sorties antérieures.
**Matcher :** Expression régulière facultative testée par rapport à `toolName`. Ancré comme `^(?:pattern)$`; doit correspondre au nom complet de l’outil. Lorsqu’il est défini, le hook se déclenche uniquement pour les noms d’outils correspondants.
Sortie json vers stdout pour contrôler la décision d’autorisation :
| Champ | Valeurs | Description |
|---|---|---|
behavior |
`"allow"`, `"deny"` | Indique s’il faut approuver ou refuser l’appel de l’outil. |
| message | string | Raison communiquée au LLM lors du refus. |
| interrupt | booléen | En cas true de combinaison avec "deny", arrête entièrement l’agent. |
Retournez une sortie vide ou {} pour passer au flux de permissions normal. Pour les crochets de commande, le code 2 de sortie est traité comme un refus ; le code JSON stdout (le cas échéant) est fusionné {"behavior":"deny"}avec , et stderr est ignoré.
`notification` Accroche
Le notification hook se déclenche de façon asynchrone lorsque l’interface CLI émet une notification système. Ces accroches sont automatiques : elles ne bloquent jamais la session, et toutes les erreurs sont enregistrées et ignorées.
**Entrée :**
{
sessionId: string;
timestamp: number;
cwd: string;
hook_event_name: "Notification";
message: string; // Human-readable notification text
title?: string; // Short title (e.g., "Permission needed", "Shell completed")
notification_type: string; // One of the types listed below
}
**Types de notification :**
| Type | Quand il se déclenche |
|---|---|
shell_completed | Une commande shell asynchrone en arrière-plan se termine |
shell_detached_completed | Une session shell détachée se termine |
agent_completed | Une sous-valeur en arrière-plan se termine (terminée ou ayant échoué) |
agent_idle | Un agent en arrière-plan termine un tour et entre dans l’état inactif (en attente de write_agent) |
permission_prompt | L’agent demande l’autorisation d’exécuter un outil |
elicitation_dialog | L’agent demande des informations supplémentaires à l’utilisateur |
**Output:**
{
additionalContext?: string; // Injected into the session as a user message
}
Si additionalContext est retourné, le texte est injecté dans la session en tant que message utilisateur préfixé. Cela peut déclencher un traitement supplémentaire de l'agent si la session est inutilisée. Renvoyer {} ou vider la sortie pour n’effectuer aucune action.
**Matcher :** Regex facultatif sur `notification_type`. Le modèle est ancré comme `^(?:pattern)$`. Omettre `matcher` pour recevoir tous les types de notifications.
Noms d’outils pour la correspondance de hooks
| Nom de l’outil | Description |
|---|---|
ask_user | Posez à l’utilisateur une question de clarification. |
bash | Exécuter des commandes shell (Unix). |
create | Créez des fichiers. |
edit | Modifiez le contenu du fichier. |
glob | Recherchez des fichiers par modèle. |
grep | Rechercher le contenu du fichier. |
powershell | Exécuter des commandes shell (Windows). |
task | Exécutez des tâches de sous-agent. |
view | Lire le contenu du fichier. |
web_fetch | Récupérer des pages web. |
Si plusieurs hooks du même type sont configurés, ils s'exécutent dans l'ordre. Pour preToolUse, si un crochet retourne "deny", l’outil est bloqué. Pour postToolUseFailure les hooks de commandes, la sortie avec le code 2 entraîne le retour de stderr comme indication de récupération pour l'assistant. Les échecs de hook (codes de sortie non nuls ou délais d’expiration) sont enregistrés et ignorés. Ils ne bloquent jamais l’exécution de l’agent.