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
|
@@ -31,6 +31,7 @@ import { trackHookEvent } from "./hook-telemetry";
|
|
|
31
31
|
import { getInstanceId } from "../../lib/telemetry-id";
|
|
32
32
|
import type { CustomHook } from "./policy-types";
|
|
33
33
|
import type { CloudManagedPolicyArtifact } from "./cloud-managed-policies";
|
|
34
|
+
import type { ResolvedPack } from "./pack-manifest";
|
|
34
35
|
import { customPoliciesDir, shimsDir } from "./fp-home";
|
|
35
36
|
|
|
36
37
|
const LOADING_KEY = "__FAILPROOFAI_LOADING_HOOKS__";
|
|
@@ -172,6 +173,11 @@ async function importWithDeadline(fileUrl: string): Promise<void> {
|
|
|
172
173
|
* Load a single policy file into the globalThis custom hooks registry.
|
|
173
174
|
* Does NOT clear the registry — caller is responsible for that.
|
|
174
175
|
*/
|
|
176
|
+
export interface PolicyLoadFailure {
|
|
177
|
+
type: "module_not_found" | "syntax_error" | "load_timeout" | "runtime_error" | "path_missing";
|
|
178
|
+
reason: string;
|
|
179
|
+
}
|
|
180
|
+
|
|
175
181
|
async function loadSingleFile(
|
|
176
182
|
absPath: string,
|
|
177
183
|
opts?: {
|
|
@@ -180,7 +186,7 @@ async function loadSingleFile(
|
|
|
180
186
|
/** Cloud-managed policies pass their pinned digest for load-time re-verification. */
|
|
181
187
|
verifyEntrySha?: string;
|
|
182
188
|
},
|
|
183
|
-
): Promise<
|
|
189
|
+
): Promise<PolicyLoadFailure | null> {
|
|
184
190
|
const g = globalThis as Record<string, unknown>;
|
|
185
191
|
g[LOADING_KEY] = true;
|
|
186
192
|
|
|
@@ -208,7 +214,7 @@ async function loadSingleFile(
|
|
|
208
214
|
const cached = policyModuleCache.get(absPath);
|
|
209
215
|
if (cached?.fingerprint === fingerprint) {
|
|
210
216
|
for (const hook of cached.hooks) customPolicies.add({ ...hook });
|
|
211
|
-
return;
|
|
217
|
+
return null;
|
|
212
218
|
}
|
|
213
219
|
|
|
214
220
|
const entryTmp = absPath + tmpSuffix;
|
|
@@ -222,6 +228,7 @@ async function loadSingleFile(
|
|
|
222
228
|
.slice(hooksBefore)
|
|
223
229
|
.map((hook) => ({ ...hook })),
|
|
224
230
|
});
|
|
231
|
+
return null;
|
|
225
232
|
} catch (err) {
|
|
226
233
|
const msg = err instanceof Error ? err.message : String(err);
|
|
227
234
|
const errorType = /Cannot find module|MODULE_NOT_FOUND|ENOENT/i.test(msg)
|
|
@@ -239,6 +246,7 @@ async function loadSingleFile(
|
|
|
239
246
|
});
|
|
240
247
|
if (opts?.strict) throw new Error(`Failed to load custom hooks from ${absPath}: ${msg}`);
|
|
241
248
|
hookLogError(`failed to load custom hooks from ${absPath}: ${msg}`);
|
|
249
|
+
return { type: errorType, reason: msg };
|
|
242
250
|
} finally {
|
|
243
251
|
g[LOADING_KEY] = false;
|
|
244
252
|
await cleanupTmpFiles(tmpFiles);
|
|
@@ -293,6 +301,8 @@ export interface ConventionSource {
|
|
|
293
301
|
export interface LoadAllResult {
|
|
294
302
|
hooks: CustomHook[];
|
|
295
303
|
conventionSources: ConventionSource[];
|
|
304
|
+
/** Import failures keyed by pack id, including artifacts that registered no hooks. */
|
|
305
|
+
packFailures: Map<string, PolicyLoadFailure>;
|
|
296
306
|
}
|
|
297
307
|
|
|
298
308
|
export function customPolicyId(file: string, name: string): string {
|
|
@@ -330,17 +340,53 @@ function warnSkippedPolicyFiles(dir: string, scope: "project" | "user"): void {
|
|
|
330
340
|
);
|
|
331
341
|
}
|
|
332
342
|
|
|
343
|
+
/**
|
|
344
|
+
* A pack's manifest declares what it contains; its artifact decides what runs.
|
|
345
|
+
* Nothing binds the two, so they can disagree — and the disagreement is silent
|
|
346
|
+
* in both directions and worse in one.
|
|
347
|
+
*
|
|
348
|
+
* A policy the artifact registers but the manifest omits is enforcement that no
|
|
349
|
+
* `failproofai policies` listing will ever show. A policy the manifest declares
|
|
350
|
+
* but the artifact never registers is the dangerous one: the listing says the
|
|
351
|
+
* machine is protected against something nothing is checking.
|
|
352
|
+
*
|
|
353
|
+
* Both are announced rather than corrected. The artifact is digest-pinned, so
|
|
354
|
+
* what it registers IS what the publisher shipped and dropping any of it would
|
|
355
|
+
* be inventing a third answer; the manifest is what needs fixing, upstream.
|
|
356
|
+
*/
|
|
357
|
+
function reconcilePackManifest(pack: ResolvedPack | undefined, loaded: CustomHook[]): void {
|
|
358
|
+
if (!pack || pack.policies.length === 0) return;
|
|
359
|
+
const declared = new Set(pack.policies.map((p) => p.name));
|
|
360
|
+
const registered = new Set(loaded.map((h) => h.name));
|
|
361
|
+
const missing = [...declared].filter((n) => !registered.has(n));
|
|
362
|
+
const extra = [...registered].filter((n) => !declared.has(n));
|
|
363
|
+
if (missing.length > 0) {
|
|
364
|
+
hookLogWarn(
|
|
365
|
+
`pack ${pack.id}@${pack.version} declares ${missing.join(", ")} but its artifact does not ` +
|
|
366
|
+
`register ${missing.length === 1 ? "it" : "them"} — listed as protection that never runs`,
|
|
367
|
+
);
|
|
368
|
+
}
|
|
369
|
+
if (extra.length > 0) {
|
|
370
|
+
hookLogWarn(
|
|
371
|
+
`pack ${pack.id}@${pack.version} registers undeclared ${extra.join(", ")} — ` +
|
|
372
|
+
`${extra.length === 1 ? "it enforces" : "they enforce"} but will not appear in listings`,
|
|
373
|
+
);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
333
377
|
export async function loadAllCustomHooks(
|
|
334
378
|
customPoliciesPaths: string | string[] | undefined,
|
|
335
379
|
opts?: {
|
|
336
380
|
sessionCwd?: string;
|
|
337
381
|
customPoliciesEnabled?: boolean;
|
|
338
382
|
cloudManagedPolicies?: CloudManagedPolicyArtifact[];
|
|
383
|
+
packs?: ResolvedPack[];
|
|
339
384
|
},
|
|
340
385
|
): Promise<LoadAllResult> {
|
|
341
386
|
clearCustomHooks();
|
|
342
387
|
|
|
343
388
|
const conventionSources: ConventionSource[] = [];
|
|
389
|
+
const packFailures = new Map<string, PolicyLoadFailure>();
|
|
344
390
|
|
|
345
391
|
const projectRoot = findProjectConfigDir(opts?.sessionCwd ?? process.cwd());
|
|
346
392
|
|
|
@@ -395,6 +441,30 @@ export async function loadAllCustomHooks(
|
|
|
395
441
|
}
|
|
396
442
|
}
|
|
397
443
|
|
|
444
|
+
// Installed packs, keyed by artifact path — the same content-addressing, and
|
|
445
|
+
// therefore the same collision, as the cloud map above: two packs whose entry
|
|
446
|
+
// file is byte-identical resolve to ONE artifact, `loadedPaths` imports it
|
|
447
|
+
// once, and the loser would vanish silently with its effect deciding nothing.
|
|
448
|
+
// Resolved the same way and for the same reason — toward ENFORCEMENT, because
|
|
449
|
+
// over-enforcing is visible to whoever hits it and under-enforcing is the
|
|
450
|
+
// silent failure — and announced, so an operator can act on it.
|
|
451
|
+
const packByPath = new Map<string, ResolvedPack>();
|
|
452
|
+
for (const pack of opts?.packs ?? []) {
|
|
453
|
+
const key = resolve(pack.path);
|
|
454
|
+
const existing = packByPath.get(key);
|
|
455
|
+
if (!existing) {
|
|
456
|
+
packByPath.set(key, pack);
|
|
457
|
+
continue;
|
|
458
|
+
}
|
|
459
|
+
hookLogWarn(
|
|
460
|
+
`packs ${existing.id} and ${pack.id} have identical source, so they share one artifact ` +
|
|
461
|
+
`and load as one pack; enforcing it if either asks to enforce`,
|
|
462
|
+
);
|
|
463
|
+
if (existing.effect !== "enforce" && pack.effect === "enforce") {
|
|
464
|
+
packByPath.set(key, pack);
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
|
|
398
468
|
// 1. Explicit custom policy paths. Accept a string for callers/configs using
|
|
399
469
|
// the legacy singular form.
|
|
400
470
|
for (const customPoliciesPath of typeof customPoliciesPaths === "string"
|
|
@@ -403,31 +473,44 @@ export async function loadAllCustomHooks(
|
|
|
403
473
|
// resolve() also normalizes absolute paths, so aliases containing `.` or
|
|
404
474
|
// `..` share a dedup key with convention-discovered canonical paths.
|
|
405
475
|
const absPath = resolve(projectRoot, customPoliciesPath);
|
|
476
|
+
const cloudManaged = cloudManagedByPath.get(absPath);
|
|
477
|
+
const pack = packByPath.get(absPath);
|
|
406
478
|
if (existsSync(absPath)) {
|
|
407
479
|
if (!loadedPaths.has(absPath)) {
|
|
408
480
|
loadedPaths.add(absPath);
|
|
409
481
|
const hooksBefore = getCustomHooks().length;
|
|
410
482
|
// A cloud-managed policy re-verifies its pinned digest at load, binding
|
|
411
483
|
// the imported bytes to what desired-state promised.
|
|
412
|
-
|
|
413
|
-
|
|
484
|
+
// A pack re-verifies its pinned digest at load for the same reason a
|
|
485
|
+
// cloud policy does: the manifest read and the import are two moments,
|
|
486
|
+
// and only this one binds the bytes actually executed to what was
|
|
487
|
+
// promised.
|
|
488
|
+
const failure = await loadSingleFile(absPath, {
|
|
489
|
+
verifyEntrySha:
|
|
490
|
+
cloudManaged?.sha256 ?? pack?.sha256,
|
|
414
491
|
});
|
|
492
|
+
if (failure && pack) packFailures.set(pack.id, failure);
|
|
415
493
|
for (const hook of getCustomHooks().slice(hooksBefore)) {
|
|
416
|
-
const cloudManaged = cloudManagedByPath.get(absPath);
|
|
417
494
|
const tagged = hook as CustomHook & {
|
|
418
495
|
__policyId?: string;
|
|
419
496
|
__cloudManaged?: CloudManagedPolicyArtifact;
|
|
497
|
+
__pack?: ResolvedPack;
|
|
420
498
|
};
|
|
421
499
|
if (cloudManaged) {
|
|
422
500
|
tagged.__cloudManaged = cloudManaged;
|
|
423
501
|
tagged.__policyId = `cloud:${cloudManaged.id}@${cloudManaged.version}:${hook.name}`;
|
|
502
|
+
} else if (pack) {
|
|
503
|
+
tagged.__pack = pack;
|
|
504
|
+
tagged.__policyId = `pack:${pack.id}@${pack.version}:${hook.name}`;
|
|
424
505
|
} else {
|
|
425
506
|
tagged.__policyId = customPolicyId(absPath, hook.name);
|
|
426
507
|
}
|
|
427
508
|
}
|
|
509
|
+
reconcilePackManifest(pack, getCustomHooks().slice(hooksBefore));
|
|
428
510
|
}
|
|
429
511
|
} else {
|
|
430
512
|
hookLogWarn(`custom policy path not found: ${absPath}`);
|
|
513
|
+
if (pack) packFailures.set(pack.id, { type: "path_missing", reason: `path missing: ${absPath}` });
|
|
431
514
|
}
|
|
432
515
|
}
|
|
433
516
|
|
|
@@ -569,5 +652,5 @@ export async function loadAllCustomHooks(
|
|
|
569
652
|
}
|
|
570
653
|
}
|
|
571
654
|
|
|
572
|
-
return { hooks: allHooks, conventionSources };
|
|
655
|
+
return { hooks: allHooks, conventionSources, packFailures };
|
|
573
656
|
}
|
package/src/hooks/fp-home.ts
CHANGED
|
@@ -210,6 +210,26 @@ export const globalPolicyConfigFile = (home?: string) =>
|
|
|
210
210
|
*/
|
|
211
211
|
export const cloudPoliciesDir = (home?: string) => resolve(policiesDir(home), "cloud-policies");
|
|
212
212
|
|
|
213
|
+
/**
|
|
214
|
+
* Installed policy packs — a sibling of `cloudPoliciesDir` and flat for the same
|
|
215
|
+
* reason: `artifacts/<sha256>.mjs` is content-addressed, so an install can only
|
|
216
|
+
* ever write a file that does not exist yet and is structurally incapable of
|
|
217
|
+
* disturbing what is currently live. `installed.json` names which artifacts are
|
|
218
|
+
* active and is written last, so activation is one atomic flip.
|
|
219
|
+
*
|
|
220
|
+
* Living under `policies/` is safe ONLY because the convention loader does not
|
|
221
|
+
* recurse — `discoverPolicyFiles` and `findSkippedPolicyFiles` both filter on
|
|
222
|
+
* `isFile()`, so nothing under `packs/` can be picked up as an unverified
|
|
223
|
+
* convention policy. `fp-home.test.ts` pins that non-recursion.
|
|
224
|
+
*/
|
|
225
|
+
export const packsDir = (home?: string) => resolve(policiesDir(home), "packs");
|
|
226
|
+
|
|
227
|
+
/** The activation pointer. Written last and atomically. */
|
|
228
|
+
export const packsInstalledFile = (home?: string) => resolve(packsDir(home), "installed.json");
|
|
229
|
+
|
|
230
|
+
/** Content-addressed pack artifacts, shared across packs and versions. */
|
|
231
|
+
export const packArtifactsDir = (home?: string) => resolve(packsDir(home), "artifacts");
|
|
232
|
+
|
|
213
233
|
// ── Collector ────────────────────────────────────────────────────────────────
|
|
214
234
|
|
|
215
235
|
/** Per-source watermarks. One directory per source — never shared: the cursor
|
|
@@ -218,7 +238,14 @@ export const cloudPoliciesDir = (home?: string) => resolve(policiesDir(home), "c
|
|
|
218
238
|
export const cursorsDir = (source?: string, home?: string) =>
|
|
219
239
|
source ? resolve(atHome(home, "cursors"), source) : atHome(home, "cursors");
|
|
220
240
|
|
|
221
|
-
/** The SDK spool root
|
|
241
|
+
/** The SDK spool root, and the ONLY root `failproofai-sdk` writes to.
|
|
242
|
+
*
|
|
243
|
+
* The daemon additionally watches `~/.agenteye/events` (see `spool_dirs` in
|
|
244
|
+
* `crates/fpai-collect/src/config.rs`) so that SDKs old enough to write there,
|
|
245
|
+
* and batches already sitting there, keep being collected. But no current SDK
|
|
246
|
+
* puts anything in it: `$AGENTEYE_HOME` used to redirect the spool and no
|
|
247
|
+
* longer does, precisely so that exporting it for the older
|
|
248
|
+
* `agenteye-collector` cannot relocate the SDK as a side effect. */
|
|
222
249
|
export const customAgentsDir = (home?: string) => atHome(home, "custom-agents");
|
|
223
250
|
export const customAgentsEventsDir = (home?: string) => resolve(customAgentsDir(home), "events");
|
|
224
251
|
export const customAgentsFailedDir = (home?: string) => resolve(customAgentsDir(home), "failed");
|
|
@@ -273,6 +300,48 @@ export const auditSessionFile = (home?: string) => resolve(auditDir(home), "sess
|
|
|
273
300
|
export const auditMachineFile = (home?: string) => resolve(auditDir(home), "machine.json");
|
|
274
301
|
|
|
275
302
|
|
|
303
|
+
// ── fp-cloud-cli ───────────────────────────────────────────────────────────────────
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* The Cloud CLI's own directory (`fp-cloud-cli` on PyPI, command `fp`).
|
|
307
|
+
*
|
|
308
|
+
* Written by PYTHON, not by anything in this repo's TypeScript or Rust — the
|
|
309
|
+
* CLI resolves it independently in `fp-cloud-cli/fp_cli/config.py`. It is declared
|
|
310
|
+
* here anyway because this file is the register of what may exist in the home,
|
|
311
|
+
* and a path absent from it is only safe by accident: `resettablePaths()` is a
|
|
312
|
+
* filter over `HOME_CLASSES`, so an unregistered directory survives today and
|
|
313
|
+
* survives the next migration only until someone lists its parent.
|
|
314
|
+
*
|
|
315
|
+
* Not classified itself — `auditDir`'s rule applies, classify the children. The
|
|
316
|
+
* directory may grow a cache later; the credential in it must never be dropped.
|
|
317
|
+
*/
|
|
318
|
+
export const fpcliDir = (home?: string) => atHome(home, "fpcli");
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* The CLI's signed-in session. `0600`, written only by `fp login` / `fp logout`.
|
|
322
|
+
*
|
|
323
|
+
* Was `~/.fp/cli.json` — a third top-level dotfile for one product. The old
|
|
324
|
+
* file is deliberately left where it is: `load_config` in
|
|
325
|
+
* `fp-cloud-cli/fp_cli/config.py` reads it when nothing is here yet, writes the
|
|
326
|
+
* session to this path, and does NOT delete the original, so downgrading to a
|
|
327
|
+
* previous `fp` finds its session intact. Adoption is best-effort — an
|
|
328
|
+
* unwritable home hands back the session it found rather than logging the
|
|
329
|
+
* machine out — and it costs the user no login.
|
|
330
|
+
*
|
|
331
|
+
* This paragraph said the opposite until it was checked against the code: that
|
|
332
|
+
* there was no migration and the upgrade cost a login. There is one, it is
|
|
333
|
+
* covered by `fp-cloud-cli/tests/test_failproofai_home.py`, and the only true half
|
|
334
|
+
* was that the old file survives.
|
|
335
|
+
*
|
|
336
|
+
* `user-typed` for the same reason as `auditSessionFile` beside it: nothing
|
|
337
|
+
* regenerates a session, and dropping it silently signs the machine out.
|
|
338
|
+
*
|
|
339
|
+
* TS-side only, like `auditSessionFile`, and absent from `paths.rs` by design —
|
|
340
|
+
* the daemon has no reason to open a human credential, and mirroring a path
|
|
341
|
+
* only Python writes would give `paths.rs` an entry nothing there reads.
|
|
342
|
+
*/
|
|
343
|
+
export const fpcliAuthFile = (home?: string) => resolve(fpcliDir(home), "cli-auth.json");
|
|
344
|
+
|
|
276
345
|
// ── Hook activity ────────────────────────────────────────────────────────────
|
|
277
346
|
|
|
278
347
|
/** The decision log: page-sized JSONL the dashboard's activity tab reads. */
|
|
@@ -469,9 +538,15 @@ export type DataClass =
|
|
|
469
538
|
* else under it is scratch. Listing the parent is exactly how a reset came
|
|
470
539
|
* to delete undelivered events and the machine's own telemetry identity.
|
|
471
540
|
*
|
|
472
|
-
* `home
|
|
473
|
-
* module is either classified here or covered by a classified parent, so
|
|
474
|
-
* next path added to the home cannot skip the one question that matters.
|
|
541
|
+
* `__tests__/hooks/fp-home.test.ts` asserts every exported path function in
|
|
542
|
+
* this module is either classified here or covered by a classified parent, so
|
|
543
|
+
* the next path added to the home cannot skip the one question that matters.
|
|
544
|
+
*
|
|
545
|
+
* It cited `home-classification.test.ts` until that was checked — a file that
|
|
546
|
+
* has never existed. The guard was real and in the wrong place, which is the
|
|
547
|
+
* failure this header already describes happening once before: a citation is
|
|
548
|
+
* only load-bearing if somebody follows it, and the person who does is looking
|
|
549
|
+
* for the rule they are about to break.
|
|
475
550
|
*/
|
|
476
551
|
export const HOME_CLASSES: readonly { path: (home?: string) => string; class: DataClass }[] = [
|
|
477
552
|
// ── Never deleted: a person typed it ──
|
|
@@ -498,6 +573,11 @@ export const HOME_CLASSES: readonly { path: (home?: string) => string; class: Da
|
|
|
498
573
|
// with no notice, and the machine only finds out the next time it tries to
|
|
499
574
|
// report.
|
|
500
575
|
{ path: auditSessionFile, class: "user-typed" },
|
|
576
|
+
// The Cloud CLI's session, written by Python (`fp-cloud-cli/fp_cli/config.py`). The
|
|
577
|
+
// one entry here whose writer is outside this repo's TS and Rust, which is
|
|
578
|
+
// exactly why it needs listing: nothing in a migration would otherwise know a
|
|
579
|
+
// credential lives under `fpcli/`.
|
|
580
|
+
{ path: fpcliAuthFile, class: "user-typed" },
|
|
501
581
|
|
|
502
582
|
// ── Never deleted: recorded and not yet shipped ──
|
|
503
583
|
// Batches read out of transcripts and queued for upload. The reason losing
|
|
@@ -574,6 +654,14 @@ export const HOME_CLASSES: readonly { path: (home?: string) => string; class: Da
|
|
|
574
654
|
// directory holds both the files a person wrote and the ones the fleet sent,
|
|
575
655
|
// and only the second kind may be thrown away.
|
|
576
656
|
{ path: cloudPoliciesDir, class: "refetchable" },
|
|
657
|
+
// Installed packs. Third-party packs are re-fetchable by `failproofai pack
|
|
658
|
+
// add`; the bundled default pack is restored from the package immediately
|
|
659
|
+
// after reset. So this is the fleet's argument again: one directory holds both
|
|
660
|
+
// what a person wrote and what a command fetched, and only the second kind may
|
|
661
|
+
// be thrown away. Without this row `packs/` inherits `policiesDir`'s
|
|
662
|
+
// `user-typed` and survives a reset that is supposed to clear re-fetchable
|
|
663
|
+
// state.
|
|
664
|
+
{ path: packsDir, class: "refetchable" },
|
|
577
665
|
|
|
578
666
|
// ── Never touched ──
|
|
579
667
|
// A downloaded daemon binary is large, version-pinned and re-verified on use,
|
package/src/hooks/fp-reset.ts
CHANGED
|
@@ -98,6 +98,7 @@ import {
|
|
|
98
98
|
isDaemonSupportedPlatform,
|
|
99
99
|
probeDaemonEndToEnd,
|
|
100
100
|
} from "./daemon-service";
|
|
101
|
+
import { readHooksConfig } from "./hooks-config";
|
|
101
102
|
|
|
102
103
|
export interface ResetOutcome {
|
|
103
104
|
/** Paths that existed and were removed. */
|
|
@@ -964,6 +965,33 @@ export function resetHome(from: number, to: number = LAYOUT_VERSION): ResetOutco
|
|
|
964
965
|
// straight out of the same file. Both paths end at the same key, and only one
|
|
965
966
|
// of them represents something a person typed.
|
|
966
967
|
if (telemetryOptOut) updateConfig({ telemetry: { enabled: false } });
|
|
968
|
+
// `packs/` is resettable, but the package's default pack is also the offline
|
|
969
|
+
// enforcement floor. Restore it from the installed package before declaring
|
|
970
|
+
// the migration complete; third-party packs remain explicitly re-fetchable.
|
|
971
|
+
//
|
|
972
|
+
// Carrying `enabledPolicies` INTO the selection, not installing defaults over
|
|
973
|
+
// it. This is the upgrade path every existing user takes, and installing
|
|
974
|
+
// defaults meant a machine that had switched `block-force-push` and
|
|
975
|
+
// `block-kubectl` on came back with them off — guards that were denying
|
|
976
|
+
// before the upgrade and allowing after, with nothing said.
|
|
977
|
+
const carried = (() => {
|
|
978
|
+
try {
|
|
979
|
+
const names = readHooksConfig().enabledPolicies ?? [];
|
|
980
|
+
return names.length > 0 ? { only: names } : undefined;
|
|
981
|
+
} catch {
|
|
982
|
+
return undefined;
|
|
983
|
+
}
|
|
984
|
+
})();
|
|
985
|
+
// Deliberately does NOT install a pack. There is no copy in this package to
|
|
986
|
+
// install any more, and `resetHome` is synchronous and runs inside
|
|
987
|
+
// `failproofai update` — an upgrade that blocks on github.com, and fails when
|
|
988
|
+
// it is unreachable, is a worse upgrade than one that finishes.
|
|
989
|
+
//
|
|
990
|
+
// The carried names stay in config, which is what the no-pack fallback reads,
|
|
991
|
+
// so a machine mid-upgrade keeps enforcing exactly what it enforced before.
|
|
992
|
+
// `failproofai policies add core` turns them into a real pack when the user
|
|
993
|
+
// is online, and carries this selection into it.
|
|
994
|
+
void carried;
|
|
967
995
|
// The step's OWN target, not LAYOUT_VERSION.
|
|
968
996
|
//
|
|
969
997
|
// Every step used to end stamping the current layout, which was harmless
|
|
@@ -1344,8 +1372,12 @@ function staleDaemonHint(): string[] {
|
|
|
1344
1372
|
`[failproofai] daemon is ${skew.installed}, CLI is ${skew.expected}.`,
|
|
1345
1373
|
`This machine is configured to REQUIRE the daemon. A daemon built against a`,
|
|
1346
1374
|
`different on-disk layout refuses to start, and this version moved it — so the`,
|
|
1347
|
-
|
|
1348
|
-
|
|
1375
|
+
// The wrap is load-bearing: "denies every tool call" is the consequence
|
|
1376
|
+
// this message exists to state, and splitting it across two lines is
|
|
1377
|
+
// what made the test asserting that phrase fail while the text looked
|
|
1378
|
+
// perfectly correct to a human reading it.
|
|
1379
|
+
`next reboot or restart can leave the service down, which`,
|
|
1380
|
+
`denies every tool call until it is fixed.`,
|
|
1349
1381
|
`Run \`failproofai update\` now to bring the daemon in line.`,
|
|
1350
1382
|
``,
|
|
1351
1383
|
];
|