Hooks
Les hooks fournissent un système événementiel extensible pour automatiser les actions en réponse aux commandes et événements de l’agent. Les hooks sont découverts automatiquement à partir des répertoires et peuvent être gérés via les commandes CLI, de manière similaire au fonctionnement des compétences dans OpenClaw.
Prise en main
Section intitulée « Prise en main »Les hooks sont de petits scripts qui s’exécutent lorsqu’un événement se produit. Il en existe deux types :
- Hooks (cette page) : s’exécutent à l’intérieur du Gateway lorsque des événements d’agent se déclenchent, comme
/new,/reset,/stop, ou des événements de cycle de vie. - Webhooks : webhooks HTTP externes qui permettent à d’autres systèmes de déclencher des travaux dans OpenClaw. Voir Webhook Hooks ou utilisez
openclaw webhookspour les commandes d’aide Gmail.
Les hooks peuvent également être regroupés dans des plugins ; voir Plugins.
Cas d’usage courants :
- Enregistrer un instantané de la mémoire lorsque vous réinitialisez une session
- Garder une trace d’audit des commandes pour le dépannage ou la conformité
- Déclencher une automatisation de suivi lorsqu’une session commence ou se termine
- Écrire des fichiers dans l’espace de travail de l’agent ou appeler des API externes lorsque des événements se déclenchent
Si vous savez écrire une petite fonction TypeScript, vous pouvez écrire un hook. Les hooks sont découverts automatiquement et vous les activez ou désactivez via le CLI.
Vue d’ensemble
Section intitulée « Vue d’ensemble »Le système de hooks vous permet de :
- Sauvegarder le contexte de la session en mémoire lorsque
/newest émis - Enregistrer toutes les commandes pour l’audit
- Déclencher des automations personnalisées sur les événements du cycle de vie de l’agent
- Étendre le comportement de OpenClaw sans modifier le code principal
Getting Started
Section intitulée « Getting Started »Hooks inclus
Section intitulée « Hooks inclus »OpenClaw est fourni avec quatre hooks inclus qui sont découverts automatiquement :
- 💾 session-memory : Enregistre le contexte de la session dans votre espace de travail de l’agent (par défaut
~/.openclaw/workspace/memory/) lorsque vous émettez/new - 📝 command-logger : Enregistre tous les événements de commande dans
~/.openclaw/logs/commands.log - 🚀 boot-md : Exécute
BOOT.mdau démarrage de la passerelle (nécessite l’activation des hooks internes) - 😈 soul-evil : Remplace le contenu
SOUL.mdinjecté parSOUL_EVIL.mdpendant une fenêtre de purge ou par hasard
Lister les hooks disponibles :
openclaw hooks listActiver un hook :
openclaw hooks enable session-memoryVérifier l’état du hook :
openclaw hooks checkObtenir des informations détaillées :
openclaw hooks info session-memoryOnboarding
Section intitulée « Onboarding »Pendant l’onboarding (openclaw onboard), vous serez invité à activer les hooks recommandés. L’assistant détecte automatiquement les hooks éligibles et les présente pour sélection.
Découverte de hooks
Section intitulée « Découverte de hooks »Les hooks sont automatiquement découverts dans trois répertoires (par ordre de priorité) :
- Hooks de l’espace de travail :
<workspace>/hooks/(par agent, priorité la plus élevée) - Hooks gérés :
~/.openclaw/hooks/(installés par l’utilisateur, partagés entre les espaces de travail) - Hooks intégrés :
<openclaw>/dist/hooks/bundled/(fournis avec OpenClaw)
Les répertoires de hooks gérés peuvent contenir soit un hook unique soit un pack de hooks (répertoire de package).
Chaque hook est un répertoire contenant :
my-hook/├── HOOK.md # Metadata + documentation└── handler.ts # Handler implementationPacks de hooks (npm/archives)
Section intitulée « Packs de hooks (npm/archives) »Les packs de hooks sont des packages npm standard qui exportent un ou plusieurs hooks via openclaw.hooks dans
package.json. Installez-les avec :
openclaw hooks install <path-or-spec>Exemple package.json :
{ "name": "@acme/my-hooks", "version": "0.1.0", "openclaw": { "hooks": ["./hooks/my-hook", "./hooks/other-hook"] }}Chaque entrée pointe vers un répertoire de hook contenant HOOK.md et handler.ts (ou index.ts).
Les packs de hooks peuvent inclure des dépendances ; elles seront installées sous ~/.openclaw/hooks/<id>.
Structure du hook
Section intitulée « Structure du hook »Format HOOK.md
Section intitulée « Format HOOK.md »Le fichier HOOK.md contient des métadonnées dans le frontmatter YAML ainsi que de la documentation Markdown :
---name: my-hookdescription: "Short description of what this hook does"homepage: https://docs.openclaw.ai/hooks#my-hookmetadata: { "openclaw": { "emoji": "🔗", "events": ["command:new"], "requires": { "bins": ["node"] } } }---
# My Hook
Detailed documentation goes here...
## What It Does
- Listens for `/new` commands- Performs some action- Logs the result
## Requirements
- Node.js must be installed
## Configuration
No configuration needed.Champs de métadonnées
Section intitulée « Champs de métadonnées »L’objet metadata.openclaw prend en charge :
emoji: Emoji d’affichage pour la CLI (par exemple,"💾")events: Tableau des événements à écouter (par exemple,["command:new", "command:reset"])export: Export nommé à utiliser (par défaut"default")homepage: URL de la documentationrequires: Prérequis facultatifsbins: Binaires requis dans le PATH (ex. :["git", "node"])anyBins: Au moins l’un de ces binaires doit être présentenv: Variables d’environnement requisesconfig: Chemins de configuration requis (ex. :["workspace.dir"])os: Plateformes requises (ex. :["darwin", "linux"])
always: Contourner les vérifications d’éligibilité (booléen)install: Méthodes d’installation (pour les hooks groupés :[{"id":"bundled","kind":"bundled"}])
Implémentation du gestionnaire
Section intitulée « Implémentation du gestionnaire »Le fichier handler.ts exporte une fonction HookHandler :
import type { HookHandler } from "../../src/hooks/hooks.js";
const myHandler: HookHandler = async (event) => { // Only trigger on 'new' command if (event.type !== "command" || event.action !== "new") { return; }
console.log(`[my-hook] New command triggered`); console.log(` Session: ${event.sessionKey}`); console.log(` Timestamp: ${event.timestamp.toISOString()}`);
// Your custom logic here
// Optionally send message to user event.messages.push("✨ My hook executed!");};
export default myHandler;Contexte de l’événement
Section intitulée « Contexte de l’événement »Chaque événement inclut :
{ type: 'command' | 'session' | 'agent' | 'gateway', action: string, // e.g., 'new', 'reset', 'stop' sessionKey: string, // Session identifier timestamp: Date, // When the event occurred messages: string[], // Push messages here to send to user context: { sessionEntry?: SessionEntry, sessionId?: string, sessionFile?: string, commandSource?: string, // e.g., 'whatsapp', 'telegram' senderId?: string, workspaceDir?: string, bootstrapFiles?: WorkspaceBootstrapFile[], cfg?: OpenClawConfig }}Types d’événements
Section intitulée « Types d’événements »Événements de commande
Section intitulée « Événements de commande »Déclenchés lorsque des commandes d’agent sont émises :
command: Tous les événements de commande (écouteur général)command:new: Lorsque la commande/newest émisecommand:reset: Lorsque la commande/resetest émisecommand:stop: Lorsque la commande/stopest émise
Événements de l’agent
Section intitulée « Événements de l’agent »agent:bootstrap: Avant l’injection des fichiers d’amorçage de l’espace de travail (les hooks peuvent modifiercontext.bootstrapFiles)
Événements Gateway
Section intitulée « Événements Gateway »Déclenchés au démarrage de la passerelle :
gateway:startup: Après le démarrage des canaux et le chargement des hooks
Hooks de résultat d’outil (Plugin API)
Section intitulée « Hooks de résultat d’outil (Plugin API) »Ces hooks ne sont pas des écouteurs de flux d’événements ; ils permettent aux plugins d’ajuster de manière synchrone les résultats des outils avant que OpenClaw ne les persiste.
tool_result_persist: transformer les résultats des outils avant qu’ils ne soient écrits dans la transcription de session. Doit être synchrone ; renvoyer la charge utile du résultat de l’outil mise à jour ouundefinedpour la laisser telle quelle. Voir Agent Loop.
Événements futurs
Section intitulée « Événements futurs »Types d’événements prévus :
session:start: Lorsqu’une nouvelle session commencesession:end: Lorsqu’une session se termineagent:error: Lorsqu’un agent rencontre une erreurmessage:sent: Lorsqu’un message est envoyémessage:received: Lorsqu’un message est reçu
Créer des hooks personnalisés
Section intitulée « Créer des hooks personnalisés »1. Choisir l’emplacement
Section intitulée « 1. Choisir l’emplacement »- Hooks de l’espace de travail (
<workspace>/hooks/) : Par agent, priorité la plus élevée - Hooks gérés (
~/.openclaw/hooks/) : Partagés entre les espaces de travail
2. Créer la structure des répertoires
Section intitulée « 2. Créer la structure des répertoires »mkdir -p ~/.openclaw/hooks/my-hookcd ~/.openclaw/hooks/my-hook3. Créer HOOK.md
Section intitulée « 3. Créer HOOK.md »---name: my-hookdescription: "Does something useful"metadata: { "openclaw": { "emoji": "🎯", "events": ["command:new"] } }---
# My Custom Hook
This hook does something useful when you issue `/new`.4. Créer handler.ts
Section intitulée « 4. Créer handler.ts »import type { HookHandler } from "../../src/hooks/hooks.js";
const handler: HookHandler = async (event) => { if (event.type !== "command" || event.action !== "new") { return; }
console.log("[my-hook] Running!"); // Your logic here};
export default handler;5. Activer et tester
Section intitulée « 5. Activer et tester »# Verify hook is discoveredopenclaw hooks list
# Enable itopenclaw hooks enable my-hook
# Restart your gateway process (menu bar app restart on macOS, or restart your dev process)
# Trigger the event# Send /new via your messaging channelConfiguration
Section intitulée « Configuration »Nouveau format de configuration (Recommandé)
Section intitulée « Nouveau format de configuration (Recommandé) »{ "hooks": { "internal": { "enabled": true, "entries": { "session-memory": { "enabled": true }, "command-logger": { "enabled": false } } } }}Configuration par hook
Section intitulée « Configuration par hook »Les hooks peuvent avoir une configuration personnalisée :
{ "hooks": { "internal": { "enabled": true, "entries": { "my-hook": { "enabled": true, "env": { "MY_CUSTOM_VAR": "value" } } } } }}Répertoires supplémentaires
Section intitulée « Répertoires supplémentaires »Charger les hooks à partir de répertoires supplémentaires :
{ "hooks": { "internal": { "enabled": true, "load": { "extraDirs": ["/path/to/more/hooks"] } } }}Format de configuration hérité (Toujours pris en charge)
Section intitulée « Format de configuration hérité (Toujours pris en charge) »L’ancien format de configuration fonctionne toujours pour la compatibilité descendante :
{ "hooks": { "internal": { "enabled": true, "handlers": [ { "event": "command:new", "module": "./hooks/handlers/my-handler.ts", "export": "default" } ] } }}Migration : Utilisez le nouveau système basé sur la découverte pour les nouveaux hooks. Les gestionnaires hérités sont chargés après les hooks basés sur les répertoires.
Commandes CLI
Section intitulée « Commandes CLI »Lister les hooks
Section intitulée « Lister les hooks »# List all hooksopenclaw hooks list
# Show only eligible hooksopenclaw hooks list --eligible
# Verbose output (show missing requirements)openclaw hooks list --verbose
# JSON outputopenclaw hooks list --jsonInformations sur le hook
Section intitulée « Informations sur le hook »# Show detailed info about a hookopenclaw hooks info session-memory
# JSON outputopenclaw hooks info session-memory --jsonVérifier l’éligibilité
Section intitulée « Vérifier l’éligibilité »# Show eligibility summaryopenclaw hooks check
# JSON outputopenclaw hooks check --jsonActiver/Désactiver
Section intitulée « Activer/Désactiver »# Enable a hookopenclaw hooks enable session-memory
# Disable a hookopenclaw hooks disable command-loggerHooks inclus
Section intitulée « Hooks inclus »session-memory
Section intitulée « session-memory »Enregistre le contexte de la session dans la mémoire lorsque vous émettez /new.
Événements : command:new
Conditions requises : workspace.dir doit être configuré
Sortie : <workspace>/memory/YYYY-MM-DD-slug.md (par défaut ~/.openclaw/workspace)
Ce qu’il fait :
- Utilise l’entrée de session pré-réinitialisée pour localiser la transcription correcte
- Extrait les 15 dernières lignes de la conversation
- Utilise LLM pour générer un slug de nom de fichier descriptif
- Enregistre les métadonnées de la session dans un fichier de mémoire daté
Exemple de sortie :
# Session: 2026-01-16 14:30:00 UTC
- **Session Key**: agent:main:main- **Session ID**: abc123def456- **Source**: telegramExemples de noms de fichiers :
2026-01-16-vendor-pitch.md2026-01-16-api-design.md2026-01-16-1430.md(horodatage de secours si la génération de slug échoue)
Activer :
openclaw hooks enable session-memorycommand-logger
Section intitulée « command-logger »Enregistre tous les événements de commande dans un fichier d’audit centralisé.
Événements : command
Conditions requises : Aucune
Sortie : ~/.openclaw/logs/commands.log
Ce qu’il fait :
- Capture les détails de l’événement (action de commande, horodatage, clé de session, ID de l’expéditeur, source)
- Ajoute au fichier journal au format JSONL
- S’exécute en silence en arrière-plan
Exemples d’entrées de journal :
{"timestamp":"2026-01-16T14:30:00.000Z","action":"new","sessionKey":"agent:main:main","senderId":"+1234567890","source":"telegram"}{"timestamp":"2026-01-16T15:45:22.000Z","action":"stop","sessionKey":"agent:main:main","senderId":"[email protected]","source":"whatsapp"}Voir les journaux :
# View recent commandstail -n 20 ~/.openclaw/logs/commands.log
# Pretty-print with jqcat ~/.openclaw/logs/commands.log | jq .
# Filter by actiongrep '"action":"new"' ~/.openclaw/logs/commands.log | jq .Activer :
openclaw hooks enable command-loggersoul-evil
Section intitulée « soul-evil »Échange le contenu SOUL.md injecté avec SOUL_EVIL.md pendant une fenêtre de purge ou par hasard.
Événements : agent:bootstrap
Documentation : SOUL Evil Hook
Sortie : Aucun fichier écrit ; les échanges se produisent uniquement en mémoire.
Activer :
openclaw hooks enable soul-evilConfiguration :
{ "hooks": { "internal": { "enabled": true, "entries": { "soul-evil": { "enabled": true, "file": "SOUL_EVIL.md", "chance": 0.1, "purge": { "at": "21:00", "duration": "15m" } } } } }}Exécute BOOT.md lorsque la passerelle démarre (après le démarrage des canaux).
Les hooks internes doivent être activés pour que cela s’exécute.
Événements : gateway:startup
Conditions requises : workspace.dir doit être configuré
Ce qu’il fait :
- Lit
BOOT.mddepuis votre espace de travail - Exécute les instructions via l’exécuteur d’agent
- Envoie tous les messages sortants demandés via l’outil de message
Activer :
openclaw hooks enable boot-mdBonnes pratiques
Section intitulée « Bonnes pratiques »Garder les gestionnaires rapides
Section intitulée « Garder les gestionnaires rapides »Les hooks s’exécutent pendant le traitement des commandes. Gardez-les légers :
// ✓ Good - async work, returns immediatelyconst handler: HookHandler = async (event) => { void processInBackground(event); // Fire and forget};
// ✗ Bad - blocks command processingconst handler: HookHandler = async (event) => { await slowDatabaseQuery(event); await evenSlowerAPICall(event);};Gérer les erreurs avec élégance
Section intitulée « Gérer les erreurs avec élégance »Enveloppez toujours les opérations risquées :
const handler: HookHandler = async (event) => { try { await riskyOperation(event); } catch (err) { console.error("[my-handler] Failed:", err instanceof Error ? err.message : String(err)); // Don't throw - let other handlers run }};Filtrer les événements tôt
Section intitulée « Filtrer les événements tôt »Retournez tôt si l’événement n’est pas pertinent :
const handler: HookHandler = async (event) => { // Only handle 'new' commands if (event.type !== "command" || event.action !== "new") { return; }
// Your logic here};Utiliser des clés d’événement spécifiques
Section intitulée « Utiliser des clés d’événement spécifiques »Spécifiez les événements exacts dans les métadonnées lorsque cela est possible :
metadata: { "openclaw": { "events": ["command:new"] } } # SpecificPlutôt que :
metadata: { "openclaw": { "events": ["command"] } } # General - more overheadDébogage
Section intitulée « Débogage »Activer la journalisation des hooks
Section intitulée « Activer la journalisation des hooks »La passerelle enregistre le chargement des hooks au démarrage :
Registered hook: session-memory -> command:newRegistered hook: command-logger -> commandRegistered hook: boot-md -> gateway:startupVérifier la découverte
Section intitulée « Vérifier la découverte »Lister tous les hooks découverts :
openclaw hooks list --verboseVérifier l’enregistrement
Section intitulée « Vérifier l’enregistrement »Dans votre gestionnaire, enregistrez quand il est appelé :
const handler: HookHandler = async (event) => { console.log("[my-handler] Triggered:", event.type, event.action); // Your logic};Vérifier l’éligibilité
Section intitulée « Vérifier l’éligibilité »Vérifiez pourquoi un hook n’est pas éligible :
openclaw hooks info my-hookRecherchez les conditions requises manquantes dans la sortie.
Gateway Logs
Section intitulée « Gateway Logs »Surveillez les journaux de la passerelle pour voir l’exécution des hooks :
# macOS./scripts/clawlog.sh -f
# Other platformstail -f ~/.openclaw/gateway.logTest Hooks Directly
Section intitulée « Test Hooks Directly »Test your handlers in isolation:
import { test } from "vitest";import { createHookEvent } from "./src/hooks/hooks.js";import myHandler from "./hooks/my-hook/handler.js";
test("my handler works", async () => { const event = createHookEvent("command", "new", "test-session", { foo: "bar", });
await myHandler(event);
// Assert side effects});Architecture
Section intitulée « Architecture »Core Components
Section intitulée « Core Components »src/hooks/types.ts: Type definitionssrc/hooks/workspace.ts: Directory scanning and loadingsrc/hooks/frontmatter.ts: HOOK.md metadata parsingsrc/hooks/config.ts: Eligibility checkingsrc/hooks/hooks-status.ts: Status reportingsrc/hooks/loader.ts: Dynamic module loadersrc/cli/hooks-cli.ts: CLI commandssrc/gateway/server-startup.ts: Loads hooks at gateway startsrc/auto-reply/reply/commands-core.ts: Triggers command events
Discovery Flow
Section intitulée « Discovery Flow »Gateway startup ↓Scan directories (workspace → managed → bundled) ↓Parse HOOK.md files ↓Check eligibility (bins, env, config, os) ↓Load handlers from eligible hooks ↓Register handlers for eventsEvent Flow
Section intitulée « Event Flow »User sends /new ↓Command validation ↓Create hook event ↓Trigger hook (all registered handlers) ↓Command processing continues ↓Session resetTroubleshooting
Section intitulée « Troubleshooting »Hook Not Discovered
Section intitulée « Hook Not Discovered »-
Check directory structure:
Fenêtre de terminal ls -la ~/.openclaw/hooks/my-hook/# Should show: HOOK.md, handler.ts -
Verify HOOK.md format:
Fenêtre de terminal cat ~/.openclaw/hooks/my-hook/HOOK.md# Should have YAML frontmatter with name and metadata -
List all discovered hooks:
Fenêtre de terminal openclaw hooks list
Hook Not Eligible
Section intitulée « Hook Not Eligible »Check requirements:
openclaw hooks info my-hookLook for missing:
- Binaries (check PATH)
- Environment variables
- Config values
- OS compatibility
Hook Not Executing
Section intitulée « Hook Not Executing »-
Verify hook is enabled:
Fenêtre de terminal openclaw hooks list# Should show ✓ next to enabled hooks -
Restart your gateway process so hooks reload.
-
Check gateway logs for errors:
Fenêtre de terminal ./scripts/clawlog.sh | grep hook
Handler Errors
Section intitulée « Handler Errors »Check for TypeScript/import errors:
# Test import directlynode -e "import('./path/to/handler.ts').then(console.log)"Migration Guide
Section intitulée « Migration Guide »From Legacy Config to Discovery
Section intitulée « From Legacy Config to Discovery »Before:
{ "hooks": { "internal": { "enabled": true, "handlers": [ { "event": "command:new", "module": "./hooks/handlers/my-handler.ts" } ] } }}After:
-
Create hook directory:
Fenêtre de terminal mkdir -p ~/.openclaw/hooks/my-hookmv ./hooks/handlers/my-handler.ts ~/.openclaw/hooks/my-hook/handler.ts -
Create HOOK.md:
---name: my-hookdescription: "My custom hook"metadata: { "openclaw": { "emoji": "🎯", "events": ["command:new"] } }---# My HookDoes something useful. -
Update config:
{"hooks": {"internal": {"enabled": true,"entries": {"my-hook": { "enabled": true }}}}} -
Verify and restart your gateway process:
Fenêtre de terminal openclaw hooks list# Should show: 🎯 my-hook ✓
Benefits of migration:
- Automatic discovery
- CLI management
- Eligibility checking
- Better documentation
- Consistent structure