failproofai 0.0.11-beta.9 → 0.0.11
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 +3 -3
- package/.next/standalone/.next/prerender-manifest.json +3 -3
- package/.next/standalone/.next/required-server-files.json +1 -1
- package/.next/standalone/.next/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 +2 -2
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
- package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +3 -3
- package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +3 -3
- package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +1 -1
- package/.next/standalone/.next/server/app/_not-found.rsc +15 -15
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +15 -15
- package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
- package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +10 -10
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
- package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/api/audit/invite/route.js +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 +1 -1
- package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/login-request/route.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-verify/route.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/logout/route.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/reminder/route.js +1 -1
- package/.next/standalone/.next/server/app/api/auth/reminder/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/status/route.js +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/server-reference-manifest.json +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 +2 -2
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
- package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +4 -4
- package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +10 -10
- package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +8 -8
- package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/chunks/[externals]__1_g_b3t._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0dwpg-h._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0lnenda._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__13i_sva._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1_mqemn._.js +1 -1
- package/.next/standalone/.next/server/chunks/node_modules_0-tu4ot._.js +1 -1
- package/.next/standalone/.next/server/chunks/node_modules_1bnh1y0._.js +1 -1
- package/.next/standalone/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_17k9e3w.js +3 -3
- package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_01r25oi._.js +1 -1
- package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_09z9-p7._.js +1 -1
- package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0e446gb._.js → [root-of-the-server]__00uwqi6._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0808sha._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0e4-6d8._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ehe24g._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0g253ve._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0k65l27._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0wprfyc._.js → [root-of-the-server]__0kjb_s4._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0vxf0_g._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__12mcauo._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1mt35_w._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1pcxxwg._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1uvfwgr._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_11_p9y8._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +49 -21
- 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/{node_modules_html-to-image_es_index_0y4a-0q.js → node_modules_html-to-image_es_index_0ihmbv4.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules_posthog-node_dist_entrypoints_index_node_mjs_11bnuzn._.js +1 -1
- package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
- 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 +10 -10
- package/.next/standalone/.next/static/chunks/{3ty6dhcuogout.js → 02fywjt0by40a.js} +1 -1
- package/.next/standalone/.next/static/chunks/0xdx2ehtbdoeg.js +1 -0
- package/.next/standalone/.next/static/chunks/{07_d165p5h5ys.js → 1-a5rvq67k7ed.js} +1 -1
- package/.next/standalone/.next/static/chunks/{3nj6g3xu9uy78.js → 15csyj1_rf0-w.js} +1 -1
- package/.next/standalone/.next/static/chunks/1o0xa47736gi9.css +2 -0
- package/.next/standalone/.next/static/chunks/24cv31x607n7k.js +1 -0
- package/.next/standalone/.next/static/chunks/2n_s8v1ae38_a.js +69 -0
- package/.next/standalone/.next/static/chunks/{277oc363p56n6.js → 2y-jmvrjxz60x.js} +2 -2
- package/.next/standalone/.next/static/chunks/{1kvadxkgnapyj.js → 3eik_d9qrvoft.js} +1 -1
- package/.next/standalone/.next/static/chunks/{168k-8z6k7e8z.css → 3i27c3hcriawq.css} +1 -1
- package/.next/standalone/.next/static/chunks/{2z42u62k-8-_q.js → 3v61675vr6jav.js} +1 -1
- package/.next/standalone/app/api/audit/invite/route.ts +10 -1
- package/.next/standalone/app/api/audit/run/route.ts +35 -0
- package/.next/standalone/app/api/auth/login-request/route.ts +2 -2
- package/.next/standalone/app/api/auth/login-verify/route.ts +10 -2
- package/.next/standalone/app/audit/_components/audit-dashboard.tsx +9 -1
- package/.next/standalone/app/audit/_components/audit-poster.tsx +11 -7
- package/.next/standalone/app/audit/_components/auth-dialog.tsx +6 -4
- package/.next/standalone/app/audit/_components/come-back-better-section.tsx +23 -3
- package/.next/standalone/app/audit/_components/invite-dialog.tsx +6 -3
- package/.next/standalone/app/audit/_components/share-templates.ts +58 -28
- package/.next/standalone/app/audit/audit-styles.css +17 -22
- package/.next/standalone/app/globals.css +27 -2
- package/.next/standalone/app/policies/hooks-client.tsx +33 -24
- package/.next/standalone/components/reach-developers.tsx +10 -25
- package/.next/standalone/lib/auth/api-server-client.ts +5 -2
- package/.next/standalone/lib/client-telemetry.ts +4 -0
- package/.next/standalone/package.json +6 -4
- package/.next/standalone/server.js +1 -1
- package/README.md +2 -2
- package/bin/failproofai.mjs +24 -5
- package/dist/cli.mjs +2328 -381
- package/lib/auth/api-server-client.ts +5 -2
- package/lib/client-telemetry.ts +4 -0
- package/package.json +6 -4
- package/scripts/launch.ts +30 -4
- package/scripts/postinstall.mjs +10 -1
- package/scripts/skew-log-filter.ts +46 -0
- package/scripts/validate-mdx.ts +139 -0
- package/src/audit/cli.ts +330 -0
- package/src/audit/open-browser.ts +69 -0
- package/src/auth/cli.ts +16 -13
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1r1h8v9._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1uatkiv._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1y6gxxb._.js +0 -3
- package/.next/standalone/.next/static/chunks/28mkxkl_d91-l.js +0 -1
- package/.next/standalone/.next/static/chunks/28x7jvo3kxd3u.js +0 -41
- package/.next/standalone/.next/static/chunks/29nrs5xs9c4hx.css +0 -2
- package/.next/standalone/.next/static/chunks/29tg7deqmq32l.js +0 -1
- /package/.next/standalone/.next/static/{NYPiJP6Rv_exQdSFVS8HP → P_MIRSeoE296wkbE-Icin}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{NYPiJP6Rv_exQdSFVS8HP → P_MIRSeoE296wkbE-Icin}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{NYPiJP6Rv_exQdSFVS8HP → P_MIRSeoE296wkbE-Icin}/_ssgManifest.js +0 -0
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Social-share copy for the audit identity card.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
4
|
+
* Ten templates for X and ten for LinkedIn. `pickTemplate` selects one
|
|
5
|
+
* deterministically from a seed (the behaviour fingerprint), so a given audit
|
|
6
|
+
* run always renders the same post while different runs / personas vary — then
|
|
7
|
+
* appends a clipboard paste hint. Pure — no React, no DOM — so it's
|
|
8
|
+
* unit-testable and shared by the client poster component.
|
|
9
|
+
*
|
|
10
|
+
* Each template references the score and/or archetype and ends on the
|
|
11
|
+
* install-free CTA + handle. We intentionally never include a URL: a bare link
|
|
12
|
+
* would make X/LinkedIn render a link-preview card and swallow the copied
|
|
13
|
+
* image. The npx command is the call to action instead.
|
|
9
14
|
*/
|
|
10
15
|
import type { Grade } from "@/src/audit/scoring";
|
|
11
16
|
|
|
12
|
-
const SITE_URL = "https://befailproof.ai";
|
|
13
|
-
|
|
14
17
|
export interface ShareCtx {
|
|
15
18
|
score: number;
|
|
16
19
|
/** Lowercased archetype name, e.g. "the cowboy". */
|
|
@@ -20,35 +23,60 @@ export interface ShareCtx {
|
|
|
20
23
|
missing: number;
|
|
21
24
|
}
|
|
22
25
|
|
|
23
|
-
|
|
26
|
+
/** Call-to-action + handle per channel. No URL by design (see file header). */
|
|
27
|
+
const X_CTA = "npx -y failproofai audit · @failproofai";
|
|
28
|
+
const LI_CTA = "npx -y failproofai audit · @Failproof AI";
|
|
24
29
|
|
|
25
|
-
/**
|
|
26
|
-
*
|
|
30
|
+
/** Appended to every picked share so the user knows the audit-card PNG is on
|
|
31
|
+
* their clipboard and just needs pasting into the post. */
|
|
32
|
+
const PASTE_LINE = "[ audit card copied to your clipboard — paste it into the post ]";
|
|
33
|
+
|
|
34
|
+
/** Short, curiosity-forward — for X / Twitter. Ends on the npx CTA + @failproofai. */
|
|
27
35
|
export const X_TEMPLATES: ((c: ShareCtx) => string)[] = [
|
|
28
|
-
({ score, arch, missing }) =>
|
|
29
|
-
`my AI coding agent just got profiled and it's "${arch}" 🤠\n\nscored ${score}/100${missing > 0 ? ` · ${missing} ${pol(missing)} between me and a clean run` : ` · every guardrail live`}\n\nwhat's yours? → ${SITE_URL}`,
|
|
30
36
|
({ score, arch }) =>
|
|
31
|
-
`
|
|
37
|
+
`my coding 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}`,
|
|
38
|
+
({ score, arch }) =>
|
|
39
|
+
`spent 30 seconds auditing my coding agent. learned more about it than i did all month.\n\nit's ${arch}. scored ${score}/100. → ${X_CTA}`,
|
|
40
|
+
({ score }) =>
|
|
41
|
+
`my agent scored ${score}/100. think yours can beat it?\n\n30 sec audit, runs locally, gives you a personality too → ${X_CTA}`,
|
|
42
|
+
({ arch }) =>
|
|
43
|
+
`turns out my coding agent is ${arch} and honestly it explains everything.\n\n→ ${X_CTA}`,
|
|
44
|
+
({ score, arch }) =>
|
|
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}. score: ${score}/100. all local → ${X_CTA}`,
|
|
46
|
+
({ score, arch }) =>
|
|
47
|
+
`got to know my coding agent today. it's ${arch} and scored ${score}/100. wow.\n\naudit yours in 30s, nothing leaves your machine → ${X_CTA}`,
|
|
48
|
+
({ score, arch }) =>
|
|
49
|
+
`your coding agent has a personality. you just haven't met it.\n\ni met mine today: ${arch}, ${score}/100. → ${X_CTA}`,
|
|
50
|
+
({ score, arch }) =>
|
|
51
|
+
`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}`,
|
|
32
52
|
({ score, arch }) =>
|
|
33
|
-
`
|
|
34
|
-
({ score, arch, missing }) =>
|
|
35
|
-
`plot twist: my AI agent is ${arch} 🎭\n\n${score}/100${missing > 0 ? ` · ${missing} ${pol(missing)} away from behaving` : ` · spotless, somehow`}\n\nbefailproof.ai`,
|
|
53
|
+
`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}`,
|
|
36
54
|
({ score, arch }) =>
|
|
37
|
-
`i
|
|
55
|
+
`i'll go first: ${arch}, ${score}/100.\n\nwhat's your coding agent? 30 sec audit, no signup → ${X_CTA}`,
|
|
38
56
|
];
|
|
39
57
|
|
|
40
|
-
/**
|
|
58
|
+
/** Longer, reflective — for LinkedIn. Ends on the npx CTA + @Failproof AI. */
|
|
41
59
|
export const LI_TEMPLATES: ((c: ShareCtx) => string)[] = [
|
|
42
|
-
({ score, arch, missing }) =>
|
|
43
|
-
`I ran a failproofai audit on our AI coding agents.\n\nResult: ${score}/100, behavioural archetype "${arch}". ${missing > 0 ? `${missing} prescribed ${pol(missing)} would close the remaining gaps.` : `Every prescribed policy is already live.`}\n\nUnderstanding how agents actually behave across real sessions is the first step to securing them. Free and open-source: ${SITE_URL}`,
|
|
44
|
-
({ score, arch, missing }) =>
|
|
45
|
-
`Security posture check on our coding-agent stack, via failproofai.\n\nScore: ${score}/100. Behavioural profile: "${arch}". ${missing > 0 ? `${missing} ${pol(missing)} flagged as real, addressable attack surface.` : `No open policy gaps.`}\n\nThirty seconds to run your own assessment: ${SITE_URL}`,
|
|
46
60
|
({ score, arch }) =>
|
|
47
|
-
`
|
|
48
|
-
({ score, arch
|
|
49
|
-
`
|
|
61
|
+
`I've spent more hours with my coding 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}`,
|
|
62
|
+
({ score, arch }) =>
|
|
63
|
+
`Took a personality test today. It wasn't for me — it was for my AI coding 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}`,
|
|
64
|
+
({ score, arch }) =>
|
|
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}. It also scored its quality at ${score}/100.\n\nOddly useful to see it written down. 30 seconds, all local: ${LI_CTA}`,
|
|
66
|
+
({ score, arch }) =>
|
|
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}, 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}`,
|
|
68
|
+
({ score, arch }) =>
|
|
69
|
+
`My AI coding 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}`,
|
|
70
|
+
({ score, arch }) =>
|
|
71
|
+
`I'm usually the first to scroll past "audit your X" tools. This one took 30 seconds and actually told me something.\n\nMy coding 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}`,
|
|
72
|
+
({ score, arch }) =>
|
|
73
|
+
`What is your coding 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}`,
|
|
74
|
+
({ score, arch }) =>
|
|
75
|
+
`I trusted my coding 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}`,
|
|
76
|
+
({ score, arch }) =>
|
|
77
|
+
`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}`,
|
|
50
78
|
({ score, arch }) =>
|
|
51
|
-
`
|
|
79
|
+
`Found out my AI coding 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}`,
|
|
52
80
|
];
|
|
53
81
|
|
|
54
82
|
/** djb2 hash — stable per seed so the template choice is deterministic. */
|
|
@@ -58,11 +86,13 @@ function hashStr(s: string): number {
|
|
|
58
86
|
return h >>> 0;
|
|
59
87
|
}
|
|
60
88
|
|
|
61
|
-
/** Deterministically pick + render one template for the given seed
|
|
89
|
+
/** Deterministically pick + render one template for the given seed, then append
|
|
90
|
+
* the clipboard paste hint so the user knows to paste the copied audit card. */
|
|
62
91
|
export function pickTemplate(
|
|
63
92
|
templates: ((c: ShareCtx) => string)[],
|
|
64
93
|
seed: string,
|
|
65
94
|
ctx: ShareCtx,
|
|
66
95
|
): string {
|
|
67
|
-
|
|
96
|
+
const body = templates[hashStr(seed) % templates.length](ctx);
|
|
97
|
+
return `${body}\n\n${PASTE_LINE}`;
|
|
68
98
|
}
|
|
@@ -617,7 +617,7 @@
|
|
|
617
617
|
padding-bottom: 12px;
|
|
618
618
|
border-bottom: 1px dashed var(--line);
|
|
619
619
|
font-family: var(--font-mono);
|
|
620
|
-
font-size:
|
|
620
|
+
font-size: 14px;
|
|
621
621
|
letter-spacing: 0.04em;
|
|
622
622
|
}
|
|
623
623
|
.poster-wordmark {
|
|
@@ -625,7 +625,7 @@
|
|
|
625
625
|
display: inline-flex; align-items: center; gap: 8px;
|
|
626
626
|
}
|
|
627
627
|
.poster-wordmark .poster-logo {
|
|
628
|
-
height:
|
|
628
|
+
height: 18px;
|
|
629
629
|
width: auto;
|
|
630
630
|
display: block;
|
|
631
631
|
}
|
|
@@ -693,8 +693,7 @@
|
|
|
693
693
|
.poster-persona .persona-rarity .lbl { color: var(--dim); }
|
|
694
694
|
.poster-persona .persona-rarity .pct { color: var(--accent-pink); font-weight: 600; }
|
|
695
695
|
|
|
696
|
-
/* score —
|
|
697
|
-
* baseline-aligned, so the pill can never overlap the digits. */
|
|
696
|
+
/* score — score-n + /100, baseline-aligned and centered in the card. */
|
|
698
697
|
.poster-score {
|
|
699
698
|
display: flex;
|
|
700
699
|
align-items: baseline;
|
|
@@ -718,19 +717,6 @@
|
|
|
718
717
|
color: var(--dim);
|
|
719
718
|
letter-spacing: 0.04em;
|
|
720
719
|
line-height: 1;
|
|
721
|
-
margin-right: clamp(12px, 2vh, 28px);
|
|
722
|
-
}
|
|
723
|
-
.poster-score .score-rank {
|
|
724
|
-
font-family: var(--font-mono);
|
|
725
|
-
font-size: clamp(10px, 1.3vh, 12px);
|
|
726
|
-
letter-spacing: 0.32em;
|
|
727
|
-
text-transform: uppercase;
|
|
728
|
-
color: var(--accent-green);
|
|
729
|
-
padding: 6px 14px;
|
|
730
|
-
border: 1px solid var(--accent-green);
|
|
731
|
-
background: rgba(102, 209, 181, 0.05);
|
|
732
|
-
line-height: 1;
|
|
733
|
-
white-space: nowrap;
|
|
734
720
|
}
|
|
735
721
|
.poster-sigil .sigil .px { background: transparent; }
|
|
736
722
|
.poster-sigil .sigil .px.on { background: var(--ink); }
|
|
@@ -738,16 +724,25 @@
|
|
|
738
724
|
.poster-sigil .sigil .px.g { background: var(--accent-green); }
|
|
739
725
|
.poster-sigil .sigil .px.d { background: var(--dim); }
|
|
740
726
|
|
|
741
|
-
/* foot —
|
|
727
|
+
/* foot — brand stamp (left) + CTA (right) ─────────────────────── */
|
|
742
728
|
.poster-foot {
|
|
743
|
-
display: flex; justify-content:
|
|
729
|
+
display: flex; justify-content: space-between; align-items: baseline;
|
|
744
730
|
padding-top: 10px;
|
|
745
731
|
border-top: 1px dashed var(--line);
|
|
746
732
|
font-family: var(--font-mono);
|
|
747
|
-
font-size:
|
|
733
|
+
font-size: 14px;
|
|
734
|
+
}
|
|
735
|
+
.poster-brand {
|
|
736
|
+
color: var(--ink);
|
|
737
|
+
letter-spacing: 0.04em;
|
|
738
|
+
text-shadow: 0 0 6px rgba(255, 255, 255, 0.5), 0 0 14px rgba(255, 255, 255, 0.22);
|
|
748
739
|
}
|
|
749
740
|
.poster-cta { color: var(--accent-green); letter-spacing: 0.04em; }
|
|
750
741
|
.poster-cta .arrow { color: var(--accent-pink); margin: 0 4px; }
|
|
742
|
+
/* glow just the copy-paste command so it reads as the actionable bit */
|
|
743
|
+
.poster-cta .cta-cmd {
|
|
744
|
+
text-shadow: 0 0 6px rgba(102, 209, 181, 0.6), 0 0 14px rgba(102, 209, 181, 0.3);
|
|
745
|
+
}
|
|
751
746
|
|
|
752
747
|
/* share-row — UI only, outside the PNG capture ─────────────── */
|
|
753
748
|
.poster-share-row {
|
|
@@ -807,7 +802,7 @@
|
|
|
807
802
|
.poster { padding: 24px 22px; }
|
|
808
803
|
.poster-body { gap: 28px; padding: 12px 0; }
|
|
809
804
|
.poster-share-row { grid-template-columns: 1fr; }
|
|
810
|
-
.poster-head { font-size:
|
|
805
|
+
.poster-head { font-size: 12px; }
|
|
811
806
|
.poster-score .score-n { font-size: clamp(72px, 18vw, 120px); }
|
|
812
807
|
.poster-persona .persona-name { font-size: clamp(36px, 9vw, 56px); }
|
|
813
808
|
}
|
|
@@ -1180,4 +1175,4 @@
|
|
|
1180
1175
|
padding: 16px 0;
|
|
1181
1176
|
}
|
|
1182
1177
|
.quirks-thead { display: none; }
|
|
1183
|
-
}
|
|
1178
|
+
}
|
|
@@ -387,8 +387,24 @@ input[type="date"] { color-scheme: dark; }
|
|
|
387
387
|
border: 1px solid var(--line-2);
|
|
388
388
|
border-top: 0;
|
|
389
389
|
background: var(--bg-2);
|
|
390
|
-
|
|
391
|
-
|
|
390
|
+
/* Scroll horizontally on narrow / portrait viewports instead of letting the
|
|
391
|
+
fixed-layout columns collapse into each other. Themed thin scrollbar so it
|
|
392
|
+
reads as part of the same instrument family. */
|
|
393
|
+
overflow-x: auto;
|
|
394
|
+
overflow-y: hidden;
|
|
395
|
+
scrollbar-width: thin;
|
|
396
|
+
scrollbar-color: var(--line-2) transparent;
|
|
397
|
+
}
|
|
398
|
+
.activity-table-wrap::-webkit-scrollbar { height: 10px; }
|
|
399
|
+
.activity-table-wrap::-webkit-scrollbar-track { background: var(--bg-3); }
|
|
400
|
+
.activity-table-wrap::-webkit-scrollbar-thumb {
|
|
401
|
+
background: var(--line-2);
|
|
402
|
+
border: 2px solid var(--bg-3);
|
|
403
|
+
}
|
|
404
|
+
.activity-table-wrap::-webkit-scrollbar-thumb:hover { background: var(--accent-green); }
|
|
405
|
+
/* min-width keeps every column wide enough for its header/badge; below it,
|
|
406
|
+
the wrap scrolls instead of squeezing columns into each other. */
|
|
407
|
+
.activity-table { width: 100%; min-width: 1280px; }
|
|
392
408
|
.activity-thead { background: var(--bg-3); }
|
|
393
409
|
.activity-thead tr { border-bottom: 1px solid var(--line-2); }
|
|
394
410
|
.activity-th {
|
|
@@ -399,8 +415,17 @@ input[type="date"] { color-scheme: dark; }
|
|
|
399
415
|
font-weight: 500;
|
|
400
416
|
color: var(--accent-green);
|
|
401
417
|
text-align: left;
|
|
418
|
+
white-space: nowrap;
|
|
402
419
|
}
|
|
403
420
|
.activity-th.text-right { text-align: right; }
|
|
421
|
+
/* Data cells stay on one line and clip (with ellipsis) at their own column
|
|
422
|
+
edge, so a wide badge/value/header can never overlap the next column.
|
|
423
|
+
Scoped to data rows so the expanded detail row (colSpan) is untouched. */
|
|
424
|
+
.activity-data-row > td {
|
|
425
|
+
overflow: hidden;
|
|
426
|
+
text-overflow: ellipsis;
|
|
427
|
+
white-space: nowrap;
|
|
428
|
+
}
|
|
404
429
|
|
|
405
430
|
/* zebra rhythm — adds ambient banding without breaking the dark feel.
|
|
406
431
|
Hover overrides the stripe so rows feel responsive. */
|
|
@@ -183,9 +183,14 @@ function IntegrationBadge({ integration }: { integration?: string }) {
|
|
|
183
183
|
|
|
184
184
|
function ModeBadge({ mode }: { mode: string }) {
|
|
185
185
|
const isDefault = mode === "default";
|
|
186
|
+
// inline-block + max-w-full + truncate: the pill fits its column for known
|
|
187
|
+
// modes (incl. the longest, "bypassPermissions") and, for any unexpectedly
|
|
188
|
+
// long / custom mode, ellipsizes inside the pill with a hover tooltip rather
|
|
189
|
+
// than being hard-clipped mid-word at the cell edge by .activity-data-row > td.
|
|
186
190
|
return (
|
|
187
191
|
<span
|
|
188
|
-
|
|
192
|
+
title={mode}
|
|
193
|
+
className={`inline-block max-w-full truncate rounded px-1.5 py-0.5 align-middle text-[0.6rem] font-medium border ${
|
|
189
194
|
isDefault
|
|
190
195
|
? "bg-sky-500/10 text-sky-400 border-sky-500/20"
|
|
191
196
|
: "bg-amber-500/10 text-amber-400 border-amber-500/20"
|
|
@@ -632,32 +637,36 @@ function ActivityTab({
|
|
|
632
637
|
) : (
|
|
633
638
|
<div className="overflow-x-auto activity-table-wrap">
|
|
634
639
|
<table className="w-full text-xs activity-table" style={{ tableLayout: "fixed" }}>
|
|
640
|
+
{/* Column widths (table-layout: fixed). Order must match <thead>:
|
|
641
|
+
chevron · time · decision · event · cli · tool · policy · reason · mode · duration · session.
|
|
642
|
+
Badge columns (decision/event/cli/mode) must stay wide enough for their widest
|
|
643
|
+
pill — mode holds "bypassPermissions", the longest badge text in the table. */}
|
|
635
644
|
<colgroup>
|
|
636
645
|
<col style={{ width: 32 }} />
|
|
637
|
-
<col style={{ width: "8%" }} />
|
|
638
|
-
<col style={{ width: "8%" }} />
|
|
639
|
-
<col style={{ width: "8%" }} />
|
|
640
646
|
<col style={{ width: "7%" }} />
|
|
641
|
-
<col style={{ width: "
|
|
642
|
-
<col style={{ width: "
|
|
643
|
-
<col style={{ width: "
|
|
647
|
+
<col style={{ width: "9%" }} />
|
|
648
|
+
<col style={{ width: "12%" }} />
|
|
649
|
+
<col style={{ width: "11%" }} />
|
|
650
|
+
<col style={{ width: "9%" }} />
|
|
651
|
+
<col style={{ width: "13%" }} />
|
|
652
|
+
<col style={{ width: "12%" }} />
|
|
653
|
+
<col style={{ width: "11%" }} />
|
|
644
654
|
<col style={{ width: "8%" }} />
|
|
645
655
|
<col style={{ width: "8%" }} />
|
|
646
|
-
<col style={{ width: "7%" }} />
|
|
647
656
|
</colgroup>
|
|
648
657
|
<thead className="activity-thead">
|
|
649
658
|
<tr>
|
|
650
659
|
<th className="px-4 py-3" />
|
|
660
|
+
<th className="px-3 py-3 activity-th">Time</th>
|
|
651
661
|
<th className="px-3 py-3 activity-th">Decision</th>
|
|
652
662
|
<th className="px-3 py-3 activity-th">Event</th>
|
|
653
663
|
<th className="px-3 py-3 activity-th">CLI</th>
|
|
654
664
|
<th className="px-3 py-3 activity-th">Tool</th>
|
|
655
665
|
<th className="px-3 py-3 activity-th">Policy</th>
|
|
656
666
|
<th className="px-3 py-3 activity-th">Reason</th>
|
|
667
|
+
<th className="px-3 py-3 activity-th">Mode</th>
|
|
657
668
|
<th className="px-3 py-3 activity-th">Duration</th>
|
|
658
669
|
<th className="px-3 py-3 activity-th">Session</th>
|
|
659
|
-
<th className="px-3 py-3 activity-th">Mode</th>
|
|
660
|
-
<th className="px-3 py-3 activity-th text-right">Time</th>
|
|
661
670
|
</tr>
|
|
662
671
|
</thead>
|
|
663
672
|
<tbody className="divide-y divide-border/30">
|
|
@@ -669,7 +678,7 @@ function ActivityTab({
|
|
|
669
678
|
<React.Fragment key={`${item.timestamp}-${i}`}>
|
|
670
679
|
<tr
|
|
671
680
|
onClick={() => toggleRow(i)}
|
|
672
|
-
className={`cursor-pointer transition-colors ${
|
|
681
|
+
className={`activity-data-row cursor-pointer transition-colors ${
|
|
673
682
|
isDeny
|
|
674
683
|
? "bg-red-500/[0.03] hover:bg-red-500/[0.07] border-l-2 border-l-red-500/40"
|
|
675
684
|
: isInstruct
|
|
@@ -686,6 +695,12 @@ function ActivityTab({
|
|
|
686
695
|
}`}
|
|
687
696
|
/>
|
|
688
697
|
</td>
|
|
698
|
+
<td
|
|
699
|
+
className="px-3 py-2 text-muted-foreground whitespace-nowrap"
|
|
700
|
+
title={formatAbsoluteTime(item.timestamp)}
|
|
701
|
+
>
|
|
702
|
+
{formatRelativeTime(item.timestamp)}
|
|
703
|
+
</td>
|
|
689
704
|
<td className="px-3 py-2">
|
|
690
705
|
<DecisionBadge decision={item.decision} />
|
|
691
706
|
</td>
|
|
@@ -714,6 +729,13 @@ function ActivityTab({
|
|
|
714
729
|
>
|
|
715
730
|
{item.reason ?? "\u2014"}
|
|
716
731
|
</td>
|
|
732
|
+
<td className="px-3 py-2">
|
|
733
|
+
{item.permissionMode ? (
|
|
734
|
+
<ModeBadge mode={item.permissionMode} />
|
|
735
|
+
) : (
|
|
736
|
+
"\u2014"
|
|
737
|
+
)}
|
|
738
|
+
</td>
|
|
717
739
|
<td className="px-3 py-2">
|
|
718
740
|
<DurationDisplay ms={item.durationMs} />
|
|
719
741
|
</td>
|
|
@@ -725,19 +747,6 @@ function ActivityTab({
|
|
|
725
747
|
cwd={item.cwd}
|
|
726
748
|
/>
|
|
727
749
|
</td>
|
|
728
|
-
<td className="px-3 py-2">
|
|
729
|
-
{item.permissionMode ? (
|
|
730
|
-
<ModeBadge mode={item.permissionMode} />
|
|
731
|
-
) : (
|
|
732
|
-
"\u2014"
|
|
733
|
-
)}
|
|
734
|
-
</td>
|
|
735
|
-
<td
|
|
736
|
-
className="px-3 py-2 text-right text-muted-foreground whitespace-nowrap"
|
|
737
|
-
title={formatAbsoluteTime(item.timestamp)}
|
|
738
|
-
>
|
|
739
|
-
{formatRelativeTime(item.timestamp)}
|
|
740
|
-
</td>
|
|
741
750
|
</tr>
|
|
742
751
|
{isExpanded && <DetailPanel item={item} />}
|
|
743
752
|
</React.Fragment>
|
|
@@ -2,10 +2,9 @@
|
|
|
2
2
|
"use client";
|
|
3
3
|
|
|
4
4
|
import React, { useState, useCallback } from "react";
|
|
5
|
-
import { GitBranch,
|
|
5
|
+
import { GitBranch, ChevronDown, Star, BookOpen, MessageCircle, MessageSquareWarning } from "lucide-react";
|
|
6
6
|
import { Button } from "@/components/ui/button";
|
|
7
7
|
|
|
8
|
-
const GITHUB_REPO = "https://github.com/failproofai/failproofai";
|
|
9
8
|
const CONTACT_EMAIL = "failproofai@exosphere.host";
|
|
10
9
|
|
|
11
10
|
const options = [
|
|
@@ -19,38 +18,24 @@ const options = [
|
|
|
19
18
|
{
|
|
20
19
|
label: "Documentation",
|
|
21
20
|
icon: BookOpen,
|
|
22
|
-
href: "https://docs.befailproof.ai/",
|
|
21
|
+
href: "https://docs.befailproof.ai/introduction",
|
|
23
22
|
color: "#60a5fa",
|
|
24
23
|
bg: "rgba(96,165,250,0.08)",
|
|
25
24
|
},
|
|
26
25
|
{
|
|
27
|
-
label: "Join our
|
|
28
|
-
icon:
|
|
29
|
-
href: "https://
|
|
30
|
-
color: "#
|
|
31
|
-
bg: "rgba(
|
|
26
|
+
label: "Join our Discord",
|
|
27
|
+
icon: MessageCircle,
|
|
28
|
+
href: "https://discord.gg/2zjBZP7yQJ",
|
|
29
|
+
color: "#5865f2",
|
|
30
|
+
bg: "rgba(88,101,242,0.08)",
|
|
32
31
|
},
|
|
33
32
|
{
|
|
34
|
-
label: "
|
|
35
|
-
icon:
|
|
36
|
-
href:
|
|
33
|
+
label: "Feedback & Issues",
|
|
34
|
+
icon: MessageSquareWarning,
|
|
35
|
+
href: "https://github.com/FailproofAI/failproofai/issues/new/choose",
|
|
37
36
|
color: "#34d399",
|
|
38
37
|
bg: "rgba(52,211,153,0.08)",
|
|
39
38
|
},
|
|
40
|
-
{
|
|
41
|
-
label: "Report an Issue",
|
|
42
|
-
icon: Bug,
|
|
43
|
-
href: `${GITHUB_REPO}/issues/new?labels=bug&title=Bug+Report%3A+`,
|
|
44
|
-
color: "#f87171",
|
|
45
|
-
bg: "rgba(248,113,113,0.08)",
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
label: "Ask a Question",
|
|
49
|
-
icon: MessageSquare,
|
|
50
|
-
href: `${GITHUB_REPO}/discussions/new?category=q-a`,
|
|
51
|
-
color: "#fb923c",
|
|
52
|
-
bg: "rgba(251,146,60,0.08)",
|
|
53
|
-
},
|
|
54
39
|
] as const;
|
|
55
40
|
|
|
56
41
|
export const ReachDevelopers: React.FC = () => {
|
|
@@ -249,17 +249,20 @@ export interface InviteSendResult {
|
|
|
249
249
|
/**
|
|
250
250
|
* Send invite emails to a batch of friends. The api-server pulls the sender's
|
|
251
251
|
* email from the access-token claims and Cc's them on every outbound message
|
|
252
|
-
* so the recipient sees who invited them.
|
|
252
|
+
* so the recipient sees who invited them. `score` (the sender's audit score,
|
|
253
|
+
* 0–100) is forwarded so the invite body can show "mine came out at N/100";
|
|
254
|
+
* omit it and the api-server renders score-free copy.
|
|
253
255
|
*
|
|
254
256
|
* Contract is handed over to the platform team separately.
|
|
255
257
|
*/
|
|
256
258
|
export async function sendInvites(
|
|
257
259
|
accessToken: string,
|
|
258
260
|
to: string[],
|
|
261
|
+
score?: number,
|
|
259
262
|
): Promise<InviteSendResult> {
|
|
260
263
|
return postJson<InviteSendResult>(
|
|
261
264
|
"/v0/invite",
|
|
262
|
-
{ to },
|
|
265
|
+
score === undefined ? { to } : { to, score },
|
|
263
266
|
{ accessToken },
|
|
264
267
|
);
|
|
265
268
|
}
|
|
@@ -34,6 +34,10 @@ export function captureClientEvent(
|
|
|
34
34
|
method: "POST",
|
|
35
35
|
headers: { "Content-Type": "application/json" },
|
|
36
36
|
body: payload,
|
|
37
|
+
// keepalive lets the request outlive a page navigation/unload — without it,
|
|
38
|
+
// events fired right before the page goes away (client_error / unhandled_*
|
|
39
|
+
// from an error boundary, or a share click that opens a new tab) are dropped.
|
|
40
|
+
keepalive: true,
|
|
37
41
|
signal: AbortSignal.timeout(5000),
|
|
38
42
|
}).catch(() => {});
|
|
39
43
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "failproofai",
|
|
3
|
-
"version": "0.0.11
|
|
3
|
+
"version": "0.0.11",
|
|
4
4
|
"description": "The easiest way to manage policies that keep your AI agents reliable, on-task, and running autonomously — for Claude Code & the Agents SDK",
|
|
5
5
|
"bin": {
|
|
6
6
|
"failproofai": "./dist/cli.mjs"
|
|
@@ -38,7 +38,8 @@
|
|
|
38
38
|
"translate:readme": "bun scripts/translate-docs/cli.ts --readme-only",
|
|
39
39
|
"translate:docs": "bun scripts/translate-docs/cli.ts --docs-only",
|
|
40
40
|
"translate:dry-run": "bun scripts/translate-docs/cli.ts --dry-run",
|
|
41
|
-
"translate:validate": "bun scripts/translate-docs/cli.ts --validate"
|
|
41
|
+
"translate:validate": "bun scripts/translate-docs/cli.ts --validate",
|
|
42
|
+
"validate:mdx": "bun scripts/validate-mdx.ts"
|
|
42
43
|
},
|
|
43
44
|
"keywords": [
|
|
44
45
|
"claude",
|
|
@@ -71,13 +72,14 @@
|
|
|
71
72
|
"access": "public"
|
|
72
73
|
},
|
|
73
74
|
"devDependencies": {
|
|
74
|
-
"@anthropic-ai/sdk": "^0.
|
|
75
|
+
"@anthropic-ai/sdk": "^0.105.0",
|
|
76
|
+
"@mdx-js/mdx": "^3.1.1",
|
|
75
77
|
"@tailwindcss/postcss": "^4.3.1",
|
|
76
78
|
"@tanstack/react-virtual": "^3.14.3",
|
|
77
79
|
"@testing-library/jest-dom": "^6.9.1",
|
|
78
80
|
"@testing-library/react": "^16.3.2",
|
|
79
81
|
"@testing-library/user-event": "^14.6.1",
|
|
80
|
-
"@types/node": "
|
|
82
|
+
"@types/node": "26.0.0",
|
|
81
83
|
"@types/react": "19.2.17",
|
|
82
84
|
"@types/react-dom": "^19.2.3",
|
|
83
85
|
"@vitejs/plugin-react": "^6.0.1",
|
|
@@ -9,7 +9,7 @@ const currentPort = parseInt(process.env.PORT, 10) || 3000
|
|
|
9
9
|
const hostname = process.env.HOSTNAME || '0.0.0.0'
|
|
10
10
|
|
|
11
11
|
let keepAliveTimeout = parseInt(process.env.KEEP_ALIVE_TIMEOUT, 10)
|
|
12
|
-
const nextConfig = {"env":{"NEXT_PUBLIC_APP_VERSION":"0.0.11
|
|
12
|
+
const nextConfig = {"env":{"NEXT_PUBLIC_APP_VERSION":"0.0.11"},"typescript":{"ignoreBuildErrors":false},"typedRoutes":false,"distDir":"./.next","cleanDistDir":true,"assetPrefix":"","cacheMaxMemorySize":52428800,"configOrigin":"next.config.ts","useFileSystemPublicRoutes":true,"generateEtags":true,"pageExtensions":["tsx","ts","jsx","js"],"poweredByHeader":true,"compress":true,"images":{"deviceSizes":[640,750,828,1080,1200,1920,2048,3840],"imageSizes":[32,48,64,96,128,256,384],"path":"/_next/image","loader":"default","loaderFile":"","domains":[],"disableStaticImages":false,"minimumCacheTTL":14400,"formats":["image/webp"],"maximumRedirects":3,"maximumResponseBody":50000000,"dangerouslyAllowLocalIP":false,"dangerouslyAllowSVG":false,"contentSecurityPolicy":"script-src 'none'; frame-src 'none'; sandbox;","contentDispositionType":"attachment","localPatterns":[{"pathname":"**","search":""}],"remotePatterns":[],"qualities":[75],"unoptimized":true,"customCacheHandler":false},"devIndicators":{"position":"bottom-left"},"onDemandEntries":{"maxInactiveAge":60000,"pagesBufferLength":5},"basePath":"","sassOptions":{},"trailingSlash":false,"i18n":null,"productionBrowserSourceMaps":false,"excludeDefaultMomentLocales":true,"reactProductionProfiling":false,"reactStrictMode":null,"reactMaxHeadersLength":6000,"httpAgentOptions":{"keepAlive":true},"logging":{"serverFunctions":true,"browserToTerminal":"warn"},"compiler":{},"expireTime":31536000,"staticPageGenerationTimeout":60,"output":"standalone","modularizeImports":{"@mui/icons-material":{"transform":"@mui/icons-material/{{member}}"},"lodash":{"transform":"lodash/{{member}}"}},"outputFileTracingRoot":"/home/runner/work/failproofai/failproofai","cacheComponents":false,"cacheLife":{"default":{"stale":300,"revalidate":900,"expire":4294967294},"seconds":{"stale":30,"revalidate":1,"expire":60},"minutes":{"stale":300,"revalidate":60,"expire":3600},"hours":{"stale":300,"revalidate":3600,"expire":86400},"days":{"stale":300,"revalidate":86400,"expire":604800},"weeks":{"stale":300,"revalidate":604800,"expire":2592000},"max":{"stale":300,"revalidate":2592000,"expire":31536000}},"cacheHandlers":{},"experimental":{"appNewScrollHandler":false,"useSkewCookie":false,"cssChunking":true,"multiZoneDraftMode":false,"appNavFailHandling":false,"prerenderEarlyExit":true,"serverMinification":true,"linkNoTouchStart":false,"caseSensitiveRoutes":false,"cachedNavigations":false,"partialFallbacks":false,"dynamicOnHover":false,"varyParams":false,"prefetchInlining":false,"preloadEntriesOnStart":true,"clientRouterFilter":true,"clientRouterFilterRedirects":false,"fetchCacheKeyPrefix":"","proxyPrefetch":"flexible","optimisticClientCache":true,"manualClientBasePath":false,"cpus":3,"memoryBasedWorkersCount":false,"imgOptConcurrency":null,"imgOptTimeoutInSeconds":7,"imgOptMaxInputPixels":268402689,"imgOptSequentialRead":null,"imgOptSkipMetadata":null,"isrFlushToDisk":true,"workerThreads":false,"optimizeCss":false,"nextScriptWorkers":false,"scrollRestoration":false,"externalDir":false,"disableOptimizedLoading":false,"gzipSize":true,"craCompat":false,"esmExternals":true,"fullySpecified":false,"swcTraceProfiling":false,"forceSwcTransforms":false,"largePageDataBytes":128000,"typedEnv":false,"parallelServerCompiles":false,"parallelServerBuildTraces":false,"ppr":false,"authInterrupts":false,"webpackMemoryOptimizations":false,"optimizeServerReact":true,"strictRouteTypes":false,"viewTransition":false,"removeUncaughtErrorAndRejectionListeners":false,"validateRSCRequestHeaders":false,"staleTimes":{"dynamic":0,"static":300},"reactDebugChannel":true,"serverComponentsHmrCache":true,"staticGenerationMaxConcurrency":8,"staticGenerationMinPagesPerWorker":25,"transitionIndicator":false,"gestureTransition":false,"inlineCss":false,"useCache":false,"globalNotFound":false,"browserDebugInfoInTerminal":"warn","lockDistDir":true,"proxyClientMaxBodySize":10485760,"hideLogsAfterAbort":false,"mcpServer":true,"turbopackFileSystemCacheForDev":true,"turbopackFileSystemCacheForBuild":false,"turbopackInferModuleSideEffects":true,"turbopackPluginRuntimeStrategy":"childProcesses","optimizePackageImports":["lucide-react","date-fns","lodash-es","ramda","antd","react-bootstrap","ahooks","@ant-design/icons","@headlessui/react","@headlessui-float/react","@heroicons/react/20/solid","@heroicons/react/24/solid","@heroicons/react/24/outline","@visx/visx","@tremor/react","rxjs","@mui/material","@mui/icons-material","recharts","react-use","effect","@effect/schema","@effect/platform","@effect/platform-node","@effect/platform-browser","@effect/platform-bun","@effect/sql","@effect/sql-mssql","@effect/sql-mysql2","@effect/sql-pg","@effect/sql-sqlite-node","@effect/sql-sqlite-bun","@effect/sql-sqlite-wasm","@effect/sql-sqlite-react-native","@effect/rpc","@effect/rpc-http","@effect/typeclass","@effect/experimental","@effect/opentelemetry","@material-ui/core","@material-ui/icons","@tabler/icons-react","mui-core","react-icons/ai","react-icons/bi","react-icons/bs","react-icons/cg","react-icons/ci","react-icons/di","react-icons/fa","react-icons/fa6","react-icons/fc","react-icons/fi","react-icons/gi","react-icons/go","react-icons/gr","react-icons/hi","react-icons/hi2","react-icons/im","react-icons/io","react-icons/io5","react-icons/lia","react-icons/lib","react-icons/lu","react-icons/md","react-icons/pi","react-icons/ri","react-icons/rx","react-icons/si","react-icons/sl","react-icons/tb","react-icons/tfi","react-icons/ti","react-icons/vsc","react-icons/wi"],"trustHostHeader":false,"isExperimentalCompile":false},"htmlLimitedBots":"[\\w-]+-Google|Google-[\\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight","bundlePagesRouterDependencies":false,"configFileName":"next.config.ts","outputFileTracingExcludes":{"*":["node_modules/@img/**","node_modules/sharp/**"]},"turbopack":{"root":"/home/runner/work/failproofai/failproofai"},"distDirRoot":".next"}
|
|
13
13
|
|
|
14
14
|
process.env.__NEXT_PRIVATE_STANDALONE_CONFIG = JSON.stringify(nextConfig)
|
|
15
15
|
|
package/README.md
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
[](https://www.npmjs.com/package/failproofai)
|
|
6
6
|
[](https://github.com/failproofai/failproofai/actions)
|
|
7
7
|
[](https://github.com/failproofai/failproofai/actions/workflows/osv-scanner.yml)
|
|
8
|
-
[](https://docs.befailproof.ai)
|
|
8
|
+
[](https://discord.gg/2zjBZP7yQJ)
|
|
9
|
+
[](https://docs.befailproof.ai/introduction)
|
|
10
10
|
[](./LICENSE)
|
|
11
11
|
|
|
12
12
|
**Translations:** [简体中文](./docs/i18n/README.zh.md) · [日本語](./docs/i18n/README.ja.md) · [한국어](./docs/i18n/README.ko.md) · [Español](./docs/i18n/README.es.md) · [Português](./docs/i18n/README.pt-br.md) · [Deutsch](./docs/i18n/README.de.md) · [Français](./docs/i18n/README.fr.md) · [Русский](./docs/i18n/README.ru.md) · [हिन्दी](./docs/i18n/README.hi.md) · [Türkçe](./docs/i18n/README.tr.md) · [Tiếng Việt](./docs/i18n/README.vi.md) · [Italiano](./docs/i18n/README.it.md) · [العربية](./docs/i18n/README.ar.md) · [עברית](./docs/i18n/README.he.md)
|