Claude Code · Hooks · settings.json

كل مرة Claude بيعدّل ملف… 5 أشياء بتصير لحالها: ملف الـ hooks جاهز للصق

تنسيق تلقائي، اختبارات بتشتغل بعد كل تعديل، إشعار على الجوال لما يخلص، منع للأوامر الخطرة قبل ما تنفّذ، وسجل لكل أداة شغّلها. كلها بملف واحد settings.json. هون الملف كامل جاهز للصق، وشرح كل hook وليش هو هيك، وملف المنع، والأخطاء اللي بتخلي الـ hooks ما تشتغل.

شو الـ hook وكيف بيشتغل؟

الـ hook أمر إنت بتكتبه، وClaude Code بينفّذه لحاله عند حدث معيّن: قبل ما يشغّل أداة، بعد ما يعدّل ملف، لما يخلص الرد. مش Claude اللي بيقرّر ينفّذه؛ هو بينفّذ دايماً، زي قاعدة بالنظام.

PreToolUse
قبل الأداة
بيقدر يمنع التنفيذ. هون ملف المنع.
PostToolUse
بعد الأداة
التنسيق، الاختبارات، السجل.
Stop
لما يخلص الرد
الإشعار على الجوال.
كيف بيعرف الـ hook أي ملف انعدّل؟ Claude Code بيبعتله تفاصيل الحدث كـ JSON على الـ stdin: اسم الأداة بـ tool_name، ومدخلاتها بـ tool_input (مسار الملف بـ tool_input.file_path لأدوات التعديل، والأمر بـ tool_input.command لأداة Bash). عشان هيك كل الأوامر تحت بتبدأ بـ jq: هو اللي بيقرأ الـ JSON.

الـ hooks جزء من إعدادات الأمان الأوسع: الصلاحيات والقواعد بـ دليل إعدادات الأمان.

انسخ، الصق، وبدّل أمرين

ملف واحد بمجلد المشروع. الأوامر فيه لمشروع JavaScript/Node؛ بدّلها حسب مشروعك بالقسم 5.

1

ملف الـ hooks الخمسة (الصقه)

احفظه باسم .claude/settings.json جوّا مجلد المشروع (أو ادمجه مع الملف الموجود إذا عندك واحد). بدّل YOUR-TOPIC بكلمة سرية إلك:

.claude/settings.json

{ "hooks": { "PostToolUse": [ { "matcher": "Edit|Write", "hooks": [ { "type": "command", "command": "jq -r '.tool_input.file_path' | xargs npx prettier --write" }, { "type": "command", "command": "npm test --silent || { echo 'tests failed after this edit' >&2; exit 2; }", "timeout": 120 } ] }, { "matcher": "", "hooks": [ { "type": "command", "command": "jq -c '[(now|strftime(\"%H:%M\")), .tool_name, (.tool_input.file_path // .tool_input.command // \"\")]' >> .claude/tool-log.jsonl" } ] } ], "PreToolUse": [ { "matcher": "Bash", "hooks": [ { "type": "command", "command": "sh .claude/guard.sh" } ] } ], "Stop": [ { "hooks": [ { "type": "command", "command": "curl -s -d 'Claude: done' ntfy.sh/YOUR-TOPIC" } ] } ] } }
  • الهيكل: اسم الحدث ← قائمة فيها matcher (أي أداة) وhooks (الأوامر). الـ Stop ما إله matcher لأنه بيشتغل كل مرة.
  • الـ matcher: "Edit|Write" يعني أداتي التعديل والكتابة بالضبط. "" (فاضي) أو "*" يعني كل الأدوات.
  • الترتيب: الـ hooks اللي بنفس الـ matcher بتشتغل بالتوازي، فما تعتمد على إنه التنسيق بيخلص قبل الاختبارات.
2

ملف المنع guard.sh

هاد الملف بيقرأ أمر الـ Bash قبل ما ينفّذ. إذا لقى فيه نمط خطر بيرجّع exit 2: الأمر بيتوقف، والسبب بيروح لـ Claude عشان يغيّر طريقته. احفظه باسم .claude/guard.sh:

.claude/guard.sh

#!/bin/sh # exit 2 = block the command and tell Claude why. exit 0 = let it through. CMD=$(jq -r '.tool_input.command // ""') case "$CMD" in *"rm -rf /"*|*"rm -rf ~"*|*"rm -rf .."*|*"rm -rf *"*|*"git push --force"*|*"git push -f"*|*"git reset --hard"*|*"DROP TABLE"*|*"DROP DATABASE"*|*"mkfs"*|*"> /dev/sd"*) echo "blocked by guard.sh: $CMD" >&2 exit 2 ;; esac exit 0
  • الأنماط بين النجمتين: أي أمر فيه هالنص بيتوقف. ضيف أنماطك: *"terraform destroy"*، *".env"*، اسم قاعدة بيانات الإنتاج.
  • ليش exit 2 بالذات؟ هو الكود الوحيد اللي بيمنع. exit 0 بيمرّر، وأي رقم تاني بيعرض الخطأ إلك وبيكمّل.
  • بديل بالـ JSON: بدل exit 2 بتقدر تطبع {"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"…"}}. نفس النتيجة، بس بتقدر تختار ask كمان عشان يسألك بدل ما يمنع.
المنع مش بديل عن القراءة: الـ guard بيمسك الأنماط اللي كتبتها بس. أمر حذف مكتوب بطريقة ثانية بيمرق. خلّيه خط دفاع تاني، وخلّي عينك على أوامر الحذف أول.
3

شو بيعمل كل hook وليش هيك

format
بعد كل Edit أو Write: prettier بينسّق الملف اللي انعدّل بس (مساره من tool_input.file_path).هاد المثال نفسه الموجود بتوثيق Claude Code. التعديلات اللي بتصير بأمر Bash مش بأداة Edit ما بتنمسك.
tests
بعد كل تعديل: npm test. لو فشلت، الـ hook بيرجّع exit 2 ورسالة الفشل بتروح لـ Claude، فبيعرف قبلك وبيصلّح.الـ timeout 120 ثانية عشان اختبارات طويلة ما توقف الجلسة. مشروع كبير؟ شغّل اختبارات الملف بس (القسم 5).
إشعار
عند Stop (خلّص الرد): طلب لـ ntfy.sh بيوصلك إشعار على الجوال من تطبيق ntfy المجاني.بدك إشعار لما يحتاج موافقتك مش لما يخلص؟ استعمل حدث Notification مع matcher permission_prompt. وإذا بتشتغل بـ Remote Control، الإشعارات على الجوال مبنية فيه أصلاً.
منع
قبل أي أمر Bash: guard.sh بيفحصه. أمر خطر = بيتوقف قبل ما ينفّذ، وClaude بيقرأ السبب.الوحيد من الخمسة اللي بيقدر يمنع، لأنه PreToolUse.
سجل
بعد كل أداة: سطر بملف .claude/tool-log.jsonl فيه الوقت، اسم الأداة، والملف أو الأمر.الصبح بتفتحه وبتشوف شو عمل بالليل. ضيف الملف لـ .gitignore.
5 دقايق

جرّب كل hook لحاله قبل ما تعتمد عليه.

4

التثبيت والتجربة

  1. ثبّت jq (قارئ الـ JSON): على Mac brew install jq، على Windows winget install jqlang.jq، على Ubuntu sudo apt install jq. وعلى Windows لازم Git for Windows عشان أوامر الـ sh.
  2. احفظ الملفين بمجلد .claude/ جوّا المشروع، وبدّل YOUR-TOPIC. على Mac وLinux اعطي ملف المنع صلاحية تنفيذ: chmod +x .claude/guard.sh.
  3. افتح Claude Code بالمشروع (أو خلّيه مفتوح: التعديل على ملف الإعدادات بينلقط لحاله)، واكتب /hooks عشان تشوف الخمسة مسجّلين مع أوامرهم. هاد الأمر للعرض بس؛ التعديل من الملف.
  4. جرّب المنع: قوله «نفّذ echo test && git push --force». لازم يتوقف ويحكيلك إنه guard.sh منعه.
  5. جرّب التنسيق والسجل: اطلب تعديل صغير بأي ملف، وافتح .claude/tool-log.jsonl. لازم تلاقي السطر.
  6. جرّب الإشعار: ثبّت تطبيق ntfy على الجوال واشترك بنفس الـ topic. أول رد بيخلّصه Claude بيوصلك إشعار.
بدك الـ hooks بكل مشاريعك؟ حطها بـ ~/.claude/settings.json بدل مجلد المشروع. بس وقتها بدّل الأوامر الخاصة بالمشروع (npm test) بشي عام، أو خلّي التنسيق والاختبارات بملف المشروع والإشعار والسجل بملف الحساب.
5

عدّله على مشروعك

مشروعكformattests
JavaScript / TypeScriptnpx prettier --write (زي الملف)npm test --silent أو اختبارات الملف بس: npx vitest related --run
Pythonjq -r '.tool_input.file_path' | xargs ruff formatpytest -q
Gojq -r '.tool_input.file_path' | xargs gofmt -wgo test ./...
مش مبرمج؟احذف hook التنسيقاحذف hook الاختبارات. خلّي الإشعار والمنع والسجل: هدول بينفعوا بأي شغل
  • الاختبارات بطيئة؟ خلّيها تشتغل عند Stop بدل PostToolUse: مرة لما يخلص، بدل كل تعديل.
  • إشعار على Mac بدون جوال: بدّل أمر curl بـ osascript -e 'display notification "Claude: done"'. على Linux: notify-send "Claude: done".
  • الـ timeout: الافتراضي لأوامر الـ command طويل (600 ثانية). للاختبارات حدّده إنت زي ما بالملف عشان ما تعلق الجلسة.
6

أخطاء بتخلي الـ hooks ما تشتغل

متغيّرات مش موجودةتكتب $CLAUDE_FILE_PATH أو $CLAUDE_TOOL_NAME. ما إلهم وجود، فالأمر بيشتغل على مسار فاضي.
اقرأ من الـ stdin بـ jqمسار الملف من .tool_input.file_path، والأمر من .tool_input.command. المتغيّر الوحيد اللي بتحتاجه غالباً $CLAUDE_PROJECT_DIR (جذر المشروع).
jq مش مثبّتكل الـ hooks بتفشل بصمت أو بخطأ «command not found».
ثبّته أول (القسم 4)وجرّب echo '{"a":1}' | jq .a بالطرفية قبل.
exit 1 للمنعبتفكر أي خطأ بيمنع. لا: exit 1 بيعرض الخطأ إلك والأمر بيكمّل.
exit 2 بسهو الوحيد اللي بيوقف الأداة وبيرجّع السبب لـ Claude.
بتعدّل الملف وبتفكره ما انلقطبتعيد تشغيل Claude Code كل مرة.
بينلقط لحالهالتعديل على ملف الإعدادات بينقرأ مباشرة. /hooks بيوريك الحالة الحالية.
اختبارات دقيقتين بعد كل تعديلكل Edit بيستنى الاختبارات، والجلسة بتصير بطيئة.
اختبارات الملف بس، أو عند Stopالقسم 5. والـ timeout محدّد.
?

أسئلة شائعة

شو الفرق بين hook وقاعدة بـ CLAUDE.md؟
القاعدة بـ CLAUDE.md تعليمات Claude بيقرأها وبيحاول يلتزم فيها. الـ hook أمر النظام بينفّذه دايماً بدون ما يقرّر Claude. للأشياء اللي لازم تصير 100% (المنع، السجل) استعمل hook. قالب CLAUDE.md بـ هاد الدليل.
في أحداث غير الثلاثة؟
كثير: SessionStart، UserPromptSubmit، Notification، SubagentStop، PreCompact، SessionEnd، وغيرها. الثلاثة بالملف هم اللي بتحتاجهم 90% من الوقت.
بيشتغل على Windows؟
إيه مع Git for Windows (الأوامر بتشتغل بـ Git Bash) وjq مثبّت. لو أمر ما اشتغل، جرّبه بالطرفية لحاله أول. وبدّل sh .claude/guard.sh بـ bash .claude/guard.sh إذا لزم.
الـ hook بيشوف شو كتبت بالمحادثة؟
بيشوف تفاصيل الحدث بس (الأداة ومدخلاتها)، ومسار ملف المحادثة بـ transcript_path إذا بدك تقرأه. ما بيوصله شي تلقائياً غير هيك.
ممكن Claude يعدّل الـ hooks لحاله؟
إذا طلبت منه، إيه (هو ملف بالمشروع). عشان هيك خلّي ملف المنع بسيط وراجعه إنت. وبتقدر تطلب منه: «ضيف hook يشغّل الاختبارات بعد كل تعديل» وهو بيكتبه بالصيغة الصح.
✓ تم النسخ

الدليل الجاي يوصلك أول واحد

اترك إيميلك وبتوصلك الأدلة الجديدة أول بأول، بدون إزعاج.

إيميلك بيضل عندي، وبتقدر تطلب حذفه بأي وقت.