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,260 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Kiểm thử
|
|
3
|
+
description: "Kiểm thử đơn vị, kiểm thử end-to-end và trình hỗ trợ kiểm thử"
|
|
4
|
+
icon: flask-vial
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
failproofai có hai bộ kiểm thử: **kiểm thử đơn vị** (nhanh, được mock) và **kiểm thử end-to-end** (gọi subprocess thực tế).
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Chạy kiểm thử
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Chạy tất cả kiểm thử đơn vị một lần
|
|
15
|
+
bun run test:run
|
|
16
|
+
|
|
17
|
+
# Chạy kiểm thử đơn vị ở chế độ watch
|
|
18
|
+
bun run test
|
|
19
|
+
|
|
20
|
+
# Chạy kiểm thử E2E (yêu cầu cài đặt - xem bên dưới)
|
|
21
|
+
bun run test:e2e
|
|
22
|
+
|
|
23
|
+
# Kiểm tra kiểu dữ liệu mà không xây dựng
|
|
24
|
+
bunx tsc --noEmit
|
|
25
|
+
|
|
26
|
+
# Lint
|
|
27
|
+
bun run lint
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Kiểm thử đơn vị
|
|
33
|
+
|
|
34
|
+
Các kiểm thử đơn vị nằm trong `__tests__/` và sử dụng [Vitest](https://vitest.dev) với `happy-dom`.
|
|
35
|
+
|
|
36
|
+
```text
|
|
37
|
+
__tests__/
|
|
38
|
+
hooks/
|
|
39
|
+
builtin-policies.test.ts # Logic chính sách cho mỗi builtin
|
|
40
|
+
hooks-config.test.ts # Tải config và gộp scope
|
|
41
|
+
policy-evaluator.test.ts # Tiêm param và thứ tự đánh giá
|
|
42
|
+
custom-hooks-registry.test.ts # Thêm/lấy/xóa registry globalThis
|
|
43
|
+
custom-hooks-loader.test.ts # Trình tải ESM, import bắc cầu, xử lý lỗi
|
|
44
|
+
manager.test.ts # Hoạt động install/remove/list
|
|
45
|
+
components/
|
|
46
|
+
sessions-list.test.tsx # Thành phần danh sách phiên
|
|
47
|
+
project-list.test.tsx # Thành phần danh sách dự án
|
|
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
|
+
### Viết kiểm thử đơn vị cho chính sách
|
|
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
|
+
## Kiểm thử end-to-end
|
|
112
|
+
|
|
113
|
+
Các kiểm thử E2E gọi binary `failproofai` thực tế dưới dạng subprocess, pipe payload JSON tới stdin, và kiểm tra kết quả stdout và mã thoát. Điều này kiểm thử đường dẫn tích hợp hoàn chỉnh mà Claude Code sử dụng.
|
|
114
|
+
|
|
115
|
+
### Cài đặt
|
|
116
|
+
|
|
117
|
+
Các kiểm thử E2E chạy binary trực tiếp từ mã nguồn repo. Trước lần chạy đầu tiên, xây dựng gói CJS mà các tệp custom hook sử dụng khi nhập từ `'failproofai'`:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
bun build src/index.ts --outdir dist --target node --format cjs
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Sau đó chạy kiểm thử:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
bun run test:e2e
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Xây dựng lại `dist/` bất cứ khi nào bạn thay đổi API hook công khai (`src/hooks/custom-hooks-registry.ts`, `src/hooks/policy-helpers.ts`, hoặc `src/hooks/policy-types.ts`).
|
|
130
|
+
|
|
131
|
+
### Cấu trúc kiểm thử E2E
|
|
132
|
+
|
|
133
|
+
```text
|
|
134
|
+
__tests__/e2e/
|
|
135
|
+
helpers/
|
|
136
|
+
hook-runner.ts # Sinh binary, pipe payload JSON, bắt mã thoát + stdout + stderr
|
|
137
|
+
fixture-env.ts # Thư mục tạm biệt lập cho mỗi kiểm thử với các tệp config
|
|
138
|
+
payloads.ts # Nhà máy payload chính xác theo Claude cho mỗi loại sự kiện
|
|
139
|
+
hooks/
|
|
140
|
+
builtin-policies.e2e.test.ts # Mỗi chính sách builtin với subprocess thực
|
|
141
|
+
custom-hooks.e2e.test.ts # Tải và đánh giá custom hook
|
|
142
|
+
config-scopes.e2e.test.ts # Gộp config trên project/local/global
|
|
143
|
+
policy-params.e2e.test.ts # Tiêm tham số cho mỗi chính sách tham số hóa
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Sử dụng trình hỗ trợ E2E
|
|
147
|
+
|
|
148
|
+
**`FixtureEnv`** - môi trường biệt lập cho mỗi kiểm thử:
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
import { createFixtureEnv } from "../helpers/fixture-env";
|
|
152
|
+
|
|
153
|
+
const env = createFixtureEnv();
|
|
154
|
+
// env.cwd - thư mục tạm; truyền làm payload.cwd để lấy .failproofai/policies-config.json
|
|
155
|
+
// env.home - thư mục home biệt lập; không rò rỉ ~/.failproofai thực tế
|
|
156
|
+
|
|
157
|
+
env.writeConfig({
|
|
158
|
+
enabledPolicies: ["block-sudo"],
|
|
159
|
+
policyParams: {
|
|
160
|
+
"block-sudo": { allowPatterns: ["sudo systemctl status"] },
|
|
161
|
+
},
|
|
162
|
+
});
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
`createFixtureEnv()` đăng ký dọn dẹp `afterEach` tự động.
|
|
166
|
+
|
|
167
|
+
**`runHook`** - gọi binary:
|
|
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`** - nhà máy payload có sẵn:
|
|
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
|
+
### Viết kiểm thử 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 trống
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Hình dạng phản hồi E2E
|
|
235
|
+
|
|
236
|
+
| Quyết định | Mã thoát | stdout |
|
|
237
|
+
|----------|-----------|--------|
|
|
238
|
+
| `PreToolUse` deny | `0` | `{"hookSpecificOutput":{"permissionDecision":"deny","permissionDecisionReason":"..."}}` |
|
|
239
|
+
| `PostToolUse` deny | `0` | `{"hookSpecificOutput":{"additionalContext":"Blocked ... because: ..."}}` |
|
|
240
|
+
| Instruct (không-Stop) | `0` | `{"hookSpecificOutput":{"additionalContext":"Instruction from failproofai: ..."}}` |
|
|
241
|
+
| Instruct Stop | `2` | stdout trống; lý do trong stderr |
|
|
242
|
+
| Allow | `0` | chuỗi trống |
|
|
243
|
+
|
|
244
|
+
### Cấu hình Vitest
|
|
245
|
+
|
|
246
|
+
Các kiểm thử E2E sử dụng `vitest.config.e2e.mts` với:
|
|
247
|
+
|
|
248
|
+
- `environment: "node"` - không cần globals trình duyệt
|
|
249
|
+
- `pool: "forks"` - cô lập process thực (kiểm thử sinh subprocess)
|
|
250
|
+
- `testTimeout: 20_000` - 20s cho mỗi kiểm thử (khởi động binary + đánh giá hook)
|
|
251
|
+
|
|
252
|
+
Pool `forks` rất quan trọng: worker dựa trên luồng chia sẻ `globalThis`, điều này có thể gây ảnh hưởng đến các kiểm thử sinh subprocess. Các forks dựa trên process tránh điều này.
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
## CI
|
|
257
|
+
|
|
258
|
+
Chạy CI đầy đủ (`bun run lint && bunx tsc --noEmit && bun run test:run && bun run build`) được yêu cầu phải vượt qua trước khi merge. Bộ kiểm thử E2E chạy như một công việc CI riêng biệt song song.
|
|
259
|
+
|
|
260
|
+
Xem [Contributing](../CONTRIBUTING.md) để biết danh sách kiểm tra trước merge hoàn chỉnh.
|
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: 架构
|
|
3
|
+
description: "钩子处理器、配置加载和策略评估的内部工作原理"
|
|
4
|
+
icon: sitemap
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
本文档介绍 failproofai 的内部工作机制:钩子系统如何拦截 Agent 工具调用、配置如何加载与合并、策略如何评估,以及仪表板如何监控 Agent 活动。
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 概述
|
|
12
|
+
|
|
13
|
+
failproofai 包含两个独立的子系统:
|
|
14
|
+
|
|
15
|
+
1. **钩子处理器** - 一个高速 CLI 子进程,Claude Code 在每次 Agent 工具调用时调用它。负责评估策略并返回决策结果。
|
|
16
|
+
2. **Agent 监控器(仪表板)** - 一个 Next.js Web 应用,用于监控 Agent 会话和管理策略。
|
|
17
|
+
|
|
18
|
+
两个子系统共享 `~/.failproofai/` 目录和项目 `.failproofai/` 目录中的配置文件,但它们作为独立进程运行,仅通过文件系统进行通信。
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 钩子处理器
|
|
23
|
+
|
|
24
|
+
### 与 Claude Code 的集成
|
|
25
|
+
|
|
26
|
+
运行 `failproofai policies --install` 时,它会将如下条目写入 `~/.claude/settings.json`:
|
|
27
|
+
|
|
28
|
+
```json
|
|
29
|
+
{
|
|
30
|
+
"hooks": {
|
|
31
|
+
"PreToolUse": [
|
|
32
|
+
{
|
|
33
|
+
"matcher": "",
|
|
34
|
+
"hooks": [
|
|
35
|
+
{
|
|
36
|
+
"type": "command",
|
|
37
|
+
"command": "failproofai --hook PreToolUse"
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
],
|
|
42
|
+
"PostToolUse": [ ... ]
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
之后,Claude Code 会在每次工具调用前将 `failproofai --hook PreToolUse` 作为子进程调用,并通过 stdin 传入 JSON 负载。
|
|
48
|
+
|
|
49
|
+
### 负载格式
|
|
50
|
+
|
|
51
|
+
```json
|
|
52
|
+
{
|
|
53
|
+
"session_id": "abc123",
|
|
54
|
+
"transcript_path": "/home/user/.claude/projects/myproject/sessions/abc123.jsonl",
|
|
55
|
+
"cwd": "/home/user/myproject",
|
|
56
|
+
"permission_mode": "default",
|
|
57
|
+
"hook_event_name": "PreToolUse",
|
|
58
|
+
"tool_name": "Bash",
|
|
59
|
+
"tool_input": { "command": "sudo apt install nodejs" }
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
对于 `PostToolUse` 事件,负载还包含工具输出结果 `tool_result`。
|
|
64
|
+
|
|
65
|
+
处理器强制限制 stdin 最大为 1 MB。超出此限制的负载将被丢弃,所有策略隐式允许通过。
|
|
66
|
+
|
|
67
|
+
### 响应格式
|
|
68
|
+
|
|
69
|
+
**拒绝(PreToolUse):**
|
|
70
|
+
```json
|
|
71
|
+
{
|
|
72
|
+
"hookSpecificOutput": {
|
|
73
|
+
"permissionDecision": "deny",
|
|
74
|
+
"permissionDecisionReason": "Blocked by failproofai: sudo command blocked"
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**拒绝(PostToolUse):**
|
|
80
|
+
```json
|
|
81
|
+
{
|
|
82
|
+
"hookSpecificOutput": {
|
|
83
|
+
"additionalContext": "Blocked by failproofai because: API key detected in output"
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**指令(除 Stop 事件外的任意事件):**
|
|
89
|
+
```json
|
|
90
|
+
{
|
|
91
|
+
"hookSpecificOutput": {
|
|
92
|
+
"additionalContext": "Instruction from failproofai: Verify tests pass before committing."
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**Stop 事件的指令:**
|
|
98
|
+
- 退出码:`2`
|
|
99
|
+
- 原因写入 stderr(而非 stdout)
|
|
100
|
+
|
|
101
|
+
**允许:**
|
|
102
|
+
- 退出码:`0`
|
|
103
|
+
- stdout 为空
|
|
104
|
+
|
|
105
|
+
**允许并携带消息(测试版):**
|
|
106
|
+
|
|
107
|
+
自 v0.0.2-beta.3 起,`allow(message)` 允许策略在操作被允许时仍向 Claude 发送信息性上下文。钩子处理器将以下 JSON 写入 **stdout**(这不是配置文件——这是处理器对 Claude Code 的响应,与 deny 和 instruct 响应的方式相同):
|
|
108
|
+
|
|
109
|
+
```json
|
|
110
|
+
// Written to stdout by the hook handler process
|
|
111
|
+
{
|
|
112
|
+
"hookSpecificOutput": {
|
|
113
|
+
"additionalContext": "All CI checks passed on branch 'feat/my-feature'."
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
- 退出码:`0`(操作被允许)
|
|
118
|
+
- 当多个策略返回带消息的 `allow` 时,其消息将以换行符拼接为一个 `additionalContext` 字符串
|
|
119
|
+
- 若没有策略提供消息,stdout 为空(与之前行为相同)
|
|
120
|
+
|
|
121
|
+
### 处理流水线
|
|
122
|
+
|
|
123
|
+
`src/hooks/handler.ts` 实现了完整的处理流水线:
|
|
124
|
+
|
|
125
|
+
```text
|
|
126
|
+
stdin JSON
|
|
127
|
+
→ 解析负载(最大 1 MB)
|
|
128
|
+
→ 提取会话元数据(session_id、cwd、tool_name、tool_input 等)
|
|
129
|
+
→ readMergedHooksConfig(cwd) ← 合并项目 + 本地 + 全局配置
|
|
130
|
+
→ 注册已启用的内置策略(含解析后的参数)
|
|
131
|
+
→ 从 customPoliciesPath 加载自定义策略(如已设置)
|
|
132
|
+
→ 将自定义策略注册到策略注册表
|
|
133
|
+
→ 评估所有策略(先内置,后自定义)
|
|
134
|
+
→ 首个 deny 立即短路
|
|
135
|
+
→ instruct 决策累积
|
|
136
|
+
→ allow 消息累积
|
|
137
|
+
→ 将 JSON 决策写入 stdout
|
|
138
|
+
→ 将事件持久化到 ~/.failproofai/hook-activity.jsonl
|
|
139
|
+
→ 退出
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
整个过程在典型负载下耗时不超过 100ms,且无需 LLM 调用。
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## 配置加载
|
|
147
|
+
|
|
148
|
+
`src/hooks/hooks-config.ts` 实现了三级范围的配置加载。
|
|
149
|
+
|
|
150
|
+
```text
|
|
151
|
+
[1] {cwd}/.failproofai/policies-config.json ← 项目级(最高优先级)
|
|
152
|
+
[2] {cwd}/.failproofai/policies-config.local.json ← 本地级
|
|
153
|
+
[3] ~/.failproofai/policies-config.json ← 全局级(最低优先级)
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
合并逻辑:
|
|
157
|
+
- `enabledPolicies` - 三个文件取去重并集
|
|
158
|
+
- `policyParams` - 按策略名称为键,第一个定义该键的文件完全优先
|
|
159
|
+
- `customPoliciesPath` - 第一个定义它的文件优先
|
|
160
|
+
- `llm` - 第一个定义它的文件优先
|
|
161
|
+
|
|
162
|
+
由于 Web 仪表板不是通过项目 cwd 调用的,它使用 `readHooksConfig()`(仅全局)进行读写。
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## 策略评估
|
|
167
|
+
|
|
168
|
+
`src/hooks/policy-evaluator.ts` 按顺序执行策略。
|
|
169
|
+
|
|
170
|
+
对每条策略:
|
|
171
|
+
|
|
172
|
+
1. 查找策略的 `params` 模式(如果有)。
|
|
173
|
+
2. 从合并后的配置中读取 `policyParams[policy.name]`。
|
|
174
|
+
3. 将用户提供的值覆盖到模式默认值上,生成 `ctx.params`。
|
|
175
|
+
4. 以解析后的上下文调用 `policy.fn(ctx)`。
|
|
176
|
+
5. 若结果为 `deny`,立即停止并返回该决策。
|
|
177
|
+
6. 若结果为 `instruct`,累积消息并继续。
|
|
178
|
+
7. 若结果为 `allow`,继续处理下一条策略。
|
|
179
|
+
|
|
180
|
+
所有策略执行完毕后:
|
|
181
|
+
- 若存在任意 `deny`,输出拒绝响应。
|
|
182
|
+
- 若收集到任意 `instruct`,输出单条指令响应(所有消息拼接)。
|
|
183
|
+
- 否则,输出允许响应(stdout 为空,退出码 0)。
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## 内置策略
|
|
188
|
+
|
|
189
|
+
`src/hooks/builtin-policies.ts` 将全部 26 条内置策略定义为 `BuiltinPolicyDefinition` 对象:
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
interface BuiltinPolicyDefinition {
|
|
193
|
+
name: string;
|
|
194
|
+
description: string;
|
|
195
|
+
fn: (ctx: PolicyContext) => PolicyResult;
|
|
196
|
+
match: {
|
|
197
|
+
events: HookEventType[];
|
|
198
|
+
tools?: string[];
|
|
199
|
+
};
|
|
200
|
+
defaultEnabled: boolean;
|
|
201
|
+
category: string;
|
|
202
|
+
beta?: boolean;
|
|
203
|
+
params?: PolicyParamsSchema;
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
接受 `params` 的策略会声明一个 `PolicyParamsSchema`,为每个参数指定类型和默认值。策略评估器在调用 `fn` 前将解析后的值注入 `ctx.params`。策略函数读取 `ctx.params` 时无需空值判断,因为默认值始终会被预先应用。
|
|
208
|
+
|
|
209
|
+
策略内部的模式匹配使用已解析的命令 token(argv),而非原始字符串匹配。这可防止通过 shell 操作符注入绕过策略(例如,针对 `sudo systemctl status *` 的模式无法通过在命令后追加 `; rm -rf /` 来绕过)。
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## 自定义策略
|
|
214
|
+
|
|
215
|
+
`src/hooks/custom-hooks-registry.ts` 实现了一个基于 `globalThis` 的注册表:
|
|
216
|
+
|
|
217
|
+
```typescript
|
|
218
|
+
const REGISTRY_KEY = "__failproofai_custom_hooks__";
|
|
219
|
+
|
|
220
|
+
export const customPolicies = {
|
|
221
|
+
add(hook: CustomHook): void { ... }
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
export function getCustomHooks(): CustomHook[] { ... }
|
|
225
|
+
export function clearCustomHooks(): void { ... } // used in tests
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
`src/hooks/custom-hooks-loader.ts` 负责加载用户的策略文件:
|
|
229
|
+
|
|
230
|
+
1. 从配置中读取 `customPoliciesPath`;若不存在则跳过。
|
|
231
|
+
2. 解析为绝对路径;检查文件是否存在。
|
|
232
|
+
3. 将所有 `from "failproofai"` 导入重写为实际的 dist 路径,使 `customPolicies` 指向同一个 `globalThis` 注册表。
|
|
233
|
+
4. 递归重写传递性本地导入,确保 ESM 兼容性。
|
|
234
|
+
5. 写入临时 `.mjs` 文件并通过 `import()` 引入入口文件。
|
|
235
|
+
6. 调用 `getCustomHooks()` 获取已注册的钩子。
|
|
236
|
+
7. 在 `finally` 块中清理所有临时文件。
|
|
237
|
+
|
|
238
|
+
遇到任何错误(文件未找到、语法错误、导入失败)时,错误信息会被记录到 `~/.failproofai/hook.log`,加载器返回空数组。内置策略不受影响。
|
|
239
|
+
|
|
240
|
+
自定义策略在所有内置策略之后评估。自定义策略的 `deny` 仍会短路后续自定义策略(但此时所有内置策略已执行完毕)。
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## 活动日志
|
|
245
|
+
|
|
246
|
+
每次钩子事件处理后,处理器会向 `~/.failproofai/hook-activity.jsonl` 追加一行 JSONL 记录:
|
|
247
|
+
|
|
248
|
+
```json
|
|
249
|
+
{
|
|
250
|
+
"timestamp": "2026-04-06T12:34:56.789Z",
|
|
251
|
+
"sessionId": "abc123",
|
|
252
|
+
"eventType": "PreToolUse",
|
|
253
|
+
"toolName": "Bash",
|
|
254
|
+
"policyName": "block-sudo",
|
|
255
|
+
"decision": "deny",
|
|
256
|
+
"reason": "sudo command blocked by failproofai",
|
|
257
|
+
"durationMs": 12
|
|
258
|
+
}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
每条记录对应一条做出非允许决策的策略。允许决策不记录日志(以保持文件精简)。
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## 仪表板架构
|
|
266
|
+
|
|
267
|
+
仪表板是一个 **Next.js 16** 应用,采用 App Router,使用 React Server Components 和 Server Actions。
|
|
268
|
+
|
|
269
|
+
```text
|
|
270
|
+
app/
|
|
271
|
+
layout.tsx ← 根布局(主题、遥测、导航)
|
|
272
|
+
projects/page.tsx ← 服务端组件:列出所有 Claude 项目
|
|
273
|
+
project/[name]/page.tsx ← 服务端组件:列出项目中的会话
|
|
274
|
+
project/[name]/session/
|
|
275
|
+
[sessionId]/page.tsx ← 服务端组件:渲染会话查看器
|
|
276
|
+
policies/page.tsx ← 客户端组件:策略管理 + 活动日志
|
|
277
|
+
actions/
|
|
278
|
+
get-hooks-config.ts ← 读取配置 + 策略列表
|
|
279
|
+
update-hooks-config.ts ← 开启/关闭策略
|
|
280
|
+
update-policy-params.ts ← 更新策略参数
|
|
281
|
+
get-hook-activity.ts ← 分页/搜索活动日志
|
|
282
|
+
install-hooks-web.ts ← 从浏览器安装/移除钩子
|
|
283
|
+
api/
|
|
284
|
+
download/[project]/[session]/route.ts ← 将会话导出为 ZIP/JSONL
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
**数据流:**
|
|
288
|
+
|
|
289
|
+
- 页面组件调用 `lib/projects.ts` 和 `lib/log-entries.ts`,直接从文件系统读取项目/会话数据(读取操作无需 API 层)。
|
|
290
|
+
- 策略页面的所有变更操作(切换、参数更新、安装/移除)均通过 Server Actions 实现。
|
|
291
|
+
- 会话查看器解析 Claude 的 JSONL 转录格式,并渲染消息和工具调用的时间线。
|
|
292
|
+
|
|
293
|
+
**关键设计决策:**
|
|
294
|
+
|
|
295
|
+
- 无数据库——所有持久化状态存储在普通文件中(`~/.failproofai/`、`~/.claude/projects/`)。
|
|
296
|
+
- 变更操作使用 Server Actions——CRUD 操作无需 REST API。
|
|
297
|
+
- 读取页面使用 React Server Components——加快首次加载速度,数据获取无需客户端包。
|
|
298
|
+
- 仅在需要交互的地方使用客户端组件(策略切换、活动搜索、日志查看器)。
|
|
299
|
+
|
|
300
|
+
---
|
|
301
|
+
|
|
302
|
+
## 文件结构
|
|
303
|
+
|
|
304
|
+
```text
|
|
305
|
+
failproofai/
|
|
306
|
+
├── bin/
|
|
307
|
+
│ └── failproofai.mjs # CLI 路由器(hook / dashboard / install 等)
|
|
308
|
+
├── src/hooks/
|
|
309
|
+
│ ├── handler.ts # 钩子事件流水线
|
|
310
|
+
│ ├── builtin-policies.ts # 26 条策略定义
|
|
311
|
+
│ ├── policy-evaluator.ts # 策略执行引擎
|
|
312
|
+
│ ├── policy-registry.ts # 策略注册与查找
|
|
313
|
+
│ ├── policy-types.ts # TypeScript 接口
|
|
314
|
+
│ ├── hooks-config.ts # 多级范围配置加载
|
|
315
|
+
│ ├── custom-hooks-registry.ts # 基于 globalThis 的钩子注册表
|
|
316
|
+
│ ├── custom-hooks-loader.ts # 用户 JS 钩子的 ESM 加载器
|
|
317
|
+
│ ├── manager.ts # 安装 / 移除 / 列出操作
|
|
318
|
+
│ ├── install-prompt.ts # 交互式策略选择提示
|
|
319
|
+
│ ├── hook-logger.ts # 日志写入 hook.log
|
|
320
|
+
│ ├── hook-activity-store.ts # 将活动持久化到 hook-activity.jsonl
|
|
321
|
+
│ └── llm-client.ts # LLM API 客户端(用于 AI 驱动的策略)
|
|
322
|
+
├── app/ # Next.js 仪表板(页面 + 服务端 Actions)
|
|
323
|
+
├── lib/ # 共享工具库
|
|
324
|
+
│ ├── projects.ts # 从文件系统枚举 Claude 项目
|
|
325
|
+
│ ├── log-entries.ts # 解析 Claude 转录 JSONL 格式
|
|
326
|
+
│ ├── paths.ts # 解析系统路径
|
|
327
|
+
│ └── ...
|
|
328
|
+
├── components/ # 共享 React UI 组件
|
|
329
|
+
├── contexts/ # React Context 提供者(主题、自动刷新、遥测)
|
|
330
|
+
├── examples/ # 自定义钩子文件示例
|
|
331
|
+
└── __tests__/ # 单元测试与 E2E 测试
|
|
332
|
+
```
|