failproofai 1.0.12-beta.2 → 1.0.13-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 +13 -13
- package/.next/standalone/.next/prerender-manifest.json +3 -3
- package/.next/standalone/.next/required-server-files.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page.js +2 -1
- package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_global-error.html +1 -1
- package/.next/standalone/.next/server/app/_global-error.rsc +2 -2
- package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page.js +4 -3
- 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 +3 -3
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/api/audit/invite/route.js +6 -5
- 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 +27 -26
- 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 +4 -3
- 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 +6 -5
- 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 +6 -5
- 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 +6 -5
- 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 +6 -5
- 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 +4 -3
- package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/audit/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
- package/.next/standalone/.next/server/app/audit/page.js +7 -6
- 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 +3 -3
- package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +3 -3
- package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/page.js +6 -5
- package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/policies/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +14 -14
- 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/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page.js +21 -20
- package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js +10 -9
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/projects/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/projects/page.js +7 -6
- 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/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +8 -8
- package/.next/standalone/.next/server/app/settings/page.js +6 -5
- 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]__0vt9i6fqinjne._.js → [externals]__1h83uo-b1b6-2._.js} +1 -1
- package/.next/standalone/.next/server/chunks/[externals]__214wn4wh2x79y._.js +3 -0
- package/.next/standalone/.next/server/chunks/{[externals]__1rlxpymm37wel._.js → [root-of-the-server]__031qp1lkow_kc._.js} +2 -2
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__038kwryp970nh._.js +3 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0_hsnj_a2mvl_._.js → [root-of-the-server]__03s1za0hn71yp._.js} +2 -2
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0wg9dk8x8bnau._.js → [root-of-the-server]__07a0sa6fuw5_b._.js} +2 -2
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__08atcie7jzswm._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__08dchfudh2_4f._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0car70pylmvor._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0spt0kv8azrpl._.js +1 -1
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__12kq3x-h7t7i1._.js → [root-of-the-server]__0yvyp5b7jmlc4._.js} +2 -2
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__02vous7mpi2xm._.js → [root-of-the-server]__145vo_drnuvas._.js} +2 -2
- package/.next/standalone/.next/server/chunks/{[externals]__0h0p9dmv_e7r7._.js → [root-of-the-server]__1a2d0ewycsp6k._.js} +2 -2
- package/.next/standalone/.next/server/chunks/{[externals]__1_407huhlmj1m._.js → [root-of-the-server]__1am_1tz0o0aqz._.js} +2 -2
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__03i5o4a840guz._.js → [root-of-the-server]__1gxfzuvpyw30j._.js} +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1j6kfp0vzu5rw._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1l0ayum_hqqsw._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1lh8c0mmhdrbj._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1o9rznwc0w7og._.js +3 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0f_4g-vazrvxv._.js → [root-of-the-server]__1o_622x0fglpr._.js} +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1oclamblhzhrf._.js +68 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1v1-l-83czzsr._.js +63 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__1a5zkndjwlc13._.js → [root-of-the-server]__1wwi53kkqhnfi._.js} +1 -1
- package/.next/standalone/.next/server/chunks/{_1y590mjzpkbos._.js → _02sa8fcu9_9xo._.js} +2 -2
- package/.next/standalone/.next/server/chunks/_0tovk6q0miud6._.js +1 -1
- package/.next/standalone/.next/server/chunks/_0trp3ycqv17cl._.js +1 -1
- package/.next/standalone/.next/server/chunks/_1-2owkp-1_987._.js +1 -1
- package/.next/standalone/.next/server/chunks/_13ltj8a9z92o8._.js +1 -1
- package/.next/standalone/.next/server/chunks/_15k37au70vjvg._.js +1 -1
- package/.next/standalone/.next/server/chunks/_18rfu4__wjhwb._.js +1 -1
- package/.next/standalone/.next/server/chunks/_1ek68lnh2daur._.js +2 -2
- package/.next/standalone/.next/server/chunks/_1fz8m31sndkcu._.js +1 -1
- package/.next/standalone/.next/server/chunks/_1ogwigfb0163w._.js +1 -1
- package/.next/standalone/.next/server/chunks/_1vslkoe35wok6._.js +1 -1
- package/.next/standalone/.next/server/chunks/node_modules_@opentelemetry_api_build_esm_index_0oo58a7rymoxh.js +3 -0
- package/.next/standalone/.next/server/chunks/node_modules_@opentelemetry_api_build_esm_index_1jp9ij0_ddtgk.js +3 -0
- package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_01r25oigsgz07._.js +2 -2
- package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_09z9-p77cu37y._.js +2 -2
- package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4vkpxxu7._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0ffu2-38y03ic._.js → [root-of-the-server]__021vebe-4il8s._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__075uro8t92s0_._.js +14 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__08ch3staq3ejw._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{[externals]__12qr51qgrrt6o._.js → [root-of-the-server]__097i34ct1o88x._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0alpzjn3450sr._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0aup10z2o8zc1._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0bigvy9xmv2ka._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0bioghlkjf7s7._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__01j58mdcdw0vn._.js → [root-of-the-server]__0ed1zh4scn7-k._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0naevg4bcoh54._.js → [root-of-the-server]__0evgy902m9h5e._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0h86bl2qf0k_o._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__00l2u6j86cb8y._.js → [root-of-the-server]__0mhtkwwx1pxcq._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0nhm28v58ty9z._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0pia5h3p8re4c._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0vse4qi496ol-._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__17r4zrwanhp6r._.js → [root-of-the-server]__0yb3u36xjy3b9._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0g8b0kyorya-t._.js → [root-of-the-server]__0ywj2u6ovfm_5._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1-ey9fgesfbc0._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0zn1d4blhd3bu._.js → [root-of-the-server]__10v5cyxvj64j4._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__15usvs-ms-0hf._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__16gb3_92zvk5x._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__190xwrr5zrfi3._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1avi2kypusyb_._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1vx7o8ukefudh._.js → [root-of-the-server]__1guwlpkyurdn9._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1k96jctukf65_._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1r7drlqli-ado._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1sj-wn2jp6va5._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1vofkb2oq7p7e._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1s2-ck3k3rsoo._.js → [root-of-the-server]__20dt376-socef._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1lnfv02ucky7m._.js → [root-of-the-server]__2158020r_amn9._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{_1fw0_nzkae5ao._.js → _0bc4f4quq6w47._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_0bseae9u7g98r._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_0eoura3_9gjb-._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_0mouhaflye1ro._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_0ouu886szh6yj._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_0pedwblqdoh58._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_1_ozgifqv1ssi._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_1djqs9i27e4kg._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_20hn4gn87nsjc._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_next-internal_server_app_policies_page_actions_1sp2-yo5_vm5f.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/app_actions_get-scheduled-audit_ts_0ei9snixb5fd-._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47q0xq5w._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_components_project-list_tsx_1ke6anr0vt64h._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x33jqb6._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpcz0uxur._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_settings_02tf1h47jmhhd._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules_09s4n108bqreq._.js → node_modules_0ptcnmeaxvd_a._.js} +22 -2
- package/.next/standalone/.next/server/chunks/ssr/node_modules_@opentelemetry_api_build_esm_index_0ntwr8lzj6p2i.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{node_modules_html-to-image_es_index_1fv03uigni8s5.js → node_modules_html-to-image_es_index_1jwgv0pf-gy96.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_0bz67659f5z-3._.js +32 -0
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_0janj0i6dqko7._.js +3 -3
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_0ocrceo0c9psx._.js +32 -0
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_1alv566ojmz5j._.js +32 -0
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_1khq67j4vo9y4._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_shared_lib_0ftnv26hg1lry._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/node_modules_posthog-node_dist_entrypoints_index_node_mjs_0dagmbznysrc2._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules_posthog-node_dist_entrypoints_index_node_mjs_11bnuznb72p7z._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/package_json_[json]_cjs_013tntikdft59._.js +1 -1
- package/.next/standalone/.next/server/middleware-build-manifest.js +13 -13
- package/.next/standalone/.next/server/middleware.js +2 -2
- 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/preview-props.json +3 -3
- package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +23 -23
- package/.next/standalone/.next/static/chunks/0cbom4-ijx_a_.js +1 -0
- package/.next/standalone/.next/static/chunks/0u5weo5jdn2s8.js +1 -0
- package/.next/standalone/.next/static/chunks/{1c_jf6g5wnslk.js → 18-icoqze51kl.js} +1 -1
- package/.next/standalone/.next/static/chunks/2d-u90dt4-8rd.js +6 -0
- package/.next/standalone/.next/static/chunks/2n-bzb7pxe7hu.js +1 -0
- package/.next/standalone/.next/static/chunks/{2o6d37j425uci.js → 2zc7lg-jq353g.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0tbm3vjm62h-2.js → 33djjf12bhcsv.js} +1 -1
- package/.next/standalone/.next/static/chunks/{42xptz88mtq3x.js → 38u_i3j5funpi.js} +1 -1
- package/.next/standalone/.next/static/chunks/{20py8k1gd_i1m.js → 3symuj7t4js-c.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0ay__-d2h1xb5.js → 3vzut6zpdrvtx.js} +1 -1
- package/.next/standalone/.next/static/chunks/{063al_q720fkj.js → 3xgxl1s_in776.js} +2 -2
- package/.next/standalone/SECURITY.md +20 -4
- package/.next/standalone/fp-cloud-cli/CHANGELOG.md +34 -1
- package/.next/standalone/fp-cloud-cli/README.md +120 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/_version.py +1 -1
- package/.next/standalone/fp-cloud-cli/fp_cli/app.py +15 -1
- package/.next/standalone/fp-cloud-cli/fp_cli/client.py +198 -7
- package/.next/standalone/fp-cloud-cli/fp_cli/cloud_output.py +523 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/_cloud.py +45 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/_write.py +3 -1
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/account_cmds.py +171 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/agent_cmds.py +80 -7
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/alerts_cmds.py +23 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/audits_cmds.py +2 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/contracts_cmds.py +67 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/dashboards_cmds.py +159 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/evaluators_cmds.py +380 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/events_cmds.py +14 -1
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/incidents_cmds.py +82 -6
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/list_cmds.py +4 -1
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/orgs_cmds.py +17 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/policies_cmds.py +143 -1
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/queries_cmds.py +70 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/sentiment_cmds.py +49 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/sessions_cmds.py +95 -1
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/settings_cmds.py +2 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/usage_cmds.py +21 -1
- package/.next/standalone/fp-cloud-cli/fp_cli/commands/users_cmds.py +14 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/errors.py +3 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/evaluator_spec.py +266 -0
- package/.next/standalone/fp-cloud-cli/fp_cli/output.py +187 -81
- package/.next/standalone/fp-cloud-cli/fp_cli/theme.py +21 -24
- package/.next/standalone/fp-cloud-cli/skill/SKILL.md +124 -23
- package/.next/standalone/fp-cloud-cli/skill/agents/openai.yaml +2 -1
- package/.next/standalone/fp-cloud-cli/skill/references/commands.md +168 -16
- package/.next/standalone/fp-cloud-cli/tests/fake_cloud_smoke.py +312 -0
- package/.next/standalone/fp-cloud-cli/tests/test_cloud_account.py +125 -0
- package/.next/standalone/fp-cloud-cli/tests/test_cloud_agent.py +253 -0
- package/.next/standalone/fp-cloud-cli/tests/test_cloud_human_views.py +287 -0
- package/.next/standalone/fp-cloud-cli/tests/test_cloud_observability.py +116 -0
- package/.next/standalone/fp-cloud-cli/tests/test_cloud_transport.py +141 -0
- package/.next/standalone/fp-cloud-cli/tests/test_commands.py +3 -3
- package/.next/standalone/fp-cloud-cli/tests/test_dashboards_agent.py +3 -3
- package/.next/standalone/fp-cloud-cli/tests/test_evaluator_authoring.py +449 -0
- package/.next/standalone/fp-cloud-cli/tests/test_facets.py +1 -1
- package/.next/standalone/fp-cloud-cli/tests/test_help_table_coverage.py +15 -0
- package/.next/standalone/fp-cloud-cli/tests/test_operator.py +1 -1
- package/.next/standalone/fp-cloud-cli/tests/test_orgs.py +1 -1
- package/.next/standalone/fp-cloud-cli/tests/test_output.py +37 -37
- package/.next/standalone/fp-cloud-cli/tests/test_round4_behaviour.py +144 -0
- package/.next/standalone/fp-cloud-cli/tests/test_screen_language.py +80 -0
- package/.next/standalone/fp-cloud-cli/tests/test_session_reevaluate.py +33 -0
- package/.next/standalone/fp-cloud-cli/tests/test_staging_parity.py +198 -0
- package/.next/standalone/fp-cloud-cli/tests/test_whoami.py +1 -1
- package/.next/standalone/fp-cloud-cli/uv.lock +4 -4
- package/.next/standalone/hermes-plugin/plugin.yaml +1 -1
- package/.next/standalone/node_modules/@next/env/package.json +1 -1
- package/.next/standalone/node_modules/next/dist/build/swc/index.js +1 -1
- package/.next/standalone/node_modules/next/dist/compiled/next-server/app-page-turbo-experimental.runtime.prod.js +24 -24
- package/.next/standalone/node_modules/next/dist/compiled/next-server/app-page-turbo.runtime.prod.js +26 -26
- package/.next/standalone/node_modules/next/dist/compiled/next-server/app-route-turbo.runtime.prod.js +3 -3
- package/.next/standalone/node_modules/next/dist/compiled/next-server/pages-turbo.runtime.prod.js +13 -13
- package/.next/standalone/node_modules/next/dist/lib/patch-incorrect-lockfile.js +3 -3
- package/.next/standalone/node_modules/next/dist/server/app-render/app-render.js +41 -40
- package/.next/standalone/node_modules/next/dist/server/app-render/async-local-storage.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/app-render/dynamic-rendering-validation.js +814 -0
- package/.next/standalone/node_modules/next/dist/server/app-render/dynamic-rendering.js +1 -799
- package/.next/standalone/node_modules/next/dist/server/base-server.js +39 -5
- package/.next/standalone/node_modules/next/dist/server/config.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-turbopack.js +2 -2
- package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-webpack.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/lib/app-info-log.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/lib/dedupe-fetch.js +4 -43
- package/.next/standalone/node_modules/next/dist/server/lib/patch-fetch-symbol.js +13 -0
- package/.next/standalone/node_modules/next/dist/server/lib/patch-fetch.js +3 -7
- package/.next/standalone/node_modules/next/dist/server/lib/router-server.js +3 -3
- package/.next/standalone/node_modules/next/dist/server/lib/router-utils/instrumentation-globals.external.js +77 -12
- package/.next/standalone/node_modules/next/dist/server/lib/start-server.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/lib/trace/constants.js +12 -0
- package/.next/standalone/node_modules/next/dist/server/lib/trace/tracer.js +30 -14
- package/.next/standalone/node_modules/next/dist/server/next-server.js +10 -11
- package/.next/standalone/node_modules/next/dist/server/route-modules/pages/pages-handler.js +29 -23
- package/.next/standalone/node_modules/next/dist/server/route-modules/route-module.js +85 -8
- package/.next/standalone/node_modules/next/dist/server/use-cache/use-cache-wrapper.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/web/adapter.js +124 -65
- package/.next/standalone/node_modules/next/dist/server/web/forward-trace-context.js +102 -0
- package/.next/standalone/node_modules/next/dist/telemetry/anonymous-meta.js +1 -1
- package/.next/standalone/node_modules/next/dist/telemetry/events/swc-load-failure.js +1 -1
- package/.next/standalone/node_modules/next/dist/telemetry/events/version.js +2 -2
- package/.next/standalone/node_modules/next/package.json +10 -10
- package/.next/standalone/node_modules/react/cjs/react.production.js +1 -1
- package/.next/standalone/node_modules/react/package.json +1 -1
- package/.next/standalone/node_modules/react-dom/cjs/react-dom-server-legacy.browser.production.js +1 -1
- package/.next/standalone/node_modules/react-dom/cjs/react-dom-server-legacy.node.production.js +1 -1
- package/.next/standalone/node_modules/react-dom/cjs/react-dom-server.browser.production.js +31 -27
- package/.next/standalone/node_modules/react-dom/cjs/react-dom-server.edge.production.js +33 -27
- package/.next/standalone/node_modules/react-dom/cjs/react-dom-server.node.production.js +38 -30
- package/.next/standalone/node_modules/react-dom/cjs/react-dom.production.js +1 -1
- package/.next/standalone/node_modules/react-dom/package.json +2 -2
- package/.next/standalone/package.json +10 -10
- package/.next/standalone/sdk/python/CHANGELOG.md +8 -4
- package/.next/standalone/sdk/python/failproofai_sdk/evaluator/source.py +2 -2
- package/.next/standalone/sdk/python/pyproject.toml +2 -7
- package/.next/standalone/sdk/python/skill/references/frameworks.md +0 -15
- package/.next/standalone/sdk/python/tests/test_docs.py +1 -4
- package/.next/standalone/sdk/python/tests/test_evaluator_source.py +1 -1
- package/.next/standalone/sdk/python/tests/test_packaging.py +4 -7
- package/.next/standalone/sdk/python/tests/test_zero_dependencies.py +2 -13
- package/.next/standalone/sdk/python/uv.lock +43 -905
- package/.next/standalone/sdk/typescript/CHANGELOG.md +52 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/package-lock.json +7 -7
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/package.json +2 -2
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-6/package-lock.json +7 -7
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-6/package.json +1 -1
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-7/package-lock.json +7 -7
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-7/package.json +1 -1
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-1/package-lock.json +4 -4
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-1/package.json +1 -1
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/package-lock.json +4 -4
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/package.json +1 -1
- package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.11/package-lock.json +3 -3
- package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.11/package.json +3 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.12/package-lock.json +4 -4
- package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.12/package.json +1 -1
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-0/package-lock.json +25 -25
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-0/package.json +1 -1
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-1/package-lock.json +34 -22
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-1/package.json +3 -2
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/package-lock.json +10 -10
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/package.json +1 -1
- package/.next/standalone/sdk/typescript/integration/fixtures/runtimes/deno-npm.ts +1 -1
- package/.next/standalone/sdk/typescript/integration/fixtures/runtimes/package-lock.json +7 -7
- package/.next/standalone/sdk/typescript/integration/fixtures/runtimes/package.json +1 -1
- package/.next/standalone/server.js +1 -1
- package/README.md +0 -6
- package/dist/cli.mjs +87 -38
- package/dist/worker.mjs +73 -28
- package/hermes-plugin/plugin.yaml +1 -1
- package/openclaw-plugin/daemon-client.js +254 -0
- package/openclaw-plugin/hooks.js +187 -0
- package/openclaw-plugin/index.js +17 -211
- package/package.json +10 -10
- package/scripts/sync-agent-cli-harnesses-prompt.md +26 -31
- package/src/hooks/agent-skill.ts +3 -0
- package/src/hooks/enforcement-capability.ts +1 -1
- package/src/hooks/fp-home.ts +1 -1
- package/src/hooks/handler.ts +22 -3
- package/src/hooks/integrations.ts +5 -2
- package/src/hooks/semantic/intent.ts +127 -24
- package/src/hooks/semantic/jev-review.ts +21 -2
- package/.next/standalone/.codex/hooks.json +0 -76
- package/.next/standalone/.cursor/hooks.json +0 -47
- package/.next/standalone/.factory/hooks.json +0 -112
- package/.next/standalone/.next/server/chunks/[externals]__1x24dzcbbq6-g._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0__a_je8fsn65._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0l-oi4gdtmlo5._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0t9ufnv5hi2hq._.js +0 -327
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1aaw59g-5uty7._.js +0 -322
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1hqpg6vgmfexv._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[externals]__0ilfh9mfnzsth._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[externals]__0ohnuzsaozaca._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0pwj2h2efe5f-._.js +0 -14
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_0zuikgt2xho-v._.js +0 -271
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_158jo-9mwvgad._.js +0 -291
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_19r82zsxo2jj1._.js +0 -291
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_1dupwucoqt5qm._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_shared_lib_03w27x2kh17_8._.js +0 -23
- package/.next/standalone/.next/static/chunks/1my3-5p47t7r-.js +0 -1
- package/.next/standalone/.next/static/chunks/21hckpmsc4g70.js +0 -6
- package/.next/standalone/.next/static/chunks/2hmex93ppj1ke.js +0 -1
- package/.next/standalone/.next/static/chunks/40oworn_-x12p.js +0 -1
- package/.next/standalone/.opencode/opencode.json +0 -4
- package/.next/standalone/.opencode/plugins/failproofai.mjs +0 -210
- package/.next/standalone/.pi/settings.json +0 -5
- package/.next/standalone/node_modules/react/cjs/react.development.js +0 -1330
- package/scripts/dev-hook.mjs +0 -333
- /package/.next/standalone/.next/static/{LHCtFxVG0mdvd4lsXAOFC → 1n2dyfTQb0MDajeqlipJy}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{LHCtFxVG0mdvd4lsXAOFC → 1n2dyfTQb0MDajeqlipJy}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{LHCtFxVG0mdvd4lsXAOFC → 1n2dyfTQb0MDajeqlipJy}/_ssgManifest.js +0 -0
|
@@ -22,7 +22,7 @@ from .. import _click_compat as click # the Click Typer is running; see _click_
|
|
|
22
22
|
from ..enforcement import RefError, RefUsageError, parse_semantic, read_source, resolve_kind
|
|
23
23
|
from ..policy_check import SyntaxResult, check_syntax, run_policy
|
|
24
24
|
from ..errors import ApiError, NotFoundError
|
|
25
|
-
from . import _write
|
|
25
|
+
from . import _cloud, _write
|
|
26
26
|
|
|
27
27
|
#: Every command here is session-only. These endpoints are ROOT-ONLY on the
|
|
28
28
|
#: server — deliberately absent from `/v1`, because `/v1` is internet-facing and
|
|
@@ -565,4 +565,146 @@ def register(app: typer.Typer) -> None:
|
|
|
565
565
|
policies_app.command("delete", epilog=GLOBALS_EPILOG)(policies_delete)
|
|
566
566
|
policies_app.command("test", epilog=GLOBALS_EPILOG)(policies_test)
|
|
567
567
|
policies_app.command("compose", epilog=GLOBALS_EPILOG)(policies_compose)
|
|
568
|
+
policies_app.command("author", epilog=GLOBALS_EPILOG)(policies_author)
|
|
569
|
+
policies_app.command("backtest", epilog=GLOBALS_EPILOG)(policies_backtest)
|
|
570
|
+
policies_app.command("candidacy", epilog=GLOBALS_EPILOG)(policies_candidacy)
|
|
568
571
|
app.add_typer(policies_app, name="policies")
|
|
572
|
+
|
|
573
|
+
|
|
574
|
+
def policies_author(
|
|
575
|
+
ctx: typer.Context,
|
|
576
|
+
intent: str = typer.Argument(...),
|
|
577
|
+
kind: Optional[str] = typer.Option(
|
|
578
|
+
None, "--kind",
|
|
579
|
+
help="regex | jev | both. Default: the assistant writes a regex (JavaScript) policy.",
|
|
580
|
+
),
|
|
581
|
+
) -> None:
|
|
582
|
+
"""Author a vetted policy from an intent (session; does not publish).
|
|
583
|
+
|
|
584
|
+
`--kind jev` asks for Jev checks only, `--kind both` for JavaScript plus the
|
|
585
|
+
Jev checks that may clear it. Publish the result with `fp policies publish`.
|
|
586
|
+
"""
|
|
587
|
+
_cloud.session_only(ctx.obj, "policies author")
|
|
588
|
+
if kind is not None and kind not in ("regex", "jev", "both"):
|
|
589
|
+
raise click.UsageError("--kind must be regex, jev or both")
|
|
590
|
+
body = {"issue": {"title": intent, "source": "manual"}}
|
|
591
|
+
if kind in ("jev", "both"):
|
|
592
|
+
# The dashboard proxy treats anything else as regex, exactly as before kinds.
|
|
593
|
+
body["kind"] = kind
|
|
594
|
+
events = list(api.cloud_stream(require_auth(ctx.obj), "/api/agent/policy-author", body))
|
|
595
|
+
for event in events:
|
|
596
|
+
if event.get("type") == "error":
|
|
597
|
+
raise ApiError(str(event.get("message") or event.get("error") or event.get("reason") or "Policy author failed"))
|
|
598
|
+
result = next((e.get("result", e) for e in reversed(events) if e.get("type") in ("result", "done")), None)
|
|
599
|
+
if result is None:
|
|
600
|
+
raise ApiError("Policy author returned no result; nothing was published")
|
|
601
|
+
_cloud.emit(ctx.obj, result, "Policy draft")
|
|
602
|
+
|
|
603
|
+
|
|
604
|
+
def policies_backtest(
|
|
605
|
+
ctx: typer.Context,
|
|
606
|
+
file_or_id: Optional[str] = typer.Argument(None, metavar="FILE_OR_ID"),
|
|
607
|
+
kind: Optional[str] = typer.Option(
|
|
608
|
+
None, "--kind",
|
|
609
|
+
help="regex | jev | both. Default: a published policy's own kind; for a file, "
|
|
610
|
+
"regex, or jev/both when --semantic is given.",
|
|
611
|
+
),
|
|
612
|
+
semantic_path: Optional[str] = typer.Option(
|
|
613
|
+
None, "--semantic", help="Jev checks JSON (the same file `policies publish --semantic` takes).",
|
|
614
|
+
),
|
|
615
|
+
hours: Optional[float] = typer.Option(None, "--hours", help="How far back to replay (default 168 for jev/both)."),
|
|
616
|
+
agent_id: Optional[str] = typer.Option(None, "--agent-id", help="Replay only this agent's calls."),
|
|
617
|
+
env: Optional[str] = typer.Option(None, "--env", help="Replay only this environment's calls."),
|
|
618
|
+
run: bool = typer.Option(
|
|
619
|
+
False, "--run",
|
|
620
|
+
help="jev/both: actually ask Jev (spends the org's Jev allowance). Default is a free estimate.",
|
|
621
|
+
),
|
|
622
|
+
sample: Optional[int] = typer.Option(None, "--sample", help="jev/both with --run: calls to ask Jev about (max 50)."),
|
|
623
|
+
) -> None:
|
|
624
|
+
"""Replay local or published policy source against stored events (session).
|
|
625
|
+
|
|
626
|
+
A regex policy (a .mjs file or a published regex id) is replayed module-only,
|
|
627
|
+
as before. A jev/both policy — a published one, or `--semantic checks.json`
|
|
628
|
+
with or without a source file — runs the every-kind backtest: an estimate
|
|
629
|
+
by default, `--run` to spend Jev allowance on up to `--sample` calls.
|
|
630
|
+
Needs policies:write and events:read.
|
|
631
|
+
"""
|
|
632
|
+
from pathlib import Path
|
|
633
|
+
_cloud.session_only(ctx.obj, "policies backtest")
|
|
634
|
+
if kind is not None and kind not in ("regex", "jev", "both"):
|
|
635
|
+
raise click.UsageError("--kind must be regex, jev or both")
|
|
636
|
+
if file_or_id is None and semantic_path is None:
|
|
637
|
+
raise click.UsageError("give a policy file or published id, or --semantic checks.json")
|
|
638
|
+
if hours is not None and not hours > 0:
|
|
639
|
+
raise click.UsageError("--hours must be a positive number")
|
|
640
|
+
if sample is not None and not 1 <= sample <= 50:
|
|
641
|
+
raise click.UsageError("--sample must be between 1 and 50")
|
|
642
|
+
if file_or_id == "-" and semantic_path == "-":
|
|
643
|
+
raise click.UsageError("only one of the source and --semantic can come from stdin")
|
|
644
|
+
cctx = require_auth(ctx.obj)
|
|
645
|
+
source: Optional[str] = None
|
|
646
|
+
semantic = None
|
|
647
|
+
published_kind = None
|
|
648
|
+
if file_or_id is not None:
|
|
649
|
+
if file_or_id == "-" or file_or_id.startswith("@") or Path(file_or_id).is_file():
|
|
650
|
+
source = _write.read_text_arg(file_or_id.removeprefix("@"))
|
|
651
|
+
else:
|
|
652
|
+
data = api.cloud_request(cctx, "GET", "/api/enforcement/policies")
|
|
653
|
+
versions = [p for p in _cloud.rows(data, "policies") if p.get("id") == file_or_id]
|
|
654
|
+
if not versions:
|
|
655
|
+
raise NotFoundError(f"no policy named {file_or_id}")
|
|
656
|
+
newest = max(versions, key=lambda p: p.get("version", 0))
|
|
657
|
+
published_kind = newest.get("kind") or "regex"
|
|
658
|
+
source = newest.get("source") or None
|
|
659
|
+
if semantic_path is None and isinstance(newest.get("semantic"), list):
|
|
660
|
+
semantic = newest["semantic"]
|
|
661
|
+
if semantic_path is not None:
|
|
662
|
+
try:
|
|
663
|
+
semantic = parse_semantic(read_source(semantic_path, isatty=False))
|
|
664
|
+
except RefUsageError as exc:
|
|
665
|
+
raise click.UsageError(str(exc))
|
|
666
|
+
except RefError as exc:
|
|
667
|
+
raise ApiError(str(exc))
|
|
668
|
+
resolved = kind or published_kind or ("regex" if not semantic else ("both" if source else "jev"))
|
|
669
|
+
if resolved == "regex":
|
|
670
|
+
if semantic_path is not None:
|
|
671
|
+
raise click.UsageError("--semantic needs --kind jev or both")
|
|
672
|
+
if not isinstance(source, str) or not source.strip():
|
|
673
|
+
raise click.UsageError("Policy source is empty")
|
|
674
|
+
body = {"source": source}
|
|
675
|
+
if agent_id:
|
|
676
|
+
body["agentId"] = agent_id
|
|
677
|
+
if env:
|
|
678
|
+
body["environment"] = env
|
|
679
|
+
if hours is not None:
|
|
680
|
+
body["hours"] = hours
|
|
681
|
+
_cloud.emit(ctx.obj, api.cloud_request(cctx, "POST", "/api/agent/policy-backtest",
|
|
682
|
+
body=body), "Policy backtest")
|
|
683
|
+
return
|
|
684
|
+
if resolved == "both" and not (source or "").strip():
|
|
685
|
+
raise click.UsageError("a both backtest needs the JavaScript source too")
|
|
686
|
+
if not semantic:
|
|
687
|
+
raise click.UsageError(f"a {resolved} backtest needs Jev checks: pass --semantic checks.json")
|
|
688
|
+
body = {"kind": resolved, "semantic": semantic, "hours": hours if hours is not None else 168,
|
|
689
|
+
"mode": "run" if run else "estimate"}
|
|
690
|
+
if resolved == "both":
|
|
691
|
+
body["source"] = source
|
|
692
|
+
if agent_id:
|
|
693
|
+
body["agentId"] = agent_id
|
|
694
|
+
if env:
|
|
695
|
+
body["environment"] = env
|
|
696
|
+
if sample is not None:
|
|
697
|
+
body["sample"] = sample
|
|
698
|
+
if run and not ctx.obj.json:
|
|
699
|
+
output.warn("--run asks Jev about stored calls and spends the org's Jev allowance.")
|
|
700
|
+
_cloud.emit(ctx.obj, api.cloud_request(cctx, "POST", "/api/agent/policy-backtest-all",
|
|
701
|
+
body=body), "Policy backtest")
|
|
702
|
+
|
|
703
|
+
|
|
704
|
+
def policies_candidacy(ctx: typer.Context, issue: str = typer.Option(..., "--issue")) -> None:
|
|
705
|
+
"""Ask whether a policy could address an issue (session; read-only)."""
|
|
706
|
+
_cloud.session_only(ctx.obj, "policies candidacy")
|
|
707
|
+
cctx = require_auth(ctx.obj)
|
|
708
|
+
row = api.cloud_request(cctx, "GET", f"/api/issues/{issue}")
|
|
709
|
+
_cloud.emit(ctx.obj, api.cloud_request(cctx, "POST", "/api/agent/policy-candidacy",
|
|
710
|
+
body={"issue": row}), "Policy candidacy")
|
|
@@ -17,6 +17,7 @@ from .._context import GLOBALS_EPILOG, AppState, require_auth, resolve_fields, v
|
|
|
17
17
|
from ..errors import NotFoundError
|
|
18
18
|
from ..models import SavedQuery
|
|
19
19
|
from . import _write
|
|
20
|
+
from . import _cloud
|
|
20
21
|
|
|
21
22
|
|
|
22
23
|
def _humanize_list(items: List[str]) -> str:
|
|
@@ -375,4 +376,73 @@ def register(app: typer.Typer) -> None:
|
|
|
375
376
|
query_app.command("delete", epilog=GLOBALS_EPILOG)(query_delete)
|
|
376
377
|
query_app.command("run", epilog=GLOBALS_EPILOG)(query_run)
|
|
377
378
|
query_app.command("schema", epilog=GLOBALS_EPILOG)(query_schema)
|
|
379
|
+
query_app.command("compose", epilog=GLOBALS_EPILOG)(query_compose)
|
|
380
|
+
query_app.command("export", epilog=GLOBALS_EPILOG)(query_export)
|
|
378
381
|
app.add_typer(query_app, name="query")
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
def query_compose(ctx: typer.Context, question: str = typer.Argument(...),
|
|
385
|
+
run: bool = typer.Option(False, "--run")) -> None:
|
|
386
|
+
"""AI-compose SQL (session only); optionally run it."""
|
|
387
|
+
_cloud.session_only(ctx.obj, "query compose")
|
|
388
|
+
cctx = require_auth(ctx.obj)
|
|
389
|
+
draft = None
|
|
390
|
+
for event in api.cloud_stream(cctx, "/api/agent/compose-sql", {"intent": question}):
|
|
391
|
+
if event.get("type") == "error":
|
|
392
|
+
from ..errors import ApiError
|
|
393
|
+
raise ApiError(str(event.get("error") or event.get("reason") or "SQL composer failed"))
|
|
394
|
+
if event.get("type") in ("result", "done"):
|
|
395
|
+
draft = event.get("result", event)
|
|
396
|
+
if not isinstance(draft, dict):
|
|
397
|
+
raise click.UsageError("Cloud did not return composed SQL")
|
|
398
|
+
sql = draft.get("sql") or draft.get("sql_text")
|
|
399
|
+
if not isinstance(sql, str) or not sql.strip():
|
|
400
|
+
raise click.UsageError("Cloud did not return composed SQL")
|
|
401
|
+
if run:
|
|
402
|
+
data = api.cloud_request(cctx, "POST", "/api/queries/run", body={"sql": sql, "params": []})
|
|
403
|
+
_cloud.emit(ctx.obj, {"sql": sql, "result": data}, "Composed query")
|
|
404
|
+
elif ctx.obj.json:
|
|
405
|
+
output.emit_json(draft)
|
|
406
|
+
else:
|
|
407
|
+
_cloud.emit(ctx.obj, {"sql": sql}, "Composed query")
|
|
408
|
+
|
|
409
|
+
|
|
410
|
+
def query_export(ctx: typer.Context, id: Optional[str] = typer.Argument(None),
|
|
411
|
+
sql: Optional[str] = typer.Option(None, "--sql"),
|
|
412
|
+
format: str = typer.Option("csv", "--format"),
|
|
413
|
+
out: Optional[str] = typer.Option(None, "--out")) -> None:
|
|
414
|
+
"""Export a saved or ad-hoc query as CSV/JSON (all returned rows).
|
|
415
|
+
|
|
416
|
+
--json wraps CSV in {format,content} unless --out writes the file.
|
|
417
|
+
"""
|
|
418
|
+
import csv
|
|
419
|
+
import io
|
|
420
|
+
import json
|
|
421
|
+
if (id is None) == (sql is None):
|
|
422
|
+
raise click.UsageError("Pass a saved query id or --sql, exactly one")
|
|
423
|
+
if format not in ("csv", "json"):
|
|
424
|
+
raise click.UsageError("--format must be csv or json")
|
|
425
|
+
data = api.cloud_request(require_auth(ctx.obj), "POST", "/api/queries/run",
|
|
426
|
+
body={"query_id": id, "sql": _read_sql(sql) if sql is not None else None, "params": []})
|
|
427
|
+
if format == "json":
|
|
428
|
+
content = json.dumps(data, indent=2, ensure_ascii=False) + "\n"
|
|
429
|
+
else:
|
|
430
|
+
buf = io.StringIO()
|
|
431
|
+
writer = csv.writer(buf)
|
|
432
|
+
writer.writerow([c.get("name", "") if isinstance(c, dict) else c for c in data.get("columns", [])])
|
|
433
|
+
# Spreadsheet-safe export of untrusted event cells.
|
|
434
|
+
writer.writerows([
|
|
435
|
+
["'" + v if isinstance(v, str) and v.startswith(("=", "+", "-", "@", "\t", "\r")) else v for v in row]
|
|
436
|
+
for row in data.get("rows", [])
|
|
437
|
+
])
|
|
438
|
+
content = buf.getvalue()
|
|
439
|
+
if out:
|
|
440
|
+
_cloud.write_file(out, content)
|
|
441
|
+
_cloud.emit(ctx.obj, {"out": out, "format": format}, "Query exported")
|
|
442
|
+
elif ctx.obj.json:
|
|
443
|
+
output.emit_json(data if format == "json" else {"format": format, "content": content})
|
|
444
|
+
elif format == "json":
|
|
445
|
+
from .. import cloud_output
|
|
446
|
+
cloud_output.query_result(data, "Query export")
|
|
447
|
+
else:
|
|
448
|
+
print(content, end="")
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"""Conversation sentiment summary, messages and sessions."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Optional
|
|
6
|
+
|
|
7
|
+
import typer
|
|
8
|
+
|
|
9
|
+
from .. import client as api
|
|
10
|
+
from .._context import GLOBALS_EPILOG, require_auth, resolve_dates, validate_limit
|
|
11
|
+
from . import _cloud
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def read(ctx, suffix, since=None, limit=None, session_id=None):
|
|
15
|
+
validate_limit(limit)
|
|
16
|
+
frm, to = resolve_dates(since, None, None)
|
|
17
|
+
data = api.cloud_request(require_auth(ctx.obj), "GET", f"/api/events/sentiment{suffix}",
|
|
18
|
+
params={"ts_from": frm, "ts_to": to, "limit": limit, "session_id": session_id})
|
|
19
|
+
_cloud.emit(ctx.obj, data, "Sentiment", view=suffix.strip("/") or "summary")
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def summary(ctx: typer.Context, since: Optional[str] = typer.Option(None, "--since")) -> None:
|
|
23
|
+
"""Summarize conversation sentiment."""
|
|
24
|
+
read(ctx, "", since)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def messages(ctx: typer.Context, since: Optional[str] = typer.Option(None, "--since"),
|
|
28
|
+
limit: int = typer.Option(50, "--limit"),
|
|
29
|
+
session_id: Optional[str] = typer.Option(None, "--session-id")) -> None:
|
|
30
|
+
"""List sentiment-scored messages."""
|
|
31
|
+
read(ctx, "/messages", since, limit, session_id)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def sessions(ctx: typer.Context, since: Optional[str] = typer.Option(None, "--since"),
|
|
35
|
+
limit: int = typer.Option(50, "--limit")) -> None:
|
|
36
|
+
"""List sentiment-scored sessions."""
|
|
37
|
+
read(ctx, "/sessions", since, limit)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def session(ctx: typer.Context, id: str = typer.Argument(...)) -> None:
|
|
41
|
+
"""Show one session's sentiment."""
|
|
42
|
+
read(ctx, f"/sessions/{id}")
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def register(app: typer.Typer) -> None:
|
|
46
|
+
group = typer.Typer(no_args_is_help=True, help="Inspect conversation sentiment.", context_settings={"help_option_names": ["-h", "--help"]})
|
|
47
|
+
for name, fn in (("summary", summary), ("messages", messages), ("sessions", sessions), ("session", session)):
|
|
48
|
+
group.command(name, epilog=GLOBALS_EPILOG)(fn)
|
|
49
|
+
app.add_typer(group, name="sentiment")
|
|
@@ -18,7 +18,9 @@ from .._context import (
|
|
|
18
18
|
validate_choice,
|
|
19
19
|
validate_limit,
|
|
20
20
|
)
|
|
21
|
+
from .. import _click_compat as click
|
|
21
22
|
from ..models import Session
|
|
23
|
+
from . import _cloud, _write
|
|
22
24
|
|
|
23
25
|
|
|
24
26
|
def sessions(
|
|
@@ -70,6 +72,8 @@ def sessions(
|
|
|
70
72
|
* `fp sessions --agents` — expand each multi-agent session to its full agent roster
|
|
71
73
|
* `fp --json sessions --all --fields session_id,agents | jq '.sessions'` — every session's full agent roster as JSON
|
|
72
74
|
"""
|
|
75
|
+
if ctx.invoked_subcommand:
|
|
76
|
+
return
|
|
73
77
|
state: AppState = ctx.obj
|
|
74
78
|
cctx = require_auth(state)
|
|
75
79
|
validate_limit(limit)
|
|
@@ -147,5 +151,95 @@ def sessions(
|
|
|
147
151
|
output.recheck_filters_hint(active_filters)
|
|
148
152
|
|
|
149
153
|
|
|
154
|
+
def re_evaluate(ctx: typer.Context, session_id: str = typer.Argument(...)) -> None:
|
|
155
|
+
"""Re-run evaluators on one session. Needs evaluations:trigger."""
|
|
156
|
+
_write.confirm(ctx.obj, f"Re-evaluate session {session_id}", assume_yes=False)
|
|
157
|
+
_cloud.emit(ctx.obj, api.cloud_request(require_auth(ctx.obj), "POST",
|
|
158
|
+
f"/api/sessions/{session_id}/re-evaluate"), "Session re-evaluation", body=session_id)
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def import_sessions(
|
|
162
|
+
ctx: typer.Context,
|
|
163
|
+
files: List[str] = typer.Argument(..., metavar="FILE...", help="Event JSONL, Claude Code transcripts or Codex rollouts (.gz ok)."),
|
|
164
|
+
format: str = typer.Option("auto", "--format", help="auto | failproofai (FailproofAI event JSONL) | claude | codex."),
|
|
165
|
+
env: Optional[str] = typer.Option(None, "--env", help="Environment for events that name none (server default: upload)."),
|
|
166
|
+
dry_run: bool = typer.Option(False, "--dry-run", help="Convert and report; store nothing."),
|
|
167
|
+
) -> None:
|
|
168
|
+
"""Import sessions from files, as the dashboard's Import sessions dialog does.
|
|
169
|
+
|
|
170
|
+
Each file is gzipped and sent on its own. Sessions already in the org are skipped
|
|
171
|
+
whole; secrets are redacted the way the collector redacts them live. Claude Code
|
|
172
|
+
and Codex files take the session id from the file name, so pass the original files.
|
|
173
|
+
Needs events:add. With `--json`: `{"files": [{file, result}]}`.
|
|
174
|
+
"""
|
|
175
|
+
import gzip
|
|
176
|
+
import time
|
|
177
|
+
from pathlib import Path
|
|
178
|
+
validate_choice(format, ("auto", "failproofai", "agenteye", "claude", "codex"), flag="--format")
|
|
179
|
+
# The server names FailproofAI's own event JSONL `agenteye`; `failproofai` is its public name.
|
|
180
|
+
wire_format = "agenteye" if format == "failproofai" else format
|
|
181
|
+
payloads = []
|
|
182
|
+
for name in files:
|
|
183
|
+
path = Path(name)
|
|
184
|
+
try:
|
|
185
|
+
raw = path.read_bytes()
|
|
186
|
+
except OSError as exc:
|
|
187
|
+
raise click.BadParameter(f"cannot read '{name}': {exc.strerror or exc}", param_hint="FILE")
|
|
188
|
+
rel = "/".join(path.resolve().parts[-2:])
|
|
189
|
+
payloads.append((name, rel, raw if raw[:2] == b"\x1f\x8b" else gzip.compress(raw)))
|
|
190
|
+
if not dry_run:
|
|
191
|
+
_write.confirm(ctx.obj, f"Import {len(files)} file{'s' if len(files) != 1 else ''}", assume_yes=False)
|
|
192
|
+
cctx = require_auth(ctx.obj)
|
|
193
|
+
# One cutoff for the whole run, so a later file of a session this run created
|
|
194
|
+
# is not skipped as "already present".
|
|
195
|
+
before = int(time.time() * 1000)
|
|
196
|
+
results = []
|
|
197
|
+
for name, rel, data in payloads:
|
|
198
|
+
result = api.import_events_file(cctx, data, {
|
|
199
|
+
"format": wire_format, "path": rel, "environment": env,
|
|
200
|
+
"dry_run": "true" if dry_run else None, "existing_before": before,
|
|
201
|
+
})
|
|
202
|
+
results.append({"file": name, "result": result})
|
|
203
|
+
if not dry_run:
|
|
204
|
+
_write.record_action("sessions_imported", resource="events", success=True)
|
|
205
|
+
_cloud.emit(ctx.obj, {"files": results}, "Session import")
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
def show(ctx: typer.Context, id: str = typer.Argument(...)) -> None:
|
|
209
|
+
"""Show a session overview and its event timeline."""
|
|
210
|
+
cctx = require_auth(ctx.obj)
|
|
211
|
+
overview = api.cloud_request(cctx, "GET", "/api/sessions", params={"session_id": id, "limit": 1})
|
|
212
|
+
items = _cloud.rows(overview, "sessions")
|
|
213
|
+
if not items:
|
|
214
|
+
from ..errors import NotFoundError
|
|
215
|
+
raise NotFoundError(f"no session {id}")
|
|
216
|
+
timeline = api.cloud_request(cctx, "GET", "/api/events/summary", params={"session_id": id, "limit": 200, "order": "asc"})
|
|
217
|
+
_cloud.emit(ctx.obj, {"overview": items[0], "timeline": timeline}, "Session")
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
def export(ctx: typer.Context, id: str = typer.Argument(...),
|
|
221
|
+
out: Optional[str] = typer.Option(None, "--out")) -> None:
|
|
222
|
+
"""Export a full session as JSON."""
|
|
223
|
+
import json
|
|
224
|
+
data = api.cloud_request(require_auth(ctx.obj), "GET", f"/api/sessions/{id}/export")
|
|
225
|
+
if out:
|
|
226
|
+
_cloud.write_file(out, json.dumps(data, indent=2, ensure_ascii=False) + "\n")
|
|
227
|
+
_cloud.emit(ctx.obj, {"out": out}, "Session exported")
|
|
228
|
+
else:
|
|
229
|
+
_cloud.emit(ctx.obj, data, "Session")
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
def history(ctx: typer.Context, id: str = typer.Argument(...)) -> None:
|
|
233
|
+
"""Show a session's evaluation history."""
|
|
234
|
+
_cloud.emit(ctx.obj, api.cloud_request(require_auth(ctx.obj), "GET", f"/api/sessions/{id}/evaluation-history"), "Evaluation history")
|
|
235
|
+
|
|
236
|
+
|
|
150
237
|
def register(app: typer.Typer) -> None:
|
|
151
|
-
|
|
238
|
+
group = typer.Typer(invoke_without_command=True, rich_markup_mode="markdown", context_settings={"help_option_names": ["-h", "--help"]})
|
|
239
|
+
group.callback(epilog=GLOBALS_EPILOG)(sessions)
|
|
240
|
+
group.command("re-evaluate", epilog=GLOBALS_EPILOG)(re_evaluate)
|
|
241
|
+
group.command("show", epilog=GLOBALS_EPILOG)(show)
|
|
242
|
+
group.command("export", epilog=GLOBALS_EPILOG)(export)
|
|
243
|
+
group.command("history", epilog=GLOBALS_EPILOG)(history)
|
|
244
|
+
group.command("import", epilog=GLOBALS_EPILOG)(import_sessions)
|
|
245
|
+
app.add_typer(group, name="sessions")
|
|
@@ -147,4 +147,6 @@ def register(app: typer.Typer) -> None:
|
|
|
147
147
|
settings_app.command("list", epilog=GLOBALS_EPILOG)(settings_list)
|
|
148
148
|
settings_app.command("schema", epilog=GLOBALS_EPILOG)(settings_schema)
|
|
149
149
|
settings_app.command("set", epilog=GLOBALS_EPILOG)(settings_set)
|
|
150
|
+
from .account_cmds import register_context_windows
|
|
151
|
+
register_context_windows(settings_app)
|
|
150
152
|
app.add_typer(settings_app, name="settings")
|
|
@@ -23,6 +23,8 @@ def usage(ctx: typer.Context) -> None:
|
|
|
23
23
|
* `fp usage`
|
|
24
24
|
* `fp --json usage | jq '.usage.events_ingested'`
|
|
25
25
|
"""
|
|
26
|
+
if ctx.invoked_subcommand:
|
|
27
|
+
return
|
|
26
28
|
state: AppState = ctx.obj
|
|
27
29
|
data = api.get_usage(require_auth(state))
|
|
28
30
|
if state.json:
|
|
@@ -32,4 +34,22 @@ def usage(ctx: typer.Context) -> None:
|
|
|
32
34
|
|
|
33
35
|
|
|
34
36
|
def register(app: typer.Typer) -> None:
|
|
35
|
-
|
|
37
|
+
group = typer.Typer(invoke_without_command=True, rich_markup_mode="markdown", context_settings={"help_option_names": ["-h", "--help"]})
|
|
38
|
+
group.callback(epilog=GLOBALS_EPILOG)(usage)
|
|
39
|
+
group.command("windows", epilog=GLOBALS_EPILOG)(usage_windows)
|
|
40
|
+
app.add_typer(group, name="usage")
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def usage_windows(ctx: typer.Context) -> None:
|
|
44
|
+
"""List usage metering windows. API key only (the dashboard has no session route)."""
|
|
45
|
+
from .account_cmds import request
|
|
46
|
+
from ..client import AuthMode
|
|
47
|
+
from ..errors import KeyModeUnsupportedError
|
|
48
|
+
if ctx.obj.auth_mode is not AuthMode.API_KEY:
|
|
49
|
+
# GET /usage/windows is served on the versioned API only; a signed-in
|
|
50
|
+
# session would reach a dashboard 404 and print a misleading message.
|
|
51
|
+
raise KeyModeUnsupportedError(
|
|
52
|
+
"`fp usage windows` needs an API key — the dashboard has no session route for it.",
|
|
53
|
+
hint="pass --api-key (or FP_API_KEY) with a usage:read key",
|
|
54
|
+
)
|
|
55
|
+
request(ctx, "GET", "/api/usage/windows")
|
|
@@ -401,4 +401,18 @@ def register(app: typer.Typer) -> None:
|
|
|
401
401
|
users_app.command("update", epilog=GLOBALS_EPILOG)(users_update)
|
|
402
402
|
users_app.command("disable", epilog=GLOBALS_EPILOG)(users_disable)
|
|
403
403
|
users_app.command("enable", epilog=GLOBALS_EPILOG)(users_enable)
|
|
404
|
+
users_app.command("delete", epilog=GLOBALS_EPILOG)(users_delete)
|
|
405
|
+
users_app.command("defaults", epilog=GLOBALS_EPILOG)(users_defaults)
|
|
404
406
|
app.add_typer(users_app, name="users")
|
|
407
|
+
|
|
408
|
+
|
|
409
|
+
def users_delete(ctx: typer.Context, id: str = typer.Argument(...)) -> None:
|
|
410
|
+
"""Delete a member by id (not email)."""
|
|
411
|
+
from .account_cmds import request
|
|
412
|
+
request(ctx, "DELETE", f"/api/users/{id}")
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
def users_defaults(ctx: typer.Context) -> None:
|
|
416
|
+
"""Show defaults for new members."""
|
|
417
|
+
from .account_cmds import request
|
|
418
|
+
request(ctx, "GET", "/api/users/defaults")
|
|
@@ -85,6 +85,9 @@ class NotFoundError(FpCliError):
|
|
|
85
85
|
"""The requested resource does not exist."""
|
|
86
86
|
|
|
87
87
|
exit_code = 6
|
|
88
|
+
# The HTTP response may explicitly distinguish an absent endpoint from a
|
|
89
|
+
# missing record. None means callers must fall back to the request shape.
|
|
90
|
+
route_unknown: Optional[bool] = None
|
|
88
91
|
|
|
89
92
|
|
|
90
93
|
class ApiError(FpCliError):
|