failproofai 0.0.13 → 0.0.14-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 (310) hide show
  1. package/.next/standalone/.codex/hooks.json +6 -6
  2. package/.next/standalone/.cursor/hooks.json +6 -6
  3. package/.next/standalone/.factory/hooks.json +112 -0
  4. package/.next/standalone/.next/BUILD_ID +1 -1
  5. package/.next/standalone/.next/build-manifest.json +5 -5
  6. package/.next/standalone/.next/prerender-manifest.json +3 -3
  7. package/.next/standalone/.next/required-server-files.json +1 -1
  8. package/.next/standalone/.next/server/app/_global-error/page/build-manifest.json +2 -2
  9. package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -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 +2 -2
  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.nft.json +1 -1
  22. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  23. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  24. package/.next/standalone/.next/server/app/_not-found.rsc +15 -15
  25. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +15 -15
  26. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
  27. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +10 -10
  28. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  29. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
  30. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  31. package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -1
  32. package/.next/standalone/.next/server/app/api/audit/run/route.js +3 -3
  33. package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
  34. package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
  35. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
  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/reminder/route.js.nft.json +1 -1
  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 +2 -1
  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.nft.json +1 -1
  44. package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
  45. package/.next/standalone/.next/server/app/index.html +1 -1
  46. package/.next/standalone/.next/server/app/index.rsc +15 -15
  47. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  48. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
  49. package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +4 -4
  50. package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +10 -10
  51. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  52. package/.next/standalone/.next/server/app/page/build-manifest.json +2 -2
  53. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
  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 +8 -8
  58. package/.next/standalone/.next/server/app/policies/page.js +1 -1
  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 +3 -2
  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 +5 -3
  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 +1 -1
  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/chunks/[root-of-the-server]__0--lkk6._.js +3 -0
  78. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0-219ec._.js +3 -0
  79. package/.next/standalone/.next/server/chunks/[root-of-the-server]__04_h-a5._.js +3 -0
  80. package/.next/standalone/.next/server/chunks/[root-of-the-server]__06cuf1y._.js +3 -0
  81. package/.next/standalone/.next/server/chunks/[root-of-the-server]__08w4wmd._.js +3 -0
  82. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0g6bbuw._.js +3 -0
  83. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0jllheg._.js +3 -0
  84. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0jnjf2t._.js +3 -0
  85. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0q-v9z2._.js +1 -1
  86. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0q0qzx1._.js +3 -0
  87. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0q2nbsl._.js +3 -0
  88. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0rv7m0k._.js +1 -1
  89. package/.next/standalone/.next/server/chunks/[root-of-the-server]__16le-kd._.js +3 -0
  90. package/.next/standalone/.next/server/chunks/[root-of-the-server]__17g9wh7._.js +1 -1
  91. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1d9qen3._.js +3 -0
  92. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1ffkmds._.js +3 -0
  93. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1fwl2mz._.js +1 -1
  94. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1legmza._.js +1 -1
  95. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1mrihkj._.js +1 -1
  96. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1myjm-d._.js +1 -1
  97. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1qb590j._.js +3 -0
  98. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1qxztj-._.js +1 -1
  99. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1shcqgr._.js +3 -0
  100. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1xuedea._.js +3 -0
  101. package/.next/standalone/.next/server/chunks/{_1z062h5._.js → _1vslkoe._.js} +2 -2
  102. package/.next/standalone/.next/server/chunks/lib_factory-projects_ts_1eo_bk-._.js +3 -0
  103. package/.next/standalone/.next/server/chunks/lib_openclaw-projects_ts_0gc-p24._.js +3 -0
  104. package/.next/standalone/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_17k9e3w.js +24 -12
  105. package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_01r25oi._.js +1 -1
  106. package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_09z9-p7._.js +1 -1
  107. package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
  108. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__00cz9as._.js +3 -0
  109. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__015_i4t._.js +2 -2
  110. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__030k0c6._.js +3 -0
  111. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__03lv-pe._.js +2 -2
  112. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__042d3cd._.js +3 -0
  113. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__05r_17v._.js +3 -0
  114. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__09q1168._.js +3 -0
  115. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__108slqn._.js → [root-of-the-server]__0brjczq._.js} +2 -2
  116. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0e2l3c1._.js +3 -0
  117. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0hci7t3._.js +3 -0
  118. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0hdsupo._.js +2 -2
  119. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0p84xee._.js +3 -0
  120. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qeuy9c._.js +2 -2
  121. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0s89hoe._.js +2 -2
  122. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__07iom4f._.js → [root-of-the-server]__0wp9w6i._.js} +2 -2
  123. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ynf7tx._.js +2 -2
  124. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__170799-._.js +12 -9
  125. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__17ai7sy._.js +4 -0
  126. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1d8omgc._.js +1 -1
  127. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1nq7ivq._.js +3 -0
  128. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1tkjqka._.js +2 -2
  129. package/.next/standalone/.next/server/chunks/ssr/_05whahf._.js +1 -1
  130. package/.next/standalone/.next/server/chunks/ssr/_0_9_ytf._.js +3 -0
  131. package/.next/standalone/.next/server/chunks/ssr/_11_p9y8._.js +1 -1
  132. package/.next/standalone/.next/server/chunks/ssr/{_0ul5rf_._.js → _1_ozgif._.js} +2 -2
  133. package/.next/standalone/.next/server/chunks/ssr/_1p0-leb._.js +1 -1
  134. package/.next/standalone/.next/server/chunks/ssr/app_087bt9w._.js +1 -1
  135. package/.next/standalone/.next/server/chunks/ssr/app_1fvisnp._.js +1 -1
  136. package/.next/standalone/.next/server/chunks/ssr/app_209u41o._.js +1 -1
  137. package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +2 -2
  138. package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
  139. package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +1 -1
  140. package/.next/standalone/.next/server/chunks/ssr/lib_0xkhw_v._.js +3 -0
  141. package/.next/standalone/.next/server/chunks/ssr/lib_antigravity-projects_ts_0_6zf11._.js +3 -0
  142. package/.next/standalone/.next/server/chunks/ssr/lib_devin-projects_ts_0a64qdy._.js +3 -0
  143. package/.next/standalone/.next/server/chunks/ssr/lib_factory-projects_ts_1uyaahq._.js +3 -0
  144. package/.next/standalone/.next/server/chunks/ssr/lib_goose-projects_ts_0zkscri._.js +3 -0
  145. package/.next/standalone/.next/server/chunks/ssr/lib_openclaw-projects_ts_0qxq3bp._.js +3 -0
  146. package/.next/standalone/.next/server/chunks/ssr/{node_modules_html-to-image_es_index_13p7zob.js → node_modules_html-to-image_es_index_12rjfea.js} +1 -1
  147. package/.next/standalone/.next/server/chunks/ssr/node_modules_posthog-node_dist_entrypoints_index_node_mjs_11bnuzn._.js +1 -1
  148. package/.next/standalone/.next/server/chunks/ssr/src_hooks_1ezd2jf._.js +1 -1
  149. package/.next/standalone/.next/server/chunks/ssr/src_hooks_1tnuifj._.js +1 -1
  150. package/.next/standalone/.next/server/middleware-build-manifest.js +5 -5
  151. package/.next/standalone/.next/server/pages/404.html +1 -1
  152. package/.next/standalone/.next/server/pages/500.html +1 -1
  153. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  154. package/.next/standalone/.next/server/server-reference-manifest.json +10 -10
  155. package/.next/standalone/.next/static/chunks/{13f1kmjea-0md.js → 02jcotghcxrbu.js} +1 -1
  156. package/.next/standalone/.next/static/chunks/{30ysv-_8jj052.js → 0d5lypu1zs21r.js} +1 -1
  157. package/.next/standalone/.next/static/chunks/0emg30_6svycu.js +1 -0
  158. package/.next/standalone/.next/static/chunks/0o9wpnze1ey8y.js +6 -0
  159. package/.next/standalone/.next/static/chunks/{05apzuand0c22.js → 1359o5785rmve.js} +2 -2
  160. package/.next/standalone/.next/static/chunks/20tuctw38jbgw.js +1 -0
  161. package/.next/standalone/.next/static/chunks/{0vc0eak148vo6.js → 2ldhnaweu9ew3.js} +1 -1
  162. package/.next/standalone/.next/static/chunks/{23c7v2svx90dp.js → 2vav_x0_336ds.js} +1 -1
  163. package/.next/standalone/.next/static/chunks/3-ogr79xqbw0h.js +1 -0
  164. package/.next/standalone/.next/static/chunks/36j05kb2x323i.css +2 -0
  165. package/.next/standalone/.next/static/chunks/3cg7x0joi2b98.js +1 -0
  166. package/.next/standalone/.next/static/chunks/{36wdtkgdf0zrd.js → 3k87p-tijud-4.js} +1 -1
  167. package/.next/standalone/.next/static/chunks/{2cejn75gug3j8.js → 3kmaqcp7rldad.js} +1 -1
  168. package/.next/standalone/.next/static/chunks/{turbopack-0vavqo2d-tlt3.js → turbopack-10hj8t5pf33tu.js} +1 -1
  169. package/.next/standalone/.opencode/plugins/failproofai.mjs +30 -11
  170. package/.next/standalone/app/api/audit/run/route.ts +2 -0
  171. package/.next/standalone/app/audit/_components/empty-state.tsx +1 -1
  172. package/.next/standalone/app/components/global-error-listeners.tsx +27 -0
  173. package/.next/standalone/app/globals.css +25 -1
  174. package/.next/standalone/app/policies/hooks-client.tsx +2 -4
  175. package/.next/standalone/app/project/[name]/page.tsx +30 -10
  176. package/.next/standalone/app/project/[name]/session/[sessionId]/page.tsx +71 -21
  177. package/.next/standalone/assets/logos/antigravity.svg +1 -0
  178. package/.next/standalone/assets/logos/devin.svg +1 -0
  179. package/.next/standalone/assets/logos/factory-dark.png +0 -0
  180. package/.next/standalone/assets/logos/factory-light.png +0 -0
  181. package/.next/standalone/assets/logos/goose-dark.svg +1 -0
  182. package/.next/standalone/assets/logos/goose-light.svg +1 -0
  183. package/.next/standalone/assets/logos/openclaw.svg +22 -0
  184. package/.next/standalone/ci/cli-integration/Dockerfile +47 -0
  185. package/.next/standalone/ci/cli-integration/README.md +69 -0
  186. package/.next/standalone/ci/cli-integration/canary-policies.mjs +45 -0
  187. package/.next/standalone/ci/cli-integration/capture-tokens.sh +48 -0
  188. package/.next/standalone/ci/cli-integration/inject-tokens.sh +44 -0
  189. package/.next/standalone/ci/cli-integration/install-clis.sh +91 -0
  190. package/.next/standalone/ci/cli-integration/probe-cli.sh +208 -0
  191. package/.next/standalone/ci/cli-integration/report.js +74 -0
  192. package/.next/standalone/ci/cli-integration/run.sh +107 -0
  193. package/.next/standalone/components/navbar.tsx +5 -11
  194. package/.next/standalone/components/reach-developers.tsx +2 -2
  195. package/.next/standalone/docker-hook-sync/Dockerfile +8 -4
  196. package/.next/standalone/lib/antigravity-projects.ts +224 -0
  197. package/.next/standalone/lib/antigravity-sessions.ts +283 -0
  198. package/.next/standalone/lib/cli-registry.ts +26 -6
  199. package/.next/standalone/lib/devin-projects.ts +141 -0
  200. package/.next/standalone/lib/devin-sessions.ts +343 -0
  201. package/.next/standalone/lib/download-session.ts +56 -5
  202. package/.next/standalone/lib/error-origin.ts +67 -0
  203. package/.next/standalone/lib/factory-projects.ts +109 -0
  204. package/.next/standalone/lib/factory-sessions.ts +312 -0
  205. package/.next/standalone/lib/goose-projects.ts +148 -0
  206. package/.next/standalone/lib/goose-sessions.ts +296 -0
  207. package/.next/standalone/lib/install-check.ts +231 -0
  208. package/.next/standalone/lib/openclaw-projects.ts +182 -0
  209. package/.next/standalone/lib/openclaw-sessions.ts +284 -0
  210. package/.next/standalone/lib/projects.ts +33 -9
  211. package/.next/standalone/lib/telemetry-sanitize.ts +43 -0
  212. package/.next/standalone/openclaw-plugin/index.js +223 -0
  213. package/.next/standalone/openclaw-plugin/openclaw.plugin.json +6 -0
  214. package/.next/standalone/openclaw-plugin/package.json +12 -0
  215. package/.next/standalone/package.json +2 -3
  216. package/.next/standalone/server.js +1 -1
  217. package/README.md +94 -62
  218. package/bin/failproofai.mjs +98 -30
  219. package/dist/cli.mjs +12499 -9243
  220. package/lib/antigravity-projects.ts +224 -0
  221. package/lib/antigravity-sessions.ts +283 -0
  222. package/lib/cli-registry.ts +26 -6
  223. package/lib/devin-projects.ts +141 -0
  224. package/lib/devin-sessions.ts +343 -0
  225. package/lib/download-session.ts +56 -5
  226. package/lib/error-origin.ts +67 -0
  227. package/lib/factory-projects.ts +109 -0
  228. package/lib/factory-sessions.ts +312 -0
  229. package/lib/goose-projects.ts +148 -0
  230. package/lib/goose-sessions.ts +296 -0
  231. package/lib/install-check.ts +231 -0
  232. package/lib/openclaw-projects.ts +182 -0
  233. package/lib/openclaw-sessions.ts +284 -0
  234. package/lib/projects.ts +33 -9
  235. package/lib/telemetry-sanitize.ts +43 -0
  236. package/openclaw-plugin/index.js +223 -0
  237. package/openclaw-plugin/openclaw.plugin.json +6 -0
  238. package/openclaw-plugin/package.json +12 -0
  239. package/package.json +2 -3
  240. package/scripts/dev-hook.mjs +292 -0
  241. package/scripts/install-diagnosis.mjs +5 -8
  242. package/scripts/install-telemetry.mjs +12 -4
  243. package/scripts/launch.ts +4 -8
  244. package/scripts/sync-agent-cli-harnesses-prompt.md +7 -10
  245. package/scripts/translate-docs/cli.ts +120 -53
  246. package/scripts/translate-docs/config.ts +57 -13
  247. package/scripts/translate-docs/mdx-translator.ts +177 -28
  248. package/scripts/translate-docs/mintlify-nav.ts +91 -10
  249. package/scripts/translate-docs/readme-translator.ts +13 -5
  250. package/scripts/translate-docs/translator.ts +38 -2
  251. package/scripts/translate-docs/types.ts +3 -0
  252. package/scripts/validate-mdx.ts +12 -4
  253. package/src/audit/cli-adapters/antigravity.ts +87 -0
  254. package/src/audit/cli-adapters/devin.ts +53 -0
  255. package/src/audit/cli-adapters/factory.ts +75 -0
  256. package/src/audit/cli-adapters/goose.ts +53 -0
  257. package/src/audit/cli-adapters/index.ts +30 -6
  258. package/src/audit/cli-adapters/openclaw.ts +56 -0
  259. package/src/audit/cli.ts +83 -8
  260. package/src/audit/report.ts +1 -1
  261. package/src/audit/types.ts +1 -1
  262. package/src/hooks/builtin-policies.ts +5 -5
  263. package/src/hooks/configure-wizard.ts +356 -0
  264. package/src/hooks/handler.ts +283 -218
  265. package/src/hooks/hook-telemetry.ts +43 -3
  266. package/src/hooks/install-prompt.ts +92 -173
  267. package/src/hooks/integrations.ts +739 -138
  268. package/src/hooks/manager.ts +46 -2
  269. package/src/hooks/policy-evaluator.ts +301 -121
  270. package/src/hooks/policy-presets.ts +71 -0
  271. package/src/hooks/resolve-cwd.ts +1 -1
  272. package/src/hooks/resolve-permission-mode.ts +1 -5
  273. package/src/hooks/resolve-transcript-path.ts +25 -7
  274. package/src/hooks/tool-name-canonicalize.ts +36 -3
  275. package/src/hooks/tui.ts +578 -0
  276. package/src/hooks/types.ts +447 -109
  277. package/.next/standalone/.gemini/settings.json +0 -147
  278. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0cag8qd._.js +0 -3
  279. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0cefjd9._.js +0 -3
  280. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ekj92q._.js +0 -3
  281. package/.next/standalone/.next/server/chunks/[root-of-the-server]__12v-lma._.js +0 -3
  282. package/.next/standalone/.next/server/chunks/[root-of-the-server]__136y39g._.js +0 -3
  283. package/.next/standalone/.next/server/chunks/[root-of-the-server]__13h8pzr._.js +0 -3
  284. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1hgv_75._.js +0 -3
  285. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__04bqvos._.js +0 -3
  286. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0dqgs96._.js +0 -3
  287. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0q5rfxg._.js +0 -3
  288. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qukut7._.js +0 -4
  289. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1ql-mch._.js +0 -3
  290. package/.next/standalone/.next/server/chunks/ssr/_11v0g3z._.js +0 -3
  291. package/.next/standalone/.next/server/chunks/ssr/lib_gemini-projects_ts_1c7bgx-._.js +0 -3
  292. package/.next/standalone/.next/static/chunks/0fa7j157kg9_d.js +0 -1
  293. package/.next/standalone/.next/static/chunks/0nrah-qv6smeg.js +0 -6
  294. package/.next/standalone/.next/static/chunks/0wtagd8a5gwq-.js +0 -1
  295. package/.next/standalone/.next/static/chunks/1c8i78p7t1i-5.js +0 -1
  296. package/.next/standalone/.next/static/chunks/25qr0e6ez0ei0.js +0 -1
  297. package/.next/standalone/.next/static/chunks/25s52un3k_wht.css +0 -2
  298. package/.next/standalone/assets/logos/gemini-dark.svg +0 -13
  299. package/.next/standalone/assets/logos/gemini-light.svg +0 -13
  300. package/.next/standalone/lib/gemini-projects.ts +0 -243
  301. package/.next/standalone/lib/gemini-sessions.ts +0 -365
  302. package/lib/gemini-projects.ts +0 -243
  303. package/lib/gemini-sessions.ts +0 -365
  304. package/scripts/postinstall.mjs +0 -243
  305. package/scripts/preuninstall.mjs +0 -131
  306. package/src/audit/cli-adapters/gemini.ts +0 -51
  307. package/src/hooks/first-run-nudge.ts +0 -146
  308. /package/.next/standalone/.next/static/{kmzdjTLVs6LqsfyOaUf69 → LkN-JjmhKGmL-WklH7WVi}/_buildManifest.js +0 -0
  309. /package/.next/standalone/.next/static/{kmzdjTLVs6LqsfyOaUf69 → LkN-JjmhKGmL-WklH7WVi}/_clientMiddlewareManifest.js +0 -0
  310. /package/.next/standalone/.next/static/{kmzdjTLVs6LqsfyOaUf69 → LkN-JjmhKGmL-WklH7WVi}/_ssgManifest.js +0 -0
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Factory (droid) transcript adapter — AUDIT (Pillar 2).
3
+ *
4
+ * droid writes real JSONL transcripts at
5
+ * `~/.factory/sessions/<encoded-cwd>/<sessionId>.jsonl` (Claude-style
6
+ * encoded-cwd folders; verified live against droid v0.171.0).
7
+ * lib/factory-sessions.ts enumerates and parses them into the shared
8
+ * LogEntry[] shape, so `logEntriesToEvents` handles the rest.
9
+ */
10
+ import { readFile } from "node:fs/promises";
11
+ import {
12
+ listFactoryTranscripts,
13
+ factoryLinesToLogEntries,
14
+ } from "../../../lib/factory-sessions";
15
+ import { parseRawLines } from "../../../lib/log-entries";
16
+ import type { NormalizedToolEvent, TranscriptMetadata } from "../types";
17
+ import type { ListOpts } from "./claude";
18
+ import { logEntriesToEvents } from "./shared";
19
+
20
+ export async function listFactoryTranscriptMetadata(
21
+ opts: ListOpts = {},
22
+ ): Promise<TranscriptMetadata[]> {
23
+ const projectFilter = opts.projects ? new Set(opts.projects) : null;
24
+ const sinceMs = opts.sinceMs ?? 0;
25
+ const out: TranscriptMetadata[] = [];
26
+
27
+ for (const t of listFactoryTranscripts()) {
28
+ if (t.mtimeMs < sinceMs) continue;
29
+ // `audit --project <cwd>` filters on the decoded working directory.
30
+ if (projectFilter && !projectFilter.has(t.cwd)) continue;
31
+ out.push({
32
+ cli: "factory",
33
+ projectName: t.projectName,
34
+ sessionId: t.sessionId,
35
+ transcriptPath: t.transcriptPath,
36
+ mtimeMs: t.mtimeMs,
37
+ sizeBytes: t.sizeBytes,
38
+ });
39
+ }
40
+ return out;
41
+ }
42
+
43
+ export async function streamFactoryEvents(
44
+ meta: TranscriptMetadata,
45
+ ): Promise<NormalizedToolEvent[]> {
46
+ let content: string;
47
+ try {
48
+ content = await readFile(meta.transcriptPath, "utf-8");
49
+ } catch {
50
+ return [];
51
+ }
52
+
53
+ const rawLines = parseRawLines(content, "session");
54
+ const entries = factoryLinesToLogEntries(rawLines, "session");
55
+
56
+ // cwd lives on the `type:"session_start"` header line — recover the canonical
57
+ // value rather than re-decoding the (lossy) folder name.
58
+ let cwd = "";
59
+ for (const line of rawLines) {
60
+ if (line && typeof line === "object" && (line as Record<string, unknown>).type === "session_start") {
61
+ const c = (line as Record<string, unknown>).cwd;
62
+ if (typeof c === "string" && c.length > 0) {
63
+ cwd = c;
64
+ break;
65
+ }
66
+ }
67
+ }
68
+
69
+ return logEntriesToEvents(entries, {
70
+ cli: "factory",
71
+ sessionId: meta.sessionId,
72
+ transcriptPath: meta.transcriptPath,
73
+ cwd,
74
+ });
75
+ }
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Goose (codename goose, Block) transcript adapter — AUDIT-ONLY (Pillar 2).
3
+ *
4
+ * Goose keeps every session in one SQLite DB at
5
+ * `~/.local/share/goose/sessions/sessions.db`. We read it directly via the
6
+ * bundled sql.js reader (lib/goose-projects.ts enumerates the `sessions` table;
7
+ * lib/goose-sessions.ts parses each session's `messages`), producing the same
8
+ * LogEntry[] shape the other adapters do — so `logEntriesToEvents` handles the
9
+ * rest. Like Devin, each Goose session carries a real `working_dir`, so
10
+ * `audit --project <cwd>` filters work (unlike the cwd-less Hermes gateway).
11
+ */
12
+ import { getGooseSessions } from "../../../lib/goose-projects";
13
+ import { getGooseSessionLog } from "../../../lib/goose-sessions";
14
+ import type { NormalizedToolEvent, TranscriptMetadata } from "../types";
15
+ import type { ListOpts } from "./claude";
16
+ import { logEntriesToEvents } from "./shared";
17
+
18
+ export async function listGooseTranscriptMetadata(
19
+ opts: ListOpts = {},
20
+ ): Promise<TranscriptMetadata[]> {
21
+ const projectFilter = opts.projects ? new Set(opts.projects) : null;
22
+ const sinceMs = opts.sinceMs ?? 0;
23
+ const sessions = await getGooseSessions();
24
+ const out: TranscriptMetadata[] = [];
25
+ for (const s of sessions) {
26
+ if (s.mtimeMs < sinceMs) continue;
27
+ // `audit --project <cwd>` filters on the session's working directory.
28
+ if (projectFilter && (!s.cwd || !projectFilter.has(s.cwd))) continue;
29
+ out.push({
30
+ cli: "goose",
31
+ projectName: s.projectName,
32
+ sessionId: s.sessionId,
33
+ transcriptPath: `goose-db://${s.sessionId}`,
34
+ mtimeMs: s.mtimeMs,
35
+ // mtime advances on each message, so (mtime) forms a real cache key.
36
+ sizeBytes: 0,
37
+ });
38
+ }
39
+ return out;
40
+ }
41
+
42
+ export async function streamGooseEvents(
43
+ meta: TranscriptMetadata,
44
+ ): Promise<NormalizedToolEvent[]> {
45
+ const log = await getGooseSessionLog(meta.sessionId);
46
+ if (!log) return [];
47
+ return logEntriesToEvents(log.entries, {
48
+ cli: "goose",
49
+ sessionId: meta.sessionId,
50
+ transcriptPath: meta.transcriptPath,
51
+ cwd: log.cwd ?? "",
52
+ });
53
+ }
@@ -17,8 +17,12 @@ import { listCopilotTranscriptMetadata, streamCopilotEvents } from "./copilot";
17
17
  import { listCursorTranscriptMetadata, streamCursorEvents } from "./cursor";
18
18
  import { listOpenCodeTranscriptMetadata, streamOpenCodeEvents } from "./opencode";
19
19
  import { listPiTranscriptMetadata, streamPiEvents } from "./pi";
20
- import { listGeminiTranscriptMetadata, streamGeminiEvents } from "./gemini";
21
20
  import { listHermesTranscriptMetadata, streamHermesEvents } from "./hermes";
21
+ import { listOpenClawTranscriptMetadata, streamOpenClawEvents } from "./openclaw";
22
+ import { listFactoryTranscriptMetadata, streamFactoryEvents } from "./factory";
23
+ import { listAntigravityTranscriptMetadata, streamAntigravityEvents } from "./antigravity";
24
+ import { listDevinTranscriptMetadata, streamDevinEvents } from "./devin";
25
+ import { listGooseTranscriptMetadata, streamGooseEvents } from "./goose";
22
26
 
23
27
  export type { ListOpts };
24
28
 
@@ -59,16 +63,36 @@ export const ADAPTERS: Record<IntegrationType, CliAdapter> = {
59
63
  listTranscripts: listPiTranscriptMetadata,
60
64
  streamEvents: streamPiEvents,
61
65
  },
62
- gemini: {
63
- cli: "gemini",
64
- listTranscripts: listGeminiTranscriptMetadata,
65
- streamEvents: streamGeminiEvents,
66
- },
67
66
  hermes: {
68
67
  cli: "hermes",
69
68
  listTranscripts: listHermesTranscriptMetadata,
70
69
  streamEvents: streamHermesEvents,
71
70
  },
71
+ openclaw: {
72
+ cli: "openclaw",
73
+ listTranscripts: listOpenClawTranscriptMetadata,
74
+ streamEvents: streamOpenClawEvents,
75
+ },
76
+ factory: {
77
+ cli: "factory",
78
+ listTranscripts: listFactoryTranscriptMetadata,
79
+ streamEvents: streamFactoryEvents,
80
+ },
81
+ devin: {
82
+ cli: "devin",
83
+ listTranscripts: listDevinTranscriptMetadata,
84
+ streamEvents: streamDevinEvents,
85
+ },
86
+ antigravity: {
87
+ cli: "antigravity",
88
+ listTranscripts: listAntigravityTranscriptMetadata,
89
+ streamEvents: streamAntigravityEvents,
90
+ },
91
+ goose: {
92
+ cli: "goose",
93
+ listTranscripts: listGooseTranscriptMetadata,
94
+ streamEvents: streamGooseEvents,
95
+ },
72
96
  };
73
97
 
74
98
  export function getAdapter(cli: IntegrationType): CliAdapter {
@@ -0,0 +1,56 @@
1
+ /**
2
+ * OpenClaw (openclaw gateway) transcript adapter — AUDIT (Pillar 2).
3
+ *
4
+ * OpenClaw writes real JSONL transcripts at
5
+ * `~/.openclaw/agents/<agentId>/sessions/<uuid>.jsonl` (verified live against
6
+ * v2026.7.1). lib/openclaw-sessions.ts enumerates and parses them into the
7
+ * shared LogEntry[] shape, so `logEntriesToEvents` handles the rest.
8
+ *
9
+ * Gateway sessions run in the container workspace, not a host repo, so they
10
+ * group by agentId (`openclaw:<agentId>`) and contribute nothing to a
11
+ * cwd-scoped audit.
12
+ */
13
+ import {
14
+ listOpenClawTranscripts,
15
+ getOpenClawSessionLog,
16
+ } from "../../../lib/openclaw-sessions";
17
+ import type { NormalizedToolEvent, TranscriptMetadata } from "../types";
18
+ import type { ListOpts } from "./claude";
19
+ import { logEntriesToEvents } from "./shared";
20
+
21
+ export async function listOpenClawTranscriptMetadata(
22
+ opts: ListOpts = {},
23
+ ): Promise<TranscriptMetadata[]> {
24
+ // `audit --project <cwd>` filters on working directory; gateway sessions run
25
+ // in the container workspace, not a host repo, so OpenClaw contributes
26
+ // nothing to a cwd-scoped audit.
27
+ if (opts.projects && opts.projects.length > 0) return [];
28
+
29
+ const sinceMs = opts.sinceMs ?? 0;
30
+ const out: TranscriptMetadata[] = [];
31
+ for (const t of listOpenClawTranscripts()) {
32
+ if (t.mtimeMs < sinceMs) continue;
33
+ out.push({
34
+ cli: "openclaw",
35
+ projectName: `openclaw:${t.agentId}`,
36
+ sessionId: t.sessionId,
37
+ transcriptPath: t.transcriptPath,
38
+ mtimeMs: t.mtimeMs,
39
+ sizeBytes: t.sizeBytes,
40
+ });
41
+ }
42
+ return out;
43
+ }
44
+
45
+ export async function streamOpenClawEvents(
46
+ meta: TranscriptMetadata,
47
+ ): Promise<NormalizedToolEvent[]> {
48
+ const log = await getOpenClawSessionLog(meta.sessionId);
49
+ if (!log) return [];
50
+ return logEntriesToEvents(log.entries, {
51
+ cli: "openclaw",
52
+ sessionId: meta.sessionId,
53
+ transcriptPath: meta.transcriptPath,
54
+ cwd: log.cwd ?? "",
55
+ });
56
+ }
package/src/audit/cli.ts CHANGED
@@ -20,6 +20,7 @@ import { writeDashboardCache } from "./dashboard-cache";
20
20
  import type { AuditResult, RunAuditOptions } from "./types";
21
21
  import { trackHookEvent } from "../hooks/hook-telemetry";
22
22
  import { getInstanceId } from "../../lib/telemetry-id";
23
+ import { sanitizeErrorMessage } from "../../lib/telemetry-sanitize";
23
24
  import { openWhenReady } from "./open-browser";
24
25
 
25
26
  /** Port the bundled dashboard binds to. Matches `scripts/launch.ts`'s default
@@ -49,7 +50,7 @@ USAGE
49
50
 
50
51
  WHAT IT DOES
51
52
  1. Scans past sessions from every installed agent CLI (Claude, Codex, Cursor,
52
- Copilot, OpenCode, Pi, Gemini) — entirely on your machine.
53
+ Copilot, OpenCode, Pi) — entirely on your machine.
53
54
  2. Starts the local dashboard and opens
54
55
  http://localhost:${DASHBOARD_PORT}/audit with your results.
55
56
 
@@ -236,6 +237,85 @@ function printSummary(result: AuditResult): void {
236
237
  for (const line of buildSummary(result)) process.stdout.write(` ${line}\n`);
237
238
  }
238
239
 
240
+ // ── Audit telemetry ──────────────────────────────────────────────────────────
241
+
242
+ /**
243
+ * Which entry point ran the audit. `onboarding` is the automatic post-setup run;
244
+ * `cli` is an explicit `failproofai audit`. Carried on every cli_audit_* event so
245
+ * the first audit a user ever runs is distinguishable from later deliberate ones.
246
+ */
247
+ type AuditSource = "cli" | "onboarding";
248
+
249
+ /** Shared so both entry points report cli_audit_completed identically. */
250
+ function auditCompletedProps(source: AuditSource, result: AuditResult) {
251
+ return {
252
+ source,
253
+ events_scanned: result.eventsScanned,
254
+ sessions_scanned: result.transcripts.scanned,
255
+ total_hits: result.totals.hits,
256
+ findings: result.results.length,
257
+ };
258
+ }
259
+
260
+ // ── Post-setup background audit ────────────────────────────────────────────────
261
+
262
+ /**
263
+ * Run the audit *pipeline* (scan + cache write + summary) once the setup flow
264
+ * completes, right before the dashboard boots. Pre-warms
265
+ * `~/.failproofai/audit-dashboard.json` so the dashboard renders instantly, and
266
+ * immediately shows the user what's slipping through.
267
+ *
268
+ * Shows the same animated stages as `failproofai audit`. The scan runs to
269
+ * completion; Ctrl+C interrupts it the usual way (default SIGINT). Best-effort:
270
+ * never throws, never exits the process; the caller boots the dashboard
271
+ * afterward. Opt out with `FAILPROOFAI_NO_AUTO_AUDIT=1`.
272
+ */
273
+ export async function runPostSetupAudit(): Promise<void> {
274
+ if (process.env.FAILPROOFAI_NO_AUTO_AUDIT === "1") return;
275
+
276
+ const instanceId = getInstanceId();
277
+ // Fire-and-forget, as in runAuditCli: the multi-second scan below keeps the
278
+ // process alive long enough for this to land, and the completed/failed event
279
+ // that follows is awaited.
280
+ void trackHookEvent(instanceId, "cli_audit_started", { source: "onboarding" });
281
+
282
+ process.stdout.write(
283
+ `\n ${c(PINK, "✦")} ${c(BOLD, "failproofai audit now running")} ${c(DIM, "· ctrl+c to stop")}\n\n`,
284
+ );
285
+
286
+ let result: AuditResult;
287
+ try {
288
+ result = await runWithProgress({});
289
+ } catch (err) {
290
+ // Awaited: this function returns straight into the dashboard boot, and a
291
+ // fire-and-forget fetch would race it.
292
+ await trackHookEvent(instanceId, "cli_audit_failed", {
293
+ source: "onboarding",
294
+ error_type: err instanceof Error ? err.name : "unknown",
295
+ error_message: sanitizeErrorMessage(err),
296
+ });
297
+ process.stdout.write(
298
+ ` ${c(PINK, "!")} ${c(DIM, "audit couldn't finish — run")} ${c(CYAN, "failproofai audit")} ${c(DIM, "later.")}\n\n`,
299
+ );
300
+ return;
301
+ }
302
+
303
+ // Reported before the empty-history return below, so an onboarding audit that
304
+ // finds nothing is still counted — matching runAuditCli, which reports
305
+ // completed regardless of what the scan turned up.
306
+ await trackHookEvent(instanceId, "cli_audit_completed", auditCompletedProps("onboarding", result));
307
+
308
+ if (result.eventsScanned === 0) {
309
+ process.stdout.write(
310
+ `\n ${c(DIM, "no agent sessions to audit yet — come back after using your agent.")}\n\n`,
311
+ );
312
+ return;
313
+ }
314
+ writeDashboardCache({}, result);
315
+ printSummary(result);
316
+ process.stdout.write("\n");
317
+ }
318
+
239
319
  // ── Entry point ──────────────────────────────────────────────────────────────
240
320
 
241
321
  export async function runAuditCli(args: string[]): Promise<void> {
@@ -275,6 +355,7 @@ export async function runAuditCli(args: string[]): Promise<void> {
275
355
  await trackHookEvent(instanceId, "cli_audit_failed", {
276
356
  source: "cli",
277
357
  error_type: err instanceof Error ? err.name : "unknown",
358
+ error_message: sanitizeErrorMessage(err),
278
359
  });
279
360
  die(`Audit failed: ${err instanceof Error ? err.message : String(err)}`);
280
361
  }
@@ -285,13 +366,7 @@ export async function runAuditCli(args: string[]): Promise<void> {
285
366
  // would otherwise drop this event. On the dashboard path launch() keeps the
286
367
  // process alive, but awaiting makes delivery reliable on every exit path.
287
368
  // Bounded (5s) and never throws.
288
- await trackHookEvent(instanceId, "cli_audit_completed", {
289
- source: "cli",
290
- events_scanned: result.eventsScanned,
291
- sessions_scanned: result.transcripts.scanned,
292
- total_hits: result.totals.hits,
293
- findings: result.results.length,
294
- });
369
+ await trackHookEvent(instanceId, "cli_audit_completed", auditCompletedProps("cli", result));
295
370
 
296
371
  // No sessions on disk — guide the user instead of opening an empty dashboard.
297
372
  if (result.eventsScanned === 0) {
@@ -273,7 +273,7 @@ export function formatMarkdown(result: AuditResult): string {
273
273
  );
274
274
  }
275
275
  out.push("");
276
- out.push("> [failproofai](https://github.com/FailproofAI/failproofai) is a hook-based policy engine for Claude Code, Codex, Copilot, Cursor, OpenCode, Pi, and Gemini CLI. The `audit` command replays past agent sessions through every builtin policy to surface patterns that were (or could've been) stopped.");
276
+ out.push("> [failproofai](https://github.com/FailproofAI/failproofai) is a hook-based policy engine for Claude Code, Codex, Copilot, Cursor, OpenCode, and Pi. The `audit` command replays past agent sessions through every builtin policy to surface patterns that were (or could've been) stopped.");
277
277
  out.push("");
278
278
 
279
279
  if (totalHits === 0) return out.join("\n");
@@ -24,7 +24,7 @@ export interface NormalizedToolEvent {
24
24
  toolName: string;
25
25
  /** Canonicalized tool input (snake_case keys for OpenCode/Pi). */
26
26
  toolInput: Record<string, unknown>;
27
- /** Pre-canonicalization tool name (e.g. "run_shell_command" for Gemini). */
27
+ /** Pre-canonicalization tool name (e.g. "exec" for OpenClaw). */
28
28
  rawToolName: string;
29
29
  /**
30
30
  * Result text from the matching tool_result block, if present in the
@@ -53,9 +53,9 @@ function isAgentInternalPath(resolved: string): boolean {
53
53
  * • Pi: `.pi/settings.json` (project) and `.pi/agent/settings.json`
54
54
  * (user); also the Pi-managed extension dir
55
55
  * `.pi/extensions/` / `.pi/agent/extensions/`.
56
- * • Gemini CLI: `.gemini/settings.json` (both project and user scope —
57
- * user is `~/.gemini/settings.json`); also the Gemini-managed
58
- * hooks scripts dir `.gemini/hooks/`.
56
+ * • Antigravity CLI (agy): reuses `~/.gemini/` — `~/.gemini/settings.json`
57
+ * and the customization-root hook config
58
+ * `~/.gemini/config/hooks.json`.
59
59
  * These must NEVER be edited by the agent itself — that would let it disable
60
60
  * its own protections.
61
61
  */
@@ -74,9 +74,9 @@ function isAgentSettingsFile(resolved: string): boolean {
74
74
  // Pi: settings + extensions dirs (project and user-scope variants).
75
75
  if (/[\\/]\.pi[\\/](?:agent[\\/])?settings\.json$/.test(resolved)) return true;
76
76
  if (/[\\/]\.pi[\\/](?:agent[\\/])?extensions[\\/]/.test(resolved)) return true;
77
- // Gemini: settings.json + hooks dir referenced by `command: $GEMINI_PROJECT_DIR/.gemini/hooks/...`.
77
+ // Antigravity (agy) reuses ~/.gemini/: settings.json + the customization-root hooks.json.
78
78
  if (/[\\/]\.gemini[\\/]settings\.json$/.test(resolved)) return true;
79
- if (/[\\/]\.gemini[\\/]hooks[\\/]/.test(resolved)) return true;
79
+ if (/[\\/]\.gemini[\\/]config[\\/]hooks\.json$/.test(resolved)) return true;
80
80
  return false;
81
81
  }
82
82