failproofai 0.0.2-beta.7 → 0.0.2-beta.9

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 (390) hide show
  1. package/.next/standalone/.claude/settings.json +316 -0
  2. package/.next/standalone/.failproofai/policies/workflow-policies.mjs +62 -0
  3. package/.next/standalone/.failproofai/policies-config.json +39 -0
  4. package/.next/standalone/.next/BUILD_ID +1 -1
  5. package/.next/standalone/.next/build-manifest.json +3 -3
  6. package/.next/standalone/.next/prerender-manifest.json +3 -3
  7. package/.next/standalone/.next/required-server-files.json +1 -1
  8. package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
  9. package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  10. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  11. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  12. package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
  13. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +2 -2
  14. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
  15. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +3 -3
  16. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +3 -3
  17. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  18. package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  19. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  20. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  21. package/.next/standalone/.next/server/app/_not-found.html +2 -2
  22. package/.next/standalone/.next/server/app/_not-found.rsc +17 -17
  23. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +17 -17
  24. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
  25. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +11 -11
  26. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  27. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
  28. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  29. package/.next/standalone/.next/server/app/index.html +1 -1
  30. package/.next/standalone/.next/server/app/index.rsc +16 -16
  31. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  32. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +16 -16
  33. package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +4 -4
  34. package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +11 -11
  35. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  36. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
  37. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  38. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  39. package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +8 -8
  40. package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
  41. package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
  42. package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
  43. package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
  44. package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
  45. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
  46. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
  47. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
  48. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
  49. package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
  50. package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
  51. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  52. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0g72weg._.js +3 -0
  53. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0kjo7d_._.js +1 -1
  54. package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_0z7w.hh._.js +1 -1
  55. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__092s1ta._.js +2 -2
  56. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__09icjsf._.js +2 -2
  57. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0g.lg8b._.js +2 -2
  58. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0h..k-e._.js +2 -2
  59. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0okos0k._.js +2 -2
  60. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__05zi2mt._.js → [root-of-the-server]__0vn1ciw._.js} +2 -2
  61. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0w6l33k._.js +2 -1
  62. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0kkt_9z._.js → [root-of-the-server]__0z-n~~r._.js} +2 -2
  63. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__11pa2ra._.js +2 -2
  64. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__12t-wym._.js +2 -2
  65. package/.next/standalone/.next/server/chunks/ssr/_0x..fj-._.js +1 -1
  66. package/.next/standalone/.next/server/chunks/ssr/_10lm7or._.js +2 -2
  67. package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_0xerkr6._.js +1 -1
  68. package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_0q-m0y-._.js +1 -1
  69. package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
  70. package/.next/standalone/.next/server/pages/404.html +2 -2
  71. package/.next/standalone/.next/server/pages/500.html +1 -1
  72. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  73. package/.next/standalone/.next/server/server-reference-manifest.json +9 -9
  74. package/.next/standalone/.next/static/chunks/{0ltx5i0xv85_s.js → 04wavch6dsfes.js} +1 -1
  75. package/.next/standalone/.next/static/chunks/{13jdpvk~s2da8.js → 0drr--vxs_m-c.js} +1 -1
  76. package/.next/standalone/.next/static/chunks/{0jf9lx3rkmqx_.css → 0gu_a.a80ritd.css} +1 -1
  77. package/.next/standalone/.next/static/chunks/{0e76l4~hq_sei.js → 0i1ilz5554nv9.js} +1 -1
  78. package/.next/standalone/.next/static/chunks/{0suauczjqzn07.js → 0keqg6-cjs8aa.js} +1 -1
  79. package/.next/standalone/.next/static/chunks/{0w.rtg9.m8dk-.js → 0myzx7y.rqqi3.js} +2 -2
  80. package/.next/standalone/.next/static/chunks/{02u4v.k5amfah.js → 0zfrusm~j404v.js} +1 -1
  81. package/.next/standalone/.next/static/chunks/{0bkizbynk9via.js → 10xhknzfyigcu.js} +1 -1
  82. package/.next/standalone/.next/static/chunks/{0q7atesxo-36k.js → 16yg3xhkmdb9v.js} +1 -1
  83. package/.next/standalone/CHANGELOG.md +27 -0
  84. package/.next/standalone/CLAUDE.md +14 -0
  85. package/.next/standalone/README.md +16 -0
  86. package/.next/standalone/bun.lock +45 -0
  87. package/.next/standalone/dist/cli.mjs +44 -23
  88. package/.next/standalone/docs/ar/architecture.mdx +333 -0
  89. package/.next/standalone/docs/ar/built-in-policies.mdx +566 -0
  90. package/.next/standalone/docs/ar/cli/dashboard.mdx +28 -0
  91. package/.next/standalone/docs/ar/cli/environment-variables.mdx +34 -0
  92. package/.next/standalone/docs/ar/cli/hook.mdx +31 -0
  93. package/.next/standalone/docs/ar/cli/install-policies.mdx +49 -0
  94. package/.next/standalone/docs/ar/cli/list-policies.mdx +31 -0
  95. package/.next/standalone/docs/ar/cli/remove-policies.mdx +45 -0
  96. package/.next/standalone/docs/ar/cli/version.mdx +13 -0
  97. package/.next/standalone/docs/ar/configuration.mdx +223 -0
  98. package/.next/standalone/docs/ar/custom-policies.mdx +359 -0
  99. package/.next/standalone/docs/ar/dashboard.mdx +142 -0
  100. package/.next/standalone/docs/ar/examples.mdx +254 -0
  101. package/.next/standalone/docs/ar/for-agents.mdx +39 -0
  102. package/.next/standalone/docs/ar/getting-started.mdx +134 -0
  103. package/.next/standalone/docs/ar/introduction.mdx +58 -0
  104. package/.next/standalone/docs/ar/package-aliases.mdx +82 -0
  105. package/.next/standalone/docs/ar/testing.mdx +261 -0
  106. package/.next/standalone/docs/built-in-policies.mdx +17 -1
  107. package/.next/standalone/docs/configuration.mdx +1 -1
  108. package/.next/standalone/docs/custom-policies.mdx +3 -3
  109. package/.next/standalone/docs/de/architecture.mdx +332 -0
  110. package/.next/standalone/docs/de/built-in-policies.mdx +564 -0
  111. package/.next/standalone/docs/de/cli/dashboard.mdx +28 -0
  112. package/.next/standalone/docs/de/cli/environment-variables.mdx +34 -0
  113. package/.next/standalone/docs/de/cli/hook.mdx +30 -0
  114. package/.next/standalone/docs/de/cli/install-policies.mdx +48 -0
  115. package/.next/standalone/docs/de/cli/list-policies.mdx +31 -0
  116. package/.next/standalone/docs/de/cli/remove-policies.mdx +44 -0
  117. package/.next/standalone/docs/de/cli/version.mdx +12 -0
  118. package/.next/standalone/docs/de/configuration.mdx +222 -0
  119. package/.next/standalone/docs/de/custom-policies.mdx +357 -0
  120. package/.next/standalone/docs/de/dashboard.mdx +142 -0
  121. package/.next/standalone/docs/de/examples.mdx +253 -0
  122. package/.next/standalone/docs/de/for-agents.mdx +38 -0
  123. package/.next/standalone/docs/de/getting-started.mdx +134 -0
  124. package/.next/standalone/docs/de/introduction.mdx +57 -0
  125. package/.next/standalone/docs/de/package-aliases.mdx +82 -0
  126. package/.next/standalone/docs/de/testing.mdx +260 -0
  127. package/.next/standalone/docs/docs.json +922 -35
  128. package/.next/standalone/docs/es/architecture.mdx +332 -0
  129. package/.next/standalone/docs/es/built-in-policies.mdx +564 -0
  130. package/.next/standalone/docs/es/cli/dashboard.mdx +28 -0
  131. package/.next/standalone/docs/es/cli/environment-variables.mdx +34 -0
  132. package/.next/standalone/docs/es/cli/hook.mdx +30 -0
  133. package/.next/standalone/docs/es/cli/install-policies.mdx +48 -0
  134. package/.next/standalone/docs/es/cli/list-policies.mdx +31 -0
  135. package/.next/standalone/docs/es/cli/remove-policies.mdx +44 -0
  136. package/.next/standalone/docs/es/cli/version.mdx +12 -0
  137. package/.next/standalone/docs/es/configuration.mdx +222 -0
  138. package/.next/standalone/docs/es/custom-policies.mdx +357 -0
  139. package/.next/standalone/docs/es/dashboard.mdx +142 -0
  140. package/.next/standalone/docs/es/examples.mdx +253 -0
  141. package/.next/standalone/docs/es/for-agents.mdx +38 -0
  142. package/.next/standalone/docs/es/getting-started.mdx +134 -0
  143. package/.next/standalone/docs/es/introduction.mdx +57 -0
  144. package/.next/standalone/docs/es/package-aliases.mdx +82 -0
  145. package/.next/standalone/docs/es/testing.mdx +260 -0
  146. package/.next/standalone/docs/fr/architecture.mdx +332 -0
  147. package/.next/standalone/docs/fr/built-in-policies.mdx +564 -0
  148. package/.next/standalone/docs/fr/cli/dashboard.mdx +28 -0
  149. package/.next/standalone/docs/fr/cli/environment-variables.mdx +34 -0
  150. package/.next/standalone/docs/fr/cli/hook.mdx +30 -0
  151. package/.next/standalone/docs/fr/cli/install-policies.mdx +48 -0
  152. package/.next/standalone/docs/fr/cli/list-policies.mdx +31 -0
  153. package/.next/standalone/docs/fr/cli/remove-policies.mdx +44 -0
  154. package/.next/standalone/docs/fr/cli/version.mdx +12 -0
  155. package/.next/standalone/docs/fr/configuration.mdx +222 -0
  156. package/.next/standalone/docs/fr/custom-policies.mdx +357 -0
  157. package/.next/standalone/docs/fr/dashboard.mdx +142 -0
  158. package/.next/standalone/docs/fr/examples.mdx +253 -0
  159. package/.next/standalone/docs/fr/for-agents.mdx +38 -0
  160. package/.next/standalone/docs/fr/getting-started.mdx +134 -0
  161. package/.next/standalone/docs/fr/introduction.mdx +57 -0
  162. package/.next/standalone/docs/fr/package-aliases.mdx +82 -0
  163. package/.next/standalone/docs/fr/testing.mdx +260 -0
  164. package/.next/standalone/docs/he/architecture.mdx +333 -0
  165. package/.next/standalone/docs/he/built-in-policies.mdx +564 -0
  166. package/.next/standalone/docs/he/cli/dashboard.mdx +28 -0
  167. package/.next/standalone/docs/he/cli/environment-variables.mdx +34 -0
  168. package/.next/standalone/docs/he/cli/hook.mdx +30 -0
  169. package/.next/standalone/docs/he/cli/install-policies.mdx +48 -0
  170. package/.next/standalone/docs/he/cli/list-policies.mdx +32 -0
  171. package/.next/standalone/docs/he/cli/remove-policies.mdx +44 -0
  172. package/.next/standalone/docs/he/cli/version.mdx +12 -0
  173. package/.next/standalone/docs/he/configuration.mdx +222 -0
  174. package/.next/standalone/docs/he/custom-policies.mdx +357 -0
  175. package/.next/standalone/docs/he/dashboard.mdx +142 -0
  176. package/.next/standalone/docs/he/examples.mdx +253 -0
  177. package/.next/standalone/docs/he/for-agents.mdx +38 -0
  178. package/.next/standalone/docs/he/getting-started.mdx +135 -0
  179. package/.next/standalone/docs/he/introduction.mdx +57 -0
  180. package/.next/standalone/docs/he/package-aliases.mdx +82 -0
  181. package/.next/standalone/docs/he/testing.mdx +260 -0
  182. package/.next/standalone/docs/hi/architecture.mdx +334 -0
  183. package/.next/standalone/docs/hi/built-in-policies.mdx +564 -0
  184. package/.next/standalone/docs/hi/cli/dashboard.mdx +28 -0
  185. package/.next/standalone/docs/hi/cli/environment-variables.mdx +34 -0
  186. package/.next/standalone/docs/hi/cli/hook.mdx +30 -0
  187. package/.next/standalone/docs/hi/cli/install-policies.mdx +48 -0
  188. package/.next/standalone/docs/hi/cli/list-policies.mdx +31 -0
  189. package/.next/standalone/docs/hi/cli/remove-policies.mdx +44 -0
  190. package/.next/standalone/docs/hi/cli/version.mdx +12 -0
  191. package/.next/standalone/docs/hi/configuration.mdx +222 -0
  192. package/.next/standalone/docs/hi/custom-policies.mdx +357 -0
  193. package/.next/standalone/docs/hi/dashboard.mdx +142 -0
  194. package/.next/standalone/docs/hi/examples.mdx +255 -0
  195. package/.next/standalone/docs/hi/for-agents.mdx +38 -0
  196. package/.next/standalone/docs/hi/getting-started.mdx +134 -0
  197. package/.next/standalone/docs/hi/introduction.mdx +57 -0
  198. package/.next/standalone/docs/hi/package-aliases.mdx +82 -0
  199. package/.next/standalone/docs/hi/testing.mdx +260 -0
  200. package/.next/standalone/docs/i18n/README.ar.md +312 -0
  201. package/.next/standalone/docs/i18n/README.de.md +307 -0
  202. package/.next/standalone/docs/i18n/README.es.md +307 -0
  203. package/.next/standalone/docs/i18n/README.fr.md +307 -0
  204. package/.next/standalone/docs/i18n/README.he.md +312 -0
  205. package/.next/standalone/docs/i18n/README.hi.md +307 -0
  206. package/.next/standalone/docs/i18n/README.it.md +307 -0
  207. package/.next/standalone/docs/i18n/README.ja.md +307 -0
  208. package/.next/standalone/docs/i18n/README.ko.md +307 -0
  209. package/.next/standalone/docs/i18n/README.pt-br.md +307 -0
  210. package/.next/standalone/docs/i18n/README.ru.md +308 -0
  211. package/.next/standalone/docs/i18n/README.tr.md +308 -0
  212. package/.next/standalone/docs/i18n/README.vi.md +308 -0
  213. package/.next/standalone/docs/i18n/README.zh.md +307 -0
  214. package/.next/standalone/docs/it/architecture.mdx +333 -0
  215. package/.next/standalone/docs/it/built-in-policies.mdx +564 -0
  216. package/.next/standalone/docs/it/cli/dashboard.mdx +28 -0
  217. package/.next/standalone/docs/it/cli/environment-variables.mdx +34 -0
  218. package/.next/standalone/docs/it/cli/hook.mdx +30 -0
  219. package/.next/standalone/docs/it/cli/install-policies.mdx +48 -0
  220. package/.next/standalone/docs/it/cli/list-policies.mdx +31 -0
  221. package/.next/standalone/docs/it/cli/remove-policies.mdx +44 -0
  222. package/.next/standalone/docs/it/cli/version.mdx +12 -0
  223. package/.next/standalone/docs/it/configuration.mdx +223 -0
  224. package/.next/standalone/docs/it/custom-policies.mdx +358 -0
  225. package/.next/standalone/docs/it/dashboard.mdx +142 -0
  226. package/.next/standalone/docs/it/examples.mdx +253 -0
  227. package/.next/standalone/docs/it/for-agents.mdx +38 -0
  228. package/.next/standalone/docs/it/getting-started.mdx +134 -0
  229. package/.next/standalone/docs/it/introduction.mdx +57 -0
  230. package/.next/standalone/docs/it/package-aliases.mdx +82 -0
  231. package/.next/standalone/docs/it/testing.mdx +260 -0
  232. package/.next/standalone/docs/ja/architecture.mdx +332 -0
  233. package/.next/standalone/docs/ja/built-in-policies.mdx +562 -0
  234. package/.next/standalone/docs/ja/cli/dashboard.mdx +28 -0
  235. package/.next/standalone/docs/ja/cli/environment-variables.mdx +34 -0
  236. package/.next/standalone/docs/ja/cli/hook.mdx +30 -0
  237. package/.next/standalone/docs/ja/cli/install-policies.mdx +48 -0
  238. package/.next/standalone/docs/ja/cli/list-policies.mdx +31 -0
  239. package/.next/standalone/docs/ja/cli/remove-policies.mdx +44 -0
  240. package/.next/standalone/docs/ja/cli/version.mdx +12 -0
  241. package/.next/standalone/docs/ja/configuration.mdx +222 -0
  242. package/.next/standalone/docs/ja/custom-policies.mdx +357 -0
  243. package/.next/standalone/docs/ja/dashboard.mdx +142 -0
  244. package/.next/standalone/docs/ja/examples.mdx +253 -0
  245. package/.next/standalone/docs/ja/for-agents.mdx +38 -0
  246. package/.next/standalone/docs/ja/getting-started.mdx +134 -0
  247. package/.next/standalone/docs/ja/introduction.mdx +57 -0
  248. package/.next/standalone/docs/ja/package-aliases.mdx +82 -0
  249. package/.next/standalone/docs/ja/testing.mdx +260 -0
  250. package/.next/standalone/docs/ko/architecture.mdx +332 -0
  251. package/.next/standalone/docs/ko/built-in-policies.mdx +562 -0
  252. package/.next/standalone/docs/ko/cli/dashboard.mdx +28 -0
  253. package/.next/standalone/docs/ko/cli/environment-variables.mdx +34 -0
  254. package/.next/standalone/docs/ko/cli/hook.mdx +30 -0
  255. package/.next/standalone/docs/ko/cli/install-policies.mdx +48 -0
  256. package/.next/standalone/docs/ko/cli/list-policies.mdx +31 -0
  257. package/.next/standalone/docs/ko/cli/remove-policies.mdx +44 -0
  258. package/.next/standalone/docs/ko/cli/version.mdx +12 -0
  259. package/.next/standalone/docs/ko/configuration.mdx +222 -0
  260. package/.next/standalone/docs/ko/custom-policies.mdx +357 -0
  261. package/.next/standalone/docs/ko/dashboard.mdx +142 -0
  262. package/.next/standalone/docs/ko/examples.mdx +253 -0
  263. package/.next/standalone/docs/ko/for-agents.mdx +38 -0
  264. package/.next/standalone/docs/ko/getting-started.mdx +134 -0
  265. package/.next/standalone/docs/ko/introduction.mdx +57 -0
  266. package/.next/standalone/docs/ko/package-aliases.mdx +82 -0
  267. package/.next/standalone/docs/ko/testing.mdx +260 -0
  268. package/.next/standalone/docs/pt-br/architecture.mdx +332 -0
  269. package/.next/standalone/docs/pt-br/built-in-policies.mdx +564 -0
  270. package/.next/standalone/docs/pt-br/cli/dashboard.mdx +28 -0
  271. package/.next/standalone/docs/pt-br/cli/environment-variables.mdx +34 -0
  272. package/.next/standalone/docs/pt-br/cli/hook.mdx +30 -0
  273. package/.next/standalone/docs/pt-br/cli/install-policies.mdx +48 -0
  274. package/.next/standalone/docs/pt-br/cli/list-policies.mdx +31 -0
  275. package/.next/standalone/docs/pt-br/cli/remove-policies.mdx +44 -0
  276. package/.next/standalone/docs/pt-br/cli/version.mdx +12 -0
  277. package/.next/standalone/docs/pt-br/configuration.mdx +222 -0
  278. package/.next/standalone/docs/pt-br/custom-policies.mdx +357 -0
  279. package/.next/standalone/docs/pt-br/dashboard.mdx +142 -0
  280. package/.next/standalone/docs/pt-br/examples.mdx +253 -0
  281. package/.next/standalone/docs/pt-br/for-agents.mdx +38 -0
  282. package/.next/standalone/docs/pt-br/getting-started.mdx +134 -0
  283. package/.next/standalone/docs/pt-br/introduction.mdx +57 -0
  284. package/.next/standalone/docs/pt-br/package-aliases.mdx +82 -0
  285. package/.next/standalone/docs/pt-br/testing.mdx +260 -0
  286. package/.next/standalone/docs/ru/architecture.mdx +334 -0
  287. package/.next/standalone/docs/ru/built-in-policies.mdx +562 -0
  288. package/.next/standalone/docs/ru/cli/dashboard.mdx +28 -0
  289. package/.next/standalone/docs/ru/cli/environment-variables.mdx +34 -0
  290. package/.next/standalone/docs/ru/cli/hook.mdx +30 -0
  291. package/.next/standalone/docs/ru/cli/install-policies.mdx +48 -0
  292. package/.next/standalone/docs/ru/cli/list-policies.mdx +32 -0
  293. package/.next/standalone/docs/ru/cli/remove-policies.mdx +44 -0
  294. package/.next/standalone/docs/ru/cli/version.mdx +12 -0
  295. package/.next/standalone/docs/ru/configuration.mdx +223 -0
  296. package/.next/standalone/docs/ru/custom-policies.mdx +357 -0
  297. package/.next/standalone/docs/ru/dashboard.mdx +142 -0
  298. package/.next/standalone/docs/ru/examples.mdx +254 -0
  299. package/.next/standalone/docs/ru/for-agents.mdx +38 -0
  300. package/.next/standalone/docs/ru/getting-started.mdx +134 -0
  301. package/.next/standalone/docs/ru/introduction.mdx +57 -0
  302. package/.next/standalone/docs/ru/package-aliases.mdx +82 -0
  303. package/.next/standalone/docs/ru/testing.mdx +260 -0
  304. package/.next/standalone/docs/tr/architecture.mdx +333 -0
  305. package/.next/standalone/docs/tr/built-in-policies.mdx +562 -0
  306. package/.next/standalone/docs/tr/cli/dashboard.mdx +28 -0
  307. package/.next/standalone/docs/tr/cli/environment-variables.mdx +34 -0
  308. package/.next/standalone/docs/tr/cli/hook.mdx +30 -0
  309. package/.next/standalone/docs/tr/cli/install-policies.mdx +48 -0
  310. package/.next/standalone/docs/tr/cli/list-policies.mdx +31 -0
  311. package/.next/standalone/docs/tr/cli/remove-policies.mdx +45 -0
  312. package/.next/standalone/docs/tr/cli/version.mdx +12 -0
  313. package/.next/standalone/docs/tr/configuration.mdx +223 -0
  314. package/.next/standalone/docs/tr/custom-policies.mdx +357 -0
  315. package/.next/standalone/docs/tr/dashboard.mdx +142 -0
  316. package/.next/standalone/docs/tr/examples.mdx +253 -0
  317. package/.next/standalone/docs/tr/for-agents.mdx +38 -0
  318. package/.next/standalone/docs/tr/getting-started.mdx +134 -0
  319. package/.next/standalone/docs/tr/introduction.mdx +57 -0
  320. package/.next/standalone/docs/tr/package-aliases.mdx +82 -0
  321. package/.next/standalone/docs/tr/testing.mdx +260 -0
  322. package/.next/standalone/docs/vi/architecture.mdx +333 -0
  323. package/.next/standalone/docs/vi/built-in-policies.mdx +564 -0
  324. package/.next/standalone/docs/vi/cli/dashboard.mdx +28 -0
  325. package/.next/standalone/docs/vi/cli/environment-variables.mdx +34 -0
  326. package/.next/standalone/docs/vi/cli/hook.mdx +30 -0
  327. package/.next/standalone/docs/vi/cli/install-policies.mdx +48 -0
  328. package/.next/standalone/docs/vi/cli/list-policies.mdx +31 -0
  329. package/.next/standalone/docs/vi/cli/remove-policies.mdx +44 -0
  330. package/.next/standalone/docs/vi/cli/version.mdx +13 -0
  331. package/.next/standalone/docs/vi/configuration.mdx +222 -0
  332. package/.next/standalone/docs/vi/custom-policies.mdx +357 -0
  333. package/.next/standalone/docs/vi/dashboard.mdx +142 -0
  334. package/.next/standalone/docs/vi/examples.mdx +253 -0
  335. package/.next/standalone/docs/vi/for-agents.mdx +38 -0
  336. package/.next/standalone/docs/vi/getting-started.mdx +134 -0
  337. package/.next/standalone/docs/vi/introduction.mdx +57 -0
  338. package/.next/standalone/docs/vi/package-aliases.mdx +82 -0
  339. package/.next/standalone/docs/vi/testing.mdx +260 -0
  340. package/.next/standalone/docs/zh/architecture.mdx +332 -0
  341. package/.next/standalone/docs/zh/built-in-policies.mdx +562 -0
  342. package/.next/standalone/docs/zh/cli/dashboard.mdx +28 -0
  343. package/.next/standalone/docs/zh/cli/environment-variables.mdx +34 -0
  344. package/.next/standalone/docs/zh/cli/hook.mdx +30 -0
  345. package/.next/standalone/docs/zh/cli/install-policies.mdx +48 -0
  346. package/.next/standalone/docs/zh/cli/list-policies.mdx +31 -0
  347. package/.next/standalone/docs/zh/cli/remove-policies.mdx +44 -0
  348. package/.next/standalone/docs/zh/cli/version.mdx +12 -0
  349. package/.next/standalone/docs/zh/configuration.mdx +222 -0
  350. package/.next/standalone/docs/zh/custom-policies.mdx +357 -0
  351. package/.next/standalone/docs/zh/dashboard.mdx +142 -0
  352. package/.next/standalone/docs/zh/examples.mdx +253 -0
  353. package/.next/standalone/docs/zh/for-agents.mdx +38 -0
  354. package/.next/standalone/docs/zh/getting-started.mdx +134 -0
  355. package/.next/standalone/docs/zh/introduction.mdx +57 -0
  356. package/.next/standalone/docs/zh/package-aliases.mdx +82 -0
  357. package/.next/standalone/docs/zh/testing.mdx +260 -0
  358. package/.next/standalone/package.json +8 -2
  359. package/.next/standalone/scripts/translate-docs/cache.ts +62 -0
  360. package/.next/standalone/scripts/translate-docs/cli.ts +357 -0
  361. package/.next/standalone/scripts/translate-docs/config.ts +248 -0
  362. package/.next/standalone/scripts/translate-docs/mdx-translator.ts +153 -0
  363. package/.next/standalone/scripts/translate-docs/mintlify-nav.ts +107 -0
  364. package/.next/standalone/scripts/translate-docs/readme-translator.ts +154 -0
  365. package/.next/standalone/scripts/translate-docs/translator.ts +68 -0
  366. package/.next/standalone/scripts/translate-docs/types.ts +43 -0
  367. package/.next/standalone/server.js +1 -1
  368. package/.next/standalone/src/hooks/custom-hooks-loader.ts +12 -5
  369. package/.next/standalone/src/hooks/handler.ts +9 -3
  370. package/.next/standalone/src/hooks/manager.ts +10 -2
  371. package/.next/standalone/src/hooks/policy-evaluator.ts +20 -16
  372. package/README.md +16 -0
  373. package/dist/cli.mjs +44 -23
  374. package/package.json +8 -2
  375. package/scripts/translate-docs/cache.ts +62 -0
  376. package/scripts/translate-docs/cli.ts +357 -0
  377. package/scripts/translate-docs/config.ts +248 -0
  378. package/scripts/translate-docs/mdx-translator.ts +153 -0
  379. package/scripts/translate-docs/mintlify-nav.ts +107 -0
  380. package/scripts/translate-docs/readme-translator.ts +154 -0
  381. package/scripts/translate-docs/translator.ts +68 -0
  382. package/scripts/translate-docs/types.ts +43 -0
  383. package/src/hooks/custom-hooks-loader.ts +12 -5
  384. package/src/hooks/handler.ts +9 -3
  385. package/src/hooks/manager.ts +10 -2
  386. package/src/hooks/policy-evaluator.ts +20 -16
  387. package/.next/standalone/.next/server/chunks/[root-of-the-server]__02nt~6d._.js +0 -3
  388. /package/.next/standalone/.next/static/{Opbai6exOQP2W488FWmr6 → XqGmAwGDuJ6fEQgD-8y60}/_buildManifest.js +0 -0
  389. /package/.next/standalone/.next/static/{Opbai6exOQP2W488FWmr6 → XqGmAwGDuJ6fEQgD-8y60}/_clientMiddlewareManifest.js +0 -0
  390. /package/.next/standalone/.next/static/{Opbai6exOQP2W488FWmr6 → XqGmAwGDuJ6fEQgD-8y60}/_ssgManifest.js +0 -0
@@ -0,0 +1,68 @@
1
+ import Anthropic from "@anthropic-ai/sdk";
2
+ import { DO_NOT_TRANSLATE } from "./config";
3
+
4
+ let client: Anthropic | null = null;
5
+
6
+ function getClient(): Anthropic {
7
+ if (!client) {
8
+ client = new Anthropic();
9
+ }
10
+ return client;
11
+ }
12
+
13
+ const SYSTEM_PROMPT = `You are a professional technical documentation translator. Your task is to translate documentation content precisely and naturally into the target language.
14
+
15
+ ## Rules
16
+
17
+ 1. **Preserve all code blocks exactly as-is** — never translate content inside backtick-fenced code blocks (\`\`\`...\`\`\`) or inline code (\`...\`).
18
+ 2. **Preserve MDX component syntax** — tags like <Card>, <CardGroup>, <CodeGroup>, <Steps>, <Step>, <Note>, <Tip>, <Tabs>, <Tab>, <Warning> must remain unchanged. Their attribute names (title, icon, href, cols) must remain in English. Only translate the text content of the \`title\` attribute and the text body between tags.
19
+ 3. **Preserve YAML frontmatter keys** — only translate the string values of \`title\` and \`description\`. Keep the \`icon\` value unchanged.
20
+ 4. **Preserve all URLs and paths** — never modify href values, image paths, or links.
21
+ 5. **Preserve Markdown structure** — headers (#, ##), lists (-, *), tables (|), bold (**), italic (*), links ([text](url)) must keep their Markdown formatting.
22
+ 6. **Preserve badge/shield URLs** — any [![...](https://img.shields.io/...)](url) pattern must remain completely unchanged.
23
+
24
+ ## Do-not-translate list
25
+
26
+ The following terms must NEVER be translated — keep them exactly as-is in the output:
27
+ ${DO_NOT_TRANSLATE.map((t) => `- ${t}`).join("\n")}
28
+
29
+ ## Translation quality
30
+
31
+ - Use natural, idiomatic phrasing in the target language — do NOT produce word-for-word literal translations.
32
+ - Technical documentation should read as if originally written in the target language by a native-speaking developer.
33
+ - Maintain the same level of formality and tone as the source.
34
+ - For languages that distinguish formal/informal registers, use a professional but approachable tone.
35
+
36
+ ## Output
37
+
38
+ Return ONLY the translated content. Do not add explanations, notes, or commentary.`;
39
+
40
+ export async function translateContent(
41
+ content: string,
42
+ targetLang: string,
43
+ targetLangName: string,
44
+ model: string = "claude-sonnet-4-6",
45
+ ): Promise<{ translated: string; inputTokens: number; outputTokens: number }> {
46
+ const anthropic = getClient();
47
+
48
+ const response = await anthropic.messages.create({
49
+ model,
50
+ max_tokens: 16384,
51
+ system: [{ type: "text", text: SYSTEM_PROMPT, cache_control: { type: "ephemeral" } }],
52
+ messages: [
53
+ {
54
+ role: "user",
55
+ content: `Translate the following documentation content into ${targetLangName} (${targetLang}).\n\n---\n\n${content}`,
56
+ },
57
+ ],
58
+ });
59
+
60
+ const translated =
61
+ response.content[0].type === "text" ? response.content[0].text : "";
62
+
63
+ return {
64
+ translated,
65
+ inputTokens: response.usage.input_tokens,
66
+ outputTokens: response.usage.output_tokens,
67
+ };
68
+ }
@@ -0,0 +1,43 @@
1
+ export interface LanguageConfig {
2
+ code: string;
3
+ name: string;
4
+ nativeName: string;
5
+ tier: 1 | 2 | 3;
6
+ rtl?: boolean;
7
+ }
8
+
9
+ export interface CacheEntry {
10
+ sourceHash: string;
11
+ targetLang: string;
12
+ translatedAt: string;
13
+ inputTokens: number;
14
+ outputTokens: number;
15
+ }
16
+
17
+ export interface TranslationCache {
18
+ sourceHash: string;
19
+ lastUpdated: string;
20
+ translations: Record<string, CacheEntry>;
21
+ }
22
+
23
+ export interface TranslateOptions {
24
+ languages: string[];
25
+ tier?: number;
26
+ pagesFilter?: string[];
27
+ readmeOnly?: boolean;
28
+ docsOnly?: boolean;
29
+ dryRun?: boolean;
30
+ force?: boolean;
31
+ updateNav?: boolean;
32
+ validate?: boolean;
33
+ model?: string;
34
+ }
35
+
36
+ export interface TranslationResult {
37
+ lang: string;
38
+ sourcePath: string;
39
+ outputPath: string;
40
+ inputTokens: number;
41
+ outputTokens: number;
42
+ cached: boolean;
43
+ }
@@ -9,7 +9,7 @@ const currentPort = parseInt(process.env.PORT, 10) || 3000
9
9
  const hostname = process.env.HOSTNAME || '0.0.0.0'
10
10
 
11
11
  let keepAliveTimeout = parseInt(process.env.KEEP_ALIVE_TIMEOUT, 10)
12
- const nextConfig = {"env":{"NEXT_PUBLIC_APP_VERSION":"0.0.2-beta.7"},"typescript":{"ignoreBuildErrors":false},"typedRoutes":false,"distDir":"./.next","cleanDistDir":true,"assetPrefix":"","cacheMaxMemorySize":52428800,"configOrigin":"next.config.ts","useFileSystemPublicRoutes":true,"generateEtags":true,"pageExtensions":["tsx","ts","jsx","js"],"poweredByHeader":true,"compress":true,"images":{"deviceSizes":[640,750,828,1080,1200,1920,2048,3840],"imageSizes":[32,48,64,96,128,256,384],"path":"/_next/image","loader":"default","loaderFile":"","domains":[],"disableStaticImages":false,"minimumCacheTTL":14400,"formats":["image/webp"],"maximumRedirects":3,"maximumResponseBody":50000000,"dangerouslyAllowLocalIP":false,"dangerouslyAllowSVG":false,"contentSecurityPolicy":"script-src 'none'; frame-src 'none'; sandbox;","contentDispositionType":"attachment","localPatterns":[{"pathname":"**","search":""}],"remotePatterns":[],"qualities":[75],"unoptimized":true,"customCacheHandler":false},"devIndicators":{"position":"bottom-left"},"onDemandEntries":{"maxInactiveAge":60000,"pagesBufferLength":5},"basePath":"","sassOptions":{},"trailingSlash":false,"i18n":null,"productionBrowserSourceMaps":false,"excludeDefaultMomentLocales":true,"reactProductionProfiling":false,"reactStrictMode":null,"reactMaxHeadersLength":6000,"httpAgentOptions":{"keepAlive":true},"logging":{"serverFunctions":true,"browserToTerminal":"warn"},"compiler":{},"expireTime":31536000,"staticPageGenerationTimeout":60,"output":"standalone","modularizeImports":{"@mui/icons-material":{"transform":"@mui/icons-material/{{member}}"},"lodash":{"transform":"lodash/{{member}}"}},"outputFileTracingRoot":"/home/runner/work/failproofai/failproofai","cacheComponents":false,"cacheLife":{"default":{"stale":300,"revalidate":900,"expire":4294967294},"seconds":{"stale":30,"revalidate":1,"expire":60},"minutes":{"stale":300,"revalidate":60,"expire":3600},"hours":{"stale":300,"revalidate":3600,"expire":86400},"days":{"stale":300,"revalidate":86400,"expire":604800},"weeks":{"stale":300,"revalidate":604800,"expire":2592000},"max":{"stale":300,"revalidate":2592000,"expire":31536000}},"cacheHandlers":{},"experimental":{"appNewScrollHandler":false,"useSkewCookie":false,"cssChunking":true,"multiZoneDraftMode":false,"appNavFailHandling":false,"prerenderEarlyExit":true,"serverMinification":true,"linkNoTouchStart":false,"caseSensitiveRoutes":false,"cachedNavigations":false,"partialFallbacks":false,"dynamicOnHover":false,"varyParams":false,"prefetchInlining":false,"preloadEntriesOnStart":true,"clientRouterFilter":true,"clientRouterFilterRedirects":false,"fetchCacheKeyPrefix":"","proxyPrefetch":"flexible","optimisticClientCache":true,"manualClientBasePath":false,"cpus":3,"memoryBasedWorkersCount":false,"imgOptConcurrency":null,"imgOptTimeoutInSeconds":7,"imgOptMaxInputPixels":268402689,"imgOptSequentialRead":null,"imgOptSkipMetadata":null,"isrFlushToDisk":true,"workerThreads":false,"optimizeCss":false,"nextScriptWorkers":false,"scrollRestoration":false,"externalDir":false,"disableOptimizedLoading":false,"gzipSize":true,"craCompat":false,"esmExternals":true,"fullySpecified":false,"swcTraceProfiling":false,"forceSwcTransforms":false,"largePageDataBytes":128000,"typedEnv":false,"parallelServerCompiles":false,"parallelServerBuildTraces":false,"ppr":false,"authInterrupts":false,"webpackMemoryOptimizations":false,"optimizeServerReact":true,"strictRouteTypes":false,"viewTransition":false,"removeUncaughtErrorAndRejectionListeners":false,"validateRSCRequestHeaders":false,"staleTimes":{"dynamic":0,"static":300},"reactDebugChannel":true,"serverComponentsHmrCache":true,"staticGenerationMaxConcurrency":8,"staticGenerationMinPagesPerWorker":25,"transitionIndicator":false,"gestureTransition":false,"inlineCss":false,"useCache":false,"globalNotFound":false,"browserDebugInfoInTerminal":"warn","lockDistDir":true,"proxyClientMaxBodySize":10485760,"hideLogsAfterAbort":false,"mcpServer":true,"turbopackFileSystemCacheForDev":true,"turbopackFileSystemCacheForBuild":false,"turbopackInferModuleSideEffects":true,"turbopackPluginRuntimeStrategy":"childProcesses","optimizePackageImports":["lucide-react","date-fns","lodash-es","ramda","antd","react-bootstrap","ahooks","@ant-design/icons","@headlessui/react","@headlessui-float/react","@heroicons/react/20/solid","@heroicons/react/24/solid","@heroicons/react/24/outline","@visx/visx","@tremor/react","rxjs","@mui/material","@mui/icons-material","recharts","react-use","effect","@effect/schema","@effect/platform","@effect/platform-node","@effect/platform-browser","@effect/platform-bun","@effect/sql","@effect/sql-mssql","@effect/sql-mysql2","@effect/sql-pg","@effect/sql-sqlite-node","@effect/sql-sqlite-bun","@effect/sql-sqlite-wasm","@effect/sql-sqlite-react-native","@effect/rpc","@effect/rpc-http","@effect/typeclass","@effect/experimental","@effect/opentelemetry","@material-ui/core","@material-ui/icons","@tabler/icons-react","mui-core","react-icons/ai","react-icons/bi","react-icons/bs","react-icons/cg","react-icons/ci","react-icons/di","react-icons/fa","react-icons/fa6","react-icons/fc","react-icons/fi","react-icons/gi","react-icons/go","react-icons/gr","react-icons/hi","react-icons/hi2","react-icons/im","react-icons/io","react-icons/io5","react-icons/lia","react-icons/lib","react-icons/lu","react-icons/md","react-icons/pi","react-icons/ri","react-icons/rx","react-icons/si","react-icons/sl","react-icons/tb","react-icons/tfi","react-icons/ti","react-icons/vsc","react-icons/wi"],"trustHostHeader":false,"isExperimentalCompile":false},"htmlLimitedBots":"[\\w-]+-Google|Google-[\\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight","bundlePagesRouterDependencies":false,"configFileName":"next.config.ts","turbopack":{"root":"/home/runner/work/failproofai/failproofai"},"distDirRoot":".next"}
12
+ const nextConfig = {"env":{"NEXT_PUBLIC_APP_VERSION":"0.0.2-beta.9"},"typescript":{"ignoreBuildErrors":false},"typedRoutes":false,"distDir":"./.next","cleanDistDir":true,"assetPrefix":"","cacheMaxMemorySize":52428800,"configOrigin":"next.config.ts","useFileSystemPublicRoutes":true,"generateEtags":true,"pageExtensions":["tsx","ts","jsx","js"],"poweredByHeader":true,"compress":true,"images":{"deviceSizes":[640,750,828,1080,1200,1920,2048,3840],"imageSizes":[32,48,64,96,128,256,384],"path":"/_next/image","loader":"default","loaderFile":"","domains":[],"disableStaticImages":false,"minimumCacheTTL":14400,"formats":["image/webp"],"maximumRedirects":3,"maximumResponseBody":50000000,"dangerouslyAllowLocalIP":false,"dangerouslyAllowSVG":false,"contentSecurityPolicy":"script-src 'none'; frame-src 'none'; sandbox;","contentDispositionType":"attachment","localPatterns":[{"pathname":"**","search":""}],"remotePatterns":[],"qualities":[75],"unoptimized":true,"customCacheHandler":false},"devIndicators":{"position":"bottom-left"},"onDemandEntries":{"maxInactiveAge":60000,"pagesBufferLength":5},"basePath":"","sassOptions":{},"trailingSlash":false,"i18n":null,"productionBrowserSourceMaps":false,"excludeDefaultMomentLocales":true,"reactProductionProfiling":false,"reactStrictMode":null,"reactMaxHeadersLength":6000,"httpAgentOptions":{"keepAlive":true},"logging":{"serverFunctions":true,"browserToTerminal":"warn"},"compiler":{},"expireTime":31536000,"staticPageGenerationTimeout":60,"output":"standalone","modularizeImports":{"@mui/icons-material":{"transform":"@mui/icons-material/{{member}}"},"lodash":{"transform":"lodash/{{member}}"}},"outputFileTracingRoot":"/home/runner/work/failproofai/failproofai","cacheComponents":false,"cacheLife":{"default":{"stale":300,"revalidate":900,"expire":4294967294},"seconds":{"stale":30,"revalidate":1,"expire":60},"minutes":{"stale":300,"revalidate":60,"expire":3600},"hours":{"stale":300,"revalidate":3600,"expire":86400},"days":{"stale":300,"revalidate":86400,"expire":604800},"weeks":{"stale":300,"revalidate":604800,"expire":2592000},"max":{"stale":300,"revalidate":2592000,"expire":31536000}},"cacheHandlers":{},"experimental":{"appNewScrollHandler":false,"useSkewCookie":false,"cssChunking":true,"multiZoneDraftMode":false,"appNavFailHandling":false,"prerenderEarlyExit":true,"serverMinification":true,"linkNoTouchStart":false,"caseSensitiveRoutes":false,"cachedNavigations":false,"partialFallbacks":false,"dynamicOnHover":false,"varyParams":false,"prefetchInlining":false,"preloadEntriesOnStart":true,"clientRouterFilter":true,"clientRouterFilterRedirects":false,"fetchCacheKeyPrefix":"","proxyPrefetch":"flexible","optimisticClientCache":true,"manualClientBasePath":false,"cpus":3,"memoryBasedWorkersCount":false,"imgOptConcurrency":null,"imgOptTimeoutInSeconds":7,"imgOptMaxInputPixels":268402689,"imgOptSequentialRead":null,"imgOptSkipMetadata":null,"isrFlushToDisk":true,"workerThreads":false,"optimizeCss":false,"nextScriptWorkers":false,"scrollRestoration":false,"externalDir":false,"disableOptimizedLoading":false,"gzipSize":true,"craCompat":false,"esmExternals":true,"fullySpecified":false,"swcTraceProfiling":false,"forceSwcTransforms":false,"largePageDataBytes":128000,"typedEnv":false,"parallelServerCompiles":false,"parallelServerBuildTraces":false,"ppr":false,"authInterrupts":false,"webpackMemoryOptimizations":false,"optimizeServerReact":true,"strictRouteTypes":false,"viewTransition":false,"removeUncaughtErrorAndRejectionListeners":false,"validateRSCRequestHeaders":false,"staleTimes":{"dynamic":0,"static":300},"reactDebugChannel":true,"serverComponentsHmrCache":true,"staticGenerationMaxConcurrency":8,"staticGenerationMinPagesPerWorker":25,"transitionIndicator":false,"gestureTransition":false,"inlineCss":false,"useCache":false,"globalNotFound":false,"browserDebugInfoInTerminal":"warn","lockDistDir":true,"proxyClientMaxBodySize":10485760,"hideLogsAfterAbort":false,"mcpServer":true,"turbopackFileSystemCacheForDev":true,"turbopackFileSystemCacheForBuild":false,"turbopackInferModuleSideEffects":true,"turbopackPluginRuntimeStrategy":"childProcesses","optimizePackageImports":["lucide-react","date-fns","lodash-es","ramda","antd","react-bootstrap","ahooks","@ant-design/icons","@headlessui/react","@headlessui-float/react","@heroicons/react/20/solid","@heroicons/react/24/solid","@heroicons/react/24/outline","@visx/visx","@tremor/react","rxjs","@mui/material","@mui/icons-material","recharts","react-use","effect","@effect/schema","@effect/platform","@effect/platform-node","@effect/platform-browser","@effect/platform-bun","@effect/sql","@effect/sql-mssql","@effect/sql-mysql2","@effect/sql-pg","@effect/sql-sqlite-node","@effect/sql-sqlite-bun","@effect/sql-sqlite-wasm","@effect/sql-sqlite-react-native","@effect/rpc","@effect/rpc-http","@effect/typeclass","@effect/experimental","@effect/opentelemetry","@material-ui/core","@material-ui/icons","@tabler/icons-react","mui-core","react-icons/ai","react-icons/bi","react-icons/bs","react-icons/cg","react-icons/ci","react-icons/di","react-icons/fa","react-icons/fa6","react-icons/fc","react-icons/fi","react-icons/gi","react-icons/go","react-icons/gr","react-icons/hi","react-icons/hi2","react-icons/im","react-icons/io","react-icons/io5","react-icons/lia","react-icons/lib","react-icons/lu","react-icons/md","react-icons/pi","react-icons/ri","react-icons/rx","react-icons/si","react-icons/sl","react-icons/tb","react-icons/tfi","react-icons/ti","react-icons/vsc","react-icons/wi"],"trustHostHeader":false,"isExperimentalCompile":false},"htmlLimitedBots":"[\\w-]+-Google|Google-[\\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight","bundlePagesRouterDependencies":false,"configFileName":"next.config.ts","turbopack":{"root":"/home/runner/work/failproofai/failproofai"},"distDirRoot":".next"}
13
13
 
14
14
  process.env.__NEXT_PRIVATE_STANDALONE_CONFIG = JSON.stringify(nextConfig)
15
15
 
@@ -116,7 +116,7 @@ export interface LoadAllResult {
116
116
  * 3. User convention: ~/.failproofai/policies/*policies.{js,mjs,ts} (alphabetical)
117
117
  *
118
118
  * Each file is loaded independently (fail-open per file).
119
- * Convention hooks are tagged with __conventionSource so the handler can distinguish them.
119
+ * Convention hooks are tagged with __conventionScope so the handler can build scoped prefixes.
120
120
  */
121
121
  export async function loadAllCustomHooks(
122
122
  customPoliciesPath: string | undefined,
@@ -181,16 +181,23 @@ export async function loadAllCustomHooks(
181
181
  );
182
182
  }
183
183
 
184
- // Tag convention hooks so the handler can register them with a "convention/" prefix.
185
- // Track by object reference (not name) to avoid mis-tagging an explicit custom hook
186
- // that happens to share the same name as a convention hook.
184
+ // Tag convention hooks with their scope so the handler can build scoped prefixes.
185
+ // Build a name→scope map from conventionSources, then tag by object reference
186
+ // to avoid mis-tagging an explicit custom hook that shares the same name.
187
+ const hookNameToScope = new Map<string, string>();
188
+ for (const source of conventionSources) {
189
+ for (const name of source.hookNames) {
190
+ hookNameToScope.set(name, source.scope);
191
+ }
192
+ }
187
193
  const conventionHookRefs = new Set<CustomHook>();
188
194
  for (const hook of allHooks.slice(hooksBeforeConvention)) {
189
195
  conventionHookRefs.add(hook);
190
196
  }
191
197
  for (const hook of allHooks) {
192
198
  if (conventionHookRefs.has(hook)) {
193
- (hook as CustomHook & { __conventionSource?: boolean }).__conventionSource = true;
199
+ (hook as CustomHook & { __conventionScope?: string }).__conventionScope =
200
+ hookNameToScope.get(hook.name) ?? "project";
194
201
  }
195
202
  }
196
203
 
@@ -78,8 +78,9 @@ export async function handleHookEvent(eventType: string): Promise<number> {
78
78
 
79
79
  for (const hook of customHooksList) {
80
80
  const hookName = hook.name;
81
- const isConvention = (hook as CustomHook & { __conventionSource?: boolean }).__conventionSource === true;
82
- const prefix = isConvention ? "convention" : "custom";
81
+ const conventionScope = (hook as CustomHook & { __conventionScope?: string }).__conventionScope;
82
+ const isConvention = !!conventionScope;
83
+ const prefix = isConvention ? `.failproofai-${conventionScope}` : "custom";
83
84
  const fn: PolicyFunction = async (ctx): Promise<PolicyResult> => {
84
85
  try {
85
86
  const result = await Promise.race([
@@ -98,6 +99,7 @@ export async function handleHookEvent(eventType: string): Promise<number> {
98
99
  error_type: isTimeout ? "timeout" : "exception",
99
100
  event_type: eventType,
100
101
  is_convention_policy: isConvention,
102
+ convention_scope: conventionScope ?? null,
101
103
  });
102
104
  return { decision: "allow" };
103
105
  }
@@ -170,7 +172,10 @@ export async function handleHookEvent(eventType: string): Promise<number> {
170
172
  if (result.decision === "deny" || result.decision === "instruct") {
171
173
  try {
172
174
  const isCustomHook = result.policyName?.startsWith("custom/") ?? false;
173
- const isConventionPolicy = result.policyName?.startsWith("convention/") ?? false;
175
+ const isConventionPolicy = result.policyName?.startsWith(".failproofai-") ?? false;
176
+ const conventionScope = isConventionPolicy
177
+ ? result.policyName!.match(/^\.failproofai-(project|user)\//)?.[1] ?? null
178
+ : null;
174
179
  const hasCustomParams =
175
180
  !isCustomHook && !isConventionPolicy && !!(result.policyName && config.policyParams?.[result.policyName]);
176
181
  const paramKeysOverridden = hasCustomParams
@@ -184,6 +189,7 @@ export async function handleHookEvent(eventType: string): Promise<number> {
184
189
  decision: result.decision,
185
190
  is_custom_hook: isCustomHook,
186
191
  is_convention_policy: isConventionPolicy,
192
+ convention_scope: conventionScope,
187
193
  has_custom_params: hasCustomParams,
188
194
  param_keys_overridden: paramKeysOverridden,
189
195
  });
@@ -267,7 +267,9 @@ export async function installHooks(
267
267
  }
268
268
 
269
269
  for (const eventType of HOOK_EVENT_TYPES) {
270
- const command = `"${binaryPath}" --hook ${eventType}`;
270
+ const command = scope === "project"
271
+ ? `npx -y failproofai --hook ${eventType}`
272
+ : `"${binaryPath}" --hook ${eventType}`;
271
273
  const hookEntry: ClaudeHookEntry = {
272
274
  type: "command",
273
275
  command,
@@ -323,6 +325,7 @@ export async function installHooks(
323
325
  has_custom_hooks_path: !!(configToWrite.customPoliciesPath),
324
326
  has_policy_params: !!(configToWrite.policyParams && Object.keys(configToWrite.policyParams).length > 0),
325
327
  param_policy_names: configToWrite.policyParams ? Object.keys(configToWrite.policyParams) : [],
328
+ command_format: scope === "project" ? "npx" : "absolute",
326
329
  });
327
330
  } catch {
328
331
  // Telemetry is best-effort — never block the operation
@@ -330,7 +333,12 @@ export async function installHooks(
330
333
 
331
334
  console.log(`Failproof AI hooks installed for all ${HOOK_EVENT_TYPES.length} event types (scope: ${scope}).`);
332
335
  console.log(`Settings: ${settingsPath}`);
333
- console.log(`Binary: ${binaryPath}`);
336
+ if (scope === "project") {
337
+ console.log(`Command: npx -y failproofai`);
338
+ console.log(`\nThis file can be committed to git — no machine-specific paths.`);
339
+ } else {
340
+ console.log(`Binary: ${binaryPath}`);
341
+ }
334
342
 
335
343
  // Warn about duplicate-scope installations
336
344
  const otherScopes = deduplicateScopes(HOOK_SCOPES, cwd).filter((s) => s !== scope);
@@ -56,9 +56,8 @@ export async function evaluatePolicies(
56
56
  session,
57
57
  };
58
58
 
59
- // Track the first instruct result (accumulated, does not short-circuit)
60
- let instructPolicyName: string | null = null;
61
- let instructReason: string | null = null;
59
+ // Track all instruct results (accumulated, does not short-circuit)
60
+ const instructEntries: Array<{ policyName: string; reason: string }> = [];
62
61
 
63
62
  // Track informational messages from allow decisions (with policy attribution)
64
63
  const allowEntries: Array<{ policyName: string; reason: string }> = [];
@@ -142,14 +141,14 @@ export async function evaluatePolicies(
142
141
  };
143
142
  }
144
143
 
145
- // Accumulate first instruct (does not short-circuit — later policies can still deny)
146
- if (result.decision === "instruct" && !instructPolicyName) {
147
- instructPolicyName = policy.name;
148
- instructReason = appendHint(
144
+ // Accumulate all instruct results (does not short-circuit — later policies can still deny)
145
+ if (result.decision === "instruct") {
146
+ const reason = appendHint(
149
147
  result.reason ?? `Instruction from policy: ${policy.name}`,
150
148
  config?.policyParams?.[policy.name]?.hint,
151
149
  );
152
- hookLogInfo(`instruct by "${policy.name}": ${instructReason}`);
150
+ instructEntries.push({ policyName: policy.name, reason });
151
+ hookLogInfo(`instruct by "${policy.name}": ${reason}`);
153
152
  }
154
153
 
155
154
  // Accumulate informational messages from allow decisions
@@ -158,17 +157,21 @@ export async function evaluatePolicies(
158
157
  }
159
158
  }
160
159
 
161
- // No deny — check if we accumulated an instruct
162
- if (instructPolicyName && instructReason) {
160
+ // No deny — check if we accumulated any instructs
161
+ if (instructEntries.length > 0) {
162
+ const combined = instructEntries.map((e) => e.reason).join("\n");
163
+ const policyNames = instructEntries.map((e) => e.policyName);
164
+
163
165
  if (eventType === "Stop") {
164
166
  // Stop hook: exitCode 2 blocks Claude from stopping.
165
167
  // Reason goes to stderr so Claude Code receives it as context.
166
168
  return {
167
169
  exitCode: 2,
168
170
  stdout: "",
169
- stderr: instructReason,
170
- policyName: instructPolicyName,
171
- reason: instructReason,
171
+ stderr: combined,
172
+ policyName: policyNames[0],
173
+ policyNames,
174
+ reason: combined,
172
175
  decision: "instruct",
173
176
  };
174
177
  }
@@ -176,15 +179,16 @@ export async function evaluatePolicies(
176
179
  const response = {
177
180
  hookSpecificOutput: {
178
181
  hookEventName: eventType,
179
- additionalContext: `Instruction from failproofai: ${instructReason}`,
182
+ additionalContext: `Instruction from failproofai: ${combined}`,
180
183
  },
181
184
  };
182
185
  return {
183
186
  exitCode: 0,
184
187
  stdout: JSON.stringify(response),
185
188
  stderr: "",
186
- policyName: instructPolicyName,
187
- reason: instructReason,
189
+ policyName: policyNames[0],
190
+ policyNames,
191
+ reason: combined,
188
192
  decision: "instruct",
189
193
  };
190
194
  }
package/README.md CHANGED
@@ -15,6 +15,8 @@
15
15
  [![CI](https://img.shields.io/github/actions/workflow/status/exospherehost/failproofai/ci.yml?branch=main&style=flat-square&label=CI)](https://github.com/exospherehost/failproofai/actions)
16
16
  [![Slack](https://img.shields.io/badge/Slack-join%20us-4A154B?style=flat-square&logo=slack)](https://join.slack.com/t/failproofai/shared_invite/zt-3v63b7k5e-O3NBHmj8X6n9gZSGDx6ggQ)
17
17
 
18
+ **Translations**: [简体中文](docs/i18n/README.zh.md) | [日本語](docs/i18n/README.ja.md) | [한국어](docs/i18n/README.ko.md) | [Español](docs/i18n/README.es.md) | [Português](docs/i18n/README.pt-br.md) | [Deutsch](docs/i18n/README.de.md) | [Français](docs/i18n/README.fr.md) | [Русский](docs/i18n/README.ru.md) | [हिन्दी](docs/i18n/README.hi.md) | [Türkçe](docs/i18n/README.tr.md) | [Tiếng Việt](docs/i18n/README.vi.md) | [Italiano](docs/i18n/README.it.md) | [العربية](docs/i18n/README.ar.md) | [עברית](docs/i18n/README.he.md)
19
+
18
20
  The easiest way to manage policies that keep your AI agents reliable, on-task, and running autonomously - for **Claude Code** & the **Agents SDK**.
19
21
 
20
22
  - **30 Built-in Policies** - Catch common agent failure modes out of the box. Block destructive commands, prevent secret leakage, keep agents inside project boundaries, detect loops, and more.
@@ -274,6 +276,16 @@ docker run --rm -p 3000:3000 -v $(pwd)/docs:/app/docs failproofai-docs
274
276
 
275
277
  ---
276
278
 
279
+ ## Note for failproofai contributors
280
+
281
+ This repo's `.claude/settings.json` uses `bun ./bin/failproofai.mjs --hook <EventType>` instead of the standard `npx -y failproofai` command. This is because running `npx -y failproofai` inside the failproofai project itself creates a self-referencing conflict.
282
+
283
+ For all other repos, the recommended approach is `npx -y failproofai`, installed via:
284
+
285
+ ```bash
286
+ failproofai policies --install --scope project
287
+ ```
288
+
277
289
  ## Contributing
278
290
 
279
291
  See [CONTRIBUTING.md](CONTRIBUTING.md).
@@ -283,3 +295,7 @@ See [CONTRIBUTING.md](CONTRIBUTING.md).
283
295
  ## License
284
296
 
285
297
  See [LICENSE](LICENSE).
298
+
299
+ ---
300
+
301
+ Built and Maintained by **ExosphereHost: Reliability Research Lab for Your Agents**. We help enterprises and startups improve the reliability of their AI agents through our own agents, software, and expertise. Learn more at [exosphere.host](https://exosphere.host).
package/dist/cli.mjs CHANGED
@@ -1402,8 +1402,7 @@ async function evaluatePolicies(eventType, payload, session, config) {
1402
1402
  toolInput,
1403
1403
  session
1404
1404
  };
1405
- let instructPolicyName = null;
1406
- let instructReason = null;
1405
+ const instructEntries = [];
1407
1406
  const allowEntries = [];
1408
1407
  for (const policy of policies) {
1409
1408
  const schema = POLICY_PARAMS_MAP.get(policy.name);
@@ -1471,38 +1470,43 @@ async function evaluatePolicies(eventType, payload, session, config) {
1471
1470
  decision: "deny"
1472
1471
  };
1473
1472
  }
1474
- if (result.decision === "instruct" && !instructPolicyName) {
1475
- instructPolicyName = policy.name;
1476
- instructReason = appendHint(result.reason ?? `Instruction from policy: ${policy.name}`, config?.policyParams?.[policy.name]?.hint);
1477
- hookLogInfo(`instruct by "${policy.name}": ${instructReason}`);
1473
+ if (result.decision === "instruct") {
1474
+ const reason = appendHint(result.reason ?? `Instruction from policy: ${policy.name}`, config?.policyParams?.[policy.name]?.hint);
1475
+ instructEntries.push({ policyName: policy.name, reason });
1476
+ hookLogInfo(`instruct by "${policy.name}": ${reason}`);
1478
1477
  }
1479
1478
  if (result.decision === "allow" && result.reason) {
1480
1479
  allowEntries.push({ policyName: policy.name, reason: result.reason });
1481
1480
  }
1482
1481
  }
1483
- if (instructPolicyName && instructReason) {
1482
+ if (instructEntries.length > 0) {
1483
+ const combined = instructEntries.map((e) => e.reason).join(`
1484
+ `);
1485
+ const policyNames = instructEntries.map((e) => e.policyName);
1484
1486
  if (eventType === "Stop") {
1485
1487
  return {
1486
1488
  exitCode: 2,
1487
1489
  stdout: "",
1488
- stderr: instructReason,
1489
- policyName: instructPolicyName,
1490
- reason: instructReason,
1490
+ stderr: combined,
1491
+ policyName: policyNames[0],
1492
+ policyNames,
1493
+ reason: combined,
1491
1494
  decision: "instruct"
1492
1495
  };
1493
1496
  }
1494
1497
  const response = {
1495
1498
  hookSpecificOutput: {
1496
1499
  hookEventName: eventType,
1497
- additionalContext: `Instruction from failproofai: ${instructReason}`
1500
+ additionalContext: `Instruction from failproofai: ${combined}`
1498
1501
  }
1499
1502
  };
1500
1503
  return {
1501
1504
  exitCode: 0,
1502
1505
  stdout: JSON.stringify(response),
1503
1506
  stderr: "",
1504
- policyName: instructPolicyName,
1505
- reason: instructReason,
1507
+ policyName: policyNames[0],
1508
+ policyNames,
1509
+ reason: combined,
1506
1510
  decision: "instruct"
1507
1511
  };
1508
1512
  }
@@ -1762,13 +1766,19 @@ async function loadAllCustomHooks(customPoliciesPath, opts) {
1762
1766
  if (projectFiles.length > 0 || userFiles.length > 0) {
1763
1767
  hookLogInfo(`convention policies: ${projectFiles.length} project file(s), ${userFiles.length} user file(s), ${conventionCount} hook(s)`);
1764
1768
  }
1769
+ const hookNameToScope = new Map;
1770
+ for (const source of conventionSources) {
1771
+ for (const name of source.hookNames) {
1772
+ hookNameToScope.set(name, source.scope);
1773
+ }
1774
+ }
1765
1775
  const conventionHookRefs = new Set;
1766
1776
  for (const hook of allHooks.slice(hooksBeforeConvention)) {
1767
1777
  conventionHookRefs.add(hook);
1768
1778
  }
1769
1779
  for (const hook of allHooks) {
1770
1780
  if (conventionHookRefs.has(hook)) {
1771
- hook.__conventionSource = true;
1781
+ hook.__conventionScope = hookNameToScope.get(hook.name) ?? "project";
1772
1782
  }
1773
1783
  }
1774
1784
  return { hooks: allHooks, conventionSources };
@@ -1904,7 +1914,7 @@ var init_hook_activity_store = __esm(() => {
1904
1914
  });
1905
1915
 
1906
1916
  // package.json
1907
- var version2 = "0.0.2-beta.7";
1917
+ var version2 = "0.0.2-beta.9";
1908
1918
  var init_package = () => {};
1909
1919
 
1910
1920
  // src/posthog-key.ts
@@ -2071,8 +2081,9 @@ async function handleHookEvent(eventType) {
2071
2081
  const conventionHookNames = new Set(loadResult.conventionSources.flatMap((s) => s.hookNames));
2072
2082
  for (const hook of customHooksList) {
2073
2083
  const hookName = hook.name;
2074
- const isConvention = hook.__conventionSource === true;
2075
- const prefix = isConvention ? "convention" : "custom";
2084
+ const conventionScope = hook.__conventionScope;
2085
+ const isConvention = !!conventionScope;
2086
+ const prefix = isConvention ? `.failproofai-${conventionScope}` : "custom";
2076
2087
  const fn = async (ctx) => {
2077
2088
  try {
2078
2089
  const result2 = await Promise.race([
@@ -2088,7 +2099,8 @@ async function handleHookEvent(eventType) {
2088
2099
  hook_name: hookName,
2089
2100
  error_type: isTimeout ? "timeout" : "exception",
2090
2101
  event_type: eventType,
2091
- is_convention_policy: isConvention
2102
+ is_convention_policy: isConvention,
2103
+ convention_scope: conventionScope ?? null
2092
2104
  });
2093
2105
  return { decision: "allow" };
2094
2106
  }
@@ -2143,7 +2155,8 @@ async function handleHookEvent(eventType) {
2143
2155
  if (result.decision === "deny" || result.decision === "instruct") {
2144
2156
  try {
2145
2157
  const isCustomHook = result.policyName?.startsWith("custom/") ?? false;
2146
- const isConventionPolicy = result.policyName?.startsWith("convention/") ?? false;
2158
+ const isConventionPolicy = result.policyName?.startsWith(".failproofai-") ?? false;
2159
+ const conventionScope = isConventionPolicy ? result.policyName.match(/^\.failproofai-(project|user)\//)?.[1] ?? null : null;
2147
2160
  const hasCustomParams = !isCustomHook && !isConventionPolicy && !!(result.policyName && config.policyParams?.[result.policyName]);
2148
2161
  const paramKeysOverridden = hasCustomParams ? Object.keys(config.policyParams[result.policyName]) : [];
2149
2162
  const distinctId = getInstanceId();
@@ -2154,6 +2167,7 @@ async function handleHookEvent(eventType) {
2154
2167
  decision: result.decision,
2155
2168
  is_custom_hook: isCustomHook,
2156
2169
  is_convention_policy: isConventionPolicy,
2170
+ convention_scope: conventionScope,
2157
2171
  has_custom_params: hasCustomParams,
2158
2172
  param_keys_overridden: paramKeysOverridden
2159
2173
  });
@@ -2667,7 +2681,7 @@ Enabled ${selectedPolicies.length} policy(ies): ${selectedPolicies.join(", ")}`)
2667
2681
  settings.hooks = {};
2668
2682
  }
2669
2683
  for (const eventType of HOOK_EVENT_TYPES) {
2670
- const command = `"${binaryPath}" --hook ${eventType}`;
2684
+ const command = scope === "project" ? `npx -y failproofai --hook ${eventType}` : `"${binaryPath}" --hook ${eventType}`;
2671
2685
  const hookEntry = {
2672
2686
  type: "command",
2673
2687
  command,
@@ -2712,12 +2726,19 @@ Enabled ${selectedPolicies.length} policy(ies): ${selectedPolicies.join(", ")}`)
2712
2726
  hostname_hash: hashToId(hostname()),
2713
2727
  has_custom_hooks_path: !!configToWrite.customPoliciesPath,
2714
2728
  has_policy_params: !!(configToWrite.policyParams && Object.keys(configToWrite.policyParams).length > 0),
2715
- param_policy_names: configToWrite.policyParams ? Object.keys(configToWrite.policyParams) : []
2729
+ param_policy_names: configToWrite.policyParams ? Object.keys(configToWrite.policyParams) : [],
2730
+ command_format: scope === "project" ? "npx" : "absolute"
2716
2731
  });
2717
2732
  } catch {}
2718
2733
  console.log(`Failproof AI hooks installed for all ${HOOK_EVENT_TYPES.length} event types (scope: ${scope}).`);
2719
2734
  console.log(`Settings: ${settingsPath}`);
2720
- console.log(`Binary: ${binaryPath}`);
2735
+ if (scope === "project") {
2736
+ console.log(`Command: npx -y failproofai`);
2737
+ console.log(`
2738
+ This file can be committed to git — no machine-specific paths.`);
2739
+ } else {
2740
+ console.log(`Binary: ${binaryPath}`);
2741
+ }
2721
2742
  const otherScopes = deduplicateScopes(HOOK_SCOPES, cwd).filter((s) => s !== scope);
2722
2743
  const duplicates = otherScopes.filter((s) => hooksInstalledInSettings(s, cwd));
2723
2744
  if (duplicates.length > 0) {
@@ -3185,7 +3206,7 @@ import { realpathSync as realpathSync2 } from "fs";
3185
3206
  import { dirname as dirname5, resolve as resolve8 } from "path";
3186
3207
  import { fileURLToPath as fileURLToPath2 } from "url";
3187
3208
  // package.json
3188
- var version = "0.0.2-beta.7";
3209
+ var version = "0.0.2-beta.9";
3189
3210
 
3190
3211
  // bin/failproofai.mjs
3191
3212
  if (!process.env.FAILPROOFAI_PACKAGE_ROOT) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "failproofai",
3
- "version": "0.0.2-beta.7",
3
+ "version": "0.0.2-beta.9",
4
4
  "description": "The easiest way to manage policies that keep your AI agents reliable, on-task, and running autonomously — for Claude Code & the Agents SDK",
5
5
  "bin": {
6
6
  "failproofai": "./dist/cli.mjs"
@@ -32,7 +32,12 @@
32
32
  "preuninstall": "node scripts/preuninstall.mjs",
33
33
  "prepare": "bun run build",
34
34
  "test:e2e": "vitest run --config vitest.config.e2e.mts",
35
- "test:e2e:watch": "vitest --config vitest.config.e2e.mts"
35
+ "test:e2e:watch": "vitest --config vitest.config.e2e.mts",
36
+ "translate": "bun scripts/translate-docs/cli.ts",
37
+ "translate:readme": "bun scripts/translate-docs/cli.ts --readme-only",
38
+ "translate:docs": "bun scripts/translate-docs/cli.ts --docs-only",
39
+ "translate:dry-run": "bun scripts/translate-docs/cli.ts --dry-run",
40
+ "translate:validate": "bun scripts/translate-docs/cli.ts --validate"
36
41
  },
37
42
  "keywords": [
38
43
  "claude",
@@ -85,6 +90,7 @@
85
90
  "tailwind-merge": "^3.4.0",
86
91
  "tailwindcss": "^4.1.18",
87
92
  "typescript": "^6.0.2",
93
+ "@anthropic-ai/sdk": "^0.39.0",
88
94
  "vitest": "^4.0.18"
89
95
  },
90
96
  "dependencies": {
@@ -0,0 +1,62 @@
1
+ import { createHash } from "node:crypto";
2
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
3
+ import { dirname, join } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import type { CacheEntry, TranslationCache } from "./types";
6
+
7
+ const __dirname = dirname(fileURLToPath(import.meta.url));
8
+ const CACHE_FILE = join(__dirname, ".translation-cache.json");
9
+
10
+ export function contentHash(content: string): string {
11
+ return createHash("sha256").update(content).digest("hex").slice(0, 16);
12
+ }
13
+
14
+ export function readCache(): TranslationCache {
15
+ if (!existsSync(CACHE_FILE)) {
16
+ return { sourceHash: "", lastUpdated: "", translations: {} };
17
+ }
18
+ try {
19
+ return JSON.parse(readFileSync(CACHE_FILE, "utf-8"));
20
+ } catch {
21
+ return { sourceHash: "", lastUpdated: "", translations: {} };
22
+ }
23
+ }
24
+
25
+ export function writeCache(cache: TranslationCache): void {
26
+ cache.lastUpdated = new Date().toISOString();
27
+ writeFileSync(CACHE_FILE, JSON.stringify(cache, null, 2));
28
+ }
29
+
30
+ export function getCacheKey(sourcePath: string, lang: string): string {
31
+ return `${sourcePath}::${lang}`;
32
+ }
33
+
34
+ export function isCached(
35
+ cache: TranslationCache,
36
+ sourcePath: string,
37
+ lang: string,
38
+ sourceContent: string,
39
+ ): boolean {
40
+ const key = getCacheKey(sourcePath, lang);
41
+ const entry = cache.translations[key];
42
+ if (!entry) return false;
43
+ return entry.sourceHash === contentHash(sourceContent);
44
+ }
45
+
46
+ export function setCacheEntry(
47
+ cache: TranslationCache,
48
+ sourcePath: string,
49
+ lang: string,
50
+ sourceContent: string,
51
+ inputTokens: number,
52
+ outputTokens: number,
53
+ ): void {
54
+ const key = getCacheKey(sourcePath, lang);
55
+ cache.translations[key] = {
56
+ sourceHash: contentHash(sourceContent),
57
+ targetLang: lang,
58
+ translatedAt: new Date().toISOString(),
59
+ inputTokens,
60
+ outputTokens,
61
+ };
62
+ }