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.
Files changed (144) hide show
  1. package/.next/standalone/.failproofai/policies/workflow-policies.mjs +2 -1
  2. package/.next/standalone/.next/BUILD_ID +1 -1
  3. package/.next/standalone/.next/build-manifest.json +3 -3
  4. package/.next/standalone/.next/prerender-manifest.json +3 -3
  5. package/.next/standalone/.next/required-server-files.json +1 -1
  6. package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
  7. package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  8. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  10. package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
  11. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +2 -2
  12. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
  13. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +3 -3
  14. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +3 -3
  15. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  16. package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  17. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  18. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  19. package/.next/standalone/.next/server/app/_not-found.html +2 -2
  20. package/.next/standalone/.next/server/app/_not-found.rsc +15 -15
  21. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +15 -15
  22. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
  23. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +10 -10
  24. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  25. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
  26. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  27. package/.next/standalone/.next/server/app/index.html +1 -1
  28. package/.next/standalone/.next/server/app/index.rsc +15 -15
  29. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  30. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
  31. package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +4 -4
  32. package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +10 -10
  33. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  34. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
  35. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  36. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  37. package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +8 -8
  38. package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
  39. package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
  40. package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
  41. package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
  42. package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
  43. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
  44. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
  45. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
  46. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
  47. package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
  48. package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
  49. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  50. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0g72weg._.js +1 -1
  51. package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_0z7w.hh._.js +1 -1
  52. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0a~g15g._.js → [root-of-the-server]__0.~fd7s._.js} +2 -2
  53. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__092s1ta._.js +2 -2
  54. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__09icjsf._.js +2 -2
  55. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0qn95h3._.js → [root-of-the-server]__0a.nuas._.js} +2 -2
  56. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0g.lg8b._.js +2 -2
  57. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0h..k-e._.js +2 -2
  58. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0okos0k._.js +2 -2
  59. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0w6l33k._.js +2 -2
  60. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__11pa2ra._.js +2 -2
  61. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__12t-wym._.js +2 -2
  62. package/.next/standalone/.next/server/chunks/ssr/_10lm7or._.js +2 -2
  63. package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_0xerkr6._.js +1 -1
  64. package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_0q-m0y-._.js +1 -1
  65. package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
  66. package/.next/standalone/.next/server/pages/404.html +2 -2
  67. package/.next/standalone/.next/server/pages/500.html +1 -1
  68. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  69. package/.next/standalone/.next/server/server-reference-manifest.json +9 -9
  70. package/.next/standalone/.next/static/chunks/{09ikntpt2-o9b.js → 0.z51twd.0l5z.js} +1 -1
  71. package/.next/standalone/.next/static/chunks/{0sme4lkv.tgn-.js → 0hctoh28rg838.js} +1 -1
  72. package/.next/standalone/.next/static/chunks/{13juklu.vksks.js → 0hplx-8c-4vpv.js} +1 -1
  73. package/.next/standalone/.next/static/chunks/{0em7tspi4kylh.js → 0maq.q1t.ri85.js} +2 -2
  74. package/.next/standalone/.next/static/chunks/{17manv47o-~wp.js → 0teq8wdh3po1n.js} +1 -1
  75. package/.next/standalone/.next/static/chunks/{0lgbwkfqmnsmc.js → 0uc0um_uz51m_.js} +1 -1
  76. package/.next/standalone/.next/static/chunks/{0yumumfzx_f27.js → 0ul6fk-z.6k-0.js} +1 -1
  77. package/.next/standalone/.next/static/chunks/{0_yayar~bpphd.js → 0w9lwqy0-v1dk.js} +1 -1
  78. package/.next/standalone/CHANGELOG.md +5 -0
  79. package/.next/standalone/dist/cli.mjs +19 -2
  80. package/.next/standalone/docs/ar/architecture.mdx +65 -64
  81. package/.next/standalone/docs/ar/configuration.mdx +42 -42
  82. package/.next/standalone/docs/ar/custom-policies.mdx +62 -64
  83. package/.next/standalone/docs/de/architecture.mdx +92 -92
  84. package/.next/standalone/docs/de/configuration.mdx +34 -34
  85. package/.next/standalone/docs/de/custom-policies.mdx +49 -50
  86. package/.next/standalone/docs/es/architecture.mdx +72 -72
  87. package/.next/standalone/docs/es/configuration.mdx +25 -25
  88. package/.next/standalone/docs/es/custom-policies.mdx +48 -49
  89. package/.next/standalone/docs/fr/architecture.mdx +53 -53
  90. package/.next/standalone/docs/fr/configuration.mdx +25 -25
  91. package/.next/standalone/docs/fr/custom-policies.mdx +42 -43
  92. package/.next/standalone/docs/he/architecture.mdx +66 -66
  93. package/.next/standalone/docs/he/configuration.mdx +53 -52
  94. package/.next/standalone/docs/he/custom-policies.mdx +72 -73
  95. package/.next/standalone/docs/hi/architecture.mdx +106 -106
  96. package/.next/standalone/docs/hi/configuration.mdx +39 -39
  97. package/.next/standalone/docs/hi/custom-policies.mdx +75 -76
  98. package/.next/standalone/docs/i18n/README.ar.md +66 -66
  99. package/.next/standalone/docs/i18n/README.de.md +38 -38
  100. package/.next/standalone/docs/i18n/README.es.md +38 -38
  101. package/.next/standalone/docs/i18n/README.fr.md +42 -42
  102. package/.next/standalone/docs/i18n/README.he.md +67 -67
  103. package/.next/standalone/docs/i18n/README.hi.md +70 -70
  104. package/.next/standalone/docs/i18n/README.it.md +62 -62
  105. package/.next/standalone/docs/i18n/README.ja.md +54 -54
  106. package/.next/standalone/docs/i18n/README.ko.md +58 -58
  107. package/.next/standalone/docs/i18n/README.pt-br.md +43 -43
  108. package/.next/standalone/docs/i18n/README.ru.md +69 -69
  109. package/.next/standalone/docs/i18n/README.tr.md +76 -76
  110. package/.next/standalone/docs/i18n/README.vi.md +70 -70
  111. package/.next/standalone/docs/i18n/README.zh.md +52 -52
  112. package/.next/standalone/docs/it/architecture.mdx +54 -53
  113. package/.next/standalone/docs/it/configuration.mdx +44 -45
  114. package/.next/standalone/docs/it/custom-policies.mdx +76 -78
  115. package/.next/standalone/docs/ja/architecture.mdx +93 -93
  116. package/.next/standalone/docs/ja/configuration.mdx +47 -47
  117. package/.next/standalone/docs/ja/custom-policies.mdx +62 -63
  118. package/.next/standalone/docs/ko/architecture.mdx +66 -66
  119. package/.next/standalone/docs/ko/configuration.mdx +35 -35
  120. package/.next/standalone/docs/ko/custom-policies.mdx +71 -72
  121. package/.next/standalone/docs/pt-br/architecture.mdx +55 -55
  122. package/.next/standalone/docs/pt-br/configuration.mdx +35 -35
  123. package/.next/standalone/docs/pt-br/custom-policies.mdx +60 -61
  124. package/.next/standalone/docs/ru/architecture.mdx +59 -60
  125. package/.next/standalone/docs/ru/configuration.mdx +52 -53
  126. package/.next/standalone/docs/ru/custom-policies.mdx +68 -69
  127. package/.next/standalone/docs/tr/architecture.mdx +124 -124
  128. package/.next/standalone/docs/tr/configuration.mdx +45 -46
  129. package/.next/standalone/docs/tr/custom-policies.mdx +75 -75
  130. package/.next/standalone/docs/vi/architecture.mdx +65 -64
  131. package/.next/standalone/docs/vi/configuration.mdx +41 -41
  132. package/.next/standalone/docs/vi/custom-policies.mdx +68 -69
  133. package/.next/standalone/docs/zh/architecture.mdx +67 -67
  134. package/.next/standalone/docs/zh/configuration.mdx +34 -34
  135. package/.next/standalone/docs/zh/custom-policies.mdx +53 -54
  136. package/.next/standalone/package.json +1 -1
  137. package/.next/standalone/server.js +1 -1
  138. package/.next/standalone/src/hooks/builtin-policies.ts +30 -0
  139. package/dist/cli.mjs +19 -2
  140. package/package.json +1 -1
  141. package/src/hooks/builtin-policies.ts +30 -0
  142. /package/.next/standalone/.next/static/{hYQM6iCWnF1W5XDpsIRhV → 8mygPGI5bzrtWK36ZYO59}/_buildManifest.js +0 -0
  143. /package/.next/standalone/.next/static/{hYQM6iCWnF1W5XDpsIRhV → 8mygPGI5bzrtWK36ZYO59}/_clientMiddlewareManifest.js +0 -0
  144. /package/.next/standalone/.next/static/{hYQM6iCWnF1W5XDpsIRhV → 8mygPGI5bzrtWK36ZYO59}/_ssgManifest.js +0 -0
@@ -1,14 +1,14 @@
1
1
  ---
2
2
  title: 커스텀 정책
3
- description: "JavaScript로 직접 정책을 작성하세요 - 컨벤션 적용, 드리프트 방지, 실패 감지, 외부 시스템 연동"
3
+ description: "JavaScript로 나만의 정책을 작성하세요 - 컨벤션 강제, 드리프트 방지, 실패 감지, 외부 시스템 연동"
4
4
  icon: code
5
5
  ---
6
6
 
7
- 커스텀 정책을 사용하면 에이전트 동작에 대한 규칙을 직접 작성할 수 있습니다. 프로젝트 컨벤션 강제 적용, 드리프트 방지, 위험한 작업 차단, 멈춘 에이전트 감지, Slack이나 승인 워크플로우 연동 등 다양한 용도로 활용할 수 있습니다. 내장 정책과 동일한 훅 이벤트 시스템 `allow`, `deny`, `instruct` 결정 방식을 사용합니다.
7
+ 커스텀 정책을 사용하면 에이전트 동작에 대한 규칙을 직접 작성할 수 있습니다: 프로젝트 컨벤션 강제, 드리프트 방지, 위험한 작업 차단, 멈춘 에이전트 감지, Slack 연동, 승인 워크플로우 연동 등 다양한 용도로 활용할 수 있습니다. 빌트인 정책과 동일한 훅 이벤트 시스템과 `allow`, `deny`, `instruct` 결정 방식을 사용합니다.
8
8
 
9
9
  ---
10
10
 
11
- ## 빠른 예제
11
+ ## 빠른 예시
12
12
 
13
13
  ```js
14
14
  // my-policies.js
@@ -37,30 +37,30 @@ failproofai policies --install --custom ./my-policies.js
37
37
 
38
38
  ---
39
39
 
40
- ## 커스텀 정책을 불러오는 두 가지 방법
40
+ ## 커스텀 정책을 로드하는 두 가지 방법
41
41
 
42
42
  ### 방법 1: 컨벤션 기반 (권장)
43
43
 
44
- `.failproofai/policies/` 디렉터리에 `*policies.{js,mjs,ts}` 파일을 넣으면 자동으로 불러옵니다 — 별도의 플래그나 설정 변경이 필요 없습니다. git 훅처럼 파일을 넣으면 바로 작동합니다.
44
+ `.failproofai/policies/` 디렉터리에 `*policies.{js,mjs,ts}` 파일을 넣기만 하면 자동으로 로드됩니다 — 별도의 플래그나 설정 변경이 필요 없습니다. git 훅처럼 파일만 넣으면 바로 동작합니다.
45
45
 
46
46
  ```
47
- # 프로젝트 레벨 — git에 커밋되어 팀과 공유
47
+ # 프로젝트 레벨 — git에 커밋되어 전체에 공유
48
48
  .failproofai/policies/security-policies.mjs
49
49
  .failproofai/policies/workflow-policies.mjs
50
50
 
51
- # 사용자 레벨 — 개인용, 모든 프로젝트에 적용
51
+ # 사용자 레벨 — 개인 설정, 모든 프로젝트에 적용
52
52
  ~/.failproofai/policies/my-policies.mjs
53
53
  ```
54
54
 
55
55
  **동작 방식:**
56
- - 프로젝트와 사용자 디렉터리 모두 탐색합니다 (합집합 방식 — 번째 스코프 우선이 아님)
57
- - 각 디렉터리 내에서 파일은 알파벳 순으로 불러옵니다. 순서를 제어하려면 `01-`, `02-` 접두사를 사용하세요
58
- - `*policies.{js,mjs,ts}` 패턴에 맞는 파일만 불러옵니다. 그 외 파일은 무시됩니다
59
- - 각 파일은 독립적으로 불러옵니다 (파일 단위 fail-open)
60
- - 명시적 `--custom` 및 내장 정책과 함께 사용할 수 있습니다
56
+ - 프로젝트 디렉터리와 사용자 디렉터리를 모두 스캔합니다 (합집합 방식 — 스코프 우선순위 방식 아님)
57
+ - 각 디렉터리 내에서 파일은 알파벳 순서로 로드됩니다. 순서를 제어하려면 `01-`, `02-` 등의 접두사를 사용하세요
58
+ - `*policies.{js,mjs,ts}` 패턴에 맞는 파일만 로드되며, 그 외 파일은 무시됩니다
59
+ - 각 파일은 독립적으로 로드됩니다 (파일별 fail-open)
60
+ - 명시적 `--custom` 및 빌트인 정책과 함께 사용할 수 있습니다
61
61
 
62
62
  <Tip>
63
- 컨벤션 정책은 팀 전체에 정책을 공유하는 가장 쉬운 방법입니다. `.failproofai/policies/`를 git에 커밋하면 팀원 모두가 자동으로 적용받습니다.
63
+ 컨벤션 정책은 팀 전체에 정책을 공유하는 가장 쉬운 방법입니다. `.failproofai/policies/`를 git에 커밋하면 모든 팀원이 자동으로 적용받습니다.
64
64
  </Tip>
65
65
 
66
66
  ### 방법 2: 명시적 파일 경로
@@ -76,11 +76,11 @@ failproofai policies --install --custom ./new-policies.js
76
76
  failproofai policies --uninstall --custom
77
77
  ```
78
78
 
79
- 확인된 절대 경로는 `policies-config.json`에 `customPoliciesPath`로 저장됩니다. 파일은 매 훅 이벤트마다 새로 불러옵니다 이벤트 간 캐싱은 없습니다.
79
+ 변환된 절대 경로는 `policies-config.json`의 `customPoliciesPath`에 저장됩니다. 파일은 매 훅 이벤트마다 새로 로드됩니다 - 이벤트 간 캐싱은 없습니다.
80
80
 
81
81
  ### 두 방법 함께 사용하기
82
82
 
83
- 컨벤션 정책과 명시적 `--custom` 파일은 함께 사용할 수 있습니다. 불러오는 순서:
83
+ 컨벤션 정책과 명시적 `--custom` 파일은 함께 사용할 수 있습니다. 로드 순서:
84
84
 
85
85
  1. 명시적 `customPoliciesPath` 파일 (설정된 경우)
86
86
  2. 프로젝트 컨벤션 파일 (`{cwd}/.failproofai/policies/`, 알파벳 순)
@@ -90,7 +90,7 @@ failproofai policies --uninstall --custom
90
90
 
91
91
  ## API
92
92
 
93
- ### Import
93
+ ### 임포트
94
94
 
95
95
  ```js
96
96
  import { customPolicies, allow, deny, instruct } from "failproofai";
@@ -98,13 +98,13 @@ import { customPolicies, allow, deny, instruct } from "failproofai";
98
98
 
99
99
  ### `customPolicies.add(hook)`
100
100
 
101
- 정책을 등록합니다. 같은 파일에 여러 정책을 등록하려면 필요한 만큼 호출하세요.
101
+ 정책을 등록합니다. 하나의 파일에 여러 정책을 추가하려면 여러 호출하면 됩니다.
102
102
 
103
103
  ```ts
104
104
  customPolicies.add({
105
105
  name: string; // 필수 - 고유 식별자
106
106
  description?: string; // `failproofai policies` 출력에 표시됨
107
- match?: { events?: HookEventType[] }; // 이벤트 유형으로 필터링; 생략 시 모든 이벤트에 적용
107
+ match?: { events?: HookEventType[] }; // 이벤트 타입으로 필터링; 생략 시 모든 이벤트에 매칭
108
108
  fn: (ctx: PolicyContext) => PolicyResult | Promise<PolicyResult>;
109
109
  });
110
110
  ```
@@ -113,31 +113,30 @@ customPolicies.add({
113
113
 
114
114
  | 함수 | 효과 | 사용 시점 |
115
115
  |----------|--------|----------|
116
- | `allow()` | 조용히 작업을 허용 | 작업이 안전하고 메시지가 필요 없을 때 |
117
- | `deny(message)` | 작업을 차단 | 에이전트가 해당 작업을 수행해서는 안 될 때 |
118
- | `instruct(message)` | 차단 없이 컨텍스트 추가 | 에이전트가 올바른 방향을 유지하도록 추가 정보를 제공할 때 |
116
+ | `allow()` | 조용히 작업을 허용 | 동작이 안전하고 메시지가 필요 없을 때 |
117
+ | `deny(message)` | 작업을 차단 | 에이전트가 동작을 수행해서는 안 될 때 |
118
+ | `instruct(message)` | 차단 없이 컨텍스트 추가 | 에이전트가 올바른 방향을 유지하도록 추가 컨텍스트를 제공할 때 |
119
119
 
120
- `deny(message)` 메시지는 `"Blocked by failproofai:"` 접두사가 붙어 Claude에게 전달됩니다. 하나의 `deny`가 이후 모든 평가를 단락시킵니다.
120
+ `deny(message)` - 메시지는 `"Blocked by failproofai:"` 접두사와 함께 Claude에게 표시됩니다. 하나의 `deny`가 발생하면 이후 모든 평가가 중단됩니다.
121
121
 
122
- `instruct(message)` 메시지는 현재 도구 호출에 대한 Claude의 컨텍스트에 추가됩니다. 모든 `instruct` 메시지는 누적되어 함께 전달됩니다.
122
+ `instruct(message)` - 메시지는 현재 호출에 대한 Claude의 컨텍스트에 추가됩니다. 모든 `instruct` 메시지는 누적되어 함께 전달됩니다.
123
123
 
124
124
  <Tip>
125
- `policyParams`의 `hint` 필드를 추가하면 코드 변경 없이 `deny` 또는 `instruct` 메시지에 추가 안내를 덧붙일 수 있습니다. 커스텀(`custom/`), 프로젝트 컨벤션(`.failproofai-project/`), 사용자 컨벤션(`.failproofai-user/`) 정책 모두에서 작동합니다. 자세한 내용은 [Configuration → hint](/ko/configuration#hint-cross-cutting)를 참고하세요.
125
+ `policyParams`의 `hint` 필드를 추가하면 코드 변경 없이 `deny` 또는 `instruct` 메시지에 추가 가이던스를 붙일 수 있습니다. 커스텀(`custom/`), 프로젝트 컨벤션(`.failproofai-project/`), 사용자 컨벤션(`.failproofai-user/`) 정책 모두에서 동작합니다. 자세한 내용은 [설정 → hint](/ko/configuration#hint-cross-cutting)를 참조하세요.
126
126
  </Tip>
127
127
 
128
128
  ### 정보성 allow 메시지
129
129
 
130
-
131
- `allow(message)`는 작업을 허용하면서 **동시에** 정보성 메시지를 Claude에게 전달합니다. 메시지는 훅 핸들러의 stdout 응답에서 `additionalContext`로 전달됩니다 — `instruct`와 동일한 메커니즘이지만, 의미적으로 다릅니다. 이는 경고가 아닌 상태 업데이트입니다.
130
+ `allow(message)`는 작업을 허용하면서 **동시에** Claude에게 정보성 메시지를 전달합니다. 메시지는 훅 핸들러의 stdout 응답에서 `additionalContext`로 전달되며, `instruct`와 동일한 메커니즘을 사용하지만 의미상 다릅니다: 경고가 아닌 상태 업데이트입니다.
132
131
 
133
132
  | 함수 | 효과 | 사용 시점 |
134
133
  |----------|--------|----------|
135
134
  | `allow(message)` | 허용하면서 Claude에게 컨텍스트 전달 | 검사가 통과되었음을 확인하거나, 검사가 건너뛰어진 이유를 설명할 때 |
136
135
 
137
- 사용 사례:
138
- - **상태 확인:** `allow("All CI checks passed.")` — 모든 것이 정상임을 Claude에게 알림
139
- - **Fail-open 설명:** `allow("GitHub CLI not installed, skipping CI check.")` — 검사가 건너뛰어진 이유를 Claude에게 알려 전체 컨텍스트를 제공
140
- - **다중 메시지 누적:** 여러 정책이 각각 `allow(message)`를 반환하면 모든 메시지가 줄바꿈으로 이어져 함께 전달됨
136
+ 활용 예시:
137
+ - **상태 확인:** `allow("All CI checks passed.")` — Claude에게 모든 것이 정상임을 알림
138
+ - **Fail-open 설명:** `allow("GitHub CLI not installed, skipping CI check.")` — Claude가 완전한 컨텍스트를 갖도록 검사가 건너뛰어진 이유를 알림
139
+ - **다중 메시지 누적:** 여러 정책이 각각 `allow(message)`를 반환하면 모든 메시지가 줄바꿈으로 연결되어 함께 전달됩니다
141
140
 
142
141
  ```js
143
142
  customPolicies.add({
@@ -161,9 +160,9 @@ customPolicies.add({
161
160
  | 필드 | 타입 | 설명 |
162
161
  |-------|------|-------------|
163
162
  | `eventType` | `string` | `"PreToolUse"`, `"PostToolUse"`, `"Notification"`, `"Stop"` |
164
- | `toolName` | `string \| undefined` | 호출되는 도구 (예: `"Bash"`, `"Write"`, `"Read"`) |
165
- | `toolInput` | `Record<string, unknown> \| undefined` | 도구의 입력 파라미터 |
166
- | `payload` | `Record<string, unknown>` | Claude Code에서 전달된 전체 원시 이벤트 페이로드 |
163
+ | `toolName` | `string \| undefined` | 호출되는 (예: `"Bash"`, `"Write"`, `"Read"`) |
164
+ | `toolInput` | `Record<string, unknown> \| undefined` | 툴의 입력 파라미터 |
165
+ | `payload` | `Record<string, unknown>` | Claude Code로부터의 전체 원시 이벤트 페이로드 |
167
166
  | `session` | `SessionMetadata \| undefined` | 세션 컨텍스트 (아래 참조) |
168
167
 
169
168
  ### `SessionMetadata` 필드
@@ -174,14 +173,14 @@ customPolicies.add({
174
173
  | `cwd` | `string` | Claude Code 세션의 작업 디렉터리 |
175
174
  | `transcriptPath` | `string` | 세션의 JSONL 트랜스크립트 파일 경로 |
176
175
 
177
- ### 이벤트 유형
176
+ ### 이벤트 타입
178
177
 
179
178
  | 이벤트 | 발생 시점 | `toolInput` 내용 |
180
179
  |-------|--------------|----------------------|
181
- | `PreToolUse` | Claude가 도구를 실행하기 전 | 도구의 입력 (예: Bash의 경우 `{ command: "..." }`) |
182
- | `PostToolUse` | 도구 실행 완료 후 | 도구의 입력 + `tool_result` (출력값) |
183
- | `Notification` | Claude가 알림을 보낼 때 | `{ message: "...", notification_type: "idle" \| "permission_prompt" \| ... }` - 훅은 항상 `allow()`를 반환해야 하며 알림을 차단할 수 없습니다 |
184
- | `Stop` | Claude 세션 종료 | 비어 있음 |
180
+ | `PreToolUse` | Claude가 툴을 실행하기 전 | 툴의 입력 (예: Bash의 경우 `{ command: "..." }`) |
181
+ | `PostToolUse` | 실행 완료 후 | 툴의 입력 + `tool_result` (출력) |
182
+ | `Notification` | Claude가 알림을 보낼 때 | `{ message: "...", notification_type: "idle" \| "permission_prompt" \| ... }` - 훅은 항상 `allow()`를 반환해야 하며, 알림을 차단할 수 없습니다 |
183
+ | `Stop` | Claude 세션이 종료될 | 비어 있음 |
185
184
 
186
185
  ---
187
186
 
@@ -189,20 +188,20 @@ customPolicies.add({
189
188
 
190
189
  정책은 다음 순서로 평가됩니다:
191
190
 
192
- 1. 내장 정책 (정의 순서대로)
193
- 2. `customPoliciesPath`의 명시적 커스텀 정책 (`.add()` 호출 순서대로)
194
- 3. 프로젝트 `.failproofai/policies/`의 컨벤션 정책 (파일은 알파벳 순, 파일 내에서는 `.add()` 순서)
195
- 4. 사용자 `~/.failproofai/policies/`의 컨벤션 정책 (파일은 알파벳 순, 파일 내에서는 `.add()` 순서)
191
+ 1. 빌트인 정책 (정의 순서)
192
+ 2. `customPoliciesPath`의 명시적 커스텀 정책 (`.add()` 순서)
193
+ 3. 프로젝트 `.failproofai/policies/`의 컨벤션 정책 (파일 알파벳 순, 파일 `.add()` 순서)
194
+ 4. 사용자 `~/.failproofai/policies/`의 컨벤션 정책 (파일 알파벳 순, 파일 `.add()` 순서)
196
195
 
197
196
  <Note>
198
- 첫 번째 `deny`는 이후 모든 정책을 단락시킵니다. 모든 `instruct` 메시지는 누적되어 함께 전달됩니다.
197
+ 첫 번째 `deny`가 이후 모든 정책 평가를 중단시킵니다. 모든 `instruct` 메시지는 누적되어 함께 전달됩니다.
199
198
  </Note>
200
199
 
201
200
  ---
202
201
 
203
- ## 전이적 import
202
+ ## 전이적 임포트
204
203
 
205
- 커스텀 정책 파일은 상대 경로를 사용해 로컬 모듈을 import할 수 있습니다:
204
+ 커스텀 정책 파일은 상대 경로를 사용하여 로컬 모듈을 임포트할 수 있습니다:
206
205
 
207
206
  ```js
208
207
  // my-policies.js
@@ -219,46 +218,46 @@ customPolicies.add({
219
218
  });
220
219
  ```
221
220
 
222
- 엔트리 파일에서 도달 가능한 모든 상대 import가 처리됩니다. 이는 `from "failproofai"` import를 실제 dist 경로로 재작성하고, ESM 호환성을 보장하기 위해 임시 `.mjs` 파일을 생성하는 방식으로 구현됩니다.
221
+ 엔트리 파일에서 도달 가능한 모든 상대 임포트가 해석됩니다. 이는 `from "failproofai"` 임포트를 실제 dist 경로로 재작성하고 ESM 호환성을 보장하기 위해 임시 `.mjs` 파일을 생성하는 방식으로 구현됩니다.
223
222
 
224
223
  ---
225
224
 
226
- ## 이벤트 유형 필터링
225
+ ## 이벤트 타입 필터링
227
226
 
228
- `match.events`를 사용해 정책이 발동되는 시점을 제한하세요:
227
+ `match.events`를 사용하여 정책이 발동되는 시점을 제한합니다:
229
228
 
230
229
  ```js
231
230
  customPolicies.add({
232
231
  name: "require-summary-on-stop",
233
232
  match: { events: ["Stop"] },
234
233
  fn: async (ctx) => {
235
- // 세션이 종료될 때만 발동
236
- // ctx.session.transcriptPath에 전체 세션 로그가 포함됨
234
+ // 세션이 종료될 때만 발동됨
235
+ // ctx.session.transcriptPath에 전체 세션 로그가 있음
237
236
  return allow();
238
237
  },
239
238
  });
240
239
  ```
241
240
 
242
- `match`를 완전히 생략하면 모든 이벤트 유형에서 발동됩니다.
241
+ `match`를 완전히 생략하면 모든 이벤트 타입에서 발동됩니다.
243
242
 
244
243
  ---
245
244
 
246
- ## 오류 처리 및 실패 모드
245
+ ## 에러 처리 및 실패 모드
247
246
 
248
- 커스텀 정책은 **fail-open** 방식입니다: 오류가 발생해도 내장 정책을 차단하거나핸들러를 중단시키지 않습니다.
247
+ 커스텀 정책은 **fail-open** 방식입니다: 에러가 발생해도 빌트인 정책이 차단되거나핸들러가 크래시되지 않습니다.
249
248
 
250
249
  | 실패 상황 | 동작 |
251
250
  |---------|----------|
252
- | `customPoliciesPath` 미설정 | 명시적 커스텀 정책이 실행되지 않음; 컨벤션 정책과 내장 정책은 정상 계속 |
253
- | 파일을 찾을 수 없음 | `~/.failproofai/hook.log`에 경고 기록; 내장 정책은 계속 |
254
- | 구문/import 오류 (명시적) | `~/.failproofai/hook.log`에 오류 기록; 명시적 커스텀 정책 건너뜀 |
255
- | 구문/import 오류 (컨벤션) | 오류 기록; 해당 파일 건너뜀, 다른 컨벤션 파일은 계속 로드 |
256
- | `fn` 런타임 예외 | 오류 기록; 해당 훅은 `allow`로 처리; 다른 훅은 계속 |
257
- | `fn` 실행 10초 초과 | 타임아웃 기록; `allow`로 처리 |
258
- | 컨벤션 디렉터리 없음 | 컨벤션 정책 실행 안 됨; 오류 없음 |
251
+ | `customPoliciesPath` 미설정 | 명시적 커스텀 정책이 실행되지 않음; 컨벤션 정책과 빌트인은 정상 계속 |
252
+ | 파일 없음 | `~/.failproofai/hook.log`에 경고 기록; 빌트인 계속 |
253
+ | 문법/임포트 에러 (명시적) | `~/.failproofai/hook.log`에 에러 기록; 명시적 커스텀 정책 건너뜀 |
254
+ | 문법/임포트 에러 (컨벤션) | 에러 기록; 해당 파일 건너뜀, 다른 컨벤션 파일은 계속 로드 |
255
+ | `fn` 런타임 에러 | 에러 기록; 해당 훅은 `allow`로 처리; 다른 훅은 계속 |
256
+ | `fn`이 10초 초과 | 타임아웃 기록; `allow`로 처리 |
257
+ | 컨벤션 디렉터리 없음 | 컨벤션 정책 실행 안 됨; 에러 없음 |
259
258
 
260
259
  <Tip>
261
- 커스텀 정책 오류를 디버깅하려면 로그 파일을 모니터링하세요:
260
+ 커스텀 정책 에러를 디버깅하려면 로그 파일을 모니터링하세요:
262
261
 
263
262
  ```bash
264
263
  tail -f ~/.failproofai/hook.log
@@ -267,7 +266,7 @@ tail -f ~/.failproofai/hook.log
267
266
 
268
267
  ---
269
268
 
270
- ## 전체 예제: 다중 정책
269
+ ## 전체 예시: 다중 정책
271
270
 
272
271
  ```js
273
272
  // my-policies.js
@@ -286,7 +285,7 @@ customPolicies.add({
286
285
  },
287
286
  });
288
287
 
289
- // 에이전트가 올바른 방향 유지: 커밋 전 테스트 확인
288
+ // 에이전트가 올바른 방향을 유지하도록: 커밋 전 테스트 확인
290
289
  customPolicies.add({
291
290
  name: "remind-test-before-commit",
292
291
  description: "Keep the agent on track: verify tests pass before committing",
@@ -301,7 +300,7 @@ customPolicies.add({
301
300
  },
302
301
  });
303
302
 
304
- // 프리즈 기간 중 계획되지 않은 의존성 변경 방지
303
+ // 동결 기간 중 계획되지 않은 의존성 변경 방지
305
304
  customPolicies.add({
306
305
  name: "dependency-freeze",
307
306
  description: "Prevent unplanned dependency changes during freeze period",
@@ -322,24 +321,24 @@ export { customPolicies };
322
321
 
323
322
  ---
324
323
 
325
- ## 예제 파일
324
+ ## 예시 파일
326
325
 
327
- `examples/` 디렉터리에는 바로 실행 가능한 정책 파일이 포함되어 있습니다:
326
+ `examples/` 디렉터리에는 바로 실행 가능한 정책 파일들이 있습니다:
328
327
 
329
328
  | 파일 | 내용 |
330
329
  |------|----------|
331
330
  | `examples/policies-basic.js` | 일반적인 에이전트 실패 모드를 다루는 5가지 기본 정책 |
332
- | `examples/policies-advanced/index.js` | 고급 패턴: 전이적 import, 비동기 호출, 출력 스크러빙, 세션 종료 훅 |
333
- | `examples/convention-policies/security-policies.mjs` | 컨벤션 기반 보안 정책 (.env 쓰기 차단, git 히스토리 재작성 방지) |
334
- | `examples/convention-policies/workflow-policies.mjs` | 컨벤션 기반 워크플로우 정책 (테스트 알림, 감사 파일 쓰기) |
331
+ | `examples/policies-advanced/index.js` | 고급 패턴: 전이적 임포트, 비동기 호출, 출력 스크러빙, 세션 종료 훅 |
332
+ | `examples/convention-policies/security-policies.mjs` | 컨벤션 기반 보안 정책 (.env 파일 쓰기 차단, git 히스토리 재작성 방지) |
333
+ | `examples/convention-policies/workflow-policies.mjs` | 컨벤션 기반 워크플로우 정책 (테스트 리마인더, 파일 쓰기 감사) |
335
334
 
336
- ### 명시적 파일 예제 사용하기
335
+ ### 명시적 파일 예시 사용
337
336
 
338
337
  ```bash
339
338
  failproofai policies --install --custom ./examples/policies-basic.js
340
339
  ```
341
340
 
342
- ### 컨벤션 기반 예제 사용하기
341
+ ### 컨벤션 기반 예시 사용
343
342
 
344
343
  ```bash
345
344
  # 프로젝트 레벨로 복사
@@ -351,4 +350,4 @@ mkdir -p ~/.failproofai/policies
351
350
  cp examples/convention-policies/*.mjs ~/.failproofai/policies/
352
351
  ```
353
352
 
354
- 설치 명령이 필요하지 않습니다 — 다음 훅 이벤트 시 파일이 자동으로 인식됩니다.
353
+ 설치 명령어가 필요 없습니다 — 다음 훅 이벤트 시 파일이 자동으로 감지됩니다.
@@ -12,18 +12,18 @@ Este documento explica como o failproofai funciona internamente: como o sistema
12
12
 
13
13
  O failproofai possui dois subsistemas independentes:
14
14
 
15
- 1. **Hook handler** - Um subprocesso CLI rápido que o Claude Code invoca a cada chamada de ferramenta do agente. Avalia as políticas e retorna uma decisão.
15
+ 1. **Handler de hooks** - Um subprocesso CLI rápido que o Claude Code invoca em cada chamada de ferramenta do agente. Avalia as políticas e retorna uma decisão.
16
16
  2. **Monitor de Agentes (Dashboard)** - Uma aplicação web Next.js para monitorar sessões de agentes e gerenciar políticas.
17
17
 
18
18
  Ambos os subsistemas compartilham arquivos de configuração em `~/.failproofai/` e no diretório `.failproofai/` do projeto, mas são executados como processos separados e se comunicam apenas pelo sistema de arquivos.
19
19
 
20
20
  ---
21
21
 
22
- ## Hook handler
22
+ ## Handler de hooks
23
23
 
24
24
  ### Integração com o Claude Code
25
25
 
26
- Quando você executa `failproofai policies --install`, ele escreve entradas como esta em `~/.claude/settings.json`:
26
+ Quando você executa `failproofai policies --install`, ele escreve entradas como esta no `~/.claude/settings.json`:
27
27
 
28
28
  ```json
29
29
  {
@@ -44,7 +44,7 @@ Quando você executa `failproofai policies --install`, ele escreve entradas como
44
44
  }
45
45
  ```
46
46
 
47
- O Claude Code então invoca `failproofai --hook PreToolUse` como subprocesso antes de cada chamada de ferramenta, passando um payload JSON via stdin.
47
+ O Claude Code então invoca `failproofai --hook PreToolUse` como um subprocesso antes de cada chamada de ferramenta, passando um payload JSON via stdin.
48
48
 
49
49
  ### Formato do payload
50
50
 
@@ -62,11 +62,11 @@ O Claude Code então invoca `failproofai --hook PreToolUse` como subprocesso ant
62
62
 
63
63
  Para eventos `PostToolUse`, o payload também contém `tool_result` com a saída da ferramenta.
64
64
 
65
- O handler impõe um limite de 1 MB para stdin. Payloads que excedam esse tamanho são descartados e todas as políticas permitem implicitamente.
65
+ O handler aplica um limite de 1 MB para o stdin. Payloads que excedam esse limite são descartados e todas as políticas implicitamente permitem a operação.
66
66
 
67
67
  ### Formato da resposta
68
68
 
69
- **Deny (PreToolUse):**
69
+ **Negar (PreToolUse):**
70
70
  ```json
71
71
  {
72
72
  "hookSpecificOutput": {
@@ -76,7 +76,7 @@ O handler impõe um limite de 1 MB para stdin. Payloads que excedam esse tamanho
76
76
  }
77
77
  ```
78
78
 
79
- **Deny (PostToolUse):**
79
+ **Negar (PostToolUse):**
80
80
  ```json
81
81
  {
82
82
  "hookSpecificOutput": {
@@ -85,7 +85,7 @@ O handler impõe um limite de 1 MB para stdin. Payloads que excedam esse tamanho
85
85
  }
86
86
  ```
87
87
 
88
- **Instruct (qualquer evento exceto Stop):**
88
+ **Instruir (qualquer evento exceto Stop):**
89
89
  ```json
90
90
  {
91
91
  "hookSpecificOutput": {
@@ -94,17 +94,17 @@ O handler impõe um limite de 1 MB para stdin. Payloads que excedam esse tamanho
94
94
  }
95
95
  ```
96
96
 
97
- **Instruct para evento Stop:**
97
+ **Instruir em evento Stop:**
98
98
  - Código de saída: `2`
99
- - Motivo escrito em stderr (não em stdout)
99
+ - Motivo escrito no stderr (não no stdout)
100
100
 
101
- **Allow:**
101
+ **Permitir:**
102
102
  - Código de saída: `0`
103
103
  - stdout vazio
104
104
 
105
- **Allow com mensagem:**
105
+ **Permitir com mensagem:**
106
106
 
107
- `allow(message)` permite que uma política envie contexto informativo de volta ao Claude mesmo quando a operação é permitida. O hook handler escreve o seguinte JSON em **stdout** (não em um arquivo de configuração — esta é a resposta do handler ao Claude Code, assim como as respostas de deny e instruct acima):
107
+ `allow(message)` permite que uma política envie contexto informativo de volta ao Claude mesmo quando a operação é permitida. O handler de hooks escreve o seguinte JSON no **stdout** (não em um arquivo de configuração — esta é a resposta do handler ao Claude Code, assim como as respostas de deny e instruct acima):
108
108
 
109
109
  ```json
110
110
  // Written to stdout by the hook handler process
@@ -115,8 +115,8 @@ O handler impõe um limite de 1 MB para stdin. Payloads que excedam esse tamanho
115
115
  }
116
116
  ```
117
117
  - Código de saída: `0` (a operação é permitida)
118
- - Quando múltiplas políticas retornam `allow` com uma mensagem, suas mensagens são unidas com quebras de linha em uma única string `additionalContext`
119
- - Se nenhuma política fornecer uma mensagem, stdout fica vazio (igual ao comportamento anterior)
118
+ - Quando múltiplas políticas retornam `allow` com uma mensagem, as mensagens são unidas com quebras de linha em uma única string `additionalContext`
119
+ - Se nenhuma política fornecer uma mensagem, o stdout fica vazio (como antes)
120
120
 
121
121
  ### Pipeline de processamento
122
122
 
@@ -139,7 +139,7 @@ stdin JSON
139
139
  → exit
140
140
  ```
141
141
 
142
- Todo o processo é executado em menos de 100ms para payloads típicos, sem nenhuma chamada a LLMs.
142
+ Todo o processo é executado em menos de 100ms para payloads típicos, sem nenhuma chamada a LLM.
143
143
 
144
144
  ---
145
145
 
@@ -154,12 +154,12 @@ Todo o processo é executado em menos de 100ms para payloads típicos, sem nenhu
154
154
  ```
155
155
 
156
156
  Lógica de mesclagem:
157
- - `enabledPolicies` - união sem duplicatas entre os três arquivos
158
- - `policyParams` - por chave de política, o primeiro arquivo que a define vence inteiramente
159
- - `customPoliciesPath` - o primeiro arquivo que a define vence
160
- - `llm` - o primeiro arquivo que a define vence
157
+ - `enabledPolicies` - união deduplicada entre os três arquivos
158
+ - `policyParams` - por chave de política, o primeiro arquivo que a define prevalece inteiramente
159
+ - `customPoliciesPath` - o primeiro arquivo que o define prevalece
160
+ - `llm` - o primeiro arquivo que o define prevalece
161
161
 
162
- O dashboard web utiliza `readHooksConfig()` (somente global) para leitura e escrita, pois não é invocado com um cwd de projeto.
162
+ O dashboard web usa `readHooksConfig()` (somente global) para leitura e escrita, pois não é invocado com um cwd de projeto.
163
163
 
164
164
  ---
165
165
 
@@ -169,24 +169,24 @@ O dashboard web utiliza `readHooksConfig()` (somente global) para leitura e escr
169
169
 
170
170
  Para cada política:
171
171
 
172
- 1. Busca o esquema de `params` da política (se houver).
172
+ 1. Busca o schema de `params` da política (se houver).
173
173
  2. Lê `policyParams[policy.name]` da configuração mesclada.
174
- 3. Mescla os valores fornecidos pelo usuário sobre os padrões do esquema para produzir `ctx.params`.
174
+ 3. Mescla os valores fornecidos pelo usuário sobre os padrões do schema para produzir `ctx.params`.
175
175
  4. Chama `policy.fn(ctx)` com o contexto resolvido.
176
- 5. Se o resultado for `deny`, interrompe imediatamente e retorna essa decisão.
176
+ 5. Se o resultado for `deny`, para imediatamente e retorna essa decisão.
177
177
  6. Se o resultado for `instruct`, acumula a mensagem e continua.
178
178
  7. Se o resultado for `allow`, continua para a próxima política.
179
179
 
180
180
  Após todas as políticas serem executadas:
181
181
  - Se algum `deny` foi retornado, emite a resposta de deny.
182
- - Se algum retorno `instruct` foi coletado, emite uma única resposta instruct com todas as mensagens unidas.
183
- - Caso contrário, emite uma resposta allow (stdout vazio, saída 0).
182
+ - Se algum retorno `instruct` foi coletado, emite uma única resposta de instruct com todas as mensagens unidas.
183
+ - Caso contrário, emite uma resposta de allow (stdout vazio, exit 0).
184
184
 
185
185
  ---
186
186
 
187
- ## Políticas embutidas
187
+ ## Políticas integradas
188
188
 
189
- `src/hooks/builtin-policies.ts` define todas as 26 políticas embutidas como objetos `BuiltinPolicyDefinition`:
189
+ `src/hooks/builtin-policies.ts` define todas as 26 políticas integradas como objetos `BuiltinPolicyDefinition`:
190
190
 
191
191
  ```typescript
192
192
  interface BuiltinPolicyDefinition {
@@ -206,11 +206,11 @@ interface BuiltinPolicyDefinition {
206
206
 
207
207
  Políticas que aceitam `params` declaram um `PolicyParamsSchema` com tipos e valores padrão para cada parâmetro. O avaliador de políticas injeta os valores resolvidos em `ctx.params` antes de chamar `fn`. As funções de política leem `ctx.params` sem verificações de nulo porque os padrões são sempre aplicados primeiro.
208
208
 
209
- A correspondência de padrões dentro das políticas usa tokens de comando analisados (argv), não correspondência de strings brutas. Isso evita bypass por injeção de operadores shell (por exemplo, um padrão para `sudo systemctl status *` não pode ser ignorado anexando `; rm -rf /` ao comando).
209
+ A correspondência de padrões dentro das políticas usa tokens de comando analisados (argv), não correspondência de strings brutas. Isso evita bypass por injeção de operadores de shell (por exemplo, um padrão para `sudo systemctl status *` não pode ser contornado adicionando `; rm -rf /` ao comando).
210
210
 
211
211
  ---
212
212
 
213
- ## Políticas personalizadas
213
+ ## Políticas customizadas
214
214
 
215
215
  `src/hooks/custom-hooks-registry.ts` implementa um registro baseado em `globalThis`:
216
216
 
@@ -225,25 +225,25 @@ export function getCustomHooks(): CustomHook[] { ... }
225
225
  export function clearCustomHooks(): void { ... } // used in tests
226
226
  ```
227
227
 
228
- `src/hooks/custom-hooks-loader.ts` carrega o arquivo de políticas do usuário:
228
+ `src/hooks/custom-hooks-loader.ts` carrega o arquivo de política do usuário:
229
229
 
230
230
  1. Lê `customPoliciesPath` da configuração; ignora se ausente.
231
231
  2. Resolve para caminho absoluto; verifica se o arquivo existe.
232
- 3. Reescreve todas as importações `from "failproofai"` para o caminho real do dist, de modo que `customPolicies` resolva para o mesmo registro `globalThis`.
233
- 4. Reescreve recursivamente importações locais transitivas para garantir compatibilidade ESM.
234
- 5. Grava arquivos `.mjs` temporários e realiza `import()` do arquivo de entrada.
232
+ 3. Reescreve todas as importações `from "failproofai"` para o caminho real de dist, de modo que `customPolicies` resolva para o mesmo registro `globalThis`.
233
+ 4. Reescreve recursivamente as importações locais transitivas para garantir compatibilidade com ESM.
234
+ 5. Escreve arquivos `.mjs` temporários e faz `import()` do arquivo de entrada.
235
235
  6. Chama `getCustomHooks()` para recuperar os hooks registrados.
236
- 7. Limpa todos os arquivos temporários em um bloco `finally`.
236
+ 7. Remove todos os arquivos temporários em um bloco `finally`.
237
237
 
238
- Em caso de qualquer erro (arquivo não encontrado, erro de sintaxe, falha na importação), o erro é registrado em `~/.failproofai/hook.log` e o loader retorna um array vazio. As políticas embutidas não são afetadas.
238
+ Em caso de qualquer erro (arquivo não encontrado, erro de sintaxe, falha de importação), o erro é registrado em `~/.failproofai/hook.log` e o loader retorna um array vazio. As políticas integradas não são afetadas.
239
239
 
240
- As políticas personalizadas são avaliadas após todas as políticas embutidas. Um `deny` de política personalizada ainda interrompe as demais políticas personalizadas (mas todos os embutidos já terão sido executados nesse ponto).
240
+ As políticas customizadas são avaliadas após todas as políticas integradas. Um `deny` de uma política customizada ainda interrompe as demais políticas customizadas (mas todas as políticas integradas já terão sido executadas nesse ponto).
241
241
 
242
242
  ---
243
243
 
244
- ## Log de atividade
244
+ ## Registro de atividade
245
245
 
246
- Após cada evento de hook, o handler anexa uma linha JSONL em `~/.failproofai/hook-activity.jsonl`:
246
+ Após cada evento de hook, o handler anexa uma linha JSONL ao `~/.failproofai/hook-activity.jsonl`:
247
247
 
248
248
  ```json
249
249
  {
@@ -258,17 +258,17 @@ Após cada evento de hook, o handler anexa uma linha JSONL em `~/.failproofai/ho
258
258
  }
259
259
  ```
260
260
 
261
- Uma linha por política que tomou uma decisão diferente de allow. Decisões allow não são registradas (para manter o arquivo pequeno).
261
+ Uma linha por política que tomou uma decisão diferente de allow. Decisões de allow não são registradas (para manter o arquivo pequeno).
262
262
 
263
263
  ---
264
264
 
265
265
  ## Arquitetura do dashboard
266
266
 
267
- O dashboard é uma aplicação **Next.js 16** usando o App Router com React Server Components e Server Actions.
267
+ O dashboard é uma aplicação **Next.js 16** que utiliza o App Router com React Server Components e Server Actions.
268
268
 
269
269
  ```text
270
270
  app/
271
- layout.tsx ← Layout raiz (tema, telemetria, navegação)
271
+ layout.tsx ← Layout raiz (tema, telemetria, nav)
272
272
  projects/page.tsx ← Server component: lista todos os projetos Claude
273
273
  project/[name]/page.tsx ← Server component: lista sessões em um projeto
274
274
  project/[name]/session/
@@ -277,8 +277,8 @@ app/
277
277
  actions/
278
278
  get-hooks-config.ts ← Lê configuração + lista de políticas
279
279
  update-hooks-config.ts ← Ativa/desativa política
280
- update-policy-params.ts ← Atualiza parâmetros da política
281
- get-hook-activity.ts ← Paginação/busca no log de atividade
280
+ update-policy-params.ts ← Atualiza parâmetros de política
281
+ get-hook-activity.ts ← Pagina/pesquisa log de atividade
282
282
  install-hooks-web.ts ← Instala/remove hooks pelo navegador
283
283
  api/
284
284
  download/[project]/[session]/route.ts ← Exporta sessão como ZIP/JSONL
@@ -287,15 +287,15 @@ app/
287
287
  **Fluxo de dados:**
288
288
 
289
289
  - Os componentes de página chamam `lib/projects.ts` e `lib/log-entries.ts` para ler dados de projeto/sessão diretamente do sistema de arquivos (sem camada de API para leituras).
290
- - A página de Políticas usa Server Actions para todas as mutações (alternar, atualizar parâmetros, instalar/remover).
290
+ - A página de Políticas usa Server Actions para todas as mutações (toggle, atualização de parâmetros, instalação/remoção).
291
291
  - O visualizador de sessão analisa o formato de transcrição JSONL do Claude e renderiza uma linha do tempo de mensagens e chamadas de ferramentas.
292
292
 
293
293
  **Principais decisões de design:**
294
294
 
295
- - Sem banco de dados - todo estado persistente está em arquivos simples (`~/.failproofai/`, `~/.claude/projects/`).
296
- - Server Actions para mutações - sem necessidade de API REST para operações CRUD.
297
- - React Server Components para páginas de leitura - carregamento inicial mais rápido, sem bundle no cliente para busca de dados.
298
- - Client components apenas onde interatividade é necessária (alternância de políticas, busca de atividade, visualizador de log).
295
+ - Sem banco de dados - todo o estado persistente está em arquivos simples (`~/.failproofai/`, `~/.claude/projects/`).
296
+ - Server Actions para mutações - nenhuma API REST necessária para operações CRUD.
297
+ - React Server Components para páginas de leitura - carregamento inicial mais rápido, sem bundle do cliente para busca de dados.
298
+ - Client components apenas onde a interatividade é necessária (toggles de política, pesquisa de atividade, visualizador de log).
299
299
 
300
300
  ---
301
301
 
@@ -313,20 +313,20 @@ failproofai/
313
313
  │ ├── policy-types.ts # Interfaces TypeScript
314
314
  │ ├── hooks-config.ts # Carregamento de configuração multi-escopo
315
315
  │ ├── custom-hooks-registry.ts # Registro de hooks baseado em globalThis
316
- │ ├── custom-hooks-loader.ts # Carregador ESM para hooks JS do usuário
316
+ │ ├── custom-hooks-loader.ts # Loader ESM para hooks JS do usuário
317
317
  │ ├── manager.ts # Operações de instalação / remoção / listagem
318
318
  │ ├── install-prompt.ts # Prompt interativo de seleção de políticas
319
319
  │ ├── hook-logger.ts # Registro em hook.log
320
- │ ├── hook-activity-store.ts # Persiste atividade em hook-activity.jsonl
321
- │ └── llm-client.ts # Cliente de API LLM (para políticas com IA)
320
+ │ ├── hook-activity-store.ts # Persistência de atividade em hook-activity.jsonl
321
+ │ └── llm-client.ts # Cliente de API LLM (para políticas baseadas em IA)
322
322
  ├── app/ # Dashboard Next.js (páginas + server actions)
323
323
  ├── lib/ # Utilitários compartilhados
324
324
  │ ├── projects.ts # Enumera projetos Claude do sistema de arquivos
325
325
  │ ├── log-entries.ts # Analisa o formato JSONL de transcrição do Claude
326
326
  │ ├── paths.ts # Resolve caminhos do sistema
327
327
  │ └── ...
328
- ├── components/ # Componentes React de UI compartilhados
329
- ├── contexts/ # Provedores de contexto React (tema, atualização automática, telemetria)
330
- ├── examples/ # Exemplos de arquivos de hooks personalizados
328
+ ├── components/ # Componentes React UI compartilhados
329
+ ├── contexts/ # Provedores de contexto React (tema, auto-refresh, telemetria)
330
+ ├── examples/ # Exemplos de arquivos de hooks customizados
331
331
  └── __tests__/ # Testes unitários e E2E
332
332
  ```