failproofai 1.0.4-beta.7 → 1.0.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 +4 -4
- 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 +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 +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 +2 -2
- 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 +14 -14
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +14 -14
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +13 -13
- 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.nft.json +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/status/route.js.nft.json +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-verify/route.js.nft.json +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/status/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/audit/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +4 -37
- 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 +14 -14
- package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +13 -13
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +14 -14
- package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- 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 +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 +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 +4 -4
- 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 +4 -4
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/projects/page/build-manifest.json +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 +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 +2 -2
- package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +4 -15
- package/.next/standalone/.next/server/app/settings/page.js +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]__0v1hz15._.js → [externals]__0-9ti7z._.js} +1 -1
- package/.next/standalone/.next/server/chunks/{[externals]__1nb206a._.js → [externals]__0u3wrvq._.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]__0rv7m0k._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__17g9wh7._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1legmza._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1p-qi2t._.js +1 -1
- 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/{_0otft92._.js → _1-akg6w._.js} +2 -2
- package/.next/standalone/.next/server/chunks/_1ek68ln._.js +10 -10
- package/.next/standalone/.next/server/chunks/_1vslkoe._.js +1 -1
- package/.next/standalone/.next/server/chunks/lib_telemetry_ts_0dctyyw._.js +1 -1
- package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.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]__1fvfw59._.js → [root-of-the-server]__00-s7h8._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__013jr2b._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__01wy8d-._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__02npjtd._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__12hbpha._.js → [root-of-the-server]__09flfsx._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0da85px._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ftmoxc._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0kokc8z._.js → [root-of-the-server]__0n_lxhg._.js} +1 -1
- 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 +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0s740oi._.js +6 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0dxf928._.js → [root-of-the-server]__190won8._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0n2txhk._.js → [root-of-the-server]__1ctpynv._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1p2otjt._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/_02yoeej._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{_0a0zlpr._.js → _04rbnaq._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_08x1r5t._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{_0s-77v5._.js → _0h_douw._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_1_ozgif._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_1ddpc5g._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_1es2j7i._.js +14 -51
- package/.next/standalone/.next/server/chunks/ssr/{_07t3jol._.js → _1u8-lu2._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_1ylae7o._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_1zopuov._.js +3 -0
- 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 +69 -1
- 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_html-to-image_es_index_1ao30b1.js +3 -0
- 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 +21 -65
- package/.next/standalone/.next/static/chunks/{0f1pznnc7zlub.js → 0-tyrpwuc3lla.js} +1 -1
- package/.next/standalone/.next/static/chunks/0ca7octhod0g2.js +69 -0
- package/.next/standalone/.next/static/chunks/0u64yey446k4f.css +1 -0
- package/.next/standalone/.next/static/chunks/{1csubx9gwhsf6.js → 1j6o9min_6qa9.js} +1 -1
- package/.next/standalone/.next/static/chunks/27cl8h-c2w7cd.js +1 -0
- package/.next/standalone/.next/static/chunks/{0jpd8dv2vk930.css → 29-iqnp9v_axt.css} +1 -1
- package/.next/standalone/.next/static/chunks/{3uyhmm01g64k4.css → 2k9f4tyv04809.css} +0 -1
- package/.next/standalone/.next/static/chunks/{0t6ea7d3bkmdv.js → 2lwipmv5etc8m.js} +1 -1
- package/.next/standalone/.next/static/chunks/2pd16tn5qmx13.js +1 -0
- package/.next/standalone/.next/static/chunks/{0ntdfr2552x-h.js → 2u8vh73tpw28_.js} +1 -1
- package/.next/standalone/.next/static/chunks/{15uon66hpwbgg.js → 31u94yukw9fz-.js} +1 -1
- package/.next/standalone/.next/static/chunks/{2pwfrn6_mw-1u.js → 3p9_8x5ezce-9.js} +1 -1
- package/.next/standalone/.next/static/chunks/3qfoeqhy5l10x.js +1 -0
- package/.next/standalone/.next/static/chunks/{083fk73jtv9a0.js → 3tjji451hrgc0.js} +1 -1
- package/.next/standalone/.next/static/chunks/3zkg2s2vzxc3d.js +1 -0
- package/.next/standalone/.next/static/chunks/{turbopack-3s3c-u_u_l0u9.js → turbopack-3p73obe0xmrxm.js} +1 -1
- package/.next/standalone/.opencode/plugins/failproofai.mjs +27 -51
- package/.next/standalone/app/actions/get-scheduled-audit.ts +0 -5
- package/.next/standalone/app/actions/update-scheduled-audit.ts +57 -18
- package/.next/standalone/app/api/auth/status/route.ts +2 -3
- package/.next/standalone/app/audit/_components/audit-dashboard.tsx +34 -140
- package/.next/standalone/app/audit/_components/audit-poster.tsx +10 -29
- package/.next/standalone/app/audit/_components/come-back-better-section.tsx +1 -6
- package/.next/standalone/app/audit/_components/empty-state.tsx +1 -4
- package/.next/standalone/app/audit/_components/how-to-improve-section.tsx +5 -19
- package/.next/standalone/app/audit/_components/share-templates.ts +44 -110
- package/.next/standalone/app/audit/audit-styles.css +1 -132
- package/.next/standalone/app/settings/page.tsx +1 -1
- package/.next/standalone/app/settings/settings-client.tsx +45 -50
- package/.next/standalone/lib/auth/api-server-client.ts +5 -33
- package/.next/standalone/lib/claude-sessions.ts +27 -101
- package/.next/standalone/lib/codex-sessions.ts +4 -20
- package/.next/standalone/lib/copilot-sessions.ts +1 -32
- package/.next/standalone/lib/cursor-sessions.ts +5 -62
- package/.next/standalone/lib/sqlite-reader.ts +1 -78
- package/.next/standalone/package.json +9 -9
- package/.next/standalone/server.js +1 -1
- package/bin/failproofai.mjs +1 -1
- package/dist/cli.mjs +500 -1762
- package/dist/worker.mjs +16 -138
- package/lib/auth/api-server-client.ts +5 -33
- package/lib/claude-sessions.ts +27 -101
- package/lib/codex-sessions.ts +4 -20
- package/lib/copilot-sessions.ts +1 -32
- package/lib/cursor-sessions.ts +5 -62
- package/lib/sqlite-reader.ts +1 -78
- package/package.json +9 -9
- package/pi-extension/index.ts +5 -50
- package/src/audit/cache.ts +0 -6
- package/src/audit/cli-adapters/claude.ts +0 -13
- package/src/audit/cli-login.ts +1 -4
- package/src/audit/cli.ts +7 -157
- package/src/audit/harm-report.ts +4 -111
- package/src/audit/index.ts +15 -286
- package/src/audit/machine-store.ts +9 -8
- package/src/audit/redact-example.ts +15 -324
- package/src/audit/report-harm.ts +37 -33
- package/src/audit/report.ts +3 -6
- package/src/audit/schedule-cli.ts +33 -54
- package/src/audit/scoring.ts +0 -49
- package/src/audit/types.ts +0 -52
- package/src/hooks/builtin-policies.ts +2 -67
- package/src/hooks/configure-wizard.ts +0 -55
- package/src/hooks/fp-config.ts +48 -83
- package/src/hooks/fp-home.ts +0 -27
- package/src/hooks/integrations.ts +14 -51
- package/src/hooks/uninstall-cli.ts +2 -17
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0-4ja6q._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__00cr3xu._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__04px77e._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0egr5s1._.js +0 -6
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0i0l1di._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0r3c1_0._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__17xnxlx._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1ckpmkk._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/_04ng_6x._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_0l2hi_d._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/app_audit__components_rerun-button_tsx_0blihgw._.js +0 -3
- package/.next/standalone/.next/static/chunks/0divvxng208xo.js +0 -1
- package/.next/standalone/.next/static/chunks/27du9n7ssja7l.js +0 -1
- package/.next/standalone/.next/static/chunks/2h_pcb1y8_jde.js +0 -1
- package/.next/standalone/app/actions/get-leaks.ts +0 -104
- package/.next/standalone/app/audit/_components/leak-section.tsx +0 -192
- package/src/audit/desktop-notify.ts +0 -420
- package/src/audit/leak-fingerprint.ts +0 -198
- package/src/audit/leak-record.ts +0 -248
- package/src/audit/leak-scan.ts +0 -268
- package/src/audit/leak-store.ts +0 -220
- package/src/audit/macos-notifier.ts +0 -298
- package/src/hooks/notice.ts +0 -24
- /package/.next/standalone/.next/static/{YiPsVpjrc-pEQoN7XvhZ0 → dg8VQ7Ejlo0Qsh_x92oIt}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{YiPsVpjrc-pEQoN7XvhZ0 → dg8VQ7Ejlo0Qsh_x92oIt}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{YiPsVpjrc-pEQoN7XvhZ0 → dg8VQ7Ejlo0Qsh_x92oIt}/_ssgManifest.js +0 -0
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* Top-level client wrapper for /audit.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* Composes the calm personality report: classify the agent into one of
|
|
7
|
+
* 8 archetypes, derive a score, and render the 5-section flow:
|
|
8
8
|
*
|
|
9
9
|
* 01 AuditPoster — single-screen shareable poster
|
|
10
10
|
* 02 StrengthsSection — what it's great at
|
|
@@ -12,36 +12,23 @@
|
|
|
12
12
|
* 04 HowToImproveSection — install / configure
|
|
13
13
|
* 05 ComeBackBetterSection — spread the audit (invite)
|
|
14
14
|
*
|
|
15
|
-
* Every one of those components, and the score / persona / strengths / findings
|
|
16
|
-
* modules behind them, is intact and still unit-tested — only the renders and
|
|
17
|
-
* the imports here are commented out, so restoring any of it is deleting a pair
|
|
18
|
-
* of comment markers. See the header of `src/audit/scoring.ts` for why.
|
|
19
|
-
*
|
|
20
|
-
* What this page renders now is `AuditReportPlaceholder`: the scan's own
|
|
21
|
-
* numbers. The scan, the 12-CLI transcript reader and the emailed digest all
|
|
22
|
-
* still run.
|
|
23
|
-
*
|
|
24
15
|
* Empty / running states fall back to EmptyState and RunProgress.
|
|
25
16
|
*/
|
|
26
17
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
27
18
|
import { getAuditResultAction } from "@/app/actions/get-audit-result";
|
|
28
19
|
import type { AuditResult, RunAuditOptions } from "@/src/audit/types";
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
// import { deriveFindings } from "@/src/audit/findings";
|
|
20
|
+
import { classifyAgent } from "@/src/audit/archetypes";
|
|
21
|
+
import { deriveScore, gradeFor, projectedScore } from "@/src/audit/scoring";
|
|
22
|
+
import { deriveStrengths } from "@/src/audit/strengths";
|
|
23
|
+
import { deriveFindings } from "@/src/audit/findings";
|
|
34
24
|
import { usePostHog } from "@/contexts/PostHogContext";
|
|
35
25
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
// import { HowToImproveSection } from "./how-to-improve-section";
|
|
42
|
-
// import { ComeBackBetterSection } from "./come-back-better-section";
|
|
26
|
+
import { AuditPoster } from "./audit-poster";
|
|
27
|
+
import { StrengthsSection } from "./strengths-section";
|
|
28
|
+
import { QuirksSection } from "./quirks-section";
|
|
29
|
+
import { HowToImproveSection } from "./how-to-improve-section";
|
|
30
|
+
import { ComeBackBetterSection } from "./come-back-better-section";
|
|
43
31
|
import { ReportFooter } from "./report-footer";
|
|
44
|
-
import { LeakSection } from "./leak-section";
|
|
45
32
|
import { EmptyState } from "./empty-state";
|
|
46
33
|
import { RunProgress } from "./run-progress";
|
|
47
34
|
import { AuditProgressStrip, type RerunStatus } from "./audit-progress-strip";
|
|
@@ -59,9 +46,7 @@ type Initial =
|
|
|
59
46
|
/** Tag passed to the shared `startRerun()` handler so PostHog can tell
|
|
60
47
|
* whether the click came from the bottom return-section button or the
|
|
61
48
|
* empty-state CTA. */
|
|
62
|
-
|
|
63
|
-
// page has now that the old report's sections are switched off.
|
|
64
|
-
export type RerunSource = "return_section" | "empty_state" | "scan_header";
|
|
49
|
+
export type RerunSource = "return_section" | "empty_state";
|
|
65
50
|
|
|
66
51
|
interface Props {
|
|
67
52
|
initial: Initial;
|
|
@@ -74,9 +59,6 @@ interface Props {
|
|
|
74
59
|
totalCatalogSize: number;
|
|
75
60
|
}
|
|
76
61
|
|
|
77
|
-
/* Switched off with the persona layer — this named the project that seeded the
|
|
78
|
-
archetype classifier and the leaderboard row. Restore alongside
|
|
79
|
-
`classifyAgent` in this file.
|
|
80
62
|
function inferProjectName(result: AuditResult, override?: string): string {
|
|
81
63
|
if (override && override.trim()) return override;
|
|
82
64
|
// Pick the cwd that appears in the most examples — proxy for "your
|
|
@@ -99,7 +81,6 @@ function inferProjectName(result: AuditResult, override?: string): string {
|
|
|
99
81
|
if (segs.length >= 2) return `${segs[segs.length - 2]} / ${segs[segs.length - 1]}`;
|
|
100
82
|
return segs[segs.length - 1] ?? "your agent";
|
|
101
83
|
}
|
|
102
|
-
*/
|
|
103
84
|
|
|
104
85
|
export function AuditDashboard({ initial, projectFromUrl, totalCatalogSize }: Props) {
|
|
105
86
|
const [cache, setCache] = useState<Initial>(initial);
|
|
@@ -298,22 +279,16 @@ function MainReport({
|
|
|
298
279
|
onDismissRerun,
|
|
299
280
|
}: MainReportProps) {
|
|
300
281
|
const { capture } = usePostHog();
|
|
301
|
-
|
|
302
|
-
// const project = useMemo(() => inferProjectName(result, projectFromUrl), [result, projectFromUrl]);
|
|
282
|
+
const project = useMemo(() => inferProjectName(result, projectFromUrl), [result, projectFromUrl]);
|
|
303
283
|
// Seed classification with the project name so the behaviour fingerprint
|
|
304
284
|
// (used for tie-breaks + copy variants) is stable per project.
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
// const projected = useMemo(() => projectedScore(result, score), [result, score]);
|
|
313
|
-
// const grade = gradeFor(score);
|
|
314
|
-
// const projectedGrade = gradeFor(projected);
|
|
315
|
-
// const strengths = useMemo(() => deriveStrengths(result), [result]);
|
|
316
|
-
// const findings = useMemo(() => deriveFindings(result), [result]);
|
|
285
|
+
const classification = useMemo(() => classifyAgent(result, project), [result, project]);
|
|
286
|
+
const score = useMemo(() => deriveScore(result), [result]);
|
|
287
|
+
const projected = useMemo(() => projectedScore(result, score), [result, score]);
|
|
288
|
+
const grade = gradeFor(score);
|
|
289
|
+
const projectedGrade = gradeFor(projected);
|
|
290
|
+
const strengths = useMemo(() => deriveStrengths(result), [result]);
|
|
291
|
+
const findings = useMemo(() => deriveFindings(result), [result]);
|
|
317
292
|
|
|
318
293
|
// One pass over result.results: detectors triggered + missing prescribed
|
|
319
294
|
// policies. Both feed PostHog instrumentation; `missing` also feeds the
|
|
@@ -335,13 +310,10 @@ function MainReport({
|
|
|
335
310
|
if (dashboardViewedRef.current) return;
|
|
336
311
|
dashboardViewedRef.current = true;
|
|
337
312
|
capture("audit_dashboard_viewed", {
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
// grade,
|
|
343
|
-
// archetype: classification.archetype,
|
|
344
|
-
// secondary: classification.secondary ?? null,
|
|
313
|
+
score,
|
|
314
|
+
grade,
|
|
315
|
+
archetype: classification.archetype,
|
|
316
|
+
secondary: classification.secondary ?? null,
|
|
345
317
|
missing,
|
|
346
318
|
transcripts_scanned: result.transcripts.scanned,
|
|
347
319
|
results_count: result.results.length,
|
|
@@ -349,6 +321,10 @@ function MainReport({
|
|
|
349
321
|
});
|
|
350
322
|
}, [
|
|
351
323
|
capture,
|
|
324
|
+
score,
|
|
325
|
+
grade,
|
|
326
|
+
classification.archetype,
|
|
327
|
+
classification.secondary,
|
|
352
328
|
missing,
|
|
353
329
|
result.transcripts.scanned,
|
|
354
330
|
result.results.length,
|
|
@@ -356,43 +332,19 @@ function MainReport({
|
|
|
356
332
|
]);
|
|
357
333
|
|
|
358
334
|
/** Poster ref — captured to PNG by the poster's share buttons. */
|
|
359
|
-
|
|
335
|
+
const posterRef = useRef<HTMLDivElement>(null);
|
|
360
336
|
|
|
361
337
|
return (
|
|
362
338
|
<div className="app">
|
|
363
339
|
<AuditProgressStrip status={rerunStatus} onDismiss={onDismissRerun} />
|
|
364
340
|
<div className="app-shell">
|
|
365
341
|
<div className="report">
|
|
366
|
-
<AuditReportPlaceholder
|
|
367
|
-
transcripts={result.transcripts.scanned}
|
|
368
|
-
events={result.eventsScanned ?? 0}
|
|
369
|
-
projects={result.projectsScanned?.length ?? 0}
|
|
370
|
-
isRunning={isRunning || rerunStatus.kind === "running"}
|
|
371
|
-
onRerun={() => onRerun("scan_header")}
|
|
372
|
-
/>
|
|
373
|
-
{/* The rebuilt report. It reads the leak record rather than this
|
|
374
|
-
scan's result, deliberately: a credential found last month and
|
|
375
|
-
not touched by today's transcripts is still a credential to
|
|
376
|
-
rotate, and a report that showed only the current scan's findings
|
|
377
|
-
would go quiet on exactly those. */}
|
|
378
|
-
<LeakSection />
|
|
379
|
-
{/* The whole old report is switched off — the persona poster, the
|
|
380
|
-
strengths and quirks sections, the punch-list with its install-all
|
|
381
|
-
funnel, and the invite section. It is being rebuilt bottom-up
|
|
382
|
-
around leak detection; see the header of `src/audit/scoring.ts`
|
|
383
|
-
for the reasoning and `~/Desktop/failproofai-leak-detection-
|
|
384
|
-
verdict-2026-09-07.md` for the measurements behind it.
|
|
385
|
-
|
|
386
|
-
Every component below is intact and still unit-tested — only the
|
|
387
|
-
render is commented — so restoring any one of them is deleting a
|
|
388
|
-
pair of comment markers.
|
|
389
|
-
|
|
390
342
|
<AuditPoster
|
|
391
343
|
ref={posterRef}
|
|
392
344
|
archetypeKey={classification.archetype}
|
|
393
345
|
seed={classification.variantSeed}
|
|
394
|
-
|
|
395
|
-
|
|
346
|
+
score={score}
|
|
347
|
+
grade={grade}
|
|
396
348
|
missing={missing}
|
|
397
349
|
auditedAt={cachedAt ?? new Date().toISOString()}
|
|
398
350
|
/>
|
|
@@ -400,11 +352,10 @@ function MainReport({
|
|
|
400
352
|
<QuirksSection findings={findings} />
|
|
401
353
|
<HowToImproveSection
|
|
402
354
|
result={result}
|
|
403
|
-
|
|
404
|
-
|
|
355
|
+
projected={projected}
|
|
356
|
+
projectedGrade={projectedGrade}
|
|
405
357
|
/>
|
|
406
|
-
<ComeBackBetterSection />
|
|
407
|
-
*/}
|
|
358
|
+
<ComeBackBetterSection score={score} />
|
|
408
359
|
</div>
|
|
409
360
|
<ReportFooter cachedAt={cachedAt} />
|
|
410
361
|
</div>
|
|
@@ -412,63 +363,6 @@ function MainReport({
|
|
|
412
363
|
);
|
|
413
364
|
}
|
|
414
365
|
|
|
415
|
-
/**
|
|
416
|
-
* What `/audit` shows while the report is being rebuilt.
|
|
417
|
-
*
|
|
418
|
-
* Deliberately states the scan's own numbers rather than nothing at all: the
|
|
419
|
-
* scan still runs, still walks every transcript across all 12 CLIs, and still
|
|
420
|
-
* feeds the emailed digest. Saying so is the difference between "this page is
|
|
421
|
-
* under construction" and "this product is broken".
|
|
422
|
-
*/
|
|
423
|
-
function AuditReportPlaceholder(
|
|
424
|
-
{
|
|
425
|
-
transcripts,
|
|
426
|
-
events,
|
|
427
|
-
projects,
|
|
428
|
-
isRunning,
|
|
429
|
-
onRerun,
|
|
430
|
-
}: {
|
|
431
|
-
transcripts: number;
|
|
432
|
-
events: number;
|
|
433
|
-
projects: number;
|
|
434
|
-
isRunning: boolean;
|
|
435
|
-
onRerun: () => void;
|
|
436
|
-
},
|
|
437
|
-
) {
|
|
438
|
-
const n = (x: number) => x.toLocaleString();
|
|
439
|
-
return (
|
|
440
|
-
<section className="audit-sec" data-screen-label="01 Scan">
|
|
441
|
-
<div className="audit-sec-head">
|
|
442
|
-
<span className="audit-sec-eyebrow">
|
|
443
|
-
<span className="ix">01</span>{"// scan"}
|
|
444
|
-
</span>
|
|
445
|
-
{/* The re-scan control. It lived in the old report's sections and went
|
|
446
|
-
dormant when they were commented out, which left the page with no way
|
|
447
|
-
to run an audit again at all — you had to go back to the terminal. */}
|
|
448
|
-
<button
|
|
449
|
-
type="button"
|
|
450
|
-
className="scan-rerun"
|
|
451
|
-
onClick={onRerun}
|
|
452
|
-
disabled={isRunning}
|
|
453
|
-
>
|
|
454
|
-
{isRunning ? "scanning…" : "run again"}
|
|
455
|
-
</button>
|
|
456
|
-
</div>
|
|
457
|
-
<h2 className="audit-sec-title">scan complete</h2>
|
|
458
|
-
<div className="audit-sec-sub">
|
|
459
|
-
{n(events)} tool call{events === 1 ? "" : "s"} across {n(transcripts)}{" "}
|
|
460
|
-
transcript{transcripts === 1 ? "" : "s"}
|
|
461
|
-
{projects > 0 ? ` · ${n(projects)} project${projects === 1 ? "" : "s"}` : ""}
|
|
462
|
-
</div>
|
|
463
|
-
<div className="audit-sec-sub">
|
|
464
|
-
{"// the report is being rebuilt around leak detection. the scan, the"}
|
|
465
|
-
<br />
|
|
466
|
-
{"// 12-CLI transcript reader and the emailed digest are unaffected."}
|
|
467
|
-
</div>
|
|
468
|
-
</section>
|
|
469
|
-
);
|
|
470
|
-
}
|
|
471
|
-
|
|
472
366
|
interface ShellEmptyProps {
|
|
473
367
|
running: boolean;
|
|
474
368
|
mode?: "no-cache" | "zero-sessions";
|
|
@@ -24,12 +24,7 @@
|
|
|
24
24
|
import React, { forwardRef, useMemo, useState } from "react";
|
|
25
25
|
import { pickArchetypeVariant, type ArchetypeKey } from "@/src/audit/archetypes";
|
|
26
26
|
import { type Grade } from "@/src/audit/scoring";
|
|
27
|
-
|
|
28
|
-
// ("Seeded with snapshot values; swap for live aggregates once that pipeline
|
|
29
|
-
// lands"), and this is the ONLY surface that rendered them: baked by
|
|
30
|
-
// html-to-image into the PNG people post publicly. A fabricated population
|
|
31
|
-
// statistic on a shared card is a claim we cannot support.
|
|
32
|
-
// import { getArchetypeRarityPct } from "@/src/audit/social-proof";
|
|
27
|
+
import { getArchetypeRarityPct } from "@/src/audit/social-proof";
|
|
33
28
|
import { copyOrDownloadCard, downloadCard, shareCardNative, shareCardToastMessage } from "@/lib/share-card";
|
|
34
29
|
import { toast } from "@/app/components/toast";
|
|
35
30
|
import { usePostHog } from "@/contexts/PostHogContext";
|
|
@@ -50,11 +45,8 @@ interface Props {
|
|
|
50
45
|
archetypeKey: ArchetypeKey;
|
|
51
46
|
/** Stable seed for variant selection (project name is the natural fit). */
|
|
52
47
|
seed: string;
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
* re-threading: the dashboard simply stops passing them. */
|
|
56
|
-
score?: number;
|
|
57
|
-
grade?: Grade;
|
|
48
|
+
score: number;
|
|
49
|
+
grade: Grade;
|
|
58
50
|
/** Count of unenabled prescribed policies — passed to the share-text
|
|
59
51
|
* templates, not rendered on the poster itself. */
|
|
60
52
|
missing: number;
|
|
@@ -71,7 +63,7 @@ export const AuditPoster = forwardRef<HTMLDivElement, Props>(function AuditPoste
|
|
|
71
63
|
() => pickArchetypeVariant(archetypeKey, seed),
|
|
72
64
|
[archetypeKey, seed],
|
|
73
65
|
);
|
|
74
|
-
|
|
66
|
+
const rarityPct = getArchetypeRarityPct(archetypeKey);
|
|
75
67
|
const indexLabel = String(archetype.index).padStart(2, "0");
|
|
76
68
|
const auditedDate = useMemo(() => formatAuditedDate(auditedAt), [auditedAt]);
|
|
77
69
|
|
|
@@ -142,11 +134,8 @@ export const AuditPoster = forwardRef<HTMLDivElement, Props>(function AuditPoste
|
|
|
142
134
|
}
|
|
143
135
|
};
|
|
144
136
|
|
|
145
|
-
// Score switched off — the filename is keyed on the archetype instead, which
|
|
146
|
-
// is what the card now actually shows. Original:
|
|
147
|
-
// `failproofai-${channel}-${grade.toLowerCase()}-${score}.png`
|
|
148
137
|
const filenameFor = (channel: "x" | "linkedin" | "download") =>
|
|
149
|
-
`failproofai-${channel}-${
|
|
138
|
+
`failproofai-${channel}-${grade.toLowerCase()}-${score}.png`;
|
|
150
139
|
|
|
151
140
|
const handleShare = async (channel: "x" | "linkedin" | "download") => {
|
|
152
141
|
if (busy) return;
|
|
@@ -154,11 +143,8 @@ export const AuditPoster = forwardRef<HTMLDivElement, Props>(function AuditPoste
|
|
|
154
143
|
capture("audit_card_share_clicked", {
|
|
155
144
|
channel,
|
|
156
145
|
source: "poster",
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
// dashboard keyed on them breaks rather than reading zero.
|
|
160
|
-
// score,
|
|
161
|
-
// grade,
|
|
146
|
+
score,
|
|
147
|
+
grade,
|
|
162
148
|
missing_policies: missing,
|
|
163
149
|
});
|
|
164
150
|
try {
|
|
@@ -188,10 +174,10 @@ export const AuditPoster = forwardRef<HTMLDivElement, Props>(function AuditPoste
|
|
|
188
174
|
}
|
|
189
175
|
|
|
190
176
|
const shareCtx: ShareCtx = {
|
|
177
|
+
score,
|
|
191
178
|
arch: archetype.name.toLowerCase(),
|
|
179
|
+
grade,
|
|
192
180
|
missing,
|
|
193
|
-
// score,
|
|
194
|
-
// grade,
|
|
195
181
|
};
|
|
196
182
|
const shareText = channel === "x"
|
|
197
183
|
? pickTemplate(X_TEMPLATES, seed, shareCtx)
|
|
@@ -262,7 +248,6 @@ export const AuditPoster = forwardRef<HTMLDivElement, Props>(function AuditPoste
|
|
|
262
248
|
</React.Fragment>
|
|
263
249
|
))}
|
|
264
250
|
</div>
|
|
265
|
-
{/* Rarity switched off — see the import above.
|
|
266
251
|
{typeof rarityPct === "number" && (
|
|
267
252
|
<div className="persona-rarity">
|
|
268
253
|
<span className="lbl">{"// only"}</span>{" "}
|
|
@@ -270,17 +255,13 @@ export const AuditPoster = forwardRef<HTMLDivElement, Props>(function AuditPoste
|
|
|
270
255
|
<span className="lbl">of agents are this archetype</span>
|
|
271
256
|
</div>
|
|
272
257
|
)}
|
|
273
|
-
*/}
|
|
274
258
|
</div>
|
|
275
259
|
|
|
276
|
-
{/* Score block — heroic number, centered in the card
|
|
277
|
-
see `src/audit/scoring.ts` for why. The archetype is the card's
|
|
278
|
-
headline now.
|
|
260
|
+
{/* Score block — heroic number, centered in the card */}
|
|
279
261
|
<div className="poster-score">
|
|
280
262
|
<span className="score-n">{score}</span>
|
|
281
263
|
<span className="score-of">/100</span>
|
|
282
264
|
</div>
|
|
283
|
-
*/}
|
|
284
265
|
</div>
|
|
285
266
|
|
|
286
267
|
<footer className="poster-foot">
|
|
@@ -21,12 +21,7 @@ import { AuthDialog, type AuthedUser } from "./auth-dialog";
|
|
|
21
21
|
import { InviteDialog } from "./invite-dialog";
|
|
22
22
|
|
|
23
23
|
interface Props {
|
|
24
|
-
/** Current audit score (0–100), forwarded into the invite email body.
|
|
25
|
-
*
|
|
26
|
-
* Always undefined while the score is switched off (see
|
|
27
|
-
* `src/audit/scoring.ts`) — the dashboard no longer passes it. Nothing
|
|
28
|
-
* breaks: `/api/audit/invite` already treats it as optional and simply
|
|
29
|
-
* leaves it out of the email body when it is not a finite number. */
|
|
24
|
+
/** Current audit score (0–100), forwarded into the invite email body. */
|
|
30
25
|
score?: number;
|
|
31
26
|
}
|
|
32
27
|
|
|
@@ -74,10 +74,7 @@ export function EmptyState({ mode, running, onStarted, onCompleted }: Props) {
|
|
|
74
74
|
<p className="empty-sub">
|
|
75
75
|
we'll walk every transcript across your installed CLIs — Claude Code,
|
|
76
76
|
Codex, Copilot, Cursor, OpenCode, Pi — and count every wasteful
|
|
77
|
-
|
|
78
|
-
rendered and the score is switched off, so this promised two
|
|
79
|
-
things the page did not show. */}
|
|
80
|
-
or risky action. you'll get a leak report and a scan summary.
|
|
77
|
+
or risky action. you'll get a tier, a score, and a punch-list.
|
|
81
78
|
</p>
|
|
82
79
|
|
|
83
80
|
<div className="empty-actions">
|
|
@@ -12,18 +12,13 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import { useMemo, useState } from "react";
|
|
14
14
|
import type { AuditResult } from "@/src/audit/types";
|
|
15
|
-
|
|
16
|
-
// import { type Grade, tierName } from "@/src/audit/scoring";
|
|
17
|
-
import type { Grade } from "@/src/audit/scoring";
|
|
15
|
+
import { type Grade, tierName } from "@/src/audit/scoring";
|
|
18
16
|
import { usePostHog } from "@/contexts/PostHogContext";
|
|
19
17
|
|
|
20
18
|
interface Props {
|
|
21
19
|
result: AuditResult;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
* `audit-dashboard.tsx` and the sub-heading below. */
|
|
25
|
-
projected?: number;
|
|
26
|
-
projectedGrade?: Grade;
|
|
20
|
+
projected: number;
|
|
21
|
+
projectedGrade: Grade;
|
|
27
22
|
}
|
|
28
23
|
|
|
29
24
|
const DETECTOR_TO_PRIMARY_POLICY: Record<string, string> = {
|
|
@@ -104,7 +99,7 @@ function bulkInstall(fixes: FixRow[]): string {
|
|
|
104
99
|
return `failproofai policies --install ${fixes.map((f) => f.name).join(" ")}`;
|
|
105
100
|
}
|
|
106
101
|
|
|
107
|
-
export function HowToImproveSection({ result }: Props) {
|
|
102
|
+
export function HowToImproveSection({ result, projected, projectedGrade }: Props) {
|
|
108
103
|
const { capture } = usePostHog();
|
|
109
104
|
const fixes = useMemo(() => buildFixes(result), [result]);
|
|
110
105
|
const installAllCmd = useMemo(() => bulkInstall(fixes), [fixes]);
|
|
@@ -141,18 +136,9 @@ export function HowToImproveSection({ result }: Props) {
|
|
|
141
136
|
</button>
|
|
142
137
|
</div>
|
|
143
138
|
<h2 className="audit-sec-title">install or configure</h2>
|
|
144
|
-
|
|
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:
|
|
139
|
+
<div className="audit-sec-sub">
|
|
150
140
|
enable all {fixes.length === 1 ? "one" : fixes.length} → projected{" "}
|
|
151
141
|
<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
|
|
156
142
|
</div>
|
|
157
143
|
|
|
158
144
|
<div className="fix-list">
|