Хуки

Хуки предоставляют расширяемую систему на основе событий для автоматизации действий в ответ на команды и события агента. Хуки автоматически обнаруживаются из директорий и могут управляться через CLI-команды, аналогично тому, как работают навыки в OpenClaw.

Ориентирование

Хуки — это небольшие скрипты, которые запускаются при возникновении событий. Существует два вида:

  • Хуки (эта страница): запускаются внутри Gateway при срабатывании событий агента, таких как /new, /reset, /stop или событий жизненного цикла.
  • Вебхуки: внешние HTTP-вебхуки, которые позволяют другим системам запускать работу в OpenClaw. См. Webhook Hooks или используйте openclaw webhooks для вспомогательных команд Gmail.

Хуки также могут быть упакованы внутри плагинов; см. Плагины.

Распространённые применения:

  • Сохранение снимка памяти при сбросе сессии
  • Ведение журнала аудита команд для устранения неполадок или соблюдения требований
  • Запуск последующей автоматизации при старте или завершении сессии
  • Запись файлов в рабочее пространство агента или вызов внешних API при срабатывании событий

Если вы можете написать небольшую TypeScript-функцию, вы можете написать хук. Хуки обнаруживаются автоматически, и вы включаете или отключаете их через CLI.

Обзор

Система хуков позволяет:

  • Сохранять контекст сессии в память при выполнении /new
  • Регистрировать все команды для аудита
  • Запускать пользовательскую автоматизацию при событиях жизненного цикла агента
  • Расширять поведение OpenClaw без изменения основного кода

Начало работы

Встроенные хуки

OpenClaw поставляется с четырьмя встроенными хуками, которые автоматически обнаруживаются:

  • 💾 session-memory: Сохраняет контекст сессии в рабочее пространство агента (по умолчанию ~/.openclaw/workspace/memory/) при выполнении /new
  • 📝 command-logger: Регистрирует все события команд в ~/.openclaw/logs/commands.log
  • 🚀 boot-md: Запускает BOOT.md при старте шлюза (требуется включение внутренних хуков)
  • 😈 soul-evil: Заменяет внедрённое содержимое SOUL.md на SOUL_EVIL.md во время окна очистки или случайным образом

Список доступных хуков:

openclaw hooks list

Включить хук:

openclaw hooks enable session-memory

Проверить статус хука:

openclaw hooks check

Получить подробную информацию:

openclaw hooks info session-memory

Адаптация

Во время адаптации (openclaw onboard) вам будет предложено включить рекомендуемые хуки. Мастер автоматически обнаруживает подходящие хуки и представляет их для выбора.

Обнаружение хуков

Хуки автоматически обнаруживаются из трёх директорий (в порядке приоритета):

  1. Хуки рабочего пространства: <workspace>/hooks/ (для каждого агента, наивысший приоритет)
  2. Управляемые хуки: ~/.openclaw/hooks/ (устанавливаются пользователем, общие для всех рабочих пространств)
  3. Встроенные хуки: <openclaw>/dist/hooks/bundled/ (поставляются с OpenClaw)

Директории управляемых хуков могут быть либо одиночным хуком, либо пакетом хуков (каталогом пакета).

Каждый хук представляет собой директорию, содержащую:

my-hook/
├── HOOK.md          # Метаданные + документация
└── handler.ts       # Реализация обработчика

Пакеты хуков (npm/архивы)

Пакеты хуков — это стандартные npm-пакеты, которые экспортируют один или несколько хуков через openclaw.hooks в package.json. Устанавливайте их с помощью:

openclaw hooks install <path-or-spec>

Пример package.json:

{
  "name": "@acme/my-hooks",
  "version": "0.1.0",
  "openclaw": {
    "hooks": ["./hooks/my-hook", "./hooks/other-hook"]
  }
}

Каждая запись указывает на директорию хука, содержащую HOOK.md и handler.ts (или index.ts). Пакеты хуков могут поставляться с зависимостями; они будут установлены в ~/.openclaw/hooks/<id>.

Структура хука

Формат HOOK.md

Файл HOOK.md содержит метаданные в YAML frontmatter плюс Markdown-документацию:

---
name: my-hook
description: "Краткое описание того, что делает этот хук"
homepage: https://docs.openclaw.ai/hooks#my-hook
metadata: {"openclaw":{"emoji":"🔗","events":["command:new"],"requires":{"bins":["node"]}}}
---

# My Hook

Подробная документация размещается здесь...

## Что он делает

- Слушает команды `/new`
- Выполняет некоторое действие
- Регистрирует результат

## Требования

- Должен быть установлен Node.js

## Конфигурация

Конфигурация не требуется.

Поля метаданных

Объект metadata.openclaw поддерживает:

  • emoji: Отображаемый эмодзи для CLI (например, "💾")
  • events: Массив событий для прослушивания (например, ["command:new", "command:reset"])
  • export: Именованный экспорт для использования (по умолчанию "default")
  • homepage: URL документации
  • requires: Опциональные требования
    • bins: Требуемые бинарные файлы в PATH (например, ["git", "node"])
    • anyBins: Хотя бы один из этих бинарных файлов должен присутствовать
    • env: Требуемые переменные окружения
    • config: Требуемые пути конфигурации (например, ["workspace.dir"])
    • os: Требуемые платформы (например, ["darwin", "linux"])
  • always: Обход проверок соответствия (логическое значение)
  • install: Методы установки (для встроенных хуков: [{"id":"bundled","kind":"bundled"}])

Реализация обработчика

Файл handler.ts экспортирует функцию HookHandler:

import type { HookHandler } from '../../src/hooks/hooks.js';

const myHandler: HookHandler = async (event) => {
  // Срабатывать только при команде 'new'
  if (event.type !== 'command' || event.action !== 'new') {
    return;
  }

  console.log(`[my-hook] Запущена команда New`);
  console.log(`  Сессия: ${event.sessionKey}`);
  console.log(`  Временная метка: ${event.timestamp.toISOString()}`);

  // Ваша пользовательская логика здесь

  // Опционально отправить сообщение пользователю
  event.messages.push('✨ Мой хук выполнен!');
};

export default myHandler;

Контекст события

Каждое событие включает:

{
  type: 'command' | 'session' | 'agent' | 'gateway',
  action: string,              // например, 'new', 'reset', 'stop'
  sessionKey: string,          // Идентификатор сессии
  timestamp: Date,             // Когда произошло событие
  messages: string[],          // Помещайте сюда сообщения для отправки пользователю
  context: {
    sessionEntry?: SessionEntry,
    sessionId?: string,
    sessionFile?: string,
    commandSource?: string,    // например, 'whatsapp', 'telegram'
    senderId?: string,
    workspaceDir?: string,
    bootstrapFiles?: WorkspaceBootstrapFile[],
    cfg?: OpenClawConfig
  }
}

Типы событий

События команд

Срабатывают при выполнении команд агента:

  • command: Все события команд (общий слушатель)
  • command:new: При выполнении команды /new
  • command:reset: При выполнении команды /reset
  • command:stop: При выполнении команды /stop

События агента

  • agent:bootstrap: Перед внедрением файлов начальной загрузки рабочего пространства (хуки могут изменять context.bootstrapFiles)

События шлюза

Срабатывают при старте шлюза:

  • gateway:startup: После запуска каналов и загрузки хуков

Хуки результатов инструментов (API плагинов)

Эти хуки не являются слушателями потока событий; они позволяют плагинам синхронно корректировать результаты инструментов до того, как OpenClaw их сохранит.

  • tool_result_persist: преобразование результатов инструментов перед их записью в транскрипт сессии. Должен быть синхронным; возвращайте обновлённую полезную нагрузку результата инструмента или undefined, чтобы оставить её как есть. См. Цикл агента.

Будущие события

Планируемые типы событий:

  • session:start: Когда начинается новая сессия
  • session:end: Когда сессия завершается
  • agent:error: Когда агент сталкивается с ошибкой
  • message:sent: Когда отправляется сообщение
  • message:received: Когда получено сообщение

Создание пользовательских хуков

1. Выберите расположение

  • Хуки рабочего пространства (<workspace>/hooks/): Для каждого агента, наивысший приоритет
  • Управляемые хуки (~/.openclaw/hooks/): Общие для всех рабочих пространств

2. Создайте структуру директорий

mkdir -p ~/.openclaw/hooks/my-hook
cd ~/.openclaw/hooks/my-hook

3. Создайте HOOK.md

---
name: my-hook
description: "Делает что-то полезное"
metadata: {"openclaw":{"emoji":"🎯","events":["command:new"]}}
---

# My Custom Hook

Этот хук делает что-то полезное, когда вы выполняете `/new`.

4. Создайте 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] Выполняется!');
  // Ваша логика здесь
};

export default handler;

5. Включите и протестируйте

# Проверьте, что хук обнаружен
openclaw hooks list

# Включите его
openclaw hooks enable my-hook

# Перезапустите процесс шлюза (перезапуск приложения строки меню на macOS или перезапуск процесса разработки)

# Вызовите событие
# Отправьте /new через ваш канал обмена сообщениями

Конфигурация

Новый формат конфигурации (рекомендуется)

{
  "hooks": {
    "internal": {
      "enabled": true,
      "entries": {
        "session-memory": { "enabled": true },
        "command-logger": { "enabled": false }
      }
    }
  }
}

Конфигурация для каждого хука

Хуки могут иметь пользовательскую конфигурацию:

{
  "hooks": {
    "internal": {
      "enabled": true,
      "entries": {
        "my-hook": {
          "enabled": true,
          "env": {
            "MY_CUSTOM_VAR": "value"
          }
        }
      }
    }
  }
}

Дополнительные директории

Загружайте хуки из дополнительных директорий:

{
  "hooks": {
    "internal": {
      "enabled": true,
      "load": {
        "extraDirs": ["/path/to/more/hooks"]
      }
    }
  }
}

Устаревший формат конфигурации (всё ещё поддерживается)

Старый формат конфигурации всё ещё работает для обратной совместимости:

{
  "hooks": {
    "internal": {
      "enabled": true,
      "handlers": [
        {
          "event": "command:new",
          "module": "./hooks/handlers/my-handler.ts",
          "export": "default"
        }
      ]
    }
  }
}

Миграция: Используйте новую систему на основе обнаружения для новых хуков. Устаревшие обработчики загружаются после хуков на основе директорий.

CLI-команды

Список хуков

# Список всех хуков
openclaw hooks list

# Показать только подходящие хуки
openclaw hooks list --eligible

# Подробный вывод (показать отсутствующие требования)
openclaw hooks list --verbose

# Вывод в JSON
openclaw hooks list --json

Информация о хуке

# Показать подробную информацию о хуке
openclaw hooks info session-memory

# Вывод в JSON
openclaw hooks info session-memory --json

Проверка соответствия

# Показать сводку соответствия
openclaw hooks check

# Вывод в JSON
openclaw hooks check --json

Включение/отключение

# Включить хук
openclaw hooks enable session-memory

# Отключить хук
openclaw hooks disable command-logger

Встроенные хуки

session-memory

Сохраняет контекст сессии в память при выполнении /new.

События: command:new

Требования: Должен быть настроен workspace.dir

Вывод: <workspace>/memory/YYYY-MM-DD-slug.md (по умолчанию ~/.openclaw/workspace)

Что делает:

  1. Использует запись сессии перед сбросом для определения правильного транскрипта
  2. Извлекает последние 15 строк разговора
  3. Использует LLM для генерации описательного слага имени файла
  4. Сохраняет метаданные сессии в датированный файл памяти

Пример вывода:

# Session: 2026-01-16 14:30:00 UTC

- **Session Key**: agent:main:main
- **Session ID**: abc123def456
- **Source**: telegram

Примеры имён файлов:

  • 2026-01-16-vendor-pitch.md
  • 2026-01-16-api-design.md
  • 2026-01-16-1430.md (резервная временная метка, если генерация слага не удалась)

Включить:

openclaw hooks enable session-memory

command-logger

Регистрирует все события команд в централизованный файл аудита.

События: command

Требования: Нет

Вывод: ~/.openclaw/logs/commands.log

Что делает:

  1. Захватывает детали события (действие команды, временная метка, ключ сессии, ID отправителя, источник)
  2. Добавляет в файл журнала в формате JSONL
  3. Работает тихо в фоновом режиме

Примеры записей журнала:

{"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"}

Просмотр журналов:

# Просмотр последних команд
tail -n 20 ~/.openclaw/logs/commands.log

# Красивый вывод с jq
cat ~/.openclaw/logs/commands.log | jq .

# Фильтр по действию
grep '"action":"new"' ~/.openclaw/logs/commands.log | jq .

Включить:

openclaw hooks enable command-logger

soul-evil

Заменяет внедрённое содержимое SOUL.md на SOUL_EVIL.md во время окна очистки или случайным образом.

События: agent:bootstrap

Документация: SOUL Evil Hook

Вывод: Файлы не записываются; замены происходят только в памяти.

Включить:

openclaw hooks enable soul-evil

Конфигурация:

{
  "hooks": {
    "internal": {
      "enabled": true,
      "entries": {
        "soul-evil": {
          "enabled": true,
          "file": "SOUL_EVIL.md",
          "chance": 0.1,
          "purge": { "at": "21:00", "duration": "15m" }
        }
      }
    }
  }
}

boot-md

Запускает BOOT.md при старте шлюза (после запуска каналов). Для работы должны быть включены внутренние хуки.

События: gateway:startup

Требования: Должен быть настроен workspace.dir

Что делает:

  1. Читает BOOT.md из вашего рабочего пространства
  2. Запускает инструкции через исполнитель агента
  3. Отправляет любые запрошенные исходящие сообщения через инструмент сообщений

Включить:

openclaw hooks enable boot-md

Лучшие практики

Делайте обработчики быстрыми

Хуки запускаются во время обработки команд. Делайте их лёгкими:

// ✓ Хорошо - асинхронная работа, возвращается немедленно
const handler: HookHandler = async (event) => {
  void processInBackground(event); // Запустить и забыть
};

// ✗ Плохо - блокирует обработку команд
const handler: HookHandler = async (event) => {
  await slowDatabaseQuery(event);
  await evenSlowerAPICall(event);
};

Обрабатывайте ошибки корректно

Всегда оборачивайте рискованные операции:

const handler: HookHandler = async (event) => {
  try {
    await riskyOperation(event);
  } catch (err) {
    console.error('[my-handler] Ошибка:', err instanceof Error ? err.message : String(err));
    // Не выбрасывайте исключение - позвольте другим обработчикам запуститься
  }
};

Фильтруйте события рано

Возвращайтесь рано, если событие не относится к делу:

const handler: HookHandler = async (event) => {
  // Обрабатывать только команды 'new'
  if (event.type !== 'command' || event.action !== 'new') {
    return;
  }

  // Ваша логика здесь
};

Используйте конкретные ключи событий

По возможности указывайте точные события в метаданных:

metadata: {"openclaw":{"events":["command:new"]}}  # Конкретно

Вместо:

metadata: {"openclaw":{"events":["command"]}}      # Общее - больше накладных расходов

Отладка

Включение логирования хуков

Шлюз регистрирует загрузку хуков при запуске:

Registered hook: session-memory -> command:new
Registered hook: command-logger -> command
Registered hook: boot-md -> gateway:startup

Проверка обнаружения

Список всех обнаруженных хуков:

openclaw hooks list --verbose

Проверка регистрации

В вашем обработчике логируйте, когда он вызывается:

const handler: HookHandler = async (event) => {
  console.log('[my-handler] Запущен:', event.type, event.action);
  // Ваша логика
};

Проверка соответствия

Проверьте, почему хук не подходит:

openclaw hooks info my-hook

Ищите отсутствующие требования в выводе.

Тестирование

Журналы шлюза

Отслеживайте журналы шлюза для просмотра выполнения хуков:

# macOS
./scripts/clawlog.sh -f

# Другие платформы
tail -f ~/.openclaw/gateway.log

Прямое тестирование хуков

Тестируйте обработчики изолированно:

import { test } from 'vitest';
import { createHookEvent } from './src/hooks/hooks.js';
import myHandler from './hooks/my-hook/handler.js';

test('мой обработчик работает', async () => {
  const event = createHookEvent('command', 'new', 'test-session', {
    foo: 'bar'
  });

  await myHandler(event);

  // Проверить побочные эффекты
});

Архитектура

Основные компоненты

  • src/hooks/types.ts: Определения типов
  • src/hooks/workspace.ts: Сканирование и загрузка директорий
  • src/hooks/frontmatter.ts: Парсинг метаданных HOOK.md
  • src/hooks/config.ts: Проверка соответствия
  • src/hooks/hooks-status.ts: Отчётность о статусе
  • src/hooks/loader.ts: Динамический загрузчик модулей
  • src/cli/hooks-cli.ts: CLI-команды
  • src/gateway/server-startup.ts: Загружает хуки при старте шлюза
  • src/auto-reply/reply/commands-core.ts: Запускает события команд

Поток обнаружения

Запуск шлюза
    ↓
Сканирование директорий (workspace → managed → bundled)
    ↓
Парсинг файлов HOOK.md
    ↓
Проверка соответствия (bins, env, config, os)
    ↓
Загрузка обработчиков из подходящих хуков
    ↓
Регистрация обработчиков для событий

Поток событий

Пользователь отправляет /new
    ↓
Валидация команды
    ↓
Создание события хука
    ↓
Запуск хука (все зарегистрированные обработчики)
    ↓
Обработка команды продолжается
    ↓
Сброс сессии

Устранение неполадок

Хук не обнаружен

  1. Проверьте структуру директорий:

    ls -la ~/.openclaw/hooks/my-hook/
    # Должно показать: HOOK.md, handler.ts
    
  2. Проверьте формат HOOK.md:

    cat ~/.openclaw/hooks/my-hook/HOOK.md
    # Должен иметь YAML frontmatter с именем и метаданными
    
  3. Список всех обнаруженных хуков:

    openclaw hooks list
    

Хук не подходит

Проверьте требования:

openclaw hooks info my-hook

Ищите отсутствующие:

  • Бинарные файлы (проверьте PATH)
  • Переменные окружения
  • Значения конфигурации
  • Совместимость с ОС

Хук не выполняется

  1. Проверьте, что хук включён:

    openclaw hooks list
    # Должен показывать ✓ рядом с включёнными хуками
    
  2. Перезапустите процесс шлюза, чтобы хуки перезагрузились.

  3. Проверьте журналы шлюза на наличие ошибок:

    ./scripts/clawlog.sh | grep hook
    

Ошибки обработчика

Проверьте наличие ошибок TypeScript/импорта:

# Протестируйте импорт напрямую
node -e "import('./path/to/handler.ts').then(console.log)"

Руководство по миграции

От устаревшей конфигурации к обнаружению

До:

{
  "hooks": {
    "internal": {
      "enabled": true,
      "handlers": [
        {
          "event": "command:new",
          "module": "./hooks/handlers/my-handler.ts"
        }
      ]
    }
  }
}

После:

  1. Создайте директорию хука:

    mkdir -p ~/.openclaw/hooks/my-hook
    mv ./hooks/handlers/my-handler.ts ~/.openclaw/hooks/my-hook/handler.ts
    
  2. Создайте HOOK.md:

    ---
    name: my-hook
    description: "Мой пользовательский хук"
    metadata: {"openclaw":{"emoji":"🎯","events":["command:new"]}}
    ---
    
    # My Hook
    
    Делает что-то полезное.
    
  3. Обновите конфигурацию:

    {
      "hooks": {
        "internal": {
          "enabled": true,
          "entries": {
            "my-hook": { "enabled": true }
          }
        }
      }
    }
    
  4. Проверьте и перезапустите процесс шлюза:

    openclaw hooks list
    # Должен показать: 🎯 my-hook ✓
    

Преимущества миграции:

  • Автоматическое обнаружение
  • Управление через CLI
  • Проверка соответствия
  • Лучшая документация
  • Согласованная структура

См. также