failproofai 0.0.14 → 0.0.15-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 (270) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/build-manifest.json +6 -6
  3. package/.next/standalone/.next/prerender-manifest.json +3 -3
  4. package/.next/standalone/.next/required-server-files.json +2 -2
  5. package/.next/standalone/.next/server/app/_global-error/page/build-manifest.json +3 -3
  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 -2
  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 +7 -7
  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 +7 -7
  14. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +3 -3
  15. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +3 -3
  16. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  17. package/.next/standalone/.next/server/app/_not-found/page/build-manifest.json +3 -3
  18. package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  19. package/.next/standalone/.next/server/app/_not-found/page.js +2 -2
  20. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  21. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  22. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  23. package/.next/standalone/.next/server/app/_not-found.rsc +15 -15
  24. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +15 -15
  25. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
  26. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +10 -10
  27. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  28. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
  29. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  30. package/.next/standalone/.next/server/app/api/audit/invite/route.js +1 -1
  31. package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -1
  32. package/.next/standalone/.next/server/app/api/audit/run/route.js +1 -1
  33. package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
  34. package/.next/standalone/.next/server/app/api/auth/login-request/route.js +1 -1
  35. package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
  36. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js +1 -1
  37. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
  38. package/.next/standalone/.next/server/app/api/auth/logout/route.js +1 -1
  39. package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
  40. package/.next/standalone/.next/server/app/api/auth/reminder/route.js +1 -1
  41. package/.next/standalone/.next/server/app/api/auth/reminder/route.js.nft.json +1 -1
  42. package/.next/standalone/.next/server/app/api/auth/status/route.js +1 -1
  43. package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
  44. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js +1 -1
  45. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
  46. package/.next/standalone/.next/server/app/audit/page/build-manifest.json +3 -3
  47. package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
  48. package/.next/standalone/.next/server/app/audit/page.js +2 -2
  49. package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
  50. package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
  51. package/.next/standalone/.next/server/app/index.html +1 -1
  52. package/.next/standalone/.next/server/app/index.rsc +15 -15
  53. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  54. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
  55. package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +4 -4
  56. package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +10 -10
  57. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  58. package/.next/standalone/.next/server/app/page/build-manifest.json +3 -3
  59. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
  60. package/.next/standalone/.next/server/app/page.js +2 -2
  61. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  62. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  63. package/.next/standalone/.next/server/app/policies/page/build-manifest.json +3 -3
  64. package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +20 -8
  65. package/.next/standalone/.next/server/app/policies/page.js +2 -2
  66. package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
  67. package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
  68. package/.next/standalone/.next/server/app/project/[name]/page/build-manifest.json +3 -3
  69. package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
  70. package/.next/standalone/.next/server/app/project/[name]/page.js +4 -4
  71. package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
  72. package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
  73. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/build-manifest.json +3 -3
  74. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
  75. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
  76. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js +4 -4
  77. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
  78. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
  79. package/.next/standalone/.next/server/app/projects/page/build-manifest.json +3 -3
  80. package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
  81. package/.next/standalone/.next/server/app/projects/page.js +3 -3
  82. package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
  83. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  84. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0-219ec._.js +1 -1
  85. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0hv08mx._.js → [root-of-the-server]__0-dh5jy._.js} +1 -1
  86. package/.next/standalone/.next/server/chunks/[root-of-the-server]__04_h-a5._.js +1 -1
  87. package/.next/standalone/.next/server/chunks/[root-of-the-server]__06cuf1y._.js +1 -1
  88. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0obaznk._.js → [root-of-the-server]__0h3lfmp._.js} +1 -1
  89. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0jnjf2t._.js +1 -1
  90. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0xvsnvt._.js → [root-of-the-server]__0l4vuqm._.js} +1 -1
  91. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0longh-._.js +3 -0
  92. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0sb_5m8._.js +4 -4
  93. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0xuaoik._.js +6 -4
  94. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__1hkdkmz._.js → [root-of-the-server]__10oa-v9._.js} +1 -1
  95. package/.next/standalone/.next/server/chunks/[root-of-the-server]__16le-kd._.js +1 -1
  96. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__1i9rknc._.js → [root-of-the-server]__18d-9oi._.js} +1 -1
  97. package/.next/standalone/.next/server/chunks/[root-of-the-server]__19120tr._.js +3 -0
  98. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1fwl2mz._.js +1 -1
  99. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1is3glr._.js +3 -0
  100. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1myjm-d._.js +1 -1
  101. package/.next/standalone/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_17k9e3w.js +6 -6
  102. package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_01r25oi._.js +1 -1
  103. package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_09z9-p7._.js +1 -1
  104. package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
  105. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0hdsupo._.js → [root-of-the-server]__0114ewg._.js} +3 -3
  106. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__01od0m6._.js +3 -0
  107. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__02r5bgf._.js +4 -0
  108. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0e8sjqm._.js +4 -0
  109. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0lkzqax._.js +4 -0
  110. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0lpvwqm._.js +21 -0
  111. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0ynf7tx._.js → [root-of-the-server]__0qucxyj._.js} +3 -3
  112. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0u02miy._.js +4 -0
  113. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0uno39i._.js +3 -0
  114. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1s2b6h0._.js → [root-of-the-server]__0x3anhr._.js} +2 -2
  115. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0y4wf1u._.js +3 -0
  116. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__170799-._.js +10 -10
  117. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__00cz9as._.js → [root-of-the-server]__1apb7k_._.js} +1 -1
  118. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1ath6v_._.js +4 -0
  119. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1nq7ivq._.js +1 -1
  120. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1py795m._.js +3 -0
  121. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1qapotl._.js +3 -0
  122. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1zqz4v8._.js +4 -0
  123. package/.next/standalone/.next/server/chunks/ssr/_077y5np._.js +3 -0
  124. package/.next/standalone/.next/server/chunks/ssr/_1-3unkg._.js +3 -0
  125. package/.next/standalone/.next/server/chunks/ssr/_1e19atl._.js +3 -0
  126. package/.next/standalone/.next/server/chunks/ssr/_1m_p7pi._.js +3 -0
  127. package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +1 -1
  128. package/.next/standalone/.next/server/chunks/ssr/app_components_project-list_tsx_1ke6anr._.js +3 -0
  129. package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
  130. package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +2 -2
  131. package/.next/standalone/.next/server/chunks/ssr/lib_0xkhw_v._.js +1 -1
  132. package/.next/standalone/.next/server/chunks/ssr/lib_hermes-projects_ts_05b8-it._.js +1 -1
  133. package/.next/standalone/.next/server/chunks/ssr/lib_openclaw-projects_ts_0qxq3bp._.js +1 -1
  134. package/.next/standalone/.next/server/chunks/ssr/{node_modules_html-to-image_es_index_0gkzjaa.js → node_modules_html-to-image_es_index_1wnt2ya.js} +1 -1
  135. package/.next/standalone/.next/server/chunks/ssr/node_modules_posthog-node_dist_entrypoints_index_node_mjs_11bnuzn._.js +1 -1
  136. package/.next/standalone/.next/server/middleware-build-manifest.js +6 -6
  137. package/.next/standalone/.next/server/pages/404.html +1 -1
  138. package/.next/standalone/.next/server/pages/500.html +1 -1
  139. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  140. package/.next/standalone/.next/server/server-reference-manifest.json +22 -10
  141. package/.next/standalone/.next/static/chunks/{29o4j32z643_a.js → 05h7pau8d3rpj.js} +1 -1
  142. package/.next/standalone/.next/static/chunks/0oos4ntyvkmjl.js +1 -0
  143. package/.next/standalone/.next/static/chunks/0tuwf_7uhfn2y.js +6 -0
  144. package/.next/standalone/.next/static/chunks/1hdhteui932bq.js +1 -0
  145. package/.next/standalone/.next/static/chunks/1l6q2-8m0gk19.js +1 -0
  146. package/.next/standalone/.next/static/chunks/2geqsiz0n8e3w.js +1 -0
  147. package/.next/standalone/.next/static/chunks/{3-ogr79xqbw0h.js → 2mazwb1qmur1p.js} +1 -1
  148. package/.next/standalone/.next/static/chunks/2pujpnfx4pws6.css +2 -0
  149. package/.next/standalone/.next/static/chunks/{1ua5armwfph8o.js → 31fmsp1soxi07.js} +1 -1
  150. package/.next/standalone/.next/static/chunks/{3s8aaig91937v.js → 37-so-zy208k7.js} +1 -1
  151. package/.next/standalone/.next/static/chunks/3a_o5v_sl858j.js +1 -0
  152. package/.next/standalone/.next/static/chunks/{02jcotghcxrbu.js → 3kmwfieo15mr2.js} +1 -1
  153. package/.next/standalone/.next/static/chunks/{2uh_4k4m296z5.js → 3p66lo2y-ezfr.js} +1 -1
  154. package/.next/standalone/.next/static/chunks/{06z_ex1ts3n4s.js → 412ajx6jkb5_i.js} +1 -1
  155. package/.next/standalone/.next/static/chunks/{turbopack-10hj8t5pf33tu.js → turbopack-1lsv92x7klwrn.js} +1 -1
  156. package/.next/standalone/app/actions/get-hooks-config.ts +125 -8
  157. package/.next/standalone/app/actions/update-hooks-config.ts +38 -1
  158. package/.next/standalone/app/components/project-list.tsx +229 -42
  159. package/.next/standalone/app/policies/hooks-client.tsx +149 -27
  160. package/.next/standalone/app/project/[name]/page.tsx +12 -2
  161. package/.next/standalone/integration-suite/README.md +43 -1
  162. package/.next/standalone/integration-suite/ci-entrypoint.sh +21 -6
  163. package/.next/standalone/integration-suite/install-clis.sh +58 -13
  164. package/.next/standalone/integration-suite/probe-cli.sh +51 -11
  165. package/.next/standalone/integration-suite/report.js +52 -6
  166. package/.next/standalone/integration-suite/run.sh +55 -3
  167. package/.next/standalone/lib/hermes-profiles.ts +156 -0
  168. package/.next/standalone/lib/hermes-projects.ts +91 -25
  169. package/.next/standalone/lib/hermes-sessions.ts +65 -10
  170. package/.next/standalone/lib/openclaw-projects.ts +111 -18
  171. package/.next/standalone/lib/openclaw-sessions.ts +20 -0
  172. package/.next/standalone/lib/paths.ts +36 -0
  173. package/.next/standalone/lib/project-tree.ts +193 -0
  174. package/.next/standalone/lib/projects.ts +22 -0
  175. package/.next/standalone/node_modules/@next/env/package.json +1 -1
  176. package/.next/standalone/node_modules/next/dist/build/next-config-ts/transpile-config.js +3 -114
  177. package/.next/standalone/node_modules/next/dist/build/swc/index.js +1 -1
  178. package/.next/standalone/node_modules/next/dist/cli/next-test.js +2 -1
  179. package/.next/standalone/node_modules/next/dist/compiled/http-proxy/index.js +5 -5
  180. package/.next/standalone/node_modules/next/dist/compiled/next-server/app-page-turbo-experimental.runtime.prod.js +11 -10
  181. package/.next/standalone/node_modules/next/dist/compiled/next-server/app-page-turbo.runtime.prod.js +11 -10
  182. package/.next/standalone/node_modules/next/dist/compiled/next-server/app-route-turbo.runtime.prod.js +2 -2
  183. package/.next/standalone/node_modules/next/dist/compiled/next-server/pages-turbo.runtime.prod.js +9 -9
  184. package/.next/standalone/node_modules/next/dist/lib/install-dependencies.js +1 -1
  185. package/.next/standalone/node_modules/next/dist/lib/patch-incorrect-lockfile.js +3 -3
  186. package/.next/standalone/node_modules/next/dist/lib/typescript/loadTsConfig.js +181 -0
  187. package/.next/standalone/node_modules/next/dist/lib/typescript/missingDependencyError.js +1 -1
  188. package/.next/standalone/node_modules/next/dist/lib/typescript/runTypeCheckCli.js +53 -0
  189. package/.next/standalone/node_modules/next/dist/lib/typescript/runTypeScriptCli.js +256 -0
  190. package/.next/standalone/node_modules/next/dist/lib/verify-typescript-setup.js +97 -56
  191. package/.next/standalone/node_modules/next/dist/server/app-render/action-handler.js +129 -34
  192. package/.next/standalone/node_modules/next/dist/server/app-render/manifests-singleton.js +52 -4
  193. package/.next/standalone/node_modules/next/dist/server/config-schema.js +1 -1
  194. package/.next/standalone/node_modules/next/dist/server/config-shared.js +1 -2
  195. package/.next/standalone/node_modules/next/dist/server/config.js +1 -1
  196. package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-turbopack.js +2 -2
  197. package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-webpack.js +1 -1
  198. package/.next/standalone/node_modules/next/dist/server/image-optimizer.js +8 -27
  199. package/.next/standalone/node_modules/next/dist/server/lib/app-info-log.js +1 -1
  200. package/.next/standalone/node_modules/next/dist/server/lib/incremental-cache/index.js +90 -53
  201. package/.next/standalone/node_modules/next/dist/server/lib/patch-fetch.js +15 -2
  202. package/.next/standalone/node_modules/next/dist/server/lib/router-utils/proxy-request.js +4 -0
  203. package/.next/standalone/node_modules/next/dist/server/lib/start-server.js +1 -1
  204. package/.next/standalone/node_modules/next/dist/server/web/spec-extension/unstable-cache.js +1 -1
  205. package/.next/standalone/node_modules/next/dist/shared/lib/errors/canary-only-config-error.js +1 -1
  206. package/.next/standalone/node_modules/next/dist/shared/lib/router/utils/prepare-destination.js +2 -1
  207. package/.next/standalone/node_modules/next/dist/shared/lib/server-reference-info.js +12 -0
  208. package/.next/standalone/node_modules/next/dist/telemetry/anonymous-meta.js +1 -1
  209. package/.next/standalone/node_modules/next/dist/telemetry/events/swc-load-failure.js +1 -1
  210. package/.next/standalone/node_modules/next/dist/telemetry/events/version.js +2 -2
  211. package/.next/standalone/node_modules/next/package.json +10 -10
  212. package/.next/standalone/package.json +7 -6
  213. package/.next/standalone/pi-extension/index.ts +38 -5
  214. package/.next/standalone/server.js +1 -1
  215. package/bin/failproofai.mjs +14 -13
  216. package/dist/cli.mjs +789 -399
  217. package/lib/hermes-profiles.ts +156 -0
  218. package/lib/hermes-projects.ts +91 -25
  219. package/lib/hermes-sessions.ts +65 -10
  220. package/lib/openclaw-projects.ts +111 -18
  221. package/lib/openclaw-sessions.ts +20 -0
  222. package/lib/paths.ts +36 -0
  223. package/lib/project-tree.ts +193 -0
  224. package/lib/projects.ts +22 -0
  225. package/package.json +7 -6
  226. package/pi-extension/index.ts +38 -5
  227. package/scripts/launch.ts +7 -0
  228. package/src/audit/cli-adapters/hermes.ts +6 -3
  229. package/src/audit/cli-adapters/openclaw.ts +17 -13
  230. package/src/hooks/configure-wizard.ts +24 -2
  231. package/src/hooks/custom-hooks-loader.ts +90 -13
  232. package/src/hooks/enforcement-capability.ts +266 -0
  233. package/src/hooks/handler.ts +20 -3
  234. package/src/hooks/hook-activity-store.ts +14 -0
  235. package/src/hooks/hooks-config.ts +90 -6
  236. package/src/hooks/integrations.ts +123 -19
  237. package/src/hooks/manager.ts +206 -75
  238. package/src/hooks/policy-evaluator.ts +59 -7
  239. package/src/hooks/policy-types.ts +31 -0
  240. package/src/hooks/types.ts +50 -2
  241. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0q2nbsl._.js +0 -3
  242. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1d9qen3._.js +0 -3
  243. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1mrihkj._.js +0 -3
  244. package/.next/standalone/.next/server/chunks/lib_openclaw-projects_ts_0gc-p24._.js +0 -3
  245. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__015_i4t._.js +0 -4
  246. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__030k0c6._.js +0 -3
  247. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__03lv-pe._.js +0 -4
  248. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__042d3cd._.js +0 -3
  249. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__09q1168._.js +0 -3
  250. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qeuy9c._.js +0 -4
  251. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0s89hoe._.js +0 -4
  252. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0zf8xlq._.js +0 -3
  253. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__17ai7sy._.js +0 -4
  254. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1d8omgc._.js +0 -3
  255. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1fax1sl._.js +0 -19
  256. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1tkjqka._.js +0 -4
  257. package/.next/standalone/.next/server/chunks/ssr/_05whahf._.js +0 -3
  258. package/.next/standalone/.next/server/chunks/ssr/_0_9_ytf._.js +0 -3
  259. package/.next/standalone/.next/server/chunks/ssr/_1kje4fm._.js +0 -3
  260. package/.next/standalone/.next/server/chunks/ssr/_1p0-leb._.js +0 -3
  261. package/.next/standalone/.next/static/chunks/0o0ut0ugd0_-s.js +0 -1
  262. package/.next/standalone/.next/static/chunks/0xl97x-874k-u.js +0 -1
  263. package/.next/standalone/.next/static/chunks/19d7hqx8udopz.js +0 -1
  264. package/.next/standalone/.next/static/chunks/36j05kb2x323i.css +0 -2
  265. package/.next/standalone/.next/static/chunks/370sj2lgkw5ey.js +0 -1
  266. package/.next/standalone/.next/static/chunks/3w7g0n0iwwnbs.js +0 -1
  267. package/.next/standalone/.next/static/chunks/42oeva1-w0z2d.js +0 -6
  268. /package/.next/standalone/.next/static/{WQRKgSfFekLcC_pvyzp4S → nhn6Tt0--xZKdgVGIqR6E}/_buildManifest.js +0 -0
  269. /package/.next/standalone/.next/static/{WQRKgSfFekLcC_pvyzp4S → nhn6Tt0--xZKdgVGIqR6E}/_clientMiddlewareManifest.js +0 -0
  270. /package/.next/standalone/.next/static/{WQRKgSfFekLcC_pvyzp4S → nhn6Tt0--xZKdgVGIqR6E}/_ssgManifest.js +0 -0
@@ -4,10 +4,17 @@
4
4
  import { readFileSync, writeFileSync, existsSync, mkdirSync, statSync } from "node:fs";
5
5
  import { resolve, dirname } from "node:path";
6
6
  import { homedir } from "node:os";
7
- import type { HooksConfig } from "./policy-types";
7
+ import type { HooksConfig, ConventionPolicyRecord } from "./policy-types";
8
8
  import type { HookScope } from "./types";
9
9
  import { hookLogInfo, hookLogWarn } from "./hook-logger";
10
10
 
11
+ /** Normalize plural and legacy singular explicit policy paths for consumers. */
12
+ export function configuredCustomPolicyPaths(
13
+ config: Pick<HooksConfig, "customPoliciesPaths" | "customPoliciesPath">,
14
+ ): string[] {
15
+ return config.customPoliciesPaths ?? (config.customPoliciesPath ? [config.customPoliciesPath] : []);
16
+ }
17
+
11
18
  function readConfigAt(path: string): Partial<HooksConfig> {
12
19
  if (!existsSync(path)) return {};
13
20
  try {
@@ -55,7 +62,7 @@ export function findProjectConfigDir(start: string): string {
55
62
  * Merge rules:
56
63
  * enabledPolicies: union + dedup across all three
57
64
  * policyParams: per-policy key, first scope that defines it wins entirely
58
- * customPoliciesPath: first scope that defines it wins
65
+ * customPoliciesPaths/customPoliciesPath: first scope defining either wins
59
66
  * llm: first scope that defines it wins
60
67
  */
61
68
  export function readMergedHooksConfig(cwd?: string): HooksConfig {
@@ -86,9 +93,26 @@ export function readMergedHooksConfig(cwd?: string): HooksConfig {
86
93
  }
87
94
  }
88
95
 
89
- // customPoliciesPath: first scope wins
90
- const customPoliciesPath =
91
- project.customPoliciesPath ?? local.customPoliciesPath ?? global_.customPoliciesPath;
96
+ // Explicit custom policy paths: first scope defining either the current
97
+ // array form or the legacy singular form wins.
98
+ const customPoliciesPaths = [project, local, global_]
99
+ .map((scope) =>
100
+ scope.customPoliciesPaths !== undefined
101
+ ? scope.customPoliciesPaths
102
+ : scope.customPoliciesPath !== undefined
103
+ ? [scope.customPoliciesPath]
104
+ : undefined,
105
+ )
106
+ .find((paths) => paths !== undefined);
107
+
108
+ const disabledCustomPolicies = new Set<string>([
109
+ ...(project.disabledCustomPolicies ?? []),
110
+ ...(local.disabledCustomPolicies ?? []),
111
+ ...(global_.disabledCustomPolicies ?? []),
112
+ ]);
113
+
114
+ const customPoliciesEnabled =
115
+ project.customPoliciesEnabled ?? local.customPoliciesEnabled ?? global_.customPoliciesEnabled;
92
116
 
93
117
  // llm: first scope wins
94
118
  const llm = project.llm ?? local.llm ?? global_.llm;
@@ -96,7 +120,9 @@ export function readMergedHooksConfig(cwd?: string): HooksConfig {
96
120
  return {
97
121
  enabledPolicies: [...enabledSet],
98
122
  ...(Object.keys(mergedParams).length > 0 ? { policyParams: mergedParams } : {}),
99
- ...(customPoliciesPath !== undefined ? { customPoliciesPath } : {}),
123
+ ...(customPoliciesPaths !== undefined ? { customPoliciesPaths } : {}),
124
+ ...(disabledCustomPolicies.size ? { disabledCustomPolicies: [...disabledCustomPolicies] } : {}),
125
+ ...(customPoliciesEnabled !== undefined ? { customPoliciesEnabled } : {}),
100
126
  ...(llm !== undefined ? { llm } : {}),
101
127
  };
102
128
  }
@@ -171,6 +197,64 @@ export function writeScopedHooksConfig(config: HooksConfig, scope: HookScope, cw
171
197
  writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n", "utf8");
172
198
  }
173
199
 
200
+ /**
201
+ * Mirror the convention policies discovered at `scope` into that scope's
202
+ * config file, so `policies-config.json` shows what is installed rather than
203
+ * only what was explicitly enabled.
204
+ *
205
+ * Wholesale replace, not merge: the point is to reflect the directory as it is
206
+ * now, so a deleted file must vanish from the record. Writes only when the
207
+ * value actually changes, so repeated `failproofai policies` runs do not
208
+ * rewrite the file (and do not churn its mtime) for no reason.
209
+ *
210
+ * Callers must be one-shot commands. This is never safe to call from the hook
211
+ * path — see the `conventionPolicies` doc comment on `HooksConfig`.
212
+ *
213
+ * Returns true when the file was written.
214
+ */
215
+ export function syncConventionPolicies(
216
+ entries: ConventionPolicyRecord[],
217
+ scope: HookScope,
218
+ cwd?: string,
219
+ ): boolean {
220
+ const configPath = getConfigPathForScope(scope, cwd);
221
+
222
+ // Never bring a config file into existence just to record an empty list —
223
+ // that would litter every directory the CLI is run from.
224
+ if (!existsSync(configPath) && entries.length === 0) return false;
225
+
226
+ // NEVER write over a file we could not parse. `readScopedHooksConfig` fails
227
+ // soft, returning `{enabledPolicies: []}` on a syntax error — correct for the
228
+ // hook path, which must not die because a config is malformed, but fatal
229
+ // here: writing that default back silently DESTROYS the user's real settings.
230
+ // A hand-edited file with one stray comma would lose every enabled policy the
231
+ // moment someone ran `failproofai policies`, a read-only command. Bail and
232
+ // leave the file exactly as it is; the parse warning already surfaced.
233
+ if (existsSync(configPath)) {
234
+ try {
235
+ JSON.parse(readFileSync(configPath, "utf8"));
236
+ } catch {
237
+ hookLogWarn(
238
+ `not recording convention policies: ${configPath} is not valid JSON — ` +
239
+ `fix the syntax error and re-run. Nothing was written.`,
240
+ );
241
+ return false;
242
+ }
243
+ }
244
+
245
+ const config = readScopedHooksConfig(scope, cwd);
246
+ const sorted = [...entries].sort((a, b) => a.file.localeCompare(b.file));
247
+ const next: HooksConfig = { ...config };
248
+ if (sorted.length === 0) delete next.conventionPolicies;
249
+ else next.conventionPolicies = sorted;
250
+
251
+ if (JSON.stringify(next.conventionPolicies ?? null) === JSON.stringify(config.conventionPolicies ?? null)) {
252
+ return false;
253
+ }
254
+ writeScopedHooksConfig(next, scope, cwd);
255
+ return true;
256
+ }
257
+
174
258
  export interface ResolvedLlmConfig {
175
259
  baseUrl: string;
176
260
  apiKey: string;
@@ -12,8 +12,10 @@ import { resolve, dirname } from "node:path";
12
12
  import { fileURLToPath } from "node:url";
13
13
  import { homedir } from "node:os";
14
14
  import { parseDocument, type Document } from "yaml";
15
+ import { listHermesProfiles, hermesRoot } from "../../lib/hermes-profiles";
15
16
  import {
16
17
  HOOK_EVENT_TYPES,
18
+ CLAUDE_INSTALL_EVENT_TYPES,
17
19
  HOOK_SCOPES,
18
20
  CODEX_HOOK_EVENT_TYPES,
19
21
  CODEX_HOOK_SCOPES,
@@ -118,6 +120,18 @@ export interface Integration {
118
120
  /** Resolve the per-scope settings/hooks file path. */
119
121
  getSettingsPath(scope: HookScope, cwd?: string): string;
120
122
 
123
+ /**
124
+ * Every settings file this integration must write for a scope.
125
+ *
126
+ * Optional — defaults to `[getSettingsPath(scope, cwd)]`, which is right for
127
+ * every CLI whose scope maps to exactly one file. Hermes overrides it because
128
+ * each of its PROFILES is a separate home dir with its own `config.yaml`:
129
+ * writing only `~/.hermes/config.yaml` would leave every other profile running
130
+ * unhooked, silently. Use `settingsPathsFor(integration, …)` at call sites
131
+ * rather than calling this directly.
132
+ */
133
+ getSettingsPaths?(scope: HookScope, cwd?: string): string[];
134
+
121
135
  /** Read the raw settings/hooks file (returns {} when missing). */
122
136
  readSettings(settingsPath: string): Record<string, unknown>;
123
137
 
@@ -143,13 +157,28 @@ export interface Integration {
143
157
  detectInstalled(): boolean;
144
158
  }
145
159
 
160
+ /**
161
+ * Every settings file to write/remove for `(integration, scope)`.
162
+ *
163
+ * Single-file integrations (all but Hermes) return exactly one path, so callers
164
+ * can loop unconditionally.
165
+ */
166
+ export function settingsPathsFor(
167
+ integration: Integration,
168
+ scope: HookScope,
169
+ cwd?: string,
170
+ ): string[] {
171
+ const paths = integration.getSettingsPaths?.(scope, cwd);
172
+ return paths && paths.length > 0 ? paths : [integration.getSettingsPath(scope, cwd)];
173
+ }
174
+
146
175
  // ── Claude Code integration ─────────────────────────────────────────────────
147
176
 
148
177
  export const claudeCode: Integration = {
149
178
  id: "claude",
150
179
  displayName: "Claude Code",
151
180
  scopes: HOOK_SCOPES,
152
- eventTypes: HOOK_EVENT_TYPES,
181
+ eventTypes: CLAUDE_INSTALL_EVENT_TYPES,
153
182
 
154
183
  getSettingsPath(scope, cwd) {
155
184
  const base = cwd ? resolve(cwd) : process.cwd();
@@ -196,7 +225,48 @@ export const claudeCode: Integration = {
196
225
  const s = settings as ClaudeSettings;
197
226
  if (!s.hooks) s.hooks = {};
198
227
 
199
- for (const eventType of HOOK_EVENT_TYPES) {
228
+ // Drop our hook from any event we no longer install. Without this, an
229
+ // event removed from the list stays in settings.json forever on existing
230
+ // machines — reinstalling would not repair it — which is exactly the
231
+ // situation `WorktreeCreate` created: registered, silent on allow, and
232
+ // therefore breaking `claude --worktree` until hand-edited. Only OUR
233
+ // marked entries are touched; anyone else's hooks on the same event stay.
234
+ //
235
+ // This walks EVERY key the file happens to carry, including ones
236
+ // failproofai has never written — a newer Claude event, another tool's
237
+ // entry, a typo. Their values are therefore unvalidated input, and a
238
+ // non-array one (`"Foo": {}` or `"Foo": "bar"`) makes the iteration below
239
+ // throw. That aborts the whole install AFTER the policies were recorded as
240
+ // enabled, so the user is left believing they are covered while no hook was
241
+ // written at all — the silent non-enforcement this file exists to prevent.
242
+ // Skip anything not shaped like a matcher list and leave it untouched.
243
+ const installed = new Set<string>(CLAUDE_INSTALL_EVENT_TYPES);
244
+ for (const eventType of Object.keys(s.hooks)) {
245
+ if (installed.has(eventType)) continue;
246
+ const matchers = s.hooks[eventType];
247
+ if (!Array.isArray(matchers)) continue;
248
+ // Drop a matcher group only when WE emptied it. A group we never touched
249
+ // (no `hooks` array, or one that held nothing of ours) is somebody else's
250
+ // and is written back exactly as found — pruning is for our own entries,
251
+ // not a cleanup pass over the user's file.
252
+ const kept: ClaudeHookMatcher[] = [];
253
+ for (const matcher of matchers as ClaudeHookMatcher[]) {
254
+ if (!matcher || !Array.isArray(matcher.hooks)) {
255
+ if (matcher) kept.push(matcher);
256
+ continue;
257
+ }
258
+ const before = matcher.hooks.length;
259
+ matcher.hooks = matcher.hooks.filter(
260
+ (h) => !isMarkedHook(h as Record<string, unknown>),
261
+ );
262
+ const weEmptiedIt = matcher.hooks.length === 0 && before > 0;
263
+ if (!weEmptiedIt) kept.push(matcher);
264
+ }
265
+ s.hooks[eventType] = kept;
266
+ if (kept.length === 0) delete s.hooks[eventType];
267
+ }
268
+
269
+ for (const eventType of CLAUDE_INSTALL_EVENT_TYPES) {
200
270
  const hookEntry = this.buildHookEntry(binaryPath, eventType, scope) as unknown as ClaudeHookEntry;
201
271
  if (!s.hooks[eventType]) s.hooks[eventType] = [];
202
272
  const matchers: ClaudeHookMatcher[] = s.hooks[eventType];
@@ -1315,10 +1385,19 @@ export const hermes: Integration = {
1315
1385
  scopes: HERMES_HOOK_SCOPES,
1316
1386
  eventTypes: HERMES_HOOK_EVENT_TYPES,
1317
1387
 
1318
- // Hermes config is USER-scope only (`~/.hermes/config.yaml`); there is no
1319
- // project/local file, so scope/cwd are irrelevant here.
1388
+ // Hermes config is USER-scope only (`<HERMES_HOME>/config.yaml`); there is no
1389
+ // project/local file, so scope/cwd are irrelevant here. This is the DEFAULT
1390
+ // profile's config — see getSettingsPaths for the rest.
1320
1391
  getSettingsPath() {
1321
- return resolve(homedir(), ".hermes", "config.yaml");
1392
+ return resolve(hermesRoot(), "config.yaml");
1393
+ },
1394
+
1395
+ // Every profile is a separate Hermes home with its own config.yaml, so a
1396
+ // single-file install would leave non-default profiles running unhooked —
1397
+ // silently, since Hermes never reports a missing hook. Install/uninstall
1398
+ // therefore cover them all.
1399
+ getSettingsPaths() {
1400
+ return listHermesProfiles().map((p) => resolve(p.home, "config.yaml"));
1322
1401
  },
1323
1402
 
1324
1403
  readSettings(settingsPath) {
@@ -1403,21 +1482,13 @@ export const hermes: Integration = {
1403
1482
  return removed;
1404
1483
  },
1405
1484
 
1485
+ // "Installed" means EVERY profile is hooked, not just some. A profile created
1486
+ // after install has no hooks, and reporting green there would hide exactly the
1487
+ // silent-unenforcement gap this integration exists to close; reporting "not
1488
+ // installed" instead prompts a re-install, which writes the missing profiles.
1406
1489
  hooksInstalledInSettings(scope, cwd) {
1407
- const settingsPath = this.getSettingsPath(scope, cwd);
1408
- if (!existsSync(settingsPath)) return false;
1409
- try {
1410
- const doc = readYamlDoc(settingsPath);
1411
- const js = (doc.toJS() ?? {}) as { hooks?: Record<string, HermesHookEntry[]> };
1412
- const hooks = js.hooks;
1413
- if (!hooks || typeof hooks !== "object") return false;
1414
- for (const entries of Object.values(hooks)) {
1415
- if (Array.isArray(entries) && entries.some((h) => isMarkedHook(h))) return true;
1416
- }
1417
- } catch {
1418
- // Corrupt config — treat as not installed.
1419
- }
1420
- return false;
1490
+ const paths = settingsPathsFor(this, scope, cwd);
1491
+ return paths.length > 0 && paths.every((p) => hermesConfigHasHooks(p));
1421
1492
  },
1422
1493
 
1423
1494
  detectInstalled() {
@@ -1425,6 +1496,39 @@ export const hermes: Integration = {
1425
1496
  },
1426
1497
  };
1427
1498
 
1499
+ function hermesConfigHasHooks(settingsPath: string): boolean {
1500
+ if (!existsSync(settingsPath)) return false;
1501
+ try {
1502
+ const doc = readYamlDoc(settingsPath);
1503
+ const js = (doc.toJS() ?? {}) as { hooks?: Record<string, HermesHookEntry[]> };
1504
+ const hooks = js.hooks;
1505
+ if (!hooks || typeof hooks !== "object") return false;
1506
+ for (const entries of Object.values(hooks)) {
1507
+ if (Array.isArray(entries) && entries.some((h) => isMarkedHook(h))) return true;
1508
+ }
1509
+ } catch {
1510
+ // Corrupt config — treat as not installed.
1511
+ }
1512
+ return false;
1513
+ }
1514
+
1515
+ /**
1516
+ * Profiles that exist but have no failproofai hooks — i.e. Hermes instances
1517
+ * currently running unenforced. Empty when Hermes isn't installed at all.
1518
+ *
1519
+ * `listHermesProfiles()` always seeds a `default` entry so install has a path to
1520
+ * write even on a fresh machine, so this filters to homes that actually exist —
1521
+ * otherwise every machine WITHOUT Hermes would report one unhooked profile and
1522
+ * the wizard would replace its accurate "not on PATH" hint with a phantom
1523
+ * warning.
1524
+ */
1525
+ export function unhookedHermesProfiles(): string[] {
1526
+ return listHermesProfiles()
1527
+ .filter((p) => existsSync(p.home))
1528
+ .filter((p) => !hermesConfigHasHooks(resolve(p.home, "config.yaml")))
1529
+ .map((p) => p.name);
1530
+ }
1531
+
1428
1532
  // ── OpenClaw integration ────────────────────────────────────────────────────
1429
1533
  //
1430
1534
  // OpenClaw is a self-hosted assistant gateway. Enforcement is via its in-process