Hooks¶
توفر Hooks نظامًا قابلاً للتوسعة قائمًا على الأحداث لأتمتة الإجراءات استجابةً لأوامر الوكيل والأحداث. يتم اكتشاف Hooks تلقائيًا من الأدلة، ويمكن إدارتها عبر أوامر CLI، على نحو مشابه لكيفية عمل Skills في OpenClaw.
التعرّف على الأساسيات¶
تُعد Hooks سكربتات صغيرة تعمل عند حدوث شيء ما. وهناك نوعان:
- Hooks (هذه الصفحة): تعمل داخل Gateway عند إطلاق أحداث الوكيل، مثل
/newو/resetو/stop، أو أحداث دورة الحياة. - Webhooks: Webhooks خارجية عبر HTTP تتيح لأنظمة أخرى تشغيل مهام داخل OpenClaw. راجع Webhook Hooks أو استخدم
openclaw webhooksلأوامر مساعد Gmail.
يمكن أيضًا تضمين Hooks داخل الإضافات؛ راجع Plugins.
الاستخدامات الشائعة:
- حفظ لقطة ذاكرة عند إعادة تعيين جلسة
- الاحتفاظ بسجل تدقيق للأوامر لأغراض استكشاف الأخطاء وإصلاحها أو الامتثال
- تشغيل أتمتة لاحقة عند بدء الجلسة أو انتهائها
- كتابة ملفات داخل مساحة عمل الوكيل أو استدعاء واجهات برمجة تطبيقات خارجية عند إطلاق الأحداث
إذا كنت تستطيع كتابة دالة TypeScript صغيرة، فيمكنك كتابة Hook. يتم اكتشاف Hooks تلقائيًا، ويمكنك تمكينها أو تعطيلها عبر CLI.
نظرة عامة¶
يتيح لك نظام Hooks ما يلي:
- حفظ سياق الجلسة في الذاكرة عند إصدار
/new - تسجيل جميع الأوامر لأغراض التدقيق
- تشغيل أتمتة مخصصة عند أحداث دورة حياة الوكيل
- توسيع سلوك OpenClaw دون تعديل الشيفرة الأساسية
البدء¶
الخطافات المضمنة¶
يأتي OpenClaw مع أربع Hooks مضمّنة يتم اكتشافها تلقائيًا:
- 💾 session-memory: يحفظ سياق الجلسة في مساحة عمل الوكيل (الافتراضي
~/.openclaw/workspace/memory/) عند إصدار/new - 📝 command-logger: يسجل جميع أحداث الأوامر إلى
~/.openclaw/logs/commands.log - 🚀 boot-md: يشغّل
BOOT.mdعند بدء Gateway (يتطلب تمكين Hooks الداخلية) - 😈 soul-evil: يستبدل محتوى
SOUL.mdالمُحقن بـSOUL_EVIL.mdخلال نافذة تطهير أو باحتمال عشوائي
عرض Hooks المتاحة:
openclaw hooks list
تمكين Hook:
openclaw hooks enable session-memory
التحقق من حالة Hook:
openclaw hooks check
الحصول على معلومات تفصيلية:
openclaw hooks info session-memory
الإعداد الأولي¶
أثناء التهيئة الأولية (openclaw onboard)، سيُطلب منك تمكين Hooks الموصى بها. يقوم معالج الإعداد باكتشاف Hooks المؤهلة تلقائيًا وعرضها للاختيار.
اكتشاف الخطافات¶
يتم اكتشاف Hooks تلقائيًا من ثلاثة أدلة (حسب أولوية الترتيب):
- Workspace hooks:
<workspace>/hooks/(لكل وكيل، أعلى أولوية) - Managed hooks:
~/.openclaw/hooks/(مثبّتة من المستخدم، مشتركة عبر مساحات العمل) - Bundled hooks:
<openclaw>/dist/hooks/bundled/(مضمّنة مع OpenClaw)
يمكن أن تكون أدلة Managed hooks إما Hook واحدة أو حزمة Hooks (دليل حِزمي).
تتكون كل Hook من دليل يحتوي على:
my-hook/
├── HOOK.md # Metadata + documentation
└── handler.ts # Handler implementation
حزم الخطافات (npm/الأرشيفات)¶
حزم Hooks هي حزم npm قياسية تُصدّر Hook واحدة أو أكثر عبر 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 يحتوي على HOOK.md وhandler.ts (أو index.ts).
يمكن لحزم Hooks شحن تبعيات؛ وسيتم تثبيتها ضمن ~/.openclaw/hooks/<id>.
Hook Structure¶
HOOK.md Format¶
يحتوي ملف HOOK.md على بيانات وصفية في واجهة YAML الأمامية بالإضافة إلى توثيق Markdown:
---
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.
Metadata Fields¶
يدعم كائن metadata.openclaw ما يلي:
emoji: رمز تعبيري للعرض في CLI (مثل"💾")events: مصفوفة بالأحداث المراد الاستماع إليها (مثل["command:new", "command:reset"])export: التصدير المسمّى المراد استخدامه (الافتراضي"default")homepage: رابط التوثيقrequires: متطلبات اختياريةbins: الثنائيات المطلوبة على PATH (مثل["git", "node"])anyBins: يجب توفر واحد على الأقل من هذه الثنائياتenv: متغيرات البيئة المطلوبةconfig: مسارات التهيئة المطلوبة (مثل["workspace.dir"])os: الأنظمة الأساسية المطلوبة (مثل["darwin", "linux"])always: تجاوز فحوصات الأهلية (قيمة منطقية)install: طرق التثبيت (بالنسبة للـ Hooks المضمّنة:[{"id":"bundled","kind":"bundled"}])
Handler Implementation¶
يُصدّر ملف handler.ts دالة 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;
Event Context¶
يتضمن كل حدث:
{
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
}
}
Event Types¶
Command Events¶
تُطلق عند إصدار أوامر الوكيل:
command: جميع أحداث الأوامر (مستمع عام)command:new: عند إصدار أمر/newcommand:reset: عند إصدار أمر/resetcommand:stop: عند إصدار أمر/stop
Agent Events¶
agent:bootstrap: قبل حقن ملفات تهيئة مساحة العمل (قد تُعدّل Hooks context.bootstrapFiles)
Gateway Events¶
تُطلق عند بدء Gateway:
gateway:startup: بعد بدء القنوات وتحميل Hooks
Tool Result Hooks (Plugin API)¶
هذه Hooks ليست مستمعات لتدفق الأحداث؛ بل تتيح للإضافات تعديل نتائج الأدوات بشكل متزامن قبل أن يحفظها OpenClaw.
tool_result_persist: تحويل نتائج الأداة قبل كتابتها في سجل الجلسة. يجب أن تكون متزامنة؛ أعد حمولة نتيجة الأداة المُحدّثة أوundefinedللإبقاء عليها كما هي. راجع Agent Loop.
Future Events¶
أنواع أحداث مخططة:
session:start: عند بدء جلسة جديدةsession:end: عند انتهاء جلسةagent:error: عند مواجهة الوكيل خطأًmessage:sent: عند إرسال رسالةmessage:received: عند استلام رسالة
Creating Custom Hooks¶
1. Choose Location¶
- Workspace hooks (
<workspace>/hooks/): لكل وكيل، أعلى أولوية - Managed hooks (
~/.openclaw/hooks/): مشتركة عبر مساحات العمل
2. Create Directory Structure¶
mkdir -p ~/.openclaw/hooks/my-hook
cd ~/.openclaw/hooks/my-hook
3. Create HOOK.md¶
---
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. Create 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. Enable and Test¶
# 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
Configuration¶
New Config Format (Recommended)¶
{
"hooks": {
"internal": {
"enabled": true,
"entries": {
"session-memory": { "enabled": true },
"command-logger": { "enabled": false }
}
}
}
}
Per-Hook Configuration¶
يمكن أن تمتلك Hooks تهيئة مخصصة:
{
"hooks": {
"internal": {
"enabled": true,
"entries": {
"my-hook": {
"enabled": true,
"env": {
"MY_CUSTOM_VAR": "value"
}
}
}
}
}
}
Extra Directories¶
تحميل Hooks من أدلة إضافية:
{
"hooks": {
"internal": {
"enabled": true,
"load": {
"extraDirs": ["/path/to/more/hooks"]
}
}
}
}
Legacy Config Format (Still Supported)¶
لا يزال تنسيق التهيئة القديم مدعومًا للتوافق العكسي:
{
"hooks": {
"internal": {
"enabled": true,
"handlers": [
{
"event": "command:new",
"module": "./hooks/handlers/my-handler.ts",
"export": "default"
}
]
}
}
}
الترحيل: استخدم نظام الاكتشاف الجديد المعتمد على الأدلة للـ Hooks الجديدة. يتم تحميل المعالِجات القديمة بعد Hooks المعتمدة على الأدلة.
CLI Commands¶
List Hooks¶
# 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 Information¶
# Show detailed info about a hook
openclaw hooks info session-memory
# JSON output
openclaw hooks info session-memory --json
Check Eligibility¶
# Show eligibility summary
openclaw hooks check
# JSON output
openclaw hooks check --json
Enable/Disable¶
# Enable a hook
openclaw hooks enable session-memory
# Disable a hook
openclaw hooks disable command-logger
Bundled hook reference¶
session-memory¶
يحفظ سياق الجلسة في الذاكرة عند إصدار /new.
Events: command:new
Requirements: يجب تهيئة workspace.dir
Output: <workspace>/memory/YYYY-MM-DD-slug.md (الافتراضي ~/.openclaw/workspace)
What it does:
- يستخدم إدخال الجلسة قبل إعادة التعيين لتحديد النص الكامل الصحيح
- يستخرج آخر 15 سطرًا من المحادثة
- يستخدم LLM لتوليد اسم ملف وصفي (slug)
- يحفظ بيانات الجلسة الوصفية في ملف ذاكرة مؤرخ
Example output:
# Session: 2026-01-16 14:30:00 UTC
- **Session Key**: agent:main:main
- **Session ID**: abc123def456
- **Source**: telegram
Filename examples:
2026-01-16-vendor-pitch.md2026-01-16-api-design.md2026-01-16-1430.md(طابع زمني احتياطي إذا فشل توليد الاسم)
Enable:
openclaw hooks enable session-memory
command-logger¶
يسجل جميع أحداث الأوامر إلى ملف تدقيق مركزي.
Events: command
Requirements: لا شيء
Output: ~/.openclaw/logs/commands.log
What it does:
- يلتقط تفاصيل الحدث (إجراء الأمر، الطابع الزمني، مفتاح الجلسة، معرّف المُرسِل، المصدر)
- يُلحِق السجل بملف بتنسيق JSONL
- يعمل بصمت في الخلفية
Example log entries:
{"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"}
View logs:
# 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 .
Enable:
openclaw hooks enable command-logger
soul-evil¶
يستبدل محتوى SOUL.md المُحقن بـ SOUL_EVIL.md خلال نافذة تطهير أو باحتمال عشوائي.
Events: agent:bootstrap
Docs: SOUL Evil Hook
Output: لا يتم كتابة ملفات؛ تتم عمليات الاستبدال في الذاكرة فقط.
Enable:
openclaw hooks enable soul-evil
Config:
{
"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 (بعد بدء القنوات).
يجب تمكين Hooks الداخلية لتعمل.
Events: gateway:startup
Requirements: يجب تهيئة workspace.dir
What it does:
- يقرأ
BOOT.mdمن مساحة عملك - ينفّذ التعليمات عبر مُشغّل الوكيل
- يرسل أي رسائل صادرة مطلوبة عبر أداة الرسائل
Enable:
openclaw hooks enable boot-md
Best Practices¶
Keep Handlers Fast¶
تعمل Hooks أثناء معالجة الأوامر. اجعلها خفيفة:
// ✓ 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);
};
Handle Errors Gracefully¶
قم دائمًا بتغليف العمليات الخطِرة:
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
}
};
Filter Events Early¶
أعِد الخروج مبكرًا إذا لم يكن الحدث ذا صلة:
const handler: HookHandler = async (event) => {
// Only handle 'new' commands
if (event.type !== "command" || event.action !== "new") {
return;
}
// Your logic here
};
Use Specific Event Keys¶
حدّد أحداثًا دقيقة في البيانات الوصفية كلما أمكن:
metadata: { "openclaw": { "events": ["command:new"] } } # Specific
بدلاً من:
metadata: { "openclaw": { "events": ["command"] } } # General - more overhead
Debugging¶
Enable Hook Logging¶
يسجّل Gateway تحميل Hooks عند بدء التشغيل:
Registered hook: session-memory -> command:new
Registered hook: command-logger -> command
Registered hook: boot-md -> gateway:startup
Check Discovery¶
اعرض جميع Hooks المكتشفة:
openclaw hooks list --verbose
Check Registration¶
في المعالج الخاص بك، سجل عند استدعائه:
const handler: HookHandler = async (event) => {
console.log("[my-handler] Triggered:", event.type, event.action);
// Your logic
};
Verify Eligibility¶
تحقق من سبب عدم أهلية Hook:
openclaw hooks info my-hook
ابحث عن متطلبات مفقودة في المخرجات.
Testing¶
Gateway Logs¶
راقب سجلات Gateway لرؤية تنفيذ Hooks:
# macOS
./scripts/clawlog.sh -f
# Other platforms
tail -f ~/.openclaw/gateway.log
Test Hooks Directly¶
اختبر المعالِجات بشكل معزول:
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¶
Core Components¶
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: أوامر CLIsrc/gateway/server-startup.ts: تحميل Hooks عند بدء Gatewaysrc/auto-reply/reply/commands-core.ts: إطلاق أحداث الأوامر
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 events
Event Flow¶
User sends /new
↓
Command validation
↓
Create hook event
↓
Trigger hook (all registered handlers)
↓
Command processing continues
↓
Session reset
Troubleshooting¶
Hook Not Discovered¶
- تحقق من بنية الدليل:
bash
ls -la ~/.openclaw/hooks/my-hook/
# Should show: HOOK.md, handler.ts
- تحقق من تنسيق HOOK.md:
bash
cat ~/.openclaw/hooks/my-hook/HOOK.md
# Should have YAML frontmatter with name and metadata
- اعرض جميع Hooks المكتشفة:
bash
openclaw hooks list
Hook Not Eligible¶
تحقق من المتطلبات:
openclaw hooks info my-hook
ابحث عن المفقود:
- الثنائيات (تحقق من PATH)
- متغيرات البيئة
- قيم التهيئة
- توافق نظام التشغيل
Hook Not Executing¶
- تحقق من تمكين Hook:
bash
openclaw hooks list
# Should show ✓ next to enabled hooks
-
أعد تشغيل عملية Gateway لإعادة تحميل Hooks.
-
تحقق من سجلات Gateway بحثًا عن أخطاء:
bash
./scripts/clawlog.sh | grep hook
Handler Errors¶
تحقق من أخطاء TypeScript/الاستيراد:
# Test import directly
node -e "import('./path/to/handler.ts').then(console.log)"
Migration Guide¶
From Legacy Config to Discovery¶
Before:
{
"hooks": {
"internal": {
"enabled": true,
"handlers": [
{
"event": "command:new",
"module": "./hooks/handlers/my-handler.ts"
}
]
}
}
}
After:
- أنشئ دليل Hook:
bash
mkdir -p ~/.openclaw/hooks/my-hook
mv ./hooks/handlers/my-handler.ts ~/.openclaw/hooks/my-hook/handler.ts
- أنشئ HOOK.md:
```markdown
name: my-hook description: "My custom hook" metadata: { "openclaw": { "emoji": "🎯", "events": ["command:new"] } }
# My Hook
Does something useful. ```
- تحديث الإعداد:
json
{
"hooks": {
"internal": {
"enabled": true,
"entries": {
"my-hook": { "enabled": true }
}
}
}
}
- تحقّق وأعد تشغيل عملية Gateway:
bash
openclaw hooks list
# Should show: 🎯 my-hook ✓
Benefits of migration:
- الاكتشاف التلقائي
- إدارة عبر CLI
- التحقق من الأهلية
- توثيق أفضل
- بنية متسقة