Hooks¶
Hooks bieten ein erweiterbares, ereignisgesteuertes System zur Automatisierung von Aktionen als Reaktion auf Agent-Befehle und -Ereignisse. Hooks werden automatisch aus Verzeichnissen erkannt und können über CLI-Befehle verwaltet werden, ähnlich wie Skills in OpenClaw funktionieren.
Orientierung¶
Hooks sind kleine Skripte, die ausgeführt werden, wenn etwas passiert. Es gibt zwei Arten:
- Hooks (diese Seite): werden im Gateway ausgeführt, wenn Agent-Ereignisse ausgelöst werden, z. B.
/new,/reset,/stopoder Lifecycle-Ereignisse. - Webhooks: externe HTTP-Webhooks, mit denen andere Systeme Arbeit in OpenClaw auslösen können. Siehe Webhook Hooks oder verwenden Sie
openclaw webhooksfür Gmail-Hilfsbefehle.
Hooks können auch in Plugins gebündelt werden; siehe Plugins.
Häufige Anwendungsfälle:
- Einen Memory-Snapshot speichern, wenn Sie eine Sitzung zurücksetzen
- Einen Audit-Trail von Befehlen zur Fehlerbehebung oder Compliance führen
- Folgeautomatisierungen auslösen, wenn eine Sitzung beginnt oder endet
- Dateien in den Agent-Arbeitsbereich schreiben oder externe APIs aufrufen, wenn Ereignisse ausgelöst werden
Wenn Sie eine kleine TypeScript-Funktion schreiben können, können Sie auch einen Hook schreiben. Hooks werden automatisch erkannt, und Sie aktivieren oder deaktivieren sie über die CLI.
Überblick¶
Das Hook-System ermöglicht Ihnen:
- Sitzungs-Kontext in den Speicher zu sichern, wenn
/newausgeführt wird - Alle Befehle für Audit-Zwecke zu protokollieren
- Benutzerdefinierte Automatisierungen bei Agent-Lifecycle-Ereignissen auszulösen
- Das Verhalten von OpenClaw zu erweitern, ohne den Core-Code zu verändern
Erste Schritte¶
Gebündelte Hooks¶
OpenClaw wird mit vier gebündelten Hooks ausgeliefert, die automatisch erkannt werden:
- 💾 session-memory: Speichert den Sitzungs-Kontext in Ihrem Agent-Arbeitsbereich (Standard
~/.openclaw/workspace/memory/), wenn Sie/newausführen - 📝 command-logger: Protokolliert alle Befehlsereignisse in
~/.openclaw/logs/commands.log - 🚀 boot-md: Führt
BOOT.mdaus, wenn das Gateway startet (erfordert aktivierte interne Hooks) - 😈 soul-evil: Tauscht injizierten
SOUL.md-Inhalt während eines Purge-Fensters oder mit zufälliger Wahrscheinlichkeit gegenSOUL_EVIL.mdaus
Verfügbare Hooks auflisten:
openclaw hooks list
Einen Hook aktivieren:
openclaw hooks enable session-memory
Hook-Status prüfen:
openclaw hooks check
Detaillierte Informationen abrufen:
openclaw hooks info session-memory
Einführung¶
Während des Onboardings (openclaw onboard) werden Sie aufgefordert, empfohlene Hooks zu aktivieren. Der Assistent erkennt automatisch geeignete Hooks und stellt sie zur Auswahl.
Hook-Erkennung¶
Hooks werden automatisch aus drei Verzeichnissen erkannt (in der Reihenfolge der Priorität):
- Workspace-Hooks:
<workspace>/hooks/(pro Agent, höchste Priorität) - Verwaltete Hooks:
~/.openclaw/hooks/(benutzerinstalliert, gemeinsam über Workspaces hinweg) - Gebündelte 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 folgendem Inhalt:
my-hook/
├── HOOK.md # Metadata + documentation
└── handler.ts # Handler implementation
Hook-Packs (npm/Archive)¶
Hook-Packs sind standardmäßige npm-Pakete, die einen oder mehrere Hooks über openclaw.hooks in
package.json exportieren. Installieren Sie sie mit:
openclaw hooks install <path-or-spec>
Beispiel package.json:
{
"name": "@acme/my-hooks",
"version": "0.1.0",
"openclaw": {
"hooks": ["./hooks/my-hook", "./hooks/other-hook"]
}
}
Jeder Eintrag verweist auf ein Hook-Verzeichnis, das HOOK.md und handler.ts (oder index.ts) enthält.
Hook-Packs können Abhängigkeiten mitbringen; diese werden unter ~/.openclaw/hooks/<id> installiert.
Hook-Struktur¶
HOOK.md-Format¶
Die Datei HOOK.md enthält Metadaten im YAML-Frontmatter sowie Markdown-Dokumentation:
---
name: my-hook
description: "Short description of what this hook does"
homepage: https://docs.openclaw.ai/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.
Metadatenfelder¶
Das Objekt metadata.openclaw unterstützt:
emoji: Anzeige-Emoji für die CLI (z. B."💾")events: Array von Ereignissen, auf die gehört wird (z. B.["command:new", "command:reset"])export: Zu verwendender 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: Eignungsprüfungen umgehen (boolean)install: Installationsmethoden (für gebündelte Hooks:[{"id":"bundled","kind":"bundled"}])
Handler-Implementierung¶
Die Datei handler.ts exportiert eine Funktion 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;
Ereigniskontext¶
Jedes Ereignis enthält:
{
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
}
}
Ereignistypen¶
Befehlsereignisse¶
Ausgelöst, wenn Agent-Befehle ausgeführt werden:
command: Alle Befehlsereignisse (allgemeiner Listener)command:new: Wenn der Befehl/newausgeführt wirdcommand:reset: Wenn der Befehl/resetausgeführt wirdcommand:stop: Wenn der Befehl/stopausgeführt wird
Agent-Ereignisse¶
agent:bootstrap: Bevor Workspace-Bootstrap-Dateien injiziert werden (Hooks dürfencontext.bootstrapFilesverändern)
Gateway-Ereignisse¶
Ausgelöst, wenn das Gateway startet:
gateway:startup: Nachdem Kanäle gestartet sind und Hooks geladen wurden
Tool-Result-Hooks (Plugin-API)¶
Diese Hooks sind keine Event-Stream-Listener; sie ermöglichen es Plugins, Tool-Ergebnisse synchron anzupassen, bevor OpenClaw sie persistiert.
tool_result_persist: Transformiert Tool-Ergebnisse, bevor sie in das Sitzungsprotokoll geschrieben werden. Muss synchron sein; geben Sie die aktualisierte Tool-Ergebnis-Payload zurück oderundefined, um sie unverändert zu lassen. Siehe Agent Loop.
Zukünftige Ereignisse¶
Geplante Ereignistypen:
session:start: Wenn eine neue Sitzung beginntsession:end: Wenn eine Sitzung endetagent:error: Wenn ein Agent auf einen Fehler stößtmessage:sent: Wenn eine Nachricht gesendet wirdmessage:received: Wenn eine Nachricht empfangen wird
Eigene Hooks erstellen¶
1. Ort wählen¶
- Workspace-Hooks (
<workspace>/hooks/): Pro Agent, höchste Priorität - Verwaltete Hooks (
~/.openclaw/hooks/): Gemeinsam über Workspaces hinweg
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¶
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. Aktivieren und testen¶
# Verify hook is discovered
openclaw hooks list
# Enable it
openclaw 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 channel
Konfiguration¶
Neues Konfigurationsformat (empfohlen)¶
{
"hooks": {
"internal": {
"enabled": true,
"entries": {
"session-memory": { "enabled": true },
"command-logger": { "enabled": false }
}
}
}
}
Pro-Hook-Konfiguration¶
Hooks können eine 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 aus Gründen der Abwärtskompatibilität weiterhin:
{
"hooks": {
"internal": {
"enabled": true,
"handlers": [
{
"event": "command:new",
"module": "./hooks/handlers/my-handler.ts",
"export": "default"
}
]
}
}
}
Migration: Verwenden Sie für neue Hooks das neue, erkennungsgestützte System. Legacy-Handler werden nach den verzeichnisbasierten Hooks geladen.
CLI-Befehle¶
Hooks auflisten¶
# List all hooks
openclaw hooks list
# Show only eligible hooks
openclaw hooks list --eligible
# Verbose output (show missing requirements)
openclaw hooks list --verbose
# JSON output
openclaw hooks list --json
Hook-Informationen¶
# Show detailed info about a hook
openclaw hooks info session-memory
# JSON output
openclaw hooks info session-memory --json
Eignung prüfen¶
# Show eligibility summary
openclaw hooks check
# JSON output
openclaw hooks check --json
Aktivieren/Deaktivieren¶
# Enable a hook
openclaw hooks enable session-memory
# Disable a hook
openclaw hooks disable command-logger
Referenz der gebündelten Hooks¶
session-memory¶
Speichert den Sitzungs-Kontext im Speicher, wenn Sie /new ausführen.
Ereignisse: command:new
Anforderungen: workspace.dir muss konfiguriert sein
Ausgabe: <workspace>/memory/YYYY-MM-DD-slug.md (Standard: ~/.openclaw/workspace)
Was es tut:
- Verwendet den Vor-Reset-Sitzungseintrag, um das korrekte Transkript zu finden
- Extrahiert die letzten 15 Zeilen der Konversation
- Verwendet ein LLM, um einen beschreibenden Dateinamen-Slug zu generieren
- Speichert Sitzungsmetadaten in einer datierten Memory-Datei
Beispielausgabe:
# Session: 2026-01-16 14:30:00 UTC
- **Session Key**: agent:main:main
- **Session ID**: abc123def456
- **Source**: telegram
Beispiele für Dateinamen:
2026-01-16-vendor-pitch.md2026-01-16-api-design.md2026-01-16-1430.md(Fallback-Zeitstempel, falls die Slug-Generierung fehlschlägt)
Aktivieren:
openclaw hooks enable session-memory
command-logger¶
Protokolliert alle Befehlsereignisse in eine zentrale Audit-Datei.
Ereignisse: command
Anforderungen: Keine
Ausgabe: ~/.openclaw/logs/commands.log
Was es tut:
- Erfasst Ereignisdetails (Befehlsaktion, Zeitstempel, Sitzungs-Schlüssel, Absender-ID, Quelle)
- Hängt sie im JSONL-Format an die Logdatei an
- Läuft unauffällig im Hintergrund
Beispiel-Logeinträ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":"user@example.com","source":"whatsapp"}
Logs anzeigen:
# View recent commands
tail -n 20 ~/.openclaw/logs/commands.log
# Pretty-print with jq
cat ~/.openclaw/logs/commands.log | jq .
# Filter by action
grep '"action":"new"' ~/.openclaw/logs/commands.log | jq .
Aktivieren:
openclaw hooks enable command-logger
soul-evil¶
Tauscht injizierten SOUL.md-Inhalt während eines Purge-Fensters oder mit zufälliger Wahrscheinlichkeit gegen SOUL_EVIL.md aus.
Ereignisse: agent:bootstrap
Docs: SOUL Evil Hook
Ausgabe: Es werden keine Dateien geschrieben; die Tauschaktionen erfolgen ausschließlich im Speicher.
Aktivieren:
openclaw hooks enable soul-evil
Konfiguration:
{
"hooks": {
"internal": {
"enabled": true,
"entries": {
"soul-evil": {
"enabled": true,
"file": "SOUL_EVIL.md",
"chance": 0.1,
"purge": { "at": "21:00", "duration": "15m" }
}
}
}
}
}
boot-md¶
Führt BOOT.md aus, wenn das Gateway startet (nachdem die Kanäle gestartet sind).
Interne Hooks müssen aktiviert sein, damit dies ausgeführt wird.
Ereignisse: gateway:startup
Anforderungen: workspace.dir muss konfiguriert sein
Was es tut:
- Liest
BOOT.mdaus Ihrem Workspace - Führt die Anweisungen über den Agent-Runner aus
- Sendet angeforderte ausgehende Nachrichten über das Nachrichten-Werkzeug
Aktivieren:
openclaw hooks enable boot-md
Best Practices¶
Handler schnell halten¶
Hooks laufen während der Befehlsverarbeitung. Halten Sie sie leichtgewichtig:
// ✓ Good - async work, returns immediately
const handler: HookHandler = async (event) => {
void processInBackground(event); // Fire and forget
};
// ✗ Bad - blocks command processing
const handler: HookHandler = async (event) => {
await slowDatabaseQuery(event);
await evenSlowerAPICall(event);
};
Fehler robust behandeln¶
Umschließen Sie riskante Operationen immer:
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
}
};
Ereignisse früh filtern¶
Beenden Sie frühzeitig, wenn das Ereignis nicht relevant ist:
const handler: HookHandler = async (event) => {
// Only handle 'new' commands
if (event.type !== "command" || event.action !== "new") {
return;
}
// Your logic here
};
Spezifische Ereignisschlüssel verwenden¶
Geben Sie in den Metadaten nach Möglichkeit exakte Ereignisse an:
metadata: { "openclaw": { "events": ["command:new"] } } # Specific
Stattdessen:
metadata: { "openclaw": { "events": ["command"] } } # General - more overhead
Debugging¶
Hook-Logging aktivieren¶
Das Gateway protokolliert das Laden von Hooks beim Start:
Registered hook: session-memory -> command:new
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¶
Protokollieren Sie in Ihrem Handler, wann er aufgerufen wird:
const handler: HookHandler = async (event) => {
console.log("[my-handler] Triggered:", event.type, event.action);
// Your logic
};
Eignung verifizieren¶
Prüfen Sie, warum ein Hook nicht geeignet ist:
openclaw hooks info my-hook
Achten Sie in der Ausgabe auf fehlende Anforderungen.
Testen¶
Gateway-Logs¶
Überwachen Sie die Gateway-Logs, um die Ausführung von Hooks zu sehen:
# macOS
./scripts/clawlog.sh -f
# Other platforms
tail -f ~/.openclaw/gateway.log
Hooks direkt testen¶
Testen Sie Ihre Handler isoliert:
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
});
Architektur¶
Kernkomponenten¶
src/hooks/types.ts: Typdefinitionensrc/hooks/workspace.ts: Verzeichnisscans und Ladensrc/hooks/frontmatter.ts: Parsing der HOOK.md-Metadatensrc/hooks/config.ts: Eignungsprüfungsrc/hooks/hooks-status.ts: Statusberichterstattungsrc/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 Befehlsereignisse aus
Erkennungsfluss¶
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 events
Ereignisfluss¶
User sends /new
↓
Command validation
↓
Create hook event
↓
Trigger hook (all registered handlers)
↓
Command processing continues
↓
Session reset
Fehlerbehebung¶
Hook nicht erkannt¶
- Verzeichnisstruktur prüfen:
bash
ls -la ~/.openclaw/hooks/my-hook/
# Should show: HOOK.md, handler.ts
- HOOK.md-Format verifizieren:
bash
cat ~/.openclaw/hooks/my-hook/HOOK.md
# Should have YAML frontmatter with name and metadata
- Alle erkannten Hooks auflisten:
bash
openclaw hooks list
Hook nicht geeignet¶
Anforderungen prüfen:
openclaw hooks info my-hook
Achten Sie auf fehlende:
- Binaries (PATH prüfen)
- Umgebungsvariablen
- Konfigurationswerte
- OS-Kompatibilität
Hook wird nicht ausgeführt¶
- Prüfen, ob der Hook aktiviert ist:
bash
openclaw hooks list
# Should show ✓ next to enabled hooks
-
Starten Sie Ihren Gateway-Prozess neu, damit Hooks neu geladen werden.
-
Prüfen Sie die Gateway-Logs auf Fehler:
bash
./scripts/clawlog.sh | grep hook
Handler-Fehler¶
Auf TypeScript-/Import-Fehler prüfen:
# Test import directly
node -e "import('./path/to/handler.ts').then(console.log)"
Migrationsleitfaden¶
Von Legacy-Konfiguration zu Erkennung¶
Vorher:
{
"hooks": {
"internal": {
"enabled": true,
"handlers": [
{
"event": "command:new",
"module": "./hooks/handlers/my-handler.ts"
}
]
}
}
}
Nachher:
- Hook-Verzeichnis erstellen:
bash
mkdir -p ~/.openclaw/hooks/my-hook
mv ./hooks/handlers/my-handler.ts ~/.openclaw/hooks/my-hook/handler.ts
- HOOK.md erstellen:
```markdown
name: my-hook description: "My custom hook" metadata: { "openclaw": { "emoji": "🎯", "events": ["command:new"] } }
# My Hook
Does something useful. ```
- Konfiguration aktualisieren:
json
{
"hooks": {
"internal": {
"enabled": true,
"entries": {
"my-hook": { "enabled": true }
}
}
}
}
- Verifizieren und Ihren Gateway-Prozess neu starten:
bash
openclaw hooks list
# Should show: 🎯 my-hook ✓
Vorteile der Migration:
- Automatische Erkennung
- CLI-Verwaltung
- Berechtigungsprüfung
- Bessere Dokumentation
- Konsistente Struktur