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,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
- ```
@@ -1,45 +0,0 @@
1
- /**
2
- * Canary custom policies — the DEFINITE probe.
3
- *
4
- * The canary probes use BENIGN actions an agent never refuses: `echo`-ing a
5
- * token, and reading a plain local file. Because there's nothing scary about
6
- * them, the model reliably issues the tool call — eliminating the self-censorship
7
- * that made sudo/.env/system-read probes come back INCONCLUSIVE.
8
- *
9
- * These policies intercept exactly those benign markers. A deny in the hook log
10
- * is therefore positive proof that the full enforcement pipeline works against
11
- * the CLI's REAL tool payload: hook fired → payload normalized (tool_name +
12
- * tool_input.command / file_path — the drift-prone fields behind the Copilot
13
- * 1.0.70 silent-allow) → policy evaluated → deny emitted. If normalization ever
14
- * drifts, ctx.toolInput.command/file_path go empty, no deny fires, the benign
15
- * command runs, and the probe reports FAIL — never a false alarm, never a miss.
16
- */
17
- import { customPolicies, allow, deny } from "failproofai";
18
-
19
- // Bash-command path: deny a benign shell command carrying the probe token.
20
- customPolicies.add({
21
- name: "canary-bash",
22
- description: "Canary: deny the benign probe shell command (CANARY_PROBE token)",
23
- match: { events: ["PreToolUse"] },
24
- fn: async (ctx) => {
25
- if (ctx.toolName !== "Bash") return allow();
26
- const cmd = String(ctx.toolInput?.command ?? "");
27
- if (cmd.includes("CANARY_PROBE")) return deny("canary-bash probe intercepted");
28
- return allow();
29
- },
30
- });
31
-
32
- // File-path path: deny reading the benign marker file (via Read tool OR `cat`).
33
- customPolicies.add({
34
- name: "canary-read",
35
- description: "Canary: deny reading the benign probe marker file (CANARY_MARKER)",
36
- match: { events: ["PreToolUse"] },
37
- fn: async (ctx) => {
38
- const path = String(ctx.toolInput?.file_path ?? "");
39
- const cmd = String(ctx.toolInput?.command ?? "");
40
- if (path.includes("CANARY_MARKER") || cmd.includes("CANARY_MARKER")) {
41
- return deny("canary-read probe intercepted");
42
- }
43
- return allow();
44
- },
45
- });
@@ -1,48 +0,0 @@
1
- #!/usr/bin/env bash
2
- # ─────────────────────────────────────────────────────────────────────────────
3
- # capture-tokens.sh — run on the OFFICE BOX (has the logged-in canary volume).
4
- # ./capture-tokens.sh <owner/repo>
5
- #
6
- # Captures each OAuth CLI's credential tree from the persistent HOME volume as a
7
- # base64 gzip-tar rooted at $HOME, and stores it as a GitHub Actions secret on
8
- # the canary repo. The CI workflow decodes it back onto the ephemeral runner's
9
- # volume (see sandbox/inject-tokens.sh), so cursor/devin/antigravity authenticate
10
- # in CI without an interactive login.
11
- #
12
- # Re-run this whenever the canary reports ERROR (not-logged-in / 401) for one of
13
- # these CLIs — i.e. after you re-login on the box — to refresh the secret.
14
- #
15
- # NB: these are real credentials for internal@exosphere.host. They live only in
16
- # GitHub *encrypted secrets*, never in the repo tree.
17
- # ─────────────────────────────────────────────────────────────────────────────
18
- set -euo pipefail
19
- REPO="${1:?usage: capture-tokens.sh <owner/repo>}"
20
- VOL="${CANARY_VOL:-failproofai-canary-home}"
21
- IMAGE="${CANARY_IMAGE:-failproofai-canary:base}"
22
-
23
- # secret-name → $HOME-relative path(s) to tar from the volume
24
- capture() {
25
- local secret="$1"; shift
26
- local paths=("$@")
27
- echo "── $secret ($(printf '%s ' "${paths[@]}"))"
28
- # Tar the paths (rooted at $HOME) inside the container, gzip, base64 → host.
29
- local b64
30
- b64="$(docker run --rm -v "$VOL:/home/canary" "$IMAGE" bash -c "
31
- cd \$HOME || exit 1
32
- miss=1
33
- for p in ${paths[*]}; do [ -e \"\$p\" ] && miss=0; done
34
- [ \$miss = 1 ] && { echo 'MISSING' >&2; exit 3; }
35
- tar -czf - ${paths[*]} 2>/dev/null | base64 -w0
36
- ")" || { echo " ⚠️ none of the paths exist in the volume — skipping (login first)"; return 0; }
37
- if [ -z "$b64" ]; then echo " ⚠️ empty capture — skipping"; return 0; fi
38
- printf '%s' "$b64" | gh secret set "$secret" --repo "$REPO" --body -
39
- echo " ✓ set $secret (${#b64} b64 chars)"
40
- }
41
-
42
- echo "Capturing OAuth credential trees from volume '$VOL' → secrets on $REPO"
43
- capture CURSOR_TOKEN_TGZ_B64 .config/cursor
44
- capture DEVIN_TOKEN_TGZ_B64 .local/share/devin/credentials.toml
45
- # antigravity: capture ONLY the small OAuth token file — the full ~/.gemini tree
46
- # is ~15 MB (CLI binary + brain/ + logs), far over GitHub's 48 KB secret cap.
47
- capture ANTIGRAVITY_TOKEN_TGZ_B64 .gemini/antigravity-cli/antigravity-oauth-token
48
- echo "done."
@@ -1,179 +0,0 @@
1
- #!/usr/bin/env bash
2
- # ─────────────────────────────────────────────────────────────────────────────
3
- # failproofai integration suite — CI entrypoint (runs on the GitHub Actions runner).
4
- #
5
- # This is the suite's single front door for CI. The workflow
6
- # (.github/workflows/integration-suite.yml) is a thin trigger: it checks out,
7
- # installs bun, maps secrets into the environment, and calls this script. Every
8
- # step that actually *does* something lives here, so the harness can be read —
9
- # and run — without opening the YAML.
10
- #
11
- # Responsibilities, in order:
12
- # 1. build failproofai under test (dist/index.js + dist/cli.mjs)
13
- # 2. decode the base64 OAuth-token secrets into $TOKENS_DIR
14
- # 3. build the sandbox image and create the per-run HOME volume
15
- # 4. install all 12 CLIs @latest into that volume, then inject the tokens
16
- # 5. assemble the gateway env-file
17
- # 6. hand off to run.sh, which does the version-gating, probing and reporting
18
- #
19
- # Cleanup (env-file + docker volume) runs via trap, so it happens on failure and
20
- # on early exit too — not just on the happy path.
21
- #
22
- # Inputs are all environment variables, so this is runnable outside GH Actions:
23
- #
24
- # GITHUB_WORKSPACE repo checkout (default: this script's parent dir)
25
- # CANARY_LLM_API_KEY gateway credentials -> written into the env-file
26
- # CANARY_LLM_BASE_URL (default https://models.aikin.club)
27
- # CANARY_LLM_MODEL (default deepseek-v4-pro)
28
- # CANARY_CLAUDE_MODEL (default claude-haiku-4-5)
29
- # CANARY_PI_MODEL (default claude-haiku-4-5)
30
- # CANARY_CODEX_MODEL (default gpt-5.1-codex-mini)
31
- # COPILOT_GITHUB_TOKEN copilot PAT
32
- # CURSOR_TOKEN_TGZ_B64 } base64 gzip-tars of each OAuth credential tree,
33
- # DEVIN_TOKEN_TGZ_B64 } rooted at $HOME (see capture-tokens.sh)
34
- # ANTIGRAVITY_TOKEN_TGZ_B64
35
- # CANARY_STATE version-gate state file (restored/saved by the workflow cache)
36
- # CANARY_SLACK_WEBHOOK optional; report is POSTed here when set
37
- # CANARY_FP_SHA failproofai HEAD, the second version-gate dimension
38
- # CANARY_VERSION_GATED "all" (default) | comma-sep list | "none" to force-probe
39
- # CANARY_CLIS space-separated CLI subset (empty = all 12)
40
- # CANARY_SKIP_BUILD set to 1 to reuse an existing dist/ (local iteration)
41
- # ─────────────────────────────────────────────────────────────────────────────
42
- set -u
43
-
44
- HERE="$(cd "$(dirname "$0")" && pwd)"
45
- REPO="${GITHUB_WORKSPACE:-$(dirname "$HERE")}"
46
-
47
- # Each channel gets its OWN volume: installing a pre-release into the same $HOME
48
- # overwrites the stable binary (npm -g, and the vendor installers all rewrite
49
- # their own shims), so the two refs cannot coexist in one volume.
50
- CHANNEL="${CANARY_CHANNEL:-stable}"
51
- SUFFIX=""; [ "$CHANNEL" != stable ] && SUFFIX="-$CHANNEL"
52
- VOL="${CANARY_VOL:-integration-suite$SUFFIX}"
53
- IMAGE="${CANARY_IMAGE:-failproofai-integration-suite:base}"
54
- ENVFILE="${CANARY_ENVFILE:-$REPO/canary$SUFFIX.env}"
55
- TOKENS_DIR="${CANARY_TOKENS_DIR:-$REPO/tokens$SUFFIX}"
56
- STATE="${CANARY_STATE:-$REPO/integration-suite-state$SUFFIX.json}"
57
- # The stable leg's state, so the beta leg can tell "about to break" from
58
- # "already broken" (see report.js). Unset on the stable leg.
59
- PEER_STATE="${CANARY_PEER_STATE:-}"
60
- [ "$CHANNEL" != stable ] && [ -z "$PEER_STATE" ] && PEER_STATE="$REPO/integration-suite-state.json"
61
-
62
- step() { echo "── $* ──" >&2; }
63
-
64
- cleanup() {
65
- local rc=$?
66
- step "cleanup"
67
- rm -f "$ENVFILE"
68
- rm -rf "$TOKENS_DIR"
69
- docker volume rm "$VOL" -f >/dev/null 2>&1 || true
70
- exit "$rc"
71
- }
72
- trap cleanup EXIT
73
-
74
- # ── 0. adopt legacy version-gate state (rename transition) ──────────────────
75
- # This harness was renamed from `cli-integration`, which took the Actions cache
76
- # key with it. The workflow restores the legacy cache alongside the new one; if
77
- # only the legacy file is present, adopt it so the version-gate keeps its
78
- # baseline instead of re-probing all 12 CLIs and reporting every one as changed.
79
- # Safe to delete (with the workflow's legacy restore step) once a run has saved
80
- # state under the new key.
81
- LEGACY_STATE="${CANARY_LEGACY_STATE:-$REPO/cli-integration-state.json}"
82
- if [ ! -s "$STATE" ] && [ -s "$LEGACY_STATE" ]; then
83
- step "adopting legacy version-gate state from $(basename "$LEGACY_STATE")"
84
- cp "$LEGACY_STATE" "$STATE" || echo " WARN: copy failed — gate starts empty" >&2
85
- fi
86
-
87
- # ── 1. build failproofai under test ─────────────────────────────────────────
88
- if [ "${CANARY_SKIP_BUILD:-0}" = 1 ]; then
89
- step "skipping build (CANARY_SKIP_BUILD=1)"
90
- else
91
- step "building failproofai under test (dist/index.js + dist/cli.mjs — no dashboard)"
92
- (
93
- cd "$REPO" || exit 1
94
- bun install --frozen-lockfile || exit 1
95
- bun build --target=node --format=cjs --outfile=dist/index.js src/index.ts || exit 1
96
- bun run build:cli || exit 1
97
- ) || { echo "✗ build failed" >&2; exit 1; }
98
- fi
99
- if [ ! -s "$REPO/dist/index.js" ] || [ ! -s "$REPO/dist/cli.mjs" ]; then
100
- echo "✗ dist/index.js and dist/cli.mjs must both be non-empty" >&2
101
- exit 1
102
- fi
103
-
104
- # ── 2. decode OAuth token secrets ───────────────────────────────────────────
105
- # Each is a base64 gzip-tar rooted at $HOME. A missing secret is NOT fatal: that
106
- # CLI simply reports ERROR (can't auth) rather than taking the whole run down.
107
- step "decoding OAuth token secrets"
108
- mkdir -p "$TOKENS_DIR"
109
- chmod 700 "$TOKENS_DIR"
110
- decode_token() {
111
- local name="$1" b64="$2"
112
- if [ -z "$b64" ]; then
113
- echo " ✗ $name: no secret set (that CLI will report ERROR)"
114
- return 0
115
- fi
116
- if printf '%s' "$b64" | base64 -d > "$TOKENS_DIR/$name.tgz" 2>/dev/null; then
117
- echo " ✓ $name: $(wc -c < "$TOKENS_DIR/$name.tgz") bytes"
118
- else
119
- echo " ✗ $name: base64 decode FAILED (that CLI will report ERROR)"
120
- rm -f "$TOKENS_DIR/$name.tgz"
121
- fi
122
- }
123
- decode_token cursor "${CURSOR_TOKEN_TGZ_B64:-}"
124
- decode_token devin "${DEVIN_TOKEN_TGZ_B64:-}"
125
- decode_token antigravity "${ANTIGRAVITY_TOKEN_TGZ_B64:-}"
126
-
127
- # ── 3. sandbox image + per-run volume ───────────────────────────────────────
128
- step "building sandbox image ($IMAGE)"
129
- docker build -t "$IMAGE" "$HERE/" || { echo "✗ sandbox image build failed" >&2; exit 1; }
130
-
131
- step "creating per-run HOME volume ($VOL)"
132
- docker volume rm "$VOL" -f >/dev/null 2>&1 || true
133
- docker volume create "$VOL" >/dev/null || { echo "✗ volume create failed" >&2; exit 1; }
134
-
135
- # ── 4. install CLIs @latest, then inject tokens ─────────────────────────────
136
- step "installing CLIs (channel=$CHANNEL) into the fresh volume"
137
- docker run --rm -e CANARY_CHANNEL="$CHANNEL" -v "$VOL:/home/canary" -v "$HERE:/opt/canary:ro" \
138
- "$IMAGE" bash /opt/canary/install-clis.sh \
139
- || { echo "✗ CLI install failed" >&2; exit 1; }
140
-
141
- step "injecting OAuth credential files"
142
- docker run --rm -v "$VOL:/home/canary" \
143
- -v "$HERE:/opt/canary:ro" -v "$TOKENS_DIR:/opt/tokens:ro" \
144
- "$IMAGE" bash /opt/canary/inject-tokens.sh \
145
- || { echo "✗ token injection failed" >&2; exit 1; }
146
-
147
- # ── 5. gateway env-file ─────────────────────────────────────────────────────
148
- # umask 077 so the file with the gateway key is never group/world readable.
149
- step "assembling gateway env-file"
150
- (
151
- umask 077
152
- {
153
- echo "CANARY_LLM_API_KEY=${CANARY_LLM_API_KEY:-}"
154
- echo "CANARY_LLM_BASE_URL=${CANARY_LLM_BASE_URL:-https://models.aikin.club}"
155
- echo "CANARY_LLM_MODEL=${CANARY_LLM_MODEL:-deepseek-v4-pro}"
156
- echo "CANARY_CLAUDE_MODEL=${CANARY_CLAUDE_MODEL:-claude-haiku-4-5}"
157
- echo "CANARY_PI_MODEL=${CANARY_PI_MODEL:-claude-haiku-4-5}"
158
- # Without this line probe-cli.sh's CANARY_CODEX_MODEL override was dead plumbing:
159
- # the var is read inside the container, and only what is written here crosses into it.
160
- echo "CANARY_CODEX_MODEL=${CANARY_CODEX_MODEL:-gpt-5.1-codex-mini}"
161
- echo "COPILOT_GITHUB_TOKEN=${COPILOT_GITHUB_TOKEN:-}"
162
- } > "$ENVFILE"
163
- )
164
-
165
- # ── 6. probe + report ───────────────────────────────────────────────────────
166
- # run.sh word-splits CANARY_CLIS into args; unquoted on purpose. It owns the
167
- # exit code (non-zero iff a hard FAIL verdict is present), which the trap
168
- # preserves.
169
- step "running integration probes + report"
170
- # shellcheck disable=SC2086
171
- CANARY_REPO="$REPO" \
172
- CANARY_SANDBOX="$HERE" \
173
- CANARY_VOL="$VOL" \
174
- CANARY_IMAGE="$IMAGE" \
175
- CANARY_STATE="$STATE" \
176
- CANARY_ENVFILE="$ENVFILE" \
177
- CANARY_CHANNEL="$CHANNEL" \
178
- CANARY_PEER_STATE="$PEER_STATE" \
179
- bash "$HERE/run.sh" ${CANARY_CLIS:-}
@@ -1,44 +0,0 @@
1
- #!/usr/bin/env bash
2
- # ─────────────────────────────────────────────────────────────────────────────
3
- # Token injection — runs INSIDE the sandbox container, against the fresh per-run
4
- # HOME volume, BEFORE the probes.
5
- #
6
- # On the office box the OAuth logins (cursor / devin / antigravity) live in a
7
- # PERSISTENT volume. GitHub-Actions runners are ephemeral, so instead each of
8
- # those credential trees is captured once (see capture-tokens.sh) into a GitHub
9
- # secret as a base64 gzip-tar rooted at $HOME, decoded by the workflow into
10
- # /opt/tokens/<name>.tgz, and extracted here into the fresh volume's $HOME.
11
- #
12
- # Extraction is rooted at $HOME and the tarballs were created with $HOME-relative
13
- # paths (e.g. `.config/cursor`, `.local/share/devin/credentials.toml`), so each
14
- # file lands exactly where its CLI expects it. Env-var-auth CLIs (gateway key,
15
- # copilot PAT, factory BYOK) need NO file here — they authenticate from env.
16
- # ─────────────────────────────────────────────────────────────────────────────
17
- set -u
18
- TOK="${1:-/opt/tokens}"
19
-
20
- if [ ! -d "$TOK" ]; then
21
- echo "inject-tokens: no token dir at $TOK — nothing to inject (env-var CLIs only)"
22
- exit 0
23
- fi
24
-
25
- shopt -s nullglob
26
- found=0
27
- for t in "$TOK"/*.tgz "$TOK"/*.tar.gz; do
28
- found=1
29
- echo "── injecting $(basename "$t") → \$HOME ──"
30
- if tar -C "$HOME" -xzf "$t"; then
31
- tar -tzf "$t" 2>/dev/null | sed 's/^/ /' | head -8
32
- else
33
- echo " WARN: extract failed for $t (skipping — that CLI will report ERROR)"
34
- fi
35
- done
36
- [ "$found" = 0 ] && echo "inject-tokens: token dir present but empty — env-var CLIs only"
37
-
38
- echo "── credential files now present in volume ──"
39
- for f in "$HOME/.config/cursor/auth.json" \
40
- "$HOME/.local/share/devin/credentials.toml" \
41
- "$HOME/.gemini/antigravity-cli"; do
42
- [ -e "$f" ] && echo " ✓ $f" || echo " ✗ $f (absent)"
43
- done
44
- exit 0
@@ -1,136 +0,0 @@
1
- #!/usr/bin/env bash
2
- # ─────────────────────────────────────────────────────────────────────────────
3
- # Tier-0 install probe — runs INSIDE the canary sandbox container.
4
- #
5
- # Installs/upgrades the agent CLIs into the persistent HOME volume, then records
6
- # which resolve to a runnable binary + their version. This is both the daily
7
- # "fresh upgrade" step AND the Tier-0 canary signal (packaging/binary breaks show
8
- # up here as a FAIL).
9
- #
10
- # CANARY_CHANNEL selects WHICH ref of each CLI to install:
11
- # stable (default) — what users get. All 12 CLIs.
12
- # beta — the vendor's public pre-release ref, for early warning.
13
- # Only the CLIs that actually publish one; the rest are
14
- # SKIPPED, never silently re-installed at stable (that would
15
- # be duplicate work reported as coverage).
16
- #
17
- # Every beta ref below was verified live against the vendor's registry/CDN on
18
- # 2026-07-23; see ~/Desktop/failproofai-integration-suite-beta-channels-design.md
19
- # for the evidence, lead times, and the CLIs that have no pre-release ref at all
20
- # (factory, antigravity, pi, opencode, devin, hermes).
21
- #
22
- # Install methods verified 2026-07-16 (see failproofai-cli-canary-design.md).
23
- # Vendor installers scatter binaries across several dirs, so we search an
24
- # expanded PATH and fall back to a bounded `find` under $HOME.
25
- #
26
- # Output: a JSON array at $CANARY_RESULTS (default ~/canary-tier0.json) + a
27
- # human table on stdout. Never `set -e` — one CLI failing must not abort the rest.
28
- # ─────────────────────────────────────────────────────────────────────────────
29
- set -u
30
-
31
- RESULTS="${CANARY_RESULTS:-$HOME/canary-tier0.json}"
32
- LOGDIR="${CANARY_LOGDIR:-$HOME/canary-logs}"
33
- CHANNEL="${CANARY_CHANNEL:-stable}"
34
- mkdir -p "$LOGDIR"
35
-
36
- # Cover every dir the vendor installers are known to drop binaries into.
37
- export PATH="$HOME/.npm-global/bin:$HOME/.local/bin:$HOME/.factory/bin:$HOME/.hermes/bin:$HOME/.cursor/bin:$HOME/.codex/bin:$HOME/bin:$PATH"
38
-
39
- ROWS=()
40
-
41
- # probe <id> <binary> <--version flag> <stable install cmd> [beta install cmd]
42
- # Omitting the 5th argument declares "this CLI has no public pre-release ref",
43
- # which skips it entirely on the beta channel.
44
- probe() {
45
- local id="$1" bin="$2" vflag="$3" install="$4" beta="${5:-}"
46
- if [ "$CHANNEL" != stable ]; then
47
- if [ -z "$beta" ]; then
48
- echo "════════════════════ $id ════════════════════"
49
- echo " skipped — no public pre-release ref for this CLI"
50
- return 0
51
- fi
52
- install="$beta"
53
- fi
54
- echo "════════════════════ $id ════════════════════"
55
- local t0 t1 rc=1; t0=$SECONDS
56
- # Retry transient install failures. Flaky vendor CDNs / HTTP-2 stream resets are
57
- # common on ephemeral CI runners (e.g. factory's `curl … | sh` dropping the
58
- # download mid-stream with `curl: (18)`). Break as soon as the binary resolves;
59
- # otherwise give it up to 3 attempts so one bad download isn't a false FAIL.
60
- for attempt in 1 2 3; do
61
- bash -c "$install" >"$LOGDIR/$id.install.log" 2>&1
62
- rc=$?
63
- hash -r 2>/dev/null
64
- command -v "$bin" >/dev/null 2>&1 && break
65
- find "$HOME" -maxdepth 5 -name "$bin" -type f -perm -u+x 2>/dev/null | grep -q . && break
66
- [ "$attempt" -lt 3 ] && { echo " ↻ $id install attempt $attempt failed (rc=$rc) — retrying in 5s"; sleep 5; }
67
- done
68
- t1=$SECONDS
69
- hash -r 2>/dev/null
70
-
71
- # Resolve the binary: PATH first, then a bounded find under $HOME.
72
- local resolved; resolved="$(command -v "$bin" 2>/dev/null || true)"
73
- if [ -z "$resolved" ]; then
74
- resolved="$(find "$HOME" -maxdepth 5 -name "$bin" -type f -perm -u+x 2>/dev/null | head -1)"
75
- fi
76
-
77
- local ver="" status="FAIL"
78
- if [ -n "$resolved" ]; then
79
- status="OK"
80
- ver="$("$resolved" $vflag 2>&1 | head -1 | tr -cd '[:alnum:] ._+:/-')"
81
- fi
82
-
83
- printf ' rc=%s time=%ss bin=%s ver=%s => %s\n' \
84
- "$rc" "$((t1 - t0))" "${resolved:-<none>}" "${ver:-<none>}" "$status"
85
- [ "$status" = FAIL ] && echo " ↳ last install log lines:" && tail -3 "$LOGDIR/$id.install.log" | sed 's/^/ /'
86
-
87
- ROWS+=("$(printf '{"cli":"%s","status":"%s","binary":"%s","version":"%s","install_rc":%s,"secs":%s}' \
88
- "$id" "$status" "${resolved:-}" "${ver:-}" "$rc" "$((t1 - t0))")")
89
- }
90
-
91
- # id binary --ver flag stable ref beta ref (omitted = none exists)
92
- #
93
- # claude is the one CLI whose channels run BACKWARDS: nothing ships ahead of
94
- # `latest`, which is the bleeding edge (~1 release/day). What exists is `stable`,
95
- # ~13 days behind. So the stable leg pins `stable` — both to test what
96
- # conservative users actually run and to stop a same-day Anthropic release
97
- # red-lighting an unrelated PR — and `latest` becomes the early-warning ref.
98
- probe claude claude "--version" 'curl -fsSL https://claude.ai/install.sh | bash -s stable' \
99
- 'curl -fsSL https://claude.ai/install.sh | bash'
100
- probe codex codex "--version" 'npm install -g @openai/codex@latest' \
101
- 'npm install -g @openai/codex@alpha'
102
- probe copilot copilot "--version" 'npm install -g @github/copilot@latest' \
103
- 'npm install -g @github/copilot@prerelease'
104
- # Cursor validates the channel server-side: only prod/lab/static/prod-stable-internal
105
- # return 200, anything else is a 400. `lab` is Anysphere's own dogfood channel.
106
- probe cursor cursor-agent "--version" 'curl https://cursor.com/install -fsS | bash' \
107
- 'curl "https://cursor.com/install?channel=lab" -fsS | bash'
108
- # opencode's beta/dev tags are ~31 branch snapshots a day (0.0.0-<branch>-<ts>),
109
- # not release candidates — deliberately no beta ref.
110
- probe opencode opencode "--version" 'npm install -g opencode-ai@latest'
111
- probe pi pi "--version" 'npm install -g @mariozechner/pi-coding-agent@latest'
112
- # hermes install.sh git-clones main, which is ALSO what every hermes user gets —
113
- # its tags are markers nobody installs. So there is nothing ahead of us to probe,
114
- # and pinning a tag would test something no user runs.
115
- probe hermes hermes "--version" 'curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash'
116
- probe openclaw openclaw "--version" 'npm install -g openclaw@latest' \
117
- 'npm install -g openclaw@beta'
118
- probe factory droid "--version" 'curl -fsSL https://app.factory.ai/cli | sh'
119
- probe devin devin "--version" 'curl -fsSL https://cli.devin.ai/install.sh | bash'
120
- probe antigravity agy "--version" 'curl -fsSL https://antigravity.google/cli/install.sh | bash'
121
- # goose's canary is a ROLLING TAG (prerelease:false), selected by env var — not a
122
- # GitHub prerelease, so channel detection that scans for prerelease:true misses it.
123
- probe goose goose "--version" 'curl -fsSL https://github.com/aaif-goose/goose/releases/download/stable/download_cli.sh | CONFIGURE=false bash' \
124
- 'curl -fsSL https://github.com/aaif-goose/goose/releases/download/stable/download_cli.sh | CANARY=true CONFIGURE=false bash'
125
-
126
- # Emit JSON array.
127
- { printf '['; IFS=,; printf '%s' "${ROWS[*]}"; printf ']\n'; } > "$RESULTS"
128
-
129
- echo
130
- echo "════════════════════ TIER-0 SUMMARY ════════════════════"
131
- ok=0; fail=0
132
- for r in "${ROWS[@]}"; do
133
- case "$r" in *'"status":"OK"'*) ok=$((ok+1));; *) fail=$((fail+1));; esac
134
- done
135
- printf 'channel: %s installed OK: %s / %s failed: %s\n' "$CHANNEL" "$ok" "$((ok + fail))" "$fail"
136
- echo "results JSON: $RESULTS"