failproofai 1.0.4-beta.1 → 1.0.4-beta.4
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 +5 -5
- package/.next/standalone/.next/prerender-manifest.json +5 -5
- package/.next/standalone/.next/required-server-files.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page/build-manifest.json +2 -2
- 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.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 +6 -6
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
- 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 +2 -2
- 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.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/_not-found/__PAGE__.segment.rsc +14 -14
- 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.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/audit/invite/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/audit/run/route.js +4 -4
- package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/audit/run/route_client-reference-manifest.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/audit/status/route_client-reference-manifest.js +1 -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-request/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/login-verify/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/status/route_client-reference-manifest.js +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/api/download/[project]/[session]/route_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/audit/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +37 -4
- package/.next/standalone/.next/server/app/audit/page.js +2 -2
- 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 +14 -14
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
- package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/policies/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +14 -14
- package/.next/standalone/.next/server/app/policies/page.js +1 -1
- 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 +2 -2
- 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 +3 -3
- 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 +2 -2
- 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 +2 -2
- 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 +2 -2
- package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/projects/page.js +1 -1
- 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 +2 -2
- package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +4 -4
- 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]__1zndo1i._.js → [externals]__0v1hz15._.js} +1 -1
- package/.next/standalone/.next/server/chunks/{[externals]__0_gzk8q._.js → [externals]__1nb206a._.js} +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0--lkk6._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__08dchfu._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0cuho4x._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o07qi9._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0q0qzx1._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1adacul._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1le9jqc._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1p-qi2t._.js +5 -0
- package/.next/standalone/.next/server/chunks/_09dz7xv._.js +1 -1
- package/.next/standalone/.next/server/chunks/_0otft92._.js +3 -0
- package/.next/standalone/.next/server/chunks/_0tovk6q._.js +1 -1
- package/.next/standalone/.next/server/chunks/_0trp3yc._.js +1 -1
- package/.next/standalone/.next/server/chunks/_1ek68ln._.js +14 -21
- package/.next/standalone/.next/server/chunks/_1vslkoe._.js +1 -1
- package/.next/standalone/.next/server/chunks/lib_factory-projects_ts_1eo_bk-._.js +1 -1
- package/.next/standalone/.next/server/chunks/lib_telemetry_ts_0dctyyw._.js +1 -1
- package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_01r25oi._.js +2 -2
- package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_09z9-p7._.js +2 -2
- package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
- package/.next/standalone/.next/server/chunks/src_hooks_0iu54mz._.js +1 -1
- package/.next/standalone/.next/server/chunks/src_hooks_fp-home_ts_09kv0bn._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__00-s7h8._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__013jr2b._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__01wy8d-._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__02npjtd._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0da85px._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ftmoxc._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0wvusu0._.js → [root-of-the-server]__0n_lxhg._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0oa1lav._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0p-5p8u._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0s740oi._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__16gamwq._.js → [root-of-the-server]__0yl9wb5._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__190won8._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1ctpynv._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1p2otjt._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1qapotl._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1sc84bb._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1zl_r0t._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_0-yi74u._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_08x1r5t._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{_1byck5v._.js → _0guxnh-._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_0l2hi_d._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_0oq1dh6._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_0wso5d3._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_1_ozgif._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_1es2j7i._.js +61 -168
- package/.next/standalone/.next/server/chunks/ssr/{_08f0jd2._.js → _1if9ixi._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_1u8-lu2._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_next-internal_server_app_policies_page_actions_1sp2-yo.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +1 -69
- package/.next/standalone/.next/server/chunks/ssr/app_audit__components_rerun-button_tsx_0blihgw._.js +3 -0
- 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 +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_settings_settings-client_tsx_20lq-mq._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules_13n822a._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules_posthog-node_dist_entrypoints_index_node_mjs_11bnuzn._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_builtin-policies_ts_09j2ndl._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_fp-config_ts_04t589g._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_fp-home_ts_0je3xkv._.js +1 -1
- package/.next/standalone/.next/server/middleware-build-manifest.js +5 -5
- 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 -21
- package/.next/standalone/.next/static/chunks/04o5zfl7p5lhx.js +1 -0
- package/.next/standalone/.next/static/chunks/{29-iqnp9v_axt.css → 0jpd8dv2vk930.css} +1 -1
- package/.next/standalone/.next/static/chunks/{1po3lirgk2riw.js → 0po8n4tyotjf2.js} +1 -1
- package/.next/standalone/.next/static/chunks/0qmsunv04x4na.css +2 -0
- package/.next/standalone/.next/static/chunks/0qx7gav1c2_vu.js +1 -0
- package/.next/standalone/.next/static/chunks/17tfki9x5rd_7.js +1 -0
- package/.next/standalone/.next/static/chunks/{1_bxotmf9qngs.js → 1i-i0pxg9q_8y.js} +1 -1
- package/.next/standalone/.next/static/chunks/{1_2jsatfuthrw.js → 2bxr2_2h4kaqq.js} +1 -1
- package/.next/standalone/.next/static/chunks/{01hvwwrhvbzyh.js → 2zafgs90r_leq.js} +1 -1
- package/.next/standalone/.next/static/chunks/{00gv0v91mycm-.js → 323cyb3a2s06y.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0qn9khv0oo9ex.js → 364cqbpeg1y5i.js} +1 -1
- package/.next/standalone/.next/static/chunks/{2bvwsyu6x__ia.js → 38dqur43qthrl.js} +1 -1
- package/.next/standalone/.next/static/chunks/{3_--3ibia6ba1.js → 3l36d73kj18zw.js} +1 -1
- package/.next/standalone/.next/static/chunks/{2k9f4tyv04809.css → 3uyhmm01g64k4.css} +1 -0
- package/.next/standalone/.next/static/chunks/{2bnf_4pgyk1rq.js → 40lpt2o2b283e.js} +1 -1
- package/.next/standalone/.next/static/chunks/42gwu2bsz4ske.js +6 -0
- package/.next/standalone/.next/static/chunks/{turbopack-18qf4jodtft6b.js → turbopack-3s3c-u_u_l0u9.js} +1 -1
- package/.next/standalone/.opencode/plugins/failproofai.mjs +51 -27
- package/.next/standalone/app/actions/get-leaks.ts +109 -0
- package/.next/standalone/app/audit/_components/audit-dashboard.tsx +140 -34
- package/.next/standalone/app/audit/_components/audit-poster.tsx +29 -10
- package/.next/standalone/app/audit/_components/come-back-better-section.tsx +6 -1
- package/.next/standalone/app/audit/_components/empty-state.tsx +4 -1
- package/.next/standalone/app/audit/_components/how-to-improve-section.tsx +19 -5
- package/.next/standalone/app/audit/_components/leak-section.tsx +192 -0
- package/.next/standalone/app/audit/_components/share-templates.ts +110 -44
- package/.next/standalone/app/audit/audit-styles.css +132 -1
- package/.next/standalone/app/project/[name]/page.tsx +4 -24
- package/.next/standalone/fp-cloud-cli/CHANGELOG.md +26 -3
- package/.next/standalone/fp-cloud-cli/fp_cli/_click_compat.py +31 -8
- package/.next/standalone/fp-cloud-cli/fp_cli/permissions.py +1 -0
- package/.next/standalone/fp-cloud-cli/pyproject.toml +9 -2
- package/.next/standalone/fp-cloud-cli/tests/test_click_compat.py +54 -0
- package/.next/standalone/fp-cloud-cli/uv.lock +9 -12
- package/.next/standalone/lib/auth/api-server-client.ts +28 -0
- package/.next/standalone/lib/claude-sessions.ts +101 -27
- package/.next/standalone/lib/cli-registry.ts +1 -33
- package/.next/standalone/lib/download-session.ts +0 -37
- package/.next/standalone/lib/projects.ts +3 -27
- package/.next/standalone/lib/sqlite-reader.ts +78 -1
- package/.next/standalone/node_modules/@next/env/package.json +1 -1
- package/.next/standalone/node_modules/next/dist/build/swc/index.js +1 -1
- package/.next/standalone/node_modules/next/dist/compiled/next-server/pages-turbo.runtime.prod.js +1 -1
- package/.next/standalone/node_modules/next/dist/experimental/testmode/fetch.js +10 -2
- package/.next/standalone/node_modules/next/dist/lib/patch-incorrect-lockfile.js +3 -3
- package/.next/standalone/node_modules/next/dist/lib/typescript/runTypeScriptCli.js +2 -2
- package/.next/standalone/node_modules/next/dist/lib/verify-typescript-setup.js +3 -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/image-optimizer.js +2 -2
- package/.next/standalone/node_modules/next/dist/server/lib/app-info-log.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/lib/start-server.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 +15 -14
- package/.next/standalone/sdk/python/CHANGELOG.md +155 -0
- package/.next/standalone/sdk/python/README.md +8 -0
- package/.next/standalone/sdk/python/examples/evaluator_worker.py +121 -0
- package/.next/standalone/sdk/python/failproofai_sdk/_version.py +1 -1
- package/.next/standalone/sdk/python/failproofai_sdk/evaluator/__init__.py +101 -0
- package/.next/standalone/sdk/python/failproofai_sdk/evaluator/__main__.py +49 -0
- package/.next/standalone/sdk/python/failproofai_sdk/evaluator/_sandbox_runner.py +63 -0
- package/.next/standalone/sdk/python/failproofai_sdk/evaluator/authoring.py +404 -0
- package/.next/standalone/sdk/python/failproofai_sdk/evaluator/client.py +299 -0
- package/.next/standalone/sdk/python/failproofai_sdk/evaluator/protocol.py +754 -0
- package/.next/standalone/sdk/python/failproofai_sdk/evaluator/runtime.py +936 -0
- package/.next/standalone/sdk/python/failproofai_sdk/evaluator/source.py +684 -0
- package/.next/standalone/sdk/python/tests/fixtures/evaluator_v2/README.md +28 -0
- package/.next/standalone/sdk/python/tests/fixtures/evaluator_v2/contract.json +252 -0
- package/.next/standalone/sdk/python/tests/test_evaluator_authoring.py +124 -0
- package/.next/standalone/sdk/python/tests/test_evaluator_client.py +253 -0
- package/.next/standalone/sdk/python/tests/test_evaluator_example.py +35 -0
- package/.next/standalone/sdk/python/tests/test_evaluator_http_e2e.py +636 -0
- package/.next/standalone/sdk/python/tests/test_evaluator_main.py +47 -0
- package/.next/standalone/sdk/python/tests/test_evaluator_protocol.py +246 -0
- package/.next/standalone/sdk/python/tests/test_evaluator_review_fixes.py +164 -0
- package/.next/standalone/sdk/python/tests/test_evaluator_runtime.py +1103 -0
- package/.next/standalone/sdk/python/tests/test_evaluator_source.py +430 -0
- package/.next/standalone/sdk/python/tests/test_zero_dependencies.py +17 -0
- package/.next/standalone/sdk/python/uv.lock +18 -18
- package/.next/standalone/server.js +1 -1
- package/README.md +19 -95
- package/bin/failproofai.mjs +8 -25
- package/dist/cli.mjs +20091 -25864
- package/dist/worker.mjs +4881 -6361
- package/lib/auth/api-server-client.ts +28 -0
- package/lib/claude-sessions.ts +101 -27
- package/lib/cli-registry.ts +1 -33
- package/lib/download-session.ts +0 -37
- package/lib/projects.ts +3 -27
- package/lib/sqlite-reader.ts +78 -1
- package/package.json +15 -14
- package/pi-extension/index.ts +61 -8
- package/scripts/changelog-open.py +115 -0
- package/src/audit/cache.ts +6 -0
- package/src/audit/cli-adapters/claude.ts +13 -0
- package/src/audit/cli-adapters/index.ts +0 -24
- package/src/audit/cli-login.ts +4 -1
- package/src/audit/cli.ts +164 -5
- package/src/audit/desktop-notify.ts +420 -0
- package/src/audit/harm-report.ts +101 -0
- package/src/audit/index.ts +284 -15
- package/src/audit/leak-fingerprint.ts +200 -0
- package/src/audit/leak-notice.ts +259 -0
- package/src/audit/leak-record.ts +232 -0
- package/src/audit/leak-scan.ts +268 -0
- package/src/audit/leak-store.ts +265 -0
- package/src/audit/macos-notifier.ts +310 -0
- package/src/audit/redact-example.ts +322 -15
- package/src/audit/report-harm.ts +12 -1
- package/src/audit/report.ts +6 -3
- package/src/audit/schedule-cli.ts +37 -0
- package/src/audit/scoring.ts +49 -0
- package/src/audit/types.ts +47 -0
- package/src/hooks/builtin-policies.ts +71 -8
- package/src/hooks/configure-wizard.ts +20 -0
- package/src/hooks/enforcement-capability.ts +0 -97
- package/src/hooks/fp-config.ts +71 -11
- package/src/hooks/fp-home.ts +27 -0
- package/src/hooks/handler.ts +84 -62
- package/src/hooks/harness-cli.ts +1 -3
- package/src/hooks/integrations.ts +63 -769
- package/src/hooks/normalize-cli-payload.ts +0 -126
- package/src/hooks/notice.ts +191 -0
- package/src/hooks/policy-evaluator.ts +6 -297
- package/src/hooks/resolve-transcript-path.ts +0 -10
- package/src/hooks/tool-name-canonicalize.ts +0 -64
- package/src/hooks/types.ts +2 -533
- package/src/hooks/uninstall-cli.ts +15 -0
- package/.next/standalone/.grok/hooks/failproofai.json +0 -172
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__07hor7h._.js +0 -5
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0elsuli._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0gnj_qa._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ljuzm_._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0w23bpg._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0x5c7sh._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0yik9_w._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1jg6s9m._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1s6qci9._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1xfm05z._.js +0 -3
- package/.next/standalone/.next/server/chunks/_0tdy_6l._.js +0 -3
- package/.next/standalone/.next/server/chunks/lib_grok-projects_ts_1i2epl_._.js +0 -3
- package/.next/standalone/.next/server/chunks/lib_qwen-projects_ts_0wu_a8e._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0_4gcz8._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0d--wmy._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qqrlf_._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0s11fx1._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1bbk-si._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1c3ybxr._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1izi7zn._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__21bj7uw._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_00z5uuq._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_1ylae7o._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_1zopuov._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/lib_cline-projects_ts_13_hbdd._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/lib_grok-projects_ts_0rc-d0o._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/lib_ori-projects_ts_04tofqo._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/lib_qwen-projects_ts_0w3i9o7._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/node_modules_html-to-image_es_index_1ao30b1.js +0 -3
- package/.next/standalone/.next/static/chunks/0hzmxwb2pvk5p.js +0 -6
- package/.next/standalone/.next/static/chunks/0j884dwnwtyrt.js +0 -1
- package/.next/standalone/.next/static/chunks/0mr9dg3bnloa1.js +0 -1
- package/.next/standalone/.next/static/chunks/0u64yey446k4f.css +0 -1
- package/.next/standalone/.next/static/chunks/3gf1jg-5m-u1t.css +0 -2
- package/.next/standalone/.next/static/chunks/3qfoeqhy5l10x.js +0 -1
- package/.next/standalone/.next/static/chunks/3ws7eljkq25wg.js +0 -69
- package/.next/standalone/.next/static/chunks/3zkg2s2vzxc3d.js +0 -1
- package/.next/standalone/.qwen/settings.json +0 -251
- package/.next/standalone/assets/logos/cline.png +0 -0
- package/.next/standalone/assets/logos/grok-dark.svg +0 -1
- package/.next/standalone/assets/logos/grok-light.svg +0 -1
- package/.next/standalone/assets/logos/ori-dark.svg +0 -1
- package/.next/standalone/assets/logos/ori-light.svg +0 -1
- package/.next/standalone/assets/logos/qwen.svg +0 -1
- package/.next/standalone/lib/cline-projects.ts +0 -155
- package/.next/standalone/lib/cline-sessions.ts +0 -268
- package/.next/standalone/lib/grok-projects.ts +0 -123
- package/.next/standalone/lib/grok-sessions.ts +0 -355
- package/.next/standalone/lib/ori-projects.ts +0 -141
- package/.next/standalone/lib/ori-sessions.ts +0 -221
- package/.next/standalone/lib/qwen-projects.ts +0 -106
- package/.next/standalone/lib/qwen-sessions.ts +0 -313
- package/lib/cline-projects.ts +0 -155
- package/lib/cline-sessions.ts +0 -268
- package/lib/grok-projects.ts +0 -123
- package/lib/grok-sessions.ts +0 -355
- package/lib/ori-projects.ts +0 -141
- package/lib/ori-sessions.ts +0 -221
- package/lib/qwen-projects.ts +0 -106
- package/lib/qwen-sessions.ts +0 -313
- package/src/audit/cli-adapters/cline.ts +0 -50
- package/src/audit/cli-adapters/grok.ts +0 -70
- package/src/audit/cli-adapters/ori.ts +0 -55
- package/src/audit/cli-adapters/qwen.ts +0 -71
- package/src/hooks/batch-expand.ts +0 -380
- package/src/hooks/batch-fanout.ts +0 -142
- package/src/hooks/risk-patterns.ts +0 -26
- /package/.next/standalone/.next/static/{qJx3mbOQV-5ElrcRb4Sp7 → P6icI2V2PvVuePJrqjHCr}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{qJx3mbOQV-5ElrcRb4Sp7 → P6icI2V2PvVuePJrqjHCr}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{qJx3mbOQV-5ElrcRb4Sp7 → P6icI2V2PvVuePJrqjHCr}/_ssgManifest.js +0 -0
|
@@ -12,13 +12,18 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import { useMemo, useState } from "react";
|
|
14
14
|
import type { AuditResult } from "@/src/audit/types";
|
|
15
|
-
|
|
15
|
+
// Score switched off — see `src/audit/scoring.ts`.
|
|
16
|
+
// import { type Grade, tierName } from "@/src/audit/scoring";
|
|
17
|
+
import type { Grade } from "@/src/audit/scoring";
|
|
16
18
|
import { usePostHog } from "@/contexts/PostHogContext";
|
|
17
19
|
|
|
18
20
|
interface Props {
|
|
19
21
|
result: AuditResult;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
+
/** The projection is switched off — see `src/audit/scoring.ts`. Optional
|
|
23
|
+
* rather than removed so restoring it is un-commenting the two lines in
|
|
24
|
+
* `audit-dashboard.tsx` and the sub-heading below. */
|
|
25
|
+
projected?: number;
|
|
26
|
+
projectedGrade?: Grade;
|
|
22
27
|
}
|
|
23
28
|
|
|
24
29
|
const DETECTOR_TO_PRIMARY_POLICY: Record<string, string> = {
|
|
@@ -99,7 +104,7 @@ function bulkInstall(fixes: FixRow[]): string {
|
|
|
99
104
|
return `failproofai policies --install ${fixes.map((f) => f.name).join(" ")}`;
|
|
100
105
|
}
|
|
101
106
|
|
|
102
|
-
export function HowToImproveSection({ result
|
|
107
|
+
export function HowToImproveSection({ result }: Props) {
|
|
103
108
|
const { capture } = usePostHog();
|
|
104
109
|
const fixes = useMemo(() => buildFixes(result), [result]);
|
|
105
110
|
const installAllCmd = useMemo(() => bulkInstall(fixes), [fixes]);
|
|
@@ -136,9 +141,18 @@ export function HowToImproveSection({ result, projected, projectedGrade }: Props
|
|
|
136
141
|
</button>
|
|
137
142
|
</div>
|
|
138
143
|
<h2 className="audit-sec-title">install or configure</h2>
|
|
139
|
-
|
|
144
|
+
{/* The projected-score clause is switched off. It was also the one place
|
|
145
|
+
the product promised a number it could not deliver: `deriveScore`
|
|
146
|
+
never read `enabledInConfig`, so taking this prescription and
|
|
147
|
+
re-running returned the SAME score with the projection gone. What
|
|
148
|
+
replaces it is the thing that was always true — one command, enforced
|
|
149
|
+
on every tool call. Original:
|
|
140
150
|
enable all {fixes.length === 1 ? "one" : fixes.length} → projected{" "}
|
|
141
151
|
<strong>{projected}</strong> · {tierName(projectedGrade).toLowerCase()}
|
|
152
|
+
*/}
|
|
153
|
+
<div className="audit-sec-sub">
|
|
154
|
+
enable all {fixes.length === 1 ? "one" : fixes.length} → one command,
|
|
155
|
+
enforced on every tool call
|
|
142
156
|
</div>
|
|
143
157
|
|
|
144
158
|
<div className="fix-list">
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The leak report: every credential this machine found in its own transcripts.
|
|
5
|
+
*
|
|
6
|
+
* This is what replaced the persona poster and the five scored sections. The
|
|
7
|
+
* old report answered "what kind of agent user are you"; this one answers the
|
|
8
|
+
* only question a leaked key raises — what is it, where did it go, how did it
|
|
9
|
+
* get there, and what do I do now.
|
|
10
|
+
*
|
|
11
|
+
* Each row is one DISTINCT credential, not one sighting: a key pasted into
|
|
12
|
+
* forty commands is one thing to rotate, not forty. The count of exposures is a
|
|
13
|
+
* column, which is the honest way to show forty without implying forty problems.
|
|
14
|
+
*/
|
|
15
|
+
import { useCallback, useEffect, useState } from "react";
|
|
16
|
+
import {
|
|
17
|
+
dismissLeakAction,
|
|
18
|
+
getLeaksAction,
|
|
19
|
+
setLeakNotifyAction,
|
|
20
|
+
type LeakRow,
|
|
21
|
+
} from "@/app/actions/get-leaks";
|
|
22
|
+
|
|
23
|
+
/** Rendered in the reader's timezone, which is why it is not done server-side. */
|
|
24
|
+
function when(iso: string): string {
|
|
25
|
+
const t = Date.parse(iso);
|
|
26
|
+
if (!Number.isFinite(t)) return "unknown";
|
|
27
|
+
const days = Math.floor((Date.now() - t) / 86_400_000);
|
|
28
|
+
if (days <= 0) return "today";
|
|
29
|
+
if (days === 1) return "yesterday";
|
|
30
|
+
if (days < 30) return `${days}d ago`;
|
|
31
|
+
return new Date(t).toLocaleDateString(undefined, { month: "short", day: "numeric" });
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* What to actually do about this one.
|
|
36
|
+
*
|
|
37
|
+
* Two genuinely different situations, and conflating them is what makes
|
|
38
|
+
* security advice useless. A recognised prefix means a console exists and the
|
|
39
|
+
* key can be revoked there in a minute. An unattributed value — the majority,
|
|
40
|
+
* per the pattern census — has no console at all: the only move is to find
|
|
41
|
+
* where it came from, and the identifier name is usually the only clue.
|
|
42
|
+
*/
|
|
43
|
+
function advice(row: LeakRow): string {
|
|
44
|
+
if (row.attributed) return `rotate it in the ${row.label.replace(/ (API )?(key|token).*$/i, "")} console`;
|
|
45
|
+
if (row.name) return `find what reads ${row.name}, then rotate it there`;
|
|
46
|
+
return "trace it to its owner, then rotate it";
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function LeakSection() {
|
|
50
|
+
const [rows, setRows] = useState<LeakRow[] | null>(null);
|
|
51
|
+
const [notify, setNotify] = useState(true);
|
|
52
|
+
const [busy, setBusy] = useState<string | null>(null);
|
|
53
|
+
|
|
54
|
+
const load = useCallback(async () => {
|
|
55
|
+
const payload = await getLeaksAction();
|
|
56
|
+
setRows(payload.rows);
|
|
57
|
+
setNotify(payload.notify);
|
|
58
|
+
}, []);
|
|
59
|
+
|
|
60
|
+
useEffect(() => {
|
|
61
|
+
void load();
|
|
62
|
+
}, [load]);
|
|
63
|
+
|
|
64
|
+
const dismiss = useCallback(
|
|
65
|
+
async (id: string) => {
|
|
66
|
+
setBusy(id);
|
|
67
|
+
try {
|
|
68
|
+
// Optimism would be wrong here: a dismissal that did not persist means
|
|
69
|
+
// the row comes back on the next load, and the user has to guess which
|
|
70
|
+
// of the two states is real.
|
|
71
|
+
if (await dismissLeakAction(id)) setRows((prev) => prev?.filter((r) => r.id !== id) ?? null);
|
|
72
|
+
} finally {
|
|
73
|
+
setBusy(null);
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
[],
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
const toggleNotify = useCallback(async () => {
|
|
80
|
+
const next = !notify;
|
|
81
|
+
setNotify(next);
|
|
82
|
+
if (!(await setLeakNotifyAction(next))) setNotify(!next);
|
|
83
|
+
}, [notify]);
|
|
84
|
+
|
|
85
|
+
if (rows === null) return null;
|
|
86
|
+
|
|
87
|
+
return (
|
|
88
|
+
<section className="audit-sec" data-screen-label="02 Leaks">
|
|
89
|
+
<div className="audit-sec-head">
|
|
90
|
+
<span className="audit-sec-eyebrow">
|
|
91
|
+
<span className="ix">02</span>{"// credentials"}
|
|
92
|
+
</span>
|
|
93
|
+
<button
|
|
94
|
+
type="button"
|
|
95
|
+
className="cbb-toggle leak-notify"
|
|
96
|
+
data-on={notify}
|
|
97
|
+
onClick={toggleNotify}
|
|
98
|
+
aria-label={notify ? "turn desktop notifications off" : "turn desktop notifications on"}
|
|
99
|
+
title="desktop notification when a new credential is found"
|
|
100
|
+
>
|
|
101
|
+
<span className="cbb-toggle-knob" />
|
|
102
|
+
</button>
|
|
103
|
+
</div>
|
|
104
|
+
|
|
105
|
+
{rows.length === 0 ? (
|
|
106
|
+
<>
|
|
107
|
+
<h2 className="audit-sec-title">no credentials found</h2>
|
|
108
|
+
<div className="audit-sec-sub">
|
|
109
|
+
{"// nothing in this machine's transcripts matched a known key format"}
|
|
110
|
+
<br />
|
|
111
|
+
{"// or a secret-named assignment."}
|
|
112
|
+
</div>
|
|
113
|
+
</>
|
|
114
|
+
) : (
|
|
115
|
+
<>
|
|
116
|
+
<h2 className="audit-sec-title">
|
|
117
|
+
{rows.length} credential{rows.length === 1 ? "" : "s"} in your transcripts
|
|
118
|
+
</h2>
|
|
119
|
+
<div className="audit-sec-sub">
|
|
120
|
+
{"// one row per distinct key — an exposure count is not a key count."}
|
|
121
|
+
</div>
|
|
122
|
+
|
|
123
|
+
<ul className="leak-list">
|
|
124
|
+
{rows.map((row) => (
|
|
125
|
+
<li key={row.id} className="leak-row" data-attributed={row.attributed}>
|
|
126
|
+
<div className="leak-row-top">
|
|
127
|
+
<code className="leak-key">{row.display}</code>
|
|
128
|
+
<span className="leak-label">{row.label}</span>
|
|
129
|
+
{row.name ? <span className="leak-name">{row.name}</span> : null}
|
|
130
|
+
<button
|
|
131
|
+
type="button"
|
|
132
|
+
className="leak-dismiss"
|
|
133
|
+
onClick={() => void dismiss(row.id)}
|
|
134
|
+
disabled={busy === row.id}
|
|
135
|
+
>
|
|
136
|
+
not a secret
|
|
137
|
+
</button>
|
|
138
|
+
</div>
|
|
139
|
+
|
|
140
|
+
{/* The 5W1H, as one sentence rather than a grid of labelled
|
|
141
|
+
cells — a person reading a leak wants the story, and the
|
|
142
|
+
grid version made every row look like a form to fill in. */}
|
|
143
|
+
{/* The date is FIRST seen, not last. "When did this key get
|
|
144
|
+
into a transcript" is the question a leak raises; "when did
|
|
145
|
+
I last run a scan that noticed" is not. They also looked
|
|
146
|
+
identical in practice — the record keeps the 500 most
|
|
147
|
+
recently seen findings, so everything surviving the cap
|
|
148
|
+
reported the same recent `lastSeen` and every row read
|
|
149
|
+
"today", which is true and useless. */}
|
|
150
|
+
<div className="leak-how">
|
|
151
|
+
<span className="leak-verb">{row.mechanism}</span>
|
|
152
|
+
{" in "}
|
|
153
|
+
<span className="leak-where">{row.project}</span>
|
|
154
|
+
{" via "}
|
|
155
|
+
<span className="leak-who">{row.cli}</span>
|
|
156
|
+
{" · leaked "}
|
|
157
|
+
<span className="leak-when">{when(row.firstSeen)}</span>
|
|
158
|
+
{when(row.firstSeen) !== when(row.lastSeen) ? (
|
|
159
|
+
<>
|
|
160
|
+
{" · last seen "}
|
|
161
|
+
<span className="leak-when">{when(row.lastSeen)}</span>
|
|
162
|
+
</>
|
|
163
|
+
) : null}
|
|
164
|
+
</div>
|
|
165
|
+
|
|
166
|
+
<div className="leak-foot">
|
|
167
|
+
<span className="leak-meta">
|
|
168
|
+
{row.occurrences} exposure{row.occurrences === 1 ? "" : "s"}
|
|
169
|
+
{row.sessions > 1 ? ` · ${row.sessions} sessions` : ""}
|
|
170
|
+
{" · "}
|
|
171
|
+
{row.length} chars
|
|
172
|
+
</span>
|
|
173
|
+
{/* The direction is the difference between a leak a gate can
|
|
174
|
+
stop next time and one it cannot. An input travelled OUT
|
|
175
|
+
of the machine with the agent's request; a result came
|
|
176
|
+
back INTO the transcript from a file or a command, where
|
|
177
|
+
no PreToolUse hook can intercept it. */}
|
|
178
|
+
<span className="leak-dir">
|
|
179
|
+
{row.direction === "input"
|
|
180
|
+
? "sent by the agent — blockable at PreToolUse"
|
|
181
|
+
: "returned to the agent — already in the transcript"}
|
|
182
|
+
</span>
|
|
183
|
+
<span className="leak-fix">{advice(row)}</span>
|
|
184
|
+
</div>
|
|
185
|
+
</li>
|
|
186
|
+
))}
|
|
187
|
+
</ul>
|
|
188
|
+
</>
|
|
189
|
+
)}
|
|
190
|
+
</section>
|
|
191
|
+
);
|
|
192
|
+
}
|
|
@@ -7,20 +7,31 @@
|
|
|
7
7
|
* appends a clipboard paste hint. Pure — no React, no DOM — so it's
|
|
8
8
|
* unit-testable and shared by the client poster component.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
10
|
+
* ## The score is switched off (2026-09-07)
|
|
11
|
+
*
|
|
12
|
+
* Every template but one used to interpolate `${score}/100`. The score is
|
|
13
|
+
* commented out across the audit — see the header of `src/audit/scoring.ts` for
|
|
14
|
+
* why — so the copy is archetype-only. Eighteen templates lost a subordinate
|
|
15
|
+
* clause; two whose entire premise WAS the number ("my agent scored X/100,
|
|
16
|
+
* think yours can beat it?") are commented out in place rather than reworded,
|
|
17
|
+
* because there is nothing left of them once the number goes.
|
|
18
|
+
*
|
|
19
|
+
* `ShareCtx.score` is kept and still populated so restoring is re-adding the
|
|
20
|
+
* clause, not re-plumbing the type. The originals are preserved verbatim in the
|
|
21
|
+
* block at the bottom of this file.
|
|
14
22
|
*/
|
|
15
23
|
import type { Grade } from "@/src/audit/scoring";
|
|
16
24
|
|
|
17
25
|
export interface ShareCtx {
|
|
18
|
-
score: number;
|
|
19
26
|
/** Lowercased archetype name, e.g. "the cowboy". */
|
|
20
27
|
arch: string;
|
|
21
|
-
grade: Grade;
|
|
22
28
|
/** Count of unenabled prescribed policies. */
|
|
23
29
|
missing: number;
|
|
30
|
+
/** Optional ONLY because the score is switched off and nothing upstream
|
|
31
|
+
* computes them any more. Restoring the score means making these required
|
|
32
|
+
* again — which the compiler will then walk you through. */
|
|
33
|
+
score?: number;
|
|
34
|
+
grade?: Grade;
|
|
24
35
|
}
|
|
25
36
|
|
|
26
37
|
/** Call-to-action + handle per channel. No URL by design (see file header). */
|
|
@@ -33,52 +44,107 @@ const PASTE_LINE = "[ audit card copied to your clipboard — paste it into the
|
|
|
33
44
|
|
|
34
45
|
/** Short, curiosity-forward — for X / Twitter. Ends on the npx CTA + @failproofai. */
|
|
35
46
|
export const X_TEMPLATES: ((c: ShareCtx) => string)[] = [
|
|
36
|
-
({
|
|
37
|
-
`my agent has a personality and it's ${arch}. did not see that coming.\n\nran a failproof audit,
|
|
38
|
-
({
|
|
39
|
-
`spent 30 seconds auditing my agent. learned more about it than i did all month.\n\nit's ${arch}.
|
|
40
|
-
|
|
41
|
-
|
|
47
|
+
({ arch }) =>
|
|
48
|
+
`my agent has a personality and it's ${arch}. did not see that coming.\n\nran a failproof audit, all local. find out what yours is → ${X_CTA}`,
|
|
49
|
+
({ arch }) =>
|
|
50
|
+
`spent 30 seconds auditing my agent. learned more about it than i did all month.\n\nit's ${arch}. → ${X_CTA}`,
|
|
51
|
+
// Score-spined — nothing survives removing the number:
|
|
52
|
+
// ({ score }) =>
|
|
53
|
+
// `my agent scored ${score}/100. think yours can beat it?\n\n30 sec audit, runs locally, gives you a personality too → ${X_CTA}`,
|
|
42
54
|
({ arch }) =>
|
|
43
55
|
`turns out my agent is ${arch} and honestly it explains everything.\n\n→ ${X_CTA}`,
|
|
44
|
-
({
|
|
45
|
-
`ran a failproof audit on my agent. it reads how it actually behaves when things break, not just the happy path.\n\npersonality: ${arch}.
|
|
46
|
-
({
|
|
47
|
-
`got to know my agent today. it's ${arch}
|
|
48
|
-
({
|
|
49
|
-
`your agent has a personality. you just haven't met it.\n\ni met mine today: ${arch}
|
|
50
|
-
({
|
|
51
|
-
`everyone talks about what their agent can build. nobody talks about how it acts when it breaks.\n\nmine's ${arch},
|
|
52
|
-
({
|
|
53
|
-
`every agent builder should run this once.\n\n30 sec, local, gives your agent a personality
|
|
54
|
-
({
|
|
55
|
-
`i'll go first: ${arch}
|
|
56
|
+
({ arch }) =>
|
|
57
|
+
`ran a failproof audit on my agent. it reads how it actually behaves when things break, not just the happy path.\n\npersonality: ${arch}. all local → ${X_CTA}`,
|
|
58
|
+
({ arch }) =>
|
|
59
|
+
`got to know my agent today. it's ${arch}. wow.\n\naudit yours in 30s, nothing leaves your machine → ${X_CTA}`,
|
|
60
|
+
({ arch }) =>
|
|
61
|
+
`your agent has a personality. you just haven't met it.\n\ni met mine today: ${arch}. → ${X_CTA}`,
|
|
62
|
+
({ arch }) =>
|
|
63
|
+
`everyone talks about what their agent can build. nobody talks about how it acts when it breaks.\n\nmine's ${arch}, all local → ${X_CTA}`,
|
|
64
|
+
({ arch }) =>
|
|
65
|
+
`every agent builder should run this once.\n\n30 sec, local, gives your agent a personality. mine: ${arch}.\n\n${X_CTA}`,
|
|
66
|
+
({ arch }) =>
|
|
67
|
+
`i'll go first: ${arch}.\n\nwhat's your agent? 30 sec audit, no signup → ${X_CTA}`,
|
|
56
68
|
];
|
|
57
69
|
|
|
58
70
|
/** Longer, reflective — for LinkedIn. Ends on the npx CTA + @Failproof AI. */
|
|
59
71
|
export const LI_TEMPLATES: ((c: ShareCtx) => string)[] = [
|
|
60
|
-
({
|
|
61
|
-
`I've spent more hours with my agent this month than with most people I know. Today I realized I couldn't tell you a single thing about how it actually behaves.\n\nSo I audited it. Turns out it's ${arch}
|
|
62
|
-
({
|
|
63
|
-
`Took a personality test today. It wasn't for me — it was for my AI agent.\n\nThe result: ${arch}
|
|
64
|
-
({
|
|
65
|
-
`Everyone asks what their AI agent can build. I just found out mine has a temper.\n\nAfter watching how it reacts to a failed command, the audit called it ${arch}
|
|
66
|
-
({
|
|
67
|
-
`My agent does this very specific thing every time a command fails. Today I learned there's basically a name for it.\n\nRan a quick audit and it came back ${arch}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
72
|
+
({ arch }) =>
|
|
73
|
+
`I've spent more hours with my agent this month than with most people I know. Today I realized I couldn't tell you a single thing about how it actually behaves.\n\nSo I audited it. Turns out it's ${arch}.\n\nThe audit reads its real history, including how it handles failures, not just the clean runs. 30 seconds, runs entirely locally.\n\nMeet yours: ${LI_CTA}`,
|
|
74
|
+
({ arch }) =>
|
|
75
|
+
`Took a personality test today. It wasn't for me — it was for my AI agent.\n\nThe result: ${arch}.\n\nIt works by reading the agent's actual run history, so the personality comes from how it really behaves, not a vibe. Took 30 seconds and stayed local.\n\nTry it on yours: ${LI_CTA}`,
|
|
76
|
+
({ arch }) =>
|
|
77
|
+
`Everyone asks what their AI agent can build. I just found out mine has a temper.\n\nAfter watching how it reacts to a failed command, the audit called it ${arch}.\n\nOddly useful to see it written down. 30 seconds, all local: ${LI_CTA}`,
|
|
78
|
+
({ arch }) =>
|
|
79
|
+
`My agent does this very specific thing every time a command fails. Today I learned there's basically a name for it.\n\nRan a quick audit and it came back ${arch}. The whole read is based on how the agent handles things going wrong, which is where its real character shows.\n\n30 seconds, nothing leaves your machine: ${LI_CTA}`,
|
|
80
|
+
// Score-spined — the opening line is the number:
|
|
81
|
+
// ({ score, arch }) =>
|
|
82
|
+
// `My AI agent scored ${score}/100 today. I didn't know you could even measure that.\n\nThe same audit also handed it a personality: ${arch}.\n\nIt reads the agent's real history and tells you where it's solid and where it slips. Took 30 seconds and ran fully locally: ${LI_CTA}`,
|
|
83
|
+
({ arch }) =>
|
|
84
|
+
`I'm usually the first to scroll past "audit your X" tools. This one took 30 seconds and actually told me something.\n\nMy agent is ${arch}.\n\nIt reads the agent's real run history rather than asking me anything, and none of it leaves the machine: ${LI_CTA}`,
|
|
85
|
+
({ arch }) =>
|
|
86
|
+
`What is your agent's personality? I realized today that I had no answer.\n\nSo I checked. Mine is ${arch}, with a clear read on where it shines and where it slips.\n\nIf you work with agents, run it and drop yours in the comments. 30 seconds, fully local: ${LI_CTA}`,
|
|
87
|
+
({ arch }) =>
|
|
88
|
+
`I trusted my agent a little less after this morning, and quite a bit more by the afternoon.\n\nI ran an audit on it. It showed me exactly where it's reliable and where it isn't, and gave it a personality: ${arch}.\n\nKnowing the gaps is what made me trust it more. 30 seconds, all local: ${LI_CTA}`,
|
|
89
|
+
({ arch }) =>
|
|
90
|
+
`I almost skipped this because I assumed it would quietly ship my code off somewhere. It doesn't. Everything runs locally.\n\n30 seconds later I had my agent's personality: ${arch}.\n\nIf privacy is usually what stops you from trying these, this one is different: ${LI_CTA}`,
|
|
91
|
+
({ arch }) =>
|
|
92
|
+
`Found out my AI agent has a personality type. Found out it's ${arch}. Found out that explains a lot.\n\nThe audit reads how the agent handles failures, not just the runs where everything goes fine.\n\n30 seconds, runs locally: ${LI_CTA}`,
|
|
80
93
|
];
|
|
81
94
|
|
|
95
|
+
/* ---------------------------------------------------------------------------
|
|
96
|
+
* THE ORIGINAL SCORE-BEARING COPY, verbatim. To restore: put these two arrays
|
|
97
|
+
* back in place of the two above, and re-enable the score at its source (see
|
|
98
|
+
* `src/audit/scoring.ts`). Nothing else has to change — `ShareCtx` is unchanged
|
|
99
|
+
* and `score` is still populated by `audit-poster.tsx`.
|
|
100
|
+
*
|
|
101
|
+
* export const X_TEMPLATES: ((c: ShareCtx) => string)[] = [
|
|
102
|
+
* ({ score, arch }) =>
|
|
103
|
+
* `my agent has a personality and it's ${arch}. did not see that coming.\n\nran a failproof audit, scored ${score}/100, all local. find out what yours is → ${X_CTA}`,
|
|
104
|
+
* ({ score, arch }) =>
|
|
105
|
+
* `spent 30 seconds auditing my agent. learned more about it than i did all month.\n\nit's ${arch}. scored ${score}/100. → ${X_CTA}`,
|
|
106
|
+
* ({ score }) =>
|
|
107
|
+
* `my agent scored ${score}/100. think yours can beat it?\n\n30 sec audit, runs locally, gives you a personality too → ${X_CTA}`,
|
|
108
|
+
* ({ arch }) =>
|
|
109
|
+
* `turns out my agent is ${arch} and honestly it explains everything.\n\n→ ${X_CTA}`,
|
|
110
|
+
* ({ score, arch }) =>
|
|
111
|
+
* `ran a failproof audit on my agent. it reads how it actually behaves when things break, not just the happy path.\n\npersonality: ${arch}. score: ${score}/100. all local → ${X_CTA}`,
|
|
112
|
+
* ({ score, arch }) =>
|
|
113
|
+
* `got to know my agent today. it's ${arch} and scored ${score}/100. wow.\n\naudit yours in 30s, nothing leaves your machine → ${X_CTA}`,
|
|
114
|
+
* ({ score, arch }) =>
|
|
115
|
+
* `your agent has a personality. you just haven't met it.\n\ni met mine today: ${arch}, ${score}/100. → ${X_CTA}`,
|
|
116
|
+
* ({ score, arch }) =>
|
|
117
|
+
* `everyone talks about what their agent can build. nobody talks about how it acts when it breaks.\n\nmine's ${arch}, scored ${score}/100, all local → ${X_CTA}`,
|
|
118
|
+
* ({ score, arch }) =>
|
|
119
|
+
* `every agent builder should run this once.\n\n30 sec, local, gives your agent a personality and a quality score. mine: ${arch}, ${score}/100.\n\n${X_CTA}`,
|
|
120
|
+
* ({ score, arch }) =>
|
|
121
|
+
* `i'll go first: ${arch}, ${score}/100.\n\nwhat's your agent? 30 sec audit, no signup → ${X_CTA}`,
|
|
122
|
+
* ];
|
|
123
|
+
*
|
|
124
|
+
* export const LI_TEMPLATES: ((c: ShareCtx) => string)[] = [
|
|
125
|
+
* ({ score, arch }) =>
|
|
126
|
+
* `I've spent more hours with my agent this month than with most people I know. Today I realized I couldn't tell you a single thing about how it actually behaves.\n\nSo I audited it. Turns out it's ${arch}, and it scored ${score}/100.\n\nThe audit reads its real history, including how it handles failures, not just the clean runs. 30 seconds, runs entirely locally.\n\nMeet yours: ${LI_CTA}`,
|
|
127
|
+
* ({ score, arch }) =>
|
|
128
|
+
* `Took a personality test today. It wasn't for me — it was for my AI agent.\n\nThe result: ${arch}, with a quality score of ${score}/100.\n\nIt works by reading the agent's actual run history, so the personality comes from how it really behaves, not a vibe. Took 30 seconds and stayed local.\n\nTry it on yours: ${LI_CTA}`,
|
|
129
|
+
* ({ score, arch }) =>
|
|
130
|
+
* `Everyone asks what their AI agent can build. I just found out mine has a temper.\n\nAfter watching how it reacts to a failed command, the audit called it ${arch}. It also scored its quality at ${score}/100.\n\nOddly useful to see it written down. 30 seconds, all local: ${LI_CTA}`,
|
|
131
|
+
* ({ score, arch }) =>
|
|
132
|
+
* `My agent does this very specific thing every time a command fails. Today I learned there's basically a name for it.\n\nRan a quick audit and it came back ${arch}, scored ${score}/100. The whole read is based on how the agent handles things going wrong, which is where its real character shows.\n\n30 seconds, nothing leaves your machine: ${LI_CTA}`,
|
|
133
|
+
* ({ score, arch }) =>
|
|
134
|
+
* `My AI agent scored ${score}/100 today. I didn't know you could even measure that.\n\nThe same audit also handed it a personality: ${arch}.\n\nIt reads the agent's real history and tells you where it's solid and where it slips. Took 30 seconds and ran fully locally: ${LI_CTA}`,
|
|
135
|
+
* ({ score, arch }) =>
|
|
136
|
+
* `I'm usually the first to scroll past "audit your X" tools. This one took 30 seconds and actually told me something.\n\nMy agent is ${arch}, and it scored ${score}/100.\n\nIt reads the agent's real run history rather than asking me anything, and none of it leaves the machine: ${LI_CTA}`,
|
|
137
|
+
* ({ score, arch }) =>
|
|
138
|
+
* `What is your agent's personality? I realized today that I had no answer.\n\nSo I checked. Mine is ${arch}, scored ${score}/100, with a clear read on where it shines and where it slips.\n\nIf you work with agents, run it and drop yours in the comments. 30 seconds, fully local: ${LI_CTA}`,
|
|
139
|
+
* ({ score, arch }) =>
|
|
140
|
+
* `I trusted my agent a little less after this morning, and quite a bit more by the afternoon.\n\nI ran an audit on it. It showed me exactly where it's reliable and where it isn't, gave it a personality (${arch}), and scored it ${score}/100.\n\nKnowing the gaps is what made me trust it more. 30 seconds, all local: ${LI_CTA}`,
|
|
141
|
+
* ({ score, arch }) =>
|
|
142
|
+
* `I almost skipped this because I assumed it would quietly ship my code off somewhere. It doesn't. Everything runs locally.\n\n30 seconds later I had my agent's personality (${arch}) and a quality score (${score}/100).\n\nIf privacy is usually what stops you from trying these, this one is different: ${LI_CTA}`,
|
|
143
|
+
* ({ score, arch }) =>
|
|
144
|
+
* `Found out my AI agent has a personality type. Found out it's ${arch}. Found out that explains a lot.\n\nIt scored ${score}/100 too. The audit reads how the agent handles failures, not just the runs where everything goes fine.\n\n30 seconds, runs locally: ${LI_CTA}`,
|
|
145
|
+
* ];
|
|
146
|
+
* ------------------------------------------------------------------------- */
|
|
147
|
+
|
|
82
148
|
/** djb2 hash — stable per seed so the template choice is deterministic. */
|
|
83
149
|
function hashStr(s: string): number {
|
|
84
150
|
let h = 5381;
|
|
@@ -496,7 +496,13 @@
|
|
|
496
496
|
.poster-meta .of { color: var(--dim); }
|
|
497
497
|
.poster-meta .poster-sep { color: var(--dim); }
|
|
498
498
|
|
|
499
|
-
/* body — vertical centered stack: sigil → persona → score ───
|
|
499
|
+
/* body — vertical centered stack: sigil → persona → score ───
|
|
500
|
+
The score block is switched off (see `src/audit/scoring.ts`), so this stack
|
|
501
|
+
currently renders two children, not three. It is a centered flex column with
|
|
502
|
+
a gap and no fixed track count, so it re-centers on its own. The
|
|
503
|
+
`.poster-score` rules below are kept, dormant, against the score coming
|
|
504
|
+
back — do not tidy them away, or restoring it means rewriting the styles
|
|
505
|
+
too. */
|
|
500
506
|
.poster-body {
|
|
501
507
|
display: flex;
|
|
502
508
|
flex-direction: column;
|
|
@@ -555,6 +561,7 @@
|
|
|
555
561
|
.poster-persona .persona-rarity .pct { color: var(--accent-pink); font-weight: 600; }
|
|
556
562
|
|
|
557
563
|
/* score — score-n + /100, baseline-aligned and centered in the card. */
|
|
564
|
+
/* Dormant while the score is switched off — see `src/audit/scoring.ts`. */
|
|
558
565
|
.poster-score {
|
|
559
566
|
display: flex;
|
|
560
567
|
align-items: baseline;
|
|
@@ -1157,3 +1164,127 @@
|
|
|
1157
1164
|
.share-card {
|
|
1158
1165
|
max-width: 420px;
|
|
1159
1166
|
}
|
|
1167
|
+
|
|
1168
|
+
/* ── Leak report ─────────────────────────────────────────────────────────────
|
|
1169
|
+
One block per distinct credential. Deliberately NOT a table: a table implies
|
|
1170
|
+
columns worth scanning down, and the interesting comparison between two
|
|
1171
|
+
leaked keys is never "which is longer" — it is what each one is and where it
|
|
1172
|
+
went, which reads as a sentence. */
|
|
1173
|
+
|
|
1174
|
+
.leak-notify { margin-left: auto; }
|
|
1175
|
+
|
|
1176
|
+
.leak-list {
|
|
1177
|
+
list-style: none;
|
|
1178
|
+
margin: 20px 0 0;
|
|
1179
|
+
padding: 0;
|
|
1180
|
+
display: flex;
|
|
1181
|
+
flex-direction: column;
|
|
1182
|
+
gap: 10px;
|
|
1183
|
+
}
|
|
1184
|
+
|
|
1185
|
+
.leak-row {
|
|
1186
|
+
border: 1px solid var(--line-2);
|
|
1187
|
+
/* Hard-offset pixel shadow, never a blur — the house rule. Pink is the
|
|
1188
|
+
accent that means "this one is yours to act on". */
|
|
1189
|
+
box-shadow: 4px 4px 0 0 var(--line-2);
|
|
1190
|
+
padding: 14px 16px;
|
|
1191
|
+
display: flex;
|
|
1192
|
+
flex-direction: column;
|
|
1193
|
+
gap: 8px;
|
|
1194
|
+
background: var(--bg);
|
|
1195
|
+
}
|
|
1196
|
+
/* A recognised prefix means a console exists and this is revocable in a
|
|
1197
|
+
minute. That is a real difference in what the reader has to do, so it is the
|
|
1198
|
+
one thing the row's own frame encodes. */
|
|
1199
|
+
.leak-row[data-attributed="true"] { box-shadow: 4px 4px 0 0 var(--accent-pink); }
|
|
1200
|
+
|
|
1201
|
+
.leak-row-top {
|
|
1202
|
+
display: flex;
|
|
1203
|
+
align-items: baseline;
|
|
1204
|
+
gap: 10px;
|
|
1205
|
+
flex-wrap: wrap;
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
.leak-key {
|
|
1209
|
+
font-family: var(--font-mono);
|
|
1210
|
+
font-size: 14px;
|
|
1211
|
+
color: var(--ink);
|
|
1212
|
+
letter-spacing: 0.02em;
|
|
1213
|
+
/* The masked value can be long; it must wrap rather than push the row wide. */
|
|
1214
|
+
word-break: break-all;
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1217
|
+
.leak-label {
|
|
1218
|
+
font-family: var(--font-mono);
|
|
1219
|
+
font-size: 11px;
|
|
1220
|
+
color: var(--accent-pink);
|
|
1221
|
+
text-transform: lowercase;
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1224
|
+
.leak-name {
|
|
1225
|
+
font-family: var(--font-mono);
|
|
1226
|
+
font-size: 11px;
|
|
1227
|
+
color: var(--ink-2);
|
|
1228
|
+
border: 1px solid var(--line-2);
|
|
1229
|
+
padding: 1px 5px;
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1232
|
+
.leak-dismiss {
|
|
1233
|
+
margin-left: auto;
|
|
1234
|
+
font-family: var(--font-mono);
|
|
1235
|
+
font-size: 10px;
|
|
1236
|
+
color: var(--dim);
|
|
1237
|
+
background: none;
|
|
1238
|
+
border: 1px solid var(--line-2);
|
|
1239
|
+
padding: 3px 8px;
|
|
1240
|
+
cursor: pointer;
|
|
1241
|
+
text-transform: lowercase;
|
|
1242
|
+
}
|
|
1243
|
+
.leak-dismiss:hover:not(:disabled) { color: var(--ink); border-color: var(--ink-2); }
|
|
1244
|
+
.leak-dismiss:disabled { opacity: 0.4; cursor: not-allowed; }
|
|
1245
|
+
.leak-dismiss:focus-visible { outline: 2px solid var(--accent-pink); outline-offset: 2px; }
|
|
1246
|
+
|
|
1247
|
+
.leak-how {
|
|
1248
|
+
font-family: var(--font-mono);
|
|
1249
|
+
font-size: 12px;
|
|
1250
|
+
color: var(--ink-2);
|
|
1251
|
+
line-height: 1.6;
|
|
1252
|
+
}
|
|
1253
|
+
.leak-verb { color: var(--ink); }
|
|
1254
|
+
.leak-where { color: var(--accent-green); }
|
|
1255
|
+
.leak-who { color: var(--ink); }
|
|
1256
|
+
.leak-when { color: var(--dim); }
|
|
1257
|
+
|
|
1258
|
+
.leak-foot {
|
|
1259
|
+
display: flex;
|
|
1260
|
+
gap: 14px;
|
|
1261
|
+
flex-wrap: wrap;
|
|
1262
|
+
font-family: var(--font-mono);
|
|
1263
|
+
font-size: 10px;
|
|
1264
|
+
color: var(--dim);
|
|
1265
|
+
}
|
|
1266
|
+
.leak-fix { color: var(--accent-green); }
|
|
1267
|
+
.leak-dir { color: var(--ink-2); }
|
|
1268
|
+
|
|
1269
|
+
@media (max-width: 640px) {
|
|
1270
|
+
.leak-dismiss { margin-left: 0; }
|
|
1271
|
+
.leak-foot { gap: 6px; flex-direction: column; }
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1274
|
+
/* The re-scan control in the scan header. Sits at the end of the eyebrow row so
|
|
1275
|
+
it reads as an action on that section rather than a page-level nav item. */
|
|
1276
|
+
.scan-rerun {
|
|
1277
|
+
margin-left: auto;
|
|
1278
|
+
font-family: var(--font-mono);
|
|
1279
|
+
font-size: 10.5px;
|
|
1280
|
+
letter-spacing: 0.1em;
|
|
1281
|
+
text-transform: lowercase;
|
|
1282
|
+
color: var(--ink-2);
|
|
1283
|
+
background: none;
|
|
1284
|
+
border: 1px solid var(--line-2);
|
|
1285
|
+
padding: 4px 10px;
|
|
1286
|
+
cursor: pointer;
|
|
1287
|
+
}
|
|
1288
|
+
.scan-rerun:hover:not(:disabled) { color: var(--ink); border-color: var(--accent-pink); }
|
|
1289
|
+
.scan-rerun:disabled { opacity: 0.5; cursor: not-allowed; }
|
|
1290
|
+
.scan-rerun:focus-visible { outline: 2px solid var(--accent-pink); outline-offset: 2px; }
|