failproofai 1.0.4-beta.6 → 1.0.4-beta.7

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 (118) 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 +6 -6
  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/_tree.segment.rsc +1 -1
  13. package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  14. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  15. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  16. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  17. package/.next/standalone/.next/server/app/_not-found.rsc +14 -14
  18. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +14 -14
  19. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +13 -13
  20. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  21. package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -1
  22. package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
  23. package/.next/standalone/.next/server/app/api/audit/status/route.js.nft.json +1 -1
  24. package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
  25. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
  26. package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
  27. package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
  28. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
  29. package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +5 -5
  30. package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
  31. package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
  32. package/.next/standalone/.next/server/app/index.html +1 -1
  33. package/.next/standalone/.next/server/app/index.rsc +14 -14
  34. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +13 -13
  35. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +14 -14
  36. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  37. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
  38. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  39. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  40. package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +14 -14
  41. package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
  42. package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
  43. package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
  44. package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
  45. package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
  46. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
  47. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
  48. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
  49. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
  50. package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
  51. package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
  52. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  53. package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +15 -4
  54. package/.next/standalone/.next/server/app/settings/page.js +2 -2
  55. package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
  56. package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  57. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o07qi9._.js +1 -1
  58. package/.next/standalone/.next/server/chunks/_0tovk6q._.js +1 -1
  59. package/.next/standalone/.next/server/chunks/_0trp3yc._.js +1 -1
  60. package/.next/standalone/.next/server/chunks/_1ek68ln._.js +10 -10
  61. package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
  62. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0-4ja6q._.js +2 -2
  63. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__00cr3xu._.js +2 -2
  64. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__04px77e._.js +2 -2
  65. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0egr5s1._.js +2 -2
  66. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0i0l1di._.js +2 -2
  67. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0oa1lav._.js +1 -1
  68. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0r3c1_0._.js +2 -2
  69. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1ui5ur8._.js → [root-of-the-server]__12hbpha._.js} +2 -2
  70. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__17xnxlx._.js +2 -2
  71. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1ckpmkk._.js +2 -2
  72. package/.next/standalone/.next/server/chunks/ssr/_04ng_6x._.js +1 -1
  73. package/.next/standalone/.next/server/chunks/ssr/_07t3jol._.js +1 -1
  74. package/.next/standalone/.next/server/chunks/ssr/_08x1r5t._.js +1 -1
  75. package/.next/standalone/.next/server/chunks/ssr/{_02b3i98._.js → _0a0zlpr._.js} +2 -2
  76. package/.next/standalone/.next/server/chunks/ssr/_next-internal_server_app_policies_page_actions_1sp2-yo.js +2 -2
  77. package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +1 -1
  78. package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
  79. package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +1 -1
  80. package/.next/standalone/.next/server/chunks/ssr/app_settings_settings-client_tsx_20lq-mq._.js +1 -1
  81. package/.next/standalone/.next/server/chunks/ssr/src_hooks_builtin-policies_ts_09j2ndl._.js +1 -1
  82. package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
  83. package/.next/standalone/.next/server/pages/404.html +1 -1
  84. package/.next/standalone/.next/server/pages/500.html +1 -1
  85. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  86. package/.next/standalone/.next/server/server-reference-manifest.json +33 -22
  87. package/.next/standalone/.next/static/chunks/{20xkiqzvfkuvm.js → 083fk73jtv9a0.js} +1 -1
  88. package/.next/standalone/.next/static/chunks/{1xgq22tri86an.js → 0divvxng208xo.js} +1 -1
  89. package/.next/standalone/.next/static/chunks/{1gn08w2pgqh09.js → 0f1pznnc7zlub.js} +1 -1
  90. package/.next/standalone/.next/static/chunks/{3jxd133cw2vm3.js → 0ntdfr2552x-h.js} +1 -1
  91. package/.next/standalone/.next/static/chunks/{32m2ryfankf_2.js → 0t6ea7d3bkmdv.js} +1 -1
  92. package/.next/standalone/.next/static/chunks/{07c6l1lq5_69b.js → 15uon66hpwbgg.js} +1 -1
  93. package/.next/standalone/.next/static/chunks/{2a84ug32tzik2.js → 1csubx9gwhsf6.js} +1 -1
  94. package/.next/standalone/.next/static/chunks/27du9n7ssja7l.js +1 -0
  95. package/.next/standalone/.next/static/chunks/2h_pcb1y8_jde.js +1 -0
  96. package/.next/standalone/.next/static/chunks/{12bsgz8czvcnn.js → 2pwfrn6_mw-1u.js} +1 -1
  97. package/.next/standalone/app/actions/get-scheduled-audit.ts +5 -0
  98. package/.next/standalone/app/actions/update-scheduled-audit.ts +14 -1
  99. package/.next/standalone/app/audit/_components/audit-dashboard.tsx +1 -1
  100. package/.next/standalone/app/audit/_components/empty-state.tsx +1 -1
  101. package/.next/standalone/app/audit/_components/leak-section.tsx +1 -1
  102. package/.next/standalone/app/settings/settings-client.tsx +42 -11
  103. package/.next/standalone/package.json +9 -9
  104. package/.next/standalone/server.js +1 -1
  105. package/dist/cli.mjs +69 -68
  106. package/dist/worker.mjs +3 -3
  107. package/package.json +9 -9
  108. package/src/audit/index.ts +1 -1
  109. package/src/audit/leak-record.ts +24 -12
  110. package/src/audit/macos-notifier.ts +54 -66
  111. package/src/hooks/builtin-policies.ts +2 -2
  112. package/src/hooks/configure-wizard.ts +8 -1
  113. package/src/hooks/uninstall-cli.ts +3 -3
  114. package/.next/standalone/.next/static/chunks/3ioub_lpen-sq.js +0 -1
  115. package/.next/standalone/.next/static/chunks/44ncu88eq6z71.js +0 -1
  116. /package/.next/standalone/.next/static/{aeM365dNTtUZOZvNkX8ba → YiPsVpjrc-pEQoN7XvhZ0}/_buildManifest.js +0 -0
  117. /package/.next/standalone/.next/static/{aeM365dNTtUZOZvNkX8ba → YiPsVpjrc-pEQoN7XvhZ0}/_clientMiddlewareManifest.js +0 -0
  118. /package/.next/standalone/.next/static/{aeM365dNTtUZOZvNkX8ba → YiPsVpjrc-pEQoN7XvhZ0}/_ssgManifest.js +0 -0
@@ -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.4-beta.6"},"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"],"instrumentationClientInject":[],"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","enablePrerenderSourceMaps":true,"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":true,"coldCacheBadge":false,"devValidationWorker":true,"useSkewCookie":false,"cssChunking":true,"multiZoneDraftMode":false,"appNavFailHandling":false,"prerenderEarlyExit":true,"serverMinification":true,"linkNoTouchStart":false,"caseSensitiveRoutes":false,"cachedNavigations":false,"dynamicOnHover":false,"useOffline":false,"varyParams":true,"optimisticRouting":true,"instrumentationClientRouterTransitionEvents":false,"prefetchInlining":{"maxSize":2048,"maxBundleSize":10240},"preloadEntriesOnStart":true,"clientRouterFilter":true,"clientRouterFilterRedirects":false,"fetchCacheKeyPrefix":"","proxyPrefetch":"flexible","optimisticClientCache":true,"manualClientBasePath":false,"cpus":3,"memoryBasedWorkersCount":false,"imgOptConcurrency":null,"imgOptOperationCache":null,"imgOptTimeoutInSeconds":7,"imgOptMaxInputPixels":268402689,"imgOptSequentialRead":null,"isrFlushToDisk":true,"workerThreads":false,"optimizeCss":false,"nextScriptWorkers":false,"scrollRestoration":false,"externalDir":false,"devMemoryThresholdRestart":true,"disableOptimizedLoading":false,"gzipSize":true,"craCompat":false,"esmExternals":true,"fullySpecified":false,"swcTraceProfiling":false,"forceSwcTransforms":false,"requestInsights":false,"largePageDataBytes":128000,"typedEnv":false,"parallelServerCompiles":false,"parallelServerBuildTraces":false,"ppr":false,"authInterrupts":false,"webpackMemoryOptimizations":false,"optimizeServerReact":true,"strictRouteTypes":false,"useTypeScriptCli":true,"removeUncaughtErrorAndRejectionListeners":false,"validateRSCRequestHeaders":true,"staleTimes":{"dynamic":0,"static":300},"reactDebugChannel":true,"serverComponentsHmrCache":true,"serverComponentsHmrCancellation":false,"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":true,"turbopackInferModuleSideEffects":true,"turbopackPluginRuntimeStrategy":"childProcesses","turbopackMemoryEvictionMode":"auto","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"],"useCacheTimeout":54,"instantInsights":{"validationLevel":"warning"},"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"},"repoRoot":"/home/runner/work/failproofai/failproofai","distDirRoot":".next"}
12
+ const nextConfig = {"env":{"NEXT_PUBLIC_APP_VERSION":"1.0.4-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"],"instrumentationClientInject":[],"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","enablePrerenderSourceMaps":true,"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":true,"coldCacheBadge":false,"devValidationWorker":true,"useSkewCookie":false,"cssChunking":true,"multiZoneDraftMode":false,"appNavFailHandling":false,"prerenderEarlyExit":true,"serverMinification":true,"linkNoTouchStart":false,"caseSensitiveRoutes":false,"cachedNavigations":false,"dynamicOnHover":false,"useOffline":false,"varyParams":true,"optimisticRouting":true,"instrumentationClientRouterTransitionEvents":false,"prefetchInlining":{"maxSize":2048,"maxBundleSize":10240},"preloadEntriesOnStart":true,"clientRouterFilter":true,"clientRouterFilterRedirects":false,"fetchCacheKeyPrefix":"","proxyPrefetch":"flexible","optimisticClientCache":true,"manualClientBasePath":false,"cpus":3,"memoryBasedWorkersCount":false,"imgOptConcurrency":null,"imgOptOperationCache":null,"imgOptTimeoutInSeconds":7,"imgOptMaxInputPixels":268402689,"imgOptSequentialRead":null,"isrFlushToDisk":true,"workerThreads":false,"optimizeCss":false,"nextScriptWorkers":false,"scrollRestoration":false,"externalDir":false,"devMemoryThresholdRestart":true,"disableOptimizedLoading":false,"gzipSize":true,"craCompat":false,"esmExternals":true,"fullySpecified":false,"swcTraceProfiling":false,"forceSwcTransforms":false,"requestInsights":false,"largePageDataBytes":128000,"typedEnv":false,"parallelServerCompiles":false,"parallelServerBuildTraces":false,"ppr":false,"authInterrupts":false,"webpackMemoryOptimizations":false,"optimizeServerReact":true,"strictRouteTypes":false,"useTypeScriptCli":true,"removeUncaughtErrorAndRejectionListeners":false,"validateRSCRequestHeaders":true,"staleTimes":{"dynamic":0,"static":300},"reactDebugChannel":true,"serverComponentsHmrCache":true,"serverComponentsHmrCancellation":false,"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":true,"turbopackInferModuleSideEffects":true,"turbopackPluginRuntimeStrategy":"childProcesses","turbopackMemoryEvictionMode":"auto","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"],"useCacheTimeout":54,"instantInsights":{"validationLevel":"warning"},"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"},"repoRoot":"/home/runner/work/failproofai/failproofai","distDirRoot":".next"}
13
13
 
14
14
  process.env.__NEXT_PRIVATE_STANDALONE_CONFIG = JSON.stringify(nextConfig)
15
15
 
package/dist/cli.mjs CHANGED
@@ -29,7 +29,7 @@ var __esm = (fn, res, err) => () => {
29
29
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
30
30
 
31
31
  // package.json
32
- var version2 = "1.0.4-beta.6", package_default;
32
+ var version2 = "1.0.4-beta.7", package_default;
33
33
  var init_package = __esm(() => {
34
34
  package_default = {
35
35
  name: "failproofai",
@@ -154,16 +154,16 @@ var init_package = __esm(() => {
154
154
  browserslist: "4.28.8"
155
155
  },
156
156
  optionalDependencies: {
157
- "@failproofai/failproofaid-linux-x64": "1.0.4-beta.6",
158
- "@failproofai/failproofaid-linux-arm64": "1.0.4-beta.6",
159
- "@failproofai/failproofaid-darwin-x64": "1.0.4-beta.6",
160
- "@failproofai/failproofaid-darwin-arm64": "1.0.4-beta.6"
157
+ "@failproofai/failproofaid-linux-x64": "1.0.4-beta.7",
158
+ "@failproofai/failproofaid-linux-arm64": "1.0.4-beta.7",
159
+ "@failproofai/failproofaid-darwin-x64": "1.0.4-beta.7",
160
+ "@failproofai/failproofaid-darwin-arm64": "1.0.4-beta.7"
161
161
  },
162
162
  failproofaidBinaries: {
163
- "linux-x64": "24118b8bd058cc5d8711053c4c77cdca9361c12dbf0f421a757d33f07596d428",
164
- "linux-arm64": "b4278c34a288de2c747bcebcc623d8fd5bda3a1f1e55800926eb1a4b89f0a5e9",
165
- "darwin-x64": "ecb66699f45f605b0d54ac9e4bac360ac11e4e136442dcccdd083514d77c7d42",
166
- "darwin-arm64": "b3dbad58bda960ef9481f90bc5085ba8624b2472519cc0bf212a0e8451dd2db4"
163
+ "linux-x64": "e59735a8f94cd8ac697b2bd67aafdd8d76a8394d53db229876980cc13a18f07e",
164
+ "linux-arm64": "b9ce50dd2f79b55f4f7112add265a776a4a6d002c2a56f971e666fbb796f3906",
165
+ "darwin-x64": "b46efc8ec33945a5cc26b7bb288fb87cea65b5983bd83094b5e607d53b8eda4c",
166
+ "darwin-arm64": "a8cc6112cee5ca8a7d517900e9ce32118855135980f22979fa0ff7aa6f68d954"
167
167
  }
168
168
  };
169
169
  });
@@ -3874,8 +3874,8 @@ var init_builtin_policies = __esm(() => {
3874
3874
  [/sk-ant-oat01-[A-Za-z0-9\-_]{20,}/, "Anthropic OAuth token"],
3875
3875
  [/sk-ant-[A-Za-z0-9\-_]{20,}/, "Anthropic API key"],
3876
3876
  [/sk-proj-[A-Za-z0-9\-_]{20,}/, "OpenAI project API key"],
3877
- [/sk-svcacct-[A-Za-z0-9\-_]{20,}/, "OpenAI service-account key"],
3878
- [/sk-admin-[A-Za-z0-9\-_]{20,}/, "OpenAI admin key"],
3877
+ [/(?<!\w)sk-svcacct-[A-Za-z0-9\-_]{20,}/, "OpenAI service-account key"],
3878
+ [/(?<!\w)sk-admin-[A-Za-z0-9\-_]{20,}/, "OpenAI admin key"],
3879
3879
  [/sk-or-v1-[A-Za-z0-9\-_]{20,}/, "OpenRouter API key"],
3880
3880
  [/sk-[A-Za-z0-9]{20,}/, "OpenAI-compatible key (issuer unknown)"],
3881
3881
  [/github_pat_[A-Za-z0-9_]{82}/, "GitHub fine-grained token"],
@@ -25190,12 +25190,15 @@ var init_leak_fingerprint = __esm(() => {
25190
25190
 
25191
25191
  // src/audit/macos-notifier.ts
25192
25192
  import { execFileSync as execFileSync3 } from "node:child_process";
25193
- import { existsSync as existsSync26, mkdirSync as mkdirSync17, readdirSync as readdirSync16, renameSync as renameSync8, rmSync as rmSync9, writeFileSync as writeFileSync15 } from "node:fs";
25193
+ import { chmodSync as chmodSync5, existsSync as existsSync26, mkdirSync as mkdirSync17, readdirSync as readdirSync16, renameSync as renameSync8, rmSync as rmSync9, writeFileSync as writeFileSync15 } from "node:fs";
25194
25194
  import { homedir as homedir24 } from "node:os";
25195
25195
  import { resolve as resolve22 } from "node:path";
25196
25196
  function macNotifierAppPath(home) {
25197
25197
  return resolve22(runDir(home), "..", "bin", "FailproofAI Notifier.app");
25198
25198
  }
25199
+ function macNotifierRunnerPath(home) {
25200
+ return resolve22(runDir(home), "..", "bin", "failproofai-notifier.zsh");
25201
+ }
25199
25202
  function macNotifierPlistPath() {
25200
25203
  return resolve22(homedir24(), "Library", "LaunchAgents", `${MAC_NOTIFIER_LABEL}.plist`);
25201
25204
  }
@@ -25204,35 +25207,28 @@ function escapeXml2(s) {
25204
25207
  }
25205
25208
  function notifierScript(home) {
25206
25209
  const dir = macNotifyDir(home);
25207
- return `on run
25208
- set dropDir to ${JSON.stringify(dir + "/")}
25209
- set listing to ""
25210
- try
25211
- set listing to do shell script "ls -1 " & quoted form of dropDir & " 2>/dev/null"
25212
- end try
25213
- repeat with entryName in paragraphs of listing
25214
- set entryPath to dropDir & (entryName as string)
25215
- if (entryName as string) is not "" then
25216
- try
25217
- set payload to do shell script "cat " & quoted form of entryPath & " 2>/dev/null"
25218
- do shell script "rm -f " & quoted form of entryPath
25219
- set lines_ to paragraphs of payload
25220
- if (count of lines_) is greater than 1 then
25221
- set noteTitle to item 1 of lines_
25222
- set noteBody to ""
25223
- repeat with i from 2 to (count of lines_)
25224
- if noteBody is not "" then set noteBody to noteBody & " "
25225
- set noteBody to noteBody & (item i of lines_)
25226
- end repeat
25227
- display notification noteBody with title noteTitle
25228
- end if
25229
- end try
25230
- end if
25231
- end repeat
25210
+ const quotedDir = `'${dir.replace(/'/g, `'\\''`)}'`;
25211
+ return `#!/bin/zsh
25212
+ set -u
25213
+ setopt NULL_GLOB
25214
+
25215
+ drop_dir=${quotedDir}
25216
+
25217
+ for entry_path in "$drop_dir"/*; do
25218
+ [ -f "$entry_path" ] || continue
25219
+ note_title=$(/usr/bin/sed -n '1p' "$entry_path")
25220
+ note_body=$(/usr/bin/sed -n '2,$p' "$entry_path" | /usr/bin/tr '\\n' ' ')
25221
+ /bin/rm -f "$entry_path"
25222
+ [ -n "$note_title" ] || continue
25223
+ /usr/bin/osascript - "$note_title" "$note_body" <<'APPLESCRIPT'
25224
+ on run argv
25225
+ display notification (item 2 of argv) with title (item 1 of argv)
25232
25226
  end run
25227
+ APPLESCRIPT
25228
+ done
25233
25229
  `;
25234
25230
  }
25235
- function notifierPlistContents(appPath, watchDir) {
25231
+ function notifierPlistContents(runnerPath, watchDir) {
25236
25232
  return `<?xml version="1.0" encoding="UTF-8"?>
25237
25233
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
25238
25234
  <plist version="1.0">
@@ -25241,7 +25237,7 @@ function notifierPlistContents(appPath, watchDir) {
25241
25237
  <string>${escapeXml2(MAC_NOTIFIER_LABEL)}</string>
25242
25238
  <key>ProgramArguments</key>
25243
25239
  <array>
25244
- <string>${escapeXml2(resolve22(appPath, "Contents", "MacOS", "applet"))}</string>
25240
+ <string>${escapeXml2(runnerPath)}</string>
25245
25241
  </array>
25246
25242
  <!-- Started only when something is queued, and it exits when the queue is
25247
25243
  empty. RunAtLoad would fire it once at login with nothing to say. -->
@@ -25268,20 +25264,15 @@ function installMacNotifier(home) {
25268
25264
  if (process.platform !== "darwin")
25269
25265
  return { installed: false, reason: "not macOS" };
25270
25266
  try {
25271
- const app = macNotifierAppPath(home);
25267
+ const runner = macNotifierRunnerPath(home);
25272
25268
  const watch = macNotifyDir(home);
25273
25269
  mkdirSync17(watch, { recursive: true, mode: 448 });
25274
- mkdirSync17(resolve22(app, ".."), { recursive: true });
25275
- const scriptPath = resolve22(watch, "..", "notifier.applescript");
25276
- writeFileSync15(scriptPath, notifierScript(home), { mode: 384 });
25277
- rmSync9(app, { recursive: true, force: true });
25278
- run("osacompile", ["-o", app, scriptPath]);
25279
- rmSync9(scriptPath, { force: true });
25280
- const plist = resolve22(app, "Contents", "Info.plist");
25281
- run("defaults", ["write", plist, "CFBundleIdentifier", MAC_NOTIFIER_LABEL]);
25282
- run("defaults", ["write", plist, "CFBundleName", "failproofai"]);
25270
+ mkdirSync17(resolve22(runner, ".."), { recursive: true });
25271
+ writeFileSync15(runner, notifierScript(home), { mode: 448 });
25272
+ chmodSync5(runner, 448);
25273
+ rmSync9(macNotifierAppPath(home), { recursive: true, force: true });
25283
25274
  mkdirSync17(resolve22(macNotifierPlistPath(), ".."), { recursive: true });
25284
- writeFileSync15(macNotifierPlistPath(), notifierPlistContents(app, watch), { mode: 420 });
25275
+ writeFileSync15(macNotifierPlistPath(), notifierPlistContents(runner, watch), { mode: 420 });
25285
25276
  const target = `gui/${process.getuid?.() ?? 0}`;
25286
25277
  try {
25287
25278
  run("launchctl", ["bootout", `${target}/${MAC_NOTIFIER_LABEL}`]);
@@ -25300,6 +25291,7 @@ function uninstallMacNotifier(home) {
25300
25291
  } catch {}
25301
25292
  rmSync9(macNotifierPlistPath(), { force: true });
25302
25293
  rmSync9(macNotifierAppPath(home), { recursive: true, force: true });
25294
+ rmSync9(macNotifierRunnerPath(home), { force: true });
25303
25295
  rmSync9(macNotifyDir(home), { recursive: true, force: true });
25304
25296
  }
25305
25297
  function queueMacNotification(id, title, body, home) {
@@ -25323,7 +25315,7 @@ ${body.replace(/\s+/g, " ")}
25323
25315
  }
25324
25316
  }
25325
25317
  function macNotifierInstalled(home) {
25326
- return existsSync26(macNotifierPlistPath()) && existsSync26(macNotifierAppPath(home));
25318
+ return existsSync26(macNotifierPlistPath()) && existsSync26(macNotifierRunnerPath(home));
25327
25319
  }
25328
25320
  function pruneMacNotifyQueue(home, maxAgeMs = 7 * 86400000) {
25329
25321
  try {
@@ -27431,24 +27423,24 @@ function upsertFinding(record, incoming) {
27431
27423
  });
27432
27424
  return { record, isNew: true };
27433
27425
  }
27426
+ const seen = existing.sightings.some((s) => s.sessionId === sighting.sessionId && s.at === sighting.at && s.mechanism.direction === sighting.mechanism.direction && s.mechanism.summary === sighting.mechanism.summary);
27427
+ if (seen)
27428
+ return { record, isNew: false };
27434
27429
  existing.occurrences += 1;
27435
27430
  if (sighting.at > existing.lastSeen)
27436
27431
  existing.lastSeen = sighting.at;
27437
27432
  if (sighting.at < existing.firstSeen)
27438
27433
  existing.firstSeen = sighting.at;
27439
- const seen = existing.sightings.some((s) => s.sessionId === sighting.sessionId && s.at === sighting.at);
27440
- if (!seen) {
27441
- existing.sightings.push(sighting);
27442
- existing.sightings.sort((a, b) => a.at.localeCompare(b.at));
27443
- if (existing.sightings.length > MAX_SIGHTINGS) {
27444
- existing.sightings.splice(1, existing.sightings.length - MAX_SIGHTINGS);
27445
- }
27434
+ existing.sightings.push(sighting);
27435
+ existing.sightings.sort((a, b) => a.at.localeCompare(b.at));
27436
+ if (existing.sightings.length > MAX_SIGHTINGS) {
27437
+ existing.sightings.splice(1, existing.sightings.length - MAX_SIGHTINGS);
27446
27438
  }
27447
27439
  return { record, isNew: false };
27448
27440
  }
27449
27441
  function pruneRecord(record, nowMs) {
27450
27442
  const cutoff = new Date(nowMs - FINDING_TTL_DAYS * 86400000).toISOString();
27451
- const live = record.findings.filter((f) => f.lastSeen >= cutoff);
27443
+ const live = record.findings.filter((f) => !f.lastSeen || !Number.isFinite(Date.parse(f.lastSeen)) || f.lastSeen >= cutoff);
27452
27444
  live.sort((a, b) => a.lastSeen < b.lastSeen ? 1 : a.lastSeen > b.lastSeen ? -1 : 0);
27453
27445
  record.findings = live.slice(0, MAX_FINDINGS);
27454
27446
  return record;
@@ -27730,7 +27722,7 @@ var init_redact_example = __esm(() => {
27730
27722
 
27731
27723
  // src/audit/cache.ts
27732
27724
  import { createHash as createHash8 } from "node:crypto";
27733
- import { existsSync as existsSync32, mkdirSync as mkdirSync21, readFileSync as readFileSync27, writeFileSync as writeFileSync18, chmodSync as chmodSync5, openSync, readSync, closeSync } from "node:fs";
27725
+ import { existsSync as existsSync32, mkdirSync as mkdirSync21, readFileSync as readFileSync27, writeFileSync as writeFileSync18, chmodSync as chmodSync6, openSync, readSync, closeSync } from "node:fs";
27734
27726
  import { join as join33 } from "node:path";
27735
27727
  function getEngineVersion() {
27736
27728
  if (cachedEngineVersion)
@@ -27856,7 +27848,7 @@ function writeCachedTranscriptResult(transcriptPath, mtimeMs, sizeBytes, result,
27856
27848
  }
27857
27849
  writeFileSync18(cachePath, JSON.stringify(entry), { encoding: "utf-8", mode: 384 });
27858
27850
  try {
27859
- chmodSync5(cachePath, 384);
27851
+ chmodSync6(cachePath, 384);
27860
27852
  } catch {}
27861
27853
  } catch {}
27862
27854
  }
@@ -30210,7 +30202,15 @@ Hooks keep enforcing; scheduled audits stay off until it is.
30210
30202
  } catch {}
30211
30203
  }
30212
30204
  pruneOldDaemonBinaries();
30213
- installMacNotifier();
30205
+ const notifier = installMacNotifier();
30206
+ if (process.platform === "darwin" && !notifier.installed) {
30207
+ hookLogWarn(`macOS notification helper was not installed: ${notifier.reason ?? "unknown error"}`);
30208
+ stdout.write(`
30209
+ System notifications could not be installed. Scheduled scans and email alerts
30210
+ still work; re-run \`failproofai config\` after checking the local LaunchAgent.
30211
+
30212
+ `);
30213
+ }
30214
30214
  }
30215
30215
  const applied = emit("configure_applied", {
30216
30216
  target,
@@ -30789,7 +30789,7 @@ var init_harness_cli = __esm(() => {
30789
30789
  });
30790
30790
 
30791
30791
  // src/hooks/fp-config.ts
30792
- import { chmodSync as chmodSync6, existsSync as existsSync39, mkdirSync as mkdirSync26, readFileSync as readFileSync33, statSync as statSync24, writeFileSync as writeFileSync23 } from "node:fs";
30792
+ import { chmodSync as chmodSync7, existsSync as existsSync39, mkdirSync as mkdirSync26, readFileSync as readFileSync33, statSync as statSync24, writeFileSync as writeFileSync23 } from "node:fs";
30793
30793
  function detectLayout2() {
30794
30794
  const raw = readVersionFile2();
30795
30795
  if (raw) {
@@ -30859,7 +30859,7 @@ var init_fp_home2 = () => {};
30859
30859
 
30860
30860
  // src/hooks/migrations.ts
30861
30861
  import {
30862
- chmodSync as chmodSync7,
30862
+ chmodSync as chmodSync8,
30863
30863
  copyFileSync as copyFileSync3,
30864
30864
  existsSync as existsSync40,
30865
30865
  mkdirSync as mkdirSync27,
@@ -30910,7 +30910,7 @@ function migrateToLayout42() {
30910
30910
  if (!existsSync40(secret))
30911
30911
  continue;
30912
30912
  try {
30913
- chmodSync7(secret, 384);
30913
+ chmodSync8(secret, 384);
30914
30914
  } catch {}
30915
30915
  }
30916
30916
  writeVersionFile({ layout: 4 });
@@ -31645,6 +31645,7 @@ async function runUninstallCommand(opts = {}) {
31645
31645
  if (found.daemonConfigured) {
31646
31646
  plan.push(` • stop requiring the daemon (policies go back to evaluating in-process)`);
31647
31647
  }
31648
+ let removeDaemon = opts.purge === true;
31648
31649
  if (found.serviceInstalled) {
31649
31650
  plan.push(opts.purge || opts.yes ? ` • stop, disable and delete the service at ${found.servicePath} — needs sudo` : ` • ask whether to remove the service at ${found.servicePath} (kept unless you say so)`);
31650
31651
  }
@@ -31704,7 +31705,7 @@ async function runUninstallCommand(opts = {}) {
31704
31705
  }
31705
31706
  }
31706
31707
  if (found.serviceInstalled) {
31707
- const removeDaemon = opts.purge || opts.yes ? true : await opts.confirmDaemon?.() ?? false;
31708
+ removeDaemon = opts.purge || opts.yes ? true : await opts.confirmDaemon?.() ?? false;
31708
31709
  if (!removeDaemon) {
31709
31710
  lines.push(`• kept the daemon service at ${found.servicePath}`, ` Remove it later with: failproofai uninstall --purge`);
31710
31711
  } else {
@@ -31724,7 +31725,7 @@ async function runUninstallCommand(opts = {}) {
31724
31725
  }
31725
31726
  }
31726
31727
  }
31727
- if (opts.purge || found.serviceInstalled && (opts.purge || opts.yes)) {
31728
+ if (opts.purge || removeDaemon) {
31728
31729
  uninstallMacNotifier();
31729
31730
  }
31730
31731
  if (opts.purge && found.homeExists) {
@@ -35886,7 +35887,7 @@ import { realpathSync as realpathSync7 } from "fs";
35886
35887
  import { dirname as dirname25, resolve as resolve35 } from "path";
35887
35888
  import { fileURLToPath as fileURLToPath4 } from "url";
35888
35889
  // package.json
35889
- var version = "1.0.4-beta.6";
35890
+ var version = "1.0.4-beta.7";
35890
35891
 
35891
35892
  // bin/failproofai.mjs
35892
35893
  if (!process.env.FAILPROOFAI_PACKAGE_ROOT) {
package/dist/worker.mjs CHANGED
@@ -2809,8 +2809,8 @@ var init_builtin_policies = __esm(() => {
2809
2809
  [/sk-ant-oat01-[A-Za-z0-9\-_]{20,}/, "Anthropic OAuth token"],
2810
2810
  [/sk-ant-[A-Za-z0-9\-_]{20,}/, "Anthropic API key"],
2811
2811
  [/sk-proj-[A-Za-z0-9\-_]{20,}/, "OpenAI project API key"],
2812
- [/sk-svcacct-[A-Za-z0-9\-_]{20,}/, "OpenAI service-account key"],
2813
- [/sk-admin-[A-Za-z0-9\-_]{20,}/, "OpenAI admin key"],
2812
+ [/(?<!\w)sk-svcacct-[A-Za-z0-9\-_]{20,}/, "OpenAI service-account key"],
2813
+ [/(?<!\w)sk-admin-[A-Za-z0-9\-_]{20,}/, "OpenAI admin key"],
2814
2814
  [/sk-or-v1-[A-Za-z0-9\-_]{20,}/, "OpenRouter API key"],
2815
2815
  [/sk-[A-Za-z0-9]{20,}/, "OpenAI-compatible key (issuer unknown)"],
2816
2816
  [/github_pat_[A-Za-z0-9_]{82}/, "GitHub fine-grained token"],
@@ -3507,7 +3507,7 @@ function parsePackPolicyName(canonicalName) {
3507
3507
  }
3508
3508
 
3509
3509
  // package.json
3510
- var version = "1.0.4-beta.6";
3510
+ var version = "1.0.4-beta.7";
3511
3511
  var init_package = () => {};
3512
3512
 
3513
3513
  // src/posthog-key.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "failproofai",
3
- "version": "1.0.4-beta.6",
3
+ "version": "1.0.4-beta.7",
4
4
  "description": "Observability and enforcement for AI agent harnesses. 39 built-in policies hooked into 12 of them — Claude Code, Codex, Cursor, Hermes, OpenClaw and more — blocking the tool call before it runs. Local dashboard included, no account needed.",
5
5
  "bin": {
6
6
  "failproofai": "./dist/cli.mjs",
@@ -121,15 +121,15 @@
121
121
  "browserslist": "4.28.8"
122
122
  },
123
123
  "optionalDependencies": {
124
- "@failproofai/failproofaid-linux-x64": "1.0.4-beta.6",
125
- "@failproofai/failproofaid-linux-arm64": "1.0.4-beta.6",
126
- "@failproofai/failproofaid-darwin-x64": "1.0.4-beta.6",
127
- "@failproofai/failproofaid-darwin-arm64": "1.0.4-beta.6"
124
+ "@failproofai/failproofaid-linux-x64": "1.0.4-beta.7",
125
+ "@failproofai/failproofaid-linux-arm64": "1.0.4-beta.7",
126
+ "@failproofai/failproofaid-darwin-x64": "1.0.4-beta.7",
127
+ "@failproofai/failproofaid-darwin-arm64": "1.0.4-beta.7"
128
128
  },
129
129
  "failproofaidBinaries": {
130
- "linux-x64": "24118b8bd058cc5d8711053c4c77cdca9361c12dbf0f421a757d33f07596d428",
131
- "linux-arm64": "b4278c34a288de2c747bcebcc623d8fd5bda3a1f1e55800926eb1a4b89f0a5e9",
132
- "darwin-x64": "ecb66699f45f605b0d54ac9e4bac360ac11e4e136442dcccdd083514d77c7d42",
133
- "darwin-arm64": "b3dbad58bda960ef9481f90bc5085ba8624b2472519cc0bf212a0e8451dd2db4"
130
+ "linux-x64": "e59735a8f94cd8ac697b2bd67aafdd8d76a8394d53db229876980cc13a18f07e",
131
+ "linux-arm64": "b9ce50dd2f79b55f4f7112add265a776a4a6d002c2a56f971e666fbb796f3906",
132
+ "darwin-x64": "b46efc8ec33945a5cc26b7bb288fb87cea65b5983bd83094b5e607d53b8eda4c",
133
+ "darwin-arm64": "a8cc6112cee5ca8a7d517900e9ce32118855135980f22979fa0ff7aa6f68d954"
134
134
  }
135
135
  }
@@ -70,7 +70,7 @@ const TRANSCRIPT_BYTE_BUDGET = 48 * 1024 * 1024;
70
70
  * otherwise the largest transcript on the machine could never be scanned, which
71
71
  * is precisely the one most likely to hold something.
72
72
  */
73
- class ByteGate {
73
+ export class ByteGate {
74
74
  private inFlight = 0;
75
75
  private waiting: Array<() => void> = [];
76
76
 
@@ -152,23 +152,30 @@ export function upsertFinding(
152
152
  return { record, isNew: true };
153
153
  }
154
154
 
155
- existing.occurrences += 1;
156
- if (sighting.at > existing.lastSeen) existing.lastSeen = sighting.at;
157
- if (sighting.at < existing.firstSeen) existing.firstSeen = sighting.at;
158
-
159
155
  // Keep the earliest sighting AND the most recent evidence. The report/email
160
156
  // promises the CLI and timestamp of the latest exposure; keeping only the
161
157
  // first five made those fields stale forever after a busy credential crossed
162
158
  // the cap. Middle sightings are the expendable ones.
163
159
  const seen = existing.sightings.some(
164
- (s) => s.sessionId === sighting.sessionId && s.at === sighting.at,
160
+ (s) =>
161
+ s.sessionId === sighting.sessionId &&
162
+ s.at === sighting.at &&
163
+ s.mechanism.direction === sighting.mechanism.direction &&
164
+ s.mechanism.summary === sighting.mechanism.summary,
165
165
  );
166
- if (!seen) {
167
- existing.sightings.push(sighting);
168
- existing.sightings.sort((a, b) => a.at.localeCompare(b.at));
169
- if (existing.sightings.length > MAX_SIGHTINGS) {
170
- existing.sightings.splice(1, existing.sightings.length - MAX_SIGHTINGS);
171
- }
166
+ // Cached transcript results are folded through this function again. An
167
+ // identical sighting is therefore not a new exposure and must not inflate
168
+ // the count each time the same cache entry is reused.
169
+ if (seen) return { record, isNew: false };
170
+
171
+ existing.occurrences += 1;
172
+ if (sighting.at > existing.lastSeen) existing.lastSeen = sighting.at;
173
+ if (sighting.at < existing.firstSeen) existing.firstSeen = sighting.at;
174
+
175
+ existing.sightings.push(sighting);
176
+ existing.sightings.sort((a, b) => a.at.localeCompare(b.at));
177
+ if (existing.sightings.length > MAX_SIGHTINGS) {
178
+ existing.sightings.splice(1, existing.sightings.length - MAX_SIGHTINGS);
172
179
  }
173
180
  return { record, isNew: false };
174
181
  }
@@ -181,7 +188,12 @@ export function upsertFinding(
181
188
  */
182
189
  export function pruneRecord(record: LeakRecord, nowMs: number): LeakRecord {
183
190
  const cutoff = new Date(nowMs - FINDING_TTL_DAYS * 86_400_000).toISOString();
184
- const live = record.findings.filter((f) => f.lastSeen >= cutoff);
191
+ // A missing or malformed timestamp cannot be aged out safely. Keep it until
192
+ // the bounded-cap pass below rather than silently deleting a finding that the
193
+ // reporting path deliberately surfaces as having an unknown date.
194
+ const live = record.findings.filter(
195
+ (f) => !f.lastSeen || !Number.isFinite(Date.parse(f.lastSeen)) || f.lastSeen >= cutoff,
196
+ );
185
197
  live.sort((a, b) => (a.lastSeen < b.lastSeen ? 1 : a.lastSeen > b.lastSeen ? -1 : 0));
186
198
  record.findings = live.slice(0, MAX_FINDINGS);
187
199
  return record;