Free

الدليل الشامل لـ Claude Code Hooks: تحكم في كل إجراء يقوم به Claude

تحليل شامل لآلية Claude Code Hooks: خمسة أنواع من الأحداث، التحكم في رموز الخروج، وأربعة تكوينات حقيقية لجعل إجراءات الذكاء الاصطناعي قابلة للتدقيق والاعتراض والأتمتة.


في كل مرة يقرأ فيها Claude Code ملفًا أو يكتب كودًا أو ينفذ أمرًا، يعمل نظام أحداث في الخلفية. Hooks هي الواجهة للاتصال بهذا النظام — يمكنك حقن منطقك الخاص في أي وقت: تشغيل أدوات الفحص تلقائيًا، وتسجيل العمليات، وحجب الإجراءات الخطيرة، أو تشغيل أي أمر shell.

تغطي هذه المقالة آلية Hooks وطريقة الإعداد والاستخدام العملي بشكل كامل.


ما هي Hooks

Hooks هي أوامر shell مُهيَّأة في settings.json يُشغِّلها Claude Code تلقائيًا عند وقوع أحداث معينة.

أقرب تشبيه: git hooks. يمكن لـ git تشغيل سكريبتات قبل وبعد عمليات مثل commit وpush. تعمل Claude Code Hooks بنفس الطريقة تمامًا — الفرق أن نقاط التشغيل هي استدعاءات أدوات الذكاء الاصطناعي.

لماذا هذا مهم؟

كلما ازدادت قدرات Claude Code، كلما احتجت إلى طبقة تحكم حتمية. توفر Hooks:
- ضمانات تنفيذ لا تعتمد على الـ prompt (قد يتجاهل Claude التعليمات، لكن hook سيعمل دائمًا)
- سجلات عمليات قابلة للتدقيق
- فحوصات جودة آلية


خمسة أنواع من Hooks

النوع المُشغِّل الاستخدام الشائع
PreToolUse قبل استدعاء أداة حجب العمليات الخطيرة، تسجيل النية
PostToolUse بعد استدعاء أداة Lint تلقائي، تشغيل الاختبارات
PreCompact قبل ضغط السياق حفظ لقطة للحالة الحالية
Notification عندما يُرسل Claude إشعارًا تنبيهات سطح المكتب، رسائل Slack
Stop عندما يُكمل Claude الرد تلخيص السجلات، تشغيل مسارات لاحقة

الأكثر استخدامًا هما PreToolUse وPostToolUse، للاعتراض على استدعاءات الأدوات ومعالجتها لاحقًا.


صيغة الإعداد

تُكتب Hooks في ~/.claude/settings.json (عام) أو .claude/settings.json في جذر المشروع (مستوى المشروع):

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "npm run lint --silent"
          }
        ]
      }
    ]
  }
}

ثلاثة حقول أساسية:

  • matcher: تعبير نمطي يطابق أسماء الأدوات، يحدد استدعاءات الأدوات التي تُشغِّل هذا الـ hook. "Write|Edit" يُشغَّل عند كتابة أو تعديل الملفات. اتركه فارغًا أو استخدم ".*" لمطابقة جميع الأدوات.
  • type: حاليًا "command" فقط.
  • command: أي أمر shell.

مرجع أسماء الأدوات

أسماء الأدوات التي تحتاجها لكتابة matcher:

اسم الأداة العملية
Write كتابة ملف جديد
Edit تعديل ملف
Bash تنفيذ أمر shell
Read قراءة ملف
Glob البحث عن ملفات
Grep البحث في المحتوى
TodoWrite تحديث قائمة المهام

بيئة تنفيذ Hook

أثناء التنفيذ، تُمرَّر البيانات كـ JSON عبر stdin:

{
  "tool_name": "Write",
  "tool_input": {
    "file_path": "/path/to/file.rb",
    "content": "..."
  },
  "tool_response": "..."
}

يستقبل PreToolUse الـ tool_input (المعطيات قبل الاستدعاء). يستقبل PostToolUse أيضًا tool_response (القيمة المُرجَعة من الأداة).

مثال على hook بمنطق شرطي:

#!/bin/bash
input=$(cat)
file=$(echo "$input" | jq -r '.tool_input.file_path')

# تشغيل rubocop على ملفات .rb فقط
if [[ "$file" == *.rb ]]; then
  rubocop "$file" --autocorrect-all --no-color
fi

معنى رموز الخروج

يتحكم رمز خروج الـ hook في السلوك اللاحق لـ Claude Code:

رمز الخروج المعنى
0 نجاح، استمر في التنفيذ
2 حجب: إلغاء استدعاء الأداة الحالي، إرسال مخرجات stderr إلى Claude
غير صفري آخر تسجيل الخطأ والاستمرار

رمز الخروج 2 هو الأكثر فائدة — يتيح لك كتابة منطق الاعتراض في PreToolUse لمنع Claude من تنفيذ عملية وإخباره بالسبب.


عملي: أربعة إعدادات Hook حقيقية

1. التنسيق التلقائي بعد كتابة الملفات

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "bash -c 'file=$(echo \"$CLAUDE_TOOL_INPUT\" | jq -r .file_path 2>/dev/null); [[ \"$file\" == *.rb ]] && rubocop -A \"$file\" --no-color -q || true'"
          }
        ]
      }
    ]
  }
}

2. منع حذف مجلدات معينة

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "bash -c 'cmd=$(echo \"$CLAUDE_TOOL_INPUT\" | jq -r .command); if echo \"$cmd\" | grep -qE \"rm.*/(migrations|seeds)\"; then echo \"لا يُسمح بحذف مجلدات migrations أو seeds\" >&2; exit 2; fi'"
          }
        ]
      }
    ]
  }
}

3. سجل تدقيق العمليات

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit|Bash",
        "hooks": [
          {
            "type": "command",
            "command": "echo \"$(date '+%Y-%m-%d %H:%M:%S') $CLAUDE_TOOL_NAME: $(echo $CLAUDE_TOOL_INPUT | jq -c .)\" >> ~/.claude/audit.log"
          }
        ]
      }
    ]
  }
}

4. إشعار سطح المكتب عند الانتهاء

{
  "hooks": {
    "Stop": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "osascript -e 'display notification \"اكتمل Claude\" with title \"Claude Code\"'"
          }
        ]
      }
    ]
  }
}

عام vs. مستوى المشروع

يمكن وضع Hooks في مكانين:

عام (~/.claude/settings.json): قواعد تنطبق على جميع المشاريع — السجلات، الإشعارات.

مستوى المشروع (.claude/settings.json): فحوصات خاصة بالمشروع. تُدمج hooks المشروع والـ hooks العامة وتُشغَّل معًا.

في مشاريع الفريق، يُنصح بعمل commit لـ settings.json الخاص بالمشروع في git حتى يُشغِّل الجميع نفس الـ hooks.


تصحيح أخطاء Hook

خطوات استكشاف الأخطاء عندما لا يعمل hook:

  1. تحقق من إملاء matcher: أسماء الأدوات حساسة لحالة الأحرف — write ليست Write
  2. شغِّل الأمر منفردًا: انسخ أمر الـ hook وشغِّله مباشرة في الطرفية
  3. راجع مخرجات Claude Code: يظهر stderr الـ hook في المحادثة
  4. بسِّط للاختبار: ابدأ بـ echo "hook triggered" >> /tmp/hook.log لتأكيد التشغيل

خلاصة

القيمة الجوهرية لـ Hooks هي ربط سلوك الذكاء الاصطناعي غير المتوقع بمعايير الهندسة الحتمية. قد ينسى Claude تشغيل الاختبارات، لكن PostToolUse hook لن ينسى. قد يحذف Claude ملفات بالخطأ، لكن معترض PreToolUse لن يسمح بذلك.

ابدأ بـ hook واحد: lint تلقائي بعد كتابة الملفات. بعد أن يعمل بسلاسة، أضف المزيد.