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: Тестирование
|
|
3
|
+
description: "Модульные тесты, E2E тесты и вспомогательные инструменты для тестирования"
|
|
4
|
+
icon: flask-vial
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
failproofai имеет два набора тестов: **модульные тесты** (быстрые, с моками) и **сквозные тесты** (реальные вызовы подпроцессов).
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Запуск тестов
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Запустить все модульные тесты один раз
|
|
15
|
+
bun run test:run
|
|
16
|
+
|
|
17
|
+
# Запустить модульные тесты в режиме наблюдения
|
|
18
|
+
bun run test
|
|
19
|
+
|
|
20
|
+
# Запустить E2E тесты (требуется подготовка - см. ниже)
|
|
21
|
+
bun run test:e2e
|
|
22
|
+
|
|
23
|
+
# Проверка типов без сборки
|
|
24
|
+
bunx tsc --noEmit
|
|
25
|
+
|
|
26
|
+
# Проверка кода
|
|
27
|
+
bun run lint
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Модульные тесты
|
|
33
|
+
|
|
34
|
+
Модульные тесты находятся в `__tests__/` и используют [Vitest](https://vitest.dev) с `happy-dom`.
|
|
35
|
+
|
|
36
|
+
```text
|
|
37
|
+
__tests__/
|
|
38
|
+
hooks/
|
|
39
|
+
builtin-policies.test.ts # Логика политик для каждой встроенной
|
|
40
|
+
hooks-config.test.ts # Загрузка конфига и объединение областей
|
|
41
|
+
policy-evaluator.test.ts # Внедрение параметров и порядок оценки
|
|
42
|
+
custom-hooks-registry.test.ts # Реестр globalThis добавления/получения/очистки
|
|
43
|
+
custom-hooks-loader.test.ts # ESM загрузчик, транзитивные импорты, обработка ошибок
|
|
44
|
+
manager.test.ts # Операции установки/удаления/списания
|
|
45
|
+
components/
|
|
46
|
+
sessions-list.test.tsx # Компонент списка сессий
|
|
47
|
+
project-list.test.tsx # Компонент списка проектов
|
|
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
|
+
### Написание модульного теста политики
|
|
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
|
+
## Сквозные тесты
|
|
112
|
+
|
|
113
|
+
E2E тесты вызывают реальный бинарный файл `failproofai` как подпроцесс, передают JSON-полезную нагрузку в stdin и проверяют выходные данные stdout и код выхода. Это тестирует полный путь интеграции, который использует Claude Code.
|
|
114
|
+
|
|
115
|
+
### Подготовка
|
|
116
|
+
|
|
117
|
+
E2E тесты запускают бинарный файл непосредственно из исходного кода репозитория. Перед первым запуском соберите CJS-пакет, который используют файлы пользовательских хуков при импорте из `'failproofai'`:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
bun build src/index.ts --outdir dist --target node --format cjs
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Затем запустите тесты:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
bun run test:e2e
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Пересобирайте `dist/` всякий раз, когда вы изменяете публичный API хуков (`src/hooks/custom-hooks-registry.ts`, `src/hooks/policy-helpers.ts` или `src/hooks/policy-types.ts`).
|
|
130
|
+
|
|
131
|
+
### Структура E2E теста
|
|
132
|
+
|
|
133
|
+
```text
|
|
134
|
+
__tests__/e2e/
|
|
135
|
+
helpers/
|
|
136
|
+
hook-runner.ts # Запуск бинарного файла, передача полезной нагрузки JSON, захват кода выхода + stdout + stderr
|
|
137
|
+
fixture-env.ts # Изолированные на тест временные каталоги с файлами конфига
|
|
138
|
+
payloads.ts # Фабрики полезных нагрузок с точностью Claude для каждого типа события
|
|
139
|
+
hooks/
|
|
140
|
+
builtin-policies.e2e.test.ts # Каждая встроенная политика с реальным подпроцессом
|
|
141
|
+
custom-hooks.e2e.test.ts # Загрузка и оценка пользовательских хуков
|
|
142
|
+
config-scopes.e2e.test.ts # Объединение конфига между проектом/локальным/глобальным
|
|
143
|
+
policy-params.e2e.test.ts # Внедрение параметров для каждой параметризованной политики
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Использование E2E вспомогательных инструментов
|
|
147
|
+
|
|
148
|
+
**`FixtureEnv`** - изолированная среда для каждого теста:
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
import { createFixtureEnv } from "../helpers/fixture-env";
|
|
152
|
+
|
|
153
|
+
const env = createFixtureEnv();
|
|
154
|
+
// env.cwd - временный каталог; передайте как payload.cwd для использования .failproofai/policies-config.json
|
|
155
|
+
// env.home - изолированный домашний каталог; нет утечек реального ~/.failproofai
|
|
156
|
+
|
|
157
|
+
env.writeConfig({
|
|
158
|
+
enabledPolicies: ["block-sudo"],
|
|
159
|
+
policyParams: {
|
|
160
|
+
"block-sudo": { allowPatterns: ["sudo systemctl status"] },
|
|
161
|
+
},
|
|
162
|
+
});
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
`createFixtureEnv()` автоматически регистрирует очистку `afterEach`.
|
|
166
|
+
|
|
167
|
+
**`runHook`** - запуск бинарного файла:
|
|
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`** - готовые фабрики полезных нагрузок:
|
|
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
|
+
### Написание 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
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Формы ответов E2E
|
|
235
|
+
|
|
236
|
+
| Решение | Код выхода | stdout |
|
|
237
|
+
|----------|-----------|--------|
|
|
238
|
+
| `PreToolUse` deny | `0` | `{"hookSpecificOutput":{"permissionDecision":"deny","permissionDecisionReason":"..."}}` |
|
|
239
|
+
| `PostToolUse` deny | `0` | `{"hookSpecificOutput":{"additionalContext":"Blocked ... because: ..."}}` |
|
|
240
|
+
| Instruct (не-Stop) | `0` | `{"hookSpecificOutput":{"additionalContext":"Instruction from failproofai: ..."}}` |
|
|
241
|
+
| Stop instruct | `2` | пустой stdout; причина в stderr |
|
|
242
|
+
| Allow | `0` | пустая строка |
|
|
243
|
+
|
|
244
|
+
### Конфигурация Vitest
|
|
245
|
+
|
|
246
|
+
E2E тесты используют `vitest.config.e2e.mts` с:
|
|
247
|
+
|
|
248
|
+
- `environment: "node"` - глобальные переменные браузера не требуются
|
|
249
|
+
- `pool: "forks"` - истинная изоляция процессов (тесты запускают подпроцессы)
|
|
250
|
+
- `testTimeout: 20_000` - 20 сек на тест (запуск бинарного файла + оценка хука)
|
|
251
|
+
|
|
252
|
+
Пул `forks` важен: рабочие потоки используют совместно `globalThis`, что может помешать тестам, запускающим подпроцессы. Процессные fork избегают этой проблемы.
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
## CI
|
|
257
|
+
|
|
258
|
+
Полный запуск CI (`bun run lint && bunx tsc --noEmit && bun run test:run && bun run build`) должен пройти перед слиянием. Набор E2E запускается как отдельная задача CI параллельно.
|
|
259
|
+
|
|
260
|
+
См. [Contributing](../CONTRIBUTING.md) для полного контрольного списка перед слиянием.
|
|
@@ -17,7 +17,7 @@ bun run test:run
|
|
|
17
17
|
# Run unit tests in watch mode
|
|
18
18
|
bun run test
|
|
19
19
|
|
|
20
|
-
# Run E2E tests (requires setup
|
|
20
|
+
# Run E2E tests (requires setup - see below)
|
|
21
21
|
bun run test:e2e
|
|
22
22
|
|
|
23
23
|
# Type-check without building
|
|
@@ -33,7 +33,7 @@ bun run lint
|
|
|
33
33
|
|
|
34
34
|
Unit tests live in `__tests__/` and use [Vitest](https://vitest.dev) with `happy-dom`.
|
|
35
35
|
|
|
36
|
-
```
|
|
36
|
+
```text
|
|
37
37
|
__tests__/
|
|
38
38
|
hooks/
|
|
39
39
|
builtin-policies.test.ts # Policy logic for each builtin
|
|
@@ -130,7 +130,7 @@ Rebuild `dist/` whenever you change the public hook API (`src/hooks/custom-hooks
|
|
|
130
130
|
|
|
131
131
|
### E2E test structure
|
|
132
132
|
|
|
133
|
-
```
|
|
133
|
+
```text
|
|
134
134
|
__tests__/e2e/
|
|
135
135
|
helpers/
|
|
136
136
|
hook-runner.ts # Spawn the binary, pipe payload JSON, capture exit code + stdout + stderr
|
|
@@ -145,14 +145,14 @@ __tests__/e2e/
|
|
|
145
145
|
|
|
146
146
|
### Using the E2E helpers
|
|
147
147
|
|
|
148
|
-
**`FixtureEnv`**
|
|
148
|
+
**`FixtureEnv`** - isolated per-test environment:
|
|
149
149
|
|
|
150
150
|
```typescript
|
|
151
151
|
import { createFixtureEnv } from "../helpers/fixture-env";
|
|
152
152
|
|
|
153
153
|
const env = createFixtureEnv();
|
|
154
|
-
// env.cwd
|
|
155
|
-
// env.home
|
|
154
|
+
// env.cwd - temp dir; pass as payload.cwd to pick up .failproofai/policies-config.json
|
|
155
|
+
// env.home - isolated home dir; no real ~/.failproofai leaks in
|
|
156
156
|
|
|
157
157
|
env.writeConfig({
|
|
158
158
|
enabledPolicies: ["block-sudo"],
|
|
@@ -164,7 +164,7 @@ env.writeConfig({
|
|
|
164
164
|
|
|
165
165
|
`createFixtureEnv()` registers `afterEach` cleanup automatically.
|
|
166
166
|
|
|
167
|
-
**`runHook`**
|
|
167
|
+
**`runHook`** - invoke the binary:
|
|
168
168
|
|
|
169
169
|
```typescript
|
|
170
170
|
import { runHook } from "../helpers/hook-runner";
|
|
@@ -180,7 +180,7 @@ expect(result.exitCode).toBe(0);
|
|
|
180
180
|
expect(result.parsed?.hookSpecificOutput?.permissionDecision).toBe("deny");
|
|
181
181
|
```
|
|
182
182
|
|
|
183
|
-
**`Payloads`**
|
|
183
|
+
**`Payloads`** - ready-made payload factories:
|
|
184
184
|
|
|
185
185
|
```typescript
|
|
186
186
|
Payloads.preToolUse.bash(command, cwd)
|
|
@@ -245,9 +245,9 @@ describe("block-rm-rf (E2E)", () => {
|
|
|
245
245
|
|
|
246
246
|
E2E tests use `vitest.config.e2e.mts` with:
|
|
247
247
|
|
|
248
|
-
- `environment: "node"`
|
|
249
|
-
- `pool: "forks"`
|
|
250
|
-
- `testTimeout: 20_000`
|
|
248
|
+
- `environment: "node"` - no browser globals needed
|
|
249
|
+
- `pool: "forks"` - true process isolation (tests spawn subprocesses)
|
|
250
|
+
- `testTimeout: 20_000` - 20s per test (binary startup + hook eval)
|
|
251
251
|
|
|
252
252
|
The `forks` pool is important: thread-based workers share `globalThis`, which can interfere with subprocess-spawning tests. Process-based forks avoid this.
|
|
253
253
|
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
---
|
|
2
|
+
---
|
|
3
|
+
title: Mimari
|
|
4
|
+
description: "Hook handler, config yükleme ve policy değerlendirmesinin dahili olarak nasıl çalıştığı"
|
|
5
|
+
icon: sitemap
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Bu belge failproofai'nin dahili işleyişini açıklar: hook sistemi agent tool çağrılarını nasıl keser, yapılandırma nasıl yüklenir ve birleştirilir, policiler nasıl değerlendirilir ve dashboard agent aktivitesini nasıl izler.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Genel Bakış
|
|
13
|
+
|
|
14
|
+
failproofai iki bağımsız alt sistemden oluşur:
|
|
15
|
+
|
|
16
|
+
1. **Hook handler** - Claude Code'un her agent tool çağrısında invoke ettiği hızlı bir CLI alt işlemi. Policileri değerlendirir ve bir karar döner.
|
|
17
|
+
2. **Agent Monitor (Dashboard)** - Agent oturumlarını izlemek ve policileri yönetmek için bir Next.js web uygulaması.
|
|
18
|
+
|
|
19
|
+
Her iki alt sistem `~/.failproofai/` ve projenin `.failproofai/` dizininde yapılandırma dosyalarını paylaşır, ancak ayrı işlemler olarak çalışırlar ve yalnızca dosya sistemi üzerinden iletişim kurarlar.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Hook handler
|
|
24
|
+
|
|
25
|
+
### Claude Code ile Entegrasyon
|
|
26
|
+
|
|
27
|
+
`failproofai policies --install` çalıştırdığınızda, `~/.claude/settings.json` dosyasına şu gibi girişler yazar:
|
|
28
|
+
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"hooks": {
|
|
32
|
+
"PreToolUse": [
|
|
33
|
+
{
|
|
34
|
+
"matcher": "",
|
|
35
|
+
"hooks": [
|
|
36
|
+
{
|
|
37
|
+
"type": "command",
|
|
38
|
+
"command": "failproofai --hook PreToolUse"
|
|
39
|
+
}
|
|
40
|
+
]
|
|
41
|
+
}
|
|
42
|
+
],
|
|
43
|
+
"PostToolUse": [ ... ]
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Claude Code daha sonra her tool çağrısından önce `failproofai --hook PreToolUse` komutunu bir alt işlem olarak invoke eder, stdin üzerinde bir JSON payload iletir.
|
|
49
|
+
|
|
50
|
+
### Payload formatı
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
{
|
|
54
|
+
"session_id": "abc123",
|
|
55
|
+
"transcript_path": "/home/user/.claude/projects/myproject/sessions/abc123.jsonl",
|
|
56
|
+
"cwd": "/home/user/myproject",
|
|
57
|
+
"permission_mode": "default",
|
|
58
|
+
"hook_event_name": "PreToolUse",
|
|
59
|
+
"tool_name": "Bash",
|
|
60
|
+
"tool_input": { "command": "sudo apt install nodejs" }
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
`PostToolUse` olayları için, payload ayrıca tool'un çıktısını içeren `tool_result` öğesini içerir.
|
|
65
|
+
|
|
66
|
+
Handler 1 MB'lık stdin sınırını zorunlu kılar. Bu limiti aşan payload'lar atılır ve tüm policiler zımnen izin verir.
|
|
67
|
+
|
|
68
|
+
### Yanıt formatı
|
|
69
|
+
|
|
70
|
+
**Reddet (PreToolUse):**
|
|
71
|
+
```json
|
|
72
|
+
{
|
|
73
|
+
"hookSpecificOutput": {
|
|
74
|
+
"permissionDecision": "deny",
|
|
75
|
+
"permissionDecisionReason": "Blocked by failproofai: sudo command blocked"
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**Reddet (PostToolUse):**
|
|
81
|
+
```json
|
|
82
|
+
{
|
|
83
|
+
"hookSpecificOutput": {
|
|
84
|
+
"additionalContext": "Blocked by failproofai because: API key detected in output"
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**Talimat (Stop dışındaki herhangi bir olay):**
|
|
90
|
+
```json
|
|
91
|
+
{
|
|
92
|
+
"hookSpecificOutput": {
|
|
93
|
+
"additionalContext": "Instruction from failproofai: Verify tests pass before committing."
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**Stop olayı talimatı:**
|
|
99
|
+
- Çıkış kodu: `2`
|
|
100
|
+
- Neden stderr'e yazılır (stdout'a değil)
|
|
101
|
+
|
|
102
|
+
**İzin Ver:**
|
|
103
|
+
- Çıkış kodu: `0`
|
|
104
|
+
- Boş stdout
|
|
105
|
+
|
|
106
|
+
**İzinle mesaj (beta):**
|
|
107
|
+
|
|
108
|
+
v0.0.2-beta.3'ten itibaren `allow(message)`, bir policy işleme izin verildiğinde bile Claude'a bilgilendirici bağlam gönderebilir. Hook handler aşağıdaki JSON'u **stdout'a** yazar (bir config dosyasına değil — bu handler'ın Claude Code'a yanıtıdır, reddet ve talimat yanıtları gibi):
|
|
109
|
+
|
|
110
|
+
```json
|
|
111
|
+
// Hook handler işlemi tarafından stdout'a yazılır
|
|
112
|
+
{
|
|
113
|
+
"hookSpecificOutput": {
|
|
114
|
+
"additionalContext": "All CI checks passed on branch 'feat/my-feature'."
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
- Çıkış kodu: `0` (işleme izin verilir)
|
|
119
|
+
- Birden çok policy `allow` ile mesaj döndüğünde, mesajları satır sonlarıyla birleştirilmiş bir `additionalContext` dizesine katılır
|
|
120
|
+
- Hiçbir policy mesaj sağlamıyorsa, stdout boştur (öncekiyle aynı)
|
|
121
|
+
|
|
122
|
+
### İşleme hattı
|
|
123
|
+
|
|
124
|
+
`src/hooks/handler.ts` tam hattı uygular:
|
|
125
|
+
|
|
126
|
+
```text
|
|
127
|
+
stdin JSON
|
|
128
|
+
→ parse payload (max 1 MB)
|
|
129
|
+
→ extract session metadata (session_id, cwd, tool_name, tool_input, etc.)
|
|
130
|
+
→ readMergedHooksConfig(cwd) ← merges project + local + global config
|
|
131
|
+
→ register enabled builtin policies with resolved params
|
|
132
|
+
→ load custom policies from customPoliciesPath (if set)
|
|
133
|
+
→ register custom policies into policy registry
|
|
134
|
+
→ evaluate all policies (builtins first, then custom)
|
|
135
|
+
→ first deny short-circuits
|
|
136
|
+
→ instruct decisions accumulate
|
|
137
|
+
→ allow messages accumulate
|
|
138
|
+
→ write JSON decision to stdout
|
|
139
|
+
→ persist event to ~/.failproofai/hook-activity.jsonl
|
|
140
|
+
→ exit
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Tipik payload'lar için tüm işlem LLM çağrıları olmadan 100ms altında çalışır.
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## Yapılandırma yükleme
|
|
148
|
+
|
|
149
|
+
`src/hooks/hooks-config.ts` üç kapsamlı config yüklemeyi uygular.
|
|
150
|
+
|
|
151
|
+
```text
|
|
152
|
+
[1] {cwd}/.failproofai/policies-config.json ← project (highest priority)
|
|
153
|
+
[2] {cwd}/.failproofai/policies-config.local.json ← local
|
|
154
|
+
[3] ~/.failproofai/policies-config.json ← global (lowest priority)
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Birleştirme mantığı:
|
|
158
|
+
- `enabledPolicies` - üç dosya arasında birleştirilmiş tekil union
|
|
159
|
+
- `policyParams` - policy başına anahtar, bunu tanımlayan ilk dosya tamamen kazanır
|
|
160
|
+
- `customPoliciesPath` - bunu tanımlayan ilk dosya kazanır
|
|
161
|
+
- `llm` - bunu tanımlayan ilk dosya kazanır
|
|
162
|
+
|
|
163
|
+
Web dashboard, project cwd ile invoke edilmediği için okuma ve yazma için `readHooksConfig()` (yalnızca global) kullanır.
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## Policy değerlendirmesi
|
|
168
|
+
|
|
169
|
+
`src/hooks/policy-evaluator.ts` policileri sırayla çalıştırır.
|
|
170
|
+
|
|
171
|
+
Her policy için:
|
|
172
|
+
|
|
173
|
+
1. Policy'nin `params` şemasını ara (varsa).
|
|
174
|
+
2. Birleştirilmiş config'ten `policyParams[policy.name]` oku.
|
|
175
|
+
3. Kullanıcı tarafından sağlanan değerleri schema varsayılanları üzerine birleştirerek `ctx.params` oluştur.
|
|
176
|
+
4. Çözümlenen context ile `policy.fn(ctx)` çağır.
|
|
177
|
+
5. Sonuç `deny` ise, hemen dur ve bu kararı döndür.
|
|
178
|
+
6. Sonuç `instruct` ise, mesajı birikdir ve devam et.
|
|
179
|
+
7. Sonuç `allow` ise, sonraki policiye geç.
|
|
180
|
+
|
|
181
|
+
Tüm policiler çalıştıktan sonra:
|
|
182
|
+
- Herhangi bir `deny` döndürülüyse, deny yanıtını yayınla.
|
|
183
|
+
- Herhangi bir `instruct` dönüşü toplanmışsa, tüm mesajlar birleştirilmiş tek bir instruct yanıtı yayınla.
|
|
184
|
+
- Aksi halde, allow yanıtını yayınla (boş stdout, exit 0).
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## Yerleşik policiler
|
|
189
|
+
|
|
190
|
+
`src/hooks/builtin-policies.ts` 26 yerleşik policy'yi `BuiltinPolicyDefinition` nesneleri olarak tanımlar:
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
interface BuiltinPolicyDefinition {
|
|
194
|
+
name: string;
|
|
195
|
+
description: string;
|
|
196
|
+
fn: (ctx: PolicyContext) => PolicyResult;
|
|
197
|
+
match: {
|
|
198
|
+
events: HookEventType[];
|
|
199
|
+
tools?: string[];
|
|
200
|
+
};
|
|
201
|
+
defaultEnabled: boolean;
|
|
202
|
+
category: string;
|
|
203
|
+
beta?: boolean;
|
|
204
|
+
params?: PolicyParamsSchema;
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
`params` kabul eden policiler, her parametre için türler ve varsayılanlar ile bir `PolicyParamsSchema` bildirirler. Policy değerlendiricisi çözümlenen değerleri `fn` çağrılmadan önce `ctx.params` içerisine enjekte eder. Policy fonksiyonları `ctx.params` okur, null kontrol etmez çünkü varsayılanlar her zaman önce uygulanır.
|
|
209
|
+
|
|
210
|
+
Policilerin içindeki desen eşleştirmesi, ham string eşleştirmesinde değil, ayrıştırılmış command token'larını (argv) kullanır. Bu, shell operatörü enjeksiyonu yoluyla bypass'ı engeller (örn. `sudo systemctl status *` için bir desen `;` ekleyerek bypass edilemez rm -rf /`).
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## Özel policiler
|
|
215
|
+
|
|
216
|
+
`src/hooks/custom-hooks-registry.ts` `globalThis` destekli bir registry uygular:
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
const REGISTRY_KEY = "__failproofai_custom_hooks__";
|
|
220
|
+
|
|
221
|
+
export const customPolicies = {
|
|
222
|
+
add(hook: CustomHook): void { ... }
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
export function getCustomHooks(): CustomHook[] { ... }
|
|
226
|
+
export function clearCustomHooks(): void { ... } // used in tests
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
`src/hooks/custom-hooks-loader.ts` kullanıcı policy dosyasını yükler:
|
|
230
|
+
|
|
231
|
+
1. Config'ten `customPoliciesPath` oku; yoksa atla.
|
|
232
|
+
2. Mutlak yola çöz; dosyayı kontrol et var mı.
|
|
233
|
+
3. Tüm `from "failproofai"` importlarını gerçek dist path'e yeniden yaz böylece `customPolicies` aynı `globalThis` registry'ye çözülür.
|
|
234
|
+
4. ESM uyumluluğunu sağlamak için geçişli yerel importları yinelemeli olarak yeniden yaz.
|
|
235
|
+
5. Geçici `.mjs` dosyaları yaz ve giriş dosyasını `import()` et.
|
|
236
|
+
6. Kayıtlı hook'ları almak için `getCustomHooks()` çağır.
|
|
237
|
+
7. Tüm temp dosyaları bir `finally` bloğunda temizle.
|
|
238
|
+
|
|
239
|
+
Herhangi bir hata (dosya bulunamadı, söz dizimi hatası, import başarısızlığı) durumunda, hata `~/.failproofai/hook.log` dosyasına kaydedilir ve loader boş bir dizi döner. Yerleşik policiler etkilenmez.
|
|
240
|
+
|
|
241
|
+
Özel policiler tüm yerleşik policilerden sonra değerlendirilir. Bir özel policy `deny` yine de diğer özel policileri kısa devreye soksa da (yerleşik policilerin tümü o noktada zaten çalıştırılmıştır).
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## Aktivite Logging
|
|
246
|
+
|
|
247
|
+
Her hook olayından sonra, handler `~/.failproofai/hook-activity.jsonl` dosyasına bir JSONL satırı ekler:
|
|
248
|
+
|
|
249
|
+
```json
|
|
250
|
+
{
|
|
251
|
+
"timestamp": "2026-04-06T12:34:56.789Z",
|
|
252
|
+
"sessionId": "abc123",
|
|
253
|
+
"eventType": "PreToolUse",
|
|
254
|
+
"toolName": "Bash",
|
|
255
|
+
"policyName": "block-sudo",
|
|
256
|
+
"decision": "deny",
|
|
257
|
+
"reason": "sudo command blocked by failproofai",
|
|
258
|
+
"durationMs": 12
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
Non-allow kararı alan her policy için bir satır. Allow kararları kaydedilmez (dosya küçük tutmak için).
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
## Dashboard mimarisi
|
|
267
|
+
|
|
268
|
+
Dashboard, App Router ile React Server Components ve Server Actions kullanan bir **Next.js 16** uygulamasıdır.
|
|
269
|
+
|
|
270
|
+
```text
|
|
271
|
+
app/
|
|
272
|
+
layout.tsx ← Root layout (theme, telemetry, nav)
|
|
273
|
+
projects/page.tsx ← Server component: list all Claude projects
|
|
274
|
+
project/[name]/page.tsx ← Server component: list sessions in a project
|
|
275
|
+
project/[name]/session/
|
|
276
|
+
[sessionId]/page.tsx ← Server component: render session viewer
|
|
277
|
+
policies/page.tsx ← Client component: policy management + activity log
|
|
278
|
+
actions/
|
|
279
|
+
get-hooks-config.ts ← Read config + policy list
|
|
280
|
+
update-hooks-config.ts ← Toggle policy on/off
|
|
281
|
+
update-policy-params.ts ← Update policy parameters
|
|
282
|
+
get-hook-activity.ts ← Paginate/search activity log
|
|
283
|
+
install-hooks-web.ts ← Install/remove hooks from the browser
|
|
284
|
+
api/
|
|
285
|
+
download/[project]/[session]/route.ts ← Export session as ZIP/JSONL
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
**Veri akışı:**
|
|
289
|
+
|
|
290
|
+
- Sayfa bileşenleri proje/oturum verilerini doğrudan dosya sisteminden okumak için `lib/projects.ts` ve `lib/log-entries.ts` çağırır (okumalar için API katmanı yok).
|
|
291
|
+
- Policies sayfası tüm mutasyonlar (toggle, params güncelleme, install/remove) için Server Actions kullanır.
|
|
292
|
+
- Oturum viewer'ı Claude'un JSONL transkript formatını ayrıştırır ve mesajlar ile tool çağrılarının bir zaman çizelgesini renderler.
|
|
293
|
+
|
|
294
|
+
**Temel tasarım kararları:**
|
|
295
|
+
|
|
296
|
+
- Veritabanı yok - tüm kalıcı state düz dosyalardadır (`~/.failproofai/`, `~/.claude/projects/`).
|
|
297
|
+
- Mutasyonlar için Server Actions - CRUD işlemleri için REST API gerekli değil.
|
|
298
|
+
- Okuma sayfaları için React Server Components - daha hızlı ilk yükleme, veri getirme için client bundle yok.
|
|
299
|
+
- Client bileşenleri sadece etkileşimlilik gerekli yerlerde (policy toggle'ları, aktivite arama, log viewer).
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## Dosya düzeni
|
|
304
|
+
|
|
305
|
+
```text
|
|
306
|
+
failproofai/
|
|
307
|
+
├── bin/
|
|
308
|
+
│ └── failproofai.mjs # CLI router (hook / dashboard / install / etc.)
|
|
309
|
+
├── src/hooks/
|
|
310
|
+
│ ├── handler.ts # Hook event pipeline
|
|
311
|
+
│ ├── builtin-policies.ts # 26 policy definitions
|
|
312
|
+
│ ├── policy-evaluator.ts # Policy execution engine
|
|
313
|
+
│ ├── policy-registry.ts # Policy registration and lookup
|
|
314
|
+
│ ├── policy-types.ts # TypeScript interfaces
|
|
315
|
+
│ ├── hooks-config.ts # Multi-scope config loading
|
|
316
|
+
│ ├── custom-hooks-registry.ts # globalThis-backed hook registry
|
|
317
|
+
│ ├── custom-hooks-loader.ts # ESM loader for user JS hooks
|
|
318
|
+
│ ├── manager.ts # install / remove / list operations
|
|
319
|
+
│ ├── install-prompt.ts # Interactive policy selection prompt
|
|
320
|
+
│ ├── hook-logger.ts # Logging to hook.log
|
|
321
|
+
│ ├── hook-activity-store.ts # Persist activity to hook-activity.jsonl
|
|
322
|
+
│ └── llm-client.ts # LLM API client (for AI-powered policies)
|
|
323
|
+
├── app/ # Next.js dashboard (pages + server actions)
|
|
324
|
+
├── lib/ # Shared utilities
|
|
325
|
+
│ ├── projects.ts # Enumerate Claude projects from filesystem
|
|
326
|
+
│ ├── log-entries.ts # Parse Claude transcript JSONL format
|
|
327
|
+
│ ├── paths.ts # Resolve system paths
|
|
328
|
+
│ └── ...
|
|
329
|
+
├── components/ # Shared React UI components
|
|
330
|
+
├── contexts/ # React context providers (theme, auto-refresh, telemetry)
|
|
331
|
+
├── examples/ # Example custom hook files
|
|
332
|
+
└── __tests__/ # Unit and E2E tests
|
|
333
|
+
```
|