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
|
@@ -19,10 +19,12 @@
|
|
|
19
19
|
* real command.
|
|
20
20
|
*/
|
|
21
21
|
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
|
|
22
|
-
import { resolve } from "node:path";
|
|
22
|
+
import { dirname, resolve } from "node:path";
|
|
23
23
|
import { platform, arch, release, homedir, hostname } from "node:os";
|
|
24
24
|
import { createHmac } from "node:crypto";
|
|
25
25
|
import { trackInstallEvent } from "../scripts/install-telemetry.mjs";
|
|
26
|
+
import { isTelemetryEnabled } from "./telemetry-enabled";
|
|
27
|
+
import { globalPolicyConfigFile, lastVersionFile } from "../src/hooks/fp-home";
|
|
26
28
|
|
|
27
29
|
const FAILPROOFAI_HOOK_MARKER = "__failproofai_hook__";
|
|
28
30
|
const NAMESPACE = "failproofai-telemetry-v1";
|
|
@@ -47,7 +49,7 @@ function hashToId(raw: string): string {
|
|
|
47
49
|
}
|
|
48
50
|
|
|
49
51
|
function lastVersionPath(): string {
|
|
50
|
-
return
|
|
52
|
+
return lastVersionFile();
|
|
51
53
|
}
|
|
52
54
|
|
|
53
55
|
/**
|
|
@@ -110,7 +112,13 @@ export interface HooksState {
|
|
|
110
112
|
* script so the event keeps its historical meaning.
|
|
111
113
|
*/
|
|
112
114
|
export function checkHooks(): HooksState {
|
|
113
|
-
|
|
115
|
+
// Layout 2's global policy config, via the one module allowed to join a path
|
|
116
|
+
// onto the home. This read `~/.failproofai/policies-config.json` — layout 1's
|
|
117
|
+
// location — so on every layout-2 machine it found nothing and reported the
|
|
118
|
+
// install as unconfigured with zero policies, which is what
|
|
119
|
+
// `package_installed` telemetry has been recording for every user since the
|
|
120
|
+
// reorganisation.
|
|
121
|
+
const hooksConfigPath = globalPolicyConfigFile();
|
|
114
122
|
if (!existsSync(hooksConfigPath)) {
|
|
115
123
|
return { configured: false, registered: false, policyCount: 0 };
|
|
116
124
|
}
|
|
@@ -177,6 +185,13 @@ export async function maybeReportInstall(version: string): Promise<void> {
|
|
|
177
185
|
// Steady state: same version already reported. Costs one stat() per command.
|
|
178
186
|
if (previousVersion === version) return;
|
|
179
187
|
|
|
188
|
+
// The install dispatcher is a dependency-free .mjs and cannot import the
|
|
189
|
+
// TOML config, so it is told the verdict rather than resolving it. Passed
|
|
190
|
+
// per call rather than checked here, because the version marker below must
|
|
191
|
+
// still be written when telemetry is off — otherwise this whole check would
|
|
192
|
+
// re-run on every single CLI invocation, forever.
|
|
193
|
+
const telemetryEnabled = isTelemetryEnabled();
|
|
194
|
+
|
|
180
195
|
const hooks = checkHooks();
|
|
181
196
|
|
|
182
197
|
const events: Promise<void>[] = [];
|
|
@@ -187,7 +202,7 @@ export async function maybeReportInstall(version: string): Promise<void> {
|
|
|
187
202
|
arch: arch(),
|
|
188
203
|
os_release: release(),
|
|
189
204
|
node_version: process.versions.node,
|
|
190
|
-
}, { version, timeoutMs: REPORT_TIMEOUT_MS }),
|
|
205
|
+
}, { version, timeoutMs: REPORT_TIMEOUT_MS, enabled: telemetryEnabled }),
|
|
191
206
|
);
|
|
192
207
|
} else {
|
|
193
208
|
const cmp = compareSemver(previousVersion, version);
|
|
@@ -198,7 +213,7 @@ export async function maybeReportInstall(version: string): Promise<void> {
|
|
|
198
213
|
direction: cmp < 0 ? "upgrade" : "downgrade",
|
|
199
214
|
platform: platform(),
|
|
200
215
|
arch: arch(),
|
|
201
|
-
}, { version, timeoutMs: REPORT_TIMEOUT_MS }),
|
|
216
|
+
}, { version, timeoutMs: REPORT_TIMEOUT_MS, enabled: telemetryEnabled }),
|
|
202
217
|
);
|
|
203
218
|
}
|
|
204
219
|
|
|
@@ -212,13 +227,13 @@ export async function maybeReportInstall(version: string): Promise<void> {
|
|
|
212
227
|
hooks_configured: hooks.configured,
|
|
213
228
|
hooks_registered: hooks.registered,
|
|
214
229
|
enabled_policy_count: hooks.policyCount,
|
|
215
|
-
}, { version, timeoutMs: REPORT_TIMEOUT_MS }),
|
|
230
|
+
}, { version, timeoutMs: REPORT_TIMEOUT_MS, enabled: telemetryEnabled }),
|
|
216
231
|
);
|
|
217
232
|
|
|
218
233
|
// Record before awaiting: a dropped event is cheaper than re-reporting the
|
|
219
234
|
// same version on every command because delivery kept failing.
|
|
220
235
|
try {
|
|
221
|
-
mkdirSync(
|
|
236
|
+
mkdirSync(dirname(versionFile), { recursive: true });
|
|
222
237
|
writeFileSync(versionFile, version, "utf8");
|
|
223
238
|
} catch {
|
|
224
239
|
// best-effort
|
|
@@ -17,12 +17,33 @@
|
|
|
17
17
|
* {type: "message", id, parentId, timestamp,
|
|
18
18
|
* message: {role, content[], timestamp}}
|
|
19
19
|
*
|
|
20
|
-
* `message.content[]` items can be `{type: "text", text}
|
|
21
|
-
* `{type: "thinking", thinking, thinkingSignature}
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
20
|
+
* `message.content[]` items can be `{type: "text", text}`,
|
|
21
|
+
* `{type: "thinking", thinking, thinkingSignature}` or `{type: "toolCall",
|
|
22
|
+
* id, name, arguments}`.
|
|
23
|
+
*
|
|
24
|
+
* Tool calls WERE previously believed not to exist here — the header used to
|
|
25
|
+
* say no tool-using run had been captured, so `toolCall` blocks fell through
|
|
26
|
+
* to the generic "system" branch and every tool event Pi emits was silently
|
|
27
|
+
* dropped from the audit path. A live capture (pi 0.73.1 and 0.83.0, driven
|
|
28
|
+
* against a real provider) shows Pi emits them in full:
|
|
29
|
+
*
|
|
30
|
+
* assistant turn content[] contains {type:"toolCall", id, name, arguments}
|
|
31
|
+
* and the message carries stopReason:"toolUse"
|
|
32
|
+
* tool result its own record with a THIRD role —
|
|
33
|
+
* message.role === "toolResult", carrying toolCallId,
|
|
34
|
+
* toolName, content[], isError, timestamp (epoch ms)
|
|
35
|
+
*
|
|
36
|
+
* `toolResult.toolCallId` pairs exactly with `toolCall.id`, one result record
|
|
37
|
+
* per call, emitted in call order — so results attach by id, never by
|
|
38
|
+
* position. Pi supplies no duration, so it is derived from the gap between
|
|
39
|
+
* the call and its result, the same way the OpenClaw parser does it.
|
|
40
|
+
*
|
|
41
|
+
* The format is identical across the 0.73.1 (`@mariozechner/pi-coding-agent`)
|
|
42
|
+
* and 0.83.0 (`@earendil-works/pi-coding-agent`) packages — same `version: 3`
|
|
43
|
+
* header, same record types — so one parser covers both. One difference worth
|
|
44
|
+
* guarding: 0.83.0 emits leading prose alongside the calls
|
|
45
|
+
* (`["text","toolCall","toolCall"]`) where 0.73.1 emitted only the calls, so
|
|
46
|
+
* assistant content must not be assumed homogeneous.
|
|
26
47
|
*/
|
|
27
48
|
import { readFileSync, readdirSync, existsSync, statSync } from "node:fs";
|
|
28
49
|
import { readFile } from "node:fs/promises";
|
|
@@ -38,8 +59,10 @@ import {
|
|
|
38
59
|
type GenericEntry,
|
|
39
60
|
type QueueOperationEntry,
|
|
40
61
|
type ContentBlock,
|
|
62
|
+
type ToolUseBlock,
|
|
41
63
|
type LogSource,
|
|
42
64
|
} from "./log-entries";
|
|
65
|
+
import { formatDuration } from "./format-duration";
|
|
43
66
|
|
|
44
67
|
// ── Paths ──
|
|
45
68
|
|
|
@@ -107,6 +130,10 @@ interface PiSessionRecord {
|
|
|
107
130
|
role?: string;
|
|
108
131
|
content?: Array<Record<string, unknown>>;
|
|
109
132
|
timestamp?: number;
|
|
133
|
+
/** Present on `role: "toolResult"` records — pairs with a `toolCall.id`. */
|
|
134
|
+
toolCallId?: string;
|
|
135
|
+
toolName?: string;
|
|
136
|
+
isError?: boolean;
|
|
110
137
|
};
|
|
111
138
|
}
|
|
112
139
|
|
|
@@ -129,9 +156,19 @@ function extractMessageText(content: Array<Record<string, unknown>> | undefined)
|
|
|
129
156
|
return parts.join("\n\n");
|
|
130
157
|
}
|
|
131
158
|
|
|
132
|
-
/** Build a list of ContentBlocks for the assistant entry, preserving text
|
|
133
|
-
* thinking blocks. Skips blocks with non-string payloads
|
|
134
|
-
|
|
159
|
+
/** Build a list of ContentBlocks for the assistant entry, preserving text,
|
|
160
|
+
* thinking and tool-call blocks. Skips blocks with non-string payloads
|
|
161
|
+
* (typeof guards).
|
|
162
|
+
*
|
|
163
|
+
* Every `tool_use` block built here is also handed to `onToolUse` so the
|
|
164
|
+
* caller can index it by id and attach the matching `toolResult` record when
|
|
165
|
+
* it arrives on a later line. The block is passed by reference and mutated
|
|
166
|
+
* in place, exactly as the OpenClaw parser does — the entry has already been
|
|
167
|
+
* pushed by then, so there is nothing else to attach it to. */
|
|
168
|
+
function buildAssistantContent(
|
|
169
|
+
content: Array<Record<string, unknown>> | undefined,
|
|
170
|
+
onToolUse?: (block: ToolUseBlock) => void,
|
|
171
|
+
): ContentBlock[] {
|
|
135
172
|
if (!Array.isArray(content)) return [];
|
|
136
173
|
const blocks: ContentBlock[] = [];
|
|
137
174
|
for (const block of content) {
|
|
@@ -143,6 +180,22 @@ function buildAssistantContent(content: Array<Record<string, unknown>> | undefin
|
|
|
143
180
|
if (block?.type === "thinking" && typeof block.thinking === "string" && block.thinking.length > 0) {
|
|
144
181
|
blocks.push({ type: "text", text: `[thinking] ${block.thinking}` });
|
|
145
182
|
}
|
|
183
|
+
if (block?.type === "toolCall") {
|
|
184
|
+
// Fall back to a positional id only when Pi omits one. A synthetic id
|
|
185
|
+
// still renders, but it can never pair with a result — so it must not
|
|
186
|
+
// collide with a real one, hence the index suffix.
|
|
187
|
+
const id = typeof block.id === "string" && block.id.length > 0
|
|
188
|
+
? block.id
|
|
189
|
+
: `${typeof block.name === "string" ? block.name : "tool"}-${blocks.length}`;
|
|
190
|
+
const name = typeof block.name === "string" ? block.name : "tool";
|
|
191
|
+
const input =
|
|
192
|
+
block.arguments && typeof block.arguments === "object" && !Array.isArray(block.arguments)
|
|
193
|
+
? (block.arguments as Record<string, unknown>)
|
|
194
|
+
: {};
|
|
195
|
+
const toolUse: ToolUseBlock = { type: "tool_use", id, name, input };
|
|
196
|
+
blocks.push(toolUse);
|
|
197
|
+
onToolUse?.(toolUse);
|
|
198
|
+
}
|
|
146
199
|
}
|
|
147
200
|
return blocks;
|
|
148
201
|
}
|
|
@@ -161,6 +214,12 @@ export async function parsePiLog(
|
|
|
161
214
|
const rawLines: Record<string, unknown>[] = [];
|
|
162
215
|
let cwd: string | undefined;
|
|
163
216
|
let seenSessionStart = false;
|
|
217
|
+
// In-flight tool calls, so a later `toolResult` record can attach its output
|
|
218
|
+
// to the block it belongs to. Keyed by the provider's own call id, never by
|
|
219
|
+
// position — Pi emits results in call order today, but pairing by order
|
|
220
|
+
// would break silently the first time it does not.
|
|
221
|
+
const toolUseById = new Map<string, ToolUseBlock>();
|
|
222
|
+
const toolUseStartMs = new Map<string, number>();
|
|
164
223
|
|
|
165
224
|
for (let i = 0; i < lines.length; i++) {
|
|
166
225
|
if (i > 0 && i % 200 === 0) await new Promise<void>((r) => setImmediate(r));
|
|
@@ -215,7 +274,10 @@ export async function parsePiLog(
|
|
|
215
274
|
}
|
|
216
275
|
|
|
217
276
|
if (role === "assistant") {
|
|
218
|
-
const blocks = buildAssistantContent(content)
|
|
277
|
+
const blocks = buildAssistantContent(content, (block) => {
|
|
278
|
+
toolUseById.set(block.id, block);
|
|
279
|
+
toolUseStartMs.set(block.id, date.getTime());
|
|
280
|
+
});
|
|
219
281
|
if (blocks.length === 0) {
|
|
220
282
|
entries.push({
|
|
221
283
|
type: "system",
|
|
@@ -232,6 +294,33 @@ export async function parsePiLog(
|
|
|
232
294
|
continue;
|
|
233
295
|
}
|
|
234
296
|
|
|
297
|
+
// Pi's third role: a tool result, on its own record, pairing back to an
|
|
298
|
+
// assistant turn's toolCall by id. Attaching it to that block is what
|
|
299
|
+
// makes the tool's OUTPUT visible — without this the call renders with
|
|
300
|
+
// no result and the audit path sees no `toolResultText` at all.
|
|
301
|
+
if (role === "toolResult") {
|
|
302
|
+
const callId = raw.message.toolCallId;
|
|
303
|
+
const block = typeof callId === "string" ? toolUseById.get(callId) : undefined;
|
|
304
|
+
if (block) {
|
|
305
|
+
// Pi records no duration on the result, so derive it from the gap
|
|
306
|
+
// between the call and its result. `startMs` is always present for
|
|
307
|
+
// a block we indexed; the fallback keeps the arithmetic total.
|
|
308
|
+
const startMs = (typeof callId === "string" && toolUseStartMs.get(callId)) || date.getTime();
|
|
309
|
+
const durationMs = Math.max(0, date.getTime() - startMs);
|
|
310
|
+
block.result = {
|
|
311
|
+
timestamp,
|
|
312
|
+
timestampFormatted: formatTimestamp(date),
|
|
313
|
+
content: extractMessageText(content),
|
|
314
|
+
durationMs,
|
|
315
|
+
durationFormatted: formatDuration(durationMs),
|
|
316
|
+
};
|
|
317
|
+
continue;
|
|
318
|
+
}
|
|
319
|
+
// Orphan result — the call was never seen (truncated file, or a
|
|
320
|
+
// resumed session whose earlier half is in another file). Fall
|
|
321
|
+
// through so the record is preserved rather than dropped.
|
|
322
|
+
}
|
|
323
|
+
|
|
235
324
|
// Unknown role — preserve raw so nothing is dropped.
|
|
236
325
|
entries.push({
|
|
237
326
|
type: "system",
|
|
@@ -319,7 +408,3 @@ export function readPiTranscriptSync(sessionId: string): string | null {
|
|
|
319
408
|
return null;
|
|
320
409
|
}
|
|
321
410
|
}
|
|
322
|
-
|
|
323
|
-
/** Suppress unused-import warning for formatTimestamp; reserved for tool-call
|
|
324
|
-
* rendering once Pi emits it (see header comment). */
|
|
325
|
-
void formatTimestamp;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The single answer to "may we send telemetry?", shared by every dispatcher.
|
|
3
|
+
*
|
|
4
|
+
* There are four of them — the CLI and hook path (`src/hooks/hook-telemetry.ts`),
|
|
5
|
+
* the Next.js server (`lib/telemetry.ts`), the browser (`lib/client-telemetry.ts`,
|
|
6
|
+
* which inherits this via `getTelemetryConfig`), and the install script
|
|
7
|
+
* (`scripts/install-telemetry.mjs`, gated by its TypeScript caller). A dispatcher
|
|
8
|
+
* that resolved this differently would be an opt-out that silently does not hold,
|
|
9
|
+
* which is worse than having no opt-out at all.
|
|
10
|
+
*
|
|
11
|
+
* ## Two sources, and why the file is the important one
|
|
12
|
+
*
|
|
13
|
+
* `FAILPROOFAI_TELEMETRY_DISABLED=1` is read from `process.env`. That works for
|
|
14
|
+
* anything the user launches from a shell, and it is kept because people already
|
|
15
|
+
* rely on it. It cannot work for **failproofaid**: the daemon is a system-scope
|
|
16
|
+
* service unit whose environment carries essentially nothing, so an exported
|
|
17
|
+
* variable is structurally incapable of reaching it. `[telemetry] enabled` in
|
|
18
|
+
* config.toml is a file both the CLI and the daemon read, which is why it is the
|
|
19
|
+
* off-switch the documentation points at.
|
|
20
|
+
*
|
|
21
|
+
* They resolve to the **more restrictive** of the two: either says stop, and we
|
|
22
|
+
* stop. The environment can never re-enable something the file switched off —
|
|
23
|
+
* an env var that could override a written preference is not an opt-out.
|
|
24
|
+
*/
|
|
25
|
+
import { readConfig } from "../src/hooks/fp-config";
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Resolved fresh on every call, deliberately.
|
|
29
|
+
*
|
|
30
|
+
* Memoising this was the obvious optimisation and it is the wrong one. An
|
|
31
|
+
* opt-out that a long-lived process (the dashboard server, the warm worker)
|
|
32
|
+
* keeps ignoring until it restarts is an opt-out that does not hold, and
|
|
33
|
+
* "telemetry stopped only after a reboot" is precisely the bug that destroys
|
|
34
|
+
* trust in a switch like this.
|
|
35
|
+
*
|
|
36
|
+
* The cost is a small `readFileSync` + TOML parse per event. That is affordable
|
|
37
|
+
* even on the hook path's 150ms fail-closed budget: the same `readConfig()` is
|
|
38
|
+
* already called there by `isDaemonConfigured()`, so this adds a repeat of work
|
|
39
|
+
* the path was already paying for, on a file of a few hundred bytes.
|
|
40
|
+
*/
|
|
41
|
+
export function isTelemetryEnabled(): boolean {
|
|
42
|
+
// Checked first, and cheaply: an env lookup costs nothing, and letting it
|
|
43
|
+
// short-circuit means an operator who exported the variable never pays for a
|
|
44
|
+
// file read at all.
|
|
45
|
+
if (process.env.FAILPROOFAI_TELEMETRY_DISABLED === "1") return false;
|
|
46
|
+
try {
|
|
47
|
+
return readConfig().telemetry.enabled;
|
|
48
|
+
} catch {
|
|
49
|
+
// readConfig already resolves an unreadable or malformed file to the
|
|
50
|
+
// defaults, so reaching here means something more unusual. Fall back to the
|
|
51
|
+
// shipped default rather than inventing a third answer.
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -3,6 +3,7 @@ import path from "node:path";
|
|
|
3
3
|
import os from "node:os";
|
|
4
4
|
import crypto from "node:crypto";
|
|
5
5
|
import { execSync } from "node:child_process";
|
|
6
|
+
import { telemetryIdFile } from "../src/hooks/fp-home";
|
|
6
7
|
|
|
7
8
|
const NAMESPACE = "failproofai-telemetry-v1";
|
|
8
9
|
const ID_DIR = path.join(os.homedir(), ".failproofai");
|
|
@@ -66,6 +67,52 @@ function getFileBasedId(): string {
|
|
|
66
67
|
return id;
|
|
67
68
|
}
|
|
68
69
|
|
|
70
|
+
/**
|
|
71
|
+
* Publish the resolved id where **failproofaid** can read it.
|
|
72
|
+
*
|
|
73
|
+
* The daemon cannot re-derive this. Tier 2 below hashes `os.arch()` and
|
|
74
|
+
* `os.cpus()[0].model`, which are Node's own formatting — Node says `x64` where
|
|
75
|
+
* Rust says `x86_64` — and a near-miss there does not fail, it silently files
|
|
76
|
+
* one machine under two different PostHog persons with nothing in the data to
|
|
77
|
+
* say so. So the CLI writes what it resolved and the daemon reads it
|
|
78
|
+
* (`telemetry_id_path()` in `crates/failproofaid/src/paths.rs`).
|
|
79
|
+
*
|
|
80
|
+
* Deliberately NOT gated on the telemetry opt-out. This sends nothing — it
|
|
81
|
+
* writes one anonymous HMAC to a local file — and gating it would mean a machine
|
|
82
|
+
* that opted out and later opted back in reported under a different identity
|
|
83
|
+
* until the next CLI run. The gate belongs on the sending, which is where both
|
|
84
|
+
* this process and the daemon apply it.
|
|
85
|
+
*
|
|
86
|
+
* Every failure is swallowed. This runs on the hook path, and a telemetry id
|
|
87
|
+
* that could not be published is worth exactly nothing next to a tool call that
|
|
88
|
+
* did not complete. The read-and-compare is what keeps the common case to one
|
|
89
|
+
* small `readFileSync` rather than a write per process.
|
|
90
|
+
*/
|
|
91
|
+
function publishInstanceId(id: string): void {
|
|
92
|
+
let target: string;
|
|
93
|
+
try {
|
|
94
|
+
target = telemetryIdFile();
|
|
95
|
+
if (fs.readFileSync(target, "utf-8").trim() === id) return;
|
|
96
|
+
} catch {
|
|
97
|
+
// Absent or unreadable — fall through and try to write it.
|
|
98
|
+
try {
|
|
99
|
+
target = telemetryIdFile();
|
|
100
|
+
} catch {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
try {
|
|
105
|
+
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
106
|
+
// tmp → rename, and the tmp name carries the pid: two CLI processes racing
|
|
107
|
+
// here is ordinary (every hook call resolves an id), and a shared temp name
|
|
108
|
+
// would let one truncate the file the other is renaming into place, leaving
|
|
109
|
+
// a torn id that the daemon would then adopt as a permanent, wrong person.
|
|
110
|
+
const tmp = `${target}.${process.pid}.tmp`;
|
|
111
|
+
fs.writeFileSync(tmp, id, { encoding: "utf-8", mode: 0o600 });
|
|
112
|
+
fs.renameSync(tmp, target);
|
|
113
|
+
} catch {}
|
|
114
|
+
}
|
|
115
|
+
|
|
69
116
|
/**
|
|
70
117
|
* Returns a stable, anonymous machine ID for telemetry.
|
|
71
118
|
*
|
|
@@ -75,7 +122,8 @@ function getFileBasedId(): string {
|
|
|
75
122
|
* 3. File-based random UUID at `~/.failproofai/instance-id` (final fallback)
|
|
76
123
|
*
|
|
77
124
|
* All raw values are HMAC-hashed with an app-specific namespace so no PII
|
|
78
|
-
* is transmitted. The result is cached in-process to avoid repeated I/O
|
|
125
|
+
* is transmitted. The result is cached in-process to avoid repeated I/O, and
|
|
126
|
+
* published once per process for the daemon (see `publishInstanceId`).
|
|
79
127
|
*/
|
|
80
128
|
export function getInstanceId(): string {
|
|
81
129
|
if (cachedId) return cachedId;
|
|
@@ -83,15 +131,18 @@ export function getInstanceId(): string {
|
|
|
83
131
|
const machineId = getPlatformMachineId();
|
|
84
132
|
if (machineId) {
|
|
85
133
|
cachedId = hashToId(machineId);
|
|
134
|
+
publishInstanceId(cachedId);
|
|
86
135
|
return cachedId;
|
|
87
136
|
}
|
|
88
137
|
|
|
89
138
|
const sysProps = getSystemPropertiesId();
|
|
90
139
|
if (sysProps) {
|
|
91
140
|
cachedId = hashToId(sysProps);
|
|
141
|
+
publishInstanceId(cachedId);
|
|
92
142
|
return cachedId;
|
|
93
143
|
}
|
|
94
144
|
|
|
95
145
|
cachedId = getFileBasedId();
|
|
146
|
+
publishInstanceId(cachedId);
|
|
96
147
|
return cachedId;
|
|
97
148
|
}
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import { getInstanceId } from "./telemetry-id";
|
|
12
|
+
import { isTelemetryEnabled } from "./telemetry-enabled";
|
|
12
13
|
import { version } from "../package.json";
|
|
13
14
|
import { POSTHOG_API_KEY, POSTHOG_PRODUCT } from "../src/posthog-key";
|
|
14
15
|
|
|
@@ -74,10 +75,13 @@ async function resilientFetch(
|
|
|
74
75
|
return new Response("{}", { status: 200 });
|
|
75
76
|
}
|
|
76
77
|
|
|
77
|
-
/**
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
78
|
+
/**
|
|
79
|
+
* Returns true unless the user has explicitly opted out, via either
|
|
80
|
+
* `FAILPROOFAI_TELEMETRY_DISABLED=1` or `[telemetry] enabled = false` in
|
|
81
|
+
* config.toml. Re-exported from the shared resolver so all four dispatchers
|
|
82
|
+
* cannot drift — see lib/telemetry-enabled.ts.
|
|
83
|
+
*/
|
|
84
|
+
export { isTelemetryEnabled };
|
|
81
85
|
|
|
82
86
|
/**
|
|
83
87
|
* Lazily import posthog-node and create a client.
|
|
@@ -1276,7 +1276,7 @@
|
|
|
1276
1276
|
exports.useTransition = function () {
|
|
1277
1277
|
return resolveDispatcher().useTransition();
|
|
1278
1278
|
};
|
|
1279
|
-
exports.version = "19.2.
|
|
1279
|
+
exports.version = "19.2.8";
|
|
1280
1280
|
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
|
|
1281
1281
|
"function" ===
|
|
1282
1282
|
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
"keywords": [
|
|
5
5
|
"react"
|
|
6
6
|
],
|
|
7
|
-
"version": "19.2.
|
|
7
|
+
"version": "19.2.8",
|
|
8
8
|
"homepage": "https://react.dev/",
|
|
9
|
-
"bugs": "https://github.com/
|
|
9
|
+
"bugs": "https://github.com/react/react/issues",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"files": [
|
|
12
12
|
"LICENSE",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
},
|
|
43
43
|
"repository": {
|
|
44
44
|
"type": "git",
|
|
45
|
-
"url": "https://github.com/
|
|
45
|
+
"url": "https://github.com/react/react.git",
|
|
46
46
|
"directory": "packages/react"
|
|
47
47
|
},
|
|
48
48
|
"engines": {
|
package/.next/standalone/node_modules/react-dom/cjs/react-dom-server-legacy.browser.production.js
CHANGED
|
@@ -6600,4 +6600,4 @@ exports.renderToString = function (children, options) {
|
|
|
6600
6600
|
'The server used "renderToString" which does not support Suspense. If you intended for this Suspense boundary to render the fallback content on the server consider throwing an Error somewhere within the Suspense boundary. If you intended to have the server wait for the suspended component please switch to "renderToReadableStream" which supports Suspense on the server'
|
|
6601
6601
|
);
|
|
6602
6602
|
};
|
|
6603
|
-
exports.version = "19.2.
|
|
6603
|
+
exports.version = "19.2.8";
|
package/.next/standalone/node_modules/react-dom/cjs/react-dom-server-legacy.node.production.js
CHANGED
|
@@ -6689,4 +6689,4 @@ exports.renderToString = function (children, options) {
|
|
|
6689
6689
|
'The server used "renderToString" which does not support Suspense. If you intended for this Suspense boundary to render the fallback content on the server consider throwing an Error somewhere within the Suspense boundary. If you intended to have the server wait for the suspended component please switch to "renderToPipeableStream" which supports Suspense on the server'
|
|
6690
6690
|
);
|
|
6691
6691
|
};
|
|
6692
|
-
exports.version = "19.2.
|
|
6692
|
+
exports.version = "19.2.8";
|
|
@@ -7147,12 +7147,12 @@ function getPostponedState(request) {
|
|
|
7147
7147
|
}
|
|
7148
7148
|
function ensureCorrectIsomorphicReactVersion() {
|
|
7149
7149
|
var isomorphicReactPackageVersion = React.version;
|
|
7150
|
-
if ("19.2.
|
|
7150
|
+
if ("19.2.8" !== isomorphicReactPackageVersion)
|
|
7151
7151
|
throw Error(
|
|
7152
7152
|
formatProdErrorMessage(
|
|
7153
7153
|
527,
|
|
7154
7154
|
isomorphicReactPackageVersion,
|
|
7155
|
-
"19.2.
|
|
7155
|
+
"19.2.8"
|
|
7156
7156
|
)
|
|
7157
7157
|
);
|
|
7158
7158
|
}
|
|
@@ -7407,4 +7407,4 @@ exports.resumeAndPrerender = function (children, postponedState, options) {
|
|
|
7407
7407
|
startWork(request);
|
|
7408
7408
|
});
|
|
7409
7409
|
};
|
|
7410
|
-
exports.version = "19.2.
|
|
7410
|
+
exports.version = "19.2.8";
|
|
@@ -7251,11 +7251,11 @@ function getPostponedState(request) {
|
|
|
7251
7251
|
}
|
|
7252
7252
|
function ensureCorrectIsomorphicReactVersion() {
|
|
7253
7253
|
var isomorphicReactPackageVersion = React.version;
|
|
7254
|
-
if ("19.2.
|
|
7254
|
+
if ("19.2.8" !== isomorphicReactPackageVersion)
|
|
7255
7255
|
throw Error(
|
|
7256
7256
|
'Incompatible React versions: The "react" and "react-dom" packages must have the exact same version. Instead got:\n - react: ' +
|
|
7257
7257
|
(isomorphicReactPackageVersion +
|
|
7258
|
-
"\n - react-dom: 19.2.
|
|
7258
|
+
"\n - react-dom: 19.2.8\nLearn more: https://react.dev/warnings/version-mismatch")
|
|
7259
7259
|
);
|
|
7260
7260
|
}
|
|
7261
7261
|
ensureCorrectIsomorphicReactVersion();
|
|
@@ -7509,4 +7509,4 @@ exports.resumeAndPrerender = function (children, postponedState, options) {
|
|
|
7509
7509
|
startWork(request);
|
|
7510
7510
|
});
|
|
7511
7511
|
};
|
|
7512
|
-
exports.version = "19.2.
|
|
7512
|
+
exports.version = "19.2.8";
|
|
@@ -7142,11 +7142,11 @@ function getPostponedState(request) {
|
|
|
7142
7142
|
}
|
|
7143
7143
|
function ensureCorrectIsomorphicReactVersion() {
|
|
7144
7144
|
var isomorphicReactPackageVersion = React.version;
|
|
7145
|
-
if ("19.2.
|
|
7145
|
+
if ("19.2.8" !== isomorphicReactPackageVersion)
|
|
7146
7146
|
throw Error(
|
|
7147
7147
|
'Incompatible React versions: The "react" and "react-dom" packages must have the exact same version. Instead got:\n - react: ' +
|
|
7148
7148
|
(isomorphicReactPackageVersion +
|
|
7149
|
-
"\n - react-dom: 19.2.
|
|
7149
|
+
"\n - react-dom: 19.2.8\nLearn more: https://react.dev/warnings/version-mismatch")
|
|
7150
7150
|
);
|
|
7151
7151
|
}
|
|
7152
7152
|
ensureCorrectIsomorphicReactVersion();
|
|
@@ -7704,4 +7704,4 @@ exports.resumeToPipeableStream = function (children, postponedState, options) {
|
|
|
7704
7704
|
}
|
|
7705
7705
|
};
|
|
7706
7706
|
};
|
|
7707
|
-
exports.version = "19.2.
|
|
7707
|
+
exports.version = "19.2.8";
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-dom",
|
|
3
|
-
"version": "19.2.
|
|
3
|
+
"version": "19.2.8",
|
|
4
4
|
"description": "React package for working with the DOM.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
|
-
"url": "https://github.com/
|
|
8
|
+
"url": "https://github.com/react/react.git",
|
|
9
9
|
"directory": "packages/react-dom"
|
|
10
10
|
},
|
|
11
11
|
"keywords": [
|
|
@@ -13,14 +13,14 @@
|
|
|
13
13
|
],
|
|
14
14
|
"license": "MIT",
|
|
15
15
|
"bugs": {
|
|
16
|
-
"url": "https://github.com/
|
|
16
|
+
"url": "https://github.com/react/react/issues"
|
|
17
17
|
},
|
|
18
18
|
"homepage": "https://react.dev/",
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"scheduler": "^0.27.0"
|
|
21
21
|
},
|
|
22
22
|
"peerDependencies": {
|
|
23
|
-
"react": "^19.2.
|
|
23
|
+
"react": "^19.2.8"
|
|
24
24
|
},
|
|
25
25
|
"files": [
|
|
26
26
|
"LICENSE",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "failproofai",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.21",
|
|
4
4
|
"description": "The easiest way to manage policies that keep your AI agents reliable, on-task, and running autonomously — for Claude Code & the Agents SDK",
|
|
5
5
|
"bin": {
|
|
6
6
|
"failproofai": "./dist/cli.mjs",
|
|
@@ -76,19 +76,19 @@
|
|
|
76
76
|
"@anthropic-ai/sdk": "^0.115.0",
|
|
77
77
|
"@mdx-js/mdx": "^3.1.1",
|
|
78
78
|
"@tailwindcss/postcss": "^4.3.1",
|
|
79
|
-
"@tanstack/react-virtual": "^3.14.
|
|
79
|
+
"@tanstack/react-virtual": "^3.14.9",
|
|
80
80
|
"@testing-library/jest-dom": "^7.0.0",
|
|
81
81
|
"@testing-library/react": "^16.3.2",
|
|
82
82
|
"@testing-library/user-event": "^14.6.1",
|
|
83
|
-
"@types/node": "26.1.
|
|
84
|
-
"@types/react": "19.2.
|
|
83
|
+
"@types/node": "26.1.2",
|
|
84
|
+
"@types/react": "19.2.18",
|
|
85
85
|
"@types/react-dom": "^19.2.3",
|
|
86
|
-
"@vitejs/plugin-react": "^6.0.
|
|
86
|
+
"@vitejs/plugin-react": "^6.0.5",
|
|
87
87
|
"clsx": "^2.1.1",
|
|
88
88
|
"eslint": "^10.5.0",
|
|
89
89
|
"eslint-config-next": "^16.2.9",
|
|
90
|
-
"jsdom": "^30.0.
|
|
91
|
-
"lucide-react": "^1.
|
|
90
|
+
"jsdom": "^30.0.1",
|
|
91
|
+
"lucide-react": "^1.28.0",
|
|
92
92
|
"next": "^16.2.11",
|
|
93
93
|
"react": "^19.2.4",
|
|
94
94
|
"react-dom": "^19.2.4",
|
|
@@ -99,17 +99,28 @@
|
|
|
99
99
|
},
|
|
100
100
|
"dependencies": {
|
|
101
101
|
"html-to-image": "^1.11.13",
|
|
102
|
-
"
|
|
103
|
-
"posthog-node": "^5.37.1",
|
|
102
|
+
"posthog-node": "^5.47.7",
|
|
104
103
|
"sql.js": "^1.14.1",
|
|
105
104
|
"yaml": "^2.9.0"
|
|
106
105
|
},
|
|
107
106
|
"overrides": {
|
|
108
|
-
"postcss": "8.5.
|
|
107
|
+
"postcss": "8.5.26",
|
|
109
108
|
"eslint-plugin-react-hooks": "7.0.1",
|
|
110
109
|
"vite": "8.0.16",
|
|
111
|
-
"undici": "7.
|
|
112
|
-
"brace-expansion": "5.0.
|
|
110
|
+
"undici": "7.29.0",
|
|
111
|
+
"brace-expansion": "5.0.9",
|
|
113
112
|
"sharp": "0.35.0"
|
|
113
|
+
},
|
|
114
|
+
"optionalDependencies": {
|
|
115
|
+
"@failproofai/failproofaid-linux-x64": "1.0.0-beta.21",
|
|
116
|
+
"@failproofai/failproofaid-linux-arm64": "1.0.0-beta.21",
|
|
117
|
+
"@failproofai/failproofaid-darwin-x64": "1.0.0-beta.21",
|
|
118
|
+
"@failproofai/failproofaid-darwin-arm64": "1.0.0-beta.21"
|
|
119
|
+
},
|
|
120
|
+
"failproofaidBinaries": {
|
|
121
|
+
"linux-x64": "78848fa69407c528ee9fea02bdd64c2f95aad6a84a4d3973780200c5644fe61c",
|
|
122
|
+
"linux-arm64": "eef4b4a435c44ba913610f213436bd34a873299ef774961a1af70cf76da934a2",
|
|
123
|
+
"darwin-x64": "abdfbdac60f06db20c69b11ff477123481622da3e03bd531e1896b8757ce0884",
|
|
124
|
+
"darwin-arm64": "49fc9dc590c38ece592aa46e734bb6c0743559e3dbb90996e8381056abb2f5da"
|
|
114
125
|
}
|
|
115
126
|
}
|