failproofai 1.0.1 → 1.0.2-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (390) 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]__0l4748x._.js +3 -0
  97. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0oa1lav._.js +1 -1
  98. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0p-5p8u._.js +4 -0
  99. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0s740oi._.js +6 -0
  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/_08x1r5t._.js +1 -1
  103. package/.next/standalone/.next/server/chunks/ssr/_0bwu160._.js +23 -0
  104. package/.next/standalone/.next/server/chunks/ssr/{_0u5zauv._.js → _0ns6k3a._.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/{3c808qrfcq0im.js → 01u1cf8js2yd6.js} +1 -1
  121. package/.next/standalone/.next/static/chunks/{0k5050ezjvv49.js → 0izgu7nqh2zp-.js} +1 -1
  122. package/.next/standalone/.next/static/chunks/0u4-org_e7zde.js +1 -0
  123. package/.next/standalone/.next/static/chunks/1mfzsja6ftim5.css +2 -0
  124. package/.next/standalone/.next/static/chunks/{2zpp1we2jv6tb.js → 1tynnrrh711lr.js} +1 -1
  125. package/.next/standalone/.next/static/chunks/{1ide1wl2f7zi1.js → 22rqvlr7p_1mv.js} +13 -13
  126. package/.next/standalone/.next/static/chunks/{31s1smp-g7gks.js → 2whxqyskpirbk.js} +1 -1
  127. package/.next/standalone/.next/static/chunks/31mwk8k0q3_3g.js +6 -0
  128. package/.next/standalone/.next/static/chunks/3ms6gxfm82t6s.js +1 -0
  129. package/.next/standalone/.next/static/chunks/{37fcpc36x9gpe.js → 3tbbs_d8xrvyp.js} +1 -1
  130. package/.next/standalone/.next/static/chunks/43nlc236oo898.js +1 -0
  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 +163 -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 -15
  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 +27 -21
  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 +579 -306
  319. package/dist/cli.mjs +6499 -3662
  320. package/dist/index.js +5 -5
  321. package/dist/worker.mjs +2390 -1978
  322. package/package.json +27 -21
  323. package/scripts/build-policy-pack.mjs +121 -0
  324. package/scripts/changelog-section.py +77 -0
  325. package/scripts/prune-standalone.mjs +3 -0
  326. package/scripts/python-version.py +232 -0
  327. package/scripts/translate-docs/cli.ts +21 -0
  328. package/scripts/translate-docs/mintlify-nav.ts +85 -13
  329. package/scripts/translate-docs/translator.ts +66 -11
  330. package/src/audit/cache.ts +40 -3
  331. package/src/audit/cli.ts +1 -1
  332. package/src/audit/index.ts +1 -1
  333. package/src/audit/replay.ts +89 -3
  334. package/src/audit/report.ts +5 -5
  335. package/src/audit/schedule-cli.ts +49 -53
  336. package/src/hooks/builtin-policies.ts +217 -579
  337. package/src/hooks/cloud-enrollment-cli.ts +66 -27
  338. package/src/hooks/cloud-managed-policies.ts +6 -1
  339. package/src/hooks/configure-wizard.ts +56 -369
  340. package/src/hooks/custom-hooks-loader.ts +89 -6
  341. package/src/hooks/fp-home.ts +92 -4
  342. package/src/hooks/fp-reset.ts +34 -2
  343. package/src/hooks/handler.ts +181 -11
  344. package/src/hooks/harness-cli.ts +79 -25
  345. package/src/hooks/hook-activity-store.ts +13 -3
  346. package/src/hooks/install-prompt.ts +25 -3
  347. package/src/hooks/manager.ts +424 -172
  348. package/src/hooks/migrations.ts +2 -2
  349. package/src/hooks/pack-cli.ts +885 -0
  350. package/src/hooks/pack-failclosed.ts +189 -0
  351. package/src/hooks/pack-manifest.ts +352 -0
  352. package/src/hooks/pack-store.ts +891 -0
  353. package/src/hooks/policy-catalog.ts +535 -0
  354. package/src/hooks/policy-evaluator.ts +24 -16
  355. package/src/hooks/policy-registry.ts +8 -2
  356. package/src/hooks/policy-types.ts +26 -0
  357. package/src/hooks/session-pause-cli.ts +33 -9
  358. package/src/hooks/tui.ts +695 -39
  359. package/src/hooks/types.ts +15 -1
  360. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0_usx0j._.js +0 -3
  361. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0_zk340._.js +0 -3
  362. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0agdw2a._.js +0 -3
  363. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0d1u_na._.js +0 -3
  364. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0oy4kxb._.js +0 -3
  365. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0zf034w._.js +0 -3
  366. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1tvn4wf._.js +0 -3
  367. package/.next/standalone/.next/server/chunks/_0lxbzdq._.js +0 -3
  368. package/.next/standalone/.next/server/chunks/_1ger0a2._.js +0 -3
  369. package/.next/standalone/.next/server/chunks/_1zuiiy3._.js +0 -3
  370. package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_1iiwm5e._.js +0 -3
  371. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__07tbbf3._.js +0 -3
  372. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0kc8_v5._.js +0 -4
  373. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0kgy9da._.js +0 -4
  374. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0mhqk5a._.js +0 -4
  375. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0pltpn8._.js +0 -4
  376. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qkcyf-._.js +0 -4
  377. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0w0x_ok._.js +0 -4
  378. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1_dfocn._.js +0 -4
  379. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1bfex62._.js +0 -5
  380. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1kzapg5._.js +0 -6
  381. package/.next/standalone/.next/server/chunks/ssr/_0lvyuv4._.js +0 -23
  382. package/.next/standalone/.next/static/chunks/2_2lhuojq2xop.js +0 -1
  383. package/.next/standalone/.next/static/chunks/36fw6yk1s6x_f.js +0 -1
  384. package/.next/standalone/.next/static/chunks/3k7mxbp9hiom0.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/src/hooks/policy-presets.ts +0 -135
  388. /package/.next/standalone/.next/static/{ZklXxyA5ygsWSQz2u_zii → I5kEb9kSgYS63j4iqfVLO}/_buildManifest.js +0 -0
  389. /package/.next/standalone/.next/static/{ZklXxyA5ygsWSQz2u_zii → I5kEb9kSgYS63j4iqfVLO}/_clientMiddlewareManifest.js +0 -0
  390. /package/.next/standalone/.next/static/{ZklXxyA5ygsWSQz2u_zii → I5kEb9kSgYS63j4iqfVLO}/_ssgManifest.js +0 -0
@@ -6,7 +6,7 @@
6
6
  * 0. Daemon — REQUIRED. Asks for sudo first, on a clean terminal.
7
7
  * 1. Where — inferred from cwd, then confirmed (global / project / both)
8
8
  * 2. Policies — multi-select of themed presets (combine any) or Everything
9
- * 3. Assistants— multi-select of agent CLIs (detected + install-ahead)
9
+ * 3. Assistants— multi-select of agent harnesses (detected + install-ahead)
10
10
  * 4. Connect — paste an API key, or stay fully local
11
11
  * 5. Review — shows exactly which files change, then Apply.
12
12
  *
@@ -33,7 +33,6 @@ import { dirname, resolve, sep } from "node:path";
33
33
  import {
34
34
  selectOne,
35
35
  multiSelect,
36
- BACK,
37
36
  promptText,
38
37
  intro,
39
38
  outro,
@@ -54,8 +53,7 @@ import {
54
53
  } from "./integrations";
55
54
  import { INTEGRATION_TYPES, type IntegrationType, type HookScope } from "./types";
56
55
  import { installHooks } from "./manager";
57
- import { getConfigPathForScope, readHooksConfig, readScopedHooksConfig } from "./hooks-config";
58
- import { POLICY_PRESETS, resolvePreset, resolveEverything, RECOMMENDED_POLICIES } from "./policy-presets";
56
+ import { getConfigPathForScope, readScopedHooksConfig } from "./hooks-config";
59
57
  import { discoverPolicyFiles, findSkippedPolicyFiles } from "./custom-hooks-loader";
60
58
  import { trackHookEvent } from "./hook-telemetry";
61
59
  import { getInstanceId } from "../../lib/telemetry-id";
@@ -226,175 +224,7 @@ export function buildAgentChoices(scope: HookScope, cwd: string): MultiChoice<In
226
224
  });
227
225
  }
228
226
 
229
- const EVERYTHING = "__everything__";
230
227
  const ALL_CLIS = "__all_clis__";
231
- /** Sentinel for the locked "Custom" row — informational, never resolves to
232
- * builtin policy names (custom policies load by convention, not by config). */
233
- const CUSTOM = "__custom__";
234
- /**
235
- * Sentinel for the locked "enabled individually" row.
236
- *
237
- * Policies enabled one at a time (`failproofai policies add <name>`) need not map
238
- * onto any preset, so seeding the preset boxes cannot represent them. The wizard
239
- * writes with `replace: true`, which makes the ticked set the WHOLE enabled set —
240
- * so anything this row stands for must be unioned back in, or confirming the
241
- * wizard would silently drop it. Locked and pre-checked, because it reports a
242
- * state rather than offering a choice.
243
- */
244
- const INDIVIDUAL = "__individual__";
245
-
246
- /**
247
- * Split what is enabled now into the bundles that cover it and the leftovers.
248
- *
249
- * A pure function, and the SINGLE definition of that split — `buildPresetChoices`
250
- * renders it and the wizard writes from it, so the row the user sees and the set
251
- * that gets written can never disagree. The first version of this derived the
252
- * leftovers by parsing them back out of the row's hint text, which coupled a
253
- * display string to enforcement behaviour and would have broken on any policy
254
- * name containing the separator.
255
- */
256
- export function splitEnabled(currentlyEnabled: readonly string[] = []): {
257
- /** Preset ids (or `EVERYTHING`) whose policies are all already enabled. */
258
- presets: string[];
259
- /** Enabled policies no ticked bundle accounts for. */
260
- individual: string[];
261
- } {
262
- const current = new Set(currentlyEnabled);
263
- // A bundle is ticked when everything it turns on is already on. Not "any", or
264
- // one shared policy would tick every bundle containing it and confirming would
265
- // enable all of them.
266
- const isOn = (policies: string[]) =>
267
- policies.length > 0 && policies.every((name) => current.has(name));
268
-
269
- const everything = resolveEverything();
270
- const presets = isOn(everything)
271
- ? [EVERYTHING]
272
- : POLICY_PRESETS.filter((p) => isOn(resolvePreset(p.id))).map((p) => p.id);
273
-
274
- // Against the TICKED bundles, not all of them: a policy belonging only to a
275
- // bundle the user has NOT enabled is still enabled, and that is the fact the
276
- // locked row exists to make visible.
277
- const accounted = new Set(
278
- presets.flatMap((id) => (id === EVERYTHING ? everything : resolvePreset(id))),
279
- );
280
- const individual = [...current].filter((name) => !accounted.has(name)).sort();
281
- return { presets, individual };
282
- }
283
-
284
- /** The themed preset bundles for the wizard's multi-select, plus an "Everything"
285
- * option that enables the full builtin policy set. */
286
- export function buildPresetChoices(
287
- cwd: string = process.cwd(),
288
- enabled = true,
289
- /**
290
- * What is enabled at this scope RIGHT NOW, used to tick the boxes.
291
- *
292
- * Without it every row rendered unticked on every run while the wizard wrote
293
- * with `replace: true` — so re-running setup showed a blank slate and then made
294
- * that blank slate authoritative, discarding the user's selection with nothing
295
- * on screen to say it had happened. The comment on the Custom row below has
296
- * always described the intended behaviour ("shows the current state rather than
297
- * resetting it every run"); it was implemented for that one row out of eight.
298
- *
299
- * Optional so the first-run call sites stay unchanged: an empty set ticks
300
- * nothing, which is the correct rendering for a machine with no selection.
301
- */
302
- currentlyEnabled: readonly string[] = [],
303
- ) {
304
- const { presets: onPresets, individual } = splitEnabled(currentlyEnabled);
305
- const on = new Set(onPresets);
306
-
307
- const choices: MultiChoice<string>[] = POLICY_PRESETS.map((p) => ({
308
- label: p.label,
309
- value: p.id,
310
- hint: p.description,
311
- checked: on.has(p.id),
312
- }));
313
- choices.push({
314
- label: "Everything",
315
- value: EVERYTHING,
316
- hint: `all ${resolveEverything().length} policies`,
317
- checked: on.has(EVERYTHING),
318
- });
319
-
320
- // The Custom row is ALWAYS present, because it is the only place the feature
321
- // is discoverable: a user who has never written a policy cannot learn the
322
- // capability exists, and one who wrote a badly-named file cannot learn why
323
- // nothing happened.
324
- //
325
- // When there are loadable files it is a REAL checkbox — unticking writes
326
- // `customPoliciesEnabled: false`, which switches convention discovery off
327
- // without renaming or deleting anything. With nothing to toggle (no files,
328
- // or only skipped ones) it falls back to a locked status row.
329
- const custom = describeCustomPolicies(cwd);
330
- const skipped = custom.warnings.length;
331
- const plural = (n: number) => `${n} file${n === 1 ? "" : "s"}`;
332
- const skippedNote = skipped > 0 ? ` · ${skipped} skipped, see next screen` : "";
333
-
334
- if (custom.fileCount > 0) {
335
- choices.push({
336
- label: "Custom",
337
- value: CUSTOM,
338
- checked: enabled,
339
- // Deliberately NOT summaryExclude'd: this one is a real choice, and the
340
- // step summary is the only place the user sees what they picked. Hiding
341
- // it meant unticking Custom and every bundle showed "none", giving no
342
- // way to tell the toggle had registered.
343
- hint: `${plural(custom.fileCount)} in ${custom.scopes.join(" + ")}${skippedNote}`,
344
- });
345
- } else {
346
- choices.push({
347
- label: "Custom",
348
- value: CUSTOM,
349
- locked: true,
350
- checked: false,
351
- summaryExclude: true,
352
- hint:
353
- skipped > 0
354
- ? `${plural(skipped)} found but NOT loaded — see next screen`
355
- : "none yet · drop *-policies.mjs in .failproofai/policies/",
356
- });
357
- }
358
- if (individual.length > 0) {
359
- choices.push({
360
- label: `${individual.length} enabled individually`,
361
- value: INDIVIDUAL,
362
- locked: true,
363
- hint: `kept as-is · ${individual.join(", ")}`,
364
- // Not one of the bundles being counted, like the Everything and Custom rows.
365
- summaryExclude: true,
366
- });
367
- }
368
- return choices;
369
- }
370
-
371
-
372
- /**
373
- * Resolve the ticked options to a concrete policy set. Presets are additive —
374
- * the deduped union of every selected preset's policies — while "Everything"
375
- * enables the full policy set and wins over any presets.
376
- */
377
- export function resolvePresetSelection(
378
- values: string[],
379
- /**
380
- * What the locked "enabled individually" row stands for. Unioned in whenever
381
- * that row is present, INCLUDING under "Everything": `resolveEverything()`
382
- * covers the non-beta builtins only, so a beta policy someone enabled by hand
383
- * would otherwise be dropped by the very branch meant to enable everything.
384
- */
385
- individual: readonly string[] = [],
386
- ): string[] {
387
- // The Custom row is informational — custom policies are discovered from disk
388
- // by the loader, never named in the enabled-policies config — so it must not
389
- // reach resolvePreset(), which only knows builtin bundle ids. Same for the
390
- // locked individually-enabled row, which carries its policies in `individual`.
391
- const selected = values.filter((v) => v !== CUSTOM && v !== INDIVIDUAL);
392
- const carried = values.includes(INDIVIDUAL) ? individual : [];
393
- if (selected.includes(EVERYTHING)) {
394
- return [...new Set([...resolveEverything(), ...carried])];
395
- }
396
- return [...new Set([...selected.flatMap((id) => resolvePreset(id)), ...carried])];
397
- }
398
228
 
399
229
  const DIM_NOTE = "(auto-loaded)";
400
230
 
@@ -528,15 +358,6 @@ export function buildCompletionSummary(
528
358
  customEnabled: boolean | undefined,
529
359
  daemonInstalled: boolean,
530
360
  connected: boolean,
531
- /**
532
- * What was ticked on the policy step, so the summary can NAME the bundles.
533
- *
534
- * "9 policies" is a number the user cannot check and did not choose — they
535
- * picked two named bundles two screens earlier, and the line that confirms
536
- * their setup should say which. Optional so the existing callers and tests
537
- * that only have a count keep working and keep the old wording.
538
- */
539
- presetValues?: readonly string[],
540
361
  ): string {
541
362
  const extras: string[] = [];
542
363
  if (customEnabled === true) extras.push("custom");
@@ -554,9 +375,7 @@ export function buildCompletionSummary(
554
375
  // full line will not fit, which is checked rather than guessed at: the extras
555
376
  // clause grows too ("custom, daemon, reporting" is 25 characters), so a names
556
377
  // budget alone was wrong for exactly the combinations that need it most.
557
- const named = line(describeSelection(policiesCount, presetValues));
558
- if (named.length <= MAX_SUMMARY_COLUMNS) return named;
559
- return line(describeSelection(policiesCount, undefined));
378
+ return line(describeSelection(policiesCount));
560
379
  }
561
380
 
562
381
  /**
@@ -603,43 +422,13 @@ export function policyNamesLine(names: string[]): string[] {
603
422
  return [];
604
423
  }
605
424
 
606
- /**
607
- * Name the bundles rather than counting the policies inside them.
608
- *
609
- * BOUNDED AT TWO NAMES ON PURPOSE. `writeLines` truncates with a hard cut and no
610
- * ellipsis, so an over-long line does not lose its tail, it reads as broken
611
- * output — the same constraint that stopped this summary naming all twelve CLIs.
612
- * All four bundle labels joined is 57 characters, which with the prefix, the
613
- * harness clause and the extras clause runs to about 106. Two names plus a count
614
- * of the rest stays inside 80 for every combination, and two is also the common
615
- * case, so most runs see every name.
616
- *
617
- * Falls back to the old "N policies" when nothing maps to a bundle — a machine
618
- * whose policies were all enabled one at a time with `policies add` has no bundle
619
- * to name, and inventing one would be worse than the count.
620
- */
621
- function describeSelection(policiesCount: number, presetValues?: readonly string[]): string {
622
- const plural = `${policiesCount} polic${policiesCount === 1 ? "y" : "ies"}`;
623
- if (!presetValues) return plural;
624
-
625
- // "Everything" is one name for the whole set, and the count is the useful half
626
- // of it — "Everything" alone does not say how much that is.
627
- if (presetValues.includes(EVERYTHING)) return `Everything (${plural})`;
628
-
629
- const named = POLICY_PRESETS.filter((p) => presetValues.includes(p.id)).map((p) => p.label);
630
- // The locked "enabled individually" row stands for policies outside every
631
- // bundle, so it is counted among the unnamed rest rather than named.
632
- const individual = presetValues.includes(INDIVIDUAL) ? 1 : 0;
633
- if (named.length === 0) return plural;
634
-
635
- const shown = named.slice(0, 2);
636
- const rest = named.length - shown.length + individual;
637
- // `+N` rather than `+N more`: five characters, and they decide whether the
638
- // mixed case (two bundles plus a policy added by hand) gets named at all — with
639
- // "more" the line is 83 and falls back to a bare count.
640
- return rest > 0 ? `${shown.join(", ")} +${rest}` : shown.join(", ");
425
+ /** The Policies line's value. With policies no longer chosen during setup, this
426
+ * reports what is enabled and nothing about how it got that way. */
427
+ function describeSelection(policiesCount: number): string {
428
+ return `${policiesCount} ${policiesCount === 1 ? "policy" : "policies"}`;
641
429
  }
642
430
 
431
+
643
432
  export function reviewLines(state: {
644
433
  /** What the scope step resolved to. Expands to one or two real scopes. */
645
434
  target: SetupTarget;
@@ -1128,13 +917,13 @@ export async function runConfigureWizard(io: WizardIO = {}): Promise<WizardResul
1128
917
  label: "Recommended",
1129
918
  value: "recommended",
1130
919
  hint: recommendedClis.length
1131
- ? `${recommendedClis.length} detected ${recommendedClis.length === 1 ? "CLI" : "CLIs"} · ${RECOMMENDED_POLICIES.length} policies · global`
1132
- : `${RECOMMENDED_POLICIES.length} policies · global`,
920
+ ? `${recommendedClis.length} detected ${recommendedClis.length === 1 ? "CLI" : "CLIs"} · global`
921
+ : "global",
1133
922
  },
1134
923
  {
1135
924
  label: "Customize",
1136
925
  value: "customize",
1137
- hint: "choose scope, policies and harnesses",
926
+ hint: "choose scope and harnesses",
1138
927
  },
1139
928
  ],
1140
929
  stdin,
@@ -1186,165 +975,65 @@ export async function runConfigureWizard(io: WizardIO = {}): Promise<WizardResul
1186
975
  // merge time, which is exactly the layering the policy loader already does.
1187
976
  const primaryScope: HookScope = scopes.includes("project") ? "project" : "user";
1188
977
 
1189
- // 2 — Which policies? Multi-select of themed presets — additive, so the
1190
- // enabled set is the union of every ticked bundle.
1191
- //
1192
- // Before the assistants step, because "what do you want guarded" is the
1193
- // question the user came here to answer; which CLIs to wire it into is
1194
- // plumbing that follows from it.
978
+ // 2 — Which harnesses?
1195
979
  //
1196
- // Seed the Custom checkbox AND the bundle boxes from whatever the config already
1197
- // says, so the wizard shows the current state rather than resetting it every run.
980
+ // Setup no longer asks which policies to enable, and that is deliberate.
981
+ // failproofai ships no policies of its own any more: they arrive as packs —
982
+ // from inside this package (`pack add core`) or from anyone's GitHub release.
983
+ // A wizard that pre-ticks OUR list makes a product decision on behalf of
984
+ // somebody who has not seen the list yet, and not everyone wants the set we
985
+ // would have chosen. So setup wires the hooks, and choosing what they
986
+ // enforce is a separate act, taken later and on purpose.
1198
987
  //
1199
- // Read at the scope this run will WRITE to, not the merged view. `installHooks`
1200
- // is called with `replace: true` per scope, so seeding from the merge would tick
1201
- // a bundle because it is enabled at PROJECT scope and then write it into USER
1202
- // scope — copying a selection between scopes as a side effect of opening the
1203
- // wizard. `readHooksConfig()` stays for the custom flag, which is read the same
1204
- // merged way everywhere else.
1205
- const customEnabledBefore = readHooksConfig().customPoliciesEnabled !== false;
988
+ // Whatever is already enabled at THIS scope is read and carried through
989
+ // untouched. `installHooks` is called with `replace: true`, so passing
990
+ // anything less would switch OFF policies the user had turned on — running
991
+ // setup a second time must never reduce protection.
1206
992
  const enabledHere = readScopedHooksConfig(primaryScope, cwd).enabledPolicies ?? [];
1207
- const presetChoices = buildPresetChoices(cwd, customEnabledBefore, enabledHere);
1208
- // The policies no ticked bundle accounts for. Derived from the SAME pure split
1209
- // the rows are built from, so the locked row and the written set agree.
1210
- const carriedIndividual = splitEnabled(enabledHere).individual;
1211
- const hasCustomFiles = describeCustomPolicies(cwd).fileCount > 0;
1212
-
1213
- // No minimum. Ticking nothing is a real answer — someone who only wants their
1214
- // own custom policies, or who intends to pick bundles later from the
1215
- // dashboard, was previously stuck on this step with no way forward and no
1216
- // explanation beyond "Select at least 1". An empty set is already supported
1217
- // end to end: `installHooksImpl` documents its explicit-array path as "may be
1218
- // empty", `replace: true` makes it the full enabled set, and `summarize([])`
1219
- // renders "none". Hooks still install, so enforcement can be switched on
1220
- // later without re-running setup.
1221
- //
1222
- // The assistants step below keeps its minimum deliberately: an empty CLI list
1223
- // does NOT mean "no assistants" there — `installHooksImpl` falls back to
1224
- // ["claude"], so letting it through would silently install for Claude.
1225
- // Steps 2 and 3 are navigable: ← on the harness step returns to the policy
1226
- // step with the previous answer still selected. Before this, changing an
1227
- // earlier answer meant abandoning setup and starting over, because a prompt
1228
- // had exactly one way out and it was `null`.
993
+ const policies = enabledHere;
994
+
995
+ // Left alone, in both modes. This was a checkbox on the policy step, which is
996
+ // gone; with no row to read, the only honest value is "do not touch it".
997
+ // Writing `false` here switched off every convention policy on disk as a side
998
+ // effect of finishing setup.
999
+ const customEnabled: boolean | undefined = undefined;
1000
+
1001
+ // An "Everything available" row protects every supported CLI (detected +
1002
+ // set-up-ahead); when ticked it wins over the individual boxes.
1229
1003
  //
1230
- // The policy step itself takes no `allowBack`: the only thing before it is
1231
- // the scope question, which is frequently not asked at all (a single choice
1232
- // is stated, not prompted), so ← there would sometimes go nowhere.
1233
- let presets: string[] | null = null;
1234
- let clisSel: string[] | null = null;
1235
- /**
1236
- * What the harness step had ticked when ← was last pressed.
1237
- *
1238
- * A SEPARATE variable, because `clisSel` cannot do this job: it is the loop's
1239
- * own condition (`while (clisSel === null)`), so it is null on every entry into
1240
- * the body by definition, and it is assigned only on the line that ends the
1241
- * loop. The restore that read `clisSel` was therefore unreachable — provably
1242
- * dead, with a comment stating the opposite intent.
1243
- *
1244
- * The cost was not cosmetic: deselect a CLI, press ← to fix an earlier answer,
1245
- * come back, and the step showed the detected defaults again. Pressing ↵ then —
1246
- * reasonably, having been told the selection was carried back — re-enabled hook
1247
- * installation for a CLI the user had explicitly turned off.
1248
- *
1249
- * `presets` just above works because it is assigned MID-loop and survives to the
1250
- * next iteration; this mirrors that, filled from the prompt's `onBack`.
1251
- */
1252
- const carried: { clis: string[] | null } = { clis: null };
1253
- // The recommended path answers both questions here, which is what SKIPS the
1254
- // loop below — its condition is `clisSel === null` and this fills it in.
1255
- // Written as a pre-fill rather than as an extra clause on the loop condition
1256
- // so the invariant the rest of the function depends on ("past this loop, both
1257
- // are assigned") stays provable by the compiler rather than by argument.
1004
+ // No `allowBack`: with the policy step gone there is nothing before this
1005
+ // inside setup to return to — the scope question is frequently not asked at
1006
+ // all (a single choice is stated, not prompted), so a ← here would sometimes
1007
+ // go nowhere. That also retires the loop this step used to sit in, and the
1008
+ // carried-selection machinery the loop needed.
1009
+ let clisSel: string[];
1258
1010
  if (mode === "recommended") {
1259
- presets = [];
1260
1011
  clisSel = recommendedClis;
1261
- }
1262
- while (clisSel === null) {
1263
- // Re-entering after a ← must show what was picked, not a blank slate.
1264
- // Selection state lives on each choice, so carry it back in.
1265
- // Loop-carried: narrowed to `null` on the first pass, repopulated on a ←.
1266
- const priorPresets = presets as string[] | null;
1267
- presets = await multiSelect<string>({
1268
- message: "What should we guard against?",
1269
- choices: priorPresets
1270
- ? presetChoices.map((c) => ({ ...c, checked: priorPresets.includes(c.value) }))
1271
- : presetChoices,
1272
- summaryNoun: "bundles",
1273
- hint: "space toggles · combine presets · ↵ confirm · none is fine",
1274
- stdin,
1275
- stdout,
1276
- });
1277
- if (presets === null) return cancel();
1278
-
1279
- // 3 — Which harnesses? An "Everything available" row protects every supported
1280
- // CLI (detected + set-up-ahead); when ticked it wins over the individual boxes.
1281
- // Read off a HOLDER OBJECT, not a bare `let`, and not through a cast.
1282
- //
1283
- // A `let` assigned only inside a callback is narrowed by control-flow analysis
1284
- // to its initializer, so `priorClis.includes` will not compile — and the
1285
- // original defeated that with `clisSel as string[] | null`. That cast is
1286
- // precisely why the dead code type-checked and nobody noticed: it silenced the
1287
- // compiler making exactly the point the reviewer later made by hand, that the
1288
- // value could only ever be null. A property read carries the declared type
1289
- // without suppressing anything.
1290
- const priorClis = carried.clis;
1291
- const picked: string[] | typeof BACK | null = await multiSelect<string>({
1292
- message: "Which harnesses should it protect?",
1293
- choices: [
1294
- {
1295
- label: "Everything available",
1296
- value: ALL_CLIS,
1297
- // Counts only what this scope can actually take — expanding to all 12
1298
- // under project scope is what crashed the apply on Hermes.
1299
- hint: `protect all ${clisSupportingScope(primaryScope).length} CLIs configurable here`,
1300
- // A selector, not a harness. Counting it gave "13 harnesses" for
1301
- // the 12 supported CLIs, and listed "Everything available" among them.
1302
- summaryExclude: true,
1303
- },
1304
- ...buildAgentChoices(primaryScope, cwd),
1305
- ].map((c) => (priorClis ? { ...c, checked: priorClis.includes(c.value) } : c)),
1012
+ } else {
1013
+ const picked = await multiSelect<string>({
1014
+ message: "Which harnesses should it protect?",
1015
+ choices: [
1016
+ {
1017
+ label: "Everything available",
1018
+ value: ALL_CLIS,
1019
+ // Counts only what this scope can actually take — expanding to all 12
1020
+ // under project scope is what crashed the apply on Hermes.
1021
+ hint: `protect all ${clisSupportingScope(primaryScope).length} CLIs configurable here`,
1022
+ // A selector, not a harness. Counting it gave "13 harnesses" for
1023
+ // the 12 supported CLIs, and listed "Everything available" among them.
1024
+ summaryExclude: true,
1025
+ },
1026
+ ...buildAgentChoices(primaryScope, cwd),
1027
+ ],
1306
1028
  minSelected: 1,
1307
1029
  summaryNoun: "harnesses",
1308
- hint: "detected CLIs are pre-selected · space toggles · ctrl+a all · ← back · ↵ confirm",
1309
- allowBack: true as const,
1310
- // `BACK` is a symbol and cannot carry the selection, so the prompt reports
1311
- // it here instead — otherwise a ← discards what the user had ticked and the
1312
- // next pass redraws the detected defaults.
1313
- onBack: (checkedNow) => {
1314
- carried.clis = checkedNow;
1315
- },
1030
+ hint: "detected CLIs are pre-selected · space toggles · ctrl+a all · ↵ confirm",
1316
1031
  stdin,
1317
1032
  stdout,
1318
1033
  });
1319
1034
  if (picked === null) return cancel();
1320
- // ← re-runs the loop, which re-asks the policy step with its answer intact.
1321
- if (picked === BACK) continue;
1322
1035
  clisSel = picked;
1323
1036
  }
1324
- // Non-null by construction: the loop only exits once both are assigned, and
1325
- // the recommended path assigned both before it, which is why it never ran.
1326
- const chosenPresets: string[] = presets ?? [];
1327
- const policies =
1328
- mode === "recommended"
1329
- ? // UNION with what is already enabled here, never a replacement for it.
1330
- // `installHooks` is called with `replace: true`, so writing the bare
1331
- // recommended list would silently switch OFF anything the user had
1332
- // added themselves — turning "give me the sensible defaults" into a
1333
- // reduction in protection, which is the one direction this must never
1334
- // move. On a fresh machine `enabledHere` is empty and this is exactly
1335
- // the 15.
1336
- [...new Set([...RECOMMENDED_POLICIES, ...enabledHere])]
1337
- : resolvePresetSelection(chosenPresets, carriedIndividual);
1338
- // Only meaningful when there are files to switch off; with none, the row is
1339
- // locked-unchecked and must not write a disabling flag.
1340
- //
1341
- // `undefined` on the recommended path, which means "leave the flag alone".
1342
- // The customize expression would read as `false` here — no bundle was ticked,
1343
- // so `chosenPresets.includes(CUSTOM)` is false — and would write
1344
- // `customPoliciesEnabled: false`, disabling every convention policy the user
1345
- // has on disk as a side effect of choosing the default setup.
1346
- const customEnabled =
1347
- mode === "recommended" ? undefined : hasCustomFiles ? chosenPresets.includes(CUSTOM) : undefined;
1348
1037
  // Filter to what the chosen scopes support in BOTH branches: "Everything
1349
1038
  // available" must not expand to CLIs that cannot take any selected scope,
1350
1039
  // and a locked row can't be ticked but belt-and-braces keeps the invariant
@@ -1764,7 +1453,6 @@ export async function runConfigureWizard(io: WizardIO = {}): Promise<WizardResul
1764
1453
  cli: clis,
1765
1454
  cli_count: clis.length,
1766
1455
  policy_count: policies.length,
1767
- source: chosenPresets.join("+"),
1768
1456
  connected: connect !== null,
1769
1457
  });
1770
1458
 
@@ -1867,7 +1555,6 @@ export async function runConfigureWizard(io: WizardIO = {}): Promise<WizardResul
1867
1555
  customEnabled,
1868
1556
  daemonInstalled,
1869
1557
  connected,
1870
- chosenPresets,
1871
1558
  ),
1872
1559
  { ok: true },
1873
1560
  stdout,