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
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: fp-cloud-cli
|
|
3
|
+
description: |-
|
|
4
|
+
The way to answer "how are my production AI agents doing?" and to run the team's agent-observability deployment — reach for it even on casual phrasing that names no tool.
|
|
5
|
+
|
|
6
|
+
Trigger when the user wants to:
|
|
7
|
+
• inspect agent telemetry — did agents error/fail/go flaky; sessions, events, latency, token usage, slowest models; eval/quality scores and whether quality dropped;
|
|
8
|
+
• operate the deployment — ack/assign/resolve/mute/dismiss issues (alerts, reports, and audit findings) with notes; run and triage audits; see who has access and change roles (e.g. read-only); create or scope API keys (e.g. a push-only CI key); change settings; run saved or ad-hoc ClickHouse queries.
|
|
9
|
+
|
|
10
|
+
Served by the `fp` CLI against FailproofAI Cloud.
|
|
11
|
+
|
|
12
|
+
NOT for writing or designing an evaluator service / scoring logic (that's `agenteye-evaluator`), adding SDK/instrumentation to your app (that's `failproofai-sdk`, imported as `failproofai_sdk`), debugging the collector/daemon, or unrelated dev work (why a build/CI run failed, rotating non-FailproofAI Cloud secrets).
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# FailproofAI Cloud CLI
|
|
16
|
+
|
|
17
|
+
`fp` is a command-line client for a FailproofAI Cloud deployment. It authenticates
|
|
18
|
+
either as a signed-in **user** or with a scoped **API key** (§2), and every command
|
|
19
|
+
takes `--json`, so it's built to be driven by an agent.
|
|
20
|
+
|
|
21
|
+
## 1. Find how to invoke it
|
|
22
|
+
|
|
23
|
+
Resolve this once, then reuse it for every call:
|
|
24
|
+
|
|
25
|
+
1. If `fp` is on `PATH` (`command -v fp`) → use **`fp`** (it's
|
|
26
|
+
installed via pipx / uv tool / pip). This is the normal case.
|
|
27
|
+
2. Else, if you're in (or under) a repo with an `fp-cloud-cli/` directory containing the
|
|
28
|
+
`fp_cli` package → run it from there with **`uv run fp`** (a local dev
|
|
29
|
+
build). The first run after a code change prints `Building…`/`Installed…` on
|
|
30
|
+
stderr — that's `uv`, not CLI output; ignore it.
|
|
31
|
+
3. Else the CLI isn't available here → tell the user to install it
|
|
32
|
+
(`pipx install fp-cloud-cli` or `uv tool install fp-cloud-cli`) and stop. Don't try to
|
|
33
|
+
reach the dashboard another way.
|
|
34
|
+
|
|
35
|
+
Don't go spelunking in the CLI source tree for flags — if you're unsure of one,
|
|
36
|
+
run `fp <group> <cmd> --help`. The source is not the documented contract
|
|
37
|
+
and reading it wastes effort.
|
|
38
|
+
|
|
39
|
+
Throughout this skill, `fp` means "whichever form you resolved."
|
|
40
|
+
|
|
41
|
+
## 2. The contract (the CLI enforces it, work with it, don't fight it)
|
|
42
|
+
|
|
43
|
+
- **Global options go BEFORE the command:** `fp --json events`, never
|
|
44
|
+
`fp events --json`. Globals are `--base-url`, `--org`, `--token`,
|
|
45
|
+
`--api-key`, `--json`, `--insecure`/`--secure`. After the command they're a
|
|
46
|
+
usage error.
|
|
47
|
+
- **Two ways to authenticate, and they are not interchangeable:**
|
|
48
|
+
|
|
49
|
+
| | How you supply it | What it is |
|
|
50
|
+
|---|---|---|
|
|
51
|
+
| **Session** | `fp login` (interactive; it emails a one-time code) | a signed-in **user**, carrying that person's org memberships and permissions |
|
|
52
|
+
| **API key** | `--api-key <key>`, or `FP_API_KEY` in the environment | a scoped **credential**, carrying exactly the permissions it was granted |
|
|
53
|
+
|
|
54
|
+
A key is what you want in CI or any other non-interactive context: no browser, no
|
|
55
|
+
emailed code, nothing to expire mid-run.
|
|
56
|
+
|
|
57
|
+
**Credential precedence, in full** (`resolve_auth`, `fp_cli/_context.py`). Read it
|
|
58
|
+
as a ladder — the first rung that applies wins, and an explicit flag outranks
|
|
59
|
+
*every* environment variable, not just its own:
|
|
60
|
+
|
|
61
|
+
0. `--api-key` **and** `--token` together → usage error, exit 2. A silent guess
|
|
62
|
+
about which you meant is the one outcome worth refusing.
|
|
63
|
+
1. `--api-key <key>` → key mode
|
|
64
|
+
2. `--token <tok>` → session mode. **This beats an ambient `FP_API_KEY`** — the
|
|
65
|
+
flag is checked before the environment value, so "`FP_API_KEY` wins" is only
|
|
66
|
+
true between the two env vars.
|
|
67
|
+
3. `FP_API_KEY` → key mode
|
|
68
|
+
4. `FP_TOKEN` → session mode
|
|
69
|
+
5. the saved session from `fp login` → session mode
|
|
70
|
+
|
|
71
|
+
The rung that catches people is 2: exporting `FP_API_KEY` in CI and *also*
|
|
72
|
+
passing `--token` runs as that user's saved session, with their org memberships,
|
|
73
|
+
rather than under the scoped key you meant to audit.
|
|
74
|
+
|
|
75
|
+
**A key is never written to the CLI's saved config** — pass it every time, from
|
|
76
|
+
the environment. `--api-key ""` means "no override" and does **not** fall back to
|
|
77
|
+
a saved session (Click treats an empty env var as unset, so it falls to rung 4).
|
|
78
|
+
|
|
79
|
+
- **Some commands need a signed-in user.** `login`, `logout`, `orgs *`, the whole
|
|
80
|
+
`agent` group, `keys update`, and all of `policies *` / `fleet *` /
|
|
81
|
+
`guardrails *` refuse a key with a usage error (**exit 2**) and make **no
|
|
82
|
+
network call at all** — there is no user to sign in, no saved active org to
|
|
83
|
+
switch, no private assistant thread to own, and the enforcement write routes
|
|
84
|
+
are root-only and deliberately absent from `/v1`. `keys update` is in that list
|
|
85
|
+
rather than a special case: `keys:update` can never be granted to a key, so it
|
|
86
|
+
is refused up front like the rest. The key is not the problem to fix — plan
|
|
87
|
+
around them rather than retrying or hunting for a flag.
|
|
88
|
+
- **Default to `--json` and parse it.** It prints clean JSON to stdout and
|
|
89
|
+
nothing else. The plain output is a boxed Rich UI meant for human eyes — it
|
|
90
|
+
burns context with box-drawing characters and is awkward to parse. Use the
|
|
91
|
+
rendered output only when the user explicitly wants to *look* at something.
|
|
92
|
+
- **Data → stdout, status/errors/prompts → stderr.** So a `--json` stdout
|
|
93
|
+
capture is pure JSON even when a status line is shown.
|
|
94
|
+
- **Branch on exit codes — don't scrape error text:**
|
|
95
|
+
|
|
96
|
+
| code | meaning | what to do |
|
|
97
|
+
|---|---|---|
|
|
98
|
+
| 0 | ok | parse stdout |
|
|
99
|
+
| 1 | unexpected / server error | report it to the user |
|
|
100
|
+
| 2 | usage error (bad flags/args) | fix the command and retry |
|
|
101
|
+
| 3 | can't reach the dashboard | check base-url / connectivity |
|
|
102
|
+
| 4 | no usable credential — not signed in, session expired, **or the API key was rejected** | session: user must run `fp login`. Key: it's missing, mistyped, disabled, or belongs to another deployment — don't retry, and don't fall back to a session |
|
|
103
|
+
| 5 | authenticated but missing permission | message names the exact permission |
|
|
104
|
+
| 6 | resource not found | the named resource doesn't exist |
|
|
105
|
+
|
|
106
|
+
## 3. First call: confirm you're connected
|
|
107
|
+
|
|
108
|
+
Before real work, run `fp --json whoami` and react to the exit code:
|
|
109
|
+
|
|
110
|
+
- **exit 4** → no usable credential. If the user is working from a session, tell
|
|
111
|
+
them to run `fp login` (it emails a one-time code and prompts
|
|
112
|
+
interactively — you can't complete it for them, and don't fabricate a token).
|
|
113
|
+
If a key was supplied, the key itself was rejected — say so and stop; logging in
|
|
114
|
+
is not the fix, and silently switching to a session would run the command as a
|
|
115
|
+
different identity than the user asked for.
|
|
116
|
+
- **base-url** → the CLI defaults to the hosted product,
|
|
117
|
+
`https://app.befailproof.ai`, so a plain `fp login` works out of the box.
|
|
118
|
+
Only pass `--base-url <url>` (or set `FP_DASHBOARD_URL`) for a self-hosted
|
|
119
|
+
or dev deployment — a local dev stack is usually `http://localhost:3000`. A
|
|
120
|
+
scheme-less URL is rejected as a usage error (exit 2).
|
|
121
|
+
- **exit 0** → `whoami` returns the active org slug and your permissions; trust
|
|
122
|
+
that for the org name and to know what you're allowed to do before attempting a
|
|
123
|
+
gated command (don't assume a particular org slug — read it from `whoami`).
|
|
124
|
+
- **In key mode, `whoami` answers a different question.** It still exits 0 —
|
|
125
|
+
`whoami` never errors — but it reports *how* you are authenticated rather than
|
|
126
|
+
*who* you are: there is no signed-in user, so it says so and names the auth mode
|
|
127
|
+
and the org it will act on. Read the auth mode; don't read "no user" as "not
|
|
128
|
+
authenticated" and don't try to log in on the strength of it. Since it isn't a
|
|
129
|
+
permission check either, let your first real read (`fp --json list envs`)
|
|
130
|
+
be what confirms the key works.
|
|
131
|
+
|
|
132
|
+
**Multi-tenant:** a user can belong to several orgs; the active one is chosen at
|
|
133
|
+
login. Override for a single command with the global `--org <slug>`
|
|
134
|
+
(`fp --org acme sessions`); change the saved default with
|
|
135
|
+
`fp orgs switch <slug>`.
|
|
136
|
+
|
|
137
|
+
> ⚠️ **With a key, name the org explicitly.** A key bound to one organization only
|
|
138
|
+
> ever acts on that one. But a key that is **not** bound to a single organization
|
|
139
|
+
> has nothing to fall back on — key mode never reads a saved active org — so the
|
|
140
|
+
> deployment resolves it to its own default, and you get **that** org's data: no
|
|
141
|
+
> error, no warning, results that look perfectly valid. If you cannot tell which
|
|
142
|
+
> kind of key you hold, pass `--org <slug>` (or set `FP_ORG`) on every
|
|
143
|
+
> command. Naming the org the key already belongs to is a no-op, and naming the
|
|
144
|
+
> wrong one fails loudly instead of quietly — both better than guessing.
|
|
145
|
+
|
|
146
|
+
## 4. Mutations: confirm with the user FIRST
|
|
147
|
+
|
|
148
|
+
The CLI normally prompts "are you sure?" before a destructive action — **but it
|
|
149
|
+
auto-skips that prompt whenever it isn't attached to a terminal, which is
|
|
150
|
+
exactly how you run it. `--json` skips it too.** So the safety prompt will not
|
|
151
|
+
fire for you.
|
|
152
|
+
|
|
153
|
+
Therefore: **before running any command that changes state, tell the user
|
|
154
|
+
plainly what will change (which resource, what value) and get an explicit OK.**
|
|
155
|
+
Then run it. (When the user's request *is* the instruction to act — "create a
|
|
156
|
+
key called X" — state the exact command you'll run and proceed; when it's vague
|
|
157
|
+
or wide-blast — delete, disable a user, rotate a key, resolve an incident —
|
|
158
|
+
stop and confirm.)
|
|
159
|
+
|
|
160
|
+
If a create fails because the name already exists (exit 2), **report that and
|
|
161
|
+
ask** — don't rename-and-retry or rotate/regenerate the existing one. A
|
|
162
|
+
`keys regenerate` you didn't intend breaks whatever already uses that key.
|
|
163
|
+
|
|
164
|
+
State-changing commands: `keys create/update/disable/regenerate`,
|
|
165
|
+
`users create/update/disable/enable`, `settings set`,
|
|
166
|
+
`alerts create/update/delete/test`, the writing `issues` subcommands
|
|
167
|
+
(`ack/assign/resolve/comment-add/comment-delete/subscribe/unsubscribe/open`),
|
|
168
|
+
`audits create/edit/delete/run` and the finding-triage verbs
|
|
169
|
+
(`ack/mute/dismiss/resolve/reopen/assign`),
|
|
170
|
+
`query create/update/delete`, `agent rename/delete`, `orgs switch`, and — the
|
|
171
|
+
highest-consequence of the lot — `policies publish/enable/disable/delete` and
|
|
172
|
+
`fleet deploy/rollback/rename`, which change what is ENFORCED on production
|
|
173
|
+
machines. A `fleet deploy` replaces a machine's entire policy set, so name the
|
|
174
|
+
policies being dropped, not just the ones being added.
|
|
175
|
+
Read-only commands (§5 "Observe") never need this.
|
|
176
|
+
|
|
177
|
+
## 5. Command map
|
|
178
|
+
|
|
179
|
+
Pick the right group; full flags are in `references/commands.md` — read it when
|
|
180
|
+
you need a flag you don't already know.
|
|
181
|
+
|
|
182
|
+
**Observe (read-only):**
|
|
183
|
+
- `events` — event log (light/payload-free responses by default; `--search` still scans payload server-side; `--full` or `--fields payload` returns the raw payload — keep bounded to a `--session-id`). `--session-id --event-type --env --agent-id --since --search --full --all`
|
|
184
|
+
- `sessions` — agent runs (time/env/agent/session/status), no scores.
|
|
185
|
+
- `evals` — evaluation results + scores; `--aggregate` for a health rollup; `--score key:min..max`.
|
|
186
|
+
- `errors` — errored events; `--aggregate` for count / sessions / agents / last-seen.
|
|
187
|
+
- `usage` — current org usage for its fixed 30-day metering window; needs `usage:read`.
|
|
188
|
+
- `list <kind>` — **discover valid filter values first**: `envs agents event_types score_filters models hooks tools error_types`.
|
|
189
|
+
|
|
190
|
+
**Manage (permission-gated, mutations):**
|
|
191
|
+
- `keys list|show|create|update|disable|regenerate` — API keys; secret shown once.
|
|
192
|
+
- `users list|show|create|update|disable|enable` — referenced by **email**.
|
|
193
|
+
- `settings list|schema|set` — fixed registry; `schema` shows what each key accepts.
|
|
194
|
+
- `alerts list|show|create|update|delete|test` — referenced by **name**.
|
|
195
|
+
- `issues list|count|show|ack|assign|resolve|comment-add|comment-list|comment-delete|subscribe|subscribers|unsubscribe|open` — by id (short ids accepted). **One board for everything needing attention**: alert breaches, hand-raised issues, and audit findings, told apart by a `source` of `alert` / `manual` / `audit`. (This group was called `incidents` before; the old name is gone.)
|
|
196
|
+
- `audits list|show|create|edit|delete|run|runs` — scheduled sweeps, referenced by **name**; `audits findings|finding` + the triage verbs `ack|mute|dismiss|resolve|reopen|assign` act on a finding **id**. `audits run <name>` only *queues* a run (poll `audits runs <name>` for completion). See §8.
|
|
197
|
+
|
|
198
|
+
**Enforce (cloud-managed policy, session-only — see §2):**
|
|
199
|
+
- `policies list|show|publish|enable|disable|delete|test|compose` — policy versions. `publish` mints a version from a local `.mjs`; `test` runs one against a synthetic context locally (it applies each policy's `match` filter, so a policy that does not cover the `--event`/`--tool` you pass is reported `skipped`, not run). `enable`/`disable`/`delete` take `--yes`.
|
|
200
|
+
- `fleet list|show|deploy|diff|history|rollback|rename` — which machines run which policies. **`deploy` REPLACES a machine's whole set** (`--add`/`--remove` amend it, `--set` replaces, `--create` mints a deployment); it prints the plan and asks **only on an interactive terminal without `--json`** — under `--json` or with stdin redirected it applies immediately, so read `fleet show` first if you want review.
|
|
201
|
+
- `guardrails summary|timeline` — what enforcement actually did; `--since 1h|6h|24h|7d`, `--machine`.
|
|
202
|
+
|
|
203
|
+
**Analytics & assistant:**
|
|
204
|
+
- `query list|show|create|update|delete|run|schema` — saved ClickHouse SQL + ad-hoc runner (`query run <name>` or `query run --sql "…"`); `query schema [table]` for table layout.
|
|
205
|
+
- `agent health|models|chats|ask|show|rename|delete` — built-in assistant; `agent ask "…"` starts a chat, `--chat <short-id>` continues one.
|
|
206
|
+
|
|
207
|
+
**Identity:** `login`, `logout`, `whoami`, `orgs {list,switch,current,perms}`, `version`, `help`.
|
|
208
|
+
All of `login` / `logout` / `orgs` — like the whole `agent` group, `keys update`, and
|
|
209
|
+
every `policies` / `fleet` / `guardrails` subcommand — are **session-only**: with a key
|
|
210
|
+
they exit 2 without calling anything (§2). `whoami`, `version` and `help` work either way.
|
|
211
|
+
|
|
212
|
+
## 6. Translating plain-English requests
|
|
213
|
+
|
|
214
|
+
Users speak in outcomes, not commands ("is anything broken?", "give CI a key",
|
|
215
|
+
"who has access?"). Map intent → command; when a value is fuzzy, run a discovery
|
|
216
|
+
command (`list <kind>`, `whoami`, a `list` subcommand) before committing.
|
|
217
|
+
|
|
218
|
+
| The user says… | Reach for |
|
|
219
|
+
|---|---|
|
|
220
|
+
| "is anything broken / failing today?", "any errors?" | `errors --since 24h --aggregate`, then `errors --since 24h --all --limit 1000` to break down |
|
|
221
|
+
| "why did that run fail?", "what happened in session X?" | `events --session-id X --all --limit 1000` (and `errors --session-id X`) |
|
|
222
|
+
| "how are my agents doing?", "show recent runs" | `sessions --since 24h` (add `--status error` for just failures) |
|
|
223
|
+
| "are the evals / quality scores ok?", "did quality drop?" | `evals --aggregate`; drill with `evals --score <key>:..0.5` |
|
|
224
|
+
| "how many events / how much traffic last week?" | `query schema` then `query run --sql "SELECT count() FROM events WHERE ts >= now() - INTERVAL 7 DAY"` |
|
|
225
|
+
| "what has this org used this metering window?" | `usage` (or `--json usage` for the complete response) |
|
|
226
|
+
| "is anything on fire?", "any alerts firing / open issues?" | `alerts list` + `issues list` (and `issues count`) |
|
|
227
|
+
| "ack / look at / resolve that issue" | `issues list` → `issues show <id>` → **confirm** → `issues ack`/`resolve <id>` |
|
|
228
|
+
| "run an audit", "what did the audit find?", "any findings to triage?" | `audits list` → `audits run <name>` (queues) → `audits runs <name>` (wait for `succeeded`) → `audits findings --audit <name>`; triage with `audits resolve/mute/dismiss <id>` — **confirm first** |
|
|
229
|
+
| "give CI / this service an API key" | `keys create <name> --add events:add` (scope to what they describe) — **state it, then create**; capture the one-time secret |
|
|
230
|
+
| "who has access?", "add / remove a teammate", "make them read-only" | `users list` / `users show <email>` / `users create`/`update`/`disable` |
|
|
231
|
+
| "change a setting", "what can I configure?" | `settings schema` (what's tunable) then `settings set <key> --value …` — **confirm first** |
|
|
232
|
+
| "what models can the assistant use?", "ask the assistant …" | `agent models`; `agent ask "…"` |
|
|
233
|
+
| "what can I query?", "run this SQL" | `query schema` / `query run --sql "…"` (or a saved `query run <name>`) |
|
|
234
|
+
| "what am I allowed to do?", "which org am I in?" | `whoami`, `orgs current`, `orgs perms` |
|
|
235
|
+
|
|
236
|
+
If the ask is ambiguous about scope (which org, which agent, read vs. change),
|
|
237
|
+
resolve it with a discovery command or a quick clarifying question rather than
|
|
238
|
+
guessing.
|
|
239
|
+
|
|
240
|
+
## 7. How to actually use it (recipes)
|
|
241
|
+
|
|
242
|
+
Discover → filter → read JSON → answer in prose:
|
|
243
|
+
|
|
244
|
+
```bash
|
|
245
|
+
fp --json list agents # find valid agent ids
|
|
246
|
+
fp --json errors --since 24h --aggregate # how bad is it right now? (full-window totals)
|
|
247
|
+
fp --json errors --since 24h --all --limit 1000 | jq '.errors[] | {session_id, error_type}'
|
|
248
|
+
fp --json sessions --status error --since 7d --all --limit 1000 # which runs failed
|
|
249
|
+
fp --json events --session-id run-001 --all --limit 1000 # a run's timeline (light: summaries, no payload)
|
|
250
|
+
fp --json events --full --session-id run-001 --all | jq '.events[].payload' # that run's RAW payloads (--full, bounded)
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
- **Raw `payload` is opt-in** — `events`/`errors` responses are payload-free by default; add
|
|
254
|
+
`--full` (or `--fields payload`) to get it, and **always bound it to a `--session-id`**
|
|
255
|
+
(the full feed is slow/OOM-prone at scale). For one event or a precise slice, read the
|
|
256
|
+
column directly: `fp --json query run --sql "SELECT payload FROM events WHERE id = <id>"`
|
|
257
|
+
(or `WHERE session_id = '<id>'`). See `references/commands.md` → "Getting the raw payload".
|
|
258
|
+
|
|
259
|
+
- **`list <kind>` before filtering** — don't guess an env or agent id; the
|
|
260
|
+
discovery command tells you exactly what exists.
|
|
261
|
+
- **`--since`** takes `24h` / `7d` / etc.
|
|
262
|
+
- **`--all` is bounded by `--limit`, which defaults to 50.** So a bare
|
|
263
|
+
`errors --since 24h --all` silently returns only the first 50 rows (with
|
|
264
|
+
`next_cursor: null`, looking complete). For a real sweep pass a high explicit
|
|
265
|
+
limit: **`--all --limit 1000`** (or higher). When you only need the totals, use
|
|
266
|
+
`--aggregate` — it covers the whole window regardless of row caps, so it's the
|
|
267
|
+
reliable cross-check that you pulled everything.
|
|
268
|
+
- **Triage flow:** `issues list` → `issues show <id>` (read the activity
|
|
269
|
+
log) → confirm with the user → `issues ack <id>` or `resolve <id>`.
|
|
270
|
+
- **Investigate a regression:** `evals --aggregate` to see which score dropped →
|
|
271
|
+
`evals --score helpfulness:..0.5` to list the bad runs → `events --session-id <id>`
|
|
272
|
+
to see what happened inside one.
|
|
273
|
+
|
|
274
|
+
When you've pulled what you need, answer the user in prose or a small table —
|
|
275
|
+
don't paste raw JSON back unless they asked for it.
|
|
276
|
+
|
|
277
|
+
## 8. Audits — the async sweep, and how findings become issues
|
|
278
|
+
|
|
279
|
+
An **audit** is a scheduled sweep that analyses recent agent behaviour (errors,
|
|
280
|
+
runaway tool loops, leaked secrets, low eval scores, …) and emits **findings**.
|
|
281
|
+
Two things about the flow matter when driving it from the CLI:
|
|
282
|
+
|
|
283
|
+
- **`audits run <name>` is asynchronous — it only *queues*.** A `{"queued": true}`
|
|
284
|
+
does NOT mean the run finished (the analysis can take minutes). Poll
|
|
285
|
+
`audits runs <name>` until the newest row reads `succeeded` (or `failed`) before
|
|
286
|
+
reading findings — don't assume results are ready on the call that queued them.
|
|
287
|
+
A disabled audit, or one already mid-run, refuses to queue (exit 1).
|
|
288
|
+
- **Findings ARE issues — it's one bucket.** Every finding graduates to an issue
|
|
289
|
+
(`source = audit`) and carries its full content there, so the same problem shows
|
|
290
|
+
up under both `audits findings` and `issues list`. Triage is **globally
|
|
291
|
+
consistent in both directions**: `audits resolve <finding-id>` closes the linked
|
|
292
|
+
issue, and `issues resolve <issue-id>` on an audit issue resolves the finding —
|
|
293
|
+
either surface works, they never disagree. Triage a finding with
|
|
294
|
+
`audits ack|mute|dismiss|resolve|reopen <id>` (durable **mute/dismiss** suppress
|
|
295
|
+
the pattern org-wide by fingerprint; **resolve** leaves no suppression, so a true
|
|
296
|
+
recurrence reopens as new). Reads need `audits:read`, every mutation
|
|
297
|
+
`audits:write` (note: triaging a finding needs `audits:write`, not an `issues:*`
|
|
298
|
+
permission — the audit is the system of record and the issue follows it).
|
|
299
|
+
|
|
300
|
+
Typical end-to-end: `audits list` → `audits run <name>` → poll `audits runs <name>`
|
|
301
|
+
→ `audits findings --audit <name>` (highest priority first) → `audits finding <id>`
|
|
302
|
+
for the full write-up → **confirm with the user** → `audits resolve <id>`.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Codex skill configuration (optional). See https://developers.openai.com/codex/skills
|
|
2
|
+
#
|
|
3
|
+
# Codex reads SKILL.md's `name`/`description` the same way Claude Code does.
|
|
4
|
+
# This file only tunes Codex-specific behavior.
|
|
5
|
+
|
|
6
|
+
# Let Codex auto-select this skill when a task matches the description
|
|
7
|
+
# (set to false to require explicit `$fp-cloud-cli` invocation).
|
|
8
|
+
allow_implicit_invocation: true
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
# FailproofAI Cloud CLI — full command reference
|
|
2
|
+
|
|
3
|
+
Flag-level detail for every group. Read the section you need; the SKILL.md body
|
|
4
|
+
already has the workflow and the contract. Remember: **globals before the
|
|
5
|
+
command**, **`--json` to parse**, **branch on exit codes**.
|
|
6
|
+
|
|
7
|
+
## Contents
|
|
8
|
+
- [Global options](#global-options)
|
|
9
|
+
- [Shared input conventions](#shared-input-conventions)
|
|
10
|
+
- [Identity: login / logout / whoami / orgs](#identity)
|
|
11
|
+
- [Observe: events / sessions / evals / errors / usage / list](#observe)
|
|
12
|
+
- [keys](#keys)
|
|
13
|
+
- [users](#users)
|
|
14
|
+
- [settings](#settings)
|
|
15
|
+
- [alerts](#alerts)
|
|
16
|
+
- [audits](#audits)
|
|
17
|
+
- [issues](#issues)
|
|
18
|
+
- [query](#query)
|
|
19
|
+
- [agent](#agent)
|
|
20
|
+
|
|
21
|
+
## Global options
|
|
22
|
+
Set on the CLI, **before** the subcommand. Precedence: flag > env var > config file (`~/.failproofai/fpcli/cli-auth.json`, mode 0600).
|
|
23
|
+
|
|
24
|
+
| Flag | Env var | Meaning |
|
|
25
|
+
|---|---|---|
|
|
26
|
+
| `--base-url <url>` | `FP_DASHBOARD_URL` | Dashboard URL. Defaults to `https://app.befailproof.ai` (the hosted product); override for self-hosted/dev. Must start with `http://`/`https://`. |
|
|
27
|
+
| `--org <slug>` | `FP_ORG` | Active org for this command (multi-tenant override). |
|
|
28
|
+
| `--token <t>` | `FP_TOKEN` | Session token (normally from config after `login`). |
|
|
29
|
+
| `--api-key <k>` | `FP_API_KEY` | Scoped API key — authenticate as a credential instead of as a signed-in user. Never saved to the config file. |
|
|
30
|
+
| `--json` | `FP_JSON` | Machine-readable JSON to stdout, nothing else. |
|
|
31
|
+
| `--insecure` / `--secure` | `FP_INSECURE` | Skip / require TLS verification (for self-signed dev certs; saved at login). |
|
|
32
|
+
| `--version` | | Print version (also `fp version`). |
|
|
33
|
+
|
|
34
|
+
Config dir resolves as `FP_HOME` > `$FAILPROOFAI_HOME/fpcli` > `~/.failproofai/fpcli`; `FP_HOME` is used as-is, `FAILPROOFAI_HOME` gets `fpcli/` appended. Telemetry is currently disabled globally while its send path is made fully non-blocking. `FP_ANALYTICS_DISABLED=1` and `DO_NOT_TRACK=1` remain supported opt-out controls for when telemetry is re-enabled.
|
|
35
|
+
|
|
36
|
+
### Session or API key
|
|
37
|
+
Exactly one credential is in play per invocation, chosen in this order:
|
|
38
|
+
|
|
39
|
+
| You supply | Result |
|
|
40
|
+
|---|---|
|
|
41
|
+
| `--api-key` **and** `--token` | usage error, exit 2 — it never guesses |
|
|
42
|
+
| `--api-key` | key mode |
|
|
43
|
+
| `--token` | session mode |
|
|
44
|
+
| `FP_API_KEY` | key mode — **wins over `FP_TOKEN`** |
|
|
45
|
+
| `FP_TOKEN` | session mode |
|
|
46
|
+
| a saved session (from `login`) | session mode |
|
|
47
|
+
| nothing | exit 4 |
|
|
48
|
+
|
|
49
|
+
- **The key is never persisted.** A session token is saved by `login` and expires on its own; an API key is valid until someone revokes it, so the CLI keeps it out of the config file entirely. Supply it per invocation, normally via `FP_API_KEY`.
|
|
50
|
+
- **`--api-key ""` means "no override", not "fall back".** Mode stays *key*, the credential is empty, and the command exits 4 — it will not quietly use a saved session. (Same rule as `--token ""`.) An empty *environment variable* is a different story: `FP_API_KEY=""` reads as unset and falls through to the next credential, so an unset CI variable can silently run as whichever human is logged in on that machine. Pass the flag if you need the strict behaviour.
|
|
51
|
+
- **A rejected key is exit 4**, same as an expired session. Report it; don't retry and don't switch credentials.
|
|
52
|
+
- **Session-only commands:** `login`, `logout`, `orgs *`, `agent *`, `keys update`, and all of `policies *`, `fleet *`, `guardrails *`. In key mode each exits **2** *before making any request* — there's no user to sign in or switch orgs for, no private assistant thread to own, and the enforcement write routes are root-only and deliberately absent from `/v1`. `keys update` is in this list and not a special case: it calls `deny_in_key_mode` as the FIRST statement of the command body, so it exits 2 with zero HTTP calls like the rest, because `keys:update` cannot be granted to any API key.
|
|
53
|
+
- **Name the org when using a key.** Key mode sends the org only when you supply it (`--org <slug>` / `FP_ORG`) — it never reuses the saved active org from `login`. A key bound to one organization only ever acts on that one; a key that is not bound to a single organization falls back to the deployment's default, and you get plausible-looking data from the wrong tenant with no error and no warning. Naming the key's own org is a no-op; naming a different one is rejected. Both beat guessing.
|
|
54
|
+
|
|
55
|
+
## Shared input conventions
|
|
56
|
+
- **`--json`** on any command → pure JSON on stdout (no Rich chrome). Mutations under `--json` auto-skip their confirm prompt.
|
|
57
|
+
- **`--yes` / `-y`** explicitly skips a confirm prompt. (Confirms are also auto-skipped on a non-TTY — i.e. whenever Claude runs it — so always confirm with the user yourself first.)
|
|
58
|
+
- **`--all` + `--limit`**: `--limit` (`-n`) defaults to **50**; `--all` auto-paginates (client chunks of 200) **up to `--limit`**, NOT without bound. So a bare `--all` still stops at 50 rows. For a full sweep on `events/sessions/evals/errors`, pass a high explicit cap: **`--all --limit 1000`** (or higher). To just get window totals, use `--aggregate` (covers the whole window regardless of row caps).
|
|
59
|
+
- **`--fields a,b,c`** projects only those keys (where supported: sessions/evals, keys, query list).
|
|
60
|
+
- **Policy source** (`policies publish` / `policies test`) comes from a path, `@path`, a pipe, `-`, or an interactive paste. A path that is not readable UTF-8 text — a binary file pointed at by mistake — is refused by name (**exit 2**), as is a missing path; neither reaches the server.
|
|
61
|
+
- **`--since <window>`** relative window — one of `15m`, `1h`, `6h`, `24h`, `7d`, `all` (any other value is a usage error, exit 2). `--from`/`--to` take ISO timestamps **with `T` and a timezone** (e.g. `2026-06-01T00:00:00Z`) — space-separated or tz-less is a usage error (exit 2).
|
|
62
|
+
- **`--file payload.json`** (or `--file -` for stdin) supplies a full JSON request body on `alerts`, `settings set`, and `users create/update` — mutually exclusive with the discrete flags. Saved-query SQL uses `--sql @file.sql`.
|
|
63
|
+
- **Multi-value filters** are CSV → `IN (...)` (union within a filter, AND across filters): `--event-type tool_use,tool_result`. `--search` is repeated/OR (matches ANY term), payload-only.
|
|
64
|
+
|
|
65
|
+
## Identity
|
|
66
|
+
|
|
67
|
+
### login / logout / whoami
|
|
68
|
+
- `fp login [--email you@x.com] [--org <slug>]` — emails a one-time code; on a real TTY it's a single interactive box, else a plain prompt. Saves the session to `~/.failproofai/fpcli/cli-auth.json` (was `~/.fp/cli.json`; a session at the old path is adopted automatically on the next command, so an upgrade signs nobody out). **You cannot complete this for the user** (it needs the emailed code). `--org` picks the tenant at login. **Session-only** — exit 2 under a key.
|
|
69
|
+
- `fp logout` — clears the saved session. **Session-only** — exit 2 under a key (a key cannot be "logged out"; revoke it instead).
|
|
70
|
+
- `fp whoami` — active org + your permissions. Run this first; exit 4 = no usable credential.
|
|
71
|
+
**Under a key it answers a different question and still exits 0:** it reports that there is no signed-in user, names the auth mode, and gives the org it will act on. So branch on the auth mode, not on the absence of a user identity — and note that it does not prove the key is accepted or check any permission. Let the first real read do that.
|
|
72
|
+
|
|
73
|
+
### orgs
|
|
74
|
+
**Session-only, the whole group** — each exits 2 under a key, with no request made. Use `--org <slug>` per command instead.
|
|
75
|
+
- `orgs list` — your orgs + role in each (active marked).
|
|
76
|
+
- `orgs switch [<slug>]` — change the saved active org; omit slug to pick from a list (TTY only). **State change** (mild) — affects later commands.
|
|
77
|
+
- `orgs current` — identity card for the active org.
|
|
78
|
+
- `orgs perms` — your permissions in the active org, grouped by resource.
|
|
79
|
+
|
|
80
|
+
## Observe
|
|
81
|
+
All read-only; never need confirmation.
|
|
82
|
+
|
|
83
|
+
### events
|
|
84
|
+
`fp events [filters] [--all]` — event log, newest first. **Default is the light,
|
|
85
|
+
payload-free feed**: rows carry `summary, is_error, error_type, output_tokens,
|
|
86
|
+
context_window, context_fill` (a server-computed `summary`, no raw payload).
|
|
87
|
+
`--session-id`, `--all`, and structured filters stay on this fast path. `--search` is the
|
|
88
|
+
exception: responses remain payload-free, but the server must scan `payload` to match the
|
|
89
|
+
free-text term, so broad searches can still be expensive. To get the raw `payload`, opt
|
|
90
|
+
into the **full feed** with `--full` (or `--fields payload`) — that read is slow at scale,
|
|
91
|
+
so keep it bounded (pair `--full` with one `--session-id`).
|
|
92
|
+
e.g. `fp --json events --full --session-id run-1 --all | jq '.events[].payload'`.
|
|
93
|
+
Filters: `--session-id <id>` `--agent-id <id>` `--event-type <csv>` `--env <csv>` `--since <window>` / `--from`/`--to` `--search <term>` (repeatable, payload OR-match).
|
|
94
|
+
|
|
95
|
+
#### Getting the raw payload
|
|
96
|
+
The default `events`/`errors` reads are payload-free. Only `--full` (or `--fields payload`)
|
|
97
|
+
returns the raw `payload`, and that is the heavy feed — **always bound it** (pair with
|
|
98
|
+
`--session-id`); an unbounded `events --full` can time out or degrade the event store at
|
|
99
|
+
scale.
|
|
100
|
+
- **A whole session:** `fp --json events --full --session-id <SESSION_ID> --all --limit 1000 | jq '.events[].payload'`
|
|
101
|
+
- **A single event:** scope to its session, then pick by id — `fp --json events --full --session-id <SESSION_ID> --all | jq '.events[] | select(.id == <EVENT_ID>) | .payload'`
|
|
102
|
+
- **An error's payload:** two steps — `fp --json errors --error-type <T> --since 24h` (gives the error's `id` and `session_id`; `errors` is light-only, no payload), then `fp --json events --full --session-id <SESSION_ID> --all | jq '.events[] | select(.id == <ERROR_EVENT_ID>) | .payload'`
|
|
103
|
+
- **Precise / by id (avoids the heavy list query):** `fp --json query run --sql "SELECT id, event_type, payload FROM events WHERE session_id = '<SESSION_ID>' ORDER BY ts"` — or `WHERE id = <EVENT_ID>`. Reads `payload` directly via the read-only SQL runner; a bounded `WHERE` is fast.
|
|
104
|
+
|
|
105
|
+
### sessions
|
|
106
|
+
`fp sessions [filters] [--all]` — agent runs: time/env/agent/session/status (no scores). Filters: `--session-id --agent-id --env --status <error|...> --since`. JSON rows still carry `scores`.
|
|
107
|
+
|
|
108
|
+
### evals
|
|
109
|
+
`fp evals [filters] [--score key:min..max] [--scores-full] [--all]` — evaluation results + scores.
|
|
110
|
+
`fp evals --aggregate [--since 7d]` — rollup: `{total, status_counts, score_stats, timeline}` (status mix + per-metric score stats). `--score helpfulness:..0.5` = max 0.5; `helpfulness:0.8..` = min 0.8; `helpfulness:0.5..0.9` = range.
|
|
111
|
+
|
|
112
|
+
### errors
|
|
113
|
+
`fp errors [filters] [--all]` — errored events (time/event/env/agent/session/summary), from the light payload-free feed; the `summary` is the server-computed field, and `--json` rows carry no payload. For a run's raw payload use `fp events --full --session-id <id>`. Filters incl. `--error-type <csv>`.
|
|
114
|
+
`fp errors --aggregate [--since 7d]` — `{total, sessions, agents, last_ts, bins}`.
|
|
115
|
+
|
|
116
|
+
### usage
|
|
117
|
+
`fp usage` — the active org's current fixed 30-day metering window, grouped for human
|
|
118
|
+
reading. Needs `usage:read`. `fp --json usage` returns the dashboard contract unchanged:
|
|
119
|
+
`org_id`, `billing_anchor`, `window`, `usage`, `calculated_at`, and `stale_after`. It has no
|
|
120
|
+
filters or subcommands and is read-only; limits and enforcement are not part of this command.
|
|
121
|
+
|
|
122
|
+
### list
|
|
123
|
+
`fp list <kind>` — discover valid filter values. Kinds: `envs agents event_types score_filters models hooks tools error_types`. JSON `{kind, values}`. Run this before filtering by a value you're unsure of.
|
|
124
|
+
|
|
125
|
+
## keys
|
|
126
|
+
API keys; the secret is shown **once** on create/regenerate (capture it then). Referenced by **name**.
|
|
127
|
+
- `keys list [--show-id] [--fields ...]` — active keys first, then revoked.
|
|
128
|
+
- `keys show <name>`
|
|
129
|
+
- `keys create <name> [--permission-set <set>] [--add <tok>] [--remove <tok>]` — permissions work **exactly like `users create`**: optionally seed from a role with `--permission-set` (`read-only`/`standard`/`admin` or a custom org set), then fine-tune with `--add`/`--remove`. Effective grants = `(set ∪ added) − removed`. For a narrowly-scoped key (the common case) just use `--add` with no set: `keys create ci-pipeline --add events:add`. Secret → stdout when piped. (There is **no** positional `PERMISSIONS` arg and **no** `-p` flag — those forms error.)
|
|
130
|
+
- `keys update <name> [--permission-set <set>] [--add <tok>] [--remove <tok>]` — incremental on the key's CURRENT grants (merges --add/--remove), unless `--permission-set` is given (which reseeds, then applies --add/--remove). `--yes`/`-y` to skip confirm. **Needs a signed-in user** — under a key it exits **2** with no request made, because `keys:update` is never assignable to a key. Every other `keys` subcommand works under a key that holds the matching grant.
|
|
131
|
+
- `keys disable <name>` — revoke.
|
|
132
|
+
- `keys regenerate <name>` — rotate secret (old one dies).
|
|
133
|
+
|
|
134
|
+
Permission token format (for `--add`/`--remove`): `slug:action` flat, or `slug:action.action` to expand several actions on one resource (e.g. `events:read.add` → `events:read`, `events:add`). Several via comma, repeated flag, or a quoted group: `--add events:read,keys:read` · `--add a --add b` · `--add "a b"`. Human-only perms (`keys:update`) can't be granted to a key. Unknown/malformed → exit 2.
|
|
135
|
+
|
|
136
|
+
## users
|
|
137
|
+
Referenced by **email** (UUID id also accepted).
|
|
138
|
+
- `users list [--show-id] [--active-only]` — `[lock] email · access · perms · joined · status`.
|
|
139
|
+
- `users show <email>` — identity + all grants.
|
|
140
|
+
- `users create [EMAIL] [--permission-set <set>] [--add tok] [--remove tok]` — `--permission-set` one of the builtin sets (`admin`/`standard`/`read-only`) or a custom set name (client-validated; unknown → exit 2). `--add`/`--remove` take compact permission tokens.
|
|
141
|
+
- `users update <email>` — assign a set, or incrementally `--add`/`--remove`. Predicts the resulting grants and confirms.
|
|
142
|
+
- `users disable <email>` / `users enable <email>` — disable has protected/self guards.
|
|
143
|
+
|
|
144
|
+
**Multi-token `--add`:** Click options aren't variadic — `--add a b` breaks. Use `--add a,b` (comma), `--add a --add b` (repeat), or `--add "a b"` (quoted).
|
|
145
|
+
|
|
146
|
+
## settings
|
|
147
|
+
A fixed registry — you read/inspect/change existing keys, you cannot create new ones.
|
|
148
|
+
- `settings list` — `key · value · type · updated` (secrets masked).
|
|
149
|
+
- `settings schema` — `key · type · accepts · description` (what each key accepts).
|
|
150
|
+
- `settings set <key> (--value V | --json-value JSON | --file f)` — exactly one value source. Unknown key → exit 6. No-op if unchanged. Server validation errors surface as `✗ <message>` (e.g. range bounds). Some keys are sensitive (signing secrets, sign-in allowlist) — confirm carefully.
|
|
151
|
+
- `allowed_sign_ins` restricts which of the organization's members may sign in; it does not grant access to anyone else. An **empty list means no restriction** (every member can sign in), so clearing it widens access rather than removing it. A non-empty list admits only matching addresses and locks out every other member. Entries are exact addresses or `*@domain.tld`; a bare `*` is rejected — use an empty list. Saving a list that does not include your own address is refused, because you could not sign in again.
|
|
152
|
+
|
|
153
|
+
## audits
|
|
154
|
+
Scheduled sweeps over agent activity, and the **findings** they produce. Audits are referenced by **name** (UUID id also accepted); findings by **id** (short ids shown in the table, `--show-id` for the full ones).
|
|
155
|
+
- `audits list [--enabled-only] [--show-id]` — `created · name · every · findings · status · last run`; disabled audits are dimmed and the footer carries the on/off split plus the open-finding total.
|
|
156
|
+
- `audits show <name>` — identity + `schedule` / `scope` / `analysis` / `channels` cards. The creator and the raw `scope`/`channels` blobs live here and in `--json`, not in the list.
|
|
157
|
+
- `audits create <name> [--file f] [--description ...] [--enabled|--disabled] [--schedule-interval-secs N] [--schedule-anchor ISO8601] [--window-mode fixed|since_last] [--lookback-window-secs N] [--scope JSON] [--ignore-error-type <csv>] [--llm|--no-llm] [--top-k N] [--sensitivity low|medium|high] [--channels JSON] [--text ... | --text-file f] [--url URL]…` — everything but the name has a server default. Name collision is pre-checked (exit 2). No confirm (creating isn't destructive). `--text`/`--text-file`/`--url` attach the reference context **in the same request**, and that is the only way to be sure the first run has it: a new enabled audit is due immediately, so context set afterwards can miss it. Same caps as `context-set` (8192 chars, 5 URLs, public `https://`); a URL the guard refuses fails the whole create, so no half-made audit is left behind. `--json` returns `{id, created_at, sources}`.
|
|
158
|
+
- `audits edit <name> [--name ...] [same flags as create] [--yes]` — the server replaces the whole definition, so a flag-only edit re-sends the current audit with your change applied (needs read **and** write). Rename onto an existing name → exit 2. Confirms first.
|
|
159
|
+
- `audits delete <name> [--yes]` — amber preview (naming the findings and run history that go with it) + confirm.
|
|
160
|
+
- `audits run <name>` — queue a run **now**, ahead of schedule. Success means queued, not finished; a disabled audit or one already mid-run is refused with the server's explanation (exit 1). JSON `{"queued": true}`.
|
|
161
|
+
- `audits context-show <name>` — the operator brief plus every reference URL with its fetch state (chars stored, whether truncated, how many secret-shaped values were masked, whether the page carries phrases that read as instructions to an AI).
|
|
162
|
+
- `audits context-set <name> [--text ... | --text-file f] [--url URL]… [--clear-urls]` — the brief and the URL list are independent, and **whatever you omit is left alone**: `--text` alone keeps the current URLs, `--url` alone keeps the current brief. `--url` replaces the whole list. Removal is always explicit — `--text ""` clears the brief, `--clear-urls` drops every URL and its stored snapshot; passing both `--url` and `--clear-urls` is a usage error (exit 2). At least one of the four is required. Max 8192 chars and 5 URLs, public `https://` only — private, loopback and cloud-metadata addresses are refused at save with the reason (exit 1). Pages are fetched in the background, so this returns before the snapshot exists.
|
|
163
|
+
- `audits context-refresh <name>` — re-fetch every non-blocked reference URL now. Snapshots refresh weekly on their own; URLs the guard refused are never retried, because nothing about them can change until the URL does.
|
|
164
|
+
|
|
165
|
+
Context is a **separate sub-resource on purpose**: `audits edit` read-merges the definition from a fixed field list, so a brief carried in that body would be silently wiped by an unrelated flag-only edit. Writing it through `context-set` makes that impossible. Creation is the one exception, and only because of a race: the audit's first run is queued the instant its row is written, so context that follows in a second request can arrive after that run started. `audits create` therefore sends it inline and the server commits both together — `audits edit` still refuses it (exit 1), which is what keeps the read-merge harmless. `--file` bodies are filtered before they are sent, so `audits show --json > f && audits edit <name> --file f` round-trips cleanly even though `show` emits server-owned fields; sending `additional_context` or `reference_urls` to the definition endpoint by hand is refused rather than ignored.
|
|
166
|
+
- `audits runs <name> [--limit N] [--show-id]` — run history, newest first: `started · status · trigger · findings · new · took`. A failed run's `error` and each run's `stats`/`report` are in `--json` only.
|
|
167
|
+
- `audits findings [--audit <name>] [--run-id <id>] [--status <csv>] [--limit N] [--offset N] [--show-id]` — the triage queue, highest priority first: `id · title · severity · status · kind · seen · last`. With no `--status` you get the live set (open + recurring); valid statuses are `open recurring resolved dismissed muted`. `--audit` takes an audit **name**.
|
|
168
|
+
- `audits finding <id>` — one finding in full: identity + `analysis` (what + likely cause) + `recommendation` (do / impact / effort) + `scope` + `evidence`. Empty sections are omitted.
|
|
169
|
+
- `audits ack <id> [--reason ...]` — seen, stays visible, ranked lower. No confirm.
|
|
170
|
+
- `audits mute <id> [--reason ...] [--yes]` — stop surfacing this pattern in future runs (durable). Confirms first.
|
|
171
|
+
- `audits dismiss <id> [--reason ...] [--yes]` — judged not worth acting on; suppressed like mute. Confirms first.
|
|
172
|
+
- `audits resolve <id> [--yes]` — you fixed it. Leaves **no** suppression, so a genuine recurrence is raised as new. Confirms first.
|
|
173
|
+
- `audits reopen <id>` — back to `open` **and** clears any mute/dismiss suppression. The undo for the three above.
|
|
174
|
+
- `audits assign <id> --to <email>` — set the owner; the status is untouched. `--to` is required (exit 2 without it).
|
|
175
|
+
|
|
176
|
+
The title column truncates to whatever width is left so the fixed columns always survive — read the full text with `audits finding <id>` or `--json`. A bad `--status`, `--window-mode`, `--sensitivity`, a non-ISO-8601 `--schedule-anchor`, or an out-of-range `--schedule-interval-secs`/`--lookback-window-secs` is rejected before any request (exit 2). `--schedule-anchor` pins the fixed UTC slot runs land on (`anchor + N * interval`), so a slow run or `audits run` can't drift the cadence; omit it on create and the server uses the next 09:00 UTC. An unknown audit name → exit 6; an unknown or malformed finding id → calm `✗ no finding …`, exit 6. Reads need `audits:read`, every mutation `audits:write`.
|
|
177
|
+
|
|
178
|
+
**`audits run` is async — it only queues.** Success is `{"queued": true}`, not a finished run; the analysis can take minutes. Poll `audits runs <name>` until the newest row is `succeeded`/`failed` before reading `audits findings`, rather than assuming results exist on the call that queued them.
|
|
179
|
+
|
|
180
|
+
**Findings and issues are one bucket.** Every finding graduates to an issue (`source: audit`) that stores the finding's full content, so the same problem appears under both `audits findings` and `issues list`. Triage is consistent in **both** directions and needs `audits:write` either way: `audits resolve|mute|dismiss|ack|reopen <finding-id>` mirrors onto the linked issue, and `issues resolve <issue-id>` on an audit issue mirrors back onto the finding — the two never disagree. **resolve** leaves no suppression (a genuine recurrence reopens as new); **mute/dismiss** suppress the pattern org-wide by fingerprint.
|
|
181
|
+
|
|
182
|
+
## issues
|
|
183
|
+
The single board for everything needing human attention — alert breaches (`source: alert`), hand-raised issues (`manual`), and audit findings (`audit`). Referenced by id (short ids accepted, `--show-id` shows them). This group was **renamed from `incidents`**; the old name no longer exists. Reads and ack/comment need `issues:read`; opening, assigning, and subscribing others need `issues:create`; resolving needs `issues:close`.
|
|
184
|
+
- `issues list [--state firing|acknowledged|resolved] [--alert-id <id>] [--limit N] [--show-id]` — there is **no** `--severity` filter on this command.
|
|
185
|
+
- `issues count`
|
|
186
|
+
- `issues show <id>` — identity + comments + subscribers + **activity log** (read this before acting). An audit-born issue (`source: audit`) carries the full finding it graduated from and back-links to the audit/run.
|
|
187
|
+
- `issues ack <id>` · `issues assign <id> --assignee <member>` (repeatable; omit to clear all assignees; each must be an operator) · `issues resolve <id>` (calm confirm). **On an audit issue these stay in sync with the finding** — resolving the issue resolves the underlying audit finding, so it can't reappear on the next run (equivalently, triage it with `audits resolve <finding-id>`; both surfaces agree).
|
|
188
|
+
- `issues open --summary <text> (--title <text> | --alert-id <id>) [--title ...] [--severity ...]` — `--title` is **required** for a standalone issue (nothing to borrow a name from); with `--alert-id` it is optional and defaults to the alert's name. Missing `--title` on the standalone path → exit 2.
|
|
189
|
+
- `issues comment-add <id> (--body <text> | --file <path>)` — `--file -` reads stdin; exactly one of the two · `comment-list <id>` · `comment-delete <id> <comment-id>`
|
|
190
|
+
- `issues subscribe <id> [--email <addr>]` · `unsubscribe <id> [--email <addr>]` · `subscribers <id>` — `--email` defaults to you; naming someone else needs `issues:create`
|
|
191
|
+
|
|
192
|
+
Malformed (non-UUID) id → calm `✗ no incident …` exit 6. Assign to a non-operator → clean 422 message.
|
|
193
|
+
|
|
194
|
+
## query
|
|
195
|
+
Saved ClickHouse SQL + ad-hoc runner. Saved queries referenced by **name**.
|
|
196
|
+
- `query list [--fields ...] [--show-id]` — `name · description · created by · created`.
|
|
197
|
+
- `query show <name>` — metadata + syntax-highlighted SQL.
|
|
198
|
+
- `query create <name> --sql "…"|@file.sql [--description ...]` — name-collision pre-checked (exit 2).
|
|
199
|
+
- `query update <name> [--name ...] [--sql ...] [--description ...] [--yes]` — partial update (≥1 field).
|
|
200
|
+
- `query delete <name>` — amber preview + confirm.
|
|
201
|
+
- `query run <name> | --sql "…" [--limit N] [--all] [--arg VALUE]…` — arguments are **positional**, bound to `$1..$N` in the order given (`--param` is an alias of `--arg`; there is no `k=v` form — `--param agent_id=x` binds the literal string `"agent_id=x"` to `$1`). Adaptive render: scalar / record / table. JSON = full QueryResult (never capped). Exec/permission errors → clean `✗ query failed` + exit code.
|
|
202
|
+
- `query schema [TABLE]` — column layout; JSON `{schema, columns:[{table,column,type,nullable}]}`.
|
|
203
|
+
|
|
204
|
+
## agent
|
|
205
|
+
**Session-only, the whole group** — each subcommand exits 2 under a key, with no request made: a chat is private to the person who owns it, and a key is not a person.
|
|
206
|
+
|
|
207
|
+
Built-in assistant. Chats referenced by a **short chat-id** (first 8 hex; prefix-resolved).
|
|
208
|
+
- `agent health` · `agent models` (available models for `--model`, default marked).
|
|
209
|
+
- `agent chats` — `chat-id · title · messages · updated`.
|
|
210
|
+
- `agent ask "MESSAGE" [--chat <short-id>] [--model <m>]` — starts a new chat (prints its short id) or continues `--chat`. On a TTY the answer renders as Markdown; piped/non-TTY prints the raw answer to stdout.
|
|
211
|
+
- `agent show <short-id>` — transcript. `agent rename <short-id> --title "…"` · `agent delete <short-id>`.
|
|
212
|
+
- Ambiguous prefix → exit 2; unknown chat → exit 6.
|
|
213
|
+
|
|
214
|
+
## policies · fleet · guardrails
|
|
215
|
+
**Session-only, all three groups** — every subcommand exits 2 under a key, with no request made. These routes are absent from the versioned API an API key authenticates against; they are an operator surface.
|
|
216
|
+
|
|
217
|
+
Cloud-managed enforcement, split the way the dashboard splits it: `policies` writes a version, `fleet` decides which machines run it, `guardrails` reports what it blocked. Needs `policies:read` to read, `policies:write` to change anything.
|
|
218
|
+
|
|
219
|
+
### policies
|
|
220
|
+
- `policies list` — one row per published VERSION (versions are immutable and all stay addressable), newest of each policy first; the title counts distinct policies and captions the version total. `state` is active / disabled / archived. JSON `{policies:[…]}` — also every version, so deduplicate on `id` for one row per policy.
|
|
221
|
+
- `policies show <id>` — the NEWEST version, including the full `source`.
|
|
222
|
+
- `policies publish <id> [SOURCE] [--description "…"] [--no-verify]` — mints a **new version**; never edits one. SOURCE is a path, `@path`, `-`, a pipe, or omitted to paste on a TTY (Ctrl-D ends). The source is **parse-checked with node** before it is sent; nothing downstream does this, and a broken policy otherwise fails on the machine at enforcement time. `--no-verify` skips it, and a host without node publishes with a warning rather than a block. **Publishing deploys nothing** — the version is unused until `fleet deploy` puts it on a machine.
|
|
223
|
+
- `policies enable <id>` · `policies disable <id> [-y]` — **disable REMOVES the policy from every deployment carrying it**, reissuing each affected machine at a new generation (visible in `fleet history`). `enable` is the exact inverse — it puts the policy back into every deployment it was removed from, reissuing those machines again. Nothing needs redeploying by hand, and `machinesUpdated` in the JSON reports the count for both directions.
|
|
224
|
+
- `policies test [SOURCE] [--tool Bash] [--command "…"] [--file PATH] [--event PreToolUse] [--expect allow|deny|instruct]` — run a policy LOCALLY and print what it decides. Executes the real file (bare `import { deny } from "failproofai"` and all) against a synthetic context; nothing is published, nothing installed. Needs `node`. `--expect` asserts the decision and exits 1 when it differs — a correct `deny` is a PASSING test, so the decision alone never sets the exit code. JSON `{ok, decision, policies:[{name,decision,reason}], expected, met}`; `decision` is the strictest any registered policy returned.
|
|
225
|
+
- `policies compose "<description>" [--out FILE] [--publish ID]` — the assistant drafts policy source from plain English. Prints it and stops by default: a generated policy that deploys itself is one nobody read. `--publish` still syntax-checks first. Needs `policies:write` for BOTH the draft and the publish — `POST /api/agent/compose-policy` is `withAuth("policies:write")`; `agent:use` gates the assistant's other routes and is not checked on this one. The composer has a **30s server-side limit** — a long or vague description simply does not finish, and raising `--timeout` does not help because the cut is not client-side. Retry with something shorter and more specific.
|
|
226
|
+
- `policies delete <id> [-y]` — archives. **A machine already carrying the policy keeps enforcing it** until redeployed; `disable` is what stops enforcement everywhere.
|
|
227
|
+
|
|
228
|
+
### fleet
|
|
229
|
+
- `fleet list` — `machine · label · pol · intended · applied · seen · events · state`. `intended` is the generation deployed, `applied` what the machine last collected (they differ until it polls), and `seen` how long since it last reported anything — a machine can be in sync and dead, or alive and behind, which are different problems. JSON `{machines, deployments}` with raw epoch-ms timestamps plus the computed `drifted`.
|
|
230
|
+
- `fleet show <machine>` — the set the machine is told to run, **and whether it has collected it**. Reads both the deployment and the machine record, so it reports `not yet collected` / `machine is on #N` / `collected` alongside who deployed it, when, and last-seen. A machine can be told to run a policy it has never picked up; the policy list alone cannot tell you which. JSON `{machine, deployment}` with raw timestamps and both label fields; `deployment: null` when nothing is deployed.
|
|
231
|
+
- `fleet deploy <machine> [--add REF]… [--remove ID]… [--set REF]… [--create] [-y]`
|
|
232
|
+
|
|
233
|
+
**A deploy REPLACES the whole set.** The endpoint takes the full list and does not merge. `--add`/`--remove` are a read-modify-write: the CLI reads the current set, applies the delta, prints the complete result, writes that. `--set` replaces everything and is refused alongside `--add`/`--remove`.
|
|
234
|
+
|
|
235
|
+
REF is `id`, `id@version`, `id:effect`, or `id@version:effect`. Effect is `enforce` (default) or `observe`. A bare `--add` of an already-deployed policy **keeps its pinned version** — pass `id@version` to move it.
|
|
236
|
+
|
|
237
|
+
Deploying to an id that has never checked in is refused (a typo would mint a machine); `--create` allows it for pre-staging.
|
|
238
|
+
|
|
239
|
+
**Races.** No server-side lock. The CLI records the generation it read and exits non-zero if the write does not land at exactly one higher — somebody else deployed, and a replace does not merge. Re-read with `fleet show` and retry.
|
|
240
|
+
|
|
241
|
+
**Idempotent.** Re-running the same deploy is a no-op that exits 0 without writing — desired-state semantics, so a retrying harness succeeds rather than errors. `applied` in the JSON is the only way to tell "changed it" from "already matched"; the exit code is 0 for both. The no-op short-circuits before the write, so a reader without `policies:write` also gets 0 there — exit 0 from a no-op is not proof of write access.
|
|
242
|
+
|
|
243
|
+
**Exit codes.** A malformed ref (`bad ref!!`, `id:banana`, empty), or `--set` combined with `--add`/`--remove`, is a usage error → **exit 2**, like every other bad flag value. A ref that parses but names something that does not exist (`--add ghost-policy`, an unpublished `@version`) is **exit 1**; an unknown machine is **exit 6**. Branch on these rather than on the message.
|
|
244
|
+
|
|
245
|
+
JSON `{plan:{result,added,removed,changed,unchanged,noop}, deployment, applied}` — the plan is included so a harness does not recompute the diff.
|
|
246
|
+
- `fleet diff [machine]` — intent vs delivery per machine, with a `drifted` flag. A machine id nobody has reported under is refused (exit 6), not rendered as an empty fleet.
|
|
247
|
+
- `fleet history <machine>` · `fleet rollback <machine> <generation> [-y]` — rollback mints a NEW generation carrying the old set; history stays append-only. The `change` column uses the deploy plan's vocabulary: `+` added, `-` removed, `~` same policy at a different version or effect (an enforce → observe flip is a policy that stopped blocking, so it is never "no change").
|
|
248
|
+
- `fleet rename <machine> "<label>"` — a human label; the id never changes. The server stores it as an override beside the machine's self-asserted label. An empty label **clears** the override (the machine falls back to its own label, else its id) and the CLI says so rather than reporting a rename to nothing. A machine that has never checked in cannot be renamed → exit 6.
|
|
249
|
+
|
|
250
|
+
### guardrails
|
|
251
|
+
- `guardrails summary [--since 1h|6h|24h|7d] [--machine ID]` — coverage, blocked/evaluated totals, a deny sparkline, and the per-policy table. Bare `fp guardrails` prints help, like every other group; the flags live on the subcommands.
|
|
252
|
+
- `guardrails timeline [--since …] [--machine ID]` — one row per time bucket: a bar scaled to the busiest bucket with the blocked share in red, plus total / denied / instructed counts. Answers *when* enforcement bit, which the summary's sparkline only sketches.
|
|
253
|
+
- A `(no policy)` row is **normal**: most evaluations are allows nothing objected to, and the row keeps the denominator visible.
|
|
254
|
+
- Coverage comes from the control plane, decision counts from reported telemetry — a machine can be deployed-to and silent, or reporting and undeployed.
|
|
File without changes
|