حين يعمل Claude Code داخل مستودعك، يكفي قرار واحد خاطئ ليكتب فوق ملف .env أو يدفع commit مباشرة إلى الفرع الرئيسي. هذه الحزمة أربع بطاقات تصف Hooks أمان تعترض أدوات Claude في لحظتين: قبل أن يعدّل ملفًا أو يشغّل أمرًا في الطرفية، وبعد أن يحفظ التعديل. وهي لـ Claude Code وحده، لا لمحادثات claude.ai.
أربع وصفات، لكل منها لحظتها
- branch-guard: يعمل قبل أداة Bash، وتقول بطاقته إنه يرفض git push origin main و
git push --force origin master، ويترك الدفع إلى develop وفروع الميزات. تحدد الفروع المحمية بالمتغير CC_PROTECT_BRANCHES، وقيمته الافتراضية main:master، ويحتاج jq. - file-protection: يعمل قبل Edit وMultiEdit وWrite، ويرفض الكتابة في الملفات الحساسة. تذكر بطاقته المتغير CLAUDE_TOOL_FILE_PATH، لكن سكربته الكامل لا يستخدمه.
- file-protection-hook: نسخة شقيقة بالحدث والمطابِق نفسيهما، يزيد نصها الكامل كلمة secrets على قائمة الأنماط المحمية.
- security-scanner: يعمل بعد Edit وWrite عند الحدث PostToolUse، فيبحث في الملف المحفوظ عن مفاتيح وكلمات مرور مكتوبة صراحة.
نقلتُ البطاقات الأربع كما هي. تحدد كل بطاقة الحدث (event) والمطابِق (matcher) ولغة السكربت، لكنها لا تتضمن السكربت نفسه. السكربتات الكاملة للثلاث الأخيرة في مجموعة أمثلة Hooks، أما سكربت branch-guard فتنسبه بطاقته إلى مشروع claude-code-hooks، ولم أجده في أي من الحزمتين.
مثال: Claude يحاول تعديل ملف .env
تطلب من Claude إضافة متغير إلى إعدادات مشروعك، فيقرر تعديل .env بأداة Edit. قبل التنفيذ يطلق Claude Code الحدث PreToolUse ويمرر بيانات الأداة بصيغة JSON، فيستخرج سكربت file-protection المسار من الحقل tool_input.file_path بأداة jq، ويقارنه بأربعة أنماط: .env وpackage-lock.json و.git/ وnode_modules/. يطابق المسار النمط الأول، فيكتب الرسالة Blocked: Cannot modify protected file ويخرج بالرمز 2، فيُلغى التعديل وتصل الرسالة إلى Claude فيعرف سبب الرفض.
من البطاقة إلى حاجز يعمل
- ثبّت jq أولًا، وعلى ويندوز Git Bash، فالسكربتات مكتوبة بـ bash.
- انسخ نص السكربت إلى ملف مثل .claude/hooks/file-protection.sh.
- في .claude/settings.json، تحت المفتاح hooks، أضف الحدث PreToolUse بالمطابِق Edit|MultiEdit|Write وأمرًا من النوع command مثل bash “$CLAUDE_PROJECT_DIR/.claude/hooks/file-protection.sh”. حارس الفروع يأخذ الحدث نفسه بالمطابِق Bash، وفاحص الأسرار يأخذ PostToolUse بالمطابِق Edit|Write.
- اكتب /hooks داخل Claude Code لتتأكد أن الإعداد سُجّل. الصيغة الكاملة في توثيق Hooks الرسمي.
لا يحوي مجلد plugin ملف hooks.json، فتثبيته إضافةً لا يفعّل أي وصفة. وأرفقتُ دليلًا عربيًا بخطوات البداية وفهرسًا بأسماء الملفات.
ما لا تحميك منه هذه الوصفات
- حاجزا الملفات يراقبان أدوات التعديل وحدها، فأمر في Bash يكتب في .env لا يمر عليهما.
- المطابقة جزئية: يُرفض كل مسار يحتوي النص .env، ومنه .env.example، وكلمة secrets في file-protection-hook تمنع أيضًا ملفًا مثل docs/secrets-guide.md.
- فاحص الأسرار لا يمنع شيئًا: يعمل بعد حفظ الملف ويخرج بالرمز 0، فيذهب تحذيره إلى سجل التصحيح (debug) وحده، فلا تراه في المحادثة ولا يراه Claude. ليصل إليه أضف exit 2 بعد سطر التحذير.
- نمط الفاحص حساس لحالة الأحرف، فيلتقط api_key ولا يلتقط API_KEY، ويشترط قيمة متصلة من 20 حرفًا بلا شرطات، فتفوته كلمة المرور القصيرة والمفاتيح التي تبدأ بـ sk-ant- أو sk-proj-. ويذكر gitleaks متطلبًا اختياريًا لا يستدعيه سكربته.
- لا تذكر بطاقة branch-guard حكم git push دون اسم فرع وأنت على main.
- file-protection وfile-protection-hook متطابقتان تقريبًا، ففعّل واحدة منهما.
الترخيص MIT، والحقوق لـ davepoon ومجتمع BuildWithClaude، ووصفة branch-guard منسوبة في بطاقتها إلى مشروع claude-code-hooks.



