failproofai 1.0.1 → 1.0.2-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (389) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/build-manifest.json +3 -3
  3. package/.next/standalone/.next/prerender-manifest.json +6 -6
  4. package/.next/standalone/.next/required-server-files.json +1 -1
  5. package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
  6. package/.next/standalone/.next/server/app/_global-error/page.js +2 -2
  7. package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  8. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  10. package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
  11. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +6 -6
  12. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
  13. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  14. package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  15. package/.next/standalone/.next/server/app/_not-found/page.js +2 -2
  16. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  17. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  18. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  19. package/.next/standalone/.next/server/app/_not-found.rsc +15 -15
  20. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +15 -15
  21. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +14 -14
  22. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  23. package/.next/standalone/.next/server/app/api/audit/invite/route.js +3 -2
  24. package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -1
  25. package/.next/standalone/.next/server/app/api/audit/run/route.js +5 -4
  26. package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
  27. package/.next/standalone/.next/server/app/api/audit/status/route.js.nft.json +1 -1
  28. package/.next/standalone/.next/server/app/api/auth/login-request/route.js +2 -2
  29. package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
  30. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js +4 -3
  31. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
  32. package/.next/standalone/.next/server/app/api/auth/logout/route.js +4 -4
  33. package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
  34. package/.next/standalone/.next/server/app/api/auth/status/route.js +4 -4
  35. package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
  36. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
  37. package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
  38. package/.next/standalone/.next/server/app/audit/page.js +2 -2
  39. package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
  40. package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
  41. package/.next/standalone/.next/server/app/index.html +1 -1
  42. package/.next/standalone/.next/server/app/index.rsc +15 -15
  43. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +14 -14
  44. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
  45. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  46. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
  47. package/.next/standalone/.next/server/app/page.js +2 -2
  48. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  49. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  50. package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +66 -22
  51. package/.next/standalone/.next/server/app/policies/page.js +5 -4
  52. package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
  53. package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
  54. package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
  55. package/.next/standalone/.next/server/app/project/[name]/page.js +2 -2
  56. package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
  57. package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
  58. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
  59. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
  60. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js +2 -2
  61. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
  62. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
  63. package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
  64. package/.next/standalone/.next/server/app/projects/page.js +2 -2
  65. package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
  66. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  67. package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +4 -4
  68. package/.next/standalone/.next/server/app/settings/page.js +1 -1
  69. package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
  70. package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  71. package/.next/standalone/.next/server/chunks/{[externals]__1qzqcio._.js → [externals]__0e32-7c._.js} +1 -1
  72. package/.next/standalone/.next/server/chunks/[externals]__1s462yl._.js +3 -0
  73. package/.next/standalone/.next/server/chunks/[root-of-the-server]__01eqny5._.js +3 -0
  74. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0_0xu5z._.js +1 -1
  75. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__1p8poxd._.js → [root-of-the-server]__0igxt32._.js} +2 -2
  76. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0neqlu-._.js +3 -0
  77. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o07qi9._.js +3 -0
  78. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0t9oqnn._.js +3 -0
  79. package/.next/standalone/.next/server/chunks/_0bs-v8p._.js +3 -0
  80. package/.next/standalone/.next/server/chunks/_0tovk6q._.js +3 -0
  81. package/.next/standalone/.next/server/chunks/_0trp3yc._.js +3 -0
  82. package/.next/standalone/.next/server/chunks/_185gyk9._.js +3 -0
  83. package/.next/standalone/.next/server/chunks/_1ek68ln._.js +5 -6
  84. package/.next/standalone/.next/server/chunks/lib_telemetry-id_ts_1k8gj9o._.js +3 -0
  85. package/.next/standalone/.next/server/chunks/{node_modules_posthog-node_dist_entrypoints_index_node_mjs_09d5c79._.js → node_modules_posthog-node_dist_entrypoints_index_node_mjs_04op_ou._.js} +1 -1
  86. package/.next/standalone/.next/server/chunks/{node_modules_posthog-node_dist_entrypoints_index_node_mjs_1d2g73o._.js → node_modules_posthog-node_dist_entrypoints_index_node_mjs_0dr20uz._.js} +1 -1
  87. package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
  88. package/.next/standalone/.next/server/chunks/src_hooks_0xbw3bu._.js +12 -0
  89. package/.next/standalone/.next/server/chunks/src_hooks_fp-home_ts_09kv0bn._.js +1 -1
  90. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__013jr2b._.js +4 -0
  91. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__01wy8d-._.js +4 -0
  92. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__02npjtd._.js +4 -0
  93. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0spkm68._.js → [root-of-the-server]__07gm3zl._.js} +21 -20
  94. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0da85px._.js +4 -0
  95. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ftmoxc._.js +4 -0
  96. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0oa1lav._.js +1 -1
  97. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0p-5p8u._.js +4 -0
  98. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0s740oi._.js +6 -0
  99. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__07tbbf3._.js → [root-of-the-server]__0zig5sv._.js} +2 -2
  100. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__192nhvh._.js +5 -0
  101. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1p2otjt._.js +4 -0
  102. package/.next/standalone/.next/server/chunks/ssr/{_0lvyuv4._.js → _00e9tnf._.js} +2 -2
  103. package/.next/standalone/.next/server/chunks/ssr/_08x1r5t._.js +1 -1
  104. package/.next/standalone/.next/server/chunks/ssr/{_0u5zauv._.js → _12l4a_k._.js} +1 -1
  105. package/.next/standalone/.next/server/chunks/ssr/_1u8-lu2._.js +1 -1
  106. package/.next/standalone/.next/server/chunks/ssr/_1zopuov._.js +1 -1
  107. package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +13 -13
  108. package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
  109. package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +2 -2
  110. package/.next/standalone/.next/server/chunks/ssr/app_settings_settings-client_tsx_20lq-mq._.js +1 -1
  111. package/.next/standalone/.next/server/chunks/ssr/src_hooks_08o7bqo._.js +10 -0
  112. package/.next/standalone/.next/server/chunks/ssr/src_hooks_builtin-policies_ts_09j2ndl._.js +1 -1
  113. package/.next/standalone/.next/server/chunks/ssr/src_hooks_fp-home_ts_0je3xkv._.js +1 -1
  114. package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
  115. package/.next/standalone/.next/server/middleware.js +1 -1
  116. package/.next/standalone/.next/server/pages/404.html +1 -1
  117. package/.next/standalone/.next/server/pages/500.html +1 -1
  118. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  119. package/.next/standalone/.next/server/server-reference-manifest.json +71 -27
  120. package/.next/standalone/.next/static/chunks/{37fcpc36x9gpe.js → 0eqky-7n7dgdm.js} +1 -1
  121. package/.next/standalone/.next/static/chunks/{1ide1wl2f7zi1.js → 0sa9v5mhc8861.js} +13 -13
  122. package/.next/standalone/.next/static/chunks/1mfzsja6ftim5.css +2 -0
  123. package/.next/standalone/.next/static/chunks/{3k7mxbp9hiom0.js → 1nuqytbta44af.js} +1 -1
  124. package/.next/standalone/.next/static/chunks/1sl2xmn9inx3y.js +6 -0
  125. package/.next/standalone/.next/static/chunks/{2_2lhuojq2xop.js → 2aawsjld9ied_.js} +1 -1
  126. package/.next/standalone/.next/static/chunks/2gn7ut4svofm2.js +1 -0
  127. package/.next/standalone/.next/static/chunks/{31s1smp-g7gks.js → 2hs7ycvsav7v2.js} +1 -1
  128. package/.next/standalone/.next/static/chunks/{0k5050ezjvv49.js → 2i2yt3hzjredm.js} +1 -1
  129. package/.next/standalone/.next/static/chunks/{3c808qrfcq0im.js → 35xg6retpe6rp.js} +1 -1
  130. package/.next/standalone/.next/static/chunks/{2zpp1we2jv6tb.js → 3y54nw0i7dsjl.js} +1 -1
  131. package/.next/standalone/SECURITY.md +5 -4
  132. package/.next/standalone/app/actions/get-hooks-config.ts +108 -17
  133. package/.next/standalone/app/actions/pack-actions.ts +153 -0
  134. package/.next/standalone/app/audit/_components/run-progress.tsx +1 -1
  135. package/.next/standalone/app/audit/_components/share-templates.ts +13 -13
  136. package/.next/standalone/app/policies/hooks-client.tsx +320 -14
  137. package/.next/standalone/components/navbar.tsx +2 -28
  138. package/.next/standalone/components/reach-developers.tsx +8 -1
  139. package/.next/standalone/docs-old/agenteye/python-sdk-skill.mdx +1 -1
  140. package/.next/standalone/docs-old/agenteye/python-sdk.mdx +59 -35
  141. package/.next/standalone/docs-old/i18n/README.ar.md +1 -0
  142. package/.next/standalone/docs-old/i18n/README.de.md +1 -0
  143. package/.next/standalone/docs-old/i18n/README.es.md +1 -0
  144. package/.next/standalone/docs-old/i18n/README.fr.md +1 -0
  145. package/.next/standalone/docs-old/i18n/README.he.md +1 -0
  146. package/.next/standalone/docs-old/i18n/README.hi.md +1 -0
  147. package/.next/standalone/docs-old/i18n/README.it.md +1 -0
  148. package/.next/standalone/docs-old/i18n/README.ja.md +1 -0
  149. package/.next/standalone/docs-old/i18n/README.ko.md +1 -0
  150. package/.next/standalone/docs-old/i18n/README.pt-br.md +1 -0
  151. package/.next/standalone/docs-old/i18n/README.ru.md +1 -0
  152. package/.next/standalone/docs-old/i18n/README.tr.md +1 -0
  153. package/.next/standalone/docs-old/i18n/README.vi.md +1 -0
  154. package/.next/standalone/docs-old/i18n/README.zh.md +1 -0
  155. package/.next/standalone/fp-cloud-cli/CHANGELOG.md +431 -0
  156. package/.next/standalone/fp-cloud-cli/LICENSE +42 -0
  157. package/.next/standalone/fp-cloud-cli/MANIFEST.in +10 -0
  158. package/.next/standalone/fp-cloud-cli/README.md +259 -0
  159. package/.next/standalone/fp-cloud-cli/fp_cli/__init__.py +10 -0
  160. package/.next/standalone/fp-cloud-cli/fp_cli/__main__.py +4 -0
  161. package/.next/standalone/fp-cloud-cli/fp_cli/_click_compat.py +64 -0
  162. package/.next/standalone/fp-cloud-cli/fp_cli/_context.py +332 -0
  163. package/.next/standalone/fp-cloud-cli/fp_cli/_version.py +1 -0
  164. package/.next/standalone/fp-cloud-cli/fp_cli/analytics.py +432 -0
  165. package/.next/standalone/fp-cloud-cli/fp_cli/analytics_config.py +77 -0
  166. package/.next/standalone/fp-cloud-cli/fp_cli/analytics_registry.py +83 -0
  167. package/.next/standalone/fp-cloud-cli/fp_cli/app.py +492 -0
  168. package/.next/standalone/fp-cloud-cli/fp_cli/auth.py +160 -0
  169. package/.next/standalone/fp-cloud-cli/fp_cli/client.py +1694 -0
  170. package/.next/standalone/fp-cloud-cli/fp_cli/commands/__init__.py +0 -0
  171. package/.next/standalone/fp-cloud-cli/fp_cli/commands/_write.py +214 -0
  172. package/.next/standalone/fp-cloud-cli/fp_cli/commands/agent_cmds.py +407 -0
  173. package/.next/standalone/fp-cloud-cli/fp_cli/commands/alerts_cmds.py +445 -0
  174. package/.next/standalone/fp-cloud-cli/fp_cli/commands/audits_cmds.py +1054 -0
  175. package/.next/standalone/fp-cloud-cli/fp_cli/commands/auth_cmds.py +512 -0
  176. package/.next/standalone/fp-cloud-cli/fp_cli/commands/errors_cmds.py +190 -0
  177. package/.next/standalone/fp-cloud-cli/fp_cli/commands/evals_cmds.py +161 -0
  178. package/.next/standalone/fp-cloud-cli/fp_cli/commands/events_cmds.py +159 -0
  179. package/.next/standalone/fp-cloud-cli/fp_cli/commands/fleet_cmds.py +416 -0
  180. package/.next/standalone/fp-cloud-cli/fp_cli/commands/guardrails_cmds.py +148 -0
  181. package/.next/standalone/fp-cloud-cli/fp_cli/commands/incidents_cmds.py +472 -0
  182. package/.next/standalone/fp-cloud-cli/fp_cli/commands/keys_cmds.py +407 -0
  183. package/.next/standalone/fp-cloud-cli/fp_cli/commands/list_cmds.py +63 -0
  184. package/.next/standalone/fp-cloud-cli/fp_cli/commands/orgs_cmds.py +319 -0
  185. package/.next/standalone/fp-cloud-cli/fp_cli/commands/policies_cmds.py +499 -0
  186. package/.next/standalone/fp-cloud-cli/fp_cli/commands/queries_cmds.py +378 -0
  187. package/.next/standalone/fp-cloud-cli/fp_cli/commands/sessions_cmds.py +151 -0
  188. package/.next/standalone/fp-cloud-cli/fp_cli/commands/settings_cmds.py +150 -0
  189. package/.next/standalone/fp-cloud-cli/fp_cli/commands/usage_cmds.py +35 -0
  190. package/.next/standalone/fp-cloud-cli/fp_cli/commands/users_cmds.py +404 -0
  191. package/.next/standalone/fp-cloud-cli/fp_cli/config.py +330 -0
  192. package/.next/standalone/fp-cloud-cli/fp_cli/dates.py +78 -0
  193. package/.next/standalone/fp-cloud-cli/fp_cli/enforcement.py +345 -0
  194. package/.next/standalone/fp-cloud-cli/fp_cli/errors.py +98 -0
  195. package/.next/standalone/fp-cloud-cli/fp_cli/models.py +891 -0
  196. package/.next/standalone/fp-cloud-cli/fp_cli/orgs.py +30 -0
  197. package/.next/standalone/fp-cloud-cli/fp_cli/output.py +6593 -0
  198. package/.next/standalone/fp-cloud-cli/fp_cli/permissions.py +208 -0
  199. package/.next/standalone/fp-cloud-cli/fp_cli/policy_check.py +290 -0
  200. package/.next/standalone/fp-cloud-cli/fp_cli/py.typed +0 -0
  201. package/.next/standalone/fp-cloud-cli/fp_cli/select.py +322 -0
  202. package/.next/standalone/fp-cloud-cli/fp_cli/theme.py +53 -0
  203. package/.next/standalone/fp-cloud-cli/pyproject.toml +106 -0
  204. package/.next/standalone/fp-cloud-cli/skill/SKILL.md +302 -0
  205. package/.next/standalone/fp-cloud-cli/skill/agents/openai.yaml +8 -0
  206. package/.next/standalone/fp-cloud-cli/skill/references/commands.md +254 -0
  207. package/.next/standalone/fp-cloud-cli/tests/__init__.py +0 -0
  208. package/.next/standalone/fp-cloud-cli/tests/conftest.py +92 -0
  209. package/.next/standalone/fp-cloud-cli/tests/test_alerting.py +644 -0
  210. package/.next/standalone/fp-cloud-cli/tests/test_analytics.py +385 -0
  211. package/.next/standalone/fp-cloud-cli/tests/test_audits.py +950 -0
  212. package/.next/standalone/fp-cloud-cli/tests/test_auth.py +98 -0
  213. package/.next/standalone/fp-cloud-cli/tests/test_auth_mode.py +272 -0
  214. package/.next/standalone/fp-cloud-cli/tests/test_click_compat.py +118 -0
  215. package/.next/standalone/fp-cloud-cli/tests/test_client.py +299 -0
  216. package/.next/standalone/fp-cloud-cli/tests/test_commands.py +814 -0
  217. package/.next/standalone/fp-cloud-cli/tests/test_config.py +99 -0
  218. package/.next/standalone/fp-cloud-cli/tests/test_dashboards_agent.py +340 -0
  219. package/.next/standalone/fp-cloud-cli/tests/test_dates.py +76 -0
  220. package/.next/standalone/fp-cloud-cli/tests/test_enforcement_logic.py +481 -0
  221. package/.next/standalone/fp-cloud-cli/tests/test_facets.py +170 -0
  222. package/.next/standalone/fp-cloud-cli/tests/test_failproofai_home.py +722 -0
  223. package/.next/standalone/fp-cloud-cli/tests/test_fp_home_contract.py +198 -0
  224. package/.next/standalone/fp-cloud-cli/tests/test_hardening.py +186 -0
  225. package/.next/standalone/fp-cloud-cli/tests/test_help_table_coverage.py +127 -0
  226. package/.next/standalone/fp-cloud-cli/tests/test_keys_queries.py +496 -0
  227. package/.next/standalone/fp-cloud-cli/tests/test_list.py +59 -0
  228. package/.next/standalone/fp-cloud-cli/tests/test_multivalue.py +183 -0
  229. package/.next/standalone/fp-cloud-cli/tests/test_no_customer_identifiers.py +168 -0
  230. package/.next/standalone/fp-cloud-cli/tests/test_operator.py +492 -0
  231. package/.next/standalone/fp-cloud-cli/tests/test_orgs.py +692 -0
  232. package/.next/standalone/fp-cloud-cli/tests/test_output.py +1732 -0
  233. package/.next/standalone/fp-cloud-cli/tests/test_policy_check.py +191 -0
  234. package/.next/standalone/fp-cloud-cli/tests/test_readme_matches_reality.py +125 -0
  235. package/.next/standalone/fp-cloud-cli/tests/test_review_fixes.py +161 -0
  236. package/.next/standalone/fp-cloud-cli/tests/test_telemetry_completeness.py +90 -0
  237. package/.next/standalone/fp-cloud-cli/tests/test_usage.py +115 -0
  238. package/.next/standalone/fp-cloud-cli/tests/test_v1_origin_diagnostic.py +70 -0
  239. package/.next/standalone/fp-cloud-cli/tests/test_v1_routing.py +214 -0
  240. package/.next/standalone/fp-cloud-cli/tests/test_whoami.py +104 -0
  241. package/.next/standalone/fp-cloud-cli/uv.lock +552 -0
  242. package/.next/standalone/package.json +29 -22
  243. package/.next/standalone/sdk/python/CHANGELOG.md +70 -0
  244. package/.next/standalone/sdk/python/LICENSE +42 -0
  245. package/.next/standalone/sdk/python/MANIFEST.in +21 -0
  246. package/.next/standalone/sdk/python/README.md +466 -0
  247. package/.next/standalone/sdk/python/docs/README.md +249 -0
  248. package/.next/standalone/sdk/python/docs/_shared/README.md +43 -0
  249. package/.next/standalone/sdk/python/docs/_shared/__init__.py +195 -0
  250. package/.next/standalone/sdk/python/docs/crewai/README.md +328 -0
  251. package/.next/standalone/sdk/python/docs/crewai/examples/quickstart.py +61 -0
  252. package/.next/standalone/sdk/python/docs/crewai/examples/research_crew.py +92 -0
  253. package/.next/standalone/sdk/python/docs/langgraph/README.md +481 -0
  254. package/.next/standalone/sdk/python/docs/langgraph/examples/quickstart.py +51 -0
  255. package/.next/standalone/sdk/python/docs/langgraph/examples/research_agent.py +86 -0
  256. package/.next/standalone/sdk/python/docs/langgraph/examples/supervisor_handoff.py +83 -0
  257. package/.next/standalone/sdk/python/docs/llama_index/README.md +332 -0
  258. package/.next/standalone/sdk/python/docs/llama_index/examples/quickstart.py +62 -0
  259. package/.next/standalone/sdk/python/docs/llama_index/examples/research_agent.py +93 -0
  260. package/.next/standalone/sdk/python/docs/manual/README.md +491 -0
  261. package/.next/standalone/sdk/python/docs/manual/examples/quickstart.py +57 -0
  262. package/.next/standalone/sdk/python/docs/manual/examples/research_agent.py +133 -0
  263. package/.next/standalone/sdk/python/docs/pydantic_ai/README.md +323 -0
  264. package/.next/standalone/sdk/python/docs/pydantic_ai/examples/quickstart.py +48 -0
  265. package/.next/standalone/sdk/python/docs/pydantic_ai/examples/research_agent.py +94 -0
  266. package/.next/standalone/sdk/python/failproofai_sdk/__init__.py +131 -0
  267. package/.next/standalone/sdk/python/failproofai_sdk/_context.py +218 -0
  268. package/.next/standalone/sdk/python/failproofai_sdk/_environment.py +78 -0
  269. package/.next/standalone/sdk/python/failproofai_sdk/_events.py +752 -0
  270. package/.next/standalone/sdk/python/failproofai_sdk/_resolver.py +118 -0
  271. package/.next/standalone/sdk/python/failproofai_sdk/_runtime.py +21 -0
  272. package/.next/standalone/sdk/python/failproofai_sdk/_schema.py +317 -0
  273. package/.next/standalone/sdk/python/failproofai_sdk/_scopes.py +422 -0
  274. package/.next/standalone/sdk/python/failproofai_sdk/_version.py +1 -0
  275. package/.next/standalone/sdk/python/failproofai_sdk/_writer.py +750 -0
  276. package/.next/standalone/sdk/python/failproofai_sdk/integrations/__init__.py +274 -0
  277. package/.next/standalone/sdk/python/failproofai_sdk/integrations/_compat.py +247 -0
  278. package/.next/standalone/sdk/python/failproofai_sdk/integrations/_core.py +1076 -0
  279. package/.next/standalone/sdk/python/failproofai_sdk/integrations/crewai.py +1669 -0
  280. package/.next/standalone/sdk/python/failproofai_sdk/integrations/langchain.py +2151 -0
  281. package/.next/standalone/sdk/python/failproofai_sdk/integrations/llama_index.py +1588 -0
  282. package/.next/standalone/sdk/python/failproofai_sdk/integrations/pydantic_ai.py +977 -0
  283. package/.next/standalone/sdk/python/failproofai_sdk/py.typed +0 -0
  284. package/.next/standalone/sdk/python/pyproject.toml +92 -0
  285. package/.next/standalone/sdk/python/skill/SKILL.md +399 -0
  286. package/.next/standalone/sdk/python/skill/agents/openai.yaml +8 -0
  287. package/.next/standalone/sdk/python/skill/references/events.md +234 -0
  288. package/.next/standalone/sdk/python/skill/references/frameworks.md +314 -0
  289. package/.next/standalone/sdk/python/skill/references/install.md +100 -0
  290. package/.next/standalone/sdk/python/skill/references/integration.md +352 -0
  291. package/.next/standalone/sdk/python/tests/__init__.py +0 -0
  292. package/.next/standalone/sdk/python/tests/conftest.py +169 -0
  293. package/.next/standalone/sdk/python/tests/integrations/__init__.py +6 -0
  294. package/.next/standalone/sdk/python/tests/integrations/test_crewai.py +1299 -0
  295. package/.next/standalone/sdk/python/tests/integrations/test_langchain.py +2338 -0
  296. package/.next/standalone/sdk/python/tests/integrations/test_llama_index.py +1576 -0
  297. package/.next/standalone/sdk/python/tests/integrations/test_pydantic_ai.py +1102 -0
  298. package/.next/standalone/sdk/python/tests/test_context.py +410 -0
  299. package/.next/standalone/sdk/python/tests/test_docs.py +411 -0
  300. package/.next/standalone/sdk/python/tests/test_durability.py +1352 -0
  301. package/.next/standalone/sdk/python/tests/test_encoding.py +571 -0
  302. package/.next/standalone/sdk/python/tests/test_integrations.py +1127 -0
  303. package/.next/standalone/sdk/python/tests/test_no_customer_identifiers.py +214 -0
  304. package/.next/standalone/sdk/python/tests/test_packaging.py +185 -0
  305. package/.next/standalone/sdk/python/tests/test_resolver_umbrella.py +178 -0
  306. package/.next/standalone/sdk/python/tests/test_scopes.py +487 -0
  307. package/.next/standalone/sdk/python/tests/test_sdk.py +923 -0
  308. package/.next/standalone/sdk/python/tests/test_server_contract.py +650 -0
  309. package/.next/standalone/sdk/python/tests/test_site_docs.py +371 -0
  310. package/.next/standalone/sdk/python/tests/test_skill_snippets.py +165 -0
  311. package/.next/standalone/sdk/python/tests/test_spool_contract.py +287 -0
  312. package/.next/standalone/sdk/python/tests/test_spool_creation.py +360 -0
  313. package/.next/standalone/sdk/python/tests/test_wire_format.py +279 -0
  314. package/.next/standalone/sdk/python/tests/test_zero_dependencies.py +378 -0
  315. package/.next/standalone/sdk/python/uv.lock +6005 -0
  316. package/.next/standalone/server.js +1 -1
  317. package/README.md +77 -21
  318. package/bin/failproofai.mjs +145 -11
  319. package/dist/cli.mjs +4482 -2205
  320. package/dist/index.js +5 -5
  321. package/dist/worker.mjs +2399 -1978
  322. package/package.json +29 -22
  323. package/policy-pack/SHA256SUMS +2 -0
  324. package/policy-pack/failproofai-pack.json +732 -0
  325. package/policy-pack/failproofai-pack.mjs +2017 -0
  326. package/scripts/build-policy-pack.mjs +121 -0
  327. package/scripts/changelog-section.py +77 -0
  328. package/scripts/prune-standalone.mjs +3 -0
  329. package/scripts/python-version.py +232 -0
  330. package/scripts/translate-docs/cli.ts +21 -0
  331. package/scripts/translate-docs/mintlify-nav.ts +85 -13
  332. package/scripts/translate-docs/translator.ts +66 -11
  333. package/src/audit/cache.ts +40 -3
  334. package/src/audit/cli.ts +1 -1
  335. package/src/audit/index.ts +1 -1
  336. package/src/audit/replay.ts +89 -3
  337. package/src/audit/report.ts +5 -5
  338. package/src/audit/schedule-cli.ts +49 -53
  339. package/src/hooks/builtin-policies.ts +217 -579
  340. package/src/hooks/cloud-enrollment-cli.ts +66 -27
  341. package/src/hooks/cloud-managed-policies.ts +6 -1
  342. package/src/hooks/configure-wizard.ts +1 -1
  343. package/src/hooks/custom-hooks-loader.ts +89 -6
  344. package/src/hooks/fp-home.ts +92 -4
  345. package/src/hooks/fp-reset.ts +26 -2
  346. package/src/hooks/handler.ts +181 -11
  347. package/src/hooks/harness-cli.ts +79 -25
  348. package/src/hooks/hook-activity-store.ts +13 -3
  349. package/src/hooks/install-prompt.ts +25 -3
  350. package/src/hooks/manager.ts +418 -172
  351. package/src/hooks/migrations.ts +2 -2
  352. package/src/hooks/pack-cli.ts +505 -0
  353. package/src/hooks/pack-failclosed.ts +189 -0
  354. package/src/hooks/pack-manifest.ts +344 -0
  355. package/src/hooks/pack-store.ts +930 -0
  356. package/src/hooks/policy-catalog.ts +535 -0
  357. package/src/hooks/policy-evaluator.ts +24 -16
  358. package/src/hooks/policy-presets.ts +4 -2
  359. package/src/hooks/policy-registry.ts +8 -2
  360. package/src/hooks/policy-types.ts +26 -0
  361. package/src/hooks/session-pause-cli.ts +33 -9
  362. package/src/hooks/tui.ts +570 -0
  363. package/src/hooks/types.ts +15 -1
  364. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0_usx0j._.js +0 -3
  365. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0_zk340._.js +0 -3
  366. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0agdw2a._.js +0 -3
  367. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0d1u_na._.js +0 -3
  368. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0oy4kxb._.js +0 -3
  369. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0zf034w._.js +0 -3
  370. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1tvn4wf._.js +0 -3
  371. package/.next/standalone/.next/server/chunks/_0lxbzdq._.js +0 -3
  372. package/.next/standalone/.next/server/chunks/_1ger0a2._.js +0 -3
  373. package/.next/standalone/.next/server/chunks/_1zuiiy3._.js +0 -3
  374. package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_1iiwm5e._.js +0 -3
  375. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0kc8_v5._.js +0 -4
  376. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0kgy9da._.js +0 -4
  377. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0mhqk5a._.js +0 -4
  378. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0pltpn8._.js +0 -4
  379. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qkcyf-._.js +0 -4
  380. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0w0x_ok._.js +0 -4
  381. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1_dfocn._.js +0 -4
  382. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1bfex62._.js +0 -5
  383. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1kzapg5._.js +0 -6
  384. package/.next/standalone/.next/static/chunks/36fw6yk1s6x_f.js +0 -1
  385. package/.next/standalone/.next/static/chunks/3tzq0260n17ae.js +0 -6
  386. package/.next/standalone/.next/static/chunks/3wq9x0c-7ld5d.css +0 -2
  387. /package/.next/standalone/.next/static/{ZklXxyA5ygsWSQz2u_zii → nwbyWT06Ud0XdXOrVJyvS}/_buildManifest.js +0 -0
  388. /package/.next/standalone/.next/static/{ZklXxyA5ygsWSQz2u_zii → nwbyWT06Ud0XdXOrVJyvS}/_clientMiddlewareManifest.js +0 -0
  389. /package/.next/standalone/.next/static/{ZklXxyA5ygsWSQz2u_zii → nwbyWT06Ud0XdXOrVJyvS}/_ssgManifest.js +0 -0
@@ -1 +1 @@
1
- (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,64237,e=>{"use strict";var t=e.i(43476),a=e.i(71645),s=e.i(12344),n=e.i(29054);let i=/^[^\s@]+@[^\s@]+\.[^\s@]+$/;function r(e){if((0,n.isAbortError)(e))return"request timed out. check your network and try again.";let t=e instanceof Error?e.message:String(e);return`network error: ${t}`}e.s(["AuthDialog",0,function({open:e,headline:l="where to route the reminder?",subhead:o="we'll send a one-time code to confirm.",onClose:c,onAuthed:d,source:u="unknown"}){let{capture:h}=(0,s.usePostHog)(),[m,f]=(0,a.useState)({kind:"email",error:null}),[b,p]=(0,a.useState)(!1),v=(0,a.useRef)(!1),x=(0,a.useRef)(null),g=(0,a.useRef)(null);(0,a.useEffect)(()=>{e&&(f({kind:"email",error:null}),p(!1),v.current=!1,h("audit_auth_dialog_opened",{source:u}))},[h,e,u]);let y=(0,a.useRef)(!1);(0,a.useEffect)(()=>{if(e){y.current=!0;return}y.current&&!v.current&&h("audit_auth_dialog_dismissed",{source:u,step:m.kind}),y.current=!1},[h,e,u,m.kind]),(0,a.useEffect)(()=>{if(!e)return;let t=setTimeout(()=>{"email"===m.kind?x.current?.focus():"code"===m.kind&&g.current?.focus()},50);return()=>clearTimeout(t)},[e,m.kind]),(0,a.useEffect)(()=>{if(!e)return;let t=e=>{"Escape"!==e.key||b||c()};return window.addEventListener("keydown",t),()=>window.removeEventListener("keydown",t)},[e,b,c]);let w="code"===m.kind&&m.resendIn>0;(0,a.useEffect)(()=>{if(!w)return;let e=setInterval(()=>{f(e=>"code"===e.kind?{...e,resendIn:Math.max(0,e.resendIn-1)}:e)},1e3);return()=>clearInterval(e)},[w]);let j=(0,a.useCallback)(async(e,t={})=>{let{isResend:a=!1}=t,s=e=>{a?f(t=>"code"===t.kind?{...t,error:e}:t):f({kind:"email",error:e})};p(!0);try{let t=await (0,n.fetchWithTimeout)("/api/auth/login-request",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({email:e})}),a=await t.json().catch(()=>({}));if(!t.ok){let e=a.message??"could not send code.";"rate_limited"===a.code&&void 0!==a.retry_after_secs?e=`too many tries. wait ${a.retry_after_secs}s and try again.`:"upstream_unreachable"===a.code&&(e="api-server unreachable. check your network."),s(e);return}f({kind:"code",email:e,error:null,expiresIn:a.expires_in??600,resendIn:a.resend_available_in??30})}catch(e){s(r(e))}finally{p(!1)}},[]),k=(0,a.useCallback)(async(e,t)=>{p(!0);try{let a=await (0,n.fetchWithTimeout)("/api/auth/login-verify",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({email:e,code:t})}),s=await a.json().catch(()=>({}));if(!a.ok||!s.authenticated||!s.user){let e=s.message??"invalid code.";"invalid_code"===s.code&&(e="wrong code, or it expired. try again."),f(t=>"code"===t.kind?{...t,error:e}:t);return}v.current=!0,h("audit_auth_dialog_succeeded",{source:u}),f({kind:"done",user:s.user}),d(s.user)}catch(t){let e=r(t);f(t=>"code"===t.kind?{...t,error:e}:t)}finally{p(!1)}},[h,d,u]),N=(0,a.useCallback)(async e=>{if(e.preventDefault(),b||"email"!==m.kind)return;let t=String(new FormData(e.currentTarget).get("email")??"").trim().toLowerCase();i.test(t)?await j(t):f({kind:"email",error:"that doesn't look like an email."})},[b,m,j]),S=(0,a.useCallback)(async e=>{if(e.preventDefault(),b||"code"!==m.kind)return;let t=String(new FormData(e.currentTarget).get("code")??"").trim();t.length<4||t.length>12?f(e=>"code"===e.kind?{...e,error:"code is 4–12 characters."}:e):await k(m.email,t)},[b,m,k]),C=(0,a.useCallback)(async()=>{"code"!==m.kind||m.resendIn>0||b||await j(m.email,{isResend:!0})},[m,b,j]);return e?(0,t.jsx)("div",{className:"auth-dialog-backdrop",role:"dialog","aria-modal":"true","aria-labelledby":"auth-dialog-title",onClick:e=>{b||e.target!==e.currentTarget||c()},children:(0,t.jsxs)("div",{className:"auth-dialog",children:[(0,t.jsx)("button",{type:"button",className:"auth-close",onClick:c,disabled:b,"aria-label":"close",children:"×"}),(0,t.jsx)("h2",{id:"auth-dialog-title",className:"auth-headline",children:l}),"email"===m.kind&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("p",{className:"auth-sub",children:o}),(0,t.jsxs)("form",{onSubmit:N,className:"auth-form",children:[(0,t.jsx)("input",{ref:x,id:"auth-dialog-email",name:"email",type:"email",autoComplete:"email",inputMode:"email",spellCheck:!1,placeholder:"you@yourdomain.com",disabled:b,className:"auth-input",required:!0}),m.error&&(0,t.jsx)("div",{className:"auth-error",children:m.error}),(0,t.jsxs)("div",{className:"auth-actions",children:[(0,t.jsx)("button",{type:"submit",className:"auth-btn primary",disabled:b,children:b?"sending…":"send code"}),(0,t.jsx)("button",{type:"button",className:"auth-btn",onClick:c,disabled:b,children:"cancel"})]})]})]}),"code"===m.kind&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)("p",{className:"auth-sub",children:["code sent to ",(0,t.jsx)("span",{className:"auth-email",children:m.email}),". expires in ",Math.ceil(m.expiresIn/60)," min."]}),(0,t.jsxs)("form",{onSubmit:S,className:"auth-form",children:[(0,t.jsx)("input",{ref:g,id:"auth-dialog-code",name:"code",type:"text",inputMode:"numeric",autoComplete:"one-time-code",spellCheck:!1,placeholder:"123456",disabled:b,className:"auth-input auth-input-code",maxLength:12,required:!0}),m.error&&(0,t.jsx)("div",{className:"auth-error",children:m.error}),(0,t.jsxs)("div",{className:"auth-actions",children:[(0,t.jsx)("button",{type:"submit",className:"auth-btn primary",disabled:b,children:b?"verifying…":"verify"}),(0,t.jsx)("button",{type:"button",className:"auth-btn",onClick:C,disabled:b||m.resendIn>0,children:m.resendIn>0?`resend in ${m.resendIn}s`:"resend code"})]}),(0,t.jsx)("button",{type:"button",className:"auth-back",onClick:()=>f({kind:"email",error:null}),disabled:b,children:"← use a different email"})]})]}),"done"===m.kind&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)("p",{className:"auth-sub",children:[(0,t.jsx)("span",{className:"auth-ok",children:"✓"})," signed in as"," ",(0,t.jsx)("span",{className:"auth-email",children:m.user.email}),"."]}),(0,t.jsx)("div",{className:"auth-actions",children:(0,t.jsx)("button",{type:"button",className:"auth-btn primary",onClick:c,children:"continue"})})]})]})}):null}])},86616,e=>{"use strict";var t=e.i(29054);class a extends Error{kind;constructor(e,t){super(t),this.kind=e,this.name="RerunError"}}async function s(e){try{let s=await (0,t.fetchWithTimeout)("/api/audit/run",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({cli:e.cli.length>0?e.cli:void 0,since:"all"===e.since?void 0:e.since,noCache:!!e.noCache||void 0})});if(!s.ok&&409!==s.status){let e=await s.text().catch(()=>"");throw console.error("audit run failed:",s.status,e),new a("post_failed",`audit run failed (${s.status})`)}}catch(e){if(e instanceof a)throw e;throw console.error("audit run request failed:",e),new a((0,t.isAbortError)(e)?"timeout":"network","audit run request failed")}let s=0;for(;;){await new Promise(e=>setTimeout(e,1e3));let e=null;try{let a=await (0,t.fetchWithTimeout)("/api/audit/status",{cache:"no-store"});a.ok&&(e=await a.json())}catch{}if(null===e){if(++s>=10)throw new a("network","audit status poll lost the server");continue}if(s=0,!e.running){if(e.error)throw new a("post_failed",e.error);return}}}e.s(["RerunError",0,a,"triggerRun",0,s])},93237,e=>{"use strict";var t=e.i(43476),a=e.i(71645),s=e.i(95187);let n=(0,s.createServerReference)("000b18659612e9b17bee280c106f9faa0121effceb",s.callServer,void 0,s.findSourceMapURL,"getScheduledAuditAction"),i=(0,s.createServerReference)("404a84e2a89574746d288bda16b982eb96c52ce956",s.callServer,void 0,s.findSourceMapURL,"setAutoAuditAction"),r=(0,s.createServerReference)("40f335bda8d3c68676276af234cab49fbd7458fce8",s.callServer,void 0,s.findSourceMapURL,"setAuditIntervalAction");var l=e.i(86616),o=e.i(64237),c=e.i(55574),d=e.i(34713);function u(e){return new Date(e).toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}function h(e,t){let a=e-t;if(a<=0)return"now";let s=Math.floor(a/864e5),n=Math.floor(a%864e5/36e5);return s>0?n>0?`${s}d ${n}h`:`${s}d`:n>0?`${n}h`:`${Math.max(1,Math.floor(a/6e4))}m`}function m(e){return e.toLocaleString("en-US")}function f({label:e,value:a,sub:s,tone:n}){return(0,t.jsxs)("div",{className:"set-stat",children:[(0,t.jsx)("div",{className:"set-stat-label",children:e}),(0,t.jsx)("div",{className:`set-stat-value${n?` ${n}`:""}`,children:a}),(0,t.jsx)("div",{className:"set-stat-sub",children:s??" "})]})}function b({lastRunAtMs:e,nextDueAtMs:a,now:s}){if(null==e||null==a||a<=e)return null;let n=Math.min(100,Math.max(0,(s-e)/(a-e)*100));return(0,t.jsxs)("div",{className:"tape","aria-hidden":"true",children:[(0,t.jsxs)("div",{className:"tape-rail",children:[(0,t.jsx)("div",{className:"tape-fill",style:{width:`${n}%`}}),(0,t.jsx)("div",{className:"tape-now",style:{left:`${n}%`}})]}),(0,t.jsxs)("div",{className:"tape-ends",children:[(0,t.jsxs)("span",{children:["last scan · ",u(e)]}),(0,t.jsxs)("span",{className:"tape-next",children:["next · ",h(a,s)]})]})]})}function p({enabled:e,onChange:a,disabled:s,label:n}){return(0,t.jsx)("button",{type:"button",role:"switch","aria-checked":e,"aria-label":n,disabled:s,onClick:a,className:"sw","data-on":e?"true":"false",children:(0,t.jsx)("span",{className:"sw-knob"})})}let v=[{label:"reads",body:"every session transcript on disk — your prompts, the files your agents read and wrote, and command output."},{label:"runs",body:"entirely on this machine. the transcripts never leave it."},{label:"sends",body:"counts, redacted examples, and this machine's name — and only when a scan finds something harmful."}];e.s(["default",0,function({initial:e}){let[s,x]=(0,a.useState)(e),[g,y]=(0,a.useState)(e?.auto??!1),[w,j]=(0,a.useState)(e?.intervalDays??7),[k,N]=(0,a.useState)(!1),[S,C]=(0,a.useState)(!1),[M,$]=(0,a.useState)(!1),[A,E]=(0,a.useState)(null===e),[D,R]=(0,a.useState)(0),_=(0,a.useRef)(!0),T=(0,a.useRef)(null!==e),I=(0,a.useCallback)(async()=>{try{let e=await n();if(!_.current)return;x(e),T.current=!0,y(e.auto),j(e.intervalDays),R(Date.now()),E(!1)}catch{_.current&&!T.current&&E(!0)}},[]);(0,a.useEffect)(()=>(_.current=!0,I(),()=>{_.current=!1}),[I]),(0,a.useEffect)(()=>{let e=()=>void I();return window.addEventListener("focus",e),document.addEventListener("visibilitychange",e),()=>{window.removeEventListener("focus",e),document.removeEventListener("visibilitychange",e)}},[I]);let L=s?.signedInAs??null,F=s?.daemon==="running",O=s?.daemon==="unsupported-platform",P=s?.schedule??null,q=s?.lastScan??null,U=P?.lastExitCode!=null&&0!==P.lastExitCode&&75!==P.lastExitCode,W=(0,a.useCallback)(async()=>{N(!0);try{let e=await i(!0);if(!e.ok){if(y(!1),"unreachable"===e.reason)return void(0,c.toast)("could not reach the server. check your connection and try again.");await I(),$(!0),(0,c.toast)("that sign-in expired. one more code and it's on.");return}y(e.auto),(0,c.toast)("scheduled audits on."),await I()}catch{y(!1),(0,c.toast)("could not turn that on.")}finally{N(!1)}},[I]),B=(0,a.useCallback)(async()=>{if(g){N(!0);try{let e=await i(!1);e.ok&&y(e.auto),(0,c.toast)("scheduled audits off."),await I()}catch{(0,c.toast)("could not turn that off.")}finally{N(!1)}return}L?await W():$(!0)},[g,W,I,L]),J=(0,a.useCallback)(async e=>{N(!0);try{let t=await r(e);j(t.intervalDays),x(e=>e?{...e,intervalDays:t.intervalDays}:e),(0,c.toast)(`scanning every ${t.intervalDays} day${1===t.intervalDays?"":"s"}.`)}catch{j(s?.intervalDays??7),(0,c.toast)("could not save that.")}finally{N(!1)}},[s?.intervalDays]),K=(0,a.useCallback)(async()=>{N(!0);try{await fetch("/api/auth/logout",{method:"POST"}),(0,c.toast)("signed out. scans continue; digests pause."),await I()}catch{(0,c.toast)("could not sign out.")}finally{N(!1)}},[I]),H=(0,a.useCallback)(async()=>{if(!S){C(!0);try{await (0,l.triggerRun)({cli:[],since:"all",noCache:!1}),(0,c.toast)("scan complete."),await I()}catch(e){(0,c.toast)(e instanceof l.RerunError&&"timeout"===e.kind?"the scan is taking a while — it will finish in the background.":"the scan could not be completed.")}finally{C(!1)}}},[I,S]),z=(0,a.useCallback)(async e=>{$(!1),await I(),await W()},[W,I]),G=s?F?{value:"running",sub:null!=s.daemonStartedAtMs&&D>0?`up ${function(e){let t=Math.floor(e/864e5);if(t>0)return`${t}d`;let a=Math.floor(e/36e5);return a>0?`${a}h`:`${Math.max(1,Math.floor(e/6e4))}m`}(Math.max(0,D-s.daemonStartedAtMs))}`:"",tone:"ok"}:O?{value:"unavailable",sub:"not on this platform"}:"not-installed"===s.daemon?{value:"not installed",sub:"run failproofai config",tone:"warn"}:"unknown"===s.daemon?{value:"unknown",sub:"could not read it"}:{value:"stopped",sub:"run failproofai config",tone:"warn"}:{value:"…",sub:"reading"},Q=g?P?.nextDueAtMs==null?{value:"pending",sub:"after the next scan"}:{value:D>0?h(P.nextDueAtMs,D):"—",sub:u(P.nextDueAtMs)}:{value:"off",sub:"nothing scheduled"},V=q?{value:(0,d.formatRelativeTime)(Date.parse(q.finishedAt)),sub:null!=q.sessionsScanned?`${m(q.sessionsScanned)} sessions`:"scanned"}:{value:"none yet",sub:"run one below"},X=q?null==q.findings?{value:"—",sub:"unreadable"}:{value:m(q.findings),sub:"this scan",...q.findings>0?{tone:"warn"}:{}}:{value:"—",sub:"no scan yet"};return(0,t.jsxs)("main",{className:"report",children:[(0,t.jsxs)("section",{className:"section set-sec",children:[(0,t.jsxs)("div",{className:"set-mast",children:[(0,t.jsx)("h1",{className:"set-title",children:"settings"}),(0,t.jsx)("p",{className:"set-lede",children:"keeping watch, so you don't have to."})]}),A?(0,t.jsx)("div",{className:"set-console",children:(0,t.jsx)("div",{className:"set-cell",children:(0,t.jsxs)("p",{className:"set-warn",children:["could not read this machine's settings. check that the dashboard can reach ",(0,t.jsx)("code",{children:"~/.failproofai/config.json"}),"."]})})}):(0,t.jsxs)("div",{className:"set-console",children:[(0,t.jsxs)("div",{className:"set-stats",children:[(0,t.jsx)(f,{label:"daemon",...G}),(0,t.jsx)(f,{label:"next scan",...Q}),(0,t.jsx)(f,{label:"last scan",...V}),(0,t.jsx)(f,{label:"findings",...X})]}),(0,t.jsxs)("div",{className:"set-cols",children:[(0,t.jsxs)("div",{className:"set-cell set-config",children:[(0,t.jsx)("h2",{className:"set-cell-title",children:"scheduled audit"}),(0,t.jsxs)("div",{className:"set-row set-row-main",children:[(0,t.jsx)(p,{enabled:g,disabled:k||null===s,onChange:()=>void B(),label:g?"turn off scheduled audits":"turn on scheduled audits"}),(0,t.jsxs)("div",{className:"set-row-copy",children:[(0,t.jsx)("span",{className:"set-strong",children:g?"scanning on a schedule.":"scan on a schedule."}),(0,t.jsx)("span",{className:"set-dim",children:g?"you'll get an email only when a scan finds something.":"off. nothing runs and nothing is sent."})]})]}),(0,t.jsxs)("div",{className:"set-row set-row-interval",children:[(0,t.jsx)("span",{className:"set-dim",children:"scan every"}),(0,t.jsx)("input",{type:"number",className:"set-num",min:1,max:90,value:w,disabled:k||null===s,"aria-label":"days between scheduled scans",onChange:e=>j(Number(e.target.value)),onBlur:e=>{let t=Number(e.target.value);Number.isFinite(t)?t!==s?.intervalDays&&J(t):j(s?.intervalDays??7)}}),(0,t.jsx)("span",{className:"set-dim",children:"days"}),(0,t.jsxs)("span",{className:"set-hint",children:[1,"–",90]})]}),(0,t.jsx)("div",{className:"set-rule"}),(0,t.jsx)("div",{className:"set-row set-row-identity",children:L?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("span",{className:"set-dim",children:"reports go to"}),(0,t.jsx)("span",{className:"set-email",children:L.email}),(0,t.jsx)("button",{type:"button",className:"set-link",disabled:k,onClick:()=>void K(),children:"sign out"})]}):g?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("span",{className:"set-warn",children:"signed out — scans continue, digests are paused."}),(0,t.jsx)("button",{type:"button",className:"set-link",disabled:k,onClick:()=>$(!0),children:"sign in to resume"})]}):(0,t.jsx)("span",{className:"set-dim",children:"turning this on asks for an email, so there is somewhere to send the report."})}),g&&s&&!F&&(0,t.jsx)("p",{className:"set-warn",children:O?"the background service isn't available on this platform, so scheduled scans can't run here. you can still run one now.":"not-installed"===s.daemon?"the background service isn't installed, so nothing will run on the timer. install it with `failproofai config`.":"the background service is stopped, so nothing will run until it starts. repair it with `failproofai config`."}),U&&(0,t.jsxs)("p",{className:"set-warn",children:["the last scheduled scan exited ",P?.lastExitCode,". the next one will still run."]}),(0,t.jsx)("div",{className:"set-actions",children:(0,t.jsx)("button",{type:"button",className:"btn btn-press",disabled:S,onClick:()=>void H(),children:S?"[ scanning… ]":"[ run a scan now ]"})})]}),(0,t.jsxs)("div",{className:"set-cell set-how",children:[(0,t.jsx)("h2",{className:"set-cell-title",children:"how it works"}),(0,t.jsx)("dl",{className:"set-how-list",children:v.map(e=>(0,t.jsxs)("div",{className:"set-how-row",children:[(0,t.jsx)("dt",{className:"set-how-label",children:e.label}),(0,t.jsx)("dd",{className:"set-how-body",children:e.body})]},e.label))})]})]})]}),g&&D>0&&(0,t.jsx)(b,{lastRunAtMs:P?.lastRunAtMs??null,nextDueAtMs:P?.nextDueAtMs??null,now:D})]}),(0,t.jsx)(o.AuthDialog,{open:M,source:"settings_scheduled_audit",headline:"where should the report go?",subhead:"we'll send a one-time code to confirm.",onClose:()=>$(!1),onAuthed:e=>void z(e)})]})}],93237)},29054,e=>{"use strict";e.s(["fetchWithTimeout",0,function(e,t={},a=15e3){let s=AbortSignal.timeout(a),n=t.signal?AbortSignal.any([t.signal,s]):s;return fetch(e,{...t,signal:n})},"isAbortError",0,function(e){if(null===e||"object"!=typeof e)return!1;let t=e.name;return"AbortError"===t||"TimeoutError"===t}])},34713,e=>{"use strict";e.s(["formatDuration",0,function(e){if(e<1e3)return`${e}ms`;let t=Math.round(e/100);if(t<600)return`${(t/10).toFixed(1)}s`;let a=Math.round(e/1e3);if(a<3600){let e=Math.floor(a/60);return`${e}m ${a%60}s`}let s=Math.round(e/6e4),n=Math.floor(s/60);return`${n}h ${s%60}m`},"formatRelativeTime",0,function(e){let t=Date.now()-e;return t<6e4?`${Math.max(1,Math.floor(t/1e3))}s ago`:t<36e5?`${Math.floor(t/6e4)}m ago`:t<864e5?`${Math.floor(t/36e5)}h ago`:`${Math.floor(t/864e5)}d ago`}])}]);
1
+ (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,64237,e=>{"use strict";var t=e.i(43476),a=e.i(71645),s=e.i(12344),n=e.i(29054);let i=/^[^\s@]+@[^\s@]+\.[^\s@]+$/;function r(e){if((0,n.isAbortError)(e))return"request timed out. check your network and try again.";let t=e instanceof Error?e.message:String(e);return`network error: ${t}`}e.s(["AuthDialog",0,function({open:e,headline:l="where to route the reminder?",subhead:o="we'll send a one-time code to confirm.",onClose:c,onAuthed:d,source:u="unknown"}){let{capture:h}=(0,s.usePostHog)(),[m,f]=(0,a.useState)({kind:"email",error:null}),[b,p]=(0,a.useState)(!1),v=(0,a.useRef)(!1),x=(0,a.useRef)(null),g=(0,a.useRef)(null);(0,a.useEffect)(()=>{e&&(f({kind:"email",error:null}),p(!1),v.current=!1,h("audit_auth_dialog_opened",{source:u}))},[h,e,u]);let y=(0,a.useRef)(!1);(0,a.useEffect)(()=>{if(e){y.current=!0;return}y.current&&!v.current&&h("audit_auth_dialog_dismissed",{source:u,step:m.kind}),y.current=!1},[h,e,u,m.kind]),(0,a.useEffect)(()=>{if(!e)return;let t=setTimeout(()=>{"email"===m.kind?x.current?.focus():"code"===m.kind&&g.current?.focus()},50);return()=>clearTimeout(t)},[e,m.kind]),(0,a.useEffect)(()=>{if(!e)return;let t=e=>{"Escape"!==e.key||b||c()};return window.addEventListener("keydown",t),()=>window.removeEventListener("keydown",t)},[e,b,c]);let w="code"===m.kind&&m.resendIn>0;(0,a.useEffect)(()=>{if(!w)return;let e=setInterval(()=>{f(e=>"code"===e.kind?{...e,resendIn:Math.max(0,e.resendIn-1)}:e)},1e3);return()=>clearInterval(e)},[w]);let j=(0,a.useCallback)(async(e,t={})=>{let{isResend:a=!1}=t,s=e=>{a?f(t=>"code"===t.kind?{...t,error:e}:t):f({kind:"email",error:e})};p(!0);try{let t=await (0,n.fetchWithTimeout)("/api/auth/login-request",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({email:e})}),a=await t.json().catch(()=>({}));if(!t.ok){let e=a.message??"could not send code.";"rate_limited"===a.code&&void 0!==a.retry_after_secs?e=`too many tries. wait ${a.retry_after_secs}s and try again.`:"upstream_unreachable"===a.code&&(e="api-server unreachable. check your network."),s(e);return}f({kind:"code",email:e,error:null,expiresIn:a.expires_in??600,resendIn:a.resend_available_in??30})}catch(e){s(r(e))}finally{p(!1)}},[]),k=(0,a.useCallback)(async(e,t)=>{p(!0);try{let a=await (0,n.fetchWithTimeout)("/api/auth/login-verify",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({email:e,code:t})}),s=await a.json().catch(()=>({}));if(!a.ok||!s.authenticated||!s.user){let e=s.message??"invalid code.";"invalid_code"===s.code&&(e="wrong code, or it expired. try again."),f(t=>"code"===t.kind?{...t,error:e}:t);return}v.current=!0,h("audit_auth_dialog_succeeded",{source:u}),f({kind:"done",user:s.user}),d(s.user)}catch(t){let e=r(t);f(t=>"code"===t.kind?{...t,error:e}:t)}finally{p(!1)}},[h,d,u]),N=(0,a.useCallback)(async e=>{if(e.preventDefault(),b||"email"!==m.kind)return;let t=String(new FormData(e.currentTarget).get("email")??"").trim().toLowerCase();i.test(t)?await j(t):f({kind:"email",error:"that doesn't look like an email."})},[b,m,j]),S=(0,a.useCallback)(async e=>{if(e.preventDefault(),b||"code"!==m.kind)return;let t=String(new FormData(e.currentTarget).get("code")??"").trim();t.length<4||t.length>12?f(e=>"code"===e.kind?{...e,error:"code is 4–12 characters."}:e):await k(m.email,t)},[b,m,k]),C=(0,a.useCallback)(async()=>{"code"!==m.kind||m.resendIn>0||b||await j(m.email,{isResend:!0})},[m,b,j]);return e?(0,t.jsx)("div",{className:"auth-dialog-backdrop",role:"dialog","aria-modal":"true","aria-labelledby":"auth-dialog-title",onClick:e=>{b||e.target!==e.currentTarget||c()},children:(0,t.jsxs)("div",{className:"auth-dialog",children:[(0,t.jsx)("button",{type:"button",className:"auth-close",onClick:c,disabled:b,"aria-label":"close",children:"×"}),(0,t.jsx)("h2",{id:"auth-dialog-title",className:"auth-headline",children:l}),"email"===m.kind&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("p",{className:"auth-sub",children:o}),(0,t.jsxs)("form",{onSubmit:N,className:"auth-form",children:[(0,t.jsx)("input",{ref:x,id:"auth-dialog-email",name:"email",type:"email",autoComplete:"email",inputMode:"email",spellCheck:!1,placeholder:"you@yourdomain.com",disabled:b,className:"auth-input",required:!0}),m.error&&(0,t.jsx)("div",{className:"auth-error",children:m.error}),(0,t.jsxs)("div",{className:"auth-actions",children:[(0,t.jsx)("button",{type:"submit",className:"auth-btn primary",disabled:b,children:b?"sending…":"send code"}),(0,t.jsx)("button",{type:"button",className:"auth-btn",onClick:c,disabled:b,children:"cancel"})]})]})]}),"code"===m.kind&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)("p",{className:"auth-sub",children:["code sent to ",(0,t.jsx)("span",{className:"auth-email",children:m.email}),". expires in ",Math.ceil(m.expiresIn/60)," min."]}),(0,t.jsxs)("form",{onSubmit:S,className:"auth-form",children:[(0,t.jsx)("input",{ref:g,id:"auth-dialog-code",name:"code",type:"text",inputMode:"numeric",autoComplete:"one-time-code",spellCheck:!1,placeholder:"123456",disabled:b,className:"auth-input auth-input-code",maxLength:12,required:!0}),m.error&&(0,t.jsx)("div",{className:"auth-error",children:m.error}),(0,t.jsxs)("div",{className:"auth-actions",children:[(0,t.jsx)("button",{type:"submit",className:"auth-btn primary",disabled:b,children:b?"verifying…":"verify"}),(0,t.jsx)("button",{type:"button",className:"auth-btn",onClick:C,disabled:b||m.resendIn>0,children:m.resendIn>0?`resend in ${m.resendIn}s`:"resend code"})]}),(0,t.jsx)("button",{type:"button",className:"auth-back",onClick:()=>f({kind:"email",error:null}),disabled:b,children:"← use a different email"})]})]}),"done"===m.kind&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)("p",{className:"auth-sub",children:[(0,t.jsx)("span",{className:"auth-ok",children:"✓"})," signed in as"," ",(0,t.jsx)("span",{className:"auth-email",children:m.user.email}),"."]}),(0,t.jsx)("div",{className:"auth-actions",children:(0,t.jsx)("button",{type:"button",className:"auth-btn primary",onClick:c,children:"continue"})})]})]})}):null}])},86616,e=>{"use strict";var t=e.i(29054);class a extends Error{kind;constructor(e,t){super(t),this.kind=e,this.name="RerunError"}}async function s(e){try{let s=await (0,t.fetchWithTimeout)("/api/audit/run",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({cli:e.cli.length>0?e.cli:void 0,since:"all"===e.since?void 0:e.since,noCache:!!e.noCache||void 0})});if(!s.ok&&409!==s.status){let e=await s.text().catch(()=>"");throw console.error("audit run failed:",s.status,e),new a("post_failed",`audit run failed (${s.status})`)}}catch(e){if(e instanceof a)throw e;throw console.error("audit run request failed:",e),new a((0,t.isAbortError)(e)?"timeout":"network","audit run request failed")}let s=0;for(;;){await new Promise(e=>setTimeout(e,1e3));let e=null;try{let a=await (0,t.fetchWithTimeout)("/api/audit/status",{cache:"no-store"});a.ok&&(e=await a.json())}catch{}if(null===e){if(++s>=10)throw new a("network","audit status poll lost the server");continue}if(s=0,!e.running){if(e.error)throw new a("post_failed",e.error);return}}}e.s(["RerunError",0,a,"triggerRun",0,s])},93237,e=>{"use strict";var t=e.i(43476),a=e.i(71645),s=e.i(95187);let n=(0,s.createServerReference)("00aa430d336fe5b9f2c7e99dcd724a2140126b7df5",s.callServer,void 0,s.findSourceMapURL,"getScheduledAuditAction"),i=(0,s.createServerReference)("401a4233577ae78a8a9148d4d6fd172599a73d44e4",s.callServer,void 0,s.findSourceMapURL,"setAutoAuditAction"),r=(0,s.createServerReference)("400b31c249d9e9935f930f4c64cb4bcab3daae4a25",s.callServer,void 0,s.findSourceMapURL,"setAuditIntervalAction");var l=e.i(86616),o=e.i(64237),c=e.i(55574),d=e.i(34713);function u(e){return new Date(e).toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}function h(e,t){let a=e-t;if(a<=0)return"now";let s=Math.floor(a/864e5),n=Math.floor(a%864e5/36e5);return s>0?n>0?`${s}d ${n}h`:`${s}d`:n>0?`${n}h`:`${Math.max(1,Math.floor(a/6e4))}m`}function m(e){return e.toLocaleString("en-US")}function f({label:e,value:a,sub:s,tone:n}){return(0,t.jsxs)("div",{className:"set-stat",children:[(0,t.jsx)("div",{className:"set-stat-label",children:e}),(0,t.jsx)("div",{className:`set-stat-value${n?` ${n}`:""}`,children:a}),(0,t.jsx)("div",{className:"set-stat-sub",children:s??" "})]})}function b({lastRunAtMs:e,nextDueAtMs:a,now:s}){if(null==e||null==a||a<=e)return null;let n=Math.min(100,Math.max(0,(s-e)/(a-e)*100));return(0,t.jsxs)("div",{className:"tape","aria-hidden":"true",children:[(0,t.jsxs)("div",{className:"tape-rail",children:[(0,t.jsx)("div",{className:"tape-fill",style:{width:`${n}%`}}),(0,t.jsx)("div",{className:"tape-now",style:{left:`${n}%`}})]}),(0,t.jsxs)("div",{className:"tape-ends",children:[(0,t.jsxs)("span",{children:["last scan · ",u(e)]}),(0,t.jsxs)("span",{className:"tape-next",children:["next · ",h(a,s)]})]})]})}function p({enabled:e,onChange:a,disabled:s,label:n}){return(0,t.jsx)("button",{type:"button",role:"switch","aria-checked":e,"aria-label":n,disabled:s,onClick:a,className:"sw","data-on":e?"true":"false",children:(0,t.jsx)("span",{className:"sw-knob"})})}let v=[{label:"reads",body:"every session transcript on disk — your prompts, the files your agents read and wrote, and command output."},{label:"runs",body:"entirely on this machine. the transcripts never leave it."},{label:"sends",body:"counts, redacted examples, and this machine's name — and only when a scan finds something harmful."}];e.s(["default",0,function({initial:e}){let[s,x]=(0,a.useState)(e),[g,y]=(0,a.useState)(e?.auto??!1),[w,j]=(0,a.useState)(e?.intervalDays??7),[k,N]=(0,a.useState)(!1),[S,C]=(0,a.useState)(!1),[M,$]=(0,a.useState)(!1),[A,E]=(0,a.useState)(null===e),[D,R]=(0,a.useState)(0),_=(0,a.useRef)(!0),T=(0,a.useRef)(null!==e),I=(0,a.useCallback)(async()=>{try{let e=await n();if(!_.current)return;x(e),T.current=!0,y(e.auto),j(e.intervalDays),R(Date.now()),E(!1)}catch{_.current&&!T.current&&E(!0)}},[]);(0,a.useEffect)(()=>(_.current=!0,I(),()=>{_.current=!1}),[I]),(0,a.useEffect)(()=>{let e=()=>void I();return window.addEventListener("focus",e),document.addEventListener("visibilitychange",e),()=>{window.removeEventListener("focus",e),document.removeEventListener("visibilitychange",e)}},[I]);let L=s?.signedInAs??null,F=s?.daemon==="running",O=s?.daemon==="unsupported-platform",P=s?.schedule??null,q=s?.lastScan??null,U=P?.lastExitCode!=null&&0!==P.lastExitCode&&75!==P.lastExitCode,W=(0,a.useCallback)(async()=>{N(!0);try{let e=await i(!0);if(!e.ok){if(y(!1),"unreachable"===e.reason)return void(0,c.toast)("could not reach the server. check your connection and try again.");await I(),$(!0),(0,c.toast)("that sign-in expired. one more code and it's on.");return}y(e.auto),(0,c.toast)("scheduled audits on."),await I()}catch{y(!1),(0,c.toast)("could not turn that on.")}finally{N(!1)}},[I]),B=(0,a.useCallback)(async()=>{if(g){N(!0);try{let e=await i(!1);e.ok&&y(e.auto),(0,c.toast)("scheduled audits off."),await I()}catch{(0,c.toast)("could not turn that off.")}finally{N(!1)}return}L?await W():$(!0)},[g,W,I,L]),J=(0,a.useCallback)(async e=>{N(!0);try{let t=await r(e);j(t.intervalDays),x(e=>e?{...e,intervalDays:t.intervalDays}:e),(0,c.toast)(`scanning every ${t.intervalDays} day${1===t.intervalDays?"":"s"}.`)}catch{j(s?.intervalDays??7),(0,c.toast)("could not save that.")}finally{N(!1)}},[s?.intervalDays]),K=(0,a.useCallback)(async()=>{N(!0);try{await fetch("/api/auth/logout",{method:"POST"}),(0,c.toast)("signed out. scans continue; digests pause."),await I()}catch{(0,c.toast)("could not sign out.")}finally{N(!1)}},[I]),H=(0,a.useCallback)(async()=>{if(!S){C(!0);try{await (0,l.triggerRun)({cli:[],since:"all",noCache:!1}),(0,c.toast)("scan complete."),await I()}catch(e){(0,c.toast)(e instanceof l.RerunError&&"timeout"===e.kind?"the scan is taking a while — it will finish in the background.":"the scan could not be completed.")}finally{C(!1)}}},[I,S]),z=(0,a.useCallback)(async e=>{$(!1),await I(),await W()},[W,I]),G=s?F?{value:"running",sub:null!=s.daemonStartedAtMs&&D>0?`up ${function(e){let t=Math.floor(e/864e5);if(t>0)return`${t}d`;let a=Math.floor(e/36e5);return a>0?`${a}h`:`${Math.max(1,Math.floor(e/6e4))}m`}(Math.max(0,D-s.daemonStartedAtMs))}`:"",tone:"ok"}:O?{value:"unavailable",sub:"not on this platform"}:"not-installed"===s.daemon?{value:"not installed",sub:"run failproofai config",tone:"warn"}:"unknown"===s.daemon?{value:"unknown",sub:"could not read it"}:{value:"stopped",sub:"run failproofai config",tone:"warn"}:{value:"…",sub:"reading"},Q=g?P?.nextDueAtMs==null?{value:"pending",sub:"after the next scan"}:{value:D>0?h(P.nextDueAtMs,D):"—",sub:u(P.nextDueAtMs)}:{value:"off",sub:"nothing scheduled"},V=q?{value:(0,d.formatRelativeTime)(Date.parse(q.finishedAt)),sub:null!=q.sessionsScanned?`${m(q.sessionsScanned)} sessions`:"scanned"}:{value:"none yet",sub:"run one below"},X=q?null==q.findings?{value:"—",sub:"unreadable"}:{value:m(q.findings),sub:"this scan",...q.findings>0?{tone:"warn"}:{}}:{value:"—",sub:"no scan yet"};return(0,t.jsxs)("main",{className:"report",children:[(0,t.jsxs)("section",{className:"section set-sec",children:[(0,t.jsxs)("div",{className:"set-mast",children:[(0,t.jsx)("h1",{className:"set-title",children:"settings"}),(0,t.jsx)("p",{className:"set-lede",children:"keeping watch, so you don't have to."})]}),A?(0,t.jsx)("div",{className:"set-console",children:(0,t.jsx)("div",{className:"set-cell",children:(0,t.jsxs)("p",{className:"set-warn",children:["could not read this machine's settings. check that the dashboard can reach ",(0,t.jsx)("code",{children:"~/.failproofai/config.json"}),"."]})})}):(0,t.jsxs)("div",{className:"set-console",children:[(0,t.jsxs)("div",{className:"set-stats",children:[(0,t.jsx)(f,{label:"daemon",...G}),(0,t.jsx)(f,{label:"next scan",...Q}),(0,t.jsx)(f,{label:"last scan",...V}),(0,t.jsx)(f,{label:"findings",...X})]}),(0,t.jsxs)("div",{className:"set-cols",children:[(0,t.jsxs)("div",{className:"set-cell set-config",children:[(0,t.jsx)("h2",{className:"set-cell-title",children:"scheduled audit"}),(0,t.jsxs)("div",{className:"set-row set-row-main",children:[(0,t.jsx)(p,{enabled:g,disabled:k||null===s,onChange:()=>void B(),label:g?"turn off scheduled audits":"turn on scheduled audits"}),(0,t.jsxs)("div",{className:"set-row-copy",children:[(0,t.jsx)("span",{className:"set-strong",children:g?"scanning on a schedule.":"scan on a schedule."}),(0,t.jsx)("span",{className:"set-dim",children:g?"you'll get an email only when a scan finds something.":"off. nothing runs and nothing is sent."})]})]}),(0,t.jsxs)("div",{className:"set-row set-row-interval",children:[(0,t.jsx)("span",{className:"set-dim",children:"scan every"}),(0,t.jsx)("input",{type:"number",className:"set-num",min:1,max:90,value:w,disabled:k||null===s,"aria-label":"days between scheduled scans",onChange:e=>j(Number(e.target.value)),onBlur:e=>{let t=Number(e.target.value);Number.isFinite(t)?t!==s?.intervalDays&&J(t):j(s?.intervalDays??7)}}),(0,t.jsx)("span",{className:"set-dim",children:"days"}),(0,t.jsxs)("span",{className:"set-hint",children:[1,"–",90]})]}),(0,t.jsx)("div",{className:"set-rule"}),(0,t.jsx)("div",{className:"set-row set-row-identity",children:L?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("span",{className:"set-dim",children:"reports go to"}),(0,t.jsx)("span",{className:"set-email",children:L.email}),(0,t.jsx)("button",{type:"button",className:"set-link",disabled:k,onClick:()=>void K(),children:"sign out"})]}):g?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("span",{className:"set-warn",children:"signed out — scans continue, digests are paused."}),(0,t.jsx)("button",{type:"button",className:"set-link",disabled:k,onClick:()=>$(!0),children:"sign in to resume"})]}):(0,t.jsx)("span",{className:"set-dim",children:"turning this on asks for an email, so there is somewhere to send the report."})}),g&&s&&!F&&(0,t.jsx)("p",{className:"set-warn",children:O?"the background service isn't available on this platform, so scheduled scans can't run here. you can still run one now.":"not-installed"===s.daemon?"the background service isn't installed, so nothing will run on the timer. install it with `failproofai config`.":"the background service is stopped, so nothing will run until it starts. repair it with `failproofai config`."}),U&&(0,t.jsxs)("p",{className:"set-warn",children:["the last scheduled scan exited ",P?.lastExitCode,". the next one will still run."]}),(0,t.jsx)("div",{className:"set-actions",children:(0,t.jsx)("button",{type:"button",className:"btn btn-press",disabled:S,onClick:()=>void H(),children:S?"[ scanning… ]":"[ run a scan now ]"})})]}),(0,t.jsxs)("div",{className:"set-cell set-how",children:[(0,t.jsx)("h2",{className:"set-cell-title",children:"how it works"}),(0,t.jsx)("dl",{className:"set-how-list",children:v.map(e=>(0,t.jsxs)("div",{className:"set-how-row",children:[(0,t.jsx)("dt",{className:"set-how-label",children:e.label}),(0,t.jsx)("dd",{className:"set-how-body",children:e.body})]},e.label))})]})]})]}),g&&D>0&&(0,t.jsx)(b,{lastRunAtMs:P?.lastRunAtMs??null,nextDueAtMs:P?.nextDueAtMs??null,now:D})]}),(0,t.jsx)(o.AuthDialog,{open:M,source:"settings_scheduled_audit",headline:"where should the report go?",subhead:"we'll send a one-time code to confirm.",onClose:()=>$(!1),onAuthed:e=>void z(e)})]})}],93237)},29054,e=>{"use strict";e.s(["fetchWithTimeout",0,function(e,t={},a=15e3){let s=AbortSignal.timeout(a),n=t.signal?AbortSignal.any([t.signal,s]):s;return fetch(e,{...t,signal:n})},"isAbortError",0,function(e){if(null===e||"object"!=typeof e)return!1;let t=e.name;return"AbortError"===t||"TimeoutError"===t}])},34713,e=>{"use strict";e.s(["formatDuration",0,function(e){if(e<1e3)return`${e}ms`;let t=Math.round(e/100);if(t<600)return`${(t/10).toFixed(1)}s`;let a=Math.round(e/1e3);if(a<3600){let e=Math.floor(a/60);return`${e}m ${a%60}s`}let s=Math.round(e/6e4),n=Math.floor(s/60);return`${n}h ${s%60}m`},"formatRelativeTime",0,function(e){let t=Date.now()-e;return t<6e4?`${Math.max(1,Math.floor(t/1e3))}s ago`:t<36e5?`${Math.floor(t/6e4)}m ago`:t<864e5?`${Math.floor(t/36e5)}h ago`:`${Math.floor(t/864e5)}d ago`}])}]);
@@ -1 +1 @@
1
- (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,77003,e=>{"use strict";var t=e.i(95187);let r=(0,t.createServerReference)("00eb2c42451cea80fb88a3d80076ecc96edfab5a2e",t.callServer,void 0,t.findSourceMapURL,"getTelemetryConfig");e.s(["getTelemetryConfig",0,r])},53348,e=>{"use strict";var t=e.i(43476),r=e.i(71645),n=e.i(77003),l=e.i(9969);e.s(["default",0,function({error:e,reset:a}){return(0,r.useEffect)(()=>{(0,n.getTelemetryConfig)().then(t=>{(0,l.setClientTelemetryConfig)(t),(0,l.captureClientEvent)("client_error",{error_message:e.message,error_name:e.name,error_digest:e.digest,boundary:"global"})}).catch(()=>{})},[e]),(0,t.jsx)("html",{children:(0,t.jsx)("body",{children:(0,t.jsx)("main",{style:{minHeight:"100vh",display:"flex",alignItems:"center",justifyContent:"center",background:"#031035",color:"#f8fafc",fontFamily:"system-ui, sans-serif"},children:(0,t.jsxs)("div",{style:{textAlign:"center",padding:"2rem",border:"1px solid rgba(239,68,68,0.4)",borderRadius:"0.5rem",maxWidth:"500px"},children:[(0,t.jsx)("h2",{style:{color:"#ef4444",marginBottom:"0.5rem",fontSize:"1.25rem"},children:"Something went wrong"}),(0,t.jsx)("p",{style:{color:"#94a3b8",marginBottom:"1.5rem"},children:e.message||"An unexpected error occurred."}),(0,t.jsx)("button",{onClick:a,style:{padding:"0.5rem 1.25rem",background:"#3b82f6",color:"white",border:"none",borderRadius:"0.375rem",cursor:"pointer",fontSize:"0.875rem"},children:"Try again"})]})})})})}])},9969,e=>{"use strict";let t=null;e.s(["captureClientEvent",0,function(e,r){if(!t||!t.enabled)return;let n=JSON.stringify({api_key:t.apiKey,event:e,distinct_id:t.distinctId,properties:{...r,$lib:"failproofai-web",failproofai_version:t.version,product:"failproofai-oss",$current_url:window.location.href,$pathname:window.location.pathname}});fetch(t.host.replace(/\/+$/,"")+"/capture/",{method:"POST",headers:{"Content-Type":"application/json"},body:n,keepalive:!0,signal:AbortSignal.timeout(5e3)}).catch(()=>{})},"setClientTelemetryConfig",0,function(e){t=e}],9969)},95187,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0});var n={callServer:function(){return a.callServer},createServerReference:function(){return u.createServerReference},findSourceMapURL:function(){return o.findSourceMapURL}};for(var l in n)Object.defineProperty(r,l,{enumerable:!0,get:n[l]});let a=e.r(32120),o=e.r(92245),u=e.r(35326)},28298,(e,t,r)=>{"use strict";e.i(47167),Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"useRouterBFCache",{enumerable:!0,get:function(){return l}});let n=e.r(71645);function l(e,t,r){let[l,a]=(0,n.useState)(()=>({tree:e,cacheNode:t,stateKey:r,next:null}));if(l.tree===e)return l;let o={tree:e,cacheNode:t,stateKey:r,next:null},u=1,i=l,s=o;for(;null!==i&&u<1;){if(i.stateKey===r){s.next=i.next;break}{u++;let e={tree:i.tree,cacheNode:i.cacheNode,stateKey:i.stateKey,next:null};s.next=e,s=e}i=i.next}return a(o),o}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},47257,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"ClientPageRoot",{enumerable:!0,get:function(){return s}});let n=e.r(43476),l=e.r(8372),a=e.r(71645),o=e.r(33906),u=e.r(61994),i=e.r(15783);function s({Component:e,serverProvidedParams:t}){let r,d;if(null!==t)r=t.searchParams,d=t.params;else{let e=(0,a.use)(l.LayoutRouterContext);d=null!==e?e.parentParams:{},r=(0,o.urlSearchParamsToParsedUrlQuery)((0,a.use)(u.SearchParamsContext))}let c=(0,i.createClientSearchParams)(r),f=(0,i.createClientParams)(d);return(0,n.jsx)(e,{params:f,searchParams:c})}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},92825,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"ClientSegmentRoot",{enumerable:!0,get:function(){return u}});let n=e.r(43476),l=e.r(8372),a=e.r(71645),o=e.r(15783);function u({Component:e,slots:t,serverProvidedParams:r}){let i;if(null!==r)i=r.params;else{let e=(0,a.use)(l.LayoutRouterContext);i=null!==e?e.parentParams:{}}let s=(0,o.createClientParams)(i);return(0,n.jsx)(e,{...t,params:s})}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},68017,(e,t,r)=>{"use strict";e.i(47167),Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"HTTPAccessFallbackBoundary",{enumerable:!0,get:function(){return d}});let n=e.r(90809),l=e.r(43476),a=n._(e.r(71645)),o=e.r(90373),u=e.r(54394),i=e.r(8372);class s extends a.default.Component{constructor(e){super(e),this.state={triggeredStatus:void 0,previousPathname:e.pathname}}componentDidCatch(){}static getDerivedStateFromError(e){if((0,u.isHTTPAccessFallbackError)(e))return{triggeredStatus:(0,u.getAccessFallbackHTTPStatus)(e)};throw e}static getDerivedStateFromProps(e,t){return e.pathname!==t.previousPathname&&t.triggeredStatus?{triggeredStatus:void 0,previousPathname:e.pathname}:{triggeredStatus:t.triggeredStatus,previousPathname:e.pathname}}render(){let{notFound:e,forbidden:t,unauthorized:r,children:n}=this.props,{triggeredStatus:a}=this.state,o={[u.HTTPAccessErrorStatus.NOT_FOUND]:e,[u.HTTPAccessErrorStatus.FORBIDDEN]:t,[u.HTTPAccessErrorStatus.UNAUTHORIZED]:r};if(a){let i=a===u.HTTPAccessErrorStatus.NOT_FOUND&&e,s=a===u.HTTPAccessErrorStatus.FORBIDDEN&&t,d=a===u.HTTPAccessErrorStatus.UNAUTHORIZED&&r;return i||s||d?(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)("meta",{name:"robots",content:"noindex"}),!1,o[a]]}):n}return n}}function d({notFound:e,forbidden:t,unauthorized:r,children:n}){let u=(0,o.useUntrackedPathname)(),c=(0,a.useContext)(i.MissingSlotContext);return e||t||r?(0,l.jsx)(s,{pathname:u,notFound:e,forbidden:t,unauthorized:r,missingSlots:c,children:n}):(0,l.jsx)(l.Fragment,{children:n})}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},22976,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0});var n={InstantValidationBoundaryContext:function(){return a},PlaceValidationBoundaryBelowThisLevel:function(){return o},RenderValidationBoundaryAtThisLevel:function(){return u},SlotMarker:function(){return i}};for(var l in n)Object.defineProperty(r,l,{enumerable:!0,get:n[l]});let a=null,o=null,u=null,i=null;("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},77694,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0});var n={InstantValidationBoundaryContext:function(){return a.InstantValidationBoundaryContext},PlaceValidationBoundaryBelowThisLevel:function(){return a.PlaceValidationBoundaryBelowThisLevel},RenderValidationBoundaryAtThisLevel:function(){return a.RenderValidationBoundaryAtThisLevel},SlotMarker:function(){return a.SlotMarker}};for(var l in n)Object.defineProperty(r,l,{enumerable:!0,get:n[l]});let a=e.r(22976);("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},39756,(e,t,r)=>{"use strict";e.i(47167),Object.defineProperty(r,"__esModule",{value:!0});var n={LoadingBoundaryProvider:function(){return C},default:function(){return S}};for(var l in n)Object.defineProperty(r,l,{enumerable:!0,get:n[l]});let a=e.r(55682),o=e.r(90809),u=e.r(43476),i=o._(e.r(71645)),s=a._(e.r(74080)),d=e.r(8372),c=e.r(1244),f=e.r(72383),p=e.r(91915),m=e.r(58442),y=e.r(68017);e.r(77694);let b=e.r(70725),h=e.r(28298);e.r(74180);let g=e.r(61994),_=e.r(33906),v=e.r(95871);s.default.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;function P(e,t,r){let n=e.getClientRects();if(0===n.length)return 0;let l=1/0;for(let e=0;e<n.length;e++){let t=n[e];t.top<l&&(l=t.top)}return l>=r()&&l<=t?1:2}i.default.Component;let j=function(e){let t=i.default.useRef(null);return(0,i.useLayoutEffect)(()=>{let{focusAndScrollRef:r,cacheNode:n}=e,l=r.forceScroll?r.scrollRef:n.scrollRef;if(null===l||!l.current)return;let a=null,o=r.hashFragment;if(o){var u;if(null===(a="top"===(u=o)?document.body:document.getElementById(u)??document.getElementsByName(u)[0]??null)){l.current=!1,r.onlyHashChange=!1,r.hashFragment=null;return}}else a=t.current;if(null===a)return;let i=!1;(0,p.disableSmoothScrollDuringRouteTransition)(()=>{let e=document.documentElement,t=null,r=null,n=null,u=()=>{var r,l;let a,o;return null===n&&(r=e,l=t,n=!Number.isFinite(o=Number.parseFloat(a=getComputedStyle(r).scrollPaddingTop))||o<0?0:a.endsWith("px")?o:a.endsWith("%")?o/100*l:0),n};(o||(t=e.clientHeight,0!==(r=P(a,t,u))))&&((i=!0,l.current=!1,o)?a.scrollIntoView():1!==r&&(e.scrollTop=0,2===P(a,t,u)&&a.scrollIntoView()))},{dontForceLayout:!0,onlyHashChange:r.onlyHashChange}),i&&(r.onlyHashChange=!1,r.hashFragment=null)},void 0),(0,u.jsx)(i.Fragment,{ref:t,children:e.children})};function x({children:e,cacheNode:t}){let r=(0,i.useContext)(d.GlobalLayoutRouterContext);if(!r)throw Object.defineProperty(Error("invariant global layout router not mounted"),"__NEXT_ERROR_CODE",{value:"E473",enumerable:!1,configurable:!0});return(0,u.jsx)(j,{focusAndScrollRef:r.focusAndScrollRef,cacheNode:t,children:e})}function O({tree:e,segmentPath:t,debugNameContext:r,cacheNode:n,params:l,url:a,isActive:o}){let s,f=(0,i.useContext)(d.GlobalLayoutRouterContext);if((0,i.useContext)(g.NavigationPromisesContext),!f)throw Object.defineProperty(Error("invariant global layout router not mounted"),"__NEXT_ERROR_CODE",{value:"E473",enumerable:!1,configurable:!0});let p=null!==n?n:(0,i.use)(c.unresolvedThenable),m=null!==p.prefetchRsc?p.prefetchRsc:p.rsc,y=(0,i.useDeferredValue)(p.rsc,m);if((0,v.isDeferredRsc)(y)){let e=(0,i.use)(y);null===e&&(0,i.use)(c.unresolvedThenable),s=e}else null===y&&(0,i.use)(c.unresolvedThenable),s=y;let b=s;return(0,u.jsx)(d.LayoutRouterContext.Provider,{value:{parentTree:e,parentCacheNode:p,parentSegmentPath:t,parentParams:l,parentLoadingData:null,debugNameContext:r,url:a,isActive:o},children:b})}function C({loading:e,children:t}){let r=(0,i.use)(d.LayoutRouterContext);return null===r?t:(0,u.jsx)(d.LayoutRouterContext.Provider,{value:{parentTree:r.parentTree,parentCacheNode:r.parentCacheNode,parentSegmentPath:r.parentSegmentPath,parentParams:r.parentParams,parentLoadingData:e,debugNameContext:r.debugNameContext,url:r.url,isActive:r.isActive},children:t})}function R({name:e,loading:t,children:r}){if(null!==t){let n=t[0],l=t[1],a=t[2];return(0,u.jsx)(i.Suspense,{name:e,fallback:(0,u.jsxs)(u.Fragment,{children:[l,a,n]}),children:r})}return(0,u.jsx)(u.Fragment,{children:r})}function S({parallelRouterKey:e,error:t,errorStyles:r,errorScripts:n,templateStyles:l,templateScripts:a,template:o,notFound:s,forbidden:p,unauthorized:g,segmentViewBoundaries:v}){let P=(0,i.useContext)(d.LayoutRouterContext);if(!P)throw Object.defineProperty(Error("invariant expected layout router to be mounted"),"__NEXT_ERROR_CODE",{value:"E56",enumerable:!1,configurable:!0});let{parentTree:j,parentCacheNode:C,parentSegmentPath:T,parentParams:M,parentLoadingData:E,url:N,isActive:F,debugNameContext:A}=P,B=j[0],L=null===T?[e]:T.concat([B,e]),D=j[1][e],w=C.slots;(void 0===D||null===w)&&(0,i.use)(c.unresolvedThenable);let H=D[0],k=w[e]??null,U=(0,b.createRouterCacheKey)(H,!0),I=(0,h.useRouterBFCache)(D,k,U),V=[];do{let e=I.tree,i=I.cacheNode,c=I.stateKey,b=e[0],h=M;if(Array.isArray(b)){let e=b[0],t=b[1],r=b[2],n=(0,_.getParamValueFromCacheKey)(t,r);null!==n&&(h={...M,[e]:n})}let v=function(e){if("/"===e)return"/";if("string"==typeof e)if("(__SLOT__)"===e)return;else return e+"/";return e[1]+"/"}(b),P=v??A,j=void 0===v?void 0:A,C=(0,u.jsxs)(x,{cacheNode:i,children:[(0,u.jsx)(f.ErrorBoundary,{errorComponent:t,errorStyles:r,errorScripts:n,children:(0,u.jsx)(R,{name:j,loading:E,children:(0,u.jsx)(y.HTTPAccessFallbackBoundary,{notFound:s,forbidden:p,unauthorized:g,children:(0,u.jsxs)(m.RedirectBoundary,{children:[(0,u.jsx)(O,{url:N,tree:e,params:h,cacheNode:i,segmentPath:L,debugNameContext:P,isActive:F&&c===U}),null]})})})}),null]}),S=(0,u.jsxs)(d.TemplateContext.Provider,{value:C,children:[l,a,o]},c);V.push(S),I=I.next}while(null!==I)return V}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},37457,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"default",{enumerable:!0,get:function(){return u}});let n=e.r(90809),l=e.r(43476),a=n._(e.r(71645)),o=e.r(8372);function u(){let e=(0,a.useContext)(o.TemplateContext);return(0,l.jsx)(l.Fragment,{children:e})}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},6831,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"createRenderParamsFromClient",{enumerable:!0,get:function(){return l}});let n=new WeakMap;function l(e){let t=n.get(e);if(t)return t;let r=Promise.resolve(e);return n.set(e,r),r}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},14193,(e,t,r)=>{"use strict";e.i(47167),Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"createRenderParamsFromClient",{enumerable:!0,get:function(){return n}});let n=e.r(6831).createRenderParamsFromClient;("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},93504,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"createRenderSearchParamsFromClient",{enumerable:!0,get:function(){return l}});let n=new WeakMap;function l(e){let t=n.get(e);if(t)return t;let r=Promise.resolve(e);return n.set(e,r),r}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},66996,(e,t,r)=>{"use strict";e.i(47167),Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"createRenderSearchParamsFromClient",{enumerable:!0,get:function(){return n}});let n=e.r(93504).createRenderSearchParamsFromClient;("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},15783,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0});var n={createClientParams:function(){return a.createRenderParamsFromClient},createClientSearchParams:function(){return o.createRenderSearchParamsFromClient}};for(var l in n)Object.defineProperty(r,l,{enumerable:!0,get:n[l]});let a=e.r(14193),o=e.r(66996);("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},27201,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"IconMark",{enumerable:!0,get:function(){return l}});let n=e.r(43476),l=()=>"u">typeof window?null:(0,n.jsx)("meta",{name:"«nxt-icon»"})},91915,(e,t,r)=>{"use strict";function n(e,t={}){if(t.onlyHashChange)return void e();let r=document.documentElement;if("smooth"!==r.dataset.scrollBehavior)return void e();let l=r.style.scrollBehavior;r.style.scrollBehavior="auto",t.dontForceLayout||r.getClientRects(),e(),r.style.scrollBehavior=l}e.i(47167),Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"disableSmoothScrollDuringRouteTransition",{enumerable:!0,get:function(){return n}})}]);
1
+ (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,20706,e=>{"use strict";var t=e.i(95187);let r=(0,t.createServerReference)("00b801c035726aaa9d297e34f35258369a37177149",t.callServer,void 0,t.findSourceMapURL,"getTelemetryConfig");e.s(["getTelemetryConfig",0,r])},53348,e=>{"use strict";var t=e.i(43476),r=e.i(71645),n=e.i(20706),l=e.i(9969);e.s(["default",0,function({error:e,reset:a}){return(0,r.useEffect)(()=>{(0,n.getTelemetryConfig)().then(t=>{(0,l.setClientTelemetryConfig)(t),(0,l.captureClientEvent)("client_error",{error_message:e.message,error_name:e.name,error_digest:e.digest,boundary:"global"})}).catch(()=>{})},[e]),(0,t.jsx)("html",{children:(0,t.jsx)("body",{children:(0,t.jsx)("main",{style:{minHeight:"100vh",display:"flex",alignItems:"center",justifyContent:"center",background:"#031035",color:"#f8fafc",fontFamily:"system-ui, sans-serif"},children:(0,t.jsxs)("div",{style:{textAlign:"center",padding:"2rem",border:"1px solid rgba(239,68,68,0.4)",borderRadius:"0.5rem",maxWidth:"500px"},children:[(0,t.jsx)("h2",{style:{color:"#ef4444",marginBottom:"0.5rem",fontSize:"1.25rem"},children:"Something went wrong"}),(0,t.jsx)("p",{style:{color:"#94a3b8",marginBottom:"1.5rem"},children:e.message||"An unexpected error occurred."}),(0,t.jsx)("button",{onClick:a,style:{padding:"0.5rem 1.25rem",background:"#3b82f6",color:"white",border:"none",borderRadius:"0.375rem",cursor:"pointer",fontSize:"0.875rem"},children:"Try again"})]})})})})}])},9969,e=>{"use strict";let t=null;e.s(["captureClientEvent",0,function(e,r){if(!t||!t.enabled)return;let n=JSON.stringify({api_key:t.apiKey,event:e,distinct_id:t.distinctId,properties:{...r,$lib:"failproofai-web",failproofai_version:t.version,product:"failproofai-oss",$current_url:window.location.href,$pathname:window.location.pathname}});fetch(t.host.replace(/\/+$/,"")+"/capture/",{method:"POST",headers:{"Content-Type":"application/json"},body:n,keepalive:!0,signal:AbortSignal.timeout(5e3)}).catch(()=>{})},"setClientTelemetryConfig",0,function(e){t=e}],9969)},95187,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0});var n={callServer:function(){return a.callServer},createServerReference:function(){return u.createServerReference},findSourceMapURL:function(){return o.findSourceMapURL}};for(var l in n)Object.defineProperty(r,l,{enumerable:!0,get:n[l]});let a=e.r(32120),o=e.r(92245),u=e.r(35326)},28298,(e,t,r)=>{"use strict";e.i(47167),Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"useRouterBFCache",{enumerable:!0,get:function(){return l}});let n=e.r(71645);function l(e,t,r){let[l,a]=(0,n.useState)(()=>({tree:e,cacheNode:t,stateKey:r,next:null}));if(l.tree===e)return l;let o={tree:e,cacheNode:t,stateKey:r,next:null},u=1,i=l,s=o;for(;null!==i&&u<1;){if(i.stateKey===r){s.next=i.next;break}{u++;let e={tree:i.tree,cacheNode:i.cacheNode,stateKey:i.stateKey,next:null};s.next=e,s=e}i=i.next}return a(o),o}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},47257,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"ClientPageRoot",{enumerable:!0,get:function(){return s}});let n=e.r(43476),l=e.r(8372),a=e.r(71645),o=e.r(33906),u=e.r(61994),i=e.r(15783);function s({Component:e,serverProvidedParams:t}){let r,d;if(null!==t)r=t.searchParams,d=t.params;else{let e=(0,a.use)(l.LayoutRouterContext);d=null!==e?e.parentParams:{},r=(0,o.urlSearchParamsToParsedUrlQuery)((0,a.use)(u.SearchParamsContext))}let c=(0,i.createClientSearchParams)(r),f=(0,i.createClientParams)(d);return(0,n.jsx)(e,{params:f,searchParams:c})}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},92825,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"ClientSegmentRoot",{enumerable:!0,get:function(){return u}});let n=e.r(43476),l=e.r(8372),a=e.r(71645),o=e.r(15783);function u({Component:e,slots:t,serverProvidedParams:r}){let i;if(null!==r)i=r.params;else{let e=(0,a.use)(l.LayoutRouterContext);i=null!==e?e.parentParams:{}}let s=(0,o.createClientParams)(i);return(0,n.jsx)(e,{...t,params:s})}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},68017,(e,t,r)=>{"use strict";e.i(47167),Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"HTTPAccessFallbackBoundary",{enumerable:!0,get:function(){return d}});let n=e.r(90809),l=e.r(43476),a=n._(e.r(71645)),o=e.r(90373),u=e.r(54394),i=e.r(8372);class s extends a.default.Component{constructor(e){super(e),this.state={triggeredStatus:void 0,previousPathname:e.pathname}}componentDidCatch(){}static getDerivedStateFromError(e){if((0,u.isHTTPAccessFallbackError)(e))return{triggeredStatus:(0,u.getAccessFallbackHTTPStatus)(e)};throw e}static getDerivedStateFromProps(e,t){return e.pathname!==t.previousPathname&&t.triggeredStatus?{triggeredStatus:void 0,previousPathname:e.pathname}:{triggeredStatus:t.triggeredStatus,previousPathname:e.pathname}}render(){let{notFound:e,forbidden:t,unauthorized:r,children:n}=this.props,{triggeredStatus:a}=this.state,o={[u.HTTPAccessErrorStatus.NOT_FOUND]:e,[u.HTTPAccessErrorStatus.FORBIDDEN]:t,[u.HTTPAccessErrorStatus.UNAUTHORIZED]:r};if(a){let i=a===u.HTTPAccessErrorStatus.NOT_FOUND&&e,s=a===u.HTTPAccessErrorStatus.FORBIDDEN&&t,d=a===u.HTTPAccessErrorStatus.UNAUTHORIZED&&r;return i||s||d?(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)("meta",{name:"robots",content:"noindex"}),!1,o[a]]}):n}return n}}function d({notFound:e,forbidden:t,unauthorized:r,children:n}){let u=(0,o.useUntrackedPathname)(),c=(0,a.useContext)(i.MissingSlotContext);return e||t||r?(0,l.jsx)(s,{pathname:u,notFound:e,forbidden:t,unauthorized:r,missingSlots:c,children:n}):(0,l.jsx)(l.Fragment,{children:n})}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},22976,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0});var n={InstantValidationBoundaryContext:function(){return a},PlaceValidationBoundaryBelowThisLevel:function(){return o},RenderValidationBoundaryAtThisLevel:function(){return u},SlotMarker:function(){return i}};for(var l in n)Object.defineProperty(r,l,{enumerable:!0,get:n[l]});let a=null,o=null,u=null,i=null;("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},77694,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0});var n={InstantValidationBoundaryContext:function(){return a.InstantValidationBoundaryContext},PlaceValidationBoundaryBelowThisLevel:function(){return a.PlaceValidationBoundaryBelowThisLevel},RenderValidationBoundaryAtThisLevel:function(){return a.RenderValidationBoundaryAtThisLevel},SlotMarker:function(){return a.SlotMarker}};for(var l in n)Object.defineProperty(r,l,{enumerable:!0,get:n[l]});let a=e.r(22976);("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},39756,(e,t,r)=>{"use strict";e.i(47167),Object.defineProperty(r,"__esModule",{value:!0});var n={LoadingBoundaryProvider:function(){return C},default:function(){return S}};for(var l in n)Object.defineProperty(r,l,{enumerable:!0,get:n[l]});let a=e.r(55682),o=e.r(90809),u=e.r(43476),i=o._(e.r(71645)),s=a._(e.r(74080)),d=e.r(8372),c=e.r(1244),f=e.r(72383),p=e.r(91915),m=e.r(58442),y=e.r(68017);e.r(77694);let b=e.r(70725),h=e.r(28298);e.r(74180);let g=e.r(61994),_=e.r(33906),v=e.r(95871);s.default.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;function P(e,t,r){let n=e.getClientRects();if(0===n.length)return 0;let l=1/0;for(let e=0;e<n.length;e++){let t=n[e];t.top<l&&(l=t.top)}return l>=r()&&l<=t?1:2}i.default.Component;let j=function(e){let t=i.default.useRef(null);return(0,i.useLayoutEffect)(()=>{let{focusAndScrollRef:r,cacheNode:n}=e,l=r.forceScroll?r.scrollRef:n.scrollRef;if(null===l||!l.current)return;let a=null,o=r.hashFragment;if(o){var u;if(null===(a="top"===(u=o)?document.body:document.getElementById(u)??document.getElementsByName(u)[0]??null)){l.current=!1,r.onlyHashChange=!1,r.hashFragment=null;return}}else a=t.current;if(null===a)return;let i=!1;(0,p.disableSmoothScrollDuringRouteTransition)(()=>{let e=document.documentElement,t=null,r=null,n=null,u=()=>{var r,l;let a,o;return null===n&&(r=e,l=t,n=!Number.isFinite(o=Number.parseFloat(a=getComputedStyle(r).scrollPaddingTop))||o<0?0:a.endsWith("px")?o:a.endsWith("%")?o/100*l:0),n};(o||(t=e.clientHeight,0!==(r=P(a,t,u))))&&((i=!0,l.current=!1,o)?a.scrollIntoView():1!==r&&(e.scrollTop=0,2===P(a,t,u)&&a.scrollIntoView()))},{dontForceLayout:!0,onlyHashChange:r.onlyHashChange}),i&&(r.onlyHashChange=!1,r.hashFragment=null)},void 0),(0,u.jsx)(i.Fragment,{ref:t,children:e.children})};function x({children:e,cacheNode:t}){let r=(0,i.useContext)(d.GlobalLayoutRouterContext);if(!r)throw Object.defineProperty(Error("invariant global layout router not mounted"),"__NEXT_ERROR_CODE",{value:"E473",enumerable:!1,configurable:!0});return(0,u.jsx)(j,{focusAndScrollRef:r.focusAndScrollRef,cacheNode:t,children:e})}function O({tree:e,segmentPath:t,debugNameContext:r,cacheNode:n,params:l,url:a,isActive:o}){let s,f=(0,i.useContext)(d.GlobalLayoutRouterContext);if((0,i.useContext)(g.NavigationPromisesContext),!f)throw Object.defineProperty(Error("invariant global layout router not mounted"),"__NEXT_ERROR_CODE",{value:"E473",enumerable:!1,configurable:!0});let p=null!==n?n:(0,i.use)(c.unresolvedThenable),m=null!==p.prefetchRsc?p.prefetchRsc:p.rsc,y=(0,i.useDeferredValue)(p.rsc,m);if((0,v.isDeferredRsc)(y)){let e=(0,i.use)(y);null===e&&(0,i.use)(c.unresolvedThenable),s=e}else null===y&&(0,i.use)(c.unresolvedThenable),s=y;let b=s;return(0,u.jsx)(d.LayoutRouterContext.Provider,{value:{parentTree:e,parentCacheNode:p,parentSegmentPath:t,parentParams:l,parentLoadingData:null,debugNameContext:r,url:a,isActive:o},children:b})}function C({loading:e,children:t}){let r=(0,i.use)(d.LayoutRouterContext);return null===r?t:(0,u.jsx)(d.LayoutRouterContext.Provider,{value:{parentTree:r.parentTree,parentCacheNode:r.parentCacheNode,parentSegmentPath:r.parentSegmentPath,parentParams:r.parentParams,parentLoadingData:e,debugNameContext:r.debugNameContext,url:r.url,isActive:r.isActive},children:t})}function R({name:e,loading:t,children:r}){if(null!==t){let n=t[0],l=t[1],a=t[2];return(0,u.jsx)(i.Suspense,{name:e,fallback:(0,u.jsxs)(u.Fragment,{children:[l,a,n]}),children:r})}return(0,u.jsx)(u.Fragment,{children:r})}function S({parallelRouterKey:e,error:t,errorStyles:r,errorScripts:n,templateStyles:l,templateScripts:a,template:o,notFound:s,forbidden:p,unauthorized:g,segmentViewBoundaries:v}){let P=(0,i.useContext)(d.LayoutRouterContext);if(!P)throw Object.defineProperty(Error("invariant expected layout router to be mounted"),"__NEXT_ERROR_CODE",{value:"E56",enumerable:!1,configurable:!0});let{parentTree:j,parentCacheNode:C,parentSegmentPath:T,parentParams:M,parentLoadingData:E,url:N,isActive:F,debugNameContext:A}=P,B=j[0],L=null===T?[e]:T.concat([B,e]),D=j[1][e],w=C.slots;(void 0===D||null===w)&&(0,i.use)(c.unresolvedThenable);let H=D[0],k=w[e]??null,U=(0,b.createRouterCacheKey)(H,!0),I=(0,h.useRouterBFCache)(D,k,U),V=[];do{let e=I.tree,i=I.cacheNode,c=I.stateKey,b=e[0],h=M;if(Array.isArray(b)){let e=b[0],t=b[1],r=b[2],n=(0,_.getParamValueFromCacheKey)(t,r);null!==n&&(h={...M,[e]:n})}let v=function(e){if("/"===e)return"/";if("string"==typeof e)if("(__SLOT__)"===e)return;else return e+"/";return e[1]+"/"}(b),P=v??A,j=void 0===v?void 0:A,C=(0,u.jsxs)(x,{cacheNode:i,children:[(0,u.jsx)(f.ErrorBoundary,{errorComponent:t,errorStyles:r,errorScripts:n,children:(0,u.jsx)(R,{name:j,loading:E,children:(0,u.jsx)(y.HTTPAccessFallbackBoundary,{notFound:s,forbidden:p,unauthorized:g,children:(0,u.jsxs)(m.RedirectBoundary,{children:[(0,u.jsx)(O,{url:N,tree:e,params:h,cacheNode:i,segmentPath:L,debugNameContext:P,isActive:F&&c===U}),null]})})})}),null]}),S=(0,u.jsxs)(d.TemplateContext.Provider,{value:C,children:[l,a,o]},c);V.push(S),I=I.next}while(null!==I)return V}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},37457,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"default",{enumerable:!0,get:function(){return u}});let n=e.r(90809),l=e.r(43476),a=n._(e.r(71645)),o=e.r(8372);function u(){let e=(0,a.useContext)(o.TemplateContext);return(0,l.jsx)(l.Fragment,{children:e})}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},6831,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"createRenderParamsFromClient",{enumerable:!0,get:function(){return l}});let n=new WeakMap;function l(e){let t=n.get(e);if(t)return t;let r=Promise.resolve(e);return n.set(e,r),r}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},14193,(e,t,r)=>{"use strict";e.i(47167),Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"createRenderParamsFromClient",{enumerable:!0,get:function(){return n}});let n=e.r(6831).createRenderParamsFromClient;("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},93504,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"createRenderSearchParamsFromClient",{enumerable:!0,get:function(){return l}});let n=new WeakMap;function l(e){let t=n.get(e);if(t)return t;let r=Promise.resolve(e);return n.set(e,r),r}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},66996,(e,t,r)=>{"use strict";e.i(47167),Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"createRenderSearchParamsFromClient",{enumerable:!0,get:function(){return n}});let n=e.r(93504).createRenderSearchParamsFromClient;("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},15783,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0});var n={createClientParams:function(){return a.createRenderParamsFromClient},createClientSearchParams:function(){return o.createRenderSearchParamsFromClient}};for(var l in n)Object.defineProperty(r,l,{enumerable:!0,get:n[l]});let a=e.r(14193),o=e.r(66996);("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},27201,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"IconMark",{enumerable:!0,get:function(){return l}});let n=e.r(43476),l=()=>"u">typeof window?null:(0,n.jsx)("meta",{name:"«nxt-icon»"})},91915,(e,t,r)=>{"use strict";function n(e,t={}){if(t.onlyHashChange)return void e();let r=document.documentElement;if("smooth"!==r.dataset.scrollBehavior)return void e();let l=r.style.scrollBehavior;r.style.scrollBehavior="auto",t.dontForceLayout||r.getClientRects(),e(),r.style.scrollBehavior=l}e.i(47167),Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"disableSmoothScrollDuringRouteTransition",{enumerable:!0,get:function(){return n}})}]);
@@ -1,9 +1,10 @@
1
1
  # Security Policy
2
2
 
3
- failproofai is an npm package that installs hooks into AI coding agents (Claude
4
- Code, Codex, and others) and runs locally in developers' environments, observing
5
- and gating agent actions. A compromised dependency would therefore run on our
6
- users' machines, inside their agent sessions so we treat our supply chain as
3
+ failproofai is an npm package that installs hooks into AI agent harnesses
4
+ (Claude Code, Codex, Cursor, the Hermes and OpenClaw gateways, and others) and
5
+ runs locally in the environment the agent runs in, observing and gating agent
6
+ actions. A compromised dependency would therefore run on our
7
+ users' machines and servers, inside their agent sessions — so we treat our supply chain as
7
8
  part of our users' trust boundary. This document covers how to report a
8
9
  vulnerability and how our dependency supply-chain scanning works.
9
10
 
@@ -2,7 +2,6 @@
2
2
 
3
3
  import { configuredCustomPolicyPaths, readMergedHooksConfig } from "@/src/hooks/hooks-config";
4
4
  import { hooksInstalledInSettings, getSettingsPath } from "@/src/hooks/manager";
5
- import { BUILTIN_POLICIES } from "@/src/hooks/builtin-policies";
6
5
  import { listIntegrations } from "@/src/hooks/integrations";
7
6
  import { HOOK_SCOPES } from "@/src/hooks/types";
8
7
  import type { HookScope, IntegrationType } from "@/src/hooks/types";
@@ -13,6 +12,8 @@ import { readFile } from "node:fs/promises";
13
12
  import { existsSync } from "node:fs";
14
13
  import { basename, resolve } from "node:path";
15
14
  import { customPoliciesDir } from "@/src/hooks/fp-home";
15
+ import { readInstalledPacks } from "@/src/hooks/pack-manifest";
16
+ import type { PackError, ResolvedPack } from "@/src/hooks/pack-manifest";
16
17
 
17
18
  export interface PolicyParamSpec {
18
19
  type: string;
@@ -30,6 +31,9 @@ export interface PolicyInfo {
30
31
  eventScope: string;
31
32
  params?: Record<string, PolicyParamSpec>;
32
33
  currentParams?: Record<string, unknown>;
34
+ /** The pack this policy came from — every policy has one now. */
35
+ packId: string;
36
+ packVersion: string;
33
37
  }
34
38
 
35
39
  export interface CustomPolicyInfo {
@@ -68,6 +72,25 @@ export interface CliInstallStatus {
68
72
  detected: boolean;
69
73
  }
70
74
 
75
+ /** One policy carried by an installed pack. */
76
+ export interface PackPolicyInfo {
77
+ name: string;
78
+ description: string;
79
+ category: string;
80
+ enabled: boolean;
81
+ }
82
+
83
+ export interface InstalledPackInfo {
84
+ id: string;
85
+ version: string;
86
+ /** Where it came from, verbatim — `github:acme/ops@v1.0.0` or `bundled:...`. */
87
+ source: string;
88
+ effect: "enforce" | "observe";
89
+ policies: PackPolicyInfo[];
90
+ /** Set when the record itself could not be read, e.g. its digest changed. */
91
+ error?: string;
92
+ }
93
+
71
94
  export interface HooksConfigPayload {
72
95
  enabledPolicies: string[];
73
96
  /** Claude-only legacy field; kept for back-compat. New UI should consume `clis`. */
@@ -83,6 +106,8 @@ export interface HooksConfigPayload {
83
106
  customPolicies?: CustomPolicyInfo[];
84
107
  /** Convention-discovered policy files, project scope first. */
85
108
  conventionPolicies: ConventionPolicyFile[];
109
+ /** Installed policy packs, read from `installed.json`. */
110
+ packs: InstalledPackInfo[];
86
111
  }
87
112
 
88
113
  /**
@@ -179,7 +204,6 @@ export async function getHooksConfigAction(): Promise<HooksConfigPayload> {
179
204
  // Match runtime enforcement: project, local, and user config all
180
205
  // contribute to the effective policy state shown by the dashboard.
181
206
  const config = readMergedHooksConfig(launchCwd);
182
- const enabledSet = new Set(config.enabledPolicies);
183
207
  const disabledCustomPolicies = new Set(config.disabledCustomPolicies ?? []);
184
208
 
185
209
  const installedScopes = HOOK_SCOPES.filter((s) => hooksInstalledInSettings(s));
@@ -194,21 +218,52 @@ export async function getHooksConfigAction(): Promise<HooksConfigPayload> {
194
218
  detected: integration.detectInstalled(),
195
219
  }));
196
220
 
197
- const policies: PolicyInfo[] = BUILTIN_POLICIES.map((p) => ({
198
- name: p.name,
199
- description: p.description,
200
- category: p.category,
201
- defaultEnabled: p.defaultEnabled,
202
- beta: !!p.beta,
203
- enabled: enabledSet.has(p.name),
204
- eventScope: buildEventScope(p.match),
205
- params: p.params
206
- ? Object.fromEntries(
207
- Object.entries(p.params).map(([k, v]) => [k, { type: v.type, description: v.description, default: v.default }])
208
- )
209
- : undefined,
210
- currentParams: p.params ? (config.policyParams?.[p.name] ?? {}) : undefined,
211
- }));
221
+ // Read once, ahead of everything that needs it: the policy list IS the packs'
222
+ // policies now, and the pack listing further down describes the same read.
223
+ let installedPacks: ResolvedPack[] = [];
224
+ let packErrors: PackError[] = [];
225
+ try {
226
+ const result = readInstalledPacks();
227
+ installedPacks = result.packs;
228
+ packErrors = result.errors;
229
+ } catch {
230
+ // A listing must not be the thing that turns an unreadable manifest into a
231
+ // broken page.
232
+ }
233
+
234
+ // Every policy that enforces here comes from an installed PACK. Nothing is
235
+ // compiled into this build any more except the always-on self-protection
236
+ // guard — which no listing can switch off, so it has no row.
237
+ const policies: PolicyInfo[] = [];
238
+ for (const pack of installedPacks) {
239
+ const taken = pack.enabled ?? pack.policies.map((p) => p.name);
240
+ for (const policy of pack.policies) {
241
+ policies.push({
242
+ name: policy.name,
243
+ description: policy.description,
244
+ category: policy.category,
245
+ defaultEnabled: policy.defaultEnabled,
246
+ beta: false,
247
+ enabled:
248
+ taken.includes(policy.name) &&
249
+ !disabledCustomPolicies.has(`pack:${pack.id}@${pack.version}:${policy.name}`),
250
+ eventScope: buildEventScope(policy.match),
251
+ packId: pack.id,
252
+ packVersion: pack.version,
253
+ ...(policy.params
254
+ ? {
255
+ params: Object.fromEntries(
256
+ Object.entries(policy.params).map(([k, v]) => [
257
+ k,
258
+ { type: v.type, description: v.description, default: v.default },
259
+ ]),
260
+ ),
261
+ currentParams: config.policyParams?.[policy.name] ?? {},
262
+ }
263
+ : {}),
264
+ });
265
+ }
266
+ }
212
267
 
213
268
  const customPoliciesPaths = configuredCustomPolicyPaths(config);
214
269
  const launchRoot = findProjectConfigDir(launchCwd);
@@ -232,6 +287,41 @@ export async function getHooksConfigAction(): Promise<HooksConfigPayload> {
232
287
  new Set(resolvedCustomPaths),
233
288
  );
234
289
 
290
+ // Metadata only — deliberately never imported. Same rule as the convention
291
+ // files above: this runs on every page load, and importing a pack's artifact
292
+ // would execute a third party's code inside the long-lived dashboard server.
293
+ // The import check that proves a pack still loads belongs to the CLI and to
294
+ // the user-initiated install action.
295
+ const packs: InstalledPackInfo[] = installedPacks.map((pack) => {
296
+ const taken = pack.enabled ?? pack.policies.map((p) => p.name);
297
+ return {
298
+ id: pack.id,
299
+ version: pack.version,
300
+ source: pack.source,
301
+ effect: pack.effect,
302
+ policies: pack.policies.map((policy) => ({
303
+ name: policy.name,
304
+ description: policy.description,
305
+ category: policy.category,
306
+ enabled:
307
+ taken.includes(policy.name) &&
308
+ !disabledCustomPolicies.has(`pack:${pack.id}@${pack.version}:${policy.name}`),
309
+ })),
310
+ };
311
+ });
312
+ for (const err of packErrors) {
313
+ // A pack that will not load is what the machine denies for; a listing that
314
+ // omitted it would be the quietest possible way to report that.
315
+ packs.push({
316
+ id: err.id ?? "(unnamed pack)",
317
+ version: "",
318
+ source: "",
319
+ effect: "enforce",
320
+ policies: [],
321
+ error: err.reason,
322
+ });
323
+ }
324
+
235
325
  return {
236
326
  enabledPolicies: config.enabledPolicies,
237
327
  installedScopes,
@@ -242,5 +332,6 @@ export async function getHooksConfigAction(): Promise<HooksConfigPayload> {
242
332
  customPoliciesPath: customPoliciesPaths.length === 1 ? customPoliciesPaths[0] : undefined,
243
333
  customPolicies: customPolicies.length ? customPolicies : undefined,
244
334
  conventionPolicies,
335
+ packs,
245
336
  };
246
337
  }
@@ -0,0 +1,153 @@
1
+ "use server";
2
+
3
+ /**
4
+ * Installing and managing policy packs from the local dashboard.
5
+ *
6
+ * These are USER-INITIATED actions, which is what makes it acceptable for
7
+ * `addPack` to import the pack's artifact here: it verifies that what a
8
+ * publisher declared is what their code registers, and refusing at install time
9
+ * is the whole reason a broken pack cannot brick the machine. `get-hooks-config`
10
+ * deliberately does the opposite — it lists packs from `installed.json` and
11
+ * imports nothing, because that runs on every page load.
12
+ */
13
+ import {
14
+ addPackFromSource,
15
+ fetchPackPreview,
16
+ installBundledPack,
17
+ removePack,
18
+ setPackPolicyEnabled,
19
+ } from "@/src/hooks/pack-store";
20
+ import { readHooksConfig, writeHooksConfig } from "@/src/hooks/hooks-config";
21
+ import { readInstalledPacks } from "@/src/hooks/pack-manifest";
22
+
23
+ export interface PackActionResult {
24
+ ok: boolean;
25
+ /** Present when ok — what landed, so the UI can say it without a refetch. */
26
+ id?: string;
27
+ version?: string;
28
+ enabled?: string[];
29
+ available?: string[];
30
+ /** Present when not ok — the publisher's or the loader's own words. */
31
+ error?: string;
32
+ }
33
+
34
+ /**
35
+ * Install a pack by the source a person typed: `core`, `acme/ops`,
36
+ * `acme/ops@v1.2.0`, or a release URL.
37
+ *
38
+ * Routed through the SAME resolver the CLI uses. While the alias list lived in
39
+ * `pack-cli.ts`, `core` worked in the terminal and failed in the browser — the
40
+ * one thing a shared entry point exists to prevent.
41
+ */
42
+ export async function addPackWebAction(
43
+ source: string,
44
+ opts?: { all?: boolean; only?: string[]; categories?: string[] },
45
+ ): Promise<PackActionResult> {
46
+ const trimmed = source.trim();
47
+ if (!trimmed) return { ok: false, error: "Enter a pack source, for example acme/ops" };
48
+ try {
49
+ const result = await addPackFromSource(trimmed, opts ?? {});
50
+ return {
51
+ ok: true,
52
+ id: result.id,
53
+ version: result.version,
54
+ enabled: result.enabled,
55
+ available: result.available,
56
+ };
57
+ } catch (err) {
58
+ // Surfaced verbatim. Every refusal on this path already names what was wrong
59
+ // and whose fault it is — an unresolvable source, a digest that does not
60
+ // match, a manifest declaring a policy its artifact never registers.
61
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
62
+ }
63
+ }
64
+
65
+ /** Install the pack that ships inside this package. No network. */
66
+ export async function addBundledPackWebAction(): Promise<PackActionResult> {
67
+ const result = installBundledPack();
68
+ if (!result.installed) return { ok: false, error: result.reason ?? "could not install" };
69
+ return {
70
+ ok: true,
71
+ id: result.id,
72
+ version: result.version,
73
+ enabled: result.enabled,
74
+ available: result.available,
75
+ };
76
+ }
77
+
78
+ export async function removePackWebAction(id: string): Promise<PackActionResult> {
79
+ return removePack(id) ? { ok: true, id } : { ok: false, error: `No installed pack with id ${id}` };
80
+ }
81
+
82
+ /**
83
+ * Turn one policy of an installed pack on or off.
84
+ *
85
+ * Writes the pack's own SELECTION, the same lever the CLI uses — not a
86
+ * `disabledCustomPolicies` entry, which is keyed by version and would silently
87
+ * switch everything back on at the next upgrade. Enabling also clears any such
88
+ * key, so a policy switched off before this existed can still be switched back on.
89
+ */
90
+ export async function togglePackPolicyAction(
91
+ packId: string,
92
+ name: string,
93
+ enabled: boolean,
94
+ ): Promise<PackActionResult> {
95
+ const result = setPackPolicyEnabled(packId, name, enabled);
96
+ if (!result.ok) return { ok: false, error: result.reason };
97
+ if (enabled) {
98
+ const pack = readInstalledPacks().packs.find((p) => p.id === packId);
99
+ if (pack) {
100
+ const key = `pack:${pack.id}@${pack.version}:${name}`;
101
+ const config = readHooksConfig();
102
+ const remaining = (config.disabledCustomPolicies ?? []).filter((k) => k !== key);
103
+ if (remaining.length !== (config.disabledCustomPolicies ?? []).length) {
104
+ const { disabledCustomPolicies: _dropped, ...rest } = config;
105
+ writeHooksConfig(
106
+ remaining.length > 0 ? { ...rest, disabledCustomPolicies: remaining } : rest,
107
+ );
108
+ }
109
+ }
110
+ }
111
+ return { ok: true, id: packId };
112
+ }
113
+
114
+ export interface PackPreviewResult {
115
+ ok: boolean;
116
+ id?: string;
117
+ version?: string;
118
+ source?: string;
119
+ effect?: "enforce" | "observe";
120
+ policies?: Array<{ name: string; description: string; category: string; defaultEnabled: boolean }>;
121
+ error?: string;
122
+ }
123
+
124
+ /**
125
+ * Read what a pack contains WITHOUT installing it — the browser half of
126
+ * `failproofai pack list <source>`.
127
+ *
128
+ * Fetches the manifest only. The entry artifact is never downloaded and never
129
+ * imported, so previewing a stranger's pack from the dashboard cannot run a
130
+ * stranger's code inside this long-lived server.
131
+ */
132
+ export async function previewPackWebAction(source: string): Promise<PackPreviewResult> {
133
+ const trimmed = source.trim();
134
+ if (!trimmed) return { ok: false, error: "Enter a pack source, for example acme/ops" };
135
+ try {
136
+ const preview = await fetchPackPreview(trimmed);
137
+ return {
138
+ ok: true,
139
+ id: preview.id,
140
+ version: preview.version,
141
+ source: preview.source,
142
+ effect: preview.effect,
143
+ policies: preview.policies.map((p) => ({
144
+ name: p.name,
145
+ description: p.description,
146
+ category: p.category,
147
+ defaultEnabled: p.defaultEnabled,
148
+ })),
149
+ };
150
+ } catch (err) {
151
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
152
+ }
153
+ }
@@ -21,7 +21,7 @@ import { useEffect, useState } from "react";
21
21
  const STAGES = [
22
22
  { label: "discovering transcripts", detail: "walking ~/.claude, ~/.codex, ~/.cursor, …" },
23
23
  { label: "parsing session logs", detail: "reading JSONL + sqlite session stores" },
24
- { label: "running policy checks", detail: "replaying through 30 builtin policies" },
24
+ { label: "running policy checks", detail: "replaying every policy against each tool call" },
25
25
  { label: "aggregating results", detail: "counting hits, ranking by frequency" },
26
26
  ];
27
27
 
@@ -34,49 +34,49 @@ const PASTE_LINE = "[ audit card copied to your clipboard — paste it into the
34
34
  /** Short, curiosity-forward — for X / Twitter. Ends on the npx CTA + @failproofai. */
35
35
  export const X_TEMPLATES: ((c: ShareCtx) => string)[] = [
36
36
  ({ score, arch }) =>
37
- `my coding agent has a personality and it's ${arch}. did not see that coming.\n\nran a failproof audit, scored ${score}/100, all local. find out what yours is → ${X_CTA}`,
37
+ `my agent has a personality and it's ${arch}. did not see that coming.\n\nran a failproof audit, scored ${score}/100, all local. find out what yours is → ${X_CTA}`,
38
38
  ({ score, arch }) =>
39
- `spent 30 seconds auditing my coding agent. learned more about it than i did all month.\n\nit's ${arch}. scored ${score}/100. → ${X_CTA}`,
39
+ `spent 30 seconds auditing my agent. learned more about it than i did all month.\n\nit's ${arch}. scored ${score}/100. → ${X_CTA}`,
40
40
  ({ score }) =>
41
41
  `my agent scored ${score}/100. think yours can beat it?\n\n30 sec audit, runs locally, gives you a personality too → ${X_CTA}`,
42
42
  ({ arch }) =>
43
- `turns out my coding agent is ${arch} and honestly it explains everything.\n\n→ ${X_CTA}`,
43
+ `turns out my agent is ${arch} and honestly it explains everything.\n\n→ ${X_CTA}`,
44
44
  ({ score, arch }) =>
45
45
  `ran a failproof audit on my agent. it reads how it actually behaves when things break, not just the happy path.\n\npersonality: ${arch}. score: ${score}/100. all local → ${X_CTA}`,
46
46
  ({ score, arch }) =>
47
- `got to know my coding agent today. it's ${arch} and scored ${score}/100. wow.\n\naudit yours in 30s, nothing leaves your machine → ${X_CTA}`,
47
+ `got to know my agent today. it's ${arch} and scored ${score}/100. wow.\n\naudit yours in 30s, nothing leaves your machine → ${X_CTA}`,
48
48
  ({ score, arch }) =>
49
- `your coding agent has a personality. you just haven't met it.\n\ni met mine today: ${arch}, ${score}/100. → ${X_CTA}`,
49
+ `your agent has a personality. you just haven't met it.\n\ni met mine today: ${arch}, ${score}/100. → ${X_CTA}`,
50
50
  ({ score, arch }) =>
51
51
  `everyone talks about what their agent can build. nobody talks about how it acts when it breaks.\n\nmine's ${arch}, scored ${score}/100, all local → ${X_CTA}`,
52
52
  ({ score, arch }) =>
53
53
  `every agent builder should run this once.\n\n30 sec, local, gives your agent a personality and a quality score. mine: ${arch}, ${score}/100.\n\n${X_CTA}`,
54
54
  ({ score, arch }) =>
55
- `i'll go first: ${arch}, ${score}/100.\n\nwhat's your coding agent? 30 sec audit, no signup → ${X_CTA}`,
55
+ `i'll go first: ${arch}, ${score}/100.\n\nwhat's your agent? 30 sec audit, no signup → ${X_CTA}`,
56
56
  ];
57
57
 
58
58
  /** Longer, reflective — for LinkedIn. Ends on the npx CTA + @Failproof AI. */
59
59
  export const LI_TEMPLATES: ((c: ShareCtx) => string)[] = [
60
60
  ({ score, arch }) =>
61
- `I've spent more hours with my coding agent this month than with most people I know. Today I realized I couldn't tell you a single thing about how it actually behaves.\n\nSo I audited it. Turns out it's ${arch}, and it scored ${score}/100.\n\nThe audit reads its real history, including how it handles failures, not just the clean runs. 30 seconds, runs entirely locally.\n\nMeet yours: ${LI_CTA}`,
61
+ `I've spent more hours with my agent this month than with most people I know. Today I realized I couldn't tell you a single thing about how it actually behaves.\n\nSo I audited it. Turns out it's ${arch}, and it scored ${score}/100.\n\nThe audit reads its real history, including how it handles failures, not just the clean runs. 30 seconds, runs entirely locally.\n\nMeet yours: ${LI_CTA}`,
62
62
  ({ score, arch }) =>
63
- `Took a personality test today. It wasn't for me — it was for my AI coding agent.\n\nThe result: ${arch}, with a quality score of ${score}/100.\n\nIt works by reading the agent's actual run history, so the personality comes from how it really behaves, not a vibe. Took 30 seconds and stayed local.\n\nTry it on yours: ${LI_CTA}`,
63
+ `Took a personality test today. It wasn't for me — it was for my AI agent.\n\nThe result: ${arch}, with a quality score of ${score}/100.\n\nIt works by reading the agent's actual run history, so the personality comes from how it really behaves, not a vibe. Took 30 seconds and stayed local.\n\nTry it on yours: ${LI_CTA}`,
64
64
  ({ score, arch }) =>
65
65
  `Everyone asks what their AI agent can build. I just found out mine has a temper.\n\nAfter watching how it reacts to a failed command, the audit called it ${arch}. It also scored its quality at ${score}/100.\n\nOddly useful to see it written down. 30 seconds, all local: ${LI_CTA}`,
66
66
  ({ score, arch }) =>
67
67
  `My agent does this very specific thing every time a command fails. Today I learned there's basically a name for it.\n\nRan a quick audit and it came back ${arch}, scored ${score}/100. The whole read is based on how the agent handles things going wrong, which is where its real character shows.\n\n30 seconds, nothing leaves your machine: ${LI_CTA}`,
68
68
  ({ score, arch }) =>
69
- `My AI coding agent scored ${score}/100 today. I didn't know you could even measure that.\n\nThe same audit also handed it a personality: ${arch}.\n\nIt reads the agent's real history and tells you where it's solid and where it slips. Took 30 seconds and ran fully locally: ${LI_CTA}`,
69
+ `My AI agent scored ${score}/100 today. I didn't know you could even measure that.\n\nThe same audit also handed it a personality: ${arch}.\n\nIt reads the agent's real history and tells you where it's solid and where it slips. Took 30 seconds and ran fully locally: ${LI_CTA}`,
70
70
  ({ score, arch }) =>
71
- `I'm usually the first to scroll past "audit your X" tools. This one took 30 seconds and actually told me something.\n\nMy coding agent is ${arch}, and it scored ${score}/100.\n\nIt reads the agent's real run history rather than asking me anything, and none of it leaves the machine: ${LI_CTA}`,
71
+ `I'm usually the first to scroll past "audit your X" tools. This one took 30 seconds and actually told me something.\n\nMy agent is ${arch}, and it scored ${score}/100.\n\nIt reads the agent's real run history rather than asking me anything, and none of it leaves the machine: ${LI_CTA}`,
72
72
  ({ score, arch }) =>
73
- `What is your coding agent's personality? I realized today that I had no answer.\n\nSo I checked. Mine is ${arch}, scored ${score}/100, with a clear read on where it shines and where it slips.\n\nIf you work with agents, run it and drop yours in the comments. 30 seconds, fully local: ${LI_CTA}`,
73
+ `What is your agent's personality? I realized today that I had no answer.\n\nSo I checked. Mine is ${arch}, scored ${score}/100, with a clear read on where it shines and where it slips.\n\nIf you work with agents, run it and drop yours in the comments. 30 seconds, fully local: ${LI_CTA}`,
74
74
  ({ score, arch }) =>
75
- `I trusted my coding agent a little less after this morning, and quite a bit more by the afternoon.\n\nI ran an audit on it. It showed me exactly where it's reliable and where it isn't, gave it a personality (${arch}), and scored it ${score}/100.\n\nKnowing the gaps is what made me trust it more. 30 seconds, all local: ${LI_CTA}`,
75
+ `I trusted my agent a little less after this morning, and quite a bit more by the afternoon.\n\nI ran an audit on it. It showed me exactly where it's reliable and where it isn't, gave it a personality (${arch}), and scored it ${score}/100.\n\nKnowing the gaps is what made me trust it more. 30 seconds, all local: ${LI_CTA}`,
76
76
  ({ score, arch }) =>
77
77
  `I almost skipped this because I assumed it would quietly ship my code off somewhere. It doesn't. Everything runs locally.\n\n30 seconds later I had my agent's personality (${arch}) and a quality score (${score}/100).\n\nIf privacy is usually what stops you from trying these, this one is different: ${LI_CTA}`,
78
78
  ({ score, arch }) =>
79
- `Found out my AI coding agent has a personality type. Found out it's ${arch}. Found out that explains a lot.\n\nIt scored ${score}/100 too. The audit reads how the agent handles failures, not just the runs where everything goes fine.\n\n30 seconds, runs locally: ${LI_CTA}`,
79
+ `Found out my AI agent has a personality type. Found out it's ${arch}. Found out that explains a lot.\n\nIt scored ${score}/100 too. The audit reads how the agent handles failures, not just the runs where everything goes fine.\n\n30 seconds, runs locally: ${LI_CTA}`,
80
80
  ];
81
81
 
82
82
  /** djb2 hash — stable per seed so the template choice is deterministic. */