failproofai 0.0.5 → 0.0.6-beta.0
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/workflow-policies.mjs +2 -1
- package/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/build-manifest.json +3 -3
- 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/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/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/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/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/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/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/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]__0a~g15g._.js → [root-of-the-server]__0.~fd7s._.js} +2 -2
- 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]__0qn95h3._.js → [root-of-the-server]__0a.nuas._.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]__0w6l33k._.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 +3 -3
- 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/{09ikntpt2-o9b.js → 0.z51twd.0l5z.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0sme4lkv.tgn-.js → 0hctoh28rg838.js} +1 -1
- package/.next/standalone/.next/static/chunks/{13juklu.vksks.js → 0hplx-8c-4vpv.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0em7tspi4kylh.js → 0maq.q1t.ri85.js} +2 -2
- package/.next/standalone/.next/static/chunks/{17manv47o-~wp.js → 0teq8wdh3po1n.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0lgbwkfqmnsmc.js → 0uc0um_uz51m_.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0yumumfzx_f27.js → 0ul6fk-z.6k-0.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0_yayar~bpphd.js → 0w9lwqy0-v1dk.js} +1 -1
- package/.next/standalone/CHANGELOG.md +5 -0
- package/.next/standalone/dist/cli.mjs +19 -2
- 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/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/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/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/package.json +1 -1
- package/.next/standalone/server.js +1 -1
- package/.next/standalone/src/hooks/builtin-policies.ts +30 -0
- package/dist/cli.mjs +19 -2
- package/package.json +1 -1
- package/src/hooks/builtin-policies.ts +30 -0
- /package/.next/standalone/.next/static/{hYQM6iCWnF1W5XDpsIRhV → 8mygPGI5bzrtWK36ZYO59}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{hYQM6iCWnF1W5XDpsIRhV → 8mygPGI5bzrtWK36ZYO59}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{hYQM6iCWnF1W5XDpsIRhV → 8mygPGI5bzrtWK36ZYO59}/_ssgManifest.js +0 -0
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
---
|
|
3
|
+
title: Özel İlkeler
|
|
4
|
+
description: "JavaScript'te kendi ilkelerinizi yazın - kuralları uygulayın, kaymaları önleyin, arızaları tespit edin, dış sistemlerle entegre olun"
|
|
4
5
|
icon: code
|
|
5
6
|
---
|
|
6
7
|
|
|
7
|
-
Özel
|
|
8
|
+
Özel ilkeler, herhangi bir agent davranışı için kurallar yazmanıza izin verir: proje kurallarını uygulayın, kaymaları önleyin, yıkıcı işlemleri engelleyin, takılmış agent'ları tespit edin veya Slack, onay iş akışları ve daha fazlasıyla entegre olun. Yerleşik ilkelerle aynı hook event sistemini ve `allow`, `deny`, `instruct` kararlarını kullanırlar.
|
|
8
9
|
|
|
9
10
|
---
|
|
10
11
|
|
|
@@ -37,14 +38,14 @@ failproofai policies --install --custom ./my-policies.js
|
|
|
37
38
|
|
|
38
39
|
---
|
|
39
40
|
|
|
40
|
-
## Özel
|
|
41
|
+
## Özel ilkeleri yüklemenin iki yolu
|
|
41
42
|
|
|
42
|
-
### Seçenek 1: Kural tabanlı (
|
|
43
|
+
### Seçenek 1: Kural tabanlı (önerilir)
|
|
43
44
|
|
|
44
|
-
|
|
45
|
+
`*policies.{js,mjs,ts}` dosyalarını `.failproofai/policies/` dizinine bırakın ve otomatik olarak yüklenir — bayrak veya yapılandırma değişikliğine gerek yoktur. Bu, git hook'ları gibi çalışır: bir dosya bırakın, çalışır.
|
|
45
46
|
|
|
46
47
|
```
|
|
47
|
-
# Proje düzeyi — git'e kaydedilir,
|
|
48
|
+
# Proje düzeyi — git'e kaydedilir, takımla paylaşılır
|
|
48
49
|
.failproofai/policies/security-policies.mjs
|
|
49
50
|
.failproofai/policies/workflow-policies.mjs
|
|
50
51
|
|
|
@@ -53,38 +54,38 @@ failproofai policies --install --custom ./my-policies.js
|
|
|
53
54
|
```
|
|
54
55
|
|
|
55
56
|
**Nasıl çalışır:**
|
|
56
|
-
- Hem proje hem de kullanıcı dizinleri taranır (birleşim — ilk
|
|
57
|
-
- Dosyalar her dizin içinde alfabetik olarak yüklenir. Sırayı kontrol etmek için `01-`, `02-`
|
|
57
|
+
- Hem proje hem de kullanıcı dizinleri taranır (birleşim — ilk kapsam kazanmaz)
|
|
58
|
+
- Dosyalar her dizin içinde alfabetik olarak yüklenir. Sırayı kontrol etmek için `01-`, `02-` ön eki ekleyin
|
|
58
59
|
- Yalnızca `*policies.{js,mjs,ts}` ile eşleşen dosyalar yüklenir; diğer dosyalar yoksayılır
|
|
59
|
-
- Her dosya bağımsız olarak yüklenir (dosya başına açık
|
|
60
|
-
- Açık `--custom` ve yerleşik
|
|
60
|
+
- Her dosya bağımsız olarak yüklenir (dosya başına açık başarısızlık)
|
|
61
|
+
- Açık `--custom` ve yerleşik ilkelerle birlikte çalışır
|
|
61
62
|
|
|
62
63
|
<Tip>
|
|
63
|
-
Kural
|
|
64
|
+
Kural tabanlı ilkeler, ilkeleri bir takım arasında paylaşmanın en kolay yoludur. `.failproofai/policies/` öğesini git'e gönderin ve her takım üyesi otomatik olarak bunları alır.
|
|
64
65
|
</Tip>
|
|
65
66
|
|
|
66
67
|
### Seçenek 2: Açık dosya yolu
|
|
67
68
|
|
|
68
69
|
```bash
|
|
69
|
-
# Özel
|
|
70
|
+
# Özel ilkeler dosyasıyla yükleyin
|
|
70
71
|
failproofai policies --install --custom ./my-policies.js
|
|
71
72
|
|
|
72
|
-
#
|
|
73
|
+
# İlkeler dosya yolunu değiştirin
|
|
73
74
|
failproofai policies --install --custom ./new-policies.js
|
|
74
75
|
|
|
75
|
-
# Yapılandırmadan özel
|
|
76
|
+
# Yapılandırmadan özel ilkeler yolunu kaldırın
|
|
76
77
|
failproofai policies --uninstall --custom
|
|
77
78
|
```
|
|
78
79
|
|
|
79
|
-
Çözümlenen mutlak yol, `policies-config.json`
|
|
80
|
+
Çözümlenen mutlak yol, `policies-config.json` öğesine `customPoliciesPath` olarak depolanır. Dosya her hook event'i sırasında yeni yüklenir - event'ler arasında hiçbir önbelleğe alma yoktur.
|
|
80
81
|
|
|
81
82
|
### Her ikisini birlikte kullanma
|
|
82
83
|
|
|
83
|
-
Kural
|
|
84
|
+
Kural tabanlı ilkeler ve açık `--custom` dosyası bir arada bulunabilir. Yükleme sırası:
|
|
84
85
|
|
|
85
86
|
1. Açık `customPoliciesPath` dosyası (yapılandırılmışsa)
|
|
86
|
-
2. Proje kural dosyaları (`{cwd}/.failproofai/policies/`, alfabetik)
|
|
87
|
-
3. Kullanıcı kural dosyaları (`~/.failproofai/policies/`, alfabetik)
|
|
87
|
+
2. Proje kural tabanlı dosyaları (`{cwd}/.failproofai/policies/`, alfabetik)
|
|
88
|
+
3. Kullanıcı kural tabanlı dosyaları (`~/.failproofai/policies/`, alfabetik)
|
|
88
89
|
|
|
89
90
|
---
|
|
90
91
|
|
|
@@ -98,13 +99,13 @@ import { customPolicies, allow, deny, instruct } from "failproofai";
|
|
|
98
99
|
|
|
99
100
|
### `customPolicies.add(hook)`
|
|
100
101
|
|
|
101
|
-
Bir
|
|
102
|
+
Bir ilkeyi kaydeder. Aynı dosyada birden fazla ilke için gerektiği kadar çağırın.
|
|
102
103
|
|
|
103
104
|
```ts
|
|
104
105
|
customPolicies.add({
|
|
105
|
-
name: string; //
|
|
106
|
+
name: string; // gerekli - benzersiz tanımlayıcı
|
|
106
107
|
description?: string; // `failproofai policies` çıktısında gösterilir
|
|
107
|
-
match?: { events?: HookEventType[] }; //
|
|
108
|
+
match?: { events?: HookEventType[] }; // event türüne göre filtre; tümüyle eşleştirmek için atla
|
|
108
109
|
fn: (ctx: PolicyContext) => PolicyResult | Promise<PolicyResult>;
|
|
109
110
|
});
|
|
110
111
|
```
|
|
@@ -113,31 +114,30 @@ customPolicies.add({
|
|
|
113
114
|
|
|
114
115
|
| İşlev | Etki | Ne zaman kullanılır |
|
|
115
116
|
|----------|--------|----------|
|
|
116
|
-
| `allow()` | İşleme
|
|
117
|
+
| `allow()` | İşleme izin ver sessizce | İşlem güvenli, ileti gerekmez |
|
|
117
118
|
| `deny(message)` | İşlemi engelle | Agent bu işlemi yapmamalı |
|
|
118
|
-
| `instruct(message)` |
|
|
119
|
+
| `instruct(message)` | Engellemeden bağlam ekle | Agent'a yolunda kalmak için ek bağlam ver |
|
|
119
120
|
|
|
120
|
-
`deny(message)` - ileti Claude'a `"Blocked by failproofai:"` ön
|
|
121
|
+
`deny(message)` - ileti Claude'a `"Blocked by failproofai:"` ön ekiyle görünür. Tek bir `deny`, tüm sonraki değerlendirmeleri kısaltır.
|
|
121
122
|
|
|
122
|
-
`instruct(message)` - ileti,
|
|
123
|
+
`instruct(message)` - ileti, geçerli araç çağrısı için Claude'un bağlamına eklenir. Tüm `instruct` iletileri biriktirilir ve birlikte teslim edilir.
|
|
123
124
|
|
|
124
125
|
<Tip>
|
|
125
|
-
`policyParams`
|
|
126
|
+
Kod değişikliğine gerek olmadan `policyParams` öğesinde bir `hint` alanı ekleyerek herhangi bir `deny` veya `instruct` iletisine ek rehberlik ekleyebilirsiniz. Bu, özel (`custom/`), proje kuralı (`.failproofai-project/`), ve kullanıcı kuralı (`.failproofai-user/`) ilkeleri için de çalışır. Ayrıntılar için bkz. [Yapılandırma → hint](/tr/configuration#hint-cross-cutting).
|
|
126
127
|
</Tip>
|
|
127
128
|
|
|
128
|
-
###
|
|
129
|
-
|
|
129
|
+
### Bilgisel izin iletileri
|
|
130
130
|
|
|
131
|
-
`allow(message)` işleme izin verir **ve** Claude'a
|
|
131
|
+
`allow(message)` işleme izin verir **ve** Claude'a geri bilgisel bir ileti gönderir. İleti, hook handler'ın stdout yanıtında `additionalContext` olarak teslim edilir — `instruct` tarafından kullanılan aynı mekanizma, ancak anlamsal olarak farklıdır: bir uyarı değil, bir durum güncellemesidir.
|
|
132
132
|
|
|
133
133
|
| İşlev | Etki | Ne zaman kullanılır |
|
|
134
134
|
|----------|--------|----------|
|
|
135
|
-
| `allow(message)` | İzin ver ve Claude'a bağlam gönder | Bir
|
|
135
|
+
| `allow(message)` | İzin ver ve Claude'a bağlam gönder | Bir kontrolün geçtiğini doğrula veya neden atlandığını açıkla |
|
|
136
136
|
|
|
137
|
-
Kullanım
|
|
137
|
+
Kullanım durumları:
|
|
138
138
|
- **Durum onayları:** `allow("All CI checks passed.")` — Claude'a her şeyin yeşil olduğunu söyler
|
|
139
|
-
- **
|
|
140
|
-
- **Birden
|
|
139
|
+
- **Açık başarısızlık açıklamaları:** `allow("GitHub CLI not installed, skipping CI check.")` — Claude'a bir kontrolün neden atlandığını söyler böylece tam bağlama sahip olur
|
|
140
|
+
- **Birden fazla ileti birikir:** birkaç ilke her biri `allow(message)` döndürürse, tüm iletiler yeni satırlarla birleştirilir ve birlikte teslim edilir
|
|
141
141
|
|
|
142
142
|
```js
|
|
143
143
|
customPolicies.add({
|
|
@@ -147,7 +147,7 @@ customPolicies.add({
|
|
|
147
147
|
const cwd = ctx.session?.cwd;
|
|
148
148
|
if (!cwd) return allow("No working directory, skipping branch check.");
|
|
149
149
|
|
|
150
|
-
// ... branch
|
|
150
|
+
// ... check branch status ...
|
|
151
151
|
if (allPushed) {
|
|
152
152
|
return allow("Branch is up to date with remote.");
|
|
153
153
|
}
|
|
@@ -161,9 +161,9 @@ customPolicies.add({
|
|
|
161
161
|
| Alan | Tür | Açıklama |
|
|
162
162
|
|-------|------|-------------|
|
|
163
163
|
| `eventType` | `string` | `"PreToolUse"`, `"PostToolUse"`, `"Notification"`, `"Stop"` |
|
|
164
|
-
| `toolName` | `string \| undefined` | Çağrılan araç (
|
|
165
|
-
| `toolInput` | `Record<string, unknown> \| undefined` |
|
|
166
|
-
| `payload` | `Record<string, unknown>` | Claude Code'dan tam ham
|
|
164
|
+
| `toolName` | `string \| undefined` | Çağrılan araç (ör. `"Bash"`, `"Write"`, `"Read"`) |
|
|
165
|
+
| `toolInput` | `Record<string, unknown> \| undefined` | Aracın giriş parametreleri |
|
|
166
|
+
| `payload` | `Record<string, unknown>` | Claude Code'dan tam ham event payload |
|
|
167
167
|
| `session` | `SessionMetadata \| undefined` | Oturum bağlamı (aşağıya bakın) |
|
|
168
168
|
|
|
169
169
|
### `SessionMetadata` alanları
|
|
@@ -172,37 +172,37 @@ customPolicies.add({
|
|
|
172
172
|
|-------|------|-------------|
|
|
173
173
|
| `sessionId` | `string` | Claude Code oturum tanımlayıcısı |
|
|
174
174
|
| `cwd` | `string` | Claude Code oturumunun çalışma dizini |
|
|
175
|
-
| `transcriptPath` | `string` | Oturumun JSONL
|
|
175
|
+
| `transcriptPath` | `string` | Oturumun JSONL transcript dosyasının yolu |
|
|
176
176
|
|
|
177
|
-
###
|
|
177
|
+
### Event türleri
|
|
178
178
|
|
|
179
|
-
|
|
|
179
|
+
| Event | Ne zaman çalışır | `toolInput` içeriği |
|
|
180
180
|
|-------|--------------|----------------------|
|
|
181
|
-
| `PreToolUse` | Claude bir aracı çalıştırmadan önce |
|
|
182
|
-
| `PostToolUse` | Bir araç tamamlandıktan sonra |
|
|
183
|
-
| `Notification` | Claude bir bildirim gönderdiğinde | `{ message: "...", notification_type: "idle" \| "permission_prompt" \| ... }` - hook'lar her zaman `allow()` döndürmelidir, bildirimleri
|
|
181
|
+
| `PreToolUse` | Claude bir aracı çalıştırmadan önce | Aracın girdisi (ör. Bash için `{ command: "..." }`) |
|
|
182
|
+
| `PostToolUse` | Bir araç tamamlandıktan sonra | Aracın girdisi + `tool_result` (çıktı) |
|
|
183
|
+
| `Notification` | Claude bir bildirim gönderdiğinde | `{ message: "...", notification_type: "idle" \| "permission_prompt" \| ... }` - hook'lar her zaman `allow()` döndürmelidir, bildirimleri engelleyemezler |
|
|
184
184
|
| `Stop` | Claude oturumu sona erdiğinde | Boş |
|
|
185
185
|
|
|
186
186
|
---
|
|
187
187
|
|
|
188
188
|
## Değerlendirme sırası
|
|
189
189
|
|
|
190
|
-
|
|
190
|
+
İlkeler şu sırayla değerlendirilir:
|
|
191
191
|
|
|
192
|
-
1. Yerleşik
|
|
193
|
-
2. `customPoliciesPath` öğesinden açık özel
|
|
194
|
-
3. Proje `.failproofai/policies/` öğesinden kural
|
|
195
|
-
4. Kullanıcı `~/.failproofai/policies/` öğesinden kural
|
|
192
|
+
1. Yerleşik ilkeler (tanım sırasında)
|
|
193
|
+
2. `customPoliciesPath` öğesinden açık özel ilkeler (.add() sırasında)
|
|
194
|
+
3. Proje `.failproofai/policies/` öğesinden kural ilkeleri (dosyalar alfabetik, .add() sırasında)
|
|
195
|
+
4. Kullanıcı `~/.failproofai/policies/` öğesinden kural ilkeleri (dosyalar alfabetik, .add() sırasında)
|
|
196
196
|
|
|
197
197
|
<Note>
|
|
198
|
-
İlk `deny
|
|
198
|
+
İlk `deny`, sonraki tüm ilkeleri kısaltır. Tüm `instruct` iletileri biriktirilir ve birlikte teslim edilir.
|
|
199
199
|
</Note>
|
|
200
200
|
|
|
201
201
|
---
|
|
202
202
|
|
|
203
203
|
## Geçişli içe aktarmalar
|
|
204
204
|
|
|
205
|
-
Özel
|
|
205
|
+
Özel ilke dosyaları, göreceli yollar kullanarak yerel modülleri içe aktarabilir:
|
|
206
206
|
|
|
207
207
|
```js
|
|
208
208
|
// my-policies.js
|
|
@@ -219,46 +219,46 @@ customPolicies.add({
|
|
|
219
219
|
});
|
|
220
220
|
```
|
|
221
221
|
|
|
222
|
-
Giriş dosyasından
|
|
222
|
+
Giriş dosyasından ulaşılabilir tüm göreceli içe aktarmalar çözümlenir. Bu, `from "failproofai"` içe aktarmalarını gerçek dist yoluna yeniden yazarak ve ESM uyumluluğunu sağlamak için geçici `.mjs` dosyaları oluşturarak uygulanır.
|
|
223
223
|
|
|
224
224
|
---
|
|
225
225
|
|
|
226
|
-
##
|
|
226
|
+
## Event türü filtrelemesi
|
|
227
227
|
|
|
228
|
-
Bir
|
|
228
|
+
Bir ilkenin ne zaman çalıştığını sınırlandırmak için `match.events` kullanın:
|
|
229
229
|
|
|
230
230
|
```js
|
|
231
231
|
customPolicies.add({
|
|
232
232
|
name: "require-summary-on-stop",
|
|
233
233
|
match: { events: ["Stop"] },
|
|
234
234
|
fn: async (ctx) => {
|
|
235
|
-
// Yalnızca oturum sona erdiğinde
|
|
235
|
+
// Yalnızca oturum sona erdiğinde çalışır
|
|
236
236
|
// ctx.session.transcriptPath tam oturum günlüğünü içerir
|
|
237
237
|
return allow();
|
|
238
238
|
},
|
|
239
239
|
});
|
|
240
240
|
```
|
|
241
241
|
|
|
242
|
-
Her
|
|
242
|
+
Her event türüne ateş etmek için `match` öğesini tamamen atlayın.
|
|
243
243
|
|
|
244
244
|
---
|
|
245
245
|
|
|
246
246
|
## Hata işleme ve başarısızlık modları
|
|
247
247
|
|
|
248
|
-
Özel
|
|
248
|
+
Özel ilkeler **açık başarısızlıktır**: hatalar asla yerleşik ilkeleri engelleme veya hook handler'ı kilitlenmez.
|
|
249
249
|
|
|
250
250
|
| Başarısızlık | Davranış |
|
|
251
251
|
|---------|----------|
|
|
252
|
-
| `customPoliciesPath` ayarlanmadı | Açık özel
|
|
253
|
-
| Dosya bulunamadı |
|
|
254
|
-
|
|
|
255
|
-
|
|
|
256
|
-
| `fn` çalışma zamanında
|
|
257
|
-
| `fn`
|
|
258
|
-
| Kural dizini eksik | Kural
|
|
252
|
+
| `customPoliciesPath` ayarlanmadı | Açık özel ilkeler çalışmaz; kural ilkeleri ve yerleşikler normal şekilde devam eder |
|
|
253
|
+
| Dosya bulunamadı | `~/.failproofai/hook.log` öğesine uyarı kaydedilir; yerleşikler devam eder |
|
|
254
|
+
| Söz dizimi/içe aktarma hatası (açık) | Hata `~/.failproofai/hook.log` öğesine kaydedilir; açık özel ilkeler atlanır |
|
|
255
|
+
| Söz dizimi/içe aktarma hatası (kural) | Hata kaydedilir; dosya atlanır, diğer kural dosyaları yine de yüklenir |
|
|
256
|
+
| `fn` çalışma zamanında throw atar | Hata kaydedilir; bu hook `allow` olarak kabul edilir; diğer hook'lar devam eder |
|
|
257
|
+
| `fn` 10s'den daha uzun sürer | Zaman aşımı kaydedilir; `allow` olarak kabul edilir |
|
|
258
|
+
| Kural dizini eksik | Kural ilkeleri çalışmaz; hata yok |
|
|
259
259
|
|
|
260
260
|
<Tip>
|
|
261
|
-
Özel
|
|
261
|
+
Özel ilke hatalarını ayıklamak için günlük dosyasını izleyin:
|
|
262
262
|
|
|
263
263
|
```bash
|
|
264
264
|
tail -f ~/.failproofai/hook.log
|
|
@@ -267,13 +267,13 @@ tail -f ~/.failproofai/hook.log
|
|
|
267
267
|
|
|
268
268
|
---
|
|
269
269
|
|
|
270
|
-
## Tam örnek: birden
|
|
270
|
+
## Tam örnek: birden fazla ilke
|
|
271
271
|
|
|
272
272
|
```js
|
|
273
273
|
// my-policies.js
|
|
274
274
|
import { customPolicies, allow, deny, instruct } from "failproofai";
|
|
275
275
|
|
|
276
|
-
// Agent'
|
|
276
|
+
// Agent'ı secrets/ dizinine yazmasını engelle
|
|
277
277
|
customPolicies.add({
|
|
278
278
|
name: "block-secrets-dir",
|
|
279
279
|
description: "Prevent agent from writing to secrets/ directory",
|
|
@@ -286,7 +286,7 @@ customPolicies.add({
|
|
|
286
286
|
},
|
|
287
287
|
});
|
|
288
288
|
|
|
289
|
-
// Agent'
|
|
289
|
+
// Agent'ı yolunda tut: commit'lemeden önce testleri doğrula
|
|
290
290
|
customPolicies.add({
|
|
291
291
|
name: "remind-test-before-commit",
|
|
292
292
|
description: "Keep the agent on track: verify tests pass before committing",
|
|
@@ -301,7 +301,7 @@ customPolicies.add({
|
|
|
301
301
|
},
|
|
302
302
|
});
|
|
303
303
|
|
|
304
|
-
// Dondurma döneminde
|
|
304
|
+
// Dondurma döneminde planlanmamış bağımlılık değişikliklerini engelle
|
|
305
305
|
customPolicies.add({
|
|
306
306
|
name: "dependency-freeze",
|
|
307
307
|
description: "Prevent unplanned dependency changes during freeze period",
|
|
@@ -324,14 +324,14 @@ export { customPolicies };
|
|
|
324
324
|
|
|
325
325
|
## Örnekler
|
|
326
326
|
|
|
327
|
-
`examples/` dizini çalışmaya hazır
|
|
327
|
+
`examples/` dizini çalışmaya hazır ilke dosyalarını içerir:
|
|
328
328
|
|
|
329
329
|
| Dosya | İçerik |
|
|
330
330
|
|------|----------|
|
|
331
|
-
| `examples/policies-basic.js` |
|
|
332
|
-
| `examples/policies-advanced/index.js` |
|
|
333
|
-
| `examples/convention-policies/security-policies.mjs` | Kural tabanlı güvenlik
|
|
334
|
-
| `examples/convention-policies/workflow-policies.mjs` | Kural tabanlı iş akışı
|
|
331
|
+
| `examples/policies-basic.js` | Yaygın agent başarısızlık modlarını kapsayan beş başlangıç ilkesi |
|
|
332
|
+
| `examples/policies-advanced/index.js` | İleri düzey desenler: geçişli içe aktarmalar, zaman uyumsuz çağrılar, çıktı temizleme ve oturum sonu hook'ları |
|
|
333
|
+
| `examples/convention-policies/security-policies.mjs` | Kural tabanlı güvenlik ilkeleri (.env yazmalarını engelle, git geçmişi yeniden yazmayı önle) |
|
|
334
|
+
| `examples/convention-policies/workflow-policies.mjs` | Kural tabanlı iş akışı ilkeleri (test anımsatıcıları, denetim dosyası yazmaları) |
|
|
335
335
|
|
|
336
336
|
### Açık dosya örneklerini kullanma
|
|
337
337
|
|
|
@@ -351,4 +351,4 @@ mkdir -p ~/.failproofai/policies
|
|
|
351
351
|
cp examples/convention-policies/*.mjs ~/.failproofai/policies/
|
|
352
352
|
```
|
|
353
353
|
|
|
354
|
-
Yükleme komutu
|
|
354
|
+
Yükleme komutu gerekmez — dosyalar sonraki hook event'i sırasında otomatik olarak alınır.
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
---
|
|
2
|
+
|
|
2
3
|
---
|
|
3
4
|
title: Kiến trúc
|
|
4
|
-
description: "Cách hook handler, config loading, và policy evaluation hoạt động
|
|
5
|
+
description: "Cách hook handler, config loading, và policy evaluation hoạt động nội bộ"
|
|
5
6
|
icon: sitemap
|
|
6
7
|
---
|
|
7
8
|
|
|
8
|
-
Tài liệu này giải thích cách failproofai hoạt động
|
|
9
|
+
Tài liệu này giải thích cách failproofai hoạt động nội bộ: cách hook system chặn các tool call của agent, cách configuration được load và merge, cách policies được đánh giá, và cách dashboard giám sát hoạt động của agent.
|
|
9
10
|
|
|
10
11
|
---
|
|
11
12
|
|
|
@@ -13,10 +14,10 @@ Tài liệu này giải thích cách failproofai hoạt động bên trong: các
|
|
|
13
14
|
|
|
14
15
|
failproofai có hai subsystem độc lập:
|
|
15
16
|
|
|
16
|
-
1. **Hook handler** - Một CLI
|
|
17
|
-
2. **Agent Monitor (Dashboard)** - Một ứng dụng web Next.js để giám sát các session
|
|
17
|
+
1. **Hook handler** - Một subprocess CLI nhanh mà Claude Code gọi trên mỗi agent tool call. Đánh giá policies và trả về quyết định.
|
|
18
|
+
2. **Agent Monitor (Dashboard)** - Một ứng dụng web Next.js để giám sát các agent session và quản lý policies.
|
|
18
19
|
|
|
19
|
-
Cả hai subsystem chia sẻ các
|
|
20
|
+
Cả hai subsystem chia sẻ các file cấu hình trong `~/.failproofai/` và thư mục `.failproofai/` của project, nhưng chúng chạy như các process riêng biệt và chỉ giao tiếp thông qua filesystem.
|
|
20
21
|
|
|
21
22
|
---
|
|
22
23
|
|
|
@@ -24,7 +25,7 @@ Cả hai subsystem chia sẻ các tệp cấu hình trong `~/.failproofai/` và
|
|
|
24
25
|
|
|
25
26
|
### Tích hợp với Claude Code
|
|
26
27
|
|
|
27
|
-
Khi bạn chạy `failproofai policies --install`, nó sẽ ghi các
|
|
28
|
+
Khi bạn chạy `failproofai policies --install`, nó sẽ ghi các entry như sau vào `~/.claude/settings.json`:
|
|
28
29
|
|
|
29
30
|
```json
|
|
30
31
|
{
|
|
@@ -45,7 +46,7 @@ Khi bạn chạy `failproofai policies --install`, nó sẽ ghi các mục như
|
|
|
45
46
|
}
|
|
46
47
|
```
|
|
47
48
|
|
|
48
|
-
Claude Code sau đó gọi `failproofai --hook PreToolUse`
|
|
49
|
+
Claude Code sau đó gọi `failproofai --hook PreToolUse` như một subprocess trước mỗi tool call, truyền một JSON payload trên stdin.
|
|
49
50
|
|
|
50
51
|
### Định dạng payload
|
|
51
52
|
|
|
@@ -61,11 +62,11 @@ Claude Code sau đó gọi `failproofai --hook PreToolUse` dưới dạng một
|
|
|
61
62
|
}
|
|
62
63
|
```
|
|
63
64
|
|
|
64
|
-
Đối với
|
|
65
|
+
Đối với `PostToolUse` events, payload cũng chứa `tool_result` với output của tool.
|
|
65
66
|
|
|
66
|
-
Handler
|
|
67
|
+
Handler enforces giới hạn stdin 1 MB. Các payload vượt quá giới hạn này được loại bỏ và tất cả policies implicit cho phép.
|
|
67
68
|
|
|
68
|
-
### Định dạng
|
|
69
|
+
### Định dạng response
|
|
69
70
|
|
|
70
71
|
**Deny (PreToolUse):**
|
|
71
72
|
```json
|
|
@@ -86,7 +87,7 @@ Handler thực thi giới hạn 1 MB cho stdin. Các payload vượt quá giới
|
|
|
86
87
|
}
|
|
87
88
|
```
|
|
88
89
|
|
|
89
|
-
**Instruct (
|
|
90
|
+
**Instruct (any event except Stop):**
|
|
90
91
|
```json
|
|
91
92
|
{
|
|
92
93
|
"hookSpecificOutput": {
|
|
@@ -96,32 +97,32 @@ Handler thực thi giới hạn 1 MB cho stdin. Các payload vượt quá giới
|
|
|
96
97
|
```
|
|
97
98
|
|
|
98
99
|
**Stop event instruct:**
|
|
99
|
-
-
|
|
100
|
+
- Exit code: `2`
|
|
100
101
|
- Lý do được ghi vào stderr (không phải stdout)
|
|
101
102
|
|
|
102
103
|
**Allow:**
|
|
103
|
-
-
|
|
104
|
+
- Exit code: `0`
|
|
104
105
|
- Stdout trống
|
|
105
106
|
|
|
106
|
-
**Allow
|
|
107
|
+
**Allow với message:**
|
|
107
108
|
|
|
108
|
-
`allow(message)` cho phép một
|
|
109
|
+
`allow(message)` cho phép một policy gửi informational context trở lại Claude ngay cả khi operation được phép. Hook handler ghi JSON sau vào **stdout** (không phải config file — đây là handler's response tới Claude Code, giống như deny và instruct responses ở trên):
|
|
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'."
|
|
115
116
|
}
|
|
116
117
|
}
|
|
117
118
|
```
|
|
118
|
-
-
|
|
119
|
-
- Khi nhiều
|
|
120
|
-
- Nếu không có
|
|
119
|
+
- Exit code: `0` (operation được phép)
|
|
120
|
+
- Khi nhiều policies trả về `allow` với một message, các messages của chúng được join với newlines thành một single `additionalContext` string
|
|
121
|
+
- Nếu không có policy nào cung cấp message, stdout trống (giống như trước)
|
|
121
122
|
|
|
122
123
|
### Processing pipeline
|
|
123
124
|
|
|
124
|
-
`src/hooks/handler.ts`
|
|
125
|
+
`src/hooks/handler.ts` implements toàn bộ pipeline:
|
|
125
126
|
|
|
126
127
|
```text
|
|
127
128
|
stdin JSON
|
|
@@ -140,13 +141,13 @@ stdin JSON
|
|
|
140
141
|
→ exit
|
|
141
142
|
```
|
|
142
143
|
|
|
143
|
-
Toàn bộ
|
|
144
|
+
Toàn bộ process chạy dưới 100ms cho các typical payloads mà không có LLM calls.
|
|
144
145
|
|
|
145
146
|
---
|
|
146
147
|
|
|
147
148
|
## Configuration loading
|
|
148
149
|
|
|
149
|
-
`src/hooks/hooks-config.ts`
|
|
150
|
+
`src/hooks/hooks-config.ts` implements three-scope config loading.
|
|
150
151
|
|
|
151
152
|
```text
|
|
152
153
|
[1] {cwd}/.failproofai/policies-config.json ← project (highest priority)
|
|
@@ -155,39 +156,39 @@ Toàn bộ quá trình chạy trong dưới 100ms cho các payload điển hình
|
|
|
155
156
|
```
|
|
156
157
|
|
|
157
158
|
Merge logic:
|
|
158
|
-
- `enabledPolicies` - union
|
|
159
|
-
- `policyParams` -
|
|
160
|
-
- `customPoliciesPath` -
|
|
161
|
-
- `llm` -
|
|
159
|
+
- `enabledPolicies` - deduplicated union across all three files
|
|
160
|
+
- `policyParams` - per-policy key, first file that defines it wins entirely
|
|
161
|
+
- `customPoliciesPath` - first file that defines it wins
|
|
162
|
+
- `llm` - first file that defines it wins
|
|
162
163
|
|
|
163
|
-
|
|
164
|
+
Web dashboard sử dụng `readHooksConfig()` (global only) để đọc và ghi, vì nó không được gọi với project cwd.
|
|
164
165
|
|
|
165
166
|
---
|
|
166
167
|
|
|
167
168
|
## Policy evaluation
|
|
168
169
|
|
|
169
|
-
`src/hooks/policy-evaluator.ts` chạy
|
|
170
|
+
`src/hooks/policy-evaluator.ts` chạy policies theo thứ tự.
|
|
170
171
|
|
|
171
|
-
|
|
172
|
+
Với mỗi policy:
|
|
172
173
|
|
|
173
|
-
1.
|
|
174
|
-
2. Đọc `policyParams[policy.name]` từ config
|
|
175
|
-
3.
|
|
176
|
-
4. Gọi `policy.fn(ctx)` với context
|
|
177
|
-
5. Nếu
|
|
178
|
-
6. Nếu
|
|
179
|
-
7. Nếu
|
|
174
|
+
1. Look up policy's `params` schema (nếu nó có).
|
|
175
|
+
2. Đọc `policyParams[policy.name]` từ merged config.
|
|
176
|
+
3. Merge user-provided values over schema defaults để tạo `ctx.params`.
|
|
177
|
+
4. Gọi `policy.fn(ctx)` với resolved context.
|
|
178
|
+
5. Nếu result là `deny`, dừng ngay lập tức và trả về quyết định đó.
|
|
179
|
+
6. Nếu result là `instruct`, accumulate message và tiếp tục.
|
|
180
|
+
7. Nếu result là `allow`, tiếp tục tới policy tiếp theo.
|
|
180
181
|
|
|
181
|
-
Sau khi tất cả
|
|
182
|
-
- Nếu bất kỳ `deny` nào được trả về,
|
|
183
|
-
- Nếu bất kỳ
|
|
184
|
-
-
|
|
182
|
+
Sau khi tất cả policies chạy:
|
|
183
|
+
- Nếu bất kỳ `deny` nào được trả về, emit deny response.
|
|
184
|
+
- Nếu bất kỳ `instruct` returns nào được collected, emit một single instruct response với tất cả messages được join.
|
|
185
|
+
- Ngoài ra, emit một allow response (empty stdout, exit 0).
|
|
185
186
|
|
|
186
187
|
---
|
|
187
188
|
|
|
188
189
|
## Builtin policies
|
|
189
190
|
|
|
190
|
-
`src/hooks/builtin-policies.ts` định nghĩa tất cả 26
|
|
191
|
+
`src/hooks/builtin-policies.ts` định nghĩa tất cả 26 built-in policies như `BuiltinPolicyDefinition` objects:
|
|
191
192
|
|
|
192
193
|
```typescript
|
|
193
194
|
interface BuiltinPolicyDefinition {
|
|
@@ -205,15 +206,15 @@ interface BuiltinPolicyDefinition {
|
|
|
205
206
|
}
|
|
206
207
|
```
|
|
207
208
|
|
|
208
|
-
Các
|
|
209
|
+
Các policies chấp nhận `params` khai báo một `PolicyParamsSchema` với types và defaults cho mỗi parameter. Policy evaluator injects resolved values vào `ctx.params` trước khi gọi `fn`. Policy functions đọc `ctx.params` mà không cần null-guarding vì defaults luôn được applied trước.
|
|
209
210
|
|
|
210
|
-
|
|
211
|
+
Pattern matching bên trong policies sử dụng parsed command tokens (argv), không phải raw string matching. Điều này ngăn chặn bypass thông qua shell operator injection (ví dụ: một pattern cho `sudo systemctl status *` không thể bypass bằng cách append `; rm -rf /` vào command).
|
|
211
212
|
|
|
212
213
|
---
|
|
213
214
|
|
|
214
215
|
## Custom policies
|
|
215
216
|
|
|
216
|
-
`src/hooks/custom-hooks-registry.ts`
|
|
217
|
+
`src/hooks/custom-hooks-registry.ts` implements một `globalThis`-backed registry:
|
|
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` load user's policy file:
|
|
230
231
|
|
|
231
|
-
1. Đọc `customPoliciesPath` từ
|
|
232
|
-
2.
|
|
233
|
-
3.
|
|
234
|
-
4.
|
|
235
|
-
5.
|
|
236
|
-
6. Gọi `getCustomHooks()` để
|
|
237
|
-
7.
|
|
232
|
+
1. Đọc `customPoliciesPath` từ config; skip nếu absent.
|
|
233
|
+
2. Resolve tới absolute path; check file exists.
|
|
234
|
+
3. Rewrite tất cả `from "failproofai"` imports tới actual dist path để `customPolicies` resolve tới cùng `globalThis` registry.
|
|
235
|
+
4. Recursively rewrite transitive local imports để ensure ESM compatibility.
|
|
236
|
+
5. Write temporary `.mjs` files và `import()` entry file.
|
|
237
|
+
6. Gọi `getCustomHooks()` để retrieve registered hooks.
|
|
238
|
+
7. Clean up tất cả temp files trong một `finally` block.
|
|
238
239
|
|
|
239
|
-
|
|
240
|
+
Trên bất kỳ error nào (file not found, syntax error, import failure), error được logged tới `~/.failproofai/hook.log` và loader trả về một empty array. Built-in policies không bị ảnh hưởng.
|
|
240
241
|
|
|
241
|
-
|
|
242
|
+
Custom policies được đánh giá sau tất cả built-in policies. Một custom policy `deny` vẫn short-circuits further custom policies (nhưng tất cả built-ins đã chạy rồi ở điểm đó).
|
|
242
243
|
|
|
243
244
|
---
|
|
244
245
|
|
|
245
246
|
## Activity logging
|
|
246
247
|
|
|
247
|
-
Sau mỗi
|
|
248
|
+
Sau mỗi hook event, handler appends một JSONL line tới `~/.failproofai/hook-activity.jsonl`:
|
|
248
249
|
|
|
249
250
|
```json
|
|
250
251
|
{
|
|
@@ -259,13 +260,13 @@ Sau mỗi sự kiện hook, handler nối một dòng JSONL vào `~/.failproofai
|
|
|
259
260
|
}
|
|
260
261
|
```
|
|
261
262
|
|
|
262
|
-
Một
|
|
263
|
+
Một line cho mỗi policy mà có một non-allow decision. Allow decisions không được logged (để giữ file nhỏ).
|
|
263
264
|
|
|
264
265
|
---
|
|
265
266
|
|
|
266
267
|
## Dashboard architecture
|
|
267
268
|
|
|
268
|
-
Dashboard là một
|
|
269
|
+
Dashboard là một **Next.js 16** application sử dụng App Router với React Server Components và Server Actions.
|
|
269
270
|
|
|
270
271
|
```text
|
|
271
272
|
app/
|
|
@@ -287,16 +288,16 @@ app/
|
|
|
287
288
|
|
|
288
289
|
**Data flow:**
|
|
289
290
|
|
|
290
|
-
-
|
|
291
|
-
-
|
|
292
|
-
- Session viewer
|
|
291
|
+
- Page components gọi `lib/projects.ts` và `lib/log-entries.ts` để đọc project/session data trực tiếp từ filesystem (không API layer cho reads).
|
|
292
|
+
- Policies page sử dụng Server Actions cho tất cả mutations (toggle, params update, install/remove).
|
|
293
|
+
- Session viewer parse Claude's JSONL transcript format và render một timeline của messages và tool calls.
|
|
293
294
|
|
|
294
295
|
**Key design decisions:**
|
|
295
296
|
|
|
296
|
-
- Không
|
|
297
|
-
- Server Actions cho mutations - không cần REST API cho
|
|
298
|
-
- React Server Components cho
|
|
299
|
-
- Client components chỉ
|
|
297
|
+
- Không database - tất cả persistent state nằm trong plain files (`~/.failproofai/`, `~/.claude/projects/`).
|
|
298
|
+
- Server Actions cho mutations - không cần REST API cho CRUD operations.
|
|
299
|
+
- React Server Components cho read pages - faster initial load, không client bundle cho data fetching.
|
|
300
|
+
- Client components chỉ ở nơi cần interactivity (policy toggles, activity search, log viewer).
|
|
300
301
|
|
|
301
302
|
---
|
|
302
303
|
|