Hooks
Hooks bieten ein erweiterbares, ereignisgesteuertes System, um Aktionen als Reaktion auf Agent-Befehle und Events zu automatisieren. Hooks werden automatisch aus Verzeichnissen erkannt und können per CLI verwaltet werden, ähnlich wie Skills in OpenClaw.
Orientierung
Hooks sind kleine Skripte, die laufen, wenn etwas passiert. Es gibt zwei Arten:
- Hooks (diese Seite): Laufen innerhalb des Gateways, wenn Agent-Events ausgelöst werden, wie
/new,/reset,/stopoder Lifecycle-Events. - Webhooks: Externe HTTP-Webhooks, mit denen andere Systeme Arbeit in OpenClaw auslösen können. Siehe Webhook Hooks oder nutze
openclaw webhooksfür Gmail-Hilfsbefehle.
Hooks können auch in Plugins gebündelt werden; siehe Plugins.
Typische Anwendungsfälle:
- Einen Memory-Snapshot speichern, wenn du eine Session zurücksetzt
- Ein Audit-Trail von Befehlen für Fehlerbehebung oder Compliance führen
- Folge-Automatisierungen auslösen, wenn eine Session startet oder endet
- Dateien in den Agent-Workspace schreiben oder externe APIs aufrufen, wenn Events feuern
Wenn du eine kleine TypeScript-Funktion schreiben kannst, kannst du auch einen Hook schreiben. Hooks werden automatisch erkannt, und du aktivierst oder deaktivierst sie über die CLI.
Überblick
Das Hook-System erlaubt dir:
- Session-Kontext beim Ausführen von
/newim Memory zu speichern - Alle Befehle für Auditing zu protokollieren
- Benutzerdefinierte Automatisierungen bei Agent-Lifecycle-Events auszulösen
- Das Verhalten von OpenClaw zu erweitern, ohne den Kerncode zu ändern
Erste Schritte
Mitgelieferte Hooks
OpenClaw wird mit vier mitgelieferten Hooks ausgeliefert, die automatisch erkannt werden:
- 💾 session-memory: Speichert den Session-Kontext in deinem Agent-Workspace (Standard
~/.openclaw/workspace/memory/), wenn du/newausführst - 📎 bootstrap-extra-files: Injiziert zusätzliche Workspace-Bootstrap-Dateien aus konfigurierten Glob-/Pfad-Mustern während
agent:bootstrap - 📝 command-logger: Protokolliert alle Befehlsevents in
~/.openclaw/logs/commands.log - 🚀 boot-md: Führt
BOOT.mdbeim Gateway-Start aus (erfordert aktivierte interne Hooks)
Verfügbare Hooks auflisten:
openclaw hooks list
Einen Hook aktivieren:
openclaw hooks enable session-memory
Hook-Status prüfen:
openclaw hooks check
Detaillierte Informationen anzeigen:
openclaw hooks info session-memory
Onboarding
Während des Onboardings (openclaw onboard) wirst du aufgefordert, empfohlene Hooks zu aktivieren. Der Assistent erkennt automatisch berechtigte Hooks und stellt sie zur Auswahl.
Hook-Erkennung
Hooks werden automatisch aus drei Verzeichnissen erkannt (in Reihenfolge der Priorität):
- Workspace-Hooks:
<workspace>/hooks/(pro Agent, höchste Priorität) - Verwaltete Hooks:
~/.openclaw/hooks/(benutzerinstalliert, über Workspaces hinweg geteilt) - Mitgelieferte Hooks:
<openclaw>/dist/hooks/bundled/(mit OpenClaw ausgeliefert)
Verwaltete Hook-Verzeichnisse können entweder ein einzelner Hook oder ein Hook-Pack (Paketverzeichnis) sein.
Jeder Hook ist ein Verzeichnis mit:
my-hook/
├── HOOK.md # Metadaten + Dokumentation
└── handler.ts # Handler-Implementierung
Hook Packs (npm/Archive)
Hook Packs sind Standard-npm-Pakete, die ein oder mehrere Hooks über openclaw.hooks in
package.json exportieren. Installiere sie mit:
openclaw hooks install <path-or-spec>
Npm-Specs sind nur Registry (Paketname + optionale exakte Version oder Dist-Tag). Git/URL/File-Specs und Semver-Ranges werden abgelehnt.
Bare Specs und @latest bleiben auf dem Stable-Track. Wenn npm eines davon
auf ein Prerelease auflöst, stoppt OpenClaw und fragt dich, explizit mit einem
Prerelease-Tag wie @beta/@rc oder einer exakten Prerelease-Version einzuwilligen.
Beispiel package.json:
{
"name": "@acme/my-hooks",
"version": "0.1.0",
"openclaw": {
"hooks": ["./hooks/my-hook", "./hooks/other-hook"]
}
}
Jeder Eintrag zeigt auf ein Hook-Verzeichnis mit HOOK.md und handler.ts (oder index.ts).
Hook Packs können Abhängigkeiten mitliefern; sie werden unter ~/.openclaw/hooks/<id> installiert.
Jeder openclaw.hooks-Eintrag muss nach Symlink-Auflösung innerhalb des Paketverzeichnisses
bleiben; Einträge die ausbrechen werden abgelehnt.
Sicherheitshinweis: openclaw hooks install installiert Abhängigkeiten mit npm install --ignore-scripts
(keine Lifecycle-Skripte). Halte Hook-Pack-Abhängigkeitsbäume auf “reines JS/TS” und vermeide Pakete,
die auf postinstall-Builds angewiesen sind.
Hook-Struktur
HOOK.md Format
Die HOOK.md-Datei enthält Metadaten im YAML-Frontmatter plus Markdown-Dokumentation:
---
name: my-hook
description: "Short description of what this hook does"
homepage: https://docs.openclaw.ai/automation/hooks#my-hook
metadata:
{ "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.
Metadaten-Felder
Das metadata.openclaw-Objekt unterstützt:
emoji: Anzeige-Emoji für die CLI (z.B."💾")events: Array von Events, auf die gehört wird (z.B.["command:new", "command:reset"])export: Benannter Export (Standard"default")homepage: Dokumentations-URLrequires: Optionale Anforderungenbins: Erforderliche Binaries im PATH (z.B.["git", "node"])anyBins: Mindestens eines dieser Binaries muss vorhanden seinenv: Erforderliche Umgebungsvariablenconfig: Erforderliche Konfigurationspfade (z.B.["workspace.dir"])os: Erforderliche Plattformen (z.B.["darwin", "linux"])
always: Berechtigungsprüfungen umgehen (boolean)install: Installationsmethoden (für mitgelieferte Hooks:[{"id":"bundled","kind":"bundled"}])
Handler-Implementierung
Die handler.ts-Datei exportiert eine HookHandler-Funktion:
const myHandler = async (event) => {
// Nur bei 'new'-Befehl auslösen
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()}`);
// Deine Logik hier
// Optional Nachricht an Benutzer senden
event.messages.push("✨ My hook executed!");
};
export default myHandler;
Event-Kontext
Jedes Event enthält:
{
type: 'command' | 'session' | 'agent' | 'gateway' | 'message',
action: string, // z.B. 'new', 'reset', 'stop', 'received', 'sent'
sessionKey: string, // Session-Bezeichner
timestamp: Date, // Zeitpunkt des Events
messages: string[], // Nachrichten hier pushen, um sie an den Benutzer zu senden
context: {
// Befehlsevents:
sessionEntry?: SessionEntry,
sessionId?: string,
sessionFile?: string,
commandSource?: string, // z.B. 'whatsapp', 'telegram'
senderId?: string,
workspaceDir?: string,
bootstrapFiles?: WorkspaceBootstrapFile[],
cfg?: OpenClawConfig,
// Message-Events (siehe Abschnitt Message Events für vollständige Details):
from?: string, // message:received
to?: string, // message:sent
content?: string,
channelId?: string,
success?: boolean, // message:sent
}
}
Event-Typen
Befehlsevents
Werden ausgelöst, wenn Agent-Befehle ausgeführt werden:
command: Alle Befehlsevents (allgemeiner Listener)command:new: Wenn/newausgeführt wirdcommand:reset: Wenn/resetausgeführt wirdcommand:stop: Wenn/stopausgeführt wird
Session-Events
session:compact:before: Direkt bevor die Komprimierung die History zusammenfasstsession:compact:after: Nach Abschluss der Komprimierung mit Zusammenfassungs-Metadaten
Interne Hook-Payloads emittieren diese als type: "session" mit action: "compact:before" / action: "compact:after"; Listener abonnieren mit den kombinierten Keys oben.
Spezifische Handler-Registrierung nutzt das Literalformat ${type}:${action}. Für diese Events registriere session:compact:before und session:compact:after.
Agent-Events
agent:bootstrap: Bevor Workspace-Bootstrap-Dateien injiziert werden (Hooks könnencontext.bootstrapFilesmutieren)
Gateway-Events
Werden beim Gateway-Start ausgelöst:
gateway:startup: Nachdem Channels gestartet und Hooks geladen wurden
Message-Events
Werden ausgelöst, wenn Nachrichten empfangen oder gesendet werden:
message: Alle Message-Events (allgemeiner Listener)message:received: Wenn eine eingehende Nachricht von einem Channel empfangen wird. Feuert früh in der Verarbeitung vor Media-Understanding. Inhalt kann rohe Platzhalter wie<media:audio>für Medienanhänge enthalten, die noch nicht verarbeitet wurden.message:transcribed: Wenn eine Nachricht vollständig verarbeitet wurde, einschließlich Audio-Transkription und Link-Understanding. Zu diesem Zeitpunkt enthälttranscriptden vollständigen Transkripttext für Audio-Nachrichten. Nutze diesen Hook, wenn du Zugriff auf transkribierte Audio-Inhalte brauchst.message:preprocessed: Feuert für jede Nachricht, nachdem alles Media- + Link-Understanding abgeschlossen ist, und gibt Hooks Zugriff auf den vollständig angereicherten Body (Transkripte, Bildbeschreibungen, Link-Zusammenfassungen), bevor der Agent ihn sieht.message:sent: Wenn eine ausgehende Nachricht erfolgreich gesendet wurde
Message-Event-Kontext
Message-Events enthalten umfangreichen Kontext über die Nachricht:
// message:received Kontext
{
from: string, // Absender-Kennung (Telefonnummer, User-ID etc.)
content: string, // Nachrichteninhalt
timestamp?: number, // Unix-Zeitstempel beim Empfang
channelId: string, // Channel (z.B. "whatsapp", "telegram", "discord")
accountId?: string, // Provider-Account-ID für Multi-Account-Setups
conversationId?: string, // Chat/Konversations-ID
messageId?: string, // Nachrichten-ID vom Provider
metadata?: { // Zusätzliche Provider-spezifische Daten
to?: string,
provider?: string,
surface?: string,
threadId?: string,
senderId?: string,
senderName?: string,
senderUsername?: string,
senderE164?: string,
}
}
// message:sent Kontext
{
to: string, // Empfänger-Kennung
content: string, // Gesendeter Nachrichteninhalt
success: boolean, // Ob der Versand erfolgreich war
error?: string, // Fehlermeldung falls Versand fehlschlug
channelId: string, // Channel (z.B. "whatsapp", "telegram", "discord")
accountId?: string, // Provider-Account-ID
conversationId?: string, // Chat/Konversations-ID
messageId?: string, // Vom Provider zurückgegebene Nachrichten-ID
isGroup?: boolean, // Ob diese ausgehende Nachricht zu einem Gruppen-/Channel-Kontext gehört
groupId?: string, // Gruppen-/Channel-Kennung zur Korrelation mit message:received
}
// message:transcribed Kontext
{
body?: string, // Roher eingehender Body vor Anreicherung
bodyForAgent?: string, // Angereicherter Body, den der Agent sieht
transcript: string, // Audio-Transkript-Text
channelId: string, // Channel (z.B. "telegram", "whatsapp")
conversationId?: string,
messageId?: string,
}
// message:preprocessed Kontext
{
body?: string, // Roher eingehender Body
bodyForAgent?: string, // Finaler angereicherter Body nach Media/Link-Understanding
transcript?: string, // Transkript wenn Audio vorhanden war
channelId: string, // Channel (z.B. "telegram", "whatsapp")
conversationId?: string,
messageId?: string,
isGroup?: boolean,
groupId?: string,
}
Beispiel: Message-Logger-Hook
const isMessageReceivedEvent = (event: { type: string; action: string }) =>
event.type === "message" && event.action === "received";
const isMessageSentEvent = (event: { type: string; action: string }) =>
event.type === "message" && event.action === "sent";
const handler = async (event) => {
if (isMessageReceivedEvent(event as { type: string; action: string })) {
console.log(`[message-logger] Received from ${event.context.from}: ${event.context.content}`);
} else if (isMessageSentEvent(event as { type: string; action: string })) {
console.log(`[message-logger] Sent to ${event.context.to}: ${event.context.content}`);
}
};
export default handler;
Tool-Result-Hooks (Plugin-API)
Diese Hooks sind keine Event-Stream-Listener; sie erlauben Plugins, Tool-Ergebnisse synchron anzupassen, bevor OpenClaw sie persistiert.
tool_result_persist: Tool-Ergebnisse transformieren, bevor sie ins Session-Transkript geschrieben werden. Muss synchron sein; gib das aktualisierte Tool-Result-Payload zurück oderundefined, um es unverändert zu lassen. Siehe Agent Loop.
Plugin-Hook-Events
Komprimierungs-Lifecycle-Hooks, die über den Plugin-Hook-Runner bereitgestellt werden:
before_compaction: Läuft vor der Komprimierung mit Count/Token-Metadatenafter_compaction: Läuft nach der Komprimierung mit Komprimierungs-Zusammenfassungs-Metadaten
Zukünftige Events
Geplante Event-Typen:
session:start: Wenn eine neue Session beginntsession:end: Wenn eine Session endetagent:error: Wenn ein Agent einen Fehler erlebt
Eigene Hooks erstellen
1. Ort wählen
- Workspace-Hooks (
<workspace>/hooks/): Pro Agent, höchste Priorität - Verwaltete Hooks (
~/.openclaw/hooks/): Über Workspaces hinweg geteilt
2. Verzeichnisstruktur erstellen
mkdir -p ~/.openclaw/hooks/my-hook
cd ~/.openclaw/hooks/my-hook
3. HOOK.md erstellen
---
name: my-hook
description: "Does something useful"
metadata: { "openclaw": { "emoji": "🎯", "events": ["command:new"] } }
---
# My Custom Hook
This hook does something useful when you issue `/new`.
4. handler.ts erstellen
const handler = async (event) => {
if (event.type !== "command" || event.action !== "new") {
return;
}
console.log("[my-hook] Running!");
// Deine Logik hier
};
export default handler;
5. Aktivieren und testen
# Prüfen ob Hook erkannt wurde
openclaw hooks list
# Aktivieren
openclaw hooks enable my-hook
# Gateway-Prozess neu starten (Menüleisten-App auf macOS neu starten, oder Dev-Prozess neu starten)
# Event auslösen
# /new über deinen Messaging-Channel senden
Konfiguration
Neues Konfigurationsformat (empfohlen)
{
"hooks": {
"internal": {
"enabled": true,
"entries": {
"session-memory": { "enabled": true },
"command-logger": { "enabled": false }
}
}
}
}
Pro-Hook-Konfiguration
Hooks können benutzerdefinierte Konfiguration haben:
{
"hooks": {
"internal": {
"enabled": true,
"entries": {
"my-hook": {
"enabled": true,
"env": {
"MY_CUSTOM_VAR": "value"
}
}
}
}
}
}
Zusätzliche Verzeichnisse
Hooks aus zusätzlichen Verzeichnissen laden:
{
"hooks": {
"internal": {
"enabled": true,
"load": {
"extraDirs": ["/path/to/more/hooks"]
}
}
}
}
Legacy-Konfigurationsformat (weiterhin unterstützt)
Das alte Konfigurationsformat funktioniert weiterhin für Abwärtskompatibilität:
{
"hooks": {
"internal": {
"enabled": true,
"handlers": [
{
"event": "command:new",
"module": "./hooks/handlers/my-handler.ts",
"export": "default"
}
]
}
}
}
Hinweis: module muss ein Workspace-relativer Pfad sein. Absolute Pfade und Traversal außerhalb des Workspace werden abgelehnt.
Migration: Nutze das neue Discovery-basierte System für neue Hooks. Legacy-Handler werden nach verzeichnisbasierten Hooks geladen.
CLI-Befehle
Hooks auflisten
# Alle Hooks auflisten
openclaw hooks list
# Nur berechtigte Hooks anzeigen
openclaw hooks list --eligible
# Ausführliche Ausgabe (fehlende Anforderungen anzeigen)
openclaw hooks list --verbose
# JSON-Ausgabe
openclaw hooks list --json
Hook-Informationen
# Detaillierte Infos zu einem Hook anzeigen
openclaw hooks info session-memory
# JSON-Ausgabe
openclaw hooks info session-memory --json
Berechtigung prüfen
# Berechtigungszusammenfassung anzeigen
openclaw hooks check
# JSON-Ausgabe
openclaw hooks check --json
Aktivieren/Deaktivieren
# Hook aktivieren
openclaw hooks enable session-memory
# Hook deaktivieren
openclaw hooks disable command-logger
Referenz der mitgelieferten Hooks
session-memory
Speichert den Session-Kontext im Memory, wenn du /new ausführst.
Events: command:new
Anforderungen: workspace.dir muss konfiguriert sein
Ausgabe: <workspace>/memory/YYYY-MM-DD-slug.md (Standard ~/.openclaw/workspace)
Was es macht:
- Nutzt den Pre-Reset-Session-Eintrag, um das richtige Transkript zu finden
- Extrahiert die letzten 15 Zeilen des Gesprächs
- Nutzt ein LLM, um einen beschreibenden Dateinamen-Slug zu generieren
- Speichert Session-Metadaten in einer datierten Memory-Datei
Beispielausgabe:
# Session: 2026-01-16 14:30:00 UTC
- **Session Key**: agent:main:main
- **Session ID**: abc123def456
- **Source**: telegram
Dateinamen-Beispiele:
2026-01-16-vendor-pitch.md2026-01-16-api-design.md2026-01-16-1430.md(Fallback-Zeitstempel wenn Slug-Generierung fehlschlägt)
Aktivieren:
openclaw hooks enable session-memory
bootstrap-extra-files
Injiziert zusätzliche Bootstrap-Dateien (zum Beispiel monorepo-lokale AGENTS.md / TOOLS.md) während agent:bootstrap.
Events: agent:bootstrap
Anforderungen: workspace.dir muss konfiguriert sein
Ausgabe: Keine Dateien werden geschrieben; Bootstrap-Kontext wird nur im Speicher geändert.
Konfiguration:
{
"hooks": {
"internal": {
"enabled": true,
"entries": {
"bootstrap-extra-files": {
"enabled": true,
"paths": ["packages/*/AGENTS.md", "packages/*/TOOLS.md"]
}
}
}
}
}
Hinweise:
- Pfade werden relativ zum Workspace aufgelöst.
- Dateien müssen innerhalb des Workspace bleiben (realpath-geprüft).
- Nur erkannte Bootstrap-Basisnamen werden geladen.
- Subagent-Allowlist bleibt erhalten (nur
AGENTS.mdundTOOLS.md).
Aktivieren:
openclaw hooks enable bootstrap-extra-files
command-logger
Protokolliert alle Befehlsevents in einer zentralen Audit-Datei.
Events: command
Anforderungen: Keine
Ausgabe: ~/.openclaw/logs/commands.log
Was es macht:
- Erfasst Event-Details (Befehlsaktion, Zeitstempel, Session-Key, Sender-ID, Quelle)
- Hängt an die Log-Datei im JSONL-Format an
- Läuft still im Hintergrund
Beispiel-Log-Einträge:
{"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"}
Logs anzeigen:
# Letzte Befehle anzeigen
tail -n 20 ~/.openclaw/logs/commands.log
# Mit jq formatiert ausgeben
cat ~/.openclaw/logs/commands.log | jq .
# Nach Aktion filtern
grep '"action":"new"' ~/.openclaw/logs/commands.log | jq .
Aktivieren:
openclaw hooks enable command-logger
boot-md
Führt BOOT.md beim Gateway-Start aus (nachdem Channels gestartet wurden).
Interne Hooks müssen dafür aktiviert sein.
Events: gateway:startup
Anforderungen: workspace.dir muss konfiguriert sein
Was es macht:
- Liest
BOOT.mdaus deinem Workspace - Führt die Anweisungen über den Agent-Runner aus
- Sendet angeforderte ausgehende Nachrichten über das Message-Tool
Aktivieren:
openclaw hooks enable boot-md
Best Practices
Handler schnell halten
Hooks laufen während der Befehlsverarbeitung. Halte sie leichtgewichtig:
// ✓ Gut – asynchrone Arbeit, gibt sofort zurück
const handler: HookHandler = async (event) => {
void processInBackground(event); // Fire and forget
};
// ✗ Schlecht – blockiert die Befehlsverarbeitung
const handler: HookHandler = async (event) => {
await slowDatabaseQuery(event);
await evenSlowerAPICall(event);
};
Fehler sauber behandeln
Riskante Operationen immer umschließen:
const handler: HookHandler = async (event) => {
try {
await riskyOperation(event);
} catch (err) {
console.error("[my-handler] Failed:", err instanceof Error ? err.message : String(err));
// Nicht werfen – andere Handler sollen weiterlaufen
}
};
Events früh filtern
Sofort zurückkehren, wenn das Event nicht relevant ist:
const handler: HookHandler = async (event) => {
// Nur 'new'-Befehle behandeln
if (event.type !== "command" || event.action !== "new") {
return;
}
// Deine Logik hier
};
Spezifische Event-Keys verwenden
Wenn möglich, genaue Events in den Metadaten angeben:
metadata: { "openclaw": { "events": ["command:new"] } } # Spezifisch
Statt:
metadata: { "openclaw": { "events": ["command"] } } # Allgemein – mehr Overhead
Debugging
Hook-Logging aktivieren
Das Gateway protokolliert das Laden von Hooks beim Start:
Registered hook: session-memory -> command:new
Registered hook: bootstrap-extra-files -> agent:bootstrap
Registered hook: command-logger -> command
Registered hook: boot-md -> gateway:startup
Erkennung prüfen
Alle erkannten Hooks auflisten:
openclaw hooks list --verbose
Registrierung prüfen
In deinem Handler loggen, wenn er aufgerufen wird:
const handler: HookHandler = async (event) => {
console.log("[my-handler] Triggered:", event.type, event.action);
// Deine Logik
};
Berechtigung überprüfen
Prüfen, warum ein Hook nicht berechtigt ist:
openclaw hooks info my-hook
Auf fehlende Anforderungen in der Ausgabe achten.
Testen
Gateway-Logs
Gateway-Logs überwachen, um Hook-Ausführung zu sehen:
# macOS
./scripts/clawlog.sh -f
# Andere Plattformen
tail -f ~/.openclaw/gateway.log
Hooks direkt testen
Handler isoliert testen:
import { test } from "vitest";
import myHandler from "./hooks/my-hook/handler.js";
test("my handler works", async () => {
const event = {
type: "command",
action: "new",
sessionKey: "test-session",
timestamp: new Date(),
messages: [],
context: { foo: "bar" },
};
await myHandler(event);
// Nebeneffekte prüfen
});
Architektur
Kernkomponenten
src/hooks/types.ts: Typdefinitionensrc/hooks/workspace.ts: Verzeichnis-Scanning und Ladensrc/hooks/frontmatter.ts: HOOK.md-Metadaten-Parsingsrc/hooks/config.ts: Berechtigungsprüfungsrc/hooks/hooks-status.ts: Status-Reportingsrc/hooks/loader.ts: Dynamischer Modul-Loadersrc/cli/hooks-cli.ts: CLI-Befehlesrc/gateway/server-startup.ts: Lädt Hooks beim Gateway-Startsrc/auto-reply/reply/commands-core.ts: Löst Befehlsevents aus
Erkennungsablauf
Gateway-Start
↓
Verzeichnisse scannen (Workspace → verwaltet → mitgeliefert)
↓
HOOK.md-Dateien parsen
↓
Berechtigung prüfen (bins, env, config, os)
↓
Handler von berechtigten Hooks laden
↓
Handler für Events registrieren
Event-Ablauf
Benutzer sendet /new
↓
Befehlsvalidierung
↓
Hook-Event erstellen
↓
Hook auslösen (alle registrierten Handler)
↓
Befehlsverarbeitung fortsetzen
↓
Session zurücksetzen
Fehlerbehebung
Hook wird nicht erkannt
-
Verzeichnisstruktur prüfen:
ls -la ~/.openclaw/hooks/my-hook/ # Sollte zeigen: HOOK.md, handler.ts -
HOOK.md-Format prüfen:
cat ~/.openclaw/hooks/my-hook/HOOK.md # Sollte YAML-Frontmatter mit name und metadata haben -
Alle erkannten Hooks auflisten:
openclaw hooks list
Hook nicht berechtigt
Anforderungen prüfen:
openclaw hooks info my-hook
Auf fehlende Einträge achten:
- Binaries (PATH prüfen)
- Umgebungsvariablen
- Konfigurationswerte
- OS-Kompatibilität
Hook wird nicht ausgeführt
-
Prüfen ob Hook aktiviert ist:
openclaw hooks list # Sollte ✓ neben aktivierten Hooks zeigen -
Gateway-Prozess neu starten, damit Hooks neu geladen werden.
-
Gateway-Logs auf Fehler prüfen:
./scripts/clawlog.sh | grep hook
Handler-Fehler
Auf TypeScript/Import-Fehler prüfen:
# Import direkt testen
node -e "import('./path/to/handler.ts').then(console.log)"
Migrations-Anleitung
Von Legacy-Konfiguration zu Discovery
Vorher:
{
"hooks": {
"internal": {
"enabled": true,
"handlers": [
{
"event": "command:new",
"module": "./hooks/handlers/my-handler.ts"
}
]
}
}
}
Nachher:
-
Hook-Verzeichnis erstellen:
mkdir -p ~/.openclaw/hooks/my-hook mv ./hooks/handlers/my-handler.ts ~/.openclaw/hooks/my-hook/handler.ts -
HOOK.md erstellen:
--- name: my-hook description: "My custom hook" metadata: { "openclaw": { "emoji": "🎯", "events": ["command:new"] } } --- # My Hook Does something useful. -
Konfiguration aktualisieren:
{ "hooks": { "internal": { "enabled": true, "entries": { "my-hook": { "enabled": true } } } } } -
Prüfen und Gateway-Prozess neu starten:
openclaw hooks list # Sollte zeigen: 🎯 my-hook ✓
Vorteile der Migration:
- Automatische Erkennung
- CLI-Verwaltung
- Berechtigungsprüfung
- Bessere Dokumentation
- Einheitliche Struktur