failproofai 1.0.0-beta.4 → 1.0.0-beta.6

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 (369) 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 +3 -3
  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/server-reference-manifest.json +1 -1
  8. package/.next/standalone/.next/server/app/_global-error/page.js +3 -1
  9. package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  10. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  11. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  12. package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
  13. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +2 -2
  14. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
  15. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +3 -3
  16. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +3 -3
  17. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  18. package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  19. package/.next/standalone/.next/server/app/_not-found/page.js +3 -1
  20. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  21. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  22. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  23. package/.next/standalone/.next/server/app/_not-found.rsc +15 -15
  24. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +15 -15
  25. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
  26. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +10 -10
  27. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  28. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
  29. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  30. package/.next/standalone/.next/server/app/api/audit/invite/route.js +3 -2
  31. package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -1
  32. package/.next/standalone/.next/server/app/api/audit/run/route.js +4 -3
  33. package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
  34. package/.next/standalone/.next/server/app/api/audit/status/route.js +1 -1
  35. package/.next/standalone/.next/server/app/api/audit/status/route.js.nft.json +1 -1
  36. package/.next/standalone/.next/server/app/api/auth/login-request/route.js +2 -1
  37. package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
  38. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js +3 -2
  39. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
  40. package/.next/standalone/.next/server/app/api/auth/logout/route.js +3 -2
  41. package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
  42. package/.next/standalone/.next/server/app/api/auth/reminder/route.js +3 -2
  43. package/.next/standalone/.next/server/app/api/auth/reminder/route.js.nft.json +1 -1
  44. package/.next/standalone/.next/server/app/api/auth/status/route.js +3 -2
  45. package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
  46. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js +1 -1
  47. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
  48. package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
  49. package/.next/standalone/.next/server/app/audit/page.js +5 -3
  50. package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
  51. package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
  52. package/.next/standalone/.next/server/app/index.html +1 -1
  53. package/.next/standalone/.next/server/app/index.rsc +15 -15
  54. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  55. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
  56. package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +4 -4
  57. package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +10 -10
  58. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  59. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
  60. package/.next/standalone/.next/server/app/page.js +3 -1
  61. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  62. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  63. package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +10 -10
  64. package/.next/standalone/.next/server/app/policies/page.js +4 -2
  65. package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
  66. package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
  67. package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
  68. package/.next/standalone/.next/server/app/project/[name]/page.js +4 -2
  69. package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
  70. package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
  71. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
  72. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
  73. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js +6 -4
  74. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
  75. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
  76. package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
  77. package/.next/standalone/.next/server/app/projects/page.js +4 -2
  78. package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
  79. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  80. package/.next/standalone/.next/server/app/settings/page/app-paths-manifest.json +3 -0
  81. package/.next/standalone/.next/server/app/settings/page/build-manifest.json +18 -0
  82. package/.next/standalone/.next/server/app/settings/page/next-font-manifest.json +6 -0
  83. package/.next/standalone/.next/server/app/settings/page/react-loadable-manifest.json +1 -0
  84. package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +53 -0
  85. package/.next/standalone/.next/server/app/settings/page.js +18 -0
  86. package/.next/standalone/.next/server/app/settings/page.js.map +5 -0
  87. package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -0
  88. package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +3 -0
  89. package/.next/standalone/.next/server/app-paths-manifest.json +2 -1
  90. package/.next/standalone/.next/server/chunks/{[externals]__1nl3dvw._.js → [externals]__0r-zamh._.js} +2 -2
  91. package/.next/standalone/.next/server/chunks/[root-of-the-server]__06hexd0._.js +3 -0
  92. package/.next/standalone/.next/server/chunks/[root-of-the-server]__094p1f1._.js +3 -0
  93. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0_0xu5z._.js +1 -1
  94. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ed01_d._.js +3 -0
  95. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0g0vcwt._.js +3 -0
  96. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0h3lfmp._.js → [root-of-the-server]__0ky_n0r._.js} +2 -2
  97. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__18d-9oi._.js → [root-of-the-server]__0lk_935._.js} +2 -2
  98. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__1p7s8-d._.js → [root-of-the-server]__0pbp9fe._.js} +2 -2
  99. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0q-v9z2._.js +1 -1
  100. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__10oa-v9._.js → [root-of-the-server]__0v2fpxe._.js} +2 -2
  101. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0sb_5m8._.js → [root-of-the-server]__131ebum._.js} +3 -3
  102. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0-dh5jy._.js → [root-of-the-server]__1_ps0jw._.js} +2 -2
  103. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0l4vuqm._.js → [root-of-the-server]__1a7i2q4._.js} +1 -1
  104. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1ibjy5x._.js +3 -0
  105. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1iny24d._.js +3 -0
  106. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1tvn4wf._.js +1 -1
  107. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1tyedjt._.js +3 -0
  108. package/.next/standalone/.next/server/chunks/_0lxbzdq._.js +5 -0
  109. package/.next/standalone/.next/server/chunks/_1zuiiy3._.js +5 -0
  110. package/.next/standalone/.next/server/chunks/lib_telemetry_ts_0dctyyw._.js +5 -0
  111. package/.next/standalone/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_17k9e3w.js +5 -5
  112. package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
  113. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__06bp_fg._.js +5 -0
  114. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__074qmkp._.js +3 -0
  115. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0spkm68._.js +10 -10
  116. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1_a_gwn._.js +3 -0
  117. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1a2hcb_._.js +3 -0
  118. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1e7-pa7._.js +3 -0
  119. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0rtdfof._.js → [root-of-the-server]__1rdruw4._.js} +1 -1
  120. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1rv-sc9._.js +3 -0
  121. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1tyf0tc._.js +5 -0
  122. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1u-wx42._.js +4 -0
  123. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1v185mo._.js +3 -0
  124. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0rag5dg._.js → [root-of-the-server]__1yw368c._.js} +2 -2
  125. package/.next/standalone/.next/server/chunks/ssr/_0-yi74u._.js +3 -0
  126. package/.next/standalone/.next/server/chunks/ssr/_04mekdy._.js +3 -0
  127. package/.next/standalone/.next/server/chunks/ssr/_0igtyj5._.js +3 -0
  128. package/.next/standalone/.next/server/chunks/ssr/_0r-dsre._.js +3 -0
  129. package/.next/standalone/.next/server/chunks/ssr/_0rjgfln._.js +3 -0
  130. package/.next/standalone/.next/server/chunks/ssr/_0se484m._.js +3 -0
  131. package/.next/standalone/.next/server/chunks/ssr/_0uz7o9y._.js +3 -0
  132. package/.next/standalone/.next/server/chunks/ssr/_11_p9y8._.js +1 -1
  133. package/.next/standalone/.next/server/chunks/ssr/_1fahg9e._.js +3 -0
  134. package/.next/standalone/.next/server/chunks/ssr/_1gmzkwj._.js +5 -0
  135. package/.next/standalone/.next/server/chunks/ssr/_1w8sola._.js +3 -0
  136. package/.next/standalone/.next/server/chunks/ssr/_1w_6p9g._.js +3 -0
  137. package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +2 -2
  138. package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
  139. package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +2 -2
  140. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0dwo94s.js +4 -0
  141. package/.next/standalone/.next/server/chunks/ssr/src_hooks_builtin-policies_ts_09j2ndl._.js +3 -0
  142. package/.next/standalone/.next/server/chunks/ssr/src_hooks_fp-config_ts_04t589g._.js +5 -0
  143. package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
  144. package/.next/standalone/.next/server/middleware.js +2 -2
  145. package/.next/standalone/.next/server/pages/404.html +1 -1
  146. package/.next/standalone/.next/server/pages/500.html +1 -1
  147. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  148. package/.next/standalone/.next/server/server-reference-manifest.json +54 -12
  149. package/.next/standalone/.next/static/chunks/{2c90h1g6x8z8y.js → 0_2n13i94rnw5.js} +1 -1
  150. package/.next/standalone/.next/static/chunks/1bm0q12hgs22l.css +2 -0
  151. package/.next/standalone/.next/static/chunks/1v1gqvpjk62jm.js +1 -0
  152. package/.next/standalone/.next/static/chunks/23557z4e6dtsr.js +1 -0
  153. package/.next/standalone/.next/static/chunks/28zkwzu50puki.js +1 -0
  154. package/.next/standalone/.next/static/chunks/2uvhw57mf9lg_.css +2 -0
  155. package/.next/standalone/.next/static/chunks/3081gykdubv8b.js +1 -0
  156. package/.next/standalone/.next/static/chunks/{06jakt_xhoolk.js → 34fa65k0cldkj.js} +1 -1
  157. package/.next/standalone/.next/static/chunks/35v07j9gc1pvr.js +6 -0
  158. package/.next/standalone/.next/static/chunks/{2zb3m1tzq6h98.js → 3f_939wi3kfnx.js} +22 -22
  159. package/.next/standalone/.next/static/chunks/{31cqiv_cpgj9m.js → 3p1vpm2_-tfwm.js} +1 -1
  160. package/.next/standalone/.next/static/chunks/{0ue9ak_xexiqh.js → 3rbpw_waieafm.js} +1 -1
  161. package/.next/standalone/.next/static/chunks/40ffnfpkeyvb0.js +1 -0
  162. package/.next/standalone/app/actions/get-hooks-config.ts +2 -1
  163. package/.next/standalone/app/actions/get-scheduled-audit.ts +70 -0
  164. package/.next/standalone/app/actions/update-scheduled-audit.ts +44 -0
  165. package/.next/standalone/app/api/audit/run/route.ts +28 -0
  166. package/.next/standalone/app/api/audit/status/route.ts +13 -1
  167. package/.next/standalone/app/api/auth/status/route.ts +1 -1
  168. package/.next/standalone/app/audit/_components/auth-dialog.css +159 -0
  169. package/.next/standalone/app/audit/_components/auth-dialog.tsx +3 -0
  170. package/.next/standalone/app/audit/audit-styles.css +6 -149
  171. package/.next/standalone/app/settings/page.tsx +31 -0
  172. package/.next/standalone/app/settings/settings-client.tsx +488 -0
  173. package/.next/standalone/components/navbar.tsx +2 -0
  174. package/.next/standalone/lib/auth/api-server-client.ts +2 -3
  175. package/.next/standalone/lib/auth/auth-store.ts +4 -4
  176. package/.next/standalone/lib/codex-sessions.ts +2 -1
  177. package/.next/standalone/lib/dashboard-host.ts +101 -0
  178. package/.next/standalone/lib/install-check.ts +22 -7
  179. package/.next/standalone/lib/pi-sessions.ts +99 -14
  180. package/.next/standalone/lib/telemetry-enabled.ts +54 -0
  181. package/.next/standalone/lib/telemetry-id.ts +52 -1
  182. package/.next/standalone/lib/telemetry.ts +8 -4
  183. package/.next/standalone/node_modules/react/cjs/react.development.js +1 -1
  184. package/.next/standalone/node_modules/react/cjs/react.production.js +1 -1
  185. package/.next/standalone/node_modules/react/package.json +3 -3
  186. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server-legacy.browser.production.js +1 -1
  187. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server-legacy.node.production.js +1 -1
  188. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server.browser.production.js +3 -3
  189. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server.edge.production.js +3 -3
  190. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server.node.production.js +3 -3
  191. package/.next/standalone/node_modules/react-dom/cjs/react-dom.production.js +1 -1
  192. package/.next/standalone/node_modules/react-dom/package.json +4 -4
  193. package/.next/standalone/package.json +7 -6
  194. package/.next/standalone/proxy.ts +89 -1
  195. package/.next/standalone/server.js +1 -1
  196. package/bin/failproofai.mjs +197 -80
  197. package/dist/cli.mjs +17699 -15345
  198. package/dist/worker.mjs +1620 -257
  199. package/lib/auth/api-server-client.ts +2 -3
  200. package/lib/auth/auth-store.ts +4 -4
  201. package/lib/codex-sessions.ts +2 -1
  202. package/lib/dashboard-host.ts +101 -0
  203. package/lib/install-check.ts +22 -7
  204. package/lib/pi-sessions.ts +99 -14
  205. package/lib/telemetry-enabled.ts +54 -0
  206. package/lib/telemetry-id.ts +52 -1
  207. package/lib/telemetry.ts +8 -4
  208. package/package.json +7 -6
  209. package/scripts/install-telemetry.mjs +8 -1
  210. package/scripts/launch.ts +25 -3
  211. package/scripts/parse-script-args.ts +17 -1
  212. package/scripts/prune-standalone.mjs +20 -0
  213. package/scripts/translate-docs/readme-translator.ts +163 -4
  214. package/scripts/validate-mdx.ts +153 -13
  215. package/src/audit/audit-lock.ts +285 -0
  216. package/src/audit/audit-schedule.ts +111 -0
  217. package/src/audit/cache.ts +18 -4
  218. package/src/audit/cli-adapters/goose.ts +2 -1
  219. package/src/audit/cli-adapters/hermes.ts +28 -10
  220. package/src/audit/cli.ts +191 -35
  221. package/src/audit/dashboard-cache.ts +2 -1
  222. package/src/hooks/builtin-policies.ts +100 -3
  223. package/src/hooks/cloud-connection.ts +163 -14
  224. package/src/hooks/cloud-enrollment-cli.ts +119 -21
  225. package/src/hooks/cloud-enrollment.ts +87 -17
  226. package/src/hooks/cloud-introspect.ts +147 -0
  227. package/src/hooks/cloud-managed-policies.ts +33 -2
  228. package/src/hooks/collector-config.ts +32 -40
  229. package/src/hooks/configure-wizard.ts +696 -318
  230. package/src/hooks/custom-hooks-loader.ts +125 -11
  231. package/src/hooks/daemon-client.ts +83 -17
  232. package/src/hooks/daemon-download.ts +54 -2
  233. package/src/hooks/daemon-service.ts +595 -27
  234. package/src/hooks/first-run-gate.ts +39 -0
  235. package/src/hooks/fp-config.ts +497 -0
  236. package/src/hooks/fp-home.ts +342 -0
  237. package/src/hooks/fp-reset.ts +332 -0
  238. package/src/hooks/handler.ts +42 -1
  239. package/src/hooks/hook-activity-store.ts +35 -20
  240. package/src/hooks/hook-logger.ts +2 -1
  241. package/src/hooks/hook-telemetry.ts +5 -1
  242. package/src/hooks/hooks-config.ts +4 -3
  243. package/src/hooks/loader-utils.ts +166 -5
  244. package/src/hooks/manager.ts +5 -4
  245. package/src/hooks/onboarding-lock.ts +119 -0
  246. package/src/hooks/policy-types.ts +0 -7
  247. package/src/hooks/session-pause-cli.ts +15 -13
  248. package/src/hooks/session-pause.ts +36 -4
  249. package/src/hooks/setup-state.ts +256 -0
  250. package/src/hooks/tui.ts +4 -4
  251. package/src/hooks/worker-server.ts +53 -1
  252. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0f8nu8d._.js +0 -3
  253. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0szqzl8._.js +0 -3
  254. package/.next/standalone/.next/server/chunks/[root-of-the-server]__17g9wh7._.js +0 -3
  255. package/.next/standalone/.next/server/chunks/[root-of-the-server]__19120tr._.js +0 -3
  256. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1fwl2mz._.js +0 -3
  257. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1myjm-d._.js +0 -3
  258. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1rhmvod._.js +0 -3
  259. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__02r5bgf._.js +0 -4
  260. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0cmdyn_._.js +0 -3
  261. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0e8sjqm._.js +0 -4
  262. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0lkzqax._.js +0 -4
  263. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ls0gsr._.js +0 -4
  264. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0n_uvv0._.js +0 -3
  265. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qucxyj._.js +0 -4
  266. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0sdrz-j._.js +0 -3
  267. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0u02miy._.js +0 -4
  268. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__14dd6h8._.js +0 -3
  269. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1j4u3yd._.js +0 -4
  270. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1zqz4v8._.js +0 -4
  271. package/.next/standalone/.next/server/chunks/ssr/_1m_p7pi._.js +0 -3
  272. package/.next/standalone/.next/server/chunks/ssr/node_modules_html-to-image_es_index_1q9xxca.js +0 -3
  273. package/.next/standalone/.next/server/chunks/ssr/src_hooks_1ezd2jf._.js +0 -5
  274. package/.next/standalone/.next/server/chunks/ssr/src_hooks_1tnuifj._.js +0 -5
  275. package/.next/standalone/.next/static/chunks/0h7auy7hzjyhw.js +0 -1
  276. package/.next/standalone/.next/static/chunks/0oe2-hp0_2tzs.js +0 -6
  277. package/.next/standalone/.next/static/chunks/1fw3pxobk_otl.js +0 -1
  278. package/.next/standalone/.next/static/chunks/3h5_3u46gu9jx.js +0 -1
  279. package/.next/standalone/.next/static/chunks/3i27c3hcriawq.css +0 -1
  280. package/.next/standalone/.next/static/chunks/3zdwnnthucs_1.css +0 -2
  281. package/.next/standalone/.next/static/chunks/43a1ywqsg9bq9.js +0 -1
  282. package/.next/standalone/Cargo.lock +0 -2222
  283. package/.next/standalone/Cargo.toml +0 -9
  284. package/.next/standalone/crates/CLOUD_POLICIES.md +0 -136
  285. package/.next/standalone/crates/PROTOCOL.md +0 -122
  286. package/.next/standalone/crates/failproofaid/Cargo.toml +0 -25
  287. package/.next/standalone/crates/failproofaid/src/cloud_client.rs +0 -484
  288. package/.next/standalone/crates/failproofaid/src/cloud_policies.rs +0 -921
  289. package/.next/standalone/crates/failproofaid/src/lock.rs +0 -81
  290. package/.next/standalone/crates/failproofaid/src/main.rs +0 -532
  291. package/.next/standalone/crates/failproofaid/src/paths.rs +0 -201
  292. package/.next/standalone/crates/failproofaid/src/server.rs +0 -502
  293. package/.next/standalone/crates/failproofaid/src/worker.rs +0 -400
  294. package/.next/standalone/crates/failproofaid/tests/daemon_e2e.rs +0 -241
  295. package/.next/standalone/crates/fpai-collect/Cargo.toml +0 -43
  296. package/.next/standalone/crates/fpai-collect/src/config.rs +0 -412
  297. package/.next/standalone/crates/fpai-collect/src/cursor.rs +0 -520
  298. package/.next/standalone/crates/fpai-collect/src/delivery.rs +0 -472
  299. package/.next/standalone/crates/fpai-collect/src/filetail.rs +0 -484
  300. package/.next/standalone/crates/fpai-collect/src/health.rs +0 -369
  301. package/.next/standalone/crates/fpai-collect/src/lib.rs +0 -34
  302. package/.next/standalone/crates/fpai-collect/src/redact.rs +0 -516
  303. package/.next/standalone/crates/fpai-collect/src/sources/claude/mod.rs +0 -279
  304. package/.next/standalone/crates/fpai-collect/src/sources/claude/transform.rs +0 -619
  305. package/.next/standalone/crates/fpai-collect/src/sources/codex/mod.rs +0 -156
  306. package/.next/standalone/crates/fpai-collect/src/sources/codex/transform.rs +0 -715
  307. package/.next/standalone/crates/fpai-collect/src/sources/copilot/mod.rs +0 -158
  308. package/.next/standalone/crates/fpai-collect/src/sources/copilot/transform.rs +0 -512
  309. package/.next/standalone/crates/fpai-collect/src/sources/goose/mod.rs +0 -511
  310. package/.next/standalone/crates/fpai-collect/src/sources/goose/transform.rs +0 -586
  311. package/.next/standalone/crates/fpai-collect/src/sources/hermes/mod.rs +0 -318
  312. package/.next/standalone/crates/fpai-collect/src/sources/hermes/transform.rs +0 -579
  313. package/.next/standalone/crates/fpai-collect/src/sources/hooks/mod.rs +0 -310
  314. package/.next/standalone/crates/fpai-collect/src/sources/hooks/transform.rs +0 -448
  315. package/.next/standalone/crates/fpai-collect/src/sources/mod.rs +0 -23
  316. package/.next/standalone/crates/fpai-collect/src/sources/openclaw/mod.rs +0 -176
  317. package/.next/standalone/crates/fpai-collect/src/sources/openclaw/transform.rs +0 -500
  318. package/.next/standalone/crates/fpai-collect/src/sources/opencode/mod.rs +0 -315
  319. package/.next/standalone/crates/fpai-collect/src/sources/opencode/transform.rs +0 -493
  320. package/.next/standalone/crates/fpai-collect/src/sources/pi/mod.rs +0 -201
  321. package/.next/standalone/crates/fpai-collect/src/sources/pi/transform.rs +0 -533
  322. package/.next/standalone/crates/fpai-collect/src/spool.rs +0 -458
  323. package/.next/standalone/crates/fpai-collect/src/sqlitepoll.rs +0 -387
  324. package/.next/standalone/crates/fpai-collect/src/supervisor.rs +0 -423
  325. package/.next/standalone/crates/fpai-collect/src/uploader.rs +0 -600
  326. package/.next/standalone/crates/fpai-collect/tests/claude_source.rs +0 -738
  327. package/.next/standalone/crates/fpai-collect/tests/claude_subagents.rs +0 -393
  328. package/.next/standalone/crates/fpai-collect/tests/codex_source.rs +0 -975
  329. package/.next/standalone/crates/fpai-collect/tests/config.rs +0 -286
  330. package/.next/standalone/crates/fpai-collect/tests/copilot_source.rs +0 -1019
  331. package/.next/standalone/crates/fpai-collect/tests/delivery.rs +0 -281
  332. package/.next/standalone/crates/fpai-collect/tests/goose_source.rs +0 -1008
  333. package/.next/standalone/crates/fpai-collect/tests/hermes_source.rs +0 -1129
  334. package/.next/standalone/crates/fpai-collect/tests/hooks_source.rs +0 -621
  335. package/.next/standalone/crates/fpai-collect/tests/openclaw_source.rs +0 -854
  336. package/.next/standalone/crates/fpai-collect/tests/opencode_source.rs +0 -1478
  337. package/.next/standalone/crates/fpai-collect/tests/pi_source.rs +0 -1191
  338. package/.next/standalone/crates/fpai-collect/tests/supervisor.rs +0 -290
  339. package/.next/standalone/crates/fpai-collect/tests/uploader.rs +0 -506
  340. package/.next/standalone/crates/fpai-ipc/Cargo.toml +0 -16
  341. package/.next/standalone/crates/fpai-ipc/src/envelope.rs +0 -175
  342. package/.next/standalone/crates/fpai-ipc/src/framing.rs +0 -177
  343. package/.next/standalone/crates/fpai-ipc/src/lib.rs +0 -10
  344. package/.next/standalone/crates/fpai-ipc/src/peer.rs +0 -80
  345. package/.next/standalone/docker-hook-sync/Dockerfile +0 -79
  346. package/.next/standalone/docker-hook-sync/entrypoint.sh +0 -109
  347. package/.next/standalone/integration-suite/Dockerfile +0 -47
  348. package/.next/standalone/integration-suite/README.md +0 -129
  349. package/.next/standalone/integration-suite/canary-policies.mjs +0 -45
  350. package/.next/standalone/integration-suite/capture-tokens.sh +0 -48
  351. package/.next/standalone/integration-suite/ci-entrypoint.sh +0 -179
  352. package/.next/standalone/integration-suite/inject-tokens.sh +0 -44
  353. package/.next/standalone/integration-suite/install-clis.sh +0 -136
  354. package/.next/standalone/integration-suite/probe-cli.sh +0 -248
  355. package/.next/standalone/integration-suite/report.js +0 -120
  356. package/.next/standalone/integration-suite/run.sh +0 -159
  357. package/.next/standalone/openclaw-plugin/index.js +0 -223
  358. package/.next/standalone/openclaw-plugin/openclaw.plugin.json +0 -6
  359. package/.next/standalone/openclaw-plugin/package.json +0 -12
  360. package/.next/standalone/osv-scanner.toml +0 -17
  361. package/.next/standalone/pi-extension/index.ts +0 -524
  362. package/.next/standalone/pi-extension/package.json +0 -12
  363. package/.next/standalone/postcss.config.mjs +0 -8
  364. package/.next/standalone/readme-arch-hq.gif +0 -0
  365. package/.next/standalone/rust-toolchain.toml +0 -4
  366. package/src/auth/cli.ts +0 -371
  367. /package/.next/standalone/.next/static/{StV6Lay7Q1cU4ysYCFJmH → Ptn8aBQl_cnNgOd0ebyv0}/_buildManifest.js +0 -0
  368. /package/.next/standalone/.next/static/{StV6Lay7Q1cU4ysYCFJmH → Ptn8aBQl_cnNgOd0ebyv0}/_clientMiddlewareManifest.js +0 -0
  369. /package/.next/standalone/.next/static/{StV6Lay7Q1cU4ysYCFJmH → Ptn8aBQl_cnNgOd0ebyv0}/_ssgManifest.js +0 -0
@@ -1,177 +0,0 @@
1
- //! Length-prefixed JSON framing shared by the daemon and every client of it.
2
- //!
3
- //! Frame = 4-byte big-endian `u32` byte length, followed by that many bytes
4
- //! of UTF-8 JSON. One frame in, one frame out, per connection — the daemon
5
- //! never keeps a connection open across multiple logical requests, so there
6
- //! is no need for a request-id-multiplexed protocol.
7
-
8
- use serde::Serialize;
9
- use serde::de::DeserializeOwned;
10
- use std::io::{self, Read, Write};
11
-
12
- /// Hard cap on a single frame's declared length. A hook payload is at most
13
- /// 1 MiB (see `handler.ts`'s own stdin cap); 16 MiB leaves headroom without
14
- /// letting a corrupt or hostile length prefix trigger an unbounded
15
- /// allocation before a single byte of the body has even been read.
16
- pub const MAX_FRAME_LEN: u32 = 16 * 1024 * 1024;
17
-
18
- #[derive(Debug)]
19
- pub enum FramingError {
20
- Io(io::Error),
21
- FrameTooLarge { declared: u32, max: u32 },
22
- Json(serde_json::Error),
23
- }
24
-
25
- impl std::fmt::Display for FramingError {
26
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
27
- match self {
28
- FramingError::Io(e) => write!(f, "io error: {e}"),
29
- FramingError::FrameTooLarge { declared, max } => {
30
- write!(f, "frame length {declared} exceeds max {max}")
31
- }
32
- FramingError::Json(e) => write!(f, "invalid JSON frame: {e}"),
33
- }
34
- }
35
- }
36
-
37
- impl std::error::Error for FramingError {}
38
-
39
- impl From<io::Error> for FramingError {
40
- fn from(e: io::Error) -> Self {
41
- FramingError::Io(e)
42
- }
43
- }
44
-
45
- impl From<serde_json::Error> for FramingError {
46
- fn from(e: serde_json::Error) -> Self {
47
- FramingError::Json(e)
48
- }
49
- }
50
-
51
- /// Serializes `value` to JSON and writes it as one length-prefixed frame.
52
- pub fn write_message<W: Write, T: Serialize>(
53
- writer: &mut W,
54
- value: &T,
55
- ) -> Result<(), FramingError> {
56
- let body = serde_json::to_vec(value)?;
57
- let len = u32::try_from(body.len()).map_err(|_| FramingError::FrameTooLarge {
58
- declared: u32::MAX,
59
- max: MAX_FRAME_LEN,
60
- })?;
61
- if len > MAX_FRAME_LEN {
62
- return Err(FramingError::FrameTooLarge {
63
- declared: len,
64
- max: MAX_FRAME_LEN,
65
- });
66
- }
67
- writer.write_all(&len.to_be_bytes())?;
68
- writer.write_all(&body)?;
69
- writer.flush()?;
70
- Ok(())
71
- }
72
-
73
- /// Reads one length-prefixed frame and deserializes it as `T`. Rejects the
74
- /// frame (without allocating a body buffer) if the declared length exceeds
75
- /// [`MAX_FRAME_LEN`], so a corrupt or adversarial length prefix can't be
76
- /// used to force a large allocation.
77
- pub fn read_message<R: Read, T: DeserializeOwned>(reader: &mut R) -> Result<T, FramingError> {
78
- let mut len_bytes = [0u8; 4];
79
- reader.read_exact(&mut len_bytes)?;
80
- let len = u32::from_be_bytes(len_bytes);
81
- if len > MAX_FRAME_LEN {
82
- return Err(FramingError::FrameTooLarge {
83
- declared: len,
84
- max: MAX_FRAME_LEN,
85
- });
86
- }
87
- let mut body = vec![0u8; len as usize];
88
- reader.read_exact(&mut body)?;
89
- let value = serde_json::from_slice(&body)?;
90
- Ok(value)
91
- }
92
-
93
- #[cfg(test)]
94
- mod tests {
95
- use super::*;
96
- use serde::Deserialize;
97
- use std::io::Cursor;
98
-
99
- #[derive(Debug, Serialize, Deserialize, PartialEq)]
100
- struct Sample {
101
- a: u32,
102
- b: String,
103
- }
104
-
105
- #[test]
106
- fn round_trips_a_simple_value() {
107
- let mut buf = Vec::new();
108
- let msg = Sample {
109
- a: 42,
110
- b: "hello".to_string(),
111
- };
112
- write_message(&mut buf, &msg).unwrap();
113
- let mut cursor = Cursor::new(buf);
114
- let decoded: Sample = read_message(&mut cursor).unwrap();
115
- assert_eq!(decoded, msg);
116
- }
117
-
118
- #[test]
119
- fn round_trips_empty_string_fields() {
120
- let mut buf = Vec::new();
121
- let msg = Sample {
122
- a: 0,
123
- b: String::new(),
124
- };
125
- write_message(&mut buf, &msg).unwrap();
126
- let mut cursor = Cursor::new(buf);
127
- let decoded: Sample = read_message(&mut cursor).unwrap();
128
- assert_eq!(decoded, msg);
129
- }
130
-
131
- #[test]
132
- fn rejects_a_declared_length_over_the_cap_without_reading_a_body() {
133
- let mut buf = Vec::new();
134
- buf.extend_from_slice(&(MAX_FRAME_LEN + 1).to_be_bytes());
135
- // Deliberately no body bytes follow — if `read_message` tried to
136
- // allocate/read the declared length before checking the cap, this
137
- // would hang or panic on the short read instead of erroring cleanly.
138
- let mut cursor = Cursor::new(buf);
139
- let result: Result<Sample, _> = read_message(&mut cursor);
140
- assert!(matches!(result, Err(FramingError::FrameTooLarge { .. })));
141
- }
142
-
143
- #[test]
144
- fn refuses_to_write_a_frame_over_the_cap() {
145
- #[derive(Serialize)]
146
- struct Big {
147
- data: String,
148
- }
149
- let big = Big {
150
- data: "x".repeat((MAX_FRAME_LEN as usize) + 1),
151
- };
152
- let mut buf = Vec::new();
153
- let result = write_message(&mut buf, &big);
154
- assert!(matches!(result, Err(FramingError::FrameTooLarge { .. })));
155
- }
156
-
157
- #[test]
158
- fn rejects_truncated_frames() {
159
- let mut buf = Vec::new();
160
- buf.extend_from_slice(&10u32.to_be_bytes());
161
- buf.extend_from_slice(b"short"); // fewer than the declared 10 bytes
162
- let mut cursor = Cursor::new(buf);
163
- let result: Result<Sample, _> = read_message(&mut cursor);
164
- assert!(matches!(result, Err(FramingError::Io(_))));
165
- }
166
-
167
- #[test]
168
- fn rejects_malformed_json_inside_a_valid_frame() {
169
- let mut buf = Vec::new();
170
- let body = b"not json";
171
- buf.extend_from_slice(&(body.len() as u32).to_be_bytes());
172
- buf.extend_from_slice(body);
173
- let mut cursor = Cursor::new(buf);
174
- let result: Result<Sample, _> = read_message(&mut cursor);
175
- assert!(matches!(result, Err(FramingError::Json(_))));
176
- }
177
- }
@@ -1,10 +0,0 @@
1
- //! Wire protocol shared by `failproofaid` and every client/test that talks
2
- //! to it: message framing, the JSON envelope, and Unix-socket peer
3
- //! verification.
4
-
5
- pub mod envelope;
6
- pub mod framing;
7
- pub mod peer;
8
-
9
- pub use envelope::{ClientMessage, PROTOCOL_VERSION, ServerMessage};
10
- pub use framing::{FramingError, MAX_FRAME_LEN, read_message, write_message};
@@ -1,80 +0,0 @@
1
- //! Verifies that a Unix socket peer is running as the same OS user as this
2
- //! process.
3
- //!
4
- //! failproofaid is user-scope only (see the plan: "no elevation, the daemon
5
- //! spawns the worker because the daemon already runs as the user"): the
6
- //! socket directory is `0700` and the socket file `0600`, which is the
7
- //! actual access-control boundary. This check is a second, defense-in-depth
8
- //! layer against the narrow window between a socket file existing and its
9
- //! permissions having been fully applied, and against misconfigured
10
- //! filesystems (e.g. a shared mount with unexpectedly loose permissions).
11
- //! It is not a stronger security boundary than the filesystem permissions
12
- //! already provide — same OS user can always reach this daemon regardless.
13
-
14
- use std::io;
15
- use std::os::unix::io::AsRawFd;
16
- use std::os::unix::net::UnixStream;
17
-
18
- /// Returns the effective UID of the process on the other end of `stream`.
19
- #[cfg(target_os = "linux")]
20
- pub fn peer_uid(stream: &UnixStream) -> io::Result<u32> {
21
- use std::mem;
22
-
23
- let fd = stream.as_raw_fd();
24
- let mut cred: libc::ucred = unsafe { mem::zeroed() };
25
- let mut len = mem::size_of::<libc::ucred>() as libc::socklen_t;
26
-
27
- let ret = unsafe {
28
- libc::getsockopt(
29
- fd,
30
- libc::SOL_SOCKET,
31
- libc::SO_PEERCRED,
32
- &mut cred as *mut libc::ucred as *mut libc::c_void,
33
- &mut len,
34
- )
35
- };
36
- if ret != 0 {
37
- return Err(io::Error::last_os_error());
38
- }
39
- Ok(cred.uid)
40
- }
41
-
42
- /// Returns the effective UID of the process on the other end of `stream`.
43
- #[cfg(target_os = "macos")]
44
- pub fn peer_uid(stream: &UnixStream) -> io::Result<u32> {
45
- let fd = stream.as_raw_fd();
46
- let mut uid: libc::uid_t = 0;
47
- let mut gid: libc::gid_t = 0;
48
-
49
- let ret = unsafe { libc::getpeereid(fd, &mut uid, &mut gid) };
50
- if ret != 0 {
51
- return Err(io::Error::last_os_error());
52
- }
53
- Ok(uid)
54
- }
55
-
56
- /// Returns this process's own effective UID, for comparison against
57
- /// [`peer_uid`].
58
- pub fn own_uid() -> u32 {
59
- unsafe { libc::geteuid() }
60
- }
61
-
62
- /// `true` if `stream`'s peer is running as this process's own OS user.
63
- pub fn is_same_user(stream: &UnixStream) -> io::Result<bool> {
64
- Ok(peer_uid(stream)? == own_uid())
65
- }
66
-
67
- #[cfg(test)]
68
- mod tests {
69
- use super::*;
70
-
71
- #[test]
72
- fn a_local_socketpair_peer_is_always_the_same_user() {
73
- // socketpair() connects two ends of the same process — the peer
74
- // UID must equal our own, on every CI runner regardless of who's
75
- // executing the test.
76
- let (a, _b) = UnixStream::pair().unwrap();
77
- assert!(is_same_user(&a).unwrap());
78
- assert_eq!(peer_uid(&a).unwrap(), own_uid());
79
- }
80
- }
@@ -1,79 +0,0 @@
1
- # Self-contained failproofai hook-sync container.
2
- #
3
- # A single-shot daily job (run by a k8s CronJob) that clones failproofai, runs
4
- # Claude Code in `--effort ultracode` mode to detect drift between every agent-CLI
5
- # harness we integrate with and this repo, and opens ONE auto-PR with the fix.
6
- #
7
- # Bundles:
8
- # - Node 20 + npm (npm is a fallback bun installer for scripts/dev-hook.mjs;
9
- # node runs the launcher itself)
10
- # - bun (STILL REQUIRED: the cloned repo's .claude/settings.json fires hooks via
11
- # `node "$CLAUDE_PROJECT_DIR/scripts/dev-hook.mjs" --hook <Event>`, and that
12
- # launcher only *locates* bun — it cannot conjure one. Without this layer the
13
- # dogfooded require-*-before-stop policies never fire and the auto-PR is
14
- # never committed/pushed. We install to BUN_INSTALL=/home/appuser/.bun, which
15
- # the launcher probes explicitly, so enforcement survives a broken PATH.)
16
- # - Claude Code CLI (`claude`) — run headless with --effort ultracode
17
- # - failproofai@latest on PATH (belt-and-suspenders; the dogfood hooks actually
18
- # run the clone's SOURCE via bun, not this global)
19
- # - git + gh + jq + dumb-init + `script` (PTY wrap for stream-json)
20
- #
21
- # Build: docker build -t hook-sync:latest docker-hook-sync/
22
- # Run: docker run --rm -e CLAUDE_CODE_OAUTH_TOKEN=... -e GH_TOKEN=... hook-sync:latest
23
- #
24
- # Every dependency is installed at build time. The daily GitHub Actions rebuild
25
- # (.github/workflows/build-image.yml) keeps claude-code@latest + failproofai@latest fresh.
26
- FROM node:20-bookworm-slim
27
-
28
- ENV DEBIAN_FRONTEND=noninteractive \
29
- HOME=/home/appuser \
30
- BUN_INSTALL=/home/appuser/.bun \
31
- FAILPROOFAI_TELEMETRY_DISABLED=1 \
32
- PATH="/home/appuser/.bun/bin:/home/appuser/.local/bin:${PATH}"
33
-
34
- # Layer 1: apt deps. dumb-init for PID 1 signal handling; git+gh for the agent's
35
- # clone/branch/push/PR flow AND the require-*-before-stop hooks; jq for the
36
- # entrypoint's policy-config edit; bsdextrautils provides `script` (PTY wrap so
37
- # Node line-flushes --output-format stream-json); curl/gnupg for the gh apt key
38
- # and the bun installer; unzip is required by the bun installer.
39
- RUN apt-get update \
40
- && apt-get install -y --no-install-recommends \
41
- ca-certificates curl gnupg dumb-init jq git bsdextrautils unzip \
42
- && rm -rf /var/lib/apt/lists/*
43
-
44
- # Layer 2: GitHub CLI (gh). Used by the agent for `gh pr create/list` and by the
45
- # require-pr-before-stop hook.
46
- RUN install -d /etc/apt/keyrings \
47
- && curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \
48
- | gpg --dearmor -o /etc/apt/keyrings/githubcli-archive-keyring.gpg \
49
- && echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" \
50
- > /etc/apt/sources.list.d/github-cli.list \
51
- && apt-get update \
52
- && apt-get install -y --no-install-recommends gh \
53
- && rm -rf /var/lib/apt/lists/*
54
-
55
- # Layer 3: npm globals. Claude Code CLI + failproofai, pinned to latest at build
56
- # time; the daily workflow rebuild keeps them fresh. Root install so symlinks land
57
- # in /usr/local/bin (executable by the non-root appuser).
58
- RUN npm install -g --omit=dev \
59
- @anthropic-ai/claude-code@latest \
60
- failproofai@latest \
61
- && npm cache clean --force
62
-
63
- # Layer 4: non-root user + chowned workspace.
64
- RUN useradd --create-home --uid 10001 --shell /bin/bash appuser \
65
- && mkdir -p /workspace \
66
- && chown -R appuser:appuser /workspace /home/appuser
67
-
68
- COPY entrypoint.sh /usr/local/bin/entrypoint.sh
69
- RUN chmod 0755 /usr/local/bin/entrypoint.sh
70
-
71
- USER appuser
72
- WORKDIR /home/appuser
73
-
74
- # Layer 5: bun (installs into $BUN_INSTALL=/home/appuser/.bun, on PATH per ENV).
75
- # The dogfood hook fast-path runs TypeScript from src/ directly — bun executes TS
76
- # natively, so no build step is needed for the hooks to work.
77
- RUN curl -fsSL https://bun.sh/install | bash
78
-
79
- ENTRYPOINT ["dumb-init", "--", "/usr/local/bin/entrypoint.sh"]
@@ -1,109 +0,0 @@
1
- #!/usr/bin/env bash
2
- #
3
- # failproofai hook-sync entrypoint (runs as PID 1 under dumb-init).
4
- #
5
- # Lifecycle:
6
- # 1. Validate env (CLAUDE_CODE_OAUTH_TOKEN, GH_TOKEN).
7
- # 2. gh auth setup-git + git identity.
8
- # 3. Clone failproofai --depth=1; cut a fresh auto/sync-cli-harnesses-<UTC> branch.
9
- # 4. NEUTRALIZE two policies in the THROWAWAY clone's .failproofai config
10
- # (require-ci-green-before-stop, block-read-outside-cwd) via jq, then
11
- # `git update-index --skip-worktree` so the edit is invisible to
12
- # git status/add and never enters the agent's commit/PR — while failproofai
13
- # reads the edited WORKTREE file at runtime and sees them gone. The
14
- # require-commit/push/pr-before-stop gates stay ACTIVE (dogfooding).
15
- # 5. exec `claude --effort ultracode -p <prompt>` wrapped in a PTY so
16
- # --output-format stream-json line-flushes to `kubectl logs -f`.
17
- # 6. Exit with claude's return code (all output streams to stdout / the pod log).
18
- #
19
- # Exit codes: 0 = agent finished (claude's rc) · 64 = missing required env ·
20
- # 65 = prompt file missing in clone · 66 = unsafe WORKSPACE · else = claude's rc.
21
- set -euo pipefail
22
-
23
- CLAUDE_CODE_OAUTH_TOKEN="${CLAUDE_CODE_OAUTH_TOKEN:-}"
24
- GH_TOKEN="${GH_TOKEN:-}"
25
- REPO_URL="${REPO_URL:-https://github.com/failproofai/failproofai.git}"
26
- REPO_BRANCH_FROM="${REPO_BRANCH_FROM:-main}"
27
- WORKSPACE="${WORKSPACE:-/workspace}"
28
- PROMPT_PATH="${PROMPT_PATH:-scripts/sync-agent-cli-harnesses-prompt.md}"
29
- CLAUDE_MODEL="${CLAUDE_MODEL:-claude-opus-4-8}"
30
-
31
- export HOME="${HOME:-/home/appuser}"
32
- export CLAUDE_CODE_OAUTH_TOKEN
33
- export GH_TOKEN
34
- export GITHUB_TOKEN="${GITHUB_TOKEN:-$GH_TOKEN}"
35
- export FAILPROOFAI_TELEMETRY_DISABLED=1
36
- # Keep ultracode background subagents alive in headless -p mode (default is ~10 min).
37
- export CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS="${CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS:-1800000}"
38
-
39
- log() { printf '[entrypoint %s] %s\n' "$(date -u +%FT%TZ)" "$*"; }
40
-
41
- # ---------------- 1. env validation ----------------
42
- if [ -z "$CLAUDE_CODE_OAUTH_TOKEN" ]; then log "ERROR: CLAUDE_CODE_OAUTH_TOKEN not set"; exit 64; fi
43
- if [ -z "$GH_TOKEN" ]; then log "ERROR: GH_TOKEN not set"; exit 64; fi
44
-
45
- # ---------------- 2. gh + git auth ----------------
46
- log "authenticating gh"
47
- gh auth setup-git >/dev/null
48
- git config --global user.name "failproofai-hook-sync"
49
- git config --global user.email "hook-sync-bot@exosphere.host"
50
- git config --global init.defaultBranch main
51
-
52
- # ---------------- 3. clone + fresh branch ----------------
53
- case "$WORKSPACE" in
54
- ""|"/"|"."|"..") log "ERROR: refusing unsafe WORKSPACE '$WORKSPACE'"; exit 66 ;;
55
- esac
56
- mkdir -p "$WORKSPACE"
57
- if [ -n "$(ls -A "$WORKSPACE" 2>/dev/null)" ]; then
58
- find "$WORKSPACE" -mindepth 1 -maxdepth 1 -exec rm -rf {} +
59
- fi
60
- log "cloning $REPO_URL@$REPO_BRANCH_FROM -> $WORKSPACE"
61
- git clone --depth=1 --branch "$REPO_BRANCH_FROM" "$REPO_URL" "$WORKSPACE"
62
- cd "$WORKSPACE"
63
- # Fetch the base ref (shallow) so require-*-before-stop can diff against origin/<base>.
64
- git fetch --depth=1 origin "$REPO_BRANCH_FROM" >/dev/null 2>&1 || true
65
- BRANCH="auto/sync-cli-harnesses-$(date -u +%Y%m%dT%H%M%SZ)"
66
- git checkout -b "$BRANCH"
67
- log "working on branch $BRANCH"
68
-
69
- # ---------------- 4. policy-config neutralization ----------------
70
- # enabledPolicies is a UNION across scopes with no disable field, so a policy must
71
- # be removed from the file that lists it. --skip-worktree then hides that edit from
72
- # git status/add (so it never lands in the PR) while failproofai still reads the
73
- # edited worktree file at runtime. Keeps require-commit/push/pr-before-stop active.
74
- CFG=".failproofai/policies-config.json"
75
- if [ -f "$CFG" ]; then
76
- cfg_tmp="$(mktemp)"
77
- jq '.enabledPolicies |= map(select(. != "require-ci-green-before-stop" and . != "block-read-outside-cwd"))' "$CFG" > "$cfg_tmp" && mv "$cfg_tmp" "$CFG"
78
- git update-index --skip-worktree "$CFG"
79
- log "neutralized require-ci-green-before-stop + block-read-outside-cwd for this run (skip-worktree; not committed)"
80
- else
81
- log "WARN: $CFG not found; running with the repo's default policy set"
82
- fi
83
-
84
- # ---------------- 5. invoke claude (ULTRACODE, headless, PTY-wrapped) ----------------
85
- PROMPT_FILE="$WORKSPACE/$PROMPT_PATH"
86
- if [ ! -f "$PROMPT_FILE" ]; then log "ERROR: prompt missing at $PROMPT_FILE"; exit 65; fi
87
-
88
- # Node block-buffers stdout when it's a pipe; `script -qefc ... /dev/null` gives
89
- # claude a PTY so --output-format stream-json line-flushes to the pod logs. `-e`
90
- # ties script's exit code to claude's.
91
- RUN_SH="$(mktemp /tmp/run-claude.XXXXXX.sh)"
92
- cat >"$RUN_SH" <<EOF
93
- #!/usr/bin/env bash
94
- exec claude --effort ultracode --model ${CLAUDE_MODEL} \\
95
- --verbose --output-format stream-json \\
96
- --dangerously-skip-permissions \\
97
- -p "\$(cat "$PROMPT_FILE")" 2>&1
98
- EOF
99
- chmod +x "$RUN_SH"
100
-
101
- log "invoking claude --effort ultracode --model ${CLAUDE_MODEL} (prompt: $PROMPT_PATH)"
102
- set +e
103
- script -qefc "$RUN_SH" /dev/null
104
- rc=$?
105
- set -e
106
- rm -f "$RUN_SH"
107
- log "claude exited $rc"
108
-
109
- exit "$rc"
@@ -1,47 +0,0 @@
1
- # failproofai CLI-canary sandbox — base image
2
- #
3
- # Design goals (see failproofai-cli-canary-design.md §4):
4
- # - SAFE: non-root user, NO sudo installed, no host FS mounted at runtime.
5
- # The canary fires `sudo whoami` / `.env`-read deny-probes; here they
6
- # are inert BY CONSTRUCTION even on a day enforcement is broken.
7
- # - LIGHT: ephemeral daily container (`docker run --rm`), not a daemon.
8
- # Only this image + one named volume persist; zero idle CPU/RAM.
9
- # - FRESH: CLIs are NOT baked in — they are `@latest`-installed into the
10
- # persistent HOME volume at run time (the whole point of the canary),
11
- # so this base image rebuilds rarely.
12
- #
13
- # The HOME volume (mounted at /home/canary) holds: npm-global CLIs, every
14
- # vendor login/token, and per-CLI config — so logins survive across daily runs.
15
-
16
- FROM node:22-bookworm-slim
17
-
18
- # bun from the official image — no `curl | bash` needed at build time.
19
- COPY --from=oven/bun:latest /usr/local/bin/bun /usr/local/bin/bun
20
-
21
- # Minimal tooling for the various vendor CLI installers. Deliberately NO sudo.
22
- # Tooling for the various vendor installers. Deliberately NO sudo.
23
- # bzip2/xz-utils : goose extracts its Rust binary with these
24
- # libsecret-1-0 : antigravity caches login tokens via libsecret (best-effort)
25
- RUN apt-get update -qq \
26
- && apt-get install -y -qq --no-install-recommends \
27
- git ca-certificates curl unzip bzip2 xz-utils libsecret-1-0 \
28
- && rm -rf /var/lib/apt/lists/*
29
-
30
- # Unprivileged user. HOME is the mount point for the persistent named volume;
31
- # because the image ships a canary-owned /home/canary, an empty named volume
32
- # mounted here is initialised canary-owned (Docker copies image content+owner).
33
- # node:22-slim already ships a `node` user at UID 1000, so pin canary to 1001.
34
- RUN useradd --create-home --uid 1001 --shell /bin/bash canary
35
- USER canary
36
- WORKDIR /home/canary
37
- RUN mkdir -p /home/canary/.npm-global/bin /home/canary/.local/bin
38
-
39
- # NPM_CONFIG_PREFIX via ENV (not `npm config set`) so it survives the volume
40
- # mount shadowing /home/canary at runtime. Runtime `npm i -g` lands in the volume.
41
- ENV NPM_CONFIG_PREFIX=/home/canary/.npm-global
42
- ENV PATH=/home/canary/.npm-global/bin:/home/canary/.local/bin:/usr/local/bin:/usr/bin:/bin
43
-
44
- # Sanity: fail the build if bun/node/npm aren't all runnable as the canary user.
45
- RUN bun --version && node --version && npm --version
46
-
47
- CMD ["bash"]
@@ -1,129 +0,0 @@
1
- # Integration suite
2
-
3
- A daily **live-enforcement integration test** for failproofai. It answers one
4
- question the unit/e2e suites can't: *does failproofai still enforce against every
5
- supported agent CLI, at the versions users actually install today?*
6
-
7
- Every day (`.github/workflows/integration-suite.yml`) it installs all 12 agent
8
- CLIs **@latest** into an isolated Docker sandbox, drives each one against
9
- failproofai's own policies (built from this repo's HEAD), and confirms the hook
10
- log shows a **DENY**. A *silent-allow* — a blocked action that ran with no deny —
11
- means enforcement broke against that CLI (e.g. a vendor changed their hook schema
12
- out from under us). The test asserts the deny **positively**, so drift surfaces
13
- as a red run + a Slack alert instead of going unnoticed until a user hits it.
14
-
15
- ## Why it's separate from `__tests__/`
16
-
17
- It drives **real vendor CLIs against real gateway models** — it needs network,
18
- Docker, credentials, and ~7-10 min, none of which belong in the fast in-process
19
- vitest suites. So it's a scheduled workflow, not a PR gate.
20
-
21
- ## How a run works
22
-
23
- The workflow is a thin trigger; `ci-entrypoint.sh` is the front door and does
24
- everything below except the Actions cache restore/save.
25
-
26
- 1. Restore `integration-suite-state.json` from Actions cache (version-gate +
27
- broke/recovered diff) — *workflow*.
28
- 2. Build failproofai under test (`dist/index.js` + `dist/cli.mjs`) from this repo.
29
- 3. Decode the OAuth token secrets, build the sandbox image, create the per-run
30
- HOME volume, install all 12 CLIs (`install-clis.sh`), inject the credential
31
- files (`inject-tokens.sh`), assemble the gateway env-file.
32
- 4. `run.sh` probes each non-gated CLI (`probe-cli.sh`), builds the report
33
- (`report.js`), and POSTs it to Slack.
34
- 5. Cleanup (env-file + volume) runs via `trap`, so it happens on failure too.
35
-
36
- Run it locally the same way CI does — every input is an env var:
37
-
38
- ```bash
39
- CANARY_LLM_API_KEY=... CANARY_SKIP_BUILD=1 \
40
- bash integration-suite/ci-entrypoint.sh
41
- ```
42
-
43
- **Version-gate:** a CLI is re-probed only when its binary version **or**
44
- failproofai's HEAD changed since its last green run — unchanged ⇒ can't have
45
- drifted ⇒ skip, protecting LLM/vendor quota. `FAIL`/`INCONCLUSIVE`/`ERROR` always
46
- re-probe until they recover. Dispatch with **force** to probe everything.
47
-
48
- ## Two channels: `stable` and `beta`
49
-
50
- The workflow runs as a **matrix over `CANARY_CHANNEL`**, in two concurrent legs
51
- answering different questions:
52
-
53
- | Leg | Installs | Question | On failure |
54
- |-----|----------|----------|------------|
55
- | `stable` | what users get, all 12 CLIs | *is enforcement broken now?* | **fails the job** + Slack |
56
- | `beta` | each vendor's public pre-release ref, 6 CLIs | *is it about to break?* | **advisory only** — never fails |
57
-
58
- Only six vendors publish something usable ahead of their release, so the beta leg
59
- skips the rest rather than re-installing a stable build and reporting it as
60
- pre-release coverage:
61
-
62
- | CLI | Pre-release ref | Typical lead |
63
- |-----|-----------------|--------------|
64
- | codex | npm `alpha` | up to ~12 d (minor bumps only — patches ship blind) |
65
- | copilot | npm `prerelease` | 0.6–5.8 d |
66
- | openclaw | npm `beta` | 0.3–11.4 d |
67
- | cursor | `install?channel=lab` | 2–4 d |
68
- | goose | `CANARY=true` (rolling tag) | ~1 release cycle |
69
- | claude | `latest` — **inverted**, see below | ~13 d |
70
-
71
- **claude runs backwards.** Nothing ships ahead of `latest`, which *is* the
72
- bleeding edge (~1 release/day); what exists is `stable`, ~13 days behind. So the
73
- stable leg pins `bash -s stable` — testing what conservative users run, and
74
- stopping a same-day Anthropic release from red-lighting an unrelated PR — and
75
- `latest` becomes the early-warning ref. **hermes** is inverted too but has no fix:
76
- its installer git-clones `main`, which is also what every hermes user gets, so
77
- there is nothing ahead of us to probe.
78
-
79
- **Escalation is a cross-leg comparison, not a beta failure.** A CLI red on both
80
- legs is already broken and belongs to the stable leg's alarm. The early warning is
81
- `stable green + beta not-green`, held for **two consecutive runs** so a broken
82
- alpha that gets reverted before release doesn't burn attention. Note the signal is
83
- usually `INCONCLUSIVE`/`ERROR`, not `FAIL` — a vendor payload change stops the
84
- model before it ever calls a tool — so a FAIL-only rule would miss it entirely.
85
-
86
- Each leg has its own Docker volume and Actions cache key: a pre-release install
87
- overwrites the stable binary in a shared `$HOME`, and a beta result must never be
88
- able to overwrite the stable leg's gating record.
89
-
90
- ## Auth & secrets (the `cli-integration` Environment)
91
-
92
- > The GitHub **Environment** is still named `cli-integration` — it's configured in
93
- > repo settings, not in this tree, so it was deliberately left alone when this
94
- > directory was renamed. Renaming it there means renaming `environment:` in the
95
- > workflow at the same time, or the job loses access to every secret.
96
-
97
- Because this repo is public, all credentials live in a scoped **GitHub
98
- Environment** (`cli-integration`) — only this workflow's job can read them — and
99
- the workflow triggers on `schedule`/`workflow_dispatch` **only**, so fork PRs can
100
- never reach them.
101
-
102
- | Auth | CLIs | Secret(s) |
103
- |------|------|-----------|
104
- | Env-var (gateway) | claude, codex, goose, opencode, pi, hermes, openclaw, factory | `CANARY_LLM_API_KEY`, `CANARY_LLM_BASE_URL` |
105
- | Env-var (PAT) | copilot | `COPILOT_GITHUB_TOKEN` |
106
- | Injected token file | cursor, devin, antigravity | `CURSOR_/DEVIN_/ANTIGRAVITY_TOKEN_TGZ_B64` |
107
- | Delivery | — | `SLACK_WEBHOOK_URL` |
108
-
109
- The injected-token CLIs carry OAuth session tokens captured from a logged-in
110
- machine (see `capture-tokens.sh`). They authenticate on a fresh runner, but may
111
- eventually expire — when that happens the test reports `⚠️ ERROR` for that CLI;
112
- re-login on the capture machine and refresh the secret.
113
-
114
- > Note: env-var / secret names keep the historical `CANARY_` prefix internally —
115
- > renaming them across the harness would be churn with no user-visible benefit.
116
-
117
- ## Files
118
-
119
- ```
120
- ci-entrypoint.sh CI front door: build -> sandbox -> install -> probe -> cleanup
121
- Dockerfile non-root sandbox base image
122
- install-clis.sh install/upgrade the CLIs for $CANARY_CHANNEL (with retries)
123
- inject-tokens.sh write captured OAuth creds into the fresh volume
124
- probe-cli.sh live enforcement probe for ONE CLI (the oracle)
125
- canary-policies.mjs benign-marker custom policies the probe trips
126
- run.sh orchestrator (gate → probe → report → Slack)
127
- report.js build the Slack report + diff state (broke/recovered)
128
- capture-tokens.sh (run on a logged-in machine) refresh the OAuth token secrets
129
- ```