Hooks
Los Hooks proporcionan un sistema extensible basado en eventos para automatizar acciones en respuesta a comandos y eventos del agente. Los Hooks se descubren automáticamente desde los directorios y se pueden gestionar mediante comandos de CLI, de manera similar a como funcionan las habilidades en OpenClaw.
Orientación
Sección titulada «Orientación»Los Hooks son pequeños scripts que se ejecutan cuando sucede algo. Hay dos tipos:
- Hooks (esta página): se ejecutan dentro de la Gateway cuando se activan eventos del agente, como
/new,/reset,/stopo eventos del ciclo de vida. - Webhooks: webhooks HTTP externos que permiten a otros sistemas activar trabajo en OpenClaw. Consulte Webhook Hooks o use
openclaw webhookspara comandos auxiliares de Gmail.
Los Hooks también se pueden incluir en paquetes (plugins); consulte Plugins.
Usos comunes:
- Guardar una instantánea de la memoria cuando restablezca una sesión
- Mantener un registro de auditoría de los comandos para solucionar problemas o cumplimiento
- Activar una automatización de seguimiento cuando una sesión inicia o termina
- Escribir archivos en el espacio de trabajo del agente o llamar a API externas cuando se activan eventos
Si puede escribir una pequeña función de TypeScript, puede escribir un hook. Los Hooks se descubren automáticamente y se habilitan o deshabilitan a través de la CLI.
Descripción general
Sección titulada «Descripción general»El sistema de Hooks le permite:
- Guardar el contexto de la sesión en la memoria cuando se emite
/new - Registrar todos los comandos para auditoría
- Activar automatizaciones personalizadas en eventos del ciclo de vida del agente
- Extender el comportamiento de OpenClaw sin modificar el código central
Primeros pasos
Sección titulada «Primeros pasos»Hooks incluidos
Sección titulada «Hooks incluidos»OpenClaw incluye cuatro hooks que se descubren automáticamente:
- 💾 session-memory: Guarda el contexto de la sesión en su espacio de trabajo del agente (por defecto
~/.openclaw/workspace/memory/) cuando emite/new - 📝 command-logger: Registra todos los eventos de comandos en
~/.openclaw/logs/commands.log - 🚀 boot-md: Ejecuta
BOOT.mdcuando se inicia la puerta de enlace (requiere que los hooks internos estén habilitados) - 😈 soul-evil: Intercambia el contenido inyectado de
SOUL.mdconSOUL_EVIL.mddurante una ventana de purga o por casualidad aleatoria
Listar los hooks disponibles:
openclaw hooks listActivar un hook:
openclaw hooks enable session-memoryVerificar el estado del hook:
openclaw hooks checkObtener información detallada:
openclaw hooks info session-memoryIncorporación
Sección titulada «Incorporación»Durante la incorporación (openclaw onboard), se le solicitará que active los hooks recomendados. El asistente descubre automáticamente los hooks elegibles y los presenta para su selección.
Descubrimiento de Hooks
Sección titulada «Descubrimiento de Hooks»Los hooks se descubren automáticamente desde tres directorios (en orden de prioridad):
- Hooks del espacio de trabajo:
<workspace>/hooks/(por agente, mayor prioridad) - Hooks gestionados:
~/.openclaw/hooks/(instalados por el usuario, compartidos entre espacios de trabajo) - Hooks incluidos:
<openclaw>/dist/hooks/bundled/(enviados con OpenClaw)
Los directorios de hooks gestionados pueden ser un único hook o un paquete de hooks (directorio de paquete).
Cada hook es un directorio que contiene:
my-hook/├── HOOK.md # Metadata + documentation└── handler.ts # Handler implementationPaquetes de Hooks (npm/archivos)
Sección titulada «Paquetes de Hooks (npm/archivos)»Los paquetes de hooks son paquetes estándar de npm que exportan uno o más hooks a través de openclaw.hooks en
package.json. Instálelos con:
openclaw hooks install <path-or-spec>Ejemplo de package.json:
{ "name": "@acme/my-hooks", "version": "0.1.0", "openclaw": { "hooks": ["./hooks/my-hook", "./hooks/other-hook"] }}Cada entrada apunta a un directorio de hooks que contiene HOOK.md y handler.ts (o index.ts).
Los paquetes de hooks pueden enviar dependencias; se instalarán en ~/.openclaw/hooks/<id>.
Estructura del Hook
Sección titulada «Estructura del Hook»Formato HOOK.md
Sección titulada «Formato HOOK.md»El archivo HOOK.md contiene metadatos en el frontmatter YAML más documentación de 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.Campos de Metadatos
Sección titulada «Campos de Metadatos»El objeto metadata.openclaw admite:
emoji: Emoji de visualización para la CLI (por ejemplo,"💾")events: Matriz de eventos a los que escuchar (por ejemplo,["command:new", "command:reset"])export: Exportación con nombre a utilizar (por defecto es"default")homepage: URL de documentaciónrequires: Requisitos opcionalesbins: Binarios requeridos en PATH (por ejemplo,["git", "node"])anyBins: Al menos uno de estos binarios debe estar presenteenv: Variables de entorno requeridasconfig: Rutas de configuración requeridas (ej.,["workspace.dir"])os: Plataformas requeridas (ej.,["darwin", "linux"])
always: Omitir comprobaciones de elegibilidad (booleano)install: Métodos de instalación (para hooks incluidos:[{"id":"bundled","kind":"bundled"}])
Implementación del controlador
Sección titulada «Implementación del controlador»El archivo handler.ts exporta una función 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;Contexto del evento
Sección titulada «Contexto del evento»Cada evento incluye:
{ 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 }}Tipos de eventos
Sección titulada «Tipos de eventos»Eventos de comandos
Sección titulada «Eventos de comandos»Activados cuando se emiten comandos del agente:
command: Todos los eventos de comandos (oyente general)command:new: Cuando se emite el comando/newcommand:reset: Cuando se emite el comando/resetcommand:stop: Cuando se emite el comando/stop
Eventos del agente
Sección titulada «Eventos del agente»agent:bootstrap: Antes de que se inyecten los archivos de arranque del espacio de trabajo (los hooks pueden mutarcontext.bootstrapFiles)
Eventos de la pasarela
Sección titulada «Eventos de la pasarela»Activados cuando se inicia la pasarela:
gateway:startup: Después de que los canales se inician y se cargan los hooks
Hooks de resultados de herramientas (API de complementos)
Sección titulada «Hooks de resultados de herramientas (API de complementos)»Estos hooks no son oyentes de flujo de eventos; permiten que los complementos ajusten sincrónicamente los resultados de las herramientas antes de que OpenClaw los guarde.
tool_result_persist: transforma los resultados de las herramientas antes de que se escriban en la transcripción de la sesión. Debe ser síncrono; devuelve la carga útil del resultado de la herramienta actualizada oundefinedpara mantenerla tal cual. Consulte Bucle del agente.
Eventos futuros
Sección titulada «Eventos futuros»Tipos de eventos planificados:
session:start: Cuando comienza una nueva sesiónsession:end: Cuando termina una sesiónagent:error: Cuando un agente encuentra un errormessage:sent: Cuando se envía un mensajemessage:received: Cuando se recibe un mensaje
Creación de Hooks Personalizados
Sección titulada «Creación de Hooks Personalizados»1. Elegir Ubicación
Sección titulada «1. Elegir Ubicación»- Hooks del espacio de trabajo (
<workspace>/hooks/): Por agente, mayor prioridad - Hooks administrados (
~/.openclaw/hooks/): Compartidos entre espacios de trabajo
2. Crear Estructura de Directorios
Sección titulada «2. Crear Estructura de Directorios»mkdir -p ~/.openclaw/hooks/my-hookcd ~/.openclaw/hooks/my-hook3. Crear HOOK.md
Sección titulada «3. Crear 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. Crear handler.ts
Sección titulada «4. Crear 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. Habilitar y Probar
Sección titulada «5. Habilitar y Probar»# 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 channelConfiguración
Sección titulada «Configuración»Nuevo Formato de Configuración (Recomendado)
Sección titulada «Nuevo Formato de Configuración (Recomendado)»{ "hooks": { "internal": { "enabled": true, "entries": { "session-memory": { "enabled": true }, "command-logger": { "enabled": false } } } }}Configuración por Hook
Sección titulada «Configuración por Hook»Los hooks pueden tener configuración personalizada:
{ "hooks": { "internal": { "enabled": true, "entries": { "my-hook": { "enabled": true, "env": { "MY_CUSTOM_VAR": "value" } } } } }}Directorios Adicionales
Sección titulada «Directorios Adicionales»Cargar hooks desde directorios adicionales:
{ "hooks": { "internal": { "enabled": true, "load": { "extraDirs": ["/path/to/more/hooks"] } } }}Formato de Configuración Heredado (Todavía Soportado)
Sección titulada «Formato de Configuración Heredado (Todavía Soportado)»El formato de configuración antiguo todavía funciona por compatibilidad hacia atrás:
{ "hooks": { "internal": { "enabled": true, "handlers": [ { "event": "command:new", "module": "./hooks/handlers/my-handler.ts", "export": "default" } ] } }}Migración: Utilice el nuevo sistema basado en descubrimiento para los nuevos hooks. Los controladores heredados se cargan después de los hooks basados en directorios.
Comandos de CLI
Sección titulada «Comandos de CLI»Listar Hooks
Sección titulada «Listar 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 --jsonInformación del Hook
Sección titulada «Información del Hook»# Show detailed info about a hookopenclaw hooks info session-memory
# JSON outputopenclaw hooks info session-memory --jsonVerificar Elegibilidad
Sección titulada «Verificar Elegibilidad»# Show eligibility summaryopenclaw hooks check
# JSON outputopenclaw hooks check --jsonHabilitar/Deshabilitar
Sección titulada «Habilitar/Deshabilitar»# Enable a hookopenclaw hooks enable session-memory
# Disable a hookopenclaw hooks disable command-loggerHooks Incluidos
Sección titulada «Hooks Incluidos»session-memory
Sección titulada «session-memory»Guarda el contexto de la sesión en la memoria cuando emites /new.
Eventos: command:new
Requisitos: workspace.dir debe estar configurado
Salida: <workspace>/memory/YYYY-MM-DD-slug.md (por defecto es ~/.openclaw/workspace)
Lo que hace:
- Utiliza la entrada de sesión previa al restablecimiento para ubicar la transcripción correcta
- Extrae las últimas 15 líneas de la conversación
- Utiliza LLM para generar un nombre de archivo descriptivo (slug)
- Guarda los metadatos de la sesión en un archivo de memoria con fecha
Ejemplo de salida:
# Session: 2026-01-16 14:30:00 UTC
- **Session Key**: agent:main:main- **Session ID**: abc123def456- **Source**: telegramEjemplos de nombres de archivo:
2026-01-16-vendor-pitch.md2026-01-16-api-design.md2026-01-16-1430.md(marca de tiempo de respaldo si falla la generación del slug)
Habilitar:
openclaw hooks enable session-memorycommand-logger
Sección titulada «command-logger»Registra todos los eventos de comandos en un archivo de auditoría centralizado.
Eventos: command
Requisitos: Ninguno
Salida: ~/.openclaw/logs/commands.log
Lo que hace:
- Captura detalles del evento (acción de comando, marca de tiempo, clave de sesión, ID del remitente, origen)
- Agrega al archivo de registro en formato JSONL
- Se ejecuta silenciosamente en segundo plano
Ejemplos de entradas de registro:
{"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"}Ver registros:
# 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 .Habilitar:
openclaw hooks enable command-loggersoul-evil
Sección titulada «soul-evil»Intercambia el contenido inyectado de SOUL.md con SOUL_EVIL.md durante una ventana de purga o por azar.
Eventos: agent:bootstrap
Documentación: SOUL Evil Hook
Salida: No se escriben archivos; los intercambios ocurren solo en memoria.
Activar:
openclaw hooks enable soul-evilConfiguración:
{ "hooks": { "internal": { "enabled": true, "entries": { "soul-evil": { "enabled": true, "file": "SOUL_EVIL.md", "chance": 0.1, "purge": { "at": "21:00", "duration": "15m" } } } } }}boot-md
Sección titulada «boot-md»Ejecuta BOOT.md cuando se inicia la puerta de enlace (después de que inicien los canales).
Los hooks internos deben estar habilitados para que esto se ejecute.
Eventos: gateway:startup
Requisitos: workspace.dir debe estar configurado
Lo que hace:
- Lee
BOOT.mdde su espacio de trabajo - Ejecuta las instrucciones a través del agente de ejecución (agent runner)
- Envía cualquier mensaje saliente solicitado a través de la herramienta de mensajes
Activar:
openclaw hooks enable boot-mdMejores Prácticas
Sección titulada «Mejores Prácticas»Mantenga los Manejadores Rápidos
Sección titulada «Mantenga los Manejadores Rápidos»Los hooks se ejecutan durante el procesamiento de comandos. Manténgalos ligeros:
// ✓ 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);};Maneje los Errores con Gracia
Sección titulada «Maneje los Errores con Gracia»Siempre envuelva las operaciones riesgosas:
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 }};Filtre Eventos Temprano
Sección titulada «Filtre Eventos Temprano»Regrese temprano si el evento no es relevante:
const handler: HookHandler = async (event) => { // Only handle 'new' commands if (event.type !== "command" || event.action !== "new") { return; }
// Your logic here};Use Claves de Evento Específicas
Sección titulada «Use Claves de Evento Específicas»Especifique eventos exactos en los metadatos cuando sea posible:
metadata: { "openclaw": { "events": ["command:new"] } } # SpecificEn lugar de:
metadata: { "openclaw": { "events": ["command"] } } # General - more overheadDepuración
Sección titulada «Depuración»Activar el Registro de Hooks
Sección titulada «Activar el Registro de Hooks»La puerta de enlace registra la carga de hooks al inicio:
Registered hook: session-memory -> command:newRegistered hook: command-logger -> commandRegistered hook: boot-md -> gateway:startupVerificar el Descubrimiento
Sección titulada «Verificar el Descubrimiento»Listar todos los hooks descubiertos:
openclaw hooks list --verboseVerificar el Registro
Sección titulada «Verificar el Registro»En su manejador, registre cuándo se llama:
const handler: HookHandler = async (event) => { console.log("[my-handler] Triggered:", event.type, event.action); // Your logic};Verificar la Elegibilidad
Sección titulada «Verificar la Elegibilidad»Verifique por qué un hook no es elegible:
openclaw hooks info my-hookBusque requisitos faltantes en la salida.
Pruebas
Sección titulada «Pruebas»Registros de la Puerta de Enlace
Sección titulada «Registros de la Puerta de Enlace»Monitoree los registros de la puerta de enlace para ver la ejecución del hook:
# macOS./scripts/clawlog.sh -f
# Other platformstail -f ~/.openclaw/gateway.logProbar Hooks Directamente
Sección titulada «Probar Hooks Directamente»Pruebe sus manejadores de forma aislada:
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});Arquitectura
Sección titulada «Arquitectura»Componentes Principales
Sección titulada «Componentes Principales»src/hooks/types.ts: Definiciones de tipossrc/hooks/workspace.ts: Escaneo y carga de directoriossrc/hooks/frontmatter.ts: Análisis de metadatos de HOOK.mdsrc/hooks/config.ts: Verificación de elegibilidadsrc/hooks/hooks-status.ts: Reporte de estadosrc/hooks/loader.ts: Cargador de módulos dinámicossrc/cli/hooks-cli.ts: Comandos de CLIsrc/gateway/server-startup.ts: Carga los hooks al inicio de la puerta de enlacesrc/auto-reply/reply/commands-core.ts: Activa eventos de comandos
Flujo de Descubrimiento
Sección titulada «Flujo de Descubrimiento»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 eventsFlujo de Eventos
Sección titulada «Flujo de Eventos»User sends /new ↓Command validation ↓Create hook event ↓Trigger hook (all registered handlers) ↓Command processing continues ↓Session resetSolución de Problemas
Sección titulada «Solución de Problemas»Hook No Descubierto
Sección titulada «Hook No Descubierto»-
Verifique la estructura del directorio:
Ventana de terminal ls -la ~/.openclaw/hooks/my-hook/# Should show: HOOK.md, handler.ts -
Verifique el formato de HOOK.md:
Ventana de terminal cat ~/.openclaw/hooks/my-hook/HOOK.md# Should have YAML frontmatter with name and metadata -
Listar todos los hooks descubiertos:
Ventana de terminal openclaw hooks list
Hook No Elegible
Sección titulada «Hook No Elegible»Verifique los requisitos:
openclaw hooks info my-hookBusque elementos faltantes:
- Binarios (verificar PATH)
- Variables de entorno
- Valores de configuración
- Compatibilidad con el sistema operativo
Hook No Se Ejecuta
Sección titulada «Hook No Se Ejecuta»-
Verifique que el enlace esté habilitado:
Ventana de terminal openclaw hooks list# Should show ✓ next to enabled hooks -
Reinicie su proceso de puerta de enlace para que los enlaces se recarguen.
-
Revise los registros de la puerta de enlace en busca de errores:
Ventana de terminal ./scripts/clawlog.sh | grep hook
Errores del controlador
Sección titulada «Errores del controlador»Busque errores de TypeScript/importación:
# Test import directlynode -e "import('./path/to/handler.ts').then(console.log)"Guía de migración
Sección titulada «Guía de migración»Desde la configuración heredada hasta el descubrimiento
Sección titulada «Desde la configuración heredada hasta el descubrimiento»Antes:
{ "hooks": { "internal": { "enabled": true, "handlers": [ { "event": "command:new", "module": "./hooks/handlers/my-handler.ts" } ] } }}Después:
-
Crear directorio de enlace:
Ventana de terminal mkdir -p ~/.openclaw/hooks/my-hookmv ./hooks/handlers/my-handler.ts ~/.openclaw/hooks/my-hook/handler.ts -
Crear HOOK.md:
---name: my-hookdescription: "My custom hook"metadata: { "openclaw": { "emoji": "🎯", "events": ["command:new"] } }---# My HookDoes something useful. -
Actualizar configuración:
{"hooks": {"internal": {"enabled": true,"entries": {"my-hook": { "enabled": true }}}}} -
Verifique y reinicie su proceso de puerta de enlace:
Ventana de terminal openclaw hooks list# Should show: 🎯 my-hook ✓
Beneficios de la migración:
- Descubrimiento automático
- Gestión por CLI
- Verificación de elegibilidad
- Mejor documentación
- Estructura consistente