failproofai 1.0.10 → 1.0.11-beta.1

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 (297) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/build-manifest.json +6 -6
  3. package/.next/standalone/.next/prerender-manifest.json +4 -4
  4. package/.next/standalone/.next/required-server-files.json +1 -1
  5. package/.next/standalone/.next/server/app/_global-error/page/build-manifest.json +3 -3
  6. package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
  7. package/.next/standalone/.next/server/app/_global-error/page.js +4 -4
  8. package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  9. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  10. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  11. package/.next/standalone/.next/server/app/_global-error.meta +8 -0
  12. package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
  13. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +6 -6
  14. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
  15. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  16. package/.next/standalone/.next/server/app/_not-found/page/build-manifest.json +3 -3
  17. package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  18. package/.next/standalone/.next/server/app/_not-found/page.js +4 -4
  19. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  20. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  21. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  22. package/.next/standalone/.next/server/app/_not-found.meta +8 -0
  23. package/.next/standalone/.next/server/app/_not-found.rsc +14 -14
  24. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +14 -14
  25. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +13 -13
  26. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  27. package/.next/standalone/.next/server/app/api/audit/invite/route.js +4 -4
  28. package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -1
  29. package/.next/standalone/.next/server/app/api/audit/run/route.js +4 -4
  30. package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
  31. package/.next/standalone/.next/server/app/api/audit/status/route.js +1 -1
  32. package/.next/standalone/.next/server/app/api/audit/status/route.js.nft.json +1 -1
  33. package/.next/standalone/.next/server/app/api/auth/login-request/route.js +2 -2
  34. package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
  35. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js +4 -4
  36. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
  37. package/.next/standalone/.next/server/app/api/auth/logout/route.js +3 -3
  38. package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
  39. package/.next/standalone/.next/server/app/api/auth/status/route.js +3 -3
  40. package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
  41. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js +1 -1
  42. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
  43. package/.next/standalone/.next/server/app/audit/page/build-manifest.json +3 -3
  44. package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
  45. package/.next/standalone/.next/server/app/audit/page.js +4 -4
  46. package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
  47. package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
  48. package/.next/standalone/.next/server/app/index.html +1 -1
  49. package/.next/standalone/.next/server/app/index.meta +8 -0
  50. package/.next/standalone/.next/server/app/index.rsc +14 -14
  51. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +13 -13
  52. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +14 -14
  53. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  54. package/.next/standalone/.next/server/app/page/build-manifest.json +3 -3
  55. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
  56. package/.next/standalone/.next/server/app/page.js +4 -4
  57. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  58. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  59. package/.next/standalone/.next/server/app/policies/page/build-manifest.json +3 -3
  60. package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +14 -14
  61. package/.next/standalone/.next/server/app/policies/page.js +8 -8
  62. package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
  63. package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
  64. package/.next/standalone/.next/server/app/project/[name]/page/build-manifest.json +3 -3
  65. package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
  66. package/.next/standalone/.next/server/app/project/[name]/page.js +5 -5
  67. package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
  68. package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
  69. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/build-manifest.json +3 -3
  70. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
  71. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
  72. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js +5 -5
  73. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
  74. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
  75. package/.next/standalone/.next/server/app/projects/page/build-manifest.json +3 -3
  76. package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
  77. package/.next/standalone/.next/server/app/projects/page.js +5 -5
  78. package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
  79. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  80. package/.next/standalone/.next/server/app/settings/page/build-manifest.json +3 -3
  81. package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +8 -8
  82. package/.next/standalone/.next/server/app/settings/page.js +9 -9
  83. package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
  84. package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  85. package/.next/standalone/.next/server/chunks/{[externals]__0qxhecv._.js → [externals]__0d7i9ea._.js} +2 -2
  86. package/.next/standalone/.next/server/chunks/{[externals]__0sg9-3p._.js → [externals]__0hjaw70._.js} +1 -1
  87. package/.next/standalone/.next/server/chunks/[externals]__1_9ze9b._.js +3 -0
  88. package/.next/standalone/.next/server/chunks/[externals]__1oenfmn._.js +3 -0
  89. package/.next/standalone/.next/server/chunks/[root-of-the-server]__08dchfu._.js +1 -1
  90. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ga9hs7._.js +3 -0
  91. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0l3yhx4._.js +2 -2
  92. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0moxohc._.js +22 -0
  93. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o07qi9._.js +1 -1
  94. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0z2ll-a._.js +3 -0
  95. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1adacul._.js +11 -11
  96. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1autwno._.js +3 -0
  97. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1v25n-6._.js +3 -0
  98. package/.next/standalone/.next/server/chunks/_09dz7xv._.js +1 -1
  99. package/.next/standalone/.next/server/chunks/_0tovk6q._.js +1 -1
  100. package/.next/standalone/.next/server/chunks/_0trp3yc._.js +1 -1
  101. package/.next/standalone/.next/server/chunks/_1ek68ln._.js +2 -2
  102. package/.next/standalone/.next/server/chunks/_1fz8m31._.js +1 -1
  103. package/.next/standalone/.next/server/chunks/_1jrv3hg._.js +3 -0
  104. package/.next/standalone/.next/server/chunks/_1nx8fim._.js +3 -0
  105. package/.next/standalone/.next/server/chunks/_1ogwigf._.js +1 -1
  106. package/.next/standalone/.next/server/chunks/{_1q5i8mb._.js → _1q27azx._.js} +2 -2
  107. package/.next/standalone/.next/server/chunks/lib_telemetry_ts_0dctyyw._.js +1 -1
  108. package/.next/standalone/.next/server/chunks/{node_modules_posthog-node_dist_entrypoints_index_node_mjs_0el6rg8._.js → node_modules_posthog-node_dist_entrypoints_index_node_mjs_0ol5pa3._.js} +2 -2
  109. package/.next/standalone/.next/server/chunks/{node_modules_posthog-node_dist_entrypoints_index_node_mjs_04op_ou._.js → node_modules_posthog-node_dist_entrypoints_index_node_mjs_1rqmk27._.js} +2 -2
  110. package/.next/standalone/.next/server/chunks/{node_modules_posthog-node_dist_entrypoints_index_node_mjs_0dr20uz._.js → node_modules_posthog-node_dist_entrypoints_index_node_mjs_1w7tiq4._.js} +2 -2
  111. package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
  112. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0oqrl71._.js → [root-of-the-server]__042u-jn._.js} +2 -2
  113. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__04usis8._.js +2 -2
  114. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1-bm5zf._.js → [root-of-the-server]__0502lat._.js} +1 -1
  115. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0_gn5iz._.js +4 -0
  116. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0f765xr._.js +4 -0
  117. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__01bmjsj._.js → [root-of-the-server]__0h38gzz._.js} +1 -1
  118. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0hoaz1g._.js +4 -0
  119. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1ouobn4._.js → [root-of-the-server]__0mxmwtx._.js} +1 -1
  120. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__19evfi8._.js → [root-of-the-server]__0uescqv._.js} +1 -1
  121. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__13d-wb6._.js +1 -1
  122. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1484zv2._.js +3 -0
  123. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1mf3zp6._.js → [root-of-the-server]__19dutr7._.js} +4 -4
  124. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1u6sn69._.js → [root-of-the-server]__1ab4ifb._.js} +1 -1
  125. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1fbrk56._.js +4 -0
  126. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1pprgri._.js +2 -2
  127. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1um4yxn._.js +4 -0
  128. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1wb4yt2._.js +4 -0
  129. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1y3n3cn._.js +4 -0
  130. package/.next/standalone/.next/server/chunks/ssr/_08x1r5t._.js +1 -1
  131. package/.next/standalone/.next/server/chunks/ssr/_0bqoto4._.js +1 -1
  132. package/.next/standalone/.next/server/chunks/ssr/{_0yq5_3a._.js → _1ffxwxz._.js} +1 -1
  133. package/.next/standalone/.next/server/chunks/ssr/_1gb0ifp._.js +2 -2
  134. package/.next/standalone/.next/server/chunks/ssr/{_042cgl1._.js → _1o95rf0._.js} +2 -2
  135. package/.next/standalone/.next/server/chunks/ssr/{_1zopuov._.js → _1thr5rf._.js} +2 -2
  136. package/.next/standalone/.next/server/chunks/ssr/{_16pa9ht._.js → _1v1o2ya._.js} +2 -2
  137. package/.next/standalone/.next/server/chunks/ssr/_next-internal_server_app_policies_page_actions_1sp2-yo.js +12 -14
  138. package/.next/standalone/.next/server/chunks/ssr/app_actions_get-scheduled-audit_ts_0ei9sni._.js +1 -1
  139. package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +1 -1
  140. package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
  141. package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +1 -1
  142. package/.next/standalone/.next/server/chunks/ssr/app_settings_02tf1h4._.js +1 -1
  143. package/.next/standalone/.next/server/chunks/ssr/node_modules_1hl81y4._.js +1 -1
  144. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_0nkkbfv._.js +6 -0
  145. package/.next/standalone/.next/server/chunks/ssr/src_hooks_fp-config_ts_04t589g._.js +1 -1
  146. package/.next/standalone/.next/server/chunks/ssr/src_hooks_fp-home_ts_0je3xkv._.js +1 -1
  147. package/.next/standalone/.next/server/middleware-build-manifest.js +6 -6
  148. package/.next/standalone/.next/server/middleware.js +1 -1
  149. package/.next/standalone/.next/server/pages/404.html +1 -1
  150. package/.next/standalone/.next/server/pages/500.html +1 -1
  151. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  152. package/.next/standalone/.next/server/server-reference-manifest.json +23 -23
  153. package/.next/standalone/.next/static/chunks/08tmc_7n-rba1.js +1 -0
  154. package/.next/standalone/.next/static/chunks/{3mjfvng11xnoo.js → 09tlrmucn6oq3.js} +1 -1
  155. package/.next/standalone/.next/static/chunks/{078dofaxvjgpd.js → 0i69k917myh7b.js} +1 -1
  156. package/.next/standalone/.next/static/chunks/{03h3b-uomi7_d.js → 0u_nhsujkactp.js} +1 -1
  157. package/.next/standalone/.next/static/chunks/{2j92xul6y24_v.js → 0zp51hzx62i-u.js} +1 -1
  158. package/.next/standalone/.next/static/chunks/{3u1s8dsqiean5.js → 1fz7q0gtnmeod.js} +1 -1
  159. package/.next/standalone/.next/static/chunks/{3ob2161ap37ul.js → 1j75le8wln-26.js} +1 -1
  160. package/.next/standalone/.next/static/chunks/{2kj826h1w9r47.js → 1z4km7tw0_50h.js} +1 -1
  161. package/.next/standalone/.next/static/chunks/{1fqukzzowjflt.js → 239ay_80-xr8z.js} +1 -1
  162. package/.next/standalone/.next/static/chunks/{3nkc2jlgyygda.js → 2c9pc5xco6rnu.js} +1 -1
  163. package/.next/standalone/.next/static/chunks/{3i8rg2fv9nd6e.js → 3n46e45atic-m.js} +1 -1
  164. package/.next/standalone/.next/static/chunks/{0542cuk_va8g1.js → 3sg07wnn969xq.js} +1 -1
  165. package/.next/standalone/.next/static/chunks/{turbopack-11dn2pegmg9_9.js → turbopack-1opxka4dtjbc5.js} +1 -1
  166. package/.next/standalone/app/actions/install-hooks-web.ts +10 -2
  167. package/.next/standalone/hermes-plugin/plugin.yaml +1 -1
  168. package/.next/standalone/node_modules/@next/env/package.json +1 -1
  169. package/.next/standalone/node_modules/next/dist/build/swc/index.js +1 -1
  170. package/.next/standalone/node_modules/next/dist/compiled/hash.js/sha256/256.js +1 -0
  171. package/.next/standalone/node_modules/next/dist/compiled/hash.js/sha256/package.json +1 -0
  172. package/.next/standalone/node_modules/next/dist/compiled/next-server/app-page-turbo-experimental.runtime.prod.js +17 -17
  173. package/.next/standalone/node_modules/next/dist/compiled/next-server/app-page-turbo.runtime.prod.js +18 -18
  174. package/.next/standalone/node_modules/next/dist/compiled/next-server/app-route-turbo.runtime.prod.js +3 -3
  175. package/.next/standalone/node_modules/next/dist/compiled/next-server/pages-turbo.runtime.prod.js +13 -13
  176. package/.next/standalone/node_modules/next/dist/lib/patch-incorrect-lockfile.js +3 -3
  177. package/.next/standalone/node_modules/next/dist/server/base-server.js +1 -2
  178. package/.next/standalone/node_modules/next/dist/server/config.js +1 -1
  179. package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-turbopack.js +2 -2
  180. package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-webpack.js +1 -1
  181. package/.next/standalone/node_modules/next/dist/server/image-optimizer.js +265 -53
  182. package/.next/standalone/node_modules/next/dist/server/lib/app-info-log.js +1 -1
  183. package/.next/standalone/node_modules/next/dist/server/lib/incremental-cache/file-system-cache.js +177 -19
  184. package/.next/standalone/node_modules/next/dist/server/lib/incremental-cache/index.js +36 -17
  185. package/.next/standalone/node_modules/next/dist/server/lib/incremental-cache/shared-cache-controls.external.js +14 -6
  186. package/.next/standalone/node_modules/next/dist/server/lib/match-next-data-pathname.js +3 -1
  187. package/.next/standalone/node_modules/next/dist/server/lib/node-fs-methods.js +14 -0
  188. package/.next/standalone/node_modules/next/dist/server/lib/route-cache-key.js +77 -0
  189. package/.next/standalone/node_modules/next/dist/server/lib/router-utils/block-cross-site-dev.js +9 -11
  190. package/.next/standalone/node_modules/next/dist/server/lib/start-server.js +1 -1
  191. package/.next/standalone/node_modules/next/dist/server/mcp/get-mcp-middleware.js +4 -2
  192. package/.next/standalone/node_modules/next/dist/server/next-server.js +7 -3
  193. package/.next/standalone/node_modules/next/dist/server/response-cache/index.js +32 -16
  194. package/.next/standalone/node_modules/next/dist/server/route-matcher-providers/app-page-route-matcher-provider.js +2 -2
  195. package/.next/standalone/node_modules/next/dist/server/route-modules/pages/pages-handler.js +6 -1
  196. package/.next/standalone/node_modules/next/dist/server/route-modules/route-module.js +9 -2
  197. package/.next/standalone/node_modules/next/dist/server/use-cache/use-cache-wrapper.js +30 -29
  198. package/.next/standalone/node_modules/next/dist/shared/lib/router/utils/app-paths.js +18 -1
  199. package/.next/standalone/node_modules/next/dist/telemetry/anonymous-meta.js +1 -1
  200. package/.next/standalone/node_modules/next/dist/telemetry/events/swc-load-failure.js +1 -1
  201. package/.next/standalone/node_modules/next/dist/telemetry/events/version.js +2 -2
  202. package/.next/standalone/node_modules/next/package.json +10 -10
  203. package/.next/standalone/package.json +14 -11
  204. package/.next/standalone/sdk/python/README.md +41 -0
  205. package/.next/standalone/sdk/python/docs/README.md +1 -0
  206. package/.next/standalone/sdk/python/docs/otel/README.md +36 -0
  207. package/.next/standalone/sdk/python/docs/otel/examples/agent_trace.py +30 -0
  208. package/.next/standalone/sdk/python/docs/otel/examples/quickstart.py +22 -0
  209. package/.next/standalone/sdk/python/failproofai_sdk/__init__.py +8 -0
  210. package/.next/standalone/sdk/python/failproofai_sdk/integrations/__init__.py +3 -0
  211. package/.next/standalone/sdk/python/failproofai_sdk/integrations/otel.py +189 -0
  212. package/.next/standalone/sdk/python/pyproject.toml +2 -1
  213. package/.next/standalone/sdk/python/tests/test_docs.py +16 -3
  214. package/.next/standalone/sdk/python/tests/test_integrations.py +1 -1
  215. package/.next/standalone/sdk/python/tests/test_otel.py +147 -0
  216. package/.next/standalone/sdk/python/tests/test_zero_dependencies.py +4 -1
  217. package/.next/standalone/sdk/python/uv.lock +258 -147
  218. package/.next/standalone/sdk/typescript/README.md +43 -0
  219. package/.next/standalone/sdk/typescript/integration/ai.test.ts +9 -2
  220. package/.next/standalone/sdk/typescript/package-lock.json +57 -5
  221. package/.next/standalone/sdk/typescript/package.json +2 -0
  222. package/.next/standalone/sdk/typescript/src/edge/index.ts +9 -0
  223. package/.next/standalone/sdk/typescript/src/index.ts +2 -0
  224. package/.next/standalone/sdk/typescript/src/integrations/index.ts +4 -1
  225. package/.next/standalone/sdk/typescript/src/integrations/otel.ts +204 -0
  226. package/.next/standalone/sdk/typescript/test/integrations.test.ts +1 -1
  227. package/.next/standalone/sdk/typescript/test/otel.test.ts +125 -0
  228. package/.next/standalone/server.js +1 -1
  229. package/bin/failproofai.mjs +653 -1077
  230. package/dist/cli.mjs +8174 -3930
  231. package/dist/worker.mjs +170 -62
  232. package/hermes-plugin/plugin.yaml +1 -1
  233. package/package.json +14 -11
  234. package/scripts/launch-facts.ts +157 -0
  235. package/scripts/launch-ready.ts +228 -0
  236. package/scripts/launch-screen.ts +202 -0
  237. package/scripts/launch.ts +106 -49
  238. package/scripts/skew-log-filter.ts +42 -0
  239. package/src/audit/cli-login.ts +39 -59
  240. package/src/audit/cli.ts +308 -228
  241. package/src/audit/index.ts +45 -2
  242. package/src/audit/schedule-cli.ts +83 -120
  243. package/src/audit/types.ts +31 -0
  244. package/src/hooks/agent-selection.ts +155 -0
  245. package/src/hooks/backfill-cli.ts +151 -137
  246. package/src/hooks/backfill-request.ts +149 -0
  247. package/src/hooks/cloud-connection.ts +1 -1
  248. package/src/hooks/cloud-enrollment-cli.ts +78 -28
  249. package/src/hooks/cloud-introspect.ts +3 -0
  250. package/src/hooks/collector-config.ts +10 -1
  251. package/src/hooks/config-status.ts +606 -0
  252. package/src/hooks/configure-wizard.ts +915 -989
  253. package/src/hooks/daemon-service.ts +16 -6
  254. package/src/hooks/did-you-mean.ts +185 -0
  255. package/src/hooks/flush-cli.ts +33 -7
  256. package/src/hooks/fp-config.ts +96 -0
  257. package/src/hooks/fp-home.ts +11 -0
  258. package/src/hooks/fp-reset.ts +102 -95
  259. package/src/hooks/handler.ts +4 -0
  260. package/src/hooks/harness-cli.ts +87 -138
  261. package/src/hooks/install-prompt.ts +38 -477
  262. package/src/hooks/integrations.ts +1 -1
  263. package/src/hooks/jev-cli.ts +183 -196
  264. package/src/hooks/manager.ts +554 -358
  265. package/src/hooks/onboarding-attempt.ts +11 -9
  266. package/src/hooks/otel-cli.ts +344 -0
  267. package/src/hooks/otel-output.ts +24 -0
  268. package/src/hooks/otel-writers.ts +225 -0
  269. package/src/hooks/pack-cli.ts +219 -204
  270. package/src/hooks/report-body.ts +50 -0
  271. package/src/hooks/safe-config-write.ts +4 -2
  272. package/src/hooks/session-pause-cli.ts +93 -73
  273. package/src/hooks/tui.ts +849 -389
  274. package/src/hooks/uninstall-cli.ts +136 -149
  275. package/src/hooks/untraced-note.ts +52 -0
  276. package/.next/standalone/.next/server/chunks/[externals]__19_pzeq._.js +0 -3
  277. package/.next/standalone/.next/server/chunks/[externals]__20kzpkf._.js +0 -3
  278. package/.next/standalone/.next/server/chunks/[root-of-the-server]__01eqny5._.js +0 -3
  279. package/.next/standalone/.next/server/chunks/[root-of-the-server]__05ja_05._.js +0 -3
  280. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0igxt32._.js +0 -3
  281. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0zyc_nm._.js +0 -3
  282. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1ttrwnd._.js +0 -22
  283. package/.next/standalone/.next/server/chunks/_0bs-v8p._.js +0 -3
  284. package/.next/standalone/.next/server/chunks/_185gyk9._.js +0 -3
  285. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__056wjo4._.js +0 -4
  286. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0n0xg95._.js +0 -4
  287. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0rwtwpm._.js +0 -4
  288. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0yrsbd_._.js +0 -3
  289. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__11mayhe._.js +0 -4
  290. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__15578wp._.js +0 -4
  291. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1m_svbe._.js +0 -4
  292. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1q4p5b8._.js +0 -4
  293. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_1n3w9lb._.js +0 -6
  294. package/.next/standalone/.next/static/chunks/1lyg_puttohbc.js +0 -1
  295. /package/.next/standalone/.next/static/{ECs8__hcNabYV58WfDh-3 → UZKCiP4Q2TeU8zOB-h9Xj}/_buildManifest.js +0 -0
  296. /package/.next/standalone/.next/static/{ECs8__hcNabYV58WfDh-3 → UZKCiP4Q2TeU8zOB-h9Xj}/_clientMiddlewareManifest.js +0 -0
  297. /package/.next/standalone/.next/static/{ECs8__hcNabYV58WfDh-3 → UZKCiP4Q2TeU8zOB-h9Xj}/_ssgManifest.js +0 -0
@@ -82,6 +82,49 @@ is unreachable.
82
82
 
83
83
  ### 2. Adapters
84
84
 
85
+ #### OpenTelemetry (opt in)
86
+
87
+ If your app already emits OpenTelemetry spans, send them through FailproofAI Cloud
88
+ without replacing its framework adapters. Install OpenTelemetry separately:
89
+
90
+ ```bash
91
+ npm install @opentelemetry/api @opentelemetry/sdk-trace-base
92
+ ```
93
+
94
+ ```ts
95
+ import * as failproofai from "@failproofai/sdk";
96
+ import { BasicTracerProvider } from "@opentelemetry/sdk-trace-base";
97
+ import type { SpanProcessor } from "@opentelemetry/sdk-trace-base";
98
+
99
+ const spanProcessors: SpanProcessor[] = []; // include your existing processors
100
+ await failproofai.instrument("otel", { spanProcessors });
101
+ const provider = new BasicTracerProvider({ spanProcessors });
102
+ const tracer = provider.getTracer("my-agent");
103
+ const span = tracer.startSpan("agent", {
104
+ attributes: { "gen_ai.operation.name": "invoke_agent" },
105
+ });
106
+ span.end();
107
+ await provider.forceFlush();
108
+ ```
109
+
110
+ With no options, `instrument("otel")` creates a provider only if none is registered.
111
+ For an existing OpenTelemetry v2 provider, add the processor before constructing
112
+ the provider, as above. For providers exposing `addSpanProcessor`, pass `{ provider }`.
113
+ You can also supply `new failproofai.OtelSpanExporter()` to your own span processor.
114
+ `uninstrument("otel")` disables only FailproofAI's processor; other exporters keep working.
115
+
116
+ The exporter writes OTLP/JSON export requests durably into the local relay spool
117
+ (`$FAILPROOFAI_HOME/state/spool-otlp`, otherwise `~/.failproofai/state/spool-otlp`).
118
+ It never sends HTTP or reads the Cloud key. Connect the daemon with `failproofai config`
119
+ and ask an admin to enable Settings → OpenTelemetry. No local TCP listener is
120
+ needed for SDK exports. `spoolDir` is an explicit override for tests or managed
121
+ deployments. `configure({ baseDir })` still applies only to the existing event adapters.
122
+
123
+ OTEL is never auto-enabled by a bare `instrument()`. The SDK still declares zero
124
+ hard runtime dependencies. Your spans control content capture; do not export
125
+ sensitive attributes unless intended. Export related spans together for complete
126
+ agent traces; call `provider.forceFlush()` before a short-lived process exits.
127
+
85
128
  ```ts
86
129
  await failproofai.instrument(); // whatever it can find
87
130
  await failproofai.instrument("langchain"); // exactly one
@@ -258,8 +258,15 @@ describe.each(FIXTURES)("%s", (fixture) => {
258
258
  };
259
259
  expect(report.text).toBe("It is 20C in Paris.");
260
260
  if (major >= 7) {
261
- // v7 has no OpenTelemetry dependency; the integration records the call.
262
- expect(report.customer).toBe("absent");
261
+ // v7 has no OpenTelemetry dependency of its own. The optional OTEL
262
+ // exporter's dev tests can make it resolvable from the parent SDK
263
+ // project; when present, their provider must still own the global slot
264
+ // and receive only their service span (ai 7 emits no OTEL spans).
265
+ if (report.customer !== "absent") {
266
+ expect(report.customer, describeTrace(result)).toEqual({
267
+ registered: true, ended: ["http.request"],
268
+ });
269
+ }
263
270
  expect(shape(result.events), describeTrace(result)).toEqual(GEN);
264
271
  return;
265
272
  }
@@ -1,18 +1,20 @@
1
1
  {
2
2
  "name": "@failproofai/sdk",
3
- "version": "0.0.1-beta.0",
3
+ "version": "0.0.1-beta.1",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@failproofai/sdk",
9
- "version": "0.0.1-beta.0",
9
+ "version": "0.0.1-beta.1",
10
10
  "license": "SEE LICENSE IN LICENSE",
11
11
  "bin": {
12
12
  "failproofai-evaluator": "dist/esm/evaluator/cli.js"
13
13
  },
14
14
  "devDependencies": {
15
15
  "@eslint/js": "^9.38.0",
16
+ "@opentelemetry/api": "^1.9.0",
17
+ "@opentelemetry/sdk-trace-base": "^2.12.0",
16
18
  "@types/node": "^22.10.2",
17
19
  "eslint": "^9.38.0",
18
20
  "typescript": "^5.9.2",
@@ -281,6 +283,56 @@
281
283
  "@jridgewell/sourcemap-codec": "^1.4.14"
282
284
  }
283
285
  },
286
+ "node_modules/@opentelemetry/api": {
287
+ "version": "1.9.1",
288
+ "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.1.tgz",
289
+ "integrity": "sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==",
290
+ "dev": true,
291
+ "engines": { "node": ">=8.0.0" }
292
+ },
293
+ "node_modules/@opentelemetry/core": {
294
+ "version": "2.12.0",
295
+ "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.12.0.tgz",
296
+ "integrity": "sha512-1HsSAuvT4/my0QrXWsyXFdWjKaPeCHsismKZgEEIb8NK13LP6DrMRlsUbvD/0F9mDWK3xDom9AMv3IscxgOnOQ==",
297
+ "dev": true,
298
+ "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" },
299
+ "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" },
300
+ "engines": { "node": "^18.19.0 || >=20.6.0" }
301
+ },
302
+ "node_modules/@opentelemetry/resources": {
303
+ "version": "2.12.0",
304
+ "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.12.0.tgz",
305
+ "integrity": "sha512-+rSRoOdln6NhXTVcBdHSlZxJDNzwxadeweK2ltZO3tVtfp6aklABc06xclDk6ovRR+EiGgIcSbh/6NgjFhnb3A==",
306
+ "dev": true,
307
+ "dependencies": { "@opentelemetry/core": "2.12.0", "@opentelemetry/semantic-conventions": "^1.29.0" },
308
+ "peerDependencies": { "@opentelemetry/api": ">=1.3.0 <1.10.0" },
309
+ "engines": { "node": "^18.19.0 || >=20.6.0" }
310
+ },
311
+ "node_modules/@opentelemetry/sdk-trace": {
312
+ "version": "2.12.0",
313
+ "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace/-/sdk-trace-2.12.0.tgz",
314
+ "integrity": "sha512-ImVuRQ6faOsTi1Wna88s2avgrrf/iDgXPigIeynkUhjstMuoQUDOJXgkez2j1mlU4btjXcXBGa+q7qKFYR3GsA==",
315
+ "dev": true,
316
+ "dependencies": { "@opentelemetry/core": "2.12.0", "@opentelemetry/resources": "2.12.0", "@opentelemetry/semantic-conventions": "^1.29.0" },
317
+ "peerDependencies": { "@opentelemetry/api": ">=1.3.0 <1.10.0" },
318
+ "engines": { "node": "^18.19.0 || >=20.6.0" }
319
+ },
320
+ "node_modules/@opentelemetry/sdk-trace-base": {
321
+ "version": "2.12.0",
322
+ "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.12.0.tgz",
323
+ "integrity": "sha512-JOERgZCxRM06FEJ5kEWxlSRChah6MmXDx3KwCruqEv/iEyLkTokCSemf2y1w8oIHtfrr8EVTpzebq/31vn2Cpg==",
324
+ "dev": true,
325
+ "dependencies": { "@opentelemetry/core": "2.12.0", "@opentelemetry/resources": "2.12.0", "@opentelemetry/sdk-trace": "2.12.0", "@opentelemetry/semantic-conventions": "^1.29.0" },
326
+ "peerDependencies": { "@opentelemetry/api": ">=1.3.0 <1.10.0" },
327
+ "engines": { "node": "^18.19.0 || >=20.6.0" }
328
+ },
329
+ "node_modules/@opentelemetry/semantic-conventions": {
330
+ "version": "1.43.0",
331
+ "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.43.0.tgz",
332
+ "integrity": "sha512-eSYWTm620tTk45EKSedaUL8MFYI8hW164hIXsgIHyxu3VobUB3fFCu5t0hQby6OoWRPsG1KkKUG2M5UadiLiVg==",
333
+ "dev": true,
334
+ "engines": { "node": ">=14" }
335
+ },
284
336
  "node_modules/@oxc-project/types": {
285
337
  "version": "0.150.0",
286
338
  "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.150.0.tgz",
@@ -2250,9 +2302,9 @@
2250
2302
  "license": "ISC"
2251
2303
  },
2252
2304
  "node_modules/source-map-js": {
2253
- "version": "1.2.1",
2254
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
2255
- "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
2305
+ "version": "1.2.2",
2306
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.2.tgz",
2307
+ "integrity": "sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==",
2256
2308
  "dev": true,
2257
2309
  "license": "BSD-3-Clause",
2258
2310
  "peer": true,
@@ -389,6 +389,8 @@
389
389
  },
390
390
  "devDependencies": {
391
391
  "@eslint/js": "^9.38.0",
392
+ "@opentelemetry/api": "^1.9.0",
393
+ "@opentelemetry/sdk-trace-base": "^2.12.0",
392
394
  "@types/node": "^22.10.2",
393
395
  "eslint": "^9.38.0",
394
396
  "typescript": "^5.9.2",
@@ -42,6 +42,15 @@ import { notice } from "./notice.js";
42
42
  export { VERSION as version };
43
43
 
44
44
  export const DEFAULT_AGENT_ID = "main";
45
+ /** File export is unavailable at the Edge, like the other telemetry surfaces. */
46
+ export class OtelSpanExporter {
47
+ export(_spans: unknown[], callback: (result: { code: number }) => void): void {
48
+ notice();
49
+ callback({ code: 0 });
50
+ }
51
+ forceFlush(): Promise<void> { return Promise.resolve(); }
52
+ shutdown(): Promise<void> { return Promise.resolve(); }
53
+ }
45
54
  /** The same registered symbol as the Node build's, so comparisons still hold. */
46
55
  export const AUTO: unique symbol = Symbol.for("failproofai.AUTO") as never;
47
56
 
@@ -88,6 +88,8 @@ export {
88
88
  uninstrument,
89
89
  } from "./integrations/index.js";
90
90
  export type { FrameworkName, InstrumentOptions } from "./integrations/index.js";
91
+ export { OtelSpanExporter } from "./integrations/otel.js";
92
+ export type { OtelReadableSpan, OtelSpanExporterOptions } from "./integrations/otel.js";
91
93
 
92
94
  export interface ConfigureOptions {
93
95
  /**
@@ -52,13 +52,14 @@ import * as compat from "./compat.js";
52
52
  import type { Adapter } from "./core.js";
53
53
  import * as core from "./core.js";
54
54
 
55
- export type FrameworkName = "langchain" | "ai" | "mastra" | "llamaindex";
55
+ export type FrameworkName = "langchain" | "ai" | "mastra" | "llamaindex" | "otel";
56
56
 
57
57
  const REGISTRY: Record<FrameworkName, () => Promise<{ adapter: Adapter }>> = {
58
58
  langchain: () => import("./langchain.js"),
59
59
  ai: () => import("./ai.js"),
60
60
  mastra: () => import("./mastra.js"),
61
61
  llamaindex: () => import("./llamaindex.js"),
62
+ otel: () => import("./otel.js"),
62
63
  };
63
64
 
64
65
  /**
@@ -90,6 +91,8 @@ const DETECT: Record<FrameworkName, readonly string[]> = {
90
91
  ai: ["ai"],
91
92
  mastra: ["@mastra/core"],
92
93
  llamaindex: ["llamaindex", "@llamaindex/core"],
94
+ // Never auto-enable a second reporting path on an existing application.
95
+ otel: [],
93
96
  };
94
97
 
95
98
  const active = new Map<FrameworkName, Adapter>();
@@ -0,0 +1,204 @@
1
+ /**
2
+ * Opt-in OTLP/JSON SpanExporter. Only disk I/O: the daemon authenticates and
3
+ * delivers opaque batches. No OpenTelemetry import until instrument("otel").
4
+ */
5
+ import { randomUUID } from "node:crypto";
6
+ import { closeSync, fsyncSync, mkdirSync, openSync, renameSync, rmSync, writeSync } from "node:fs";
7
+ import { homedir } from "node:os";
8
+ import { join } from "node:path";
9
+ import { importModule, resolveFrom, tryRequire } from "../node-require.js";
10
+ import type { Adapter } from "./core.js";
11
+
12
+ type ObjectValue = Record<string, unknown>;
13
+ export interface OtelReadableSpan {
14
+ name: string;
15
+ kind: number;
16
+ spanContext(): { traceId: string; spanId: string; traceFlags?: number; traceState?: { serialize(): string } };
17
+ parentSpanId?: string;
18
+ parentSpanContext?: { spanId: string };
19
+ startTime: readonly [number, number];
20
+ endTime: readonly [number, number];
21
+ attributes: ObjectValue;
22
+ status: { code: number; message?: string };
23
+ resource?: { attributes: ObjectValue; schemaUrl?: string };
24
+ instrumentationScope?: { name: string; version?: string; schemaUrl?: string };
25
+ instrumentationLibrary?: { name: string; version?: string; schemaUrl?: string };
26
+ events?: readonly { name: string; time: readonly [number, number]; attributes?: ObjectValue; droppedAttributesCount?: number }[];
27
+ links?: readonly { context: { traceId: string; spanId: string; traceFlags?: number; traceState?: { serialize(): string } }; attributes?: ObjectValue; droppedAttributesCount?: number }[];
28
+ droppedAttributesCount?: number;
29
+ droppedEventsCount?: number;
30
+ droppedLinksCount?: number;
31
+ }
32
+ export interface OtelExportResult { code: number; error?: Error }
33
+ export interface OtelSpanExporterOptions { spoolDir?: string }
34
+ const MAX_BYTES = 8 * 1024 * 1024;
35
+ const metadata = '{"path":"/v1/traces","content_type":"application/json","encoding":null}\n';
36
+
37
+ function anyValue(value: unknown): ObjectValue {
38
+ if (typeof value === "string") return { stringValue: value };
39
+ if (typeof value === "boolean") return { boolValue: value };
40
+ if (typeof value === "bigint") return { intValue: value.toString() };
41
+ if (typeof value === "number") {
42
+ if (!Number.isFinite(value)) return { doubleValue: String(value) };
43
+ return Number.isInteger(value) ? { intValue: String(value) } : { doubleValue: value };
44
+ }
45
+ if (value instanceof Uint8Array) return { bytesValue: Buffer.from(value).toString("base64") };
46
+ if (Array.isArray(value)) return { arrayValue: { values: value.map(anyValue) } };
47
+ if (value && typeof value === "object") return { kvlistValue: { values: attributes(value as ObjectValue) } };
48
+ return {};
49
+ }
50
+ function attributes(value: ObjectValue = {}): ObjectValue[] {
51
+ return Object.entries(value).filter(([, v]) => v !== undefined && v !== null)
52
+ .map(([key, v]) => ({ key, value: anyValue(v) }));
53
+ }
54
+ function nanos(time: readonly [number, number]): string {
55
+ return (BigInt(time[0]) * 1_000_000_000n + BigInt(time[1])).toString();
56
+ }
57
+ function resourceSpan(span: OtelReadableSpan): ObjectValue {
58
+ const context = span.spanContext();
59
+ const scope = span.instrumentationScope ?? span.instrumentationLibrary;
60
+ return {
61
+ resource: { attributes: attributes(span.resource?.attributes) },
62
+ ...(span.resource?.schemaUrl ? { schemaUrl: span.resource.schemaUrl } : {}),
63
+ scopeSpans: [{
64
+ scope: { name: scope?.name ?? "", ...(scope?.version ? { version: scope.version } : {}) },
65
+ ...(scope?.schemaUrl ? { schemaUrl: scope.schemaUrl } : {}),
66
+ spans: [{
67
+ traceId: context.traceId, spanId: context.spanId,
68
+ ...(span.parentSpanContext?.spanId || span.parentSpanId ? { parentSpanId: span.parentSpanContext?.spanId ?? span.parentSpanId } : {}),
69
+ ...(context.traceState ? { traceState: context.traceState.serialize() } : {}),
70
+ flags: context.traceFlags ?? 0, name: span.name, kind: span.kind + 1,
71
+ startTimeUnixNano: nanos(span.startTime), endTimeUnixNano: nanos(span.endTime),
72
+ attributes: attributes(span.attributes), status: span.status,
73
+ droppedAttributesCount: span.droppedAttributesCount ?? 0,
74
+ droppedEventsCount: span.droppedEventsCount ?? 0, droppedLinksCount: span.droppedLinksCount ?? 0,
75
+ events: (span.events ?? []).map(event => ({
76
+ name: event.name, timeUnixNano: nanos(event.time), attributes: attributes(event.attributes),
77
+ droppedAttributesCount: event.droppedAttributesCount ?? 0,
78
+ })),
79
+ links: (span.links ?? []).map(link => ({
80
+ traceId: link.context.traceId, spanId: link.context.spanId, flags: link.context.traceFlags ?? 0,
81
+ ...(link.context.traceState ? { traceState: link.context.traceState.serialize() } : {}),
82
+ attributes: attributes(link.attributes), droppedAttributesCount: link.droppedAttributesCount ?? 0,
83
+ })),
84
+ }],
85
+ }],
86
+ };
87
+ }
88
+
89
+ /** Structural implementation of OpenTelemetry's SpanExporter; zero hard deps. */
90
+ export class OtelSpanExporter {
91
+ private stopped = false;
92
+ private readonly directory?: string;
93
+ constructor(options: OtelSpanExporterOptions = {}) { this.directory = options.spoolDir; }
94
+
95
+ export(spans: readonly OtelReadableSpan[], callback: (result: OtelExportResult) => void): void {
96
+ let result: OtelExportResult = { code: 0 };
97
+ try {
98
+ if (this.stopped) throw new Error("OTEL exporter has shut down.");
99
+ const dir = this.directory ?? join(process.env.FAILPROOFAI_HOME || join(homedir(), ".failproofai"), "state", "spool-otlp");
100
+ // Encode each span once and split batches at the relay's request limit.
101
+ const chunks: string[] = [];
102
+ let items: string[] = [];
103
+ let size = Buffer.byteLength('{"resourceSpans":[]}');
104
+ for (const span of spans) {
105
+ const encoded = JSON.stringify(resourceSpan(span));
106
+ const bytes = Buffer.byteLength(encoded);
107
+ if (bytes + 20 > MAX_BYTES) throw new Error("OTEL span exceeds the 8 MiB relay limit.");
108
+ if (size + bytes + 1 > MAX_BYTES) {
109
+ chunks.push(`{"resourceSpans":[${items.join(",")}]}`); items = []; size = 20;
110
+ }
111
+ items.push(encoded); size += bytes + 1;
112
+ }
113
+ if (items.length) chunks.push(`{"resourceSpans":[${items.join(",")}]}`);
114
+ for (const body of chunks) this.publish(dir, body);
115
+ } catch (error) {
116
+ result = { code: 1, error: error instanceof Error ? error : new Error(String(error)) };
117
+ }
118
+ callback(result);
119
+ }
120
+ private publish(dir: string, body: string): void {
121
+ mkdirSync(dir, { recursive: true, mode: 0o700 });
122
+ const name = `otlp-sdk-${randomUUID()}`;
123
+ const temp = join(dir, `.${name}.tmp`);
124
+ let fd: number | undefined;
125
+ try {
126
+ fd = openSync(temp, "wx", 0o600);
127
+ const bytes = Buffer.from(metadata + body);
128
+ let offset = 0;
129
+ while (offset < bytes.length) offset += writeSync(fd, bytes, offset, bytes.length - offset);
130
+ fsyncSync(fd); closeSync(fd); fd = undefined;
131
+ renameSync(temp, join(dir, `${name}.jsonl`));
132
+ if (process.platform !== "win32") {
133
+ const directory = openSync(dir, "r");
134
+ try { fsyncSync(directory); } finally { closeSync(directory); }
135
+ }
136
+ } finally {
137
+ if (fd !== undefined) closeSync(fd);
138
+ rmSync(temp, { force: true });
139
+ }
140
+ }
141
+ forceFlush(): Promise<void> { return Promise.resolve(); }
142
+ shutdown(): Promise<void> { this.stopped = true; return Promise.resolve(); }
143
+ }
144
+
145
+ interface Processor {
146
+ onStart(...args: unknown[]): void;
147
+ onEnd(...args: unknown[]): void;
148
+ shutdown(): Promise<void>;
149
+ forceFlush(): Promise<void>;
150
+ }
151
+ interface Provider { addSpanProcessor(processor: Processor): void }
152
+ interface TraceSdk {
153
+ BatchSpanProcessor: new (exporter: OtelSpanExporter) => Processor;
154
+ BasicTracerProvider: new (options: { spanProcessors: Processor[] }) => unknown;
155
+ }
156
+ interface TraceApi { trace: { setGlobalTracerProvider(provider: unknown): boolean } }
157
+ let installed: { enabled: boolean; processor: Processor; list?: Processor[] } | null = null;
158
+ export const adapter: Adapter = {
159
+ name: "otel",
160
+ async install(options = {}) {
161
+ const provider = options.provider as Provider | undefined;
162
+ const list = options.spanProcessors as Processor[] | undefined;
163
+ if (provider && typeof provider.addSpanProcessor !== "function") {
164
+ throw new Error('instrument("otel") needs { spanProcessors } before constructing an OTEL v2 provider, or a provider with addSpanProcessor().');
165
+ }
166
+ const path = resolveFrom("@opentelemetry/sdk-trace-base");
167
+ if (!path) throw new Error('Install @opentelemetry/sdk-trace-base to use instrument("otel").');
168
+ const module = tryRequire<TraceSdk>("@opentelemetry/sdk-trace-base") ??
169
+ await importModule(path) as TraceSdk;
170
+ const exporter = new OtelSpanExporter({ spoolDir: options.spoolDir as string | undefined });
171
+ const batch = new module.BatchSpanProcessor(exporter);
172
+ const state = { enabled: true, processor: batch, list };
173
+ // Providers have no portable remove API. A gate makes uninstall effective
174
+ // without shutting down anybody else's processors or provider.
175
+ const gate: Processor = {
176
+ onStart: (...args) => { if (state.enabled) batch.onStart(...args); },
177
+ onEnd: (...args) => { if (state.enabled) batch.onEnd(...args); },
178
+ forceFlush: () => state.enabled ? batch.forceFlush() : Promise.resolve(),
179
+ shutdown: () => batch.shutdown(),
180
+ };
181
+ installed = state;
182
+ if (Array.isArray(list)) { list.push(gate); state.processor = gate; }
183
+ else if (provider) { provider.addSpanProcessor(gate); state.processor = gate; }
184
+ else {
185
+ state.processor = gate;
186
+ const apiPath = resolveFrom("@opentelemetry/api");
187
+ if (!apiPath) throw new Error("Install @opentelemetry/api to register the OTEL provider.");
188
+ const api = tryRequire<TraceApi>("@opentelemetry/api") ?? await importModule(apiPath) as TraceApi;
189
+ if (!api.trace.setGlobalTracerProvider(new module.BasicTracerProvider({ spanProcessors: [gate] }))) {
190
+ throw new Error('An OTEL provider is already registered; use instrument("otel", { spanProcessors }) before constructing it.');
191
+ }
192
+ }
193
+ },
194
+ uninstall() {
195
+ if (!installed) return;
196
+ installed.enabled = false;
197
+ if (installed.list) {
198
+ const index = installed.list.indexOf(installed.processor);
199
+ if (index >= 0) installed.list.splice(index, 1);
200
+ }
201
+ void installed.processor.shutdown().catch(() => { /* SDK teardown never throws into the app. */ });
202
+ installed = null;
203
+ },
204
+ };
@@ -324,7 +324,7 @@ describe("RunTracker", () => {
324
324
 
325
325
  describe("the registry", () => {
326
326
  it("lists the frameworks it can instrument", () => {
327
- expect(available()).toEqual(["ai", "langchain", "llamaindex", "mastra"]);
327
+ expect(available()).toEqual(["ai", "langchain", "llamaindex", "mastra", "otel"]);
328
328
  });
329
329
 
330
330
  it("throws on an unknown name, listing the valid ones", async () => {
@@ -0,0 +1,125 @@
1
+ import { afterEach, beforeEach, describe, expect, it } from "vitest";
2
+ import { mkdtempSync, readdirSync, readFileSync, rmSync, statSync, writeFileSync } from "node:fs";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ import { BasicTracerProvider, SimpleSpanProcessor } from "@opentelemetry/sdk-trace-base";
6
+ import type { SpanProcessor, ReadableSpan } from "@opentelemetry/sdk-trace-base";
7
+ import { ROOT_CONTEXT, SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
8
+ import { OtelSpanExporter } from "../src/index.js";
9
+ import { instrument, uninstrument, activeFrameworks } from "../src/integrations/index.js";
10
+ import { setStrict } from "../src/integrations/core.js";
11
+
12
+ let home: string;
13
+ let previousHome: string | undefined;
14
+ beforeEach(() => {
15
+ home = mkdtempSync(join(tmpdir(), "fpai-otel-sdk-"));
16
+ previousHome = process.env.FAILPROOFAI_HOME;
17
+ process.env.FAILPROOFAI_HOME = home;
18
+ });
19
+ afterEach(() => {
20
+ uninstrument("otel");
21
+ setStrict(null);
22
+ if (previousHome === undefined) delete process.env.FAILPROOFAI_HOME;
23
+ else process.env.FAILPROOFAI_HOME = previousHome;
24
+ rmSync(home, { recursive: true, force: true });
25
+ });
26
+ function files() { return readdirSync(join(home, "state/spool-otlp")); }
27
+ function body(name: string) {
28
+ const text = readFileSync(join(home, "state/spool-otlp", name), "utf8");
29
+ const split = text.indexOf("\n");
30
+ expect(JSON.parse(text.slice(0, split))).toEqual({
31
+ path: "/v1/traces", content_type: "application/json", encoding: null,
32
+ });
33
+ return JSON.parse(text.slice(split + 1)) as { resourceSpans: Array<{
34
+ resource: { attributes: unknown[] };
35
+ scopeSpans: Array<{ scope: { name: string }; spans: Array<Record<string, unknown>> }>;
36
+ }> };
37
+ }
38
+
39
+ describe("OTLP/JSON SpanExporter", () => {
40
+ it("exports real ended spans, links, events, precise nanos, status and typed attributes durably without network", async () => {
41
+ const exporter = new OtelSpanExporter();
42
+ const provider = new BasicTracerProvider({ spanProcessors: [new SimpleSpanProcessor(exporter)] });
43
+ const tracer = provider.getTracer("test-scope", "1.0");
44
+ const parent = tracer.startSpan("agent", { startTime: [1780000000, 123], attributes: { "gen_ai.operation.name": "invoke_agent" } });
45
+ const child = tracer.startSpan("chat", {
46
+ startTime: [1780000000, 456], kind: SpanKind.CLIENT,
47
+ attributes: { "gen_ai.operation.name": "chat", count: 42, enabled: true, decimal: 1.5, values: ["a", "b"] },
48
+ links: [{ context: parent.spanContext(), attributes: { linked: true } }],
49
+ }, trace.setSpanContext(ROOT_CONTEXT, parent.spanContext()));
50
+ child.addEvent("prompt", { text: "hello" }, [1780000000, 789]);
51
+ child.setStatus({ code: SpanStatusCode.ERROR, message: "failed" });
52
+ child.end([1780000001, 12]); parent.end([1780000001, 13]);
53
+ await provider.forceFlush();
54
+ expect(files()).toHaveLength(2);
55
+ const spans = files().flatMap(name => body(name).resourceSpans.flatMap(r => r.scopeSpans.flatMap(s => s.spans)));
56
+ const output = spans.find(span => span.name === "chat")!;
57
+ expect(output).toMatchObject({
58
+ traceId: child.spanContext().traceId, spanId: child.spanContext().spanId,
59
+ parentSpanId: parent.spanContext().spanId, kind: 3,
60
+ startTimeUnixNano: "1780000000000000456", endTimeUnixNano: "1780000001000000012",
61
+ status: { code: 2, message: "failed" },
62
+ events: [{ name: "prompt", timeUnixNano: "1780000000000000789" }],
63
+ links: [{ traceId: parent.spanContext().traceId, spanId: parent.spanContext().spanId }],
64
+ });
65
+ expect(output.attributes).toContainEqual({ key: "count", value: { intValue: "42" } });
66
+ expect(output.attributes).toContainEqual({ key: "values", value: { arrayValue: { values: [{ stringValue: "a" }, { stringValue: "b" }] } } });
67
+ for (const name of files()) {
68
+ expect(name).toMatch(/^otlp-sdk-.*\.jsonl$/);
69
+ expect(statSync(join(home, "state/spool-otlp", name)).mode & 0o777).toBe(0o600);
70
+ }
71
+ await provider.shutdown();
72
+ });
73
+
74
+ it("reports disk and post-shutdown failures through the callback, once", async () => {
75
+ const file = join(home, "not-a-directory");
76
+ writeFileSync(file, "x");
77
+ const exporter = new OtelSpanExporter({ spoolDir: file });
78
+ const provider = new BasicTracerProvider();
79
+ const span = provider.getTracer("test").startSpan("test");
80
+ span.end();
81
+ const results: number[] = [];
82
+ exporter.export([span as unknown as ReadableSpan], result => results.push(result.code));
83
+ await exporter.shutdown();
84
+ exporter.export([], result => results.push(result.code));
85
+ expect(results).toEqual([1, 1]);
86
+ await provider.shutdown();
87
+ });
88
+
89
+ it("splits an export above 8 MiB into complete bounded requests", async () => {
90
+ const provider = new BasicTracerProvider({ spanLimits: { attributeValueLengthLimit: 10_000_000 } });
91
+ const span = provider.getTracer("test").startSpan("big", { attributes: { content: "x".repeat(4 * 1024 * 1024) } });
92
+ span.end();
93
+ const results: number[] = [];
94
+ new OtelSpanExporter().export([span as unknown as ReadableSpan, span as unknown as ReadableSpan], result => results.push(result.code));
95
+ expect(results).toEqual([0]);
96
+ expect(files()).toHaveLength(2);
97
+ for (const name of files()) expect(body(name).resourceSpans).toHaveLength(1);
98
+ await provider.shutdown();
99
+ });
100
+
101
+ it("instrument('otel') adds one gated processor and leaves other exporters unchanged", async () => {
102
+ setStrict(true);
103
+ const processors: SpanProcessor[] = [];
104
+ expect(await instrument("otel", { spanProcessors: processors })).toEqual(["otel"]);
105
+ expect(await instrument("otel", { spanProcessors: processors })).toEqual([]);
106
+ const observed: string[] = [];
107
+ const existing: SpanProcessor = {
108
+ onStart() {}, onEnd(span) { observed.push(span.name); },
109
+ forceFlush: () => Promise.resolve(), shutdown: () => Promise.resolve(),
110
+ };
111
+ const provider = new BasicTracerProvider({ spanProcessors: [existing, ...processors] });
112
+ const tracer = provider.getTracer("app");
113
+ tracer.startSpan("before").end();
114
+ await provider.forceFlush();
115
+ expect(files()).toHaveLength(1);
116
+ expect(activeFrameworks()).toContain("otel");
117
+ expect(uninstrument("otel")).toEqual(["otel"]);
118
+ tracer.startSpan("after").end();
119
+ await provider.forceFlush();
120
+ expect(files()).toHaveLength(1);
121
+ expect(observed).toEqual(["before", "after"]);
122
+ expect(processors).toHaveLength(0);
123
+ await provider.shutdown();
124
+ });
125
+ });
@@ -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.10"},"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.11-beta.1"},"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