
بيئة معزولة (Sandbox) لوكلاء البرمجة بالذكاء الاصطناعي. تشغّل Copilot CLI أو Claude Code أو OpenCode أو Gemini CLI أو Antigravity أو Pi أو goose أو صدفة (shell) عادية داخل بيئة معزولة على مستوى النواة، مع حواجز git و gh وسياسة بيئة معزولة مُودَعة في المستودع.
بيئة معزولة مفروضة على مستوى النواة لوكلاء البرمجة بالذكاء الاصطناعي. يغلّف cplt واجهة GitHub Copilot CLI وOpenCode وGemini CLI وAntigravity CLI وPi وClaude Code وgoose وDeepSeek Harness، أو أي صدفة (shell)، بحيث يستطيع الوكيل كتابة الشيفرة لكنه لا يستطيع سرقة بيانات الاعتماد، أو الدفع إلى main، أو دمج طلبات السحب (PRs)، أو تسريب الأسرار.
sandbox-exec
ينفّذ وكلاء الذكاء الاصطناعي شيفرة عشوائية. يمكن لوكيل مخترق، سواء عبر حقن الأوامر (prompt injection)، أو هجوم على سلسلة التوريد، أو خادم MCP خبيث، أن يقرأ ~/.ssh، أو يدفع إلى main، أو يدمج طلبات السحب، أو يسرّب شيفرتك، إلا إذا رفض نظام التشغيل نفسه ذلك.
يمنحك cplt فرضًا على مستوى النواة مع سياسة قابلة للتهيئة على مستوى الفريق:
.cplt.toml، مُلتزَم بها في نظام التحكم بالإصدارات، بحيث تكون محصّنة ضد التلاعب وقابلة للتدقيقوثائق مفصّلة: التهيئة · الوكيل وتصفية النطاقات · حارس أمر gh · حارس أمر git · التأثيرات المعروفة · تفاصيل الأمان · نموذج الأمان
brew install navikt/tap/cplt # macOS. On Debian or Ubuntu, see apt below cplt --shell-install # make 'copilot' run sandboxed (persistent) # --agent opencode for any other agent cplt doctor # check your environment cplt -- -p "fix the tests" # run Copilot in sandbox
وكلاء آخرون وأوامر sandbox:```bash
cplt --agent opencode # OpenCode (Copilot subscription)
cplt --agent opencode --pass-env ANTHROPIC_API_KEY # third-party provider
cplt --agent shell # interactive sandboxed shell (no AI)
cplt exec -- npm install # sandbox any command directly
cplt exec -c "npm install && npm test" # compound commands in sandbox
alias npm="cplt exec -- npm" # sandboxed npm for every invocation
cplt init --write
cplt trust accept --all
cplt config set git_guard.protect_default_branch_only false # block every push, not just main cplt config set git_guard.mode warn # observe instead of blocking
## ما الذي يحجبه
يحجب الـ sandbox الوصول إلى بيانات الاعتماد والأسرار في النواة. تحجب حراس الأوامر العمليات المدمّرة. كل قيد يُطبَّق على الوكيل وعلى كل عملية يُشغّلها.
| المورد | الحالة | ملاحظات |
| --- | --- | --- |
| قراءة/كتابة دليل المشروع | ✅ مسموح | |
| قراءة/كتابة/حذف `.env*`، `.pem`، `.key` في المشروع | 🔒 محجوب على مستوى النواة | يمنع تسريب الأسرار وتدميرها. `--allow-env-files` يتجاوز ذلك |
| كتابة `.git/hooks`، `.git/config`، `.gitmodules` | 🔒 محجوب على مستوى النواة (macOS)، ⚠️ جزئي على Linux | يمنع الاستمرارية عبر git hooks، وإعادة توجيه hooksPath، واختطاف submodule. **Linux:** لا يستطيع Landlock رفض مسار فرعي داخل شجرة مسموح بها، لذا تبقى هذه قابلة للكتابة على مسار Landlock فقط. يعيد `bwrap` ربط `.git/hooks` للقراءة فقط لكنه يترك `.git/config` و`.gitmodules` قابلين للكتابة عمدًا، فيبقى `core.hooksPath` مسارًا للاستمرارية، انظر [قيود Linux](https://github.com/navikt/cplt/blob/main/docs/security.md#linux). ينطبق على **كل** جذر قابل للكتابة، المشروع وكل منحة `allow.write`، بما في ذلك worktree ممنوح أو bare repo تقع hooks الحقيقية فيه خارج `<root>/.git` |
| التنفيذ من `/tmp`، `/var/folders` | 🔒 محجوب على مستوى النواة | يمنع الكتابة ثم التنفيذ. يعيد دليل scratch توجيه TMPDIR إلى موقع آمن، مُفعَّل افتراضيًا |
| كتابة أدلة bin/shim المحلولة عبر PATH (`~/.bun/bin`، `~/.deno/bin`، `$PNPM_HOME`، mise `shims/` وكل `installs/`) | 🔒 محجوب على مستوى النواة (macOS)، ⚠️ mise جزئي على Linux | يمنع ترويج (trojan) ملف تنفيذي يحلّه أمرك التالي *غير المعزول* عبر PATH. لنفس السبب ظلّ `~/.cargo/bin` و`~/go/bin` للقراءة فقط دائمًا. يكسر `bun install -g`، `deno install`، `pnpm add -g`، `mise install`، `mise upgrade`، `mise use -g` داخل cplt، عمدًا، ولم يعد مستودع يثبّت toolchain غير مثبّتة يُهيّأ تلقائيًا. التثبيتات المحلية للمشروع غير متأثرة. **Linux:** اثنان من mise يعتمدان على طبقة `bwrap` للقراءة فقط؛ والبقية تصمد أصليًا. انظر [تثبيتات الأدوات العامة](https://github.com/navikt/cplt/blob/main/docs/known-impacts.md#global-tool-installs) |
| التنفيذ من `~/Library/Caches` | 🔒 محجوب على مستوى النواة افتراضيًا | يمنع تجهيز إسقاط الملفات التنفيذية. تُستثنى وحدات Copilot الأصلية عبر استثناء. أضف استثناءات موجّهة بـ `--allow-cache-exec <SUBDIR>`، مثل `ms-playwright` |
| تعديل `.vscode/tasks.json`، `launch.json` | ⚠️ مسموح، خطر معروف | حدود ثقة IDE. انظر [SECURITY.md](https://github.com/navikt/cplt/blob/main/SECURITY.md) للتخفيفات |
| قراءة/كتابة `~/.copilot` (المصادقة، الإعدادات) | ✅ مسموح | يشمل `file-map-executable` لـ `keytar.node`، `pty.node`، `computer.node` |
| كتابة `~/.copilot/pkg` (الوحدات الأصلية) | 🔒 محجوب على مستوى النواة | يمنع الاستمرارية عبر استبدال الوحدات الأصلية |
| متغيرات البيئة | 🔒 مُنقّاة + مُشدَّدة | تمرّ فقط قائمة سماح آمنة. سكربتات دورة الحياة محجوبة. `--pass-env VAR` يعيد واحدًا |
| قراءة `~/.config/gh/hosts.yml` + `config.yml` | ✅ مسموح (للقراءة فقط) | هذان الملفان فقط. بقية `.config/gh` محجوبة |
| قراءة `~/.config/mise` | ✅ مسموح (للقراءة فقط) | إصدارات الأدوات وPATH، بلا أسرار |
| قراءة `~/.gitconfig`، `~/.config/git/config` | ✅ مسموح (للقراءة فقط) | يُتبَع رابط dotfiles الرمزي إلى هدفه، فيعمل `~/.gitconfig` المُخزَّن |
| قراءة `~/.git-credentials` | 🔒 محجوب على مستوى النواة | `credential.helper = store` يحفظ الرموز النصية الصريحة هنا. لا `--allow-read` يعيد فتحه، مثل `~/.netrc`. **Linux:** منحة على *سلف* (`$HOME` نفسه) لا تزال تكشفه، لأن Landlock لا يستطيع رفض مسار فرعي داخل شجرة مسموح بها |
| قراءة git hooks العامة (`core.hooksPath`) | ✅ مسموح (للقراءة فقط، الكتابة مرفوضة) | يُكتشَف تلقائيًا. يجب أن يكون تحت `$HOME` بعمق ≥3. الكتابة محجوبة صراحةً |
| توقيع commit/tag (`commit.gpgsign`، `tag.gpgsign`) | 🔒 معطَّل | المفاتيح الخاصة في `~/.ssh` و`~/.gnupg` محجوبة، لذا التوقيع معطَّل عبر تجاوز متغير بيئة |
| قراءة `~/Library/Application Support/Microsoft` | ✅ مسموح (للقراءة فقط) | معرّف الجهاز للقياس عن بُعد |
| الوصول إلى macOS Keychain | ⚠️ مسموح (قراءة+كتابة) للوكلاء الذين يخزّنون المصادقة هناك | لا يمكن تقييد المنحة على عنصر واحد، لذا تصل إلى كل مدخل keychain يستطيع الوكيل فتحه. اشترك في `sandbox.keychain_substitute` (تجريبي، معطَّل افتراضيًا) لإسقاطه في التشغيلات التي يستطيع فيها الوكيل المصادقة بدونه — `CLAUDE_CODE_OAUTH_TOKEN` لـ Claude Code، ملف رمز احتياطي موجود لـ Antigravity. انظر [SECURITY.md](https://github.com/navikt/cplt/blob/main/SECURITY.md#keychain-access-is-all-or-nothing) |
| الشبكة الصادرة (المنفذ 443) | ✅ مسموح | كل منفذ آخر محجوب. أضف منافذ إضافية بـ `--allow-port` |
| الصادر إلى localhost | 🔒 محجوب على مستوى النواة (macOS)، ⚠️ قائم على المنفذ على Linux | يمنع الوصول إلى الخدمات المحلية. الوارد لا يزال يعمل للـ proxy. **Linux:** قواعد Landlock أرقام منافذ فقط ولا تستطيع التمييز بين `localhost:443` و`remote:443`، لذا خدمة محلية على منفذ مسموح يمكن الوصول إليها ولا يوجد رفض خاص بـ localhost. استخدم `--with-proxy` لحماية SSRF، انظر [قيود Linux](https://github.com/navikt/cplt/blob/main/docs/security.md#linux) |
| SSH agent (unix socket) | 🔒 محجوب على مستوى النواة (macOS)، ⚠️ بيئة فقط على Linux | يمنع توقيع عمليات git أو SSH إلى المضيفين. **Linux:** `connect()` على unix socket غير مُقيَّد، لذا `SSH_AUTH_SOCK` المحجوز هو الحاجز الوحيد، ووكيل يضبطه بنفسه يمكنه استخدام المفاتيح المحمّلة. يخفي `bwrap` مقبس OpenSSH القياسي تحت `/tmp`، لكن ليس gnome-keyring/gcr أو وكيل systemd تحت `$XDG_RUNTIME_DIR`. انظر [قيود Linux](https://github.com/navikt/cplt/blob/main/docs/security.md#linux) |
| أدوات المطورين (`~/.cargo`، `~/.gradle`، `~/.m2`، `~/.sdkman`، `~/.jenv`، `~/.pyenv`، `~/.konan`، إلخ) | ✅ مسموح (قراءة+كتابة للـ caches) | فقط الأدلة الموجودة على القرص. تُشدَّد وقت التشغيل بما يكتشفه `cplt doctor` |
| ملفات بيانات اعتماد السجلات (`~/.m2/settings.xml`، `~/.gradle/gradle.properties`، `~/.cargo/credentials`) | 🔒 محجوب على مستوى النواة على macOS. على Linux يبقى دليل الأداة الأب قابلًا للقراءة | تجاوز بـ `--allow-read`. انظر [السجلات الخاصة](https://github.com/navikt/cplt/blob/main/docs/known-impacts.md#private-registries) |
| قراءة `~/.npmrc` | 🔒 محجوب على مستوى النواة (كلا المنصتين) | تجاوز بـ `--allow-read`. يكسر yarn 1، انظر [yarn 1](https://github.com/navikt/cplt/blob/main/docs/known-impacts.md#yarn-1-and-unreadable-home-rc-files) |
| كود مصدر Go (`~/go/src`) | 🔒 محجوب على مستوى النواة | فقط `~/go/bin` و`~/go/pkg` قابلان للقراءة |
| قراءة `~/.ssh`، `~/.gnupg`، `~/.aws`، `~/.azure` | 🔒 محجوب على مستوى النواة | |
| قراءة `~/.kube`، `~/.docker`، `~/.nais` | 🔒 محجوب على مستوى النواة | |
| قراءة `~/.password-store`، `~/.terraform.d` | 🔒 محجوب على مستوى النواة | |
| قراءة `~/.config/gcloud`، `~/.config/op` | 🔒 محجوب على مستوى النواة | الملفات الفردية قابلة للتجاوز بـ `--allow-read`. انظر [بيانات اعتماد السحابة](https://github.com/navikt/cplt/blob/main/docs/known-impacts.md#cloud-credential-directories) |
| قراءة أو كتابة `~/.config/cplt`، `~/.nav-pilot` | 🔒 محجوب على مستوى النواة | حالة الأداة التي تقرر ما قد يفعله التشغيل *التالي*. `~/.config/cplt` غير قابل للتجاوز كشجرة كاملة؛ داخل `~/.nav-pilot`، يبقى مسار مسمّى قابلًا للمنح حتى يمكن قراءة حمولة agentpakke مثبّتة |
| قراءة `~/.netrc`، `~/.pypirc`، `~/.vault-token` | 🔒 محجوب على مستوى النواة | غير قابل للتجاوز على كلا المنصتين. تسمية أحدها في `allow.read` خطأ عند بدء التشغيل |
| قراءة `~/.gem/credentials` | 🔒 محجوب على مستوى النواة | غير قابل للتجاوز على كلا المنصتين. تسميته في `allow.read` خطأ عند بدء التشغيل |
| عمليات `gh` CLI المدمّرة (merge، delete، release) | 🔒 مُقيَّد بالأوامر (مُفعَّل افتراضيًا) | إلغاء الاشتراك بـ `--no-gh-guard`. انظر [حارس gh](https://github.com/navikt/cplt/blob/main/docs/gh-guard.md) |
| `git push` إلى الفرع الافتراضي | 🔒 مُقيَّد بالأوامر (مُفعَّل افتراضيًا) | يحجب الدفع إلى `main`/`master`؛ دفع فروع الميزات لا يزال يعمل. `protect_default_branch_only = false` يحجب كل دفع، `git_guard.mode = "warn"` يحذّر فقط، `--no-git-guard` يلغي الاشتراك |
| وراثة العمليات الفرعية | ✅ كل القيود تنطبق على العمليات الفرعية | |
هذا الجدول ملخّص. يسمح الـ sandbox أيضًا بالوصول إلى ملفات النظام (شهادات SSL، `/etc/hosts`)، وأدلة المؤقتة (قراءة وكتابة، بلا تنفيذ)، ومسارات أدوات النظام (`/usr/bin`، `/opt/homebrew`). شغّل `cplt --print-profile` لقواعد SBPL الكاملة.
للاطلاع على نموذج الأمان الكامل، وتحليل التهديدات، واستراتيجية الاختبار، اقرأ [SECURITY.md](https://github.com/navikt/cplt/blob/main/SECURITY.md).
## كيف تقارن cplt
### sandbox الخاص بـ Codex CLI
| المجال | cplt | sandbox الخاص بـ Codex CLI |
| --- | --- | --- |
| التحكم في الشبكة الصادرة | CONNECT proxy مع قوائم سماح/حجب النطاقات | لا تصفية على مستوى النطاق |
| التعامل مع البيئة | قائمة سماح مع حقن بيئة مُشدَّد | نموذج تمرير أكثر بساطة |
| حماية ملفات الأسرار | أنماط رفض مثل `.env*`، `.pem`، `.key` داخل المستودع | وصول محدود بالدليل أساسًا |
| سياسة المستودع | [`.cplt.toml`](https://github.com/navikt/cplt/blob/main/docs/configuration.md#per-repo-configuration-cplttoml) مع تدفق ثقة/موافقة صريح | لا ملف سياسة على مستوى المستودع |
| دعم الوكلاء | Copilot، OpenCode، Gemini CLI، Antigravity CLI، Pi، Claude Code، goose، DeepSeek Harness، أو shell | Codex فقط |
cplt ليست أقوى في كل مكان. يمتلك Codex CLI عزل namespaces على Linux اليوم، ويكشف بالفعل أوضاع sandbox صريحة مثل read-only وworkspace-write. لا تمتلك cplt بعد مصفوفة الأوضاع تلك.
### sandboxes القائمة على Docker
| المجال | cplt | sandbox القائم على Docker |
| --- | --- | --- |
| وقت البدء | فوري تقريبًا للاستخدام العادي لـ CLI | بدء الحاوية عادةً أبطأ |
| التحكم في الشبكة | تصفية صادرة لكل طلب عبر proxy | وصول شبكة كل شيء أو لا شيء عادةً |
| عناصر التحكم في الملفات | قواعد لكل مسار ولكل نمط | عناصر تحكم لكل mount |
| متطلبات المضيف | ملف تنفيذي واحد | يتطلب Docker daemon |
| ملاءمة الحاسوب المؤسسي | يعمل حيث Docker غير متاح أو مقيّد | غالبًا محجوب بسياسة محلية |
لا يزال Docker يمنحك عزلًا أقوى في بعض البيئات، خاصةً إذا أردت نظام ملفات وnamespace عمليات منفصلين تمامًا. تقايض cplt ذلك بإعداد أخف وتكامل أوثق مع الجهاز الذي تطوّر عليه بالفعل.
### أذونات وضع الوكيل في VS Code
تعتمد أدوات مثل وضع الوكيل في VS Code أساسًا على أذونات واجهة المستخدم. تفرض cplt قيودها في النواة، فلا يستطيع الوكيل التملّص منها بـ prompt أو تعليمة معدّلة. يهمّ ذلك أكثر لوكلاء CLI وتعريض بيانات الاعتماد:
- تعمل cplt خارج IDE
- تُصفّى متغيرات البيئة قبل بدء الوكيل
- يمكن حجب الملفات الحساسة حتى عندما تكون داخل المستودع
- تنطبق نفس القيود على العمليات الفرعية
### sandbox الخاص بـ Claude Code (Anthropic Sandbox Runtime)
[Anthropic Sandbox Runtime](https://github.com/anthropic-experimental/sandbox-runtime) (`srt`) هو طبقة العزل التي يستخدمها Claude Code. نفس النهج عالي المستوى مثل cplt، macOS Seatbelt مع فرض على مستوى نواة Linux مع HTTP proxy، لكن تنفيذ مختلف.
| المجال | cplt | Anthropic srt |
| --- | --- | --- |
| اللغة / التسليم | ملف Rust تنفيذي واحد | Node.js + حزمة npm + تبعيات خارجية |
| الواجهة الخلفية على Linux | Landlock LSM (بلا تبعيات، بلا namespaces) | bubblewrap (حاوية عبر user namespaces) |
| تصفية البيئة | قائمة سماح صارمة + رفض اللاحقة (`_TOKEN`، `_SECRET`) | يرث بيئة الأب كاملة (تمرّ الأسرار) |
| حماية أدلة بيانات الاعتماد | 15+ دليلًا محجوبًا افتراضيًا | يجب على المستخدم الإعداد يدويًا |
| حماية DNS rebinding | ✅ يُفحَص IP بعد DNS مقابل النطاقات الخاصة | ❌ غير مُنفَّذ |
| Network proxy | HTTP CONNECT + سماح/حجب النطاقات | HTTP + SOCKS5 + TLS MITM تجريبي |
| SSH git | محجوب في النواة على macOS (مقبس الوكيل مرفوض)؛ على Linux يُحجَز فقط `SSH_AUTH_SOCK` | يُمرَّر عبر SOCKS5 |
| سكربتات مدير الحزم | محجوبة افتراضيًا (`npm_config_ignore_scripts`) | غير محجوبة |
| دعم الوكلاء | Copilot، OpenCode، Gemini، Antigravity، Pi، Claude Code، goose، DSH، Shell | Claude Code |
| الإعداد | TOML (عام + لكل مستودع) | JSON (عام فقط) + تحديثات حية `--control-fd` |
| Library API | ❌ ملف تنفيذي فقط | ✅ مكتبة TypeScript قابلة للتضمين |
cplt أكثر أمانًا خارج الصندوق: تصفية البيئة، حماية بيانات الاعتماد، فحوص DNS rebinding، حجب سكربتات دورة الحياة. srt أكثر مرونة: SOCKS5، فحص TLS، callbacks لكل طلب، تضمين المكتبة. اختيار الواجهة الخلفية على Linux مهم. يحتاج bwrap إلى حلول بديلة على Ubuntu 24.04+ بسبب قيود AppArmor على userns، بينما يتطلب Landlock نواة 5.13 أو أحدث لكن بلا تبعيات خارجية.
### sandbox الخاص بـ GitHub Copilot CLI
يأتي Copilot CLI مع sandbox محلي منذ يونيو 2026، مضمّنًا في
المقعد القياسي. يشغّل أوامر shell عبر Microsoft MXC مع وصول مقيّد
إلى نظام الملفات والشبكة والنظام، على macOS وLinux وWindows.
`/sandbox enable` يفعّله.
إذا كان ذلك يغطيك، استخدمه. لا يكلّف شيئًا إضافيًا، ويعمل على Windows،
وهو ما لا تفعله cplt.
شيئان لا يفعلهما.
السياسة تقيم مع المسؤول، لا مع المستودع. تضبط المؤسسات
سياسة sandbox عبر Intune أو MDM آخر. لا شيء يجاور الكود،
فقاعدة تهمّ مستودعًا واحدًا لا يمكنها أن تتبعه إلى مساهم،
أو إلى CI، أو إلى حاسوب محمول لا يديره MDM. في cplt تكون السياسة
`.cplt.toml` في المستودع. يرى المراجعون التغييرات عليه في طلب
السحب، ويمكن للملف أن يشدّد إعداد المطوّر نفسه لكن لا يخفّفه أبدًا.
يحصر العملية، لا ما تفعله العملية ببيانات الاعتماد التي
تحملها. تغطي تبويبات `/sandbox` نظام الملفات والشبكة وقدرات
النظام، وداخل مستودع Git يُمنح الوكيل قراءة وكتابة
على `.git` افتراضيًا. لا يزال الوكيل المعزول يملك رمز `gh` الخاص بك ووصولك
إلى الدفع. دفع فرع، ودمج طلب سحب، وحذف
مستودع كلها استدعاءات API سليمة من عميل مُصرَّح له، وقاعدة
نظام ملفات أو شبكة لا رأي لها فيها. تلتفّ cplt حول `git` و
`gh` بدلًا من ذلك. يلتزم الوكيل، ويفرّع، ويعيد الأساس بحرية. `gh pr merge`،
`gh repo delete` و`gh release create` محجوبة افتراضيًا. وكذلك
`git push` إلى `main`/`master`؛ دفع فروع الميزات لا يزال يعمل، لأن
`protect_default_branch_only` مُفعَّل. اضبطه على `false` لحجب كل دفع، أو
`git_guard.mode = "warn"` للتحذير فقط.
تشغيل كليهما معقول. يحصر MXC العملية. تقرر الحراس ما
يجوز للوكيل فعله ببيانات الاعتماد التي يحملها.
### ثغرات صادقة
- تمتلك macOS أقوى فرض على مستوى الملفات اليوم. تغطية Linux تتحسّن لكنها ليست متطابقة.
- لا تقدّم cplt بعد إعدادات سياسة بسيطة مثل read-only / workspace-write / full-access.
- إذا أردت عزل حاوية كاملًا، فـ cplt لا تحاول استبدال Docker.
## التثبيت
### Homebrew (موصى به)```bash
brew install navikt/tap/cplt
mise use -g 'github:navikt/cplt@'
mise يختار أصل الإصدار المناسب لمنصتك ويتحقق من إقرار مصدر البناء الخاص به.
ثبّت الإصدار. سلاسل الإصدارات لدينا ليست semver قابلة للمقارنة — فهي تحمل أصفارًا بادئة وشرطتين — لذا قد يحل `mise latest` إلى إصدار أقدم من الأحدث ([navikt/copilot#818](https://github.com/navikt/copilot/issues/818)).
### apt (Debian/Ubuntu، موصى به على Linux)
[navikt/apt](https://navikt.github.io/apt/) هو أرشيف موقّع يُقدَّم عبر
GitHub Pages، ويحمل cplt و nav-pilot لـ amd64 و arm64:```bash
curl -fsSL https://navikt.github.io/apt/keyring/navikt-archive-keyring.gpg \
| sudo tee /usr/share/keyrings/navikt-archive-keyring.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/navikt-archive-keyring.gpg] https://navikt.github.io/apt stable main" \
| sudo tee /etc/apt/sources.list.d/navikt.list
sudo apt update && sudo apt install cplt
إنه مستودع apt عادي يعكس إصداراتنا، وليس حزمة توزيعة لها مسؤولها الخاص. تعمل مهمة النشر الخاصة به كل ساعة وتسحب أحدث ملف .deb من أحدث إصدار لكل أداة، لذا يستغرق الإصدار الذي تم إصداره قبل دقائق ما يصل إلى ساعة ليصبح قابلاً للتثبيت بهذه الطريقة.
تضع الحزمة الملف التنفيذي في /usr/bin/cplt، ومنذ ذلك الحين تتم الترقيات عبر sudo apt upgrade. يرفض cplt update المساس بتثبيت apt ويشير إلى sudo apt upgrade بدلاً من ذلك: استبدال الملف التنفيذي خلف ظهر dpkg سيتم التراجع عنه في تشغيل apt التالي.
بدون الأرشيف، يكون نفس ملف .deb أحد أصول الإصدار:```bash
arch=$(dpkg --print-architecture) # amd64 or arm64
gh release download --repo navikt/cplt --pattern "${arch}.deb"
sudo apt install ./cplt_"${arch}".deb
### curl | bash
للتوزيعات التي ليست مشتقات Debian، ولأجل CI:```bash
curl -fsSL https://raw.githubusercontent.com/navikt/cplt/main/install.sh | bash
الخيارات:```bash
curl -fsSL ... | bash -s -- --version 2026.05.05-174753-75bae5b
curl -fsSL ... | bash -s -- --dir ~/.local/bin
curl -fsSL ... | bash -s -- --no-brew
### التنزيل من الإصدارات
احصل على أحدث إصدار لمنصتك من [إصدارات GitHub](https://github.com/navikt/cplt/releases/latest):```bash
# macOS, Apple Silicon (M1/M2/M3/M4)
curl -fsSL https://github.com/navikt/cplt/releases/latest/download/cplt-aarch64-apple-darwin.tar.gz | tar xz
sudo mv cplt /usr/local/bin/
# macOS, Intel
curl -fsSL https://github.com/navikt/cplt/releases/latest/download/cplt-x86_64-apple-darwin.tar.gz | tar xz
sudo mv cplt /usr/local/bin/
# Linux, x86_64
curl -fsSL https://github.com/navikt/cplt/releases/latest/download/cplt-x86_64-unknown-linux-gnu.tar.gz | tar xz
sudo mv cplt /usr/local/bin/
# Linux, ARM64
curl -fsSL https://github.com/navikt/cplt/releases/latest/download/cplt-aarch64-unknown-linux-gnu.tar.gz | tar xz
sudo mv cplt /usr/local/bin/
كل ملف تنفيذي مُصدَّر يحمل شهادة إثبات مصدر البناء. تحقق منها:```bash gh attestation verify cplt -o navikt
### البناء من المصدر```bash
git clone https://github.com/navikt/cplt.git && cd cplt
cargo build --release
sudo cp target/release/cplt /usr/local/bin/
أو باستخدام mise:```bash mise run install
`mise run install` والبنيات اليدوية تضع cplt في `/usr/local/bin/cplt`. إذا كان لديك أيضًا بناء Homebrew في `/opt/homebrew/bin/cplt`، فضع `/usr/local/bin` أولاً في `PATH` حتى يفوز بناء التطوير الخاص بك:```bash
# Check which cplt is active
which cplt
# If it shows /opt/homebrew/bin/cplt, reorder your PATH:
export PATH="/usr/local/bin:$PATH"
أو شغّل /usr/local/bin/cplt صراحةً وتجاوز تحليل PATH بالكامل.
لا يمتلك cplt أي خلفية sandbox على Windows. التطبيق يتم عبر Apple Seatbelt على macOS وLandlock LSM على Linux، لذا لا يوجد شيء لتشغيله أصليًا على Windows. المسار المدعوم هو WSL2، حيث يكون cplt تثبيتًا عاديًا على Linux ويكون الـ sandbox مفروضًا على مستوى النواة. كل فرع من فروع نواة Microsoft يبني CONFIG_SECURITY_LANDLOCK=y ويسرد landlock أولًا في CONFIG_LSM (config-wsl)، ويُشحن منذ النواة 5.15.57.1، وسطر أوامر النواة الافتراضي في WSL لا يضبط أي تجاوز lsm=.
في PowerShell، مرة واحدة:```powershell wsl --install # WSL2 + the default distro (now Ubuntu 26.04 LTS), then reboot wsl --install -d Ubuntu-24.04 # ...or pin an older release wsl --update # keep the Microsoft kernel current, see the ABI note below
كل ما يلي يعمل **داخل التوزيعة** (`wsl`، أو ملف تعريف Ubuntu في Windows Terminal)، وليس في PowerShell:```bash
# 1. Node. Copilot CLI requires Node 22+
# Ubuntu 26.04 ships 22.x, so apt is enough:
sudo apt update && sudo apt install -y nodejs npm
# Ubuntu 24.04 ships Node 18, too old. Use nvm, fnm, or NodeSource there instead.
# 2. GitHub CLI, and log in. Ubuntu's universe package works but lags
# (2.45 on 24.04); add GitHub's apt repo if you want a current gh:
# https://github.com/cli/cli/blob/trunk/docs/install_linux.md
sudo apt install -y gh
gh auth login
# 3. The agent, installed in the distro, never on the Windows side
npm install -g @github/copilot
# 4. cplt, from the apt archive. The default distro is Ubuntu, so this is
# the same route as on any other Debian derivative.
curl -fsSL https://navikt.github.io/apt/keyring/navikt-archive-keyring.gpg \
| sudo tee /usr/share/keyrings/navikt-archive-keyring.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/navikt-archive-keyring.gpg] https://navikt.github.io/apt stable main" \
| sudo tee /etc/apt/sources.list.d/navikt.list
sudo apt update && sudo apt install cplt
# 5. Check the result
cplt doctor
لا تقم بتثبيت Copilot CLI على جانب Windows. عند تفعيل interop (وهو الوضع الافتراضي)، يُلحق PATH الخاص بـ Windows بمسار التوزيعة، لذا فإن تنفيذ npm install -g @github/copilot على جانب Windows يظهر داخل التوزيعة على المسار /mnt/c/Users/<user>/AppData/Roaming/npm/copilot. هذا تثبيت Windows يُوصَل إليه عبر interop. لا يمكن تشغيله في بيئة Linux المعزولة (sandbox)، كما أن shim الخاص بـ npm ينفّذ node الذي لن تتوفر عليه التوزيعة إلا إذا كنت قد ثبّت واحدًا هناك أيضًا. كانت الأعراض سابقًا عبارة عن خطأ استخراج وقت التشغيل غير ذي صلة. الآن يحدد cplt السبب عندما يحلّ agent تحت /mnt/<drive>/ و كان يعمل تحت WSL، ويُبلّغ cplt doctor عنه كفحص فاشل بدلًا من اجتيازه (#188). يُكتشف WSL من حالة تملكها النواة، إما /run/WSL أو اسم النواة في /proc/sys/kernel/osrelease و /proc/version، وليس من WSL_DISTRO_NAME، الذي يكون غائبًا تحت sudo وفي وحدات systemd ويمكن لأي عملية تعيينه. على جهاز Linux عادي يُترك دون مساس. فهو نقطة تحميل عادية هناك.
لهذا الفحص حدّان، وكلاهما مقصود. فهو يعتمد على جذر التحميل التلقائي الافتراضي، لذا إذا كنت قد نقلته ([automount] root في /etc/wsl.conf) فلن يُتعرّف على تثبيت جانب Windows وستحصل على الفشل القديم الأقل إفادة مع المسار فيه. كما أن إيقاف interop يمنع تسرّب PATH الخاص بـ Windows لكنه لا يلغي تحميل /mnt/c.
النواة و Landlock ABI. يأتي WSL الحالي (2.7.x وما بعده) بنواة Linux 6.18، مما يمنح Landlock ABI 7 — كل ما يستخدمه cplt باستثناء حق connect() الخاص بـ unix-socket، الذي يحتاج ABI 9 (نواة 7.1). التثبيت الذي لا يزال على خط نواة 6.6 يحصل على ABI 3: تُفرض قواعد نظام الملفات، لكن قواعد منافذ TCP (ABI 4)، وتقييد ioctl (ABI 5)، وتحديد نطاق signal/abstract-socket (ABI 6) غير متاحة، وترتد تصفية الشبكة إلى وسيط CONNECT. ينقلك wsl --update إلى الأمام. يطبع cplt doctor إصدار النواة و ABI الذي وجده، وهو الفحص المهم على جهازك.
لا تعطّل Landlock في
.wslconfig. إن[wsl2] kernelCommandLineبقائمةlsm=تُغفلlandlock، أو[wsl2] kernel=مخصص مبني بدونCONFIG_SECURITY_LANDLOCK، يزيل فرض النواة الذي يعتمد عليه cplt، وسيُبلّغcplt doctorعن Landlock كغير متاح.
أبقِ المشروع في نظام ملفات Linux. اعمل في ~/src/... داخل التوزيعة بدلًا من /mnt/c/Users/.... إرشادات Microsoft نفسها تقول إن الوصول إلى الملفات عبر أنظمة التشغيل أبطأ بشكل ملحوظ، ويُقدَّم /mnt/c عبر 9p افتراضيًا اعتبارًا من WSL 2.9.x (virtiofs اختياري عبر [wsl2] virtiofs=true). والأهم من ذلك، لم نتحقق من كيفية فرض Landlock للقواعد على نقطة التحميل تلك. لا توثّق النواة أي استثناء لأنظمة الملفات المدعومة بالشبكة أو FUSE، فقط pipes و sockets و nsfs، كما أن مجموعة اختبارات Landlock نفسها تختبر 9p و FUSE، لذا نتوقع أن يعمل. لم يؤكد ذلك أحد هنا. تعامل مع مشروع تحت /mnt/c على أنه غير مُثبت بدلًا من مدعوم.
Bubblewrap. تحجب Ubuntu 23.10+ مساحات أسماء المستخدمين غير المميزة عبر kernel.apparmor_restrict_unprivileged_userns، مما يعطّل bwrap. يأتي هذا sysctl من رقعة نواة Ubuntu الغائبة عن نواة Microsoft، لذا يُتوقع أن تعمل طبقة Bubblewrap الاختيارية على Ubuntu-under-WSL2. هذا استنتاج من مصدر النواة، وليس شيئًا قمنا بتشغيله. إذا فشل bwrap هناك، فيرجى الإبلاغ عن ذلك في #189. مرشّح seccomp الخاص بـ cplt هو برنامج BPF عادي من نوع PR_SET_SECCOMP، يتراكم فوق المرشّح الذي يثبّته WSL في كل عملية.
لم يتم التحقق بعد على تثبيت WSL2 حقيقي. تم التحقق من المصدر: أن Landlock مُجمَّع ومذكور أولًا في
CONFIG_LSMعلى نواة Microsoft؛ واكتشاف/mnt/<drive>/، وإشارات WSL التي يستخدمها، ونص الخطأ الخاص بها؛ وأنcplt doctorيفشل على مثل هذا agent ويطبع النواة + Landlock ABI؛ ومتطلبات 5.13+/6.7+؛ وأنinstall.shيثبّت ثنائي إصدار Linux. لا يزال غير مُتحقق منه من قبل أي شخص هنا: كيفية تصرف Landlock على/mnt/c، وما إذا كان Bubblewrap يعمل تحت WSL2، وإصدارات الحزم الدقيقة التي يشحنها إصدار توزيعتك، والتسلسل أعلاه من البداية إلى النهاية. إذا قمت بتشغيله، فيرجى الإبلاغ عمّا حدث فعليًا في #189.
افتراضيًا تحصل على البيئة المعزولة بكتابة cplt. لجعل copilot المجرّد يعمل معزولًا أيضًا:```bash
cplt --shell-install
هذا يكتشف الصدفة الخاصة بك، ويضيف الاسم المستعار إلى ملف rc الخاص بك، ويطبع ما قام به. شغّله بقدر ما تريد، لن يضيف تكرارات.
`--agent` يحدد الأمر الذي يحصل على الاسم المستعار، وكل وكيل يمكن لـ cplt تشغيله متاح:```bash
cplt --shell-install --agent opencode # 'opencode' runs sandboxed
cplt --shell-install --agent claude # and 'claude', alongside the others
كل عملية تثبيت تضيف إلى ملف rc الخاص بك بدلاً من استبدال ما هو موجود، لذا يمكنك عزل أكبر عدد من الوكلاء بقدر ما تستخدم. بدون --agent تحصل على copilot، وهو ما كان العلم يثبته دائمًا.
--agent antigravity يثبّت أسماء مستعارة لكل من antigravity و agy، حيث أن أيًا من الاسمين يبدأ نفس الوكيل.
أعد تشغيل shell الخاص بك أو نفّذ source على الملف للتفعيل.
لا يوجد اسم مستعار لـ --agent shell: لا يوجد ملف تنفيذي shell لتظليله. اكتب cplt --agent shell للحصول على shell معزول، أو cplt exec -- <command> لأمر واحد.
إذا كنت تفضل عدم استخدام --shell-install، أضف السطر بنفسك:```bash
eval "$(cplt --shell-setup --agent opencode)"
alias opencode 'cplt --agent opencode'
نفس النمط الذي تستخدمه mise و direnv و starship.
</details>
**لماذا يُسمّي كل اختصار وكيله.** `alias opencode=cplt` لن يفعل ما يبدو أنه يفعله. الأمر المجرّد `cplt` يختار وكيله من `--agent`، ثم من ملف الإعدادات، ثم من أي شيء يجده في PATH — واكتشاف PATH يفضّل `copilot`. كتابة `opencode` ستُعزل Copilot بدلاً من ذلك، دون أي شيء على الشاشة يوضّح ذلك. يمرّر الاختصار `--agent` بحيث يكون الأمر الذي تكتبه هو الوكيل الذي تحصل عليه.
**لماذا اختصار بدلاً من رابط رمزي؟** يُثبَّت كل من cplt و Copilot CLI في نفس دليل bin الخاص بـ Homebrew (`/opt/homebrew/bin/`)، ويمكن لملف واحد فقط باسم `copilot` أن يوجد هناك، لذا سيتعارض الرابط الرمزي. يتجنّب الاختصار ذلك. يبقى الملف التنفيذي الحقيقي `copilot` في PATH حيث يمكن لـ cplt العثور عليه وتغليفه، ويعيد الاختصار توجيه أمرك.
> **ملاحظة:** يرفض cplt التداخل. إذا اكتشف أنه يعمل بالفعل داخل بيئة معزولة (عبر متغير البيئة `__CPLT_WRAPPED`)، فلن يبدأ مرة أخرى. لا تزال الأوامر الفرعية للقراءة فقط مثل `--print-profile` و `cplt doctor` تعمل داخل بيئة معزولة موجودة.
## الاستخدام```
cplt [OPTIONS] [-- <AGENT_ARGS>...]
/mnt/c| Shell | الملف المعدّل | ما تمت إضافته (لـ --agent opencode) |
|---|
| zsh (افتراضي macOS) | ~/.zshrc | eval "$(cplt --shell-setup --agent opencode)" |
| bash | ~/.bashrc | eval "$(cplt --shell-setup --agent opencode)" |
| fish | ~/.config/fish/conf.d/cplt.fish | alias opencode 'cplt --agent opencode' |
كل ما يأتي بعد -- يذهب مباشرة إلى عملية الوكيل (copilot، opencode، gemini، antigravity، pi، claude، goose، dsh، أو shell).
يضبط الإعداد المسبق خط أساس لمفاتيح تشغيل العزل الخمسة الرئيسية بعلم واحد بدلاً من قائمة منها. لا تزال الأعلام الفردية تتغلب على الإعداد المسبق، لذا فإن --preset permissive --no-allow-tmp-exec يفعل ما يقوله. قابل للضبط أيضاً كـ [sandbox] preset = "..." في الإعدادات.
| العلم | ما يفعله |
|---|---|
--preset strict | إغلاق كامل للشبكة. جميع المفاتيح الخمسة معطلة، بالإضافة إلى gh_guard وgit_guard وproxy.forced (خروج عبر وكيل إجباري) وproxy.default_allowlist (قائمة نطاقات مسموح بها تفشل مغلقة) مفعّلة. مخرج طوارئ: --allow-all-domains يعطّل قائمة السماح فقط |
--preset standard | الإعدادات الافتراضية الحالية. جميع الخمسة معطلة، يبقى دليل المسودة مفعّلاً. نفس تمرير أي إعداد مسبق |
--preset permissive | يفعّل allow_localhost_any وallow_tmp_exec وallow_lifecycle_scripts |
--preset full-trust | ⚠️ خطير. يفعّل جميع الخمسة، مضيفاً allow_env_files وallow_docker |
مصفوفة الإعدادات المسبقة الكاملة وترتيب الحل: docs/configuration.md.
دليل المشروع هو مساحة العمل القابلة للكتابة، بالإضافة إلى قائمة سماح ضيقة مطلوبة للمصادقة ووقت التشغيل والأدوات (انظر الجدول أعلاه). تحجب النواة كل شيء آخر، بما في ذلك مفاتيح SSH وبيانات اعتماد السحابة.
| العلم | ما يفعله |
|---|---|
-d, --project-dir <DIR> | الدليل الذي يمكن لـ Copilot العمل فيه. الافتراضي هو جذر مستودع git الحالي |
--allow-read <PATH> | السماح لـ Copilot بقراءة ملفات خارج المشروع، للقراءة فقط. قابل للتكرار |
--allow-write <PATH> | السماح لـ Copilot بالقراءة والكتابة خارج المشروع. استخدمه بحذر. قابل للتكرار. الشجرة قابلة للكتابة لكن غير قابلة للتنفيذ — الشجرة التي تكون الاثنين معاً هي مسار إسقاط ثنائي، لذا فإن allow.write على ~/.cargo يوقف أيضاً تشغيل ~/.cargo/bin. استخدم --allow-exec على شجرة منفصلة غير متداخلة عندما تحتاج كليهما |
--allow-exec <PATH> | ⚠️ خطير. السماح للوكيل بتنفيذ ملفات ثنائية من شجرة خارج أدلة الأدوات الافتراضية — بادئة Homebrew أو سلسلة أدوات منقولة، مثلاً. يمنح القراءة والتنفيذ، وليس الكتابة أبداً. قابل للتكرار. يُرفض لجذر غير آمن (/، /tmp، $HOME وآبائه، أدلة نظام المنصة) ولأي شجرة تتداخل مع شجرة قابلة للكتابة — دليل المشروع، أو منحة --allow-write، أو دليل أدوات قابل للكتابة مثل ~/.cache، أو دليل بيانات وكيل قابل للكتابة (~/.claude، ~/.local/share/opencode، ~/.pi/agent وما شابه)، أو .git الحقيقي لشجرة عمل أو مستودع مجرد، أو شجرة تجعلها الواجهات الخلفية قابلة للكتابة بدون أي منحة على الإطلاق (/tmp و/dev/shm على Linux؛ /private/tmp و/private/var/folders على macOS): قابل للكتابة زائد قابل للتنفيذ هو مسار إسقاط ثنائي، ولا يمكن لأي من الواجهتين الخلفيتين طرح منحة الكتابة من منحة التنفيذ |
--allow-socket <PATH> | ⚠️ خطير. السماح بمسار مقبس نطاق Unix، على سبيل المثال خادم LSP مخصص أو مقبس قاعدة بيانات. قابل للتكرار. كل ما هو على الطرف الآخر يعمل خارج العزل، لذا فإن توجيه هذا إلى docker.sock أو مقبس وكيل يعادل --allow-docker، والضمان الوحيد هو رفض تداخلات --deny-path. على Linux لا يفعل شيئاً دون نواة 7.1، لأن اتصالات مقبس unix لا تُبوَّب بواسطة Landlock قبل ABI v9 (انظر قيود Linux) |
--deny-path <PATH> | حجب مسار كان سيُسمح به بخلاف ذلك. الرفض يفوز دائماً. قابل للتكرار |
يقوم cplt بتعقيم بيئة العملية الفرعية افتراضياً. تمر فقط المتغيرات الآمنة، وتُجرَّد بيانات اعتماد السحابة وعناوين URL لقواعد البيانات ورموز الحزم. كما يحقن متغيرات تقوية تحجب سكريبتات دورة حياة npm/yarn/pnpm (خطافات postinstall، ناقل هجوم سلسلة التوريد رقم واحد)، وتعطّل توقيع git commit وtag (بما أن ~/.ssh و~/.gnupg غير قابلين للوصول داخل العزل)، وتلغي قياس عن بعد لأدوات المطورين (DO_NOT_TRACK=1، NEXT_TELEMETRY_DISABLED=1، TURBO_TELEMETRY_DISABLED=1، CHECKPOINT_DISABLE=1، وغيرها).
ما يمر:
| الفئة | أمثلة | كيف |
|---|---|---|
| النظام الأساسي | HOME، USER، PATH، SHELL، TMPDIR، LANG | قائمة سماح صريحة |
| الطرفية | TERM، COLORTERM، TERM_PROGRAM | قائمة سماح صريحة |
| المحرر | EDITOR، VISUAL، PAGER | قائمة سماح صريحة |
| رموز المصادقة | GH_TOKEN، GITHUB_TOKEN، COPILOT_GITHUB_TOKEN | تُمرَّر فقط إذا قمت بتعيينها مسبقاً. يستخدم حارس gh ملفاً لمرة واحدة بدلاً من ذلك |
| إعدادات Copilot | COPILOT_DEBUG، COPILOT_* | قائمة سماح بالبادئة |
| أوقات تشغيل اللغات | NODE_*، GOPATH، CARGO_HOME، JAVA_HOME، VIRTUAL_ENV، PYTHONPATH | قائمة سماح صريحة |
| مديرو الأدوات | NVM_*، FNM_*، PYENV_*، MISE_*، SDKMAN_*، COREPACK_*، YARN_* | قائمة سماح بالبادئة |
| OpenTelemetry | OTEL_EXPORTER_OTLP_ENDPOINT، OTEL_SERVICE_NAME، OTEL_RESOURCE_ATTRIBUTES، OTEL_* | قائمة سماح بالبادئة (OTEL_EXPORTER_OTLP_HEADERS قد يحمل مصادقة اختيارية) |
| أدلة XDG | XDG_CONFIG_HOME، XDG_DATA_HOME، XDG_STATE_HOME، XDG_CACHE_HOME | قائمة سماح صريحة |
قائمة سماح بالبادئة مع حماية اللاحقة السرية. المتغير المطابق لبادئة مسموح بها مثل COPILOT_* أو YARN_* لا يزال يُسقَط إذا انتهى بلاحقة حاملة للأسرار: _TOKEN، _AUTH، _SECRET، _SECRET_KEY، _KEY، _PASSWORD، أو _CREDENTIALS. لذا يمر COPILOT_DEBUG ولا يمر COPILOT_API_KEY.
محجوب دائماً: AWS_*، AZURE_*، NPM_TOKEN، DATABASE_URL، VAULT_TOKEN، SSH_AUTH_SOCK، متغيرات Docker، رموز CI، وأي شيء ليس في قائمة السماح.
| العلم | ما يفعله |
|---|---|
--pass-env <VAR> | تمرير متغير بيئة واحد إلى الوكيل. قابل للتكرار |
--inherit-env | ⚠️ خطير. وراثة بيئة العملية الأصلية بالكامل. يجرّد فقط NO_COLOR، FORCE_COLOR، SSH_AUTH_SOCK، SSH_AGENT_PID. للتصحيح فقط |
| العلم | ما يفعله |
|---|---|
--allow-lifecycle-scripts | السماح بتشغيل سكريبتات دورة حياة npm/yarn/pnpm (خطافات postinstall). محجوبة افتراضياً. استخدمه عندما يحتاج npm install إليها |
--allow-gpg-signing | السماح بتوقيع GPG للـ commit والـ tag داخل العزل. يمنح وصولاً للقراءة فقط إلى حلقة المفاتيح العامة ومقبس وكيل GPG. تبقى المفاتيح الخاصة مرفوضة. انظر توقيع GPG |
--allow-jvm-attach | السماح بمقابس unix لـ JVM Attach API في /tmp. مطلوب لـ MockK inline mocking وMockito inline agents وByteBuddy. انظر JVM Attach API |
--allow-msbuild | السماح بمقابس unix لعقدة عامل MSBuild في /tmp. مطلوب لـ dotnet build. لا يفعّل خادم MSBuild الدائم. انظر MSBuild worker-node IPC |
--no-scratch-dir | تعطيل دليل المسودة لكل جلسة، وهو مفعّل افتراضياً. لن يُعاد توجيه TMPDIR |
--scratch-dir | تفعيل دليل المسودة لكل جلسة صراحةً. هو الافتراضي بالفعل، لذا هذا لتجاوز scratch_dir = false في الإعدادات |
--brief | 🧪 تجريبي. كتابة موجز العزل الموجه للوكيل إلى دليل المسودة (CPLT_BRIEF.md). معطّل افتراضياً. أيضاً sandbox.brief = true في الإعدادات. غير مستقر، لذا قد يتغير أو يُزال في إصدار مستقبلي |
--no-brief | إيقاف موجز العزل لهذه الجلسة، متجاوزاً sandbox.brief = true في الإعدادات. يمنع أيضاً كتلة AGENTS.md، التي تعتمد على الموجز |
--agents-md | 🧪 تجريبي. مع --brief، اكتب أيضاً كتلة cplt المُدارة في AGENTS.md الخاص بالمشروع. معطّل افتراضياً. أيضاً sandbox.agents_md = true في الإعدادات. لا تأثير بدون --brief. غير مستقر، لذا قد يتغير أو يُزال في إصدار مستقبلي |
--no-agents-md |
يكتشف cplt الأدوات المثبتة تلقائياً ويكتب قواعد العزل لتطابقها. عموماً، فقط الأدلة الموجودة على القرص تحصل على قواعد، لذا لا توجد مسارات وهمية. على macOS، تُضمَّن أدلة التطبيقات القابلة للكتابة عند اكتشافها حتى لو لم تكن موجودة بعد، لذا يمكن إنشاؤها عند أول استخدام. لا يمكن لـ Linux السماح بالكتابة إلى مسار غير موجود، لذا يجب أن يحدث الإنشاء خارج العزل هناك.
| وقت التشغيل | أدلة المنزل | متغيرات البيئة / البادئات | الاكتشاف |
|---|---|---|---|
| Node.js | .nvm، .local/share/fnm، .local/bin | NODE_*، NPM_*، NVM_*، FNM_* | node |
| Rust | .cargo، .rustup | CARGO_HOME، RUSTUP_HOME | cargo |
| Go | go/bin، go/pkg | GOPATH، GOROOT، GOCACHE، إلخ. | go |
| Java/Kotlin (JVM) | .sdkman، .jenv، .gradle، .m2 | JAVA_HOME، JAVA_TOOL_OPTIONS، GRADLE_*، MAVEN_*، SDKMAN_*، JENV_* | java، gradle |
| Kotlin Native | .konan | لا شيء | لا شيء |
| Python | .pyenv | VIRTUAL_ENV، PYTHONPATH، PYENV_ROOT، PYENV_* | python3 |
| Yarn Berry | .yarn | YARN_* (التقوية تتجاوز YARN_ENABLE_SCRIPTS) | yarn |
| pnpm | Library/pnpm، .local/share/pnpm | PNPM_HOME | pnpm |
| Corepack | لا شيء | COREPACK_* | لا شيء |
| mise | .local/share/mise، |
شغّل cplt doctor لمعرفة ما إذا كان cplt سيعمل هنا لوكيلك، وcplt doctor --verbose لكل ما اكتشفه على جهازك.
| العلم | ما يفعله |
|---|---|
--doctor | مهمَل. استخدم الأمر الفرعي cplt doctor بدلاً من ذلك |
--print-profile | طباعة ملف تعريف العزل المُولَّد (SBPL) والخروج |
--show-denials | بث سجلات رفض عزل macOS في الوقت الفعلي |
--no-validate | تخطي فحص بدء التشغيل الذي يتحقق من أن قيود العزل نشطة |
-y, --yes | تخطي مطالبة التأكيد التفاعلية. لا يزال ملخص الإعدادات يُطبع، للقابلية للتدقيق. مطلوب عندما لا يكون stdin طرفية، لذا تحتاجه CI والسكريبتات |
-q, --quiet | كتم لافتة بدء التشغيل والرسائل غير الضرورية. لا تزال الأخطاء والتحذيرات تُطبع. أيضاً sandbox.quiet = true في الإعدادات |
--no-quiet | تجاوز sandbox.quiet = true وإظهار ملخص بدء التشغيل على أي حال |
--no-audit | تخطي تقرير التغييرات بعد الجلسة. عادةً يقارن cplt شجرة العمل مقابل commit أساسي مثبّت قبل التشغيل ويسرد ما لمسته الجلسة، مع الإشارة إلى المسارات الحساسة. -q يكتمه أيضاً |
--init-config | إنشاء ملف إعدادات أولي في ~/.config/cplt/config.toml والخروج |
تُترجم هذه إلى أعلام جلسة الوكيل نفسه، لذا لا تحتاج إلى فاصل --.
| العلم | ما يفعله |
|---|---|
--resume[=SESSION] | استئناف جلسة سابقة. --resume المجرد يختار تفاعلياً، --resume=NAME يختار بالاسم أو المعرّف |
--continue | استئناف أحدث جلسة في الدليل الحالي |
--remote | تفعيل التحكم عن بعد، حتى تتمكن من مراقبة الجلسة وتوجيهها من GitHub.com أو الجوال |
--name SESSION | تسمية الجلسة حتى يتمكن --resume=NAME من إيجادها لاحقاً |
يُترجم --continue و--resume أيضاً لـ OpenCode وAntigravity وClaude Code:
| علم cplt | Copilot | OpenCode | Antigravity (agy) | Claude Code |
|---|---|---|---|---|
--continue | --continue | --continue | --continue | --continue |
--resume | --resume | --continue¹ | --continue¹ | --resume |
--resume=ID | --resume=ID | --session ID | --conversation ID | --resume ID |
--remote | --remote | مُتجاهَل | مُتجاهَل | مُتجاهَل |
--name NAME | --name NAME | مُتجاهَل | مُتجاهَل | مُتجاهَل |
¹ لا يمتلك OpenCode ولا Antigravity منتقي جلسات تفاعلي، لذا فإن --resume المجرد يعني "متابعة الجلسة الأخيرة". يمتلك Claude Code واحداً، لذا يُترجم مباشرة.
--remote و--name خاصان بـ Copilot فقط. لا يحصل Pi ووضع shell على أي ترجمة على الإطلاق، لذا تُسقَط الأعلام الأربعة لهما. الاستئناف التلقائي آلية منفصلة: عندما تستدعي cplt بدون وسائط تمرير وبدون أعلام جلسة، فإنه يضيف --resume نيابة عنك، وهذا ينطبق على Copilot فقط.
اجمعها مع أعلام العزل ووسائط التمرير --:```bash
cplt --resume=my-task # resume by name
cplt --remote --name my-task -- -p "fix tests" # remote + named + prompt
### الوكلاء
اختر واحدًا باستخدام `--agent <name>`، أو اجعله الافتراضي باستخدام `cplt config set sandbox.agent <name>`. يتم اكتشاف Copilot وOpenCode وAntigravity تلقائيًا من `PATH` بهذا الترتيب عندما لا تحدد اسمًا.
| الوكيل | قيمة `--agent` | الاكتشاف التلقائي | المصادقة |
| --- | --- | --- | --- |
| GitHub Copilot CLI | `copilot` | نعم، الأولوية 1 | رمز GitHub، من Keychain أو `gh` |
| [OpenCode](https://opencode.ai/) | `opencode` | نعم، الأولوية 2 | اشتراك Copilot عبر `/connect`، أو `--pass-env ANTHROPIC_API_KEY` |
| [Antigravity CLI](https://github.com/google-antigravity/antigravity-cli) | `antigravity`، الأسماء المستعارة `agy` و`agi` | نعم، الأولوية 3 | Google OAuth في المتصفح |
| [Pi](https://github.com/earendil-works/pi) | `pi` | لا | `--pass-env ANTHROPIC_API_KEY` وما شابهها |
| [Claude Code](https://docs.anthropic.com/en/docs/claude-code) | `claude`، الأسماء المستعارة `cc` و`claude-code` | لا | اشتراك OAuth في `~/.claude` أو Keychain، أو `CLAUDE_CODE_OAUTH_TOKEN` (يلغي منح Keychain)، أو `--pass-env ANTHROPIC_API_KEY` |
| [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) | `dsh`، الأسماء المستعارة `deepseek` و`deepseek-harness` | لا | `--pass-env DEEPSEEK_API_KEY`، أو `$DSH_HOME/.env` (`~/.dsh/.env`) |
| صدفة الطرفية الخاصة بك | `shell` | لا | لا شيء |
- **لا يتم اكتشاف Pi وClaude Code وgoose وDeepSeek Harness تلقائيًا أبدًا.** `pi` و`dsh` أسماء ثنائية عامة قد تتعارض مع شيء آخر على جهازك، ويجب اختيار Claude Code عن قصد.
- **مفاتيح API الخاصة بطرف ثالث اختيارية.** لا تمر `ANTHROPIC_API_KEY` و`OPENAI_API_KEY` و`GEMINI_API_KEY` و`OPENROUTER_API_KEY` و`ANTHROPIC_AUTH_TOKEN` و`CLAUDE_CODE_OAUTH_TOKEN` ومتغيرات توجيه Bedrock/Vertex (`CLAUDE_CODE_USE_BEDROCK`، `AWS_BEARER_TOKEN_BEDROCK`، `CLAUDE_CODE_USE_VERTEX`، `ANTHROPIC_VERTEX_PROJECT_ID`، `GOOGLE_CLOUD_PROJECT`) أبدًا إلا إذا حددتها باستخدام `--pass-env`.
- **مصادقة الاشتراك لا تحتاج إلى متغير بيئة.** يخزّن تدفق جهاز `/connect` في OpenCode رمزه في `~/.local/share/opencode/auth.json`، ويعيش رمز OAuth في Claude Code في `~/.claude` (`.credentials.json` على Linux) أو في Keychain على macOS. كلاهما يمكن الوصول إليه داخل البيئة المعزولة، لذا لا يلحّ cplt بشأن مفتاح API مفقود لأي منهما.
- **تدفقات OAuth في المتصفح تحتاج إلى `--allow-browser`** عند ظهور مطالبة تسجيل الدخول. يشمل ذلك Antigravity؛ كل وكيل آخر هنا يستخدم تدفق جهاز يطبع رمزًا وعنوان URL ولا يحتاج إلى متصفح. تتيح هذه العلامة للوكيل تشغيل أي تطبيق خارج البيئة المعزولة ولا يمكن تضييقها إلى عناوين URL، لذا فعّلها لتسجيل الدخول ثم عطّلها مجددًا — راجع [جدول العلامات](#sandbox-toggles) و[docs/security.md](https://github.com/navikt/cplt/blob/main/docs/security.md#--allow-browser-is-a-sandbox-escape-and-cannot-be-scoped).
- **التحديث التلقائي في Claude Code معطّل** باستخدام `DISABLE_AUTOUPDATER=1`. لا يملك Claude Code علامة `--no-auto-update`، والتحديث الذاتي داخل البيئة المعزولة يمثل ناقل استمرارية، وسيفشل على أي حال مع مسارات التثبيت للقراءة فقط.
- **يتم احترام `CLAUDE_CONFIG_DIR`.** عند تعيينه، يمنح cplt ذلك الدليل بدلاً من `~/.claude` ويمرر المتغير، لذا يستمر جذر التكوين المنقول في العمل.
- OpenCode هو [عميل Copilot مدعوم رسميًا](https://github.blog/changelog/2026-01-16-github-copilot-now-supports-opencode/)، لذا يعمل اشتراك Copilot الحالي لديك مع `/connect` داخل OpenCode.
أدلة التكوين لكل وكيل، واستخدام Keychain، وأذونات التنفيذ، وعزل متغيرات البيئة موجودة في [SECURITY.md](https://github.com/navikt/cplt/blob/main/SECURITY.md#supported-agents).
### دعم goose
يمكن لـ cplt عزل [goose](https://github.com/aaif-goose/goose)، وكيل الذكاء الاصطناعي مفتوح المصدر (الملف الثنائي `goose`). تم التحقق منه مقابل goose 1.48.0.```bash
# Run goose (must be explicit — not auto-detected)
cplt --agent goose
# goose is provider-agnostic — pass your provider's API key
cplt --agent goose --pass-env ANTHROPIC_API_KEY
cplt --agent goose --pass-env OPENAI_API_KEY
# Skip the keyring entirely: keep the key in the environment
GOOSE_DISABLE_KEYRING=1 cplt --agent goose --pass-env OPENAI_API_KEY --pass-env GOOSE_DISABLE_KEYRING
# Set goose as your default agent
cplt config set sandbox.agent goose
ملاحظات أمنية بشأن goose:
--agent goose أو اضبط sandbox.agent = "goose" في الإعداداتANTHROPIC_API_KEY، OPENAI_API_KEY، AZURE_OPENAI_API_KEY، GOOGLE_API_KEY، DATABRICKS_HOST/DATABRICKS_TOKEN، GROQ_API_KEY، OPENROUTER_API_KEY، XAI_API_KEY، AWS_BEARER_TOKEN_BEDROCK) هي تلميحات مصادقة معروفة ويجب تمريرها عبر --pass-env. يقرأ goose المتغيّر GOOGLE_API_KEY وليس GEMINI_API_KEY. أي مزوّد خارج هذه المجموعة الفرعية يظل يعمل: سمِّ متغيّره باستخدام --pass-env--observe-domains، لذا فإن قائمة السماح المدمجة لديه هي قاعدة سجل الحزم المشتركة فقط. أضف نطاق مزوّدك عبر allowed_domains قبل تمكين --default-allowlistGOOSE_DISABLE_KEYRING=1 goose يستخدم secrets.yaml في مجلد إعداداته بدلًا من ذلك، كما أن تمرير المفتاح عبر --pass-env يتجنّب الأسرار المخزّنة كليًا. على Linux يستخدم goose خدمة D-Bus Secret Service، وهو ما لا يؤثر عليه منح Keychain~/.config/goose/config.yaml عن مدخلات extensions: التي يُشغّل goose أمر cmd الخاص بها عند بداية كل جلسة، لذا فإن مجلد إعدادات قابل للكتابة يُعدّ ناقلًا لاستمرارية الاستيطان على المضيف. الجلسات العادية لا تكتب فيه؛ تغييرات /mode وأذونات الأدوات المحفوظة لا تنجو من تشغيل داخل صندوق رمل. أعد التهيئة باستخدام goose configure خارج cplt~/.local/share/goose/) وحالته (~/.local/state/goose/) قابلة للكتابة، مع رفض التنفيذ. يستخدم goose مسارات XDG هذه على macOS أيضًا، ويحترم تجاوزات XDG_* هناك--continue و--resume المجرّد يُقابلان goose session --resume؛ و--resume=ID يُقابل goose session --resume --session-id ID؛ و--name X يُقابل goose session --name X. هذه أعلام أوامر فرعية، لذا يحقن cplt الأمر الفرعي session معها. يتم تجاهل --remote (لا يوجد مقابل في goose)يستطيع cplt تشغيل DeepSeek Harness (الملف التنفيذي dsh) داخل صندوق رمل، وهو إطار عمل موجّه للإضافات من DeepSeek. يوفّره المشروع الأصلي كإصدار معاينة للمطوّرين، ويقول ملف SAFETY.md الخاص به إنه لا ينبغي الاعتماد على ضوابطه كالحد الوحيد، وهذه هي الحالة التي وُجد cplt من أجلها.```bash
cplt --agent dsh
cplt --agent dsh --pass-env DEEPSEEK_API_KEY
cplt config set sandbox.agent dsh
**ملاحظات أمنية لـ DSH:**
- **لا يتم اكتشافه تلقائيًا**: اختره باستخدام `--agent dsh` (الأسماء المستعارة `deepseek`، `deepseek-harness`) أو اضبط `sandbox.agent = "dsh"`. `dsh` هو اسم أمر قصير وعام قد ينتمي إلى شيء آخر على جهازك
- **أوقف صندوق الحماية الخاص بـ DSH داخل cplt**: يغلّف DSH كل استدعاء لأداة shell وملف في صندوق الحماية الخاص بعمليته — Seatbelt على macOS، أو bwrap أو Landlock على Linux. لا يتداخل أي منهما داخل cplt. لا يدعم macOS استدعاءات `sandbox-exec` المتداخلة (نفس القيد الذي يجعل cplt يوقف صندوق الحماية الداخلي لـ Gradle، انظر [القيود](#limitations))، ويبني bwrap مساحة الأسماء الخاصة به باستخدام `unshare`، وهو ما يرفضه مرشح seccomp الخاص بـ cplt. cplt هو الحد الفاصل المُلزِم في كلتا الحالتين، لذا اختر إعداد الأذونات `danger-full-access` المرفق مع DSH للجلسات المعزولة. اترك المشغّل الداخلي مفعّلًا وستفشل استدعاءات الأدوات بخطأ مشغّل صندوق الحماية بدلًا من خطأ المهمة
- **جذر منزلي واحد، و cplt يتبع التجاوز**: يحتفظ DSH بالجلسات والإعدادات وذاكرة التخزين المؤقت والملفات الشخصية تحت `$DSH_HOME` (`~/.dsh` افتراضيًا). `DSH_HOME` موجود في قائمة المتغيرات البيئية المسموح بها، لذا يحلّ الابن نفس الجذر الذي يمنحه cplt. يتم رفض قيمة تشير إلى جذر نظام أو دليل منزلك قبل التشغيل، نفس الفيتو الذي يمر به `CLAUDE_CONFIG_DIR`
- **حارس استمرارية المضيف**: `$DSH_HOME/cordis.patch.yml`، وهو الطبقة العلوية على مستوى المنزل التي يقرأها Loader عند الإقلاع، محظور الكتابة عليه. يبقى `$DSH_HOME/profiles/` قابلًا للكتابة لأن DSH يعيد كتابة جذر تضمين `cordis.yml` لكل ملف شخصي عند كل إقلاع، لذا فإن `cordis.patch.yml` لكل ملف شخصي والإضافات المثبّتة تُعدّ مخلفات موثّقة — قم بإجراء تعديلات الملفات الشخصية و `dsh plugin` خارج cplt، وأطلق `dsh` دائمًا عبر cplt حتى يظل أي شيء مزروع يعمل داخل صندوق الحماية
- **النطاقات الافتراضية**: `deepseek.com` فقط. محوّل `dsh-llm-deepseek` المرفق يعود افتراضيًا إلى `https://api.deepseek.com`. وجّه `DEEPSEEK_BASE_URL` إلى بوابة وستحتاج إلى إضافة نطاق تلك البوابة عبر `allowed_domains`
- **المصادقة**: مرّر المفتاح باستخدام `--pass-env DEEPSEEK_API_KEY`، أو احتفظ به في `$DSH_HOME/.env`. المفتاح المحفوظ عبر واجهة النماذج الخاصة بـ DSH يستقر في `$DSH_HOME/.credentials.yaml`، داخل نفس الجذر القابل للكتابة. يتم رفض macOS Keychain، لذا يحتاج `git push` عبر HTTPS إلى رمز `gh` في `hosts.yml` أو `--pass-env GH_TOKEN`
### وضع Shell
شغّل shell عاديًا داخل صندوق الحماية بدون وكيل ذكاء اصطناعي وبنفس القيود. مفيد لاختبار أدوات البناء، أو تصحيح مشكلات صندوق الحماية، أو مجرد العمل بعناية يدويًا.```bash
# Interactive sandboxed shell (uses $SHELL: fish, zsh, bash)
cplt --agent shell
# Inspect what's allowed without entering the shell
cplt --agent shell --print-profile
تُطبَّق نفس قواعد الرفض افتراضيًا: عزل نظام الملفات، وقيود الشبكة، وتعقيم متغيرات البيئة. تبقى أدلة إعدادات الصدفة (متغيرات وسجل fish، وسجل zsh) قابلة للكتابة.
بالنسبة لأمر واحد، يُعدّ cplt exec أنظف من cplt --agent shell -- -c 'cmd'.
شغّل أي أمر داخل البيئة المعزولة دون بدء وكيل. لا لافتة بدء، ولا مطالبة تأكيد، لذا فهو مناسب للسكربتات والأنابيب والأسماء المستعارة للصدفة.```bash
cplt exec -- npm install cplt exec -- make build cplt exec -- go test ./...
cplt exec -c "npm install && npm test"
cplt exec --allow-lifecycle-scripts -- npm install cplt exec --project-dir /path/to/repo -- make build cplt exec --with-proxy -- curl https://example.com
alias npm="cplt exec -- npm" alias node="cplt exec -- node" alias python="cplt exec -- python"
كل علامة `cplt` من المستوى الأعلى تنطبق: `--project-dir`، و`--allow-read`، و`--deny-path`، و`--with-proxy`، و`--pass-env`، وغيرها. أضف `--no-quiet` لرؤية ملخص إعدادات البيئة المعزولة الكامل قبل تشغيل الأمر.
### أمثلة```bash
# The common case: Copilot in the sandbox
cplt -- -p "fix the tests"
# Sessions
cplt --resume # pick one interactively
cplt --resume=my-refactor # by name
cplt --continue # most recent in this directory
cplt --remote --name my-task -- -p "fix tests" # named remote session
# Check the environment before the first run
cplt doctor
# Let Copilot read a shared library directory
cplt --allow-read ~/shared-libs -- -p "use shared-libs"
# Block a path you don't want Copilot to see
cplt --deny-path ~/.config/gh -- -p "refactor auth"
# Extra outbound port, e.g. an external API
cplt --allow-port 8443 -- -p "test the API"
# Localhost for MCP servers or dev servers
cplt --allow-localhost 3000 --allow-localhost 8080 -- -p "use the MCP server"
# All of localhost, needed by Next.js/Turbopack and Vite builds
cplt --allow-localhost-any -- -p "fix the build"
# Pass specific env vars through
cplt --pass-env MY_CUSTOM_VAR --pass-env ANOTHER_VAR -- -p "run with custom config"
# Inherit the full environment (dangerous, debugging only)
cplt --inherit-env -- -p "debug the build"
# Network
cplt --no-proxy -- -p "fix the tests" # proxy is on by default
cplt --blocked-domains ./blocked-domains.txt -- -p "refactor"
cplt --allow-private-domain intern.nav.no -- -p "use mcp-onboarding"
# Non-interactive / CI (skip the confirmation prompt)
cplt --yes -- -p "fix the tests"
# Inspect and debug the sandbox itself
cplt --print-profile
cplt --show-denials -- -p "fix the tests"
تتم الإعدادات على مستويين: عام، لتفضيلات المطوّر، ولكل مستودع، لسياسة الفريق.```bash
cplt settings
cplt config set sandbox.quiet true cplt config set proxy.blocked_domains "~/.config/cplt/blocked-domains.txt" cplt config set git_guard.mode warn # observe pushes instead of blocking them cplt config set gh_guard.enabled false # opt out of the gh guard entirely
cplt config set --repo sandbox.allow_jvm_attach true cplt config set --repo deny.paths "~/secrets"
cplt config show # effective config (file + defaults) cplt config explain # every key with its description
`cplt settings` هو المحرر التفاعلي، مع عروض Effective وGlobal وRepository، والبحث، والتغييرات المرحلية، وتأكيد صريح قبل حفظ أي شيء حساس أمنيًا. يظل `cplt config` الواجهة غير التفاعلية المستقرة للسكربتات وCI. لا تزال مقترحات المستودع تُلتزم وتُعتمد بشكل منفصل عبر `cplt trust`. لا يقوم المحرر أبدًا بالالتزام أو الموافقة التلقائية عليها.
تعمل الأسبقية عبر أعلام CLI، ثم ملف التكوين العام في `~/.config/cplt/config.toml`، ثم الإعدادات الافتراضية المدمجة. تكوين كل مستودع في `.cplt.toml` هو طبقة منفصلة وليس درجة في ذلك السلم: `[deny]` يشدّد دون قيد أو شرط، والأذونات المعتمدة إضافية فقط، لذا يمكن للمستودع تمكين ميزة لكن لا يمكنه أبدًا إيقاف شيء تم تعيينه بواسطة علم CLI أو التكوين العام.
يحمل `.cplt.toml` في جذر المستودع سياسة الفريق:```toml
[deny] # Applied automatically, no opt-in needed
paths = ["~/secrets", "~/.vault-token"]
env = ["VAULT_TOKEN", "DATABASE_URL"]
[propose] # Requires developer approval (cplt trust accept)
gh_guard = true
git_push_prevention = true
allow_jvm_attach = true
allow_docker = true
[propose.allow]
ports = [5432]
localhost = [3000]
socket = ["/var/run/docker.sock"]
يقرأه cplt من git HEAD، لذا لا يمكن للوكيل العبث بسياسة نفسه في منتصف الجلسة، وتُثبَّت موافقات الثقة على محتوى الملف. ملف .cplt.toml غير المُودَع لا يمنح أي شيء حتى يُودَع، رغم أن مفاتيح [deny] الخاصة به تظل سارية. في CI والسكربتات، حيث لا يمكن لأحد الإجابة على مطالبة، يوافق --accept-repo-config على مقترحات الملف المُودَع لتلك الجولة الواحدة دون حفظ أي ثقة. يكتب لك cplt init واحدًا عبر اكتشاف أدوات المشروع:```bash
cplt init # preview detected permissions
cplt init --write # write .cplt.toml to disk
cplt init --quiet # output only TOML (pipe-friendly)
cplt init --global # generate a personal ~/.config/cplt/config.toml
إنه يعرف JVM (Gradle/Maven)، وNode.js، وDocker، وPython، وRust، وGo، وPlaywright، وSpring Boot، وKtor، وTestContainers، وNext.js، وVite، وFlyway، وCypress، وأسرار البيئة من `.env.example`. تخرج الأذونات الخطيرة من المولّد مرفقةً بتحذير مخاطر. بينما ينظر `--global` إلى الأشياء على مستوى الجهاز بدلاً من ذلك: متصفحات Playwright، وتوقيع GPG، وبيانات اعتماد السجل، والوكلاء البدلاء.
بعض المفاتيح عالمية فقط ويُرفض وجودها في `.cplt.toml` لأنها خاصة بالجهاز أو تفضيل محلي: `sandbox.agent`، و`sandbox.quiet`، و`sandbox.yes`، و`sandbox.validate`، و`sandbox.scratch_dir`، و`sandbox.pass_env`، و`sandbox.inherit_env`، و`sandbox.allow_cache_exec`، و`sandbox.allow_cache_exec_any`، و`proxy.enabled`، و`proxy.port`، و`proxy.log_file`، و`proxy.log_level`، و`proxy.blocked_domains`، و`proxy.allowed_domains`، وكل مفتاح في `[gh_guard]` و`[git_guard]`.
التفاصيل الكاملة، بما في ذلك نموذج الثقة، وقواعد توسيع المسارات، والمرجع الكامل لملف الإعدادات: [docs/configuration.md](https://github.com/navikt/cplt/blob/main/docs/configuration.md).
## البنية```
┌──────────────────────────────────┐
│ cplt (Rust binary) │
│ ┌───────────┐ ┌─────────────┐ │
│ │ Policy │ │ CONNECT │ │
│ │ Generator │ │ Proxy │ │
│ └─────┬─────┘ │ (optional) │ │
│ │ └─────────────┘ │
│ ▼ │
│ ┌─────────────┬────────────┐ │
│ │ macOS │ Linux │ │
│ │ Seatbelt │ Landlock │ │
│ │ sandbox- │ + seccomp │ │
│ │ exec │ pre_exec │ │
│ └─────────────┴────────────┘ │
│ │ │
│ ▼ │
│ copilot (sandboxed) │
│ ├── All child processes │
│ ├── Cannot read ~/.ssh │
│ ├── Network port-restricted │
│ ├── SSH agent blocked │
│ └── Filesystem = primary ctrl │
└──────────────────────────────────┘
نموذج الأمان هو نظام ملفات يرفض افتراضيًا مع فرض على مستوى النواة. على macOS، وعلى Linux مع نواة 6.7+ (Landlock ABI v4)، تُقيَّد الشبكة بالمنفذ 443 افتراضيًا، مع --allow-port للإضافات. على نوى Linux الأقدم، يوفّر وكيل CONNECT هذا القيد بدلاً من ذلك، ولهذا السبب يكون مفعّلًا افتراضيًا. يُحظر الوصول إلى وكيل SSH والخروج إلى localhost في النواة على macOS. على Linux لا يُحظر أيٌّ منهما: قواعد Landlock القائمة على المنافذ لا تستطيع التمييز بين localhost والمضيف البعيد، وconnect() على مقبس unix غير محكوم بـ Landlock دون نواة 7.1، لذا بصرف النظر عن المقابس التي يحجبها bubblewrap، فإن SSH_AUTH_SOCK المحجوز هو الشيء الوحيد الذي يفصل بين الوكيل ومفاتيحك المحمّلة. يكتشف مولّد الملف التعريفي بيئتك (cplt doctor --verbose يُظهر نفس نتائج الفحص) ويصدر قواعد فقط لأدلة الأدوات الموجودة فعليًا على القرص. قواعد أقل، صندوق رمل أكثر إحكامًا.
sandbox-execpre_exec (نواة 5.13+، تصفية منافذ TCP على 6.7+)التفاصيل الداخلية وتخطيط الوحدات: docs/architecture.md. نموذج التهديد، وطبقات الدفاع، والثغرات الصريحة: SECURITY.md.
ملف تنفيذي واحد، تبعيات دنيا، لا خدمات وقت تشغيل، لا قياس عن بُعد. ثلاث طبقات دفاع، مع حدود واضحة بينها:
| الطبقة | الفرض | قابلة للتجاوز؟ | ما تحميه |
|---|---|---|---|
| 1. صندوق الرمل في النواة | macOS Seatbelt / Linux Landlock+seccomp | ❌ لا | الوصول إلى الملفات، التنفيذ، منافذ الشبكة |
| 2. وكيل الشبكة | وكيل CONNECT، تصفية النطاقات | ❌ لا (داخل صندوق الرمل) | الاتصالات الصادرة، تسريب البيانات |
| 3. حارس الأوامر | نصوص تغليف قائمة على PATH | ⚠️ حاجز لين | الدفع، الدمج، الإصدارات، كتابات API |
ما يحمي منه cplt:
.env): محظور على مستوى النواة.git/hooks محظور الكتابة عليه على مستوى النواة على macOS. على Linux، مع Landlock وبدون Bubblewrap، يبقى قابلًا للكتابة، وعندها يعمل git الخاص بـ cplt على الجانب الأب مع core.hooksPath=/dev/null فلا ينفّذ أبدًا خطافًا مزروعًا، رغم أن git الذي تشغّله بنفسك سيظل ينفّذهPNPM_HOME، ~/.deno/bin، ~/.bun/bin): تُمنح الكتابة هناك حتى تعمل pnpm add -g وما شابه داخل صندوق الرمل، لذا يمكن للوكيل أن يترك ملفًا تنفيذيًا يلتقطه صدفة لاحقة من PATH الخاص بكgit، bwrap، sandbox-exec، mise، وgh الذي يقرأ منه رمزًا) من أدلة نظام ثابتة بدلًا من PATH، لكن ملف الوكيل التنفيذي نفسه يعمل من حيث اكتُشف، وهو في تثبيت npm-global عادةً تحت شجرة mise أو node قابلة للكتابة. لا يستطيع cplt حلّه من دليل ثابت — فهو يقع بشكل مشروع حيث وضعه مدير الإصدارات لديك — لذا يتحقق من المسار المحلول مقابل قواعد الكتابة التي سيطبّقها صندوق الرمل ويحذّر عند التشغيل، مسمّيًا الملف التنفيذي والشجرة القابلة للكتابة، ثم يمضي قدمًاcplt doctor: فحوصات --version الخاصة به تشغّل كل ملف وكيل تنفيذي يجده على PATH الخاص بك، في العملية الأب، لذا يُنفَّذ ملف مزروع هناك — نفس التعرّض للمسار المكتشف كما في التشغيل أعلاه، ولهذا فإن doctor تقرير وليس حدًّا. فحص gh الخاص به يُحلّ من الأدلة الموثوقة وقراءة إصدار النواة لا تشغّل شيئًا على الإطلاقما لا يحمي منه cplt:
sandbox.keychain_substitute التنازل عن المنح حيث يملك الوكيل بيانات اعتماد أخرىأولوياتنا، بالترتيب: الصحة (كل ادعاء مُختبر، وكل حالة حدّية لها مرجع CVE أو بحث)، الشفافية (SECURITY.md لا تخفي شيئًا)، البساطة (ملف تنفيذي واحد، صفر إعداد مطلوب، إعدادات افتراضية معقولة)، والفائدة (أفسح الطريق ودع الوكيل يعمل، بأمان).
المزيد: docs/security.md · SECURITY.md
الوكيل مفعّل افتراضيًا. كل حركة الخروج من Copilot CLI وgh وcurl تمر عبر وكيل CONNECT على localhost عبر HTTP_PROXY/HTTPS_PROXY وNODE_USE_ENV_PROXY=1. يستمع على منفذ عابر مخصص من قِبل نظام التشغيل، فلا يتعارض شيء. تحصل على تسجيل الاتصالات في الوقت الفعلي، وحظر النطاقات، وقوائم النطاقات المسموح بها، وسجل تدقيق دائم، ونفس سياسة المنافذ التي يفرضها صندوق الرمل (443 بالإضافة إلى أي شيء في allow.ports).```bash
cplt --proxy-forced -- -p "fix tests" # force all egress through the proxy
cplt --no-proxy -- -p "fix tests" # disable for one run
cplt --blocked-domains blocked-domains.txt -- -p "x" # block known-bad domains
cplt --allowed-domains allowed-domains.txt -- -p "x" # allowlist mode
cplt --default-allowlist -- -p "x" # fail-closed: only the agent's own domains
cplt --observe-domains -- -p "x" # record what the agent contacts, block nothing
cplt --proxy-upstream http://proxy.corp:8080 -- -p "x" # chain through a corporate proxy
`--observe-domains-out <FILE>` يكتب المجموعة المرصودة، نطاق واحد في كل سطر، و
`--proxy-upstream-no-proxy <HOST>` يسرد المضيفين الذين يجب الوصول إليهم مباشرةً بدلاً من المرور
عبر المنبع.```bash
cplt config set proxy.enabled false
cplt config set proxy.blocked_domains "~/.config/cplt/blocked-domains.txt"
cplt config set proxy.allowed_domains "~/.config/cplt/allowed-domains.txt"
cplt config set proxy.log_file "~/.config/cplt/proxy.log"
وضع الإجبار عبر الوسيط اختياري. يقيّد خروج النواة إلى منفذ الوسيط بحيث لا يمكن تجاوز socket يُفتح مباشرة، أو env -u HTTPS_PROXY. الإنفاذ كامل على macOS، حيث يُثبَّت على localhost:<proxy_port>. على Linux يحجب TCP المباشر :443، وقاعدة seccomp تسمح فقط بـ SOCK_STREAM مع البروتوكول 0 أو IPPROTO_TCP لـ AF_INET/AF_INET6، لذا فإن UDP وraw وSCTP وDCCP مغلقة أيضًا — على حساب أي شيء يفتح مثل هذا socket، وليس فقط الكود الذي يرسل UDP. ما يتبقى هو بقايا قائمة على المنفذ، evil.com:<proxy_port>، حتى #114.
خارج وضع الإجبار عبر الوسيط، لا يقيّد Linux بروتوكول UDP. صلاحيات الشبكة في Landlock هي TCP فقط حتى ABI v10، ويتعامل cplt مع AccessNet::ConnectTcp وحده، وقاعدة seccomp أعلاه لا تُطبَّق عمدًا — رفض SOCK_DGRAM هناك سيكسر getaddrinfo(3)، وبالتالي كل DNS، لكل أداة غير موجهة عبر الوسيط. لذا فإن UDP الصادر إلى أي مضيف، وربط UDP الوارد، وأنفاق DNS، وQUIC/HTTP-3 غير وسيطة في الوضع الافتراضي، ووسيط CONNECT يحمل TCP فقط، لذا لا يظهر أي منها في سجل الوسيط. يقيّد macOS بروتوكول UDP في الوضع الافتراضي لكنه لا يوجّهه أيضًا: remote ip "*:443" يغطي UDP، لذا يخرج QUIC/HTTP-3 على 443 دون لمس الوسيط هناك أيضًا. تحت proxy.forced يكون سجل الوسيط سجلًا كاملًا للخروج على macOS. على Linux يكون كاملًا باستثناء بقايا evil.com:<proxy_port> أعلاه، والتي لا تعبر الوسيط وبالتالي لا تظهر في سجله.
تتطابق كلتا القائمتين بالطريقة نفسها: example.com يغطي النطاق الدقيق وكل النطاقات الفرعية، والمطابقة غير حساسة لحالة الأحرف، ويُزال النقاط اللاحقة. تُعاد قراءة ملفات قائمة الحظر وقائمة السماح كل خمس ثوانٍ، لذا يمكنك تعديلها مباشرة. يتجاوز مرور localhost الوسيط عبر NO_PROXY ولا يظهر أبدًا في سجل التدقيق. --proxy-timeout <SECONDS> يحدّ من قراءات الطلب والترويسات (الافتراضي 60) ولا ينهي أنفاق CONNECT القائمة، التي قد تظل خاملة لمدة تصل إلى ساعة.
كل علامة وسيط، وتفصيل تصفية النطاقات، وتسلسل وسيط الشركة الأعلى، وتنسيق سجل الاتصال: docs/proxy.md.
فعّلها فيعترض cplt الأمرين gh وgit عبر سكربتات غلاف في $PATH:
| الأمر | الإجراء |
|---|---|
gh pr merge، gh repo delete، gh release create | 🔒 محظور |
git push origin main، git push --force | 🔒 محظور |
gh api (كتابة إلى مستودعات أخرى) | 🔒 مفحوص النطاق |
gh pr list، gh issue list، git commit | ✅ مسموح |
git push origin feature-branch | ✅ مسموح مع protect_default_branch_only |
هذه هي الطبقة 3، حاجز ناعم. يمنع وكيلًا ممتثلًا من فعل شيء مدمّر عن طريق الخطأ. للحصول على حد صارم، اعتمد على صندوق رمل النواة وحماية الفروع من جانب الخادم.
مع تفعيل حارس gh، يخزّن cplt أيضًا رمز GitHub مؤقتًا عند الإطلاق ويقدمه مرة واحدة عبر callback gh auth token، ثم يحذف الذاكرة المؤقتة. هذا يقلل التسريب العرضي والقائم على البيئة. إنه ليس حدًا ضد وكيل معادٍ، لأن الذاكرة المؤقتة تعيش في TMPDIR الخاص بالوكيل نفسه، والوكيل الذي يقرأها قبل المستهلك الشرعي لا يزال يحصل على الرمز. SECURITY.md يحتوي على البيان الكامل حول block_auth_token.
السلوك الكامل: docs/gh-guard.md · docs/git-guard.md
يحجب صندوق الرمل بعض سير العمل عن قصد. الشائعة منها وإصلاحاتها:
| التأثير | الإصلاح |
|---|---|
ملفات .env محظورة | cplt config set sandbox.allow_env_files true |
| خطافات npm postinstall محظورة | cplt config set sandbox.allow_lifecycle_scripts true |
go test / mise run محظور (تنفيذ مؤقت) | مجلد scratch مفعّل افتراضيًا. إذا كنت لا تزال بحاجة إليه، cplt config set sandbox.allow_tmp_exec true |
| اتصالات localhost محظورة | cplt config set allow.localhost 3000، أو cplt config set sandbox.allow_localhost_any true |
| Docker محظور | cplt config set sandbox.allow_docker true ⚠️ |
| SSH محظور | استخدم remotes عبر HTTPS بدلًا من ذلك |
| توقيع GPG معطّل | cplt config set sandbox.allow_gpg_signing true |
| فشل JVM MockK/Mockito | cplt config set sandbox.allow_jvm_attach true |
عقد عامل MSBuild في dotnet build محظورة | cplt config set sandbox.allow_msbuild true |
| بيانات اعتماد السجل الخاص محظورة | cplt config set allow.read "~/.m2/settings.xml" |
| مستودع Maven/Nexus الداخلي غير قابل للوصول (Gradle/Maven) | cplt config set proxy.allow_private_domains "intern.example.com". عنوان URL لمستودع بصيغة IP حرفي لا يمكن السماح به — أعطِ المضيف اسم DNS؛ انظر أدناه |
| Playwright Chromium لا يبدأ | اسمح بتنفيذ cache، ثم عطّل صندوق الرمل المتداخل في Chromium؛ انظر أدناه |
يحتاج Playwright Chromium إلى cplt config set sandbox.allow_cache_exec ms-playwright، ويجب تشغيل Chromium دون صندوق الرمل المتداخل الخاص به. على macOS لا تستطيع مساعداته تهيئة صندوق رمل Seatbelt ثانٍ داخل cplt (forbidden-sandbox-reinit)؛ على Linux يحجب مرشح seccomp في cplt استدعاءات syscall الخاصة بالـ namespace التي يحتاجها صندوق الرمل. Playwright كمكتبة يبدأ بالفعل مع --no-sandbox، ونفس هذا الاشتراك يضبط PLAYWRIGHT_MCP_SANDBOX=false لـ Playwright MCP، الذي كان سيعيده إلى التشغيل لولا ذلك. أي مشغّل Chromium آخر يحتاج إلى --no-sandbox بنفسه. يبقى cplt هو حد النواة المنفّذ، لكن renderer المخترق يتلقى بعد ذلك ملف تعريف Playwright الكامل لـ cplt بدلًا من ملف تعريف Chromium الفرعي الأضيق. انظر Cache exec وSECURITY.md.
يعمل git commit مع كل وكيل؛ أما ما إذا كان git push يعمل عبر HTTPS فيعتمد على الوكيل. ثلاثة متطلبات مسبقة: استخدم remotes عبر HTTPS بدلًا من SSH (git remote set-url origin https://github.com/org/repo.git، أو أعد الكتابة عالميًا باستخدام git config --global url."https://github.com/".insteadOf "[email protected]:")، شغّل gh auth login مرة واحدة خارج صندوق الرمل، وشغّل gh auth setup-git إذا لم يكن مساعد بيانات الاعتماد مُهيأً بعد. عندئذٍ يشغّل push الأمر gh auth git-credential، الذي يحتاج إلى رمز يستطيع gh الوصول إليه من داخل صندوق الرمل — وهذا يختلف حسب الوكيل، انظر Git workflow. تُرفض عمليات الدفع إلى الفرع الافتراضي وكل عمليات الدفع القسري بواسطة حارس git افتراضيًا؛ ادفع فرع ميزة. socket وكيل SSH محظور لأنه يفتح كل مفتاح محمّل ويمكنه المصادقة مع أي مضيف، بينما مساعد بيانات الاعتماد gh مقيّد بـ GitHub.
JVM واعٍ بالوسيط، لذا يحتاج مستودع Maven داخلي على IP خاص إلى السماح الآن. يحقن cplt http(s).proxyHost/proxyPort في JAVA_TOOL_OPTIONS، لذا يمر حل تبعيات Gradle وMaven عبر وسيط CONNECT ويظهر في سجل الوسيط بدلًا من تجاوزه. ثم يرفض حارس SSRF الخاص بالوسيط مستودع Nexus أو Artifactory داخليًا يُحلّ إلى مساحة عنوان خاصة، تمامًا كما يفعل بالفعل مع curl وnpm وpip. أضف اسم DNS الخاص به إلى proxy.allow_private_domains. عنوان URL لمستودع مكتوب كـ IP حرفي مجرد (https://10.20.30.40/repository/maven-public/) لا يمكن السماح به بأي مفتاح — هذا الفحص يعمل قبل استشارة قائمة السماح — لذا يحتاج مثل هذا المستودع إلى اسم DNS. تفرعات إضافة WorkerExecutor، وعملية Gradle daemon تبدأ خارج cplt وتُعاد استخدامها في الداخل، لا تمر عبر الوسيط. انظر Internal Maven/Gradle repositories on private IPs.
يشغّل Gradle 9+ صندوق الرمل المتداخل الخاص به، ويقوم cplt بإيقافه. منذ Gradle 8.8 يلفّ الـ daemon نفسه في sandbox-exec (يتحكم فيه GRADLE_MACOS_SANDBOX، سابقًا خاصية org.gradle.daemon.sandbox). لا يدعم macOS استدعاءات sandbox-exec المتداخلة، لذا يفشل صندوق الرمل الداخلي بـ "Operation not permitted" على عمليات socket. يحقن cplt GRADLE_MACOS_SANDBOX=off، لأنه يوفر بالفعل صندوق رمل على مستوى النواة. هذه مشكلة معروفة في المنبع تصيب أي أداة تلفّ Gradle في صندوق رمل خارجي. تجاوزها باستخدام --pass-env GRADLE_MACOS_SANDBOX إذا كنت تريد حقًا صندوق الرمل الخاص بـ Gradle.
يشغّل Copilot CLI 1.0.83 صندوق الرمل المتداخل الخاص به، ويقوم cplt بإيقافه. على Linux يبني صندوق الرمل هذا namespace شبكة — slirp4netns، iptables، /dev/net/tun — ومرشح seccomp في cplt يرفض unshare الذي يتطلبه. يضبط cplt أيضًا HTTP_PROXY/HTTPS_PROXY، وهو ما يضع في 1.0.83 صندوق رمل Linux على مسار الخروج عبر الوسيط سواء طلبت ذلك أم لا، لذا يتصادم الاثنان عند كل إطلاق. العَرَض: [cplt] Starting Copilot in sandbox... ثم لا شيء. يحقن cplt خيار الانسحاب الخاص بـ Copilot، COPILOT_CLI_SANDBOX_SUPPORT_OVERRIDE=unsupported؛ يتراجع Copilot للجلسة، ويقول ذلك، ويترك sandbox.enabled المحفوظ لديك دون تغيير. cplt هو الحد، كما هو الحال مع Gradle وChromium. تجاوزه باستخدام --pass-env COPILOT_CLI_SANDBOX_SUPPORT_OVERRIDE. سياسة مُدارة على مستوى المؤسسة تتطلب صندوق الرمل تتجاوز كل هذا — انظر Copilot CLI's own command sandbox.
كل تأثير، مع جداول كل أداة، وملاحظات JVM وKotlin daemon، واستكشاف أخطاء GPG، والفروقات بين منصات السجل الخاص: docs/known-impacts.md.
sandbox-exec مهمَل. لم تزله Apple، لكنها قد تفعل في إصدار macOS مستقبلي.lsopen في SBPL مرشحًا أيضًا، لذا فإن --allow-browser هو كل Launch Services أو لا شيء منه. مع تفعيله يستطيع الوكيل تشغيل أي تطبيق خارج صندوق الرمل، ولا يمكن لأي غلاف تضييق ذلك — انظر docs/security.md..env داخل مجلد المشروع غير منفّذ على مستوى النواة. تُحجب كتابات .git/hooks عند تفعيل Bubblewrap.--deny-path وجود Bubblewrap. يُنفَّذ عبر أقنعة mount عندما يكون bwrap نشطًا. بدونه، يكون Landlock قائمة سماح فقط ويحذّر cplt من الرفض بدلًا من تطبيقه.المزيد: docs/security.md
المساهمات مرحّب بها.```bash git clone https://github.com/navikt/cplt.git && cd cplt git config core.hooksPath hack # enables pre-commit fmt + clippy checks mise run check # runs fmt, clippy, and tests
افتح issue قبل البدء بتغيير كبير. يجب أن يجتاز كل PR اختبارات CI (fmt، clippy، tests).
## المراجع
- [SECURITY.md](https://github.com/navikt/cplt/blob/main/SECURITY.md)، نموذج الأمان الكامل، وتحليل التهديدات، واستراتيجية الاختبار، والأعمال السابقة
- [Apple sandbox-exec(1)](https://keith.github.io/xcode-man-pages/sandbox-exec.1.html)
- [Chromium Seatbelt V2 Design](https://chromium.googlesource.com/chromium/src/sandbox/+show/refs/heads/main/mac/seatbelt_sandbox_design.md)
- [Landlock LSM documentation](https://docs.kernel.org/userspace-api/landlock.html)
- [seccomp-BPF documentation](https://www.kernel.org/doc/html/latest/userspace-api/seccomp_filter.html)
- [OWASP SSRF Prevention Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html)
- [michaelneale/agent-seatbelt-sandbox](https://github.com/michaelneale/agent-seatbelt-sandbox)
## الترخيص
[MIT](https://github.com/navikt/cplt/blob/main/LICENSE)
--allow-port <PORT> | السماح بحركة مرور صادرة على منفذ إضافي. 443 فقط افتراضياً. قابل للتكرار. على macOS القاعدة هي (remote ip "*:PORT")، وهي محايدة للعائلة وبالتالي تحمل UDP بالإضافة إلى TCP؛ Landlock يبوّب اتصال TCP فقط. تحت proxy.forced لا يفتح المنفذ أي مقبس مباشر على الإطلاق — يمكن الوصول إليه عبر الوكيل، لذا تستمر الأدوات المدركة للوكيل في العمل |
--allow-localhost <PORT> | السماح بالخروج إلى localhost على منفذ واحد. localhost محجوب افتراضياً. استخدمه لخوادم MCP أو خوادم التطوير. قابل للتكرار |
--allow-localhost-any | السماح بالخروج إلى localhost على جميع المنافذ. تحتاجه أدوات البناء مثل Turbopack (Next.js) وVite التي تستخدم منافذ عشوائية مؤقتة للـ IPC |
إيقاف كتلة AGENTS.md لهذه الجلسة، متجاوزاً sandbox.agents_md = true في الإعدادات. يترك موجز دليل المسودة كما هو |
--allow-tmp-exec | ⚠️ خطير. السماح بالتنفيذ من أدلة النظام المؤقتة (/private/tmp، /private/var/folders). فضّل دليل المسودة |
--allow-cache-exec <SUBDIR> | السماح بالتنفيذ من ~/Library/Caches/<SUBDIR> واحد. قابل للتكرار. للأدوات التي تخزّن الملفات الثنائية المترجمة هناك، مثل Playwright وpnpm dlx |
--allow-cache-exec-any | ⚠️ خطير. السماح بالتنفيذ من كل ~/Library/Caches. فضّل --allow-cache-exec <SUBDIR> |
--allow-browser | ⚠️ خطير. مع تفعيل هذا، يمكن للوكيل تشغيل أي تطبيق على جهازك خارج العزل. المنحة هي Launch Services، وليس متصفحاً: يبدأ launchd الهدف خارج ملف Seatbelt، لذا فإن open -a Terminal /tmp/x.sh يعمل بدون عزل. هذا لا يمكن تقييده بعناوين URL — lsopen في SBPL لا يأخذ أي مرشح، والمنحة قابلة للوصول عبر LSOpenCFURLRef() بدون الملف الثنائي open على الإطلاق، لذا لا يمكن لأي غلاف تضييقه (#251، وdocs/security.md). فعّله فقط أثناء ظهور مطالبة تسجيل الدخول فعلياً على الشاشة (OAuth لخادم MCP، إعادة المصادقة)، ثم أطفئه مرة أخرى. معطّل افتراضياً |
--deny-clipboard | حجب الوكيل من قراءة أو كتابة حافظة macOS (pbpaste/pbcopy) برفض خدمة Mach com.apple.pasteboard. كل خدمة Mach أخرى (Keychain، DNS، إطار الأمان) غير متأثرة. مفعّل افتراضياً — هذا العلم يعيد تأكيد الافتراضي |
--allow-clipboard | إعادة حافظة macOS للوكيل، التي يرفضها cplt افتراضياً. يعادل sandbox.deny_clipboard = false |
--use-bubblewrap | Linux فقط. اشتراط طبقة فضاء أسماء bubblewrap (PID، mount، IPC، UTS، cgroup، فضاءات أسماء المستخدمين بالإضافة إلى /tmp خاص) فوق Landlock وseccomp. يخطئ إذا كان bwrap مفقوداً. يُكتشف تلقائياً عند عدم إعطاء أي علم |
--no-bubblewrap | Linux فقط. لا تستخدم bubblewrap أبداً، حتى عند تثبيته. يتراجع إلى Landlock وseccomp. استخدمه عندما يكسر bwrap أداة معينة |
.miseMISE_* |
mise |