failproofai 1.0.0-beta.3 → 1.0.0-beta.5

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 (157) 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 +2 -2
  28. package/.next/standalone/.next/server/app/api/audit/run/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 +1 -1
  35. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
  36. package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
  37. package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
  38. package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
  39. package/.next/standalone/.next/server/app/index.html +1 -1
  40. package/.next/standalone/.next/server/app/index.rsc +14 -14
  41. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  42. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +14 -14
  43. package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +4 -4
  44. package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +9 -9
  45. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  46. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
  47. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  48. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  49. package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +10 -10
  50. package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
  51. package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
  52. package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
  53. package/.next/standalone/.next/server/app/project/[name]/page.js +1 -1
  54. package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
  55. package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
  56. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
  57. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
  58. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js +1 -1
  59. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
  60. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
  61. package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
  62. package/.next/standalone/.next/server/app/projects/page.js +1 -1
  63. package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
  64. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  65. package/.next/standalone/.next/server/chunks/[externals]__0h9_83k._.js +3 -0
  66. package/.next/standalone/.next/server/chunks/[externals]__1ifpkx-._.js +3 -0
  67. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0-dh5jy._.js +1 -1
  68. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0f8nu8d._.js +3 -0
  69. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0h3lfmp._.js +1 -1
  70. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0l4vuqm._.js +1 -1
  71. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0longh-._.js → [root-of-the-server]__0szqzl8._.js} +2 -2
  72. package/.next/standalone/.next/server/chunks/[root-of-the-server]__10oa-v9._.js +1 -1
  73. package/.next/standalone/.next/server/chunks/[root-of-the-server]__18d-9oi._.js +1 -1
  74. package/.next/standalone/.next/server/chunks/[root-of-the-server]__19120tr._.js +1 -1
  75. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1fwl2mz._.js +1 -1
  76. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1myjm-d._.js +1 -1
  77. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__16le-kd._.js → [root-of-the-server]__1p7s8-d._.js} +2 -2
  78. package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_01r25oi._.js +2 -1
  79. package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_09z9-p7._.js +2 -1
  80. package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
  81. package/.next/standalone/.next/server/chunks/ssr/[externals]__1aq139v._.js +3 -0
  82. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__02r5bgf._.js +2 -2
  83. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__10s_z4l._.js → [root-of-the-server]__094nop3._.js} +2 -2
  84. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0e8sjqm._.js +2 -2
  85. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0lkzqax._.js +2 -2
  86. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ls0gsr._.js +2 -2
  87. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0uno39i._.js → [root-of-the-server]__0n_uvv0._.js} +2 -2
  88. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qucxyj._.js +2 -2
  89. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__01od0m6._.js → [root-of-the-server]__0rag5dg._.js} +2 -2
  90. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1apb7k_._.js → [root-of-the-server]__0rtdfof._.js} +2 -2
  91. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0spkm68._.js +2 -2
  92. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0u02miy._.js +2 -2
  93. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1ky3im9._.js → [root-of-the-server]__1gak4pd._.js} +2 -2
  94. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1j4u3yd._.js +2 -2
  95. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1qapotl._.js +1 -1
  96. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1zqz4v8._.js +2 -2
  97. package/.next/standalone/.next/server/chunks/ssr/_1e19atl._.js +1 -1
  98. package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +1 -1
  99. package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
  100. package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +1 -1
  101. package/.next/standalone/.next/server/chunks/ssr/{node_modules_html-to-image_es_index_0jfts82.js → node_modules_html-to-image_es_index_12c_2cz.js} +1 -1
  102. package/.next/standalone/.next/server/chunks/ssr/node_modules_posthog-node_dist_entrypoints_index_node_mjs_11bnuzn._.js +2 -1
  103. package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
  104. package/.next/standalone/.next/server/pages/404.html +1 -1
  105. package/.next/standalone/.next/server/pages/500.html +1 -1
  106. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  107. package/.next/standalone/.next/server/server-reference-manifest.json +12 -12
  108. package/.next/standalone/.next/static/chunks/{29g8ykjk6sx_8.js → 0cr85wuc9gc9k.js} +1 -1
  109. package/.next/standalone/.next/static/chunks/{1hdhteui932bq.js → 0qmo2t50kpb30.js} +1 -1
  110. package/.next/standalone/.next/static/chunks/{0cvd6bcdwchc_.js → 1bkynffp3q1f7.js} +1 -1
  111. package/.next/standalone/.next/static/chunks/{2uvyh8y0naofj.js → 1bw4dfzflelcv.js} +1 -1
  112. package/.next/standalone/.next/static/chunks/{1h0_yaoq5f3yx.js → 1tp9dex23zs8y.js} +1 -1
  113. package/.next/standalone/.next/static/chunks/23kev26by1e4f.js +1 -0
  114. package/.next/standalone/.next/static/chunks/2cqk4a9s893oy.js +1 -0
  115. package/.next/standalone/.next/static/chunks/{13-obgukzg_ke.js → 2k285z07qce47.js} +1 -1
  116. package/.next/standalone/.next/static/chunks/{0a7k_x4rp_97z.js → 2s9g1dsde_ts1.js} +1 -1
  117. package/.next/standalone/.next/static/chunks/{2rqm-klet_gbl.js → 2v1rpzrh2i1wv.js} +1 -1
  118. package/.next/standalone/.next/static/chunks/{3p-n_j80zlzi3.js → 34sjdw8lv46e3.js} +2 -2
  119. package/.next/standalone/Cargo.lock +3 -3
  120. package/.next/standalone/Cargo.toml +1 -1
  121. package/.next/standalone/crates/failproofaid/src/main.rs +118 -11
  122. package/.next/standalone/crates/fpai-collect/src/config.rs +8 -0
  123. package/.next/standalone/crates/fpai-collect/src/filetail.rs +4 -1
  124. package/.next/standalone/crates/fpai-collect/src/sources/hooks/mod.rs +5 -1
  125. package/.next/standalone/crates/fpai-collect/src/spool.rs +77 -0
  126. package/.next/standalone/crates/fpai-collect/src/sqlitepoll.rs +4 -1
  127. package/.next/standalone/crates/fpai-collect/tests/claude_source.rs +1 -0
  128. package/.next/standalone/crates/fpai-collect/tests/claude_subagents.rs +1 -0
  129. package/.next/standalone/crates/fpai-collect/tests/codex_source.rs +1 -0
  130. package/.next/standalone/crates/fpai-collect/tests/copilot_source.rs +1 -0
  131. package/.next/standalone/crates/fpai-collect/tests/goose_source.rs +1 -0
  132. package/.next/standalone/crates/fpai-collect/tests/hermes_source.rs +1 -0
  133. package/.next/standalone/crates/fpai-collect/tests/hooks_source.rs +1 -0
  134. package/.next/standalone/crates/fpai-collect/tests/openclaw_source.rs +1 -0
  135. package/.next/standalone/crates/fpai-collect/tests/pi_source.rs +1 -0
  136. package/.next/standalone/package.json +14 -8
  137. package/.next/standalone/server.js +1 -1
  138. package/dist/cli.mjs +81 -28
  139. package/dist/worker.mjs +1 -1
  140. package/package.json +14 -8
  141. package/scripts/build-daemon-packages.mjs +210 -0
  142. package/scripts/daemon-platforms.mjs +42 -0
  143. package/scripts/prune-standalone.mjs +6 -0
  144. package/scripts/publish-aliases.mjs +62 -41
  145. package/src/hooks/cloud-connection.ts +3 -0
  146. package/src/hooks/collector-config.ts +10 -0
  147. package/src/hooks/daemon-download.ts +137 -27
  148. package/src/hooks/daemon-service.ts +23 -8
  149. package/.next/standalone/.next/server/chunks/[externals]__14odj07._.js +0 -3
  150. package/.next/standalone/.next/server/chunks/[externals]__1s61mel._.js +0 -3
  151. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0id_xf7._.js +0 -3
  152. package/.next/standalone/.next/server/chunks/ssr/[externals]__1_g_b3t._.js +0 -3
  153. package/.next/standalone/.next/static/chunks/01h6lfjz1_oie.js +0 -1
  154. package/.next/standalone/.next/static/chunks/2mazwb1qmur1p.js +0 -1
  155. /package/.next/standalone/.next/static/{pM1veX5Llx4YKEaiFc8Sf → LOuwMmfomO6hQYfMQYs4K}/_buildManifest.js +0 -0
  156. /package/.next/standalone/.next/static/{pM1veX5Llx4YKEaiFc8Sf → LOuwMmfomO6hQYfMQYs4K}/_clientMiddlewareManifest.js +0 -0
  157. /package/.next/standalone/.next/static/{pM1veX5Llx4YKEaiFc8Sf → LOuwMmfomO6hQYfMQYs4K}/_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.0-beta.3"},"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.5"},"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
 
package/dist/cli.mjs CHANGED
@@ -19,7 +19,7 @@ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
19
19
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
20
20
 
21
21
  // package.json
22
- var version2 = "1.0.0-beta.3";
22
+ var version2 = "1.0.0-beta.5";
23
23
  var init_package = () => {};
24
24
 
25
25
  // src/posthog-key.ts
@@ -23051,9 +23051,10 @@ var init_cloud_enrollment = __esm(() => {
23051
23051
 
23052
23052
  // src/hooks/daemon-download.ts
23053
23053
  import { createHash as createHash5 } from "node:crypto";
23054
- import { chmodSync as chmodSync3, existsSync as existsSync23, mkdirSync as mkdirSync11, renameSync as renameSync4, rmSync as rmSync5, writeFileSync as writeFileSync9 } from "node:fs";
23054
+ import { chmodSync as chmodSync3, existsSync as existsSync23, mkdirSync as mkdirSync11, readFileSync as readFileSync19, renameSync as renameSync4, rmSync as rmSync5, writeFileSync as writeFileSync9 } from "node:fs";
23055
+ import { createRequire as createRequire2 } from "node:module";
23055
23056
  import { homedir as homedir33 } from "node:os";
23056
- import { resolve as resolve19 } from "node:path";
23057
+ import { dirname as dirname9, resolve as resolve19 } from "node:path";
23057
23058
  import { gunzipSync } from "node:zlib";
23058
23059
  function baseUrl() {
23059
23060
  return (process.env.FAILPROOFAI_DAEMON_BASE_URL || DEFAULT_BASE_URL).replace(/\/+$/, "");
@@ -23070,6 +23071,58 @@ function daemonAssetUrl(key, ver = version2) {
23070
23071
  function checksumsUrl(ver = version2) {
23071
23072
  return `${baseUrl()}/v${ver}/SHA256SUMS`;
23072
23073
  }
23074
+ function platformPackageName(key) {
23075
+ return `@failproofai/failproofaid-${key}`;
23076
+ }
23077
+ function npmPlatformBinaryPath(key) {
23078
+ const packageRoot = process.env.FAILPROOFAI_PACKAGE_ROOT;
23079
+ if (!packageRoot)
23080
+ return null;
23081
+ const name = platformPackageName(key);
23082
+ try {
23083
+ const requireFromRoot = createRequire2(resolve19(packageRoot, "package.json"));
23084
+ const found = platformPackageBinary(dirname9(requireFromRoot.resolve(`${name}/package.json`)));
23085
+ if (found)
23086
+ return found;
23087
+ } catch {}
23088
+ return platformPackageBinary(resolve19(packageRoot, "node_modules", name));
23089
+ }
23090
+ function platformPackageBinary(dir) {
23091
+ try {
23092
+ const manifest = JSON.parse(readFileSync19(resolve19(dir, "package.json"), "utf8"));
23093
+ if (manifest.version !== version2)
23094
+ return null;
23095
+ } catch {
23096
+ return null;
23097
+ }
23098
+ const candidate = resolve19(dir, "bin", "failproofaid");
23099
+ return existsSync23(candidate) ? candidate : null;
23100
+ }
23101
+ function installBinaryBytes(binary) {
23102
+ const target = installedBinaryPath();
23103
+ const tempPath = `${target}.${process.pid}.tmp`;
23104
+ try {
23105
+ mkdirSync11(daemonBinaryDir(), { recursive: true });
23106
+ writeFileSync9(tempPath, binary);
23107
+ chmodSync3(tempPath, 493);
23108
+ renameSync4(tempPath, target);
23109
+ return target;
23110
+ } catch (err) {
23111
+ rmSync5(tempPath, { force: true });
23112
+ throw err;
23113
+ }
23114
+ }
23115
+ function installFromNpmPackage(key) {
23116
+ const source = npmPlatformBinaryPath(key);
23117
+ if (!source)
23118
+ return { error: `${platformPackageName(key)} is not installed` };
23119
+ try {
23120
+ return { path: installBinaryBytes(readFileSync19(source)) };
23121
+ } catch (err) {
23122
+ const message = err instanceof Error ? err.message : String(err);
23123
+ return { error: `failed to install failproofaid from ${source}: ${message}` };
23124
+ }
23125
+ }
23073
23126
  async function fetchBytes(url) {
23074
23127
  const response = await fetch(url, { signal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS) });
23075
23128
  if (!response.ok)
@@ -23093,7 +23146,6 @@ async function downloadFailproofaidBinary(key) {
23093
23146
  return { error: "daemon downloads are disabled (FAILPROOFAI_NO_DOWNLOAD)" };
23094
23147
  }
23095
23148
  const assetName = `failproofaid-${key}.gz`;
23096
- const tempPath = `${target}.${process.pid}.tmp`;
23097
23149
  try {
23098
23150
  const [asset, manifest] = await Promise.all([
23099
23151
  fetchBytes(daemonAssetUrl(key)),
@@ -23107,14 +23159,8 @@ async function downloadFailproofaidBinary(key) {
23107
23159
  if (actual !== expected) {
23108
23160
  return { error: `checksum mismatch for ${assetName} (expected ${expected}, got ${actual})` };
23109
23161
  }
23110
- const binary = gunzipSync(asset);
23111
- mkdirSync11(daemonBinaryDir(), { recursive: true });
23112
- writeFileSync9(tempPath, binary);
23113
- chmodSync3(tempPath, 493);
23114
- renameSync4(tempPath, target);
23115
- return { path: target };
23162
+ return { path: installBinaryBytes(gunzipSync(asset)) };
23116
23163
  } catch (err) {
23117
- rmSync5(tempPath, { force: true });
23118
23164
  const message = err instanceof Error ? err.message : String(err);
23119
23165
  return { error: `failed to download failproofaid v${version2} for ${key}: ${message}` };
23120
23166
  }
@@ -23129,20 +23175,20 @@ import {
23129
23175
  existsSync as existsSync24,
23130
23176
  mkdirSync as mkdirSync12,
23131
23177
  mkdtempSync,
23132
- readFileSync as readFileSync19,
23178
+ readFileSync as readFileSync20,
23133
23179
  writeFileSync as writeFileSync10,
23134
23180
  unlinkSync as unlinkSync3,
23135
23181
  rmSync as rmSync6
23136
23182
  } from "node:fs";
23137
23183
  import { homedir as homedir34, tmpdir, userInfo } from "node:os";
23138
- import { resolve as resolve20, dirname as dirname9 } from "node:path";
23184
+ import { resolve as resolve20, dirname as dirname10 } from "node:path";
23139
23185
  import { execFileSync as execFileSync4 } from "node:child_process";
23140
23186
  function setDaemonConfigured(value) {
23141
23187
  const path3 = getConfigPathForScope("user");
23142
23188
  let config = {};
23143
23189
  try {
23144
23190
  if (existsSync24(path3))
23145
- config = JSON.parse(readFileSync19(path3, "utf8"));
23191
+ config = JSON.parse(readFileSync20(path3, "utf8"));
23146
23192
  } catch {
23147
23193
  return;
23148
23194
  }
@@ -23151,7 +23197,7 @@ function setDaemonConfigured(value) {
23151
23197
  else
23152
23198
  delete config.daemonConfigured;
23153
23199
  try {
23154
- mkdirSync12(dirname9(path3), { recursive: true });
23200
+ mkdirSync12(dirname10(path3), { recursive: true });
23155
23201
  writeFileSync10(path3, JSON.stringify(config, null, 2) + `
23156
23202
  `, "utf8");
23157
23203
  } catch {}
@@ -23190,10 +23236,15 @@ async function ensureFailproofaidBinary() {
23190
23236
  if (!key) {
23191
23237
  return { reason: `failproofaid has no prebuilt binary for ${process.platform}/${process.arch}` };
23192
23238
  }
23239
+ const fromNpm = installFromNpmPackage(key);
23240
+ if (fromNpm.path)
23241
+ return { path: fromNpm.path };
23193
23242
  const result = await downloadFailproofaidBinary(key);
23194
23243
  if (result.path)
23195
23244
  return { path: result.path };
23196
- return { reason: result.error ?? "failproofaid binary could not be downloaded" };
23245
+ return {
23246
+ reason: result.error ? `${result.error} (${fromNpm.error})` : "failproofaid binary could not be installed"
23247
+ };
23197
23248
  }
23198
23249
  function resolveWorkerCommand() {
23199
23250
  if (process.env.FAILPROOFAI_WORKER_CMD)
@@ -23521,7 +23572,7 @@ import {
23521
23572
  existsSync as existsSync26,
23522
23573
  chmodSync as chmodSync4,
23523
23574
  statSync as statSync18,
23524
- readFileSync as readFileSync20,
23575
+ readFileSync as readFileSync21,
23525
23576
  rmSync as rmSync7
23526
23577
  } from "node:fs";
23527
23578
  import { join as join32 } from "node:path";
@@ -23537,7 +23588,7 @@ function hasIngestCredential() {
23537
23588
  }
23538
23589
  function readIngestCredential() {
23539
23590
  try {
23540
- const raw = JSON.parse(readFileSync20(ingestPath(), "utf8"));
23591
+ const raw = JSON.parse(readFileSync21(ingestPath(), "utf8"));
23541
23592
  if (typeof raw.url !== "string" || typeof raw.key !== "string")
23542
23593
  return null;
23543
23594
  if (!raw.url || !raw.key)
@@ -23580,7 +23631,8 @@ function writeCollectorSettings(settings) {
23580
23631
  hooks: settings.hooks,
23581
23632
  hooksVerbosity: settings.hooksVerbosity ?? "decisions",
23582
23633
  redact: settings.redact ?? "minimal",
23583
- environment: settings.environment ?? "local"
23634
+ environment: settings.environment ?? "local",
23635
+ ...settings.machineId ? { machineId: settings.machineId } : {}
23584
23636
  }
23585
23637
  });
23586
23638
  }
@@ -23677,7 +23729,8 @@ async function connectToCloud(input) {
23677
23729
  const settings = {
23678
23730
  hooks: true,
23679
23731
  sessions: input.sessions === true,
23680
- environment: input.environment
23732
+ environment: input.environment,
23733
+ machineId: input.machineId
23681
23734
  };
23682
23735
  writeCollectorSettings(settings);
23683
23736
  outcome.anyConfigured = true;
@@ -24580,7 +24633,7 @@ __export(exports_configure_wizard, {
24580
24633
  buildPresetChoices: () => buildPresetChoices,
24581
24634
  buildAgentChoices: () => buildAgentChoices
24582
24635
  });
24583
- import { existsSync as existsSync28, mkdirSync as mkdirSync14, writeFileSync as writeFileSync12, readFileSync as readFileSync21 } from "node:fs";
24636
+ import { existsSync as existsSync28, mkdirSync as mkdirSync14, writeFileSync as writeFileSync12, readFileSync as readFileSync22 } from "node:fs";
24584
24637
  import { homedir as homedir38, hostname as hostname5 } from "node:os";
24585
24638
  import { resolve as resolve23, sep as sep5 } from "node:path";
24586
24639
  async function emit(event, props) {
@@ -24704,7 +24757,7 @@ function setCustomPoliciesEnabled(scope, cwd, enabled) {
24704
24757
  let config = {};
24705
24758
  try {
24706
24759
  if (existsSync28(path3))
24707
- config = JSON.parse(readFileSync21(path3, "utf8"));
24760
+ config = JSON.parse(readFileSync22(path3, "utf8"));
24708
24761
  } catch {
24709
24762
  return;
24710
24763
  }
@@ -25166,7 +25219,7 @@ __export(exports_launch2, {
25166
25219
  });
25167
25220
  import { spawn as spawn3 } from "child_process";
25168
25221
  import { realpathSync as realpathSync4, existsSync as existsSync29 } from "node:fs";
25169
- import { resolve as resolve24, dirname as dirname10 } from "node:path";
25222
+ import { resolve as resolve24, dirname as dirname11 } from "node:path";
25170
25223
  import { fileURLToPath as fileURLToPath3 } from "node:url";
25171
25224
  import { createInterface as createInterface3 } from "node:readline";
25172
25225
  function launch2(mode) {
@@ -25181,7 +25234,7 @@ function launch2(mode) {
25181
25234
  process.env.PORT = port;
25182
25235
  process.env.HOSTNAME = "0.0.0.0";
25183
25236
  cmd = "node";
25184
- const packageRoot = process.env.FAILPROOFAI_PACKAGE_ROOT ?? resolve24(dirname10(realpathSync4(fileURLToPath3(import.meta.url))), "..");
25237
+ const packageRoot = process.env.FAILPROOFAI_PACKAGE_ROOT ?? resolve24(dirname11(realpathSync4(fileURLToPath3(import.meta.url))), "..");
25185
25238
  const serverJsPath = resolve24(packageRoot, ".next/standalone/server.js");
25186
25239
  if (!existsSync29(serverJsPath)) {
25187
25240
  let shadowMessage = null;
@@ -25278,17 +25331,17 @@ var init_cli_error2 = __esm(() => {
25278
25331
 
25279
25332
  // bin/failproofai.mjs
25280
25333
  import { realpathSync as realpathSync5 } from "fs";
25281
- import { dirname as dirname11, resolve as resolve25 } from "path";
25334
+ import { dirname as dirname12, resolve as resolve25 } from "path";
25282
25335
  import { fileURLToPath as fileURLToPath4 } from "url";
25283
25336
  // package.json
25284
- var version = "1.0.0-beta.3";
25337
+ var version = "1.0.0-beta.5";
25285
25338
 
25286
25339
  // bin/failproofai.mjs
25287
25340
  if (!process.env.FAILPROOFAI_PACKAGE_ROOT) {
25288
- process.env.FAILPROOFAI_PACKAGE_ROOT = resolve25(dirname11(realpathSync5(fileURLToPath4(import.meta.url))), "..");
25341
+ process.env.FAILPROOFAI_PACKAGE_ROOT = resolve25(dirname12(realpathSync5(fileURLToPath4(import.meta.url))), "..");
25289
25342
  }
25290
25343
  if (!process.env.FAILPROOFAI_DIST_PATH) {
25291
- process.env.FAILPROOFAI_DIST_PATH = resolve25(dirname11(realpathSync5(fileURLToPath4(import.meta.url))), "..", "dist");
25344
+ process.env.FAILPROOFAI_DIST_PATH = resolve25(dirname12(realpathSync5(fileURLToPath4(import.meta.url))), "..", "dist");
25292
25345
  }
25293
25346
  var args = process.argv.slice(2);
25294
25347
  if (args[0] === "p")
package/dist/worker.mjs CHANGED
@@ -2340,7 +2340,7 @@ var init_builtin_policies = __esm(() => {
2340
2340
  });
2341
2341
 
2342
2342
  // package.json
2343
- var version = "1.0.0-beta.3";
2343
+ var version = "1.0.0-beta.5";
2344
2344
  var init_package = () => {};
2345
2345
 
2346
2346
  // src/posthog-key.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "failproofai",
3
- "version": "1.0.0-beta.3",
3
+ "version": "1.0.0-beta.5",
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",
@@ -76,19 +76,19 @@
76
76
  "@anthropic-ai/sdk": "^0.115.0",
77
77
  "@mdx-js/mdx": "^3.1.1",
78
78
  "@tailwindcss/postcss": "^4.3.1",
79
- "@tanstack/react-virtual": "^3.14.3",
79
+ "@tanstack/react-virtual": "^3.14.9",
80
80
  "@testing-library/jest-dom": "^7.0.0",
81
81
  "@testing-library/react": "^16.3.2",
82
82
  "@testing-library/user-event": "^14.6.1",
83
- "@types/node": "26.1.1",
83
+ "@types/node": "26.1.2",
84
84
  "@types/react": "19.2.17",
85
85
  "@types/react-dom": "^19.2.3",
86
- "@vitejs/plugin-react": "^6.0.1",
86
+ "@vitejs/plugin-react": "^6.0.5",
87
87
  "clsx": "^2.1.1",
88
88
  "eslint": "^10.5.0",
89
89
  "eslint-config-next": "^16.2.9",
90
- "jsdom": "^30.0.0",
91
- "lucide-react": "^1.18.0",
90
+ "jsdom": "^30.0.1",
91
+ "lucide-react": "^1.28.0",
92
92
  "next": "^16.2.11",
93
93
  "react": "^19.2.4",
94
94
  "react-dom": "^19.2.4",
@@ -100,7 +100,7 @@
100
100
  "dependencies": {
101
101
  "html-to-image": "^1.11.13",
102
102
  "html2canvas": "^1.4.1",
103
- "posthog-node": "^5.37.1",
103
+ "posthog-node": "^5.47.7",
104
104
  "sql.js": "^1.14.1",
105
105
  "yaml": "^2.9.0"
106
106
  },
@@ -108,8 +108,14 @@
108
108
  "postcss": "8.5.23",
109
109
  "eslint-plugin-react-hooks": "7.0.1",
110
110
  "vite": "8.0.16",
111
- "undici": "7.28.0",
111
+ "undici": "7.29.0",
112
112
  "brace-expansion": "5.0.9",
113
113
  "sharp": "0.35.0"
114
+ },
115
+ "optionalDependencies": {
116
+ "@failproofai/failproofaid-linux-x64": "1.0.0-beta.5",
117
+ "@failproofai/failproofaid-linux-arm64": "1.0.0-beta.5",
118
+ "@failproofai/failproofaid-darwin-x64": "1.0.0-beta.5",
119
+ "@failproofai/failproofaid-darwin-arm64": "1.0.0-beta.5"
114
120
  }
115
121
  }
@@ -0,0 +1,210 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Publishes the four `failproofaid` binaries as npm platform packages, so a
4
+ * plain `npm install failproofai` already carries the daemon for the machine
5
+ * it landed on instead of fetching one from the GitHub Release later.
6
+ *
7
+ * The release assets stay exactly as they are — this is a second channel, not
8
+ * a replacement. `src/hooks/daemon-download.ts` prefers whichever binary is
9
+ * already on disk, then this npm package, then the release; the npm path is
10
+ * the only one that works with no network at `failproofai config` time.
11
+ *
12
+ * Two rules make this safe, and both come from the way the first attempt at
13
+ * npm-shipping the daemon failed (CHANGELOG 1.0.0-beta.3 — four
14
+ * `optionalDependencies` were declared and never published, so every install
15
+ * resolved four 404s):
16
+ *
17
+ * 1. These packages publish BEFORE the root package that pins them, so the
18
+ * names always exist by the time anything depends on them.
19
+ * 2. A publish failure here is fatal, not a warning (unlike the alias stubs
20
+ * in publish-aliases.mjs, where a missing name costs nothing). Failing
21
+ * the job leaves the registry untouched; publishing a root package whose
22
+ * optional dependency 404s would ship the broken state to every user.
23
+ *
24
+ * Usage:
25
+ * node scripts/build-daemon-packages.mjs --artifacts <dir> [--dist-tag <tag>]
26
+ * [--version <v>] [--pin-root] [--dry-run]
27
+ */
28
+ import { execFileSync } from "node:child_process";
29
+ import { chmodSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
30
+ import { tmpdir } from "node:os";
31
+ import { dirname, join, resolve } from "node:path";
32
+ import { fileURLToPath, pathToFileURL } from "node:url";
33
+ import { gunzipSync } from "node:zlib";
34
+ import {
35
+ DAEMON_PLATFORMS,
36
+ daemonAssetName,
37
+ daemonOptionalDependencies,
38
+ daemonPackageName,
39
+ } from "./daemon-platforms.mjs";
40
+
41
+ const REPO_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..");
42
+
43
+ /**
44
+ * Where the generated packages are staged — **outside the repo**, and that is
45
+ * load-bearing rather than tidy.
46
+ *
47
+ * `npm publish` re-runs `prepare`, so the Next build happens again *after*
48
+ * this script has run, and Next's file tracing pulls the whole project root
49
+ * into `.next/standalone` (see the "over-traced project artifacts" prune list
50
+ * in scripts/prune-standalone.mjs). Anything staged inside the checkout
51
+ * therefore ends up inside the published CLI tarball — measured: a dry run
52
+ * shipped 16 MB of daemon `.gz` assets under
53
+ * `.next/standalone/release-assets/`. Staging in the temp dir cannot be swept
54
+ * up by a build. `--staging` overrides it for tests.
55
+ */
56
+ export const STAGING_DIR = resolve(tmpdir(), "failproofaid-packages");
57
+
58
+ /**
59
+ * The manifest for one platform package.
60
+ *
61
+ * Deliberately carries no `bin` (it would shadow the root package's own
62
+ * `failproofaid` shim, which is what a user invoking the daemon by hand
63
+ * should reach) and no `exports` (so `require.resolve("<pkg>/package.json")`
64
+ * — how the CLI finds this package — keeps working).
65
+ */
66
+ export function platformPackageManifest(platform, version, rootPkg = {}) {
67
+ return {
68
+ name: daemonPackageName(platform.key),
69
+ version,
70
+ description: `The failproofaid background daemon binary for ${platform.os} ${platform.cpu}. Installed automatically as an optional dependency of failproofai.`,
71
+ // npm's own platform filters: with both set, only the matching package is
72
+ // installed and the other three are skipped without a warning.
73
+ os: [platform.os],
74
+ cpu: [platform.cpu],
75
+ files: ["bin/"],
76
+ publishConfig: { access: "public" },
77
+ repository: rootPkg.repository,
78
+ homepage: rootPkg.homepage,
79
+ bugs: rootPkg.bugs,
80
+ license: rootPkg.license,
81
+ };
82
+ }
83
+
84
+ /**
85
+ * Stages one platform package on disk and returns its directory.
86
+ *
87
+ * The binary is written decompressed and mode 0755: npm records the executable
88
+ * bit in the tarball, so it survives publish → install, which is how esbuild
89
+ * and swc ship their binaries.
90
+ */
91
+ export function stagePlatformPackage(platform, version, rootPkg, artifactsDir, stagingRoot = STAGING_DIR) {
92
+ const asset = resolve(artifactsDir, daemonAssetName(platform.key));
93
+ if (!existsSync(asset)) {
94
+ throw new Error(`missing artifact ${asset} — the daemon build did not produce ${daemonAssetName(platform.key)}`);
95
+ }
96
+
97
+ const dir = join(stagingRoot, `failproofaid-${platform.key}`);
98
+ rmSync(dir, { recursive: true, force: true });
99
+ mkdirSync(join(dir, "bin"), { recursive: true });
100
+
101
+ const binary = gunzipSync(readFileSync(asset));
102
+ const binaryPath = join(dir, "bin", "failproofaid");
103
+ writeFileSync(binaryPath, binary);
104
+ chmodSync(binaryPath, 0o755);
105
+
106
+ writeFileSync(
107
+ join(dir, "package.json"),
108
+ JSON.stringify(platformPackageManifest(platform, version, rootPkg), null, 2) + "\n",
109
+ );
110
+ writeFileSync(
111
+ join(dir, "README.md"),
112
+ `# ${daemonPackageName(platform.key)}\n\n` +
113
+ `The \`failproofaid\` background daemon binary for ${platform.os} ${platform.cpu}.\n\n` +
114
+ `Installed automatically as an optional dependency of [failproofai](https://www.npmjs.com/package/failproofai) — ` +
115
+ `you do not need to install it yourself.\n`,
116
+ );
117
+
118
+ return dir;
119
+ }
120
+
121
+ /**
122
+ * Writes the four platform packages into the root manifest's
123
+ * `optionalDependencies`, pinned to `version`.
124
+ *
125
+ * Called at publish time rather than committed: a pin to a version that does
126
+ * not exist yet breaks `bun install --frozen-lockfile` in this repo's own CI,
127
+ * and keeping four pins in step with every version bump by hand is the drift
128
+ * this whole file exists to avoid.
129
+ */
130
+ export function pinRootManifest(version, packageJsonPath = resolve(REPO_ROOT, "package.json")) {
131
+ const pkg = JSON.parse(readFileSync(packageJsonPath, "utf8"));
132
+ pkg.optionalDependencies = { ...pkg.optionalDependencies, ...daemonOptionalDependencies(version) };
133
+ writeFileSync(packageJsonPath, JSON.stringify(pkg, null, 2) + "\n");
134
+ return pkg.optionalDependencies;
135
+ }
136
+
137
+ function parseArgs(argv) {
138
+ const valueOf = (flag, fallback) => {
139
+ const index = argv.indexOf(flag);
140
+ return index !== -1 && argv[index + 1] ? argv[index + 1] : fallback;
141
+ };
142
+ return {
143
+ artifacts: valueOf("--artifacts", "release-assets"),
144
+ staging: valueOf("--staging", STAGING_DIR),
145
+ distTag: valueOf("--dist-tag", null),
146
+ version: valueOf("--version", null),
147
+ pinRoot: argv.includes("--pin-root"),
148
+ dryRun: argv.includes("--dry-run"),
149
+ };
150
+ }
151
+
152
+ /**
153
+ * `npm publish`, with provenance when the registry will take it.
154
+ *
155
+ * Provenance needs a supported CI and a repository field npm can match to the
156
+ * building workflow; when it refuses, the publish itself is still correct, so
157
+ * this retries once without the flag rather than failing the release.
158
+ */
159
+ function publishPackage(dir, distTag, dryRun) {
160
+ const args = ["publish", "--tag", distTag];
161
+ if (dryRun) args.push("--dry-run");
162
+
163
+ const attempt = (extra) =>
164
+ execFileSync("npm", [...args, ...extra], { cwd: dir, stdio: "pipe", encoding: "utf8" });
165
+
166
+ const withProvenance = !dryRun && process.env.GITHUB_ACTIONS === "true";
167
+ try {
168
+ return attempt(withProvenance ? ["--provenance"] : []);
169
+ } catch (err) {
170
+ const output = (err.stdout ?? "") + (err.stderr ?? "");
171
+ if (output.includes("cannot publish over")) return "[skip] already published at this version";
172
+ if (withProvenance && /provenance/i.test(output)) {
173
+ console.log("::warning::provenance was rejected — retrying the publish without it");
174
+ return attempt([]);
175
+ }
176
+ // Fatal on purpose: see the header. The root package pins these names, so
177
+ // a half-published set must stop the release rather than ship 404s.
178
+ throw new Error(`npm publish failed for ${dir}:\n${output.trim()}`);
179
+ }
180
+ }
181
+
182
+ export function main(argv = process.argv.slice(2)) {
183
+ const options = parseArgs(argv);
184
+ const rootPkg = JSON.parse(readFileSync(resolve(REPO_ROOT, "package.json"), "utf8"));
185
+ const version = options.version ?? rootPkg.version;
186
+ const distTag = options.distTag ?? (version.includes("-") ? "beta" : "latest");
187
+ const artifactsDir = resolve(process.cwd(), options.artifacts);
188
+
189
+ console.log(
190
+ `Publishing ${DAEMON_PLATFORMS.length} failproofaid platform packages at ${version} ` +
191
+ `(tag: ${distTag}${options.dryRun ? ", dry run" : ""}) from ${artifactsDir}`,
192
+ );
193
+
194
+ for (const platform of DAEMON_PLATFORMS) {
195
+ const dir = stagePlatformPackage(platform, version, rootPkg, artifactsDir, options.staging);
196
+ const name = daemonPackageName(platform.key);
197
+ console.log(`\n${name}@${version}`);
198
+ console.log(publishPackage(dir, distTag, options.dryRun).trim());
199
+ }
200
+
201
+ if (options.pinRoot) {
202
+ const pins = pinRootManifest(version);
203
+ console.log("\nPinned in the root manifest's optionalDependencies:");
204
+ console.log(JSON.stringify(pins, null, 2));
205
+ }
206
+ }
207
+
208
+ if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
209
+ main();
210
+ }
@@ -0,0 +1,42 @@
1
+ /**
2
+ * The platforms `failproofaid` is cross-compiled for, and the npm packages
3
+ * those binaries publish under.
4
+ *
5
+ * One list, three consumers: `build-daemon-packages.mjs` (publishes them),
6
+ * `publish-aliases.mjs` (pins them in every typo-squat stub), and the root
7
+ * package's injected `optionalDependencies`. They have to agree exactly — a
8
+ * name that appears in a dependency but never gets published is a 404 in
9
+ * every install, which is precisely how the first attempt at npm-shipping the
10
+ * daemon failed (see CHANGELOG 1.0.0-beta.3).
11
+ *
12
+ * `os` / `cpu` are npm's own filters, spelled in `process.platform` /
13
+ * `process.arch` values: with both set, npm and bun install only the package
14
+ * matching the machine and silently skip the other three.
15
+ */
16
+
17
+ export const DAEMON_PLATFORMS = [
18
+ { key: "linux-x64", os: "linux", cpu: "x64" },
19
+ { key: "linux-arm64", os: "linux", cpu: "arm64" },
20
+ { key: "darwin-x64", os: "darwin", cpu: "x64" },
21
+ { key: "darwin-arm64", os: "darwin", cpu: "arm64" },
22
+ ];
23
+
24
+ /** The npm package name carrying the binary for one platform key. */
25
+ export function daemonPackageName(key) {
26
+ return `@failproofai/failproofaid-${key}`;
27
+ }
28
+
29
+ /** The release asset the binary for one platform key arrives in. */
30
+ export function daemonAssetName(key) {
31
+ return `failproofaid-${key}.gz`;
32
+ }
33
+
34
+ /**
35
+ * The `optionalDependencies` block that pins all four platform packages to one
36
+ * version — what the root package and every alias stub carry when published.
37
+ */
38
+ export function daemonOptionalDependencies(version) {
39
+ return Object.fromEntries(
40
+ DAEMON_PLATFORMS.map((platform) => [daemonPackageName(platform.key), version]),
41
+ );
42
+ }
@@ -101,6 +101,12 @@ const STANDALONE_ROOT_PRUNE = [
101
101
  ".claude", ".failproofai", ".github", ".vscode", ".idea",
102
102
  // Failproofai CLI artifacts — the dashboard never loads these
103
103
  "bin", "dist", "scripts", "src",
104
+ // Release-pipeline scratch: the daemon binaries downloaded from the build
105
+ // matrix and the staged platform packages. Both are written into the
106
+ // workspace only by a local/manual run (the publish workflow keeps them in
107
+ // RUNNER_TEMP precisely so this cannot happen), and 16 MB of `.gz` shipped
108
+ // inside the CLI tarball once already because nothing pruned them.
109
+ "release-assets", ".daemon-packages",
104
110
  ];
105
111
  const STANDALONE_ROOT_PRUNE_FILES = [
106
112
  // Top-level markdown / licenses / docs