failproofai 0.0.11-beta.2 → 0.0.11-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/app-path-routes-manifest.json +8 -1
- package/.next/standalone/.next/build-manifest.json +10 -10
- package/.next/standalone/.next/prerender-manifest.json +3 -32
- package/.next/standalone/.next/required-server-files.json +2 -1
- package/.next/standalone/.next/routes-manifest.json +45 -3
- package/.next/standalone/.next/server/app/_global-error/page/build-manifest.json +7 -7
- package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page.js +6 -6
- package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_global-error.html +1 -1
- package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
- package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
- package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +3 -3
- package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +3 -3
- package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found/page/build-manifest.json +7 -7
- package/.next/standalone/.next/server/app/_not-found/page/next-font-manifest.json +2 -6
- package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page.js +12 -13
- package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +1 -1
- package/.next/standalone/.next/server/app/_not-found.rsc +16 -16
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +16 -16
- package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
- package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +10 -10
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
- package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/api/audit/run/route/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/api/audit/run/route/server-reference-manifest.json +4 -0
- package/.next/standalone/.next/server/app/api/audit/run/route.js +8 -0
- package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/api/audit/run/route_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app/api/audit/status/route/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/api/audit/status/route/build-manifest.json +9 -0
- package/.next/standalone/.next/server/app/api/audit/status/route/server-reference-manifest.json +4 -0
- package/.next/standalone/.next/server/app/api/audit/status/route.js +6 -0
- package/.next/standalone/.next/server/app/api/audit/status/route.js.map +5 -0
- package/.next/standalone/.next/server/app/api/audit/status/route.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/api/audit/status/route_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app/api/auth/login-request/route/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/api/auth/login-request/route/build-manifest.json +9 -0
- package/.next/standalone/.next/server/app/api/auth/login-request/route/server-reference-manifest.json +4 -0
- package/.next/standalone/.next/server/app/api/auth/login-request/route.js +6 -0
- package/.next/standalone/.next/server/app/api/auth/login-request/route.js.map +5 -0
- package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/api/auth/login-request/route_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app/api/auth/login-verify/route/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/api/auth/login-verify/route/build-manifest.json +9 -0
- package/.next/standalone/.next/server/app/api/auth/login-verify/route/server-reference-manifest.json +4 -0
- package/.next/standalone/.next/server/app/api/auth/login-verify/route.js +7 -0
- package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.map +5 -0
- package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/api/auth/login-verify/route_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app/api/auth/logout/route/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/api/auth/logout/route/build-manifest.json +9 -0
- package/.next/standalone/.next/server/app/api/auth/logout/route/server-reference-manifest.json +4 -0
- package/.next/standalone/.next/server/app/api/auth/logout/route.js +7 -0
- package/.next/standalone/.next/server/app/api/auth/logout/route.js.map +5 -0
- package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/api/auth/logout/route_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app/api/auth/reminder/route/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/api/auth/reminder/route/build-manifest.json +9 -0
- package/.next/standalone/.next/server/app/api/auth/reminder/route/server-reference-manifest.json +4 -0
- package/.next/standalone/.next/server/app/api/auth/reminder/route.js +7 -0
- package/.next/standalone/.next/server/app/api/auth/reminder/route.js.map +5 -0
- package/.next/standalone/.next/server/app/api/auth/reminder/route.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/api/auth/reminder/route_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app/api/auth/status/route/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/api/auth/status/route/build-manifest.json +9 -0
- package/.next/standalone/.next/server/app/api/auth/status/route/server-reference-manifest.json +4 -0
- package/.next/standalone/.next/server/app/api/auth/status/route.js +7 -0
- package/.next/standalone/.next/server/app/api/auth/status/route.js.map +5 -0
- package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/api/auth/status/route_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js +3 -3
- package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/audit/page/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/audit/page/build-manifest.json +18 -0
- package/.next/standalone/.next/server/app/audit/page/next-font-manifest.json +6 -0
- package/.next/standalone/.next/server/app/audit/page/react-loadable-manifest.json +1 -0
- package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +29 -0
- package/.next/standalone/.next/server/app/audit/page.js +17 -0
- package/.next/standalone/.next/server/app/audit/page.js.map +5 -0
- package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app/index.html +1 -1
- package/.next/standalone/.next/server/app/index.rsc +16 -17
- package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +16 -17
- package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +4 -4
- package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +10 -10
- package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -3
- package/.next/standalone/.next/server/app/page/build-manifest.json +7 -7
- package/.next/standalone/.next/server/app/page/next-font-manifest.json +2 -6
- package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/page.js +14 -15
- package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/policies/page/build-manifest.json +7 -7
- package/.next/standalone/.next/server/app/policies/page/next-font-manifest.json +2 -6
- package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +8 -8
- package/.next/standalone/.next/server/app/policies/page.js +16 -16
- package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page/build-manifest.json +7 -7
- package/.next/standalone/.next/server/app/project/[name]/page/next-font-manifest.json +2 -6
- package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page.js +16 -17
- package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/build-manifest.json +7 -7
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/next-font-manifest.json +2 -6
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js +19 -20
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/projects/page/build-manifest.json +7 -7
- package/.next/standalone/.next/server/app/projects/page/next-font-manifest.json +2 -6
- package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/projects/page.js +15 -16
- package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app-paths-manifest.json +8 -1
- package/.next/standalone/.next/server/chunks/[externals]__14odj07._.js +3 -0
- package/.next/standalone/.next/server/chunks/{[externals]__0z0j--b._.js → [externals]__1nl3dvw._.js} +1 -1
- package/.next/standalone/.next/server/chunks/{[externals]__0-p9.k~._.js → [externals]__1s61mel._.js} +1 -1
- package/.next/standalone/.next/server/chunks/{[externals]_node_os_06ur78j._.js → [externals]_node_os_0by37l-._.js} +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__07tgnzi._.js +3 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0kjo7d_._.js → [root-of-the-server]__0_0xu5z._.js} +2 -2
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0cag8qd._.js +3 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0z-180.._.js → [root-of-the-server]__0cycwg6._.js} +2 -2
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__08px0ym._.js → [root-of-the-server]__0f7mikp._.js} +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0oeun7z._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0q-v9z2._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0rv7m0k._.js +3 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0g48iv.._.js → [root-of-the-server]__0sb_5m8._.js} +2 -2
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0j8-xkl._.js → [root-of-the-server]__0xuaoik._.js} +2 -2
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__12pit4m._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__13h8pzr._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__13ra2jq._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__17g9wh7._.js +3 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0d_ob4n._.js → [root-of-the-server]__1_mqemn._.js} +2 -2
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1b9z5-i._.js +3 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0vlhtkc._.js → [root-of-the-server]__1hgv_75._.js} +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1ixjiy8._.js +3 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0wu7fr7._.js → [root-of-the-server]__1jm9fw6._.js} +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1legmza._.js +3 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0fwb7ao._.js → [root-of-the-server]__1m2_4t0._.js} +2 -2
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0yfq1yr._.js → [root-of-the-server]__1mhmdzs._.js} +1 -1
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0zso~62._.js → [root-of-the-server]__1ou2ehh._.js} +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1qxztj-._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1rhmvod._.js +3 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0.~nmr9._.js → [root-of-the-server]__1w9zl9-._.js} +1 -1
- package/.next/standalone/.next/server/chunks/{_0ebx_lc._.js → _0p53ge1._.js} +2 -2
- package/.next/standalone/.next/server/chunks/_1-1804f._.js +3 -0
- package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_audit_run_route_actions_1qgp9io.js +3 -0
- package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_audit_status_route_actions_1f7pjof.js +3 -0
- package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_auth_login-request_route_actions_1c49co0.js +3 -0
- package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_auth_login-verify_route_actions_1r3slzk.js +3 -0
- package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_auth_logout_route_actions_0regwyr.js +3 -0
- package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_auth_reminder_route_actions_1kjgxf8.js +3 -0
- package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_auth_status_route_actions_1aho9zu.js +3 -0
- package/.next/standalone/.next/server/chunks/{_next-internal_server_app_api_download_[project]_[session]_route_actions_0wb00i-.js → _next-internal_server_app_api_download_[project]_[session]_route_actions_1is7vs7.js} +1 -1
- package/.next/standalone/.next/server/chunks/{lib_logger_ts_047tt9f._.js → lib_logger_ts_07e65t5._.js} +1 -1
- package/.next/standalone/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_17k9e3w.js +23 -0
- package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_01r25oi._.js +3 -0
- package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_09z9-p7._.js +3 -0
- package/.next/standalone/.next/server/chunks/{package_json_[json]_cjs_0z7w.hh._.js → package_json_[json]_cjs_1nxcc4v._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{[externals]__12dv.x0._.js → [externals]__1_g_b3t._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{[externals]_node_async_hooks_0v0ln8c._.js → [externals]_node_async_hooks_1gjz99j._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__00jkjmt._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__013du6r._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0989_dx._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0e85wxv._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0gfxvb1._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0h12me5._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0l13qf2._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0ts150~._.js → [root-of-the-server]__0ywoypf._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1-scthx._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__100hdar._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__11rtg6s._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__14dd6h8._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1cd25c7._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0t5l7a5._.js → [root-of-the-server]__1d8omgc._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0tcyn68._.js → [root-of-the-server]__1dky4g0._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__098zro9._.js → [root-of-the-server]__1fax1sl._.js} +4 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1hlrq6y._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1ihxdo5._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1mt35_w._.js +221 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0-wn51s._.js → [root-of-the-server]__1pcxxwg._.js} +3 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1usf8v2._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1vvfde2._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__212nf49._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{_03d7qyt._.js → _05whahf._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_11_p9y8._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{_0xb8ngh._.js → _1kje4fm._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{_0zx~s__._.js → _1p0-leb._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{app_04qfs8z._.js → app_087bt9w._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{app_0uosk1e._.js → app_1fvisnp._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{app_13f0ohr._.js → app_209u41o._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +43 -0
- package/.next/standalone/.next/server/chunks/ssr/app_audit_loading_tsx_1j1kc6j._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{app_error_tsx_11t4ysq._.js → app_error_tsx_1zds1ns._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{app_global-error_tsx_0m9qisk._.js → app_global-error_tsx_113y3za._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +8 -0
- package/.next/standalone/.next/server/chunks/ssr/{app_project_[name]_error_tsx_0.9-fod._.js → app_project_[name]_error_tsx_1v02_5n._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{app_project_[name]_loading_tsx_03g9xy0._.js → app_project_[name]_loading_tsx_05-l4uf._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{app_project_[name]_session_[sessionId]_error_tsx_0ler-mr._.js → app_project_[name]_session_[sessionId]_error_tsx_0-lj3nd._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{app_project_[name]_session_[sessionId]_loading_tsx_0c0e3yx._.js → app_project_[name]_session_[sessionId]_loading_tsx_0l4aixs._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_projects_loading_tsx_20-3u8b._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{lib_codex-projects_ts_0eosib~._.js → lib_codex-projects_ts_0pqlw37._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{lib_copilot-projects_ts_0r8xkn8._.js → lib_copilot-projects_ts_19wl7tp._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{lib_cursor-projects_ts_0qt1scg._.js → lib_cursor-projects_ts_18-iwyk._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{lib_gemini-projects_ts_0sl~yqr._.js → lib_gemini-projects_ts_1c7bgx-._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{lib_opencode-projects_ts_0op9gyp._.js → lib_opencode-projects_ts_15bjxkm._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{lib_pi-projects_ts_103tsh1._.js → lib_pi-projects_ts_1wikofb._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{lib_utils_ts_068jk73._.js → lib_utils_ts_0az0sfq._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules_1ynf7el._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/node_modules_html2canvas_dist_html2canvas_esm_05gja40.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/node_modules_html2canvas_dist_html2canvas_esm_1n-0xws.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{node_modules_next_0rd0oc-._.js → node_modules_next_1a1kch7._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules_next_dist_0h9llsw._.js → node_modules_next_dist_0uboya6._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{node_modules_next_dist_11dij6w._.js → node_modules_next_dist_1d_onnt._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{node_modules_next_dist_client_components_0inhx6q._.js → node_modules_next_dist_client_components_0wpq8j3._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules_next_dist_client_components_builtin_forbidden_0ghu-f7.js → node_modules_next_dist_client_components_builtin_forbidden_0symwr9.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules_next_dist_client_components_builtin_unauthorized_0cjv-23.js → node_modules_next_dist_client_components_builtin_unauthorized_0l_sp0x.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0-uvagv.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_03c7gi5.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_09p-8om.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0v-kfiu.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/{node_modules_next_dist_esm_build_templates_app-page_0j79~gv.js → node_modules_next_dist_esm_build_templates_app-page_0xrgzyz.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_1806lsc.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_1j6dd-e.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_1sa65r-.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/node_modules_posthog-node_dist_entrypoints_index_node_mjs_11bnuzn._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_1ezd2jf._.js +5 -0
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_1tnuifj._.js +5 -0
- package/.next/standalone/.next/server/functions-config-manifest.json +3 -0
- package/.next/standalone/.next/server/instrumentation.js +1 -1
- package/.next/standalone/.next/server/middleware-build-manifest.js +10 -10
- package/.next/standalone/.next/server/middleware.js +2 -2
- package/.next/standalone/.next/server/next-font-manifest.js +1 -1
- package/.next/standalone/.next/server/next-font-manifest.json +2 -21
- package/.next/standalone/.next/server/pages/404.html +1 -1
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +27 -9
- package/.next/standalone/.next/static/chunks/{07uz2g0_38qia.js → 03fmihek9n986.js} +1 -1
- package/.next/standalone/.next/static/chunks/09ueq8s1as8xs.css +2 -0
- package/.next/standalone/.next/static/chunks/0ehe4dh0grngk.js +41 -0
- package/.next/standalone/.next/static/chunks/{0bke.~atnsbeb.js → 0gdm-xaez4l7t.js} +1 -1
- package/.next/standalone/.next/static/chunks/{11w14gnqzprir.js → 0kdglk0vtzymo.js} +1 -1
- package/.next/standalone/.next/static/chunks/0qassxjx1ef04.js +1 -0
- package/.next/standalone/.next/static/chunks/0zbxssxh53n-3.js +1 -0
- package/.next/standalone/.next/static/chunks/13f1kmjea-0md.js +2 -0
- package/.next/standalone/.next/static/chunks/1btx2c49fk9xt.css +1 -0
- package/.next/standalone/.next/static/chunks/1fmco3pvq_twz.js +1 -0
- package/.next/standalone/.next/static/chunks/2b1fzuhuk-42n.js +1 -0
- package/.next/standalone/.next/static/chunks/{0bv1oyxspkpkb.js → 2dtip-mvmihiu.js} +1 -1
- package/.next/standalone/.next/static/chunks/2srzafd1_ha5y.js +1 -0
- package/.next/standalone/.next/static/chunks/{0d3shmwh5_nmn.js → 33u59vf_8xpd-.js} +1 -1
- package/.next/standalone/.next/static/chunks/3gti1qdk5epqn.js +1 -0
- package/.next/standalone/.next/static/chunks/{0dvhi-prcsh3~.js → 3krzy-lhwfrmz.js} +1 -1
- package/.next/standalone/.next/static/chunks/{17mubwtqwijpu.js → 3w8d8k_dca5rp.js} +1 -1
- package/.next/standalone/.next/static/chunks/43lnq0c1rnflb.js +6 -0
- package/.next/standalone/.next/static/chunks/{turbopack-0nh.aopesgj~5.js → turbopack-00qy7zfa7m--m.js} +1 -1
- package/.next/standalone/SECURITY.md +73 -0
- package/.next/standalone/app/actions/get-audit-result.ts +24 -0
- package/.next/standalone/app/api/audit/_state.ts +72 -0
- package/.next/standalone/app/api/audit/run/route.ts +89 -0
- package/.next/standalone/app/api/audit/status/route.ts +23 -0
- package/.next/standalone/app/api/auth/login-request/route.ts +91 -0
- package/.next/standalone/app/api/auth/login-verify/route.ts +98 -0
- package/.next/standalone/app/api/auth/logout/route.ts +48 -0
- package/.next/standalone/app/api/auth/reminder/route.ts +213 -0
- package/.next/standalone/app/api/auth/status/route.ts +42 -0
- package/.next/standalone/app/audit/_components/audit-dashboard.tsx +364 -0
- package/.next/standalone/app/audit/_components/auth-dialog.tsx +401 -0
- package/.next/standalone/app/audit/_components/empty-state.tsx +146 -0
- package/.next/standalone/app/audit/_components/findings-section.tsx +135 -0
- package/.next/standalone/app/audit/_components/identity-section.tsx +126 -0
- package/.next/standalone/app/audit/_components/policies-section.tsx +194 -0
- package/.next/standalone/app/audit/_components/report-footer.tsx +35 -0
- package/.next/standalone/app/audit/_components/rerun-button.tsx +81 -0
- package/.next/standalone/app/audit/_components/return-section.tsx +428 -0
- package/.next/standalone/app/audit/_components/run-progress.tsx +120 -0
- package/.next/standalone/app/audit/_components/score-section.tsx +179 -0
- package/.next/standalone/app/audit/_components/share-dock.tsx +265 -0
- package/.next/standalone/app/audit/_components/share-templates.ts +67 -0
- package/.next/standalone/app/audit/_components/show-off-cta.tsx +135 -0
- package/.next/standalone/app/audit/_components/sigil.tsx +93 -0
- package/.next/standalone/app/audit/_components/strengths-section.tsx +57 -0
- package/.next/standalone/app/audit/audit-styles.css +2066 -0
- package/.next/standalone/app/audit/loading.tsx +24 -0
- package/.next/standalone/app/audit/page.tsx +53 -0
- package/.next/standalone/app/globals.css +570 -137
- package/.next/standalone/app/layout.tsx +16 -9
- package/.next/standalone/app/policies/hooks-client.tsx +223 -129
- package/.next/standalone/app/project/[name]/page.tsx +89 -39
- package/.next/standalone/app/projects/loading.tsx +30 -8
- package/.next/standalone/app/projects/page.tsx +76 -18
- package/.next/standalone/assets/audit/Audit Report.html +22 -0
- package/.next/standalone/assets/audit/Show Off Your Agent.html +22 -0
- package/.next/standalone/assets/audit/archetypes.jsx +277 -0
- package/.next/standalone/assets/audit/assets/fonts/bitcount-prop-single.woff2 +0 -0
- package/.next/standalone/assets/audit/audit.jsx +825 -0
- package/.next/standalone/assets/audit/poster-styles.css +424 -0
- package/.next/standalone/assets/audit/poster.jsx +247 -0
- package/.next/standalone/assets/audit/screenshots/poster-optimist.png +0 -0
- package/.next/standalone/assets/audit/screenshots/poster-scrolled.png +0 -0
- package/.next/standalone/assets/audit/styles.css +1225 -0
- package/.next/standalone/assets/audit/tweaks-panel.jsx +425 -0
- package/.next/standalone/assets/logos/company/icon.svg +1 -0
- package/.next/standalone/assets/logos/company/logo.svg +1 -0
- package/.next/standalone/components/navbar.tsx +154 -65
- package/.next/standalone/components/reach-developers.tsx +37 -9
- package/.next/standalone/lib/atomic-write.ts +67 -0
- package/.next/standalone/lib/auth/api-server-client.ts +281 -0
- package/.next/standalone/lib/auth/auth-store.ts +250 -0
- package/.next/standalone/lib/client-telemetry.ts +2 -0
- package/.next/standalone/lib/fetch-with-timeout.ts +42 -0
- package/.next/standalone/lib/share-card.ts +120 -0
- package/.next/standalone/lib/telemetry.ts +12 -7
- package/.next/standalone/node_modules/@next/env/package.json +1 -1
- package/.next/standalone/node_modules/next/dist/build/swc/index.js +1 -1
- package/.next/standalone/node_modules/next/dist/client/dev/debug-channel.js +102 -2
- package/.next/standalone/node_modules/next/dist/compiled/next-server/app-page-turbo-experimental.runtime.prod.js +11 -11
- package/.next/standalone/node_modules/next/dist/compiled/next-server/app-page-turbo.runtime.prod.js +13 -13
- package/.next/standalone/node_modules/next/dist/compiled/next-server/app-route-turbo.runtime.prod.js +2 -2
- package/.next/standalone/node_modules/next/dist/compiled/next-server/pages-turbo.runtime.prod.js +1 -1
- package/.next/standalone/node_modules/next/dist/lib/patch-incorrect-lockfile.js +3 -3
- package/.next/standalone/node_modules/next/dist/server/app-render/action-handler.js +18 -8
- package/.next/standalone/node_modules/next/dist/server/config-schema.js +1 -0
- package/.next/standalone/node_modules/next/dist/server/config.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-turbopack.js +2 -2
- package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-webpack.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/lib/app-info-log.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/lib/encode-cache-tag.js +45 -0
- package/.next/standalone/node_modules/next/dist/server/lib/implicit-tags.js +6 -3
- package/.next/standalone/node_modules/next/dist/server/lib/patch-fetch.js +5 -1
- package/.next/standalone/node_modules/next/dist/server/lib/start-server.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/web/spec-extension/revalidate.js +4 -3
- package/.next/standalone/node_modules/next/dist/server/web/spec-extension/unstable-cache.js +6 -2
- package/.next/standalone/node_modules/next/dist/shared/lib/errors/canary-only-config-error.js +1 -1
- package/.next/standalone/node_modules/next/dist/telemetry/anonymous-meta.js +1 -1
- package/.next/standalone/node_modules/next/dist/telemetry/events/swc-load-failure.js +1 -1
- package/.next/standalone/node_modules/next/dist/telemetry/events/version.js +2 -2
- package/.next/standalone/node_modules/next/package.json +15 -15
- package/.next/standalone/node_modules/react/cjs/react.development.js +1 -1
- package/.next/standalone/node_modules/react/cjs/react.production.js +1 -1
- package/.next/standalone/node_modules/react/package.json +1 -1
- package/.next/standalone/node_modules/react-dom/cjs/react-dom-server-legacy.browser.production.js +1 -1
- package/.next/standalone/node_modules/react-dom/cjs/react-dom-server-legacy.node.production.js +1 -1
- package/.next/standalone/node_modules/react-dom/cjs/react-dom-server.browser.production.js +3 -3
- package/.next/standalone/node_modules/react-dom/cjs/react-dom-server.edge.production.js +3 -3
- package/.next/standalone/node_modules/react-dom/cjs/react-dom-server.node.production.js +3 -3
- package/.next/standalone/node_modules/react-dom/cjs/react-dom.production.js +1 -1
- package/.next/standalone/node_modules/react-dom/package.json +2 -2
- package/.next/standalone/osv-scanner.toml +17 -0
- package/.next/standalone/package.json +8 -3
- package/.next/standalone/public/audit/fonts/bitcount-prop-single.woff2 +0 -0
- package/.next/standalone/public/icon.svg +1 -0
- package/.next/standalone/public/logo.svg +1 -0
- package/.next/standalone/server.js +1 -1
- package/.next/standalone/templates/bitcount-font/README.md +42 -0
- package/.next/standalone/templates/bitcount-font/bitcount-prop-single.woff2 +0 -0
- package/.next/standalone/templates/bitcount-font/bitcount.css +49 -0
- package/.next/standalone/templates/bitcount-font/fonts.ts.example +23 -0
- package/README.md +2 -1
- package/bin/failproofai.mjs +165 -144
- package/dist/cli.mjs +607 -1858
- package/lib/atomic-write.ts +67 -0
- package/lib/auth/api-server-client.ts +281 -0
- package/lib/auth/auth-store.ts +250 -0
- package/lib/client-telemetry.ts +2 -0
- package/lib/fetch-with-timeout.ts +42 -0
- package/lib/share-card.ts +120 -0
- package/lib/telemetry.ts +12 -7
- package/package.json +8 -3
- package/scripts/install-telemetry.mjs +4 -0
- package/src/audit/archetypes.ts +924 -0
- package/src/audit/cache.ts +21 -2
- package/src/audit/dashboard-cache.ts +111 -0
- package/src/audit/features.ts +268 -0
- package/src/audit/findings.ts +298 -0
- package/src/audit/index.ts +39 -21
- package/src/audit/replay.ts +29 -3
- package/src/audit/scoring.ts +174 -0
- package/src/audit/strengths.ts +138 -0
- package/src/audit/types.ts +24 -1
- package/src/auth/cli.ts +359 -0
- package/src/hooks/builtin-policies.ts +2 -1
- package/src/hooks/hook-telemetry.ts +2 -2
- package/src/hooks/policy-registry.ts +20 -0
- package/src/posthog-key.ts +9 -0
- package/.next/standalone/.next/server/app/icon.png/route/app-paths-manifest.json +0 -3
- package/.next/standalone/.next/server/app/icon.png/route.js +0 -7
- package/.next/standalone/.next/server/app/icon.png/route.js.nft.json +0 -1
- package/.next/standalone/.next/server/app/icon.png.body +0 -0
- package/.next/standalone/.next/server/app/icon.png.meta +0 -1
- package/.next/standalone/.next/server/chunks/[externals]_next_dist_0sqmaqd._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__06.arfm._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0__i0h0._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0fe7_q_._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0fw.e.h._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0pxn0e1._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0xv0jh2._.js +0 -3
- package/.next/standalone/.next/server/chunks/_next-internal_server_app_icon_png_route_actions_12.gv.r.js +0 -3
- package/.next/standalone/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_0bdfoky.js +0 -3
- package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_05pz9._._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__01as125._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0370~qj._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__09v.ljl._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0agrcb8._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0b7hkr~._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ehh6vp._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0g8l0tu._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0j4l6hl._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0k5n2kz._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0lp08ll._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0n0yaqw._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0o21f.o._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0t8juvy._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0uylufv._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ymlddl._.js +0 -223
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0~03grs._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/app_0cdqd9w._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_0xerkr6._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_0q-m0y-._.js +0 -8
- package/.next/standalone/.next/server/chunks/ssr/app_projects_loading_tsx_13veom4._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/node_modules_0ttbz1~._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_06u0kr8._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0a_7sdg.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0ef3uwk.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0pbja1x.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0r6o0i2.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_11y81~_.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_12or2kf.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/node_modules_posthog-node_dist_entrypoints_index_node_mjs_0mebn66._.js +0 -3
- package/.next/standalone/.next/static/chunks/07kpqoo7kuckx.js +0 -6
- package/.next/standalone/.next/static/chunks/0azb~vy9ds_uy.js +0 -1
- package/.next/standalone/.next/static/chunks/0f5p9plm.aqlp.css +0 -2
- package/.next/standalone/.next/static/chunks/0ffvlbgzgnlw7.js +0 -2
- package/.next/standalone/.next/static/chunks/0spktq7xqab9h.js +0 -1
- package/.next/standalone/.next/static/chunks/118q3uljozd5z.js +0 -4
- package/.next/standalone/.next/static/chunks/12pt~2f.c1sha.js +0 -1
- package/.next/standalone/.next/static/media/4fa387ec64143e14-s.0.qu-9752pffj.woff2 +0 -0
- package/.next/standalone/.next/static/media/5ce348bf30bf5439-s.0ee55_hj9qcer.woff2 +0 -0
- package/.next/standalone/.next/static/media/6306c77e7c8268e4-s.0mao5jbfbduzp.woff2 +0 -0
- package/.next/standalone/.next/static/media/797e433ab948586e-s.p.09zddjkbdep5a.woff2 +0 -0
- package/.next/standalone/.next/static/media/7d817b4c03b0c5f1-s.0uzt.a6d44yda.woff2 +0 -0
- package/.next/standalone/.next/static/media/bbc41e54d2fcbd21-s.0mvwgmnhv29no.woff2 +0 -0
- package/.next/standalone/.next/static/media/icon.0a.gigb3_x5pd.png +0 -0
- package/.next/standalone/app/icon.png +0 -0
- package/src/audit/telemetry.ts +0 -113
- /package/.next/standalone/.next/server/app/{icon.png → api/audit/run}/route/build-manifest.json +0 -0
- /package/.next/standalone/.next/server/app/{icon.png → api/audit/run}/route.js.map +0 -0
- /package/.next/standalone/.next/static/chunks/{03~yq9q893hmn.js → 0cz1d0mv5g_q7.js} +0 -0
- /package/.next/standalone/.next/static/chunks/{0a40sy4tk8ioe.js → 0wwt5o04i4zwh.js} +0 -0
- /package/.next/standalone/.next/static/chunks/{0n1n67imq.udf.js → 1__i9af9g78vd.js} +0 -0
- /package/.next/standalone/.next/static/chunks/{0w6fzf.07a24u.js → 2so39wg7mjbi7.js} +0 -0
- /package/.next/standalone/.next/static/chunks/{0xbo5nl6w4lka.js → 2wbuxnsvux4di.js} +0 -0
- /package/.next/standalone/.next/static/chunks/{0_s0luks5tay-.js → 35fgpd_feci6x.js} +0 -0
- /package/.next/standalone/.next/static/chunks/{15fklyav5py5m.js → 3xpjn3cdgm-7m.js} +0 -0
- /package/.next/standalone/.next/static/chunks/{17.b3suj8zjjj.js → 4448_qq7bd963.js} +0 -0
- /package/.next/standalone/.next/static/{tGVQM5SE3NvbVu0gbAJm7 → wU3ot-EKa5ApKoh785wp8}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{tGVQM5SE3NvbVu0gbAJm7 → wU3ot-EKa5ApKoh785wp8}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{tGVQM5SE3NvbVu0gbAJm7 → wU3ot-EKa5ApKoh785wp8}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Section 03 — SCORE CARD.
|
|
5
|
+
*
|
|
6
|
+
* Left column only: YOUR AUDIT SCORE (big number, tier badge, progress
|
|
7
|
+
* bar, 3 stat boxes, prescribed-policies chip strip).
|
|
8
|
+
*
|
|
9
|
+
* Share actions have moved to IdentitySection below the archetype sigil.
|
|
10
|
+
*/
|
|
11
|
+
import React, { useMemo } from "react";
|
|
12
|
+
import type { AuditResult } from "@/src/audit/types";
|
|
13
|
+
import { ARCHETYPES, type ArchetypeKey } from "@/src/audit/archetypes";
|
|
14
|
+
import { type Grade } from "@/src/audit/scoring";
|
|
15
|
+
|
|
16
|
+
const GRADE_THRESHOLDS: { g: Grade; t: number }[] = [
|
|
17
|
+
{ g: "S", t: 90 }, { g: "A", t: 80 }, { g: "B", t: 71 },
|
|
18
|
+
{ g: "C", t: 55 }, { g: "D", t: 40 },
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
function pointsToNextFor(score: number): { next: Grade; delta: number } {
|
|
22
|
+
for (const { g, t } of GRADE_THRESHOLDS) {
|
|
23
|
+
if (score < t) return { next: g, delta: t - score };
|
|
24
|
+
}
|
|
25
|
+
return { next: "S", delta: 0 };
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
interface Props {
|
|
29
|
+
result: AuditResult;
|
|
30
|
+
score: number;
|
|
31
|
+
grade: Grade;
|
|
32
|
+
archetypeKey: ArchetypeKey;
|
|
33
|
+
/** Display name shown in the card header. */
|
|
34
|
+
project: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function ScoreSection({ result, score, grade, archetypeKey, project }: Props) {
|
|
38
|
+
const archetype = ARCHETYPES[archetypeKey];
|
|
39
|
+
// Cheap scan of 5 thresholds — plain computation. React Compiler memoizes
|
|
40
|
+
// the surrounding render anyway, and `useMemo` here tripped the
|
|
41
|
+
// preserve-manual-memoization rule.
|
|
42
|
+
const pointsToNext = pointsToNextFor(score);
|
|
43
|
+
|
|
44
|
+
/** Slipping-through builtin policies (the same heuristic ReturnSection uses
|
|
45
|
+
* for its [install policies] CTA). Used as the "policies missing" stat. */
|
|
46
|
+
const missing = useMemo(
|
|
47
|
+
() => result.results.filter((r) => r.source === "builtin" && !r.enabledInConfig && r.hits > 0).length,
|
|
48
|
+
[result],
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
/** Rough "days to fix" — capped 1..14. One day per slipping policy, with a
|
|
52
|
+
* baseline of 3d on any non-S grade. */
|
|
53
|
+
const daysToFix = useMemo(() => {
|
|
54
|
+
if (grade === "S" || missing === 0) return 0;
|
|
55
|
+
return Math.max(1, Math.min(14, missing + 1));
|
|
56
|
+
}, [grade, missing]);
|
|
57
|
+
|
|
58
|
+
/** % of 0–100 bar to fill — simply score/100. */
|
|
59
|
+
const progressPct = score;
|
|
60
|
+
|
|
61
|
+
/** Top-N slipping policies → chip strip on the left card. Capped at 6. */
|
|
62
|
+
const policyChips = useMemo(() => {
|
|
63
|
+
const slipping = result.results
|
|
64
|
+
.filter((r) => r.source === "builtin" && !r.enabledInConfig && r.hits > 0)
|
|
65
|
+
.sort((a, b) => b.hits - a.hits)
|
|
66
|
+
.slice(0, 6)
|
|
67
|
+
.map((r) => ({ name: shortPolicyLabel(r.name), missing: true as const }));
|
|
68
|
+
const enabled = result.results
|
|
69
|
+
.filter((r) => r.source === "builtin" && r.enabledInConfig)
|
|
70
|
+
.slice(0, Math.max(0, 6 - slipping.length))
|
|
71
|
+
.map((r) => ({ name: shortPolicyLabel(r.name), missing: false as const }));
|
|
72
|
+
return [...slipping, ...enabled];
|
|
73
|
+
}, [result]);
|
|
74
|
+
|
|
75
|
+
return (
|
|
76
|
+
<section className="section" data-screen-label="03 Score">
|
|
77
|
+
<div className="section-mast">
|
|
78
|
+
<div className="section-label">
|
|
79
|
+
<span className="glyph">━━</span> score
|
|
80
|
+
<span style={{ color: "var(--accent-green)", marginLeft: 10, letterSpacing: "0.04em", textTransform: "none", fontSize: 11 }}>· SEE HOW YOUR AGENT IS PERFORMING</span>
|
|
81
|
+
</div>
|
|
82
|
+
</div>
|
|
83
|
+
<h2 className="section-h">your audit score.</h2>
|
|
84
|
+
|
|
85
|
+
<div className="panel score-share-card">
|
|
86
|
+
<div className="score-card-header">
|
|
87
|
+
<span style={{ color: "var(--ink)" }}>{project}</span>
|
|
88
|
+
<span style={{ color: "var(--dim)" }}> · </span>
|
|
89
|
+
<span style={{ color: "var(--accent-pink)" }}>{archetype.name.toLowerCase()}</span>
|
|
90
|
+
</div>
|
|
91
|
+
|
|
92
|
+
<div className="ss-score-row">
|
|
93
|
+
<span className={"ss-score g-" + grade}>{score}</span>
|
|
94
|
+
<span className="ss-score-of">/100</span>
|
|
95
|
+
</div>
|
|
96
|
+
|
|
97
|
+
<div className="ss-tier-row">
|
|
98
|
+
<span className={"ss-tier-badge g-" + grade}>{grade} tier</span>
|
|
99
|
+
<span className="ss-arch">{archetype.name.toLowerCase()}</span>
|
|
100
|
+
</div>
|
|
101
|
+
|
|
102
|
+
<div className="ss-progress-label">
|
|
103
|
+
<span style={{ color: "var(--dim)" }}>score</span>
|
|
104
|
+
{pointsToNext.delta > 0 ? (
|
|
105
|
+
<span style={{ color: "var(--accent-pink)" }}>
|
|
106
|
+
+{pointsToNext.delta} pts to {pointsToNext.next} tier
|
|
107
|
+
</span>
|
|
108
|
+
) : (
|
|
109
|
+
<span style={{ color: "var(--accent-green)" }}>top tier ✓</span>
|
|
110
|
+
)}
|
|
111
|
+
</div>
|
|
112
|
+
<div className="ss-progress-track">
|
|
113
|
+
{[40, 55, 71, 80, 90].map((t) => (
|
|
114
|
+
<div key={t} className="ss-progress-tick" style={{ left: `${t}%` }} />
|
|
115
|
+
))}
|
|
116
|
+
<div
|
|
117
|
+
className="ss-progress-fill audit-bar-fill"
|
|
118
|
+
style={{ ["--bar-width" as string]: `${progressPct}%` }}
|
|
119
|
+
/>
|
|
120
|
+
</div>
|
|
121
|
+
<div className="ss-grade-stops">
|
|
122
|
+
{(["D", "C", "B", "A", "S"] as Grade[]).map((g, i) => {
|
|
123
|
+
const pos = [40, 55, 71, 80, 90][i];
|
|
124
|
+
return (
|
|
125
|
+
<span
|
|
126
|
+
key={g}
|
|
127
|
+
className={"ss-grade-stop" + (grade === g ? " active" : "")}
|
|
128
|
+
style={{ left: `${pos}%` }}
|
|
129
|
+
>{g}</span>
|
|
130
|
+
);
|
|
131
|
+
})}
|
|
132
|
+
</div>
|
|
133
|
+
|
|
134
|
+
<div className="ss-stats">
|
|
135
|
+
<div className="ss-stat">
|
|
136
|
+
<div className="ss-stat-n" style={{ color: "var(--amber)" }}>{missing}</div>
|
|
137
|
+
<div className="ss-stat-l">policies<br />missing</div>
|
|
138
|
+
</div>
|
|
139
|
+
<div className="ss-stat">
|
|
140
|
+
<div className="ss-stat-n" style={{ color: "var(--accent-pink)" }}>
|
|
141
|
+
+{pointsToNext.delta}
|
|
142
|
+
</div>
|
|
143
|
+
<div className="ss-stat-l">pts to<br />{pointsToNext.next} tier</div>
|
|
144
|
+
</div>
|
|
145
|
+
<div className="ss-stat">
|
|
146
|
+
<div className="ss-stat-n" style={{ color: "var(--accent-green)" }}>
|
|
147
|
+
{daysToFix === 0 ? "—" : `~${daysToFix}d`}
|
|
148
|
+
</div>
|
|
149
|
+
<div className="ss-stat-l">est.<br />to fix</div>
|
|
150
|
+
</div>
|
|
151
|
+
</div>
|
|
152
|
+
|
|
153
|
+
{policyChips.length > 0 && (
|
|
154
|
+
<>
|
|
155
|
+
<div className="ss-policy-label">policy status</div>
|
|
156
|
+
<div className="ss-policy-chips">
|
|
157
|
+
{policyChips.map((p, i) => (
|
|
158
|
+
<span
|
|
159
|
+
key={i}
|
|
160
|
+
className={"ss-chip" + (p.missing ? " missing" : " enabled")}
|
|
161
|
+
>
|
|
162
|
+
<span className="dot" aria-hidden="true" />
|
|
163
|
+
{p.name}
|
|
164
|
+
</span>
|
|
165
|
+
))}
|
|
166
|
+
</div>
|
|
167
|
+
</>
|
|
168
|
+
)}
|
|
169
|
+
</div>
|
|
170
|
+
</section>
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/** Drop the "failproofai/" namespace prefix builtin policies carry so chips
|
|
175
|
+
* stay compact (`block-sudo` reads better than `failproofai/block-sudo`). */
|
|
176
|
+
function shortPolicyLabel(name: string): string {
|
|
177
|
+
const slash = name.indexOf("/");
|
|
178
|
+
return slash >= 0 ? name.slice(slash + 1) : name;
|
|
179
|
+
}
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Floating share dock — always-visible bottom-right panel on the /audit
|
|
5
|
+
* dashboard. Three buttons (X, LinkedIn, download) that all share the
|
|
6
|
+
* `.share-btn` styling used by the inline buttons in `identity-section`,
|
|
7
|
+
* so the visual rhythm carries between surfaces.
|
|
8
|
+
*
|
|
9
|
+
* Capture flow:
|
|
10
|
+
* 1. Dock click → ref'd `.archetype-frame` is captured to a PNG blob
|
|
11
|
+
* via html2canvas.
|
|
12
|
+
* 2. `copyOrDownloadCard` writes the blob to the clipboard if the
|
|
13
|
+
* browser supports it, falling back to a download. The user gets a
|
|
14
|
+
* toast telling them what to do next.
|
|
15
|
+
* 3. For shares, the X / LinkedIn intent window opens with the
|
|
16
|
+
* templated text.
|
|
17
|
+
*
|
|
18
|
+
* UX:
|
|
19
|
+
* - Collapses to a single 48px pink FAB via a header caret. Preference
|
|
20
|
+
* persists across page navigations within a session.
|
|
21
|
+
* - Slide-in animation on mount (respects prefers-reduced-motion).
|
|
22
|
+
* - Hidden on viewports < 760px (mobile) — the inline buttons are
|
|
23
|
+
* already visible there and a floating dock would cover content.
|
|
24
|
+
* - Hidden until the archetype hero has actually mounted (frameRef
|
|
25
|
+
* resolves to a node). On the empty / running states we render
|
|
26
|
+
* nothing.
|
|
27
|
+
*/
|
|
28
|
+
import React, { useEffect, useState } from "react";
|
|
29
|
+
import { type ArchetypeKey, pickArchetypeVariant } from "@/src/audit/archetypes";
|
|
30
|
+
import { type Grade } from "@/src/audit/scoring";
|
|
31
|
+
import { copyOrDownloadCard, downloadCard, shareCardNative, shareCardToastMessage } from "@/lib/share-card";
|
|
32
|
+
import { toast } from "@/app/components/toast";
|
|
33
|
+
import { usePostHog } from "@/contexts/PostHogContext";
|
|
34
|
+
import { X_TEMPLATES, LI_TEMPLATES, pickTemplate, type ShareCtx } from "./share-templates";
|
|
35
|
+
|
|
36
|
+
const SITE_URL = "https://failproof.ai";
|
|
37
|
+
const X_INTENT = (text: string) =>
|
|
38
|
+
`https://x.com/intent/tweet?text=${encodeURIComponent(text)}`;
|
|
39
|
+
const LI_INTENT = (text: string) =>
|
|
40
|
+
`https://www.linkedin.com/sharing/share-offsite/?url=${encodeURIComponent(SITE_URL)}&summary=${encodeURIComponent(text)}`;
|
|
41
|
+
|
|
42
|
+
const COLLAPSED_KEY = "failproofai:audit:share-dock-collapsed";
|
|
43
|
+
|
|
44
|
+
interface Props {
|
|
45
|
+
/** Ref to the `.archetype-frame` to capture. Same node `identity-section`
|
|
46
|
+
* forwards into IdentitySection's `frameRef`. */
|
|
47
|
+
frameRef: React.RefObject<HTMLDivElement | null>;
|
|
48
|
+
archetypeKey: ArchetypeKey;
|
|
49
|
+
/** Seed for deterministic archetype-variant copy. Same as IdentitySection's
|
|
50
|
+
* `seed` prop — usually the inferred project name. */
|
|
51
|
+
seed: string;
|
|
52
|
+
score: number;
|
|
53
|
+
grade: Grade;
|
|
54
|
+
missing: number;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function ShareDock({ frameRef, archetypeKey, seed, score, grade, missing }: Props) {
|
|
58
|
+
const [collapsed, setCollapsed] = useState(false);
|
|
59
|
+
const [busy, setBusy] = useState<null | "x" | "linkedin" | "download">(null);
|
|
60
|
+
const { capture } = usePostHog();
|
|
61
|
+
const archetype = pickArchetypeVariant(archetypeKey, seed);
|
|
62
|
+
const archetypeDisplayName = archetype.name;
|
|
63
|
+
|
|
64
|
+
// Restore collapsed preference from sessionStorage on first mount.
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
try {
|
|
67
|
+
if (typeof window !== "undefined" && window.sessionStorage.getItem(COLLAPSED_KEY) === "1") {
|
|
68
|
+
setCollapsed(true);
|
|
69
|
+
}
|
|
70
|
+
} catch { /* private mode, etc. — fall through to default */ }
|
|
71
|
+
}, []);
|
|
72
|
+
|
|
73
|
+
const toggle = (next: boolean) => {
|
|
74
|
+
setCollapsed(next);
|
|
75
|
+
try { window.sessionStorage.setItem(COLLAPSED_KEY, next ? "1" : "0"); } catch { /* ignore */ }
|
|
76
|
+
capture("audit_share_dock_toggled", { collapsed: next });
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const captureCardBlob = async (): Promise<Blob | null> => {
|
|
80
|
+
const node = frameRef.current;
|
|
81
|
+
if (!node) return null;
|
|
82
|
+
node.classList.add("capturing");
|
|
83
|
+
try {
|
|
84
|
+
if (typeof document !== "undefined" && document.fonts?.ready) await document.fonts.ready;
|
|
85
|
+
await new Promise<void>((r) => requestAnimationFrame(() => r()));
|
|
86
|
+
const html2canvas = (await import("html2canvas")).default;
|
|
87
|
+
const canvas = await html2canvas(node, {
|
|
88
|
+
backgroundColor: "#0e0e11",
|
|
89
|
+
scale: 2,
|
|
90
|
+
logging: false,
|
|
91
|
+
useCORS: true,
|
|
92
|
+
});
|
|
93
|
+
return await new Promise<Blob | null>((resolve) => {
|
|
94
|
+
canvas.toBlob((blob) => resolve(blob), "image/png");
|
|
95
|
+
});
|
|
96
|
+
} finally {
|
|
97
|
+
node.classList.remove("capturing");
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const filenameFor = (channel: "x" | "linkedin" | "download") =>
|
|
102
|
+
`failproofai-${channel}-${grade.toLowerCase()}-${score}.png`;
|
|
103
|
+
|
|
104
|
+
const handleShare = async (channel: "x" | "linkedin" | "download") => {
|
|
105
|
+
if (busy) return;
|
|
106
|
+
setBusy(channel);
|
|
107
|
+
capture("audit_card_share_clicked", {
|
|
108
|
+
channel: channel === "download" ? "download" : channel,
|
|
109
|
+
source: "dock",
|
|
110
|
+
score,
|
|
111
|
+
grade,
|
|
112
|
+
missing_policies: missing,
|
|
113
|
+
});
|
|
114
|
+
try {
|
|
115
|
+
const blob = await captureCardBlob().catch(() => null);
|
|
116
|
+
if (!blob) {
|
|
117
|
+
capture("audit_card_capture_completed", {
|
|
118
|
+
trigger: channel === "download" ? "download" : `share_${channel}`,
|
|
119
|
+
status: "error",
|
|
120
|
+
image_method: "failed",
|
|
121
|
+
source: "dock",
|
|
122
|
+
});
|
|
123
|
+
toast(shareCardToastMessage("failed"));
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Dedicated "save audit-card" button: always download, never clipboard.
|
|
128
|
+
if (channel === "download") {
|
|
129
|
+
const ok = downloadCard(blob, filenameFor(channel));
|
|
130
|
+
const method = ok ? "download" : "failed";
|
|
131
|
+
capture("audit_card_capture_completed", {
|
|
132
|
+
trigger: "download",
|
|
133
|
+
status: ok ? "success" : "error",
|
|
134
|
+
image_method: method,
|
|
135
|
+
source: "dock",
|
|
136
|
+
});
|
|
137
|
+
toast(shareCardToastMessage(method));
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// X / LinkedIn share: try the native share sheet with file first
|
|
142
|
+
// (one-tap "image attached" on iOS / Android / recent Safari / recent
|
|
143
|
+
// Chrome). Fall back to clipboard + opening the intent URL when the
|
|
144
|
+
// native share sheet isn't available or the user dismissed it.
|
|
145
|
+
const shareCtx: ShareCtx = {
|
|
146
|
+
score,
|
|
147
|
+
arch: archetypeDisplayName.toLowerCase(),
|
|
148
|
+
grade,
|
|
149
|
+
missing,
|
|
150
|
+
};
|
|
151
|
+
// One of five tone-matched templates (quirky for X, professional for
|
|
152
|
+
// LinkedIn), chosen deterministically from the behaviour-fingerprint
|
|
153
|
+
// seed so the copy fits this run and stays stable on re-share.
|
|
154
|
+
const shareText = channel === "x"
|
|
155
|
+
? pickTemplate(X_TEMPLATES, seed, shareCtx)
|
|
156
|
+
: pickTemplate(LI_TEMPLATES, seed, shareCtx);
|
|
157
|
+
const native = await shareCardNative(blob, filenameFor(channel), shareText);
|
|
158
|
+
if (native) {
|
|
159
|
+
capture("audit_card_capture_completed", {
|
|
160
|
+
trigger: `share_${channel}`,
|
|
161
|
+
status: "success",
|
|
162
|
+
image_method: "native",
|
|
163
|
+
source: "dock",
|
|
164
|
+
});
|
|
165
|
+
toast(shareCardToastMessage("native"));
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const fallbackMethod = await copyOrDownloadCard(blob, filenameFor(channel));
|
|
170
|
+
capture("audit_card_capture_completed", {
|
|
171
|
+
trigger: `share_${channel}`,
|
|
172
|
+
status: "success",
|
|
173
|
+
image_method: fallbackMethod,
|
|
174
|
+
source: "dock",
|
|
175
|
+
});
|
|
176
|
+
toast(shareCardToastMessage(fallbackMethod));
|
|
177
|
+
const intent = channel === "x"
|
|
178
|
+
? X_INTENT(shareText)
|
|
179
|
+
: LI_INTENT(shareText);
|
|
180
|
+
globalThis.open(intent, "_blank", "noopener,noreferrer");
|
|
181
|
+
} finally {
|
|
182
|
+
setBusy(null);
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
// Render the collapsed FAB. Single pink-tile pulse that re-expands the dock.
|
|
187
|
+
if (collapsed) {
|
|
188
|
+
return (
|
|
189
|
+
<button
|
|
190
|
+
type="button"
|
|
191
|
+
className="share-dock-fab"
|
|
192
|
+
aria-label="Expand share dock"
|
|
193
|
+
onClick={() => toggle(false)}
|
|
194
|
+
>
|
|
195
|
+
<span aria-hidden="true">𝕏</span>
|
|
196
|
+
</button>
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return (
|
|
201
|
+
<aside
|
|
202
|
+
className="share-dock"
|
|
203
|
+
aria-label="Share your audit"
|
|
204
|
+
data-busy={busy ? "true" : undefined}
|
|
205
|
+
>
|
|
206
|
+
<header className="share-dock-head">
|
|
207
|
+
<span className="share-dock-eyebrow"><span aria-hidden="true">━━</span>share your audit</span>
|
|
208
|
+
<button
|
|
209
|
+
type="button"
|
|
210
|
+
className="share-dock-caret"
|
|
211
|
+
onClick={() => toggle(true)}
|
|
212
|
+
aria-label="Collapse share dock"
|
|
213
|
+
>
|
|
214
|
+
<span aria-hidden="true">▾</span>
|
|
215
|
+
</button>
|
|
216
|
+
</header>
|
|
217
|
+
<div className="share-dock-stack">
|
|
218
|
+
<button
|
|
219
|
+
type="button"
|
|
220
|
+
className="share-btn share-btn--x"
|
|
221
|
+
onClick={() => handleShare("x")}
|
|
222
|
+
disabled={busy !== null}
|
|
223
|
+
>
|
|
224
|
+
<span className="share-btn-mark share-btn-mark--x" aria-hidden="true">𝕏</span>
|
|
225
|
+
<span className="share-btn-body">
|
|
226
|
+
<span className="share-btn-eyebrow">share on</span>
|
|
227
|
+
<span className="share-btn-label">{busy === "x" ? "rendering…" : "X · Twitter"}</span>
|
|
228
|
+
</span>
|
|
229
|
+
<span className="share-btn-arrow" aria-hidden="true">→</span>
|
|
230
|
+
</button>
|
|
231
|
+
<button
|
|
232
|
+
type="button"
|
|
233
|
+
className="share-btn share-btn--li"
|
|
234
|
+
onClick={() => handleShare("linkedin")}
|
|
235
|
+
disabled={busy !== null}
|
|
236
|
+
>
|
|
237
|
+
<span className="share-btn-mark share-btn-mark--li" aria-hidden="true">in</span>
|
|
238
|
+
<span className="share-btn-body">
|
|
239
|
+
<span className="share-btn-eyebrow">share on</span>
|
|
240
|
+
<span className="share-btn-label">{busy === "linkedin" ? "rendering…" : "LinkedIn"}</span>
|
|
241
|
+
</span>
|
|
242
|
+
<span className="share-btn-arrow" aria-hidden="true">→</span>
|
|
243
|
+
</button>
|
|
244
|
+
<button
|
|
245
|
+
type="button"
|
|
246
|
+
className="share-btn share-btn--dl"
|
|
247
|
+
onClick={() => handleShare("download")}
|
|
248
|
+
disabled={busy !== null}
|
|
249
|
+
>
|
|
250
|
+
<span className="share-btn-mark share-btn-mark--dl" aria-hidden="true">↓</span>
|
|
251
|
+
<span className="share-btn-body">
|
|
252
|
+
<span className="share-btn-eyebrow">save</span>
|
|
253
|
+
<span className="share-btn-label">{busy === "download" ? "rendering…" : "audit-card"}</span>
|
|
254
|
+
</span>
|
|
255
|
+
<span className="share-btn-arrow" aria-hidden="true">↓</span>
|
|
256
|
+
</button>
|
|
257
|
+
</div>
|
|
258
|
+
<footer className="share-dock-foot">
|
|
259
|
+
<span aria-hidden="true">▮▮</span>image auto-attaches via paste
|
|
260
|
+
</footer>
|
|
261
|
+
</aside>
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
ShareDock.displayName = "ShareDock";
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Social-share copy for the audit identity card.
|
|
3
|
+
*
|
|
4
|
+
* Five quirky, emoji-forward templates for X and five measured, professional
|
|
5
|
+
* templates for LinkedIn. `pickTemplate` selects one deterministically from a
|
|
6
|
+
* seed (the behaviour fingerprint), so a given audit run always renders the
|
|
7
|
+
* same post while different runs / personas vary. Pure — no React, no DOM — so
|
|
8
|
+
* it's unit-testable and shared by the client `IdentitySection` component.
|
|
9
|
+
*/
|
|
10
|
+
import type { Grade } from "@/src/audit/scoring";
|
|
11
|
+
|
|
12
|
+
const SITE_URL = "https://failproof.ai";
|
|
13
|
+
|
|
14
|
+
export interface ShareCtx {
|
|
15
|
+
score: number;
|
|
16
|
+
/** Lowercased archetype name, e.g. "the cowboy". */
|
|
17
|
+
arch: string;
|
|
18
|
+
grade: Grade;
|
|
19
|
+
/** Count of unenabled prescribed policies. */
|
|
20
|
+
missing: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const pol = (n: number) => (n === 1 ? "policy" : "policies");
|
|
24
|
+
|
|
25
|
+
/** Quirky, emoji-forward — for X. */
|
|
26
|
+
export const X_TEMPLATES: ((c: ShareCtx) => string)[] = [
|
|
27
|
+
({ score, arch, grade, missing }) =>
|
|
28
|
+
`my AI coding agent just got profiled and it's "${arch}" 🤠\n\n${score}/100 · ${grade} tier${missing > 0 ? ` · ${missing} ${pol(missing)} between me and glory` : ` · every guardrail live`}\n\nwhat's yours? → ${SITE_URL}`,
|
|
29
|
+
({ score, arch, grade }) =>
|
|
30
|
+
`turns out my coding agent has a whole personality and it's ${arch} 💀\n\nscored ${score}/100 (${grade} tier). the audit does not miss.\n\nrun yours in 30s → ${SITE_URL}`,
|
|
31
|
+
({ score, arch, grade }) =>
|
|
32
|
+
`${score}/100. ${grade} tier. archetype: ${arch} 👀\n\nfailproofai reverse-engineered my agent's entire vibe from its own session logs.\n\n${SITE_URL}`,
|
|
33
|
+
({ score, arch, grade, missing }) =>
|
|
34
|
+
`plot twist: my AI agent is ${arch} 🎭\n\n${score}/100 · ${grade} tier${missing > 0 ? ` · ${missing} ${pol(missing)} away from behaving` : ` · spotless, somehow`}\n\nfailproof.ai`,
|
|
35
|
+
({ score, arch, grade }) =>
|
|
36
|
+
`i let failproofai audit my coding agent and it called me ${arch} ${grade === "S" || grade === "A" ? "😎" : "😬"}\n\n${score}/100, ${grade} tier. brutally accurate. no notes.\n\n${SITE_URL}`,
|
|
37
|
+
];
|
|
38
|
+
|
|
39
|
+
/** Measured, professional — for LinkedIn. */
|
|
40
|
+
export const LI_TEMPLATES: ((c: ShareCtx) => string)[] = [
|
|
41
|
+
({ score, arch, grade, missing }) =>
|
|
42
|
+
`I ran a failproofai audit on our AI coding agents.\n\nResult: ${score}/100 — ${grade} tier, behavioural archetype "${arch}". ${missing > 0 ? `${missing} prescribed ${pol(missing)} would close the remaining gaps.` : `Every prescribed policy is already live.`}\n\nUnderstanding how agents actually behave across real sessions is the first step to securing them. Free and open-source: ${SITE_URL}`,
|
|
43
|
+
({ score, arch, grade, missing }) =>
|
|
44
|
+
`Security posture check on our coding-agent stack, via failproofai.\n\nScore: ${score}/100 (${grade} tier). Behavioural profile: "${arch}". ${missing > 0 ? `${missing} ${pol(missing)} flagged as real, addressable attack surface.` : `No open policy gaps.`}\n\nThirty seconds to run your own assessment: ${SITE_URL}`,
|
|
45
|
+
({ score, arch, grade }) =>
|
|
46
|
+
`Most teams can't answer a simple question: how do our AI agents actually behave when no one is watching?\n\nfailproofai audited ours and profiled it as "${arch}" — ${score}/100, ${grade} tier. Concrete, evidence-backed, and mapped to the exact policies that close each gap.\n\n${SITE_URL}`,
|
|
47
|
+
({ score, arch, grade, missing }) =>
|
|
48
|
+
`Agent security isn't a vibe — it's measurable.\n\nWe scored ${score}/100 (${grade} tier) on the failproofai audit, archetype "${arch}". ${missing > 0 ? `${missing} prescribed ${pol(missing)} remain to harden the stack.` : `Full coverage on every prescribed policy.`}\n\nWorth 30 seconds for any team shipping with AI agents: ${SITE_URL}`,
|
|
49
|
+
({ score, arch, grade }) =>
|
|
50
|
+
`Ran our coding agents through a failproofai behavioural audit.\n\n${score}/100, ${grade} tier — archetype "${arch}". The report maps every risky pattern to the policy that prevents it, so remediation becomes a checklist rather than a guess.\n\nOpen-source, free to run: ${SITE_URL}`,
|
|
51
|
+
];
|
|
52
|
+
|
|
53
|
+
/** djb2 hash — stable per seed so the template choice is deterministic. */
|
|
54
|
+
function hashStr(s: string): number {
|
|
55
|
+
let h = 5381;
|
|
56
|
+
for (let i = 0; i < s.length; i++) h = ((h << 5) + h + s.charCodeAt(i)) | 0;
|
|
57
|
+
return h >>> 0;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** Deterministically pick + render one template for the given seed. */
|
|
61
|
+
export function pickTemplate(
|
|
62
|
+
templates: ((c: ShareCtx) => string)[],
|
|
63
|
+
seed: string,
|
|
64
|
+
ctx: ShareCtx,
|
|
65
|
+
): string {
|
|
66
|
+
return templates[hashStr(seed) % templates.length](ctx);
|
|
67
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Section 01b — SHOW OFF CTA. Big bordered strip directly after the
|
|
5
|
+
* identity card. Sigil on the left, "show off your agent." headline +
|
|
6
|
+
* sub on the middle, "→ MAKE POSTER" action button on the right.
|
|
7
|
+
*
|
|
8
|
+
* Clicking the action captures the IdentitySection's archetype-frame
|
|
9
|
+
* DOM via html2canvas and triggers a PNG download. The capture target
|
|
10
|
+
* is passed in via a ref (avoids querying the DOM by class).
|
|
11
|
+
*/
|
|
12
|
+
import React, { useState } from "react";
|
|
13
|
+
import { ARCHETYPES, type ArchetypeKey } from "@/src/audit/archetypes";
|
|
14
|
+
import { usePostHog } from "@/contexts/PostHogContext";
|
|
15
|
+
import { Sigil } from "./sigil";
|
|
16
|
+
|
|
17
|
+
interface Props {
|
|
18
|
+
archetypeKey: ArchetypeKey;
|
|
19
|
+
/** Ref to the IdentitySection's `.archetype-frame` div — captured to PNG. */
|
|
20
|
+
identityFrameRef: React.RefObject<HTMLDivElement | null>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function buildFilename(archetypeKey: ArchetypeKey): string {
|
|
24
|
+
const date = new Date().toISOString().slice(0, 10);
|
|
25
|
+
return `failproofai-${archetypeKey}-${date}.png`;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function ShowOffCTA({ archetypeKey, identityFrameRef }: Props) {
|
|
29
|
+
const archetype = ARCHETYPES[archetypeKey];
|
|
30
|
+
const { capture } = usePostHog();
|
|
31
|
+
const [state, setState] = useState<"idle" | "busy" | "done" | "error">("idle");
|
|
32
|
+
|
|
33
|
+
const handleMakePoster = async () => {
|
|
34
|
+
const node = identityFrameRef.current;
|
|
35
|
+
if (!node || state === "busy") return;
|
|
36
|
+
capture("audit_poster_clicked", {
|
|
37
|
+
archetype: archetypeKey,
|
|
38
|
+
});
|
|
39
|
+
setState("busy");
|
|
40
|
+
/** Add a capture-only class that locks font sizes, the grid layout,
|
|
41
|
+
* and disables clamp()/text-shadow rules html2canvas renders
|
|
42
|
+
* unreliably. CSS lives in audit-styles.css under `.capturing`. */
|
|
43
|
+
node.classList.add("capturing");
|
|
44
|
+
try {
|
|
45
|
+
// Wait for the display font (Bitcount Prop Single) to load — otherwise
|
|
46
|
+
// html2canvas captures a fallback that has different metrics and the
|
|
47
|
+
// archetype name overlaps the tagline / sigil column.
|
|
48
|
+
if (typeof document !== "undefined" && document.fonts?.ready) {
|
|
49
|
+
await document.fonts.ready;
|
|
50
|
+
}
|
|
51
|
+
// Force a single rAF so the .capturing class is applied to layout
|
|
52
|
+
// before html2canvas reads computed styles.
|
|
53
|
+
await new Promise<void>((r) => requestAnimationFrame(() => r()));
|
|
54
|
+
|
|
55
|
+
const html2canvas = (await import("html2canvas")).default;
|
|
56
|
+
// Bleed: include the frame's 8px box-shadow in the capture rect.
|
|
57
|
+
const bleed = 12;
|
|
58
|
+
const canvas = await html2canvas(node, {
|
|
59
|
+
backgroundColor: "#131316",
|
|
60
|
+
scale: 2,
|
|
61
|
+
logging: false,
|
|
62
|
+
useCORS: true,
|
|
63
|
+
x: -bleed,
|
|
64
|
+
y: -bleed,
|
|
65
|
+
width: node.offsetWidth + bleed * 2,
|
|
66
|
+
height: node.offsetHeight + bleed * 2,
|
|
67
|
+
windowWidth: Math.max(1100, node.offsetWidth + bleed * 2),
|
|
68
|
+
});
|
|
69
|
+
await new Promise<void>((resolve) => {
|
|
70
|
+
canvas.toBlob((blob) => {
|
|
71
|
+
if (!blob) { resolve(); return; }
|
|
72
|
+
const url = URL.createObjectURL(blob);
|
|
73
|
+
const a = document.createElement("a");
|
|
74
|
+
a.href = url;
|
|
75
|
+
a.download = buildFilename(archetypeKey);
|
|
76
|
+
document.body.appendChild(a);
|
|
77
|
+
a.click();
|
|
78
|
+
document.body.removeChild(a);
|
|
79
|
+
URL.revokeObjectURL(url);
|
|
80
|
+
resolve();
|
|
81
|
+
}, "image/png");
|
|
82
|
+
});
|
|
83
|
+
capture("audit_poster_completed", {
|
|
84
|
+
status: "success",
|
|
85
|
+
archetype: archetypeKey,
|
|
86
|
+
});
|
|
87
|
+
setState("done");
|
|
88
|
+
setTimeout(() => setState("idle"), 2000);
|
|
89
|
+
} catch (err) {
|
|
90
|
+
console.error("poster capture failed:", err);
|
|
91
|
+
capture("audit_poster_completed", {
|
|
92
|
+
status: "error",
|
|
93
|
+
archetype: archetypeKey,
|
|
94
|
+
});
|
|
95
|
+
setState("error");
|
|
96
|
+
setTimeout(() => setState("idle"), 2000);
|
|
97
|
+
} finally {
|
|
98
|
+
node.classList.remove("capturing");
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
const actionLabel =
|
|
103
|
+
state === "busy" ? "rendering…"
|
|
104
|
+
: state === "done" ? "downloaded ✓"
|
|
105
|
+
: state === "error" ? "render failed"
|
|
106
|
+
: "make poster";
|
|
107
|
+
|
|
108
|
+
return (
|
|
109
|
+
<section className="showoff" data-screen-label="01b Show off">
|
|
110
|
+
<button
|
|
111
|
+
type="button"
|
|
112
|
+
className="showoff-cta"
|
|
113
|
+
onClick={handleMakePoster}
|
|
114
|
+
disabled={state === "busy"}
|
|
115
|
+
style={{ cursor: state === "busy" ? "wait" : "pointer", width: "100%", textAlign: "left" }}
|
|
116
|
+
>
|
|
117
|
+
<span className="showoff-glyph" aria-hidden="true">
|
|
118
|
+
<Sigil archetypeKey={archetypeKey} hideLabel />
|
|
119
|
+
</span>
|
|
120
|
+
<span className="showoff-copy">
|
|
121
|
+
<span className="showoff-label">━━ shareable poster</span>
|
|
122
|
+
<span className="showoff-headline">show off your agent.</span>
|
|
123
|
+
<span className="showoff-sub">
|
|
124
|
+
generate a one-page poster of your {archetype.name}.
|
|
125
|
+
score, percentile, sigil. ready to post.
|
|
126
|
+
</span>
|
|
127
|
+
</span>
|
|
128
|
+
<span className="showoff-action">
|
|
129
|
+
<span className="showoff-arrow">→</span>
|
|
130
|
+
<span className="showoff-action-label">{actionLabel}</span>
|
|
131
|
+
</span>
|
|
132
|
+
</button>
|
|
133
|
+
</section>
|
|
134
|
+
);
|
|
135
|
+
}
|