failproofai 1.0.1 → 1.0.2-beta.0

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.
Files changed (389) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/build-manifest.json +3 -3
  3. package/.next/standalone/.next/prerender-manifest.json +6 -6
  4. package/.next/standalone/.next/required-server-files.json +1 -1
  5. package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
  6. package/.next/standalone/.next/server/app/_global-error/page.js +2 -2
  7. package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  8. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  10. package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
  11. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +6 -6
  12. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
  13. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  14. package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  15. package/.next/standalone/.next/server/app/_not-found/page.js +2 -2
  16. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  17. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  18. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  19. package/.next/standalone/.next/server/app/_not-found.rsc +15 -15
  20. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +15 -15
  21. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +14 -14
  22. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  23. package/.next/standalone/.next/server/app/api/audit/invite/route.js +3 -2
  24. package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -1
  25. package/.next/standalone/.next/server/app/api/audit/run/route.js +5 -4
  26. package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
  27. package/.next/standalone/.next/server/app/api/audit/status/route.js.nft.json +1 -1
  28. package/.next/standalone/.next/server/app/api/auth/login-request/route.js +2 -2
  29. package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
  30. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js +4 -3
  31. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
  32. package/.next/standalone/.next/server/app/api/auth/logout/route.js +4 -4
  33. package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
  34. package/.next/standalone/.next/server/app/api/auth/status/route.js +4 -4
  35. package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
  36. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
  37. package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
  38. package/.next/standalone/.next/server/app/audit/page.js +2 -2
  39. package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
  40. package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
  41. package/.next/standalone/.next/server/app/index.html +1 -1
  42. package/.next/standalone/.next/server/app/index.rsc +15 -15
  43. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +14 -14
  44. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
  45. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  46. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
  47. package/.next/standalone/.next/server/app/page.js +2 -2
  48. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  49. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  50. package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +66 -22
  51. package/.next/standalone/.next/server/app/policies/page.js +5 -4
  52. package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
  53. package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
  54. package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
  55. package/.next/standalone/.next/server/app/project/[name]/page.js +2 -2
  56. package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
  57. package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
  58. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
  59. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
  60. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js +2 -2
  61. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
  62. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
  63. package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
  64. package/.next/standalone/.next/server/app/projects/page.js +2 -2
  65. package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
  66. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  67. package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +4 -4
  68. package/.next/standalone/.next/server/app/settings/page.js +1 -1
  69. package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
  70. package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  71. package/.next/standalone/.next/server/chunks/{[externals]__1qzqcio._.js → [externals]__0e32-7c._.js} +1 -1
  72. package/.next/standalone/.next/server/chunks/[externals]__1s462yl._.js +3 -0
  73. package/.next/standalone/.next/server/chunks/[root-of-the-server]__01eqny5._.js +3 -0
  74. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0_0xu5z._.js +1 -1
  75. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__1p8poxd._.js → [root-of-the-server]__0igxt32._.js} +2 -2
  76. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0neqlu-._.js +3 -0
  77. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o07qi9._.js +3 -0
  78. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0t9oqnn._.js +3 -0
  79. package/.next/standalone/.next/server/chunks/_0bs-v8p._.js +3 -0
  80. package/.next/standalone/.next/server/chunks/_0tovk6q._.js +3 -0
  81. package/.next/standalone/.next/server/chunks/_0trp3yc._.js +3 -0
  82. package/.next/standalone/.next/server/chunks/_185gyk9._.js +3 -0
  83. package/.next/standalone/.next/server/chunks/_1ek68ln._.js +5 -6
  84. package/.next/standalone/.next/server/chunks/lib_telemetry-id_ts_1k8gj9o._.js +3 -0
  85. package/.next/standalone/.next/server/chunks/{node_modules_posthog-node_dist_entrypoints_index_node_mjs_09d5c79._.js → node_modules_posthog-node_dist_entrypoints_index_node_mjs_04op_ou._.js} +1 -1
  86. package/.next/standalone/.next/server/chunks/{node_modules_posthog-node_dist_entrypoints_index_node_mjs_1d2g73o._.js → node_modules_posthog-node_dist_entrypoints_index_node_mjs_0dr20uz._.js} +1 -1
  87. package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
  88. package/.next/standalone/.next/server/chunks/src_hooks_0xbw3bu._.js +12 -0
  89. package/.next/standalone/.next/server/chunks/src_hooks_fp-home_ts_09kv0bn._.js +1 -1
  90. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__013jr2b._.js +4 -0
  91. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__01wy8d-._.js +4 -0
  92. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__02npjtd._.js +4 -0
  93. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0spkm68._.js → [root-of-the-server]__07gm3zl._.js} +21 -20
  94. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0da85px._.js +4 -0
  95. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ftmoxc._.js +4 -0
  96. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0oa1lav._.js +1 -1
  97. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0p-5p8u._.js +4 -0
  98. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0s740oi._.js +6 -0
  99. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__07tbbf3._.js → [root-of-the-server]__0zig5sv._.js} +2 -2
  100. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__192nhvh._.js +5 -0
  101. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1p2otjt._.js +4 -0
  102. package/.next/standalone/.next/server/chunks/ssr/{_0lvyuv4._.js → _00e9tnf._.js} +2 -2
  103. package/.next/standalone/.next/server/chunks/ssr/_08x1r5t._.js +1 -1
  104. package/.next/standalone/.next/server/chunks/ssr/{_0u5zauv._.js → _12l4a_k._.js} +1 -1
  105. package/.next/standalone/.next/server/chunks/ssr/_1u8-lu2._.js +1 -1
  106. package/.next/standalone/.next/server/chunks/ssr/_1zopuov._.js +1 -1
  107. package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +13 -13
  108. package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
  109. package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +2 -2
  110. package/.next/standalone/.next/server/chunks/ssr/app_settings_settings-client_tsx_20lq-mq._.js +1 -1
  111. package/.next/standalone/.next/server/chunks/ssr/src_hooks_08o7bqo._.js +10 -0
  112. package/.next/standalone/.next/server/chunks/ssr/src_hooks_builtin-policies_ts_09j2ndl._.js +1 -1
  113. package/.next/standalone/.next/server/chunks/ssr/src_hooks_fp-home_ts_0je3xkv._.js +1 -1
  114. package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
  115. package/.next/standalone/.next/server/middleware.js +1 -1
  116. package/.next/standalone/.next/server/pages/404.html +1 -1
  117. package/.next/standalone/.next/server/pages/500.html +1 -1
  118. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  119. package/.next/standalone/.next/server/server-reference-manifest.json +71 -27
  120. package/.next/standalone/.next/static/chunks/{37fcpc36x9gpe.js → 0eqky-7n7dgdm.js} +1 -1
  121. package/.next/standalone/.next/static/chunks/{1ide1wl2f7zi1.js → 0sa9v5mhc8861.js} +13 -13
  122. package/.next/standalone/.next/static/chunks/1mfzsja6ftim5.css +2 -0
  123. package/.next/standalone/.next/static/chunks/{3k7mxbp9hiom0.js → 1nuqytbta44af.js} +1 -1
  124. package/.next/standalone/.next/static/chunks/1sl2xmn9inx3y.js +6 -0
  125. package/.next/standalone/.next/static/chunks/{2_2lhuojq2xop.js → 2aawsjld9ied_.js} +1 -1
  126. package/.next/standalone/.next/static/chunks/2gn7ut4svofm2.js +1 -0
  127. package/.next/standalone/.next/static/chunks/{31s1smp-g7gks.js → 2hs7ycvsav7v2.js} +1 -1
  128. package/.next/standalone/.next/static/chunks/{0k5050ezjvv49.js → 2i2yt3hzjredm.js} +1 -1
  129. package/.next/standalone/.next/static/chunks/{3c808qrfcq0im.js → 35xg6retpe6rp.js} +1 -1
  130. package/.next/standalone/.next/static/chunks/{2zpp1we2jv6tb.js → 3y54nw0i7dsjl.js} +1 -1
  131. package/.next/standalone/SECURITY.md +5 -4
  132. package/.next/standalone/app/actions/get-hooks-config.ts +108 -17
  133. package/.next/standalone/app/actions/pack-actions.ts +153 -0
  134. package/.next/standalone/app/audit/_components/run-progress.tsx +1 -1
  135. package/.next/standalone/app/audit/_components/share-templates.ts +13 -13
  136. package/.next/standalone/app/policies/hooks-client.tsx +320 -14
  137. package/.next/standalone/components/navbar.tsx +2 -28
  138. package/.next/standalone/components/reach-developers.tsx +8 -1
  139. package/.next/standalone/docs-old/agenteye/python-sdk-skill.mdx +1 -1
  140. package/.next/standalone/docs-old/agenteye/python-sdk.mdx +59 -35
  141. package/.next/standalone/docs-old/i18n/README.ar.md +1 -0
  142. package/.next/standalone/docs-old/i18n/README.de.md +1 -0
  143. package/.next/standalone/docs-old/i18n/README.es.md +1 -0
  144. package/.next/standalone/docs-old/i18n/README.fr.md +1 -0
  145. package/.next/standalone/docs-old/i18n/README.he.md +1 -0
  146. package/.next/standalone/docs-old/i18n/README.hi.md +1 -0
  147. package/.next/standalone/docs-old/i18n/README.it.md +1 -0
  148. package/.next/standalone/docs-old/i18n/README.ja.md +1 -0
  149. package/.next/standalone/docs-old/i18n/README.ko.md +1 -0
  150. package/.next/standalone/docs-old/i18n/README.pt-br.md +1 -0
  151. package/.next/standalone/docs-old/i18n/README.ru.md +1 -0
  152. package/.next/standalone/docs-old/i18n/README.tr.md +1 -0
  153. package/.next/standalone/docs-old/i18n/README.vi.md +1 -0
  154. package/.next/standalone/docs-old/i18n/README.zh.md +1 -0
  155. package/.next/standalone/fp-cloud-cli/CHANGELOG.md +431 -0
  156. package/.next/standalone/fp-cloud-cli/LICENSE +42 -0
  157. package/.next/standalone/fp-cloud-cli/MANIFEST.in +10 -0
  158. package/.next/standalone/fp-cloud-cli/README.md +259 -0
  159. package/.next/standalone/fp-cloud-cli/fp_cli/__init__.py +10 -0
  160. package/.next/standalone/fp-cloud-cli/fp_cli/__main__.py +4 -0
  161. package/.next/standalone/fp-cloud-cli/fp_cli/_click_compat.py +64 -0
  162. package/.next/standalone/fp-cloud-cli/fp_cli/_context.py +332 -0
  163. package/.next/standalone/fp-cloud-cli/fp_cli/_version.py +1 -0
  164. package/.next/standalone/fp-cloud-cli/fp_cli/analytics.py +432 -0
  165. package/.next/standalone/fp-cloud-cli/fp_cli/analytics_config.py +77 -0
  166. package/.next/standalone/fp-cloud-cli/fp_cli/analytics_registry.py +83 -0
  167. package/.next/standalone/fp-cloud-cli/fp_cli/app.py +492 -0
  168. package/.next/standalone/fp-cloud-cli/fp_cli/auth.py +160 -0
  169. package/.next/standalone/fp-cloud-cli/fp_cli/client.py +1694 -0
  170. package/.next/standalone/fp-cloud-cli/fp_cli/commands/__init__.py +0 -0
  171. package/.next/standalone/fp-cloud-cli/fp_cli/commands/_write.py +214 -0
  172. package/.next/standalone/fp-cloud-cli/fp_cli/commands/agent_cmds.py +407 -0
  173. package/.next/standalone/fp-cloud-cli/fp_cli/commands/alerts_cmds.py +445 -0
  174. package/.next/standalone/fp-cloud-cli/fp_cli/commands/audits_cmds.py +1054 -0
  175. package/.next/standalone/fp-cloud-cli/fp_cli/commands/auth_cmds.py +512 -0
  176. package/.next/standalone/fp-cloud-cli/fp_cli/commands/errors_cmds.py +190 -0
  177. package/.next/standalone/fp-cloud-cli/fp_cli/commands/evals_cmds.py +161 -0
  178. package/.next/standalone/fp-cloud-cli/fp_cli/commands/events_cmds.py +159 -0
  179. package/.next/standalone/fp-cloud-cli/fp_cli/commands/fleet_cmds.py +416 -0
  180. package/.next/standalone/fp-cloud-cli/fp_cli/commands/guardrails_cmds.py +148 -0
  181. package/.next/standalone/fp-cloud-cli/fp_cli/commands/incidents_cmds.py +472 -0
  182. package/.next/standalone/fp-cloud-cli/fp_cli/commands/keys_cmds.py +407 -0
  183. package/.next/standalone/fp-cloud-cli/fp_cli/commands/list_cmds.py +63 -0
  184. package/.next/standalone/fp-cloud-cli/fp_cli/commands/orgs_cmds.py +319 -0
  185. package/.next/standalone/fp-cloud-cli/fp_cli/commands/policies_cmds.py +499 -0
  186. package/.next/standalone/fp-cloud-cli/fp_cli/commands/queries_cmds.py +378 -0
  187. package/.next/standalone/fp-cloud-cli/fp_cli/commands/sessions_cmds.py +151 -0
  188. package/.next/standalone/fp-cloud-cli/fp_cli/commands/settings_cmds.py +150 -0
  189. package/.next/standalone/fp-cloud-cli/fp_cli/commands/usage_cmds.py +35 -0
  190. package/.next/standalone/fp-cloud-cli/fp_cli/commands/users_cmds.py +404 -0
  191. package/.next/standalone/fp-cloud-cli/fp_cli/config.py +330 -0
  192. package/.next/standalone/fp-cloud-cli/fp_cli/dates.py +78 -0
  193. package/.next/standalone/fp-cloud-cli/fp_cli/enforcement.py +345 -0
  194. package/.next/standalone/fp-cloud-cli/fp_cli/errors.py +98 -0
  195. package/.next/standalone/fp-cloud-cli/fp_cli/models.py +891 -0
  196. package/.next/standalone/fp-cloud-cli/fp_cli/orgs.py +30 -0
  197. package/.next/standalone/fp-cloud-cli/fp_cli/output.py +6593 -0
  198. package/.next/standalone/fp-cloud-cli/fp_cli/permissions.py +208 -0
  199. package/.next/standalone/fp-cloud-cli/fp_cli/policy_check.py +290 -0
  200. package/.next/standalone/fp-cloud-cli/fp_cli/py.typed +0 -0
  201. package/.next/standalone/fp-cloud-cli/fp_cli/select.py +322 -0
  202. package/.next/standalone/fp-cloud-cli/fp_cli/theme.py +53 -0
  203. package/.next/standalone/fp-cloud-cli/pyproject.toml +106 -0
  204. package/.next/standalone/fp-cloud-cli/skill/SKILL.md +302 -0
  205. package/.next/standalone/fp-cloud-cli/skill/agents/openai.yaml +8 -0
  206. package/.next/standalone/fp-cloud-cli/skill/references/commands.md +254 -0
  207. package/.next/standalone/fp-cloud-cli/tests/__init__.py +0 -0
  208. package/.next/standalone/fp-cloud-cli/tests/conftest.py +92 -0
  209. package/.next/standalone/fp-cloud-cli/tests/test_alerting.py +644 -0
  210. package/.next/standalone/fp-cloud-cli/tests/test_analytics.py +385 -0
  211. package/.next/standalone/fp-cloud-cli/tests/test_audits.py +950 -0
  212. package/.next/standalone/fp-cloud-cli/tests/test_auth.py +98 -0
  213. package/.next/standalone/fp-cloud-cli/tests/test_auth_mode.py +272 -0
  214. package/.next/standalone/fp-cloud-cli/tests/test_click_compat.py +118 -0
  215. package/.next/standalone/fp-cloud-cli/tests/test_client.py +299 -0
  216. package/.next/standalone/fp-cloud-cli/tests/test_commands.py +814 -0
  217. package/.next/standalone/fp-cloud-cli/tests/test_config.py +99 -0
  218. package/.next/standalone/fp-cloud-cli/tests/test_dashboards_agent.py +340 -0
  219. package/.next/standalone/fp-cloud-cli/tests/test_dates.py +76 -0
  220. package/.next/standalone/fp-cloud-cli/tests/test_enforcement_logic.py +481 -0
  221. package/.next/standalone/fp-cloud-cli/tests/test_facets.py +170 -0
  222. package/.next/standalone/fp-cloud-cli/tests/test_failproofai_home.py +722 -0
  223. package/.next/standalone/fp-cloud-cli/tests/test_fp_home_contract.py +198 -0
  224. package/.next/standalone/fp-cloud-cli/tests/test_hardening.py +186 -0
  225. package/.next/standalone/fp-cloud-cli/tests/test_help_table_coverage.py +127 -0
  226. package/.next/standalone/fp-cloud-cli/tests/test_keys_queries.py +496 -0
  227. package/.next/standalone/fp-cloud-cli/tests/test_list.py +59 -0
  228. package/.next/standalone/fp-cloud-cli/tests/test_multivalue.py +183 -0
  229. package/.next/standalone/fp-cloud-cli/tests/test_no_customer_identifiers.py +168 -0
  230. package/.next/standalone/fp-cloud-cli/tests/test_operator.py +492 -0
  231. package/.next/standalone/fp-cloud-cli/tests/test_orgs.py +692 -0
  232. package/.next/standalone/fp-cloud-cli/tests/test_output.py +1732 -0
  233. package/.next/standalone/fp-cloud-cli/tests/test_policy_check.py +191 -0
  234. package/.next/standalone/fp-cloud-cli/tests/test_readme_matches_reality.py +125 -0
  235. package/.next/standalone/fp-cloud-cli/tests/test_review_fixes.py +161 -0
  236. package/.next/standalone/fp-cloud-cli/tests/test_telemetry_completeness.py +90 -0
  237. package/.next/standalone/fp-cloud-cli/tests/test_usage.py +115 -0
  238. package/.next/standalone/fp-cloud-cli/tests/test_v1_origin_diagnostic.py +70 -0
  239. package/.next/standalone/fp-cloud-cli/tests/test_v1_routing.py +214 -0
  240. package/.next/standalone/fp-cloud-cli/tests/test_whoami.py +104 -0
  241. package/.next/standalone/fp-cloud-cli/uv.lock +552 -0
  242. package/.next/standalone/package.json +29 -22
  243. package/.next/standalone/sdk/python/CHANGELOG.md +70 -0
  244. package/.next/standalone/sdk/python/LICENSE +42 -0
  245. package/.next/standalone/sdk/python/MANIFEST.in +21 -0
  246. package/.next/standalone/sdk/python/README.md +466 -0
  247. package/.next/standalone/sdk/python/docs/README.md +249 -0
  248. package/.next/standalone/sdk/python/docs/_shared/README.md +43 -0
  249. package/.next/standalone/sdk/python/docs/_shared/__init__.py +195 -0
  250. package/.next/standalone/sdk/python/docs/crewai/README.md +328 -0
  251. package/.next/standalone/sdk/python/docs/crewai/examples/quickstart.py +61 -0
  252. package/.next/standalone/sdk/python/docs/crewai/examples/research_crew.py +92 -0
  253. package/.next/standalone/sdk/python/docs/langgraph/README.md +481 -0
  254. package/.next/standalone/sdk/python/docs/langgraph/examples/quickstart.py +51 -0
  255. package/.next/standalone/sdk/python/docs/langgraph/examples/research_agent.py +86 -0
  256. package/.next/standalone/sdk/python/docs/langgraph/examples/supervisor_handoff.py +83 -0
  257. package/.next/standalone/sdk/python/docs/llama_index/README.md +332 -0
  258. package/.next/standalone/sdk/python/docs/llama_index/examples/quickstart.py +62 -0
  259. package/.next/standalone/sdk/python/docs/llama_index/examples/research_agent.py +93 -0
  260. package/.next/standalone/sdk/python/docs/manual/README.md +491 -0
  261. package/.next/standalone/sdk/python/docs/manual/examples/quickstart.py +57 -0
  262. package/.next/standalone/sdk/python/docs/manual/examples/research_agent.py +133 -0
  263. package/.next/standalone/sdk/python/docs/pydantic_ai/README.md +323 -0
  264. package/.next/standalone/sdk/python/docs/pydantic_ai/examples/quickstart.py +48 -0
  265. package/.next/standalone/sdk/python/docs/pydantic_ai/examples/research_agent.py +94 -0
  266. package/.next/standalone/sdk/python/failproofai_sdk/__init__.py +131 -0
  267. package/.next/standalone/sdk/python/failproofai_sdk/_context.py +218 -0
  268. package/.next/standalone/sdk/python/failproofai_sdk/_environment.py +78 -0
  269. package/.next/standalone/sdk/python/failproofai_sdk/_events.py +752 -0
  270. package/.next/standalone/sdk/python/failproofai_sdk/_resolver.py +118 -0
  271. package/.next/standalone/sdk/python/failproofai_sdk/_runtime.py +21 -0
  272. package/.next/standalone/sdk/python/failproofai_sdk/_schema.py +317 -0
  273. package/.next/standalone/sdk/python/failproofai_sdk/_scopes.py +422 -0
  274. package/.next/standalone/sdk/python/failproofai_sdk/_version.py +1 -0
  275. package/.next/standalone/sdk/python/failproofai_sdk/_writer.py +750 -0
  276. package/.next/standalone/sdk/python/failproofai_sdk/integrations/__init__.py +274 -0
  277. package/.next/standalone/sdk/python/failproofai_sdk/integrations/_compat.py +247 -0
  278. package/.next/standalone/sdk/python/failproofai_sdk/integrations/_core.py +1076 -0
  279. package/.next/standalone/sdk/python/failproofai_sdk/integrations/crewai.py +1669 -0
  280. package/.next/standalone/sdk/python/failproofai_sdk/integrations/langchain.py +2151 -0
  281. package/.next/standalone/sdk/python/failproofai_sdk/integrations/llama_index.py +1588 -0
  282. package/.next/standalone/sdk/python/failproofai_sdk/integrations/pydantic_ai.py +977 -0
  283. package/.next/standalone/sdk/python/failproofai_sdk/py.typed +0 -0
  284. package/.next/standalone/sdk/python/pyproject.toml +92 -0
  285. package/.next/standalone/sdk/python/skill/SKILL.md +399 -0
  286. package/.next/standalone/sdk/python/skill/agents/openai.yaml +8 -0
  287. package/.next/standalone/sdk/python/skill/references/events.md +234 -0
  288. package/.next/standalone/sdk/python/skill/references/frameworks.md +314 -0
  289. package/.next/standalone/sdk/python/skill/references/install.md +100 -0
  290. package/.next/standalone/sdk/python/skill/references/integration.md +352 -0
  291. package/.next/standalone/sdk/python/tests/__init__.py +0 -0
  292. package/.next/standalone/sdk/python/tests/conftest.py +169 -0
  293. package/.next/standalone/sdk/python/tests/integrations/__init__.py +6 -0
  294. package/.next/standalone/sdk/python/tests/integrations/test_crewai.py +1299 -0
  295. package/.next/standalone/sdk/python/tests/integrations/test_langchain.py +2338 -0
  296. package/.next/standalone/sdk/python/tests/integrations/test_llama_index.py +1576 -0
  297. package/.next/standalone/sdk/python/tests/integrations/test_pydantic_ai.py +1102 -0
  298. package/.next/standalone/sdk/python/tests/test_context.py +410 -0
  299. package/.next/standalone/sdk/python/tests/test_docs.py +411 -0
  300. package/.next/standalone/sdk/python/tests/test_durability.py +1352 -0
  301. package/.next/standalone/sdk/python/tests/test_encoding.py +571 -0
  302. package/.next/standalone/sdk/python/tests/test_integrations.py +1127 -0
  303. package/.next/standalone/sdk/python/tests/test_no_customer_identifiers.py +214 -0
  304. package/.next/standalone/sdk/python/tests/test_packaging.py +185 -0
  305. package/.next/standalone/sdk/python/tests/test_resolver_umbrella.py +178 -0
  306. package/.next/standalone/sdk/python/tests/test_scopes.py +487 -0
  307. package/.next/standalone/sdk/python/tests/test_sdk.py +923 -0
  308. package/.next/standalone/sdk/python/tests/test_server_contract.py +650 -0
  309. package/.next/standalone/sdk/python/tests/test_site_docs.py +371 -0
  310. package/.next/standalone/sdk/python/tests/test_skill_snippets.py +165 -0
  311. package/.next/standalone/sdk/python/tests/test_spool_contract.py +287 -0
  312. package/.next/standalone/sdk/python/tests/test_spool_creation.py +360 -0
  313. package/.next/standalone/sdk/python/tests/test_wire_format.py +279 -0
  314. package/.next/standalone/sdk/python/tests/test_zero_dependencies.py +378 -0
  315. package/.next/standalone/sdk/python/uv.lock +6005 -0
  316. package/.next/standalone/server.js +1 -1
  317. package/README.md +77 -21
  318. package/bin/failproofai.mjs +145 -11
  319. package/dist/cli.mjs +4482 -2205
  320. package/dist/index.js +5 -5
  321. package/dist/worker.mjs +2399 -1978
  322. package/package.json +29 -22
  323. package/policy-pack/SHA256SUMS +2 -0
  324. package/policy-pack/failproofai-pack.json +732 -0
  325. package/policy-pack/failproofai-pack.mjs +2017 -0
  326. package/scripts/build-policy-pack.mjs +121 -0
  327. package/scripts/changelog-section.py +77 -0
  328. package/scripts/prune-standalone.mjs +3 -0
  329. package/scripts/python-version.py +232 -0
  330. package/scripts/translate-docs/cli.ts +21 -0
  331. package/scripts/translate-docs/mintlify-nav.ts +85 -13
  332. package/scripts/translate-docs/translator.ts +66 -11
  333. package/src/audit/cache.ts +40 -3
  334. package/src/audit/cli.ts +1 -1
  335. package/src/audit/index.ts +1 -1
  336. package/src/audit/replay.ts +89 -3
  337. package/src/audit/report.ts +5 -5
  338. package/src/audit/schedule-cli.ts +49 -53
  339. package/src/hooks/builtin-policies.ts +217 -579
  340. package/src/hooks/cloud-enrollment-cli.ts +66 -27
  341. package/src/hooks/cloud-managed-policies.ts +6 -1
  342. package/src/hooks/configure-wizard.ts +1 -1
  343. package/src/hooks/custom-hooks-loader.ts +89 -6
  344. package/src/hooks/fp-home.ts +92 -4
  345. package/src/hooks/fp-reset.ts +26 -2
  346. package/src/hooks/handler.ts +181 -11
  347. package/src/hooks/harness-cli.ts +79 -25
  348. package/src/hooks/hook-activity-store.ts +13 -3
  349. package/src/hooks/install-prompt.ts +25 -3
  350. package/src/hooks/manager.ts +418 -172
  351. package/src/hooks/migrations.ts +2 -2
  352. package/src/hooks/pack-cli.ts +505 -0
  353. package/src/hooks/pack-failclosed.ts +189 -0
  354. package/src/hooks/pack-manifest.ts +344 -0
  355. package/src/hooks/pack-store.ts +930 -0
  356. package/src/hooks/policy-catalog.ts +535 -0
  357. package/src/hooks/policy-evaluator.ts +24 -16
  358. package/src/hooks/policy-presets.ts +4 -2
  359. package/src/hooks/policy-registry.ts +8 -2
  360. package/src/hooks/policy-types.ts +26 -0
  361. package/src/hooks/session-pause-cli.ts +33 -9
  362. package/src/hooks/tui.ts +570 -0
  363. package/src/hooks/types.ts +15 -1
  364. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0_usx0j._.js +0 -3
  365. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0_zk340._.js +0 -3
  366. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0agdw2a._.js +0 -3
  367. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0d1u_na._.js +0 -3
  368. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0oy4kxb._.js +0 -3
  369. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0zf034w._.js +0 -3
  370. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1tvn4wf._.js +0 -3
  371. package/.next/standalone/.next/server/chunks/_0lxbzdq._.js +0 -3
  372. package/.next/standalone/.next/server/chunks/_1ger0a2._.js +0 -3
  373. package/.next/standalone/.next/server/chunks/_1zuiiy3._.js +0 -3
  374. package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_1iiwm5e._.js +0 -3
  375. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0kc8_v5._.js +0 -4
  376. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0kgy9da._.js +0 -4
  377. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0mhqk5a._.js +0 -4
  378. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0pltpn8._.js +0 -4
  379. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qkcyf-._.js +0 -4
  380. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0w0x_ok._.js +0 -4
  381. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1_dfocn._.js +0 -4
  382. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1bfex62._.js +0 -5
  383. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1kzapg5._.js +0 -6
  384. package/.next/standalone/.next/static/chunks/36fw6yk1s6x_f.js +0 -1
  385. package/.next/standalone/.next/static/chunks/3tzq0260n17ae.js +0 -6
  386. package/.next/standalone/.next/static/chunks/3wq9x0c-7ld5d.css +0 -2
  387. /package/.next/standalone/.next/static/{ZklXxyA5ygsWSQz2u_zii → nwbyWT06Ud0XdXOrVJyvS}/_buildManifest.js +0 -0
  388. /package/.next/standalone/.next/static/{ZklXxyA5ygsWSQz2u_zii → nwbyWT06Ud0XdXOrVJyvS}/_clientMiddlewareManifest.js +0 -0
  389. /package/.next/standalone/.next/static/{ZklXxyA5ygsWSQz2u_zii → nwbyWT06Ud0XdXOrVJyvS}/_ssgManifest.js +0 -0
@@ -0,0 +1,322 @@
1
+ """Interactive selection helpers (TTY pickers), shared across commands.
2
+
3
+ Kept in one place so the org picker used at ``login`` and at ``orgs switch`` reads
4
+ and behaves identically. Pure presentation + input; no network, no persistence.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import os
10
+ import sys
11
+ from typing import List, Optional, Sequence
12
+
13
+ from . import output
14
+
15
+
16
+ def stdin_is_tty() -> bool: # noqa: D401
17
+ """True iff stdin is an interactive terminal (so we may prompt for a choice).
18
+
19
+ Factored out so it can be stubbed in tests — the CliRunner's stdin is not a
20
+ TTY, so the interactive pickers are otherwise unreachable under test.
21
+ """
22
+ try:
23
+ return sys.stdin.isatty()
24
+ except Exception:
25
+ return False
26
+
27
+
28
+ def choose_org(slugs: Sequence[str], default: Optional[str] = None) -> str:
29
+ """Render ``slugs`` and prompt until the user picks one (by slug or number).
30
+
31
+ ``default`` (only if it is one of ``slugs``) is the Enter-to-keep choice and is
32
+ marked ``· current`` in the list. Re-prompts on any out-of-range / unknown input,
33
+ so the return value is always one of ``slugs`` — a non-member slug can never be
34
+ selected through the picker.
35
+ """
36
+ slugs = list(slugs)
37
+ output.org_picker(slugs, current=default)
38
+ prompt_default = default if (default in slugs) else None
39
+ while True:
40
+ choice = str(output.prompt("org", default=prompt_default)).strip()
41
+ if choice in slugs:
42
+ return choice
43
+ if choice.isdigit() and 1 <= int(choice) <= len(slugs):
44
+ return slugs[int(choice) - 1]
45
+ output.warn(f" '{choice}' is not one of your orgs — try again.")
46
+
47
+
48
+ # ── orgs switch — arrow-key picker (raw mode) + numbered fallback ─────────────
49
+
50
+
51
+ def _supports_raw_picker() -> bool:
52
+ """True iff we can run the raw-mode arrow picker: a real interactive TTY on both stdin
53
+ (we read keys) and stderr (we draw the menu), and POSIX ``termios`` is importable.
54
+ Anything else — pipes, CI, the test runner, Windows — falls back to the numbered prompt
55
+ (so the picker never hangs or crashes off a TTY, per the handoff spec §3/§7)."""
56
+ try:
57
+ import termios # noqa: F401
58
+ except Exception:
59
+ return False
60
+ try:
61
+ return bool(sys.stdin.isatty() and sys.stderr.isatty())
62
+ except Exception:
63
+ return False
64
+
65
+
66
+ def _read_key(fd: int) -> str:
67
+ """Read one logical keypress from a raw-mode ``fd`` → a token: ``UP``/``DOWN``/``ENTER``/
68
+ ``ESC``/``EOF`` or the raw character. Distinguishes a lone Esc from an arrow escape
69
+ sequence (``\\x1b[A``) with a tiny ``select`` timeout so Esc never blocks."""
70
+ import select as _sel
71
+
72
+ ch = os.read(fd, 1)
73
+ if not ch:
74
+ return "EOF"
75
+ if ch == b"\x1b": # Esc, or the start of an arrow escape sequence
76
+ r, _, _ = _sel.select([fd], [], [], 0.0008)
77
+ if not r:
78
+ return "ESC"
79
+ seq = os.read(fd, 2)
80
+ return {b"[A": "UP", b"[B": "DOWN", b"[C": "RIGHT", b"[D": "LEFT"}.get(seq, "ESC")
81
+ if ch in (b"\r", b"\n"):
82
+ return "ENTER"
83
+ if ch == b"\x03": # Ctrl-C (also raised as KeyboardInterrupt under cbreak)
84
+ return "CTRL_C"
85
+ return ch.decode("utf-8", "ignore")
86
+
87
+
88
+ def _numbered_pick(orgs: Sequence[dict], *, current: Optional[str]) -> str:
89
+ """Non-TTY fallback: a boxed numbered list + a typed choice (slug or number). Re-prompts on
90
+ bad input, so the return is always one of the orgs' slugs. Default is the current org. With
91
+ no input at all (closed/empty stdin, e.g. CI) the prompt aborts → a clean usage error so the
92
+ run never hangs."""
93
+ import typer
94
+
95
+ from . import _click_compat as click # the Click Typer is running
96
+
97
+ slugs: List[str] = [o["slug"] for o in orgs]
98
+ output.render_org_picker_numbered(orgs, current=current)
99
+ default = current if current in slugs else None
100
+ while True:
101
+ try:
102
+ choice = str(output.prompt("org", default=default)).strip()
103
+ except (click.Abort, EOFError):
104
+ raise typer.BadParameter(
105
+ "No org selected and no interactive terminal. "
106
+ "Pass a slug, e.g. `fp orgs switch <slug>`."
107
+ )
108
+ if choice in slugs:
109
+ return choice
110
+ if choice.isdigit() and 1 <= int(choice) <= len(slugs):
111
+ return slugs[int(choice) - 1]
112
+ output.warn(f" '{choice}' is not one of your orgs — try again.")
113
+
114
+
115
+ def choose_org_interactive(orgs: Sequence[dict], *, current_slug: Optional[str] = None) -> Optional[str]:
116
+ """Pick an org to switch to. ``orgs`` is a list of ``{"slug", "is_current"}`` dicts. Returns
117
+ the chosen slug, or ``None`` if the user cancelled (Esc / Ctrl-C). On a real TTY this is an
118
+ in-place arrow-key menu (cursor starts on the current org); otherwise it falls back to a
119
+ numbered prompt (which can't cancel — it always returns a slug)."""
120
+ orgs = list(orgs)
121
+ if not _supports_raw_picker():
122
+ return _numbered_pick(orgs, current=current_slug)
123
+
124
+ import termios
125
+ import tty
126
+
127
+ from rich.live import Live
128
+
129
+ idx = next((i for i, o in enumerate(orgs) if o.get("is_current")), 0)
130
+ fd = sys.stdin.fileno()
131
+ old = termios.tcgetattr(fd)
132
+ try:
133
+ tty.setcbreak(fd)
134
+ with Live(output.org_picker_frame(orgs, idx), console=output._stderr,
135
+ auto_refresh=False, transient=True) as live:
136
+ while True:
137
+ key = _read_key(fd)
138
+ if key in ("UP", "k"):
139
+ idx = (idx - 1) % len(orgs)
140
+ elif key in ("DOWN", "j"):
141
+ idx = (idx + 1) % len(orgs)
142
+ elif key == "ENTER":
143
+ return orgs[idx]["slug"]
144
+ elif key in ("ESC", "CTRL_C", "q", "EOF"):
145
+ return None
146
+ else:
147
+ continue
148
+ live.update(output.org_picker_frame(orgs, idx))
149
+ live.refresh()
150
+ except KeyboardInterrupt:
151
+ return None
152
+ finally:
153
+ termios.tcsetattr(fd, termios.TCSADRAIN, old)
154
+
155
+
156
+ # ── login — the single-box interactive flow (one Live panel, raw-mode in-box input) ──
157
+
158
+
159
+ class LoginCancelled(Exception):
160
+ """The user pressed Esc / Ctrl-C during the login flow (calm cancel, not an error)."""
161
+
162
+
163
+ def login_box_supported() -> bool:
164
+ """True iff the single-box interactive login can run (real TTY on stdin+stderr + termios) —
165
+ otherwise ``login`` uses the plain prompt flow (tests, pipes, CI, ``--json``)."""
166
+ return _supports_raw_picker()
167
+
168
+
169
+ class LoginBox:
170
+ """Drives the single-box ``login``: ONE Rich ``Live`` panel redrawn in place as steps advance.
171
+ email/code are read in **raw mode** (echo off) and rendered INSIDE the frame; the org step is the
172
+ shared arrow picker as a nested inset. Restores the terminal on exit. Used only on a real TTY —
173
+ the non-interactive path keeps the plain prompts."""
174
+
175
+ def __init__(self) -> None:
176
+ self.done: List = [] # collapsed ✓ steps: (label, value)
177
+ self.active: Optional[str] = None
178
+ self._fd = sys.stdin.fileno()
179
+ self._old = None
180
+ self._live = None
181
+
182
+ def __enter__(self) -> "LoginBox":
183
+ import termios
184
+ import tty
185
+
186
+ from rich.live import Live
187
+
188
+ self._old = termios.tcgetattr(self._fd)
189
+ tty.setcbreak(self._fd) # canonical + echo off, signals on (Ctrl-C → KeyboardInterrupt)
190
+ self._live = Live(output.render_login_frame(self.done, None), console=output._stderr,
191
+ auto_refresh=False, transient=False)
192
+ self._live.__enter__()
193
+ return self
194
+
195
+ def __exit__(self, *exc) -> None:
196
+ import termios
197
+
198
+ try:
199
+ if self._live is not None:
200
+ self._live.__exit__(*exc)
201
+ finally:
202
+ termios.tcsetattr(self._fd, termios.TCSADRAIN, self._old)
203
+
204
+ def _draw(self, **kw) -> None:
205
+ self._live.update(output.render_login_frame(self.done, self.active, **kw))
206
+ self._live.refresh()
207
+
208
+ def _read_line(self, *, helper, slots, error) -> str:
209
+ """Read one line in raw mode, redrawing the frame on every keystroke so the typed text
210
+ appears INSIDE the box (echo is off). Backspace edits; Enter accepts; Esc / Ctrl-C / EOF
211
+ cancel (an arrow escape-sequence mid-type is swallowed, not a cancel). A ``slots`` field
212
+ accepts digits only, capped at ``slots``."""
213
+ import select as _sel
214
+
215
+ buf = ""
216
+ self._draw(active_value=buf, active_slots=slots, helper=helper, error=error)
217
+ while True:
218
+ try:
219
+ ch = os.read(self._fd, 1)
220
+ except KeyboardInterrupt:
221
+ raise LoginCancelled()
222
+ if not ch:
223
+ raise LoginCancelled()
224
+ if ch in (b"\r", b"\n"):
225
+ return buf
226
+ if ch == b"\x03": # Ctrl-C as a byte (if signals were off)
227
+ raise LoginCancelled()
228
+ if ch == b"\x1b": # Esc, or the start of an arrow escape sequence
229
+ r, _, _ = _sel.select([self._fd], [], [], 0.0008)
230
+ if r:
231
+ os.read(self._fd, 2) # swallow the arrow/sequence — don't cancel mid-type
232
+ continue
233
+ raise LoginCancelled()
234
+ if ch in (b"\x7f", b"\x08"): # backspace / delete
235
+ buf = buf[:-1]
236
+ self._draw(active_value=buf, active_slots=slots, helper=helper, error=None)
237
+ continue
238
+ try:
239
+ c = ch.decode("utf-8")
240
+ except UnicodeDecodeError:
241
+ continue
242
+ if not c.isprintable():
243
+ continue
244
+ if slots and (not c.isdigit() or len(buf) >= slots):
245
+ continue # the code field is digits-only, capped
246
+ buf += c
247
+ self._draw(active_value=buf, active_slots=slots, helper=helper, error=None)
248
+
249
+ def text_step(self, label: str, *, helper=None, slots=None, validate=None,
250
+ error_msg=None, hidden_value: bool = False, collapse: bool = True,
251
+ initial_error=None) -> str:
252
+ """Run one bright ``❯ {label}`` input step; on a failed ``validate`` show the error sub-line
253
+ and re-prompt. On accept it collapses to a dim ``✓ {label} {value}`` line (the value is
254
+ omitted when ``hidden_value``). With ``collapse=False`` it returns the value WITHOUT adding
255
+ the ✓ line (the caller verifies it over the network first, then calls ``note``); ``initial_error``
256
+ seeds the error sub-line on the first draw (a re-prompt after a wrong code)."""
257
+ self.active = label
258
+ error = initial_error
259
+ while True:
260
+ buf = self._read_line(helper=helper, slots=slots, error=error).strip()
261
+ if validate is None or validate(buf):
262
+ self.active = None
263
+ if collapse:
264
+ self.done.append((label, "" if hidden_value else buf))
265
+ self._draw()
266
+ return buf
267
+ error = error_msg or "that doesn't look right"
268
+
269
+ def note(self, label: str, value=None) -> None:
270
+ """Add a completed ✓ line that wasn't an input step (e.g. ``✓ code sent``)."""
271
+ self.done.append((label, value))
272
+ self._draw()
273
+
274
+ def working(self, text: str) -> None:
275
+ """Show a transient dim ``· {text}`` line (e.g. while a network call runs)."""
276
+ self._draw(note=text)
277
+
278
+ def retry_text(self, message: str) -> None:
279
+ """Re-arm the code step with an error sub-line (used after a wrong code)."""
280
+ # text_step's own loop shows the error; this is for the verify-fail re-prompt path.
281
+ self._draw(error=message)
282
+
283
+ def pick(self, slugs: Sequence[str], *, default: Optional[str] = None) -> str:
284
+ """The nested org-picker inset: arrow keys move the cursor, Enter selects (collapses to
285
+ ``✓ org {slug}``), Esc / Ctrl-C raise ``LoginCancelled``."""
286
+ slugs = list(slugs)
287
+ idx = slugs.index(default) if default in slugs else 0
288
+ self.active = None
289
+ self._draw(inset=output.login_inset(slugs, idx))
290
+ while True:
291
+ try:
292
+ key = _read_key(self._fd)
293
+ except KeyboardInterrupt:
294
+ raise LoginCancelled()
295
+ if key in ("UP", "k"):
296
+ idx = (idx - 1) % len(slugs)
297
+ elif key in ("DOWN", "j"):
298
+ idx = (idx + 1) % len(slugs)
299
+ elif key == "ENTER":
300
+ chosen = slugs[idx]
301
+ self.done.append(("org", chosen))
302
+ self._draw()
303
+ return chosen
304
+ elif key in ("ESC", "CTRL_C", "q", "EOF"):
305
+ raise LoginCancelled()
306
+ else:
307
+ continue
308
+ self._draw(inset=output.login_inset(slugs, idx))
309
+
310
+ def finish(self, email: str, org: Optional[str]) -> None:
311
+ """Final state: the outer border + legend flip SUCCESS green; ``● signed in`` + email + org."""
312
+ self._draw(signed_in=(email, org))
313
+
314
+ def cancel(self, persisted: bool) -> None:
315
+ """Render the calm close — ``○ cancelled — not signed in`` (or ``○ signed in · pick an org …``
316
+ when the session was already persisted)."""
317
+ self._draw(cancelled=bool(persisted))
318
+
319
+ def fail(self, message: str, hint: Optional[str] = None) -> None:
320
+ """Render a failure INSIDE the box (red border + ``✗ {message}`` + an optional hint) — e.g.
321
+ a wrong/expired code — instead of a separate error box below the frame."""
322
+ self._draw(failed=(message, hint))
@@ -0,0 +1,53 @@
1
+ """Shared brand color tokens + the permission action→color map.
2
+
3
+ Truecolor hex; Rich downgrades to the nearest supported color automatically and drops color
4
+ entirely under ``NO_COLOR`` / non-color terminals.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ ACCENT = "#9d7bff" # brand mark, box borders, active org, command names in hints
10
+ TEXT = "#d8d2dd" # primary values
11
+ TEXT_DIM = "#7d7488" # ids, resource names, org names
12
+ LABEL = "#6b6478" # field labels, header cells, hints
13
+ FAINT = "#5a5266" # separators, inactive markers
14
+ THIN_RULE = "#2e2435" # the faint rule beneath a list-panel header
15
+ BAR_EMPTY = "#2a2530" # the unfilled cells of a mini-bar (e.g. the aggregate avg bar)
16
+ INSET_BG = "#231e2d" # a hair-lighter fill for a nested inset box (the login org picker)
17
+
18
+ # Errors theme — the one per-command border deviation (the `errors` list + aggregate card).
19
+ # Always red, regardless of error count, so the two views read as one consistent family.
20
+ BORDER_ERROR = "#e2564a" # red → the errors panel border (same as ERROR; consistent, not count-dependent)
21
+ TITLE_ERROR_DIM = "#6e3530" # dim red → the errors title's non-name part + card separators
22
+ RULE_ERROR = "#3a2d2d" # dim red → the errors list header rule (vs the neutral THIN_RULE)
23
+
24
+ # Semantic value colors — for run/job states and score thresholds. (They coincide with
25
+ # the perm risk colors below; named separately so the two uses can diverge later.)
26
+ SUCCESS = "#5dcaa5" # green → run status: done/passed
27
+ AMBER = "#ef9f27" # amber → run status: running/pending · score band .50–.80
28
+ ERROR = "#e2564a" # red → run status: failed/error · score band < .50
29
+ SCORE_HIGH = "#3ddbb8" # cyan-green → score band ≥ .80 (distinct from status green)
30
+ BLUE = "#6b86d8" # blue → schema uuid/timestamp type category
31
+ PINK = "#d4537e" # pink → numeric values (query run cells / scalar card) + numeric type category
32
+
33
+ # Permission verb colors — by ACTION (the part after `:`), never by resource.
34
+ PERM_READ = "#5dcaa5" # green → read
35
+ PERM_WRITE = "#d4537e" # pink → add, create, write, update
36
+ PERM_ACTION = "#ef9f27" # amber → use, trigger, run, ack
37
+ PERM_DANGER = "#e2564a" # red → delete, disable, regenerate
38
+
39
+ PERM_COLORS = {
40
+ "read": PERM_READ,
41
+ "add": PERM_WRITE, "create": PERM_WRITE, "write": PERM_WRITE, "update": PERM_WRITE,
42
+ "use": PERM_ACTION, "trigger": PERM_ACTION, "run": PERM_ACTION, "ack": PERM_ACTION,
43
+ "delete": PERM_DANGER, "disable": PERM_DANGER, "regenerate": PERM_DANGER,
44
+ }
45
+ DEFAULT_PERM_COLOR = LABEL # any unmapped action → neutral dim (never crash / guess a risk)
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
+
51
+ def perm_color(action: str) -> str:
52
+ """The color for a permission action, or the neutral default if it's unmapped."""
53
+ return PERM_COLORS.get(action, DEFAULT_PERM_COLOR)
@@ -0,0 +1,106 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "fp-cloud-cli"
7
+ dynamic = ["version"]
8
+ requires-python = ">=3.10"
9
+ description = "Command line client for FailproofAI Cloud — sessions, events, evaluations and audits from your terminal"
10
+ readme = "README.md"
11
+ license = { file = "LICENSE" }
12
+ authors = [{ name = "Failproof AI", email = "failproofai@exosphere.host" }]
13
+ keywords = ["agents", "observability", "ai", "monitoring", "failproofai", "cli"]
14
+ classifiers = [
15
+ "Development Status :: 4 - Beta",
16
+ "Environment :: Console",
17
+ "Intended Audience :: Developers",
18
+ "Programming Language :: Python :: 3",
19
+ "Programming Language :: Python :: 3.10",
20
+ "Programming Language :: Python :: 3.11",
21
+ "Programming Language :: Python :: 3.12",
22
+ "Programming Language :: Python :: 3.13",
23
+ "Typing :: Typed",
24
+ ]
25
+ dependencies = [
26
+ "httpx>=0.27",
27
+ # This range spans typer's Click split: 0.26 vendored Click into `typer/_click` and
28
+ # dropped the `click` dependency, so Typer's command runner catches ITS Click's
29
+ # exceptions, not the pip `click` ones. `fp_cli/_click_compat` resolves whichever
30
+ # Click the installed typer is running, and everything raises, subclasses and inspects
31
+ # through that — which is what makes both sides of the split work. Import Click from
32
+ # there and nowhere else; `tests/test_click_compat.py` enforces it, because every way
33
+ # this breaks is silent (typed errors collapse to exit 1 with an empty stderr, and the
34
+ # telemetry flag catalog empties). Suite verified against 0.25.1 and 0.27.0.
35
+ #
36
+ # The floor is 0.13, not 0.12, because 0.12 cannot BUILD this app: the global
37
+ # `--insecure/--secure` option in `app.py` is an `Optional[bool]` with a
38
+ # secondary flag, which 0.12's Click reaches as a non-boolean flag and
39
+ # rejects with `TypeError: Secondary flag is not valid for non-boolean flag`.
40
+ # That fires while the command tree is constructed, before any parsing, so
41
+ # `fp --version`, `fp --help` and every subcommand die identically — an
42
+ # installed CLI that cannot run one command. `uv.lock` pins 0.27.1, so
43
+ # neither CI nor the publish smoke test ever installed the broken part of the
44
+ # range. Measured across 0.12.0/0.12.3/0.12.5 (all fail) and 0.13.0 upward
45
+ # (all pass).
46
+ "typer>=0.13,<0.28",
47
+ # `click` is what `_click_compat` falls back to when typer is < 0.26 (0.26+ brings its
48
+ # own), and `pygments` is imported directly. Both are declared rather than relied on
49
+ # transitively: modern `typer` no longer installs `click`, and `rich` could likewise
50
+ # drop `pygments`.
51
+ "click>=8.1",
52
+ "rich>=13",
53
+ "pygments>=2.13",
54
+ "posthog>=3.5,<8",
55
+ ]
56
+
57
+ # The distribution is `fp-cloud-cli`; the command is `fp`; the import package is
58
+ # `fp_cli`. All three differ, and each for its own reason:
59
+ #
60
+ # `fp` was already registered on PyPI by someone else.
61
+ # `fp-cli` was the next choice and is ALSO unusable: PyPI refuses a name
62
+ # "too similar to an existing project", and its similarity check
63
+ # strips separators — so `fp-cli` collides with `fpcli`, a real
64
+ # package with 42 releases. It is not a squat, so there is no
65
+ # PEP 541 claim to make; the name simply is not available.
66
+ # `fp-cloud-cli` is what pip resolves, and says what this talks to: the Cloud
67
+ # dashboard's API, never the Rust server directly.
68
+ # `fp_cli` stays as the import package. Nobody imports it — this is an
69
+ # application, not a library, and the console script above is the
70
+ # entire public surface — so renaming it would churn every module
71
+ # and every test to change a string no user ever types.
72
+ #
73
+ # `~/.failproofai/fpcli/` keeps its name for a harder reason: it is an on-disk
74
+ # contract with `src/hooks/fp-home.ts` (`fpcliDir`/`fpcliAuthFile`), and moving it
75
+ # would sign every existing user out.
76
+ [project.scripts]
77
+ fp = "fp_cli.app:main_entry"
78
+
79
+ [project.urls]
80
+ Homepage = "https://befailproof.ai"
81
+ # The live route. `/agenteye/cli` is a 404 — those pages moved to `docs-old/`,
82
+ # which the docs build does not publish and `docs/docs.json` does not reference,
83
+ # and there are no `redirects`. PyPI bakes project URLs into published metadata,
84
+ # so a wrong one here needs a version bump to correct.
85
+ Documentation = "https://docs.befailproof.ai/reference/cloud-cli"
86
+ Source = "https://github.com/FailproofAI/failproofai"
87
+ # PyPI gives "Changelog" its own sidebar slot and icon. Without it the only
88
+ # thing a visitor to the project page can read is the README, and there is no
89
+ # route at all from an installed version to what changed in it.
90
+ Changelog = "https://github.com/FailproofAI/failproofai/blob/main/fp-cloud-cli/CHANGELOG.md"
91
+
92
+ [project.optional-dependencies]
93
+ dev = ["pytest>=7", "respx>=0.21"]
94
+
95
+ [tool.setuptools.dynamic]
96
+ version = { attr = "fp_cli._version.__version__" }
97
+
98
+ [tool.setuptools.packages.find]
99
+ where = ["."]
100
+ include = ["fp_cli*"]
101
+
102
+ [tool.setuptools.package-data]
103
+ fp_cli = ["py.typed"]
104
+
105
+ [tool.pytest.ini_options]
106
+ testpaths = ["tests"]