failproofai 1.0.11-beta.4 → 1.0.12-beta.0
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/build-manifest.json +23 -23
- package/.next/standalone/.next/prerender-manifest.json +3 -3
- package/.next/standalone/.next/required-server-files.json +1 -1
- 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 +2 -2
- 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 +2 -2
- 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 +2 -2
- 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 -3
- 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 +3 -3
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
- 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/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/api/audit/invite/route.js +5 -6
- 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 +9 -9
- 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 +2 -2
- 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 +4 -5
- 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 +6 -7
- 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 +6 -7
- package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/status/route.js +5 -6
- 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 +2 -2
- 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 +4 -4
- 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 +3 -3
- package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +3 -3
- package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- 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 +2 -2
- 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 +14 -14
- package/.next/standalone/.next/server/app/policies/page.js +3 -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 +7 -7
- 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 +8 -8
- 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 +3 -3
- 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/build-manifest.json +3 -3
- package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +8 -8
- package/.next/standalone/.next/server/app/settings/page.js +3 -3
- package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/chunks/{[externals]__0qkp92tjfvw8r._.js → [externals]__0-ha5ydqq0mws._.js} +1 -1
- package/.next/standalone/.next/server/chunks/[externals]__1x24dzcbbq6-g._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__02vous7mpi2xm._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__03i5o4a840guz._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0__a_je8fsn65._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0_hsnj_a2mvl_._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0jz5xqu-p_lfc._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0l-oi4gdtmlo5._.js +3 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0swiyzbmvja2d._.js → [root-of-the-server]__0t9ufnv5hi2hq._.js} +5 -5
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0wg9dk8x8bnau._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__12kq3x-h7t7i1._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1a5zkndjwlc13._.js +3 -0
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__1r7kbfkiw2xmu._.js → [root-of-the-server]__1aaw59g-5uty7._.js} +12 -12
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1ey11fel2q2qw._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1hqpg6vgmfexv._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1ztigqa01tigq._.js +1 -1
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__1izwqj_ij_9x_._.js → [root-of-the-server]__20xe05hm5u8_1._.js} +1 -1
- package/.next/standalone/.next/server/chunks/{_1ixl-kxq_ctsa._.js → _0kc-piux3hady._.js} +2 -2
- package/.next/standalone/.next/server/chunks/_0tovk6q0miud6._.js +1 -1
- package/.next/standalone/.next/server/chunks/_0trp3ycqv17cl._.js +1 -1
- package/.next/standalone/.next/server/chunks/_1vslkoe35wok6._.js +1 -1
- package/.next/standalone/.next/server/chunks/lib_11qmqmccehybz._.js +1 -1
- package/.next/standalone/.next/server/chunks/lib_1sezqnatvr8j-._.js +1 -1
- package/.next/standalone/.next/server/chunks/lib_antigravity-projects_ts_0hdx6fkrln72c._.js +1 -1
- package/.next/standalone/.next/server/chunks/lib_codex-projects_ts_0di6zenec7h7n._.js +1 -1
- package/.next/standalone/.next/server/chunks/lib_copilot-projects_ts_00-tojoja20ke._.js +1 -1
- package/.next/standalone/.next/server/chunks/lib_cursor-projects_ts_1carno5mv3ix_._.js +1 -1
- package/.next/standalone/.next/server/chunks/lib_factory-projects_ts_1eo_bk-vm4wdz._.js +1 -1
- package/.next/standalone/.next/server/chunks/lib_hermes-projects_ts_0h9ny-woruqft._.js +1 -1
- package/.next/standalone/.next/server/chunks/lib_log-entries_ts_0e1mnh5npsol1._.js +1 -1
- package/.next/standalone/.next/server/chunks/lib_openclaw-projects_ts_0gc-p24z7gzy8._.js +1 -1
- package/.next/standalone/.next/server/chunks/lib_opencode-projects_ts_1r-bu98cz4660._.js +1 -1
- package/.next/standalone/.next/server/chunks/lib_pi-projects_ts_1_cy5lfxd21kv._.js +1 -1
- package/.next/standalone/.next/server/chunks/lib_projects_ts_01v279z8xccq4._.js +1 -1
- package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4vkpxxu7._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__01j58mdcdw0vn._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__08ch3staq3ejw._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0_a8z2ldp2v3n._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0bigvy9xmv2ka._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ffu2-38y03ic._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0g8b0kyorya-t._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0h86bl2qf0k_o._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0pia5h3p8re4c._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__075uro8t92s0_._.js → [root-of-the-server]__0pwj2h2efe5f-._.js} +3 -3
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0b28bm2e-y0rp._.js → [root-of-the-server]__0ts0fg5yih1c1._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0zn1d4blhd3bu._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1-ey9fgesfbc0._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__15usvs-ms-0hf._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__16gb3_92zvk5x._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__17r4zrwanhp6r._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1avi2kypusyb_._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1lnfv02ucky7m._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1mc9-zlnh656_._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1r7drlqli-ado._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1s2-ck3k3rsoo._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1l1qgu5mfapkh._.js → [root-of-the-server]__1vx7o8ukefudh._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_0eoura3_9gjb-._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_0pedwblqdoh58._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_1_ozgifqv1ssi._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_1djqs9i27e4kg._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{_16u8ppjzw0upc._.js → _1ve8y151ua7qx._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_next-internal_server_app_policies_page_actions_1sp2-yo5_vm5f.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/app_actions_get-scheduled-audit_ts_0ei9snixb5fd-._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47q0xq5w._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x33jqb6._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpcz0uxur._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_settings_02tf1h47jmhhd._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules_html-to-image_es_index_0_zbgw5i5c7_a.js → node_modules_html-to-image_es_index_00jxj8foxqz5t.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_0janj0i6dqko7._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/package_json_[json]_cjs_013tntikdft59._.js +1 -1
- package/.next/standalone/.next/server/middleware-build-manifest.js +23 -23
- 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/preview-props.json +3 -3
- package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +23 -23
- package/.next/standalone/.next/static/chunks/{0frxv4_m-m2u5.js → 063al_q720fkj.js} +1 -1
- package/.next/standalone/.next/static/chunks/{3c5k3z60x6vuh.js → 0a-ccsp3xmypz.js} +1 -1
- package/.next/standalone/.next/static/chunks/{2ly73y3n0ddxn.js → 0pjxnp927y7_j.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0ii1av6gw3_74.js → 13jv-xvabeb62.js} +1 -1
- package/.next/standalone/.next/static/chunks/2ank2u3apy8m6.js +1 -0
- package/.next/standalone/.next/static/chunks/{14prk7fu_3vzm.js → 2meqb9kygrncb.js} +1 -1
- package/.next/standalone/.next/static/chunks/2ohktp_-lkv3x.js +1 -0
- package/.next/standalone/.next/static/chunks/2py0eldhwz8ay.js +1 -0
- package/.next/standalone/.next/static/chunks/{3yxhw5uqrh1rq.js → 2qz5piiir-qqm.js} +1 -1
- package/.next/standalone/.next/static/chunks/2tjfp9dirxnku.js +1 -0
- package/.next/standalone/.next/static/chunks/{2_2xem_wwddgy.js → 2znt1784j9gd9.js} +1 -1
- package/.next/standalone/.next/static/chunks/3tn1bzk094e8e.js +1 -0
- package/.next/standalone/fp-cloud-cli/uv.lock +6 -6
- package/.next/standalone/hermes-plugin/plugin.yaml +1 -1
- package/.next/standalone/node_modules/@next/env/package.json +1 -1
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/api/context.js +72 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/api/diag.js +84 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/api/metrics.js +50 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/api/propagation.js +80 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/api/trace.js +70 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/baggage/context-helpers.js +52 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/baggage/internal/baggage-impl.js +44 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/baggage/internal/symbol.js +12 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/baggage/utils.js +41 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/context/NoopContextManager.js +27 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/context/context.js +52 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/context-api.js +16 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/diag/ComponentLogger.js +47 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/diag/consoleLogger.js +73 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/diag/internal/logLevelLogger.js +34 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/diag/types.js +33 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/diag-api.js +20 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/index.js +71 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/internal/global-utils.js +60 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/internal/semver.js +111 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/metrics/Metric.js +18 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/metrics/NoopMeter.js +118 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/metrics/NoopMeterProvider.js +20 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/metrics-api.js +17 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/propagation/NoopTextMapPropagator.js +23 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/propagation/TextMapPropagator.js +36 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/propagation-api.js +17 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/NonRecordingSpan.js +58 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/NoopTracer.js +68 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/NoopTracerProvider.js +21 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/ProxyTracer.js +46 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/ProxyTracerProvider.js +46 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/SamplingResult.js +33 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/context-utils.js +71 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/internal/tracestate-impl.js +94 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/internal/tracestate-validators.js +35 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/internal/utils.js +16 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/invalid-span-constants.js +25 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/span_kind.js +38 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/spancontext-utils.js +66 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/status.js +29 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace/trace_flags.js +18 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/trace-api.js +17 -0
- package/.next/standalone/node_modules/@opentelemetry/api/build/src/version.js +10 -0
- package/.next/standalone/node_modules/@opentelemetry/api/package.json +96 -0
- package/.next/standalone/node_modules/next/dist/build/swc/index.js +1 -1
- package/.next/standalone/node_modules/next/dist/compiled/next-server/app-page-turbo-experimental.runtime.prod.js +2 -2
- package/.next/standalone/node_modules/next/dist/compiled/next-server/app-page-turbo.runtime.prod.js +2 -2
- package/.next/standalone/node_modules/next/dist/compiled/next-server/app-route-turbo.runtime.prod.js +1 -1
- package/.next/standalone/node_modules/next/dist/lib/patch-incorrect-lockfile.js +3 -3
- package/.next/standalone/node_modules/next/dist/server/app-render/async-local-storage.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/config.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-turbopack.js +2 -2
- package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-webpack.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/lib/app-info-log.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/lib/generate-agent-files.js +3 -3
- package/.next/standalone/node_modules/next/dist/server/lib/router-server.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/lib/start-server.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/lib/trace/tracer.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/typescript/rules/config.js +2 -2
- package/.next/standalone/node_modules/next/dist/server/use-cache/use-cache-wrapper.js +1 -1
- package/.next/standalone/node_modules/next/dist/telemetry/anonymous-meta.js +1 -1
- package/.next/standalone/node_modules/next/dist/telemetry/events/swc-load-failure.js +1 -1
- package/.next/standalone/node_modules/next/dist/telemetry/events/version.js +2 -2
- package/.next/standalone/node_modules/next/package.json +11 -11
- package/.next/standalone/package.json +11 -11
- package/.next/standalone/sdk/python/CHANGELOG.md +22 -3
- package/.next/standalone/sdk/python/failproofai_sdk/_redact.py +3 -5
- package/.next/standalone/sdk/python/failproofai_sdk/_resolver.py +13 -2
- package/.next/standalone/sdk/python/failproofai_sdk/_version.py +1 -1
- package/.next/standalone/sdk/python/failproofai_sdk/integrations/otel.py +3 -1
- package/.next/standalone/sdk/python/pyproject.toml +19 -0
- package/.next/standalone/sdk/python/tests/test_otel.py +25 -0
- package/.next/standalone/sdk/python/uv.lock +520 -301
- package/.next/standalone/sdk/typescript/CHANGELOG.md +39 -1
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-0/package-lock.json +3 -3
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-1/package-lock.json +4 -13
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-1/package.json +2 -1
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/package-lock.json +166 -175
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/package.json +4 -1
- package/.next/standalone/sdk/typescript/package-lock.json +178 -162
- package/.next/standalone/sdk/typescript/package.json +1 -1
- package/.next/standalone/sdk/typescript/src/integrations/otel.ts +2 -1
- package/.next/standalone/sdk/typescript/src/resolver.ts +2 -1
- package/.next/standalone/sdk/typescript/src/version.ts +1 -1
- package/.next/standalone/sdk/typescript/test/otel.test.ts +25 -0
- package/.next/standalone/server.js +1 -1
- package/dist/cli.mjs +658 -85
- package/dist/worker.mjs +1 -1
- package/hermes-plugin/plugin.yaml +1 -1
- package/package.json +11 -11
- package/src/audit/open-browser.ts +19 -1
- package/src/hooks/cloud-connection.ts +4 -1
- package/src/hooks/cloud-introspect.ts +5 -2
- package/src/hooks/cloud-login.ts +245 -0
- package/src/hooks/configure-wizard.ts +311 -15
- package/src/hooks/otel-cli.ts +16 -6
- package/src/hooks/otel-writers.ts +13 -0
- package/src/hooks/tui.ts +271 -0
- package/.next/standalone/.next/server/chunks/[externals]__0hjaw70fchx66._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__07l68zv0hqdiu._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0car70pylmvor._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0u3i025_setk_._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__10a2f6s636yc7._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1qt5u58xrcuk6._.js +0 -3
- package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_077n_4ip5__fu._.js +0 -3
- package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_0mqvvxcn6v0op._.js +0 -3
- package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_0pb7ds5g0vzgn._.js +0 -3
- package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_1gasm5xkeqmm3._.js +0 -3
- package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_1q1heqmkhh8l4._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0888k4s6spfmh._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0_bflu046ep5j._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0fdwgktjfhedo._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0s4deza787asx._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__18qe-hu0gwqm4._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1_p_9xe520fex._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1fmhm8_s9i4re._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1g76awtnmimd1._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1pczevlpk5lxh._.js +0 -3
- package/.next/standalone/.next/static/chunks/01c3z7b9td1j-.js +0 -1
- package/.next/standalone/.next/static/chunks/08-yz-9n_9j-u.js +0 -1
- package/.next/standalone/.next/static/chunks/0m-tv1y6ghhtk.js +0 -1
- package/.next/standalone/.next/static/chunks/2q25h0pqaw62i.js +0 -1
- package/.next/standalone/.next/static/chunks/2sbmeexp-ixmd.js +0 -1
- /package/.next/standalone/.next/static/{ZxaJShYHqvP19gYm49Rao → SNr7o_-G4kNBQTR-iLZMM}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{ZxaJShYHqvP19gYm49Rao → SNr7o_-G4kNBQTR-iLZMM}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{ZxaJShYHqvP19gYm49Rao → SNr7o_-G4kNBQTR-iLZMM}/_ssgManifest.js +0 -0
|
@@ -30,20 +30,26 @@ import { dirname, resolve, sep } from "node:path";
|
|
|
30
30
|
import { CORE_SOURCE } from "./pack-store";
|
|
31
31
|
|
|
32
32
|
import {
|
|
33
|
+
BACK,
|
|
33
34
|
collapseAfter,
|
|
34
35
|
colorsEnabled,
|
|
35
36
|
multiSelect,
|
|
36
37
|
OPEN_SOURCE,
|
|
37
38
|
optsFor,
|
|
38
39
|
paint,
|
|
40
|
+
promptBrowserLogin,
|
|
39
41
|
promptCloudKey,
|
|
40
42
|
screenKit,
|
|
43
|
+
selectOne,
|
|
41
44
|
type CloudKeyAnswer,
|
|
42
45
|
type MultiChoice,
|
|
43
46
|
type OpenSource,
|
|
47
|
+
type SelectChoice,
|
|
44
48
|
type TTYIn,
|
|
45
49
|
type TTYOut,
|
|
46
50
|
} from "./tui";
|
|
51
|
+
import { claimLogin, machineOs, pollLogin, startLogin, type LoginOrg } from "./cloud-login";
|
|
52
|
+
import { canOpenBrowser, openUrl } from "../audit/open-browser";
|
|
47
53
|
import {
|
|
48
54
|
DEFAULT_INGEST_URL,
|
|
49
55
|
readIngestCredential,
|
|
@@ -998,6 +1004,190 @@ export async function runConfigureWizard(
|
|
|
998
1004
|
stdout,
|
|
999
1005
|
});
|
|
1000
1006
|
|
|
1007
|
+
// A key typed after picking "Paste an API key" from the menu. Same field as
|
|
1008
|
+
// above minus the saved key, which the menu already offered as "keep"; Tab is
|
|
1009
|
+
// the way back to the menu, so it never means open source here.
|
|
1010
|
+
const askKey = (): Promise<CloudKeyAnswer | OpenSource | null> =>
|
|
1011
|
+
promptCloudKey({
|
|
1012
|
+
message: "Connect to cloud",
|
|
1013
|
+
meta: source ? `${host} · from ${source}` : host,
|
|
1014
|
+
tabHint: "go back",
|
|
1015
|
+
emptyError: "Paste a key, or press tab to go back.",
|
|
1016
|
+
check: async (key) => {
|
|
1017
|
+
if (!url) return { ok: false, line: badUrl ?? "No usable endpoint." };
|
|
1018
|
+
const r = await checkCloudKey(url, key);
|
|
1019
|
+
if (r.ok) {
|
|
1020
|
+
typedOrg = r.org;
|
|
1021
|
+
return { ok: true, line: r.note };
|
|
1022
|
+
}
|
|
1023
|
+
return { ok: false, line: r.refused ? `That key was refused: ${r.reason}.` : `Couldn't check the key: ${r.reason}.` };
|
|
1024
|
+
},
|
|
1025
|
+
collapsed: (answer) => (answer === OPEN_SOURCE ? [] : [...cloudLines(planFor(answer)), ""]),
|
|
1026
|
+
stdin,
|
|
1027
|
+
stdout,
|
|
1028
|
+
});
|
|
1029
|
+
|
|
1030
|
+
// The browser login. Resolves the approval, BACK for the menu of other
|
|
1031
|
+
// options (Tab / Esc, or a cloud that cannot do this), or null when the person
|
|
1032
|
+
// cancelled the whole run.
|
|
1033
|
+
type Approval = Extract<CloudPlan, { kind: "login" }>;
|
|
1034
|
+
// Set once the cloud says it has no browser login; the menu then drops it.
|
|
1035
|
+
let loginUnsupported = false;
|
|
1036
|
+
const askLogin = (endpoint: string): Promise<{ value: Approval } | typeof BACK | null> => {
|
|
1037
|
+
let pollSecret = "";
|
|
1038
|
+
return promptBrowserLogin<Approval>({
|
|
1039
|
+
message: "Connect to cloud",
|
|
1040
|
+
meta: source ? `${host} · from ${source}` : host,
|
|
1041
|
+
machineLabel,
|
|
1042
|
+
start: async () => {
|
|
1043
|
+
const r = await startLogin(endpoint, { label: machineLabel, os: machineOs(), cliVersion });
|
|
1044
|
+
if (r.kind === "ok") {
|
|
1045
|
+
pollSecret = r.pollSecret;
|
|
1046
|
+
void emit("configure_cloud_login", { step: "started" });
|
|
1047
|
+
return { ok: true, url: r.verificationUrl, expiresIn: r.expiresIn, interval: r.interval };
|
|
1048
|
+
}
|
|
1049
|
+
if (r.kind === "unsupported") {
|
|
1050
|
+
void emit("configure_cloud_login", { step: "unsupported" });
|
|
1051
|
+
loginUnsupported = true;
|
|
1052
|
+
return { ok: false, retryable: false, line: `${host} doesn't support logging in from here yet.` };
|
|
1053
|
+
}
|
|
1054
|
+
return {
|
|
1055
|
+
ok: false,
|
|
1056
|
+
retryable: true,
|
|
1057
|
+
line: r.kind === "refused" ? `Couldn't start the login: ${r.reason}.` : `Couldn't reach ${host}: ${r.reason}.`,
|
|
1058
|
+
};
|
|
1059
|
+
},
|
|
1060
|
+
poll: async () => {
|
|
1061
|
+
const p = await pollLogin(endpoint, pollSecret);
|
|
1062
|
+
switch (p.kind) {
|
|
1063
|
+
case "approved":
|
|
1064
|
+
void emit("configure_cloud_login", { step: "approved" });
|
|
1065
|
+
return {
|
|
1066
|
+
state: "approved",
|
|
1067
|
+
value: {
|
|
1068
|
+
kind: "login",
|
|
1069
|
+
pollSecret,
|
|
1070
|
+
org: p.org,
|
|
1071
|
+
approvedBy: p.approvedBy,
|
|
1072
|
+
keyName: p.keyName,
|
|
1073
|
+
permissions: p.permissions,
|
|
1074
|
+
},
|
|
1075
|
+
};
|
|
1076
|
+
case "pending":
|
|
1077
|
+
return { state: "pending", interval: p.interval };
|
|
1078
|
+
case "slow_down":
|
|
1079
|
+
return { state: "slow_down" };
|
|
1080
|
+
case "denied":
|
|
1081
|
+
void emit("configure_cloud_login", { step: "denied" });
|
|
1082
|
+
return { state: "denied" };
|
|
1083
|
+
case "unreachable":
|
|
1084
|
+
return { state: "unreachable", line: p.reason };
|
|
1085
|
+
// Expired, already claimed, or swept: in every case this link is done.
|
|
1086
|
+
default:
|
|
1087
|
+
return { state: "expired" };
|
|
1088
|
+
}
|
|
1089
|
+
},
|
|
1090
|
+
open: (link) => {
|
|
1091
|
+
if (!canOpenBrowser()) return false;
|
|
1092
|
+
openUrl(link);
|
|
1093
|
+
return true;
|
|
1094
|
+
},
|
|
1095
|
+
collapsed: (plan) => [...cloudLines(plan), ""],
|
|
1096
|
+
stdin,
|
|
1097
|
+
stdout,
|
|
1098
|
+
});
|
|
1099
|
+
};
|
|
1100
|
+
|
|
1101
|
+
// The interactive CONNECT step. A machine with no connection, or whose saved
|
|
1102
|
+
// key is refused, starts the browser login straight away — Tab or Esc there
|
|
1103
|
+
// opens the other options. A machine that is connected with a working key gets
|
|
1104
|
+
// the menu, "keep" first, so re-running config never opens a browser by itself.
|
|
1105
|
+
const chooseConnection = async (): Promise<CloudPlan | null> => {
|
|
1106
|
+
const verdict =
|
|
1107
|
+
saved && !saved.splitKeys
|
|
1108
|
+
? await transient("Checking your saved key…", () => checkCloudKey(saved.url, saved.token))
|
|
1109
|
+
: null;
|
|
1110
|
+
const savedBroken = verdict !== null && !verdict.ok && verdict.refused;
|
|
1111
|
+
const keptPlan: CloudPlan =
|
|
1112
|
+
verdict && verdict.ok
|
|
1113
|
+
? { kind: "kept", how: "saved", verified: true }
|
|
1114
|
+
: verdict && !verdict.refused
|
|
1115
|
+
? { kind: "kept", how: "saved", verified: false }
|
|
1116
|
+
: { kind: "kept", how: "skip", verified: false };
|
|
1117
|
+
const keepHint = !saved
|
|
1118
|
+
? ""
|
|
1119
|
+
: saved.splitKeys
|
|
1120
|
+
? "leave both keys as they are"
|
|
1121
|
+
: verdict?.ok
|
|
1122
|
+
? `${verdict.org ?? saved.org ?? hostOf(saved.url)} · key ${maskToken(saved.token)}`
|
|
1123
|
+
: savedBroken
|
|
1124
|
+
? "its key no longer works"
|
|
1125
|
+
: "its key couldn't be checked just now";
|
|
1126
|
+
|
|
1127
|
+
type Pick = "login" | "key" | "oss" | "keep";
|
|
1128
|
+
const login: SelectChoice<Pick> = {
|
|
1129
|
+
label: saved ? "Log in again" : "Log in to FailproofAI Cloud",
|
|
1130
|
+
value: "login",
|
|
1131
|
+
hint: savedBroken
|
|
1132
|
+
? "recommended · your saved key no longer works"
|
|
1133
|
+
: saved
|
|
1134
|
+
? "opens your browser and makes a new key"
|
|
1135
|
+
: "recommended · opens your browser",
|
|
1136
|
+
};
|
|
1137
|
+
const key: SelectChoice<Pick> = { label: "Paste an API key", value: "key", hint: "one you already have" };
|
|
1138
|
+
const oss: SelectChoice<Pick> = { label: "Use open source", value: "oss", hint: "skip the cloud" };
|
|
1139
|
+
const keep: SelectChoice<Pick> = { label: "Keep current connection", value: "keep", hint: keepHint };
|
|
1140
|
+
// No initial-cursor option on selectOne: the default is whatever is first.
|
|
1141
|
+
const choices = !saved ? [login, key, oss] : savedBroken ? [login, key, keep] : [keep, login, key];
|
|
1142
|
+
const leftLogin = (result: Awaited<ReturnType<typeof askLogin>>): CloudPlan | null | typeof BACK => {
|
|
1143
|
+
if (result === null || result === BACK) {
|
|
1144
|
+
if (result === BACK && loginUnsupported) {
|
|
1145
|
+
write([kit.caution(`${host} doesn't support logging in from here yet. Paste an API key instead.`), ""]);
|
|
1146
|
+
}
|
|
1147
|
+
return result;
|
|
1148
|
+
}
|
|
1149
|
+
return result.value;
|
|
1150
|
+
};
|
|
1151
|
+
|
|
1152
|
+
if (url && (!saved || savedBroken)) {
|
|
1153
|
+
if (savedBroken && verdict && !verdict.ok) {
|
|
1154
|
+
write([kit.caution(`Your saved key no longer works: ${verdict.reason}. Logging in again.`)]);
|
|
1155
|
+
}
|
|
1156
|
+
void emit("configure_cloud_choice", { choice: "login", connected: Boolean(saved), auto: true });
|
|
1157
|
+
const first = leftLogin(await askLogin(url));
|
|
1158
|
+
if (first !== BACK) return first;
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1161
|
+
for (;;) {
|
|
1162
|
+
const pick = await selectOne<Pick>({
|
|
1163
|
+
message: "Connect to cloud",
|
|
1164
|
+
meta: source ? `${host} · from ${source}` : host,
|
|
1165
|
+
choices: loginUnsupported ? choices.filter((c) => c.value !== "login") : choices,
|
|
1166
|
+
collapsed: (p) =>
|
|
1167
|
+
p === "keep" ? [...cloudLines(keptPlan), ""] : p === "oss" ? [...cloudLines({ kind: "oss" }), ""] : [],
|
|
1168
|
+
stdin,
|
|
1169
|
+
stdout,
|
|
1170
|
+
});
|
|
1171
|
+
if (pick === null) return null;
|
|
1172
|
+
void emit("configure_cloud_choice", { choice: pick, connected: Boolean(saved) });
|
|
1173
|
+
if (pick === "keep") return keptPlan;
|
|
1174
|
+
if (pick === "oss") return { kind: "oss" };
|
|
1175
|
+
if (pick === "key") {
|
|
1176
|
+
const answer = await askKey();
|
|
1177
|
+
if (answer === null) return null;
|
|
1178
|
+
if (answer === OPEN_SOURCE) continue;
|
|
1179
|
+
return planFor(answer);
|
|
1180
|
+
}
|
|
1181
|
+
if (!url) {
|
|
1182
|
+
write([kit.fail(badUrl ?? "No usable endpoint."), ""]);
|
|
1183
|
+
continue;
|
|
1184
|
+
}
|
|
1185
|
+
const result = leftLogin(await askLogin(url));
|
|
1186
|
+
if (result === BACK) continue;
|
|
1187
|
+
return result;
|
|
1188
|
+
}
|
|
1189
|
+
};
|
|
1190
|
+
|
|
1001
1191
|
let cloud: CloudPlan;
|
|
1002
1192
|
if (answers.oss) {
|
|
1003
1193
|
cloud = saved ? { kind: "kept", how: "skip", verified: false } : { kind: "oss" };
|
|
@@ -1032,11 +1222,12 @@ export async function runConfigureWizard(
|
|
|
1032
1222
|
cloud = saved ? { kind: "kept", how: "skip", verified: false } : { kind: "oss" };
|
|
1033
1223
|
write([...cloudLines(cloud), ""]);
|
|
1034
1224
|
} else {
|
|
1035
|
-
// Said above the
|
|
1225
|
+
// Said above the menu, which stays usable for keeping a saved key and for
|
|
1226
|
+
// open source, neither of which sends anything anywhere.
|
|
1036
1227
|
if (badUrl) write([kit.fail(badUrl)]);
|
|
1037
|
-
const
|
|
1038
|
-
if (
|
|
1039
|
-
cloud =
|
|
1228
|
+
const chosen = await chooseConnection();
|
|
1229
|
+
if (chosen === null) return cancel();
|
|
1230
|
+
cloud = chosen;
|
|
1040
1231
|
}
|
|
1041
1232
|
|
|
1042
1233
|
// ── AGENTS ──────────────────────────────────────────────────────────────────
|
|
@@ -1049,8 +1240,10 @@ export async function runConfigureWizard(
|
|
|
1049
1240
|
// Whether the daemon will be collecting once this run ends: a key is already
|
|
1050
1241
|
// on disk, or this run writes one. Removal copy and the backfill request both
|
|
1051
1242
|
// depend on it.
|
|
1052
|
-
|
|
1053
|
-
const
|
|
1243
|
+
// A browser login connects exactly like a pasted key, one step later.
|
|
1244
|
+
const connecting = cloud.kind === "connect" || cloud.kind === "login";
|
|
1245
|
+
const collectingAfter = connecting || readIngestCredential() !== null;
|
|
1246
|
+
const sessionsOn = connecting ? answers.noTranscripts !== true : fp.collector.sessions === true;
|
|
1054
1247
|
|
|
1055
1248
|
let selected: IntegrationType[];
|
|
1056
1249
|
if (answers.agents && answers.agents.length > 0) {
|
|
@@ -1105,6 +1298,37 @@ export async function runConfigureWizard(
|
|
|
1105
1298
|
// 5. The connection last.
|
|
1106
1299
|
const done: string[] = [];
|
|
1107
1300
|
let daemonInstalled = daemonAlreadyRunning;
|
|
1301
|
+
// The `sudo -v` at the top cached root for sudo's timeout — five minutes by
|
|
1302
|
+
// default on macOS, fifteen on most Linux. A browser login, or simply a slow
|
|
1303
|
+
// agents screen, can outlast it, and the install below runs `sudo -n`, which
|
|
1304
|
+
// would then fail AFTER the person did everything else. Ask once more instead.
|
|
1305
|
+
// The stale-unit refresh runs `sudo -n` too, so it is asked for the same way —
|
|
1306
|
+
// but, as at the top, losing root there costs the scheduled audit, not setup.
|
|
1307
|
+
// Unattended runs never primed anything, so there is nothing to have expired.
|
|
1308
|
+
if ((daemonWanted || daemonUnitStale) && !unattended) {
|
|
1309
|
+
let stillRoot = false;
|
|
1310
|
+
try {
|
|
1311
|
+
stillRoot = canElevate();
|
|
1312
|
+
} catch {
|
|
1313
|
+
stillRoot = false;
|
|
1314
|
+
}
|
|
1315
|
+
if (!stillRoot && daemonWanted) {
|
|
1316
|
+
if (!elevate("Your sudo session expired while you were away. Installing failproofaid needs root again.")) {
|
|
1317
|
+
write([
|
|
1318
|
+
kit.fail("Couldn't get root, so setup stopped before changing anything."),
|
|
1319
|
+
` Re-run once you can use sudo: ${kit.cmd("failproofai config")}`,
|
|
1320
|
+
]);
|
|
1321
|
+
void emit("configure_aborted", { reason: "needs_root" });
|
|
1322
|
+
return { applied: false, abort: "needs_root" };
|
|
1323
|
+
}
|
|
1324
|
+
} else if (
|
|
1325
|
+
!stillRoot &&
|
|
1326
|
+
!elevate("Your sudo session expired while you were away. Refreshing failproofaid's service definition needs root again.")
|
|
1327
|
+
) {
|
|
1328
|
+
done.push(kit.caution("No root, so its service definition stays as it is. Scheduled audits stay off until it is refreshed."));
|
|
1329
|
+
daemonUnitStale = false;
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1108
1332
|
if (daemonWanted) {
|
|
1109
1333
|
// A unit that is running but cannot answer is torn down before it is
|
|
1110
1334
|
// rebuilt: it holds the singleton flock the replacement needs, so
|
|
@@ -1214,7 +1438,7 @@ export async function runConfigureWizard(
|
|
|
1214
1438
|
pruneOldDaemonBinaries();
|
|
1215
1439
|
}
|
|
1216
1440
|
|
|
1217
|
-
const connectedAfterPlan =
|
|
1441
|
+
const connectedAfterPlan = connecting || cloud.kind === "kept";
|
|
1218
1442
|
// Telemetry runs concurrently with the rest of apply (never rejects,
|
|
1219
1443
|
// 5s-bounded) and is awaited before returning. `cli` carries the selected
|
|
1220
1444
|
// agent ids, as it always has (and as hooks_installed does): a fixed list of
|
|
@@ -1225,7 +1449,7 @@ export async function runConfigureWizard(
|
|
|
1225
1449
|
cli: selected,
|
|
1226
1450
|
cli_count: selected.length,
|
|
1227
1451
|
policy_count: (readScopedHooksConfig("user", cwd).enabledPolicies ?? []).length,
|
|
1228
|
-
connected:
|
|
1452
|
+
connected: connecting,
|
|
1229
1453
|
mode: connectedAfterPlan ? "cloud" : "oss",
|
|
1230
1454
|
agents_selected: selected.length,
|
|
1231
1455
|
agents_detected: plan.detected.size,
|
|
@@ -1273,8 +1497,36 @@ export async function runConfigureWizard(
|
|
|
1273
1497
|
// a key on disk doing nothing. `connectToCloud` re-verifies each capability
|
|
1274
1498
|
// and writes only what works.
|
|
1275
1499
|
let connected = false;
|
|
1276
|
-
|
|
1277
|
-
|
|
1500
|
+
// A browser login has an approval, not a key: claim it NOW, with the daemon
|
|
1501
|
+
// in, so a run that stopped earlier left nothing minted anywhere. The claim
|
|
1502
|
+
// is single-use — the server mints the key and hands it over exactly once.
|
|
1503
|
+
let token: string | null = cloud.kind === "connect" ? cloud.token : null;
|
|
1504
|
+
let orgLabel: string | undefined = cloud.kind === "connect" ? cloud.org : undefined;
|
|
1505
|
+
let mintedName: string | undefined;
|
|
1506
|
+
if (cloud.kind === "login" && url) {
|
|
1507
|
+
const claimed = await transient("Creating this machine's key…", () => claimLogin(url, cloud.pollSecret));
|
|
1508
|
+
void emit("configure_cloud_login", { step: "claimed", ok: claimed.kind === "ok", reason: claimed.kind });
|
|
1509
|
+
if (claimed.kind === "ok") {
|
|
1510
|
+
token = claimed.key;
|
|
1511
|
+
orgLabel = loginOrgLabel(claimed.org);
|
|
1512
|
+
mintedName = claimed.keyName;
|
|
1513
|
+
} else {
|
|
1514
|
+
hookLogWarn(`cloud login could not be completed: ${claimed.kind}`);
|
|
1515
|
+
done.push(
|
|
1516
|
+
kit.caution(
|
|
1517
|
+
claimed.kind === "expired"
|
|
1518
|
+
? "The login took too long to finish, so no key was created. Everything else was applied."
|
|
1519
|
+
: claimed.kind === "revoked"
|
|
1520
|
+
? "Whoever approved the login can no longer create keys in that org, so no key was created."
|
|
1521
|
+
: claimed.kind === "unreachable"
|
|
1522
|
+
? `Couldn't reach ${host} to create the key (${claimed.reason}); everything else was applied.`
|
|
1523
|
+
: `The key couldn't be created: ${claimed.reason}. Everything else was applied.`,
|
|
1524
|
+
"failproofai config",
|
|
1525
|
+
),
|
|
1526
|
+
);
|
|
1527
|
+
}
|
|
1528
|
+
}
|
|
1529
|
+
if (token && url) {
|
|
1278
1530
|
try {
|
|
1279
1531
|
const outcome = await transient("Connecting…", () =>
|
|
1280
1532
|
connectToCloud({
|
|
@@ -1288,7 +1540,12 @@ export async function runConfigureWizard(
|
|
|
1288
1540
|
);
|
|
1289
1541
|
connected = outcome.anyConfigured;
|
|
1290
1542
|
done.push(...(outcome.changes ?? []));
|
|
1291
|
-
done.push(...connectDoneLines(kit, outcome, host,
|
|
1543
|
+
done.push(...connectDoneLines(kit, outcome, host, orgLabel));
|
|
1544
|
+
// Logging in again makes a NEW key; the one this machine held keeps
|
|
1545
|
+
// working until someone revokes it. Said here, where it is still useful.
|
|
1546
|
+
if (cloud.kind === "login" && saved && connected) {
|
|
1547
|
+
done.push(` Your previous key for this machine still works until you revoke it on ${host}'s keys page.`);
|
|
1548
|
+
}
|
|
1292
1549
|
if (outcome.ingest.ok && answers.noTranscripts === true) {
|
|
1293
1550
|
done.push(" Decisions only: session transcripts are not sent (--no-transcripts).");
|
|
1294
1551
|
}
|
|
@@ -1298,12 +1555,22 @@ export async function runConfigureWizard(
|
|
|
1298
1555
|
hookLogWarn(`cloud connection was not written: ${err instanceof Error ? err.message : String(err)}`);
|
|
1299
1556
|
done.push(kit.caution("Couldn't connect; everything else was applied.", "failproofai config"));
|
|
1300
1557
|
}
|
|
1558
|
+
// The claim spent the approval and the key exists, but nothing here uses
|
|
1559
|
+
// it: say which one, so it can be revoked rather than left live.
|
|
1560
|
+
if (cloud.kind === "login" && !connected) {
|
|
1561
|
+
done.push(` The key ${mintedName ? `"${mintedName}" ` : ""}was created but isn't in use here; revoke it on ${host}'s keys page.`);
|
|
1562
|
+
}
|
|
1301
1563
|
} else if (cloud.kind === "kept" && cloud.how === "saved" && fp.mode !== "cloud") {
|
|
1302
1564
|
// A home migrated from layout 1 carries keys but no mode, and would read
|
|
1303
1565
|
// as open source everywhere that asks.
|
|
1304
1566
|
updateConfig({ mode: "cloud" });
|
|
1305
1567
|
}
|
|
1306
1568
|
|
|
1569
|
+
// Logging in again on a connected machine, with no key at the end of it,
|
|
1570
|
+
// changed nothing about the connection: the previous one is still there.
|
|
1571
|
+
const keptOld = cloud.kind === "login" && !token && saved !== undefined;
|
|
1572
|
+
if (keptOld) done.push(" This machine keeps its previous connection.");
|
|
1573
|
+
|
|
1307
1574
|
await applied;
|
|
1308
1575
|
// Only now — a completed apply — is the launcher considered "seen", so
|
|
1309
1576
|
// first-run onboarding stops offering itself on every command.
|
|
@@ -1321,7 +1588,7 @@ export async function runConfigureWizard(
|
|
|
1321
1588
|
done,
|
|
1322
1589
|
cwd,
|
|
1323
1590
|
agents: selected.length,
|
|
1324
|
-
connected: connected || cloud.kind === "kept",
|
|
1591
|
+
connected: connected || cloud.kind === "kept" || keptOld,
|
|
1325
1592
|
codexTrust,
|
|
1326
1593
|
}),
|
|
1327
1594
|
);
|
|
@@ -1334,7 +1601,7 @@ export async function runConfigureWizard(
|
|
|
1334
1601
|
policies,
|
|
1335
1602
|
daemonInstalled,
|
|
1336
1603
|
connected,
|
|
1337
|
-
mode: connected || cloud.kind === "kept" ? "cloud" : "oss",
|
|
1604
|
+
mode: connected || cloud.kind === "kept" || keptOld ? "cloud" : "oss",
|
|
1338
1605
|
agents: { selected, added, removed },
|
|
1339
1606
|
};
|
|
1340
1607
|
}
|
|
@@ -1345,7 +1612,19 @@ export async function runConfigureWizard(
|
|
|
1345
1612
|
type CloudPlan =
|
|
1346
1613
|
| { kind: "oss" }
|
|
1347
1614
|
| { kind: "kept"; how: "skip" | "saved"; verified: boolean }
|
|
1348
|
-
| { kind: "connect"; token: string; org?: string; note?: string }
|
|
1615
|
+
| { kind: "connect"; token: string; org?: string; note?: string }
|
|
1616
|
+
/**
|
|
1617
|
+
* Approved in the browser, not yet claimed. The key does not exist until
|
|
1618
|
+
* apply claims it — after the daemon is in — so a run that stops before then
|
|
1619
|
+
* leaves no key behind anywhere.
|
|
1620
|
+
*/
|
|
1621
|
+
| { kind: "login"; pollSecret: string; org: LoginOrg; approvedBy?: string; keyName?: string; permissions: string[] };
|
|
1622
|
+
|
|
1623
|
+
/** "Acme (acme)", or whichever half the server sent. */
|
|
1624
|
+
function loginOrgLabel(org: LoginOrg): string {
|
|
1625
|
+
if (org.name && org.slug) return `${org.name} (${org.slug})`;
|
|
1626
|
+
return org.name ?? org.slug ?? "your org";
|
|
1627
|
+
}
|
|
1349
1628
|
|
|
1350
1629
|
/**
|
|
1351
1630
|
* The connection already on this machine, from either credential: the policy
|
|
@@ -1394,7 +1673,15 @@ export function resolveCloudUrl(
|
|
|
1394
1673
|
const env = process.env.FAILPROOFAI_CLOUD_URL?.trim();
|
|
1395
1674
|
const fromFlag = flag?.trim();
|
|
1396
1675
|
const override = fromFlag || env;
|
|
1397
|
-
if (!override)
|
|
1676
|
+
if (!override) {
|
|
1677
|
+
if (!existing) return { ok: true, url: cloudBaseFor(DEFAULT_INGEST_URL) };
|
|
1678
|
+
// Checked like a typed one: login sends its secret and receives a key here
|
|
1679
|
+
// before anything else would, and the file it came from can be edited.
|
|
1680
|
+
const saved = validateCloudUrl(existing);
|
|
1681
|
+
return saved.ok
|
|
1682
|
+
? { ok: true, url: existing }
|
|
1683
|
+
: { ok: false, message: `the saved cloud address "${existing}" cannot be used: ${saved.reason}` };
|
|
1684
|
+
}
|
|
1398
1685
|
const source = fromFlag && fromFlag !== env ? "--url" : "FAILPROOFAI_CLOUD_URL";
|
|
1399
1686
|
const validated = validateCloudUrl(cloudBaseFor(override));
|
|
1400
1687
|
if (!validated.ok) {
|
|
@@ -1477,6 +1764,15 @@ export function cloudCollapsedLines(
|
|
|
1477
1764
|
kit.ok(plan.org ? `Key accepted for ${plan.org} on ${at.host}` : `Key accepted by ${at.host}`),
|
|
1478
1765
|
...(plan.note ? [kit.caution(plan.note)] : []),
|
|
1479
1766
|
];
|
|
1767
|
+
case "login":
|
|
1768
|
+
// Who approved it is said out loud: a link someone else approved into
|
|
1769
|
+
// THEIR org would otherwise connect this machine there unnoticed.
|
|
1770
|
+
return [
|
|
1771
|
+
head,
|
|
1772
|
+
kit.ok(
|
|
1773
|
+
`Logged in${plan.approvedBy ? ` as ${plan.approvedBy}` : ""} · ${loginOrgLabel(plan.org)} on ${at.host}`,
|
|
1774
|
+
),
|
|
1775
|
+
];
|
|
1480
1776
|
}
|
|
1481
1777
|
}
|
|
1482
1778
|
|
package/src/hooks/otel-cli.ts
CHANGED
|
@@ -12,10 +12,11 @@ import { collectorHealthFile, configFile, otelAgentStateFile, otlpHealthFile } f
|
|
|
12
12
|
import { writeConfigFileAtomic } from "./safe-config-write";
|
|
13
13
|
import { agentSessionsEnabled } from "./collector-config";
|
|
14
14
|
import { introspectKey } from "./cloud-introspect";
|
|
15
|
+
import { validateCloudUrl } from "./cloud-enrollment";
|
|
15
16
|
import { readJsonFile } from "./integrations";
|
|
16
17
|
import { selectOne } from "./tui";
|
|
17
18
|
import {
|
|
18
|
-
AGENT_LABELS, OTEL_AGENTS, agentConfigPath, agentOtelWrites, editAgentConfig,
|
|
19
|
+
AGENT_LABELS, OTEL_AGENTS, agentConfigPath, agentOtelWrites, editAgentConfig, otlpDestination, cloudOtlpBase,
|
|
19
20
|
getSetting, parseAgentConfig, vscodeInstalled,
|
|
20
21
|
type JsonObject, type OtelAgent, type SettingWrite,
|
|
21
22
|
} from "./otel-writers";
|
|
@@ -91,8 +92,13 @@ function credential(): { key: string; origin: string } {
|
|
|
91
92
|
const ingest = readCredentials().ingest;
|
|
92
93
|
const key = process.env.FAILPROOFAI_INGEST_KEY || ingest?.key;
|
|
93
94
|
if (!key) throw new Error("No Cloud API key configured. Run `failproofai config` first.");
|
|
94
|
-
const
|
|
95
|
-
|
|
95
|
+
const raw = process.env.FAILPROOFAI_INGEST_URL || ingest?.url || "https://app.befailproof.ai";
|
|
96
|
+
// Every caller sends or prints this key for the origin: the same rule as
|
|
97
|
+
// Cloud enrollment, https or loopback http only, so it never travels in clear.
|
|
98
|
+
const checked = validateCloudUrl(raw);
|
|
99
|
+
if (!checked.ok) throw new Error(`Invalid Cloud ingest URL: ${checked.reason}`);
|
|
100
|
+
const url = new URL(raw);
|
|
101
|
+
if (url.username || url.password) throw new Error("Invalid Cloud ingest URL.");
|
|
96
102
|
return { key, origin: url.origin };
|
|
97
103
|
}
|
|
98
104
|
function backupOnce(path: string, original: string | null): void {
|
|
@@ -185,7 +191,7 @@ async function enableAgent(agent: OtelAgent, yes: boolean, localFlag: boolean, c
|
|
|
185
191
|
const local = localFlag || agent === "copilot";
|
|
186
192
|
const port = readConfig().collector.otlp?.port ?? 4318;
|
|
187
193
|
if (!Number.isInteger(port) || port < 1 || port > 65535) throw new Error("collector.otlp.port must be between 1 and 65535.");
|
|
188
|
-
const destination = local
|
|
194
|
+
const destination = otlpDestination(origin, local, port);
|
|
189
195
|
const original = existsSync(file) ? readFileSync(file, "utf8") : null;
|
|
190
196
|
const parsed = parseAgentConfig(original ?? "", agent);
|
|
191
197
|
const oldState = existing ? privateState(agent) : null;
|
|
@@ -303,8 +309,12 @@ async function status(options: OtelOptions): Promise<OtelResult> {
|
|
|
303
309
|
try {
|
|
304
310
|
const state = privateState(agent);
|
|
305
311
|
const original = parseAgentConfig(state.original ?? "", agent);
|
|
312
|
+
const { key, origin } = credential();
|
|
313
|
+
// Cloud's address is recomputed, so settings written for an older
|
|
314
|
+
// address (or another Cloud) read as "not managed" until re-enabled.
|
|
315
|
+
const expectedDestination = record.local ? record.destination : cloudOtlpBase(origin);
|
|
306
316
|
const expected = parseAgentConfig(editAgentConfig(state.original ?? "", agent,
|
|
307
|
-
agentOtelWrites(agent,
|
|
317
|
+
agentOtelWrites(agent, expectedDestination, key, record.local, record.content, original)), agent);
|
|
308
318
|
managed = record.keys.every(k => JSON.stringify(getSetting(parsed, k.path)) === JSON.stringify(getSetting(expected, k.path)));
|
|
309
319
|
} catch { /* Missing recovery state or key. */ }
|
|
310
320
|
}
|
|
@@ -339,7 +349,7 @@ export async function runOtelCommand(args: string[], options: OtelOptions = {}):
|
|
|
339
349
|
const consumed = rest.filter((_, i) => i !== index && i !== index + 1 || index < 0).filter(x => x !== "--local");
|
|
340
350
|
if (consumed.length) throw new Error("env takes only --service <name> and --local.");
|
|
341
351
|
const local = rest.includes("--local");
|
|
342
|
-
const endpoint = local
|
|
352
|
+
const endpoint = otlpDestination(origin, local, readConfig().collector.otlp?.port ?? 4318);
|
|
343
353
|
const quote = (s: string) => `'${s.replace(/'/g, "'\\''")}'`;
|
|
344
354
|
const values = {
|
|
345
355
|
OTEL_EXPORTER_OTLP_ENDPOINT: endpoint, OTEL_EXPORTER_OTLP_PROTOCOL: "http/protobuf",
|
|
@@ -186,6 +186,19 @@ export function editAgentConfig(text: string, agent: OtelAgent, writes: SettingW
|
|
|
186
186
|
return next;
|
|
187
187
|
}
|
|
188
188
|
|
|
189
|
+
/**
|
|
190
|
+
* FailproofAI Cloud's OTLP base URL. Exporters append `/v1/<signal>` to it, as
|
|
191
|
+
* the OTLP spec says. The local relay is plain `http://127.0.0.1:<port>`.
|
|
192
|
+
*/
|
|
193
|
+
export function cloudOtlpBase(origin: string): string {
|
|
194
|
+
return `${origin.replace(/\/+$/, "")}/otel`;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/** Where an agent's exporter points: the local relay, or Cloud's OTLP base. */
|
|
198
|
+
export function otlpDestination(origin: string, local: boolean, port: number): string {
|
|
199
|
+
return local ? `http://127.0.0.1:${port}` : cloudOtlpBase(origin);
|
|
200
|
+
}
|
|
201
|
+
|
|
189
202
|
export function agentOtelWrites(agent: OtelAgent, endpoint: string, key: string, local: boolean, content: boolean, config: JsonObject = {}): SettingWrite[] {
|
|
190
203
|
const auth = local ? {} : { Authorization: `Bearer ${key}` };
|
|
191
204
|
const env: JsonObject = {
|