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
@@ -1,20 +1,31 @@
1
1
  /**
2
- * Fetches the compiled `failproofaid` binary for this platform from the
3
- * GitHub Release that matches this CLI's own version.
4
- *
5
- * Why a download rather than a dependency: the daemon is a 4-way
6
- * cross-compiled Rust binary, and shipping it through npm means four
7
- * per-platform packages that every install resolves, an npm org to own the
8
- * scope, and a second publish channel that can silently drift from the first
9
- * (it already did the platform packages were declared as
10
- * `optionalDependencies` and never published, so every install of them 404'd).
11
- * The release assets have to exist for standalone installs regardless, so
12
- * pointing the CLI at the same artifacts leaves exactly one channel.
13
- *
14
- * The URL is *constructed*, never discoveredno API call, no `releases/latest`
15
- * redirect, no rate limit, and no chance of fetching a daemon built from
16
- * different source than the CLI talking to it: the tag is this package's own
17
- * version, so a CLI upgrade downloads its own matching binary.
2
+ * Gets the compiled `failproofaid` binary for this platform onto disk, from
3
+ * whichever of its two channels can supply it.
4
+ *
5
+ * **npm first.** The four binaries publish as
6
+ * `@failproofai/failproofaid-<os>-<arch>` platform packages, pinned as
7
+ * `optionalDependencies` of this package, so `npm install failproofai` has
8
+ * usually already brought down the one matching this machine `os`/`cpu`
9
+ * make npm skip the other three. Copying that file costs no network at all,
10
+ * which is the only thing that works behind a proxy or air-gapped.
11
+ *
12
+ * **The GitHub Release second.** `failproofaid-<os>-<arch>.gz` plus a
13
+ * `SHA256SUMS` manifest are attached to the release tagged with this CLI's own
14
+ * version. That channel has to exist regardless it is how anyone installs
15
+ * the daemon standalone, and how an install that skipped optional dependencies
16
+ * still gets one.
17
+ *
18
+ * The pair failed once before in a way worth keeping in mind: the platform
19
+ * packages were declared as `optionalDependencies` and never published, so
20
+ * every install resolved four 404s (see CHANGELOG 1.0.0-beta.3). What makes
21
+ * them safe now is that `scripts/build-daemon-packages.mjs` publishes them
22
+ * *before* the root package that pins them, and fails the release if it
23
+ * cannot — the names always exist by the time anything depends on them.
24
+ *
25
+ * The download URL is *constructed*, never discovered — no API call, no
26
+ * `releases/latest` redirect, no rate limit, and no chance of fetching a daemon
27
+ * built from different source than the CLI talking to it: the tag is this
28
+ * package's own version, so a CLI upgrade fetches its own matching binary.
18
29
  *
19
30
  * Everything here fails closed and never throws. A daemon that cannot be
20
31
  * fetched leaves the machine on the in-process path it was already using;
@@ -22,12 +33,31 @@
22
33
  * this writes an executable that a service manager will then run at login.
23
34
  */
24
35
  import { createHash } from "node:crypto";
25
- import { chmodSync, existsSync, mkdirSync, renameSync, rmSync, writeFileSync } from "node:fs";
26
- import { homedir } from "node:os";
27
- import { resolve } from "node:path";
36
+ import {
37
+ chmodSync,
38
+ existsSync,
39
+ mkdirSync,
40
+ readdirSync,
41
+ readFileSync,
42
+ renameSync,
43
+ rmSync,
44
+ statSync,
45
+ writeFileSync,
46
+ } from "node:fs";
47
+ import { createRequire } from "node:module";
48
+ import { dirname, resolve } from "node:path";
28
49
  import { gunzipSync } from "node:zlib";
29
50
  import { version } from "../../package.json";
51
+ // A DEFAULT import, never a named one. `failproofaidBinaries` is written into
52
+ // the manifest at publish time (see `pinRootManifest`), so it is absent from
53
+ // every dev build and every unpublished commit — and a named import of a
54
+ // missing export throws at MODULE LOAD, before any code can guard it. On this
55
+ // module that is not a broken feature: `handler.ts` pulls it in on the hook
56
+ // path, so the throw denies every tool call on the machine. Learned the hard
57
+ // way; the runtime lookup below is the only safe shape.
58
+ import rootManifest from "../../package.json";
30
59
  import type { PlatformKey } from "./daemon-service";
60
+ import { binDir as layoutBinDir } from "./fp-home";
31
61
 
32
62
  /**
33
63
  * Where release assets live. Overridable so an air-gapped or proxied site can
@@ -50,7 +80,7 @@ function baseUrl(): string {
50
80
 
51
81
  /** Where downloaded binaries live. One directory, one file per version. */
52
82
  export function daemonBinaryDir(): string {
53
- return resolve(homedir(), ".failproofai", "bin");
83
+ return layoutBinDir();
54
84
  }
55
85
 
56
86
  /**
@@ -82,6 +112,219 @@ export interface DaemonDownloadResult {
82
112
  error?: string;
83
113
  }
84
114
 
115
+ /** The npm package carrying the daemon binary for one platform. */
116
+ export function platformPackageName(key: PlatformKey): string {
117
+ return `@failproofai/failproofaid-${key}`;
118
+ }
119
+
120
+ /**
121
+ * Locates the binary inside the installed platform package, or null.
122
+ *
123
+ * Resolution is anchored at `FAILPROOFAI_PACKAGE_ROOT` (set by
124
+ * `bin/failproofai.mjs` and the bundled `dist/cli.mjs`) rather than at
125
+ * `import.meta.url`, which does not survive the CJS bundle. Node's algorithm
126
+ * walks up from there, which covers both real layouts: a global install nests
127
+ * its dependencies at `<root>/node_modules/@failproofai/…`, a local one hoists
128
+ * them to `<project>/node_modules/@failproofai/…`.
129
+ *
130
+ * The specifier is *computed*, deliberately. A literal would make the bundler
131
+ * try to resolve a package that is optional, platform-specific, and absent on
132
+ * three machines out of four at build time.
133
+ */
134
+ export function npmPlatformBinaryPath(key: PlatformKey): string | null {
135
+ const packageRoot = process.env.FAILPROOFAI_PACKAGE_ROOT;
136
+ if (!packageRoot) return null;
137
+ const name = platformPackageName(key);
138
+
139
+ try {
140
+ const requireFromRoot = createRequire(resolve(packageRoot, "package.json"));
141
+ const found = platformPackageBinary(dirname(requireFromRoot.resolve(`${name}/package.json`)));
142
+ if (found) return found;
143
+ } catch {
144
+ // Not installed (the common case on a machine that skipped optional
145
+ // dependencies), or a resolver that cannot see it. The direct check below
146
+ // is the fallback, not a failure.
147
+ }
148
+
149
+ return platformPackageBinary(resolve(packageRoot, "node_modules", name));
150
+ }
151
+
152
+ /**
153
+ * The binary inside one candidate platform-package directory, if it is the
154
+ * right one.
155
+ *
156
+ * The version check is not belt-and-braces. npm pins the exact version, but a
157
+ * workspace holding two `failproofai` versions can hoist the other one's
158
+ * platform package to the top of the tree — and installing that binary under
159
+ * *this* version's filename would put a daemon built from different source
160
+ * behind a CLI that believes it matches, which is the single thing the
161
+ * versioned install path exists to prevent. A mismatch falls through to the
162
+ * download, whose URL is pinned to this version.
163
+ */
164
+ function platformPackageBinary(dir: string): string | null {
165
+ try {
166
+ const manifest = JSON.parse(readFileSync(resolve(dir, "package.json"), "utf8")) as {
167
+ version?: string;
168
+ };
169
+ if (manifest.version !== version) return null;
170
+ } catch {
171
+ return null;
172
+ }
173
+ const candidate = resolve(dir, "bin", "failproofaid");
174
+ return existsSync(candidate) ? candidate : null;
175
+ }
176
+
177
+ /**
178
+ * Writes the daemon binary to its versioned path.
179
+ *
180
+ * Shared by both channels so a binary lands identically however it arrived:
181
+ * staged in the same directory as the target (so the install is an atomic
182
+ * rename within one filesystem, never a half-written executable a service
183
+ * manager could pick up), mode 0755, pid-suffixed so two concurrent wizards
184
+ * stay off each other's file.
185
+ */
186
+ /**
187
+ * Delete daemon binaries older than the current and previous versions.
188
+ *
189
+ * Called AFTER the new binary is in place and the unit repointed, never
190
+ * before: a binary a running service points at must not be removed out from
191
+ * under it. One previous version is kept deliberately — a rollback is then a
192
+ * local file rather than a re-download, which is the difference between
193
+ * working and not on a machine that is offline or behind a proxy.
194
+ *
195
+ * Sorted by mtime rather than by parsing versions out of filenames: a
196
+ * prerelease ordering (`1.0.0-beta.10` vs `1.0.0-beta.9`) is easy to get
197
+ * subtly wrong, and "which did we install most recently" is the question that
198
+ * actually matters here.
199
+ */
200
+ export function pruneOldDaemonBinaries(keep = 2): string[] {
201
+ const removed: string[] = [];
202
+ try {
203
+ const dir = daemonBinaryDir();
204
+ const entries = readdirSync(dir)
205
+ .filter((f) => f.startsWith("failproofaid-") && !f.endsWith(".tmp"))
206
+ .map((f) => {
207
+ const full = resolve(dir, f);
208
+ return { full, mtime: statSync(full).mtimeMs };
209
+ })
210
+ .sort((a, b) => b.mtime - a.mtime);
211
+
212
+ for (const stale of entries.slice(keep)) {
213
+ try {
214
+ rmSync(stale.full, { force: true });
215
+ removed.push(stale.full);
216
+ } catch {
217
+ // In use, or not ours to delete. Leaving it costs disk; removing it by
218
+ // force could break a running service.
219
+ }
220
+ }
221
+ } catch {
222
+ // No directory yet, or unreadable — nothing to prune.
223
+ }
224
+ return removed;
225
+ }
226
+
227
+ function installBinaryBytes(binary: Buffer): string {
228
+ const target = installedBinaryPath();
229
+ const tempPath = `${target}.${process.pid}.tmp`;
230
+ try {
231
+ mkdirSync(daemonBinaryDir(), { recursive: true });
232
+ writeFileSync(tempPath, binary);
233
+ chmodSync(tempPath, 0o755);
234
+ renameSync(tempPath, target);
235
+ return target;
236
+ } catch (err) {
237
+ rmSync(tempPath, { force: true });
238
+ throw err;
239
+ }
240
+ }
241
+
242
+ /**
243
+ * The SHA-256 the publish recorded for each platform's binary, or null when
244
+ * this build has none.
245
+ *
246
+ * `scripts/build-daemon-packages.mjs` writes these into the ROOT manifest at
247
+ * publish time — the same step that pins the four `optionalDependencies` — so
248
+ * they are absent from a local dev build and from any tree built off an
249
+ * unpublished commit. Absent means "nothing to compare against", never "the
250
+ * comparison passed".
251
+ */
252
+ export function expectedNpmBinaryDigest(key: PlatformKey): string | null {
253
+ const map = (rootManifest as Record<string, unknown>).failproofaidBinaries as
254
+ | Record<string, string>
255
+ | undefined;
256
+ const digest = map?.[key];
257
+ return typeof digest === "string" && /^[0-9a-f]{64}$/.test(digest) ? digest : null;
258
+ }
259
+
260
+ /**
261
+ * Installs the daemon from the npm platform package, if one is present.
262
+ *
263
+ * Verified against the digest the publish recorded, when this build carries
264
+ * one. It used to do no integrity check at all on the grounds that "npm
265
+ * verified the tarball when it installed it" — true, and about a different
266
+ * moment. npm checks the tarball at EXTRACTION; this reads a loose file out of
267
+ * a shared, writable `node_modules` some time later, and installs the result as
268
+ * a root-owned, boot-persistent system service. Anything that touched the file
269
+ * in between — another package's postinstall, a partial write, a half-upgraded
270
+ * tree — went in unexamined, while the sibling download channel had verified
271
+ * against `SHA256SUMS` since it existed.
272
+ *
273
+ * What this is worth, stated plainly: the digest travels in a DIFFERENT package
274
+ * from the bytes it describes, and `bun build` inlines it into `dist/cli.mjs`,
275
+ * so it is not simply a second file the same writer could edit. It is still not
276
+ * proof against an attacker already executing code in this tree — such an
277
+ * attacker can write `~/.failproofai/bin` directly and skip all of this. It
278
+ * closes accidental corruption and the non-adaptive overwrite, and it makes the
279
+ * two install channels make the same promise.
280
+ *
281
+ * Deliberately NOT gated on `FAILPROOFAI_NO_DOWNLOAD` — that variable exists
282
+ * so an air-gapped machine does not reach out, and this is a local copy. On
283
+ * exactly those machines it is the only channel that can work.
284
+ */
285
+ export function installFromNpmPackage(key: PlatformKey): DaemonDownloadResult {
286
+ const source = npmPlatformBinaryPath(key);
287
+ if (!source) return { error: `${platformPackageName(key)} is not installed` };
288
+ try {
289
+ const bytes = readFileSync(source);
290
+ const mismatch = binaryDigestMismatch(expectedNpmBinaryDigest(key), bytes, source);
291
+ // An error, never a silent fall-through to installing it anyway. The
292
+ // caller's next channel is the release download, which is pinned to this
293
+ // version and verifies its own digest — so a machine whose package is
294
+ // tampered or corrupt still has a correct route to a good binary.
295
+ if (mismatch) return { error: mismatch };
296
+ return { path: installBinaryBytes(bytes) };
297
+ } catch (err) {
298
+ const message = err instanceof Error ? err.message : String(err);
299
+ return { error: `failed to install failproofaid from ${source}: ${message}` };
300
+ }
301
+ }
302
+
303
+ /**
304
+ * Why `bytes` may not be installed, or null if it may.
305
+ *
306
+ * Split out from `installFromNpmPackage` so the comparison is testable without
307
+ * mocking `package.json` — the digest map is inlined at build time, so a test
308
+ * cannot otherwise reach the branch that matters.
309
+ *
310
+ * A null `expected` is "this build recorded no digest", which is every dev
311
+ * build and every unpublished commit, and means there is nothing to compare
312
+ * against — never that the comparison passed.
313
+ */
314
+ export function binaryDigestMismatch(
315
+ expected: string | null,
316
+ bytes: Buffer,
317
+ source: string,
318
+ ): string | null {
319
+ if (!expected) return null;
320
+ const actual = createHash("sha256").update(bytes).digest("hex");
321
+ if (actual === expected) return null;
322
+ return (
323
+ `refusing to install failproofaid from ${source}: its SHA-256 is ${actual}, ` +
324
+ `but this build of failproofai expects ${expected}`
325
+ );
326
+ }
327
+
85
328
  async function fetchBytes(url: string): Promise<Buffer> {
86
329
  const response = await fetch(url, { signal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS) });
87
330
  if (!response.ok) throw new Error(`GET ${url} returned ${response.status}`);
@@ -118,10 +361,6 @@ export async function downloadFailproofaidBinary(key: PlatformKey): Promise<Daem
118
361
  }
119
362
 
120
363
  const assetName = `failproofaid-${key}.gz`;
121
- // Same directory as the target so the install is a rename within one
122
- // filesystem — atomic, and never a half-written binary a service manager
123
- // could pick up. The pid keeps two concurrent wizards off each other's file.
124
- const tempPath = `${target}.${process.pid}.tmp`;
125
364
 
126
365
  try {
127
366
  const [asset, manifest] = await Promise.all([
@@ -138,14 +377,8 @@ export async function downloadFailproofaidBinary(key: PlatformKey): Promise<Daem
138
377
  return { error: `checksum mismatch for ${assetName} (expected ${expected}, got ${actual})` };
139
378
  }
140
379
 
141
- const binary = gunzipSync(asset);
142
- mkdirSync(daemonBinaryDir(), { recursive: true });
143
- writeFileSync(tempPath, binary);
144
- chmodSync(tempPath, 0o755);
145
- renameSync(tempPath, target);
146
- return { path: target };
380
+ return { path: installBinaryBytes(gunzipSync(asset)) };
147
381
  } catch (err) {
148
- rmSync(tempPath, { force: true });
149
382
  const message = err instanceof Error ? err.message : String(err);
150
383
  return { error: `failed to download failproofaid v${version} for ${key}: ${message}` };
151
384
  }