failproofai 1.0.0-beta.4 → 1.0.0-beta.6
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 +3 -3
- 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/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/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 +2 -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/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/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/server-reference-manifest.json +10 -10
- package/.next/standalone/.next/server/app/policies/page.js +4 -2
- 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/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/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/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]__1nl3dvw._.js → [externals]__0r-zamh._.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]__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]__0g0vcwt._.js +3 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0h3lfmp._.js → [root-of-the-server]__0ky_n0r._.js} +2 -2
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__18d-9oi._.js → [root-of-the-server]__0lk_935._.js} +2 -2
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__1p7s8-d._.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]__10oa-v9._.js → [root-of-the-server]__0v2fpxe._.js} +2 -2
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0sb_5m8._.js → [root-of-the-server]__131ebum._.js} +3 -3
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0-dh5jy._.js → [root-of-the-server]__1_ps0jw._.js} +2 -2
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0l4vuqm._.js → [root-of-the-server]__1a7i2q4._.js} +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1ibjy5x._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1iny24d._.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]__1tyedjt._.js +3 -0
- package/.next/standalone/.next/server/chunks/_0lxbzdq._.js +5 -0
- package/.next/standalone/.next/server/chunks/_1zuiiy3._.js +5 -0
- package/.next/standalone/.next/server/chunks/lib_telemetry_ts_0dctyyw._.js +5 -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/package_json_[json]_cjs_1nxcc4v._.js +1 -1
- 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]__0spkm68._.js +10 -10
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1_a_gwn._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1a2hcb_._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1e7-pa7._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0rtdfof._.js → [root-of-the-server]__1rdruw4._.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]__1tyf0tc._.js +5 -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/{[root-of-the-server]__0rag5dg._.js → [root-of-the-server]__1yw368c._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_0-yi74u._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_04mekdy._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_0igtyj5._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_0r-dsre._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_0rjgfln._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_0se484m._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_0uz7o9y._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_11_p9y8._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_1fahg9e._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_1gmzkwj._.js +5 -0
- package/.next/standalone/.next/server/chunks/ssr/_1w8sola._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_1w_6p9g._.js +3 -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/src_hooks_builtin-policies_ts_09j2ndl._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_fp-config_ts_04t589g._.js +5 -0
- package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
- 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 +54 -12
- package/.next/standalone/.next/static/chunks/{2c90h1g6x8z8y.js → 0_2n13i94rnw5.js} +1 -1
- package/.next/standalone/.next/static/chunks/1bm0q12hgs22l.css +2 -0
- package/.next/standalone/.next/static/chunks/1v1gqvpjk62jm.js +1 -0
- package/.next/standalone/.next/static/chunks/23557z4e6dtsr.js +1 -0
- package/.next/standalone/.next/static/chunks/28zkwzu50puki.js +1 -0
- package/.next/standalone/.next/static/chunks/2uvhw57mf9lg_.css +2 -0
- package/.next/standalone/.next/static/chunks/3081gykdubv8b.js +1 -0
- package/.next/standalone/.next/static/chunks/{06jakt_xhoolk.js → 34fa65k0cldkj.js} +1 -1
- package/.next/standalone/.next/static/chunks/35v07j9gc1pvr.js +6 -0
- package/.next/standalone/.next/static/chunks/{2zb3m1tzq6h98.js → 3f_939wi3kfnx.js} +22 -22
- package/.next/standalone/.next/static/chunks/{31cqiv_cpgj9m.js → 3p1vpm2_-tfwm.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0ue9ak_xexiqh.js → 3rbpw_waieafm.js} +1 -1
- package/.next/standalone/.next/static/chunks/40ffnfpkeyvb0.js +1 -0
- package/.next/standalone/app/actions/get-hooks-config.ts +2 -1
- 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/auth-dialog.css +159 -0
- package/.next/standalone/app/audit/_components/auth-dialog.tsx +3 -0
- package/.next/standalone/app/audit/audit-styles.css +6 -149
- package/.next/standalone/app/settings/page.tsx +31 -0
- package/.next/standalone/app/settings/settings-client.tsx +488 -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 -4
- 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 +7 -6
- package/.next/standalone/proxy.ts +89 -1
- package/.next/standalone/server.js +1 -1
- package/bin/failproofai.mjs +197 -80
- package/dist/cli.mjs +17699 -15345
- package/dist/worker.mjs +1620 -257
- package/lib/auth/api-server-client.ts +2 -3
- package/lib/auth/auth-store.ts +4 -4
- 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 +7 -6
- package/scripts/install-telemetry.mjs +8 -1
- package/scripts/launch.ts +25 -3
- package/scripts/parse-script-args.ts +17 -1
- package/scripts/prune-standalone.mjs +20 -0
- 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 -4
- 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 -1
- package/src/hooks/builtin-policies.ts +100 -3
- package/src/hooks/cloud-connection.ts +163 -14
- package/src/hooks/cloud-enrollment-cli.ts +119 -21
- package/src/hooks/cloud-enrollment.ts +87 -17
- package/src/hooks/cloud-introspect.ts +147 -0
- package/src/hooks/cloud-managed-policies.ts +33 -2
- package/src/hooks/collector-config.ts +32 -40
- package/src/hooks/configure-wizard.ts +696 -318
- package/src/hooks/custom-hooks-loader.ts +125 -11
- package/src/hooks/daemon-client.ts +83 -17
- package/src/hooks/daemon-download.ts +54 -2
- package/src/hooks/daemon-service.ts +595 -27
- package/src/hooks/first-run-gate.ts +39 -0
- package/src/hooks/fp-config.ts +497 -0
- package/src/hooks/fp-home.ts +342 -0
- package/src/hooks/fp-reset.ts +332 -0
- package/src/hooks/handler.ts +42 -1
- package/src/hooks/hook-activity-store.ts +35 -20
- package/src/hooks/hook-logger.ts +2 -1
- package/src/hooks/hook-telemetry.ts +5 -1
- package/src/hooks/hooks-config.ts +4 -3
- package/src/hooks/loader-utils.ts +166 -5
- package/src/hooks/manager.ts +5 -4
- package/src/hooks/onboarding-lock.ts +119 -0
- package/src/hooks/policy-types.ts +0 -7
- package/src/hooks/session-pause-cli.ts +15 -13
- package/src/hooks/session-pause.ts +36 -4
- package/src/hooks/setup-state.ts +256 -0
- package/src/hooks/tui.ts +4 -4
- package/src/hooks/worker-server.ts +53 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0f8nu8d._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0szqzl8._.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/[root-of-the-server]__02r5bgf._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0cmdyn_._.js +0 -3
- 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]__0ls0gsr._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0n_uvv0._.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]__0sdrz-j._.js +0 -3
- 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]__14dd6h8._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1j4u3yd._.js +0 -4
- 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_1q9xxca.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/0oe2-hp0_2tzs.js +0 -6
- package/.next/standalone/.next/static/chunks/1fw3pxobk_otl.js +0 -1
- package/.next/standalone/.next/static/chunks/3h5_3u46gu9jx.js +0 -1
- package/.next/standalone/.next/static/chunks/3i27c3hcriawq.css +0 -1
- package/.next/standalone/.next/static/chunks/3zdwnnthucs_1.css +0 -2
- package/.next/standalone/.next/static/chunks/43a1ywqsg9bq9.js +0 -1
- package/.next/standalone/Cargo.lock +0 -2222
- package/.next/standalone/Cargo.toml +0 -9
- package/.next/standalone/crates/CLOUD_POLICIES.md +0 -136
- package/.next/standalone/crates/PROTOCOL.md +0 -122
- package/.next/standalone/crates/failproofaid/Cargo.toml +0 -25
- package/.next/standalone/crates/failproofaid/src/cloud_client.rs +0 -484
- package/.next/standalone/crates/failproofaid/src/cloud_policies.rs +0 -921
- package/.next/standalone/crates/failproofaid/src/lock.rs +0 -81
- package/.next/standalone/crates/failproofaid/src/main.rs +0 -532
- package/.next/standalone/crates/failproofaid/src/paths.rs +0 -201
- 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-collect/Cargo.toml +0 -43
- package/.next/standalone/crates/fpai-collect/src/config.rs +0 -412
- package/.next/standalone/crates/fpai-collect/src/cursor.rs +0 -520
- package/.next/standalone/crates/fpai-collect/src/delivery.rs +0 -472
- package/.next/standalone/crates/fpai-collect/src/filetail.rs +0 -484
- package/.next/standalone/crates/fpai-collect/src/health.rs +0 -369
- package/.next/standalone/crates/fpai-collect/src/lib.rs +0 -34
- package/.next/standalone/crates/fpai-collect/src/redact.rs +0 -516
- package/.next/standalone/crates/fpai-collect/src/sources/claude/mod.rs +0 -279
- package/.next/standalone/crates/fpai-collect/src/sources/claude/transform.rs +0 -619
- package/.next/standalone/crates/fpai-collect/src/sources/codex/mod.rs +0 -156
- package/.next/standalone/crates/fpai-collect/src/sources/codex/transform.rs +0 -715
- package/.next/standalone/crates/fpai-collect/src/sources/copilot/mod.rs +0 -158
- package/.next/standalone/crates/fpai-collect/src/sources/copilot/transform.rs +0 -512
- package/.next/standalone/crates/fpai-collect/src/sources/goose/mod.rs +0 -511
- package/.next/standalone/crates/fpai-collect/src/sources/goose/transform.rs +0 -586
- package/.next/standalone/crates/fpai-collect/src/sources/hermes/mod.rs +0 -318
- package/.next/standalone/crates/fpai-collect/src/sources/hermes/transform.rs +0 -579
- package/.next/standalone/crates/fpai-collect/src/sources/hooks/mod.rs +0 -310
- package/.next/standalone/crates/fpai-collect/src/sources/hooks/transform.rs +0 -448
- package/.next/standalone/crates/fpai-collect/src/sources/mod.rs +0 -23
- package/.next/standalone/crates/fpai-collect/src/sources/openclaw/mod.rs +0 -176
- package/.next/standalone/crates/fpai-collect/src/sources/openclaw/transform.rs +0 -500
- package/.next/standalone/crates/fpai-collect/src/sources/opencode/mod.rs +0 -315
- package/.next/standalone/crates/fpai-collect/src/sources/opencode/transform.rs +0 -493
- package/.next/standalone/crates/fpai-collect/src/sources/pi/mod.rs +0 -201
- package/.next/standalone/crates/fpai-collect/src/sources/pi/transform.rs +0 -533
- package/.next/standalone/crates/fpai-collect/src/spool.rs +0 -458
- package/.next/standalone/crates/fpai-collect/src/sqlitepoll.rs +0 -387
- package/.next/standalone/crates/fpai-collect/src/supervisor.rs +0 -423
- package/.next/standalone/crates/fpai-collect/src/uploader.rs +0 -600
- package/.next/standalone/crates/fpai-collect/tests/claude_source.rs +0 -738
- package/.next/standalone/crates/fpai-collect/tests/claude_subagents.rs +0 -393
- package/.next/standalone/crates/fpai-collect/tests/codex_source.rs +0 -975
- package/.next/standalone/crates/fpai-collect/tests/config.rs +0 -286
- package/.next/standalone/crates/fpai-collect/tests/copilot_source.rs +0 -1019
- package/.next/standalone/crates/fpai-collect/tests/delivery.rs +0 -281
- package/.next/standalone/crates/fpai-collect/tests/goose_source.rs +0 -1008
- package/.next/standalone/crates/fpai-collect/tests/hermes_source.rs +0 -1129
- package/.next/standalone/crates/fpai-collect/tests/hooks_source.rs +0 -621
- package/.next/standalone/crates/fpai-collect/tests/openclaw_source.rs +0 -854
- package/.next/standalone/crates/fpai-collect/tests/opencode_source.rs +0 -1478
- package/.next/standalone/crates/fpai-collect/tests/pi_source.rs +0 -1191
- package/.next/standalone/crates/fpai-collect/tests/supervisor.rs +0 -290
- package/.next/standalone/crates/fpai-collect/tests/uploader.rs +0 -506
- 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/{StV6Lay7Q1cU4ysYCFJmH → Ptn8aBQl_cnNgOd0ebyv0}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{StV6Lay7Q1cU4ysYCFJmH → Ptn8aBQl_cnNgOd0ebyv0}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{StV6Lay7Q1cU4ysYCFJmH → Ptn8aBQl_cnNgOd0ebyv0}/_ssgManifest.js +0 -0
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,15 @@ export function parseScriptArgs(argv: string[]): ParsedScriptArgs {
|
|
|
71
79
|
i--;
|
|
72
80
|
continue;
|
|
73
81
|
}
|
|
82
|
+
|
|
83
|
+
if (flag === "--host") {
|
|
84
|
+
const { value, spliceCount } = parseStringFlag(flag, "an address to bind (e.g. 127.0.0.1)", inlineValue, args, i);
|
|
85
|
+
host = value;
|
|
86
|
+
args.splice(i, spliceCount);
|
|
87
|
+
i--;
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
74
90
|
}
|
|
75
91
|
|
|
76
|
-
return { loggingLevel, disableTelemetry, allowedDevOrigins, remainingArgs: args };
|
|
92
|
+
return { loggingLevel, disableTelemetry, allowedDevOrigins, host, remainingArgs: args };
|
|
77
93
|
}
|
|
@@ -107,6 +107,18 @@ const STANDALONE_ROOT_PRUNE = [
|
|
|
107
107
|
// RUNNER_TEMP precisely so this cannot happen), and 16 MB of `.gz` shipped
|
|
108
108
|
// inside the CLI tarball once already because nothing pruned them.
|
|
109
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",
|
|
110
122
|
];
|
|
111
123
|
const STANDALONE_ROOT_PRUNE_FILES = [
|
|
112
124
|
// Top-level markdown / licenses / docs
|
|
@@ -117,6 +129,14 @@ const STANDALONE_ROOT_PRUNE_FILES = [
|
|
|
117
129
|
"vitest.config.mts", "vitest.config.e2e.mts",
|
|
118
130
|
// Lockfiles
|
|
119
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",
|
|
120
140
|
];
|
|
121
141
|
for (const d of STANDALONE_ROOT_PRUNE) {
|
|
122
142
|
rmSync(join(STANDALONE, d), { recursive: true, force: true });
|
|
@@ -17,6 +17,158 @@ const ROOT_DIR = join(__dirname, "..", "..");
|
|
|
17
17
|
const README_PATH = join(ROOT_DIR, "README.md");
|
|
18
18
|
const I18N_DIR = join(ROOT_DIR, "docs", "i18n");
|
|
19
19
|
|
|
20
|
+
/**
|
|
21
|
+
* Prefix that walks from `docs/i18n/` back to the repo root. Keep in sync with
|
|
22
|
+
* I18N_DIR — the disclaimer and language selector already hard-code the same
|
|
23
|
+
* two levels in their `../../README.md` links.
|
|
24
|
+
*/
|
|
25
|
+
const TO_REPO_ROOT = "../../";
|
|
26
|
+
|
|
27
|
+
/** Raw-content base for repo files that must resolve off-GitHub too. */
|
|
28
|
+
const RAW_BASE = "https://raw.githubusercontent.com/FailproofAI/failproofai/main/";
|
|
29
|
+
|
|
30
|
+
const ASSET_RE = /\.(?:png|jpe?g|gif|svg|webp|ico|mp4|webm)$/i;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Re-point the root README's repo-root-relative paths so they still resolve
|
|
34
|
+
* from `docs/i18n/README.<lang>.md`, two directories deeper.
|
|
35
|
+
*
|
|
36
|
+
* The root README lives AT the repo root, so it writes `readme-arch-hq.gif` and
|
|
37
|
+
* `assets/logos/claude.svg` — correct there. The translator is prompt-forbidden
|
|
38
|
+
* from touching paths ("Preserve all URLs and paths", translator.ts), and
|
|
39
|
+
* rightly so, but that means every translated copy inherited those paths
|
|
40
|
+
* verbatim into a directory two levels down, where they resolve against
|
|
41
|
+
* `docs/i18n/`. Both consumers 404'd: GitHub asked for
|
|
42
|
+
* `docs/i18n/assets/logos/claude.svg` and Mintlify (which also serves these
|
|
43
|
+
* pages, unlisted, at `/i18n/README.<lang>`) asked S3 for `exosphere/i18n/...`.
|
|
44
|
+
* Every logo and the architecture GIF were broken in all 14 languages.
|
|
45
|
+
*
|
|
46
|
+
* The two ref kinds get different treatment because they resolve in different
|
|
47
|
+
* places:
|
|
48
|
+
* - IMAGES become absolute raw.githubusercontent URLs. A `../../` relative
|
|
49
|
+
* path would fix GitHub but not Mintlify, whose copy of the page has no
|
|
50
|
+
* `assets/` tree above it to walk into — an absolute URL is the only form
|
|
51
|
+
* that renders on BOTH surfaces.
|
|
52
|
+
* - DOCUMENT links (`./LICENSE`, `./CONTRIBUTING.md`, the translations row's
|
|
53
|
+
* `./docs/i18n/README.*.md`) get the `../../` prefix instead. GitHub is the
|
|
54
|
+
* only surface where a link to a repo file resolves at all, and a raw URL
|
|
55
|
+
* there would serve unrendered plaintext.
|
|
56
|
+
*
|
|
57
|
+
* Left alone: absolute URLs, anchors, `mailto:`, protocol-relative `//`,
|
|
58
|
+
* site-absolute `/`, anything already starting with `../`, and everything
|
|
59
|
+
* inside a fenced code block (where a path is literal sample text, not a ref).
|
|
60
|
+
*/
|
|
61
|
+
export function rebaseReadmePaths(content: string): string {
|
|
62
|
+
// Recomputed before each pass. `String.replace` reports offsets into the
|
|
63
|
+
// string it is scanning, so one map is valid for a whole pass — but a pass
|
|
64
|
+
// that rewrites a path AHEAD of a fence lengthens the text and shifts that
|
|
65
|
+
// fence, leaving offsets from the previous string pointing short. The next
|
|
66
|
+
// pass would then read a literal `<img src=…>` inside a fence as ordinary
|
|
67
|
+
// markup and rewrite the sample path this guard exists to protect.
|
|
68
|
+
let fenceRanges = findFenceRanges(content);
|
|
69
|
+
const insideFence = (offset: number): boolean =>
|
|
70
|
+
fenceRanges.some(([start, end]) => offset >= start && offset < end);
|
|
71
|
+
|
|
72
|
+
const rebase = (path: string): string | null => {
|
|
73
|
+
if (path === "" || /^[a-z][a-z0-9+.-]*:/i.test(path)) return null; // scheme
|
|
74
|
+
if (path.startsWith("#") || path.startsWith("/")) return null; // anchor, site-absolute
|
|
75
|
+
if (path.startsWith("../")) return null; // already rebased
|
|
76
|
+
const bare = path.replace(/^\.\//, "");
|
|
77
|
+
if (bare === "" || bare.startsWith("../")) return null;
|
|
78
|
+
return ASSET_RE.test(bare.split(/[?#]/)[0])
|
|
79
|
+
? `${RAW_BASE}${bare}`
|
|
80
|
+
: `${TO_REPO_ROOT}${bare}`;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// Markdown links and images: `](path)` / `](path "title")`.
|
|
84
|
+
let out = content.replace(
|
|
85
|
+
/(\]\()([^)\s]+)/g,
|
|
86
|
+
(match, prefix: string, path: string, offset: number) => {
|
|
87
|
+
if (insideFence(offset)) return match;
|
|
88
|
+
const next = rebase(path);
|
|
89
|
+
return next === null ? match : `${prefix}${next}`;
|
|
90
|
+
},
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
// HTML/JSX attributes: the README's logo table is a raw <table> of <img>.
|
|
94
|
+
fenceRanges = findFenceRanges(out);
|
|
95
|
+
out = out.replace(
|
|
96
|
+
/((?:src|href)=(["']))(.*?)\2/g,
|
|
97
|
+
(match, prefix: string, quote: string, path: string, offset: number) => {
|
|
98
|
+
if (insideFence(offset)) return match;
|
|
99
|
+
const next = rebase(path);
|
|
100
|
+
return next === null ? match : `${prefix}${next}${quote}`;
|
|
101
|
+
},
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
// `srcset` needs its own pass: each logo cell is a <picture> whose dark-mode
|
|
105
|
+
// <source srcset="assets/logos/*-dark.svg"> sits beside the <img src>. Miss
|
|
106
|
+
// it and half the table stays broken for dark-theme readers only — the half
|
|
107
|
+
// least likely to be noticed in review.
|
|
108
|
+
fenceRanges = findFenceRanges(out);
|
|
109
|
+
out = out.replace(
|
|
110
|
+
/(srcset=(["']))(.*?)\2/g,
|
|
111
|
+
(match, prefix: string, quote: string, value: string, offset: number) => {
|
|
112
|
+
if (insideFence(offset)) return match;
|
|
113
|
+
return `${prefix}${rebaseSrcset(value)}${quote}`;
|
|
114
|
+
},
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
return out;
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Rebase every candidate in a `srcset` value, preserving each one's optional
|
|
121
|
+
* density/width descriptor (`logo.svg 2x`, `wide.png 800w`) and the original
|
|
122
|
+
* comma spacing.
|
|
123
|
+
*/
|
|
124
|
+
function rebaseSrcset(value: string): string {
|
|
125
|
+
return value
|
|
126
|
+
.split(",")
|
|
127
|
+
.map((candidate) => {
|
|
128
|
+
const [, lead, url, descriptor] =
|
|
129
|
+
/^(\s*)(\S+)(.*)$/.exec(candidate) ?? [];
|
|
130
|
+
if (url === undefined) return candidate; // whitespace-only candidate
|
|
131
|
+
const next = rebase(url);
|
|
132
|
+
return `${lead}${next ?? url}${descriptor}`;
|
|
133
|
+
})
|
|
134
|
+
.join(",");
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Byte ranges covered by fenced code blocks, per CommonMark: a fence opens with
|
|
140
|
+
* ≥3 backticks or tildes and closes only on a later line using the SAME
|
|
141
|
+
* character at ≥ the same length.
|
|
142
|
+
*
|
|
143
|
+
* Follows the scanner in `mdx-translator.convertHtmlComments`, with one
|
|
144
|
+
* correction: a CLOSING fence may carry only trailing whitespace, never an info
|
|
145
|
+
* string. Accepting ```` ```ts ```` as a close would end the block at the first
|
|
146
|
+
* *nested* opener inside it and leave the real code that follows looking like
|
|
147
|
+
* prose — whose sample paths this function exists to protect.
|
|
148
|
+
*/
|
|
149
|
+
function findFenceRanges(content: string): Array<[number, number]> {
|
|
150
|
+
const ranges: Array<[number, number]> = [];
|
|
151
|
+
const fenceRe = /^[ \t]*(`{3,}|~{3,})([^\n]*)$/gm;
|
|
152
|
+
let match: RegExpExecArray | null;
|
|
153
|
+
let open: { char: string; length: number; start: number } | null = null;
|
|
154
|
+
while ((match = fenceRe.exec(content)) !== null) {
|
|
155
|
+
const [, marker, rest] = match;
|
|
156
|
+
if (!open) {
|
|
157
|
+
open = { char: marker[0], length: marker.length, start: match.index };
|
|
158
|
+
} else if (
|
|
159
|
+
marker[0] === open.char &&
|
|
160
|
+
marker.length >= open.length &&
|
|
161
|
+
rest.trim() === ""
|
|
162
|
+
) {
|
|
163
|
+
const lineEnd = content.indexOf("\n", fenceRe.lastIndex);
|
|
164
|
+
ranges.push([open.start, lineEnd === -1 ? content.length : lineEnd]);
|
|
165
|
+
open = null;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
if (open) ranges.push([open.start, content.length]);
|
|
169
|
+
return ranges;
|
|
170
|
+
}
|
|
171
|
+
|
|
20
172
|
function buildLanguageSelector(currentLang: string): string {
|
|
21
173
|
const flags: Record<string, string> = {
|
|
22
174
|
en: "\ud83c\uddfa\ud83c\uddf8",
|
|
@@ -117,10 +269,17 @@ export async function translateReadme(
|
|
|
117
269
|
// Same MDX sanitizers as translateMdxPage — the README emits JSX (the
|
|
118
270
|
// logo table), so strip stray attribute quotes, drop any unmatched
|
|
119
271
|
// trailing code fence (which would swallow the RTL `</div>`), and
|
|
120
|
-
// convert HTML comments to MDX — then
|
|
121
|
-
//
|
|
122
|
-
|
|
123
|
-
|
|
272
|
+
// convert HTML comments to MDX — then re-point the root README's
|
|
273
|
+
// repo-root-relative paths for this file's depth, and wrap in
|
|
274
|
+
// disclaimer + selector + RTL div.
|
|
275
|
+
//
|
|
276
|
+
// The rebase runs on the model output ONLY, never on the wrapper: the
|
|
277
|
+
// disclaimer's `../../README.md` and the selector's sibling
|
|
278
|
+
// `README.<lang>.md` links are already written for `docs/i18n/`.
|
|
279
|
+
const cleaned = rebaseReadmePaths(
|
|
280
|
+
convertHtmlComments(
|
|
281
|
+
stripStrayTrailingFence(sanitizeJsxAttributes(raw)),
|
|
282
|
+
),
|
|
124
283
|
);
|
|
125
284
|
return `${disclaimer}\n\n${langSelector}\n\n---\n${rtlOpen}\n${cleaned}\n${rtlClose}`;
|
|
126
285
|
},
|
package/scripts/validate-mdx.ts
CHANGED
|
@@ -25,15 +25,22 @@
|
|
|
25
25
|
* `findPageError`), so this net is a strict superset of `mintlify validate`:
|
|
26
26
|
* it catches both the frontmatter YAML class that fails `mintlify validate`
|
|
27
27
|
* and the body-MDX class that `mintlify validate` lets through to deploy.
|
|
28
|
+
*
|
|
29
|
+
* It also covers a third class neither tool sees: image references whose target
|
|
30
|
+
* does not exist (`findBrokenAssetRefs`). Those are valid MDX and valid YAML —
|
|
31
|
+
* nothing errors, the reader just gets a broken image — which is how all 14
|
|
32
|
+
* translated READMEs shipped with every logo and the architecture GIF broken.
|
|
33
|
+
* See that function for the mechanism.
|
|
28
34
|
*/
|
|
29
|
-
import { readdirSync, statSync, readFileSync } from "node:fs";
|
|
30
|
-
import { dirname, join, relative } from "node:path";
|
|
35
|
+
import { readdirSync, statSync, readFileSync, existsSync } from "node:fs";
|
|
36
|
+
import { dirname, join, relative, resolve, posix } from "node:path";
|
|
31
37
|
import { fileURLToPath } from "node:url";
|
|
32
38
|
import { compile } from "@mdx-js/mdx";
|
|
33
39
|
import YAML from "yaml";
|
|
34
40
|
|
|
35
41
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
36
|
-
const
|
|
42
|
+
const ROOT_DIR = join(__dirname, "..");
|
|
43
|
+
const DOCS_DIR = join(ROOT_DIR, "docs");
|
|
37
44
|
|
|
38
45
|
export interface MdxParseError {
|
|
39
46
|
message: string;
|
|
@@ -178,34 +185,167 @@ export function collectMdxFiles(dir: string): string[] {
|
|
|
178
185
|
return out;
|
|
179
186
|
}
|
|
180
187
|
|
|
188
|
+
/** File extensions treated as bundled media rather than a link to a page. */
|
|
189
|
+
const ASSET_RE = /\.(?:png|jpe?g|gif|svg|webp|ico|mp4|webm)$/i;
|
|
190
|
+
|
|
191
|
+
export interface BrokenAssetRef {
|
|
192
|
+
/** The reference exactly as written in the page. */
|
|
193
|
+
ref: string;
|
|
194
|
+
/** Repo-relative path the reference resolves to, which does not exist. */
|
|
195
|
+
resolved: string;
|
|
196
|
+
/** 1-based line the reference appears on. */
|
|
197
|
+
line: number;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Report every local image reference on a page whose target does not exist on
|
|
202
|
+
* disk.
|
|
203
|
+
*
|
|
204
|
+
* Why this is a separate net from the MDX parse above: a broken image path is
|
|
205
|
+
* perfectly valid MDX and perfectly valid YAML, so `mintlify validate` and
|
|
206
|
+
* `findPageError` both pass it — it only surfaces as a missing image in a
|
|
207
|
+
* reader's browser, which nothing in CI was watching. That is exactly how all
|
|
208
|
+
* 14 translated READMEs shipped with every logo and the architecture GIF
|
|
209
|
+
* broken: the translator faithfully copies the root README's repo-root-relative
|
|
210
|
+
* `assets/logos/*.svg` into `docs/i18n/`, two directories deeper, where they
|
|
211
|
+
* resolve to nothing (GitHub 404, Mintlify S3 403). The auto-translation
|
|
212
|
+
* workflow regenerates these pages unattended, so only a deterministic check
|
|
213
|
+
* keeps that class from coming back.
|
|
214
|
+
*
|
|
215
|
+
* Resolution follows the two conventions in this repo:
|
|
216
|
+
* - A leading `/` is Mintlify site-absolute → resolve against `docs/`
|
|
217
|
+
* (`/agenteye/images/x.png` → `docs/agenteye/images/x.png`).
|
|
218
|
+
* - Anything else is relative to the page's own directory, the way GitHub and
|
|
219
|
+
* Mintlify both resolve it.
|
|
220
|
+
*
|
|
221
|
+
* Skipped: absolute URLs and any other scheme (`https:`, `mailto:`, `data:`),
|
|
222
|
+
* protocol-relative `//`, bare anchors, and non-asset references — a link to a
|
|
223
|
+
* `.md`/`.mdx` page or a bare doc slug is nav, already covered by
|
|
224
|
+
* `mintlify validate`, and would false-positive on extensionless Mintlify
|
|
225
|
+
* routes.
|
|
226
|
+
*/
|
|
227
|
+
export function findBrokenAssetRefs(
|
|
228
|
+
file: string,
|
|
229
|
+
source: string,
|
|
230
|
+
): BrokenAssetRef[] {
|
|
231
|
+
const pageDir = dirname(file);
|
|
232
|
+
const out: BrokenAssetRef[] = [];
|
|
233
|
+
const seen = new Set<string>();
|
|
234
|
+
|
|
235
|
+
const lines = source.split("\n");
|
|
236
|
+
for (let i = 0; i < lines.length; i++) {
|
|
237
|
+
const refs = [
|
|
238
|
+
...lines[i].matchAll(/\]\(([^)\s]+)/g),
|
|
239
|
+
...lines[i].matchAll(/(?:src|href)=["']([^"']+)["']/g),
|
|
240
|
+
].map((m) => m[1]);
|
|
241
|
+
|
|
242
|
+
// `srcset` carries a comma-separated candidate list, each optionally
|
|
243
|
+
// followed by a density/width descriptor (`logo.svg 2x`). The README's
|
|
244
|
+
// logo table pairs every <img src> with a dark-mode <source srcset>, so
|
|
245
|
+
// extracting only `src` would pass a table half-broken — and only for
|
|
246
|
+
// dark-theme readers, the half least likely to be caught by eye.
|
|
247
|
+
for (const m of lines[i].matchAll(/srcset=["']([^"']+)["']/g)) {
|
|
248
|
+
for (const candidate of m[1].split(",")) {
|
|
249
|
+
const url = candidate.trim().split(/\s+/)[0];
|
|
250
|
+
if (url) refs.push(url);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
for (const ref of refs) {
|
|
255
|
+
if (/^[a-z][a-z0-9+.-]*:/i.test(ref)) continue; // https:, mailto:, data:
|
|
256
|
+
if (ref.startsWith("//") || ref.startsWith("#")) continue;
|
|
257
|
+
// Strip the query/fragment before testing the extension so a versioned
|
|
258
|
+
// `x.png?v=2` is still recognised as an asset.
|
|
259
|
+
const path = ref.split(/[?#]/)[0];
|
|
260
|
+
if (!ASSET_RE.test(path)) continue;
|
|
261
|
+
|
|
262
|
+
const target = path.startsWith("/")
|
|
263
|
+
? join(DOCS_DIR, path.slice(1))
|
|
264
|
+
: resolve(pageDir, path);
|
|
265
|
+
if (existsSync(target)) continue;
|
|
266
|
+
|
|
267
|
+
const key = `${i}:${ref}`;
|
|
268
|
+
if (seen.has(key)) continue;
|
|
269
|
+
seen.add(key);
|
|
270
|
+
out.push({
|
|
271
|
+
ref,
|
|
272
|
+
resolved: relative(ROOT_DIR, target).split(/[\\/]/).join(posix.sep),
|
|
273
|
+
line: i + 1,
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
return out;
|
|
278
|
+
}
|
|
279
|
+
|
|
181
280
|
async function main(): Promise<void> {
|
|
182
281
|
const files = collectMdxFiles(DOCS_DIR).sort();
|
|
183
|
-
const failures: Array<{
|
|
282
|
+
const failures: Array<{
|
|
283
|
+
file: string;
|
|
284
|
+
error: MdxParseError;
|
|
285
|
+
kind: "MDX parse error" | "Broken image";
|
|
286
|
+
}> = [];
|
|
287
|
+
|
|
288
|
+
const collectAssetFailures = (file: string, source: string): void => {
|
|
289
|
+
for (const broken of findBrokenAssetRefs(file, source)) {
|
|
290
|
+
failures.push({
|
|
291
|
+
file: relative(process.cwd(), file),
|
|
292
|
+
kind: "Broken image",
|
|
293
|
+
error: {
|
|
294
|
+
message:
|
|
295
|
+
`Image \`${broken.ref}\` does not exist — it resolves to ` +
|
|
296
|
+
`\`${broken.resolved}\`. Paths are relative to the page's own ` +
|
|
297
|
+
"directory (a leading `/` is relative to `docs/`), so a path " +
|
|
298
|
+
"copied from a file at a different depth has to be re-pointed.",
|
|
299
|
+
line: broken.line,
|
|
300
|
+
},
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
};
|
|
184
304
|
|
|
185
305
|
for (const file of files) {
|
|
186
|
-
const
|
|
187
|
-
|
|
306
|
+
const source = readFileSync(file, "utf-8");
|
|
307
|
+
const error = await findPageError(source);
|
|
308
|
+
if (error)
|
|
309
|
+
failures.push({
|
|
310
|
+
file: relative(process.cwd(), file),
|
|
311
|
+
error,
|
|
312
|
+
kind: "MDX parse error",
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
// A page can carry a broken image and still parse, so collect these
|
|
316
|
+
// independently rather than only when the parse succeeded.
|
|
317
|
+
collectAssetFailures(file, source);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// The root README is not a docs page (it is GitHub-only, and its HTML
|
|
321
|
+
// comments are illegal MDX, so findPageError would reject it) — but it IS
|
|
322
|
+
// the source every docs/i18n/README.<lang>.md is translated from. A bad
|
|
323
|
+
// image path here propagates into 14 files as an absolute raw URL, which
|
|
324
|
+
// findBrokenAssetRefs deliberately does not follow. Check it at the source.
|
|
325
|
+
const rootReadme = join(ROOT_DIR, "README.md");
|
|
326
|
+
if (existsSync(rootReadme)) {
|
|
327
|
+
collectAssetFailures(rootReadme, readFileSync(rootReadme, "utf-8"));
|
|
188
328
|
}
|
|
189
329
|
|
|
190
330
|
if (failures.length === 0) {
|
|
191
|
-
console.log(
|
|
331
|
+
console.log(
|
|
332
|
+
`✓ ${files.length} MDX page(s) parsed cleanly with no broken images`,
|
|
333
|
+
);
|
|
192
334
|
return;
|
|
193
335
|
}
|
|
194
336
|
|
|
195
|
-
console.error(
|
|
196
|
-
|
|
197
|
-
);
|
|
198
|
-
for (const { file, error } of failures) {
|
|
337
|
+
console.error(`✗ ${failures.length} problem(s) in ${files.length} page(s):\n`);
|
|
338
|
+
for (const { file, error, kind } of failures) {
|
|
199
339
|
const pos = error.line
|
|
200
340
|
? `:${error.line}${error.column ? `:${error.column}` : ""}`
|
|
201
341
|
: "";
|
|
202
|
-
console.error(` ${file}${pos}\n ${error.message}\n`);
|
|
342
|
+
console.error(` ${file}${pos}\n ${kind}: ${error.message}\n`);
|
|
203
343
|
// GitHub Actions inline annotation.
|
|
204
344
|
const loc =
|
|
205
345
|
(error.line ? `,line=${error.line}` : "") +
|
|
206
346
|
(error.column ? `,col=${error.column}` : "");
|
|
207
347
|
console.log(
|
|
208
|
-
`::error file=${encodeAnnotation(file)}${loc}
|
|
348
|
+
`::error file=${encodeAnnotation(file)}${loc}::${kind}: ${encodeAnnotation(error.message)}`,
|
|
209
349
|
);
|
|
210
350
|
}
|
|
211
351
|
process.exitCode = 1;
|