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
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { resolve, join } from "node:path";
|
|
5
5
|
import { readFile, writeFile, stat, open } from "node:fs/promises";
|
|
6
|
-
import { execSync } from "node:child_process";
|
|
6
|
+
import { execSync, execFileSync } from "node:child_process";
|
|
7
7
|
import { homedir } from "node:os";
|
|
8
8
|
import type { BuiltinPolicyDefinition, PolicyContext, PolicyResult, PolicyParamsSchema } from "./policy-types";
|
|
9
9
|
import { allow, deny, instruct } from "./policy-helpers";
|
|
@@ -86,7 +86,7 @@ const PUBLISH_CMD_RE = /(?:npm\s+publish|bun\s+publish|pnpm\s+publish|yarn\s+npm
|
|
|
86
86
|
|
|
87
87
|
// protectEnvVars
|
|
88
88
|
const ENV_PRINTENV_RE = /(?:^|\s|;|&&|\|\|)(?:env|printenv)(?:\s|$|;|&&|\|)/;
|
|
89
|
-
const ECHO_ENV_RE = /echo\s
|
|
89
|
+
const ECHO_ENV_RE = /echo\s+.*\$\{?[A-Za-z_]/;
|
|
90
90
|
const EXPORT_RE = /(?:^|\s|;|&&|\|\|)export\s+\w+/;
|
|
91
91
|
const PS_ENV_VAR_RE = /\$env:[A-Za-z_]/i;
|
|
92
92
|
const PS_CHILDITEM_ENV_RE = /(?:Get-ChildItem|dir|gci|ls)\s+Env:/i;
|
|
@@ -103,7 +103,7 @@ const PS_ELEVATION_RE = /Start-Process\s+.*-Verb\s+RunAs/i;
|
|
|
103
103
|
const RUNAS_RE = /(?:^|;|&&|\|\|)\s*runas\s/i;
|
|
104
104
|
|
|
105
105
|
// blockCurlPipeSh
|
|
106
|
-
const CURL_PIPE_SH_RE = /(?:curl|wget)\s.*\|\s*(?:sh|bash|zsh)/;
|
|
106
|
+
const CURL_PIPE_SH_RE = /(?:curl|wget)\s.*\|\s*(?:sh|bash|zsh|dash|ksh|csh|tcsh|fish|ash)\b/;
|
|
107
107
|
const PS_WEB_PIPE_RE = /(?:Invoke-WebRequest|iwr|Invoke-RestMethod|irm)\s+.*\|\s*(?:Invoke-Expression|iex)/i;
|
|
108
108
|
|
|
109
109
|
// blockForcePush
|
|
@@ -145,12 +145,73 @@ const TMUX_DETACH_RE = /\btmux\s+(?:new-session|new)\b[^|&;]*-d\b/;
|
|
|
145
145
|
const DISOWN_RE = /\bdisown\b/;
|
|
146
146
|
const BACKGROUND_AMPERSAND_RE = /(?<![&|])\s?&\s*(?:$|#|;)/;
|
|
147
147
|
|
|
148
|
-
//
|
|
148
|
+
// Caches the current branch per cwd to avoid repeated execSync calls.
|
|
149
149
|
// Trade-off: if the user switches branches externally mid-session, the cache serves
|
|
150
150
|
// the stale value until the process restarts. This is acceptable since branch switches
|
|
151
151
|
// during an active Claude session are rare.
|
|
152
152
|
const gitBranchCache = new Map<string, string>();
|
|
153
153
|
|
|
154
|
+
function getCurrentBranch(cwd: string): string | null {
|
|
155
|
+
try {
|
|
156
|
+
let branch = gitBranchCache.get(cwd);
|
|
157
|
+
if (branch === undefined) {
|
|
158
|
+
branch = execSync("git rev-parse --abbrev-ref HEAD", {
|
|
159
|
+
cwd,
|
|
160
|
+
encoding: "utf8",
|
|
161
|
+
timeout: 3000,
|
|
162
|
+
}).trim();
|
|
163
|
+
gitBranchCache.set(cwd, branch);
|
|
164
|
+
}
|
|
165
|
+
return branch || null;
|
|
166
|
+
} catch {
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function getHeadSha(cwd: string): string | null {
|
|
172
|
+
try {
|
|
173
|
+
const sha = execSync("git rev-parse HEAD", {
|
|
174
|
+
cwd,
|
|
175
|
+
encoding: "utf8",
|
|
176
|
+
timeout: 3000,
|
|
177
|
+
}).trim();
|
|
178
|
+
return sha || null;
|
|
179
|
+
} catch {
|
|
180
|
+
return null;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
interface CiCheck {
|
|
185
|
+
name: string;
|
|
186
|
+
status: string;
|
|
187
|
+
conclusion: string;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/** Fetch third-party check runs (non-GitHub-Actions) for a commit via the Checks API. */
|
|
191
|
+
function getThirdPartyCheckRuns(cwd: string, sha: string): CiCheck[] {
|
|
192
|
+
try {
|
|
193
|
+
const json = execFileSync(
|
|
194
|
+
"gh",
|
|
195
|
+
[
|
|
196
|
+
"api",
|
|
197
|
+
`repos/{owner}/{repo}/commits/${sha}/check-runs`,
|
|
198
|
+
"--jq",
|
|
199
|
+
'.check_runs | map(select(.app.slug != "github-actions")) | map({name: .name, status: .status, conclusion: (.conclusion // "")})',
|
|
200
|
+
],
|
|
201
|
+
{
|
|
202
|
+
cwd,
|
|
203
|
+
encoding: "utf8",
|
|
204
|
+
timeout: 15000,
|
|
205
|
+
},
|
|
206
|
+
).trim();
|
|
207
|
+
|
|
208
|
+
if (!json || json === "[]") return [];
|
|
209
|
+
return JSON.parse(json) as CiCheck[];
|
|
210
|
+
} catch {
|
|
211
|
+
return [];
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
154
215
|
/**
|
|
155
216
|
* Check if a command matches an allow pattern using token-by-token comparison.
|
|
156
217
|
* The "*" token is a wildcard. Extra command tokens beyond the pattern are allowed,
|
|
@@ -423,7 +484,8 @@ function rmTargetIsAllowed(cmd: string, allowPaths: string[]): boolean {
|
|
|
423
484
|
if (rmIdx < 0) continue;
|
|
424
485
|
// Only validate recursive rm segments — non-recursive rm has no catastrophic-deletion risk
|
|
425
486
|
const flagTokens = tokens.slice(rmIdx + 1).filter((t) => /^-[^-]/.test(t));
|
|
426
|
-
|
|
487
|
+
const longFlagsInSeg = tokens.slice(rmIdx + 1).filter((t) => /^--/.test(t));
|
|
488
|
+
if (!/r/i.test(flagTokens.join("")) && !longFlagsInSeg.some(f => /^--recursive$/i.test(f))) continue;
|
|
427
489
|
const pathArgs = tokens.slice(rmIdx + 1).filter((t) => !t.startsWith("-"));
|
|
428
490
|
for (const target of pathArgs) {
|
|
429
491
|
const normalized = target.replace(/\/\*$/, "").replace(/\/+$/, "") || "/";
|
|
@@ -448,7 +510,10 @@ function rmTargetIsAllowed(cmd: string, allowPaths: string[]): boolean {
|
|
|
448
510
|
function blockRmRf(ctx: PolicyContext): PolicyResult {
|
|
449
511
|
if (ctx.toolName !== "Bash") return allow();
|
|
450
512
|
const cmd = getCommand(ctx);
|
|
451
|
-
const hasDestructivePath =
|
|
513
|
+
const hasDestructivePath = parseArgvTokens(cmd).some((token) => {
|
|
514
|
+
const normalized = token.replace(/\/\*$/, "").replace(/\/+$/, "") || (token.startsWith("/") ? "/" : "");
|
|
515
|
+
return normalized === "/" || normalized === "~" || /^\/[A-Za-z_][\w.-]*$/.test(normalized);
|
|
516
|
+
});
|
|
452
517
|
|
|
453
518
|
// Combined flags in one token: rm -rf /, rm -fr /
|
|
454
519
|
if (hasDestructivePath && (
|
|
@@ -464,7 +529,10 @@ function blockRmRf(ctx: PolicyContext): PolicyResult {
|
|
|
464
529
|
if (hasDestructivePath && /\brm\b/.test(cmd)) {
|
|
465
530
|
const tokens = parseArgvTokens(cmd);
|
|
466
531
|
const shortFlags = tokens.filter((t) => /^-[^-]/.test(t)).join("");
|
|
467
|
-
|
|
532
|
+
const longFlags = tokens.filter((t) => /^--/.test(t));
|
|
533
|
+
const hasRecursive = /r/i.test(shortFlags) || longFlags.some(f => /^--recursive$/i.test(f));
|
|
534
|
+
const hasForce = /f/.test(shortFlags) || longFlags.some(f => /^--force$/i.test(f));
|
|
535
|
+
if (hasRecursive && hasForce) {
|
|
468
536
|
const allowPaths = ((ctx.params?.allowPaths ?? []) as string[]);
|
|
469
537
|
if (rmTargetIsAllowed(cmd, allowPaths)) return allow();
|
|
470
538
|
return deny("Catastrophic deletion blocked");
|
|
@@ -627,24 +695,14 @@ function blockWorkOnMain(ctx: PolicyContext): PolicyResult {
|
|
|
627
695
|
const cwd = ctx.session?.cwd;
|
|
628
696
|
if (!cwd) return allow();
|
|
629
697
|
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
gitBranchCache.set(cwd, branch);
|
|
639
|
-
}
|
|
640
|
-
const protectedBranches = ((ctx.params?.protectedBranches ?? ["main", "master"]) as string[]);
|
|
641
|
-
if (protectedBranches.includes(branch)) {
|
|
642
|
-
return deny(
|
|
643
|
-
`Git ${cmd.match(/git\s+(\S+)/)?.[1] ?? "operation"} on ${branch} is blocked. Create a feature branch first.`,
|
|
644
|
-
);
|
|
645
|
-
}
|
|
646
|
-
} catch {
|
|
647
|
-
return allow();
|
|
698
|
+
const branch = getCurrentBranch(cwd);
|
|
699
|
+
if (!branch) return allow();
|
|
700
|
+
|
|
701
|
+
const protectedBranches = ((ctx.params?.protectedBranches ?? ["main", "master"]) as string[]);
|
|
702
|
+
if (protectedBranches.includes(branch)) {
|
|
703
|
+
return deny(
|
|
704
|
+
`Git ${cmd.match(/git\s+(\S+)/)?.[1] ?? "operation"} on ${branch} is blocked. Create a feature branch first.`,
|
|
705
|
+
);
|
|
648
706
|
}
|
|
649
707
|
return allow();
|
|
650
708
|
}
|
|
@@ -786,6 +844,273 @@ function warnBackgroundProcess(ctx: PolicyContext): PolicyResult {
|
|
|
786
844
|
return allow();
|
|
787
845
|
}
|
|
788
846
|
|
|
847
|
+
// -- Workflow (Stop event) policies --
|
|
848
|
+
|
|
849
|
+
function requireCommitBeforeStop(ctx: PolicyContext): PolicyResult {
|
|
850
|
+
const cwd = ctx.session?.cwd;
|
|
851
|
+
if (!cwd) return allow("No working directory available, skipping commit check.");
|
|
852
|
+
|
|
853
|
+
try {
|
|
854
|
+
const status = execSync("git status --porcelain", {
|
|
855
|
+
cwd,
|
|
856
|
+
encoding: "utf8",
|
|
857
|
+
timeout: 5000,
|
|
858
|
+
}).trim();
|
|
859
|
+
|
|
860
|
+
if (status.length > 0) {
|
|
861
|
+
return deny(
|
|
862
|
+
"You have uncommitted changes in the working directory. Commit all changes before stopping.",
|
|
863
|
+
);
|
|
864
|
+
}
|
|
865
|
+
return allow("All changes are committed.");
|
|
866
|
+
} catch {
|
|
867
|
+
return allow("Not a git repository, skipping commit check.");
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
function requirePushBeforeStop(ctx: PolicyContext): PolicyResult {
|
|
872
|
+
const cwd = ctx.session?.cwd;
|
|
873
|
+
if (!cwd) return allow("No working directory available, skipping push check.");
|
|
874
|
+
|
|
875
|
+
try {
|
|
876
|
+
const remotes = execSync("git remote", {
|
|
877
|
+
cwd,
|
|
878
|
+
encoding: "utf8",
|
|
879
|
+
timeout: 3000,
|
|
880
|
+
}).trim();
|
|
881
|
+
|
|
882
|
+
if (!remotes) return allow("No git remote configured, skipping push check.");
|
|
883
|
+
|
|
884
|
+
const remote = (ctx.params?.remote as string) ?? "origin";
|
|
885
|
+
|
|
886
|
+
const branch = getCurrentBranch(cwd);
|
|
887
|
+
if (!branch || branch === "HEAD") return allow("Detached HEAD, skipping push check.");
|
|
888
|
+
|
|
889
|
+
const baseBranch = (ctx.params?.baseBranch as string) ?? "main";
|
|
890
|
+
|
|
891
|
+
// If on the base branch itself, no push of a feature branch is needed
|
|
892
|
+
if (branch === baseBranch) {
|
|
893
|
+
return allow(`On base branch "${baseBranch}", skipping push check.`);
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
// Check if branch has diverged from base in any meaningful way
|
|
897
|
+
try {
|
|
898
|
+
const ahead = execFileSync(
|
|
899
|
+
"git",
|
|
900
|
+
["log", `${remote}/${baseBranch}..HEAD`, "--oneline"],
|
|
901
|
+
{ cwd, encoding: "utf8", timeout: 5000 },
|
|
902
|
+
).trim();
|
|
903
|
+
|
|
904
|
+
if (!ahead) {
|
|
905
|
+
// No commits ahead — branch is fully merged (regular merge / fast-forward)
|
|
906
|
+
return allow(`No commits ahead of ${remote}/${baseBranch}, skipping push check.`);
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
// Commits exist but might be from a squash-merged PR.
|
|
910
|
+
// Check actual file diff — if trees are identical, work is already in base.
|
|
911
|
+
const diff = execFileSync(
|
|
912
|
+
"git",
|
|
913
|
+
["diff", "--stat", `${remote}/${baseBranch}`, "HEAD"],
|
|
914
|
+
{ cwd, encoding: "utf8", timeout: 5000 },
|
|
915
|
+
).trim();
|
|
916
|
+
|
|
917
|
+
if (!diff) {
|
|
918
|
+
return allow(`No file changes compared to ${remote}/${baseBranch}, skipping push check.`);
|
|
919
|
+
}
|
|
920
|
+
} catch {
|
|
921
|
+
// remote/{baseBranch} ref missing — fall through to existing push checks
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
// Check if remote tracking branch exists
|
|
925
|
+
let hasTracking = false;
|
|
926
|
+
try {
|
|
927
|
+
execFileSync("git", ["rev-parse", "--verify", `${remote}/${branch}`], {
|
|
928
|
+
cwd,
|
|
929
|
+
encoding: "utf8",
|
|
930
|
+
timeout: 3000,
|
|
931
|
+
});
|
|
932
|
+
hasTracking = true;
|
|
933
|
+
} catch {
|
|
934
|
+
// Remote tracking branch does not exist
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
if (!hasTracking) {
|
|
938
|
+
return deny(
|
|
939
|
+
`Branch "${branch}" has not been pushed to remote "${remote}". ` +
|
|
940
|
+
`Push your branch with: git push -u ${remote} ${branch}`,
|
|
941
|
+
);
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
// Check for unpushed commits
|
|
945
|
+
const unpushed = execFileSync("git", ["log", `${remote}/${branch}..HEAD`, "--oneline"], {
|
|
946
|
+
cwd,
|
|
947
|
+
encoding: "utf8",
|
|
948
|
+
timeout: 5000,
|
|
949
|
+
}).trim();
|
|
950
|
+
|
|
951
|
+
if (unpushed.length > 0) {
|
|
952
|
+
const commitCount = unpushed.split("\n").length;
|
|
953
|
+
return deny(
|
|
954
|
+
`You have ${commitCount} unpushed commit${commitCount > 1 ? "s" : ""} on branch "${branch}". ` +
|
|
955
|
+
`Push your changes with: git push`,
|
|
956
|
+
);
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
return allow(`All commits pushed to "${remote}".`);
|
|
960
|
+
} catch {
|
|
961
|
+
return allow("Could not check push status, skipping.");
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
function requirePrBeforeStop(ctx: PolicyContext): PolicyResult {
|
|
966
|
+
const cwd = ctx.session?.cwd;
|
|
967
|
+
if (!cwd) return allow("No working directory available, skipping PR check.");
|
|
968
|
+
|
|
969
|
+
try {
|
|
970
|
+
// Check if gh CLI is available
|
|
971
|
+
try {
|
|
972
|
+
execSync("gh --version", { cwd, encoding: "utf8", timeout: 3000 });
|
|
973
|
+
} catch {
|
|
974
|
+
return allow("GitHub CLI (gh) not installed, skipping PR check.");
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
const branch = getCurrentBranch(cwd);
|
|
978
|
+
if (!branch || branch === "HEAD") return allow("Detached HEAD, skipping PR check.");
|
|
979
|
+
|
|
980
|
+
const baseBranch = (ctx.params?.baseBranch as string) ?? "main";
|
|
981
|
+
|
|
982
|
+
// If on the base branch itself, no PR is needed
|
|
983
|
+
if (branch === baseBranch) {
|
|
984
|
+
return allow(`On base branch "${baseBranch}", skipping PR check.`);
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
// Check if branch has diverged from base in any meaningful way
|
|
988
|
+
try {
|
|
989
|
+
const ahead = execFileSync(
|
|
990
|
+
"git",
|
|
991
|
+
["log", `origin/${baseBranch}..HEAD`, "--oneline"],
|
|
992
|
+
{ cwd, encoding: "utf8", timeout: 5000 },
|
|
993
|
+
).trim();
|
|
994
|
+
|
|
995
|
+
if (!ahead) {
|
|
996
|
+
// No commits ahead — branch is fully merged (regular merge / fast-forward)
|
|
997
|
+
return allow(`No commits ahead of origin/${baseBranch}, skipping PR check.`);
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
// Commits exist but might be from a squash-merged PR.
|
|
1001
|
+
// Check actual file diff — if trees are identical, work is already in main.
|
|
1002
|
+
const diff = execFileSync(
|
|
1003
|
+
"git",
|
|
1004
|
+
["diff", "--stat", `origin/${baseBranch}`, "HEAD"],
|
|
1005
|
+
{ cwd, encoding: "utf8", timeout: 5000 },
|
|
1006
|
+
).trim();
|
|
1007
|
+
|
|
1008
|
+
if (!diff) {
|
|
1009
|
+
return allow(`No file changes compared to origin/${baseBranch}, skipping PR check.`);
|
|
1010
|
+
}
|
|
1011
|
+
} catch {
|
|
1012
|
+
// origin/{baseBranch} ref missing or git error — fall through to gh pr view
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
// Check if a PR exists for this branch
|
|
1016
|
+
let prJson: string;
|
|
1017
|
+
try {
|
|
1018
|
+
prJson = execSync("gh pr view --json number,url,state", {
|
|
1019
|
+
cwd,
|
|
1020
|
+
encoding: "utf8",
|
|
1021
|
+
timeout: 15000,
|
|
1022
|
+
}).trim();
|
|
1023
|
+
} catch {
|
|
1024
|
+
// gh pr view exits non-zero when no PR exists
|
|
1025
|
+
return deny(
|
|
1026
|
+
`No pull request found for branch "${branch}". ` +
|
|
1027
|
+
`Create one with: gh pr create`,
|
|
1028
|
+
);
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
const pr = JSON.parse(prJson) as { number: number; url: string; state: string };
|
|
1032
|
+
|
|
1033
|
+
if (pr.state === "OPEN") {
|
|
1034
|
+
return allow(`PR #${pr.number} exists: ${pr.url}`);
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
return deny(
|
|
1038
|
+
`Pull request for branch "${branch}" is ${pr.state.toLowerCase()}. Create a new PR with: gh pr create`,
|
|
1039
|
+
);
|
|
1040
|
+
} catch {
|
|
1041
|
+
return allow("Could not check PR status, skipping.");
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
function requireCiGreenBeforeStop(ctx: PolicyContext): PolicyResult {
|
|
1046
|
+
const cwd = ctx.session?.cwd;
|
|
1047
|
+
if (!cwd) return allow("No working directory available, skipping CI check.");
|
|
1048
|
+
|
|
1049
|
+
try {
|
|
1050
|
+
// Check if gh CLI is available
|
|
1051
|
+
try {
|
|
1052
|
+
execSync("gh --version", { cwd, encoding: "utf8", timeout: 3000 });
|
|
1053
|
+
} catch {
|
|
1054
|
+
return allow("GitHub CLI (gh) not installed, skipping CI check.");
|
|
1055
|
+
}
|
|
1056
|
+
|
|
1057
|
+
const branch = getCurrentBranch(cwd);
|
|
1058
|
+
if (!branch || branch === "HEAD") return allow("Detached HEAD, skipping CI check.");
|
|
1059
|
+
|
|
1060
|
+
// 1. GitHub Actions workflow runs
|
|
1061
|
+
let workflowRuns: CiCheck[] = [];
|
|
1062
|
+
try {
|
|
1063
|
+
const runsJson = execFileSync(
|
|
1064
|
+
"gh",
|
|
1065
|
+
["run", "list", "--branch", branch, "--limit", "5", "--json", "status,conclusion,name"],
|
|
1066
|
+
{ cwd, encoding: "utf8", timeout: 15000 },
|
|
1067
|
+
).trim();
|
|
1068
|
+
|
|
1069
|
+
if (runsJson && runsJson !== "[]") {
|
|
1070
|
+
workflowRuns = JSON.parse(runsJson) as CiCheck[];
|
|
1071
|
+
}
|
|
1072
|
+
} catch {
|
|
1073
|
+
// fail-open for workflow runs; continue to check third-party checks
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
// 2. Third-party check runs (CodeRabbit, SonarCloud, Codecov, etc.)
|
|
1077
|
+
let thirdPartyChecks: CiCheck[] = [];
|
|
1078
|
+
const sha = getHeadSha(cwd);
|
|
1079
|
+
if (sha) {
|
|
1080
|
+
thirdPartyChecks = getThirdPartyCheckRuns(cwd, sha);
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
// 3. Merge all checks
|
|
1084
|
+
const allChecks = [...workflowRuns, ...thirdPartyChecks];
|
|
1085
|
+
|
|
1086
|
+
if (allChecks.length === 0) return allow(`No CI runs found for branch "${branch}".`);
|
|
1087
|
+
|
|
1088
|
+
const failing = allChecks.filter(
|
|
1089
|
+
(r) => r.status === "completed" && r.conclusion !== "success" && r.conclusion !== "skipped",
|
|
1090
|
+
);
|
|
1091
|
+
if (failing.length > 0) {
|
|
1092
|
+
const names = failing.map((r) => `"${r.name}"`).join(", ");
|
|
1093
|
+
return deny(
|
|
1094
|
+
`CI checks are failing on branch "${branch}": ${names}. Fix the failing checks before stopping.`,
|
|
1095
|
+
);
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
const pending = allChecks.filter(
|
|
1099
|
+
(r) => r.status === "in_progress" || r.status === "queued" || r.status === "waiting",
|
|
1100
|
+
);
|
|
1101
|
+
if (pending.length > 0) {
|
|
1102
|
+
const names = pending.map((r) => `"${r.name}"`).join(", ");
|
|
1103
|
+
return deny(
|
|
1104
|
+
`CI checks are still running on branch "${branch}": ${names}. Wait for all checks to complete and verify they pass.`,
|
|
1105
|
+
);
|
|
1106
|
+
}
|
|
1107
|
+
|
|
1108
|
+
return allow(`All CI checks passed on branch "${branch}".`);
|
|
1109
|
+
} catch {
|
|
1110
|
+
return allow("Could not check CI status, skipping.");
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
|
|
789
1114
|
// -- Registry --
|
|
790
1115
|
|
|
791
1116
|
export const BUILTIN_POLICIES: BuiltinPolicyDefinition[] = [
|
|
@@ -1053,6 +1378,61 @@ export const BUILTIN_POLICIES: BuiltinPolicyDefinition[] = [
|
|
|
1053
1378
|
defaultEnabled: false,
|
|
1054
1379
|
category: "AI Behavior",
|
|
1055
1380
|
},
|
|
1381
|
+
{
|
|
1382
|
+
name: "require-commit-before-stop",
|
|
1383
|
+
description: "Require all changes to be committed before Claude stops",
|
|
1384
|
+
fn: requireCommitBeforeStop,
|
|
1385
|
+
match: { events: ["Stop"] },
|
|
1386
|
+
defaultEnabled: false,
|
|
1387
|
+
category: "Workflow",
|
|
1388
|
+
beta: true,
|
|
1389
|
+
},
|
|
1390
|
+
{
|
|
1391
|
+
name: "require-push-before-stop",
|
|
1392
|
+
description: "Require all commits to be pushed to remote before Claude stops",
|
|
1393
|
+
fn: requirePushBeforeStop,
|
|
1394
|
+
match: { events: ["Stop"] },
|
|
1395
|
+
defaultEnabled: false,
|
|
1396
|
+
category: "Workflow",
|
|
1397
|
+
beta: true,
|
|
1398
|
+
params: {
|
|
1399
|
+
remote: {
|
|
1400
|
+
type: "string",
|
|
1401
|
+
description: "Remote name to push to (default: origin)",
|
|
1402
|
+
default: "origin",
|
|
1403
|
+
},
|
|
1404
|
+
baseBranch: {
|
|
1405
|
+
type: "string",
|
|
1406
|
+
description: "Base branch to compare against (default: main)",
|
|
1407
|
+
default: "main",
|
|
1408
|
+
},
|
|
1409
|
+
} satisfies PolicyParamsSchema,
|
|
1410
|
+
},
|
|
1411
|
+
{
|
|
1412
|
+
name: "require-pr-before-stop",
|
|
1413
|
+
description: "Require a pull request to exist for the current branch before Claude stops",
|
|
1414
|
+
fn: requirePrBeforeStop,
|
|
1415
|
+
match: { events: ["Stop"] },
|
|
1416
|
+
defaultEnabled: false,
|
|
1417
|
+
category: "Workflow",
|
|
1418
|
+
beta: true,
|
|
1419
|
+
params: {
|
|
1420
|
+
baseBranch: {
|
|
1421
|
+
type: "string",
|
|
1422
|
+
description: "Base branch to compare against (default: main)",
|
|
1423
|
+
default: "main",
|
|
1424
|
+
},
|
|
1425
|
+
} satisfies PolicyParamsSchema,
|
|
1426
|
+
},
|
|
1427
|
+
{
|
|
1428
|
+
name: "require-ci-green-before-stop",
|
|
1429
|
+
description: "Require CI checks to pass on the current branch before Claude stops",
|
|
1430
|
+
fn: requireCiGreenBeforeStop,
|
|
1431
|
+
match: { events: ["Stop"] },
|
|
1432
|
+
defaultEnabled: false,
|
|
1433
|
+
category: "Workflow",
|
|
1434
|
+
beta: true,
|
|
1435
|
+
},
|
|
1056
1436
|
];
|
|
1057
1437
|
|
|
1058
1438
|
export function registerBuiltinPolicies(enabledNames: string[]): void {
|