failproofai 1.0.1 → 1.0.2-beta.1
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/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/build-manifest.json +3 -3
- package/.next/standalone/.next/prerender-manifest.json +6 -6
- package/.next/standalone/.next/required-server-files.json +1 -1
- 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 +2 -2
- 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 +6 -6
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
- package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- 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 +2 -2
- 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 +1 -1
- package/.next/standalone/.next/server/app/_not-found.rsc +15 -15
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +15 -15
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +14 -14
- package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/api/audit/invite/route.js +3 -2
- package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/audit/run/route.js +5 -4
- package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/audit/status/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/login-request/route.js +2 -2
- package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/login-verify/route.js +4 -3
- package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/logout/route.js +4 -4
- package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/status/route.js +4 -4
- package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
- package/.next/standalone/.next/server/app/audit/page.js +2 -2
- package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/index.html +1 -1
- package/.next/standalone/.next/server/app/index.rsc +15 -15
- package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +14 -14
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
- package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/page.js +2 -2
- 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/server-reference-manifest.json +66 -22
- package/.next/standalone/.next/server/app/policies/page.js +5 -4
- 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/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page.js +2 -2
- 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/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 +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/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/projects/page.js +2 -2
- 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/app/settings/page/server-reference-manifest.json +4 -4
- package/.next/standalone/.next/server/app/settings/page.js +1 -1
- package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/chunks/{[externals]__1qzqcio._.js → [externals]__0e32-7c._.js} +1 -1
- package/.next/standalone/.next/server/chunks/[externals]__1s462yl._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__01eqny5._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0_0xu5z._.js +1 -1
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__1p8poxd._.js → [root-of-the-server]__0igxt32._.js} +2 -2
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0neqlu-._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o07qi9._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0t9oqnn._.js +3 -0
- package/.next/standalone/.next/server/chunks/_0bs-v8p._.js +3 -0
- package/.next/standalone/.next/server/chunks/_0tovk6q._.js +3 -0
- package/.next/standalone/.next/server/chunks/_0trp3yc._.js +3 -0
- package/.next/standalone/.next/server/chunks/_185gyk9._.js +3 -0
- package/.next/standalone/.next/server/chunks/_1ek68ln._.js +5 -6
- package/.next/standalone/.next/server/chunks/lib_telemetry-id_ts_1k8gj9o._.js +3 -0
- package/.next/standalone/.next/server/chunks/{node_modules_posthog-node_dist_entrypoints_index_node_mjs_09d5c79._.js → node_modules_posthog-node_dist_entrypoints_index_node_mjs_04op_ou._.js} +1 -1
- package/.next/standalone/.next/server/chunks/{node_modules_posthog-node_dist_entrypoints_index_node_mjs_1d2g73o._.js → node_modules_posthog-node_dist_entrypoints_index_node_mjs_0dr20uz._.js} +1 -1
- package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
- package/.next/standalone/.next/server/chunks/src_hooks_0xbw3bu._.js +12 -0
- package/.next/standalone/.next/server/chunks/src_hooks_fp-home_ts_09kv0bn._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__013jr2b._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__01wy8d-._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__02npjtd._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0spkm68._.js → [root-of-the-server]__07gm3zl._.js} +21 -20
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0da85px._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ftmoxc._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0l4748x._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0oa1lav._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0p-5p8u._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0s740oi._.js +6 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__192nhvh._.js +5 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1p2otjt._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/_08x1r5t._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_0bwu160._.js +23 -0
- package/.next/standalone/.next/server/chunks/ssr/{_0u5zauv._.js → _0ns6k3a._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_1u8-lu2._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_1zopuov._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +13 -13
- package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/app_settings_settings-client_tsx_20lq-mq._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_08o7bqo._.js +10 -0
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_builtin-policies_ts_09j2ndl._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_fp-home_ts_0je3xkv._.js +1 -1
- package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
- package/.next/standalone/.next/server/middleware.js +1 -1
- package/.next/standalone/.next/server/pages/404.html +1 -1
- 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 +71 -27
- package/.next/standalone/.next/static/chunks/{3c808qrfcq0im.js → 01u1cf8js2yd6.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0k5050ezjvv49.js → 0izgu7nqh2zp-.js} +1 -1
- package/.next/standalone/.next/static/chunks/0u4-org_e7zde.js +1 -0
- package/.next/standalone/.next/static/chunks/1mfzsja6ftim5.css +2 -0
- package/.next/standalone/.next/static/chunks/{2zpp1we2jv6tb.js → 1tynnrrh711lr.js} +1 -1
- package/.next/standalone/.next/static/chunks/{1ide1wl2f7zi1.js → 22rqvlr7p_1mv.js} +13 -13
- package/.next/standalone/.next/static/chunks/{31s1smp-g7gks.js → 2whxqyskpirbk.js} +1 -1
- package/.next/standalone/.next/static/chunks/31mwk8k0q3_3g.js +6 -0
- package/.next/standalone/.next/static/chunks/3ms6gxfm82t6s.js +1 -0
- package/.next/standalone/.next/static/chunks/{37fcpc36x9gpe.js → 3tbbs_d8xrvyp.js} +1 -1
- package/.next/standalone/.next/static/chunks/43nlc236oo898.js +1 -0
- package/.next/standalone/SECURITY.md +5 -4
- package/.next/standalone/app/actions/get-hooks-config.ts +108 -17
- package/.next/standalone/app/actions/pack-actions.ts +163 -0
- package/.next/standalone/app/audit/_components/run-progress.tsx +1 -1
- package/.next/standalone/app/audit/_components/share-templates.ts +13 -13
- package/.next/standalone/app/policies/hooks-client.tsx +320 -15
- package/.next/standalone/components/navbar.tsx +2 -28
- package/.next/standalone/components/reach-developers.tsx +8 -1
- package/.next/standalone/docs-old/agenteye/python-sdk-skill.mdx +1 -1
- package/.next/standalone/docs-old/agenteye/python-sdk.mdx +59 -35
- package/.next/standalone/docs-old/i18n/README.ar.md +1 -0
- package/.next/standalone/docs-old/i18n/README.de.md +1 -0
- package/.next/standalone/docs-old/i18n/README.es.md +1 -0
- package/.next/standalone/docs-old/i18n/README.fr.md +1 -0
- package/.next/standalone/docs-old/i18n/README.he.md +1 -0
- package/.next/standalone/docs-old/i18n/README.hi.md +1 -0
- package/.next/standalone/docs-old/i18n/README.it.md +1 -0
- package/.next/standalone/docs-old/i18n/README.ja.md +1 -0
- package/.next/standalone/docs-old/i18n/README.ko.md +1 -0
- package/.next/standalone/docs-old/i18n/README.pt-br.md +1 -0
- package/.next/standalone/docs-old/i18n/README.ru.md +1 -0
- package/.next/standalone/docs-old/i18n/README.tr.md +1 -0
- package/.next/standalone/docs-old/i18n/README.vi.md +1 -0
- package/.next/standalone/docs-old/i18n/README.zh.md +1 -0
- package/.next/standalone/fp-cloud-cli/CHANGELOG.md +431 -0
- package/.next/standalone/fp-cloud-cli/LICENSE +42 -0
- package/.next/standalone/fp-cloud-cli/MANIFEST.in +10 -0
- package/.next/standalone/fp-cloud-cli/README.md +259 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/__init__.py +10 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/__main__.py +4 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/_click_compat.py +64 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/_context.py +332 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/_version.py +1 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/analytics.py +432 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/analytics_config.py +77 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/analytics_registry.py +83 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/app.py +492 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/auth.py +160 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/client.py +1694 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/__init__.py +0 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/_write.py +214 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/agent_cmds.py +407 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/alerts_cmds.py +445 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/audits_cmds.py +1054 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/auth_cmds.py +512 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/errors_cmds.py +190 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/evals_cmds.py +161 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/events_cmds.py +159 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/fleet_cmds.py +416 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/guardrails_cmds.py +148 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/incidents_cmds.py +472 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/keys_cmds.py +407 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/list_cmds.py +63 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/orgs_cmds.py +319 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/policies_cmds.py +499 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/queries_cmds.py +378 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/sessions_cmds.py +151 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/settings_cmds.py +150 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/usage_cmds.py +35 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/users_cmds.py +404 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/config.py +330 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/dates.py +78 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/enforcement.py +345 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/errors.py +98 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/models.py +891 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/orgs.py +30 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/output.py +6593 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/permissions.py +208 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/policy_check.py +290 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/py.typed +0 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/select.py +322 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/theme.py +53 -0
- package/.next/standalone/fp-cloud-cli/pyproject.toml +106 -0
- package/.next/standalone/fp-cloud-cli/skill/SKILL.md +302 -0
- package/.next/standalone/fp-cloud-cli/skill/agents/openai.yaml +8 -0
- package/.next/standalone/fp-cloud-cli/skill/references/commands.md +254 -0
- package/.next/standalone/fp-cloud-cli/tests/__init__.py +0 -0
- package/.next/standalone/fp-cloud-cli/tests/conftest.py +92 -0
- package/.next/standalone/fp-cloud-cli/tests/test_alerting.py +644 -0
- package/.next/standalone/fp-cloud-cli/tests/test_analytics.py +385 -0
- package/.next/standalone/fp-cloud-cli/tests/test_audits.py +950 -0
- package/.next/standalone/fp-cloud-cli/tests/test_auth.py +98 -0
- package/.next/standalone/fp-cloud-cli/tests/test_auth_mode.py +272 -0
- package/.next/standalone/fp-cloud-cli/tests/test_click_compat.py +118 -0
- package/.next/standalone/fp-cloud-cli/tests/test_client.py +299 -0
- package/.next/standalone/fp-cloud-cli/tests/test_commands.py +814 -0
- package/.next/standalone/fp-cloud-cli/tests/test_config.py +99 -0
- package/.next/standalone/fp-cloud-cli/tests/test_dashboards_agent.py +340 -0
- package/.next/standalone/fp-cloud-cli/tests/test_dates.py +76 -0
- package/.next/standalone/fp-cloud-cli/tests/test_enforcement_logic.py +481 -0
- package/.next/standalone/fp-cloud-cli/tests/test_facets.py +170 -0
- package/.next/standalone/fp-cloud-cli/tests/test_failproofai_home.py +722 -0
- package/.next/standalone/fp-cloud-cli/tests/test_fp_home_contract.py +198 -0
- package/.next/standalone/fp-cloud-cli/tests/test_hardening.py +186 -0
- package/.next/standalone/fp-cloud-cli/tests/test_help_table_coverage.py +127 -0
- package/.next/standalone/fp-cloud-cli/tests/test_keys_queries.py +496 -0
- package/.next/standalone/fp-cloud-cli/tests/test_list.py +59 -0
- package/.next/standalone/fp-cloud-cli/tests/test_multivalue.py +183 -0
- package/.next/standalone/fp-cloud-cli/tests/test_no_customer_identifiers.py +168 -0
- package/.next/standalone/fp-cloud-cli/tests/test_operator.py +492 -0
- package/.next/standalone/fp-cloud-cli/tests/test_orgs.py +692 -0
- package/.next/standalone/fp-cloud-cli/tests/test_output.py +1732 -0
- package/.next/standalone/fp-cloud-cli/tests/test_policy_check.py +191 -0
- package/.next/standalone/fp-cloud-cli/tests/test_readme_matches_reality.py +125 -0
- package/.next/standalone/fp-cloud-cli/tests/test_review_fixes.py +161 -0
- package/.next/standalone/fp-cloud-cli/tests/test_telemetry_completeness.py +90 -0
- package/.next/standalone/fp-cloud-cli/tests/test_usage.py +115 -0
- package/.next/standalone/fp-cloud-cli/tests/test_v1_origin_diagnostic.py +70 -0
- package/.next/standalone/fp-cloud-cli/tests/test_v1_routing.py +214 -0
- package/.next/standalone/fp-cloud-cli/tests/test_whoami.py +104 -0
- package/.next/standalone/fp-cloud-cli/uv.lock +552 -0
- package/.next/standalone/package.json +27 -21
- package/.next/standalone/sdk/python/CHANGELOG.md +70 -0
- package/.next/standalone/sdk/python/LICENSE +42 -0
- package/.next/standalone/sdk/python/MANIFEST.in +21 -0
- package/.next/standalone/sdk/python/README.md +466 -0
- package/.next/standalone/sdk/python/docs/README.md +249 -0
- package/.next/standalone/sdk/python/docs/_shared/README.md +43 -0
- package/.next/standalone/sdk/python/docs/_shared/__init__.py +195 -0
- package/.next/standalone/sdk/python/docs/crewai/README.md +328 -0
- package/.next/standalone/sdk/python/docs/crewai/examples/quickstart.py +61 -0
- package/.next/standalone/sdk/python/docs/crewai/examples/research_crew.py +92 -0
- package/.next/standalone/sdk/python/docs/langgraph/README.md +481 -0
- package/.next/standalone/sdk/python/docs/langgraph/examples/quickstart.py +51 -0
- package/.next/standalone/sdk/python/docs/langgraph/examples/research_agent.py +86 -0
- package/.next/standalone/sdk/python/docs/langgraph/examples/supervisor_handoff.py +83 -0
- package/.next/standalone/sdk/python/docs/llama_index/README.md +332 -0
- package/.next/standalone/sdk/python/docs/llama_index/examples/quickstart.py +62 -0
- package/.next/standalone/sdk/python/docs/llama_index/examples/research_agent.py +93 -0
- package/.next/standalone/sdk/python/docs/manual/README.md +491 -0
- package/.next/standalone/sdk/python/docs/manual/examples/quickstart.py +57 -0
- package/.next/standalone/sdk/python/docs/manual/examples/research_agent.py +133 -0
- package/.next/standalone/sdk/python/docs/pydantic_ai/README.md +323 -0
- package/.next/standalone/sdk/python/docs/pydantic_ai/examples/quickstart.py +48 -0
- package/.next/standalone/sdk/python/docs/pydantic_ai/examples/research_agent.py +94 -0
- package/.next/standalone/sdk/python/failproofai_sdk/__init__.py +131 -0
- package/.next/standalone/sdk/python/failproofai_sdk/_context.py +218 -0
- package/.next/standalone/sdk/python/failproofai_sdk/_environment.py +78 -0
- package/.next/standalone/sdk/python/failproofai_sdk/_events.py +752 -0
- package/.next/standalone/sdk/python/failproofai_sdk/_resolver.py +118 -0
- package/.next/standalone/sdk/python/failproofai_sdk/_runtime.py +21 -0
- package/.next/standalone/sdk/python/failproofai_sdk/_schema.py +317 -0
- package/.next/standalone/sdk/python/failproofai_sdk/_scopes.py +422 -0
- package/.next/standalone/sdk/python/failproofai_sdk/_version.py +1 -0
- package/.next/standalone/sdk/python/failproofai_sdk/_writer.py +750 -0
- package/.next/standalone/sdk/python/failproofai_sdk/integrations/__init__.py +274 -0
- package/.next/standalone/sdk/python/failproofai_sdk/integrations/_compat.py +247 -0
- package/.next/standalone/sdk/python/failproofai_sdk/integrations/_core.py +1076 -0
- package/.next/standalone/sdk/python/failproofai_sdk/integrations/crewai.py +1669 -0
- package/.next/standalone/sdk/python/failproofai_sdk/integrations/langchain.py +2151 -0
- package/.next/standalone/sdk/python/failproofai_sdk/integrations/llama_index.py +1588 -0
- package/.next/standalone/sdk/python/failproofai_sdk/integrations/pydantic_ai.py +977 -0
- package/.next/standalone/sdk/python/failproofai_sdk/py.typed +0 -0
- package/.next/standalone/sdk/python/pyproject.toml +92 -0
- package/.next/standalone/sdk/python/skill/SKILL.md +399 -0
- package/.next/standalone/sdk/python/skill/agents/openai.yaml +8 -0
- package/.next/standalone/sdk/python/skill/references/events.md +234 -0
- package/.next/standalone/sdk/python/skill/references/frameworks.md +314 -0
- package/.next/standalone/sdk/python/skill/references/install.md +100 -0
- package/.next/standalone/sdk/python/skill/references/integration.md +352 -0
- package/.next/standalone/sdk/python/tests/__init__.py +0 -0
- package/.next/standalone/sdk/python/tests/conftest.py +169 -0
- package/.next/standalone/sdk/python/tests/integrations/__init__.py +6 -0
- package/.next/standalone/sdk/python/tests/integrations/test_crewai.py +1299 -0
- package/.next/standalone/sdk/python/tests/integrations/test_langchain.py +2338 -0
- package/.next/standalone/sdk/python/tests/integrations/test_llama_index.py +1576 -0
- package/.next/standalone/sdk/python/tests/integrations/test_pydantic_ai.py +1102 -0
- package/.next/standalone/sdk/python/tests/test_context.py +410 -0
- package/.next/standalone/sdk/python/tests/test_docs.py +411 -0
- package/.next/standalone/sdk/python/tests/test_durability.py +1352 -0
- package/.next/standalone/sdk/python/tests/test_encoding.py +571 -0
- package/.next/standalone/sdk/python/tests/test_integrations.py +1127 -0
- package/.next/standalone/sdk/python/tests/test_no_customer_identifiers.py +214 -0
- package/.next/standalone/sdk/python/tests/test_packaging.py +185 -0
- package/.next/standalone/sdk/python/tests/test_resolver_umbrella.py +178 -0
- package/.next/standalone/sdk/python/tests/test_scopes.py +487 -0
- package/.next/standalone/sdk/python/tests/test_sdk.py +923 -0
- package/.next/standalone/sdk/python/tests/test_server_contract.py +650 -0
- package/.next/standalone/sdk/python/tests/test_site_docs.py +371 -0
- package/.next/standalone/sdk/python/tests/test_skill_snippets.py +165 -0
- package/.next/standalone/sdk/python/tests/test_spool_contract.py +287 -0
- package/.next/standalone/sdk/python/tests/test_spool_creation.py +360 -0
- package/.next/standalone/sdk/python/tests/test_wire_format.py +279 -0
- package/.next/standalone/sdk/python/tests/test_zero_dependencies.py +378 -0
- package/.next/standalone/sdk/python/uv.lock +6005 -0
- package/.next/standalone/server.js +1 -1
- package/README.md +77 -21
- package/bin/failproofai.mjs +579 -306
- package/dist/cli.mjs +6499 -3662
- package/dist/index.js +5 -5
- package/dist/worker.mjs +2390 -1978
- package/package.json +27 -21
- package/scripts/build-policy-pack.mjs +121 -0
- package/scripts/changelog-section.py +77 -0
- package/scripts/prune-standalone.mjs +3 -0
- package/scripts/python-version.py +232 -0
- package/scripts/translate-docs/cli.ts +21 -0
- package/scripts/translate-docs/mintlify-nav.ts +85 -13
- package/scripts/translate-docs/translator.ts +66 -11
- package/src/audit/cache.ts +40 -3
- package/src/audit/cli.ts +1 -1
- package/src/audit/index.ts +1 -1
- package/src/audit/replay.ts +89 -3
- package/src/audit/report.ts +5 -5
- package/src/audit/schedule-cli.ts +49 -53
- package/src/hooks/builtin-policies.ts +217 -579
- package/src/hooks/cloud-enrollment-cli.ts +66 -27
- package/src/hooks/cloud-managed-policies.ts +6 -1
- package/src/hooks/configure-wizard.ts +56 -369
- package/src/hooks/custom-hooks-loader.ts +89 -6
- package/src/hooks/fp-home.ts +92 -4
- package/src/hooks/fp-reset.ts +34 -2
- package/src/hooks/handler.ts +181 -11
- package/src/hooks/harness-cli.ts +79 -25
- package/src/hooks/hook-activity-store.ts +13 -3
- package/src/hooks/install-prompt.ts +25 -3
- package/src/hooks/manager.ts +424 -172
- package/src/hooks/migrations.ts +2 -2
- package/src/hooks/pack-cli.ts +885 -0
- package/src/hooks/pack-failclosed.ts +189 -0
- package/src/hooks/pack-manifest.ts +352 -0
- package/src/hooks/pack-store.ts +891 -0
- package/src/hooks/policy-catalog.ts +535 -0
- package/src/hooks/policy-evaluator.ts +24 -16
- package/src/hooks/policy-registry.ts +8 -2
- package/src/hooks/policy-types.ts +26 -0
- package/src/hooks/session-pause-cli.ts +33 -9
- package/src/hooks/tui.ts +695 -39
- package/src/hooks/types.ts +15 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0_usx0j._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0_zk340._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0agdw2a._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0d1u_na._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0oy4kxb._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0zf034w._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1tvn4wf._.js +0 -3
- package/.next/standalone/.next/server/chunks/_0lxbzdq._.js +0 -3
- package/.next/standalone/.next/server/chunks/_1ger0a2._.js +0 -3
- package/.next/standalone/.next/server/chunks/_1zuiiy3._.js +0 -3
- package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_1iiwm5e._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__07tbbf3._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0kc8_v5._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0kgy9da._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0mhqk5a._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0pltpn8._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qkcyf-._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0w0x_ok._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1_dfocn._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1bfex62._.js +0 -5
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1kzapg5._.js +0 -6
- package/.next/standalone/.next/server/chunks/ssr/_0lvyuv4._.js +0 -23
- package/.next/standalone/.next/static/chunks/2_2lhuojq2xop.js +0 -1
- package/.next/standalone/.next/static/chunks/36fw6yk1s6x_f.js +0 -1
- package/.next/standalone/.next/static/chunks/3k7mxbp9hiom0.js +0 -1
- package/.next/standalone/.next/static/chunks/3tzq0260n17ae.js +0 -6
- package/.next/standalone/.next/static/chunks/3wq9x0c-7ld5d.css +0 -2
- package/src/hooks/policy-presets.ts +0 -135
- /package/.next/standalone/.next/static/{ZklXxyA5ygsWSQz2u_zii → I5kEb9kSgYS63j4iqfVLO}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{ZklXxyA5ygsWSQz2u_zii → I5kEb9kSgYS63j4iqfVLO}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{ZklXxyA5ygsWSQz2u_zii → I5kEb9kSgYS63j4iqfVLO}/_ssgManifest.js +0 -0
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* 0. Daemon — REQUIRED. Asks for sudo first, on a clean terminal.
|
|
7
7
|
* 1. Where — inferred from cwd, then confirmed (global / project / both)
|
|
8
8
|
* 2. Policies — multi-select of themed presets (combine any) or Everything
|
|
9
|
-
* 3. Assistants— multi-select of agent
|
|
9
|
+
* 3. Assistants— multi-select of agent harnesses (detected + install-ahead)
|
|
10
10
|
* 4. Connect — paste an API key, or stay fully local
|
|
11
11
|
* 5. Review — shows exactly which files change, then Apply.
|
|
12
12
|
*
|
|
@@ -33,7 +33,6 @@ import { dirname, resolve, sep } from "node:path";
|
|
|
33
33
|
import {
|
|
34
34
|
selectOne,
|
|
35
35
|
multiSelect,
|
|
36
|
-
BACK,
|
|
37
36
|
promptText,
|
|
38
37
|
intro,
|
|
39
38
|
outro,
|
|
@@ -54,8 +53,7 @@ import {
|
|
|
54
53
|
} from "./integrations";
|
|
55
54
|
import { INTEGRATION_TYPES, type IntegrationType, type HookScope } from "./types";
|
|
56
55
|
import { installHooks } from "./manager";
|
|
57
|
-
import { getConfigPathForScope,
|
|
58
|
-
import { POLICY_PRESETS, resolvePreset, resolveEverything, RECOMMENDED_POLICIES } from "./policy-presets";
|
|
56
|
+
import { getConfigPathForScope, readScopedHooksConfig } from "./hooks-config";
|
|
59
57
|
import { discoverPolicyFiles, findSkippedPolicyFiles } from "./custom-hooks-loader";
|
|
60
58
|
import { trackHookEvent } from "./hook-telemetry";
|
|
61
59
|
import { getInstanceId } from "../../lib/telemetry-id";
|
|
@@ -226,175 +224,7 @@ export function buildAgentChoices(scope: HookScope, cwd: string): MultiChoice<In
|
|
|
226
224
|
});
|
|
227
225
|
}
|
|
228
226
|
|
|
229
|
-
const EVERYTHING = "__everything__";
|
|
230
227
|
const ALL_CLIS = "__all_clis__";
|
|
231
|
-
/** Sentinel for the locked "Custom" row — informational, never resolves to
|
|
232
|
-
* builtin policy names (custom policies load by convention, not by config). */
|
|
233
|
-
const CUSTOM = "__custom__";
|
|
234
|
-
/**
|
|
235
|
-
* Sentinel for the locked "enabled individually" row.
|
|
236
|
-
*
|
|
237
|
-
* Policies enabled one at a time (`failproofai policies add <name>`) need not map
|
|
238
|
-
* onto any preset, so seeding the preset boxes cannot represent them. The wizard
|
|
239
|
-
* writes with `replace: true`, which makes the ticked set the WHOLE enabled set —
|
|
240
|
-
* so anything this row stands for must be unioned back in, or confirming the
|
|
241
|
-
* wizard would silently drop it. Locked and pre-checked, because it reports a
|
|
242
|
-
* state rather than offering a choice.
|
|
243
|
-
*/
|
|
244
|
-
const INDIVIDUAL = "__individual__";
|
|
245
|
-
|
|
246
|
-
/**
|
|
247
|
-
* Split what is enabled now into the bundles that cover it and the leftovers.
|
|
248
|
-
*
|
|
249
|
-
* A pure function, and the SINGLE definition of that split — `buildPresetChoices`
|
|
250
|
-
* renders it and the wizard writes from it, so the row the user sees and the set
|
|
251
|
-
* that gets written can never disagree. The first version of this derived the
|
|
252
|
-
* leftovers by parsing them back out of the row's hint text, which coupled a
|
|
253
|
-
* display string to enforcement behaviour and would have broken on any policy
|
|
254
|
-
* name containing the separator.
|
|
255
|
-
*/
|
|
256
|
-
export function splitEnabled(currentlyEnabled: readonly string[] = []): {
|
|
257
|
-
/** Preset ids (or `EVERYTHING`) whose policies are all already enabled. */
|
|
258
|
-
presets: string[];
|
|
259
|
-
/** Enabled policies no ticked bundle accounts for. */
|
|
260
|
-
individual: string[];
|
|
261
|
-
} {
|
|
262
|
-
const current = new Set(currentlyEnabled);
|
|
263
|
-
// A bundle is ticked when everything it turns on is already on. Not "any", or
|
|
264
|
-
// one shared policy would tick every bundle containing it and confirming would
|
|
265
|
-
// enable all of them.
|
|
266
|
-
const isOn = (policies: string[]) =>
|
|
267
|
-
policies.length > 0 && policies.every((name) => current.has(name));
|
|
268
|
-
|
|
269
|
-
const everything = resolveEverything();
|
|
270
|
-
const presets = isOn(everything)
|
|
271
|
-
? [EVERYTHING]
|
|
272
|
-
: POLICY_PRESETS.filter((p) => isOn(resolvePreset(p.id))).map((p) => p.id);
|
|
273
|
-
|
|
274
|
-
// Against the TICKED bundles, not all of them: a policy belonging only to a
|
|
275
|
-
// bundle the user has NOT enabled is still enabled, and that is the fact the
|
|
276
|
-
// locked row exists to make visible.
|
|
277
|
-
const accounted = new Set(
|
|
278
|
-
presets.flatMap((id) => (id === EVERYTHING ? everything : resolvePreset(id))),
|
|
279
|
-
);
|
|
280
|
-
const individual = [...current].filter((name) => !accounted.has(name)).sort();
|
|
281
|
-
return { presets, individual };
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
/** The themed preset bundles for the wizard's multi-select, plus an "Everything"
|
|
285
|
-
* option that enables the full builtin policy set. */
|
|
286
|
-
export function buildPresetChoices(
|
|
287
|
-
cwd: string = process.cwd(),
|
|
288
|
-
enabled = true,
|
|
289
|
-
/**
|
|
290
|
-
* What is enabled at this scope RIGHT NOW, used to tick the boxes.
|
|
291
|
-
*
|
|
292
|
-
* Without it every row rendered unticked on every run while the wizard wrote
|
|
293
|
-
* with `replace: true` — so re-running setup showed a blank slate and then made
|
|
294
|
-
* that blank slate authoritative, discarding the user's selection with nothing
|
|
295
|
-
* on screen to say it had happened. The comment on the Custom row below has
|
|
296
|
-
* always described the intended behaviour ("shows the current state rather than
|
|
297
|
-
* resetting it every run"); it was implemented for that one row out of eight.
|
|
298
|
-
*
|
|
299
|
-
* Optional so the first-run call sites stay unchanged: an empty set ticks
|
|
300
|
-
* nothing, which is the correct rendering for a machine with no selection.
|
|
301
|
-
*/
|
|
302
|
-
currentlyEnabled: readonly string[] = [],
|
|
303
|
-
) {
|
|
304
|
-
const { presets: onPresets, individual } = splitEnabled(currentlyEnabled);
|
|
305
|
-
const on = new Set(onPresets);
|
|
306
|
-
|
|
307
|
-
const choices: MultiChoice<string>[] = POLICY_PRESETS.map((p) => ({
|
|
308
|
-
label: p.label,
|
|
309
|
-
value: p.id,
|
|
310
|
-
hint: p.description,
|
|
311
|
-
checked: on.has(p.id),
|
|
312
|
-
}));
|
|
313
|
-
choices.push({
|
|
314
|
-
label: "Everything",
|
|
315
|
-
value: EVERYTHING,
|
|
316
|
-
hint: `all ${resolveEverything().length} policies`,
|
|
317
|
-
checked: on.has(EVERYTHING),
|
|
318
|
-
});
|
|
319
|
-
|
|
320
|
-
// The Custom row is ALWAYS present, because it is the only place the feature
|
|
321
|
-
// is discoverable: a user who has never written a policy cannot learn the
|
|
322
|
-
// capability exists, and one who wrote a badly-named file cannot learn why
|
|
323
|
-
// nothing happened.
|
|
324
|
-
//
|
|
325
|
-
// When there are loadable files it is a REAL checkbox — unticking writes
|
|
326
|
-
// `customPoliciesEnabled: false`, which switches convention discovery off
|
|
327
|
-
// without renaming or deleting anything. With nothing to toggle (no files,
|
|
328
|
-
// or only skipped ones) it falls back to a locked status row.
|
|
329
|
-
const custom = describeCustomPolicies(cwd);
|
|
330
|
-
const skipped = custom.warnings.length;
|
|
331
|
-
const plural = (n: number) => `${n} file${n === 1 ? "" : "s"}`;
|
|
332
|
-
const skippedNote = skipped > 0 ? ` · ${skipped} skipped, see next screen` : "";
|
|
333
|
-
|
|
334
|
-
if (custom.fileCount > 0) {
|
|
335
|
-
choices.push({
|
|
336
|
-
label: "Custom",
|
|
337
|
-
value: CUSTOM,
|
|
338
|
-
checked: enabled,
|
|
339
|
-
// Deliberately NOT summaryExclude'd: this one is a real choice, and the
|
|
340
|
-
// step summary is the only place the user sees what they picked. Hiding
|
|
341
|
-
// it meant unticking Custom and every bundle showed "none", giving no
|
|
342
|
-
// way to tell the toggle had registered.
|
|
343
|
-
hint: `${plural(custom.fileCount)} in ${custom.scopes.join(" + ")}${skippedNote}`,
|
|
344
|
-
});
|
|
345
|
-
} else {
|
|
346
|
-
choices.push({
|
|
347
|
-
label: "Custom",
|
|
348
|
-
value: CUSTOM,
|
|
349
|
-
locked: true,
|
|
350
|
-
checked: false,
|
|
351
|
-
summaryExclude: true,
|
|
352
|
-
hint:
|
|
353
|
-
skipped > 0
|
|
354
|
-
? `${plural(skipped)} found but NOT loaded — see next screen`
|
|
355
|
-
: "none yet · drop *-policies.mjs in .failproofai/policies/",
|
|
356
|
-
});
|
|
357
|
-
}
|
|
358
|
-
if (individual.length > 0) {
|
|
359
|
-
choices.push({
|
|
360
|
-
label: `${individual.length} enabled individually`,
|
|
361
|
-
value: INDIVIDUAL,
|
|
362
|
-
locked: true,
|
|
363
|
-
hint: `kept as-is · ${individual.join(", ")}`,
|
|
364
|
-
// Not one of the bundles being counted, like the Everything and Custom rows.
|
|
365
|
-
summaryExclude: true,
|
|
366
|
-
});
|
|
367
|
-
}
|
|
368
|
-
return choices;
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
/**
|
|
373
|
-
* Resolve the ticked options to a concrete policy set. Presets are additive —
|
|
374
|
-
* the deduped union of every selected preset's policies — while "Everything"
|
|
375
|
-
* enables the full policy set and wins over any presets.
|
|
376
|
-
*/
|
|
377
|
-
export function resolvePresetSelection(
|
|
378
|
-
values: string[],
|
|
379
|
-
/**
|
|
380
|
-
* What the locked "enabled individually" row stands for. Unioned in whenever
|
|
381
|
-
* that row is present, INCLUDING under "Everything": `resolveEverything()`
|
|
382
|
-
* covers the non-beta builtins only, so a beta policy someone enabled by hand
|
|
383
|
-
* would otherwise be dropped by the very branch meant to enable everything.
|
|
384
|
-
*/
|
|
385
|
-
individual: readonly string[] = [],
|
|
386
|
-
): string[] {
|
|
387
|
-
// The Custom row is informational — custom policies are discovered from disk
|
|
388
|
-
// by the loader, never named in the enabled-policies config — so it must not
|
|
389
|
-
// reach resolvePreset(), which only knows builtin bundle ids. Same for the
|
|
390
|
-
// locked individually-enabled row, which carries its policies in `individual`.
|
|
391
|
-
const selected = values.filter((v) => v !== CUSTOM && v !== INDIVIDUAL);
|
|
392
|
-
const carried = values.includes(INDIVIDUAL) ? individual : [];
|
|
393
|
-
if (selected.includes(EVERYTHING)) {
|
|
394
|
-
return [...new Set([...resolveEverything(), ...carried])];
|
|
395
|
-
}
|
|
396
|
-
return [...new Set([...selected.flatMap((id) => resolvePreset(id)), ...carried])];
|
|
397
|
-
}
|
|
398
228
|
|
|
399
229
|
const DIM_NOTE = "(auto-loaded)";
|
|
400
230
|
|
|
@@ -528,15 +358,6 @@ export function buildCompletionSummary(
|
|
|
528
358
|
customEnabled: boolean | undefined,
|
|
529
359
|
daemonInstalled: boolean,
|
|
530
360
|
connected: boolean,
|
|
531
|
-
/**
|
|
532
|
-
* What was ticked on the policy step, so the summary can NAME the bundles.
|
|
533
|
-
*
|
|
534
|
-
* "9 policies" is a number the user cannot check and did not choose — they
|
|
535
|
-
* picked two named bundles two screens earlier, and the line that confirms
|
|
536
|
-
* their setup should say which. Optional so the existing callers and tests
|
|
537
|
-
* that only have a count keep working and keep the old wording.
|
|
538
|
-
*/
|
|
539
|
-
presetValues?: readonly string[],
|
|
540
361
|
): string {
|
|
541
362
|
const extras: string[] = [];
|
|
542
363
|
if (customEnabled === true) extras.push("custom");
|
|
@@ -554,9 +375,7 @@ export function buildCompletionSummary(
|
|
|
554
375
|
// full line will not fit, which is checked rather than guessed at: the extras
|
|
555
376
|
// clause grows too ("custom, daemon, reporting" is 25 characters), so a names
|
|
556
377
|
// budget alone was wrong for exactly the combinations that need it most.
|
|
557
|
-
|
|
558
|
-
if (named.length <= MAX_SUMMARY_COLUMNS) return named;
|
|
559
|
-
return line(describeSelection(policiesCount, undefined));
|
|
378
|
+
return line(describeSelection(policiesCount));
|
|
560
379
|
}
|
|
561
380
|
|
|
562
381
|
/**
|
|
@@ -603,43 +422,13 @@ export function policyNamesLine(names: string[]): string[] {
|
|
|
603
422
|
return [];
|
|
604
423
|
}
|
|
605
424
|
|
|
606
|
-
/**
|
|
607
|
-
*
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
* ellipsis, so an over-long line does not lose its tail, it reads as broken
|
|
611
|
-
* output — the same constraint that stopped this summary naming all twelve CLIs.
|
|
612
|
-
* All four bundle labels joined is 57 characters, which with the prefix, the
|
|
613
|
-
* harness clause and the extras clause runs to about 106. Two names plus a count
|
|
614
|
-
* of the rest stays inside 80 for every combination, and two is also the common
|
|
615
|
-
* case, so most runs see every name.
|
|
616
|
-
*
|
|
617
|
-
* Falls back to the old "N policies" when nothing maps to a bundle — a machine
|
|
618
|
-
* whose policies were all enabled one at a time with `policies add` has no bundle
|
|
619
|
-
* to name, and inventing one would be worse than the count.
|
|
620
|
-
*/
|
|
621
|
-
function describeSelection(policiesCount: number, presetValues?: readonly string[]): string {
|
|
622
|
-
const plural = `${policiesCount} polic${policiesCount === 1 ? "y" : "ies"}`;
|
|
623
|
-
if (!presetValues) return plural;
|
|
624
|
-
|
|
625
|
-
// "Everything" is one name for the whole set, and the count is the useful half
|
|
626
|
-
// of it — "Everything" alone does not say how much that is.
|
|
627
|
-
if (presetValues.includes(EVERYTHING)) return `Everything (${plural})`;
|
|
628
|
-
|
|
629
|
-
const named = POLICY_PRESETS.filter((p) => presetValues.includes(p.id)).map((p) => p.label);
|
|
630
|
-
// The locked "enabled individually" row stands for policies outside every
|
|
631
|
-
// bundle, so it is counted among the unnamed rest rather than named.
|
|
632
|
-
const individual = presetValues.includes(INDIVIDUAL) ? 1 : 0;
|
|
633
|
-
if (named.length === 0) return plural;
|
|
634
|
-
|
|
635
|
-
const shown = named.slice(0, 2);
|
|
636
|
-
const rest = named.length - shown.length + individual;
|
|
637
|
-
// `+N` rather than `+N more`: five characters, and they decide whether the
|
|
638
|
-
// mixed case (two bundles plus a policy added by hand) gets named at all — with
|
|
639
|
-
// "more" the line is 83 and falls back to a bare count.
|
|
640
|
-
return rest > 0 ? `${shown.join(", ")} +${rest}` : shown.join(", ");
|
|
425
|
+
/** The Policies line's value. With policies no longer chosen during setup, this
|
|
426
|
+
* reports what is enabled and nothing about how it got that way. */
|
|
427
|
+
function describeSelection(policiesCount: number): string {
|
|
428
|
+
return `${policiesCount} ${policiesCount === 1 ? "policy" : "policies"}`;
|
|
641
429
|
}
|
|
642
430
|
|
|
431
|
+
|
|
643
432
|
export function reviewLines(state: {
|
|
644
433
|
/** What the scope step resolved to. Expands to one or two real scopes. */
|
|
645
434
|
target: SetupTarget;
|
|
@@ -1128,13 +917,13 @@ export async function runConfigureWizard(io: WizardIO = {}): Promise<WizardResul
|
|
|
1128
917
|
label: "Recommended",
|
|
1129
918
|
value: "recommended",
|
|
1130
919
|
hint: recommendedClis.length
|
|
1131
|
-
? `${recommendedClis.length} detected ${recommendedClis.length === 1 ? "CLI" : "CLIs"} ·
|
|
1132
|
-
:
|
|
920
|
+
? `${recommendedClis.length} detected ${recommendedClis.length === 1 ? "CLI" : "CLIs"} · global`
|
|
921
|
+
: "global",
|
|
1133
922
|
},
|
|
1134
923
|
{
|
|
1135
924
|
label: "Customize",
|
|
1136
925
|
value: "customize",
|
|
1137
|
-
hint: "choose scope
|
|
926
|
+
hint: "choose scope and harnesses",
|
|
1138
927
|
},
|
|
1139
928
|
],
|
|
1140
929
|
stdin,
|
|
@@ -1186,165 +975,65 @@ export async function runConfigureWizard(io: WizardIO = {}): Promise<WizardResul
|
|
|
1186
975
|
// merge time, which is exactly the layering the policy loader already does.
|
|
1187
976
|
const primaryScope: HookScope = scopes.includes("project") ? "project" : "user";
|
|
1188
977
|
|
|
1189
|
-
// 2 — Which
|
|
1190
|
-
// enabled set is the union of every ticked bundle.
|
|
1191
|
-
//
|
|
1192
|
-
// Before the assistants step, because "what do you want guarded" is the
|
|
1193
|
-
// question the user came here to answer; which CLIs to wire it into is
|
|
1194
|
-
// plumbing that follows from it.
|
|
978
|
+
// 2 — Which harnesses?
|
|
1195
979
|
//
|
|
1196
|
-
//
|
|
1197
|
-
//
|
|
980
|
+
// Setup no longer asks which policies to enable, and that is deliberate.
|
|
981
|
+
// failproofai ships no policies of its own any more: they arrive as packs —
|
|
982
|
+
// from inside this package (`pack add core`) or from anyone's GitHub release.
|
|
983
|
+
// A wizard that pre-ticks OUR list makes a product decision on behalf of
|
|
984
|
+
// somebody who has not seen the list yet, and not everyone wants the set we
|
|
985
|
+
// would have chosen. So setup wires the hooks, and choosing what they
|
|
986
|
+
// enforce is a separate act, taken later and on purpose.
|
|
1198
987
|
//
|
|
1199
|
-
//
|
|
1200
|
-
// is called with `replace: true
|
|
1201
|
-
//
|
|
1202
|
-
//
|
|
1203
|
-
// wizard. `readHooksConfig()` stays for the custom flag, which is read the same
|
|
1204
|
-
// merged way everywhere else.
|
|
1205
|
-
const customEnabledBefore = readHooksConfig().customPoliciesEnabled !== false;
|
|
988
|
+
// Whatever is already enabled at THIS scope is read and carried through
|
|
989
|
+
// untouched. `installHooks` is called with `replace: true`, so passing
|
|
990
|
+
// anything less would switch OFF policies the user had turned on — running
|
|
991
|
+
// setup a second time must never reduce protection.
|
|
1206
992
|
const enabledHere = readScopedHooksConfig(primaryScope, cwd).enabledPolicies ?? [];
|
|
1207
|
-
const
|
|
1208
|
-
|
|
1209
|
-
//
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
//
|
|
1216
|
-
//
|
|
1217
|
-
// end to end: `installHooksImpl` documents its explicit-array path as "may be
|
|
1218
|
-
// empty", `replace: true` makes it the full enabled set, and `summarize([])`
|
|
1219
|
-
// renders "none". Hooks still install, so enforcement can be switched on
|
|
1220
|
-
// later without re-running setup.
|
|
1221
|
-
//
|
|
1222
|
-
// The assistants step below keeps its minimum deliberately: an empty CLI list
|
|
1223
|
-
// does NOT mean "no assistants" there — `installHooksImpl` falls back to
|
|
1224
|
-
// ["claude"], so letting it through would silently install for Claude.
|
|
1225
|
-
// Steps 2 and 3 are navigable: ← on the harness step returns to the policy
|
|
1226
|
-
// step with the previous answer still selected. Before this, changing an
|
|
1227
|
-
// earlier answer meant abandoning setup and starting over, because a prompt
|
|
1228
|
-
// had exactly one way out and it was `null`.
|
|
993
|
+
const policies = enabledHere;
|
|
994
|
+
|
|
995
|
+
// Left alone, in both modes. This was a checkbox on the policy step, which is
|
|
996
|
+
// gone; with no row to read, the only honest value is "do not touch it".
|
|
997
|
+
// Writing `false` here switched off every convention policy on disk as a side
|
|
998
|
+
// effect of finishing setup.
|
|
999
|
+
const customEnabled: boolean | undefined = undefined;
|
|
1000
|
+
|
|
1001
|
+
// An "Everything available" row protects every supported CLI (detected +
|
|
1002
|
+
// set-up-ahead); when ticked it wins over the individual boxes.
|
|
1229
1003
|
//
|
|
1230
|
-
//
|
|
1231
|
-
// the scope question
|
|
1232
|
-
// is stated, not prompted), so ←
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
* What the harness step had ticked when ← was last pressed.
|
|
1237
|
-
*
|
|
1238
|
-
* A SEPARATE variable, because `clisSel` cannot do this job: it is the loop's
|
|
1239
|
-
* own condition (`while (clisSel === null)`), so it is null on every entry into
|
|
1240
|
-
* the body by definition, and it is assigned only on the line that ends the
|
|
1241
|
-
* loop. The restore that read `clisSel` was therefore unreachable — provably
|
|
1242
|
-
* dead, with a comment stating the opposite intent.
|
|
1243
|
-
*
|
|
1244
|
-
* The cost was not cosmetic: deselect a CLI, press ← to fix an earlier answer,
|
|
1245
|
-
* come back, and the step showed the detected defaults again. Pressing ↵ then —
|
|
1246
|
-
* reasonably, having been told the selection was carried back — re-enabled hook
|
|
1247
|
-
* installation for a CLI the user had explicitly turned off.
|
|
1248
|
-
*
|
|
1249
|
-
* `presets` just above works because it is assigned MID-loop and survives to the
|
|
1250
|
-
* next iteration; this mirrors that, filled from the prompt's `onBack`.
|
|
1251
|
-
*/
|
|
1252
|
-
const carried: { clis: string[] | null } = { clis: null };
|
|
1253
|
-
// The recommended path answers both questions here, which is what SKIPS the
|
|
1254
|
-
// loop below — its condition is `clisSel === null` and this fills it in.
|
|
1255
|
-
// Written as a pre-fill rather than as an extra clause on the loop condition
|
|
1256
|
-
// so the invariant the rest of the function depends on ("past this loop, both
|
|
1257
|
-
// are assigned") stays provable by the compiler rather than by argument.
|
|
1004
|
+
// No `allowBack`: with the policy step gone there is nothing before this
|
|
1005
|
+
// inside setup to return to — the scope question is frequently not asked at
|
|
1006
|
+
// all (a single choice is stated, not prompted), so a ← here would sometimes
|
|
1007
|
+
// go nowhere. That also retires the loop this step used to sit in, and the
|
|
1008
|
+
// carried-selection machinery the loop needed.
|
|
1009
|
+
let clisSel: string[];
|
|
1258
1010
|
if (mode === "recommended") {
|
|
1259
|
-
presets = [];
|
|
1260
1011
|
clisSel = recommendedClis;
|
|
1261
|
-
}
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
if (presets === null) return cancel();
|
|
1278
|
-
|
|
1279
|
-
// 3 — Which harnesses? An "Everything available" row protects every supported
|
|
1280
|
-
// CLI (detected + set-up-ahead); when ticked it wins over the individual boxes.
|
|
1281
|
-
// Read off a HOLDER OBJECT, not a bare `let`, and not through a cast.
|
|
1282
|
-
//
|
|
1283
|
-
// A `let` assigned only inside a callback is narrowed by control-flow analysis
|
|
1284
|
-
// to its initializer, so `priorClis.includes` will not compile — and the
|
|
1285
|
-
// original defeated that with `clisSel as string[] | null`. That cast is
|
|
1286
|
-
// precisely why the dead code type-checked and nobody noticed: it silenced the
|
|
1287
|
-
// compiler making exactly the point the reviewer later made by hand, that the
|
|
1288
|
-
// value could only ever be null. A property read carries the declared type
|
|
1289
|
-
// without suppressing anything.
|
|
1290
|
-
const priorClis = carried.clis;
|
|
1291
|
-
const picked: string[] | typeof BACK | null = await multiSelect<string>({
|
|
1292
|
-
message: "Which harnesses should it protect?",
|
|
1293
|
-
choices: [
|
|
1294
|
-
{
|
|
1295
|
-
label: "Everything available",
|
|
1296
|
-
value: ALL_CLIS,
|
|
1297
|
-
// Counts only what this scope can actually take — expanding to all 12
|
|
1298
|
-
// under project scope is what crashed the apply on Hermes.
|
|
1299
|
-
hint: `protect all ${clisSupportingScope(primaryScope).length} CLIs configurable here`,
|
|
1300
|
-
// A selector, not a harness. Counting it gave "13 harnesses" for
|
|
1301
|
-
// the 12 supported CLIs, and listed "Everything available" among them.
|
|
1302
|
-
summaryExclude: true,
|
|
1303
|
-
},
|
|
1304
|
-
...buildAgentChoices(primaryScope, cwd),
|
|
1305
|
-
].map((c) => (priorClis ? { ...c, checked: priorClis.includes(c.value) } : c)),
|
|
1012
|
+
} else {
|
|
1013
|
+
const picked = await multiSelect<string>({
|
|
1014
|
+
message: "Which harnesses should it protect?",
|
|
1015
|
+
choices: [
|
|
1016
|
+
{
|
|
1017
|
+
label: "Everything available",
|
|
1018
|
+
value: ALL_CLIS,
|
|
1019
|
+
// Counts only what this scope can actually take — expanding to all 12
|
|
1020
|
+
// under project scope is what crashed the apply on Hermes.
|
|
1021
|
+
hint: `protect all ${clisSupportingScope(primaryScope).length} CLIs configurable here`,
|
|
1022
|
+
// A selector, not a harness. Counting it gave "13 harnesses" for
|
|
1023
|
+
// the 12 supported CLIs, and listed "Everything available" among them.
|
|
1024
|
+
summaryExclude: true,
|
|
1025
|
+
},
|
|
1026
|
+
...buildAgentChoices(primaryScope, cwd),
|
|
1027
|
+
],
|
|
1306
1028
|
minSelected: 1,
|
|
1307
1029
|
summaryNoun: "harnesses",
|
|
1308
|
-
hint: "detected CLIs are pre-selected · space toggles · ctrl+a all ·
|
|
1309
|
-
allowBack: true as const,
|
|
1310
|
-
// `BACK` is a symbol and cannot carry the selection, so the prompt reports
|
|
1311
|
-
// it here instead — otherwise a ← discards what the user had ticked and the
|
|
1312
|
-
// next pass redraws the detected defaults.
|
|
1313
|
-
onBack: (checkedNow) => {
|
|
1314
|
-
carried.clis = checkedNow;
|
|
1315
|
-
},
|
|
1030
|
+
hint: "detected CLIs are pre-selected · space toggles · ctrl+a all · ↵ confirm",
|
|
1316
1031
|
stdin,
|
|
1317
1032
|
stdout,
|
|
1318
1033
|
});
|
|
1319
1034
|
if (picked === null) return cancel();
|
|
1320
|
-
// ← re-runs the loop, which re-asks the policy step with its answer intact.
|
|
1321
|
-
if (picked === BACK) continue;
|
|
1322
1035
|
clisSel = picked;
|
|
1323
1036
|
}
|
|
1324
|
-
// Non-null by construction: the loop only exits once both are assigned, and
|
|
1325
|
-
// the recommended path assigned both before it, which is why it never ran.
|
|
1326
|
-
const chosenPresets: string[] = presets ?? [];
|
|
1327
|
-
const policies =
|
|
1328
|
-
mode === "recommended"
|
|
1329
|
-
? // UNION with what is already enabled here, never a replacement for it.
|
|
1330
|
-
// `installHooks` is called with `replace: true`, so writing the bare
|
|
1331
|
-
// recommended list would silently switch OFF anything the user had
|
|
1332
|
-
// added themselves — turning "give me the sensible defaults" into a
|
|
1333
|
-
// reduction in protection, which is the one direction this must never
|
|
1334
|
-
// move. On a fresh machine `enabledHere` is empty and this is exactly
|
|
1335
|
-
// the 15.
|
|
1336
|
-
[...new Set([...RECOMMENDED_POLICIES, ...enabledHere])]
|
|
1337
|
-
: resolvePresetSelection(chosenPresets, carriedIndividual);
|
|
1338
|
-
// Only meaningful when there are files to switch off; with none, the row is
|
|
1339
|
-
// locked-unchecked and must not write a disabling flag.
|
|
1340
|
-
//
|
|
1341
|
-
// `undefined` on the recommended path, which means "leave the flag alone".
|
|
1342
|
-
// The customize expression would read as `false` here — no bundle was ticked,
|
|
1343
|
-
// so `chosenPresets.includes(CUSTOM)` is false — and would write
|
|
1344
|
-
// `customPoliciesEnabled: false`, disabling every convention policy the user
|
|
1345
|
-
// has on disk as a side effect of choosing the default setup.
|
|
1346
|
-
const customEnabled =
|
|
1347
|
-
mode === "recommended" ? undefined : hasCustomFiles ? chosenPresets.includes(CUSTOM) : undefined;
|
|
1348
1037
|
// Filter to what the chosen scopes support in BOTH branches: "Everything
|
|
1349
1038
|
// available" must not expand to CLIs that cannot take any selected scope,
|
|
1350
1039
|
// and a locked row can't be ticked but belt-and-braces keeps the invariant
|
|
@@ -1764,7 +1453,6 @@ export async function runConfigureWizard(io: WizardIO = {}): Promise<WizardResul
|
|
|
1764
1453
|
cli: clis,
|
|
1765
1454
|
cli_count: clis.length,
|
|
1766
1455
|
policy_count: policies.length,
|
|
1767
|
-
source: chosenPresets.join("+"),
|
|
1768
1456
|
connected: connect !== null,
|
|
1769
1457
|
});
|
|
1770
1458
|
|
|
@@ -1867,7 +1555,6 @@ export async function runConfigureWizard(io: WizardIO = {}): Promise<WizardResul
|
|
|
1867
1555
|
customEnabled,
|
|
1868
1556
|
daemonInstalled,
|
|
1869
1557
|
connected,
|
|
1870
|
-
chosenPresets,
|
|
1871
1558
|
),
|
|
1872
1559
|
{ ok: true },
|
|
1873
1560
|
stdout,
|