bots-garden/mini-mepublic Fork
⑂ feature/hooks
Commits
⬇ Clone ▾
git clone https://git.rickub.com/bots-garden/mini-me.git
git clone ssh://git@rickub.com/bots-garden/mini-me.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

Download ZIP
🛟 Updated. 46087c3 · on feature/hooks · k33g · 8d ago
hooks.md · 206 lines · 12.0 KBmarkdown
Blame HistoryOpen raw

Référence : les hooks

Le bloc hooks: du fichier de configuration : les événements, le JSON qu'un hook lit et écrit, l'environnement dans lequel il s'exécute, et ce que chaque décision fait au tour.

Configuration

hooks:
  preGeneration:  [<hook>, …]
  preToolCall:    [<hook>, …]
  postToolCall:   [<hook>, …]
  postGeneration: [<hook>, …]

Chaque événement prend une liste ; les hooks d'un événement s'exécutent dans l'ordre où ils sont écrits. Un événement absent, ou une liste vide, n'exécute rien. Pas de bloc hooks: = aucun hook.

Entrée d'un hook

Clé Type Défaut Description
command chaîne — (obligatoire) Exécutée par sh -c "<command>". Ne doit pas être vide ni blanche.
matcher chaîne (expression régulière, syntaxe Go) "" (tous les outils) preToolCall et postToolCall seulement. Le hook s'exécute pour les outils dont le nom correspond. Non ancrée : bash correspond aussi à my_bash ; ^bash$ ne correspond qu'à bash.
timeout durée 10s Durée maximale d'une exécution avant qu'elle soit tuée. 0 = la valeur par défaut. Doit être ≥ 0.
onError fail | warn | ignore warn Ce que fait une exécution en échec (voir Échecs).

Exemple

hooks:
  preGeneration:
    - command: node "$MM_CONFIG_DIR/hooks/no-secrets.js"
      timeout: 5s
      onError: fail
  preToolCall:
    - matcher: ^(bash|write_file|edit_file)$
      command: ./hooks/guard.sh
  postGeneration:
    - command: python3 "$MM_CONFIG_DIR/hooks/log.py"
      onError: ignore

Événements

Événement S'exécute Outils concernés Peut
preGeneration une fois par question, avant le premier appel au modèle — réécrire la question, ajouter du contexte, arrêter le tour
preToolCall avant chaque appel d'outil, avant la demande d'autorisation de l'outil intégrés et MCP, filtrés par matcher refuser l'appel, remplacer ses arguments
postToolCall après chaque appel d'outil exécuté intégrés et MCP, filtrés par matcher ajouter du contexte après la sortie de l'outil
postGeneration une fois le tour terminé : répondu, en échec, annulé ou arrêté par un hook — observer seulement

Les quatre s'exécutent dans tous les front ends : le mode ligne, la fenêtre (-tui), un éditeur (-acp), -p, et un agent démarré par /ask, ask_agent ou mm --ask (avec les hooks de son propre fichier de configuration). Un hook preGeneration ne s'exécute pas sur le résumé d'une compression de contexte.

Exécution

Aspect Valeur
Commande sh -c "<command>"
Dossier de travail celui de la session : le dossier où mm s'exécute, ou le cwd de la session de l'éditeur en ACP
Environnement celui de mm, plus les deux variables ci-dessous
stdin un objet JSON (Entrée), puis fin de fichier
stdout vide, ou un objet JSON (Réponse) ; 1 Mio au plus
stderr cité (300 premiers octets) dans la ligne d'échec quand l'exécution échoue ; ignoré sinon
Concurrence les hooks d'un événement s'exécutent l'un après l'autre ; preToolCall/postToolCall peuvent s'exécuter en parallèle pour deux appels d'outil d'une même réponse du modèle

Variables d'environnement

Variable Valeur
MM_HOOK_EVENT l'événement : preGeneration, preToolCall, postToolCall ou postGeneration
MM_CONFIG_DIR dossier absolu du fichier de configuration qui a déclaré le hook

Entrée

L'objet JSON écrit sur l'entrée standard du hook.

Champ Type Événements Description
event chaîne tous le nom de l'événement
cwd chaîne tous le dossier de travail de la session, absolu
model chaîne tous la référence du modèle, <fournisseur>/<modèle>
prompt chaîne preGeneration, postGeneration la question telle que tapée — lignes @path et $skill comprises. Dans une chaîne, la question telle que le hook précédent l'a laissée. Dans postGeneration : la question que le modèle a lue, ou le marqueur [prompt blocked by a hook: <raison>] quand un hook a arrêté le tour.
tool objet preToolCall, postToolCall l'appel d'outil : id (la référence de l'appel, peut être vide), name, input (les arguments, tels que le modèle les a envoyés ou que le hook précédent les a remplacés)
output chaîne postToolCall la sortie de l'outil, telle que le modèle la lira (en JSON quand l'outil renvoie autre chose que du texte)
answer chaîne postGeneration le texte de la dernière réponse ; vide s'il n'y en a pas
error chaîne postGeneration l'erreur du tour ; absent quand le tour a réussi

Les champs vides sont omis.

Exemples

{"event":"preGeneration","cwd":"/home/moi/projet","model":"llmman/hf.co/unsloth/gemma-4-E4B-it-GGUF:Q4_K_M","prompt":"list the files"}
{"event":"preToolCall","cwd":"/home/moi/projet","model":"llmman/…","tool":{"id":"call_1","name":"bash","input":{"command":"rm -rf build"}}}

Réponse

L'objet JSON qu'un hook peut écrire sur sa sortie standard. Une sortie vide (ou faite seulement d'espaces) vaut {"action":"continue"}. Tous les champs sont facultatifs.

Champ Type Lu sur Description
action chaîne tous continue (par défaut, y compris quand il est absent), stop, deny ou error — voir plus bas
prompt chaîne preGeneration remplace la question. Absent = inchangée ; "" = une question vide.
context chaîne preGeneration, postToolCall du texte pour le modèle. preGeneration : ajouté après la question. postToolCall : ajouté après la sortie de l'outil. Chacun est introduit par la ligne [context added by a hook]. Blanc = ignoré.
input toute valeur JSON preToolCall remplace les arguments de l'appel d'outil. Absent = inchangés.
reason chaîne preGeneration (stop), preToolCall (deny) la raison.
response chaîne preGeneration (stop) ce que l'utilisateur lit à la place d'une réponse. Absente ou blanche : ⛔ This request was blocked by a hook: <raison>.
error chaîne tous (error) le message d'échec du hook lui-même.

Les champs lus sur un autre événement sont ignorés.

Actions

Action Permise sur Effet
continue tous le tour continue, avec le prompt, le context et l'input de ce hook appliqués
stop preGeneration le tour se termine sans appeler le modèle ; les hooks suivants de l'événement ne s'exécutent pas
deny preToolCall l'outil ne s'exécute pas ; les hooks suivants de l'événement ne s'exécutent pas
error tous un échec, traité selon onError
toute autre valeur, ou stop/deny sur un autre événement — un échec : action "<action>" is not valid for <événement>

Effets sur le tour

preGeneration

Décision Le modèle lit L'historique garde L'utilisateur voit
aucun changement la question la question —
prompt et/ou context la question réécrite, puis chaque contexte la question réécrite (la copie propre au front end n'est pas modifiée pendant le tour) —
stop rien : le modèle n'est pas appelé [prompt blocked by a hook: <raison>] (ou [prompt blocked by a hook]) suivi de la response comme réponse la response, comme réponse

En chaîne : chaque hook lit le prompt laissé par le précédent ; les contextes s'accumulent dans l'ordre des hooks.

preToolCall

Décision L'outil Le modèle lit L'utilisateur voit
aucun changement s'exécute avec les arguments du modèle la sortie la ligne habituelle de l'outil
input s'exécute avec les arguments remplacés la sortie la ligne habituelle de l'outil (avec les arguments remplacés)
deny ne s'exécute pas, et ne demande pas d'autorisation [denied by a hook: <raison>] comme sortie de l'outil mode ligne : 🪝 <outil> [denied by a hook: <raison>] ; fenêtre et éditeur : un appel d'outil en échec intitulé <outil> — denied by a hook

L'historique garde l'appel d'outil tel que le modèle l'a écrit, même quand input a remplacé ses arguments.

postToolCall

Les context de tous les hooks qui correspondent sont réunis et ajoutés à la sortie : <sortie>\n\n[context added by a hook]\n<contexte>. La sortie de l'outil montrée à l'utilisateur ne change pas.

postGeneration

Aucun effet sur le tour. La réponse est décodée (une réponse invalide est un échec), puis ignorée.

Échecs

Une exécution échoue quand :

Échec Message
la commande se termine avec un code non nul exit status <n>: <stderr>
elle dure plus que timeout timed out after <timeout>
le tour est annulé pendant qu'elle s'exécute (preGeneration, preToolCall, postToolCall) cancelled
stdout dépasse 1 Mio stdout larger than 1048576 bytes
stdout n'est pas du JSON invalid JSON on stdout: …
action vaut error l'error de la réponse, ou the hook reported an error
action est inconnue ou non permise sur l'événement action "<action>" is not valid for <événement>

postGeneration n'est pas annulé avec le tour : il s'exécute aussi après une annulation (Échap, Ctrl-C, /abort), borné par son timeout.

La suite dépend d'onError :

onError preGeneration preToolCall postToolCall, postGeneration
fail ligne d'échec, tour arrêté (response : ⛔ This request was blocked by a hook: hook failed: …) ligne d'échec, appel refusé (reason : hook failed: …) ligne d'échec, on continue
warn ligne d'échec, hook suivant ligne d'échec, hook suivant ligne d'échec, on continue
ignore hook suivant, sans rien dire hook suivant, sans rien dire on continue, sans rien dire

La ligne d'échec est 🪝 <événement> hook \`: <échec>` : sur stdout en mode ligne, en ligne grisée dans la conversation de la fenêtre, sur stderr (les journaux de l'agent dans l'éditeur) en ACP.

Bannière de démarrage

Quand au moins un hook est déclaré, la bannière se termine par | hooks: <événement>×<nombre> …, une entrée par événement qui a des hooks, dans l'ordre preGeneration, preToolCall, postToolCall, postGeneration :

mm v0.4.0 | config: ../agent.yaml | … | yolo: on | hooks: preGeneration×2 preToolCall×1 postToolCall×1 postGeneration×1

Erreurs de validation

Signalées au démarrage sous la forme [config error: <chemin>: <message>], code de sortie 1.

Message Cause
hooks: unknown event "<nom>" (want one of preGeneration, preToolCall, postToolCall, postGeneration) une clé de hooks: qui n'est pas un événement (une faute de frappe : preToolcall)
hooks.<événement>[N]: command must not be empty pas de command, ou une commande blanche
hooks.<événement>[N]: matcher is only for preToolCall and postToolCall un matcher sur preGeneration ou postGeneration
hooks.<événement>[N]: matcher: error parsing regexp: … un matcher qui ne compile pas
hooks.<événement>[N]: timeout must be >= 0 un timeout négatif
hooks.<événement>[N]: onError must be "fail", "warn" or "ignore" toute autre valeur d'onError

Voir aussi

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# Référence : les hooks

> Le bloc `hooks:` du fichier de configuration : les événements, le JSON qu'un hook lit et écrit, l'environnement dans lequel il s'exécute, et ce que chaque décision fait au tour.

## Configuration

```yaml
hooks:
  preGeneration:  [<hook>, …]
  preToolCall:    [<hook>, …]
  postToolCall:   [<hook>, …]
  postGeneration: [<hook>, …]
```

Chaque événement prend une liste ; les hooks d'un événement s'exécutent dans l'ordre où ils sont écrits. Un événement absent, ou une liste vide, n'exécute rien. Pas de bloc `hooks:` = aucun hook.

### Entrée d'un hook

| Clé | Type | Défaut | Description |
|-----|------|--------|-------------|
| `command` | chaîne | — (obligatoire) | Exécutée par `sh -c "<command>"`. Ne doit pas être vide ni blanche. |
| `matcher` | chaîne (expression régulière, syntaxe Go) | `""` (tous les outils) | `preToolCall` et `postToolCall` seulement. Le hook s'exécute pour les outils dont le nom correspond. Non ancrée : `bash` correspond aussi à `my_bash` ; `^bash$` ne correspond qu'à `bash`. |
| `timeout` | durée | `10s` | Durée maximale d'une exécution avant qu'elle soit tuée. `0` = la valeur par défaut. Doit être ≥ 0. |
| `onError` | `fail` \| `warn` \| `ignore` | `warn` | Ce que fait une exécution en échec (voir [Échecs](#échecs)). |

### Exemple

```yaml
hooks:
  preGeneration:
    - command: node "$MM_CONFIG_DIR/hooks/no-secrets.js"
      timeout: 5s
      onError: fail
  preToolCall:
    - matcher: ^(bash|write_file|edit_file)$
      command: ./hooks/guard.sh
  postGeneration:
    - command: python3 "$MM_CONFIG_DIR/hooks/log.py"
      onError: ignore
```

## Événements

| Événement | S'exécute | Outils concernés | Peut |
|-----------|-----------|------------------|------|
| `preGeneration` | une fois par question, avant le premier appel au modèle | — | réécrire la question, ajouter du contexte, arrêter le tour |
| `preToolCall` | avant chaque appel d'outil, avant la demande d'autorisation de l'outil | intégrés et MCP, filtrés par `matcher` | refuser l'appel, remplacer ses arguments |
| `postToolCall` | après chaque appel d'outil exécuté | intégrés et MCP, filtrés par `matcher` | ajouter du contexte après la sortie de l'outil |
| `postGeneration` | une fois le tour terminé : répondu, en échec, annulé ou arrêté par un hook | — | observer seulement |

Les quatre s'exécutent dans tous les front ends : le mode ligne, la fenêtre (`-tui`), un éditeur (`-acp`), `-p`, et un agent démarré par `/ask`, `ask_agent` ou `mm --ask` (avec les hooks de **son propre** fichier de configuration). Un hook `preGeneration` ne s'exécute pas sur le résumé d'une compression de contexte.

## Exécution

| Aspect | Valeur |
|--------|--------|
| Commande | `sh -c "<command>"` |
| Dossier de travail | celui de la session : le dossier où `mm` s'exécute, ou le `cwd` de la session de l'éditeur en ACP |
| Environnement | celui de `mm`, plus les deux variables ci-dessous |
| stdin | un objet JSON ([Entrée](#entrée)), puis fin de fichier |
| stdout | vide, ou un objet JSON ([Réponse](#réponse)) ; 1 Mio au plus |
| stderr | cité (300 premiers octets) dans la ligne d'échec quand l'exécution échoue ; ignoré sinon |
| Concurrence | les hooks d'un événement s'exécutent l'un après l'autre ; `preToolCall`/`postToolCall` peuvent s'exécuter en parallèle pour deux appels d'outil d'une même réponse du modèle |

### Variables d'environnement

| Variable | Valeur |
|----------|--------|
| `MM_HOOK_EVENT` | l'événement : `preGeneration`, `preToolCall`, `postToolCall` ou `postGeneration` |
| `MM_CONFIG_DIR` | dossier absolu du fichier de configuration qui a déclaré le hook |

## Entrée

L'objet JSON écrit sur l'entrée standard du hook.

| Champ | Type | Événements | Description |
|-------|------|------------|-------------|
| `event` | chaîne | tous | le nom de l'événement |
| `cwd` | chaîne | tous | le dossier de travail de la session, absolu |
| `model` | chaîne | tous | la référence du modèle, `<fournisseur>/<modèle>` |
| `prompt` | chaîne | `preGeneration`, `postGeneration` | la question telle que tapée — lignes `@path` et `$skill` comprises. Dans une chaîne, la question telle que le hook précédent l'a laissée. Dans `postGeneration` : la question que le modèle a lue, ou le marqueur `[prompt blocked by a hook: <raison>]` quand un hook a arrêté le tour. |
| `tool` | objet | `preToolCall`, `postToolCall` | l'appel d'outil : `id` (la référence de l'appel, peut être vide), `name`, `input` (les arguments, tels que le modèle les a envoyés ou que le hook précédent les a remplacés) |
| `output` | chaîne | `postToolCall` | la sortie de l'outil, telle que le modèle la lira (en JSON quand l'outil renvoie autre chose que du texte) |
| `answer` | chaîne | `postGeneration` | le texte de la dernière réponse ; vide s'il n'y en a pas |
| `error` | chaîne | `postGeneration` | l'erreur du tour ; absent quand le tour a réussi |

Les champs vides sont omis.

### Exemples

```json
{"event":"preGeneration","cwd":"/home/moi/projet","model":"llmman/hf.co/unsloth/gemma-4-E4B-it-GGUF:Q4_K_M","prompt":"list the files"}
```

```json
{"event":"preToolCall","cwd":"/home/moi/projet","model":"llmman/…","tool":{"id":"call_1","name":"bash","input":{"command":"rm -rf build"}}}
```

## Réponse

L'objet JSON qu'un hook peut écrire sur sa sortie standard. **Une sortie vide (ou faite seulement d'espaces) vaut `{"action":"continue"}`.** Tous les champs sont facultatifs.

| Champ | Type | Lu sur | Description |
|-------|------|--------|-------------|
| `action` | chaîne | tous | `continue` (par défaut, y compris quand il est absent), `stop`, `deny` ou `error` — voir plus bas |
| `prompt` | chaîne | `preGeneration` | remplace la question. Absent = inchangée ; `""` = une question vide. |
| `context` | chaîne | `preGeneration`, `postToolCall` | du texte pour le modèle. `preGeneration` : ajouté après la question. `postToolCall` : ajouté après la sortie de l'outil. Chacun est introduit par la ligne `[context added by a hook]`. Blanc = ignoré. |
| `input` | toute valeur JSON | `preToolCall` | remplace les arguments de l'appel d'outil. Absent = inchangés. |
| `reason` | chaîne | `preGeneration` (`stop`), `preToolCall` (`deny`) | la raison. |
| `response` | chaîne | `preGeneration` (`stop`) | ce que l'utilisateur lit à la place d'une réponse. Absente ou blanche : `⛔ This request was blocked by a hook: <raison>`. |
| `error` | chaîne | tous (`error`) | le message d'échec du hook lui-même. |

Les champs lus sur un autre événement sont ignorés.

### Actions

| Action | Permise sur | Effet |
|--------|-------------|-------|
| `continue` | tous | le tour continue, avec le `prompt`, le `context` et l'`input` de ce hook appliqués |
| `stop` | `preGeneration` | le tour se termine sans appeler le modèle ; les hooks suivants de l'événement ne s'exécutent pas |
| `deny` | `preToolCall` | l'outil ne s'exécute pas ; les hooks suivants de l'événement ne s'exécutent pas |
| `error` | tous | un échec, traité selon `onError` |
| toute autre valeur, ou `stop`/`deny` sur un autre événement | — | un échec : `action "<action>" is not valid for <événement>` |

## Effets sur le tour

### `preGeneration`

| Décision | Le modèle lit | L'historique garde | L'utilisateur voit |
|----------|---------------|--------------------|--------------------|
| aucun changement | la question | la question | — |
| `prompt` et/ou `context` | la question réécrite, puis chaque contexte | la question réécrite (la copie propre au front end n'est pas modifiée pendant le tour) | — |
| `stop` | rien : le modèle n'est pas appelé | `[prompt blocked by a hook: <raison>]` (ou `[prompt blocked by a hook]`) suivi de la `response` comme réponse | la `response`, comme réponse |

En chaîne : chaque hook lit le `prompt` laissé par le précédent ; les contextes s'accumulent dans l'ordre des hooks.

### `preToolCall`

| Décision | L'outil | Le modèle lit | L'utilisateur voit |
|----------|---------|---------------|--------------------|
| aucun changement | s'exécute avec les arguments du modèle | la sortie | la ligne habituelle de l'outil |
| `input` | s'exécute avec les arguments remplacés | la sortie | la ligne habituelle de l'outil (avec les arguments remplacés) |
| `deny` | ne s'exécute pas, et ne demande pas d'autorisation | `[denied by a hook: <raison>]` comme sortie de l'outil | mode ligne : `🪝 <outil> [denied by a hook: <raison>]` ; fenêtre et éditeur : un appel d'outil en échec intitulé `<outil> — denied by a hook` |

L'historique garde l'appel d'outil tel que le modèle l'a écrit, même quand `input` a remplacé ses arguments.

### `postToolCall`

Les `context` de tous les hooks qui correspondent sont réunis et ajoutés à la sortie : `<sortie>\n\n[context added by a hook]\n<contexte>`. La sortie de l'outil montrée à l'utilisateur ne change pas.

### `postGeneration`

Aucun effet sur le tour. La réponse est décodée (une réponse invalide est un échec), puis ignorée.

## Échecs

Une exécution échoue quand :

| Échec | Message |
|-------|---------|
| la commande se termine avec un code non nul | `exit status <n>: <stderr>` |
| elle dure plus que `timeout` | `timed out after <timeout>` |
| le tour est annulé pendant qu'elle s'exécute (`preGeneration`, `preToolCall`, `postToolCall`) | `cancelled` |
| stdout dépasse 1 Mio | `stdout larger than 1048576 bytes` |
| stdout n'est pas du JSON | `invalid JSON on stdout: …` |
| `action` vaut `error` | l'`error` de la réponse, ou `the hook reported an error` |
| `action` est inconnue ou non permise sur l'événement | `action "<action>" is not valid for <événement>` |

`postGeneration` n'est pas annulé avec le tour : il s'exécute aussi après une annulation (Échap, Ctrl-C, `/abort`), borné par son `timeout`.

La suite dépend d'`onError` :

| `onError` | `preGeneration` | `preToolCall` | `postToolCall`, `postGeneration` |
|-----------|-----------------|---------------|----------------------------------|
| `fail` | ligne d'échec, tour arrêté (`response` : `⛔ This request was blocked by a hook: hook failed: …`) | ligne d'échec, appel refusé (`reason` : `hook failed: …`) | ligne d'échec, on continue |
| `warn` | ligne d'échec, hook suivant | ligne d'échec, hook suivant | ligne d'échec, on continue |
| `ignore` | hook suivant, sans rien dire | hook suivant, sans rien dire | on continue, sans rien dire |

La ligne d'échec est `🪝 <événement> hook \`<command>\`: <échec>` : sur stdout en mode ligne, en ligne grisée dans la conversation de la fenêtre, sur stderr (les journaux de l'agent dans l'éditeur) en ACP.

## Bannière de démarrage

Quand au moins un hook est déclaré, la bannière se termine par ` | hooks: <événement>×<nombre> …`, une entrée par événement qui a des hooks, dans l'ordre `preGeneration`, `preToolCall`, `postToolCall`, `postGeneration` :

```
mm v0.4.0 | config: ../agent.yaml | … | yolo: on | hooks: preGeneration×2 preToolCall×1 postToolCall×1 postGeneration×1
```

## Erreurs de validation

Signalées au démarrage sous la forme `[config error: <chemin>: <message>]`, code de sortie 1.

| Message | Cause |
|---------|-------|
| `hooks: unknown event "<nom>" (want one of preGeneration, preToolCall, postToolCall, postGeneration)` | une clé de `hooks:` qui n'est pas un événement (une faute de frappe : `preToolcall`) |
| `hooks.<événement>[N]: command must not be empty` | pas de `command`, ou une commande blanche |
| `hooks.<événement>[N]: matcher is only for preToolCall and postToolCall` | un `matcher` sur `preGeneration` ou `postGeneration` |
| `hooks.<événement>[N]: matcher: error parsing regexp: …` | un `matcher` qui ne compile pas |
| `hooks.<événement>[N]: timeout must be >= 0` | un `timeout` négatif |
| `hooks.<événement>[N]: onError must be "fail", "warn" or "ignore"` | toute autre valeur d'`onError` |

## Voir aussi

- [Protéger l'agent avec des hooks](../how-to/guard-the-agent-with-hooks.md)
- [Les hooks — explication](../explanation/hooks.md)
- La démo : `demos/hooks/` (quatre hooks Node.js)