failproofai 1.0.0-beta.2 → 1.0.0-beta.21

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 (381) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/app-path-routes-manifest.json +2 -1
  3. package/.next/standalone/.next/build-manifest.json +6 -6
  4. package/.next/standalone/.next/prerender-manifest.json +3 -3
  5. package/.next/standalone/.next/required-server-files.json +1 -1
  6. package/.next/standalone/.next/routes-manifest.json +6 -0
  7. package/.next/standalone/.next/server/app/_global-error/page/build-manifest.json +3 -3
  8. package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
  9. package/.next/standalone/.next/server/app/_global-error/page.js +3 -1
  10. package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  11. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  12. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  13. package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
  14. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +2 -2
  15. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
  16. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +3 -3
  17. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +3 -3
  18. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  19. package/.next/standalone/.next/server/app/_not-found/page/build-manifest.json +3 -3
  20. package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  21. package/.next/standalone/.next/server/app/_not-found/page.js +3 -1
  22. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  23. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  24. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  25. package/.next/standalone/.next/server/app/_not-found.rsc +15 -15
  26. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +15 -15
  27. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
  28. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +10 -10
  29. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  30. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
  31. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  32. package/.next/standalone/.next/server/app/api/audit/invite/route.js +3 -2
  33. package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -1
  34. package/.next/standalone/.next/server/app/api/audit/run/route.js +4 -3
  35. package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
  36. package/.next/standalone/.next/server/app/api/audit/status/route.js +1 -1
  37. package/.next/standalone/.next/server/app/api/audit/status/route.js.nft.json +1 -1
  38. package/.next/standalone/.next/server/app/api/auth/login-request/route.js +3 -1
  39. package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
  40. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js +3 -2
  41. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
  42. package/.next/standalone/.next/server/app/api/auth/logout/route.js +3 -2
  43. package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
  44. package/.next/standalone/.next/server/app/api/auth/reminder/route.js +3 -2
  45. package/.next/standalone/.next/server/app/api/auth/reminder/route.js.nft.json +1 -1
  46. package/.next/standalone/.next/server/app/api/auth/status/route.js +3 -2
  47. package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
  48. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js +1 -1
  49. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
  50. package/.next/standalone/.next/server/app/audit/page/build-manifest.json +3 -3
  51. package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
  52. package/.next/standalone/.next/server/app/audit/page.js +5 -3
  53. package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
  54. package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
  55. package/.next/standalone/.next/server/app/index.html +1 -1
  56. package/.next/standalone/.next/server/app/index.rsc +15 -15
  57. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  58. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
  59. package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +4 -4
  60. package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +10 -10
  61. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  62. package/.next/standalone/.next/server/app/page/build-manifest.json +3 -3
  63. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
  64. package/.next/standalone/.next/server/app/page.js +3 -1
  65. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  66. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  67. package/.next/standalone/.next/server/app/policies/page/build-manifest.json +3 -3
  68. package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +30 -18
  69. package/.next/standalone/.next/server/app/policies/page.js +5 -3
  70. package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
  71. package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
  72. package/.next/standalone/.next/server/app/project/[name]/page/build-manifest.json +3 -3
  73. package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
  74. package/.next/standalone/.next/server/app/project/[name]/page.js +4 -2
  75. package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
  76. package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
  77. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/build-manifest.json +3 -3
  78. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
  79. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
  80. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js +6 -4
  81. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
  82. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
  83. package/.next/standalone/.next/server/app/projects/page/build-manifest.json +3 -3
  84. package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
  85. package/.next/standalone/.next/server/app/projects/page.js +4 -2
  86. package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
  87. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  88. package/.next/standalone/.next/server/app/settings/page/app-paths-manifest.json +3 -0
  89. package/.next/standalone/.next/server/app/settings/page/build-manifest.json +18 -0
  90. package/.next/standalone/.next/server/app/settings/page/next-font-manifest.json +6 -0
  91. package/.next/standalone/.next/server/app/settings/page/react-loadable-manifest.json +1 -0
  92. package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +53 -0
  93. package/.next/standalone/.next/server/app/settings/page.js +18 -0
  94. package/.next/standalone/.next/server/app/settings/page.js.map +5 -0
  95. package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -0
  96. package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +3 -0
  97. package/.next/standalone/.next/server/app-paths-manifest.json +2 -1
  98. package/.next/standalone/.next/server/chunks/[externals]__0h9_83k._.js +3 -0
  99. package/.next/standalone/.next/server/chunks/{[externals]__1nl3dvw._.js → [externals]__0r-zamh._.js} +2 -2
  100. package/.next/standalone/.next/server/chunks/[externals]__1ifpkx-._.js +3 -0
  101. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0l4vuqm._.js → [root-of-the-server]__00ni9za._.js} +2 -2
  102. package/.next/standalone/.next/server/chunks/[root-of-the-server]__06hexd0._.js +3 -0
  103. package/.next/standalone/.next/server/chunks/[root-of-the-server]__08y94xv._.js +3 -0
  104. package/.next/standalone/.next/server/chunks/[root-of-the-server]__094p1f1._.js +3 -0
  105. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0_0xu5z._.js +1 -1
  106. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ed01_d._.js +3 -0
  107. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0-dh5jy._.js → [root-of-the-server]__0effm9m._.js} +2 -2
  108. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0g0vcwt._.js +3 -0
  109. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__18d-9oi._.js → [root-of-the-server]__0ix8gm7._.js} +2 -2
  110. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0h3lfmp._.js → [root-of-the-server]__0ji11a-._.js} +2 -2
  111. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__10oa-v9._.js → [root-of-the-server]__0ojwjxl._.js} +2 -2
  112. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__16le-kd._.js → [root-of-the-server]__0pbp9fe._.js} +2 -2
  113. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0q-v9z2._.js +1 -1
  114. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0vb5fl2._.js +3 -0
  115. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0sb_5m8._.js → [root-of-the-server]__131ebum._.js} +4 -4
  116. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1ibjy5x._.js +3 -0
  117. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1tvn4wf._.js +1 -1
  118. package/.next/standalone/.next/server/chunks/[root-of-the-server]__20d06rh._.js +3 -0
  119. package/.next/standalone/.next/server/chunks/_0lxbzdq._.js +3 -0
  120. package/.next/standalone/.next/server/chunks/_1zuiiy3._.js +3 -0
  121. package/.next/standalone/.next/server/chunks/lib_telemetry_ts_0dctyyw._.js +3 -0
  122. package/.next/standalone/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_17k9e3w.js +5 -5
  123. package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_01r25oi._.js +2 -1
  124. package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_09z9-p7._.js +2 -1
  125. package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
  126. package/.next/standalone/.next/server/chunks/ssr/[externals]__1aq139v._.js +3 -0
  127. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0-wfhrp._.js +3 -0
  128. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__06bp_fg._.js +5 -0
  129. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__074qmkp._.js +3 -0
  130. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1apb7k_._.js → [root-of-the-server]__0_1tiya._.js} +2 -2
  131. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__170799-._.js → [root-of-the-server]__0spkm68._.js} +11 -11
  132. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0t281d4._.js +3 -0
  133. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__17itmx-._.js +5 -0
  134. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__01od0m6._.js → [root-of-the-server]__1n2vcv4._.js} +2 -2
  135. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1qapotl._.js +1 -1
  136. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1rv-sc9._.js +3 -0
  137. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1tlvv9a._.js +3 -0
  138. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1u-wx42._.js +4 -0
  139. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1v185mo._.js +3 -0
  140. package/.next/standalone/.next/server/chunks/ssr/_0-yi74u._.js +3 -0
  141. package/.next/standalone/.next/server/chunks/ssr/_0rjgfln._.js +3 -0
  142. package/.next/standalone/.next/server/chunks/ssr/_0vo2qyt._.js +3 -0
  143. package/.next/standalone/.next/server/chunks/ssr/_0xej-0e._.js +3 -0
  144. package/.next/standalone/.next/server/chunks/ssr/_10399ge._.js +3 -0
  145. package/.next/standalone/.next/server/chunks/ssr/_11_p9y8._.js +1 -1
  146. package/.next/standalone/.next/server/chunks/ssr/_149k9oy._.js +3 -0
  147. package/.next/standalone/.next/server/chunks/ssr/_1_hwp06._.js +3 -0
  148. package/.next/standalone/.next/server/chunks/ssr/_1ctse6u._.js +3 -0
  149. package/.next/standalone/.next/server/chunks/ssr/_1e19atl._.js +1 -1
  150. package/.next/standalone/.next/server/chunks/ssr/_1mnhi_r._.js +3 -0
  151. package/.next/standalone/.next/server/chunks/ssr/_1ror7k9._.js +3 -0
  152. package/.next/standalone/.next/server/chunks/ssr/_1sdgprl._.js +5 -0
  153. package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +2 -2
  154. package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
  155. package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +2 -2
  156. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0dwo94s.js +4 -0
  157. package/.next/standalone/.next/server/chunks/ssr/node_modules_posthog-node_dist_entrypoints_index_node_mjs_11bnuzn._.js +2 -1
  158. package/.next/standalone/.next/server/chunks/ssr/src_hooks_builtin-policies_ts_09j2ndl._.js +3 -0
  159. package/.next/standalone/.next/server/chunks/ssr/src_hooks_fp-config_ts_04t589g._.js +4 -0
  160. package/.next/standalone/.next/server/middleware-build-manifest.js +6 -6
  161. package/.next/standalone/.next/server/middleware.js +2 -2
  162. package/.next/standalone/.next/server/pages/404.html +1 -1
  163. package/.next/standalone/.next/server/pages/500.html +1 -1
  164. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  165. package/.next/standalone/.next/server/server-reference-manifest.json +74 -20
  166. package/.next/standalone/.next/static/chunks/{03fmihek9n986.js → 06zgzyh3wv1ig.js} +1 -1
  167. package/.next/standalone/.next/static/chunks/0km-jn9o5xyqs.css +2 -0
  168. package/.next/standalone/.next/static/chunks/{1hdhteui932bq.js → 0qmo2t50kpb30.js} +1 -1
  169. package/.next/standalone/.next/static/chunks/{2sbelanzvxvv0.js → 113g8wtal6_c4.js} +22 -22
  170. package/.next/standalone/.next/static/chunks/16p68cybetr31.js +1 -0
  171. package/.next/standalone/.next/static/chunks/18wqn0_3mzylf.js +1 -0
  172. package/.next/standalone/.next/static/chunks/1v1gqvpjk62jm.js +1 -0
  173. package/.next/standalone/.next/static/chunks/{0fi645si-uiiq.js → 1xq1m8h14tnlj.js} +1 -1
  174. package/.next/standalone/.next/static/chunks/{3hp8ulqknybil.js → 1y3vwogqb88dx.js} +1 -1
  175. package/.next/standalone/.next/static/chunks/{3vs4ay36tjds_.js → 1zmh-b0ulrqu7.js} +1 -1
  176. package/.next/standalone/.next/static/chunks/23kev26by1e4f.js +1 -0
  177. package/.next/standalone/.next/static/chunks/299lhw60e8gr6.js +1 -0
  178. package/.next/standalone/.next/static/chunks/{18rvdw5v72364.js → 2adbpdaxp5ygq.js} +1 -1
  179. package/.next/standalone/.next/static/chunks/{2j94uwkb4s3qr.js → 2kbqcw-6swmav.js} +1 -1
  180. package/.next/standalone/.next/static/chunks/2n9n5m0963pdg.js +6 -0
  181. package/.next/standalone/.next/static/chunks/2uvhw57mf9lg_.css +2 -0
  182. package/.next/standalone/.next/static/chunks/{31feojxhjyjpl.js → 30nrrpwymht5m.js} +1 -1
  183. package/.next/standalone/.next/static/chunks/31coz11ia5vc4.js +1 -0
  184. package/.next/standalone/.next/static/chunks/{turbopack-1lsv92x7klwrn.js → turbopack-3diub4ctvn1n0.js} +1 -1
  185. package/.next/standalone/SECURITY.md +8 -2
  186. package/.next/standalone/app/actions/get-active-pauses.ts +16 -0
  187. package/.next/standalone/app/actions/get-hooks-config.ts +2 -2
  188. package/.next/standalone/app/actions/get-scheduled-audit.ts +70 -0
  189. package/.next/standalone/app/actions/update-scheduled-audit.ts +44 -0
  190. package/.next/standalone/app/api/audit/run/route.ts +28 -0
  191. package/.next/standalone/app/api/audit/status/route.ts +13 -1
  192. package/.next/standalone/app/api/auth/status/route.ts +1 -1
  193. package/.next/standalone/app/audit/_components/audit-dashboard.tsx +1 -3
  194. package/.next/standalone/app/audit/_components/audit-progress-strip.tsx +1 -1
  195. package/.next/standalone/app/audit/_components/auth-dialog.css +159 -0
  196. package/.next/standalone/app/audit/_components/auth-dialog.tsx +3 -0
  197. package/.next/standalone/app/audit/_components/come-back-better-section.tsx +1 -1
  198. package/.next/standalone/app/audit/_components/empty-state.tsx +0 -1
  199. package/.next/standalone/app/audit/_components/how-to-improve-section.tsx +1 -1
  200. package/.next/standalone/app/audit/_components/quirks-section.tsx +0 -1
  201. package/.next/standalone/app/audit/_components/report-footer.tsx +0 -2
  202. package/.next/standalone/app/audit/_components/run-progress.tsx +1 -1
  203. package/.next/standalone/app/audit/_components/strengths-section.tsx +0 -1
  204. package/.next/standalone/app/audit/audit-styles.css +6 -149
  205. package/.next/standalone/app/components/pause-notices.tsx +111 -0
  206. package/.next/standalone/app/components/raw-log-viewer.tsx +1 -1
  207. package/.next/standalone/app/components/toast.tsx +1 -1
  208. package/.next/standalone/app/policies/hooks-client.tsx +84 -8
  209. package/.next/standalone/app/settings/page.tsx +31 -0
  210. package/.next/standalone/app/settings/settings-client.tsx +487 -0
  211. package/.next/standalone/components/navbar.tsx +2 -0
  212. package/.next/standalone/lib/auth/api-server-client.ts +2 -3
  213. package/.next/standalone/lib/auth/auth-store.ts +4 -5
  214. package/.next/standalone/lib/codex-sessions.ts +2 -1
  215. package/.next/standalone/lib/dashboard-host.ts +101 -0
  216. package/.next/standalone/lib/install-check.ts +22 -7
  217. package/.next/standalone/lib/pi-sessions.ts +99 -14
  218. package/.next/standalone/lib/telemetry-enabled.ts +54 -0
  219. package/.next/standalone/lib/telemetry-id.ts +52 -1
  220. package/.next/standalone/lib/telemetry.ts +8 -4
  221. package/.next/standalone/node_modules/react/cjs/react.development.js +1 -1
  222. package/.next/standalone/node_modules/react/cjs/react.production.js +1 -1
  223. package/.next/standalone/node_modules/react/package.json +3 -3
  224. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server-legacy.browser.production.js +1 -1
  225. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server-legacy.node.production.js +1 -1
  226. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server.browser.production.js +3 -3
  227. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server.edge.production.js +3 -3
  228. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server.node.production.js +3 -3
  229. package/.next/standalone/node_modules/react-dom/cjs/react-dom.production.js +1 -1
  230. package/.next/standalone/node_modules/react-dom/package.json +4 -4
  231. package/.next/standalone/package.json +23 -12
  232. package/.next/standalone/proxy.ts +111 -1
  233. package/.next/standalone/server.js +1 -1
  234. package/bin/failproofai-worker.mjs +1 -1
  235. package/bin/failproofai.mjs +1041 -81
  236. package/bin/failproofaid-shim.mjs +4 -4
  237. package/dist/cli.mjs +18513 -10474
  238. package/dist/worker.mjs +1223 -299
  239. package/lib/auth/api-server-client.ts +2 -3
  240. package/lib/auth/auth-store.ts +4 -5
  241. package/lib/codex-sessions.ts +2 -1
  242. package/lib/dashboard-host.ts +101 -0
  243. package/lib/install-check.ts +22 -7
  244. package/lib/pi-sessions.ts +99 -14
  245. package/lib/telemetry-enabled.ts +54 -0
  246. package/lib/telemetry-id.ts +52 -1
  247. package/lib/telemetry.ts +8 -4
  248. package/package.json +23 -12
  249. package/scripts/build-daemon-packages.mjs +247 -0
  250. package/scripts/daemon-platforms.mjs +42 -0
  251. package/scripts/dev-hook.mjs +46 -5
  252. package/scripts/install-telemetry.mjs +8 -1
  253. package/scripts/launch.ts +25 -3
  254. package/scripts/parse-script-args.ts +27 -1
  255. package/scripts/prune-standalone.mjs +26 -0
  256. package/scripts/publish-aliases.mjs +62 -41
  257. package/scripts/repro-npm-install.sh +155 -0
  258. package/scripts/translate-docs/cache.ts +1 -1
  259. package/scripts/translate-docs/cli.ts +2 -2
  260. package/scripts/translate-docs/mintlify-nav.ts +1 -1
  261. package/scripts/translate-docs/readme-translator.ts +163 -4
  262. package/scripts/validate-mdx.ts +153 -13
  263. package/src/audit/audit-lock.ts +285 -0
  264. package/src/audit/audit-schedule.ts +111 -0
  265. package/src/audit/cache.ts +18 -5
  266. package/src/audit/cli-adapters/goose.ts +2 -1
  267. package/src/audit/cli-adapters/hermes.ts +28 -10
  268. package/src/audit/cli.ts +191 -35
  269. package/src/audit/dashboard-cache.ts +2 -3
  270. package/src/audit/report.ts +0 -1
  271. package/src/hooks/backfill-cli.ts +247 -0
  272. package/src/hooks/builtin-policies.ts +391 -3
  273. package/src/hooks/cloud-connection.ts +354 -0
  274. package/src/hooks/cloud-enrollment-cli.ts +439 -0
  275. package/src/hooks/cloud-enrollment.ts +284 -0
  276. package/src/hooks/cloud-introspect.ts +147 -0
  277. package/src/hooks/cloud-managed-policies.ts +206 -0
  278. package/src/hooks/collector-config.ts +218 -0
  279. package/src/hooks/configure-wizard.ts +1211 -233
  280. package/src/hooks/custom-hooks-loader.ts +243 -37
  281. package/src/hooks/daemon-client.ts +136 -33
  282. package/src/hooks/daemon-download.ts +264 -31
  283. package/src/hooks/daemon-service.ts +1124 -76
  284. package/src/hooks/first-run-gate.ts +50 -0
  285. package/src/hooks/flush-cli.ts +180 -0
  286. package/src/hooks/fp-config.ts +835 -0
  287. package/src/hooks/fp-home.ts +714 -0
  288. package/src/hooks/fp-reset.ts +1363 -0
  289. package/src/hooks/handler.ts +185 -6
  290. package/src/hooks/harness-cli.ts +386 -0
  291. package/src/hooks/hook-activity-store.ts +171 -24
  292. package/src/hooks/hook-logger.ts +2 -2
  293. package/src/hooks/hook-telemetry.ts +5 -1
  294. package/src/hooks/hooks-config.ts +4 -3
  295. package/src/hooks/integrations.ts +0 -1
  296. package/src/hooks/loader-utils.ts +172 -9
  297. package/src/hooks/manager.ts +41 -5
  298. package/src/hooks/migrations.ts +450 -0
  299. package/src/hooks/onboarding-attempt.ts +195 -0
  300. package/src/hooks/onboarding-lock.ts +118 -0
  301. package/src/hooks/policy-types.ts +28 -0
  302. package/src/hooks/session-pause-cli.ts +159 -0
  303. package/src/hooks/session-pause.ts +267 -0
  304. package/src/hooks/setup-state.ts +256 -0
  305. package/src/hooks/tui.ts +209 -9
  306. package/src/hooks/uninstall-cli.ts +418 -0
  307. package/src/hooks/worker-server.ts +134 -15
  308. package/.next/standalone/.next/server/chunks/[externals]__14odj07._.js +0 -3
  309. package/.next/standalone/.next/server/chunks/[externals]__1s61mel._.js +0 -3
  310. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0id_xf7._.js +0 -3
  311. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0longh-._.js +0 -3
  312. package/.next/standalone/.next/server/chunks/[root-of-the-server]__17g9wh7._.js +0 -3
  313. package/.next/standalone/.next/server/chunks/[root-of-the-server]__19120tr._.js +0 -3
  314. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1fwl2mz._.js +0 -3
  315. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1myjm-d._.js +0 -3
  316. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1rhmvod._.js +0 -3
  317. package/.next/standalone/.next/server/chunks/ssr/[externals]__1_g_b3t._.js +0 -3
  318. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0114ewg._.js +0 -4
  319. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__02r5bgf._.js +0 -4
  320. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0e8sjqm._.js +0 -4
  321. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0lkzqax._.js +0 -4
  322. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0nb0syg._.js +0 -3
  323. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qucxyj._.js +0 -4
  324. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0u02miy._.js +0 -4
  325. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0uno39i._.js +0 -3
  326. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__14dd6h8._.js +0 -3
  327. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1ath6v_._.js +0 -4
  328. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1psjybo._.js +0 -3
  329. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1zqz4v8._.js +0 -4
  330. package/.next/standalone/.next/server/chunks/ssr/_1m_p7pi._.js +0 -3
  331. package/.next/standalone/.next/server/chunks/ssr/node_modules_html-to-image_es_index_0oy_-36.js +0 -3
  332. package/.next/standalone/.next/server/chunks/ssr/src_hooks_1ezd2jf._.js +0 -5
  333. package/.next/standalone/.next/server/chunks/ssr/src_hooks_1tnuifj._.js +0 -5
  334. package/.next/standalone/.next/static/chunks/0h7auy7hzjyhw.js +0 -1
  335. package/.next/standalone/.next/static/chunks/0zbxssxh53n-3.js +0 -1
  336. package/.next/standalone/.next/static/chunks/2mazwb1qmur1p.js +0 -1
  337. package/.next/standalone/.next/static/chunks/2pujpnfx4pws6.css +0 -2
  338. package/.next/standalone/.next/static/chunks/33u59vf_8xpd-.js +0 -1
  339. package/.next/standalone/.next/static/chunks/3i27c3hcriawq.css +0 -1
  340. package/.next/standalone/.next/static/chunks/3s7myk_co0gbh.js +0 -1
  341. package/.next/standalone/.next/static/chunks/40k1_v4os4cw6.js +0 -6
  342. package/.next/standalone/Cargo.lock +0 -428
  343. package/.next/standalone/Cargo.toml +0 -9
  344. package/.next/standalone/crates/PROTOCOL.md +0 -122
  345. package/.next/standalone/crates/failproofaid/Cargo.toml +0 -18
  346. package/.next/standalone/crates/failproofaid/src/lock.rs +0 -81
  347. package/.next/standalone/crates/failproofaid/src/main.rs +0 -83
  348. package/.next/standalone/crates/failproofaid/src/paths.rs +0 -172
  349. package/.next/standalone/crates/failproofaid/src/server.rs +0 -502
  350. package/.next/standalone/crates/failproofaid/src/worker.rs +0 -400
  351. package/.next/standalone/crates/failproofaid/tests/daemon_e2e.rs +0 -241
  352. package/.next/standalone/crates/fpai-ipc/Cargo.toml +0 -16
  353. package/.next/standalone/crates/fpai-ipc/src/envelope.rs +0 -175
  354. package/.next/standalone/crates/fpai-ipc/src/framing.rs +0 -177
  355. package/.next/standalone/crates/fpai-ipc/src/lib.rs +0 -10
  356. package/.next/standalone/crates/fpai-ipc/src/peer.rs +0 -80
  357. package/.next/standalone/docker-hook-sync/Dockerfile +0 -79
  358. package/.next/standalone/docker-hook-sync/entrypoint.sh +0 -109
  359. package/.next/standalone/integration-suite/Dockerfile +0 -47
  360. package/.next/standalone/integration-suite/README.md +0 -129
  361. package/.next/standalone/integration-suite/canary-policies.mjs +0 -45
  362. package/.next/standalone/integration-suite/capture-tokens.sh +0 -48
  363. package/.next/standalone/integration-suite/ci-entrypoint.sh +0 -179
  364. package/.next/standalone/integration-suite/inject-tokens.sh +0 -44
  365. package/.next/standalone/integration-suite/install-clis.sh +0 -136
  366. package/.next/standalone/integration-suite/probe-cli.sh +0 -248
  367. package/.next/standalone/integration-suite/report.js +0 -120
  368. package/.next/standalone/integration-suite/run.sh +0 -159
  369. package/.next/standalone/openclaw-plugin/index.js +0 -223
  370. package/.next/standalone/openclaw-plugin/openclaw.plugin.json +0 -6
  371. package/.next/standalone/openclaw-plugin/package.json +0 -12
  372. package/.next/standalone/osv-scanner.toml +0 -17
  373. package/.next/standalone/pi-extension/index.ts +0 -524
  374. package/.next/standalone/pi-extension/package.json +0 -12
  375. package/.next/standalone/postcss.config.mjs +0 -8
  376. package/.next/standalone/readme-arch-hq.gif +0 -0
  377. package/.next/standalone/rust-toolchain.toml +0 -4
  378. package/src/auth/cli.ts +0 -371
  379. /package/.next/standalone/.next/static/{NWAjs0tHFyzk97gRGG09r → VjEdIL6W5uBsvEzknXqV9}/_buildManifest.js +0 -0
  380. /package/.next/standalone/.next/static/{NWAjs0tHFyzk97gRGG09r → VjEdIL6W5uBsvEzknXqV9}/_clientMiddlewareManifest.js +0 -0
  381. /package/.next/standalone/.next/static/{NWAjs0tHFyzk97gRGG09r → VjEdIL6W5uBsvEzknXqV9}/_ssgManifest.js +0 -0
@@ -0,0 +1,247 @@
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 { createHash } from "node:crypto";
30
+ import { chmodSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
31
+ import { tmpdir } from "node:os";
32
+ import { dirname, join, resolve } from "node:path";
33
+ import { fileURLToPath, pathToFileURL } from "node:url";
34
+ import { gunzipSync } from "node:zlib";
35
+ import {
36
+ DAEMON_PLATFORMS,
37
+ daemonAssetName,
38
+ daemonOptionalDependencies,
39
+ daemonPackageName,
40
+ } from "./daemon-platforms.mjs";
41
+
42
+ const REPO_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..");
43
+
44
+ /**
45
+ * Where the generated packages are staged — **outside the repo**, and that is
46
+ * load-bearing rather than tidy.
47
+ *
48
+ * `npm publish` re-runs `prepare`, so the Next build happens again *after*
49
+ * this script has run, and Next's file tracing pulls the whole project root
50
+ * into `.next/standalone` (see the "over-traced project artifacts" prune list
51
+ * in scripts/prune-standalone.mjs). Anything staged inside the checkout
52
+ * therefore ends up inside the published CLI tarball — measured: a dry run
53
+ * shipped 16 MB of daemon `.gz` assets under
54
+ * `.next/standalone/release-assets/`. Staging in the temp dir cannot be swept
55
+ * up by a build. `--staging` overrides it for tests.
56
+ */
57
+ export const STAGING_DIR = resolve(tmpdir(), "failproofaid-packages");
58
+
59
+ /**
60
+ * The manifest for one platform package.
61
+ *
62
+ * Deliberately carries no `bin` (it would shadow the root package's own
63
+ * `failproofaid` shim, which is what a user invoking the daemon by hand
64
+ * should reach) and no `exports` (so `require.resolve("<pkg>/package.json")`
65
+ * — how the CLI finds this package — keeps working).
66
+ */
67
+ export function platformPackageManifest(platform, version, rootPkg = {}) {
68
+ return {
69
+ name: daemonPackageName(platform.key),
70
+ version,
71
+ description: `The failproofaid background daemon binary for ${platform.os} ${platform.cpu}. Installed automatically as an optional dependency of failproofai.`,
72
+ // npm's own platform filters: with both set, only the matching package is
73
+ // installed and the other three are skipped without a warning.
74
+ os: [platform.os],
75
+ cpu: [platform.cpu],
76
+ files: ["bin/"],
77
+ publishConfig: { access: "public" },
78
+ repository: rootPkg.repository,
79
+ homepage: rootPkg.homepage,
80
+ bugs: rootPkg.bugs,
81
+ license: rootPkg.license,
82
+ };
83
+ }
84
+
85
+ /**
86
+ * Stages one platform package on disk and returns its directory.
87
+ *
88
+ * The binary is written decompressed and mode 0755: npm records the executable
89
+ * bit in the tarball, so it survives publish → install, which is how esbuild
90
+ * and swc ship their binaries.
91
+ */
92
+ export function stagePlatformPackage(platform, version, rootPkg, artifactsDir, stagingRoot = STAGING_DIR) {
93
+ const asset = resolve(artifactsDir, daemonAssetName(platform.key));
94
+ if (!existsSync(asset)) {
95
+ throw new Error(`missing artifact ${asset} — the daemon build did not produce ${daemonAssetName(platform.key)}`);
96
+ }
97
+
98
+ const dir = join(stagingRoot, `failproofaid-${platform.key}`);
99
+ rmSync(dir, { recursive: true, force: true });
100
+ mkdirSync(join(dir, "bin"), { recursive: true });
101
+
102
+ const binary = gunzipSync(readFileSync(asset));
103
+ const binaryPath = join(dir, "bin", "failproofaid");
104
+ writeFileSync(binaryPath, binary);
105
+ chmodSync(binaryPath, 0o755);
106
+
107
+ writeFileSync(
108
+ join(dir, "package.json"),
109
+ JSON.stringify(platformPackageManifest(platform, version, rootPkg), null, 2) + "\n",
110
+ );
111
+ writeFileSync(
112
+ join(dir, "README.md"),
113
+ `# ${daemonPackageName(platform.key)}\n\n` +
114
+ `The \`failproofaid\` background daemon binary for ${platform.os} ${platform.cpu}.\n\n` +
115
+ `Installed automatically as an optional dependency of [failproofai](https://www.npmjs.com/package/failproofai) — ` +
116
+ `you do not need to install it yourself.\n`,
117
+ );
118
+
119
+ return dir;
120
+ }
121
+
122
+ /**
123
+ * The SHA-256 of the binary inside a staged platform package.
124
+ *
125
+ * Read back off disk rather than returned from `stagePlatformPackage` so that
126
+ * function's contract stays a plain directory path, and so the digest describes
127
+ * the bytes that will actually be packed — not an in-memory buffer that was
128
+ * supposed to become them.
129
+ */
130
+ export function stagedBinaryDigest(dir) {
131
+ return createHash("sha256")
132
+ .update(readFileSync(join(dir, "bin", "failproofaid")))
133
+ .digest("hex");
134
+ }
135
+
136
+ /**
137
+ * Writes the four platform packages into the root manifest's
138
+ * `optionalDependencies`, pinned to `version`.
139
+ *
140
+ * Called at publish time rather than committed: a pin to a version that does
141
+ * not exist yet breaks `bun install --frozen-lockfile` in this repo's own CI,
142
+ * and keeping four pins in step with every version bump by hand is the drift
143
+ * this whole file exists to avoid.
144
+ *
145
+ * @param {string} version
146
+ * @param {string} [packageJsonPath]
147
+ * @param {Record<string, string> | null} [digests] platform key → SHA-256 of
148
+ * that platform's staged binary. Omitted leaves the key ABSENT, which
149
+ * `expectedNpmBinaryDigest` reads as "nothing to compare against".
150
+ */
151
+ export function pinRootManifest(version, packageJsonPath = resolve(REPO_ROOT, "package.json"), digests = null) {
152
+ const pkg = JSON.parse(readFileSync(packageJsonPath, "utf8"));
153
+ pkg.optionalDependencies = { ...pkg.optionalDependencies, ...daemonOptionalDependencies(version) };
154
+ // The SHA-256 of each binary as it was staged, recorded in the ROOT manifest
155
+ // so `installFromNpmPackage` has something to check the file it copies
156
+ // against. The download channel has verified against `SHA256SUMS` since it
157
+ // existed; the npm channel had no integrity step of any kind, and it installs
158
+ // its result as a root-owned, boot-persistent system service.
159
+ //
160
+ // Written here rather than into each platform package because a digest
161
+ // shipped alongside the bytes it describes verifies nothing. This one travels
162
+ // in a different package, published separately, and `bun build` INLINES it
163
+ // into dist/cli.mjs — so it is not merely a second file in the same tree.
164
+ if (digests) pkg.failproofaidBinaries = digests;
165
+ writeFileSync(packageJsonPath, JSON.stringify(pkg, null, 2) + "\n");
166
+ return pkg.optionalDependencies;
167
+ }
168
+
169
+ function parseArgs(argv) {
170
+ const valueOf = (flag, fallback) => {
171
+ const index = argv.indexOf(flag);
172
+ return index !== -1 && argv[index + 1] ? argv[index + 1] : fallback;
173
+ };
174
+ return {
175
+ artifacts: valueOf("--artifacts", "release-assets"),
176
+ staging: valueOf("--staging", STAGING_DIR),
177
+ distTag: valueOf("--dist-tag", null),
178
+ version: valueOf("--version", null),
179
+ pinRoot: argv.includes("--pin-root"),
180
+ dryRun: argv.includes("--dry-run"),
181
+ };
182
+ }
183
+
184
+ /**
185
+ * `npm publish`, with provenance when the registry will take it.
186
+ *
187
+ * Provenance needs a supported CI and a repository field npm can match to the
188
+ * building workflow; when it refuses, the publish itself is still correct, so
189
+ * this retries once without the flag rather than failing the release.
190
+ */
191
+ function publishPackage(dir, distTag, dryRun) {
192
+ const args = ["publish", "--tag", distTag];
193
+ if (dryRun) args.push("--dry-run");
194
+
195
+ const attempt = (extra) =>
196
+ execFileSync("npm", [...args, ...extra], { cwd: dir, stdio: "pipe", encoding: "utf8" });
197
+
198
+ const withProvenance = !dryRun && process.env.GITHUB_ACTIONS === "true";
199
+ try {
200
+ return attempt(withProvenance ? ["--provenance"] : []);
201
+ } catch (err) {
202
+ const output = (err.stdout ?? "") + (err.stderr ?? "");
203
+ if (output.includes("cannot publish over")) return "[skip] already published at this version";
204
+ if (withProvenance && /provenance/i.test(output)) {
205
+ console.log("::warning::provenance was rejected — retrying the publish without it");
206
+ return attempt([]);
207
+ }
208
+ // Fatal on purpose: see the header. The root package pins these names, so
209
+ // a half-published set must stop the release rather than ship 404s.
210
+ throw new Error(`npm publish failed for ${dir}:\n${output.trim()}`);
211
+ }
212
+ }
213
+
214
+ export function main(argv = process.argv.slice(2)) {
215
+ const options = parseArgs(argv);
216
+ const rootPkg = JSON.parse(readFileSync(resolve(REPO_ROOT, "package.json"), "utf8"));
217
+ const version = options.version ?? rootPkg.version;
218
+ const distTag = options.distTag ?? (version.includes("-") ? "beta" : "latest");
219
+ const artifactsDir = resolve(process.cwd(), options.artifacts);
220
+
221
+ console.log(
222
+ `Publishing ${DAEMON_PLATFORMS.length} failproofaid platform packages at ${version} ` +
223
+ `(tag: ${distTag}${options.dryRun ? ", dry run" : ""}) from ${artifactsDir}`,
224
+ );
225
+
226
+ const digests = {};
227
+ for (const platform of DAEMON_PLATFORMS) {
228
+ const dir = stagePlatformPackage(platform, version, rootPkg, artifactsDir, options.staging);
229
+ const sha256 = stagedBinaryDigest(dir);
230
+ digests[platform.key] = sha256;
231
+ const name = daemonPackageName(platform.key);
232
+ console.log(`\n${name}@${version} sha256:${sha256}`);
233
+ console.log(publishPackage(dir, distTag, options.dryRun).trim());
234
+ }
235
+
236
+ if (options.pinRoot) {
237
+ const pins = pinRootManifest(version, resolve(REPO_ROOT, "package.json"), digests);
238
+ console.log("\nPinned in the root manifest's optionalDependencies:");
239
+ console.log(JSON.stringify(pins, null, 2));
240
+ console.log("\nRecorded binary digests (failproofaidBinaries):");
241
+ console.log(JSON.stringify(digests, null, 2));
242
+ }
243
+ }
244
+
245
+ if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
246
+ main();
247
+ }
@@ -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
+ }
@@ -5,7 +5,7 @@
5
5
  * End users never run this. They install `npx -y failproofai --hook <Event>`
6
6
  * (see `src/hooks/integrations.ts`), which resolves the published package.
7
7
  * This file exists because this repo dogfoods itself from source, and doing so
8
- * has two prerequisites that silently rot:
8
+ * has three prerequisites that silently rot:
9
9
  *
10
10
  * 1. `bun` on the hook's PATH. `bin/failproofai.mjs` cannot run under node —
11
11
  * it does a bare `import { version } from "../package.json"` (node needs
@@ -17,13 +17,17 @@
17
17
  * When that happens every hook exits 127 and the session runs with ZERO
18
18
  * policy enforcement — silently.
19
19
  *
20
- * 2. `dist/index.js`. The committed policies in `.failproofai/policies/`
20
+ * 2. Project dependencies. A fresh checkout has no `node_modules`, so the
21
+ * source binary cannot import its runtime dependencies. The launcher
22
+ * runs the lockfile-pinned install once before attempting enforcement.
23
+ *
24
+ * 3. `dist/index.js`. The committed policies in `.failproofai/policies/`
21
25
  * `import from 'failproofai'`, which `findDistIndex()` resolves to that
22
26
  * bundle. Without it all three fail-open and only builtins enforce.
23
27
  *
24
- * So: locate bun (installing it via npm if we must), make sure the bundle
25
- * exists, then hand off to the real binary. If we cannot enforce, say so in
26
- * one line rather than failing silently.
28
+ * So: locate bun (installing it via npm if we must), install this checkout's
29
+ * dependencies, make sure the bundle exists, then hand off to the real binary.
30
+ * If we cannot enforce, say so in one line rather than failing silently.
27
31
  *
28
32
  * INVARIANT — never write to stdout. Most CLIs' deny contracts are JSON on
29
33
  * stdout (Copilot `{decision:"block"}`, Cursor `{followup_message}`, Devin,
@@ -43,6 +47,11 @@ const SRC_BIN = resolve(REPO_ROOT, "bin", "failproofai.mjs");
43
47
  const BUNDLE = resolve(REPO_ROOT, "dist", "index.js");
44
48
  const CACHE_DIR = resolve(REPO_ROOT, "node_modules", ".cache", "failproofai-dev");
45
49
  const LOCK_DIR = join(CACHE_DIR, ".lock");
50
+ const DEPENDENCY_SENTINELS = [
51
+ resolve(REPO_ROOT, "node_modules", "posthog-node", "package.json"),
52
+ resolve(REPO_ROOT, "node_modules", "sql.js", "package.json"),
53
+ resolve(REPO_ROOT, "node_modules", "yaml", "package.json"),
54
+ ];
46
55
 
47
56
  /** A lock older than this belonged to a process that died mid-install. */
48
57
  const LOCK_STALE_MS = 5 * 60_000;
@@ -58,6 +67,7 @@ const LOCK_WAIT_MS = 250;
58
67
  * @property {string} [home]
59
68
  * @property {(p: string) => boolean} [exists]
60
69
  * @property {(p: string) => string[]} [readdir]
70
+ * @property {typeof spawnSync} [spawn]
61
71
  */
62
72
 
63
73
  function warn(msg) {
@@ -167,6 +177,16 @@ export function bunMissingMessage() {
167
177
  );
168
178
  }
169
179
 
180
+ /**
181
+ * A cheap every-hook check for the runtime dependencies the source hook path
182
+ * imports. Requiring several direct dependencies also catches interrupted or
183
+ * partial installs instead of treating any non-empty node_modules as ready.
184
+ */
185
+ export function projectDependenciesInstalled(deps = {}) {
186
+ const exists = deps.exists ?? existsSync;
187
+ return DEPENDENCY_SENTINELS.every((path) => exists(path));
188
+ }
189
+
170
190
  /**
171
191
  * Run `doWork` at most once across concurrently-firing hooks. `mkdirSync` is
172
192
  * atomic, so it doubles as the lock: EEXIST means another process got there.
@@ -233,6 +253,26 @@ function installBun(deps = {}) {
233
253
  return findBun(deps);
234
254
  }
235
255
 
256
+ /** Install a fresh/partial checkout from the committed lockfile, once. */
257
+ export function ensureProjectDependencies(bunPath, deps = {}) {
258
+ const run = deps.spawn ?? spawnSync;
259
+ return ensureOnce(
260
+ () => projectDependenciesInstalled(deps),
261
+ () => {
262
+ warn("project dependencies missing — running bun install (one time)");
263
+ const r = run(bunPath, ["install", "--frozen-lockfile"], {
264
+ // Installation/build output is not hook protocol output. Keep stdout
265
+ // clean, but expose errors so a broken bootstrap is actionable.
266
+ stdio: ["ignore", "ignore", "inherit"],
267
+ cwd: REPO_ROOT,
268
+ });
269
+ if (r.status !== 0) {
270
+ warn("bun install failed — hooks are NOT enforcing; see the error above");
271
+ }
272
+ },
273
+ );
274
+ }
275
+
236
276
  /**
237
277
  * Build dist/index.js if absent, so `.failproofai/policies/*.mjs` can resolve
238
278
  * `import ... from 'failproofai'`. Non-fatal: builtins enforce without it.
@@ -258,6 +298,7 @@ function main() {
258
298
  warn(bunMissingMessage());
259
299
  process.exit(1);
260
300
  }
301
+ if (!ensureProjectDependencies(bun)) process.exit(1);
261
302
  ensureBundle(bun);
262
303
 
263
304
  // stdio:"inherit" hands the child our actual fds: the payload on stdin and
@@ -86,12 +86,19 @@ function getInstanceId() {
86
86
  * fire from the CLI (see lib/install-check.ts) because package managers block
87
87
  * install scripts by default.
88
88
  *
89
+ * `opts.enabled` carries the resolved answer from lib/telemetry-enabled.ts. This
90
+ * file is a dependency-free .mjs so that it can run with no node_modules, which
91
+ * also means it cannot import the TOML config — so the caller, which can, passes
92
+ * the verdict in. Without it `[telemetry] enabled = false` would silence three
93
+ * dispatchers out of four and this one would keep reporting.
94
+ *
89
95
  * @param {string} event
90
96
  * @param {Record<string, unknown>} [properties]
91
- * @param {{ version?: string, timeoutMs?: number }} [opts]
97
+ * @param {{ version?: string, timeoutMs?: number, enabled?: boolean }} [opts]
92
98
  */
93
99
  export async function trackInstallEvent(event, properties = {}, opts = {}) {
94
100
  if (process.env.FAILPROOFAI_TELEMETRY_DISABLED === "1") return;
101
+ if (opts.enabled === false) return;
95
102
 
96
103
  const version = opts.version ?? process.env.npm_package_version ?? "unknown";
97
104
  const body = JSON.stringify({
package/scripts/launch.ts CHANGED
@@ -10,22 +10,40 @@ import { parseScriptArgs } from "./parse-script-args";
10
10
  import { diagnoseShadow } from "./install-diagnosis.mjs";
11
11
  import { makeSkewLogFilter } from "./skew-log-filter";
12
12
  import { renderLaunchBanner } from "../src/hooks/tui";
13
+ import { isLoopbackHostname, resolveDashboardHost } from "../lib/dashboard-host";
13
14
  import { version } from "../package.json";
14
15
 
15
16
  export function launch(mode: "dev" | "start"): void {
16
- const { loggingLevel, disableTelemetry, allowedDevOrigins, remainingArgs } = parseScriptArgs(process.argv.slice(2));
17
+ const { loggingLevel, disableTelemetry, allowedDevOrigins, host, remainingArgs } = parseScriptArgs(process.argv.slice(2));
17
18
 
18
19
  // Branded splash — the same logomark + palette as the `configure` wizard, then
19
20
  // a tidy version/links column. Falls back to plain text off a TTY.
20
21
  for (const line of renderLaunchBanner(version)) console.log(line);
21
22
 
23
+ // The dashboard has no authentication and can toggle policies and uninstall
24
+ // hooks from every agent CLI, so it binds loopback unless someone asks
25
+ // otherwise. It used to bind 0.0.0.0 unconditionally, which handed all of
26
+ // that to every peer on the network.
27
+ const bindHost = resolveDashboardHost(host, process.env.FAILPROOFAI_DASHBOARD_HOST);
28
+ if (!isLoopbackHostname(bindHost)) {
29
+ console.warn(
30
+ `\n! Binding the dashboard to ${bindHost}, which is reachable from outside this machine.\n` +
31
+ ` It has no authentication: anyone who can reach it can read your session\n` +
32
+ ` transcripts, disable your policies, and uninstall failproofai's hooks.\n`,
33
+ );
34
+ }
35
+ // Read back by proxy.ts, which refuses any request whose Host is not one it
36
+ // should be answering to — the layer that stops DNS rebinding, which a
37
+ // loopback bind alone does not.
38
+ process.env.FAILPROOFAI_DASHBOARD_HOST = bindHost;
39
+
22
40
  let cmd: string;
23
41
  let cmdArgs: string[];
24
42
  if (mode === "start") {
25
43
  const portIdx = remainingArgs.indexOf("--port");
26
44
  const port = portIdx >= 0 ? remainingArgs[portIdx + 1] : "8020";
27
45
  process.env.PORT = port;
28
- process.env.HOSTNAME = "0.0.0.0";
46
+ process.env.HOSTNAME = bindHost;
29
47
  cmd = "node";
30
48
  // Resolve the real package root via realpathSync so symlinked npm global binaries
31
49
  // don't cause import.meta.url to point at the symlink dir instead of the package dir.
@@ -74,7 +92,11 @@ export function launch(mode: "dev" | "start"): void {
74
92
  cmdArgs = [serverJsPath];
75
93
  } else {
76
94
  cmd = "bunx";
77
- cmdArgs = ["--bun", "next", "dev", ...remainingArgs];
95
+ // `next dev` with no -H listens on every interface too, so dev gets the same
96
+ // default. Skipped when the caller already passed one through, so an
97
+ // explicit -H in remainingArgs still wins.
98
+ const hasHostFlag = remainingArgs.some((a) => a === "-H" || a === "--hostname" || a.startsWith("--hostname="));
99
+ cmdArgs = ["--bun", "next", "dev", ...(hasHostFlag ? [] : ["-H", bindHost]), ...remainingArgs];
78
100
  }
79
101
 
80
102
  // In `start` (the shipped standalone server) we pipe + filter the child's
@@ -7,6 +7,13 @@ export interface ParsedScriptArgs {
7
7
  loggingLevel: string | undefined;
8
8
  disableTelemetry: boolean;
9
9
  allowedDevOrigins: string[] | undefined;
10
+ /**
11
+ * Interface to bind the dashboard to. Undefined means the safe default
12
+ * (loopback) — see `resolveDashboardHost` in launch.ts. Only set this to a
13
+ * non-loopback address deliberately: the dashboard has no authentication and
14
+ * is a WRITE surface for this machine's security configuration.
15
+ */
16
+ host: string | undefined;
10
17
  remainingArgs: string[];
11
18
  }
12
19
 
@@ -32,6 +39,7 @@ export function parseScriptArgs(argv: string[]): ParsedScriptArgs {
32
39
  let loggingLevel: string | undefined;
33
40
  let disableTelemetry = false;
34
41
  let allowedDevOrigins: string[] | undefined;
42
+ let host: string | undefined;
35
43
 
36
44
  for (let i = 0; i < args.length; i++) {
37
45
  const arg = args[i];
@@ -71,7 +79,25 @@ export function parseScriptArgs(argv: string[]): ParsedScriptArgs {
71
79
  i--;
72
80
  continue;
73
81
  }
82
+
83
+ // `-H` / `--hostname` are Next's own spellings of this, and `bun run dev`
84
+ // passes unrecognised arguments straight through to `next dev`. Capturing
85
+ // only `--host` meant a raw `-H 0.0.0.0` fell into `remainingArgs`: Next
86
+ // bound the wildcard, while `bindHost` kept the loopback default and
87
+ // `FAILPROOFAI_DASHBOARD_HOST=127.0.0.1` told `proxy.ts` it was on
88
+ // loopback. It then enforced a Host-header pin — which a raw network
89
+ // client forges trivially, unlike a browser — against a server genuinely
90
+ // reachable from the network, and skipped the no-Origin refusal that is
91
+ // the real defence for that bind. The two must agree, so all three
92
+ // spellings resolve to the same value.
93
+ if (flag === "--host" || flag === "-H" || flag === "--hostname") {
94
+ const { value, spliceCount } = parseStringFlag(flag, "an address to bind (e.g. 127.0.0.1)", inlineValue, args, i);
95
+ host = value;
96
+ args.splice(i, spliceCount);
97
+ i--;
98
+ continue;
99
+ }
74
100
  }
75
101
 
76
- return { loggingLevel, disableTelemetry, allowedDevOrigins, remainingArgs: args };
102
+ return { loggingLevel, disableTelemetry, allowedDevOrigins, host, remainingArgs: args };
77
103
  }
@@ -101,6 +101,24 @@ 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",
110
+ // The Rust workspace. `target/` is the big one: on any machine that has run
111
+ // `cargo build`, NFT traces it into the standalone output and it is FIFTEEN
112
+ // GIGABYTES of compiled artifacts — `npm pack` then hangs trying to tar it,
113
+ // which is how this was found. CI has not hit it because the Rust jobs build
114
+ // in a separate workspace, so nothing caught it; a contributor who builds the
115
+ // daemon and then the package hits it every time. The dashboard is a Next
116
+ // server — it never reads any of this.
117
+ "target", "crates",
118
+ // Test/dev trees NFT also over-traces. `integration-suite` is a harness, the
119
+ // plugin/extension dirs are shipped from the package root by `files`, not
120
+ // from inside the standalone bundle.
121
+ "integration-suite", "pi-extension", "openclaw-plugin", "docker-hook-sync",
104
122
  ];
105
123
  const STANDALONE_ROOT_PRUNE_FILES = [
106
124
  // Top-level markdown / licenses / docs
@@ -111,6 +129,14 @@ const STANDALONE_ROOT_PRUNE_FILES = [
111
129
  "vitest.config.mts", "vitest.config.e2e.mts",
112
130
  // Lockfiles
113
131
  "bun.lock", "bun.lockb", "package-lock.json", "yarn.lock",
132
+ // Rust workspace manifests, siblings of the `target`/`crates` prune above.
133
+ "Cargo.toml", "Cargo.lock", "rust-toolchain.toml", "osv-scanner.toml",
134
+ // 11 MB README animation. Traced because it sits in the repo root and is
135
+ // referenced from README.md; the running dashboard never serves it.
136
+ "readme-arch-hq.gif",
137
+ // Incremental typechecker state — regenerated on every build, read by nothing
138
+ // at runtime, and routinely a few hundred KB.
139
+ "tsconfig.tsbuildinfo", "next-env.d.ts", "postcss.config.mjs",
114
140
  ];
115
141
  for (const d of STANDALONE_ROOT_PRUNE) {
116
142
  rmSync(join(STANDALONE, d), { recursive: true, force: true });