failproofai 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/standalone/.claude/settings.json +316 -0
- package/.next/standalone/.failproofai/policies/workflow-policies.mjs +62 -0
- package/.next/standalone/.failproofai/policies-config.json +39 -0
- package/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/build-manifest.json +5 -5
- package/.next/standalone/.next/prerender-manifest.json +3 -3
- package/.next/standalone/.next/required-server-files.json +3 -1
- package/.next/standalone/.next/server/app/_global-error/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_global-error.html +1 -1
- package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
- package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
- package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +3 -3
- package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +3 -3
- package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +2 -2
- package/.next/standalone/.next/server/app/_not-found.rsc +17 -17
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +17 -17
- package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
- package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +11 -11
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
- package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/index.html +1 -1
- package/.next/standalone/.next/server/app/index.rsc +16 -16
- package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +16 -16
- package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +4 -4
- package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +11 -11
- package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/policies/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +8 -8
- package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/projects/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0g72weg._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0kjo7d_._.js +1 -1
- package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_05pz9._._.js +1 -1
- package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_0z7w.hh._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__12kr5~_._.js → [root-of-the-server]__03kiqd5._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__092s1ta._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__09icjsf._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0qo8503._.js → [root-of-the-server]__0bo8s~-._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0g.lg8b._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0h..k-e._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0okos0k._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0w6l33k._.js +9 -9
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__11pa2ra._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__12t-wym._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_10lm7or._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_0xerkr6._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_0q-m0y-._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0a_7sdg.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0ef3uwk.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0j79~gv.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0pbja1x.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0r6o0i2.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_11y81~_.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_12or2kf.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/node_modules_posthog-node_dist_entrypoints_index_node_mjs_0mebn66._.js +1 -1
- package/.next/standalone/.next/server/middleware-build-manifest.js +5 -5
- package/.next/standalone/.next/server/pages/404.html +2 -2
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +9 -9
- package/.next/standalone/.next/static/chunks/{0x-625~1vx1lu.js → 02t9.s735hqyq.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0ov60i6md~37t.js → 03oepxbqx6o8~.js} +2 -2
- package/.next/standalone/.next/static/chunks/{031pa5~qfzt~_.js → 09e7drilkf1sn.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0y~0creqvl5wx.js → 0cwft44dh9bww.js} +1 -1
- package/.next/standalone/.next/static/chunks/{06og.7e9nkpjh.js → 0e2uz2g026ckb.js} +1 -1
- package/.next/standalone/.next/static/chunks/0gu_a.a80ritd.css +1 -0
- package/.next/standalone/.next/static/chunks/{15wf7x-e.8ia3.js → 0h5kbvg~.xf.v.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0_4y_t03jn2nq.js → 0od..umlku4bb.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0cvffh-pbsv5u.js → 0xbwzy4dl87-0.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0c_ljlxa._4lc.js → 18cl6wups7ouq.js} +2 -2
- package/.next/standalone/.next/static/chunks/{turbopack-0uc5y~g6h.n7-.js → turbopack-0r26pc8h0y_-e.js} +1 -1
- package/.next/standalone/CHANGELOG.md +103 -0
- package/.next/standalone/CLAUDE.md +28 -0
- package/.next/standalone/Dockerfile.docs +12 -0
- package/.next/standalone/README.md +95 -49
- package/.next/standalone/app/components/session-hooks-panel.tsx +14 -1
- package/.next/standalone/app/policies/hooks-client.tsx +14 -1
- package/.next/standalone/bin/failproofai.mjs +5 -0
- package/.next/standalone/bun.lock +76 -63
- package/.next/standalone/components/navbar.tsx +5 -0
- package/.next/standalone/dist/cli.mjs +539 -90
- package/.next/standalone/dist/index.js +2 -2
- package/.next/standalone/docs/ar/architecture.mdx +333 -0
- package/.next/standalone/docs/ar/built-in-policies.mdx +566 -0
- package/.next/standalone/docs/ar/cli/dashboard.mdx +28 -0
- package/.next/standalone/docs/ar/cli/environment-variables.mdx +34 -0
- package/.next/standalone/docs/ar/cli/hook.mdx +31 -0
- package/.next/standalone/docs/ar/cli/install-policies.mdx +49 -0
- package/.next/standalone/docs/ar/cli/list-policies.mdx +31 -0
- package/.next/standalone/docs/ar/cli/remove-policies.mdx +45 -0
- package/.next/standalone/docs/ar/cli/version.mdx +13 -0
- package/.next/standalone/docs/ar/configuration.mdx +223 -0
- package/.next/standalone/docs/ar/custom-policies.mdx +359 -0
- package/.next/standalone/docs/ar/dashboard.mdx +142 -0
- package/.next/standalone/docs/ar/examples.mdx +254 -0
- package/.next/standalone/docs/ar/for-agents.mdx +39 -0
- package/.next/standalone/docs/ar/getting-started.mdx +134 -0
- package/.next/standalone/docs/ar/introduction.mdx +58 -0
- package/.next/standalone/docs/ar/package-aliases.mdx +82 -0
- package/.next/standalone/docs/ar/testing.mdx +261 -0
- package/.next/standalone/docs/{architecture.md → architecture.mdx} +40 -23
- package/.next/standalone/docs/{built-in-policies.md → built-in-policies.mdx} +151 -13
- package/.next/standalone/docs/cli/dashboard.mdx +28 -0
- package/.next/standalone/docs/cli/environment-variables.mdx +34 -0
- package/.next/standalone/docs/cli/hook.mdx +30 -0
- package/.next/standalone/docs/cli/install-policies.mdx +48 -0
- package/.next/standalone/docs/cli/list-policies.mdx +31 -0
- package/.next/standalone/docs/cli/remove-policies.mdx +44 -0
- package/.next/standalone/docs/cli/version.mdx +12 -0
- package/.next/standalone/docs/{configuration.md → configuration.mdx} +62 -16
- package/.next/standalone/docs/custom-policies.mdx +357 -0
- package/.next/standalone/docs/{dashboard.md → dashboard.mdx} +26 -29
- package/.next/standalone/docs/de/architecture.mdx +332 -0
- package/.next/standalone/docs/de/built-in-policies.mdx +564 -0
- package/.next/standalone/docs/de/cli/dashboard.mdx +28 -0
- package/.next/standalone/docs/de/cli/environment-variables.mdx +34 -0
- package/.next/standalone/docs/de/cli/hook.mdx +30 -0
- package/.next/standalone/docs/de/cli/install-policies.mdx +48 -0
- package/.next/standalone/docs/de/cli/list-policies.mdx +31 -0
- package/.next/standalone/docs/de/cli/remove-policies.mdx +44 -0
- package/.next/standalone/docs/de/cli/version.mdx +12 -0
- package/.next/standalone/docs/de/configuration.mdx +222 -0
- package/.next/standalone/docs/de/custom-policies.mdx +357 -0
- package/.next/standalone/docs/de/dashboard.mdx +142 -0
- package/.next/standalone/docs/de/examples.mdx +253 -0
- package/.next/standalone/docs/de/for-agents.mdx +38 -0
- package/.next/standalone/docs/de/getting-started.mdx +134 -0
- package/.next/standalone/docs/de/introduction.mdx +57 -0
- package/.next/standalone/docs/de/package-aliases.mdx +82 -0
- package/.next/standalone/docs/de/testing.mdx +260 -0
- package/.next/standalone/docs/docs.json +938 -24
- package/.next/standalone/docs/es/architecture.mdx +332 -0
- package/.next/standalone/docs/es/built-in-policies.mdx +564 -0
- package/.next/standalone/docs/es/cli/dashboard.mdx +28 -0
- package/.next/standalone/docs/es/cli/environment-variables.mdx +34 -0
- package/.next/standalone/docs/es/cli/hook.mdx +30 -0
- package/.next/standalone/docs/es/cli/install-policies.mdx +48 -0
- package/.next/standalone/docs/es/cli/list-policies.mdx +31 -0
- package/.next/standalone/docs/es/cli/remove-policies.mdx +44 -0
- package/.next/standalone/docs/es/cli/version.mdx +12 -0
- package/.next/standalone/docs/es/configuration.mdx +222 -0
- package/.next/standalone/docs/es/custom-policies.mdx +357 -0
- package/.next/standalone/docs/es/dashboard.mdx +142 -0
- package/.next/standalone/docs/es/examples.mdx +253 -0
- package/.next/standalone/docs/es/for-agents.mdx +38 -0
- package/.next/standalone/docs/es/getting-started.mdx +134 -0
- package/.next/standalone/docs/es/introduction.mdx +57 -0
- package/.next/standalone/docs/es/package-aliases.mdx +82 -0
- package/.next/standalone/docs/es/testing.mdx +260 -0
- package/.next/standalone/docs/examples.mdx +253 -0
- package/.next/standalone/docs/for-agents.mdx +38 -0
- package/.next/standalone/docs/fr/architecture.mdx +332 -0
- package/.next/standalone/docs/fr/built-in-policies.mdx +564 -0
- package/.next/standalone/docs/fr/cli/dashboard.mdx +28 -0
- package/.next/standalone/docs/fr/cli/environment-variables.mdx +34 -0
- package/.next/standalone/docs/fr/cli/hook.mdx +30 -0
- package/.next/standalone/docs/fr/cli/install-policies.mdx +48 -0
- package/.next/standalone/docs/fr/cli/list-policies.mdx +31 -0
- package/.next/standalone/docs/fr/cli/remove-policies.mdx +44 -0
- package/.next/standalone/docs/fr/cli/version.mdx +12 -0
- package/.next/standalone/docs/fr/configuration.mdx +222 -0
- package/.next/standalone/docs/fr/custom-policies.mdx +357 -0
- package/.next/standalone/docs/fr/dashboard.mdx +142 -0
- package/.next/standalone/docs/fr/examples.mdx +253 -0
- package/.next/standalone/docs/fr/for-agents.mdx +38 -0
- package/.next/standalone/docs/fr/getting-started.mdx +134 -0
- package/.next/standalone/docs/fr/introduction.mdx +57 -0
- package/.next/standalone/docs/fr/package-aliases.mdx +82 -0
- package/.next/standalone/docs/fr/testing.mdx +260 -0
- package/.next/standalone/docs/getting-started.mdx +134 -0
- package/.next/standalone/docs/he/architecture.mdx +333 -0
- package/.next/standalone/docs/he/built-in-policies.mdx +564 -0
- package/.next/standalone/docs/he/cli/dashboard.mdx +28 -0
- package/.next/standalone/docs/he/cli/environment-variables.mdx +34 -0
- package/.next/standalone/docs/he/cli/hook.mdx +30 -0
- package/.next/standalone/docs/he/cli/install-policies.mdx +48 -0
- package/.next/standalone/docs/he/cli/list-policies.mdx +32 -0
- package/.next/standalone/docs/he/cli/remove-policies.mdx +44 -0
- package/.next/standalone/docs/he/cli/version.mdx +12 -0
- package/.next/standalone/docs/he/configuration.mdx +222 -0
- package/.next/standalone/docs/he/custom-policies.mdx +357 -0
- package/.next/standalone/docs/he/dashboard.mdx +142 -0
- package/.next/standalone/docs/he/examples.mdx +253 -0
- package/.next/standalone/docs/he/for-agents.mdx +38 -0
- package/.next/standalone/docs/he/getting-started.mdx +135 -0
- package/.next/standalone/docs/he/introduction.mdx +57 -0
- package/.next/standalone/docs/he/package-aliases.mdx +82 -0
- package/.next/standalone/docs/he/testing.mdx +260 -0
- package/.next/standalone/docs/hi/architecture.mdx +334 -0
- package/.next/standalone/docs/hi/built-in-policies.mdx +564 -0
- package/.next/standalone/docs/hi/cli/dashboard.mdx +28 -0
- package/.next/standalone/docs/hi/cli/environment-variables.mdx +34 -0
- package/.next/standalone/docs/hi/cli/hook.mdx +30 -0
- package/.next/standalone/docs/hi/cli/install-policies.mdx +48 -0
- package/.next/standalone/docs/hi/cli/list-policies.mdx +31 -0
- package/.next/standalone/docs/hi/cli/remove-policies.mdx +44 -0
- package/.next/standalone/docs/hi/cli/version.mdx +12 -0
- package/.next/standalone/docs/hi/configuration.mdx +222 -0
- package/.next/standalone/docs/hi/custom-policies.mdx +357 -0
- package/.next/standalone/docs/hi/dashboard.mdx +142 -0
- package/.next/standalone/docs/hi/examples.mdx +255 -0
- package/.next/standalone/docs/hi/for-agents.mdx +38 -0
- package/.next/standalone/docs/hi/getting-started.mdx +134 -0
- package/.next/standalone/docs/hi/introduction.mdx +57 -0
- package/.next/standalone/docs/hi/package-aliases.mdx +82 -0
- package/.next/standalone/docs/hi/testing.mdx +260 -0
- package/.next/standalone/docs/i18n/README.ar.md +312 -0
- package/.next/standalone/docs/i18n/README.de.md +307 -0
- package/.next/standalone/docs/i18n/README.es.md +307 -0
- package/.next/standalone/docs/i18n/README.fr.md +307 -0
- package/.next/standalone/docs/i18n/README.he.md +312 -0
- package/.next/standalone/docs/i18n/README.hi.md +307 -0
- package/.next/standalone/docs/i18n/README.it.md +307 -0
- package/.next/standalone/docs/i18n/README.ja.md +307 -0
- package/.next/standalone/docs/i18n/README.ko.md +307 -0
- package/.next/standalone/docs/i18n/README.pt-br.md +307 -0
- package/.next/standalone/docs/i18n/README.ru.md +308 -0
- package/.next/standalone/docs/i18n/README.tr.md +308 -0
- package/.next/standalone/docs/i18n/README.vi.md +308 -0
- package/.next/standalone/docs/i18n/README.zh.md +307 -0
- package/.next/standalone/docs/introduction.mdx +57 -0
- package/.next/standalone/docs/it/architecture.mdx +333 -0
- package/.next/standalone/docs/it/built-in-policies.mdx +564 -0
- package/.next/standalone/docs/it/cli/dashboard.mdx +28 -0
- package/.next/standalone/docs/it/cli/environment-variables.mdx +34 -0
- package/.next/standalone/docs/it/cli/hook.mdx +30 -0
- package/.next/standalone/docs/it/cli/install-policies.mdx +48 -0
- package/.next/standalone/docs/it/cli/list-policies.mdx +31 -0
- package/.next/standalone/docs/it/cli/remove-policies.mdx +44 -0
- package/.next/standalone/docs/it/cli/version.mdx +12 -0
- package/.next/standalone/docs/it/configuration.mdx +223 -0
- package/.next/standalone/docs/it/custom-policies.mdx +358 -0
- package/.next/standalone/docs/it/dashboard.mdx +142 -0
- package/.next/standalone/docs/it/examples.mdx +253 -0
- package/.next/standalone/docs/it/for-agents.mdx +38 -0
- package/.next/standalone/docs/it/getting-started.mdx +134 -0
- package/.next/standalone/docs/it/introduction.mdx +57 -0
- package/.next/standalone/docs/it/package-aliases.mdx +82 -0
- package/.next/standalone/docs/it/testing.mdx +260 -0
- package/.next/standalone/docs/ja/architecture.mdx +332 -0
- package/.next/standalone/docs/ja/built-in-policies.mdx +562 -0
- package/.next/standalone/docs/ja/cli/dashboard.mdx +28 -0
- package/.next/standalone/docs/ja/cli/environment-variables.mdx +34 -0
- package/.next/standalone/docs/ja/cli/hook.mdx +30 -0
- package/.next/standalone/docs/ja/cli/install-policies.mdx +48 -0
- package/.next/standalone/docs/ja/cli/list-policies.mdx +31 -0
- package/.next/standalone/docs/ja/cli/remove-policies.mdx +44 -0
- package/.next/standalone/docs/ja/cli/version.mdx +12 -0
- package/.next/standalone/docs/ja/configuration.mdx +222 -0
- package/.next/standalone/docs/ja/custom-policies.mdx +357 -0
- package/.next/standalone/docs/ja/dashboard.mdx +142 -0
- package/.next/standalone/docs/ja/examples.mdx +253 -0
- package/.next/standalone/docs/ja/for-agents.mdx +38 -0
- package/.next/standalone/docs/ja/getting-started.mdx +134 -0
- package/.next/standalone/docs/ja/introduction.mdx +57 -0
- package/.next/standalone/docs/ja/package-aliases.mdx +82 -0
- package/.next/standalone/docs/ja/testing.mdx +260 -0
- package/.next/standalone/docs/ko/architecture.mdx +332 -0
- package/.next/standalone/docs/ko/built-in-policies.mdx +562 -0
- package/.next/standalone/docs/ko/cli/dashboard.mdx +28 -0
- package/.next/standalone/docs/ko/cli/environment-variables.mdx +34 -0
- package/.next/standalone/docs/ko/cli/hook.mdx +30 -0
- package/.next/standalone/docs/ko/cli/install-policies.mdx +48 -0
- package/.next/standalone/docs/ko/cli/list-policies.mdx +31 -0
- package/.next/standalone/docs/ko/cli/remove-policies.mdx +44 -0
- package/.next/standalone/docs/ko/cli/version.mdx +12 -0
- package/.next/standalone/docs/ko/configuration.mdx +222 -0
- package/.next/standalone/docs/ko/custom-policies.mdx +357 -0
- package/.next/standalone/docs/ko/dashboard.mdx +142 -0
- package/.next/standalone/docs/ko/examples.mdx +253 -0
- package/.next/standalone/docs/ko/for-agents.mdx +38 -0
- package/.next/standalone/docs/ko/getting-started.mdx +134 -0
- package/.next/standalone/docs/ko/introduction.mdx +57 -0
- package/.next/standalone/docs/ko/package-aliases.mdx +82 -0
- package/.next/standalone/docs/ko/testing.mdx +260 -0
- package/.next/standalone/docs/logo/dark.svg +21 -0
- package/.next/standalone/docs/logo/light.svg +21 -0
- package/.next/standalone/docs/{package-aliases.md → package-aliases.mdx} +5 -5
- package/.next/standalone/docs/pt-br/architecture.mdx +332 -0
- package/.next/standalone/docs/pt-br/built-in-policies.mdx +564 -0
- package/.next/standalone/docs/pt-br/cli/dashboard.mdx +28 -0
- package/.next/standalone/docs/pt-br/cli/environment-variables.mdx +34 -0
- package/.next/standalone/docs/pt-br/cli/hook.mdx +30 -0
- package/.next/standalone/docs/pt-br/cli/install-policies.mdx +48 -0
- package/.next/standalone/docs/pt-br/cli/list-policies.mdx +31 -0
- package/.next/standalone/docs/pt-br/cli/remove-policies.mdx +44 -0
- package/.next/standalone/docs/pt-br/cli/version.mdx +12 -0
- package/.next/standalone/docs/pt-br/configuration.mdx +222 -0
- package/.next/standalone/docs/pt-br/custom-policies.mdx +357 -0
- package/.next/standalone/docs/pt-br/dashboard.mdx +142 -0
- package/.next/standalone/docs/pt-br/examples.mdx +253 -0
- package/.next/standalone/docs/pt-br/for-agents.mdx +38 -0
- package/.next/standalone/docs/pt-br/getting-started.mdx +134 -0
- package/.next/standalone/docs/pt-br/introduction.mdx +57 -0
- package/.next/standalone/docs/pt-br/package-aliases.mdx +82 -0
- package/.next/standalone/docs/pt-br/testing.mdx +260 -0
- package/.next/standalone/docs/ru/architecture.mdx +334 -0
- package/.next/standalone/docs/ru/built-in-policies.mdx +562 -0
- package/.next/standalone/docs/ru/cli/dashboard.mdx +28 -0
- package/.next/standalone/docs/ru/cli/environment-variables.mdx +34 -0
- package/.next/standalone/docs/ru/cli/hook.mdx +30 -0
- package/.next/standalone/docs/ru/cli/install-policies.mdx +48 -0
- package/.next/standalone/docs/ru/cli/list-policies.mdx +32 -0
- package/.next/standalone/docs/ru/cli/remove-policies.mdx +44 -0
- package/.next/standalone/docs/ru/cli/version.mdx +12 -0
- package/.next/standalone/docs/ru/configuration.mdx +223 -0
- package/.next/standalone/docs/ru/custom-policies.mdx +357 -0
- package/.next/standalone/docs/ru/dashboard.mdx +142 -0
- package/.next/standalone/docs/ru/examples.mdx +254 -0
- package/.next/standalone/docs/ru/for-agents.mdx +38 -0
- package/.next/standalone/docs/ru/getting-started.mdx +134 -0
- package/.next/standalone/docs/ru/introduction.mdx +57 -0
- package/.next/standalone/docs/ru/package-aliases.mdx +82 -0
- package/.next/standalone/docs/ru/testing.mdx +260 -0
- package/.next/standalone/docs/{testing.md → testing.mdx} +11 -11
- package/.next/standalone/docs/tr/architecture.mdx +333 -0
- package/.next/standalone/docs/tr/built-in-policies.mdx +562 -0
- package/.next/standalone/docs/tr/cli/dashboard.mdx +28 -0
- package/.next/standalone/docs/tr/cli/environment-variables.mdx +34 -0
- package/.next/standalone/docs/tr/cli/hook.mdx +30 -0
- package/.next/standalone/docs/tr/cli/install-policies.mdx +48 -0
- package/.next/standalone/docs/tr/cli/list-policies.mdx +31 -0
- package/.next/standalone/docs/tr/cli/remove-policies.mdx +45 -0
- package/.next/standalone/docs/tr/cli/version.mdx +12 -0
- package/.next/standalone/docs/tr/configuration.mdx +223 -0
- package/.next/standalone/docs/tr/custom-policies.mdx +357 -0
- package/.next/standalone/docs/tr/dashboard.mdx +142 -0
- package/.next/standalone/docs/tr/examples.mdx +253 -0
- package/.next/standalone/docs/tr/for-agents.mdx +38 -0
- package/.next/standalone/docs/tr/getting-started.mdx +134 -0
- package/.next/standalone/docs/tr/introduction.mdx +57 -0
- package/.next/standalone/docs/tr/package-aliases.mdx +82 -0
- package/.next/standalone/docs/tr/testing.mdx +260 -0
- package/.next/standalone/docs/vi/architecture.mdx +333 -0
- package/.next/standalone/docs/vi/built-in-policies.mdx +564 -0
- package/.next/standalone/docs/vi/cli/dashboard.mdx +28 -0
- package/.next/standalone/docs/vi/cli/environment-variables.mdx +34 -0
- package/.next/standalone/docs/vi/cli/hook.mdx +30 -0
- package/.next/standalone/docs/vi/cli/install-policies.mdx +48 -0
- package/.next/standalone/docs/vi/cli/list-policies.mdx +31 -0
- package/.next/standalone/docs/vi/cli/remove-policies.mdx +44 -0
- package/.next/standalone/docs/vi/cli/version.mdx +13 -0
- package/.next/standalone/docs/vi/configuration.mdx +222 -0
- package/.next/standalone/docs/vi/custom-policies.mdx +357 -0
- package/.next/standalone/docs/vi/dashboard.mdx +142 -0
- package/.next/standalone/docs/vi/examples.mdx +253 -0
- package/.next/standalone/docs/vi/for-agents.mdx +38 -0
- package/.next/standalone/docs/vi/getting-started.mdx +134 -0
- package/.next/standalone/docs/vi/introduction.mdx +57 -0
- package/.next/standalone/docs/vi/package-aliases.mdx +82 -0
- package/.next/standalone/docs/vi/testing.mdx +260 -0
- package/.next/standalone/docs/zh/architecture.mdx +332 -0
- package/.next/standalone/docs/zh/built-in-policies.mdx +562 -0
- package/.next/standalone/docs/zh/cli/dashboard.mdx +28 -0
- package/.next/standalone/docs/zh/cli/environment-variables.mdx +34 -0
- package/.next/standalone/docs/zh/cli/hook.mdx +30 -0
- package/.next/standalone/docs/zh/cli/install-policies.mdx +48 -0
- package/.next/standalone/docs/zh/cli/list-policies.mdx +31 -0
- package/.next/standalone/docs/zh/cli/remove-policies.mdx +44 -0
- package/.next/standalone/docs/zh/cli/version.mdx +12 -0
- package/.next/standalone/docs/zh/configuration.mdx +222 -0
- package/.next/standalone/docs/zh/custom-policies.mdx +357 -0
- package/.next/standalone/docs/zh/dashboard.mdx +142 -0
- package/.next/standalone/docs/zh/examples.mdx +253 -0
- package/.next/standalone/docs/zh/for-agents.mdx +38 -0
- package/.next/standalone/docs/zh/getting-started.mdx +134 -0
- package/.next/standalone/docs/zh/introduction.mdx +57 -0
- package/.next/standalone/docs/zh/package-aliases.mdx +82 -0
- package/.next/standalone/docs/zh/testing.mdx +260 -0
- package/.next/standalone/examples/convention-policies/security-policies.mjs +40 -0
- package/.next/standalone/examples/convention-policies/workflow-policies.mjs +41 -0
- package/.next/standalone/next.config.ts +5 -3
- package/.next/standalone/node_modules/@next/env/package.json +1 -1
- package/.next/standalone/node_modules/next/dist/build/swc/index.js +1 -1
- package/.next/standalone/node_modules/next/dist/compiled/jsonwebtoken/index.js +2 -2
- package/.next/standalone/node_modules/next/dist/compiled/next-server/app-page-turbo-experimental.runtime.prod.js +1 -1
- package/.next/standalone/node_modules/next/dist/compiled/next-server/app-page-turbo.runtime.prod.js +1 -1
- package/.next/standalone/node_modules/next/dist/compiled/next-server/pages-turbo.runtime.prod.js +1 -1
- package/.next/standalone/node_modules/next/dist/lib/patch-incorrect-lockfile.js +3 -3
- package/.next/standalone/node_modules/next/dist/server/config.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-turbopack.js +7 -2
- package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-webpack.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/lib/app-info-log.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/lib/start-server.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/render.js +20 -19
- package/.next/standalone/node_modules/next/dist/shared/lib/errors/canary-only-config-error.js +1 -1
- package/.next/standalone/node_modules/next/dist/telemetry/anonymous-meta.js +1 -1
- package/.next/standalone/node_modules/next/dist/telemetry/events/swc-load-failure.js +1 -1
- package/.next/standalone/node_modules/next/dist/telemetry/events/version.js +2 -2
- package/.next/standalone/node_modules/next/package.json +15 -15
- package/.next/standalone/node_modules/react/cjs/react.development.js +1 -1
- package/.next/standalone/node_modules/react/cjs/react.production.js +1 -1
- package/.next/standalone/node_modules/react/package.json +1 -1
- package/.next/standalone/node_modules/react-dom/cjs/react-dom-server-legacy.browser.production.js +1 -1
- package/.next/standalone/node_modules/react-dom/cjs/react-dom-server-legacy.node.production.js +1 -1
- package/.next/standalone/node_modules/react-dom/cjs/react-dom-server.browser.production.js +3 -3
- package/.next/standalone/node_modules/react-dom/cjs/react-dom-server.edge.production.js +3 -3
- package/.next/standalone/node_modules/react-dom/cjs/react-dom-server.node.production.js +3 -3
- package/.next/standalone/node_modules/react-dom/cjs/react-dom.production.js +1 -1
- package/.next/standalone/node_modules/react-dom/package.json +2 -2
- package/.next/standalone/package.json +13 -10
- package/.next/standalone/scripts/translate-docs/cache.ts +62 -0
- package/.next/standalone/scripts/translate-docs/cli.ts +357 -0
- package/.next/standalone/scripts/translate-docs/config.ts +248 -0
- package/.next/standalone/scripts/translate-docs/mdx-translator.ts +153 -0
- package/.next/standalone/scripts/translate-docs/mintlify-nav.ts +107 -0
- package/.next/standalone/scripts/translate-docs/readme-translator.ts +154 -0
- package/.next/standalone/scripts/translate-docs/translator.ts +68 -0
- package/.next/standalone/scripts/translate-docs/types.ts +43 -0
- package/.next/standalone/server.js +1 -1
- package/.next/standalone/skills-lock.json +10 -0
- package/.next/standalone/src/hooks/builtin-policies.ts +405 -25
- package/.next/standalone/src/hooks/custom-hooks-loader.ts +165 -21
- package/.next/standalone/src/hooks/handler.ts +33 -6
- package/.next/standalone/src/hooks/hook-activity-store.ts +6 -1
- package/.next/standalone/src/hooks/hooks-config.ts +47 -2
- package/.next/standalone/src/hooks/llm-client.ts +2 -2
- package/.next/standalone/src/hooks/loader-utils.ts +4 -4
- package/.next/standalone/src/hooks/manager.ts +67 -16
- package/.next/standalone/src/hooks/policy-evaluator.ts +58 -19
- package/.next/standalone/src/hooks/policy-helpers.ts +2 -2
- package/.next/standalone/vitest.config.e2e.mts +3 -0
- package/.next/standalone/vitest.config.mts +3 -0
- package/README.md +95 -49
- package/bin/failproofai.mjs +5 -0
- package/dist/cli.mjs +539 -90
- package/dist/index.js +2 -2
- package/package.json +13 -10
- package/scripts/translate-docs/cache.ts +62 -0
- package/scripts/translate-docs/cli.ts +357 -0
- package/scripts/translate-docs/config.ts +248 -0
- package/scripts/translate-docs/mdx-translator.ts +153 -0
- package/scripts/translate-docs/mintlify-nav.ts +107 -0
- package/scripts/translate-docs/readme-translator.ts +154 -0
- package/scripts/translate-docs/translator.ts +68 -0
- package/scripts/translate-docs/types.ts +43 -0
- package/src/hooks/builtin-policies.ts +405 -25
- package/src/hooks/custom-hooks-loader.ts +165 -21
- package/src/hooks/handler.ts +33 -6
- package/src/hooks/hook-activity-store.ts +6 -1
- package/src/hooks/hooks-config.ts +47 -2
- package/src/hooks/llm-client.ts +2 -2
- package/src/hooks/loader-utils.ts +4 -4
- package/src/hooks/manager.ts +67 -16
- package/src/hooks/policy-evaluator.ts +58 -19
- package/src/hooks/policy-helpers.ts +2 -2
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__02nt~6d._.js +0 -3
- package/.next/standalone/.next/static/chunks/15jpradyu_531.css +0 -1
- package/.next/standalone/docs/cli-reference.md +0 -175
- package/.next/standalone/docs/custom-hooks.md +0 -261
- package/.next/standalone/docs/getting-started.md +0 -128
- package/.next/standalone/docs/introduction.md +0 -47
- /package/.next/standalone/.next/static/{WS-OQSqL1Lp1w_obXfjvl → En9eEShUkUjgeYbY9v6Gy}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{WS-OQSqL1Lp1w_obXfjvl → En9eEShUkUjgeYbY9v6Gy}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{WS-OQSqL1Lp1w_obXfjvl → En9eEShUkUjgeYbY9v6Gy}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Aliases de Pacotes
|
|
3
|
+
description: "Aliases registrados para prevenção de typosquatting e como funcionam"
|
|
4
|
+
icon: copy
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Pacote oficial
|
|
8
|
+
|
|
9
|
+
O pacote npm canônico é **`failproofai`**:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install -g failproofai
|
|
13
|
+
# ou
|
|
14
|
+
bun add -g failproofai
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Por que somos donos dos nomes de alias
|
|
20
|
+
|
|
21
|
+
Typosquatting é um ataque comum à cadeia de suprimentos de software, no qual um agente malicioso registra um nome de pacote que difere por apenas um caractere de um pacote popular. Usuários desatentos que digitam errado o comando de instalação acabam executando código controlado pelo atacante com acesso total ao sistema — exatamente o tipo de ameaça que o Failproof AI foi criado para combater.
|
|
22
|
+
|
|
23
|
+
Para eliminar essa superfície de ataque, **registramos preventivamente todos os erros ortográficos comuns e variantes de formatação** de `failproofai` no npm. Nenhum desses nomes pode ser registrado por terceiros. Cada um deles é um proxy simples que instala e delega ao pacote real `failproofai`.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Aliases registrados
|
|
28
|
+
|
|
29
|
+
**Variantes de formatação** — diferentes formas de escrever "failproof ai":
|
|
30
|
+
|
|
31
|
+
| Pacote | Status |
|
|
32
|
+
|--------|--------|
|
|
33
|
+
| `failproof` | ✅ Publicado |
|
|
34
|
+
| `failproof-ai` | ⏳ Aguardando suporte do npm |
|
|
35
|
+
| `fail-proof-ai` | ⏳ Aguardando suporte do npm |
|
|
36
|
+
| `failproof_ai` | ⏳ Aguardando suporte do npm |
|
|
37
|
+
| `fail_proof_ai` | ⏳ Aguardando suporte do npm |
|
|
38
|
+
| `fail-proofai` | ⏳ Aguardando suporte do npm |
|
|
39
|
+
|
|
40
|
+
**Erros de digitação `failprof*`** — falta um `o` em "proof":
|
|
41
|
+
|
|
42
|
+
| Pacote | Status |
|
|
43
|
+
|--------|--------|
|
|
44
|
+
| `failprof` | ✅ Publicado |
|
|
45
|
+
| `failprof-ai` | ✅ Publicado |
|
|
46
|
+
| `failprofai` | ⏳ Aguardando suporte do npm |
|
|
47
|
+
| `fail-prof-ai` | ⏳ Aguardando suporte do npm |
|
|
48
|
+
| `failprof_ai` | ⏳ Aguardando suporte do npm |
|
|
49
|
+
|
|
50
|
+
**Erros de digitação `faliproof*`** — `a` e `i` invertidos:
|
|
51
|
+
|
|
52
|
+
| Pacote | Status |
|
|
53
|
+
|--------|--------|
|
|
54
|
+
| `faliproof` | ✅ Publicado |
|
|
55
|
+
| `faliproof-ai` | ✅ Publicado |
|
|
56
|
+
| `faliproofai` | ⏳ Aguardando suporte do npm |
|
|
57
|
+
|
|
58
|
+
> **Por que "aguardando"?** A política de prevenção de spam do npm bloqueia nomes que, após remoção de pontuação e verificações de similaridade, resultam na mesma string de um pacote já existente. Entramos em contato com o suporte do npm para reservar esses nomes com fins anti-typosquatting. Eles serão ativados após aprovação.
|
|
59
|
+
|
|
60
|
+
Você pode verificar que qualquer alias publicado pertence a nós:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
npm info failproof
|
|
64
|
+
# Procure por: "ExosphereHost Inc." no campo maintainers
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Como os aliases funcionam
|
|
70
|
+
|
|
71
|
+
Cada pacote alias:
|
|
72
|
+
|
|
73
|
+
1. Lista `failproofai` como dependência — assim, o pacote real (incluindo a configuração do hook `postinstall`) é executado durante a instalação
|
|
74
|
+
2. Expõe um binário com seu próprio nome (por exemplo, `failprof-ai`) que repassa todos os argumentos para o binário `failproofai`
|
|
75
|
+
|
|
76
|
+
O proxy é um script Node de duas linhas; não há lógica adicional, chamadas de rede nem coleta de dados além do que o próprio `failproofai` realiza.
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Se você encontrar um nome que esquecemos
|
|
81
|
+
|
|
82
|
+
Abra uma issue em [exospherehost/failproofai](https://github.com/exospherehost/failproofai/issues) e nós o registraremos.
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Testes
|
|
3
|
+
description: "Testes unitários, testes E2E e utilitários de teste"
|
|
4
|
+
icon: flask-vial
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
failproofai possui duas suítes de testes: **testes unitários** (rápidos, com mocks) e **testes end-to-end** (invocações reais de subprocessos).
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Executando os testes
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Executar todos os testes unitários uma vez
|
|
15
|
+
bun run test:run
|
|
16
|
+
|
|
17
|
+
# Executar testes unitários em modo watch
|
|
18
|
+
bun run test
|
|
19
|
+
|
|
20
|
+
# Executar testes E2E (requer configuração - veja abaixo)
|
|
21
|
+
bun run test:e2e
|
|
22
|
+
|
|
23
|
+
# Verificar tipos sem compilar
|
|
24
|
+
bunx tsc --noEmit
|
|
25
|
+
|
|
26
|
+
# Lint
|
|
27
|
+
bun run lint
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Testes unitários
|
|
33
|
+
|
|
34
|
+
Os testes unitários ficam em `__tests__/` e utilizam o [Vitest](https://vitest.dev) com `happy-dom`.
|
|
35
|
+
|
|
36
|
+
```text
|
|
37
|
+
__tests__/
|
|
38
|
+
hooks/
|
|
39
|
+
builtin-policies.test.ts # Lógica de políticas para cada builtin
|
|
40
|
+
hooks-config.test.ts # Carregamento de configuração e mesclagem de escopos
|
|
41
|
+
policy-evaluator.test.ts # Injeção de parâmetros e ordem de avaliação
|
|
42
|
+
custom-hooks-registry.test.ts # Registro globalThis: add/get/clear
|
|
43
|
+
custom-hooks-loader.test.ts # Loader ESM, imports transitivos, tratamento de erros
|
|
44
|
+
manager.test.ts # Operações install/remove/list
|
|
45
|
+
components/
|
|
46
|
+
sessions-list.test.tsx # Componente de lista de sessões
|
|
47
|
+
project-list.test.tsx # Componente de lista de projetos
|
|
48
|
+
...
|
|
49
|
+
lib/
|
|
50
|
+
logger.test.ts
|
|
51
|
+
paths.test.ts
|
|
52
|
+
date-filters.test.ts
|
|
53
|
+
telemetry.test.ts
|
|
54
|
+
...
|
|
55
|
+
actions/
|
|
56
|
+
get-hooks-config.test.ts
|
|
57
|
+
get-hook-activity.test.ts
|
|
58
|
+
...
|
|
59
|
+
contexts/
|
|
60
|
+
ThemeContext.test.tsx
|
|
61
|
+
AutoRefreshContext.test.tsx
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Escrevendo um teste unitário de política
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
import { describe, it, expect, beforeEach } from "vitest";
|
|
68
|
+
import { getBuiltinPolicies } from "../../src/hooks/builtin-policies";
|
|
69
|
+
import { allow, deny } from "../../src/hooks/policy-types";
|
|
70
|
+
|
|
71
|
+
describe("block-sudo", () => {
|
|
72
|
+
const policy = getBuiltinPolicies().find((p) => p.name === "block-sudo")!;
|
|
73
|
+
|
|
74
|
+
it("denies sudo commands", () => {
|
|
75
|
+
const ctx = {
|
|
76
|
+
eventType: "PreToolUse" as const,
|
|
77
|
+
payload: {},
|
|
78
|
+
toolName: "Bash",
|
|
79
|
+
toolInput: { command: "sudo apt install nodejs" },
|
|
80
|
+
params: { allowPatterns: [] },
|
|
81
|
+
};
|
|
82
|
+
expect(policy.fn(ctx)).toEqual(deny("sudo command blocked by failproofai"));
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it("allows non-sudo commands", () => {
|
|
86
|
+
const ctx = {
|
|
87
|
+
eventType: "PreToolUse" as const,
|
|
88
|
+
payload: {},
|
|
89
|
+
toolName: "Bash",
|
|
90
|
+
toolInput: { command: "ls -la" },
|
|
91
|
+
params: { allowPatterns: [] },
|
|
92
|
+
};
|
|
93
|
+
expect(policy.fn(ctx)).toEqual(allow());
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it("allows patterns in allowPatterns", () => {
|
|
97
|
+
const ctx = {
|
|
98
|
+
eventType: "PreToolUse" as const,
|
|
99
|
+
payload: {},
|
|
100
|
+
toolName: "Bash",
|
|
101
|
+
toolInput: { command: "sudo systemctl status nginx" },
|
|
102
|
+
params: { allowPatterns: ["sudo systemctl status"] },
|
|
103
|
+
};
|
|
104
|
+
expect(policy.fn(ctx)).toEqual(allow());
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## Testes end-to-end
|
|
112
|
+
|
|
113
|
+
Os testes E2E invocam o binário real do `failproofai` como subprocesso, enviam um payload JSON via stdin e verificam a saída no stdout e o código de saída. Isso testa o caminho completo de integração que o Claude Code utiliza.
|
|
114
|
+
|
|
115
|
+
### Configuração
|
|
116
|
+
|
|
117
|
+
Os testes E2E executam o binário diretamente do código-fonte do repositório. Antes da primeira execução, compile o bundle CJS que os arquivos de hook customizados usam ao importar de `'failproofai'`:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
bun build src/index.ts --outdir dist --target node --format cjs
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Em seguida, execute os testes:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
bun run test:e2e
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Recompile o `dist/` sempre que alterar a API pública de hooks (`src/hooks/custom-hooks-registry.ts`, `src/hooks/policy-helpers.ts` ou `src/hooks/policy-types.ts`).
|
|
130
|
+
|
|
131
|
+
### Estrutura dos testes E2E
|
|
132
|
+
|
|
133
|
+
```text
|
|
134
|
+
__tests__/e2e/
|
|
135
|
+
helpers/
|
|
136
|
+
hook-runner.ts # Inicia o binário, envia payload JSON, captura código de saída + stdout + stderr
|
|
137
|
+
fixture-env.ts # Diretórios temporários isolados por teste com arquivos de configuração
|
|
138
|
+
payloads.ts # Fábricas de payload compatíveis com Claude para cada tipo de evento
|
|
139
|
+
hooks/
|
|
140
|
+
builtin-policies.e2e.test.ts # Cada política builtin com subprocesso real
|
|
141
|
+
custom-hooks.e2e.test.ts # Carregamento e avaliação de hooks customizados
|
|
142
|
+
config-scopes.e2e.test.ts # Mesclagem de configuração entre escopos project/local/global
|
|
143
|
+
policy-params.e2e.test.ts # Injeção de parâmetros para cada política parametrizada
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Usando os utilitários E2E
|
|
147
|
+
|
|
148
|
+
**`FixtureEnv`** - ambiente isolado por teste:
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
import { createFixtureEnv } from "../helpers/fixture-env";
|
|
152
|
+
|
|
153
|
+
const env = createFixtureEnv();
|
|
154
|
+
// env.cwd - diretório temporário; passe como payload.cwd para carregar .failproofai/policies-config.json
|
|
155
|
+
// env.home - home isolado; evita vazamento do ~/.failproofai real
|
|
156
|
+
|
|
157
|
+
env.writeConfig({
|
|
158
|
+
enabledPolicies: ["block-sudo"],
|
|
159
|
+
policyParams: {
|
|
160
|
+
"block-sudo": { allowPatterns: ["sudo systemctl status"] },
|
|
161
|
+
},
|
|
162
|
+
});
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
`createFixtureEnv()` registra a limpeza via `afterEach` automaticamente.
|
|
166
|
+
|
|
167
|
+
**`runHook`** - invoca o binário:
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
import { runHook } from "../helpers/hook-runner";
|
|
171
|
+
import { Payloads } from "../helpers/payloads";
|
|
172
|
+
|
|
173
|
+
const result = await runHook(
|
|
174
|
+
"PreToolUse",
|
|
175
|
+
Payloads.preToolUse.bash("sudo apt install nodejs", env.cwd),
|
|
176
|
+
{ homeDir: env.home }
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
expect(result.exitCode).toBe(0);
|
|
180
|
+
expect(result.parsed?.hookSpecificOutput?.permissionDecision).toBe("deny");
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
**`Payloads`** - fábricas de payload prontas para uso:
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
Payloads.preToolUse.bash(command, cwd)
|
|
187
|
+
Payloads.preToolUse.write(filePath, content, cwd)
|
|
188
|
+
Payloads.preToolUse.read(filePath, cwd)
|
|
189
|
+
Payloads.postToolUse.bash(command, output, cwd)
|
|
190
|
+
Payloads.postToolUse.read(filePath, content, cwd)
|
|
191
|
+
Payloads.notification(message, cwd)
|
|
192
|
+
Payloads.stop(cwd)
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Escrevendo um teste E2E
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
import { describe, it, expect } from "vitest";
|
|
199
|
+
import { createFixtureEnv } from "../helpers/fixture-env";
|
|
200
|
+
import { runHook } from "../helpers/hook-runner";
|
|
201
|
+
import { Payloads } from "../helpers/payloads";
|
|
202
|
+
|
|
203
|
+
describe("block-rm-rf (E2E)", () => {
|
|
204
|
+
it("denies rm -rf", async () => {
|
|
205
|
+
const env = createFixtureEnv();
|
|
206
|
+
env.writeConfig({ enabledPolicies: ["block-rm-rf"] });
|
|
207
|
+
|
|
208
|
+
const result = await runHook(
|
|
209
|
+
"PreToolUse",
|
|
210
|
+
Payloads.preToolUse.bash("rm -rf /", env.cwd),
|
|
211
|
+
{ homeDir: env.home }
|
|
212
|
+
);
|
|
213
|
+
|
|
214
|
+
expect(result.exitCode).toBe(0);
|
|
215
|
+
expect(result.parsed?.hookSpecificOutput?.permissionDecision).toBe("deny");
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
it("allows non-recursive rm", async () => {
|
|
219
|
+
const env = createFixtureEnv();
|
|
220
|
+
env.writeConfig({ enabledPolicies: ["block-rm-rf"] });
|
|
221
|
+
|
|
222
|
+
const result = await runHook(
|
|
223
|
+
"PreToolUse",
|
|
224
|
+
Payloads.preToolUse.bash("rm /tmp/file.txt", env.cwd),
|
|
225
|
+
{ homeDir: env.home }
|
|
226
|
+
);
|
|
227
|
+
|
|
228
|
+
expect(result.exitCode).toBe(0);
|
|
229
|
+
expect(result.stdout).toBe(""); // allow → stdout vazio
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Formatos de resposta E2E
|
|
235
|
+
|
|
236
|
+
| Decisão | Código de saída | stdout |
|
|
237
|
+
|----------|-----------|--------|
|
|
238
|
+
| `PreToolUse` deny | `0` | `{"hookSpecificOutput":{"permissionDecision":"deny","permissionDecisionReason":"..."}}` |
|
|
239
|
+
| `PostToolUse` deny | `0` | `{"hookSpecificOutput":{"additionalContext":"Blocked ... because: ..."}}` |
|
|
240
|
+
| Instruct (não-Stop) | `0` | `{"hookSpecificOutput":{"additionalContext":"Instruction from failproofai: ..."}}` |
|
|
241
|
+
| Stop instruct | `2` | stdout vazio; motivo no stderr |
|
|
242
|
+
| Allow | `0` | string vazia |
|
|
243
|
+
|
|
244
|
+
### Configuração do Vitest
|
|
245
|
+
|
|
246
|
+
Os testes E2E utilizam `vitest.config.e2e.mts` com:
|
|
247
|
+
|
|
248
|
+
- `environment: "node"` - sem necessidade de globals do navegador
|
|
249
|
+
- `pool: "forks"` - isolamento real de processos (os testes iniciam subprocessos)
|
|
250
|
+
- `testTimeout: 20_000` - 20s por teste (inicialização do binário + avaliação do hook)
|
|
251
|
+
|
|
252
|
+
O pool `forks` é importante: workers baseados em threads compartilham `globalThis`, o que pode interferir com testes que iniciam subprocessos. Forks baseados em processos evitam esse problema.
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
## CI
|
|
257
|
+
|
|
258
|
+
A execução completa de CI (`bun run lint && bunx tsc --noEmit && bun run test:run && bun run build`) deve passar antes do merge. A suíte E2E é executada como um job de CI separado, em paralelo.
|
|
259
|
+
|
|
260
|
+
Consulte [Contributing](../CONTRIBUTING.md) para o checklist completo de pré-merge.
|
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
---
|
|
2
|
+
|
|
3
|
+
---
|
|
4
|
+
title: Архитектура
|
|
5
|
+
description: "Как работают обработчик хука, загрузка конфигурации и оценка политик"
|
|
6
|
+
icon: sitemap
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
В этом документе объясняется, как failproofai работает внутренне: как система хуков перехватывает вызовы инструментов агента, как загружается и объединяется конфигурация, как оцениваются политики и как панель мониторинга отслеживает активность агента.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Обзор
|
|
14
|
+
|
|
15
|
+
failproofai состоит из двух независимых подсистем:
|
|
16
|
+
|
|
17
|
+
1. **Обработчик хука** — быстрый CLI подпроцесс, который Claude Code вызывает при каждом вызове инструмента агента. Оценивает политики и возвращает решение.
|
|
18
|
+
2. **Agent Monitor (Dashboard)** — веб-приложение Next.js для мониторинга сеансов агента и управления политиками.
|
|
19
|
+
|
|
20
|
+
Обе подсистемы совместно используют файлы конфигурации в `~/.failproofai/` и в директории `.failproofai/` проекта, но работают как отдельные процессы и общаются только через файловую систему.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Обработчик хука
|
|
25
|
+
|
|
26
|
+
### Интеграция с Claude Code
|
|
27
|
+
|
|
28
|
+
Когда вы запускаете `failproofai policies --install`, в `~/.claude/settings.json` добавляются записи следующего вида:
|
|
29
|
+
|
|
30
|
+
```json
|
|
31
|
+
{
|
|
32
|
+
"hooks": {
|
|
33
|
+
"PreToolUse": [
|
|
34
|
+
{
|
|
35
|
+
"matcher": "",
|
|
36
|
+
"hooks": [
|
|
37
|
+
{
|
|
38
|
+
"type": "command",
|
|
39
|
+
"command": "failproofai --hook PreToolUse"
|
|
40
|
+
}
|
|
41
|
+
]
|
|
42
|
+
}
|
|
43
|
+
],
|
|
44
|
+
"PostToolUse": [ ... ]
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Затем Claude Code вызывает `failproofai --hook PreToolUse` как подпроцесс перед каждым вызовом инструмента, передавая JSON-полезную нагрузку на stdin.
|
|
50
|
+
|
|
51
|
+
### Формат полезной нагрузки
|
|
52
|
+
|
|
53
|
+
```json
|
|
54
|
+
{
|
|
55
|
+
"session_id": "abc123",
|
|
56
|
+
"transcript_path": "/home/user/.claude/projects/myproject/sessions/abc123.jsonl",
|
|
57
|
+
"cwd": "/home/user/myproject",
|
|
58
|
+
"permission_mode": "default",
|
|
59
|
+
"hook_event_name": "PreToolUse",
|
|
60
|
+
"tool_name": "Bash",
|
|
61
|
+
"tool_input": { "command": "sudo apt install nodejs" }
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Для событий `PostToolUse` полезная нагрузка также содержит `tool_result` с выходом инструмента.
|
|
66
|
+
|
|
67
|
+
Обработчик устанавливает ограничение входного потока в 1 МБ. Полезные нагрузки, превышающие этот лимит, отбрасываются и все политики неявно разрешают операцию.
|
|
68
|
+
|
|
69
|
+
### Формат ответа
|
|
70
|
+
|
|
71
|
+
**Отклонить (PreToolUse):**
|
|
72
|
+
```json
|
|
73
|
+
{
|
|
74
|
+
"hookSpecificOutput": {
|
|
75
|
+
"permissionDecision": "deny",
|
|
76
|
+
"permissionDecisionReason": "Blocked by failproofai: sudo command blocked"
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**Отклонить (PostToolUse):**
|
|
82
|
+
```json
|
|
83
|
+
{
|
|
84
|
+
"hookSpecificOutput": {
|
|
85
|
+
"additionalContext": "Blocked by failproofai because: API key detected in output"
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**Инструкция (любое событие кроме Stop):**
|
|
91
|
+
```json
|
|
92
|
+
{
|
|
93
|
+
"hookSpecificOutput": {
|
|
94
|
+
"additionalContext": "Instruction from failproofai: Verify tests pass before committing."
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
**Инструкция события Stop:**
|
|
100
|
+
- Код выхода: `2`
|
|
101
|
+
- Причина записана в stderr (не stdout)
|
|
102
|
+
|
|
103
|
+
**Разрешить:**
|
|
104
|
+
- Код выхода: `0`
|
|
105
|
+
- Пустой stdout
|
|
106
|
+
|
|
107
|
+
**Разрешить с сообщением (beta):**
|
|
108
|
+
|
|
109
|
+
Начиная с версии v0.0.2-beta.3, `allow(message)` позволяет политике отправить контекстную информацию в Claude, даже если операция разрешена. Обработчик хука записывает в **stdout** следующий JSON (не в файл конфигурации — это ответ обработчика на Claude Code, как и ответы deny и instruct выше):
|
|
110
|
+
|
|
111
|
+
```json
|
|
112
|
+
// Written to stdout by the hook handler process
|
|
113
|
+
{
|
|
114
|
+
"hookSpecificOutput": {
|
|
115
|
+
"additionalContext": "All CI checks passed on branch 'feat/my-feature'."
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
- Код выхода: `0` (операция разрешена)
|
|
120
|
+
- Когда несколько политик возвращают `allow` с сообщением, их сообщения объединяются с переносами строк в единую строку `additionalContext`
|
|
121
|
+
- Если ни одна политика не предоставляет сообщение, stdout остается пустым (как раньше)
|
|
122
|
+
|
|
123
|
+
### Конвейер обработки
|
|
124
|
+
|
|
125
|
+
`src/hooks/handler.ts` реализует полный конвейер:
|
|
126
|
+
|
|
127
|
+
```text
|
|
128
|
+
stdin JSON
|
|
129
|
+
→ parse payload (max 1 MB)
|
|
130
|
+
→ extract session metadata (session_id, cwd, tool_name, tool_input, etc.)
|
|
131
|
+
→ readMergedHooksConfig(cwd) ← merges project + local + global config
|
|
132
|
+
→ register enabled builtin policies with resolved params
|
|
133
|
+
→ load custom policies from customPoliciesPath (if set)
|
|
134
|
+
→ register custom policies into policy registry
|
|
135
|
+
→ evaluate all policies (builtins first, then custom)
|
|
136
|
+
→ first deny short-circuits
|
|
137
|
+
→ instruct decisions accumulate
|
|
138
|
+
→ allow messages accumulate
|
|
139
|
+
→ write JSON decision to stdout
|
|
140
|
+
→ persist event to ~/.failproofai/hook-activity.jsonl
|
|
141
|
+
→ exit
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Весь процесс выполняется менее чем за 100 мс для типичных полезных нагрузок без вызовов LLM.
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## Загрузка конфигурации
|
|
149
|
+
|
|
150
|
+
`src/hooks/hooks-config.ts` реализует загрузку конфигурации с тремя областями видимости.
|
|
151
|
+
|
|
152
|
+
```text
|
|
153
|
+
[1] {cwd}/.failproofai/policies-config.json ← project (highest priority)
|
|
154
|
+
[2] {cwd}/.failproofai/policies-config.local.json ← local
|
|
155
|
+
[3] ~/.failproofai/policies-config.json ← global (lowest priority)
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Логика объединения:
|
|
159
|
+
- `enabledPolicies` — объединение всех трех файлов без дубликатов
|
|
160
|
+
- `policyParams` — на политику, первый файл, который ее определяет, полностью выигрывает
|
|
161
|
+
- `customPoliciesPath` — первый файл, который его определяет, выигрывает
|
|
162
|
+
- `llm` — первый файл, который его определяет, выигрывает
|
|
163
|
+
|
|
164
|
+
Веб-панель мониторинга использует `readHooksConfig()` (только глобальная) для чтения и записи, так как она не вызывается с рабочей директорией проекта.
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Оценка политик
|
|
169
|
+
|
|
170
|
+
`src/hooks/policy-evaluator.ts` запускает политики по порядку.
|
|
171
|
+
|
|
172
|
+
Для каждой политики:
|
|
173
|
+
|
|
174
|
+
1. Найти схему `params` политики (если она существует).
|
|
175
|
+
2. Прочитать `policyParams[policy.name]` из объединенной конфигурации.
|
|
176
|
+
3. Объединить предоставленные пользователем значения со значениями по умолчанию из схемы, создав `ctx.params`.
|
|
177
|
+
4. Вызвать `policy.fn(ctx)` с разрешенным контекстом.
|
|
178
|
+
5. Если результат — `deny`, остановиться немедленно и вернуть это решение.
|
|
179
|
+
6. Если результат — `instruct`, накопить сообщение и продолжить.
|
|
180
|
+
7. Если результат — `allow`, перейти к следующей политике.
|
|
181
|
+
|
|
182
|
+
После запуска всех политик:
|
|
183
|
+
- Если было возвращено какое-либо `deny`, выдать ответ deny.
|
|
184
|
+
- Если были собраны возвращаемые значения `instruct`, выдать единый ответ instruct со всеми объединенными сообщениями.
|
|
185
|
+
- В противном случае выдать ответ allow (пустой stdout, выход 0).
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## Встроенные политики
|
|
190
|
+
|
|
191
|
+
`src/hooks/builtin-policies.ts` определяет все 26 встроенных политик как объекты `BuiltinPolicyDefinition`:
|
|
192
|
+
|
|
193
|
+
```typescript
|
|
194
|
+
interface BuiltinPolicyDefinition {
|
|
195
|
+
name: string;
|
|
196
|
+
description: string;
|
|
197
|
+
fn: (ctx: PolicyContext) => PolicyResult;
|
|
198
|
+
match: {
|
|
199
|
+
events: HookEventType[];
|
|
200
|
+
tools?: string[];
|
|
201
|
+
};
|
|
202
|
+
defaultEnabled: boolean;
|
|
203
|
+
category: string;
|
|
204
|
+
beta?: boolean;
|
|
205
|
+
params?: PolicyParamsSchema;
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
Политики, которые принимают `params`, объявляют `PolicyParamsSchema` с типами и значениями по умолчанию для каждого параметра. Оценщик политик вводит разрешенные значения в `ctx.params` перед вызовом `fn`. Функции политик читают `ctx.params` без проверки null, потому что значения по умолчанию всегда применяются в первую очередь.
|
|
210
|
+
|
|
211
|
+
Сопоставление шаблонов внутри политик использует разобранные токены команд (argv), а не сопоставление сырых строк. Это предотвращает обход путем инъекции оператора оболочки (например, шаблон для `sudo systemctl status *` не может быть обойден путем добавления `; rm -rf /` к команде).
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## Пользовательские политики
|
|
216
|
+
|
|
217
|
+
`src/hooks/custom-hooks-registry.ts` реализует реестр на основе `globalThis`:
|
|
218
|
+
|
|
219
|
+
```typescript
|
|
220
|
+
const REGISTRY_KEY = "__failproofai_custom_hooks__";
|
|
221
|
+
|
|
222
|
+
export const customPolicies = {
|
|
223
|
+
add(hook: CustomHook): void { ... }
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
export function getCustomHooks(): CustomHook[] { ... }
|
|
227
|
+
export function clearCustomHooks(): void { ... } // used in tests
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
`src/hooks/custom-hooks-loader.ts` загружает файл политики пользователя:
|
|
231
|
+
|
|
232
|
+
1. Прочитать `customPoliciesPath` из конфигурации; пропустить, если отсутствует.
|
|
233
|
+
2. Разрешить абсолютный путь; проверить, что файл существует.
|
|
234
|
+
3. Переписать все импорты `from "failproofai"` на фактический путь dist, чтобы `customPolicies` разрешался к тому же реестру `globalThis`.
|
|
235
|
+
4. Рекурсивно переписать переходные локальные импорты, чтобы обеспечить совместимость ESM.
|
|
236
|
+
5. Написать временные файлы `.mjs` и `import()` файл входа.
|
|
237
|
+
6. Вызвать `getCustomHooks()`, чтобы получить зарегистрированные хуки.
|
|
238
|
+
7. Очистить все временные файлы в блоке `finally`.
|
|
239
|
+
|
|
240
|
+
При любой ошибке (файл не найден, синтаксическая ошибка, ошибка импорта) ошибка регистрируется в `~/.failproofai/hook.log` и загрузчик возвращает пустой массив. Встроенные политики не затрагиваются.
|
|
241
|
+
|
|
242
|
+
Пользовательские политики оцениваются после всех встроенных политик. `deny` пользовательской политики по-прежнему прерывает дальнейшие пользовательские политики (но все встроенные уже запустились к этому моменту).
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## Логирование активности
|
|
247
|
+
|
|
248
|
+
После каждого события хука обработчик добавляет строку JSONL в `~/.failproofai/hook-activity.jsonl`:
|
|
249
|
+
|
|
250
|
+
```json
|
|
251
|
+
{
|
|
252
|
+
"timestamp": "2026-04-06T12:34:56.789Z",
|
|
253
|
+
"sessionId": "abc123",
|
|
254
|
+
"eventType": "PreToolUse",
|
|
255
|
+
"toolName": "Bash",
|
|
256
|
+
"policyName": "block-sudo",
|
|
257
|
+
"decision": "deny",
|
|
258
|
+
"reason": "sudo command blocked by failproofai",
|
|
259
|
+
"durationMs": 12
|
|
260
|
+
}
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
Одна строка на каждую политику, которая приняла решение, отличное от allow. Решения allow не регистрируются (чтобы файл оставался маленьким).
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## Архитектура панели мониторинга
|
|
268
|
+
|
|
269
|
+
Панель мониторинга — это приложение **Next.js 16**, использующее App Router с React Server Components и Server Actions.
|
|
270
|
+
|
|
271
|
+
```text
|
|
272
|
+
app/
|
|
273
|
+
layout.tsx ← Root layout (theme, telemetry, nav)
|
|
274
|
+
projects/page.tsx ← Server component: list all Claude projects
|
|
275
|
+
project/[name]/page.tsx ← Server component: list sessions in a project
|
|
276
|
+
project/[name]/session/
|
|
277
|
+
[sessionId]/page.tsx ← Server component: render session viewer
|
|
278
|
+
policies/page.tsx ← Client component: policy management + activity log
|
|
279
|
+
actions/
|
|
280
|
+
get-hooks-config.ts ← Read config + policy list
|
|
281
|
+
update-hooks-config.ts ← Toggle policy on/off
|
|
282
|
+
update-policy-params.ts ← Update policy parameters
|
|
283
|
+
get-hook-activity.ts ← Paginate/search activity log
|
|
284
|
+
install-hooks-web.ts ← Install/remove hooks from the browser
|
|
285
|
+
api/
|
|
286
|
+
download/[project]/[session]/route.ts ← Export session as ZIP/JSONL
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
**Поток данных:**
|
|
290
|
+
|
|
291
|
+
- Компоненты страниц вызывают `lib/projects.ts` и `lib/log-entries.ts` для чтения данных проекта/сеанса непосредственно из файловой системы (без слоя API для операций чтения).
|
|
292
|
+
- Страница Policies использует Server Actions для всех мутаций (переключение, обновление параметров, установка/удаление).
|
|
293
|
+
- Просмотрщик сеансов анализирует формат JSONL-транскрипта Claude и отображает шкалу времени сообщений и вызовов инструментов.
|
|
294
|
+
|
|
295
|
+
**Ключевые решения проектирования:**
|
|
296
|
+
|
|
297
|
+
- Нет базы данных — все постоянное состояние хранится в простых файлах (`~/.failproofai/`, `~/.claude/projects/`).
|
|
298
|
+
- Server Actions для мутаций — REST API не требуется для CRUD операций.
|
|
299
|
+
- React Server Components для страниц чтения — более быстрая начальная загрузка, отсутствие клиентского бандла для выборки данных.
|
|
300
|
+
- Клиентские компоненты только там, где требуется интерактивность (переключение политик, поиск активности, просмотр логов).
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
304
|
+
## Структура файлов
|
|
305
|
+
|
|
306
|
+
```text
|
|
307
|
+
failproofai/
|
|
308
|
+
├── bin/
|
|
309
|
+
│ └── failproofai.mjs # CLI router (hook / dashboard / install / etc.)
|
|
310
|
+
├── src/hooks/
|
|
311
|
+
│ ├── handler.ts # Hook event pipeline
|
|
312
|
+
│ ├── builtin-policies.ts # 26 policy definitions
|
|
313
|
+
│ ├── policy-evaluator.ts # Policy execution engine
|
|
314
|
+
│ ├── policy-registry.ts # Policy registration and lookup
|
|
315
|
+
│ ├── policy-types.ts # TypeScript interfaces
|
|
316
|
+
│ ├── hooks-config.ts # Multi-scope config loading
|
|
317
|
+
│ ├── custom-hooks-registry.ts # globalThis-backed hook registry
|
|
318
|
+
│ ├── custom-hooks-loader.ts # ESM loader for user JS hooks
|
|
319
|
+
│ ├── manager.ts # install / remove / list operations
|
|
320
|
+
│ ├── install-prompt.ts # Interactive policy selection prompt
|
|
321
|
+
│ ├── hook-logger.ts # Logging to hook.log
|
|
322
|
+
│ ├── hook-activity-store.ts # Persist activity to hook-activity.jsonl
|
|
323
|
+
│ └── llm-client.ts # LLM API client (for AI-powered policies)
|
|
324
|
+
├── app/ # Next.js dashboard (pages + server actions)
|
|
325
|
+
├── lib/ # Shared utilities
|
|
326
|
+
│ ├── projects.ts # Enumerate Claude projects from filesystem
|
|
327
|
+
│ ├── log-entries.ts # Parse Claude transcript JSONL format
|
|
328
|
+
│ ├── paths.ts # Resolve system paths
|
|
329
|
+
│ └── ...
|
|
330
|
+
├── components/ # Shared React UI components
|
|
331
|
+
├── contexts/ # React context providers (theme, auto-refresh, telemetry)
|
|
332
|
+
├── examples/ # Example custom hook files
|
|
333
|
+
└── __tests__/ # Unit and E2E tests
|
|
334
|
+
```
|