failproofai 1.0.12 → 1.0.13-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (306) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/build-manifest.json +13 -13
  3. package/.next/standalone/.next/prerender-manifest.json +4 -4
  4. package/.next/standalone/.next/required-server-files.json +1 -1
  5. package/.next/standalone/.next/server/app/_global-error/page/build-manifest.json +2 -2
  6. package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
  7. package/.next/standalone/.next/server/app/_global-error/page.js +2 -1
  8. package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  9. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  10. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  11. package/.next/standalone/.next/server/app/_global-error.rsc +2 -2
  12. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +2 -2
  13. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +2 -2
  14. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  15. package/.next/standalone/.next/server/app/_not-found/page/build-manifest.json +2 -2
  16. package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  17. package/.next/standalone/.next/server/app/_not-found/page.js +4 -3
  18. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  19. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  20. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  21. package/.next/standalone/.next/server/app/_not-found.rsc +3 -3
  22. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  23. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  24. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  25. package/.next/standalone/.next/server/app/api/audit/invite/route.js +6 -5
  26. package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -1
  27. package/.next/standalone/.next/server/app/api/audit/run/route.js +27 -26
  28. package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
  29. package/.next/standalone/.next/server/app/api/audit/status/route.js +4 -3
  30. package/.next/standalone/.next/server/app/api/audit/status/route.js.nft.json +1 -1
  31. package/.next/standalone/.next/server/app/api/auth/login-request/route.js +6 -5
  32. package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
  33. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js +6 -5
  34. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
  35. package/.next/standalone/.next/server/app/api/auth/logout/route.js +6 -5
  36. package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
  37. package/.next/standalone/.next/server/app/api/auth/status/route.js +6 -5
  38. package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
  39. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js +4 -3
  40. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
  41. package/.next/standalone/.next/server/app/audit/page/build-manifest.json +2 -2
  42. package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
  43. package/.next/standalone/.next/server/app/audit/page.js +7 -6
  44. package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
  45. package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
  46. package/.next/standalone/.next/server/app/index.html +1 -1
  47. package/.next/standalone/.next/server/app/index.rsc +3 -3
  48. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  49. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +3 -3
  50. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  51. package/.next/standalone/.next/server/app/page/build-manifest.json +2 -2
  52. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
  53. package/.next/standalone/.next/server/app/page.js +6 -5
  54. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  55. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  56. package/.next/standalone/.next/server/app/policies/page/build-manifest.json +2 -2
  57. package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +14 -14
  58. package/.next/standalone/.next/server/app/policies/page.js +5 -4
  59. package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
  60. package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
  61. package/.next/standalone/.next/server/app/project/[name]/page/build-manifest.json +2 -2
  62. package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
  63. package/.next/standalone/.next/server/app/project/[name]/page.js +21 -20
  64. package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
  65. package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
  66. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/build-manifest.json +2 -2
  67. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
  68. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
  69. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js +10 -9
  70. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
  71. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
  72. package/.next/standalone/.next/server/app/projects/page/build-manifest.json +2 -2
  73. package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
  74. package/.next/standalone/.next/server/app/projects/page.js +7 -6
  75. package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
  76. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  77. package/.next/standalone/.next/server/app/settings/page/build-manifest.json +2 -2
  78. package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +8 -8
  79. package/.next/standalone/.next/server/app/settings/page.js +6 -5
  80. package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
  81. package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  82. package/.next/standalone/.next/server/chunks/{[externals]__0vt9i6fqinjne._.js → [externals]__1h83uo-b1b6-2._.js} +1 -1
  83. package/.next/standalone/.next/server/chunks/[externals]__214wn4wh2x79y._.js +3 -0
  84. package/.next/standalone/.next/server/chunks/{[externals]__1rlxpymm37wel._.js → [root-of-the-server]__031qp1lkow_kc._.js} +2 -2
  85. package/.next/standalone/.next/server/chunks/[root-of-the-server]__038kwryp970nh._.js +3 -0
  86. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0_hsnj_a2mvl_._.js → [root-of-the-server]__03s1za0hn71yp._.js} +2 -2
  87. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0wg9dk8x8bnau._.js → [root-of-the-server]__07a0sa6fuw5_b._.js} +2 -2
  88. package/.next/standalone/.next/server/chunks/[root-of-the-server]__08atcie7jzswm._.js +3 -0
  89. package/.next/standalone/.next/server/chunks/[root-of-the-server]__08dchfudh2_4f._.js +1 -1
  90. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0car70pylmvor._.js +3 -0
  91. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0spt0kv8azrpl._.js +1 -1
  92. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__12kq3x-h7t7i1._.js → [root-of-the-server]__0yvyp5b7jmlc4._.js} +2 -2
  93. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__02vous7mpi2xm._.js → [root-of-the-server]__145vo_drnuvas._.js} +2 -2
  94. package/.next/standalone/.next/server/chunks/{[externals]__0h0p9dmv_e7r7._.js → [root-of-the-server]__1a2d0ewycsp6k._.js} +2 -2
  95. package/.next/standalone/.next/server/chunks/{[externals]__1_407huhlmj1m._.js → [root-of-the-server]__1am_1tz0o0aqz._.js} +2 -2
  96. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__03i5o4a840guz._.js → [root-of-the-server]__1gxfzuvpyw30j._.js} +1 -1
  97. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1j6kfp0vzu5rw._.js +3 -0
  98. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1l0ayum_hqqsw._.js +3 -0
  99. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1lh8c0mmhdrbj._.js +3 -0
  100. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1o9rznwc0w7og._.js +3 -0
  101. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0f_4g-vazrvxv._.js → [root-of-the-server]__1o_622x0fglpr._.js} +1 -1
  102. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1oclamblhzhrf._.js +68 -0
  103. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1v1-l-83czzsr._.js +63 -0
  104. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__1a5zkndjwlc13._.js → [root-of-the-server]__1wwi53kkqhnfi._.js} +1 -1
  105. package/.next/standalone/.next/server/chunks/{_1y590mjzpkbos._.js → _02sa8fcu9_9xo._.js} +2 -2
  106. package/.next/standalone/.next/server/chunks/_0tovk6q0miud6._.js +1 -1
  107. package/.next/standalone/.next/server/chunks/_0trp3ycqv17cl._.js +1 -1
  108. package/.next/standalone/.next/server/chunks/_1-2owkp-1_987._.js +1 -1
  109. package/.next/standalone/.next/server/chunks/_13ltj8a9z92o8._.js +1 -1
  110. package/.next/standalone/.next/server/chunks/_15k37au70vjvg._.js +1 -1
  111. package/.next/standalone/.next/server/chunks/_18rfu4__wjhwb._.js +1 -1
  112. package/.next/standalone/.next/server/chunks/_1ek68lnh2daur._.js +2 -2
  113. package/.next/standalone/.next/server/chunks/_1fz8m31sndkcu._.js +1 -1
  114. package/.next/standalone/.next/server/chunks/_1ogwigfb0163w._.js +1 -1
  115. package/.next/standalone/.next/server/chunks/_1vslkoe35wok6._.js +1 -1
  116. package/.next/standalone/.next/server/chunks/node_modules_@opentelemetry_api_build_esm_index_0oo58a7rymoxh.js +3 -0
  117. package/.next/standalone/.next/server/chunks/node_modules_@opentelemetry_api_build_esm_index_1jp9ij0_ddtgk.js +3 -0
  118. package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_01r25oigsgz07._.js +2 -2
  119. package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_09z9-p77cu37y._.js +2 -2
  120. package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4vkpxxu7._.js +1 -1
  121. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0ffu2-38y03ic._.js → [root-of-the-server]__021vebe-4il8s._.js} +1 -1
  122. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__075uro8t92s0_._.js +14 -0
  123. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__08ch3staq3ejw._.js +1 -1
  124. package/.next/standalone/.next/server/chunks/ssr/{[externals]__12qr51qgrrt6o._.js → [root-of-the-server]__097i34ct1o88x._.js} +2 -2
  125. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0alpzjn3450sr._.js +3 -0
  126. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0aup10z2o8zc1._.js +3 -0
  127. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0bigvy9xmv2ka._.js +1 -1
  128. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0bioghlkjf7s7._.js +3 -0
  129. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__01j58mdcdw0vn._.js → [root-of-the-server]__0ed1zh4scn7-k._.js} +1 -1
  130. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0naevg4bcoh54._.js → [root-of-the-server]__0evgy902m9h5e._.js} +2 -2
  131. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0h86bl2qf0k_o._.js +1 -1
  132. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__167mipqmjprq5._.js → [root-of-the-server]__0mhtkwwx1pxcq._.js} +2 -2
  133. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0nhm28v58ty9z._.js +3 -0
  134. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0pia5h3p8re4c._.js +1 -1
  135. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0vse4qi496ol-._.js +3 -0
  136. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__17r4zrwanhp6r._.js → [root-of-the-server]__0yb3u36xjy3b9._.js} +1 -1
  137. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0g8b0kyorya-t._.js → [root-of-the-server]__0ywj2u6ovfm_5._.js} +1 -1
  138. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1-ey9fgesfbc0._.js +1 -1
  139. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0zn1d4blhd3bu._.js → [root-of-the-server]__10v5cyxvj64j4._.js} +1 -1
  140. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__15usvs-ms-0hf._.js +1 -1
  141. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__16gb3_92zvk5x._.js +1 -1
  142. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__190xwrr5zrfi3._.js +3 -0
  143. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1avi2kypusyb_._.js +1 -1
  144. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1vx7o8ukefudh._.js → [root-of-the-server]__1guwlpkyurdn9._.js} +1 -1
  145. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1k96jctukf65_._.js +3 -0
  146. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1r7drlqli-ado._.js +1 -1
  147. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1sj-wn2jp6va5._.js +3 -0
  148. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1vofkb2oq7p7e._.js +1 -1
  149. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1s2-ck3k3rsoo._.js → [root-of-the-server]__20dt376-socef._.js} +1 -1
  150. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1lnfv02ucky7m._.js → [root-of-the-server]__2158020r_amn9._.js} +1 -1
  151. package/.next/standalone/.next/server/chunks/ssr/{_1d98fyfrcaqhy._.js → _0bc4f4quq6w47._.js} +2 -2
  152. package/.next/standalone/.next/server/chunks/ssr/_0eoura3_9gjb-._.js +1 -1
  153. package/.next/standalone/.next/server/chunks/ssr/_0ouu886szh6yj._.js +1 -1
  154. package/.next/standalone/.next/server/chunks/ssr/_0pedwblqdoh58._.js +1 -1
  155. package/.next/standalone/.next/server/chunks/ssr/_1_ozgifqv1ssi._.js +1 -1
  156. package/.next/standalone/.next/server/chunks/ssr/_1djqs9i27e4kg._.js +1 -1
  157. package/.next/standalone/.next/server/chunks/ssr/_next-internal_server_app_policies_page_actions_1sp2-yo5_vm5f.js +2 -2
  158. package/.next/standalone/.next/server/chunks/ssr/app_actions_get-scheduled-audit_ts_0ei9snixb5fd-._.js +1 -1
  159. package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47q0xq5w._.js +1 -1
  160. package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x33jqb6._.js +1 -1
  161. package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpcz0uxur._.js +1 -1
  162. package/.next/standalone/.next/server/chunks/ssr/app_settings_02tf1h47jmhhd._.js +1 -1
  163. package/.next/standalone/.next/server/chunks/ssr/{node_modules_09s4n108bqreq._.js → node_modules_0ptcnmeaxvd_a._.js} +22 -2
  164. package/.next/standalone/.next/server/chunks/ssr/node_modules_@opentelemetry_api_build_esm_index_0ntwr8lzj6p2i.js +3 -0
  165. package/.next/standalone/.next/server/chunks/ssr/{node_modules_html-to-image_es_index_0tqc05n832v7a.js → node_modules_html-to-image_es_index_1jwgv0pf-gy96.js} +1 -1
  166. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_0bz67659f5z-3._.js +32 -0
  167. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_0janj0i6dqko7._.js +3 -3
  168. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_0ocrceo0c9psx._.js +32 -0
  169. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_1alv566ojmz5j._.js +32 -0
  170. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_1khq67j4vo9y4._.js +3 -0
  171. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_shared_lib_0ftnv26hg1lry._.js +3 -0
  172. package/.next/standalone/.next/server/chunks/ssr/node_modules_posthog-node_dist_entrypoints_index_node_mjs_0dagmbznysrc2._.js +1 -1
  173. package/.next/standalone/.next/server/chunks/ssr/node_modules_posthog-node_dist_entrypoints_index_node_mjs_11bnuznb72p7z._.js +2 -2
  174. package/.next/standalone/.next/server/chunks/ssr/package_json_[json]_cjs_013tntikdft59._.js +1 -1
  175. package/.next/standalone/.next/server/middleware-build-manifest.js +13 -13
  176. package/.next/standalone/.next/server/middleware.js +2 -2
  177. package/.next/standalone/.next/server/pages/404.html +1 -1
  178. package/.next/standalone/.next/server/pages/500.html +1 -1
  179. package/.next/standalone/.next/server/preview-props.json +3 -3
  180. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  181. package/.next/standalone/.next/server/server-reference-manifest.json +23 -23
  182. package/.next/standalone/.next/static/chunks/0cbom4-ijx_a_.js +1 -0
  183. package/.next/standalone/.next/static/chunks/0u5weo5jdn2s8.js +1 -0
  184. package/.next/standalone/.next/static/chunks/{0el9n3h9_zp5m.js → 18-icoqze51kl.js} +1 -1
  185. package/.next/standalone/.next/static/chunks/2d-u90dt4-8rd.js +6 -0
  186. package/.next/standalone/.next/static/chunks/2n-bzb7pxe7hu.js +1 -0
  187. package/.next/standalone/.next/static/chunks/{0umzct31duk5g.js → 2zc7lg-jq353g.js} +1 -1
  188. package/.next/standalone/.next/static/chunks/{27cavoc8paelg.js → 33djjf12bhcsv.js} +1 -1
  189. package/.next/standalone/.next/static/chunks/{0wobqgosirs8p.js → 38u_i3j5funpi.js} +1 -1
  190. package/.next/standalone/.next/static/chunks/3symuj7t4js-c.js +1 -0
  191. package/.next/standalone/.next/static/chunks/{1kduj74-715jh.js → 3vzut6zpdrvtx.js} +1 -1
  192. package/.next/standalone/.next/static/chunks/{063al_q720fkj.js → 3xgxl1s_in776.js} +2 -2
  193. package/.next/standalone/SECURITY.md +20 -4
  194. package/.next/standalone/fp-cloud-cli/CHANGELOG.md +15 -1
  195. package/.next/standalone/fp-cloud-cli/fp_cli/_version.py +1 -1
  196. package/.next/standalone/fp-cloud-cli/uv.lock +4 -4
  197. package/.next/standalone/hermes-plugin/plugin.yaml +1 -1
  198. package/.next/standalone/node_modules/@next/env/package.json +1 -1
  199. package/.next/standalone/node_modules/next/dist/build/swc/index.js +1 -1
  200. package/.next/standalone/node_modules/next/dist/compiled/next-server/app-page-turbo-experimental.runtime.prod.js +24 -24
  201. package/.next/standalone/node_modules/next/dist/compiled/next-server/app-page-turbo.runtime.prod.js +26 -26
  202. package/.next/standalone/node_modules/next/dist/compiled/next-server/app-route-turbo.runtime.prod.js +3 -3
  203. package/.next/standalone/node_modules/next/dist/compiled/next-server/pages-turbo.runtime.prod.js +13 -13
  204. package/.next/standalone/node_modules/next/dist/lib/patch-incorrect-lockfile.js +3 -3
  205. package/.next/standalone/node_modules/next/dist/server/app-render/app-render.js +41 -40
  206. package/.next/standalone/node_modules/next/dist/server/app-render/async-local-storage.js +1 -1
  207. package/.next/standalone/node_modules/next/dist/server/app-render/dynamic-rendering-validation.js +814 -0
  208. package/.next/standalone/node_modules/next/dist/server/app-render/dynamic-rendering.js +1 -799
  209. package/.next/standalone/node_modules/next/dist/server/base-server.js +39 -5
  210. package/.next/standalone/node_modules/next/dist/server/config.js +1 -1
  211. package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-turbopack.js +2 -2
  212. package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-webpack.js +1 -1
  213. package/.next/standalone/node_modules/next/dist/server/lib/app-info-log.js +1 -1
  214. package/.next/standalone/node_modules/next/dist/server/lib/dedupe-fetch.js +4 -43
  215. package/.next/standalone/node_modules/next/dist/server/lib/patch-fetch-symbol.js +13 -0
  216. package/.next/standalone/node_modules/next/dist/server/lib/patch-fetch.js +3 -7
  217. package/.next/standalone/node_modules/next/dist/server/lib/router-server.js +3 -3
  218. package/.next/standalone/node_modules/next/dist/server/lib/router-utils/instrumentation-globals.external.js +77 -12
  219. package/.next/standalone/node_modules/next/dist/server/lib/start-server.js +1 -1
  220. package/.next/standalone/node_modules/next/dist/server/lib/trace/constants.js +12 -0
  221. package/.next/standalone/node_modules/next/dist/server/lib/trace/tracer.js +30 -14
  222. package/.next/standalone/node_modules/next/dist/server/next-server.js +10 -11
  223. package/.next/standalone/node_modules/next/dist/server/route-modules/pages/pages-handler.js +29 -23
  224. package/.next/standalone/node_modules/next/dist/server/route-modules/route-module.js +85 -8
  225. package/.next/standalone/node_modules/next/dist/server/use-cache/use-cache-wrapper.js +1 -1
  226. package/.next/standalone/node_modules/next/dist/server/web/adapter.js +124 -65
  227. package/.next/standalone/node_modules/next/dist/server/web/forward-trace-context.js +102 -0
  228. package/.next/standalone/node_modules/next/dist/telemetry/anonymous-meta.js +1 -1
  229. package/.next/standalone/node_modules/next/dist/telemetry/events/swc-load-failure.js +1 -1
  230. package/.next/standalone/node_modules/next/dist/telemetry/events/version.js +2 -2
  231. package/.next/standalone/node_modules/next/package.json +10 -10
  232. package/.next/standalone/node_modules/react/cjs/react.production.js +1 -1
  233. package/.next/standalone/node_modules/react/package.json +1 -1
  234. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server-legacy.browser.production.js +1 -1
  235. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server-legacy.node.production.js +1 -1
  236. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server.browser.production.js +31 -27
  237. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server.edge.production.js +33 -27
  238. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server.node.production.js +38 -30
  239. package/.next/standalone/node_modules/react-dom/cjs/react-dom.production.js +1 -1
  240. package/.next/standalone/node_modules/react-dom/package.json +2 -2
  241. package/.next/standalone/package.json +10 -10
  242. package/.next/standalone/sdk/python/CHANGELOG.md +8 -4
  243. package/.next/standalone/sdk/python/failproofai_sdk/evaluator/source.py +2 -2
  244. package/.next/standalone/sdk/python/pyproject.toml +2 -7
  245. package/.next/standalone/sdk/python/skill/references/frameworks.md +0 -15
  246. package/.next/standalone/sdk/python/tests/test_docs.py +1 -4
  247. package/.next/standalone/sdk/python/tests/test_evaluator_source.py +1 -1
  248. package/.next/standalone/sdk/python/tests/test_packaging.py +4 -7
  249. package/.next/standalone/sdk/python/tests/test_zero_dependencies.py +2 -13
  250. package/.next/standalone/sdk/python/uv.lock +43 -905
  251. package/.next/standalone/sdk/typescript/CHANGELOG.md +52 -0
  252. package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/package-lock.json +176 -68
  253. package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/package.json +2 -2
  254. package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/package-lock.json +3 -3
  255. package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/package.json +1 -1
  256. package/.next/standalone/sdk/typescript/integration/fixtures/langchain-0.3/package-lock.json +115 -98
  257. package/.next/standalone/sdk/typescript/integration/fixtures/langchain-0.3/package.json +3 -3
  258. package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/package-lock.json +4 -4
  259. package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/package.json +1 -1
  260. package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.11/package-lock.json +171 -149
  261. package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.11/package.json +5 -2
  262. package/.next/standalone/sdk/typescript/integration/fixtures/mastra-1/package-lock.json +27 -15
  263. package/.next/standalone/sdk/typescript/integration/fixtures/mastra-1/package.json +2 -1
  264. package/.next/standalone/sdk/typescript/integration/fixtures/runtimes/deno-npm.ts +1 -1
  265. package/.next/standalone/server.js +1 -1
  266. package/README.md +0 -6
  267. package/dist/cli.mjs +12 -11
  268. package/dist/worker.mjs +1 -1
  269. package/hermes-plugin/plugin.yaml +1 -1
  270. package/openclaw-plugin/daemon-client.js +254 -0
  271. package/openclaw-plugin/hooks.js +187 -0
  272. package/openclaw-plugin/index.js +17 -211
  273. package/package.json +10 -10
  274. package/scripts/sync-agent-cli-harnesses-prompt.md +26 -31
  275. package/src/hooks/enforcement-capability.ts +1 -1
  276. package/src/hooks/integrations.ts +5 -2
  277. package/.next/standalone/.codex/hooks.json +0 -76
  278. package/.next/standalone/.cursor/hooks.json +0 -47
  279. package/.next/standalone/.factory/hooks.json +0 -112
  280. package/.next/standalone/.next/server/chunks/[externals]__1x24dzcbbq6-g._.js +0 -3
  281. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0__a_je8fsn65._.js +0 -3
  282. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0l-oi4gdtmlo5._.js +0 -3
  283. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0t9ufnv5hi2hq._.js +0 -327
  284. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1aaw59g-5uty7._.js +0 -322
  285. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1hqpg6vgmfexv._.js +0 -3
  286. package/.next/standalone/.next/server/chunks/ssr/[externals]__0ilfh9mfnzsth._.js +0 -3
  287. package/.next/standalone/.next/server/chunks/ssr/[externals]__0ohnuzsaozaca._.js +0 -3
  288. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0pwj2h2efe5f-._.js +0 -14
  289. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_0zuikgt2xho-v._.js +0 -271
  290. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_158jo-9mwvgad._.js +0 -291
  291. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_19r82zsxo2jj1._.js +0 -291
  292. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_1dupwucoqt5qm._.js +0 -3
  293. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_shared_lib_03w27x2kh17_8._.js +0 -23
  294. package/.next/standalone/.next/static/chunks/0k7g_8x3o6gd-.js +0 -1
  295. package/.next/standalone/.next/static/chunks/12rug3jilwqzs.js +0 -1
  296. package/.next/standalone/.next/static/chunks/2701amhrbsbot.js +0 -1
  297. package/.next/standalone/.next/static/chunks/2ve23a7keupjw.js +0 -1
  298. package/.next/standalone/.next/static/chunks/3bv6xaoitjpnh.js +0 -6
  299. package/.next/standalone/.opencode/opencode.json +0 -4
  300. package/.next/standalone/.opencode/plugins/failproofai.mjs +0 -210
  301. package/.next/standalone/.pi/settings.json +0 -5
  302. package/.next/standalone/node_modules/react/cjs/react.development.js +0 -1330
  303. package/scripts/dev-hook.mjs +0 -333
  304. /package/.next/standalone/.next/static/{D7LY1YSrw96ZxKSpxxrFw → 1n2dyfTQb0MDajeqlipJy}/_buildManifest.js +0 -0
  305. /package/.next/standalone/.next/static/{D7LY1YSrw96ZxKSpxxrFw → 1n2dyfTQb0MDajeqlipJy}/_clientMiddlewareManifest.js +0 -0
  306. /package/.next/standalone/.next/static/{D7LY1YSrw96ZxKSpxxrFw → 1n2dyfTQb0MDajeqlipJy}/_ssgManifest.js +0 -0
package/dist/worker.mjs CHANGED
@@ -1166,7 +1166,7 @@ function instruct(reason) {
1166
1166
  }
1167
1167
 
1168
1168
  // package.json
1169
- var version = "1.0.12";
1169
+ var version = "1.0.13-beta.1";
1170
1170
  var init_package = () => {};
1171
1171
 
1172
1172
  // src/hooks/agent-targets.ts
@@ -1,5 +1,5 @@
1
1
  name: failproofai
2
- version: 1.0.12
2
+ version: 1.0.13-beta.1
3
3
  description: Real-time FailproofAI policy enforcement for Hermes
4
4
  manifest_version: 2
5
5
  api_version: 1
@@ -0,0 +1,254 @@
1
+ /**
2
+ * Asks failproofaid for a verdict over its owner-only Unix socket — the same
3
+ * `hook` request `failproofai --hook <event> --cli openclaw` sends to the
4
+ * daemon (crates/PROTOCOL.md), made from inside the gateway instead of from a
5
+ * process spawned per hook. The Hermes plugin (hermes-plugin/client.py) reaches
6
+ * the daemon the same way.
7
+ *
8
+ * Why not spawn the CLI: OpenClaw ≥ 2026.9.6 imports this plugin from a copy
9
+ * under ~/.openclaw/tmp/plugin-captures/…, and the copy holds only this
10
+ * directory's files. A CLI path derived from import.meta.url (`../dist/cli.mjs`)
11
+ * then points at nothing; the old shim read the spawn failure as "allow", so
12
+ * every tool call ran unchecked and no hook activity was recorded. The socket
13
+ * path depends only on the environment, never on where this file sits.
14
+ *
15
+ * Self-contained on purpose — node built-ins only, nothing imported from
16
+ * outside this directory — because the capture copies nothing else.
17
+ */
18
+ import { createConnection } from "node:net";
19
+ import { homedir } from "node:os";
20
+ import { resolve } from "node:path";
21
+
22
+ export const PROTOCOL_VERSION = 2;
23
+ // The daemon's frame limit (crates/fpai-ipc/src/framing.rs), both ways.
24
+ const MAX_FRAME_BYTES = 16 * 1024 * 1024;
25
+ // The payload limit the CLI applies to its stdin (handler.ts, read-stdin.ts).
26
+ // It bounds the RAW payload: the envelope carries it as an escaped JSON
27
+ // string plus routing fields, so it is larger, and only the frame limit
28
+ // applies to the envelope.
29
+ export const MAX_PAYLOAD_BYTES = 1_048_576;
30
+
31
+ // The CLI's daemon client budgets these separately for the reason it gives:
32
+ // connecting is the "is anything listening" probe, the response covers the
33
+ // whole evaluation. 250 ms matches the Hermes plugin; 30 s matches the
34
+ // daemon's own read timeout on its worker (worker.rs).
35
+ export const CONNECT_TIMEOUT_MS = 250;
36
+ export const RESPONSE_TIMEOUT_MS = 30_000;
37
+
38
+ const PROTOCOL_MISMATCH_MESSAGE =
39
+ "failproofaid is running a different protocol version than this plugin, so it cannot " +
40
+ "evaluate this call. Run `failproofai update` to update the daemon.";
41
+ const UNREACHABLE_MESSAGE =
42
+ "failproofaid could not be reached. This machine is configured to run hooks through it " +
43
+ "— check the daemon (see `failproofai config`) rather than retrying blindly.";
44
+
45
+ /** Mirrors `daemonSocket()` in src/hooks/fp-home.ts. */
46
+ export function daemonSocketPath(env = process.env, home = homedir()) {
47
+ return (
48
+ env.FAILPROOFAI_DAEMON_SOCKET ||
49
+ resolve(env.FAILPROOFAI_HOME || resolve(home, ".failproofai"), "run", "failproofaid.sock")
50
+ );
51
+ }
52
+
53
+ /**
54
+ * The gateway profile's openclaw.json — what the spawned CLI computed from the
55
+ * gateway's environment (`runtimeAgentSettingsPath("openclaw", …)` in
56
+ * src/hooks/agent-roster.ts). Sent explicitly: left out, the daemon's worker
57
+ * would resolve it from the DAEMON's environment and attribute a
58
+ * `--profile <name>` gateway to the default profile.
59
+ */
60
+ export function openclawAgentSettingsPath(env = process.env, home = homedir()) {
61
+ const config = env.OPENCLAW_CONFIG_PATH;
62
+ if (config?.trim()) return resolve(config);
63
+ const state = env.OPENCLAW_STATE_DIR || env.OPENCLAW_HOME;
64
+ if (state?.trim()) return resolve(state, "openclaw.json");
65
+ const profile = env.OPENCLAW_PROFILE?.trim();
66
+ if (profile && profile !== "default" && /^[A-Za-z0-9._-]{1,80}$/.test(profile) && !profile.startsWith(".")) {
67
+ return resolve(home, `.openclaw-${profile}`, "openclaw.json");
68
+ }
69
+ return resolve(home, ".openclaw", "openclaw.json");
70
+ }
71
+
72
+ function failed(failure, message) {
73
+ return { ok: false, failure, message };
74
+ }
75
+
76
+ /**
77
+ * Turn the daemon's reply into a flat `{permission, reason}` verdict. For
78
+ * OpenClaw the evaluator always exits 0 and prints either nothing (allow) or
79
+ * one JSON object, so anything else is an evaluation failure — never an allow.
80
+ */
81
+ function readHookResult(message) {
82
+ if (message === null || typeof message !== "object" || Array.isArray(message)) {
83
+ return failed("invalid", "failproofaid returned a non-object response");
84
+ }
85
+ if (message.protocolVersion !== PROTOCOL_VERSION) {
86
+ return failed("protocol-mismatch", PROTOCOL_MISMATCH_MESSAGE);
87
+ }
88
+ if (message.type === "error") {
89
+ const detail = typeof message.message === "string" && message.message ? message.message : "no detail";
90
+ return failed("evaluation", `failproofaid could not evaluate this call: ${detail}`);
91
+ }
92
+ if (message.type !== "hookResult") {
93
+ return failed("invalid", `failproofaid returned an unexpected ${JSON.stringify(message.type)} response`);
94
+ }
95
+ // The daemon always serializes all three (crates/fpai-ipc/src/envelope.rs);
96
+ // a frame missing one is not a hookResult, and must not read as an empty
97
+ // stdout — that is the allow.
98
+ if (
99
+ !Number.isInteger(message.exitCode) ||
100
+ typeof message.stdout !== "string" ||
101
+ typeof message.stderr !== "string"
102
+ ) {
103
+ return failed("invalid", "failproofaid returned an incomplete hookResult");
104
+ }
105
+ if (message.exitCode !== 0) {
106
+ return failed("evaluation", `failproofai exited ${String(message.exitCode)} without a verdict`);
107
+ }
108
+ const stdout = message.stdout.trim();
109
+ if (!stdout) return { ok: true, verdict: { permission: "allow" } };
110
+ let verdict;
111
+ try {
112
+ verdict = JSON.parse(stdout);
113
+ } catch {
114
+ return failed("invalid", "failproofai returned a verdict that is not JSON");
115
+ }
116
+ return isVerdict(verdict)
117
+ ? { ok: true, verdict }
118
+ : failed("invalid", "failproofai returned a malformed verdict");
119
+ }
120
+
121
+ const PERMISSIONS = new Set(["allow", "deny", "instruct"]);
122
+
123
+ /** The flat shape policy-evaluator.ts prints for `--cli openclaw`; unknown keys are ignored. */
124
+ function isVerdict(verdict) {
125
+ if (verdict === null || typeof verdict !== "object" || Array.isArray(verdict)) return false;
126
+ if (!PERMISSIONS.has(verdict.permission)) return false;
127
+ if (verdict.reason !== undefined && typeof verdict.reason !== "string") return false;
128
+ if (verdict.policyName !== undefined && typeof verdict.policyName !== "string") return false;
129
+ if (
130
+ verdict.policyNames !== undefined &&
131
+ !(Array.isArray(verdict.policyNames) && verdict.policyNames.every((name) => typeof name === "string"))
132
+ ) {
133
+ return false;
134
+ }
135
+ return true;
136
+ }
137
+
138
+ /**
139
+ * One request, one connection, one frame each way. Never rejects: resolves to
140
+ * `{ok: true, verdict}` (plus `oversized: true`, see below) or
141
+ * `{ok: false, failure, message}`.
142
+ *
143
+ * A payload over MAX_PAYLOAD_BYTES is sent as an empty stdin, exactly as the
144
+ * CLI discards an oversized stdin and evaluates an empty payload;
145
+ * `oversized: true` lets the caller say so instead of discarding it silently.
146
+ */
147
+ export function requestHookVerdict({
148
+ event,
149
+ payload,
150
+ cwd = "",
151
+ agentSettingsPath = "",
152
+ socketPath = daemonSocketPath(),
153
+ connectTimeoutMs = CONNECT_TIMEOUT_MS,
154
+ responseTimeoutMs = RESPONSE_TIMEOUT_MS,
155
+ }) {
156
+ return new Promise((done) => {
157
+ let body;
158
+ let oversized = false;
159
+ try {
160
+ let stdin = JSON.stringify(payload ?? {});
161
+ if (Buffer.byteLength(stdin, "utf8") > MAX_PAYLOAD_BYTES) {
162
+ stdin = "";
163
+ oversized = true;
164
+ }
165
+ body = Buffer.from(
166
+ JSON.stringify({
167
+ type: "hook",
168
+ protocolVersion: PROTOCOL_VERSION,
169
+ hookEvent: event,
170
+ cli: "openclaw",
171
+ stdin,
172
+ ...(typeof cwd === "string" && cwd ? { cwd } : {}),
173
+ agentSettingsPath: agentSettingsPath || "",
174
+ }),
175
+ "utf8",
176
+ );
177
+ } catch (err) {
178
+ done(failed("invalid", `could not encode the hook request: ${err?.message ?? String(err)}`));
179
+ return;
180
+ }
181
+ // Unreachable for a payload within MAX_PAYLOAD_BYTES (escaping at most
182
+ // sextuples it); kept so nothing over the daemon's limit is ever sent.
183
+ if (body.length > MAX_FRAME_BYTES) {
184
+ done(failed("invalid", "hook request exceeds the daemon's 16 MiB frame limit"));
185
+ return;
186
+ }
187
+
188
+ let settled = false;
189
+ let connected = false;
190
+ let received = Buffer.alloc(0);
191
+ let timer;
192
+ let socket;
193
+ const finish = (result) => {
194
+ if (settled) return;
195
+ settled = true;
196
+ clearTimeout(timer);
197
+ try { socket?.destroy(); } catch { /* already closed */ }
198
+ done(result);
199
+ };
200
+
201
+ try {
202
+ socket = createConnection(socketPath);
203
+ } catch {
204
+ finish(failed("unreachable", UNREACHABLE_MESSAGE));
205
+ return;
206
+ }
207
+ timer = setTimeout(() => finish(failed("unreachable", UNREACHABLE_MESSAGE)), connectTimeoutMs);
208
+
209
+ socket.on("connect", () => {
210
+ connected = true;
211
+ clearTimeout(timer);
212
+ timer = setTimeout(
213
+ () => finish(failed("timeout", `failproofaid did not answer within ${responseTimeoutMs} ms`)),
214
+ responseTimeoutMs,
215
+ );
216
+ const header = Buffer.alloc(4);
217
+ header.writeUInt32BE(body.length, 0);
218
+ socket.write(Buffer.concat([header, body]));
219
+ });
220
+ socket.on("data", (chunk) => {
221
+ received = Buffer.concat([received, chunk]);
222
+ if (received.length < 4) return;
223
+ const length = received.readUInt32BE(0);
224
+ if (length > MAX_FRAME_BYTES) {
225
+ finish(failed("invalid", "failproofaid response exceeds the 16 MiB limit"));
226
+ return;
227
+ }
228
+ if (received.length < 4 + length) return;
229
+ let message;
230
+ try {
231
+ message = JSON.parse(received.subarray(4, 4 + length).toString("utf8"));
232
+ } catch {
233
+ finish(failed("invalid", "failproofaid returned a response that is not JSON"));
234
+ return;
235
+ }
236
+ const result = readHookResult(message);
237
+ finish(result.ok && oversized ? { ...result, oversized: true } : result);
238
+ });
239
+ socket.on("error", (err) => {
240
+ finish(
241
+ connected
242
+ ? failed("evaluation", `failproofaid connection failed: ${err?.message ?? String(err)}`)
243
+ : failed("unreachable", UNREACHABLE_MESSAGE),
244
+ );
245
+ });
246
+ socket.on("close", () => {
247
+ finish(
248
+ connected
249
+ ? failed("evaluation", "failproofaid closed the connection before returning a verdict")
250
+ : failed("unreachable", UNREACHABLE_MESSAGE),
251
+ );
252
+ });
253
+ });
254
+ }
@@ -0,0 +1,187 @@
1
+ /**
2
+ * OpenClaw typed plugin hooks → failproofai verdicts.
3
+ *
4
+ * Kept apart from index.js (whose only job is `definePluginEntry`) so the
5
+ * hook wiring is importable without the `openclaw/plugin-sdk` package, which
6
+ * only resolves inside the gateway.
7
+ *
8
+ * Each hook sends a Claude-shaped payload (params→tool_input, toolName→
9
+ * tool_name, transcriptPath→transcript_path, stopHookActive→stop_hook_active,
10
+ * sessionKey→session_id) with the RAW event and tool names; the daemon's
11
+ * worker canonicalizes them via the OPENCLAW_* maps in src/hooks/types.ts
12
+ * (single source of truth — no inline maps here, unlike the OpenCode/Pi shims).
13
+ *
14
+ * When failproofaid cannot return a verdict the gates fail closed, as every
15
+ * other CLI does on a daemon-configured machine (bin/failproofai.mjs): a tool
16
+ * call or prompt is blocked with the reason, and the reason is logged. The
17
+ * turn-end gate is the exception — a revise cannot bring the daemon back, so
18
+ * forcing one would loop the turn instead of protecting anything.
19
+ */
20
+ import { createInstructRetryGate, mapBeforeToolVerdict } from "./instruct-retry-gate.js";
21
+ import { createWorkspaceContext } from "./workspace-context.js";
22
+ import { openclawAgentSettingsPath, requestHookVerdict } from "./daemon-client.js";
23
+
24
+ const sharedRetryGate = createInstructRetryGate();
25
+ const sharedWorkspace = createWorkspaceContext();
26
+
27
+ const OBSERVATION_EVENTS = [
28
+ "after_tool_call",
29
+ "session_start",
30
+ "session_end",
31
+ "subagent_ended",
32
+ "before_compaction",
33
+ ];
34
+
35
+ const HOOK_OPTIONS = { priority: 100, timeoutMs: 60_000 };
36
+
37
+ /** Claude-shaped stdin base. Extra keys are ignored by the evaluator's payload
38
+ * parser; they're forwarded for activity attribution. */
39
+ function baseMeta(payload, ctx, config, workspace) {
40
+ const p = payload || {};
41
+ const c = ctx || {};
42
+ return {
43
+ session_id: c.sessionId ?? p.sessionId ?? c.sessionKey ?? p.sessionKey,
44
+ cwd: workspace.resolveWorkspace(p, c, config) ?? process.cwd(),
45
+ transcript_path: p.transcriptPath,
46
+ stop_hook_active: p.stopHookActive === true,
47
+ openclaw: {
48
+ agentId: c.agentId,
49
+ sessionKey: c.sessionKey ?? p.sessionKey,
50
+ runId: c.runId ?? p.runId,
51
+ provider: p.provider,
52
+ model: p.model,
53
+ },
54
+ };
55
+ }
56
+
57
+ function defaultEvaluate(event, payload) {
58
+ return requestHookVerdict({
59
+ event,
60
+ payload,
61
+ cwd: payload.cwd,
62
+ agentSettingsPath: openclawAgentSettingsPath(),
63
+ });
64
+ }
65
+
66
+ function logFailure(api, event, message) {
67
+ const line = `[failproofai] ${event}: ${message}`;
68
+ try {
69
+ if (typeof api?.logger?.error === "function") {
70
+ api.logger.error(line);
71
+ return;
72
+ }
73
+ } catch { /* fall through to stderr */ }
74
+ process.stderr.write(`${line}\n`);
75
+ }
76
+
77
+ const blockedReason = (message) => `FailproofAI could not check this call, so it was blocked: ${message}`;
78
+
79
+ /**
80
+ * Register every hook on `api`. `evaluate(event, payload)` resolves to
81
+ * `{ok: true, verdict}` or `{ok: false, message}`; tests inject their own.
82
+ */
83
+ export function registerFailproofaiHooks(api, {
84
+ evaluate = defaultEvaluate,
85
+ retryGate = sharedRetryGate,
86
+ workspace = sharedWorkspace,
87
+ } = {}) {
88
+ const ask = async (event, payload) => {
89
+ let result;
90
+ try {
91
+ result = await evaluate(event, payload);
92
+ } catch (err) {
93
+ result = { ok: false, message: `the failproofai plugin failed: ${err?.message ?? String(err)}` };
94
+ }
95
+ if (!result?.ok) logFailure(api, event, result?.message ?? "no verdict");
96
+ // Same outcome as the CLI's oversized stdin (warn, evaluate an empty
97
+ // payload), and said out loud for the same reason it is there.
98
+ else if (result.oversized) {
99
+ logFailure(api, event, "payload exceeds 1 MiB, so it was evaluated as an empty payload");
100
+ }
101
+ return result ?? { ok: false, message: "no verdict" };
102
+ };
103
+
104
+ // before_tool_call → PreToolUse. Deny always blocks. Instruct blocks the
105
+ // first matching attempt only, using blockReason to give the model the
106
+ // instruction, then permits retries from that session/policy for 5 minutes.
107
+ api.on(
108
+ "before_tool_call",
109
+ async (payload, ctx) => {
110
+ const p = payload || {};
111
+ const result = await ask("before_tool_call", {
112
+ ...baseMeta(payload, ctx, api.config, workspace),
113
+ tool_name: p.toolName,
114
+ tool_input: p.params,
115
+ hook_event_name: "before_tool_call",
116
+ });
117
+ if (!result.ok) return { block: true, blockReason: blockedReason(result.message) };
118
+ return mapBeforeToolVerdict(result.verdict, payload, ctx, retryGate);
119
+ },
120
+ HOOK_OPTIONS,
121
+ );
122
+
123
+ // before_agent_run → UserPromptSubmit. Deny: return {outcome:"block", reason}.
124
+ api.on(
125
+ "before_agent_run",
126
+ async (payload, ctx) => {
127
+ const p = payload || {};
128
+ workspace.remember(payload, ctx);
129
+ const result = await ask("before_agent_run", {
130
+ ...baseMeta(payload, ctx, api.config, workspace),
131
+ prompt: p.prompt,
132
+ hook_event_name: "before_agent_run",
133
+ });
134
+ if (!result.ok) return { outcome: "block", reason: blockedReason(result.message) };
135
+ if (result.verdict.permission === "deny") {
136
+ return { outcome: "block", reason: result.verdict.reason || "Blocked by failproofai" };
137
+ }
138
+ return undefined;
139
+ },
140
+ HOOK_OPTIONS,
141
+ );
142
+
143
+ // before_agent_finalize → Stop. The real turn-end gate: a deny becomes a
144
+ // revise so the agent runs another pass. The evaluator supplies the
145
+ // MANDATORY ACTION wording; the payload's stop_hook_active guards the
146
+ // require-*-before-stop builtins against infinite loops.
147
+ api.on(
148
+ "before_agent_finalize",
149
+ async (payload, ctx) => {
150
+ const result = await ask("before_agent_finalize", {
151
+ ...baseMeta(payload, ctx, api.config, workspace),
152
+ hook_event_name: "before_agent_finalize",
153
+ });
154
+ if (result.ok && result.verdict.permission === "deny") {
155
+ return { action: "revise", reason: result.verdict.reason || "Action required by failproofai" };
156
+ }
157
+ return undefined;
158
+ },
159
+ HOOK_OPTIONS,
160
+ );
161
+
162
+ // Observation hooks — await so activity ordering is stable, ignore verdict.
163
+ // after_tool_call → PostToolUse; session_start/end → SessionStart/End;
164
+ // subagent_ended → SubagentStop (obs only); before_compaction → PreCompact.
165
+ for (const event of OBSERVATION_EVENTS) {
166
+ api.on(
167
+ event,
168
+ async (payload, ctx) => {
169
+ const p = payload || {};
170
+ await ask(event, {
171
+ ...baseMeta(payload, ctx, api.config, workspace),
172
+ tool_name: p.toolName,
173
+ tool_input: p.params,
174
+ tool_response: p.result,
175
+ reason: p.reason,
176
+ hook_event_name: event,
177
+ });
178
+ if (event === "session_end") {
179
+ retryGate.clear(payload, ctx);
180
+ workspace.clear(payload, ctx);
181
+ }
182
+ return undefined;
183
+ },
184
+ HOOK_OPTIONS,
185
+ );
186
+ }
187
+ }