failproofai 0.0.11-beta.1 → 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]__0ywoypf._.js +3 -0
- 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/{13-bt.3~irg00.js → 0gdm-xaez4l7t.js} +1 -1
- package/.next/standalone/.next/static/chunks/{07kfzzinhsl7e.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/{0_vk1wsgf~q3o.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/{0wtiofzdt-l2u.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 +325 -142
- 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/claude-sessions.ts +181 -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 +4 -3
- package/bin/failproofai.mjs +248 -70
- package/dist/cli.mjs +1709 -1385
- 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/claude-sessions.ts +181 -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/scripts/postinstall.mjs +89 -1
- package/src/audit/archetypes.ts +924 -0
- package/src/audit/cache.ts +132 -0
- package/src/audit/cli-adapters/claude.ts +97 -0
- package/src/audit/cli-adapters/codex.ts +56 -0
- package/src/audit/cli-adapters/copilot.ts +51 -0
- package/src/audit/cli-adapters/cursor.ts +51 -0
- package/src/audit/cli-adapters/gemini.ts +51 -0
- package/src/audit/cli-adapters/index.ts +70 -0
- package/src/audit/cli-adapters/opencode.ts +52 -0
- package/src/audit/cli-adapters/pi.ts +51 -0
- package/src/audit/cli-adapters/shared.ts +85 -0
- package/src/audit/dashboard-cache.ts +111 -0
- package/src/audit/detectors/find-from-root.ts +27 -0
- package/src/audit/detectors/git-commit-no-verify.ts +22 -0
- package/src/audit/detectors/index.ts +33 -0
- package/src/audit/detectors/prefer-edit-over-read-cat.ts +31 -0
- package/src/audit/detectors/prefer-edit-over-sed-awk.ts +27 -0
- package/src/audit/detectors/prefer-write-over-heredoc.ts +36 -0
- package/src/audit/detectors/redundant-cd-cwd.ts +28 -0
- package/src/audit/detectors/reread-after-edit.ts +58 -0
- package/src/audit/detectors/sleep-polling-loop.ts +34 -0
- package/src/audit/features.ts +268 -0
- package/src/audit/findings.ts +298 -0
- package/src/audit/index.ts +387 -0
- package/src/audit/replay.ts +147 -0
- package/src/audit/report.ts +349 -0
- package/src/audit/scoring.ts +174 -0
- package/src/audit/strengths.ts +138 -0
- package/src/audit/types.ts +216 -0
- package/src/auth/cli.ts +359 -0
- package/src/hooks/builtin-policies.ts +80 -1
- package/src/hooks/custom-hooks-loader.ts +19 -3
- package/src/hooks/first-run-nudge.ts +146 -0
- package/src/hooks/handler.ts +21 -102
- package/src/hooks/hook-telemetry.ts +2 -2
- package/src/hooks/install-prompt.ts +34 -4
- package/src/hooks/manager.ts +72 -5
- package/src/hooks/policy-evaluator.ts +16 -1
- package/src/hooks/policy-registry.ts +20 -0
- package/src/hooks/policy-types.ts +9 -0
- package/src/hooks/tool-name-canonicalize.ts +65 -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]__0370~qj._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__09i-rsi._.js +0 -4
- 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]__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/[root-of-the-server]__101v4_7._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__12y7xmt._.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/03xhjwk6zhi8f.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/0wq808vlc8l04.js +0 -6
- package/.next/standalone/.next/static/chunks/0zg~cpc5ysg6d.js +0 -1
- package/.next/standalone/.next/static/chunks/12pt~2f.c1sha.js +0 -1
- package/.next/standalone/.next/static/chunks/16vev.do1oho7.js +0 -4
- 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/auth/login.ts +0 -104
- package/src/auth/logout.ts +0 -50
- package/src/auth/token-store.ts +0 -64
- package/src/relay/daemon.ts +0 -362
- package/src/relay/pid.ts +0 -76
- package/src/relay/queue.ts +0 -225
- /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/{s5Nn6KwDdLpPhjG3l2WNf → wU3ot-EKa5ApKoh785wp8}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{s5Nn6KwDdLpPhjG3l2WNf → wU3ot-EKa5ApKoh785wp8}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{s5Nn6KwDdLpPhjG3l2WNf → wU3ot-EKa5ApKoh785wp8}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `runAudit` — entry point for the `failproofai audit` command.
|
|
3
|
+
*
|
|
4
|
+
* Drives the pipeline: per-CLI adapters → tool events → (replay + audit
|
|
5
|
+
* detectors) → per-transcript results → aggregated `AuditResult`.
|
|
6
|
+
*
|
|
7
|
+
* Parallelizes transcript scans via `lib/concurrency.ts` `batchAll` (8 at a
|
|
8
|
+
* time — bounds disk I/O without overwhelming the policy engine).
|
|
9
|
+
*/
|
|
10
|
+
import { batchAll } from "../../lib/concurrency";
|
|
11
|
+
import { BUILTIN_POLICIES } from "../hooks/builtin-policies";
|
|
12
|
+
import { readMergedHooksConfig } from "../hooks/hooks-config";
|
|
13
|
+
import { normalizePolicyName } from "../hooks/policy-registry";
|
|
14
|
+
import { INTEGRATION_TYPES, type IntegrationType } from "../hooks/types";
|
|
15
|
+
import { ADAPTERS } from "./cli-adapters";
|
|
16
|
+
import { AUDIT_DETECTORS } from "./detectors";
|
|
17
|
+
import { severityForBuiltin } from "./features";
|
|
18
|
+
import { readCachedTranscriptResult, writeCachedTranscriptResult } from "./cache";
|
|
19
|
+
import { initReplay, replayEvent, restoreReplay } from "./replay";
|
|
20
|
+
import {
|
|
21
|
+
AUDIT_EXAMPLE_MAX_CHARS,
|
|
22
|
+
AUDIT_MAX_EXAMPLES_PER_NAME,
|
|
23
|
+
type AuditCount,
|
|
24
|
+
type AuditResult,
|
|
25
|
+
type DetectorSessionState,
|
|
26
|
+
type NormalizedToolEvent,
|
|
27
|
+
type RunAuditOptions,
|
|
28
|
+
type TranscriptAuditResult,
|
|
29
|
+
type TranscriptMetadata,
|
|
30
|
+
} from "./types";
|
|
31
|
+
|
|
32
|
+
const TRANSCRIPT_CONCURRENCY = 8;
|
|
33
|
+
|
|
34
|
+
/** Canonicalize a policy name to its short, qualified form for display
|
|
35
|
+
* (`failproofai/foo` → `foo`). */
|
|
36
|
+
function shortPolicyName(name: string): string {
|
|
37
|
+
const slash = name.indexOf("/");
|
|
38
|
+
return slash >= 0 ? name.slice(slash + 1) : name;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Look up a builtin policy definition by canonical name; null when the name
|
|
42
|
+
* doesn't match a builtin (e.g. user custom policy). */
|
|
43
|
+
function findBuiltin(name: string) {
|
|
44
|
+
const short = shortPolicyName(name);
|
|
45
|
+
for (const p of BUILTIN_POLICIES) {
|
|
46
|
+
if (p.name === name || shortPolicyName(p.name) === short) return p;
|
|
47
|
+
}
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** Build the per-row install hint shown in the report:
|
|
52
|
+
* - Already enabled builtin: a check phrase ("Already enforced — currently blocking these in real time")
|
|
53
|
+
* - Unenabled builtin: `failproofai policies --install <short-name>`
|
|
54
|
+
* - Audit-only detector: soft notice ("Audit-only — `failproofai audit` will keep tracking these")
|
|
55
|
+
* - Unknown / custom: empty string
|
|
56
|
+
*/
|
|
57
|
+
function buildInstallHint(
|
|
58
|
+
name: string,
|
|
59
|
+
source: "builtin" | "audit-detector",
|
|
60
|
+
enabled: boolean,
|
|
61
|
+
): string {
|
|
62
|
+
if (source === "audit-detector") {
|
|
63
|
+
return "Audit-only — `failproofai audit` will keep tracking these.";
|
|
64
|
+
}
|
|
65
|
+
if (enabled) {
|
|
66
|
+
return "Already enforced — failproofai is blocking these in real time.";
|
|
67
|
+
}
|
|
68
|
+
return `Enable in one command: failproofai policies --install ${shortPolicyName(name)}`;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function truncateExample(s: string): string {
|
|
72
|
+
if (s.length <= AUDIT_EXAMPLE_MAX_CHARS) return s;
|
|
73
|
+
return s.slice(0, AUDIT_EXAMPLE_MAX_CHARS - 1) + "…";
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function parseSinceOpt(since: string | undefined): number | undefined {
|
|
77
|
+
if (!since) return undefined;
|
|
78
|
+
const m = /^(\d+)\s*([dhm])$/i.exec(since.trim());
|
|
79
|
+
if (m) {
|
|
80
|
+
const n = parseInt(m[1], 10);
|
|
81
|
+
const unit = m[2].toLowerCase();
|
|
82
|
+
const ms = unit === "d" ? 86400000 : unit === "h" ? 3600000 : 60000;
|
|
83
|
+
return Date.now() - n * ms;
|
|
84
|
+
}
|
|
85
|
+
const t = Date.parse(since);
|
|
86
|
+
if (!Number.isNaN(t)) return t;
|
|
87
|
+
throw new Error(`Invalid --since value: "${since}" (expected e.g. "7d", "30d", or "2026-04-01")`);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async function scanOneTranscript(meta: TranscriptMetadata): Promise<TranscriptAuditResult> {
|
|
91
|
+
const empty: TranscriptAuditResult = {
|
|
92
|
+
transcriptPath: meta.transcriptPath,
|
|
93
|
+
cli: meta.cli,
|
|
94
|
+
projectName: meta.projectName,
|
|
95
|
+
sessionId: meta.sessionId,
|
|
96
|
+
mtimeMs: meta.mtimeMs,
|
|
97
|
+
sizeBytes: meta.sizeBytes,
|
|
98
|
+
cwd: "",
|
|
99
|
+
eventsScanned: 0,
|
|
100
|
+
hitsByName: {},
|
|
101
|
+
examplesByName: {},
|
|
102
|
+
rangeByName: {},
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
// Stream failures must propagate so the orchestrator counts them in
|
|
106
|
+
// `errors` rather than silently returning an empty hits map.
|
|
107
|
+
const events = await ADAPTERS[meta.cli].streamEvents(meta);
|
|
108
|
+
if (events.length === 0) return empty;
|
|
109
|
+
|
|
110
|
+
const result = empty;
|
|
111
|
+
result.eventsScanned = events.length;
|
|
112
|
+
// Capture the session's cwd from the first event that carried one — every
|
|
113
|
+
// event in a single transcript shares the same cwd by construction.
|
|
114
|
+
result.cwd = events[0].cwd || "";
|
|
115
|
+
const sessionState: DetectorSessionState = {};
|
|
116
|
+
|
|
117
|
+
for (const event of events) {
|
|
118
|
+
// Run audit detectors first (stateful, must see every event).
|
|
119
|
+
for (const detector of AUDIT_DETECTORS) {
|
|
120
|
+
const hit = detector.detect(event, sessionState);
|
|
121
|
+
if (!hit) continue;
|
|
122
|
+
recordHit(
|
|
123
|
+
result,
|
|
124
|
+
detector.name,
|
|
125
|
+
event.timestamp,
|
|
126
|
+
event.cwd,
|
|
127
|
+
truncateExample(hit.example),
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
// Then replay through every builtin policy.
|
|
131
|
+
let replayHits;
|
|
132
|
+
try {
|
|
133
|
+
replayHits = await replayEvent(event);
|
|
134
|
+
} catch {
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
for (const hit of replayHits) {
|
|
138
|
+
const example = formatPolicyExample(hit.policyName, event);
|
|
139
|
+
recordHit(
|
|
140
|
+
result,
|
|
141
|
+
hit.policyName,
|
|
142
|
+
event.timestamp,
|
|
143
|
+
event.cwd,
|
|
144
|
+
truncateExample(example),
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return result;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function formatPolicyExample(_policyName: string, event: NormalizedToolEvent): string {
|
|
153
|
+
if (event.toolName === "Bash") {
|
|
154
|
+
const command = (event.toolInput as { command?: unknown }).command;
|
|
155
|
+
if (typeof command === "string") return command.replace(/\s+/g, " ");
|
|
156
|
+
}
|
|
157
|
+
const filePath = (event.toolInput as { file_path?: unknown }).file_path;
|
|
158
|
+
if (typeof filePath === "string") return `${event.toolName} ${filePath}`;
|
|
159
|
+
return `${event.toolName}`;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function recordHit(
|
|
163
|
+
result: TranscriptAuditResult,
|
|
164
|
+
name: string,
|
|
165
|
+
timestamp: string,
|
|
166
|
+
cwd: string,
|
|
167
|
+
example: string,
|
|
168
|
+
): void {
|
|
169
|
+
result.hitsByName[name] = (result.hitsByName[name] ?? 0) + 1;
|
|
170
|
+
const exs = result.examplesByName[name] ?? [];
|
|
171
|
+
if (exs.length < AUDIT_MAX_EXAMPLES_PER_NAME) {
|
|
172
|
+
exs.push({ timestamp, cwd, example });
|
|
173
|
+
result.examplesByName[name] = exs;
|
|
174
|
+
}
|
|
175
|
+
const range = result.rangeByName[name];
|
|
176
|
+
if (!range) {
|
|
177
|
+
result.rangeByName[name] = { first: timestamp, last: timestamp };
|
|
178
|
+
} else {
|
|
179
|
+
if (timestamp < range.first) range.first = timestamp;
|
|
180
|
+
if (timestamp > range.last) range.last = timestamp;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function aggregateResults(
|
|
185
|
+
perTranscript: TranscriptAuditResult[],
|
|
186
|
+
enabledBuiltins: Set<string>,
|
|
187
|
+
): AuditCount[] {
|
|
188
|
+
// For each name: sum hits, count distinct projects, merge ranges + examples.
|
|
189
|
+
const byName = new Map<string, {
|
|
190
|
+
hits: number;
|
|
191
|
+
projects: Set<string>;
|
|
192
|
+
examples: { sessionId: string; cwd: string; timestamp: string; example: string }[];
|
|
193
|
+
first?: string;
|
|
194
|
+
last?: string;
|
|
195
|
+
}>();
|
|
196
|
+
|
|
197
|
+
for (const t of perTranscript) {
|
|
198
|
+
for (const [name, count] of Object.entries(t.hitsByName)) {
|
|
199
|
+
const bucket = byName.get(name) ?? {
|
|
200
|
+
hits: 0,
|
|
201
|
+
projects: new Set<string>(),
|
|
202
|
+
examples: [],
|
|
203
|
+
};
|
|
204
|
+
bucket.hits += count;
|
|
205
|
+
bucket.projects.add(t.projectName);
|
|
206
|
+
const tExs = t.examplesByName[name] ?? [];
|
|
207
|
+
for (const e of tExs) {
|
|
208
|
+
if (bucket.examples.length < AUDIT_MAX_EXAMPLES_PER_NAME) {
|
|
209
|
+
bucket.examples.push({ ...e, sessionId: t.sessionId });
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
const range = t.rangeByName[name];
|
|
213
|
+
if (range) {
|
|
214
|
+
if (!bucket.first || range.first < bucket.first) bucket.first = range.first;
|
|
215
|
+
if (!bucket.last || range.last > bucket.last) bucket.last = range.last;
|
|
216
|
+
}
|
|
217
|
+
byName.set(name, bucket);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const detectorByName = new Map(AUDIT_DETECTORS.map((d) => [d.name, d]));
|
|
222
|
+
const out: AuditCount[] = [];
|
|
223
|
+
for (const [name, bucket] of byName) {
|
|
224
|
+
const detector = detectorByName.get(name);
|
|
225
|
+
const isDetector = !!detector;
|
|
226
|
+
const builtin = isDetector ? null : findBuiltin(name);
|
|
227
|
+
const source: "builtin" | "audit-detector" = isDetector ? "audit-detector" : "builtin";
|
|
228
|
+
const enabled = isDetector ? false : enabledBuiltins.has(normalizePolicyName(name));
|
|
229
|
+
|
|
230
|
+
const displayTitle =
|
|
231
|
+
detector?.displayTitle
|
|
232
|
+
?? builtin?.displayTitle
|
|
233
|
+
?? detector?.description
|
|
234
|
+
?? builtin?.description
|
|
235
|
+
?? shortPolicyName(name);
|
|
236
|
+
const impact = detector?.impact ?? builtin?.impact ?? "";
|
|
237
|
+
|
|
238
|
+
out.push({
|
|
239
|
+
name,
|
|
240
|
+
source,
|
|
241
|
+
category: detector?.category ?? builtin?.category ?? "Custom",
|
|
242
|
+
// Builtins carry no static severity field — derive it from the policy
|
|
243
|
+
// name prefix (sanitize-/warn-/block-/…) so the score's gentle/medium
|
|
244
|
+
// buckets actually populate instead of everything collapsing to "deny".
|
|
245
|
+
severity: isDetector ? (detector?.severity ?? "info") : severityForBuiltin(name),
|
|
246
|
+
hits: bucket.hits,
|
|
247
|
+
projects: bucket.projects.size,
|
|
248
|
+
firstSeen: bucket.first,
|
|
249
|
+
lastSeen: bucket.last,
|
|
250
|
+
examples: bucket.examples,
|
|
251
|
+
displayTitle,
|
|
252
|
+
impact,
|
|
253
|
+
enabledInConfig: enabled,
|
|
254
|
+
installHint: buildInstallHint(name, source, enabled),
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
out.sort((a, b) => b.hits - a.hits);
|
|
259
|
+
return out;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export async function runAudit(opts: RunAuditOptions = {}): Promise<AuditResult> {
|
|
263
|
+
const startedAt = Date.now();
|
|
264
|
+
initReplay();
|
|
265
|
+
try {
|
|
266
|
+
return await runAuditInner(opts, startedAt);
|
|
267
|
+
} finally {
|
|
268
|
+
// Always restore the caller's policy registry, even on error. Without
|
|
269
|
+
// this, embedding runAudit() in a long-running process (e.g. the Next.js
|
|
270
|
+
// dashboard) would clobber any pre-existing policy registrations.
|
|
271
|
+
restoreReplay();
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
async function runAuditInner(opts: RunAuditOptions, startedAt: number): Promise<AuditResult> {
|
|
276
|
+
const clis = (opts.clis ?? Array.from(INTEGRATION_TYPES)) as IntegrationType[];
|
|
277
|
+
const sinceMs = parseSinceOpt(opts.since);
|
|
278
|
+
|
|
279
|
+
// Snapshot which builtin policies the user currently has enabled — drives
|
|
280
|
+
// the "already protected" vs "slipping through" split in the report.
|
|
281
|
+
const userConfig = readMergedHooksConfig();
|
|
282
|
+
const enabledBuiltins = new Set(
|
|
283
|
+
(userConfig.enabledPolicies ?? []).map((n) => normalizePolicyName(n)),
|
|
284
|
+
);
|
|
285
|
+
|
|
286
|
+
// 1. Discover transcripts across all selected CLIs.
|
|
287
|
+
const allTranscripts: TranscriptMetadata[] = [];
|
|
288
|
+
for (const cli of clis) {
|
|
289
|
+
const adapter = ADAPTERS[cli];
|
|
290
|
+
let list: TranscriptMetadata[];
|
|
291
|
+
try {
|
|
292
|
+
list = await adapter.listTranscripts({ projects: opts.projects, sinceMs });
|
|
293
|
+
} catch {
|
|
294
|
+
continue; // adapter failures shouldn't kill the whole audit
|
|
295
|
+
}
|
|
296
|
+
allTranscripts.push(...list);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// 2. Scan each transcript (cache-aware), 8 in parallel.
|
|
300
|
+
let skipped = 0;
|
|
301
|
+
let errors = 0;
|
|
302
|
+
const tasks = allTranscripts.map((meta) => async (): Promise<TranscriptAuditResult> => {
|
|
303
|
+
if (!opts.noCache) {
|
|
304
|
+
const cached = readCachedTranscriptResult(meta.transcriptPath, meta.mtimeMs, meta.sizeBytes);
|
|
305
|
+
if (cached) return cached;
|
|
306
|
+
}
|
|
307
|
+
try {
|
|
308
|
+
const fresh = await scanOneTranscript(meta);
|
|
309
|
+
if (!opts.noCache) {
|
|
310
|
+
writeCachedTranscriptResult(meta.transcriptPath, meta.mtimeMs, meta.sizeBytes, fresh);
|
|
311
|
+
}
|
|
312
|
+
return fresh;
|
|
313
|
+
} catch {
|
|
314
|
+
errors++;
|
|
315
|
+
// Match the empty/full result shape — `cwd` is unknowable here (we
|
|
316
|
+
// never got to scan the events that carry it), but `eventsScanned: 0`
|
|
317
|
+
// is right and keeps the aggregator's `t.eventsScanned ?? 0` shape
|
|
318
|
+
// explicit. cwd defaults to "" so `if (t.cwd)` skips it cleanly.
|
|
319
|
+
return {
|
|
320
|
+
transcriptPath: meta.transcriptPath,
|
|
321
|
+
cli: meta.cli,
|
|
322
|
+
projectName: meta.projectName,
|
|
323
|
+
cwd: "",
|
|
324
|
+
sessionId: meta.sessionId,
|
|
325
|
+
mtimeMs: meta.mtimeMs,
|
|
326
|
+
sizeBytes: meta.sizeBytes,
|
|
327
|
+
eventsScanned: 0,
|
|
328
|
+
hitsByName: {},
|
|
329
|
+
examplesByName: {},
|
|
330
|
+
rangeByName: {},
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
const settled = await batchAll(tasks, TRANSCRIPT_CONCURRENCY);
|
|
336
|
+
const perTranscript: TranscriptAuditResult[] = [];
|
|
337
|
+
for (const s of settled) {
|
|
338
|
+
if (s.status === "fulfilled") perTranscript.push(s.value);
|
|
339
|
+
else skipped++;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// 3. Aggregate.
|
|
343
|
+
let results = aggregateResults(perTranscript, enabledBuiltins);
|
|
344
|
+
if (opts.policies?.length) {
|
|
345
|
+
const wanted = new Set(opts.policies.map(shortPolicyName));
|
|
346
|
+
results = results.filter((r) => wanted.has(shortPolicyName(r.name)));
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
const totalsHits = results.reduce((sum, r) => sum + r.hits, 0);
|
|
350
|
+
const projectsWithHits = new Set<string>();
|
|
351
|
+
const projectsScannedSet = new Set<string>();
|
|
352
|
+
let eventsScanned = 0;
|
|
353
|
+
for (const t of perTranscript) {
|
|
354
|
+
if (Object.keys(t.hitsByName).length > 0) projectsWithHits.add(t.projectName);
|
|
355
|
+
if (t.cwd) projectsScannedSet.add(t.cwd);
|
|
356
|
+
eventsScanned += t.eventsScanned ?? 0;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
const auditResult: AuditResult = {
|
|
360
|
+
version: 2,
|
|
361
|
+
scannedAt: new Date(startedAt).toISOString(),
|
|
362
|
+
scope: {
|
|
363
|
+
cli: clis,
|
|
364
|
+
projects: opts.projects ?? "all",
|
|
365
|
+
since: opts.since ?? null,
|
|
366
|
+
},
|
|
367
|
+
transcripts: {
|
|
368
|
+
scanned: allTranscripts.length,
|
|
369
|
+
skipped,
|
|
370
|
+
errors,
|
|
371
|
+
durationMs: Date.now() - startedAt,
|
|
372
|
+
},
|
|
373
|
+
results,
|
|
374
|
+
totals: {
|
|
375
|
+
hits: totalsHits,
|
|
376
|
+
projectsWithHits: projectsWithHits.size,
|
|
377
|
+
},
|
|
378
|
+
projectsScanned: [...projectsScannedSet].sort(),
|
|
379
|
+
eventsScanned,
|
|
380
|
+
// Pull short names off the user's enabled builtin set so the dashboard
|
|
381
|
+
// can answer "is policy X enabled?" without iterating result rows.
|
|
382
|
+
enabledBuiltinNames: [...enabledBuiltins]
|
|
383
|
+
.map((n) => (n.includes("/") ? n.slice(n.indexOf("/") + 1) : n)),
|
|
384
|
+
};
|
|
385
|
+
|
|
386
|
+
return auditResult;
|
|
387
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Replay engine — turns a NormalizedToolEvent into one (or two) synthetic hook
|
|
3
|
+
* payloads, runs them through the existing `evaluatePolicies` function, and
|
|
4
|
+
* returns the policy decisions.
|
|
5
|
+
*
|
|
6
|
+
* Why two events: builtin sanitize-* policies match on PostToolUse and inspect
|
|
7
|
+
* the tool result text. PreToolUse alone misses them. Per event we synthesize:
|
|
8
|
+
* 1. PreToolUse — { tool_name, tool_input }
|
|
9
|
+
* 2. PostToolUse — { tool_name, tool_input, tool_response } (only when the
|
|
10
|
+
* transcript captured a tool_result)
|
|
11
|
+
*
|
|
12
|
+
* Workflow policies (`require-*-before-stop`) match only on `Stop` and
|
|
13
|
+
* execSync against live git, so they never fire on PreToolUse/PostToolUse
|
|
14
|
+
* replay — no explicit skip needed.
|
|
15
|
+
*/
|
|
16
|
+
import type { EvaluationResult } from "../hooks/policy-evaluator";
|
|
17
|
+
import { evaluatePolicies } from "../hooks/policy-evaluator";
|
|
18
|
+
import { BUILTIN_POLICIES, registerBuiltinPolicies } from "../hooks/builtin-policies";
|
|
19
|
+
import {
|
|
20
|
+
clearPolicies,
|
|
21
|
+
getAllPolicies,
|
|
22
|
+
normalizePolicyName,
|
|
23
|
+
setAllPolicies,
|
|
24
|
+
} from "../hooks/policy-registry";
|
|
25
|
+
import type { RegisteredPolicy } from "../hooks/policy-types";
|
|
26
|
+
import type { SessionMetadata } from "../hooks/types";
|
|
27
|
+
import type { NormalizedToolEvent } from "./types";
|
|
28
|
+
|
|
29
|
+
/** Policies the audit skips on purpose. `warn-repeated-tool-calls` mutates a
|
|
30
|
+
* per-session sidecar file on every evaluation, which would pollute the
|
|
31
|
+
* user's real transcript directory during a replay (and inflate counts
|
|
32
|
+
* because the replay always re-traverses the full session). */
|
|
33
|
+
const SKIP_POLICIES = new Set(
|
|
34
|
+
["warn-repeated-tool-calls"].map((n) => normalizePolicyName(n)),
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
let initialized = false;
|
|
38
|
+
/** Snapshot of the registry taken at `initReplay()`. Restored by
|
|
39
|
+
* `restoreReplay()` so embedding `runAudit()` in a long-running process
|
|
40
|
+
* (e.g. the Next.js dashboard) doesn't wipe any prior policy registrations. */
|
|
41
|
+
let savedSnapshot: RegisteredPolicy[] | null = null;
|
|
42
|
+
|
|
43
|
+
/** Register every builtin policy (regardless of user config) so the replay
|
|
44
|
+
* shows what *could* be caught, not just what's currently enabled. Called
|
|
45
|
+
* once per `runAudit` invocation. Snapshots the existing registry so it can
|
|
46
|
+
* be restored by `restoreReplay()` once the audit is done. */
|
|
47
|
+
export function initReplay(): void {
|
|
48
|
+
if (initialized) return;
|
|
49
|
+
savedSnapshot = getAllPolicies();
|
|
50
|
+
clearPolicies();
|
|
51
|
+
const enabled = BUILTIN_POLICIES
|
|
52
|
+
.map((p) => p.name)
|
|
53
|
+
.filter((n) => !SKIP_POLICIES.has(normalizePolicyName(n)));
|
|
54
|
+
registerBuiltinPolicies(enabled);
|
|
55
|
+
initialized = true;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** Restore the registry to whatever was there before `initReplay()`. Safe to
|
|
59
|
+
* call when not initialized (no-op). Always paired with `initReplay()` in a
|
|
60
|
+
* try/finally inside `runAudit()`. */
|
|
61
|
+
export function restoreReplay(): void {
|
|
62
|
+
if (!initialized) return;
|
|
63
|
+
if (savedSnapshot !== null) {
|
|
64
|
+
setAllPolicies(savedSnapshot);
|
|
65
|
+
savedSnapshot = null;
|
|
66
|
+
}
|
|
67
|
+
initialized = false;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** Reset for tests / repeated audits in the same process. Drops the snapshot
|
|
71
|
+
* too — tests usually start with an empty registry and want it back. */
|
|
72
|
+
export function resetReplay(): void {
|
|
73
|
+
initialized = false;
|
|
74
|
+
savedSnapshot = null;
|
|
75
|
+
clearPolicies();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export interface ReplayHit {
|
|
79
|
+
policyName: string;
|
|
80
|
+
decision: "deny" | "instruct" | "allow";
|
|
81
|
+
reason: string | null;
|
|
82
|
+
eventType: "PreToolUse" | "PostToolUse";
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** Replay one normalized tool event through every registered policy. Returns
|
|
86
|
+
* one ReplayHit per non-allow decision (deny + instruct). Allow-with-reason
|
|
87
|
+
* is reported too, so sanitize policies that emit informational notes still
|
|
88
|
+
* surface in the audit. */
|
|
89
|
+
export async function replayEvent(event: NormalizedToolEvent): Promise<ReplayHit[]> {
|
|
90
|
+
if (!initialized) initReplay();
|
|
91
|
+
|
|
92
|
+
const session: SessionMetadata = {
|
|
93
|
+
sessionId: event.sessionId,
|
|
94
|
+
transcriptPath: event.transcriptPath,
|
|
95
|
+
cwd: event.cwd,
|
|
96
|
+
cli: event.cli,
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const baseToolPayload: Record<string, unknown> = {
|
|
100
|
+
tool_name: event.toolName,
|
|
101
|
+
tool_input: event.toolInput,
|
|
102
|
+
session_id: event.sessionId,
|
|
103
|
+
cwd: event.cwd,
|
|
104
|
+
transcript_path: event.transcriptPath,
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const out: ReplayHit[] = [];
|
|
108
|
+
|
|
109
|
+
// PreToolUse
|
|
110
|
+
const pre = await evaluatePolicies("PreToolUse", baseToolPayload, session);
|
|
111
|
+
collectHits(pre, "PreToolUse", out);
|
|
112
|
+
|
|
113
|
+
// PostToolUse — only if the transcript captured a tool result.
|
|
114
|
+
if (event.toolResultText !== undefined) {
|
|
115
|
+
const postPayload = { ...baseToolPayload, tool_response: event.toolResultText };
|
|
116
|
+
const post = await evaluatePolicies("PostToolUse", postPayload, session);
|
|
117
|
+
collectHits(post, "PostToolUse", out);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return out;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function collectHits(
|
|
124
|
+
result: EvaluationResult,
|
|
125
|
+
eventType: "PreToolUse" | "PostToolUse",
|
|
126
|
+
out: ReplayHit[],
|
|
127
|
+
): void {
|
|
128
|
+
// `policyNames` is set when multiple policies fired (sanitize stack);
|
|
129
|
+
// otherwise fall back to `policyName`.
|
|
130
|
+
const names = result.policyNames && result.policyNames.length > 0
|
|
131
|
+
? result.policyNames
|
|
132
|
+
: result.policyName
|
|
133
|
+
? [result.policyName]
|
|
134
|
+
: [];
|
|
135
|
+
for (const name of names) {
|
|
136
|
+
// The aggregate `decision` reflects the most severe firing, but the audit
|
|
137
|
+
// wants per-policy counts. We re-tag each name with the aggregate decision
|
|
138
|
+
// for now — accurate enough for the table; a future audit-detail mode can
|
|
139
|
+
// re-evaluate per-policy if precision becomes important.
|
|
140
|
+
out.push({
|
|
141
|
+
policyName: name,
|
|
142
|
+
decision: result.decision,
|
|
143
|
+
reason: result.reason,
|
|
144
|
+
eventType,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
}
|