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
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Publishes the four `failproofaid` binaries as npm platform packages, so a
|
|
4
|
+
* plain `npm install failproofai` already carries the daemon for the machine
|
|
5
|
+
* it landed on instead of fetching one from the GitHub Release later.
|
|
6
|
+
*
|
|
7
|
+
* The release assets stay exactly as they are — this is a second channel, not
|
|
8
|
+
* a replacement. `src/hooks/daemon-download.ts` prefers whichever binary is
|
|
9
|
+
* already on disk, then this npm package, then the release; the npm path is
|
|
10
|
+
* the only one that works with no network at `failproofai config` time.
|
|
11
|
+
*
|
|
12
|
+
* Two rules make this safe, and both come from the way the first attempt at
|
|
13
|
+
* npm-shipping the daemon failed (CHANGELOG 1.0.0-beta.3 — four
|
|
14
|
+
* `optionalDependencies` were declared and never published, so every install
|
|
15
|
+
* resolved four 404s):
|
|
16
|
+
*
|
|
17
|
+
* 1. These packages publish BEFORE the root package that pins them, so the
|
|
18
|
+
* names always exist by the time anything depends on them.
|
|
19
|
+
* 2. A publish failure here is fatal, not a warning (unlike the alias stubs
|
|
20
|
+
* in publish-aliases.mjs, where a missing name costs nothing). Failing
|
|
21
|
+
* the job leaves the registry untouched; publishing a root package whose
|
|
22
|
+
* optional dependency 404s would ship the broken state to every user.
|
|
23
|
+
*
|
|
24
|
+
* Usage:
|
|
25
|
+
* node scripts/build-daemon-packages.mjs --artifacts <dir> [--dist-tag <tag>]
|
|
26
|
+
* [--version <v>] [--pin-root] [--dry-run]
|
|
27
|
+
*/
|
|
28
|
+
import { execFileSync } from "node:child_process";
|
|
29
|
+
import { createHash } from "node:crypto";
|
|
30
|
+
import { chmodSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
31
|
+
import { tmpdir } from "node:os";
|
|
32
|
+
import { dirname, join, resolve } from "node:path";
|
|
33
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
34
|
+
import { gunzipSync } from "node:zlib";
|
|
35
|
+
import {
|
|
36
|
+
DAEMON_PLATFORMS,
|
|
37
|
+
daemonAssetName,
|
|
38
|
+
daemonOptionalDependencies,
|
|
39
|
+
daemonPackageName,
|
|
40
|
+
} from "./daemon-platforms.mjs";
|
|
41
|
+
|
|
42
|
+
const REPO_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Where the generated packages are staged — **outside the repo**, and that is
|
|
46
|
+
* load-bearing rather than tidy.
|
|
47
|
+
*
|
|
48
|
+
* `npm publish` re-runs `prepare`, so the Next build happens again *after*
|
|
49
|
+
* this script has run, and Next's file tracing pulls the whole project root
|
|
50
|
+
* into `.next/standalone` (see the "over-traced project artifacts" prune list
|
|
51
|
+
* in scripts/prune-standalone.mjs). Anything staged inside the checkout
|
|
52
|
+
* therefore ends up inside the published CLI tarball — measured: a dry run
|
|
53
|
+
* shipped 16 MB of daemon `.gz` assets under
|
|
54
|
+
* `.next/standalone/release-assets/`. Staging in the temp dir cannot be swept
|
|
55
|
+
* up by a build. `--staging` overrides it for tests.
|
|
56
|
+
*/
|
|
57
|
+
export const STAGING_DIR = resolve(tmpdir(), "failproofaid-packages");
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* The manifest for one platform package.
|
|
61
|
+
*
|
|
62
|
+
* Deliberately carries no `bin` (it would shadow the root package's own
|
|
63
|
+
* `failproofaid` shim, which is what a user invoking the daemon by hand
|
|
64
|
+
* should reach) and no `exports` (so `require.resolve("<pkg>/package.json")`
|
|
65
|
+
* — how the CLI finds this package — keeps working).
|
|
66
|
+
*/
|
|
67
|
+
export function platformPackageManifest(platform, version, rootPkg = {}) {
|
|
68
|
+
return {
|
|
69
|
+
name: daemonPackageName(platform.key),
|
|
70
|
+
version,
|
|
71
|
+
description: `The failproofaid background daemon binary for ${platform.os} ${platform.cpu}. Installed automatically as an optional dependency of failproofai.`,
|
|
72
|
+
// npm's own platform filters: with both set, only the matching package is
|
|
73
|
+
// installed and the other three are skipped without a warning.
|
|
74
|
+
os: [platform.os],
|
|
75
|
+
cpu: [platform.cpu],
|
|
76
|
+
files: ["bin/"],
|
|
77
|
+
publishConfig: { access: "public" },
|
|
78
|
+
repository: rootPkg.repository,
|
|
79
|
+
homepage: rootPkg.homepage,
|
|
80
|
+
bugs: rootPkg.bugs,
|
|
81
|
+
license: rootPkg.license,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Stages one platform package on disk and returns its directory.
|
|
87
|
+
*
|
|
88
|
+
* The binary is written decompressed and mode 0755: npm records the executable
|
|
89
|
+
* bit in the tarball, so it survives publish → install, which is how esbuild
|
|
90
|
+
* and swc ship their binaries.
|
|
91
|
+
*/
|
|
92
|
+
export function stagePlatformPackage(platform, version, rootPkg, artifactsDir, stagingRoot = STAGING_DIR) {
|
|
93
|
+
const asset = resolve(artifactsDir, daemonAssetName(platform.key));
|
|
94
|
+
if (!existsSync(asset)) {
|
|
95
|
+
throw new Error(`missing artifact ${asset} — the daemon build did not produce ${daemonAssetName(platform.key)}`);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const dir = join(stagingRoot, `failproofaid-${platform.key}`);
|
|
99
|
+
rmSync(dir, { recursive: true, force: true });
|
|
100
|
+
mkdirSync(join(dir, "bin"), { recursive: true });
|
|
101
|
+
|
|
102
|
+
const binary = gunzipSync(readFileSync(asset));
|
|
103
|
+
const binaryPath = join(dir, "bin", "failproofaid");
|
|
104
|
+
writeFileSync(binaryPath, binary);
|
|
105
|
+
chmodSync(binaryPath, 0o755);
|
|
106
|
+
|
|
107
|
+
writeFileSync(
|
|
108
|
+
join(dir, "package.json"),
|
|
109
|
+
JSON.stringify(platformPackageManifest(platform, version, rootPkg), null, 2) + "\n",
|
|
110
|
+
);
|
|
111
|
+
writeFileSync(
|
|
112
|
+
join(dir, "README.md"),
|
|
113
|
+
`# ${daemonPackageName(platform.key)}\n\n` +
|
|
114
|
+
`The \`failproofaid\` background daemon binary for ${platform.os} ${platform.cpu}.\n\n` +
|
|
115
|
+
`Installed automatically as an optional dependency of [failproofai](https://www.npmjs.com/package/failproofai) — ` +
|
|
116
|
+
`you do not need to install it yourself.\n`,
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
return dir;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* The SHA-256 of the binary inside a staged platform package.
|
|
124
|
+
*
|
|
125
|
+
* Read back off disk rather than returned from `stagePlatformPackage` so that
|
|
126
|
+
* function's contract stays a plain directory path, and so the digest describes
|
|
127
|
+
* the bytes that will actually be packed — not an in-memory buffer that was
|
|
128
|
+
* supposed to become them.
|
|
129
|
+
*/
|
|
130
|
+
export function stagedBinaryDigest(dir) {
|
|
131
|
+
return createHash("sha256")
|
|
132
|
+
.update(readFileSync(join(dir, "bin", "failproofaid")))
|
|
133
|
+
.digest("hex");
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Writes the four platform packages into the root manifest's
|
|
138
|
+
* `optionalDependencies`, pinned to `version`.
|
|
139
|
+
*
|
|
140
|
+
* Called at publish time rather than committed: a pin to a version that does
|
|
141
|
+
* not exist yet breaks `bun install --frozen-lockfile` in this repo's own CI,
|
|
142
|
+
* and keeping four pins in step with every version bump by hand is the drift
|
|
143
|
+
* this whole file exists to avoid.
|
|
144
|
+
*
|
|
145
|
+
* @param {string} version
|
|
146
|
+
* @param {string} [packageJsonPath]
|
|
147
|
+
* @param {Record<string, string> | null} [digests] platform key → SHA-256 of
|
|
148
|
+
* that platform's staged binary. Omitted leaves the key ABSENT, which
|
|
149
|
+
* `expectedNpmBinaryDigest` reads as "nothing to compare against".
|
|
150
|
+
*/
|
|
151
|
+
export function pinRootManifest(version, packageJsonPath = resolve(REPO_ROOT, "package.json"), digests = null) {
|
|
152
|
+
const pkg = JSON.parse(readFileSync(packageJsonPath, "utf8"));
|
|
153
|
+
pkg.optionalDependencies = { ...pkg.optionalDependencies, ...daemonOptionalDependencies(version) };
|
|
154
|
+
// The SHA-256 of each binary as it was staged, recorded in the ROOT manifest
|
|
155
|
+
// so `installFromNpmPackage` has something to check the file it copies
|
|
156
|
+
// against. The download channel has verified against `SHA256SUMS` since it
|
|
157
|
+
// existed; the npm channel had no integrity step of any kind, and it installs
|
|
158
|
+
// its result as a root-owned, boot-persistent system service.
|
|
159
|
+
//
|
|
160
|
+
// Written here rather than into each platform package because a digest
|
|
161
|
+
// shipped alongside the bytes it describes verifies nothing. This one travels
|
|
162
|
+
// in a different package, published separately, and `bun build` INLINES it
|
|
163
|
+
// into dist/cli.mjs — so it is not merely a second file in the same tree.
|
|
164
|
+
if (digests) pkg.failproofaidBinaries = digests;
|
|
165
|
+
writeFileSync(packageJsonPath, JSON.stringify(pkg, null, 2) + "\n");
|
|
166
|
+
return pkg.optionalDependencies;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function parseArgs(argv) {
|
|
170
|
+
const valueOf = (flag, fallback) => {
|
|
171
|
+
const index = argv.indexOf(flag);
|
|
172
|
+
return index !== -1 && argv[index + 1] ? argv[index + 1] : fallback;
|
|
173
|
+
};
|
|
174
|
+
return {
|
|
175
|
+
artifacts: valueOf("--artifacts", "release-assets"),
|
|
176
|
+
staging: valueOf("--staging", STAGING_DIR),
|
|
177
|
+
distTag: valueOf("--dist-tag", null),
|
|
178
|
+
version: valueOf("--version", null),
|
|
179
|
+
pinRoot: argv.includes("--pin-root"),
|
|
180
|
+
dryRun: argv.includes("--dry-run"),
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* `npm publish`, with provenance when the registry will take it.
|
|
186
|
+
*
|
|
187
|
+
* Provenance needs a supported CI and a repository field npm can match to the
|
|
188
|
+
* building workflow; when it refuses, the publish itself is still correct, so
|
|
189
|
+
* this retries once without the flag rather than failing the release.
|
|
190
|
+
*/
|
|
191
|
+
function publishPackage(dir, distTag, dryRun) {
|
|
192
|
+
const args = ["publish", "--tag", distTag];
|
|
193
|
+
if (dryRun) args.push("--dry-run");
|
|
194
|
+
|
|
195
|
+
const attempt = (extra) =>
|
|
196
|
+
execFileSync("npm", [...args, ...extra], { cwd: dir, stdio: "pipe", encoding: "utf8" });
|
|
197
|
+
|
|
198
|
+
const withProvenance = !dryRun && process.env.GITHUB_ACTIONS === "true";
|
|
199
|
+
try {
|
|
200
|
+
return attempt(withProvenance ? ["--provenance"] : []);
|
|
201
|
+
} catch (err) {
|
|
202
|
+
const output = (err.stdout ?? "") + (err.stderr ?? "");
|
|
203
|
+
if (output.includes("cannot publish over")) return "[skip] already published at this version";
|
|
204
|
+
if (withProvenance && /provenance/i.test(output)) {
|
|
205
|
+
console.log("::warning::provenance was rejected — retrying the publish without it");
|
|
206
|
+
return attempt([]);
|
|
207
|
+
}
|
|
208
|
+
// Fatal on purpose: see the header. The root package pins these names, so
|
|
209
|
+
// a half-published set must stop the release rather than ship 404s.
|
|
210
|
+
throw new Error(`npm publish failed for ${dir}:\n${output.trim()}`);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export function main(argv = process.argv.slice(2)) {
|
|
215
|
+
const options = parseArgs(argv);
|
|
216
|
+
const rootPkg = JSON.parse(readFileSync(resolve(REPO_ROOT, "package.json"), "utf8"));
|
|
217
|
+
const version = options.version ?? rootPkg.version;
|
|
218
|
+
const distTag = options.distTag ?? (version.includes("-") ? "beta" : "latest");
|
|
219
|
+
const artifactsDir = resolve(process.cwd(), options.artifacts);
|
|
220
|
+
|
|
221
|
+
console.log(
|
|
222
|
+
`Publishing ${DAEMON_PLATFORMS.length} failproofaid platform packages at ${version} ` +
|
|
223
|
+
`(tag: ${distTag}${options.dryRun ? ", dry run" : ""}) from ${artifactsDir}`,
|
|
224
|
+
);
|
|
225
|
+
|
|
226
|
+
const digests = {};
|
|
227
|
+
for (const platform of DAEMON_PLATFORMS) {
|
|
228
|
+
const dir = stagePlatformPackage(platform, version, rootPkg, artifactsDir, options.staging);
|
|
229
|
+
const sha256 = stagedBinaryDigest(dir);
|
|
230
|
+
digests[platform.key] = sha256;
|
|
231
|
+
const name = daemonPackageName(platform.key);
|
|
232
|
+
console.log(`\n${name}@${version} sha256:${sha256}`);
|
|
233
|
+
console.log(publishPackage(dir, distTag, options.dryRun).trim());
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
if (options.pinRoot) {
|
|
237
|
+
const pins = pinRootManifest(version, resolve(REPO_ROOT, "package.json"), digests);
|
|
238
|
+
console.log("\nPinned in the root manifest's optionalDependencies:");
|
|
239
|
+
console.log(JSON.stringify(pins, null, 2));
|
|
240
|
+
console.log("\nRecorded binary digests (failproofaidBinaries):");
|
|
241
|
+
console.log(JSON.stringify(digests, null, 2));
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
|
|
246
|
+
main();
|
|
247
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The platforms `failproofaid` is cross-compiled for, and the npm packages
|
|
3
|
+
* those binaries publish under.
|
|
4
|
+
*
|
|
5
|
+
* One list, three consumers: `build-daemon-packages.mjs` (publishes them),
|
|
6
|
+
* `publish-aliases.mjs` (pins them in every typo-squat stub), and the root
|
|
7
|
+
* package's injected `optionalDependencies`. They have to agree exactly — a
|
|
8
|
+
* name that appears in a dependency but never gets published is a 404 in
|
|
9
|
+
* every install, which is precisely how the first attempt at npm-shipping the
|
|
10
|
+
* daemon failed (see CHANGELOG 1.0.0-beta.3).
|
|
11
|
+
*
|
|
12
|
+
* `os` / `cpu` are npm's own filters, spelled in `process.platform` /
|
|
13
|
+
* `process.arch` values: with both set, npm and bun install only the package
|
|
14
|
+
* matching the machine and silently skip the other three.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
export const DAEMON_PLATFORMS = [
|
|
18
|
+
{ key: "linux-x64", os: "linux", cpu: "x64" },
|
|
19
|
+
{ key: "linux-arm64", os: "linux", cpu: "arm64" },
|
|
20
|
+
{ key: "darwin-x64", os: "darwin", cpu: "x64" },
|
|
21
|
+
{ key: "darwin-arm64", os: "darwin", cpu: "arm64" },
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
/** The npm package name carrying the binary for one platform key. */
|
|
25
|
+
export function daemonPackageName(key) {
|
|
26
|
+
return `@failproofai/failproofaid-${key}`;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** The release asset the binary for one platform key arrives in. */
|
|
30
|
+
export function daemonAssetName(key) {
|
|
31
|
+
return `failproofaid-${key}.gz`;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* The `optionalDependencies` block that pins all four platform packages to one
|
|
36
|
+
* version — what the root package and every alias stub carry when published.
|
|
37
|
+
*/
|
|
38
|
+
export function daemonOptionalDependencies(version) {
|
|
39
|
+
return Object.fromEntries(
|
|
40
|
+
DAEMON_PLATFORMS.map((platform) => [daemonPackageName(platform.key), version]),
|
|
41
|
+
);
|
|
42
|
+
}
|
package/scripts/dev-hook.mjs
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* End users never run this. They install `npx -y failproofai --hook <Event>`
|
|
6
6
|
* (see `src/hooks/integrations.ts`), which resolves the published package.
|
|
7
7
|
* This file exists because this repo dogfoods itself from source, and doing so
|
|
8
|
-
* has
|
|
8
|
+
* has three prerequisites that silently rot:
|
|
9
9
|
*
|
|
10
10
|
* 1. `bun` on the hook's PATH. `bin/failproofai.mjs` cannot run under node —
|
|
11
11
|
* it does a bare `import { version } from "../package.json"` (node needs
|
|
@@ -17,13 +17,17 @@
|
|
|
17
17
|
* When that happens every hook exits 127 and the session runs with ZERO
|
|
18
18
|
* policy enforcement — silently.
|
|
19
19
|
*
|
|
20
|
-
* 2.
|
|
20
|
+
* 2. Project dependencies. A fresh checkout has no `node_modules`, so the
|
|
21
|
+
* source binary cannot import its runtime dependencies. The launcher
|
|
22
|
+
* runs the lockfile-pinned install once before attempting enforcement.
|
|
23
|
+
*
|
|
24
|
+
* 3. `dist/index.js`. The committed policies in `.failproofai/policies/`
|
|
21
25
|
* `import from 'failproofai'`, which `findDistIndex()` resolves to that
|
|
22
26
|
* bundle. Without it all three fail-open and only builtins enforce.
|
|
23
27
|
*
|
|
24
|
-
* So: locate bun (installing it via npm if we must),
|
|
25
|
-
* exists, then hand off to the real binary.
|
|
26
|
-
* one line rather than failing silently.
|
|
28
|
+
* So: locate bun (installing it via npm if we must), install this checkout's
|
|
29
|
+
* dependencies, make sure the bundle exists, then hand off to the real binary.
|
|
30
|
+
* If we cannot enforce, say so in one line rather than failing silently.
|
|
27
31
|
*
|
|
28
32
|
* INVARIANT — never write to stdout. Most CLIs' deny contracts are JSON on
|
|
29
33
|
* stdout (Copilot `{decision:"block"}`, Cursor `{followup_message}`, Devin,
|
|
@@ -43,6 +47,11 @@ const SRC_BIN = resolve(REPO_ROOT, "bin", "failproofai.mjs");
|
|
|
43
47
|
const BUNDLE = resolve(REPO_ROOT, "dist", "index.js");
|
|
44
48
|
const CACHE_DIR = resolve(REPO_ROOT, "node_modules", ".cache", "failproofai-dev");
|
|
45
49
|
const LOCK_DIR = join(CACHE_DIR, ".lock");
|
|
50
|
+
const DEPENDENCY_SENTINELS = [
|
|
51
|
+
resolve(REPO_ROOT, "node_modules", "posthog-node", "package.json"),
|
|
52
|
+
resolve(REPO_ROOT, "node_modules", "sql.js", "package.json"),
|
|
53
|
+
resolve(REPO_ROOT, "node_modules", "yaml", "package.json"),
|
|
54
|
+
];
|
|
46
55
|
|
|
47
56
|
/** A lock older than this belonged to a process that died mid-install. */
|
|
48
57
|
const LOCK_STALE_MS = 5 * 60_000;
|
|
@@ -58,6 +67,7 @@ const LOCK_WAIT_MS = 250;
|
|
|
58
67
|
* @property {string} [home]
|
|
59
68
|
* @property {(p: string) => boolean} [exists]
|
|
60
69
|
* @property {(p: string) => string[]} [readdir]
|
|
70
|
+
* @property {typeof spawnSync} [spawn]
|
|
61
71
|
*/
|
|
62
72
|
|
|
63
73
|
function warn(msg) {
|
|
@@ -167,6 +177,16 @@ export function bunMissingMessage() {
|
|
|
167
177
|
);
|
|
168
178
|
}
|
|
169
179
|
|
|
180
|
+
/**
|
|
181
|
+
* A cheap every-hook check for the runtime dependencies the source hook path
|
|
182
|
+
* imports. Requiring several direct dependencies also catches interrupted or
|
|
183
|
+
* partial installs instead of treating any non-empty node_modules as ready.
|
|
184
|
+
*/
|
|
185
|
+
export function projectDependenciesInstalled(deps = {}) {
|
|
186
|
+
const exists = deps.exists ?? existsSync;
|
|
187
|
+
return DEPENDENCY_SENTINELS.every((path) => exists(path));
|
|
188
|
+
}
|
|
189
|
+
|
|
170
190
|
/**
|
|
171
191
|
* Run `doWork` at most once across concurrently-firing hooks. `mkdirSync` is
|
|
172
192
|
* atomic, so it doubles as the lock: EEXIST means another process got there.
|
|
@@ -233,6 +253,26 @@ function installBun(deps = {}) {
|
|
|
233
253
|
return findBun(deps);
|
|
234
254
|
}
|
|
235
255
|
|
|
256
|
+
/** Install a fresh/partial checkout from the committed lockfile, once. */
|
|
257
|
+
export function ensureProjectDependencies(bunPath, deps = {}) {
|
|
258
|
+
const run = deps.spawn ?? spawnSync;
|
|
259
|
+
return ensureOnce(
|
|
260
|
+
() => projectDependenciesInstalled(deps),
|
|
261
|
+
() => {
|
|
262
|
+
warn("project dependencies missing — running bun install (one time)");
|
|
263
|
+
const r = run(bunPath, ["install", "--frozen-lockfile"], {
|
|
264
|
+
// Installation/build output is not hook protocol output. Keep stdout
|
|
265
|
+
// clean, but expose errors so a broken bootstrap is actionable.
|
|
266
|
+
stdio: ["ignore", "ignore", "inherit"],
|
|
267
|
+
cwd: REPO_ROOT,
|
|
268
|
+
});
|
|
269
|
+
if (r.status !== 0) {
|
|
270
|
+
warn("bun install failed — hooks are NOT enforcing; see the error above");
|
|
271
|
+
}
|
|
272
|
+
},
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
|
|
236
276
|
/**
|
|
237
277
|
* Build dist/index.js if absent, so `.failproofai/policies/*.mjs` can resolve
|
|
238
278
|
* `import ... from 'failproofai'`. Non-fatal: builtins enforce without it.
|
|
@@ -258,6 +298,7 @@ function main() {
|
|
|
258
298
|
warn(bunMissingMessage());
|
|
259
299
|
process.exit(1);
|
|
260
300
|
}
|
|
301
|
+
if (!ensureProjectDependencies(bun)) process.exit(1);
|
|
261
302
|
ensureBundle(bun);
|
|
262
303
|
|
|
263
304
|
// stdio:"inherit" hands the child our actual fds: the payload on stdin and
|
|
@@ -86,12 +86,19 @@ function getInstanceId() {
|
|
|
86
86
|
* fire from the CLI (see lib/install-check.ts) because package managers block
|
|
87
87
|
* install scripts by default.
|
|
88
88
|
*
|
|
89
|
+
* `opts.enabled` carries the resolved answer from lib/telemetry-enabled.ts. This
|
|
90
|
+
* file is a dependency-free .mjs so that it can run with no node_modules, which
|
|
91
|
+
* also means it cannot import the TOML config — so the caller, which can, passes
|
|
92
|
+
* the verdict in. Without it `[telemetry] enabled = false` would silence three
|
|
93
|
+
* dispatchers out of four and this one would keep reporting.
|
|
94
|
+
*
|
|
89
95
|
* @param {string} event
|
|
90
96
|
* @param {Record<string, unknown>} [properties]
|
|
91
|
-
* @param {{ version?: string, timeoutMs?: number }} [opts]
|
|
97
|
+
* @param {{ version?: string, timeoutMs?: number, enabled?: boolean }} [opts]
|
|
92
98
|
*/
|
|
93
99
|
export async function trackInstallEvent(event, properties = {}, opts = {}) {
|
|
94
100
|
if (process.env.FAILPROOFAI_TELEMETRY_DISABLED === "1") return;
|
|
101
|
+
if (opts.enabled === false) return;
|
|
95
102
|
|
|
96
103
|
const version = opts.version ?? process.env.npm_package_version ?? "unknown";
|
|
97
104
|
const body = JSON.stringify({
|
package/scripts/launch.ts
CHANGED
|
@@ -10,22 +10,40 @@ import { parseScriptArgs } from "./parse-script-args";
|
|
|
10
10
|
import { diagnoseShadow } from "./install-diagnosis.mjs";
|
|
11
11
|
import { makeSkewLogFilter } from "./skew-log-filter";
|
|
12
12
|
import { renderLaunchBanner } from "../src/hooks/tui";
|
|
13
|
+
import { isLoopbackHostname, resolveDashboardHost } from "../lib/dashboard-host";
|
|
13
14
|
import { version } from "../package.json";
|
|
14
15
|
|
|
15
16
|
export function launch(mode: "dev" | "start"): void {
|
|
16
|
-
const { loggingLevel, disableTelemetry, allowedDevOrigins, remainingArgs } = parseScriptArgs(process.argv.slice(2));
|
|
17
|
+
const { loggingLevel, disableTelemetry, allowedDevOrigins, host, remainingArgs } = parseScriptArgs(process.argv.slice(2));
|
|
17
18
|
|
|
18
19
|
// Branded splash — the same logomark + palette as the `configure` wizard, then
|
|
19
20
|
// a tidy version/links column. Falls back to plain text off a TTY.
|
|
20
21
|
for (const line of renderLaunchBanner(version)) console.log(line);
|
|
21
22
|
|
|
23
|
+
// The dashboard has no authentication and can toggle policies and uninstall
|
|
24
|
+
// hooks from every agent CLI, so it binds loopback unless someone asks
|
|
25
|
+
// otherwise. It used to bind 0.0.0.0 unconditionally, which handed all of
|
|
26
|
+
// that to every peer on the network.
|
|
27
|
+
const bindHost = resolveDashboardHost(host, process.env.FAILPROOFAI_DASHBOARD_HOST);
|
|
28
|
+
if (!isLoopbackHostname(bindHost)) {
|
|
29
|
+
console.warn(
|
|
30
|
+
`\n! Binding the dashboard to ${bindHost}, which is reachable from outside this machine.\n` +
|
|
31
|
+
` It has no authentication: anyone who can reach it can read your session\n` +
|
|
32
|
+
` transcripts, disable your policies, and uninstall failproofai's hooks.\n`,
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
// Read back by proxy.ts, which refuses any request whose Host is not one it
|
|
36
|
+
// should be answering to — the layer that stops DNS rebinding, which a
|
|
37
|
+
// loopback bind alone does not.
|
|
38
|
+
process.env.FAILPROOFAI_DASHBOARD_HOST = bindHost;
|
|
39
|
+
|
|
22
40
|
let cmd: string;
|
|
23
41
|
let cmdArgs: string[];
|
|
24
42
|
if (mode === "start") {
|
|
25
43
|
const portIdx = remainingArgs.indexOf("--port");
|
|
26
44
|
const port = portIdx >= 0 ? remainingArgs[portIdx + 1] : "8020";
|
|
27
45
|
process.env.PORT = port;
|
|
28
|
-
process.env.HOSTNAME =
|
|
46
|
+
process.env.HOSTNAME = bindHost;
|
|
29
47
|
cmd = "node";
|
|
30
48
|
// Resolve the real package root via realpathSync so symlinked npm global binaries
|
|
31
49
|
// don't cause import.meta.url to point at the symlink dir instead of the package dir.
|
|
@@ -74,7 +92,11 @@ export function launch(mode: "dev" | "start"): void {
|
|
|
74
92
|
cmdArgs = [serverJsPath];
|
|
75
93
|
} else {
|
|
76
94
|
cmd = "bunx";
|
|
77
|
-
|
|
95
|
+
// `next dev` with no -H listens on every interface too, so dev gets the same
|
|
96
|
+
// default. Skipped when the caller already passed one through, so an
|
|
97
|
+
// explicit -H in remainingArgs still wins.
|
|
98
|
+
const hasHostFlag = remainingArgs.some((a) => a === "-H" || a === "--hostname" || a.startsWith("--hostname="));
|
|
99
|
+
cmdArgs = ["--bun", "next", "dev", ...(hasHostFlag ? [] : ["-H", bindHost]), ...remainingArgs];
|
|
78
100
|
}
|
|
79
101
|
|
|
80
102
|
// In `start` (the shipped standalone server) we pipe + filter the child's
|
|
@@ -7,6 +7,13 @@ export interface ParsedScriptArgs {
|
|
|
7
7
|
loggingLevel: string | undefined;
|
|
8
8
|
disableTelemetry: boolean;
|
|
9
9
|
allowedDevOrigins: string[] | undefined;
|
|
10
|
+
/**
|
|
11
|
+
* Interface to bind the dashboard to. Undefined means the safe default
|
|
12
|
+
* (loopback) — see `resolveDashboardHost` in launch.ts. Only set this to a
|
|
13
|
+
* non-loopback address deliberately: the dashboard has no authentication and
|
|
14
|
+
* is a WRITE surface for this machine's security configuration.
|
|
15
|
+
*/
|
|
16
|
+
host: string | undefined;
|
|
10
17
|
remainingArgs: string[];
|
|
11
18
|
}
|
|
12
19
|
|
|
@@ -32,6 +39,7 @@ export function parseScriptArgs(argv: string[]): ParsedScriptArgs {
|
|
|
32
39
|
let loggingLevel: string | undefined;
|
|
33
40
|
let disableTelemetry = false;
|
|
34
41
|
let allowedDevOrigins: string[] | undefined;
|
|
42
|
+
let host: string | undefined;
|
|
35
43
|
|
|
36
44
|
for (let i = 0; i < args.length; i++) {
|
|
37
45
|
const arg = args[i];
|
|
@@ -71,7 +79,25 @@ export function parseScriptArgs(argv: string[]): ParsedScriptArgs {
|
|
|
71
79
|
i--;
|
|
72
80
|
continue;
|
|
73
81
|
}
|
|
82
|
+
|
|
83
|
+
// `-H` / `--hostname` are Next's own spellings of this, and `bun run dev`
|
|
84
|
+
// passes unrecognised arguments straight through to `next dev`. Capturing
|
|
85
|
+
// only `--host` meant a raw `-H 0.0.0.0` fell into `remainingArgs`: Next
|
|
86
|
+
// bound the wildcard, while `bindHost` kept the loopback default and
|
|
87
|
+
// `FAILPROOFAI_DASHBOARD_HOST=127.0.0.1` told `proxy.ts` it was on
|
|
88
|
+
// loopback. It then enforced a Host-header pin — which a raw network
|
|
89
|
+
// client forges trivially, unlike a browser — against a server genuinely
|
|
90
|
+
// reachable from the network, and skipped the no-Origin refusal that is
|
|
91
|
+
// the real defence for that bind. The two must agree, so all three
|
|
92
|
+
// spellings resolve to the same value.
|
|
93
|
+
if (flag === "--host" || flag === "-H" || flag === "--hostname") {
|
|
94
|
+
const { value, spliceCount } = parseStringFlag(flag, "an address to bind (e.g. 127.0.0.1)", inlineValue, args, i);
|
|
95
|
+
host = value;
|
|
96
|
+
args.splice(i, spliceCount);
|
|
97
|
+
i--;
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
74
100
|
}
|
|
75
101
|
|
|
76
|
-
return { loggingLevel, disableTelemetry, allowedDevOrigins, remainingArgs: args };
|
|
102
|
+
return { loggingLevel, disableTelemetry, allowedDevOrigins, host, remainingArgs: args };
|
|
77
103
|
}
|
|
@@ -101,6 +101,24 @@ const STANDALONE_ROOT_PRUNE = [
|
|
|
101
101
|
".claude", ".failproofai", ".github", ".vscode", ".idea",
|
|
102
102
|
// Failproofai CLI artifacts — the dashboard never loads these
|
|
103
103
|
"bin", "dist", "scripts", "src",
|
|
104
|
+
// Release-pipeline scratch: the daemon binaries downloaded from the build
|
|
105
|
+
// matrix and the staged platform packages. Both are written into the
|
|
106
|
+
// workspace only by a local/manual run (the publish workflow keeps them in
|
|
107
|
+
// RUNNER_TEMP precisely so this cannot happen), and 16 MB of `.gz` shipped
|
|
108
|
+
// inside the CLI tarball once already because nothing pruned them.
|
|
109
|
+
"release-assets", ".daemon-packages",
|
|
110
|
+
// The Rust workspace. `target/` is the big one: on any machine that has run
|
|
111
|
+
// `cargo build`, NFT traces it into the standalone output and it is FIFTEEN
|
|
112
|
+
// GIGABYTES of compiled artifacts — `npm pack` then hangs trying to tar it,
|
|
113
|
+
// which is how this was found. CI has not hit it because the Rust jobs build
|
|
114
|
+
// in a separate workspace, so nothing caught it; a contributor who builds the
|
|
115
|
+
// daemon and then the package hits it every time. The dashboard is a Next
|
|
116
|
+
// server — it never reads any of this.
|
|
117
|
+
"target", "crates",
|
|
118
|
+
// Test/dev trees NFT also over-traces. `integration-suite` is a harness, the
|
|
119
|
+
// plugin/extension dirs are shipped from the package root by `files`, not
|
|
120
|
+
// from inside the standalone bundle.
|
|
121
|
+
"integration-suite", "pi-extension", "openclaw-plugin", "docker-hook-sync",
|
|
104
122
|
];
|
|
105
123
|
const STANDALONE_ROOT_PRUNE_FILES = [
|
|
106
124
|
// Top-level markdown / licenses / docs
|
|
@@ -111,6 +129,14 @@ const STANDALONE_ROOT_PRUNE_FILES = [
|
|
|
111
129
|
"vitest.config.mts", "vitest.config.e2e.mts",
|
|
112
130
|
// Lockfiles
|
|
113
131
|
"bun.lock", "bun.lockb", "package-lock.json", "yarn.lock",
|
|
132
|
+
// Rust workspace manifests, siblings of the `target`/`crates` prune above.
|
|
133
|
+
"Cargo.toml", "Cargo.lock", "rust-toolchain.toml", "osv-scanner.toml",
|
|
134
|
+
// 11 MB README animation. Traced because it sits in the repo root and is
|
|
135
|
+
// referenced from README.md; the running dashboard never serves it.
|
|
136
|
+
"readme-arch-hq.gif",
|
|
137
|
+
// Incremental typechecker state — regenerated on every build, read by nothing
|
|
138
|
+
// at runtime, and routinely a few hundred KB.
|
|
139
|
+
"tsconfig.tsbuildinfo", "next-env.d.ts", "postcss.config.mjs",
|
|
114
140
|
];
|
|
115
141
|
for (const d of STANDALONE_ROOT_PRUNE) {
|
|
116
142
|
rmSync(join(STANDALONE, d), { recursive: true, force: true });
|