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
|
@@ -19,12 +19,93 @@ import typer
|
|
|
19
19
|
from rich.box import ROUNDED, SIMPLE_HEAD
|
|
20
20
|
from rich.console import Console, Group
|
|
21
21
|
from rich.padding import Padding
|
|
22
|
-
from rich.panel import Panel
|
|
23
|
-
from rich.rule import Rule
|
|
24
|
-
from rich.table import Table
|
|
22
|
+
from rich.panel import Panel as RichPanel
|
|
23
|
+
from rich.rule import Rule as RichRule
|
|
24
|
+
from rich.table import Table as RichTable
|
|
25
|
+
from rich.measure import Measurement
|
|
25
26
|
from rich.text import Text
|
|
26
27
|
|
|
27
28
|
from . import theme
|
|
29
|
+
from ._version import __version__
|
|
30
|
+
|
|
31
|
+
_screen_started = False
|
|
32
|
+
_screen_context = "Cloud"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def wordmark(context: Optional[str] = None) -> Text:
|
|
36
|
+
line = Text("fa", style="bold")
|
|
37
|
+
line.append("il", style=f"bold {theme.PINK}")
|
|
38
|
+
line.append("proof ai", style="bold")
|
|
39
|
+
line.append(f" v{__version__} · {context or _screen_context}", style=theme.LABEL)
|
|
40
|
+
return line
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def heading(value: Any) -> Text:
|
|
44
|
+
text = value.copy() if isinstance(value, Text) else Text.from_markup(str(value))
|
|
45
|
+
# Change chrome, never the case of a resource name/id in a title.
|
|
46
|
+
name, sep, rest = text.plain.partition(" · ")
|
|
47
|
+
known = {"events", "sessions", "evals", "errors", "keys", "users", "queries", "settings",
|
|
48
|
+
"issues", "models", "chats", "audits", "findings", "commands", "version",
|
|
49
|
+
"permissions", "orgs", "assistant", "usage", "guardrails", "policies", "fleet",
|
|
50
|
+
"options", "arguments"}
|
|
51
|
+
if name.lower() in known:
|
|
52
|
+
text = Text(name.upper(), style=f"bold {theme.TEXT}") + Text(sep + rest, style=theme.LABEL)
|
|
53
|
+
return text
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def screen_header(console=None) -> None:
|
|
57
|
+
global _screen_started
|
|
58
|
+
if not _screen_started and not _quiet and not _json_out:
|
|
59
|
+
_screen_started = True
|
|
60
|
+
(console or _stdout).print(wordmark())
|
|
61
|
+
(console or _stdout).print()
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class Panel(RichPanel):
|
|
65
|
+
"""Legacy cards rendered through the open-screen primitive, without boxes.
|
|
66
|
+
|
|
67
|
+
Keep RichPanel's constructor/attributes so existing renderers need no rewrite.
|
|
68
|
+
"""
|
|
69
|
+
def __rich_console__(self, console, options):
|
|
70
|
+
global _screen_started
|
|
71
|
+
if not _screen_started and not _quiet and not _json_out:
|
|
72
|
+
_screen_started = True
|
|
73
|
+
yield wordmark()
|
|
74
|
+
yield Text("")
|
|
75
|
+
if self.title:
|
|
76
|
+
yield heading(self.title)
|
|
77
|
+
yield self.renderable
|
|
78
|
+
if self.subtitle:
|
|
79
|
+
yield heading(self.subtitle)
|
|
80
|
+
|
|
81
|
+
def __rich_measure__(self, console, options):
|
|
82
|
+
parts = [self.renderable]
|
|
83
|
+
if self.title:
|
|
84
|
+
parts.insert(0, heading(self.title))
|
|
85
|
+
return Measurement.get(console, options, Group(*parts))
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
class Rule(RichRule):
|
|
89
|
+
"""Legacy separators are intentionally invisible in the 2026-10 language."""
|
|
90
|
+
def __rich_console__(self, console, options):
|
|
91
|
+
return iter(())
|
|
92
|
+
|
|
93
|
+
def __rich_measure__(self, console, options):
|
|
94
|
+
return Measurement(0, 0)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
class Table(RichTable):
|
|
98
|
+
"""Shared tables: grey labels, no borders/rules, fold instead of cut."""
|
|
99
|
+
def __init__(self, *args, **kwargs):
|
|
100
|
+
kwargs["box"] = None
|
|
101
|
+
kwargs["show_edge"] = False
|
|
102
|
+
kwargs["header_style"] = theme.LABEL
|
|
103
|
+
super().__init__(*args, **kwargs)
|
|
104
|
+
|
|
105
|
+
def add_column(self, *args, **kwargs):
|
|
106
|
+
kwargs["overflow"] = "fold"
|
|
107
|
+
kwargs["no_wrap"] = False
|
|
108
|
+
return super().add_column(*args, **kwargs)
|
|
28
109
|
|
|
29
110
|
_stdout = Console()
|
|
30
111
|
_stderr = Console(stderr=True)
|
|
@@ -33,14 +114,16 @@ _no_color = False
|
|
|
33
114
|
_json_out = False
|
|
34
115
|
|
|
35
116
|
|
|
36
|
-
def configure(*, no_color: bool = False, quiet: bool = False, json: bool = False) -> None:
|
|
117
|
+
def configure(*, no_color: bool = False, quiet: bool = False, json: bool = False, context: str = "Cloud") -> None:
|
|
37
118
|
"""Reconfigure the consoles from the resolved global flags."""
|
|
38
|
-
global _stdout, _stderr, _quiet, _no_color, _json_out
|
|
119
|
+
global _stdout, _stderr, _quiet, _no_color, _json_out, _screen_started, _screen_context
|
|
39
120
|
_stdout = Console(no_color=no_color)
|
|
40
121
|
_stderr = Console(stderr=True, no_color=no_color)
|
|
41
122
|
_quiet = quiet
|
|
42
123
|
_no_color = no_color
|
|
43
124
|
_json_out = json
|
|
125
|
+
_screen_started = False
|
|
126
|
+
_screen_context = context
|
|
44
127
|
|
|
45
128
|
|
|
46
129
|
def is_json() -> bool:
|
|
@@ -70,6 +153,11 @@ def _ansi(text: str, **style: Any) -> str:
|
|
|
70
153
|
"""A click-styled string for use in input prompts, or plain when colour is off."""
|
|
71
154
|
if _no_color:
|
|
72
155
|
return text
|
|
156
|
+
# Click accepts RGB tuples, not Rich's hex colour strings.
|
|
157
|
+
for key in ("fg", "bg"):
|
|
158
|
+
color = style.get(key)
|
|
159
|
+
if isinstance(color, str) and re.fullmatch(r"#[0-9a-fA-F]{6}", color):
|
|
160
|
+
style[key] = tuple(int(color[i:i + 2], 16) for i in (1, 3, 5))
|
|
73
161
|
return typer.style(text, **style)
|
|
74
162
|
|
|
75
163
|
|
|
@@ -126,16 +214,30 @@ def print_table(
|
|
|
126
214
|
title: Optional[str] = None,
|
|
127
215
|
show_header: bool = True,
|
|
128
216
|
) -> None:
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
217
|
+
screen_header()
|
|
218
|
+
if title:
|
|
219
|
+
_stdout.print(Text(str(title).upper(), style="bold"))
|
|
220
|
+
widths = [max([len(str(column))] + [len(_cell(row[i])) for row in rows if i < len(row)]) for i, column in enumerate(columns)]
|
|
221
|
+
if len(columns) > 1 and sum(widths) + 3 * len(columns) > _stdout.width:
|
|
222
|
+
# On a narrow terminal, wrapped adjacent columns interleave copyable
|
|
223
|
+
# ids and URLs. Stack the fields so each value remains a whole line.
|
|
224
|
+
for row in rows:
|
|
225
|
+
for column, value in zip(columns, row):
|
|
226
|
+
_stdout.print(Text(str(column).upper(), style=theme.LABEL))
|
|
227
|
+
_stdout.print(Text(" " + _cell(value)), soft_wrap=True)
|
|
228
|
+
_stdout.print()
|
|
229
|
+
return
|
|
230
|
+
table = Table(show_header=show_header)
|
|
132
231
|
for column in columns:
|
|
133
232
|
table.add_column(str(column), overflow="fold")
|
|
134
233
|
for row in rows:
|
|
135
234
|
# Wrap each cell in Text so a value containing Rich markup (e.g. "[/]" or
|
|
136
235
|
# "[red]" in a server-provided field) renders literally instead of raising
|
|
137
236
|
# MarkupError mid-render (which would abort with a raw traceback).
|
|
138
|
-
table.add_row(*[
|
|
237
|
+
table.add_row(*[
|
|
238
|
+
Text(_cell(value), style=theme.LABEL if list(columns) == ["Field", "Value"] and i == 0 else "")
|
|
239
|
+
for i, value in enumerate(row)
|
|
240
|
+
])
|
|
139
241
|
_stdout.print(table)
|
|
140
242
|
|
|
141
243
|
|
|
@@ -152,7 +254,7 @@ def info(message: str) -> None:
|
|
|
152
254
|
|
|
153
255
|
def success(message: str) -> None:
|
|
154
256
|
if not _quiet:
|
|
155
|
-
_stderr.print(
|
|
257
|
+
_stderr.print(Text("✓ ", style=theme.SUCCESS) + Text(message))
|
|
156
258
|
|
|
157
259
|
|
|
158
260
|
def hint(message: str) -> None:
|
|
@@ -161,12 +263,12 @@ def hint(message: str) -> None:
|
|
|
161
263
|
|
|
162
264
|
|
|
163
265
|
def error(message: str) -> None:
|
|
164
|
-
_stderr.print(
|
|
266
|
+
_stderr.print(Text("✕ ", style=theme.ERROR) + Text(message))
|
|
165
267
|
|
|
166
268
|
|
|
167
269
|
def warn(message: str) -> None:
|
|
168
270
|
if not _quiet:
|
|
169
|
-
_stderr.print(
|
|
271
|
+
_stderr.print(Text("▲ ", style=theme.PINK) + Text(message))
|
|
170
272
|
|
|
171
273
|
|
|
172
274
|
def cli_warn(message: str) -> None:
|
|
@@ -187,7 +289,7 @@ def cli_warn(message: str) -> None:
|
|
|
187
289
|
# here is stderr status chrome (never the --json data on stdout); the accent is
|
|
188
290
|
# the project's pink/magenta. All gated on `_quiet`.
|
|
189
291
|
|
|
190
|
-
_ACCENT =
|
|
292
|
+
_ACCENT = theme.PINK
|
|
191
293
|
_NEUTRAL = "grey62" # gray for 'already in that state' no-op boxes (neutral, not red/green)
|
|
192
294
|
|
|
193
295
|
|
|
@@ -196,7 +298,8 @@ def auth_header() -> None:
|
|
|
196
298
|
if _quiet:
|
|
197
299
|
return
|
|
198
300
|
_stderr.print()
|
|
199
|
-
_stderr
|
|
301
|
+
screen_header(_stderr)
|
|
302
|
+
_stderr.print(Text("SIGN IN", style="bold"))
|
|
200
303
|
_stderr.print(" [dim]welcome — let's get you signed in with a one-time code[/]")
|
|
201
304
|
_stderr.print()
|
|
202
305
|
|
|
@@ -212,7 +315,7 @@ def code_sent(email: str) -> None:
|
|
|
212
315
|
"""Confirm the one-time code was emailed (the completed `request_otp` step)."""
|
|
213
316
|
if _quiet:
|
|
214
317
|
return
|
|
215
|
-
_stderr.print(f" [
|
|
318
|
+
_stderr.print(f" [{theme.SUCCESS}]✓[/] code sent to [bold {_ACCENT}]{email}[/]")
|
|
216
319
|
|
|
217
320
|
|
|
218
321
|
def org_picker(slugs: Sequence[str], current: Optional[str] = None) -> None:
|
|
@@ -403,6 +506,7 @@ def _panel(mark: str, color: str, title: str, body: Text, hint: Optional[str] =
|
|
|
403
506
|
highlighted. Built from a `rich.Text` (literal body — no markup injection). The colour
|
|
404
507
|
carries the meaning: **green** = success, **brand-accent** = neutral 'already-in-state'
|
|
405
508
|
no-op, **red** = failure. One shape so they all read as one family."""
|
|
509
|
+
color = theme.SUCCESS if color == "green" else theme.PINK if color in ("red", "yellow", "cyan", "magenta") else color
|
|
406
510
|
text = Text()
|
|
407
511
|
indent = ""
|
|
408
512
|
# A box may be mark-less (the colour/title carry the meaning, e.g. the red
|
|
@@ -415,7 +519,7 @@ def _panel(mark: str, color: str, title: str, body: Text, hint: Optional[str] =
|
|
|
415
519
|
text.append(f"\n{indent}")
|
|
416
520
|
text.append(hint, style="dim")
|
|
417
521
|
text.highlight_words(
|
|
418
|
-
["fp login", "fp logout", "login --force"], style="bold
|
|
522
|
+
["fp login", "fp logout", "login --force"], style=f"bold {theme.PINK}"
|
|
419
523
|
)
|
|
420
524
|
panel = Panel(
|
|
421
525
|
text,
|
|
@@ -433,8 +537,12 @@ def _panel(mark: str, color: str, title: str, body: Text, hint: Optional[str] =
|
|
|
433
537
|
|
|
434
538
|
|
|
435
539
|
def _error_box(message: str, hint: Optional[str] = None) -> None:
|
|
436
|
-
"""
|
|
437
|
-
|
|
540
|
+
"""One failure line, followed by a grey recovery hint when present."""
|
|
541
|
+
_stderr.print(Text("✕ ", style=theme.ERROR) + Text(message))
|
|
542
|
+
if hint:
|
|
543
|
+
line = Text(" " + hint, style=theme.LABEL)
|
|
544
|
+
line.highlight_regex(r"(?:fp|failproofai)\s+[^`]+", style=theme.PINK)
|
|
545
|
+
_stderr.print(line)
|
|
438
546
|
|
|
439
547
|
|
|
440
548
|
def _status_box(title: str, body: Text, hint: Optional[str] = None) -> None:
|
|
@@ -450,21 +558,8 @@ def version_banner(version: str) -> None:
|
|
|
450
558
|
if _quiet:
|
|
451
559
|
_stdout.print(version)
|
|
452
560
|
return
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
body.append("fp", style="bold")
|
|
456
|
-
body.append(" ")
|
|
457
|
-
body.append(f"v{version}", style=f"bold {_ACCENT}")
|
|
458
|
-
panel = Panel(
|
|
459
|
-
body,
|
|
460
|
-
border_style=_ACCENT,
|
|
461
|
-
title=f"[bold {_ACCENT}]version[/]",
|
|
462
|
-
title_align="left",
|
|
463
|
-
expand=False,
|
|
464
|
-
padding=(0, 1),
|
|
465
|
-
)
|
|
466
|
-
_stdout.print()
|
|
467
|
-
_stdout.print(Padding(panel, (0, 0, 0, 2)))
|
|
561
|
+
screen_header()
|
|
562
|
+
_stdout.print(Text(f"fp v{version}", style=theme.LABEL))
|
|
468
563
|
|
|
469
564
|
|
|
470
565
|
# ── top-level help (the grouped `fp` / `fp help` / `fp --help` screen) ──
|
|
@@ -482,35 +577,42 @@ _TOP_LEVEL_GROUPS = [
|
|
|
482
577
|
("whoami", "Show the current user, active org, and perms.", ""),
|
|
483
578
|
]),
|
|
484
579
|
("OBSERVE", [
|
|
485
|
-
("events", "List the raw per-step agent event trail.", ""),
|
|
486
|
-
("sessions", "List agent runs — one row per run.", ""),
|
|
580
|
+
("events", "List the raw per-step agent event trail.", "latency"),
|
|
581
|
+
("sessions", "List agent runs — one row per run.", "show export history re-evaluate import"),
|
|
487
582
|
("evals", "List scored agent evaluations.", "--aggregate"),
|
|
583
|
+
("evaluators", "Author, test and deploy managed evaluators.", "list show create deploy draft dry-run enable disable label instances schema jobs backfill"),
|
|
584
|
+
("sentiment", "Inspect conversation sentiment.", "summary messages sessions session"),
|
|
585
|
+
("dashboards", "Manage dashboards and saved-query tiles.", "list show create update delete tiles"),
|
|
488
586
|
("errors", "List errored events.", "--aggregate"),
|
|
489
|
-
("usage", "Show current org usage for the metering window.", ""),
|
|
587
|
+
("usage", "Show current org usage for the metering window.", "windows"),
|
|
490
588
|
]),
|
|
491
589
|
("ENFORCE", [
|
|
492
|
-
("policies", "Write cloud-managed policies.", "list show publish test compose enable disable delete"),
|
|
590
|
+
("policies", "Write cloud-managed policies.", "list show publish test compose author backtest candidacy enable disable delete"),
|
|
493
591
|
("fleet", "Deploy policies to machines.", "list show deploy diff history rollback rename"),
|
|
494
592
|
("guardrails", "What enforcement actually blocked.", "summary timeline"),
|
|
495
593
|
]),
|
|
496
594
|
("MANAGE", [
|
|
497
|
-
("orgs", "Switch and inspect the active org.", "list switch current perms"),
|
|
595
|
+
("orgs", "Switch and inspect the active org.", "list switch current perms create"),
|
|
498
596
|
("keys", "Provision and manage API keys.", "list show create update disable regenerate"),
|
|
499
|
-
("users", "Manage org members and their permissions.", "list show create update disable enable"),
|
|
500
|
-
("query", "Run and manage saved SQL queries.", "list show create update delete run schema"),
|
|
501
|
-
("alerts", "Define, edit, and test alerts.", "list show create update delete test"),
|
|
597
|
+
("users", "Manage org members and their permissions.", "list show create update disable enable delete defaults"),
|
|
598
|
+
("query", "Run and manage saved SQL queries.", "list show create update delete run schema compose export"),
|
|
599
|
+
("alerts", "Define, edit, and test alerts.", "list show create update delete test recipients issues"),
|
|
502
600
|
# `context-*` rather than the three names spelled out: this hint column
|
|
503
601
|
# ellipsis-truncates at ~110 cols (see `desc_max` below) and this row was
|
|
504
602
|
# already overflowing, so the long form would never render. The full list
|
|
505
603
|
# is one level down, in `fp audits --help`, which walks the real
|
|
506
604
|
# Click tree.
|
|
507
|
-
("audits", "Schedule audits and triage their findings.", "list show create edit delete run runs findings context-*"),
|
|
508
|
-
("issues", "Triage and resolve issues.", "list count show ack assign resolve comment-* subscribe open"),
|
|
509
|
-
("settings", "View and change org settings.", "list schema set"),
|
|
605
|
+
("audits", "Schedule audits and triage their findings.", "list show create edit delete run runs findings finding ack mute dismiss resolve reopen assign context-* contracts"),
|
|
606
|
+
("issues", "Triage and resolve issues.", "list count facets show ack assign resolve close archive unarchive clear comment-* subscribe subscribers unsubscribe open"),
|
|
607
|
+
("settings", "View and change org settings.", "list schema set context-windows"),
|
|
608
|
+
("roles", "Manage permission sets.", "list show create update delete"),
|
|
609
|
+
("plan", "Inspect offers and team trial.", "claim"),
|
|
610
|
+
("otel", "Control Cloud OTEL ingestion.", "status enable disable"),
|
|
611
|
+
("slack", "Manage Slack integration.", "status disconnect"),
|
|
510
612
|
]),
|
|
511
613
|
("TOOLS", [
|
|
512
|
-
("list", "List distinct values behind the filter dropdowns.", ""),
|
|
513
|
-
("agent", "Chat with the FailproofAI Cloud assistant.", "health models chats ask show rename delete"),
|
|
614
|
+
("list", "List distinct values behind the filter dropdowns.", "envs agents event_types score_filters models hooks tools error_types trigger_events eval_envs metric_keys"),
|
|
615
|
+
("agent", "Chat with the FailproofAI Cloud assistant.", "health models chats ask show rename delete brief"),
|
|
514
616
|
]),
|
|
515
617
|
]
|
|
516
618
|
|
|
@@ -530,17 +632,21 @@ def render_top_level_help() -> None:
|
|
|
530
632
|
bold-white headings, BLUE command names, white one-line descriptions, FAINT subcommand hints,
|
|
531
633
|
a FAINT footer), then aligned EXAMPLES. Presentation only — same routing, same commands.
|
|
532
634
|
NO_COLOR keeps the box + bold headings + alignment, drops colour."""
|
|
635
|
+
global _screen_started
|
|
533
636
|
total = sum(len(cmds) for _, cmds in _TOP_LEVEL_GROUPS)
|
|
534
637
|
|
|
535
638
|
def _bullet(*parts) -> Text:
|
|
536
639
|
line = Text(" · ", style=theme.FAINT)
|
|
537
640
|
for text, style in parts:
|
|
641
|
+
if text.startswith("fp "):
|
|
642
|
+
style = theme.PINK
|
|
538
643
|
line.append(text, style=style)
|
|
539
644
|
return line
|
|
540
645
|
|
|
541
646
|
# ── brand mark ──
|
|
542
647
|
_stdout.print()
|
|
543
|
-
|
|
648
|
+
_screen_started = True
|
|
649
|
+
_stdout.print(wordmark())
|
|
544
650
|
|
|
545
651
|
# ── getting started ──
|
|
546
652
|
_stdout.print()
|
|
@@ -572,9 +678,9 @@ def render_top_level_help() -> None:
|
|
|
572
678
|
glob.append(g, style=theme.TEXT_DIM)
|
|
573
679
|
_stdout.print(glob)
|
|
574
680
|
eg = Text(" e.g. ")
|
|
575
|
-
eg.append("fp --json events ", style=theme.
|
|
681
|
+
eg.append("fp --json events ", style=theme.PINK)
|
|
576
682
|
eg.append("✓", style=theme.SUCCESS)
|
|
577
|
-
eg.append(" fp events --json ", style=theme.
|
|
683
|
+
eg.append(" fp events --json ", style=theme.PINK)
|
|
578
684
|
eg.append("✗", style=theme.ERROR)
|
|
579
685
|
_stdout.print(eg)
|
|
580
686
|
mt = Text(" multi-tenant: set the org at login (", style=theme.FAINT)
|
|
@@ -624,7 +730,7 @@ def render_top_level_help() -> None:
|
|
|
624
730
|
if hint:
|
|
625
731
|
cell.append(" · ", style=theme.FAINT)
|
|
626
732
|
cell.append(hint, style=theme.FAINT)
|
|
627
|
-
table.add_row(Text(name, style=theme.
|
|
733
|
+
table.add_row(Text(name, style=theme.PINK), cell)
|
|
628
734
|
footer = Text()
|
|
629
735
|
footer.append("run ", style=theme.FAINT)
|
|
630
736
|
footer.append("fp <command> --help", style=theme.TEXT_DIM)
|
|
@@ -645,7 +751,7 @@ def render_top_level_help() -> None:
|
|
|
645
751
|
ex.add_column(no_wrap=True)
|
|
646
752
|
ex.add_column(no_wrap=True, overflow="ellipsis", max_width=max(SCORES_MIN_WIDTH, min(_stdout.width, 110) - 56))
|
|
647
753
|
for cmd, why in _TOP_LEVEL_EXAMPLES:
|
|
648
|
-
ex.add_row(Text(cmd, style=theme.
|
|
754
|
+
ex.add_row(Text(cmd, style=theme.PINK), Text(why, style=theme.TEXT_DIM))
|
|
649
755
|
_stdout.print(Padding(ex, (0, 0, 0, 2)))
|
|
650
756
|
|
|
651
757
|
_stdout.print()
|
|
@@ -730,7 +836,11 @@ def _perm_res_key(r: str):
|
|
|
730
836
|
|
|
731
837
|
def _perm_act_key(a: str):
|
|
732
838
|
"""Action sort key: risk order (read → modify → invoke → destroy), then alphabetical."""
|
|
733
|
-
|
|
839
|
+
# Risk ordering is semantic, not a function of the two accent colours.
|
|
840
|
+
rank = {"read": 0, "add": 1, "create": 1, "write": 1, "update": 1,
|
|
841
|
+
"use": 2, "trigger": 2, "run": 2, "ack": 2,
|
|
842
|
+
"delete": 3, "disable": 3, "regenerate": 3}
|
|
843
|
+
return (rank.get(a, 99), a)
|
|
734
844
|
|
|
735
845
|
|
|
736
846
|
def _group_permissions(perms: Sequence[str]):
|
|
@@ -910,6 +1020,7 @@ def render_whoami(
|
|
|
910
1020
|
"""The logged-in ``whoami`` view (stdout): an identity header, then the shared
|
|
911
1021
|
permissions + orgs panels. Presentation only; no legend."""
|
|
912
1022
|
c = _stdout
|
|
1023
|
+
screen_header(c)
|
|
913
1024
|
|
|
914
1025
|
# ── identity header (no box) ──
|
|
915
1026
|
c.print()
|
|
@@ -1316,15 +1427,10 @@ def render_events(items: Sequence[Any], *, order: Optional[str] = None,
|
|
|
1316
1427
|
|
|
1317
1428
|
|
|
1318
1429
|
def _short_session(sid: str, *, full: bool = False) -> str:
|
|
1319
|
-
"""
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
return sid
|
|
1324
|
-
if sid.startswith("sess-") and len(sid) > 14:
|
|
1325
|
-
return "sess-…" + sid[-8:]
|
|
1326
|
-
if len(sid) > 18:
|
|
1327
|
-
return sid[:6] + "…" + sid[-6:]
|
|
1430
|
+
"""Return the full session id unchanged for copyable terminal output.
|
|
1431
|
+
|
|
1432
|
+
The legacy ``full`` argument remains accepted for compatibility.
|
|
1433
|
+
"""
|
|
1328
1434
|
return sid
|
|
1329
1435
|
|
|
1330
1436
|
|
|
@@ -1803,6 +1909,8 @@ def render_eval_aggregate(data: dict, *, show_bar: Optional[bool] = None) -> Non
|
|
|
1803
1909
|
|
|
1804
1910
|
|
|
1805
1911
|
def _truncate(s: str, n: int = 80) -> str:
|
|
1912
|
+
if re.search(r"(?:https?://|\bfp\s|[0-9a-f]{8}-[0-9a-f-]{8,})", s, re.I):
|
|
1913
|
+
return s
|
|
1806
1914
|
return s[: n - 1] + "…" if len(s) > n else s
|
|
1807
1915
|
|
|
1808
1916
|
|
|
@@ -2009,19 +2117,16 @@ _KEY_STATUS = {
|
|
|
2009
2117
|
|
|
2010
2118
|
|
|
2011
2119
|
def _short_id(value: str) -> str:
|
|
2012
|
-
"""
|
|
2013
|
-
return value
|
|
2120
|
+
"""Return the full id unchanged; the legacy helper name is retained."""
|
|
2121
|
+
return value
|
|
2014
2122
|
|
|
2015
2123
|
|
|
2016
2124
|
def _short_chat_id(value: str) -> str:
|
|
2017
|
-
"""
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
if "-" in s:
|
|
2023
|
-
return s.split("-", 1)[0]
|
|
2024
|
-
return s[:8] if len(s) > 8 else s
|
|
2125
|
+
"""Return the full chat id without shortening it (empty when absent).
|
|
2126
|
+
|
|
2127
|
+
Commands still accept unambiguous prefixes, but rendered ids stay complete.
|
|
2128
|
+
"""
|
|
2129
|
+
return str(value or "")
|
|
2025
2130
|
|
|
2026
2131
|
|
|
2027
2132
|
def _fmt_key_created(iso: str) -> str:
|
|
@@ -2653,13 +2758,13 @@ def _sql_syntax_theme():
|
|
|
2653
2758
|
class _FpSqlStyle(Style):
|
|
2654
2759
|
background_color = "#0e0c12" # overridden by Syntax(background_color="default")
|
|
2655
2760
|
styles = {
|
|
2656
|
-
Token:
|
|
2761
|
+
Token: "",
|
|
2657
2762
|
Comment: f"italic {theme.FAINT}",
|
|
2658
2763
|
Keyword: f"bold {theme.ACCENT}",
|
|
2659
2764
|
Keyword.Type: theme.SCORE_HIGH,
|
|
2660
2765
|
Operator: theme.TEXT_DIM,
|
|
2661
2766
|
Operator.Word: f"bold {theme.ACCENT}", # AND / OR / NOT
|
|
2662
|
-
Name:
|
|
2767
|
+
Name: "",
|
|
2663
2768
|
Name.Builtin: theme.SUCCESS,
|
|
2664
2769
|
Name.Function: theme.SUCCESS,
|
|
2665
2770
|
Name.Variable: theme.PERM_WRITE, # :name / @var params
|
|
@@ -2791,6 +2896,8 @@ def _plain(*parts, console=None) -> None:
|
|
|
2791
2896
|
``--quiet`` for non-error chrome; callers that must always show pass ``console``)."""
|
|
2792
2897
|
line = Text(" ")
|
|
2793
2898
|
for text, style in parts:
|
|
2899
|
+
if text.startswith("fp "):
|
|
2900
|
+
style = theme.PINK
|
|
2794
2901
|
line.append(text, style=style)
|
|
2795
2902
|
(console or _stderr).print(line)
|
|
2796
2903
|
|
|
@@ -4609,7 +4716,7 @@ def confirm_issues_clear(scope_label: str, issues: int, findings: int) -> bool:
|
|
|
4609
4716
|
h.append(f"{issues} issue{'' if issues == 1 else 's'}", style=f"bold {theme.ACCENT}")
|
|
4610
4717
|
h.append(f" ({scope_label})", style=theme.LABEL)
|
|
4611
4718
|
h.append("?", style=theme.TEXT)
|
|
4612
|
-
tail =
|
|
4719
|
+
tail = "resolves them"
|
|
4613
4720
|
if findings:
|
|
4614
4721
|
tail += f" and {findings} audit finding{'' if findings == 1 else 's'}"
|
|
4615
4722
|
tail += " — nothing is deleted or suppressed"
|
|
@@ -4815,13 +4922,12 @@ def render_agent_models(models: Sequence[str], *, default_model: Optional[str] =
|
|
|
4815
4922
|
|
|
4816
4923
|
|
|
4817
4924
|
def render_agent_chats(chats: Sequence[dict]) -> None:
|
|
4818
|
-
"""The ``agent chats`` view (stdout):
|
|
4819
|
-
title · messages · updated`` (newest first).
|
|
4820
|
-
|
|
4821
|
-
|
|
4822
|
-
budget). The count glows. Empty → ``no chats``."""
|
|
4925
|
+
"""The ``agent chats`` view (stdout): an open ``chats · {n}`` table with columns
|
|
4926
|
+
``chat-id · title · messages · updated`` (newest first). Chat ids are shown in full;
|
|
4927
|
+
commands also accept unambiguous prefixes. The title absorbs width pressure
|
|
4928
|
+
(``…``-truncated on a budget). Empty → ``no chats``."""
|
|
4823
4929
|
items = sorted(chats, key=lambda c: c.get("updated_at") or "", reverse=True) # newest first
|
|
4824
|
-
ids = [_short_chat_id(str(c.get("id") or "-")) for c in items] #
|
|
4930
|
+
ids = [_short_chat_id(str(c.get("id") or "-")) for c in items] # full copyable ids
|
|
4825
4931
|
titles = [str(c.get("title") or "untitled") for c in items]
|
|
4826
4932
|
mcs = [str(c.get("message_count")) if c.get("message_count") is not None else "-" for c in items]
|
|
4827
4933
|
ages = [_age_compact(c.get("updated_at")) for c in items]
|
|
@@ -4840,7 +4946,7 @@ def render_agent_chats(chats: Sequence[dict]) -> None:
|
|
|
4840
4946
|
t = _truncate(titles[i], budget) if budget is not None else titles[i]
|
|
4841
4947
|
updated = Text(ages[i], style=theme.TEXT_DIM) if ages[i] else Text("—", style=theme.FAINT)
|
|
4842
4948
|
rows.append([
|
|
4843
|
-
Text(ids[i], style=theme.TEXT_DIM), # the
|
|
4949
|
+
Text(ids[i], style=theme.TEXT_DIM), # the full copyable id
|
|
4844
4950
|
Text(t, style=theme.TEXT),
|
|
4845
4951
|
Text(mcs[i], style=theme.TEXT_DIM),
|
|
4846
4952
|
updated,
|
|
@@ -6,35 +6,35 @@ entirely under ``NO_COLOR`` / non-color terminals.
|
|
|
6
6
|
|
|
7
7
|
from __future__ import annotations
|
|
8
8
|
|
|
9
|
-
ACCENT = "#
|
|
10
|
-
TEXT = "
|
|
11
|
-
TEXT_DIM = "#
|
|
12
|
-
LABEL = "#
|
|
13
|
-
FAINT = "#
|
|
14
|
-
THIN_RULE = "#
|
|
15
|
-
BAR_EMPTY = "#
|
|
16
|
-
INSET_BG = "
|
|
9
|
+
ACCENT = "#66d1b5" # mint: active and successful states
|
|
10
|
+
TEXT = "default" # the terminal's foreground (also works on light themes)
|
|
11
|
+
TEXT_DIM = "#767f8b"
|
|
12
|
+
LABEL = "#767f8b" # grey labels and metadata
|
|
13
|
+
FAINT = "#767f8b"
|
|
14
|
+
THIN_RULE = "#3e434c"
|
|
15
|
+
BAR_EMPTY = "#3e434c"
|
|
16
|
+
INSET_BG = "default"
|
|
17
17
|
|
|
18
18
|
# Errors theme — the one per-command border deviation (the `errors` list + aggregate card).
|
|
19
19
|
# Always red, regardless of error count, so the two views read as one consistent family.
|
|
20
|
-
BORDER_ERROR = "#
|
|
21
|
-
TITLE_ERROR_DIM =
|
|
22
|
-
RULE_ERROR =
|
|
20
|
+
BORDER_ERROR = "#e4587d"
|
|
21
|
+
TITLE_ERROR_DIM = LABEL
|
|
22
|
+
RULE_ERROR = THIN_RULE
|
|
23
23
|
|
|
24
24
|
# Semantic value colors — for run/job states and score thresholds. (They coincide with
|
|
25
25
|
# the perm risk colors below; named separately so the two uses can diverge later.)
|
|
26
|
-
SUCCESS =
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
26
|
+
SUCCESS = ACCENT
|
|
27
|
+
PINK = "#e4587d" # pink: commands, selection and attention
|
|
28
|
+
AMBER = PINK
|
|
29
|
+
ERROR = PINK
|
|
30
|
+
SCORE_HIGH = ACCENT
|
|
31
|
+
BLUE = ACCENT
|
|
32
32
|
|
|
33
33
|
# Permission verb colors — by ACTION (the part after `:`), never by resource.
|
|
34
|
-
PERM_READ =
|
|
35
|
-
PERM_WRITE =
|
|
36
|
-
PERM_ACTION =
|
|
37
|
-
PERM_DANGER =
|
|
34
|
+
PERM_READ = ACCENT
|
|
35
|
+
PERM_WRITE = PINK
|
|
36
|
+
PERM_ACTION = PINK
|
|
37
|
+
PERM_DANGER = PINK
|
|
38
38
|
|
|
39
39
|
PERM_COLORS = {
|
|
40
40
|
"read": PERM_READ,
|
|
@@ -44,9 +44,6 @@ PERM_COLORS = {
|
|
|
44
44
|
}
|
|
45
45
|
DEFAULT_PERM_COLOR = LABEL # any unmapped action → neutral dim (never crash / guess a risk)
|
|
46
46
|
|
|
47
|
-
# Risk rank for ordering actions within a row: read → modify → invoke → destroy.
|
|
48
|
-
PERM_RANK = {PERM_READ: 0, PERM_WRITE: 1, PERM_ACTION: 2, PERM_DANGER: 3}
|
|
49
|
-
|
|
50
47
|
|
|
51
48
|
def perm_color(action: str) -> str:
|
|
52
49
|
"""The color for a permission action, or the neutral default if it's unmapped."""
|