failproofai 0.0.6-beta.2 → 0.0.6-beta.4

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 (511) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/build-manifest.json +3 -3
  3. package/.next/standalone/.next/prerender-manifest.json +3 -3
  4. package/.next/standalone/.next/required-server-files.json +7 -1
  5. package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
  6. package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  7. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  8. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
  10. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +2 -2
  11. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
  12. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +3 -3
  13. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +3 -3
  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/server-reference-manifest.json +1 -1
  16. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  17. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  18. package/.next/standalone/.next/server/app/_not-found.html +2 -2
  19. package/.next/standalone/.next/server/app/_not-found.rsc +17 -17
  20. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +17 -17
  21. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
  22. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +11 -11
  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/_not-found.segment.rsc +3 -3
  25. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  26. package/.next/standalone/.next/server/app/index.html +1 -1
  27. package/.next/standalone/.next/server/app/index.rsc +16 -16
  28. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  29. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +16 -16
  30. package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +4 -4
  31. package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +11 -11
  32. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  33. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
  34. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  35. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  36. package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +8 -8
  37. package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
  38. package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
  39. package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
  40. package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
  41. package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
  42. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
  43. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
  44. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
  45. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
  46. package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
  47. package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
  48. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  49. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0g72weg._.js +1 -1
  50. package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_0z7w.hh._.js +1 -1
  51. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__092s1ta._.js +2 -2
  52. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__09icjsf._.js +2 -2
  53. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0g.lg8b._.js +2 -2
  54. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0h..k-e._.js +2 -2
  55. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0okos0k._.js +2 -2
  56. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0i5kvry._.js → [root-of-the-server]__0om-5pe._.js} +2 -2
  57. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0w6l33k._.js +2 -2
  58. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__05akje6._.js → [root-of-the-server]__111.vxi._.js} +2 -2
  59. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__11pa2ra._.js +2 -2
  60. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__12t-wym._.js +2 -2
  61. package/.next/standalone/.next/server/chunks/ssr/_10lm7or._.js +2 -2
  62. package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_0xerkr6._.js +1 -1
  63. package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_0q-m0y-._.js +1 -1
  64. package/.next/standalone/.next/server/chunks/ssr/node_modules_posthog-node_dist_entrypoints_index_node_mjs_0mebn66._.js +1 -1
  65. package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
  66. package/.next/standalone/.next/server/pages/404.html +2 -2
  67. package/.next/standalone/.next/server/pages/500.html +1 -1
  68. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  69. package/.next/standalone/.next/server/server-reference-manifest.json +9 -9
  70. package/.next/standalone/.next/static/chunks/{05j1px0r8yzh6.js → 02dqjyv6_9mhq.js} +2 -2
  71. package/.next/standalone/.next/static/chunks/{14cl9poem30dq.js → 070orfsl6.xal.js} +1 -1
  72. package/.next/standalone/.next/static/chunks/0mir9jdxn35~s.css +1 -0
  73. package/.next/standalone/.next/static/chunks/{00j0rr7rh8ef8.js → 0o547jv-k_k35.js} +1 -1
  74. package/.next/standalone/.next/static/chunks/{0ijk_kek9_wyx.js → 0pk2h2.mjxy.m.js} +1 -1
  75. package/.next/standalone/.next/static/chunks/{0xpl.oscrakvx.js → 0rcwkbh24w38b.js} +1 -1
  76. package/.next/standalone/.next/static/chunks/{1052sguyd-.ka.js → 140xx_tfr~lm_.js} +1 -1
  77. package/.next/standalone/.next/static/chunks/{0npb~873.wvg3.js → 169_e4dq~1~b6.js} +1 -1
  78. package/.next/standalone/.next/static/chunks/{0badv41uxa56..js → 17ne4p.1sw1jy.js} +1 -1
  79. package/.next/standalone/next.config.ts +6 -0
  80. package/.next/standalone/package.json +2 -2
  81. package/.next/standalone/server.js +1 -1
  82. package/bin/failproofai.mjs +91 -4
  83. package/dist/cli.mjs +1155 -54
  84. package/package.json +2 -2
  85. package/scripts/prune-standalone.mjs +128 -0
  86. package/src/auth/login.ts +104 -0
  87. package/src/auth/logout.ts +50 -0
  88. package/src/auth/token-store.ts +64 -0
  89. package/src/hooks/builtin-policies.ts +22 -20
  90. package/src/hooks/handler.ts +35 -15
  91. package/src/relay/daemon.ts +362 -0
  92. package/src/relay/pid.ts +76 -0
  93. package/src/relay/queue.ts +225 -0
  94. package/.next/standalone/.claude/settings.json +0 -316
  95. package/.next/standalone/.failproofai/policies/review-policies.mjs +0 -113
  96. package/.next/standalone/.failproofai/policies/workflow-policies.mjs +0 -63
  97. package/.next/standalone/.failproofai/policies-config.json +0 -39
  98. package/.next/standalone/.next/static/chunks/0gu_a.a80ritd.css +0 -1
  99. package/.next/standalone/AGENTS.md +0 -80
  100. package/.next/standalone/CHANGELOG.md +0 -151
  101. package/.next/standalone/CLAUDE.md +0 -165
  102. package/.next/standalone/CONTRIBUTING.md +0 -76
  103. package/.next/standalone/Dockerfile.docs +0 -12
  104. package/.next/standalone/LICENSE +0 -42
  105. package/.next/standalone/README.md +0 -301
  106. package/.next/standalone/bin/failproofai.mjs +0 -352
  107. package/.next/standalone/bun.lock +0 -1119
  108. package/.next/standalone/components.json +0 -23
  109. package/.next/standalone/dist/cli.mjs +0 -3595
  110. package/.next/standalone/dist/index.js +0 -80
  111. package/.next/standalone/docs/ar/architecture.mdx +0 -334
  112. package/.next/standalone/docs/ar/built-in-policies.mdx +0 -574
  113. package/.next/standalone/docs/ar/cli/dashboard.mdx +0 -28
  114. package/.next/standalone/docs/ar/cli/environment-variables.mdx +0 -34
  115. package/.next/standalone/docs/ar/cli/hook.mdx +0 -31
  116. package/.next/standalone/docs/ar/cli/install-policies.mdx +0 -48
  117. package/.next/standalone/docs/ar/cli/list-policies.mdx +0 -31
  118. package/.next/standalone/docs/ar/cli/remove-policies.mdx +0 -43
  119. package/.next/standalone/docs/ar/cli/version.mdx +0 -13
  120. package/.next/standalone/docs/ar/configuration.mdx +0 -223
  121. package/.next/standalone/docs/ar/custom-policies.mdx +0 -354
  122. package/.next/standalone/docs/ar/dashboard.mdx +0 -142
  123. package/.next/standalone/docs/ar/examples.mdx +0 -307
  124. package/.next/standalone/docs/ar/for-agents.mdx +0 -39
  125. package/.next/standalone/docs/ar/getting-started.mdx +0 -187
  126. package/.next/standalone/docs/ar/introduction.mdx +0 -58
  127. package/.next/standalone/docs/ar/package-aliases.mdx +0 -82
  128. package/.next/standalone/docs/ar/testing.mdx +0 -261
  129. package/.next/standalone/docs/architecture.mdx +0 -332
  130. package/.next/standalone/docs/built-in-policies.mdx +0 -574
  131. package/.next/standalone/docs/cli/dashboard.mdx +0 -28
  132. package/.next/standalone/docs/cli/environment-variables.mdx +0 -34
  133. package/.next/standalone/docs/cli/hook.mdx +0 -30
  134. package/.next/standalone/docs/cli/install-policies.mdx +0 -47
  135. package/.next/standalone/docs/cli/list-policies.mdx +0 -31
  136. package/.next/standalone/docs/cli/remove-policies.mdx +0 -43
  137. package/.next/standalone/docs/cli/version.mdx +0 -12
  138. package/.next/standalone/docs/configuration.mdx +0 -222
  139. package/.next/standalone/docs/custom-policies.mdx +0 -353
  140. package/.next/standalone/docs/dashboard.mdx +0 -142
  141. package/.next/standalone/docs/de/architecture.mdx +0 -332
  142. package/.next/standalone/docs/de/built-in-policies.mdx +0 -574
  143. package/.next/standalone/docs/de/cli/dashboard.mdx +0 -28
  144. package/.next/standalone/docs/de/cli/environment-variables.mdx +0 -34
  145. package/.next/standalone/docs/de/cli/hook.mdx +0 -30
  146. package/.next/standalone/docs/de/cli/install-policies.mdx +0 -47
  147. package/.next/standalone/docs/de/cli/list-policies.mdx +0 -31
  148. package/.next/standalone/docs/de/cli/remove-policies.mdx +0 -43
  149. package/.next/standalone/docs/de/cli/version.mdx +0 -12
  150. package/.next/standalone/docs/de/configuration.mdx +0 -222
  151. package/.next/standalone/docs/de/custom-policies.mdx +0 -353
  152. package/.next/standalone/docs/de/dashboard.mdx +0 -142
  153. package/.next/standalone/docs/de/examples.mdx +0 -307
  154. package/.next/standalone/docs/de/for-agents.mdx +0 -38
  155. package/.next/standalone/docs/de/getting-started.mdx +0 -186
  156. package/.next/standalone/docs/de/introduction.mdx +0 -57
  157. package/.next/standalone/docs/de/package-aliases.mdx +0 -82
  158. package/.next/standalone/docs/de/testing.mdx +0 -260
  159. package/.next/standalone/docs/docs.json +0 -1002
  160. package/.next/standalone/docs/es/architecture.mdx +0 -332
  161. package/.next/standalone/docs/es/built-in-policies.mdx +0 -574
  162. package/.next/standalone/docs/es/cli/dashboard.mdx +0 -28
  163. package/.next/standalone/docs/es/cli/environment-variables.mdx +0 -34
  164. package/.next/standalone/docs/es/cli/hook.mdx +0 -30
  165. package/.next/standalone/docs/es/cli/install-policies.mdx +0 -47
  166. package/.next/standalone/docs/es/cli/list-policies.mdx +0 -31
  167. package/.next/standalone/docs/es/cli/remove-policies.mdx +0 -43
  168. package/.next/standalone/docs/es/cli/version.mdx +0 -12
  169. package/.next/standalone/docs/es/configuration.mdx +0 -222
  170. package/.next/standalone/docs/es/custom-policies.mdx +0 -353
  171. package/.next/standalone/docs/es/dashboard.mdx +0 -142
  172. package/.next/standalone/docs/es/examples.mdx +0 -307
  173. package/.next/standalone/docs/es/for-agents.mdx +0 -38
  174. package/.next/standalone/docs/es/getting-started.mdx +0 -186
  175. package/.next/standalone/docs/es/introduction.mdx +0 -57
  176. package/.next/standalone/docs/es/package-aliases.mdx +0 -82
  177. package/.next/standalone/docs/es/testing.mdx +0 -260
  178. package/.next/standalone/docs/examples.mdx +0 -307
  179. package/.next/standalone/docs/favicon.ico +0 -0
  180. package/.next/standalone/docs/for-agents.mdx +0 -38
  181. package/.next/standalone/docs/fr/architecture.mdx +0 -332
  182. package/.next/standalone/docs/fr/built-in-policies.mdx +0 -574
  183. package/.next/standalone/docs/fr/cli/dashboard.mdx +0 -28
  184. package/.next/standalone/docs/fr/cli/environment-variables.mdx +0 -34
  185. package/.next/standalone/docs/fr/cli/hook.mdx +0 -30
  186. package/.next/standalone/docs/fr/cli/install-policies.mdx +0 -47
  187. package/.next/standalone/docs/fr/cli/list-policies.mdx +0 -31
  188. package/.next/standalone/docs/fr/cli/remove-policies.mdx +0 -43
  189. package/.next/standalone/docs/fr/cli/version.mdx +0 -12
  190. package/.next/standalone/docs/fr/configuration.mdx +0 -222
  191. package/.next/standalone/docs/fr/custom-policies.mdx +0 -353
  192. package/.next/standalone/docs/fr/dashboard.mdx +0 -142
  193. package/.next/standalone/docs/fr/examples.mdx +0 -307
  194. package/.next/standalone/docs/fr/for-agents.mdx +0 -38
  195. package/.next/standalone/docs/fr/getting-started.mdx +0 -186
  196. package/.next/standalone/docs/fr/introduction.mdx +0 -57
  197. package/.next/standalone/docs/fr/package-aliases.mdx +0 -82
  198. package/.next/standalone/docs/fr/testing.mdx +0 -260
  199. package/.next/standalone/docs/getting-started.mdx +0 -186
  200. package/.next/standalone/docs/he/architecture.mdx +0 -333
  201. package/.next/standalone/docs/he/built-in-policies.mdx +0 -574
  202. package/.next/standalone/docs/he/cli/dashboard.mdx +0 -28
  203. package/.next/standalone/docs/he/cli/environment-variables.mdx +0 -34
  204. package/.next/standalone/docs/he/cli/hook.mdx +0 -30
  205. package/.next/standalone/docs/he/cli/install-policies.mdx +0 -47
  206. package/.next/standalone/docs/he/cli/list-policies.mdx +0 -32
  207. package/.next/standalone/docs/he/cli/remove-policies.mdx +0 -43
  208. package/.next/standalone/docs/he/cli/version.mdx +0 -12
  209. package/.next/standalone/docs/he/configuration.mdx +0 -223
  210. package/.next/standalone/docs/he/custom-policies.mdx +0 -353
  211. package/.next/standalone/docs/he/dashboard.mdx +0 -142
  212. package/.next/standalone/docs/he/examples.mdx +0 -307
  213. package/.next/standalone/docs/he/for-agents.mdx +0 -38
  214. package/.next/standalone/docs/he/getting-started.mdx +0 -186
  215. package/.next/standalone/docs/he/introduction.mdx +0 -57
  216. package/.next/standalone/docs/he/package-aliases.mdx +0 -82
  217. package/.next/standalone/docs/he/testing.mdx +0 -260
  218. package/.next/standalone/docs/hi/architecture.mdx +0 -334
  219. package/.next/standalone/docs/hi/built-in-policies.mdx +0 -576
  220. package/.next/standalone/docs/hi/cli/dashboard.mdx +0 -28
  221. package/.next/standalone/docs/hi/cli/environment-variables.mdx +0 -34
  222. package/.next/standalone/docs/hi/cli/hook.mdx +0 -30
  223. package/.next/standalone/docs/hi/cli/install-policies.mdx +0 -47
  224. package/.next/standalone/docs/hi/cli/list-policies.mdx +0 -31
  225. package/.next/standalone/docs/hi/cli/remove-policies.mdx +0 -43
  226. package/.next/standalone/docs/hi/cli/version.mdx +0 -12
  227. package/.next/standalone/docs/hi/configuration.mdx +0 -222
  228. package/.next/standalone/docs/hi/custom-policies.mdx +0 -354
  229. package/.next/standalone/docs/hi/dashboard.mdx +0 -142
  230. package/.next/standalone/docs/hi/examples.mdx +0 -309
  231. package/.next/standalone/docs/hi/for-agents.mdx +0 -38
  232. package/.next/standalone/docs/hi/getting-started.mdx +0 -187
  233. package/.next/standalone/docs/hi/introduction.mdx +0 -57
  234. package/.next/standalone/docs/hi/package-aliases.mdx +0 -82
  235. package/.next/standalone/docs/hi/testing.mdx +0 -260
  236. package/.next/standalone/docs/i18n/README.ar.md +0 -312
  237. package/.next/standalone/docs/i18n/README.de.md +0 -307
  238. package/.next/standalone/docs/i18n/README.es.md +0 -307
  239. package/.next/standalone/docs/i18n/README.fr.md +0 -307
  240. package/.next/standalone/docs/i18n/README.he.md +0 -312
  241. package/.next/standalone/docs/i18n/README.hi.md +0 -307
  242. package/.next/standalone/docs/i18n/README.it.md +0 -307
  243. package/.next/standalone/docs/i18n/README.ja.md +0 -307
  244. package/.next/standalone/docs/i18n/README.ko.md +0 -307
  245. package/.next/standalone/docs/i18n/README.pt-br.md +0 -307
  246. package/.next/standalone/docs/i18n/README.ru.md +0 -308
  247. package/.next/standalone/docs/i18n/README.tr.md +0 -307
  248. package/.next/standalone/docs/i18n/README.vi.md +0 -307
  249. package/.next/standalone/docs/i18n/README.zh.md +0 -307
  250. package/.next/standalone/docs/introduction.mdx +0 -57
  251. package/.next/standalone/docs/it/architecture.mdx +0 -334
  252. package/.next/standalone/docs/it/built-in-policies.mdx +0 -574
  253. package/.next/standalone/docs/it/cli/dashboard.mdx +0 -28
  254. package/.next/standalone/docs/it/cli/environment-variables.mdx +0 -34
  255. package/.next/standalone/docs/it/cli/hook.mdx +0 -30
  256. package/.next/standalone/docs/it/cli/install-policies.mdx +0 -47
  257. package/.next/standalone/docs/it/cli/list-policies.mdx +0 -31
  258. package/.next/standalone/docs/it/cli/remove-policies.mdx +0 -43
  259. package/.next/standalone/docs/it/cli/version.mdx +0 -12
  260. package/.next/standalone/docs/it/configuration.mdx +0 -222
  261. package/.next/standalone/docs/it/custom-policies.mdx +0 -353
  262. package/.next/standalone/docs/it/dashboard.mdx +0 -142
  263. package/.next/standalone/docs/it/examples.mdx +0 -307
  264. package/.next/standalone/docs/it/for-agents.mdx +0 -38
  265. package/.next/standalone/docs/it/getting-started.mdx +0 -186
  266. package/.next/standalone/docs/it/introduction.mdx +0 -57
  267. package/.next/standalone/docs/it/package-aliases.mdx +0 -82
  268. package/.next/standalone/docs/it/testing.mdx +0 -260
  269. package/.next/standalone/docs/ja/architecture.mdx +0 -332
  270. package/.next/standalone/docs/ja/built-in-policies.mdx +0 -572
  271. package/.next/standalone/docs/ja/cli/dashboard.mdx +0 -28
  272. package/.next/standalone/docs/ja/cli/environment-variables.mdx +0 -34
  273. package/.next/standalone/docs/ja/cli/hook.mdx +0 -30
  274. package/.next/standalone/docs/ja/cli/install-policies.mdx +0 -47
  275. package/.next/standalone/docs/ja/cli/list-policies.mdx +0 -31
  276. package/.next/standalone/docs/ja/cli/remove-policies.mdx +0 -43
  277. package/.next/standalone/docs/ja/cli/version.mdx +0 -12
  278. package/.next/standalone/docs/ja/configuration.mdx +0 -222
  279. package/.next/standalone/docs/ja/custom-policies.mdx +0 -353
  280. package/.next/standalone/docs/ja/dashboard.mdx +0 -142
  281. package/.next/standalone/docs/ja/examples.mdx +0 -307
  282. package/.next/standalone/docs/ja/for-agents.mdx +0 -38
  283. package/.next/standalone/docs/ja/getting-started.mdx +0 -186
  284. package/.next/standalone/docs/ja/introduction.mdx +0 -57
  285. package/.next/standalone/docs/ja/package-aliases.mdx +0 -82
  286. package/.next/standalone/docs/ja/testing.mdx +0 -260
  287. package/.next/standalone/docs/ko/architecture.mdx +0 -332
  288. package/.next/standalone/docs/ko/built-in-policies.mdx +0 -572
  289. package/.next/standalone/docs/ko/cli/dashboard.mdx +0 -28
  290. package/.next/standalone/docs/ko/cli/environment-variables.mdx +0 -34
  291. package/.next/standalone/docs/ko/cli/hook.mdx +0 -30
  292. package/.next/standalone/docs/ko/cli/install-policies.mdx +0 -47
  293. package/.next/standalone/docs/ko/cli/list-policies.mdx +0 -31
  294. package/.next/standalone/docs/ko/cli/remove-policies.mdx +0 -43
  295. package/.next/standalone/docs/ko/cli/version.mdx +0 -12
  296. package/.next/standalone/docs/ko/configuration.mdx +0 -222
  297. package/.next/standalone/docs/ko/custom-policies.mdx +0 -353
  298. package/.next/standalone/docs/ko/dashboard.mdx +0 -142
  299. package/.next/standalone/docs/ko/examples.mdx +0 -307
  300. package/.next/standalone/docs/ko/for-agents.mdx +0 -38
  301. package/.next/standalone/docs/ko/getting-started.mdx +0 -186
  302. package/.next/standalone/docs/ko/introduction.mdx +0 -57
  303. package/.next/standalone/docs/ko/package-aliases.mdx +0 -82
  304. package/.next/standalone/docs/ko/testing.mdx +0 -260
  305. package/.next/standalone/docs/logo/dark.svg +0 -21
  306. package/.next/standalone/docs/logo/exosphere-dark.png +0 -0
  307. package/.next/standalone/docs/logo/exosphere-light.png +0 -0
  308. package/.next/standalone/docs/logo/light.svg +0 -21
  309. package/.next/standalone/docs/package-aliases.mdx +0 -82
  310. package/.next/standalone/docs/pt-br/architecture.mdx +0 -332
  311. package/.next/standalone/docs/pt-br/built-in-policies.mdx +0 -574
  312. package/.next/standalone/docs/pt-br/cli/dashboard.mdx +0 -28
  313. package/.next/standalone/docs/pt-br/cli/environment-variables.mdx +0 -34
  314. package/.next/standalone/docs/pt-br/cli/hook.mdx +0 -30
  315. package/.next/standalone/docs/pt-br/cli/install-policies.mdx +0 -47
  316. package/.next/standalone/docs/pt-br/cli/list-policies.mdx +0 -31
  317. package/.next/standalone/docs/pt-br/cli/remove-policies.mdx +0 -43
  318. package/.next/standalone/docs/pt-br/cli/version.mdx +0 -12
  319. package/.next/standalone/docs/pt-br/configuration.mdx +0 -222
  320. package/.next/standalone/docs/pt-br/custom-policies.mdx +0 -353
  321. package/.next/standalone/docs/pt-br/dashboard.mdx +0 -142
  322. package/.next/standalone/docs/pt-br/examples.mdx +0 -307
  323. package/.next/standalone/docs/pt-br/for-agents.mdx +0 -38
  324. package/.next/standalone/docs/pt-br/getting-started.mdx +0 -186
  325. package/.next/standalone/docs/pt-br/introduction.mdx +0 -57
  326. package/.next/standalone/docs/pt-br/package-aliases.mdx +0 -82
  327. package/.next/standalone/docs/pt-br/testing.mdx +0 -260
  328. package/.next/standalone/docs/ru/architecture.mdx +0 -333
  329. package/.next/standalone/docs/ru/built-in-policies.mdx +0 -574
  330. package/.next/standalone/docs/ru/cli/dashboard.mdx +0 -28
  331. package/.next/standalone/docs/ru/cli/environment-variables.mdx +0 -34
  332. package/.next/standalone/docs/ru/cli/hook.mdx +0 -30
  333. package/.next/standalone/docs/ru/cli/install-policies.mdx +0 -48
  334. package/.next/standalone/docs/ru/cli/list-policies.mdx +0 -32
  335. package/.next/standalone/docs/ru/cli/remove-policies.mdx +0 -43
  336. package/.next/standalone/docs/ru/cli/version.mdx +0 -12
  337. package/.next/standalone/docs/ru/configuration.mdx +0 -222
  338. package/.next/standalone/docs/ru/custom-policies.mdx +0 -354
  339. package/.next/standalone/docs/ru/dashboard.mdx +0 -142
  340. package/.next/standalone/docs/ru/examples.mdx +0 -309
  341. package/.next/standalone/docs/ru/for-agents.mdx +0 -38
  342. package/.next/standalone/docs/ru/getting-started.mdx +0 -186
  343. package/.next/standalone/docs/ru/introduction.mdx +0 -57
  344. package/.next/standalone/docs/ru/package-aliases.mdx +0 -82
  345. package/.next/standalone/docs/ru/testing.mdx +0 -260
  346. package/.next/standalone/docs/testing.mdx +0 -260
  347. package/.next/standalone/docs/tr/architecture.mdx +0 -333
  348. package/.next/standalone/docs/tr/built-in-policies.mdx +0 -574
  349. package/.next/standalone/docs/tr/cli/dashboard.mdx +0 -28
  350. package/.next/standalone/docs/tr/cli/environment-variables.mdx +0 -34
  351. package/.next/standalone/docs/tr/cli/hook.mdx +0 -30
  352. package/.next/standalone/docs/tr/cli/install-policies.mdx +0 -47
  353. package/.next/standalone/docs/tr/cli/list-policies.mdx +0 -31
  354. package/.next/standalone/docs/tr/cli/remove-policies.mdx +0 -44
  355. package/.next/standalone/docs/tr/cli/version.mdx +0 -12
  356. package/.next/standalone/docs/tr/configuration.mdx +0 -222
  357. package/.next/standalone/docs/tr/custom-policies.mdx +0 -353
  358. package/.next/standalone/docs/tr/dashboard.mdx +0 -142
  359. package/.next/standalone/docs/tr/examples.mdx +0 -308
  360. package/.next/standalone/docs/tr/for-agents.mdx +0 -38
  361. package/.next/standalone/docs/tr/getting-started.mdx +0 -186
  362. package/.next/standalone/docs/tr/introduction.mdx +0 -57
  363. package/.next/standalone/docs/tr/package-aliases.mdx +0 -82
  364. package/.next/standalone/docs/tr/testing.mdx +0 -260
  365. package/.next/standalone/docs/vi/architecture.mdx +0 -334
  366. package/.next/standalone/docs/vi/built-in-policies.mdx +0 -575
  367. package/.next/standalone/docs/vi/cli/dashboard.mdx +0 -28
  368. package/.next/standalone/docs/vi/cli/environment-variables.mdx +0 -34
  369. package/.next/standalone/docs/vi/cli/hook.mdx +0 -30
  370. package/.next/standalone/docs/vi/cli/install-policies.mdx +0 -47
  371. package/.next/standalone/docs/vi/cli/list-policies.mdx +0 -31
  372. package/.next/standalone/docs/vi/cli/remove-policies.mdx +0 -43
  373. package/.next/standalone/docs/vi/cli/version.mdx +0 -13
  374. package/.next/standalone/docs/vi/configuration.mdx +0 -222
  375. package/.next/standalone/docs/vi/custom-policies.mdx +0 -353
  376. package/.next/standalone/docs/vi/dashboard.mdx +0 -142
  377. package/.next/standalone/docs/vi/examples.mdx +0 -308
  378. package/.next/standalone/docs/vi/for-agents.mdx +0 -38
  379. package/.next/standalone/docs/vi/getting-started.mdx +0 -186
  380. package/.next/standalone/docs/vi/introduction.mdx +0 -57
  381. package/.next/standalone/docs/vi/package-aliases.mdx +0 -82
  382. package/.next/standalone/docs/vi/testing.mdx +0 -260
  383. package/.next/standalone/docs/zh/architecture.mdx +0 -332
  384. package/.next/standalone/docs/zh/built-in-policies.mdx +0 -572
  385. package/.next/standalone/docs/zh/cli/dashboard.mdx +0 -28
  386. package/.next/standalone/docs/zh/cli/environment-variables.mdx +0 -34
  387. package/.next/standalone/docs/zh/cli/hook.mdx +0 -30
  388. package/.next/standalone/docs/zh/cli/install-policies.mdx +0 -47
  389. package/.next/standalone/docs/zh/cli/list-policies.mdx +0 -31
  390. package/.next/standalone/docs/zh/cli/remove-policies.mdx +0 -43
  391. package/.next/standalone/docs/zh/cli/version.mdx +0 -12
  392. package/.next/standalone/docs/zh/configuration.mdx +0 -222
  393. package/.next/standalone/docs/zh/custom-policies.mdx +0 -353
  394. package/.next/standalone/docs/zh/dashboard.mdx +0 -142
  395. package/.next/standalone/docs/zh/examples.mdx +0 -307
  396. package/.next/standalone/docs/zh/for-agents.mdx +0 -38
  397. package/.next/standalone/docs/zh/getting-started.mdx +0 -186
  398. package/.next/standalone/docs/zh/introduction.mdx +0 -57
  399. package/.next/standalone/docs/zh/package-aliases.mdx +0 -82
  400. package/.next/standalone/docs/zh/testing.mdx +0 -260
  401. package/.next/standalone/eslint.config.mjs +0 -15
  402. package/.next/standalone/examples/convention-policies/security-policies.mjs +0 -40
  403. package/.next/standalone/examples/convention-policies/workflow-policies.mjs +0 -41
  404. package/.next/standalone/examples/policies-advanced/index.js +0 -103
  405. package/.next/standalone/examples/policies-advanced/utils.js +0 -35
  406. package/.next/standalone/examples/policies-basic.js +0 -77
  407. package/.next/standalone/examples/policies-notification.js +0 -104
  408. package/.next/standalone/node_modules/@img/colour/color.cjs +0 -1594
  409. package/.next/standalone/node_modules/@img/colour/index.cjs +0 -1
  410. package/.next/standalone/node_modules/@img/colour/package.json +0 -45
  411. package/.next/standalone/node_modules/@img/sharp-libvips-linux-x64/README.md +0 -46
  412. package/.next/standalone/node_modules/@img/sharp-libvips-linux-x64/lib/glib-2.0/include/glibconfig.h +0 -221
  413. package/.next/standalone/node_modules/@img/sharp-libvips-linux-x64/lib/index.js +0 -1
  414. package/.next/standalone/node_modules/@img/sharp-libvips-linux-x64/lib/libvips-cpp.so.8.17.3 +0 -0
  415. package/.next/standalone/node_modules/@img/sharp-libvips-linux-x64/package.json +0 -42
  416. package/.next/standalone/node_modules/@img/sharp-libvips-linux-x64/versions.json +0 -30
  417. package/.next/standalone/node_modules/@img/sharp-libvips-linuxmusl-x64/README.md +0 -46
  418. package/.next/standalone/node_modules/@img/sharp-libvips-linuxmusl-x64/lib/glib-2.0/include/glibconfig.h +0 -221
  419. package/.next/standalone/node_modules/@img/sharp-libvips-linuxmusl-x64/lib/index.js +0 -1
  420. package/.next/standalone/node_modules/@img/sharp-libvips-linuxmusl-x64/lib/libvips-cpp.so.8.17.3 +0 -0
  421. package/.next/standalone/node_modules/@img/sharp-libvips-linuxmusl-x64/package.json +0 -42
  422. package/.next/standalone/node_modules/@img/sharp-libvips-linuxmusl-x64/versions.json +0 -30
  423. package/.next/standalone/node_modules/@img/sharp-linux-x64/lib/sharp-linux-x64.node +0 -0
  424. package/.next/standalone/node_modules/@img/sharp-linux-x64/package.json +0 -46
  425. package/.next/standalone/node_modules/@img/sharp-linuxmusl-x64/lib/sharp-linuxmusl-x64.node +0 -0
  426. package/.next/standalone/node_modules/@img/sharp-linuxmusl-x64/package.json +0 -46
  427. package/.next/standalone/node_modules/detect-libc/lib/detect-libc.js +0 -313
  428. package/.next/standalone/node_modules/detect-libc/lib/elf.js +0 -39
  429. package/.next/standalone/node_modules/detect-libc/lib/filesystem.js +0 -51
  430. package/.next/standalone/node_modules/detect-libc/lib/process.js +0 -24
  431. package/.next/standalone/node_modules/detect-libc/package.json +0 -44
  432. package/.next/standalone/node_modules/sharp/lib/channel.js +0 -177
  433. package/.next/standalone/node_modules/sharp/lib/colour.js +0 -195
  434. package/.next/standalone/node_modules/sharp/lib/composite.js +0 -212
  435. package/.next/standalone/node_modules/sharp/lib/constructor.js +0 -499
  436. package/.next/standalone/node_modules/sharp/lib/index.js +0 -16
  437. package/.next/standalone/node_modules/sharp/lib/input.js +0 -809
  438. package/.next/standalone/node_modules/sharp/lib/is.js +0 -143
  439. package/.next/standalone/node_modules/sharp/lib/libvips.js +0 -207
  440. package/.next/standalone/node_modules/sharp/lib/operation.js +0 -1016
  441. package/.next/standalone/node_modules/sharp/lib/output.js +0 -1666
  442. package/.next/standalone/node_modules/sharp/lib/resize.js +0 -595
  443. package/.next/standalone/node_modules/sharp/lib/sharp.js +0 -121
  444. package/.next/standalone/node_modules/sharp/lib/utility.js +0 -291
  445. package/.next/standalone/node_modules/sharp/node_modules/semver/classes/comparator.js +0 -143
  446. package/.next/standalone/node_modules/sharp/node_modules/semver/classes/range.js +0 -557
  447. package/.next/standalone/node_modules/sharp/node_modules/semver/classes/semver.js +0 -333
  448. package/.next/standalone/node_modules/sharp/node_modules/semver/functions/cmp.js +0 -54
  449. package/.next/standalone/node_modules/sharp/node_modules/semver/functions/coerce.js +0 -62
  450. package/.next/standalone/node_modules/sharp/node_modules/semver/functions/compare.js +0 -7
  451. package/.next/standalone/node_modules/sharp/node_modules/semver/functions/eq.js +0 -5
  452. package/.next/standalone/node_modules/sharp/node_modules/semver/functions/gt.js +0 -5
  453. package/.next/standalone/node_modules/sharp/node_modules/semver/functions/gte.js +0 -5
  454. package/.next/standalone/node_modules/sharp/node_modules/semver/functions/lt.js +0 -5
  455. package/.next/standalone/node_modules/sharp/node_modules/semver/functions/lte.js +0 -5
  456. package/.next/standalone/node_modules/sharp/node_modules/semver/functions/neq.js +0 -5
  457. package/.next/standalone/node_modules/sharp/node_modules/semver/functions/parse.js +0 -18
  458. package/.next/standalone/node_modules/sharp/node_modules/semver/functions/satisfies.js +0 -12
  459. package/.next/standalone/node_modules/sharp/node_modules/semver/internal/constants.js +0 -37
  460. package/.next/standalone/node_modules/sharp/node_modules/semver/internal/debug.js +0 -11
  461. package/.next/standalone/node_modules/sharp/node_modules/semver/internal/identifiers.js +0 -29
  462. package/.next/standalone/node_modules/sharp/node_modules/semver/internal/lrucache.js +0 -42
  463. package/.next/standalone/node_modules/sharp/node_modules/semver/internal/parse-options.js +0 -17
  464. package/.next/standalone/node_modules/sharp/node_modules/semver/internal/re.js +0 -223
  465. package/.next/standalone/node_modules/sharp/node_modules/semver/package.json +0 -78
  466. package/.next/standalone/node_modules/sharp/package.json +0 -202
  467. package/.next/standalone/scripts/alias-proxy.js +0 -18
  468. package/.next/standalone/scripts/dev.ts +0 -3
  469. package/.next/standalone/scripts/install-telemetry.mjs +0 -108
  470. package/.next/standalone/scripts/launch.ts +0 -83
  471. package/.next/standalone/scripts/parse-script-args.ts +0 -87
  472. package/.next/standalone/scripts/postinstall.mjs +0 -121
  473. package/.next/standalone/scripts/preuninstall.mjs +0 -131
  474. package/.next/standalone/scripts/publish-aliases.mjs +0 -87
  475. package/.next/standalone/scripts/start.ts +0 -3
  476. package/.next/standalone/scripts/sync-hook-events-prompt.md +0 -60
  477. package/.next/standalone/scripts/translate-docs/cache.ts +0 -62
  478. package/.next/standalone/scripts/translate-docs/cli.ts +0 -357
  479. package/.next/standalone/scripts/translate-docs/config.ts +0 -248
  480. package/.next/standalone/scripts/translate-docs/mdx-translator.ts +0 -153
  481. package/.next/standalone/scripts/translate-docs/mintlify-nav.ts +0 -107
  482. package/.next/standalone/scripts/translate-docs/readme-translator.ts +0 -154
  483. package/.next/standalone/scripts/translate-docs/translator.ts +0 -68
  484. package/.next/standalone/scripts/translate-docs/types.ts +0 -43
  485. package/.next/standalone/src/cli-error.ts +0 -18
  486. package/.next/standalone/src/hooks/builtin-policies.ts +0 -1613
  487. package/.next/standalone/src/hooks/custom-hooks-loader.ts +0 -205
  488. package/.next/standalone/src/hooks/custom-hooks-registry.ts +0 -30
  489. package/.next/standalone/src/hooks/handler.ts +0 -202
  490. package/.next/standalone/src/hooks/hook-activity-store.ts +0 -349
  491. package/.next/standalone/src/hooks/hook-logger.ts +0 -133
  492. package/.next/standalone/src/hooks/hook-telemetry.ts +0 -43
  493. package/.next/standalone/src/hooks/hooks-config.ts +0 -166
  494. package/.next/standalone/src/hooks/install-prompt.ts +0 -357
  495. package/.next/standalone/src/hooks/llm-client.ts +0 -90
  496. package/.next/standalone/src/hooks/loader-utils.ts +0 -178
  497. package/.next/standalone/src/hooks/manager.ts +0 -692
  498. package/.next/standalone/src/hooks/policy-evaluator.ts +0 -224
  499. package/.next/standalone/src/hooks/policy-helpers.ts +0 -16
  500. package/.next/standalone/src/hooks/policy-registry.ts +0 -90
  501. package/.next/standalone/src/hooks/policy-types.ts +0 -77
  502. package/.next/standalone/src/hooks/types.ts +0 -63
  503. package/.next/standalone/src/index.ts +0 -19
  504. package/.next/standalone/src/posthog-key.ts +0 -5
  505. package/.next/standalone/tailwind.config.ts +0 -11
  506. package/.next/standalone/tsconfig.json +0 -42
  507. package/.next/standalone/vitest.config.e2e.mts +0 -24
  508. package/.next/standalone/vitest.config.mts +0 -23
  509. /package/.next/standalone/.next/static/{A9pNTZdoYJTVyPAYwQMx5 → wOkJXoch1UmRAmyIuKZWc}/_buildManifest.js +0 -0
  510. /package/.next/standalone/.next/static/{A9pNTZdoYJTVyPAYwQMx5 → wOkJXoch1UmRAmyIuKZWc}/_clientMiddlewareManifest.js +0 -0
  511. /package/.next/standalone/.next/static/{A9pNTZdoYJTVyPAYwQMx5 → wOkJXoch1UmRAmyIuKZWc}/_ssgManifest.js +0 -0
@@ -1,692 +0,0 @@
1
- /**
2
- * Install/remove/list failproofai hooks in Claude Code's settings.
3
- */
4
- import { execSync } from "node:child_process";
5
- import { readFileSync, writeFileSync, existsSync, mkdirSync } from "node:fs";
6
- import { resolve, dirname, basename } from "node:path";
7
- import { homedir, platform, arch, release, hostname } from "node:os";
8
- import {
9
- HOOK_EVENT_TYPES,
10
- HOOK_SCOPES,
11
- FAILPROOFAI_HOOK_MARKER,
12
- type HookScope,
13
- type ClaudeHookEntry,
14
- type ClaudeHookMatcher,
15
- type ClaudeSettings,
16
- } from "./types";
17
- import { promptPolicySelection } from "./install-prompt";
18
- import { readMergedHooksConfig, readScopedHooksConfig, writeScopedHooksConfig } from "./hooks-config";
19
- import type { HooksConfig } from "./policy-types";
20
- import { BUILTIN_POLICIES } from "./builtin-policies";
21
- import { loadCustomHooks, discoverPolicyFiles } from "./custom-hooks-loader";
22
- import { trackHookEvent } from "./hook-telemetry";
23
- import { getInstanceId, hashToId } from "../../lib/telemetry-id";
24
- import { CliError } from "../cli-error";
25
-
26
- const VALID_POLICY_NAMES = new Set(BUILTIN_POLICIES.map((p) => p.name));
27
-
28
- export function getSettingsPath(scope: HookScope, cwd?: string): string {
29
- const base = cwd ? resolve(cwd) : process.cwd();
30
- switch (scope) {
31
- case "user":
32
- return resolve(homedir(), ".claude", "settings.json");
33
- case "project":
34
- return resolve(base, ".claude", "settings.json");
35
- case "local":
36
- return resolve(base, ".claude", "settings.local.json");
37
- }
38
- }
39
-
40
- function scopeLabel(scope: HookScope): string {
41
- switch (scope) {
42
- case "user":
43
- return `~/.claude/settings.json`;
44
- case "project":
45
- return `{cwd}/.claude/settings.json`;
46
- case "local":
47
- return `{cwd}/.claude/settings.local.json`;
48
- }
49
- }
50
-
51
- function readSettings(settingsPath: string): ClaudeSettings {
52
- if (!existsSync(settingsPath)) {
53
- return {};
54
- }
55
- const raw = readFileSync(settingsPath, "utf8");
56
- return JSON.parse(raw) as ClaudeSettings;
57
- }
58
-
59
- function writeSettings(settingsPath: string, settings: ClaudeSettings): void {
60
- mkdirSync(dirname(settingsPath), { recursive: true });
61
- writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf8");
62
- }
63
-
64
- function resolveFailproofaiBinary(): string {
65
- try {
66
- const cmd = process.platform === "win32" ? "where failproofai" : "which failproofai";
67
- const result = execSync(cmd, { encoding: "utf8" }).trim();
68
- // `where` on Windows may return multiple lines; take the first
69
- return result.split("\n")[0].trim();
70
- } catch {
71
- throw new CliError(
72
- "failproofai binary not found in PATH.\n" +
73
- "Install it globally first: npm install -g failproofai"
74
- );
75
- }
76
- }
77
-
78
- function isFailproofaiHook(hook: Record<string, unknown>): boolean {
79
- if (hook[FAILPROOFAI_HOOK_MARKER] === true) return true;
80
- // Fallback for legacy installs that predate the marker
81
- const cmd = typeof hook.command === "string" ? hook.command : "";
82
- return cmd.includes("failproofai") && cmd.includes("--hook");
83
- }
84
-
85
- function validatePolicyNames(names: string[]): void {
86
- const invalid = names.filter((n) => !VALID_POLICY_NAMES.has(n));
87
- if (invalid.length > 0) {
88
- const validList = [...VALID_POLICY_NAMES].join(", ");
89
- throw new CliError(
90
- `Unknown policy name(s): ${invalid.join(", ")}\n` +
91
- `Valid policies: ${validList}`
92
- );
93
- }
94
- }
95
-
96
- /** Return only scopes whose settings paths are unique (first wins). */
97
- function deduplicateScopes(scopes: readonly HookScope[], cwd?: string): HookScope[] {
98
- const seen = new Set<string>();
99
- return scopes.filter((s) => {
100
- const p = getSettingsPath(s, cwd);
101
- if (seen.has(p)) return false;
102
- seen.add(p);
103
- return true;
104
- });
105
- }
106
-
107
- export function hooksInstalledInSettings(scope: HookScope, cwd?: string): boolean {
108
- const settingsPath = getSettingsPath(scope, cwd);
109
- if (!existsSync(settingsPath)) return false;
110
- try {
111
- const settings = readSettings(settingsPath);
112
- if (!settings.hooks) return false;
113
- for (const matchers of Object.values(settings.hooks)) {
114
- if (!Array.isArray(matchers)) continue;
115
- for (const matcher of matchers) {
116
- if (!matcher.hooks) continue;
117
- if (matcher.hooks.some((h) => isFailproofaiHook(h as Record<string, unknown>))) {
118
- return true;
119
- }
120
- }
121
- }
122
- } catch {
123
- // Corrupted settings — treat as not installed
124
- }
125
- return false;
126
- }
127
-
128
-
129
- function removeHooksFromSettingsFile(settingsPath: string): number {
130
- const settings = readSettings(settingsPath);
131
-
132
- if (!settings.hooks) return 0;
133
-
134
- let removed = 0;
135
-
136
- for (const eventType of Object.keys(settings.hooks)) {
137
- const matchers = settings.hooks[eventType];
138
- if (!Array.isArray(matchers)) continue;
139
-
140
- for (let i = matchers.length - 1; i >= 0; i--) {
141
- const matcher = matchers[i];
142
- if (!matcher.hooks) continue;
143
-
144
- const before = matcher.hooks.length;
145
- matcher.hooks = matcher.hooks.filter(
146
- (h) => !isFailproofaiHook(h as Record<string, unknown>)
147
- );
148
- removed += before - matcher.hooks.length;
149
-
150
- // Remove empty matchers
151
- if (matcher.hooks.length === 0) {
152
- matchers.splice(i, 1);
153
- }
154
- }
155
-
156
- // Remove empty event type arrays
157
- if (matchers.length === 0) {
158
- delete settings.hooks[eventType];
159
- }
160
- }
161
-
162
- // Remove empty hooks object
163
- if (Object.keys(settings.hooks).length === 0) {
164
- delete settings.hooks;
165
- }
166
-
167
- writeSettings(settingsPath, settings);
168
- return removed;
169
- }
170
-
171
- /**
172
- * Install hooks into Claude Code settings.
173
- *
174
- * @param policyNames — if provided, skip interactive prompt:
175
- * - `["all"]` → enable all policies
176
- * - `["block-sudo", "block-rm-rf"]` → enable specific policies
177
- * - `undefined` → interactive prompt (pre-loads current config if exists)
178
- * @param scope — settings scope to write to (default: "user")
179
- */
180
- export async function installHooks(
181
- policyNames?: string[],
182
- scope: HookScope = "user",
183
- cwd?: string,
184
- includeBeta = false,
185
- source?: string,
186
- customPoliciesPath?: string,
187
- removeCustomHooks = false,
188
- ): Promise<void> {
189
- // Validate user input first before any system checks
190
- if (policyNames !== undefined && policyNames.length > 0) {
191
- const nonAllNames = policyNames.filter((n) => n !== "all");
192
- // Check unknown names first (most actionable error for the user)
193
- if (nonAllNames.length > 0) validatePolicyNames(nonAllNames);
194
- // Then check if "all" is mixed with valid specific names
195
- if (policyNames.includes("all") && nonAllNames.length > 0) {
196
- throw new CliError(
197
- `"all" cannot be combined with specific policy names.\n` +
198
- `Use either: --install all or --install block-sudo sanitize-jwt ...`
199
- );
200
- }
201
- }
202
-
203
- const binaryPath = resolveFailproofaiBinary();
204
-
205
- // Capture existing config before overwriting (used for telemetry diff)
206
- const previousConfig = readScopedHooksConfig(scope, cwd);
207
- const previousEnabled = new Set(previousConfig.enabledPolicies);
208
-
209
- let selectedPolicies: string[];
210
-
211
- if (policyNames !== undefined) {
212
- // Non-interactive path: explicit array was provided (may be empty)
213
- let incoming: string[];
214
- if (policyNames.length === 1 && policyNames[0] === "all") {
215
- incoming = BUILTIN_POLICIES
216
- .filter((p) => includeBeta || !p.beta)
217
- .map((p) => p.name);
218
- } else {
219
- incoming = policyNames;
220
- }
221
- // Additive: union with whatever was already enabled, deduplicated.
222
- selectedPolicies = [...new Set([...previousConfig.enabledPolicies, ...incoming])];
223
- } else {
224
- // Interactive — pre-load current config if it exists
225
- const preSelected = previousConfig.enabledPolicies.length > 0 ? previousConfig.enabledPolicies : undefined;
226
- selectedPolicies = await promptPolicySelection(preSelected, { includeBeta });
227
- }
228
-
229
- // Preserve existing config fields (policyParams, customPoliciesPath, llm) when updating
230
- const configToWrite = { ...previousConfig, enabledPolicies: selectedPolicies };
231
- if (removeCustomHooks) {
232
- delete configToWrite.customPoliciesPath;
233
- } else if (customPoliciesPath) {
234
- configToWrite.customPoliciesPath = resolve(customPoliciesPath);
235
- // Validate the file before committing it to config
236
- let validatedHooks: Awaited<ReturnType<typeof loadCustomHooks>> = [];
237
- try {
238
- validatedHooks = await loadCustomHooks(configToWrite.customPoliciesPath, { strict: true });
239
- } catch (err) {
240
- console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);
241
- process.exit(1);
242
- }
243
- if (validatedHooks.length === 0) {
244
- console.error(
245
- `Error: no hooks registered in ${customPoliciesPath}. ` +
246
- `Make sure your file calls customPolicies.add(...) at least once.`,
247
- );
248
- process.exit(1);
249
- }
250
- console.log(
251
- `\nValidated ${validatedHooks.length} custom hook(s): ${validatedHooks.map((h) => h.name).join(", ")}`,
252
- );
253
- }
254
- writeScopedHooksConfig(configToWrite, scope, cwd);
255
- console.log(`\nEnabled ${selectedPolicies.length} policy(ies): ${selectedPolicies.join(", ")}`);
256
- if (removeCustomHooks) {
257
- console.log("Custom hooks path cleared.");
258
- } else if (configToWrite.customPoliciesPath) {
259
- console.log(`Custom hooks path: ${configToWrite.customPoliciesPath}`);
260
- }
261
-
262
- const settingsPath = getSettingsPath(scope, cwd);
263
- const settings = readSettings(settingsPath);
264
-
265
- if (!settings.hooks) {
266
- settings.hooks = {};
267
- }
268
-
269
- for (const eventType of HOOK_EVENT_TYPES) {
270
- const command = scope === "project"
271
- ? `npx -y failproofai --hook ${eventType}`
272
- : `"${binaryPath}" --hook ${eventType}`;
273
- const hookEntry: ClaudeHookEntry = {
274
- type: "command",
275
- command,
276
- timeout: 60_000,
277
- [FAILPROOFAI_HOOK_MARKER]: true,
278
- };
279
-
280
- if (!settings.hooks[eventType]) {
281
- settings.hooks[eventType] = [];
282
- }
283
-
284
- const matchers: ClaudeHookMatcher[] = settings.hooks[eventType];
285
-
286
- // Find existing failproofai matcher
287
- let found = false;
288
- for (const matcher of matchers) {
289
- if (!matcher.hooks) continue;
290
- const failproofaiIdx = matcher.hooks.findIndex((h: ClaudeHookEntry | Record<string, unknown>) =>
291
- isFailproofaiHook(h as Record<string, unknown>)
292
- );
293
- if (failproofaiIdx >= 0) {
294
- matcher.hooks[failproofaiIdx] = hookEntry;
295
- found = true;
296
- break;
297
- }
298
- }
299
-
300
- if (!found) {
301
- // Append a new matcher with the failproofai hook
302
- matchers.push({ hooks: [hookEntry] });
303
- }
304
- }
305
-
306
- writeSettings(settingsPath, settings);
307
-
308
- // Telemetry: track successful hook installation (with diff vs previous config)
309
- try {
310
- const newSet = new Set(selectedPolicies);
311
- const policiesAdded = selectedPolicies.filter((p) => !previousEnabled.has(p));
312
- const policiesRemoved = [...previousEnabled].filter((p) => !newSet.has(p));
313
- const distinctId = getInstanceId();
314
- await trackHookEvent(distinctId, "hooks_installed", {
315
- scope,
316
- policies: selectedPolicies,
317
- policy_count: selectedPolicies.length,
318
- policies_added: policiesAdded,
319
- policies_removed: policiesRemoved,
320
- ...(source ? { source } : {}),
321
- platform: platform(),
322
- arch: arch(),
323
- os_release: release(),
324
- hostname_hash: hashToId(hostname()),
325
- has_custom_hooks_path: !!(configToWrite.customPoliciesPath),
326
- has_policy_params: !!(configToWrite.policyParams && Object.keys(configToWrite.policyParams).length > 0),
327
- param_policy_names: configToWrite.policyParams ? Object.keys(configToWrite.policyParams) : [],
328
- command_format: scope === "project" ? "npx" : "absolute",
329
- });
330
- } catch {
331
- // Telemetry is best-effort — never block the operation
332
- }
333
-
334
- console.log(`Failproof AI hooks installed for all ${HOOK_EVENT_TYPES.length} event types (scope: ${scope}).`);
335
- console.log(`Settings: ${settingsPath}`);
336
- if (scope === "project") {
337
- console.log(`Command: npx -y failproofai`);
338
- console.log(`\nThis file can be committed to git — no machine-specific paths.`);
339
- } else {
340
- console.log(`Binary: ${binaryPath}`);
341
- }
342
-
343
- // Warn about duplicate-scope installations
344
- const otherScopes = deduplicateScopes(HOOK_SCOPES, cwd).filter((s) => s !== scope);
345
- const duplicates = otherScopes.filter((s) => hooksInstalledInSettings(s, cwd));
346
- if (duplicates.length > 0) {
347
- const scopeList = duplicates.map((s) => `${s} (${scopeLabel(s)})`).join(", ");
348
- console.log();
349
- console.log(`\x1B[33mWarning: Failproof AI hooks are also installed at ${scopeList}.\x1B[0m`);
350
- console.log(`Having hooks in multiple scopes may cause duplicate policy evaluation.`);
351
- console.log(`Use \`failproofai policies --uninstall --scope ${duplicates[0]}\` to remove the other installation,`);
352
- console.log(`or \`failproofai policies\` to see all scopes.`);
353
- }
354
- }
355
-
356
- /**
357
- * Remove hooks from Claude Code settings.
358
- *
359
- * @param policyNames — if provided:
360
- * - `undefined` or `["all"]` → remove all failproofai hooks from settings (original behavior)
361
- * - `["block-sudo"]` → disable specific policies in config, keep hooks installed
362
- * @param scope — settings scope to remove from (default: "user"), or "all" to remove from all scopes
363
- * @param opts.betaOnly — set to true when removing only beta policies (adds beta_only flag to telemetry)
364
- */
365
- export async function removeHooks(policyNames?: string[], scope: HookScope | "all" = "user", cwd?: string, opts?: { betaOnly?: boolean; source?: string; removeCustomHooks?: boolean }): Promise<void> {
366
- // Resolve the effective config scope ("all" falls back to "user" for config reads/writes)
367
- const configScope: HookScope = scope === "all" ? "user" : scope;
368
-
369
- // Clear custom hooks path if requested
370
- if (opts?.removeCustomHooks) {
371
- const config = readScopedHooksConfig(configScope, cwd);
372
- delete config.customPoliciesPath;
373
- writeScopedHooksConfig(config, configScope, cwd);
374
- console.log("Custom hooks path cleared.");
375
- }
376
-
377
- // Remove specific policies from config (keep hooks installed)
378
- if (policyNames && policyNames.length > 0 && !(policyNames.length === 1 && policyNames[0] === "all")) {
379
- validatePolicyNames(policyNames);
380
- const config = readScopedHooksConfig(configScope, cwd);
381
- const removeSet = new Set(policyNames);
382
- const remaining = config.enabledPolicies.filter((p) => !removeSet.has(p));
383
- const notEnabled = policyNames.filter((p) => !config.enabledPolicies.includes(p));
384
- if (notEnabled.length > 0) {
385
- console.log(`Warning: policy(ies) not currently enabled: ${notEnabled.join(", ")}`);
386
- }
387
- const { policyParams: existingParams, ...baseConfig } = config;
388
- const filteredParams = existingParams
389
- ? Object.fromEntries(Object.entries(existingParams).filter(([k]) => !removeSet.has(k)))
390
- : null;
391
- const updatedConfig: HooksConfig = {
392
- ...baseConfig,
393
- enabledPolicies: remaining,
394
- ...(filteredParams && Object.keys(filteredParams).length > 0 ? { policyParams: filteredParams } : {}),
395
- };
396
- writeScopedHooksConfig(updatedConfig, configScope, cwd);
397
-
398
- // Telemetry: track policy-only removal from config
399
- try {
400
- const distinctId = getInstanceId();
401
- const actuallyRemoved = policyNames.filter((p) => config.enabledPolicies.includes(p));
402
- await trackHookEvent(distinctId, "hooks_removed", {
403
- scope,
404
- removal_mode: opts?.betaOnly ? "beta_policies" : "policies",
405
- beta_only: opts?.betaOnly ?? false,
406
- policies_removed: actuallyRemoved,
407
- removed_count: actuallyRemoved.length,
408
- ...(opts?.source ? { source: opts.source } : {}),
409
- platform: platform(),
410
- arch: arch(),
411
- os_release: release(),
412
- hostname_hash: hashToId(hostname()),
413
- });
414
- } catch {
415
- // Telemetry is best-effort — never block the operation
416
- }
417
-
418
- console.log(`Disabled ${policyNames.length - notEnabled.length} policy(ies).`);
419
- console.log(`Remaining: ${remaining.length > 0 ? remaining.join(", ") : "(none)"}`);
420
- return;
421
- }
422
-
423
- // Capture enabled policies before clearing (used for accurate telemetry below)
424
- const configBeforeRemoval = readScopedHooksConfig(configScope, cwd);
425
-
426
- // Remove all failproofai hooks from Claude Code settings
427
- const scopesToRemove: HookScope[] = scope === "all" ? [...HOOK_SCOPES] : [scope];
428
- let totalRemoved = 0;
429
-
430
- for (const s of scopesToRemove) {
431
- const settingsPath = getSettingsPath(s, cwd);
432
-
433
- if (!existsSync(settingsPath)) {
434
- if (scope !== "all") {
435
- console.log("No settings file found. Nothing to remove.");
436
- return;
437
- }
438
- continue;
439
- }
440
-
441
- const settings = readSettings(settingsPath);
442
-
443
- if (!settings.hooks) {
444
- if (scope !== "all") {
445
- console.log("No hooks found in settings. Nothing to remove.");
446
- return;
447
- }
448
- continue;
449
- }
450
-
451
- const removed = removeHooksFromSettingsFile(settingsPath);
452
- totalRemoved += removed;
453
-
454
- if (scope !== "all") {
455
- console.log(`Removed ${removed} failproofai hook(s) from settings.`);
456
- console.log(`Settings: ${settingsPath}`);
457
- }
458
- }
459
-
460
- if (scope === "all") {
461
- console.log(`Removed ${totalRemoved} failproofai hook(s) from all scopes.`);
462
- for (const s of scopesToRemove) {
463
- console.log(` ${s}: ${getSettingsPath(s, cwd)}`);
464
- }
465
- }
466
-
467
- // Telemetry: track full hook removal from settings
468
- try {
469
- const distinctId = getInstanceId();
470
- await trackHookEvent(distinctId, "hooks_removed", {
471
- scope,
472
- removal_mode: "hooks",
473
- policies_removed: configBeforeRemoval.enabledPolicies,
474
- removed_count: totalRemoved,
475
- ...(opts?.source ? { source: opts.source } : {}),
476
- platform: platform(),
477
- arch: arch(),
478
- os_release: release(),
479
- hostname_hash: hashToId(hostname()),
480
- });
481
- } catch {
482
- // Telemetry is best-effort — never block the operation
483
- }
484
-
485
- // Clear policy config when removing from all scopes, or when no hooks remain in any scope
486
- if (scope === "all") {
487
- // Clear config across all three scopes
488
- for (const s of HOOK_SCOPES) {
489
- const existing = readScopedHooksConfig(s, cwd);
490
- if (existing.enabledPolicies.length > 0 || existing.customPoliciesPath || existing.policyParams) {
491
- const { customPoliciesPath: _drop, policyParams: _dropParams, ...rest } = existing;
492
- writeScopedHooksConfig({ ...rest, enabledPolicies: [] }, s, cwd);
493
- }
494
- }
495
- } else if (!HOOK_SCOPES.some((s) => hooksInstalledInSettings(s, cwd))) {
496
- const existing = readScopedHooksConfig(configScope, cwd);
497
- const { customPoliciesPath: _drop, policyParams: _dropParams, ...rest } = existing;
498
- writeScopedHooksConfig({ ...rest, enabledPolicies: [] }, configScope, cwd);
499
- }
500
- }
501
-
502
- /**
503
- * List all available policies with their per-scope enabled status.
504
- * Layout adapts to the number of installed scopes:
505
- * 0 scopes: compact "not installed" summary
506
- * 1 scope: table with header + checkmarks, beta policies in a separate section
507
- * 2+ scopes: column table with per-scope status, beta policies in a separate section
508
- *
509
- * Also shows:
510
- * - Configured policyParams values beneath each policy
511
- * - Warnings for unknown policyParams keys
512
- * - Custom Hooks section if customPoliciesPath is set
513
- */
514
- export async function listHooks(cwd?: string): Promise<void> {
515
- const config = readMergedHooksConfig(cwd);
516
- const enabledSet = new Set(config.enabledPolicies);
517
-
518
- // Determine which scopes have hooks installed (deduplicate when paths overlap, e.g. cwd === home)
519
- const uniqueScopes = deduplicateScopes(HOOK_SCOPES, cwd);
520
- const installedScopes = uniqueScopes.filter((s) => hooksInstalledInSettings(s, cwd));
521
-
522
- // Separate beta from regular policies
523
- const regularPolicies = BUILTIN_POLICIES.filter((p) => !p.beta);
524
- const betaPolicies = BUILTIN_POLICIES.filter((p) => p.beta);
525
-
526
- // Dynamic name column width based on longest policy name
527
- const nameColWidth = Math.max(...BUILTIN_POLICIES.map((p) => p.name.length)) + 2;
528
-
529
- // All known builtin policy names (for unknown policyParams key detection)
530
- const builtinPolicyNames = new Set(BUILTIN_POLICIES.map((p) => p.name));
531
-
532
- // Helper: print params summary lines beneath a policy row
533
- const printParamsSummary = (policyName: string, indent: string) => {
534
- const params = config.policyParams?.[policyName];
535
- if (!params) return;
536
- for (const [key, val] of Object.entries(params)) {
537
- console.log(`${indent} ${key}: ${JSON.stringify(val)}`);
538
- }
539
- };
540
-
541
- const statusCol = 8;
542
- const printSimpleRow = (policy: { name: string; description: string }) => {
543
- const mark = enabledSet.has(policy.name) ? `\x1B[32m\u2713\x1B[0m` : " ";
544
- console.log(` ${mark}${" ".repeat(statusCol - 1)}${policy.name.padEnd(nameColWidth)}${policy.description}`);
545
- printParamsSummary(policy.name, ` ${" ".repeat(statusCol)}`);
546
- };
547
- const printBetaSection = (printRow: (p: { name: string; description: string }) => void) => {
548
- if (betaPolicies.length > 0) {
549
- console.log(`\n \x1B[2m\u2500\u2500 Beta \u2500\u2500\x1B[0m`);
550
- for (const policy of betaPolicies) printRow(policy);
551
- }
552
- };
553
-
554
- if (installedScopes.length === 0) {
555
- // State A: No hooks installed — show table with configured state + descriptions
556
- console.log("\nFailproof AI Policies \u2014 not installed\n");
557
-
558
- console.log(` ${"Status".padEnd(statusCol)}${"Name".padEnd(nameColWidth)}Description`);
559
- console.log(` ${"\u2500".repeat(6)} ${"\u2500".repeat(nameColWidth - 2)} ${"\u2500".repeat(38)}`);
560
-
561
- for (const policy of regularPolicies) printSimpleRow(policy);
562
- printBetaSection(printSimpleRow);
563
-
564
- if (config.enabledPolicies.length > 0) {
565
- console.log("\n Policies not installed. Run `failproofai policies --install` to activate.");
566
- } else {
567
- console.log("\n Run `failproofai policies --install` to get started.");
568
- }
569
- console.log(" Config: ~/.failproofai/policies-config.json\n");
570
- } else if (installedScopes.length === 1) {
571
- // State B: Single scope — table with header row
572
- const scope = installedScopes[0];
573
- console.log(`\nFailproof AI Hook Policies (${scope})\n`);
574
-
575
- console.log(` ${"Status".padEnd(statusCol)}${"Name".padEnd(nameColWidth)}Description`);
576
- console.log(` ${"\u2500".repeat(6)} ${"\u2500".repeat(nameColWidth - 2)} ${"\u2500".repeat(38)}`);
577
-
578
- for (const policy of regularPolicies) printSimpleRow(policy);
579
- printBetaSection(printSimpleRow);
580
-
581
- console.log("\n Config: ~/.failproofai/policies-config.json\n");
582
- } else {
583
- // State C: Multiple scopes — column table
584
- const COL = 9;
585
- const scopeLabelMap: Record<HookScope, string> = {
586
- user: "User",
587
- project: "Project",
588
- local: "Local",
589
- };
590
-
591
- console.log("\nFailproof AI Hook Policies\n");
592
-
593
- // Header with only installed scope columns + separator
594
- const buildScopePrefix = () => {
595
- let s = " ";
596
- for (const sc of installedScopes) s += scopeLabelMap[sc].padEnd(COL);
597
- return s;
598
- };
599
- const scopeHeaderWidth = installedScopes.length * COL;
600
- console.log(`${buildScopePrefix()}${"Name".padEnd(nameColWidth)}Description`);
601
- console.log(` ${"\u2500".repeat(scopeHeaderWidth)}${"\u2500".repeat(nameColWidth)}${"\u2500".repeat(38)}`);
602
-
603
- const printMultiScopeRow = (policy: { name: string; description: string }) => {
604
- const enabled = enabledSet.has(policy.name);
605
- let row = " ";
606
- for (const _scope of installedScopes) {
607
- if (enabled) {
608
- row += `\x1B[32m\u2713 ON\x1B[0m` + " ".repeat(COL - 4);
609
- } else {
610
- row += " OFF" + " ".repeat(COL - 5);
611
- }
612
- }
613
- row += policy.name.padEnd(nameColWidth) + policy.description;
614
- console.log(row);
615
- printParamsSummary(policy.name, ` ${" ".repeat(scopeHeaderWidth)}`);
616
- };
617
-
618
- for (const policy of regularPolicies) printMultiScopeRow(policy);
619
-
620
- if (betaPolicies.length > 0) {
621
- console.log(`\n \x1B[2m\u2500\u2500 Beta \u2500\u2500\x1B[0m`);
622
- for (const policy of betaPolicies) printMultiScopeRow(policy);
623
- }
624
-
625
- console.log("\n Config: ~/.failproofai/policies-config.json");
626
-
627
- // Multi-scope warning
628
- const scopeNames = installedScopes.join(", ");
629
- console.log();
630
- console.log(`\x1B[33m\u26A0 Hooks in multiple scopes (${scopeNames}).\x1B[0m`);
631
- console.log(" Consider keeping one. Remove with: failproofai policies --uninstall --scope <scope>\n");
632
- }
633
-
634
- // Warn about unknown policyParams keys
635
- if (config.policyParams) {
636
- for (const key of Object.keys(config.policyParams)) {
637
- if (!builtinPolicyNames.has(key)) {
638
- console.log(` \x1B[33mWarning: unknown policyParams key "${key}" — possible typo\x1B[0m`);
639
- }
640
- }
641
- }
642
-
643
- // Custom Policies section
644
- if (config.customPoliciesPath) {
645
- console.log(`\n \u2500\u2500 Custom Policies (${config.customPoliciesPath}) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500`);
646
- if (!existsSync(config.customPoliciesPath)) {
647
- console.log(` \x1B[31m\u2717 File not found: ${config.customPoliciesPath}\x1B[0m`);
648
- } else {
649
- const hooks = await loadCustomHooks(config.customPoliciesPath);
650
- if (hooks.length === 0) {
651
- console.log(` \x1B[31m\u2717 ERR failed to load (check ~/.failproofai/logs/hooks.log)\x1B[0m`);
652
- } else {
653
- const descColWidth = nameColWidth;
654
- for (const hook of hooks) {
655
- console.log(` \x1B[32m\u2713\x1B[0m ${hook.name.padEnd(descColWidth)}${hook.description ?? ""}`);
656
- }
657
- }
658
- }
659
- console.log();
660
- }
661
-
662
- // Convention Policies section (.failproofai/policies/*policies.{js,mjs,ts})
663
- const base = cwd ? resolve(cwd) : process.cwd();
664
- const conventionDirs: { label: string; dir: string }[] = [
665
- { label: "Project", dir: resolve(base, ".failproofai", "policies") },
666
- { label: "User", dir: resolve(homedir(), ".failproofai", "policies") },
667
- ];
668
-
669
- for (const { label, dir } of conventionDirs) {
670
- const files = discoverPolicyFiles(dir);
671
- if (files.length === 0) continue;
672
-
673
- console.log(`\n \u2500\u2500 Convention Policies \u2014 ${label} (${dir}) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500`);
674
- for (const file of files) {
675
- try {
676
- const hooks = await loadCustomHooks(file);
677
- if (hooks.length === 0) {
678
- const filename = basename(file);
679
- console.log(` \x1B[31m\u2717\x1B[0m ${filename.padEnd(nameColWidth)}\x1B[31mfailed to load\x1B[0m`);
680
- } else {
681
- const filename = basename(file);
682
- const hookSummary = hooks.map((h) => h.name).join(", ");
683
- console.log(` \x1B[32m\u2713\x1B[0m ${filename.padEnd(nameColWidth)}${hooks.length} hook(s): ${hookSummary}`);
684
- }
685
- } catch {
686
- const filename = basename(file);
687
- console.log(` \x1B[31m\u2717\x1B[0m ${filename.padEnd(nameColWidth)}\x1B[31merror\x1B[0m`);
688
- }
689
- }
690
- console.log();
691
- }
692
- }