failproofai 1.0.0-beta.7 → 1.0.0-beta.8

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.
Files changed (124) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/build-manifest.json +3 -3
  3. package/.next/standalone/.next/prerender-manifest.json +3 -3
  4. package/.next/standalone/.next/required-server-files.json +1 -1
  5. package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
  6. package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  7. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  8. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
  10. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +2 -2
  11. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
  12. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +3 -3
  13. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +3 -3
  14. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  15. package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  16. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  17. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  18. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  19. package/.next/standalone/.next/server/app/_not-found.rsc +14 -14
  20. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +14 -14
  21. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
  22. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +9 -9
  23. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  24. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
  25. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  26. package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -1
  27. package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
  28. package/.next/standalone/.next/server/app/api/audit/status/route.js.nft.json +1 -1
  29. package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
  30. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
  31. package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
  32. package/.next/standalone/.next/server/app/api/auth/reminder/route.js.nft.json +1 -1
  33. package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
  34. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
  35. package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
  36. package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
  37. package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
  38. package/.next/standalone/.next/server/app/index.html +1 -1
  39. package/.next/standalone/.next/server/app/index.rsc +14 -14
  40. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  41. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +14 -14
  42. package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +4 -4
  43. package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +9 -9
  44. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  45. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
  46. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  47. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  48. package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +10 -10
  49. package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
  50. package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
  51. package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
  52. package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
  53. package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
  54. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
  55. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
  56. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
  57. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
  58. package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
  59. package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
  60. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  61. package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +4 -4
  62. package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
  63. package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  64. package/.next/standalone/.next/server/chunks/[root-of-the-server]__06hexd0._.js +1 -1
  65. package/.next/standalone/.next/server/chunks/_0lxbzdq._.js +1 -1
  66. package/.next/standalone/.next/server/chunks/_1zuiiy3._.js +1 -1
  67. package/.next/standalone/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_17k9e3w.js +3 -3
  68. package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
  69. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ommekk._.js +3 -0
  70. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0spkm68._.js +2 -2
  71. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1rv-sc9._.js +1 -1
  72. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0c_qcgp._.js → [root-of-the-server]__1tkyag1._.js} +2 -2
  73. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1tyf0tc._.js +1 -1
  74. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1u-wx42._.js +2 -2
  75. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1v185mo._.js +1 -1
  76. package/.next/standalone/.next/server/chunks/ssr/_04mekdy._.js +1 -1
  77. package/.next/standalone/.next/server/chunks/ssr/{_194yh9u._.js → _0i4l3_6._.js} +1 -1
  78. package/.next/standalone/.next/server/chunks/ssr/_0r-dsre._.js +1 -1
  79. package/.next/standalone/.next/server/chunks/ssr/_0rjgfln._.js +1 -1
  80. package/.next/standalone/.next/server/chunks/ssr/_0se484m._.js +1 -1
  81. package/.next/standalone/.next/server/chunks/ssr/_0uz7o9y._.js +1 -1
  82. package/.next/standalone/.next/server/chunks/ssr/_1fahg9e._.js +1 -1
  83. package/.next/standalone/.next/server/chunks/ssr/_1w8sola._.js +1 -1
  84. package/.next/standalone/.next/server/chunks/ssr/_1w_6p9g._.js +1 -1
  85. package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +1 -1
  86. package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
  87. package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +1 -1
  88. package/.next/standalone/.next/server/chunks/ssr/src_hooks_builtin-policies_ts_09j2ndl._.js +1 -1
  89. package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
  90. package/.next/standalone/.next/server/pages/404.html +1 -1
  91. package/.next/standalone/.next/server/pages/500.html +1 -1
  92. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  93. package/.next/standalone/.next/server/server-reference-manifest.json +15 -15
  94. package/.next/standalone/.next/static/chunks/{2aej0vi1fm87m.js → 02vvywmww22zz.js} +1 -1
  95. package/.next/standalone/.next/static/chunks/{3t1wr_kx6brwc.js → 0_-focvo4cuiv.js} +1 -1
  96. package/.next/standalone/.next/static/chunks/{2bxld6-rym3ah.js → 1fwh-2un_l-eo.js} +1 -1
  97. package/.next/standalone/.next/static/chunks/{2p2kz4aj1tooj.js → 1zrdsxe91qq6i.js} +1 -1
  98. package/.next/standalone/.next/static/chunks/{0m-m7wgtxdoav.js → 2047vah_v4emu.js} +1 -1
  99. package/.next/standalone/.next/static/chunks/23hl78dzffun4.js +6 -0
  100. package/.next/standalone/.next/static/chunks/{11l6oh9cyb35a.js → 2bw0stk-s-1dd.js} +1 -1
  101. package/.next/standalone/.next/static/chunks/{0gr76ps8_zm26.js → 2r_j5wrkbu5wm.js} +1 -1
  102. package/.next/standalone/.next/static/chunks/3m8onpqrjxzu5.js +1 -0
  103. package/.next/standalone/.next/static/chunks/{36pc3_8fpb6ic.js → 3yn1y6ckypqwp.js} +1 -1
  104. package/.next/standalone/package.json +5 -5
  105. package/.next/standalone/server.js +1 -1
  106. package/bin/failproofai.mjs +118 -1
  107. package/dist/cli.mjs +1166 -101
  108. package/dist/worker.mjs +77 -6
  109. package/package.json +5 -5
  110. package/scripts/repro-npm-install.sh +155 -0
  111. package/src/hooks/builtin-policies.ts +154 -2
  112. package/src/hooks/configure-wizard.ts +16 -6
  113. package/src/hooks/daemon-client.ts +35 -0
  114. package/src/hooks/daemon-service.ts +227 -22
  115. package/src/hooks/first-run-gate.ts +9 -1
  116. package/src/hooks/fp-reset.ts +25 -0
  117. package/src/hooks/uninstall-cli.ts +345 -0
  118. package/src/hooks/worker-server.ts +12 -2
  119. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0kbc9bs._.js +0 -3
  120. package/.next/standalone/.next/static/chunks/0945ybz3fsvba.js +0 -1
  121. package/.next/standalone/.next/static/chunks/166f8qnh03jqc.js +0 -6
  122. /package/.next/standalone/.next/static/{LUaLkKg40nSkHrIajexIk → gOR8i03AeQm1VnIayDHVV}/_buildManifest.js +0 -0
  123. /package/.next/standalone/.next/static/{LUaLkKg40nSkHrIajexIk → gOR8i03AeQm1VnIayDHVV}/_clientMiddlewareManifest.js +0 -0
  124. /package/.next/standalone/.next/static/{LUaLkKg40nSkHrIajexIk → gOR8i03AeQm1VnIayDHVV}/_ssgManifest.js +0 -0
@@ -1 +1 @@
1
- (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,34713,e=>{"use strict";e.s(["formatDuration",0,function(e){if(e<1e3)return`${e}ms`;let t=Math.round(e/100);if(t<600)return`${(t/10).toFixed(1)}s`;let n=Math.round(e/1e3);if(n<3600){let e=Math.floor(n/60);return`${e}m ${n%60}s`}let a=Math.round(e/6e4),r=Math.floor(a/60);return`${r}h ${a%60}m`},"formatRelativeTime",0,function(e){let t=Date.now()-e;return t<6e4?`${Math.max(1,Math.floor(t/1e3))}s ago`:t<36e5?`${Math.floor(t/6e4)}m ago`:t<864e5?`${Math.floor(t/36e5)}h ago`:`${Math.floor(t/864e5)}d ago`}])},86616,29054,e=>{"use strict";function t(e,n={},a=15e3){let r=AbortSignal.timeout(a),i=n.signal?AbortSignal.any([n.signal,r]):r;return fetch(e,{...n,signal:i})}function n(e){if(null===e||"object"!=typeof e)return!1;let t=e.name;return"AbortError"===t||"TimeoutError"===t}e.s(["fetchWithTimeout",0,t,"isAbortError",0,n],29054);class a extends Error{kind;constructor(e,t){super(t),this.kind=e,this.name="RerunError"}}async function r(e){try{let n=await t("/api/audit/run",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({cli:e.cli.length>0?e.cli:void 0,since:"all"===e.since?void 0:e.since,noCache:!!e.noCache||void 0})});if(!n.ok&&409!==n.status){let e=await n.text().catch(()=>"");throw console.error("audit run failed:",n.status,e),new a("post_failed",`audit run failed (${n.status})`)}}catch(e){if(e instanceof a)throw e;throw console.error("audit run request failed:",e),new a(n(e)?"timeout":"network","audit run request failed")}let r=0;for(;;){await new Promise(e=>setTimeout(e,1e3));let e=null;try{let n=await t("/api/audit/status",{cache:"no-store"});n.ok&&(e=await n.json())}catch{}if(null===e){if(++r>=10)throw new a("network","audit status poll lost the server");continue}if(r=0,!e.running){if(e.error)throw new a("post_failed",e.error);return}}}e.s(["RerunError",0,a,"triggerRun",0,r],86616)},93237,e=>{"use strict";var t=e.i(43476),n=e.i(71645),a=e.i(95187);let r=(0,a.createServerReference)("0075fc0acfe318e45ceb23fb5fd23941b66dd3beec",a.callServer,void 0,a.findSourceMapURL,"getScheduledAuditAction"),i=(0,a.createServerReference)("40a988a2444a72107721f91defe3ad94cc8de4159d",a.callServer,void 0,a.findSourceMapURL,"setAutoAuditAction"),s=(0,a.createServerReference)("40e94dfb38dbea8e7a1215a1cd56852cbb3e4a1b32",a.callServer,void 0,a.findSourceMapURL,"setAuditIntervalAction");var l=e.i(86616),o=e.i(55574),c=e.i(29054),d=e.i(34713);function u(e){return new Date(e).toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}function h({enabled:e,onChange:n,disabled:a,label:r}){return(0,t.jsx)("button",{type:"button",onClick:n,disabled:a,role:"switch","aria-checked":e,"aria-label":r,className:`relative inline-flex h-4 w-7 shrink-0 items-center rounded-full transition-colors disabled:opacity-40 ${e?"bg-emerald-500":"bg-muted-foreground/30"}`,children:(0,t.jsx)("span",{className:`inline-block h-3 w-3 rounded-full bg-white shadow transition-transform ${e?"translate-x-3.5":"translate-x-0.5"}`})})}let f={ok:{fg:"var(--accent-green)",bg:"rgba(102,209,181,0.10)",bd:"rgba(102,209,181,0.30)"},warn:{fg:"var(--amber)",bg:"rgba(232,196,106,0.10)",bd:"rgba(232,196,106,0.30)"},bad:{fg:"var(--accent-pink)",bg:"rgba(228,88,124,0.10)",bd:"rgba(228,88,124,0.30)"},muted:{fg:"var(--ink-2)",bg:"transparent",bd:"var(--line-2)"}};function p({tone:e,children:n}){let a=f[e];return(0,t.jsx)("span",{style:{display:"inline-flex",alignItems:"center",gap:6,padding:"3px 9px",fontFamily:"var(--font-mono)",fontSize:11,letterSpacing:"0.04em",color:a.fg,background:a.bg,border:`1px solid ${a.bd}`,textTransform:"uppercase"},children:n})}let g={fontFamily:"var(--font-mono)",fontSize:16,fontWeight:600,letterSpacing:"-0.01em",color:"var(--ink)",margin:"0 0 4px"},m={fontFamily:"var(--font-mono)",fontSize:13,color:"var(--ink-2)",lineHeight:1.65,margin:0},y={...m,color:"var(--dim)",fontSize:12},x={color:"var(--ink)",fontVariantLigatures:"none"};function b({children:e}){return(0,t.jsx)("code",{style:{fontFamily:"var(--font-mono)",fontSize:12,color:"var(--accent-green)",background:"var(--bg-2)",border:"1px solid var(--line-2)",padding:"1px 6px",whiteSpace:"nowrap"},children:e})}function v({view:e,onReload:a}){let r,[f,j]=(0,n.useState)(e.auto),[w,S]=(0,n.useState)(e.intervalDays),[k,T]=(0,n.useState)(!1),[A,M]=(0,n.useState)(!1),[R,C]=(0,n.useState)(!1),[D,$]=(0,n.useState)(!1);(0,n.useEffect)(()=>j(e.auto),[e.auto]),(0,n.useEffect)(()=>S(e.intervalDays),[e.intervalDays]),(0,n.useEffect)(()=>{let e=!1;return(async()=>{try{let t=await (0,c.fetchWithTimeout)("/api/audit/status",{cache:"no-store"});if(t.ok&&!e){let e=await t.json();C(!!e.running)}}catch{}})(),()=>{e=!0}},[]);let E="running"!==e.daemon,N="unsupported-platform"===e.daemon,F=(0,n.useCallback)(async()=>{let e=!f;j(e),T(!0);try{let t=await i(e);j(t.auto),(0,o.toast)(t.auto?"Scheduled scanning on.":"Scheduled scanning off."),await a()}catch{j(!e),(0,o.toast)("Could not save that.")}finally{T(!1)}},[f,a]),I=(0,n.useCallback)(async t=>{M(!0);try{let e=await s(t);S(e.intervalDays),(0,o.toast)(`Scanning every ${e.intervalDays} day${1===e.intervalDays?"":"s"}.`)}catch{S(e.intervalDays),(0,o.toast)("Could not save that.")}finally{M(!1)}},[e.intervalDays]),L=(0,n.useCallback)(async()=>{if(!D&&!R){$(!0),C(!0);try{await (0,l.triggerRun)({cli:[],since:"all",noCache:!1}),(0,o.toast)("Audit complete."),await a()}catch(t){let e=t instanceof l.RerunError&&"timeout"===t.kind?"The scan is taking a while — it will finish in the background.":"The scan could not be completed.";(0,o.toast)(e)}finally{$(!1),C(!1)}}},[D,R,a]),W=e.schedule,z=W?.lastExitCode!=null&&0!==W.lastExitCode&&75!==W.lastExitCode;return(0,t.jsxs)("div",{className:"panel",style:{padding:20,marginBottom:20},children:[(0,t.jsxs)("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",gap:12,flexWrap:"wrap"},children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("h3",{style:g,children:"Scheduled audit"}),(0,t.jsx)("p",{style:y,children:"Scan this machine on a timer, in the background."})]}),(0,t.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:10},children:["running"===e.daemon&&(0,t.jsx)(p,{tone:"ok",children:"daemon running"}),"stopped"===e.daemon&&(0,t.jsx)(p,{tone:"warn",children:"daemon stopped"}),"not-installed"===e.daemon&&(0,t.jsx)(p,{tone:"warn",children:"daemon not installed"}),"unsupported-platform"===e.daemon&&(0,t.jsx)(p,{tone:"muted",children:"daemon unavailable"})]})]}),(0,t.jsxs)("div",{style:{display:"flex",alignItems:"flex-start",gap:12,marginTop:18},children:[(0,t.jsx)("div",{style:{marginTop:2},children:(0,t.jsx)(h,{enabled:f,onChange:F,disabled:k||N,label:f?"Turn off scheduled scanning":"Turn on scheduled scanning"})}),(0,t.jsxs)("div",{style:{minWidth:0},children:[(0,t.jsx)("p",{style:{...m,color:"var(--ink)"},children:f?"Scanning this machine on a schedule.":"Scan this machine on a schedule."}),(0,t.jsxs)("p",{style:{...m,marginTop:6},children:["The scan reads the ",(0,t.jsx)("span",{style:x,children:"contents"})," of every session transcript on disk across all installed agent CLIs — your prompts, the files they read and wrote, and command output. It runs entirely on this machine. Nothing is sent anywhere unless you also turn on emailed reports below."]})]})]}),(0,t.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:10,marginTop:16,flexWrap:"wrap"},children:[(0,t.jsx)("label",{htmlFor:"scan-interval",style:{...m},children:"Scan every"}),(0,t.jsx)("input",{id:"scan-interval",type:"number",min:1,max:90,step:1,value:w,disabled:A||N,onChange:e=>S(Number(e.target.value)),onBlur:t=>{let n=Number(t.target.value);Number.isFinite(n)?n!==e.intervalDays&&I(n):S(e.intervalDays)},style:{width:64,padding:"6px 8px",background:"var(--bg)",border:"1px solid var(--line-2)",color:"var(--ink)",fontFamily:"var(--font-mono)",fontSize:13,textAlign:"center"}}),(0,t.jsxs)("span",{style:m,children:["day",1===w?"":"s","."]}),(0,t.jsx)("span",{style:y,children:"1–90; the config keeps it in range."})]}),(0,t.jsxs)("div",{style:{marginTop:18,paddingTop:16,borderTop:"1px dashed var(--line)",display:"flex",flexDirection:"column",gap:6},children:[R&&(0,t.jsx)("p",{style:{...m,color:"var(--accent-green)"},children:"A scan is running now…"}),W?.lastRunAtMs!=null?(0,t.jsxs)("p",{style:m,children:["Last scheduled scan:"," ",(0,t.jsx)("span",{style:x,children:u(W.lastRunAtMs)})," ",(0,t.jsxs)("span",{style:y,children:["(",(0,d.formatRelativeTime)(W.lastRunAtMs),")"]})]}):e.lastResultAt?(0,t.jsxs)("p",{style:m,children:["Last audit result:"," ",(0,t.jsx)("span",{style:x,children:u(new Date(e.lastResultAt).getTime())})," ",(0,t.jsx)("span",{style:y,children:"(no scheduled scan has run yet)"})]}):(0,t.jsx)("p",{style:m,children:"No scan has run yet."}),f?W?.nextDueAtMs!=null?(0,t.jsxs)("p",{style:m,children:["Next scan due:"," ",(0,t.jsx)("span",{style:x,children:u(W.nextDueAtMs)})," ",(0,t.jsxs)("span",{style:y,children:["(",(r=W.nextDueAtMs-Date.now())<=0?"now":r<36e5?`in ${Math.max(1,Math.floor(r/6e4))}m`:r<864e5?`in ${Math.floor(r/36e5)}h`:`in ${Math.floor(r/864e5)}d`,")"]})]}):(0,t.jsxs)("p",{style:m,children:["Next scan:"," ",(0,t.jsx)("span",{style:y,children:"the daemon will schedule it shortly."})]}):(0,t.jsx)("p",{style:y,children:"Scheduled scanning is off — no scan is scheduled."}),z&&(0,t.jsxs)("p",{style:{...m,color:"var(--amber)"},children:["The last scheduled scan exited with code ",W?.lastExitCode,". It will retry on the next tick."]}),W?.schemaAhead&&(0,t.jsx)("p",{style:y,children:"A newer daemon wrote this schedule; some fields may not be shown."})]}),f&&E&&(0,t.jsx)("p",{style:{...m,color:"var(--amber)",marginTop:14},children:N?(0,t.jsx)(t.Fragment,{children:"The background daemon isn't available on this platform, so scheduled scans can't run here. You can still run one now, and use the audit page."}):"not-installed"===e.daemon?(0,t.jsxs)(t.Fragment,{children:["Scheduled scanning is on, but the background service isn't installed, so nothing will run on the timer yet. Install it with ",(0,t.jsx)(b,{children:"failproofai config"}),"."]}):(0,t.jsxs)(t.Fragment,{children:["Scheduled scanning is on, but the background service is stopped, so nothing will run until it starts. Reinstall or repair it with ",(0,t.jsx)(b,{children:"failproofai config"}),"."]})}),(0,t.jsx)("div",{style:{marginTop:18},children:(0,t.jsx)("button",{type:"button",className:"btn",onClick:L,disabled:D||R,children:D||R?"[ scanning… ]":"[ run a scan now ]"})})]})}e.s(["default",0,function(){let[e,a]=(0,n.useState)(null),[i,s]=(0,n.useState)(!0),[l,o]=(0,n.useState)(!1),c=(0,n.useRef)(!0),d=(0,n.useCallback)(async()=>{let e=await r();c.current&&a(e)},[]);return(0,n.useEffect)(()=>(c.current=!0,(async()=>{try{await d()}catch{c.current&&o(!0)}finally{c.current&&s(!1)}})(),()=>{c.current=!1}),[d]),(0,t.jsx)("main",{className:"report",children:(0,t.jsxs)("section",{className:"section","data-screen-label":"settings",children:[(0,t.jsx)("h2",{style:{fontFamily:"var(--font-mono)",fontSize:24,fontWeight:600,letterSpacing:"-0.01em",color:"var(--ink)",margin:"0 0 8px"},children:"Settings"}),(0,t.jsx)("p",{style:{...m,maxWidth:720,margin:"0 0 24px"},children:"Machine-level controls for scheduled scanning and emailed reports."}),i?(0,t.jsx)("p",{style:y,children:"Loading…"}):l||!e?(0,t.jsx)("p",{style:{...m,color:"var(--accent-pink)"},children:"Could not load settings. Refresh to try again."}):(0,t.jsx)(v,{view:e,onReload:d})]})})}],93237)}]);
1
+ (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,34713,e=>{"use strict";e.s(["formatDuration",0,function(e){if(e<1e3)return`${e}ms`;let t=Math.round(e/100);if(t<600)return`${(t/10).toFixed(1)}s`;let n=Math.round(e/1e3);if(n<3600){let e=Math.floor(n/60);return`${e}m ${n%60}s`}let a=Math.round(e/6e4),r=Math.floor(a/60);return`${r}h ${a%60}m`},"formatRelativeTime",0,function(e){let t=Date.now()-e;return t<6e4?`${Math.max(1,Math.floor(t/1e3))}s ago`:t<36e5?`${Math.floor(t/6e4)}m ago`:t<864e5?`${Math.floor(t/36e5)}h ago`:`${Math.floor(t/864e5)}d ago`}])},86616,29054,e=>{"use strict";function t(e,n={},a=15e3){let r=AbortSignal.timeout(a),i=n.signal?AbortSignal.any([n.signal,r]):r;return fetch(e,{...n,signal:i})}function n(e){if(null===e||"object"!=typeof e)return!1;let t=e.name;return"AbortError"===t||"TimeoutError"===t}e.s(["fetchWithTimeout",0,t,"isAbortError",0,n],29054);class a extends Error{kind;constructor(e,t){super(t),this.kind=e,this.name="RerunError"}}async function r(e){try{let n=await t("/api/audit/run",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({cli:e.cli.length>0?e.cli:void 0,since:"all"===e.since?void 0:e.since,noCache:!!e.noCache||void 0})});if(!n.ok&&409!==n.status){let e=await n.text().catch(()=>"");throw console.error("audit run failed:",n.status,e),new a("post_failed",`audit run failed (${n.status})`)}}catch(e){if(e instanceof a)throw e;throw console.error("audit run request failed:",e),new a(n(e)?"timeout":"network","audit run request failed")}let r=0;for(;;){await new Promise(e=>setTimeout(e,1e3));let e=null;try{let n=await t("/api/audit/status",{cache:"no-store"});n.ok&&(e=await n.json())}catch{}if(null===e){if(++r>=10)throw new a("network","audit status poll lost the server");continue}if(r=0,!e.running){if(e.error)throw new a("post_failed",e.error);return}}}e.s(["RerunError",0,a,"triggerRun",0,r],86616)},93237,e=>{"use strict";var t=e.i(43476),n=e.i(71645),a=e.i(95187);let r=(0,a.createServerReference)("00cb80fcf09ddd676bf696dfc51f20e3b07fddb948",a.callServer,void 0,a.findSourceMapURL,"getScheduledAuditAction"),i=(0,a.createServerReference)("400d4066ae4ea7c220eeae7986f3d44690855eb4a8",a.callServer,void 0,a.findSourceMapURL,"setAutoAuditAction"),s=(0,a.createServerReference)("409a7e01647e87ce57fd37938d85df5ba7dcb7b532",a.callServer,void 0,a.findSourceMapURL,"setAuditIntervalAction");var l=e.i(86616),o=e.i(55574),c=e.i(29054),d=e.i(34713);function u(e){return new Date(e).toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}function h({enabled:e,onChange:n,disabled:a,label:r}){return(0,t.jsx)("button",{type:"button",onClick:n,disabled:a,role:"switch","aria-checked":e,"aria-label":r,className:`relative inline-flex h-4 w-7 shrink-0 items-center rounded-full transition-colors disabled:opacity-40 ${e?"bg-emerald-500":"bg-muted-foreground/30"}`,children:(0,t.jsx)("span",{className:`inline-block h-3 w-3 rounded-full bg-white shadow transition-transform ${e?"translate-x-3.5":"translate-x-0.5"}`})})}let f={ok:{fg:"var(--accent-green)",bg:"rgba(102,209,181,0.10)",bd:"rgba(102,209,181,0.30)"},warn:{fg:"var(--amber)",bg:"rgba(232,196,106,0.10)",bd:"rgba(232,196,106,0.30)"},bad:{fg:"var(--accent-pink)",bg:"rgba(228,88,124,0.10)",bd:"rgba(228,88,124,0.30)"},muted:{fg:"var(--ink-2)",bg:"transparent",bd:"var(--line-2)"}};function p({tone:e,children:n}){let a=f[e];return(0,t.jsx)("span",{style:{display:"inline-flex",alignItems:"center",gap:6,padding:"3px 9px",fontFamily:"var(--font-mono)",fontSize:11,letterSpacing:"0.04em",color:a.fg,background:a.bg,border:`1px solid ${a.bd}`,textTransform:"uppercase"},children:n})}let g={fontFamily:"var(--font-mono)",fontSize:16,fontWeight:600,letterSpacing:"-0.01em",color:"var(--ink)",margin:"0 0 4px"},m={fontFamily:"var(--font-mono)",fontSize:13,color:"var(--ink-2)",lineHeight:1.65,margin:0},y={...m,color:"var(--dim)",fontSize:12},x={color:"var(--ink)",fontVariantLigatures:"none"};function b({children:e}){return(0,t.jsx)("code",{style:{fontFamily:"var(--font-mono)",fontSize:12,color:"var(--accent-green)",background:"var(--bg-2)",border:"1px solid var(--line-2)",padding:"1px 6px",whiteSpace:"nowrap"},children:e})}function v({view:e,onReload:a}){let r,[f,j]=(0,n.useState)(e.auto),[w,S]=(0,n.useState)(e.intervalDays),[k,T]=(0,n.useState)(!1),[A,M]=(0,n.useState)(!1),[R,C]=(0,n.useState)(!1),[D,$]=(0,n.useState)(!1);(0,n.useEffect)(()=>j(e.auto),[e.auto]),(0,n.useEffect)(()=>S(e.intervalDays),[e.intervalDays]),(0,n.useEffect)(()=>{let e=!1;return(async()=>{try{let t=await (0,c.fetchWithTimeout)("/api/audit/status",{cache:"no-store"});if(t.ok&&!e){let e=await t.json();C(!!e.running)}}catch{}})(),()=>{e=!0}},[]);let E="running"!==e.daemon,N="unsupported-platform"===e.daemon,F=(0,n.useCallback)(async()=>{let e=!f;j(e),T(!0);try{let t=await i(e);j(t.auto),(0,o.toast)(t.auto?"Scheduled scanning on.":"Scheduled scanning off."),await a()}catch{j(!e),(0,o.toast)("Could not save that.")}finally{T(!1)}},[f,a]),I=(0,n.useCallback)(async t=>{M(!0);try{let e=await s(t);S(e.intervalDays),(0,o.toast)(`Scanning every ${e.intervalDays} day${1===e.intervalDays?"":"s"}.`)}catch{S(e.intervalDays),(0,o.toast)("Could not save that.")}finally{M(!1)}},[e.intervalDays]),L=(0,n.useCallback)(async()=>{if(!D&&!R){$(!0),C(!0);try{await (0,l.triggerRun)({cli:[],since:"all",noCache:!1}),(0,o.toast)("Audit complete."),await a()}catch(t){let e=t instanceof l.RerunError&&"timeout"===t.kind?"The scan is taking a while — it will finish in the background.":"The scan could not be completed.";(0,o.toast)(e)}finally{$(!1),C(!1)}}},[D,R,a]),W=e.schedule,z=W?.lastExitCode!=null&&0!==W.lastExitCode&&75!==W.lastExitCode;return(0,t.jsxs)("div",{className:"panel",style:{padding:20,marginBottom:20},children:[(0,t.jsxs)("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",gap:12,flexWrap:"wrap"},children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("h3",{style:g,children:"Scheduled audit"}),(0,t.jsx)("p",{style:y,children:"Scan this machine on a timer, in the background."})]}),(0,t.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:10},children:["running"===e.daemon&&(0,t.jsx)(p,{tone:"ok",children:"daemon running"}),"stopped"===e.daemon&&(0,t.jsx)(p,{tone:"warn",children:"daemon stopped"}),"not-installed"===e.daemon&&(0,t.jsx)(p,{tone:"warn",children:"daemon not installed"}),"unsupported-platform"===e.daemon&&(0,t.jsx)(p,{tone:"muted",children:"daemon unavailable"})]})]}),(0,t.jsxs)("div",{style:{display:"flex",alignItems:"flex-start",gap:12,marginTop:18},children:[(0,t.jsx)("div",{style:{marginTop:2},children:(0,t.jsx)(h,{enabled:f,onChange:F,disabled:k||N,label:f?"Turn off scheduled scanning":"Turn on scheduled scanning"})}),(0,t.jsxs)("div",{style:{minWidth:0},children:[(0,t.jsx)("p",{style:{...m,color:"var(--ink)"},children:f?"Scanning this machine on a schedule.":"Scan this machine on a schedule."}),(0,t.jsxs)("p",{style:{...m,marginTop:6},children:["The scan reads the ",(0,t.jsx)("span",{style:x,children:"contents"})," of every session transcript on disk across all installed agent CLIs — your prompts, the files they read and wrote, and command output. It runs entirely on this machine. Nothing is sent anywhere unless you also turn on emailed reports below."]})]})]}),(0,t.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:10,marginTop:16,flexWrap:"wrap"},children:[(0,t.jsx)("label",{htmlFor:"scan-interval",style:{...m},children:"Scan every"}),(0,t.jsx)("input",{id:"scan-interval",type:"number",min:1,max:90,step:1,value:w,disabled:A||N,onChange:e=>S(Number(e.target.value)),onBlur:t=>{let n=Number(t.target.value);Number.isFinite(n)?n!==e.intervalDays&&I(n):S(e.intervalDays)},style:{width:64,padding:"6px 8px",background:"var(--bg)",border:"1px solid var(--line-2)",color:"var(--ink)",fontFamily:"var(--font-mono)",fontSize:13,textAlign:"center"}}),(0,t.jsxs)("span",{style:m,children:["day",1===w?"":"s","."]}),(0,t.jsx)("span",{style:y,children:"1–90; the config keeps it in range."})]}),(0,t.jsxs)("div",{style:{marginTop:18,paddingTop:16,borderTop:"1px dashed var(--line)",display:"flex",flexDirection:"column",gap:6},children:[R&&(0,t.jsx)("p",{style:{...m,color:"var(--accent-green)"},children:"A scan is running now…"}),W?.lastRunAtMs!=null?(0,t.jsxs)("p",{style:m,children:["Last scheduled scan:"," ",(0,t.jsx)("span",{style:x,children:u(W.lastRunAtMs)})," ",(0,t.jsxs)("span",{style:y,children:["(",(0,d.formatRelativeTime)(W.lastRunAtMs),")"]})]}):e.lastResultAt?(0,t.jsxs)("p",{style:m,children:["Last audit result:"," ",(0,t.jsx)("span",{style:x,children:u(new Date(e.lastResultAt).getTime())})," ",(0,t.jsx)("span",{style:y,children:"(no scheduled scan has run yet)"})]}):(0,t.jsx)("p",{style:m,children:"No scan has run yet."}),f?W?.nextDueAtMs!=null?(0,t.jsxs)("p",{style:m,children:["Next scan due:"," ",(0,t.jsx)("span",{style:x,children:u(W.nextDueAtMs)})," ",(0,t.jsxs)("span",{style:y,children:["(",(r=W.nextDueAtMs-Date.now())<=0?"now":r<36e5?`in ${Math.max(1,Math.floor(r/6e4))}m`:r<864e5?`in ${Math.floor(r/36e5)}h`:`in ${Math.floor(r/864e5)}d`,")"]})]}):(0,t.jsxs)("p",{style:m,children:["Next scan:"," ",(0,t.jsx)("span",{style:y,children:"the daemon will schedule it shortly."})]}):(0,t.jsx)("p",{style:y,children:"Scheduled scanning is off — no scan is scheduled."}),z&&(0,t.jsxs)("p",{style:{...m,color:"var(--amber)"},children:["The last scheduled scan exited with code ",W?.lastExitCode,". It will retry on the next tick."]}),W?.schemaAhead&&(0,t.jsx)("p",{style:y,children:"A newer daemon wrote this schedule; some fields may not be shown."})]}),f&&E&&(0,t.jsx)("p",{style:{...m,color:"var(--amber)",marginTop:14},children:N?(0,t.jsx)(t.Fragment,{children:"The background daemon isn't available on this platform, so scheduled scans can't run here. You can still run one now, and use the audit page."}):"not-installed"===e.daemon?(0,t.jsxs)(t.Fragment,{children:["Scheduled scanning is on, but the background service isn't installed, so nothing will run on the timer yet. Install it with ",(0,t.jsx)(b,{children:"failproofai config"}),"."]}):(0,t.jsxs)(t.Fragment,{children:["Scheduled scanning is on, but the background service is stopped, so nothing will run until it starts. Reinstall or repair it with ",(0,t.jsx)(b,{children:"failproofai config"}),"."]})}),(0,t.jsx)("div",{style:{marginTop:18},children:(0,t.jsx)("button",{type:"button",className:"btn",onClick:L,disabled:D||R,children:D||R?"[ scanning… ]":"[ run a scan now ]"})})]})}e.s(["default",0,function(){let[e,a]=(0,n.useState)(null),[i,s]=(0,n.useState)(!0),[l,o]=(0,n.useState)(!1),c=(0,n.useRef)(!0),d=(0,n.useCallback)(async()=>{let e=await r();c.current&&a(e)},[]);return(0,n.useEffect)(()=>(c.current=!0,(async()=>{try{await d()}catch{c.current&&o(!0)}finally{c.current&&s(!1)}})(),()=>{c.current=!1}),[d]),(0,t.jsx)("main",{className:"report",children:(0,t.jsxs)("section",{className:"section","data-screen-label":"settings",children:[(0,t.jsx)("h2",{style:{fontFamily:"var(--font-mono)",fontSize:24,fontWeight:600,letterSpacing:"-0.01em",color:"var(--ink)",margin:"0 0 8px"},children:"Settings"}),(0,t.jsx)("p",{style:{...m,maxWidth:720,margin:"0 0 24px"},children:"Machine-level controls for scheduled scanning and emailed reports."}),i?(0,t.jsx)("p",{style:y,children:"Loading…"}):l||!e?(0,t.jsx)("p",{style:{...m,color:"var(--accent-pink)"},children:"Could not load settings. Refresh to try again."}):(0,t.jsx)(v,{view:e,onReload:d})]})})}],93237)}]);
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "failproofai",
3
- "version": "1.0.0-beta.7",
3
+ "version": "1.0.0-beta.8",
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",
@@ -114,9 +114,9 @@
114
114
  "sharp": "0.35.0"
115
115
  },
116
116
  "optionalDependencies": {
117
- "@failproofai/failproofaid-linux-x64": "1.0.0-beta.7",
118
- "@failproofai/failproofaid-linux-arm64": "1.0.0-beta.7",
119
- "@failproofai/failproofaid-darwin-x64": "1.0.0-beta.7",
120
- "@failproofai/failproofaid-darwin-arm64": "1.0.0-beta.7"
117
+ "@failproofai/failproofaid-linux-x64": "1.0.0-beta.8",
118
+ "@failproofai/failproofaid-linux-arm64": "1.0.0-beta.8",
119
+ "@failproofai/failproofaid-darwin-x64": "1.0.0-beta.8",
120
+ "@failproofai/failproofaid-darwin-arm64": "1.0.0-beta.8"
121
121
  }
122
122
  }
@@ -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":"1.0.0-beta.7"},"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,"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,"useTypeScriptCli":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"}
12
+ const nextConfig = {"env":{"NEXT_PUBLIC_APP_VERSION":"1.0.0-beta.8"},"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,"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,"useTypeScriptCli":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
 
@@ -211,7 +211,7 @@ if (hookIdx >= 0) {
211
211
  */
212
212
  async function runCli() {
213
213
  // --help / -h (only when not inside a subcommand that handles its own --help)
214
- const SUBCOMMANDS = ["policies", "policy", "audit", "config"];
214
+ const SUBCOMMANDS = ["policies", "policy", "audit", "config", "uninstall"];
215
215
  if ((args.includes("--help") || args.includes("-h")) && !SUBCOMMANDS.includes(args[0])) {
216
216
  const extraArgs = args.filter((a) => a !== "--help" && a !== "-h");
217
217
  if (extraArgs.length > 0) {
@@ -256,6 +256,16 @@ COMMANDS
256
256
  dashboard at http://localhost:8020/audit
257
257
  audit --help, -h Show this help for the audit command
258
258
 
259
+ uninstall Remove failproofai from this machine: hook
260
+ entries from every agent CLI, and the daemon
261
+ service. Run this BEFORE \`npm rm -g failproofai\`
262
+ — npm runs no uninstall script, so removing the
263
+ package alone leaves both behind.
264
+ --purge Also delete ~/.failproofai (settings,
265
+ credentials, audit history, daemon binary)
266
+ --dry-run Show what would be removed, change nothing
267
+ --yes, -y Skip the confirmation prompt
268
+
259
269
  --version, -v Print version and exit
260
270
  --help, -h Show this help message
261
271
 
@@ -410,6 +420,113 @@ LINKS
410
420
  }
411
421
  }
412
422
 
423
+ // uninstall [--purge] [--dry-run] [--yes|-y]
424
+ //
425
+ // Top-level, and deliberately NOT a flag on `policies`. `policies --uninstall`
426
+ // disables policies; this removes the product — hook entries across every
427
+ // agent CLI plus the root-owned daemon service — and the two must not be one
428
+ // keystroke apart.
429
+ if (args[0] === "uninstall") {
430
+ const subArgs = args.slice(1);
431
+ if (subArgs.includes("--help") || subArgs.includes("-h")) {
432
+ console.log(`
433
+ failproofai uninstall — remove failproofai from this machine
434
+
435
+ USAGE
436
+ failproofai uninstall [--purge] [--dry-run] [--yes]
437
+
438
+ WHAT IT REMOVES
439
+ • failproofai hook entries from every agent CLI that has them
440
+ • the failproofaid daemon service (needs sudo)
441
+ • the "require the daemon" flag — cleared FIRST, so a partial uninstall can
442
+ never leave this machine denying every tool call
443
+
444
+ OPTIONS
445
+ --purge Also delete ~/.failproofai — settings, credentials, audit
446
+ history and the downloaded daemon binary. Off by default so a
447
+ reinstall keeps your history.
448
+ --dry-run Print what would be removed and change nothing.
449
+ --yes, -y Skip the confirmation prompt. Required when there is no TTY.
450
+
451
+ WHY THIS EXISTS
452
+ npm runs no uninstall script, so \`npm rm -g failproofai\` removes the package
453
+ and leaves the hook entries and the service behind. Run this first, then:
454
+ npm rm -g failproofai
455
+ `);
456
+ process.exit(0);
457
+ }
458
+
459
+ const KNOWN = new Set(["--purge", "--dry-run", "--yes", "-y"]);
460
+ const unknown = subArgs.find((a) => !KNOWN.has(a));
461
+ if (unknown) {
462
+ throw new CliError(
463
+ `Unexpected argument: ${unknown}\nRun \`failproofai uninstall --help\` for usage.`,
464
+ );
465
+ }
466
+
467
+ lastSubcommand = "uninstall_command";
468
+ const { runUninstallCommand } = await import("../src/hooks/uninstall-cli");
469
+ const purge = subArgs.includes("--purge");
470
+ const dryRun = subArgs.includes("--dry-run");
471
+ const yes = subArgs.includes("--yes") || subArgs.includes("-y");
472
+
473
+ // Set only when the prompt actually rendered the plan, which is the one
474
+ // case where printing it again would duplicate it.
475
+ let planWasShown = false;
476
+ const result = await runUninstallCommand({
477
+ purge,
478
+ dryRun,
479
+ yes,
480
+ cwd: process.cwd(),
481
+ // Only offered when a person can actually answer. Without a TTY the
482
+ // command requires --yes rather than assuming consent — see the module.
483
+ confirm: process.stdin.isTTY
484
+ ? async (planLines) => {
485
+ planWasShown = true;
486
+ const { selectOne } = await import("../src/hooks/tui");
487
+ // "No" first, so the default landing position on Enter is the
488
+ // non-destructive one.
489
+ const answer = await selectOne({
490
+ message: purge
491
+ ? "Remove failproofai and DELETE ~/.failproofai?"
492
+ : "Remove failproofai from this machine?",
493
+ body: planLines,
494
+ choices: [
495
+ { label: "No, cancel", value: false },
496
+ { label: purge ? "Yes, remove and purge" : "Yes, remove it", value: true },
497
+ ],
498
+ });
499
+ return answer === true;
500
+ }
501
+ : undefined,
502
+ });
503
+
504
+ // The prompt already rendered the plan as its body; re-printing it would
505
+ // show the same block twice. `planLines` is reported by the command rather
506
+ // than guessed from the text — see UninstallResult.
507
+ const skip = planWasShown ? result.planLines : 0;
508
+ for (const line of result.lines.slice(skip)) {
509
+ if (result.exitCode === 0) console.log(line);
510
+ else console.error(line);
511
+ }
512
+ // NOT after a purge. `track` resolves the instance id, and `getInstanceId()`
513
+ // lazily WRITES ~/.failproofai/state/telemetry-id — which re-created the
514
+ // whole directory seconds after the purge deleted it, leaving a machine the
515
+ // user had just wiped holding a brand-new tracking identifier and making
516
+ // the command's own "✓ deleted" line false. A purge means gone; nothing
517
+ // gets to touch the home afterwards, least of all telemetry.
518
+ if (!result.purged) {
519
+ await track("cli_uninstall_command", {
520
+ ok: result.exitCode === 0,
521
+ purge,
522
+ dry_run: dryRun,
523
+ });
524
+ }
525
+ lastSubcommand = null;
526
+ await exitAfterFlush(result.exitCode);
527
+ return;
528
+ }
529
+
413
530
  // policies [--install|-i|--uninstall|-u|--help|-h] [names...] [--scope] [--beta] [--custom|-c <path>]
414
531
  if (args[0] === "policies") {
415
532
  const subArgs = args.slice(1);