failproofai 1.0.0-beta.2 → 1.0.0-beta.21
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 +2 -1
- package/.next/standalone/.next/build-manifest.json +6 -6
- package/.next/standalone/.next/prerender-manifest.json +3 -3
- package/.next/standalone/.next/required-server-files.json +1 -1
- package/.next/standalone/.next/routes-manifest.json +6 -0
- package/.next/standalone/.next/server/app/_global-error/page/build-manifest.json +3 -3
- 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 +3 -1
- 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 +3 -3
- 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 +3 -1
- 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 +15 -15
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +15 -15
- 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/invite/route.js +3 -2
- package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/audit/run/route.js +4 -3
- package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/audit/status/route.js +1 -1
- package/.next/standalone/.next/server/app/api/audit/status/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/login-request/route.js +3 -1
- package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/login-verify/route.js +3 -2
- package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/logout/route.js +3 -2
- package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/reminder/route.js +3 -2
- package/.next/standalone/.next/server/app/api/auth/reminder/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/status/route.js +3 -2
- package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js +1 -1
- package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/audit/page/build-manifest.json +3 -3
- package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
- package/.next/standalone/.next/server/app/audit/page.js +5 -3
- package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/index.html +1 -1
- package/.next/standalone/.next/server/app/index.rsc +15 -15
- package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
- 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 -2
- package/.next/standalone/.next/server/app/page/build-manifest.json +3 -3
- package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/page.js +3 -1
- 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 +3 -3
- package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +30 -18
- package/.next/standalone/.next/server/app/policies/page.js +5 -3
- 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 +3 -3
- 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 +4 -2
- 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 +3 -3
- 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 +6 -4
- 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 +3 -3
- package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/projects/page.js +4 -2
- 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/settings/page/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/settings/page/build-manifest.json +18 -0
- package/.next/standalone/.next/server/app/settings/page/next-font-manifest.json +6 -0
- package/.next/standalone/.next/server/app/settings/page/react-loadable-manifest.json +1 -0
- package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +53 -0
- package/.next/standalone/.next/server/app/settings/page.js +18 -0
- package/.next/standalone/.next/server/app/settings/page.js.map +5 -0
- package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +3 -0
- package/.next/standalone/.next/server/app-paths-manifest.json +2 -1
- package/.next/standalone/.next/server/chunks/[externals]__0h9_83k._.js +3 -0
- package/.next/standalone/.next/server/chunks/{[externals]__1nl3dvw._.js → [externals]__0r-zamh._.js} +2 -2
- package/.next/standalone/.next/server/chunks/[externals]__1ifpkx-._.js +3 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0l4vuqm._.js → [root-of-the-server]__00ni9za._.js} +2 -2
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__06hexd0._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__08y94xv._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__094p1f1._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0_0xu5z._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ed01_d._.js +3 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0-dh5jy._.js → [root-of-the-server]__0effm9m._.js} +2 -2
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0g0vcwt._.js +3 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__18d-9oi._.js → [root-of-the-server]__0ix8gm7._.js} +2 -2
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0h3lfmp._.js → [root-of-the-server]__0ji11a-._.js} +2 -2
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__10oa-v9._.js → [root-of-the-server]__0ojwjxl._.js} +2 -2
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__16le-kd._.js → [root-of-the-server]__0pbp9fe._.js} +2 -2
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0q-v9z2._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0vb5fl2._.js +3 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0sb_5m8._.js → [root-of-the-server]__131ebum._.js} +4 -4
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1ibjy5x._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1tvn4wf._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__20d06rh._.js +3 -0
- package/.next/standalone/.next/server/chunks/_0lxbzdq._.js +3 -0
- package/.next/standalone/.next/server/chunks/_1zuiiy3._.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_telemetry_ts_0dctyyw._.js +3 -0
- package/.next/standalone/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_17k9e3w.js +5 -5
- package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_01r25oi._.js +2 -1
- package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_09z9-p7._.js +2 -1
- package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[externals]__1aq139v._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0-wfhrp._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__06bp_fg._.js +5 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__074qmkp._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1apb7k_._.js → [root-of-the-server]__0_1tiya._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__170799-._.js → [root-of-the-server]__0spkm68._.js} +11 -11
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0t281d4._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__17itmx-._.js +5 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__01od0m6._.js → [root-of-the-server]__1n2vcv4._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1qapotl._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1rv-sc9._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1tlvv9a._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1u-wx42._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1v185mo._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_0-yi74u._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_0rjgfln._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_0vo2qyt._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_0xej-0e._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_10399ge._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_11_p9y8._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_149k9oy._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_1_hwp06._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_1ctse6u._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_1e19atl._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_1mnhi_r._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_1ror7k9._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_1sdgprl._.js +5 -0
- package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0dwo94s.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/node_modules_posthog-node_dist_entrypoints_index_node_mjs_11bnuzn._.js +2 -1
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_builtin-policies_ts_09j2ndl._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_fp-config_ts_04t589g._.js +4 -0
- package/.next/standalone/.next/server/middleware-build-manifest.js +6 -6
- package/.next/standalone/.next/server/middleware.js +2 -2
- 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 +74 -20
- package/.next/standalone/.next/static/chunks/{03fmihek9n986.js → 06zgzyh3wv1ig.js} +1 -1
- package/.next/standalone/.next/static/chunks/0km-jn9o5xyqs.css +2 -0
- package/.next/standalone/.next/static/chunks/{1hdhteui932bq.js → 0qmo2t50kpb30.js} +1 -1
- package/.next/standalone/.next/static/chunks/{2sbelanzvxvv0.js → 113g8wtal6_c4.js} +22 -22
- package/.next/standalone/.next/static/chunks/16p68cybetr31.js +1 -0
- package/.next/standalone/.next/static/chunks/18wqn0_3mzylf.js +1 -0
- package/.next/standalone/.next/static/chunks/1v1gqvpjk62jm.js +1 -0
- package/.next/standalone/.next/static/chunks/{0fi645si-uiiq.js → 1xq1m8h14tnlj.js} +1 -1
- package/.next/standalone/.next/static/chunks/{3hp8ulqknybil.js → 1y3vwogqb88dx.js} +1 -1
- package/.next/standalone/.next/static/chunks/{3vs4ay36tjds_.js → 1zmh-b0ulrqu7.js} +1 -1
- package/.next/standalone/.next/static/chunks/23kev26by1e4f.js +1 -0
- package/.next/standalone/.next/static/chunks/299lhw60e8gr6.js +1 -0
- package/.next/standalone/.next/static/chunks/{18rvdw5v72364.js → 2adbpdaxp5ygq.js} +1 -1
- package/.next/standalone/.next/static/chunks/{2j94uwkb4s3qr.js → 2kbqcw-6swmav.js} +1 -1
- package/.next/standalone/.next/static/chunks/2n9n5m0963pdg.js +6 -0
- package/.next/standalone/.next/static/chunks/2uvhw57mf9lg_.css +2 -0
- package/.next/standalone/.next/static/chunks/{31feojxhjyjpl.js → 30nrrpwymht5m.js} +1 -1
- package/.next/standalone/.next/static/chunks/31coz11ia5vc4.js +1 -0
- package/.next/standalone/.next/static/chunks/{turbopack-1lsv92x7klwrn.js → turbopack-3diub4ctvn1n0.js} +1 -1
- package/.next/standalone/SECURITY.md +8 -2
- package/.next/standalone/app/actions/get-active-pauses.ts +16 -0
- package/.next/standalone/app/actions/get-hooks-config.ts +2 -2
- package/.next/standalone/app/actions/get-scheduled-audit.ts +70 -0
- package/.next/standalone/app/actions/update-scheduled-audit.ts +44 -0
- package/.next/standalone/app/api/audit/run/route.ts +28 -0
- package/.next/standalone/app/api/audit/status/route.ts +13 -1
- package/.next/standalone/app/api/auth/status/route.ts +1 -1
- package/.next/standalone/app/audit/_components/audit-dashboard.tsx +1 -3
- package/.next/standalone/app/audit/_components/audit-progress-strip.tsx +1 -1
- package/.next/standalone/app/audit/_components/auth-dialog.css +159 -0
- package/.next/standalone/app/audit/_components/auth-dialog.tsx +3 -0
- package/.next/standalone/app/audit/_components/come-back-better-section.tsx +1 -1
- package/.next/standalone/app/audit/_components/empty-state.tsx +0 -1
- package/.next/standalone/app/audit/_components/how-to-improve-section.tsx +1 -1
- package/.next/standalone/app/audit/_components/quirks-section.tsx +0 -1
- package/.next/standalone/app/audit/_components/report-footer.tsx +0 -2
- package/.next/standalone/app/audit/_components/run-progress.tsx +1 -1
- package/.next/standalone/app/audit/_components/strengths-section.tsx +0 -1
- package/.next/standalone/app/audit/audit-styles.css +6 -149
- package/.next/standalone/app/components/pause-notices.tsx +111 -0
- package/.next/standalone/app/components/raw-log-viewer.tsx +1 -1
- package/.next/standalone/app/components/toast.tsx +1 -1
- package/.next/standalone/app/policies/hooks-client.tsx +84 -8
- package/.next/standalone/app/settings/page.tsx +31 -0
- package/.next/standalone/app/settings/settings-client.tsx +487 -0
- package/.next/standalone/components/navbar.tsx +2 -0
- package/.next/standalone/lib/auth/api-server-client.ts +2 -3
- package/.next/standalone/lib/auth/auth-store.ts +4 -5
- package/.next/standalone/lib/codex-sessions.ts +2 -1
- package/.next/standalone/lib/dashboard-host.ts +101 -0
- package/.next/standalone/lib/install-check.ts +22 -7
- package/.next/standalone/lib/pi-sessions.ts +99 -14
- package/.next/standalone/lib/telemetry-enabled.ts +54 -0
- package/.next/standalone/lib/telemetry-id.ts +52 -1
- package/.next/standalone/lib/telemetry.ts +8 -4
- 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 +3 -3
- 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 +4 -4
- package/.next/standalone/package.json +23 -12
- package/.next/standalone/proxy.ts +111 -1
- package/.next/standalone/server.js +1 -1
- package/bin/failproofai-worker.mjs +1 -1
- package/bin/failproofai.mjs +1041 -81
- package/bin/failproofaid-shim.mjs +4 -4
- package/dist/cli.mjs +18513 -10474
- package/dist/worker.mjs +1223 -299
- package/lib/auth/api-server-client.ts +2 -3
- package/lib/auth/auth-store.ts +4 -5
- package/lib/codex-sessions.ts +2 -1
- package/lib/dashboard-host.ts +101 -0
- package/lib/install-check.ts +22 -7
- package/lib/pi-sessions.ts +99 -14
- package/lib/telemetry-enabled.ts +54 -0
- package/lib/telemetry-id.ts +52 -1
- package/lib/telemetry.ts +8 -4
- package/package.json +23 -12
- package/scripts/build-daemon-packages.mjs +247 -0
- package/scripts/daemon-platforms.mjs +42 -0
- package/scripts/dev-hook.mjs +46 -5
- package/scripts/install-telemetry.mjs +8 -1
- package/scripts/launch.ts +25 -3
- package/scripts/parse-script-args.ts +27 -1
- package/scripts/prune-standalone.mjs +26 -0
- package/scripts/publish-aliases.mjs +62 -41
- package/scripts/repro-npm-install.sh +155 -0
- package/scripts/translate-docs/cache.ts +1 -1
- package/scripts/translate-docs/cli.ts +2 -2
- package/scripts/translate-docs/mintlify-nav.ts +1 -1
- package/scripts/translate-docs/readme-translator.ts +163 -4
- package/scripts/validate-mdx.ts +153 -13
- package/src/audit/audit-lock.ts +285 -0
- package/src/audit/audit-schedule.ts +111 -0
- package/src/audit/cache.ts +18 -5
- package/src/audit/cli-adapters/goose.ts +2 -1
- package/src/audit/cli-adapters/hermes.ts +28 -10
- package/src/audit/cli.ts +191 -35
- package/src/audit/dashboard-cache.ts +2 -3
- package/src/audit/report.ts +0 -1
- package/src/hooks/backfill-cli.ts +247 -0
- package/src/hooks/builtin-policies.ts +391 -3
- package/src/hooks/cloud-connection.ts +354 -0
- package/src/hooks/cloud-enrollment-cli.ts +439 -0
- package/src/hooks/cloud-enrollment.ts +284 -0
- package/src/hooks/cloud-introspect.ts +147 -0
- package/src/hooks/cloud-managed-policies.ts +206 -0
- package/src/hooks/collector-config.ts +218 -0
- package/src/hooks/configure-wizard.ts +1211 -233
- package/src/hooks/custom-hooks-loader.ts +243 -37
- package/src/hooks/daemon-client.ts +136 -33
- package/src/hooks/daemon-download.ts +264 -31
- package/src/hooks/daemon-service.ts +1124 -76
- package/src/hooks/first-run-gate.ts +50 -0
- package/src/hooks/flush-cli.ts +180 -0
- package/src/hooks/fp-config.ts +835 -0
- package/src/hooks/fp-home.ts +714 -0
- package/src/hooks/fp-reset.ts +1363 -0
- package/src/hooks/handler.ts +185 -6
- package/src/hooks/harness-cli.ts +386 -0
- package/src/hooks/hook-activity-store.ts +171 -24
- package/src/hooks/hook-logger.ts +2 -2
- package/src/hooks/hook-telemetry.ts +5 -1
- package/src/hooks/hooks-config.ts +4 -3
- package/src/hooks/integrations.ts +0 -1
- package/src/hooks/loader-utils.ts +172 -9
- package/src/hooks/manager.ts +41 -5
- package/src/hooks/migrations.ts +450 -0
- package/src/hooks/onboarding-attempt.ts +195 -0
- package/src/hooks/onboarding-lock.ts +118 -0
- package/src/hooks/policy-types.ts +28 -0
- package/src/hooks/session-pause-cli.ts +159 -0
- package/src/hooks/session-pause.ts +267 -0
- package/src/hooks/setup-state.ts +256 -0
- package/src/hooks/tui.ts +209 -9
- package/src/hooks/uninstall-cli.ts +418 -0
- package/src/hooks/worker-server.ts +134 -15
- package/.next/standalone/.next/server/chunks/[externals]__14odj07._.js +0 -3
- package/.next/standalone/.next/server/chunks/[externals]__1s61mel._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0id_xf7._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0longh-._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__17g9wh7._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__19120tr._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1fwl2mz._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1myjm-d._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1rhmvod._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[externals]__1_g_b3t._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0114ewg._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__02r5bgf._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0e8sjqm._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0lkzqax._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0nb0syg._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qucxyj._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0u02miy._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0uno39i._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__14dd6h8._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1ath6v_._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1psjybo._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1zqz4v8._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/_1m_p7pi._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/node_modules_html-to-image_es_index_0oy_-36.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_1ezd2jf._.js +0 -5
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_1tnuifj._.js +0 -5
- package/.next/standalone/.next/static/chunks/0h7auy7hzjyhw.js +0 -1
- package/.next/standalone/.next/static/chunks/0zbxssxh53n-3.js +0 -1
- package/.next/standalone/.next/static/chunks/2mazwb1qmur1p.js +0 -1
- package/.next/standalone/.next/static/chunks/2pujpnfx4pws6.css +0 -2
- package/.next/standalone/.next/static/chunks/33u59vf_8xpd-.js +0 -1
- package/.next/standalone/.next/static/chunks/3i27c3hcriawq.css +0 -1
- package/.next/standalone/.next/static/chunks/3s7myk_co0gbh.js +0 -1
- package/.next/standalone/.next/static/chunks/40k1_v4os4cw6.js +0 -6
- package/.next/standalone/Cargo.lock +0 -428
- package/.next/standalone/Cargo.toml +0 -9
- package/.next/standalone/crates/PROTOCOL.md +0 -122
- package/.next/standalone/crates/failproofaid/Cargo.toml +0 -18
- package/.next/standalone/crates/failproofaid/src/lock.rs +0 -81
- package/.next/standalone/crates/failproofaid/src/main.rs +0 -83
- package/.next/standalone/crates/failproofaid/src/paths.rs +0 -172
- package/.next/standalone/crates/failproofaid/src/server.rs +0 -502
- package/.next/standalone/crates/failproofaid/src/worker.rs +0 -400
- package/.next/standalone/crates/failproofaid/tests/daemon_e2e.rs +0 -241
- package/.next/standalone/crates/fpai-ipc/Cargo.toml +0 -16
- package/.next/standalone/crates/fpai-ipc/src/envelope.rs +0 -175
- package/.next/standalone/crates/fpai-ipc/src/framing.rs +0 -177
- package/.next/standalone/crates/fpai-ipc/src/lib.rs +0 -10
- package/.next/standalone/crates/fpai-ipc/src/peer.rs +0 -80
- package/.next/standalone/docker-hook-sync/Dockerfile +0 -79
- package/.next/standalone/docker-hook-sync/entrypoint.sh +0 -109
- package/.next/standalone/integration-suite/Dockerfile +0 -47
- package/.next/standalone/integration-suite/README.md +0 -129
- package/.next/standalone/integration-suite/canary-policies.mjs +0 -45
- package/.next/standalone/integration-suite/capture-tokens.sh +0 -48
- package/.next/standalone/integration-suite/ci-entrypoint.sh +0 -179
- package/.next/standalone/integration-suite/inject-tokens.sh +0 -44
- package/.next/standalone/integration-suite/install-clis.sh +0 -136
- package/.next/standalone/integration-suite/probe-cli.sh +0 -248
- package/.next/standalone/integration-suite/report.js +0 -120
- package/.next/standalone/integration-suite/run.sh +0 -159
- package/.next/standalone/openclaw-plugin/index.js +0 -223
- package/.next/standalone/openclaw-plugin/openclaw.plugin.json +0 -6
- package/.next/standalone/openclaw-plugin/package.json +0 -12
- package/.next/standalone/osv-scanner.toml +0 -17
- package/.next/standalone/pi-extension/index.ts +0 -524
- package/.next/standalone/pi-extension/package.json +0 -12
- package/.next/standalone/postcss.config.mjs +0 -8
- package/.next/standalone/readme-arch-hq.gif +0 -0
- package/.next/standalone/rust-toolchain.toml +0 -4
- package/src/auth/cli.ts +0 -371
- /package/.next/standalone/.next/static/{NWAjs0tHFyzk97gRGG09r → VjEdIL6W5uBsvEzknXqV9}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{NWAjs0tHFyzk97gRGG09r → VjEdIL6W5uBsvEzknXqV9}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{NWAjs0tHFyzk97gRGG09r → VjEdIL6W5uBsvEzknXqV9}/_ssgManifest.js +0 -0
|
@@ -255,155 +255,12 @@
|
|
|
255
255
|
margin-right: 6px;
|
|
256
256
|
}
|
|
257
257
|
|
|
258
|
-
/* ───────────────────────── auth dialog (set-a-reminder gate) ─────────────────────────
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
background: rgba(8,8,10,0.7);
|
|
265
|
-
backdrop-filter: blur(6px);
|
|
266
|
-
-webkit-backdrop-filter: blur(6px);
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
.auth-dialog {
|
|
270
|
-
position: relative;
|
|
271
|
-
width: 100%;
|
|
272
|
-
max-width: 420px;
|
|
273
|
-
padding: 28px 28px 24px;
|
|
274
|
-
border: 1px solid var(--line-2);
|
|
275
|
-
background: var(--bg-2);
|
|
276
|
-
font-family: var(--font-mono);
|
|
277
|
-
color: var(--ink);
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
.auth-close {
|
|
281
|
-
position: absolute; top: 12px; right: 14px;
|
|
282
|
-
font-family: var(--font-mono); font-size: 20px;
|
|
283
|
-
line-height: 1;
|
|
284
|
-
color: var(--dim);
|
|
285
|
-
background: transparent; border: none; padding: 4px 8px;
|
|
286
|
-
cursor: pointer;
|
|
287
|
-
transition: color 120ms;
|
|
288
|
-
}
|
|
289
|
-
.auth-close:hover { color: var(--accent-pink); }
|
|
290
|
-
.auth-close:disabled { color: var(--line-2); cursor: not-allowed; }
|
|
291
|
-
|
|
292
|
-
.auth-headline {
|
|
293
|
-
font-family: var(--font-mono);
|
|
294
|
-
font-size: 18px;
|
|
295
|
-
font-weight: 600;
|
|
296
|
-
letter-spacing: 0;
|
|
297
|
-
line-height: 1.3;
|
|
298
|
-
text-transform: none;
|
|
299
|
-
color: var(--ink);
|
|
300
|
-
margin: 0 0 8px;
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
.auth-sub {
|
|
304
|
-
font-family: var(--font-mono); font-size: 12px;
|
|
305
|
-
line-height: 1.55; color: var(--ink-2);
|
|
306
|
-
margin: 0 0 18px;
|
|
307
|
-
}
|
|
308
|
-
.auth-sub .auth-email {
|
|
309
|
-
color: var(--accent-pink);
|
|
310
|
-
}
|
|
311
|
-
.auth-sub .auth-ok {
|
|
312
|
-
color: var(--accent-green);
|
|
313
|
-
margin-right: 6px;
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
.auth-form { display: flex; flex-direction: column; gap: 10px; }
|
|
317
|
-
|
|
318
|
-
.auth-field-label {
|
|
319
|
-
font-family: var(--font-mono); font-size: 10px;
|
|
320
|
-
letter-spacing: 0.22em; text-transform: uppercase;
|
|
321
|
-
color: var(--accent-green);
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
.auth-input {
|
|
325
|
-
width: 100%;
|
|
326
|
-
padding: 11px 14px;
|
|
327
|
-
background: var(--bg);
|
|
328
|
-
border: 1px solid var(--line-2);
|
|
329
|
-
color: var(--ink);
|
|
330
|
-
font-family: var(--font-mono); font-size: 14px;
|
|
331
|
-
letter-spacing: 0.03em;
|
|
332
|
-
outline: none;
|
|
333
|
-
transition: border-color 120ms, box-shadow 120ms;
|
|
334
|
-
}
|
|
335
|
-
.auth-input:focus {
|
|
336
|
-
border-color: var(--accent-pink);
|
|
337
|
-
box-shadow: 0 0 0 1px var(--accent-pink-soft);
|
|
338
|
-
}
|
|
339
|
-
.auth-input:disabled {
|
|
340
|
-
opacity: 0.55; cursor: not-allowed;
|
|
341
|
-
}
|
|
342
|
-
.auth-input-code {
|
|
343
|
-
letter-spacing: 0.5em;
|
|
344
|
-
text-align: center;
|
|
345
|
-
font-size: 18px;
|
|
346
|
-
font-variant-numeric: tabular-nums;
|
|
347
|
-
}
|
|
348
|
-
.auth-input::placeholder { color: var(--dim); }
|
|
349
|
-
|
|
350
|
-
.auth-error {
|
|
351
|
-
font-family: var(--font-mono); font-size: 12px;
|
|
352
|
-
color: var(--accent-pink);
|
|
353
|
-
padding: 8px 12px;
|
|
354
|
-
background: var(--accent-pink-bg);
|
|
355
|
-
border: 1px solid var(--accent-pink);
|
|
356
|
-
border-left-width: 3px;
|
|
357
|
-
letter-spacing: 0.02em;
|
|
358
|
-
margin-top: 4px;
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
.auth-actions {
|
|
362
|
-
display: flex; gap: 10px; flex-wrap: wrap;
|
|
363
|
-
margin-top: 14px;
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
.auth-btn {
|
|
367
|
-
display: inline-flex; align-items: center; gap: 8px;
|
|
368
|
-
padding: 10px 16px;
|
|
369
|
-
font-family: var(--font-mono); font-size: 12px;
|
|
370
|
-
letter-spacing: 0.06em;
|
|
371
|
-
background: transparent;
|
|
372
|
-
border: 1px solid var(--line-2);
|
|
373
|
-
color: var(--ink);
|
|
374
|
-
cursor: pointer;
|
|
375
|
-
transition: all 120ms ease;
|
|
376
|
-
}
|
|
377
|
-
.auth-btn:hover:not(:disabled) {
|
|
378
|
-
border-color: var(--ink); background: rgba(255,255,255,0.04);
|
|
379
|
-
}
|
|
380
|
-
.auth-btn:disabled { opacity: 0.45; cursor: not-allowed; }
|
|
381
|
-
.auth-btn.primary {
|
|
382
|
-
border-color: var(--accent-pink);
|
|
383
|
-
color: var(--accent-pink);
|
|
384
|
-
background: var(--accent-pink-bg);
|
|
385
|
-
}
|
|
386
|
-
.auth-btn.primary:hover:not(:disabled) {
|
|
387
|
-
background: var(--accent-pink); color: var(--bg);
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
.auth-back {
|
|
391
|
-
align-self: flex-start;
|
|
392
|
-
margin-top: 4px;
|
|
393
|
-
background: transparent; border: none; padding: 6px 0;
|
|
394
|
-
font-family: var(--font-mono); font-size: 11px;
|
|
395
|
-
letter-spacing: 0.1em; color: var(--dim);
|
|
396
|
-
cursor: pointer;
|
|
397
|
-
transition: color 120ms;
|
|
398
|
-
}
|
|
399
|
-
.auth-back:hover:not(:disabled) { color: var(--ink-2); }
|
|
400
|
-
.auth-back:disabled { opacity: 0.45; cursor: not-allowed; }
|
|
401
|
-
|
|
402
|
-
@media (max-width: 520px) {
|
|
403
|
-
.auth-dialog { padding: 26px 22px 22px; }
|
|
404
|
-
.auth-actions { flex-direction: column; align-items: stretch; }
|
|
405
|
-
.auth-btn { justify-content: center; }
|
|
406
|
-
}
|
|
258
|
+
/* ───────────────────────── auth dialog (set-a-reminder gate) ─────────────────────────
|
|
259
|
+
* The dialog's own styles moved to app/audit/_components/auth-dialog.css, which
|
|
260
|
+
* <AuthDialog> imports directly, so the modal is styled on every route that
|
|
261
|
+
* renders it (/audit and now /settings) rather than only this route stylesheet.
|
|
262
|
+
* The `.auth-status-pill` below stays here — it belongs to the /audit return
|
|
263
|
+
* CTA (come-back-better-section), not the dialog. */
|
|
407
264
|
|
|
408
265
|
/* status pill in the return CTA: shows current logged-in email */
|
|
409
266
|
.auth-status-pill {
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The dashboard's rendering of a paused machine.
|
|
5
|
+
*
|
|
6
|
+
* Split out of `hooks-client.tsx` because these are the pieces that keep the
|
|
7
|
+
* activity view honest: a row evaluated during a pause looks identical to one
|
|
8
|
+
* where every policy ran and allowed, and without saying so the log asserts a
|
|
9
|
+
* clean window over exactly the window that was not enforced.
|
|
10
|
+
*/
|
|
11
|
+
import { useEffect, useState } from "react";
|
|
12
|
+
import { ShieldAlert, TriangleAlert } from "lucide-react";
|
|
13
|
+
import type { ActivePause } from "@/src/hooks/session-pause";
|
|
14
|
+
|
|
15
|
+
/** Compact "time left" for a future timestamp. */
|
|
16
|
+
export function formatRemaining(ms: number): string {
|
|
17
|
+
if (ms <= 0) return "expiring now";
|
|
18
|
+
// Sub-minute is checked before rounding: Math.round(30s) is "1m", which tells
|
|
19
|
+
// someone they have more time than they do. On a countdown to enforcement
|
|
20
|
+
// coming back, never round up.
|
|
21
|
+
if (ms < 60_000) return "under a minute";
|
|
22
|
+
const minutes = Math.round(ms / 60_000);
|
|
23
|
+
if (minutes < 60) return `${minutes}m`;
|
|
24
|
+
const hours = Math.floor(minutes / 60);
|
|
25
|
+
const rest = minutes % 60;
|
|
26
|
+
return rest === 0 ? `${hours}h` : `${hours}h${rest}m`;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Live state, not history: enforcement is paused RIGHT NOW.
|
|
31
|
+
*
|
|
32
|
+
* The rows below cannot carry this on their own — a pause set seconds ago has
|
|
33
|
+
* produced none yet, and that is precisely when someone needs telling that the
|
|
34
|
+
* machine is unguarded. An absent banner has to mean "enforcing", so this is fed
|
|
35
|
+
* from live pause state rather than inferred from whatever is on screen.
|
|
36
|
+
*/
|
|
37
|
+
export function PausedBanner({ pauses, now: nowProp }: { pauses: ActivePause[]; now?: number }) {
|
|
38
|
+
const [tick, setTick] = useState(() => Date.now());
|
|
39
|
+
// Re-render on a timer so "22m left" does not sit frozen while the pause
|
|
40
|
+
// silently drains away.
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
const id = setInterval(() => setTick(Date.now()), 30_000);
|
|
43
|
+
return () => clearInterval(id);
|
|
44
|
+
}, []);
|
|
45
|
+
const now = nowProp ?? tick;
|
|
46
|
+
|
|
47
|
+
// Filter again here rather than trusting the fetch: the list was accurate
|
|
48
|
+
// when it arrived, and a short pause can expire between polls.
|
|
49
|
+
const live = pauses.filter((p) => p.expiresAt > now);
|
|
50
|
+
if (live.length === 0) return null;
|
|
51
|
+
const soonest = live.reduce((a, b) => (a.expiresAt < b.expiresAt ? a : b));
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
<div
|
|
55
|
+
role="status"
|
|
56
|
+
className="mb-4 flex items-start gap-2.5 rounded border border-amber-500/40 bg-amber-500/[0.07] px-3 py-2.5"
|
|
57
|
+
>
|
|
58
|
+
<ShieldAlert className="h-4 w-4 shrink-0 text-amber-500 mt-0.5" aria-hidden="true" />
|
|
59
|
+
<div className="text-xs leading-relaxed">
|
|
60
|
+
<p className="font-medium text-foreground">
|
|
61
|
+
Enforcement is paused for {live.length} session{live.length === 1 ? "" : "s"} —{" "}
|
|
62
|
+
{formatRemaining(soonest.expiresAt - now)} left
|
|
63
|
+
{live.length > 1 ? " on the next to expire" : ""}.
|
|
64
|
+
</p>
|
|
65
|
+
<p className="text-muted-foreground mt-0.5">
|
|
66
|
+
Builtin, custom and convention policies are suspended for{" "}
|
|
67
|
+
{live.length === 1 ? "that session" : "those sessions"}; cloud-managed policies keep
|
|
68
|
+
enforcing. It lifts on its own — or run{" "}
|
|
69
|
+
<span className="font-mono text-foreground">failproofai config --resume</span>.
|
|
70
|
+
</p>
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** Marks a row that was evaluated while enforcement was paused. */
|
|
77
|
+
export function PausedPill() {
|
|
78
|
+
return (
|
|
79
|
+
<span
|
|
80
|
+
title="Enforcement was paused for this session — local policies did not run"
|
|
81
|
+
className="ml-1.5 inline-flex items-center rounded px-1.5 py-0.5 text-[0.6rem] font-medium uppercase tracking-wide border border-amber-500/40 bg-amber-500/10 text-amber-600 dark:text-amber-500"
|
|
82
|
+
>
|
|
83
|
+
paused
|
|
84
|
+
</span>
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** Why an `allow` on this row proves nothing. */
|
|
89
|
+
export function PausedNote({
|
|
90
|
+
item,
|
|
91
|
+
}: {
|
|
92
|
+
item: { pausedBy?: string; pauseExpiresAt?: number };
|
|
93
|
+
}) {
|
|
94
|
+
if (!item.pausedBy) return null;
|
|
95
|
+
const lifted =
|
|
96
|
+
typeof item.pauseExpiresAt === "number"
|
|
97
|
+
? new Date(item.pauseExpiresAt).toLocaleTimeString()
|
|
98
|
+
: null;
|
|
99
|
+
return (
|
|
100
|
+
<div className="sm:col-span-2 lg:col-span-3 mt-1 flex items-start gap-2 rounded border border-amber-500/30 bg-amber-500/5 px-2.5 py-2">
|
|
101
|
+
<TriangleAlert className="h-3.5 w-3.5 shrink-0 text-amber-500/80 mt-0.5" aria-hidden="true" />
|
|
102
|
+
<p className="text-[0.7rem] leading-relaxed text-muted-foreground">
|
|
103
|
+
<span className="font-medium text-foreground">Not enforced — paused.</span> Enforcement was
|
|
104
|
+
suspended for this session
|
|
105
|
+
{item.pausedBy === "cli" ? " from the CLI" : ` by ${item.pausedBy}`}
|
|
106
|
+
{lifted ? `, lifting at ${lifted}` : ""}. Builtin, custom and convention policies did not
|
|
107
|
+
run for this event; cloud-managed policies did.
|
|
108
|
+
</p>
|
|
109
|
+
</div>
|
|
110
|
+
);
|
|
111
|
+
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
"use client";
|
|
7
7
|
|
|
8
|
-
import
|
|
8
|
+
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
9
9
|
import { useWindowVirtualizer } from "@tanstack/react-virtual";
|
|
10
10
|
import { ChevronDown, Wrench } from "lucide-react";
|
|
11
11
|
import type { LogEntry, ToolUseBlock } from "@/lib/log-entries";
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import { useState, useEffect, useCallback, useMemo, useRef, useTransition } from "react";
|
|
4
|
+
import * as React from "react";
|
|
4
5
|
import { createPortal } from "react-dom";
|
|
5
6
|
import Link from "next/link";
|
|
6
7
|
import { Check, ChevronDown, Code, Copy, Settings, Shield, ShieldAlert, ShieldCheck, ShieldX, TriangleAlert, X } from "lucide-react";
|
|
7
8
|
import PaginationControls from "@/app/components/pagination-controls";
|
|
8
9
|
import { getHookActivityAction, searchHookActivityAction } from "@/app/actions/get-hook-activity";
|
|
9
10
|
import type { HookActivityPayload } from "@/app/actions/get-hook-activity";
|
|
11
|
+
import { getActivePausesAction } from "@/app/actions/get-active-pauses";
|
|
12
|
+
import type { ActivePause } from "@/src/hooks/session-pause";
|
|
13
|
+
import { PausedBanner, PausedNote, PausedPill } from "@/app/components/pause-notices";
|
|
10
14
|
import { getHooksConfigAction } from "@/app/actions/get-hooks-config";
|
|
11
|
-
import type { HooksConfigPayload, PolicyInfo
|
|
15
|
+
import type { HooksConfigPayload, PolicyInfo } from "@/app/actions/get-hooks-config";
|
|
12
16
|
import type { IntegrationType } from "@/src/hooks/types";
|
|
13
17
|
import { toggleCustomPolicyAction, togglePolicyAction } from "@/app/actions/update-hooks-config";
|
|
14
18
|
import { installHooksWebAction, removeHooksWebAction } from "@/app/actions/install-hooks-web";
|
|
@@ -386,7 +390,27 @@ function DetailPanel({
|
|
|
386
390
|
event detail
|
|
387
391
|
</span>
|
|
388
392
|
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-x-8 gap-y-2">
|
|
393
|
+
<PausedNote item={item} />
|
|
389
394
|
<EnforcementNote item={item} />
|
|
395
|
+
{item.policySource && (
|
|
396
|
+
<div>
|
|
397
|
+
<span className="text-muted-foreground">Decided by: </span>
|
|
398
|
+
<span className="font-mono text-foreground">
|
|
399
|
+
{item.policySource === "cloud" && item.cloudPolicyId
|
|
400
|
+
? `cloud · ${item.cloudPolicyId} version ${item.cloudVersion}`
|
|
401
|
+
: item.policySource}
|
|
402
|
+
</span>
|
|
403
|
+
</div>
|
|
404
|
+
)}
|
|
405
|
+
{item.cloudDeployment !== undefined && (
|
|
406
|
+
<div>
|
|
407
|
+
{/* Present on every row of a managed machine, not just cloud
|
|
408
|
+
decisions — it is what separates a rollout that changed no
|
|
409
|
+
outcomes from one that never arrived. */}
|
|
410
|
+
<span className="text-muted-foreground">Cloud deployment: </span>
|
|
411
|
+
<span className="font-mono text-foreground">{item.cloudDeployment}</span>
|
|
412
|
+
</div>
|
|
413
|
+
)}
|
|
390
414
|
<div>
|
|
391
415
|
<span className="text-muted-foreground">Session ID: </span>
|
|
392
416
|
<span className="font-mono text-foreground">
|
|
@@ -443,6 +467,7 @@ function ActivityTab({
|
|
|
443
467
|
|
|
444
468
|
const [page, setPage] = useState(() => paramToPage(url.get("page")));
|
|
445
469
|
const [data, setData] = useState<HookActivityPayload | null>(null);
|
|
470
|
+
const [activePauses, setActivePauses] = useState<ActivePause[]>([]);
|
|
446
471
|
const [expandedRow, setExpandedRow] = useState<number | null>(null);
|
|
447
472
|
|
|
448
473
|
const [filterDecision, setFilterDecision] = useState<"" | "allow" | "deny" | "instruct">(() => {
|
|
@@ -456,10 +481,14 @@ function ActivityTab({
|
|
|
456
481
|
const v = url.get("cli");
|
|
457
482
|
return isKnownCli(v) ? v : "";
|
|
458
483
|
});
|
|
484
|
+
const [filterSource, setFilterSource] = useState<"" | "builtin" | "custom" | "convention" | "cloud">(() => {
|
|
485
|
+
const v = url.get("source");
|
|
486
|
+
return v === "builtin" || v === "custom" || v === "convention" || v === "cloud" ? v : "";
|
|
487
|
+
});
|
|
459
488
|
const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
460
489
|
const filterTelemetryFirstRunRef = useRef(true);
|
|
461
|
-
const filtersRef = useRef({ filterDecision, filterEventType, filterPolicy, filterSessionId, filterCli });
|
|
462
|
-
filtersRef.current = { filterDecision, filterEventType, filterPolicy, filterSessionId, filterCli };
|
|
490
|
+
const filtersRef = useRef({ filterDecision, filterEventType, filterPolicy, filterSessionId, filterCli, filterSource });
|
|
491
|
+
filtersRef.current = { filterDecision, filterEventType, filterPolicy, filterSessionId, filterCli, filterSource };
|
|
463
492
|
|
|
464
493
|
useEffect(() => {
|
|
465
494
|
if (!mountedRef.current) {
|
|
@@ -472,17 +501,18 @@ function ActivityTab({
|
|
|
472
501
|
policy: filterPolicy || undefined,
|
|
473
502
|
session: filterSessionId || undefined,
|
|
474
503
|
cli: filterCli || undefined,
|
|
504
|
+
source: filterSource || undefined,
|
|
475
505
|
page: pageToParam(page),
|
|
476
506
|
});
|
|
477
507
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
478
|
-
}, [filterDecision, filterEventType, filterPolicy, filterSessionId, filterCli, page]);
|
|
508
|
+
}, [filterDecision, filterEventType, filterPolicy, filterSessionId, filterCli, filterSource, page]);
|
|
479
509
|
|
|
480
|
-
const hasActiveFilters = filterDecision !== "" || filterEventType !== "" || filterPolicy !== "" || filterSessionId !== "" || filterCli !== "";
|
|
510
|
+
const hasActiveFilters = filterDecision !== "" || filterEventType !== "" || filterPolicy !== "" || filterSessionId !== "" || filterCli !== "" || filterSource !== "";
|
|
481
511
|
|
|
482
512
|
const fetchData = useCallback(async (p: number) => {
|
|
483
513
|
try {
|
|
484
|
-
const { filterDecision: fd, filterEventType: fe, filterPolicy: fp, filterSessionId: fs, filterCli: fc } = filtersRef.current;
|
|
485
|
-
const active = fd !== "" || fe !== "" || fp !== "" || fs !== "" || fc !== "";
|
|
514
|
+
const { filterDecision: fd, filterEventType: fe, filterPolicy: fp, filterSessionId: fs, filterCli: fc, filterSource: fsrc } = filtersRef.current;
|
|
515
|
+
const active = fd !== "" || fe !== "" || fp !== "" || fs !== "" || fc !== "" || fsrc !== "";
|
|
486
516
|
let result: HookActivityPayload;
|
|
487
517
|
if (active) {
|
|
488
518
|
result = await searchHookActivityAction(
|
|
@@ -492,6 +522,7 @@ function ActivityTab({
|
|
|
492
522
|
policyName: fp || undefined,
|
|
493
523
|
sessionId: fs || undefined,
|
|
494
524
|
integration: fc || undefined,
|
|
525
|
+
source: fsrc || undefined,
|
|
495
526
|
},
|
|
496
527
|
p,
|
|
497
528
|
);
|
|
@@ -511,6 +542,22 @@ function ActivityTab({
|
|
|
511
542
|
return () => clearInterval(id);
|
|
512
543
|
}, [page, fetchData, intervalSec]);
|
|
513
544
|
|
|
545
|
+
// Pause state is polled independently of the activity page: it is live
|
|
546
|
+
// machine state, not a property of whichever rows are on screen, and it must
|
|
547
|
+
// keep updating while the user sits on page 3 of history.
|
|
548
|
+
useEffect(() => {
|
|
549
|
+
let cancelled = false;
|
|
550
|
+
const load = () => {
|
|
551
|
+
getActivePausesAction()
|
|
552
|
+
.then((p) => { if (!cancelled) setActivePauses(p); })
|
|
553
|
+
.catch(() => { /* non-critical: the banner simply stays hidden */ });
|
|
554
|
+
};
|
|
555
|
+
load();
|
|
556
|
+
const ms = intervalSec > 0 ? intervalSec * 1000 : 5000;
|
|
557
|
+
const id = setInterval(load, ms);
|
|
558
|
+
return () => { cancelled = true; clearInterval(id); };
|
|
559
|
+
}, [intervalSec]);
|
|
560
|
+
|
|
514
561
|
useEffect(() => {
|
|
515
562
|
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
516
563
|
debounceRef.current = setTimeout(() => {
|
|
@@ -565,6 +612,10 @@ function ActivityTab({
|
|
|
565
612
|
|
|
566
613
|
return (
|
|
567
614
|
<>
|
|
615
|
+
{/* Above the stats, deliberately: a paused machine is the most important
|
|
616
|
+
thing on this screen, and the numbers below it are being produced with
|
|
617
|
+
local enforcement switched off. */}
|
|
618
|
+
<PausedBanner pauses={activePauses} />
|
|
568
619
|
{data?.stats && data.stats.totalEvents > 0 && (
|
|
569
620
|
<div style={{ marginBottom: 18 }}>
|
|
570
621
|
<StatsBar stats={data.stats} />
|
|
@@ -593,6 +644,29 @@ function ActivityTab({
|
|
|
593
644
|
<option value="PermissionRequest">PermissionRequest</option>
|
|
594
645
|
</select>
|
|
595
646
|
</div>
|
|
647
|
+
<div className="filter-group">
|
|
648
|
+
{/* "What did my organization's policies decide here?" is the
|
|
649
|
+
question cloud rollout reporting rests on, and it is
|
|
650
|
+
unanswerable while the source is only a prefix on a name. */}
|
|
651
|
+
<span className="filter-label">source</span>
|
|
652
|
+
<select
|
|
653
|
+
value={filterSource}
|
|
654
|
+
onChange={(e) => {
|
|
655
|
+
const v = e.target.value;
|
|
656
|
+
setFilterSource(
|
|
657
|
+
v === "builtin" || v === "custom" || v === "convention" || v === "cloud" ? v : "",
|
|
658
|
+
);
|
|
659
|
+
}}
|
|
660
|
+
className="filter-input"
|
|
661
|
+
aria-label="Filter by policy source"
|
|
662
|
+
>
|
|
663
|
+
<option value="">all sources</option>
|
|
664
|
+
<option value="builtin">builtin</option>
|
|
665
|
+
<option value="custom">custom</option>
|
|
666
|
+
<option value="convention">convention</option>
|
|
667
|
+
<option value="cloud">cloud</option>
|
|
668
|
+
</select>
|
|
669
|
+
</div>
|
|
596
670
|
<div className="filter-group">
|
|
597
671
|
<span className="filter-label">cli</span>
|
|
598
672
|
<select
|
|
@@ -642,6 +716,7 @@ function ActivityTab({
|
|
|
642
716
|
setFilterCli("");
|
|
643
717
|
setFilterPolicy("");
|
|
644
718
|
setFilterSessionId("");
|
|
719
|
+
setFilterSource("");
|
|
645
720
|
}}
|
|
646
721
|
aria-label="Clear all filters"
|
|
647
722
|
>
|
|
@@ -744,6 +819,7 @@ function ActivityTab({
|
|
|
744
819
|
</td>
|
|
745
820
|
<td className="px-3 py-2">
|
|
746
821
|
<DecisionBadge decision={item.decision} />
|
|
822
|
+
{item.pausedBy && <PausedPill />}
|
|
747
823
|
</td>
|
|
748
824
|
<td className="px-3 py-2">
|
|
749
825
|
<EventTypeBadge eventType={item.eventType} />
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* /settings — one page, sections. The single home for the machine-level
|
|
3
|
+
* controls the design plan collected here: the scheduled local audit and
|
|
4
|
+
* emailed audit reports.
|
|
5
|
+
*
|
|
6
|
+
* Deliberately NOT a home for telemetry: the product decision is that telemetry
|
|
7
|
+
* is documented but not advertised in-product, so there is no telemetry control
|
|
8
|
+
* or status on this page. `config.toml` plus the docs are the whole story.
|
|
9
|
+
*
|
|
10
|
+
* Thin server wrapper (Suspense boundary + the disabled-pages gate every route
|
|
11
|
+
* uses); all the reads/writes live in the client and its server actions.
|
|
12
|
+
*/
|
|
13
|
+
import { Suspense } from "react";
|
|
14
|
+
import { notFound } from "next/navigation";
|
|
15
|
+
import SettingsClient from "./settings-client";
|
|
16
|
+
|
|
17
|
+
export const dynamic = "force-dynamic";
|
|
18
|
+
|
|
19
|
+
export default async function SettingsPage() {
|
|
20
|
+
const disabled = (process.env.FAILPROOFAI_DISABLE_PAGES ?? "")
|
|
21
|
+
.split(",")
|
|
22
|
+
.map((s) => s.trim())
|
|
23
|
+
.filter(Boolean);
|
|
24
|
+
if (disabled.includes("settings")) notFound();
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<Suspense>
|
|
28
|
+
<SettingsClient />
|
|
29
|
+
</Suspense>
|
|
30
|
+
);
|
|
31
|
+
}
|