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
@@ -31,6 +31,7 @@ import { trackHookEvent } from "./hook-telemetry";
31
31
  import { getInstanceId } from "../../lib/telemetry-id";
32
32
  import type { CustomHook } from "./policy-types";
33
33
  import type { CloudManagedPolicyArtifact } from "./cloud-managed-policies";
34
+ import type { ResolvedPack } from "./pack-manifest";
34
35
  import { customPoliciesDir, shimsDir } from "./fp-home";
35
36
 
36
37
  const LOADING_KEY = "__FAILPROOFAI_LOADING_HOOKS__";
@@ -172,6 +173,11 @@ async function importWithDeadline(fileUrl: string): Promise<void> {
172
173
  * Load a single policy file into the globalThis custom hooks registry.
173
174
  * Does NOT clear the registry — caller is responsible for that.
174
175
  */
176
+ export interface PolicyLoadFailure {
177
+ type: "module_not_found" | "syntax_error" | "load_timeout" | "runtime_error" | "path_missing";
178
+ reason: string;
179
+ }
180
+
175
181
  async function loadSingleFile(
176
182
  absPath: string,
177
183
  opts?: {
@@ -180,7 +186,7 @@ async function loadSingleFile(
180
186
  /** Cloud-managed policies pass their pinned digest for load-time re-verification. */
181
187
  verifyEntrySha?: string;
182
188
  },
183
- ): Promise<void> {
189
+ ): Promise<PolicyLoadFailure | null> {
184
190
  const g = globalThis as Record<string, unknown>;
185
191
  g[LOADING_KEY] = true;
186
192
 
@@ -208,7 +214,7 @@ async function loadSingleFile(
208
214
  const cached = policyModuleCache.get(absPath);
209
215
  if (cached?.fingerprint === fingerprint) {
210
216
  for (const hook of cached.hooks) customPolicies.add({ ...hook });
211
- return;
217
+ return null;
212
218
  }
213
219
 
214
220
  const entryTmp = absPath + tmpSuffix;
@@ -222,6 +228,7 @@ async function loadSingleFile(
222
228
  .slice(hooksBefore)
223
229
  .map((hook) => ({ ...hook })),
224
230
  });
231
+ return null;
225
232
  } catch (err) {
226
233
  const msg = err instanceof Error ? err.message : String(err);
227
234
  const errorType = /Cannot find module|MODULE_NOT_FOUND|ENOENT/i.test(msg)
@@ -239,6 +246,7 @@ async function loadSingleFile(
239
246
  });
240
247
  if (opts?.strict) throw new Error(`Failed to load custom hooks from ${absPath}: ${msg}`);
241
248
  hookLogError(`failed to load custom hooks from ${absPath}: ${msg}`);
249
+ return { type: errorType, reason: msg };
242
250
  } finally {
243
251
  g[LOADING_KEY] = false;
244
252
  await cleanupTmpFiles(tmpFiles);
@@ -293,6 +301,8 @@ export interface ConventionSource {
293
301
  export interface LoadAllResult {
294
302
  hooks: CustomHook[];
295
303
  conventionSources: ConventionSource[];
304
+ /** Import failures keyed by pack id, including artifacts that registered no hooks. */
305
+ packFailures: Map<string, PolicyLoadFailure>;
296
306
  }
297
307
 
298
308
  export function customPolicyId(file: string, name: string): string {
@@ -330,17 +340,53 @@ function warnSkippedPolicyFiles(dir: string, scope: "project" | "user"): void {
330
340
  );
331
341
  }
332
342
 
343
+ /**
344
+ * A pack's manifest declares what it contains; its artifact decides what runs.
345
+ * Nothing binds the two, so they can disagree — and the disagreement is silent
346
+ * in both directions and worse in one.
347
+ *
348
+ * A policy the artifact registers but the manifest omits is enforcement that no
349
+ * `failproofai policies` listing will ever show. A policy the manifest declares
350
+ * but the artifact never registers is the dangerous one: the listing says the
351
+ * machine is protected against something nothing is checking.
352
+ *
353
+ * Both are announced rather than corrected. The artifact is digest-pinned, so
354
+ * what it registers IS what the publisher shipped and dropping any of it would
355
+ * be inventing a third answer; the manifest is what needs fixing, upstream.
356
+ */
357
+ function reconcilePackManifest(pack: ResolvedPack | undefined, loaded: CustomHook[]): void {
358
+ if (!pack || pack.policies.length === 0) return;
359
+ const declared = new Set(pack.policies.map((p) => p.name));
360
+ const registered = new Set(loaded.map((h) => h.name));
361
+ const missing = [...declared].filter((n) => !registered.has(n));
362
+ const extra = [...registered].filter((n) => !declared.has(n));
363
+ if (missing.length > 0) {
364
+ hookLogWarn(
365
+ `pack ${pack.id}@${pack.version} declares ${missing.join(", ")} but its artifact does not ` +
366
+ `register ${missing.length === 1 ? "it" : "them"} — listed as protection that never runs`,
367
+ );
368
+ }
369
+ if (extra.length > 0) {
370
+ hookLogWarn(
371
+ `pack ${pack.id}@${pack.version} registers undeclared ${extra.join(", ")} — ` +
372
+ `${extra.length === 1 ? "it enforces" : "they enforce"} but will not appear in listings`,
373
+ );
374
+ }
375
+ }
376
+
333
377
  export async function loadAllCustomHooks(
334
378
  customPoliciesPaths: string | string[] | undefined,
335
379
  opts?: {
336
380
  sessionCwd?: string;
337
381
  customPoliciesEnabled?: boolean;
338
382
  cloudManagedPolicies?: CloudManagedPolicyArtifact[];
383
+ packs?: ResolvedPack[];
339
384
  },
340
385
  ): Promise<LoadAllResult> {
341
386
  clearCustomHooks();
342
387
 
343
388
  const conventionSources: ConventionSource[] = [];
389
+ const packFailures = new Map<string, PolicyLoadFailure>();
344
390
 
345
391
  const projectRoot = findProjectConfigDir(opts?.sessionCwd ?? process.cwd());
346
392
 
@@ -395,6 +441,30 @@ export async function loadAllCustomHooks(
395
441
  }
396
442
  }
397
443
 
444
+ // Installed packs, keyed by artifact path — the same content-addressing, and
445
+ // therefore the same collision, as the cloud map above: two packs whose entry
446
+ // file is byte-identical resolve to ONE artifact, `loadedPaths` imports it
447
+ // once, and the loser would vanish silently with its effect deciding nothing.
448
+ // Resolved the same way and for the same reason — toward ENFORCEMENT, because
449
+ // over-enforcing is visible to whoever hits it and under-enforcing is the
450
+ // silent failure — and announced, so an operator can act on it.
451
+ const packByPath = new Map<string, ResolvedPack>();
452
+ for (const pack of opts?.packs ?? []) {
453
+ const key = resolve(pack.path);
454
+ const existing = packByPath.get(key);
455
+ if (!existing) {
456
+ packByPath.set(key, pack);
457
+ continue;
458
+ }
459
+ hookLogWarn(
460
+ `packs ${existing.id} and ${pack.id} have identical source, so they share one artifact ` +
461
+ `and load as one pack; enforcing it if either asks to enforce`,
462
+ );
463
+ if (existing.effect !== "enforce" && pack.effect === "enforce") {
464
+ packByPath.set(key, pack);
465
+ }
466
+ }
467
+
398
468
  // 1. Explicit custom policy paths. Accept a string for callers/configs using
399
469
  // the legacy singular form.
400
470
  for (const customPoliciesPath of typeof customPoliciesPaths === "string"
@@ -403,31 +473,44 @@ export async function loadAllCustomHooks(
403
473
  // resolve() also normalizes absolute paths, so aliases containing `.` or
404
474
  // `..` share a dedup key with convention-discovered canonical paths.
405
475
  const absPath = resolve(projectRoot, customPoliciesPath);
476
+ const cloudManaged = cloudManagedByPath.get(absPath);
477
+ const pack = packByPath.get(absPath);
406
478
  if (existsSync(absPath)) {
407
479
  if (!loadedPaths.has(absPath)) {
408
480
  loadedPaths.add(absPath);
409
481
  const hooksBefore = getCustomHooks().length;
410
482
  // A cloud-managed policy re-verifies its pinned digest at load, binding
411
483
  // the imported bytes to what desired-state promised.
412
- await loadSingleFile(absPath, {
413
- verifyEntrySha: cloudManagedByPath.get(absPath)?.sha256,
484
+ // A pack re-verifies its pinned digest at load for the same reason a
485
+ // cloud policy does: the manifest read and the import are two moments,
486
+ // and only this one binds the bytes actually executed to what was
487
+ // promised.
488
+ const failure = await loadSingleFile(absPath, {
489
+ verifyEntrySha:
490
+ cloudManaged?.sha256 ?? pack?.sha256,
414
491
  });
492
+ if (failure && pack) packFailures.set(pack.id, failure);
415
493
  for (const hook of getCustomHooks().slice(hooksBefore)) {
416
- const cloudManaged = cloudManagedByPath.get(absPath);
417
494
  const tagged = hook as CustomHook & {
418
495
  __policyId?: string;
419
496
  __cloudManaged?: CloudManagedPolicyArtifact;
497
+ __pack?: ResolvedPack;
420
498
  };
421
499
  if (cloudManaged) {
422
500
  tagged.__cloudManaged = cloudManaged;
423
501
  tagged.__policyId = `cloud:${cloudManaged.id}@${cloudManaged.version}:${hook.name}`;
502
+ } else if (pack) {
503
+ tagged.__pack = pack;
504
+ tagged.__policyId = `pack:${pack.id}@${pack.version}:${hook.name}`;
424
505
  } else {
425
506
  tagged.__policyId = customPolicyId(absPath, hook.name);
426
507
  }
427
508
  }
509
+ reconcilePackManifest(pack, getCustomHooks().slice(hooksBefore));
428
510
  }
429
511
  } else {
430
512
  hookLogWarn(`custom policy path not found: ${absPath}`);
513
+ if (pack) packFailures.set(pack.id, { type: "path_missing", reason: `path missing: ${absPath}` });
431
514
  }
432
515
  }
433
516
 
@@ -569,5 +652,5 @@ export async function loadAllCustomHooks(
569
652
  }
570
653
  }
571
654
 
572
- return { hooks: allHooks, conventionSources };
655
+ return { hooks: allHooks, conventionSources, packFailures };
573
656
  }
@@ -210,6 +210,26 @@ export const globalPolicyConfigFile = (home?: string) =>
210
210
  */
211
211
  export const cloudPoliciesDir = (home?: string) => resolve(policiesDir(home), "cloud-policies");
212
212
 
213
+ /**
214
+ * Installed policy packs — a sibling of `cloudPoliciesDir` and flat for the same
215
+ * reason: `artifacts/<sha256>.mjs` is content-addressed, so an install can only
216
+ * ever write a file that does not exist yet and is structurally incapable of
217
+ * disturbing what is currently live. `installed.json` names which artifacts are
218
+ * active and is written last, so activation is one atomic flip.
219
+ *
220
+ * Living under `policies/` is safe ONLY because the convention loader does not
221
+ * recurse — `discoverPolicyFiles` and `findSkippedPolicyFiles` both filter on
222
+ * `isFile()`, so nothing under `packs/` can be picked up as an unverified
223
+ * convention policy. `fp-home.test.ts` pins that non-recursion.
224
+ */
225
+ export const packsDir = (home?: string) => resolve(policiesDir(home), "packs");
226
+
227
+ /** The activation pointer. Written last and atomically. */
228
+ export const packsInstalledFile = (home?: string) => resolve(packsDir(home), "installed.json");
229
+
230
+ /** Content-addressed pack artifacts, shared across packs and versions. */
231
+ export const packArtifactsDir = (home?: string) => resolve(packsDir(home), "artifacts");
232
+
213
233
  // ── Collector ────────────────────────────────────────────────────────────────
214
234
 
215
235
  /** Per-source watermarks. One directory per source — never shared: the cursor
@@ -218,7 +238,14 @@ export const cloudPoliciesDir = (home?: string) => resolve(policiesDir(home), "c
218
238
  export const cursorsDir = (source?: string, home?: string) =>
219
239
  source ? resolve(atHome(home, "cursors"), source) : atHome(home, "cursors");
220
240
 
221
- /** The SDK spool root. Mirrors `~/.agenteye/`, which stays supported. */
241
+ /** The SDK spool root, and the ONLY root `failproofai-sdk` writes to.
242
+ *
243
+ * The daemon additionally watches `~/.agenteye/events` (see `spool_dirs` in
244
+ * `crates/fpai-collect/src/config.rs`) so that SDKs old enough to write there,
245
+ * and batches already sitting there, keep being collected. But no current SDK
246
+ * puts anything in it: `$AGENTEYE_HOME` used to redirect the spool and no
247
+ * longer does, precisely so that exporting it for the older
248
+ * `agenteye-collector` cannot relocate the SDK as a side effect. */
222
249
  export const customAgentsDir = (home?: string) => atHome(home, "custom-agents");
223
250
  export const customAgentsEventsDir = (home?: string) => resolve(customAgentsDir(home), "events");
224
251
  export const customAgentsFailedDir = (home?: string) => resolve(customAgentsDir(home), "failed");
@@ -273,6 +300,48 @@ export const auditSessionFile = (home?: string) => resolve(auditDir(home), "sess
273
300
  export const auditMachineFile = (home?: string) => resolve(auditDir(home), "machine.json");
274
301
 
275
302
 
303
+ // ── fp-cloud-cli ───────────────────────────────────────────────────────────────────
304
+
305
+ /**
306
+ * The Cloud CLI's own directory (`fp-cloud-cli` on PyPI, command `fp`).
307
+ *
308
+ * Written by PYTHON, not by anything in this repo's TypeScript or Rust — the
309
+ * CLI resolves it independently in `fp-cloud-cli/fp_cli/config.py`. It is declared
310
+ * here anyway because this file is the register of what may exist in the home,
311
+ * and a path absent from it is only safe by accident: `resettablePaths()` is a
312
+ * filter over `HOME_CLASSES`, so an unregistered directory survives today and
313
+ * survives the next migration only until someone lists its parent.
314
+ *
315
+ * Not classified itself — `auditDir`'s rule applies, classify the children. The
316
+ * directory may grow a cache later; the credential in it must never be dropped.
317
+ */
318
+ export const fpcliDir = (home?: string) => atHome(home, "fpcli");
319
+
320
+ /**
321
+ * The CLI's signed-in session. `0600`, written only by `fp login` / `fp logout`.
322
+ *
323
+ * Was `~/.fp/cli.json` — a third top-level dotfile for one product. The old
324
+ * file is deliberately left where it is: `load_config` in
325
+ * `fp-cloud-cli/fp_cli/config.py` reads it when nothing is here yet, writes the
326
+ * session to this path, and does NOT delete the original, so downgrading to a
327
+ * previous `fp` finds its session intact. Adoption is best-effort — an
328
+ * unwritable home hands back the session it found rather than logging the
329
+ * machine out — and it costs the user no login.
330
+ *
331
+ * This paragraph said the opposite until it was checked against the code: that
332
+ * there was no migration and the upgrade cost a login. There is one, it is
333
+ * covered by `fp-cloud-cli/tests/test_failproofai_home.py`, and the only true half
334
+ * was that the old file survives.
335
+ *
336
+ * `user-typed` for the same reason as `auditSessionFile` beside it: nothing
337
+ * regenerates a session, and dropping it silently signs the machine out.
338
+ *
339
+ * TS-side only, like `auditSessionFile`, and absent from `paths.rs` by design —
340
+ * the daemon has no reason to open a human credential, and mirroring a path
341
+ * only Python writes would give `paths.rs` an entry nothing there reads.
342
+ */
343
+ export const fpcliAuthFile = (home?: string) => resolve(fpcliDir(home), "cli-auth.json");
344
+
276
345
  // ── Hook activity ────────────────────────────────────────────────────────────
277
346
 
278
347
  /** The decision log: page-sized JSONL the dashboard's activity tab reads. */
@@ -469,9 +538,15 @@ export type DataClass =
469
538
  * else under it is scratch. Listing the parent is exactly how a reset came
470
539
  * to delete undelivered events and the machine's own telemetry identity.
471
540
  *
472
- * `home-classification.test.ts` asserts every exported path function in this
473
- * module is either classified here or covered by a classified parent, so the
474
- * next path added to the home cannot skip the one question that matters.
541
+ * `__tests__/hooks/fp-home.test.ts` asserts every exported path function in
542
+ * this module is either classified here or covered by a classified parent, so
543
+ * the next path added to the home cannot skip the one question that matters.
544
+ *
545
+ * It cited `home-classification.test.ts` until that was checked — a file that
546
+ * has never existed. The guard was real and in the wrong place, which is the
547
+ * failure this header already describes happening once before: a citation is
548
+ * only load-bearing if somebody follows it, and the person who does is looking
549
+ * for the rule they are about to break.
475
550
  */
476
551
  export const HOME_CLASSES: readonly { path: (home?: string) => string; class: DataClass }[] = [
477
552
  // ── Never deleted: a person typed it ──
@@ -498,6 +573,11 @@ export const HOME_CLASSES: readonly { path: (home?: string) => string; class: Da
498
573
  // with no notice, and the machine only finds out the next time it tries to
499
574
  // report.
500
575
  { path: auditSessionFile, class: "user-typed" },
576
+ // The Cloud CLI's session, written by Python (`fp-cloud-cli/fp_cli/config.py`). The
577
+ // one entry here whose writer is outside this repo's TS and Rust, which is
578
+ // exactly why it needs listing: nothing in a migration would otherwise know a
579
+ // credential lives under `fpcli/`.
580
+ { path: fpcliAuthFile, class: "user-typed" },
501
581
 
502
582
  // ── Never deleted: recorded and not yet shipped ──
503
583
  // Batches read out of transcripts and queued for upload. The reason losing
@@ -574,6 +654,14 @@ export const HOME_CLASSES: readonly { path: (home?: string) => string; class: Da
574
654
  // directory holds both the files a person wrote and the ones the fleet sent,
575
655
  // and only the second kind may be thrown away.
576
656
  { path: cloudPoliciesDir, class: "refetchable" },
657
+ // Installed packs. Third-party packs are re-fetchable by `failproofai pack
658
+ // add`; the bundled default pack is restored from the package immediately
659
+ // after reset. So this is the fleet's argument again: one directory holds both
660
+ // what a person wrote and what a command fetched, and only the second kind may
661
+ // be thrown away. Without this row `packs/` inherits `policiesDir`'s
662
+ // `user-typed` and survives a reset that is supposed to clear re-fetchable
663
+ // state.
664
+ { path: packsDir, class: "refetchable" },
577
665
 
578
666
  // ── Never touched ──
579
667
  // A downloaded daemon binary is large, version-pinned and re-verified on use,
@@ -98,6 +98,7 @@ import {
98
98
  isDaemonSupportedPlatform,
99
99
  probeDaemonEndToEnd,
100
100
  } from "./daemon-service";
101
+ import { readHooksConfig } from "./hooks-config";
101
102
 
102
103
  export interface ResetOutcome {
103
104
  /** Paths that existed and were removed. */
@@ -964,6 +965,33 @@ export function resetHome(from: number, to: number = LAYOUT_VERSION): ResetOutco
964
965
  // straight out of the same file. Both paths end at the same key, and only one
965
966
  // of them represents something a person typed.
966
967
  if (telemetryOptOut) updateConfig({ telemetry: { enabled: false } });
968
+ // `packs/` is resettable, but the package's default pack is also the offline
969
+ // enforcement floor. Restore it from the installed package before declaring
970
+ // the migration complete; third-party packs remain explicitly re-fetchable.
971
+ //
972
+ // Carrying `enabledPolicies` INTO the selection, not installing defaults over
973
+ // it. This is the upgrade path every existing user takes, and installing
974
+ // defaults meant a machine that had switched `block-force-push` and
975
+ // `block-kubectl` on came back with them off — guards that were denying
976
+ // before the upgrade and allowing after, with nothing said.
977
+ const carried = (() => {
978
+ try {
979
+ const names = readHooksConfig().enabledPolicies ?? [];
980
+ return names.length > 0 ? { only: names } : undefined;
981
+ } catch {
982
+ return undefined;
983
+ }
984
+ })();
985
+ // Deliberately does NOT install a pack. There is no copy in this package to
986
+ // install any more, and `resetHome` is synchronous and runs inside
987
+ // `failproofai update` — an upgrade that blocks on github.com, and fails when
988
+ // it is unreachable, is a worse upgrade than one that finishes.
989
+ //
990
+ // The carried names stay in config, which is what the no-pack fallback reads,
991
+ // so a machine mid-upgrade keeps enforcing exactly what it enforced before.
992
+ // `failproofai policies add core` turns them into a real pack when the user
993
+ // is online, and carries this selection into it.
994
+ void carried;
967
995
  // The step's OWN target, not LAYOUT_VERSION.
968
996
  //
969
997
  // Every step used to end stamping the current layout, which was harmless
@@ -1344,8 +1372,12 @@ function staleDaemonHint(): string[] {
1344
1372
  `[failproofai] daemon is ${skew.installed}, CLI is ${skew.expected}.`,
1345
1373
  `This machine is configured to REQUIRE the daemon. A daemon built against a`,
1346
1374
  `different on-disk layout refuses to start, and this version moved it — so the`,
1347
- `next reboot or restart can leave the service down, which denies every tool`,
1348
- `call until it is fixed.`,
1375
+ // The wrap is load-bearing: "denies every tool call" is the consequence
1376
+ // this message exists to state, and splitting it across two lines is
1377
+ // what made the test asserting that phrase fail while the text looked
1378
+ // perfectly correct to a human reading it.
1379
+ `next reboot or restart can leave the service down, which`,
1380
+ `denies every tool call until it is fixed.`,
1349
1381
  `Run \`failproofai update\` now to bring the daemon in line.`,
1350
1382
  ``,
1351
1383
  ];