حين تشغّل Claude Code بخيار --dangerously-skip-permissions لا يستأذنك قبل rm أو mv، فيكفي مسار خاطئ واحد ليصل الحذف إلى ملفات خارج مشروعك. إضافة project-boundary تعترض أدوات Bash وEdit وWrite وMultiEdit عند الحدث PreToolUse، وتقارن كل مسار مستهدف بمجلد المشروع في CLAUDE_PROJECT_DIR: ما داخله يمر كالمعتاد، وما خارجه يُرفض. وهي تعمل في Claude Code وحده، لا في محادثات claude.ai.
وخلافًا لحواجز تمنع rm في كل مكان أو تطلب قائمة يدوية بالمسارات المحمية، تحمي هذه الإضافة كل ما خارج المشروع تلقائيًا.
ما يفحصه الحارس قبل التنفيذ
- الحذف والنقل والصلاحيات: rm وmv وcp وln وchmod وchown وfind -delete، مع فحص المصدر والوجهة في mv وcp وln.
- الكتابة: إعادة التوجيه > و>> وtee وcurl -o وwget -O وdd of=، وأدوات Edit وWrite وMultiEdit.
- فك الضغط والمزامنة: tar -C وunzip -d و7z وrsync وinstall، ومخرجات pg_dump -f وpsql -o.
- ما يُرفض في كل الأحوال: bash -c وeval والتمرير إلى sh، وpython -c و
node --eval، و$(…)، والمتغيرات مثل $VAR عدا $HOME؛ لأن الحارس لا يرى ما بداخلها. - أوامر git المدمرة:
git reset --hardوgit clean -f وgit push --forceوgit branch -D، حين تُنفذ من مجلد خارج المشروع.
ماذا في مجلد plugin
- hooks/hooks.json: يربط guard.sh بالأدوات الأربع، ويمرّر إلى Claude ملاحظة session_hint.md عند بدء الجلسة.
- hooks/guard.sh ومجلد lib: الحارس نفسه بـ Bash خالص، مع كاشف مستقل لكل فئة من الأوامر.
- hooks/allowlist.conf: استثناءات للكتابة وحدها، وفيه سطر افتراضي يسمح بذاكرة Claude Code التلقائية في ~/.claude/projects/*/memory/**، ولا يسري على rm أو mv. وتحذّر المؤلفة داخله من توسيعه، فكل سطر منفذ من الحماية.
- hooks/session_hint.md: يوجّه Claude إلى كتابة رسالة commit متعددة الأسطر بـ git commit -F - مع heredoc، لأن صيغة $(cat …) مرفوضة.
مثال: أمر يغادر المشروع ثم يحذف
في مثال README الأصلي يكتب Claude الأمر cd /tmp && rm -rf something. يقسم الحارس السلسلة ويفحص كل جزء وحده، فيرى أن cd غادر المشروع، فيرفض rm ويخرج بالرمز 2 برسالة Destructive command outside project directory تطلب من Claude أن يستأذنك. أما rm -rf على مجلد داخل المشروع فيمر دون اعتراض.
التثبيت والمتطلبات
- ثبّت jq أولًا: brew install jq أو apt install jq أو winget install jqlang.jq. وبدونه يرفض الحارس كل أمر وكل تعديل.
- فك الضغط مع الإبقاء على الملفات المخفية، فملف plugin.json داخل المجلد .claude-plugin.
- للتجربة في جلسة واحدة:
claude --plugin-dirمع المسار الكامل لمجلد plugin. وللتثبيت الدائم من السوق: /plugin marketplace add davepoon/buildwithclaude ثم /plugin install project-boundary@buildwithclaude. - على ويندوز تعمل تحت Bash من MSYS2، وتحتاج cygpath لتحويل المسارات التي تبدأ بحرف القرص، وإلا رفضتها.
قبل أن تعتمد عليها
- ليست عزلًا أمنيًا كاملًا: تقرأ نص الأمر وحده، فما يفعله سكربت تشغّله من داخل المشروع لا يمر عليها.
- قد ترفض أوامر سليمة تستخدم متغيرًا غير $HOME، ولا تدعم المسارات التي فيها مسافات إلا بين علامات اقتباس.
- داخل المشروع لا تمنع
git reset --hardولاgit push --force. وتعدّ بطاقة hooks/project-boundary.md هذه الأوامر وDROP TABLE ممنوعة دائمًا، لكنني لم أجد ذلك في السكربت، فالمرجع README الأصلي.
الإضافة من تأليف Justyna Wojtczak بترخيص MIT في مستودع claude-code-project-boundary، ووصلت نسختها 1.10.0 عبر فهرس BuildWithClaude دون تعديل، وأرفقتُ دليلًا عربيًا بخطوات التشغيل.



