failproofai 0.0.5 → 0.0.6-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/standalone/.failproofai/policies/review-policies.mjs +112 -0
- package/.next/standalone/.failproofai/policies/workflow-policies.mjs +2 -1
- package/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/build-manifest.json +5 -5
- package/.next/standalone/.next/prerender-manifest.json +3 -3
- package/.next/standalone/.next/required-server-files.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_global-error.html +1 -1
- package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
- package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
- package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +3 -3
- package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +3 -3
- package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +2 -2
- package/.next/standalone/.next/server/app/_not-found.rsc +15 -15
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +15 -15
- package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
- package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +10 -10
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
- package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/index.html +1 -1
- package/.next/standalone/.next/server/app/index.rsc +15 -15
- package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
- package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +4 -4
- package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +10 -10
- package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/policies/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +8 -8
- package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/projects/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0g72weg._.js +1 -1
- package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_0z7w.hh._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__092s1ta._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__09icjsf._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0g.lg8b._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0h..k-e._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0okos0k._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0a~g15g._.js → [root-of-the-server]__0rh.18_._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0w6l33k._.js +6 -6
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0qn95h3._.js → [root-of-the-server]__0~kmh8w._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__11pa2ra._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__12t-wym._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_10lm7or._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_0xerkr6._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_0q-m0y-._.js +1 -1
- package/.next/standalone/.next/server/middleware-build-manifest.js +5 -5
- package/.next/standalone/.next/server/pages/404.html +2 -2
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +9 -9
- package/.next/standalone/.next/static/chunks/{0sme4lkv.tgn-.js → 01b~z8f1ws0rk.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0lgbwkfqmnsmc.js → 03rz6ykw-a2xi.js} +1 -1
- package/.next/standalone/.next/static/chunks/{17manv47o-~wp.js → 08t08igdql9yt.js} +1 -1
- package/.next/standalone/.next/static/chunks/09_k80d~cq2wg.js +4 -0
- package/.next/standalone/.next/static/chunks/{0ksdlt_1hucdm.js → 0bvhsa6zva2o..js} +1 -1
- package/.next/standalone/.next/static/chunks/{09ikntpt2-o9b.js → 0gbf4cphy8ksq.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0yumumfzx_f27.js → 0v.yd0kg_ld3r.js} +1 -1
- package/.next/standalone/.next/static/chunks/{13juklu.vksks.js → 0wlyoif4_kj_t.js} +1 -1
- package/.next/standalone/.next/static/chunks/{09e7drilkf1sn.js → 12simlrcfk3g2.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0em7tspi4kylh.js → 12~yi9oj8av8p.js} +2 -2
- package/.next/standalone/.next/static/chunks/{turbopack-0r26pc8h0y_-e.js → turbopack-0o7k.hakttp4k.js} +1 -1
- package/.next/standalone/CHANGELOG.md +13 -0
- package/.next/standalone/README.md +2 -2
- package/.next/standalone/bun.lock +43 -85
- package/.next/standalone/dist/cli.mjs +107 -3
- package/.next/standalone/docs/ar/architecture.mdx +65 -64
- package/.next/standalone/docs/ar/configuration.mdx +42 -42
- package/.next/standalone/docs/ar/custom-policies.mdx +62 -64
- package/.next/standalone/docs/built-in-policies.mdx +37 -0
- package/.next/standalone/docs/custom-policies.mdx +1 -1
- package/.next/standalone/docs/de/architecture.mdx +92 -92
- package/.next/standalone/docs/de/configuration.mdx +34 -34
- package/.next/standalone/docs/de/custom-policies.mdx +49 -50
- package/.next/standalone/docs/es/architecture.mdx +72 -72
- package/.next/standalone/docs/es/configuration.mdx +25 -25
- package/.next/standalone/docs/es/custom-policies.mdx +48 -49
- package/.next/standalone/docs/examples.mdx +54 -0
- package/.next/standalone/docs/fr/architecture.mdx +53 -53
- package/.next/standalone/docs/fr/configuration.mdx +25 -25
- package/.next/standalone/docs/fr/custom-policies.mdx +42 -43
- package/.next/standalone/docs/getting-started.mdx +52 -0
- package/.next/standalone/docs/he/architecture.mdx +66 -66
- package/.next/standalone/docs/he/configuration.mdx +53 -52
- package/.next/standalone/docs/he/custom-policies.mdx +72 -73
- package/.next/standalone/docs/hi/architecture.mdx +106 -106
- package/.next/standalone/docs/hi/configuration.mdx +39 -39
- package/.next/standalone/docs/hi/custom-policies.mdx +75 -76
- package/.next/standalone/docs/i18n/README.ar.md +66 -66
- package/.next/standalone/docs/i18n/README.de.md +38 -38
- package/.next/standalone/docs/i18n/README.es.md +38 -38
- package/.next/standalone/docs/i18n/README.fr.md +42 -42
- package/.next/standalone/docs/i18n/README.he.md +67 -67
- package/.next/standalone/docs/i18n/README.hi.md +70 -70
- package/.next/standalone/docs/i18n/README.it.md +62 -62
- package/.next/standalone/docs/i18n/README.ja.md +54 -54
- package/.next/standalone/docs/i18n/README.ko.md +58 -58
- package/.next/standalone/docs/i18n/README.pt-br.md +43 -43
- package/.next/standalone/docs/i18n/README.ru.md +69 -69
- package/.next/standalone/docs/i18n/README.tr.md +76 -76
- package/.next/standalone/docs/i18n/README.vi.md +70 -70
- package/.next/standalone/docs/i18n/README.zh.md +52 -52
- package/.next/standalone/docs/it/architecture.mdx +54 -53
- package/.next/standalone/docs/it/configuration.mdx +44 -45
- package/.next/standalone/docs/it/custom-policies.mdx +76 -78
- package/.next/standalone/docs/ja/architecture.mdx +93 -93
- package/.next/standalone/docs/ja/configuration.mdx +47 -47
- package/.next/standalone/docs/ja/custom-policies.mdx +62 -63
- package/.next/standalone/docs/ko/architecture.mdx +66 -66
- package/.next/standalone/docs/ko/configuration.mdx +35 -35
- package/.next/standalone/docs/ko/custom-policies.mdx +71 -72
- package/.next/standalone/docs/pt-br/architecture.mdx +55 -55
- package/.next/standalone/docs/pt-br/configuration.mdx +35 -35
- package/.next/standalone/docs/pt-br/custom-policies.mdx +60 -61
- package/.next/standalone/docs/ru/architecture.mdx +59 -60
- package/.next/standalone/docs/ru/configuration.mdx +52 -53
- package/.next/standalone/docs/ru/custom-policies.mdx +68 -69
- package/.next/standalone/docs/tr/architecture.mdx +124 -124
- package/.next/standalone/docs/tr/configuration.mdx +45 -46
- package/.next/standalone/docs/tr/custom-policies.mdx +75 -75
- package/.next/standalone/docs/vi/architecture.mdx +65 -64
- package/.next/standalone/docs/vi/configuration.mdx +41 -41
- package/.next/standalone/docs/vi/custom-policies.mdx +68 -69
- package/.next/standalone/docs/zh/architecture.mdx +67 -67
- package/.next/standalone/docs/zh/configuration.mdx +34 -34
- package/.next/standalone/docs/zh/custom-policies.mdx +53 -54
- package/.next/standalone/node_modules/@next/env/package.json +1 -1
- package/.next/standalone/node_modules/next/dist/build/swc/index.js +1 -1
- package/.next/standalone/node_modules/next/dist/compiled/next-server/pages-turbo.runtime.prod.js +7 -7
- package/.next/standalone/node_modules/next/dist/lib/patch-incorrect-lockfile.js +3 -3
- package/.next/standalone/node_modules/next/dist/server/config-schema.js +10 -2
- package/.next/standalone/node_modules/next/dist/server/config.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-turbopack.js +2 -2
- package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-webpack.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/lib/app-info-log.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/lib/start-server.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/render.js +27 -20
- package/.next/standalone/node_modules/next/dist/shared/lib/errors/canary-only-config-error.js +1 -1
- package/.next/standalone/node_modules/next/dist/telemetry/anonymous-meta.js +1 -1
- package/.next/standalone/node_modules/next/dist/telemetry/events/swc-load-failure.js +1 -1
- package/.next/standalone/node_modules/next/dist/telemetry/events/version.js +2 -2
- package/.next/standalone/node_modules/next/package.json +15 -15
- package/.next/standalone/package.json +2 -2
- package/.next/standalone/server.js +1 -1
- package/.next/standalone/src/hooks/builtin-policies.ts +131 -0
- package/README.md +2 -2
- package/dist/cli.mjs +107 -3
- package/package.json +2 -2
- package/src/hooks/builtin-policies.ts +131 -0
- package/.next/standalone/.next/static/chunks/0_yayar~bpphd.js +0 -4
- /package/.next/standalone/.next/static/{hYQM6iCWnF1W5XDpsIRhV → CkmOT-ZvDN-sVULinGVKT}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{hYQM6iCWnF1W5XDpsIRhV → CkmOT-ZvDN-sVULinGVKT}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{hYQM6iCWnF1W5XDpsIRhV → CkmOT-ZvDN-sVULinGVKT}/_ssgManifest.js +0 -0
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
---
|
|
2
|
+
|
|
2
3
|
---
|
|
3
|
-
title:
|
|
4
|
-
description: "
|
|
4
|
+
title: المعمارية
|
|
5
|
+
description: "كيفية عمل معالج الخطاف وتحميل الإعدادات وتقييم السياسات داخلياً"
|
|
5
6
|
icon: sitemap
|
|
6
7
|
---
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
توضح هذه الوثيقة كيفية عمل failproofai داخلياً: كيف يعترض نظام الخطاف استدعاءات أداة الوكيل، وكيف يتم تحميل ودمج الإعدادات، وكيف يتم تقييم السياسات، وكيف تراقب لوحة التحكم نشاط الوكيل.
|
|
9
10
|
|
|
10
11
|
---
|
|
11
12
|
|
|
12
13
|
## نظرة عامة
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
يتكون failproofai من نظامين فرعيين مستقلين:
|
|
15
16
|
|
|
16
|
-
1. **معالج الخطاف** - عملية CLI سريعة يستدعيها Claude Code
|
|
17
|
-
2. **مراقب الوكيل (لوحة
|
|
17
|
+
1. **معالج الخطاف** - عملية CLI سريعة يستدعيها Claude Code على كل استدعاء أداة وكيل. يقيّم السياسات ويرجع قراراً.
|
|
18
|
+
2. **مراقب الوكيل (لوحة التحكم)** - تطبيق ويب Next.js لمراقبة جلسات الوكيل وإدارة السياسات.
|
|
18
19
|
|
|
19
|
-
يشترك كلا النظامين الفرعيين في ملفات الإعدادات في `~/.failproofai/`
|
|
20
|
+
يشترك كلا النظامين الفرعيين في ملفات الإعدادات في `~/.failproofai/` ومجلد المشروع `.failproofai/`، لكنهما يعملان كعمليات منفصلة ويتواصلان فقط عبر نظام الملفات.
|
|
20
21
|
|
|
21
22
|
---
|
|
22
23
|
|
|
@@ -24,7 +25,7 @@ icon: sitemap
|
|
|
24
25
|
|
|
25
26
|
### التكامل مع Claude Code
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
عند تشغيل `failproofai policies --install`، فإنه يكتب إدخالات مثل هذه في `~/.claude/settings.json`:
|
|
28
29
|
|
|
29
30
|
```json
|
|
30
31
|
{
|
|
@@ -45,9 +46,9 @@ icon: sitemap
|
|
|
45
46
|
}
|
|
46
47
|
```
|
|
47
48
|
|
|
48
|
-
بعد ذلك يستدعي Claude Code `failproofai --hook PreToolUse` كعملية فرعية قبل كل استدعاء أداة،
|
|
49
|
+
بعد ذلك يستدعي Claude Code `failproofai --hook PreToolUse` كعملية فرعية قبل كل استدعاء أداة، مع تمرير حمولة JSON على stdin.
|
|
49
50
|
|
|
50
|
-
###
|
|
51
|
+
### صيغة الحمولة
|
|
51
52
|
|
|
52
53
|
```json
|
|
53
54
|
{
|
|
@@ -63,11 +64,11 @@ icon: sitemap
|
|
|
63
64
|
|
|
64
65
|
بالنسبة لأحداث `PostToolUse`، تحتوي الحمولة أيضاً على `tool_result` مع مخرجات الأداة.
|
|
65
66
|
|
|
66
|
-
يفرض المعالج
|
|
67
|
+
يفرض المعالج حد أقصى بحجم 1 ميجابايت لـ stdin. يتم تجاهل الحمولات التي تتجاوز هذا الحد وجميع السياسات تسمح بشكل ضمني.
|
|
67
68
|
|
|
68
|
-
###
|
|
69
|
+
### صيغة الاستجابة
|
|
69
70
|
|
|
70
|
-
|
|
71
|
+
**الرفض (PreToolUse):**
|
|
71
72
|
```json
|
|
72
73
|
{
|
|
73
74
|
"hookSpecificOutput": {
|
|
@@ -77,7 +78,7 @@ icon: sitemap
|
|
|
77
78
|
}
|
|
78
79
|
```
|
|
79
80
|
|
|
80
|
-
|
|
81
|
+
**الرفض (PostToolUse):**
|
|
81
82
|
```json
|
|
82
83
|
{
|
|
83
84
|
"hookSpecificOutput": {
|
|
@@ -86,7 +87,7 @@ icon: sitemap
|
|
|
86
87
|
}
|
|
87
88
|
```
|
|
88
89
|
|
|
89
|
-
|
|
90
|
+
**التعليمات (أي حدث باستثناء Stop):**
|
|
90
91
|
```json
|
|
91
92
|
{
|
|
92
93
|
"hookSpecificOutput": {
|
|
@@ -95,20 +96,20 @@ icon: sitemap
|
|
|
95
96
|
}
|
|
96
97
|
```
|
|
97
98
|
|
|
98
|
-
**حدث Stop
|
|
99
|
+
**حدث التعليمات Stop:**
|
|
99
100
|
- رمز الخروج: `2`
|
|
100
|
-
- السبب
|
|
101
|
+
- السبب مكتوب على stderr (وليس stdout)
|
|
101
102
|
|
|
102
|
-
|
|
103
|
+
**السماح:**
|
|
103
104
|
- رمز الخروج: `0`
|
|
104
105
|
- stdout فارغ
|
|
105
106
|
|
|
106
107
|
**السماح مع رسالة:**
|
|
107
108
|
|
|
108
|
-
`allow(message)`
|
|
109
|
+
`allow(message)` تسمح لسياسة ما بإرسال سياق معلوماتي مرة أخرى إلى Claude حتى عندما تكون العملية مسموحة. يكتب معالج الخطاف JSON التالي إلى **stdout** (وليس ملف إعدادات — هذه استجابة المعالج لـ Claude Code، تماماً مثل استجابات الرفض والتعليمات أعلاه):
|
|
109
110
|
|
|
110
111
|
```json
|
|
111
|
-
//
|
|
112
|
+
// Written to stdout by the hook handler process
|
|
112
113
|
{
|
|
113
114
|
"hookSpecificOutput": {
|
|
114
115
|
"additionalContext": "All CI checks passed on branch 'feat/my-feature'."
|
|
@@ -116,12 +117,12 @@ icon: sitemap
|
|
|
116
117
|
}
|
|
117
118
|
```
|
|
118
119
|
- رمز الخروج: `0` (العملية مسموحة)
|
|
119
|
-
- عندما تعيد عدة سياسات `allow` مع رسالة، يتم دمج
|
|
120
|
-
- إذا لم
|
|
120
|
+
- عندما تعيد عدة سياسات `allow` مع رسالة، يتم دمج رسائلها بفواصل أسطر في سلسلة واحدة `additionalContext`
|
|
121
|
+
- إذا لم تقدم أي سياسة رسالة، فإن stdout فارغ (كما كان من قبل)
|
|
121
122
|
|
|
122
|
-
### خط
|
|
123
|
+
### خط معالجة الأنابيب
|
|
123
124
|
|
|
124
|
-
`src/hooks/handler.ts`
|
|
125
|
+
يطبق `src/hooks/handler.ts` خط الأنابيب الكامل:
|
|
125
126
|
|
|
126
127
|
```text
|
|
127
128
|
stdin JSON
|
|
@@ -140,13 +141,13 @@ stdin JSON
|
|
|
140
141
|
→ exit
|
|
141
142
|
```
|
|
142
143
|
|
|
143
|
-
تعمل العملية بأكملها في أقل من
|
|
144
|
+
تعمل العملية بأكملها في أقل من 100 ميلي ثانية للحمولات النموذجية بدون استدعاءات LLM.
|
|
144
145
|
|
|
145
146
|
---
|
|
146
147
|
|
|
147
148
|
## تحميل الإعدادات
|
|
148
149
|
|
|
149
|
-
`src/hooks/hooks-config.ts`
|
|
150
|
+
يطبق `src/hooks/hooks-config.ts` تحميل الإعدادات بثلاث نطاقات.
|
|
150
151
|
|
|
151
152
|
```text
|
|
152
153
|
[1] {cwd}/.failproofai/policies-config.json ← project (highest priority)
|
|
@@ -155,39 +156,39 @@ stdin JSON
|
|
|
155
156
|
```
|
|
156
157
|
|
|
157
158
|
منطق الدمج:
|
|
158
|
-
- `enabledPolicies` - اتحاد
|
|
159
|
-
- `policyParams` - لكل سياسة، الملف الأول الذي
|
|
160
|
-
- `customPoliciesPath` - الملف الأول الذي
|
|
161
|
-
- `llm` - الملف الأول الذي
|
|
159
|
+
- `enabledPolicies` - اتحاد مخصص عبر جميع الملفات الثلاثة
|
|
160
|
+
- `policyParams` - لكل سياسة، الملف الأول الذي يحددها يفوز تماماً
|
|
161
|
+
- `customPoliciesPath` - الملف الأول الذي يحددها يفوز
|
|
162
|
+
- `llm` - الملف الأول الذي يحددها يفوز
|
|
162
163
|
|
|
163
|
-
تستخدم لوحة
|
|
164
|
+
تستخدم لوحة تحكم الويب `readHooksConfig()` (عام فقط) للقراءة والكتابة، لأنها لا تُستدعى مع cwd مشروع.
|
|
164
165
|
|
|
165
166
|
---
|
|
166
167
|
|
|
167
168
|
## تقييم السياسة
|
|
168
169
|
|
|
169
|
-
`src/hooks/policy-evaluator.ts`
|
|
170
|
+
يشغل `src/hooks/policy-evaluator.ts` السياسات بالترتيب.
|
|
170
171
|
|
|
171
172
|
لكل سياسة:
|
|
172
173
|
|
|
173
|
-
1. ابحث عن مخطط `params`
|
|
174
|
+
1. ابحث عن مخطط `params` الخاص بالسياسة (إن كان لديها واحدة).
|
|
174
175
|
2. اقرأ `policyParams[policy.name]` من الإعدادات المدمجة.
|
|
175
|
-
3.
|
|
176
|
-
4.
|
|
177
|
-
5. إذا كانت النتيجة `deny`، توقف
|
|
176
|
+
3. دمج القيم المعطاة من قبل المستخدم على القيم الافتراضية للمخطط لإنتاج `ctx.params`.
|
|
177
|
+
4. استدع `policy.fn(ctx)` مع السياق المحل.
|
|
178
|
+
5. إذا كانت النتيجة `deny`، توقف فوراً وأرجع هذا القرار.
|
|
178
179
|
6. إذا كانت النتيجة `instruct`، اجمع الرسالة وتابع.
|
|
179
180
|
7. إذا كانت النتيجة `allow`، انتقل إلى السياسة التالية.
|
|
180
181
|
|
|
181
182
|
بعد تشغيل جميع السياسات:
|
|
182
|
-
- إذا تم إرجاع أي `deny`،
|
|
183
|
-
- إذا تم جمع أي
|
|
184
|
-
-
|
|
183
|
+
- إذا تم إرجاع أي `deny`، أصدر استجابة الرفض.
|
|
184
|
+
- إذا تم جمع أي إرجاعات `instruct`، أصدر استجابة تعليمات واحدة مع جميع الرسائل المدمجة.
|
|
185
|
+
- وإلا، أصدر استجابة السماح (stdout فارغ، خروج 0).
|
|
185
186
|
|
|
186
187
|
---
|
|
187
188
|
|
|
188
189
|
## السياسات المدمجة
|
|
189
190
|
|
|
190
|
-
`src/hooks/builtin-policies.ts`
|
|
191
|
+
يحدد `src/hooks/builtin-policies.ts` جميع السياسات المدمجة الـ 26 ك `BuiltinPolicyDefinition` كائنات:
|
|
191
192
|
|
|
192
193
|
```typescript
|
|
193
194
|
interface BuiltinPolicyDefinition {
|
|
@@ -205,15 +206,15 @@ interface BuiltinPolicyDefinition {
|
|
|
205
206
|
}
|
|
206
207
|
```
|
|
207
208
|
|
|
208
|
-
السياسات التي تقبل `params` تعلن عن `PolicyParamsSchema` مع
|
|
209
|
+
السياسات التي تقبل `params` تعلن عن `PolicyParamsSchema` مع الأنواع والقيم الافتراضية لكل معامل. يحقن محيّم السياسة القيم المحلولة في `ctx.params` قبل استدعاء `fn`. تقرأ وظائف السياسة `ctx.params` بدون حماية فارغة لأن القيم الافتراضية تُطبق دائماً أولاً.
|
|
209
210
|
|
|
210
|
-
يستخدم مطابقة الأنماط داخل السياسات رموز الأوامر المحللة (argv)، وليس مطابقة
|
|
211
|
+
يستخدم مطابقة الأنماط داخل السياسات رموز الأوامر المحللة (argv)، وليس مطابقة السلسلة الخام. يمنع هذا التجاوز عبر حقن مشغل الأصداف (على سبيل المثال، نمط لـ `sudo systemctl status *` لا يمكن تجاوزه بإضافة `; rm -rf /` إلى الأمر).
|
|
211
212
|
|
|
212
213
|
---
|
|
213
214
|
|
|
214
215
|
## السياسات المخصصة
|
|
215
216
|
|
|
216
|
-
`src/hooks/custom-hooks-registry.ts`
|
|
217
|
+
يطبق `src/hooks/custom-hooks-registry.ts` سجل مدعوم `globalThis`:
|
|
217
218
|
|
|
218
219
|
```typescript
|
|
219
220
|
const REGISTRY_KEY = "__failproofai_custom_hooks__";
|
|
@@ -226,25 +227,25 @@ export function getCustomHooks(): CustomHook[] { ... }
|
|
|
226
227
|
export function clearCustomHooks(): void { ... } // used in tests
|
|
227
228
|
```
|
|
228
229
|
|
|
229
|
-
`src/hooks/custom-hooks-loader.ts`
|
|
230
|
+
يحمل `src/hooks/custom-hooks-loader.ts` ملف السياسة الخاص بالمستخدم:
|
|
230
231
|
|
|
231
|
-
1. اقرأ `customPoliciesPath` من الإعدادات؛
|
|
232
|
-
2. حل
|
|
233
|
-
3. أعد كتابة جميع استيرادات `from "failproofai"` إلى مسار dist الفعلي بحيث
|
|
234
|
-
4. أعد كتابة
|
|
232
|
+
1. اقرأ `customPoliciesPath` من الإعدادات؛ تخطي إذا كانت غائبة.
|
|
233
|
+
2. أعد حل المسار المطلق؛ تحقق من وجود الملف.
|
|
234
|
+
3. أعد كتابة جميع استيرادات `from "failproofai"` إلى مسار dist الفعلي بحيث يتم حل `customPolicies` إلى نفس سجل `globalThis`.
|
|
235
|
+
4. أعد كتابة واردات الملفات المحلية المتعدية بشكل متكرر لضمان توافق ESM.
|
|
235
236
|
5. اكتب ملفات `.mjs` مؤقتة و `import()` ملف الإدخال.
|
|
236
|
-
6.
|
|
237
|
-
7.
|
|
237
|
+
6. استدع `getCustomHooks()` لاسترجاع الخطاف المسجلة.
|
|
238
|
+
7. انظف جميع الملفات المؤقتة في كتلة `finally`.
|
|
238
239
|
|
|
239
|
-
عند حدوث أي خطأ (
|
|
240
|
+
عند حدوث أي خطأ (الملف غير موجود، خطأ في بناء الجملة، فشل الاستيراد)، يتم تسجيل الخطأ إلى `~/.failproofai/hook.log` ويرجع المحمل مصفوفة فارغة. السياسات المدمجة لم تتأثر.
|
|
240
241
|
|
|
241
|
-
يتم تقييم السياسات المخصصة بعد جميع السياسات المدمجة.
|
|
242
|
+
يتم تقييم السياسات المخصصة بعد جميع السياسات المدمجة. الرفض من سياسة مخصصة لا يزال يختصر السياسات المخصصة الأخرى (لكن جميع السياسات المدمجة قد تم تشغيلها بالفعل في تلك النقطة).
|
|
242
243
|
|
|
243
244
|
---
|
|
244
245
|
|
|
245
246
|
## تسجيل النشاط
|
|
246
247
|
|
|
247
|
-
بعد كل حدث خطاف،
|
|
248
|
+
بعد كل حدث خطاف، يلحق المعالج سطر JSONL بـ `~/.failproofai/hook-activity.jsonl`:
|
|
248
249
|
|
|
249
250
|
```json
|
|
250
251
|
{
|
|
@@ -259,13 +260,13 @@ export function clearCustomHooks(): void { ... } // used in tests
|
|
|
259
260
|
}
|
|
260
261
|
```
|
|
261
262
|
|
|
262
|
-
سطر واحد لكل سياسة اتخذت
|
|
263
|
+
سطر واحد لكل سياسة اتخذت قرار غير سماح. قرارات السماح لا تسجل (للحفاظ على الملف صغيراً).
|
|
263
264
|
|
|
264
265
|
---
|
|
265
266
|
|
|
266
|
-
## معمارية لوحة
|
|
267
|
+
## معمارية لوحة التحكم
|
|
267
268
|
|
|
268
|
-
لوحة
|
|
269
|
+
لوحة التحكم هي تطبيق **Next.js 16** يستخدم App Router مع React Server Components و Server Actions.
|
|
269
270
|
|
|
270
271
|
```text
|
|
271
272
|
app/
|
|
@@ -287,20 +288,20 @@ app/
|
|
|
287
288
|
|
|
288
289
|
**تدفق البيانات:**
|
|
289
290
|
|
|
290
|
-
- مكونات الصفحة
|
|
291
|
-
- صفحة السياسات
|
|
292
|
-
- عارض الجلسة
|
|
291
|
+
- مكونات الصفحة تستدعي `lib/projects.ts` و `lib/log-entries.ts` لقراءة بيانات المشروع/الجلسة مباشرة من نظام الملفات (لا توجد طبقة API للقراءات).
|
|
292
|
+
- تستخدم صفحة السياسات Server Actions لجميع التغييرات (تبديل، تحديث المعاملات، التثبيت/الإزالة).
|
|
293
|
+
- يحلل عارض الجلسة صيغة نسخ Claude JSONL وينقل جدول زمني للرسائل واستدعاءات الأداة.
|
|
293
294
|
|
|
294
295
|
**قرارات التصميم الرئيسية:**
|
|
295
296
|
|
|
296
|
-
- لا توجد قاعدة بيانات - جميع الحالة
|
|
297
|
-
- Server Actions
|
|
298
|
-
- React Server Components لصفحات القراءة -
|
|
299
|
-
- مكونات العميل فقط حيث تكون
|
|
297
|
+
- لا توجد قاعدة بيانات - جميع الحالة الدائمة موجودة في ملفات عادية (`~/.failproofai/`, `~/.claude/projects/`).
|
|
298
|
+
- Server Actions للتغييرات - لا توجد حاجة لـ REST API لعمليات CRUD.
|
|
299
|
+
- React Server Components لصفحات القراءة - تحميل أولي أسرع، لا حزمة عميل لجلب البيانات.
|
|
300
|
+
- مكونات العميل فقط حيث تكون التفاعل مطلوباً (تبديل السياسة، بحث النشاط، عارض السجل).
|
|
300
301
|
|
|
301
302
|
---
|
|
302
303
|
|
|
303
|
-
## تخطيط
|
|
304
|
+
## تخطيط الملف
|
|
304
305
|
|
|
305
306
|
```text
|
|
306
307
|
failproofai/
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
---
|
|
2
2
|
---
|
|
3
3
|
title: التكوين
|
|
4
|
-
description: "صيغة ملف
|
|
4
|
+
description: "صيغة ملف التكوين ونظام النطاقات الثلاثة وقواعد الدمج"
|
|
5
5
|
icon: gear
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
يستخدم failproofai ملفات تكوين JSON للتحكم في السياسات
|
|
8
|
+
يستخدم failproofai ملفات تكوين JSON للتحكم في السياسات النشطة وكيفية عملها وأين يتم تحميل السياسات المخصصة. تم تصميم التكوين ليكون سهل المشاركة مع فريقك - قم بالتعهد به في مستودعك وسيحصل كل مطور على نفس شبكة الأمان للوكيل.
|
|
9
9
|
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
## نطاقات التكوين
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
يوجد ثلاثة نطاقات تكوين، يتم تقييمها بترتيب الأولوية:
|
|
15
15
|
|
|
16
16
|
| النطاق | مسار الملف | الغرض |
|
|
17
|
-
|
|
18
|
-
|
|
|
19
|
-
| **محلي** | `.failproofai/policies-config.local.json` | تجاوزات شخصية لكل مستودع،
|
|
20
|
-
| **عام** | `~/.failproofai/policies-config.json` |
|
|
17
|
+
|-------|-----------|--------|
|
|
18
|
+
| **المشروع** | `.failproofai/policies-config.json` | إعدادات كل مستودع، مرتكبة في التحكم بالإصدار |
|
|
19
|
+
| **محلي** | `.failproofai/policies-config.local.json` | تجاوزات شخصية لكل مستودع، مضافة إلى gitignore |
|
|
20
|
+
| **عام** | `~/.failproofai/policies-config.json` | إعدادات افتراضية على مستوى المستخدم عبر جميع المشاريع |
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
عند استقبال failproofai لحدث hook، يقوم بتحميل ودمج جميع الملفات الثلاثة الموجودة للمجلد الحالي.
|
|
23
23
|
|
|
24
24
|
### قواعد الدمج
|
|
25
25
|
|
|
@@ -30,16 +30,16 @@ project: ["block-sudo"]
|
|
|
30
30
|
local: ["block-rm-rf"]
|
|
31
31
|
global: ["block-sudo", "sanitize-api-keys"]
|
|
32
32
|
|
|
33
|
-
resolved: ["block-sudo", "block-rm-rf", "sanitize-api-keys"] ←
|
|
33
|
+
resolved: ["block-sudo", "block-rm-rf", "sanitize-api-keys"] ← اتحاد منزوع التكرار
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
**`policyParams`** -
|
|
36
|
+
**`policyParams`** - أول نطاق يحدد معاملات سياسة معينة يفوز بالكامل. لا يوجد دمج عميق للقيم داخل معاملات السياسة.
|
|
37
37
|
|
|
38
38
|
```text
|
|
39
39
|
project: block-sudo → { allowPatterns: ["sudo apt-get update"] }
|
|
40
40
|
global: block-sudo → { allowPatterns: ["sudo systemctl status"] }
|
|
41
41
|
|
|
42
|
-
resolved: { allowPatterns: ["sudo apt-get update"] } ← المشروع يفوز،
|
|
42
|
+
resolved: { allowPatterns: ["sudo apt-get update"] } ← المشروع يفوز، العام مهمل
|
|
43
43
|
```
|
|
44
44
|
|
|
45
45
|
```text
|
|
@@ -47,12 +47,12 @@ project: (no block-sudo entry)
|
|
|
47
47
|
local: (no block-sudo entry)
|
|
48
48
|
global: block-sudo → { allowPatterns: ["sudo systemctl status"] }
|
|
49
49
|
|
|
50
|
-
resolved: { allowPatterns: ["sudo systemctl status"] } ←
|
|
50
|
+
resolved: { allowPatterns: ["sudo systemctl status"] } ← ينسكب إلى العام
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
-
**`customPoliciesPath`** -
|
|
53
|
+
**`customPoliciesPath`** - أول نطاق يحدده يفوز.
|
|
54
54
|
|
|
55
|
-
**`llm`** -
|
|
55
|
+
**`llm`** - أول نطاق يحدده يفوز.
|
|
56
56
|
|
|
57
57
|
---
|
|
58
58
|
|
|
@@ -103,7 +103,7 @@ resolved: { allowPatterns: ["sudo systemctl status"] } ← ينتقل إلى ا
|
|
|
103
103
|
|
|
104
104
|
النوع: `string[]`
|
|
105
105
|
|
|
106
|
-
قائمة
|
|
106
|
+
قائمة بأسماء السياسات المراد تفعيلها. يجب أن تتطابق الأسماء بالضبط مع معرّفات السياسات التي يعرضها `failproofai policies`. انظر [السياسات المدمجة](/ar/built-in-policies) للقائمة الكاملة.
|
|
107
107
|
|
|
108
108
|
السياسات غير الموجودة في `enabledPolicies` غير نشطة، حتى لو كانت لديها إدخالات في `policyParams`.
|
|
109
109
|
|
|
@@ -111,19 +111,19 @@ resolved: { allowPatterns: ["sudo systemctl status"] } ← ينتقل إلى ا
|
|
|
111
111
|
|
|
112
112
|
النوع: `Record<string, Record<string, unknown>>`
|
|
113
113
|
|
|
114
|
-
تجاوزات معاملات
|
|
114
|
+
تجاوزات معاملات كل سياسة. المفتاح الخارجي هو اسم السياسة؛ المفاتيح الداخلية خاصة بكل سياسة. توثق كل سياسة معاملاتها المتاحة في [السياسات المدمجة](/ar/built-in-policies).
|
|
115
115
|
|
|
116
|
-
إذا كانت السياسة
|
|
116
|
+
إذا كانت لدى السياسة معاملات ولم تحددها، يتم استخدام القيم الافتراضية المدمجة للسياسة. المستخدمون الذين لا يكونون `policyParams` على الإطلاق يحصلون على سلوك متطابق مع الإصدارات السابقة.
|
|
117
117
|
|
|
118
|
-
المفاتيح غير المعروفة داخل كتلة معاملات السياسة يتم تجاهلها بصمت في وقت إطلاق hook
|
|
118
|
+
المفاتيح غير المعروفة داخل كتلة معاملات السياسة يتم تجاهلها بصمت في وقت إطلاق hook لكن يتم الإشارة إليها كتحذيرات عند تشغيل `failproofai policies`.
|
|
119
119
|
|
|
120
|
-
#### `hint` (
|
|
120
|
+
#### `hint` (عبر الأقسام)
|
|
121
121
|
|
|
122
122
|
النوع: `string` (اختياري)
|
|
123
123
|
|
|
124
|
-
رسالة
|
|
124
|
+
رسالة مُضافة إلى السبب عند عودة السياسة `deny` أو `instruct`. استخدمها لإعطاء Claude إرشادات قابلة للتنفيذ دون تعديل السياسة نفسها.
|
|
125
125
|
|
|
126
|
-
|
|
126
|
+
تعمل مع أي نوع سياسة — مدمج، مخصص (`custom/`)، اتفاقية مشروع (`.failproofai-project/`)، أو اتفاقية مستخدم (`.failproofai-user/`).
|
|
127
127
|
|
|
128
128
|
```json
|
|
129
129
|
{
|
|
@@ -142,32 +142,32 @@ resolved: { allowPatterns: ["sudo systemctl status"] } ← ينتقل إلى ا
|
|
|
142
142
|
}
|
|
143
143
|
```
|
|
144
144
|
|
|
145
|
-
|
|
145
|
+
عند رفض `block-force-push`، يرى Claude: *"Force-pushing is blocked. Try creating a fresh branch instead."*
|
|
146
146
|
|
|
147
|
-
القيم غير
|
|
147
|
+
القيم غير الرشيقة والسلاسل الفارغة يتم تجاهلها بصمت. إذا لم يتم تعيين `hint`، السلوك لم يتغير (متوافق للخلف).
|
|
148
148
|
|
|
149
149
|
### `customPoliciesPath`
|
|
150
150
|
|
|
151
151
|
النوع: `string` (مسار مطلق)
|
|
152
152
|
|
|
153
|
-
المسار إلى ملف JavaScript يحتوي على سياسات hook مخصصة. يتم تعيينه
|
|
153
|
+
المسار إلى ملف JavaScript يحتوي على سياسات hook مخصصة. يتم تعيينه تلقائياً بواسطة `failproofai policies --install --custom <path>` (يتم حل المسار إلى مطلق قبل تخزينه).
|
|
154
154
|
|
|
155
|
-
يتم تحميل الملف
|
|
155
|
+
يتم تحميل الملف بشكل جديد في كل حدث hook - لا يوجد تخزين مؤقت. انظر [السياسات المخصصة](/ar/custom-policies) للتفاصيل حول الكتابة.
|
|
156
156
|
|
|
157
|
-
###
|
|
157
|
+
### سياسات قائمة على الاتفاقية
|
|
158
158
|
|
|
159
|
-
بالإضافة إلى `customPoliciesPath` الصريح، يقوم failproofai
|
|
159
|
+
بالإضافة إلى `customPoliciesPath` الصريح، يقوم failproofai تلقائياً باكتشاف وتحميل ملفات السياسات من مجلدات `.failproofai/policies/`:
|
|
160
160
|
|
|
161
161
|
| المستوى | المجلد | النطاق |
|
|
162
|
-
|
|
163
|
-
|
|
|
164
|
-
|
|
|
162
|
+
|--------|--------|--------|
|
|
163
|
+
| المشروع | `.failproofai/policies/` | مشارك مع الفريق عبر التحكم بالإصدار |
|
|
164
|
+
| المستخدم | `~/.failproofai/policies/` | شخصي، ينطبق على جميع المشاريع |
|
|
165
165
|
|
|
166
|
-
**مطابقة الملفات:** يتم تحميل الملفات المطابقة
|
|
166
|
+
**مطابقة الملفات:** يتم تحميل الملفات المطابقة لـ `*policies.{js,mjs,ts}` فقط (مثل `security-policies.mjs`، `workflow-policies.js`). يتم تجاهل الملفات الأخرى في المجلد.
|
|
167
167
|
|
|
168
|
-
**لا
|
|
168
|
+
**لا توجد حاجة للتكوين:** سياسات الاتفاقية لا تتطلب إدخالات في `policies-config.json`. ما عليك سوى إسقاط الملفات في المجلد وسيتم اختيارها في حدث hook التالي.
|
|
169
169
|
|
|
170
|
-
|
|
170
|
+
**تحميل الاتحاد:** يتم فحص مجلدات الاتفاقية على مستوى المشروع والمستخدم. يتم تحميل جميع الملفات المطابقة من كلا المستويين (بخلاف `customPoliciesPath` الذي يستخدم أول نطاق يفوز).
|
|
171
171
|
|
|
172
172
|
انظر [السياسات المخصصة](/ar/custom-policies) لمزيد من التفاصيل والأمثلة.
|
|
173
173
|
|
|
@@ -175,7 +175,7 @@ resolved: { allowPatterns: ["sudo systemctl status"] } ← ينتقل إلى ا
|
|
|
175
175
|
|
|
176
176
|
النوع: `object` (اختياري)
|
|
177
177
|
|
|
178
|
-
تكوين عميل LLM للسياسات التي تقوم
|
|
178
|
+
تكوين عميل LLM للسياسات التي تقوم بإجراء استدعاءات AI. غير مطلوب لمعظم الإعدادات.
|
|
179
179
|
|
|
180
180
|
```json
|
|
181
181
|
{
|
|
@@ -188,20 +188,20 @@ resolved: { allowPatterns: ["sudo systemctl status"] } ← ينتقل إلى ا
|
|
|
188
188
|
|
|
189
189
|
---
|
|
190
190
|
|
|
191
|
-
## إدارة التكوين من
|
|
191
|
+
## إدارة التكوين من واجهة سطر الأوامر
|
|
192
192
|
|
|
193
|
-
|
|
193
|
+
تكتب أوامر `policies --install` و `policies --uninstall` إلى `settings.json` في Claude Code (نقاط دخول hook)، بينما `policies-config.json` هو الملف الذي تديره مباشرة. الاثنان منفصلان:
|
|
194
194
|
|
|
195
|
-
- **`settings.json`** - يخبر Claude Code
|
|
196
|
-
- **`policies-config.json`** - يخبر failproofai بالسياسات
|
|
195
|
+
- **`settings.json`** - يخبر Claude Code بـ استدعاء `failproofai --hook <event>` في كل استخدام أداة
|
|
196
|
+
- **`policies-config.json`** - يخبر failproofai بالسياسات المراد تقييمها وبأي معاملات
|
|
197
197
|
|
|
198
|
-
يمكنك تحرير `policies-config.json` مباشرة في أي وقت؛ التغييرات
|
|
198
|
+
يمكنك تحرير `policies-config.json` مباشرة في أي وقت؛ التغييرات تأخذ التأثير فوراً في حدث hook التالي بدون الحاجة لإعادة تشغيل.
|
|
199
199
|
|
|
200
200
|
---
|
|
201
201
|
|
|
202
|
-
## مثال: تكوين على مستوى المشروع مع
|
|
202
|
+
## مثال: تكوين على مستوى المشروع مع افتراضيات الفريق
|
|
203
203
|
|
|
204
|
-
|
|
204
|
+
قم بالتعهد `.failproofai/policies-config.json` إلى مستودعك:
|
|
205
205
|
|
|
206
206
|
```json
|
|
207
207
|
{
|
|
@@ -220,4 +220,4 @@ resolved: { allowPatterns: ["sudo systemctl status"] } ← ينتقل إلى ا
|
|
|
220
220
|
}
|
|
221
221
|
```
|
|
222
222
|
|
|
223
|
-
يمكن لكل مطور بعد ذلك إنشاء `.failproofai/policies-config.local.json` (
|
|
223
|
+
يمكن لكل مطور بعد ذلك إنشاء `.failproofai/policies-config.local.json` (مضافة إلى gitignore) للتجاوزات الشخصية دون التأثير على زملائهم.
|