failproofai 1.0.7-beta.0 → 1.0.7-beta.2

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 (320) 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 +1 -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 +6 -6
  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/_tree.segment.rsc +1 -1
  13. package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  14. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  15. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  16. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  17. package/.next/standalone/.next/server/app/_not-found.rsc +15 -15
  18. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +15 -15
  19. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +14 -14
  20. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  21. package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -1
  22. package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
  23. package/.next/standalone/.next/server/app/api/audit/status/route.js.nft.json +1 -1
  24. package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
  25. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
  26. package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
  27. package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
  28. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
  29. package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
  30. package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
  31. package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
  32. package/.next/standalone/.next/server/app/index.html +1 -1
  33. package/.next/standalone/.next/server/app/index.rsc +15 -15
  34. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +14 -14
  35. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
  36. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  37. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
  38. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  39. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  40. package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +14 -14
  41. package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
  42. package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
  43. package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
  44. package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
  45. package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
  46. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
  47. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
  48. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
  49. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
  50. package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
  51. package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
  52. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  53. package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +7 -7
  54. package/.next/standalone/.next/server/app/settings/page.js +2 -2
  55. package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
  56. package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  57. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0l3yhx4._.js +2 -2
  58. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o07qi9._.js +1 -1
  59. package/.next/standalone/.next/server/chunks/_0tovk6q._.js +1 -1
  60. package/.next/standalone/.next/server/chunks/_0trp3yc._.js +1 -1
  61. package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
  62. package/.next/standalone/.next/server/chunks/src_hooks_18qtd42._.js +1 -1
  63. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__04usis8._.js +2 -2
  64. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__056wjo4._.js +2 -2
  65. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1p28m0u._.js → [root-of-the-server]__0l44ual._.js} +2 -2
  66. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0n0xg95._.js +2 -2
  67. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0rwtwpm._.js +2 -2
  68. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0s_yomn._.js +2 -2
  69. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__11mayhe._.js +2 -2
  70. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1pprgri._.js +2 -2
  71. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1q4p5b8._.js +2 -2
  72. package/.next/standalone/.next/server/chunks/ssr/_042cgl1._.js +1 -1
  73. package/.next/standalone/.next/server/chunks/ssr/_08x1r5t._.js +1 -1
  74. package/.next/standalone/.next/server/chunks/ssr/_0bqoto4._.js +1 -1
  75. package/.next/standalone/.next/server/chunks/ssr/{_0cf1olg._.js → _1mel6y1._.js} +2 -2
  76. package/.next/standalone/.next/server/chunks/ssr/{_135-c3y._.js → _1v-jvrv._.js} +1 -1
  77. package/.next/standalone/.next/server/chunks/ssr/_1zopuov._.js +1 -1
  78. package/.next/standalone/.next/server/chunks/ssr/_next-internal_server_app_policies_page_actions_1sp2-yo.js +2 -2
  79. package/.next/standalone/.next/server/chunks/ssr/app_actions_get-scheduled-audit_ts_0ei9sni._.js +1 -1
  80. package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +1 -1
  81. package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
  82. package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +1 -1
  83. package/.next/standalone/.next/server/chunks/ssr/app_settings_02tf1h4._.js +1 -1
  84. package/.next/standalone/.next/server/chunks/ssr/src_hooks_15t8kqj._.js +1 -1
  85. package/.next/standalone/.next/server/chunks/ssr/src_hooks_1fm2w5z._.js +1 -1
  86. package/.next/standalone/.next/server/chunks/ssr/src_hooks_1j0zy3v._.js +1 -1
  87. package/.next/standalone/.next/server/chunks/ssr/src_hooks_builtin-policies_ts_09j2ndl._.js +1 -1
  88. package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
  89. package/.next/standalone/.next/server/pages/404.html +1 -1
  90. package/.next/standalone/.next/server/pages/500.html +1 -1
  91. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  92. package/.next/standalone/.next/server/server-reference-manifest.json +22 -22
  93. package/.next/standalone/.next/static/chunks/043j99m8ykg__.css +2 -0
  94. package/.next/standalone/.next/static/chunks/{0289oapk24zql.js → 0fqd7m_u81mi5.js} +1 -1
  95. package/.next/standalone/.next/static/chunks/{2tqszh84mp_2l.js → 129ag2bw93bdh.js} +1 -1
  96. package/.next/standalone/.next/static/chunks/{0pyy9m5cm8zku.js → 1qd741hzlmjbo.js} +1 -1
  97. package/.next/standalone/.next/static/chunks/{3vwnzfx9q80yl.js → 2_pltstd8-xgs.js} +1 -1
  98. package/.next/standalone/.next/static/chunks/{3vp7c3knkh8mr.js → 2c8j9l6j_b1ci.js} +1 -1
  99. package/.next/standalone/.next/static/chunks/3-k569wzcli8q.js +1 -0
  100. package/.next/standalone/.next/static/chunks/{3cdkxrukvlvul.js → 3brze37td_wnc.js} +1 -1
  101. package/.next/standalone/.next/static/chunks/{3dnd-_29uiaj3.js → 3otmypm6j_xfo.js} +2 -2
  102. package/.next/standalone/.next/static/chunks/{00i9thnpht4l1.js → 3ugmd_7dyn0id.js} +1 -1
  103. package/.next/standalone/.next/static/chunks/3yxro_r2_o9ad.js +69 -0
  104. package/.next/standalone/PROBE-FOLLOWUP.md +186 -0
  105. package/.next/standalone/app/actions/get-jev-config.ts +38 -23
  106. package/.next/standalone/app/actions/update-jev-config.ts +1 -1
  107. package/.next/standalone/app/settings/jev-panel.tsx +33 -29
  108. package/.next/standalone/package.json +10 -10
  109. package/.next/standalone/sdk/python/skill/SKILL.md +60 -14
  110. package/.next/standalone/sdk/python/skill/agents/openai.yaml +2 -1
  111. package/.next/standalone/sdk/python/skill/references/evaluator.md +255 -0
  112. package/.next/standalone/sdk/python/skill/references/events.md +17 -8
  113. package/.next/standalone/sdk/python/skill/references/frameworks.md +3 -0
  114. package/.next/standalone/sdk/python/skill/references/install.md +3 -0
  115. package/.next/standalone/sdk/python/skill/references/integration.md +6 -2
  116. package/.next/standalone/sdk/python/skill/references/typescript.md +568 -0
  117. package/.next/standalone/sdk/typescript/CHANGELOG.md +119 -0
  118. package/.next/standalone/sdk/typescript/LICENSE +42 -0
  119. package/.next/standalone/sdk/typescript/README.md +552 -0
  120. package/.next/standalone/sdk/typescript/eslint.config.mjs +59 -0
  121. package/.next/standalone/sdk/typescript/examples/research-agent.ts +197 -0
  122. package/.next/standalone/sdk/typescript/integration/ai.test.ts +920 -0
  123. package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/agent.ts +337 -0
  124. package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/package-lock.json +281 -0
  125. package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/package.json +13 -0
  126. package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/surfaces.ts +605 -0
  127. package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/tsconfig.json +12 -0
  128. package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/tsconfig.surfaces.json +4 -0
  129. package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/agent.ts +342 -0
  130. package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/package-lock.json +168 -0
  131. package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/package.json +13 -0
  132. package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/surfaces.ts +628 -0
  133. package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/tsconfig.json +12 -0
  134. package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/tsconfig.surfaces.json +4 -0
  135. package/.next/standalone/sdk/typescript/integration/fixtures/ai-6/agent.ts +346 -0
  136. package/.next/standalone/sdk/typescript/integration/fixtures/ai-6/package-lock.json +156 -0
  137. package/.next/standalone/sdk/typescript/integration/fixtures/ai-6/package.json +13 -0
  138. package/.next/standalone/sdk/typescript/integration/fixtures/ai-6/surfaces.ts +651 -0
  139. package/.next/standalone/sdk/typescript/integration/fixtures/ai-6/tsconfig.json +12 -0
  140. package/.next/standalone/sdk/typescript/integration/fixtures/ai-6/tsconfig.surfaces.json +4 -0
  141. package/.next/standalone/sdk/typescript/integration/fixtures/ai-7/agent.ts +350 -0
  142. package/.next/standalone/sdk/typescript/integration/fixtures/ai-7/package-lock.json +153 -0
  143. package/.next/standalone/sdk/typescript/integration/fixtures/ai-7/package.json +13 -0
  144. package/.next/standalone/sdk/typescript/integration/fixtures/ai-7/surfaces.ts +651 -0
  145. package/.next/standalone/sdk/typescript/integration/fixtures/ai-7/tsconfig.json +12 -0
  146. package/.next/standalone/sdk/typescript/integration/fixtures/ai-7/tsconfig.surfaces.json +4 -0
  147. package/.next/standalone/sdk/typescript/integration/fixtures/langchain-0.3/agent.ts +623 -0
  148. package/.next/standalone/sdk/typescript/integration/fixtures/langchain-0.3/package-lock.json +463 -0
  149. package/.next/standalone/sdk/typescript/integration/fixtures/langchain-0.3/package.json +15 -0
  150. package/.next/standalone/sdk/typescript/integration/fixtures/langchain-0.3/tsconfig.json +12 -0
  151. package/.next/standalone/sdk/typescript/integration/fixtures/langchain-1/agent-v1.ts +99 -0
  152. package/.next/standalone/sdk/typescript/integration/fixtures/langchain-1/agent.ts +623 -0
  153. package/.next/standalone/sdk/typescript/integration/fixtures/langchain-1/package-lock.json +336 -0
  154. package/.next/standalone/sdk/typescript/integration/fixtures/langchain-1/package.json +15 -0
  155. package/.next/standalone/sdk/typescript/integration/fixtures/langchain-1/tsconfig.json +12 -0
  156. package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/agent.ts +96 -0
  157. package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/package-lock.json +579 -0
  158. package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/package.json +15 -0
  159. package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/tsconfig.json +12 -0
  160. package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/vendor/lc-weather-provider/index.cjs +53 -0
  161. package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/vendor/lc-weather-provider/index.mjs +55 -0
  162. package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/vendor/lc-weather-provider/package.json +18 -0
  163. package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.11/agent.ts +659 -0
  164. package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.11/package-lock.json +635 -0
  165. package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.11/package.json +15 -0
  166. package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.11/tsconfig.json +12 -0
  167. package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.12/agent.ts +659 -0
  168. package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.12/package-lock.json +553 -0
  169. package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.12/package.json +15 -0
  170. package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.12/tsconfig.json +12 -0
  171. package/.next/standalone/sdk/typescript/integration/fixtures/mastra-0/agent.ts +877 -0
  172. package/.next/standalone/sdk/typescript/integration/fixtures/mastra-0/mcp-server.mjs +66 -0
  173. package/.next/standalone/sdk/typescript/integration/fixtures/mastra-0/package-lock.json +6417 -0
  174. package/.next/standalone/sdk/typescript/integration/fixtures/mastra-0/package.json +15 -0
  175. package/.next/standalone/sdk/typescript/integration/fixtures/mastra-0/tsconfig.json +12 -0
  176. package/.next/standalone/sdk/typescript/integration/fixtures/mastra-1/agent.ts +872 -0
  177. package/.next/standalone/sdk/typescript/integration/fixtures/mastra-1/mcp-server.mjs +66 -0
  178. package/.next/standalone/sdk/typescript/integration/fixtures/mastra-1/package-lock.json +2540 -0
  179. package/.next/standalone/sdk/typescript/integration/fixtures/mastra-1/package.json +15 -0
  180. package/.next/standalone/sdk/typescript/integration/fixtures/mastra-1/tsconfig.json +12 -0
  181. package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/actions.ts +18 -0
  182. package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/api/ai/route.ts +42 -0
  183. package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/api/edge/route.ts +29 -0
  184. package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/api/langgraph/route.ts +21 -0
  185. package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/api/llamaindex/route.ts +11 -0
  186. package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/api/mastra/route.ts +19 -0
  187. package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/api/status/route.ts +7 -0
  188. package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/layout.tsx +9 -0
  189. package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/page.tsx +15 -0
  190. package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/instrumentation.ts +15 -0
  191. package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/lib/ai.ts +61 -0
  192. package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/lib/langgraph.ts +68 -0
  193. package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/lib/llamaindex.ts +98 -0
  194. package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/lib/mastra.ts +90 -0
  195. package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/next.config.ts +52 -0
  196. package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/package-lock.json +4343 -0
  197. package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/package.json +28 -0
  198. package/.next/standalone/sdk/typescript/integration/fixtures/runtimes/agent.ts +51 -0
  199. package/.next/standalone/sdk/typescript/integration/fixtures/runtimes/deno-npm.ts +76 -0
  200. package/.next/standalone/sdk/typescript/integration/fixtures/runtimes/package-lock.json +484 -0
  201. package/.next/standalone/sdk/typescript/integration/fixtures/runtimes/package.json +15 -0
  202. package/.next/standalone/sdk/typescript/integration/fixtures/types/agent.ts +79 -0
  203. package/.next/standalone/sdk/typescript/integration/fixtures/types/package-lock.json +740 -0
  204. package/.next/standalone/sdk/typescript/integration/fixtures/types/package.json +11 -0
  205. package/.next/standalone/sdk/typescript/integration/fixtures/vanilla/agent.ts +197 -0
  206. package/.next/standalone/sdk/typescript/integration/fixtures/vanilla/package-lock.json +70 -0
  207. package/.next/standalone/sdk/typescript/integration/fixtures/vanilla/package.json +12 -0
  208. package/.next/standalone/sdk/typescript/integration/fixtures/vanilla/tsconfig.json +12 -0
  209. package/.next/standalone/sdk/typescript/integration/global-setup.ts +29 -0
  210. package/.next/standalone/sdk/typescript/integration/harness.ts +451 -0
  211. package/.next/standalone/sdk/typescript/integration/langchain.test.ts +682 -0
  212. package/.next/standalone/sdk/typescript/integration/llamaindex.test.ts +709 -0
  213. package/.next/standalone/sdk/typescript/integration/mastra-coverage.test.ts +386 -0
  214. package/.next/standalone/sdk/typescript/integration/mastra.test.ts +311 -0
  215. package/.next/standalone/sdk/typescript/integration/nextjs.test.ts +341 -0
  216. package/.next/standalone/sdk/typescript/integration/runtime-parity.ts +180 -0
  217. package/.next/standalone/sdk/typescript/integration/runtimes.bun.test.ts +15 -0
  218. package/.next/standalone/sdk/typescript/integration/runtimes.core.test.ts +113 -0
  219. package/.next/standalone/sdk/typescript/integration/runtimes.deno.test.ts +19 -0
  220. package/.next/standalone/sdk/typescript/integration/types.test.ts +141 -0
  221. package/.next/standalone/sdk/typescript/integration/vanilla.test.ts +255 -0
  222. package/.next/standalone/sdk/typescript/package-lock.json +2640 -0
  223. package/.next/standalone/sdk/typescript/package.json +401 -0
  224. package/.next/standalone/sdk/typescript/scripts/finalize-build.mjs +123 -0
  225. package/.next/standalone/sdk/typescript/scripts/release.mjs +177 -0
  226. package/.next/standalone/sdk/typescript/src/clock.ts +58 -0
  227. package/.next/standalone/sdk/typescript/src/context.ts +214 -0
  228. package/.next/standalone/sdk/typescript/src/edge/adapter.ts +18 -0
  229. package/.next/standalone/sdk/typescript/src/edge/ai.ts +116 -0
  230. package/.next/standalone/sdk/typescript/src/edge/index.ts +238 -0
  231. package/.next/standalone/sdk/typescript/src/edge/langchain.ts +18 -0
  232. package/.next/standalone/sdk/typescript/src/edge/llamaindex.ts +12 -0
  233. package/.next/standalone/sdk/typescript/src/edge/mastra.ts +17 -0
  234. package/.next/standalone/sdk/typescript/src/edge/notice.ts +33 -0
  235. package/.next/standalone/sdk/typescript/src/environment.ts +75 -0
  236. package/.next/standalone/sdk/typescript/src/evaluator/authoring.ts +480 -0
  237. package/.next/standalone/sdk/typescript/src/evaluator/cli.ts +96 -0
  238. package/.next/standalone/sdk/typescript/src/evaluator/client.ts +421 -0
  239. package/.next/standalone/sdk/typescript/src/evaluator/expression.ts +1292 -0
  240. package/.next/standalone/sdk/typescript/src/evaluator/index.ts +144 -0
  241. package/.next/standalone/sdk/typescript/src/evaluator/protocol.ts +747 -0
  242. package/.next/standalone/sdk/typescript/src/evaluator/runtime.ts +930 -0
  243. package/.next/standalone/sdk/typescript/src/evaluator/sandbox-worker.ts +171 -0
  244. package/.next/standalone/sdk/typescript/src/evaluator/source-limits.ts +27 -0
  245. package/.next/standalone/sdk/typescript/src/evaluator/source.ts +509 -0
  246. package/.next/standalone/sdk/typescript/src/events.ts +879 -0
  247. package/.next/standalone/sdk/typescript/src/exit.ts +117 -0
  248. package/.next/standalone/sdk/typescript/src/index.ts +186 -0
  249. package/.next/standalone/sdk/typescript/src/integrations/ai.ts +1566 -0
  250. package/.next/standalone/sdk/typescript/src/integrations/compat.ts +322 -0
  251. package/.next/standalone/sdk/typescript/src/integrations/core.ts +1321 -0
  252. package/.next/standalone/sdk/typescript/src/integrations/index.ts +355 -0
  253. package/.next/standalone/sdk/typescript/src/integrations/langchain.ts +2340 -0
  254. package/.next/standalone/sdk/typescript/src/integrations/llamaindex.ts +2111 -0
  255. package/.next/standalone/sdk/typescript/src/integrations/mastra.ts +1802 -0
  256. package/.next/standalone/sdk/typescript/src/logger.ts +98 -0
  257. package/.next/standalone/sdk/typescript/src/next.ts +115 -0
  258. package/.next/standalone/sdk/typescript/src/node-require.ts +446 -0
  259. package/.next/standalone/sdk/typescript/src/redact.ts +305 -0
  260. package/.next/standalone/sdk/typescript/src/resolver.ts +120 -0
  261. package/.next/standalone/sdk/typescript/src/runtime.ts +29 -0
  262. package/.next/standalone/sdk/typescript/src/schema.ts +410 -0
  263. package/.next/standalone/sdk/typescript/src/scopes.ts +701 -0
  264. package/.next/standalone/sdk/typescript/src/shared.ts +33 -0
  265. package/.next/standalone/sdk/typescript/src/version.ts +5 -0
  266. package/.next/standalone/sdk/typescript/src/writer.ts +934 -0
  267. package/.next/standalone/sdk/typescript/test/adapters.test.ts +397 -0
  268. package/.next/standalone/sdk/typescript/test/ai.test.ts +1076 -0
  269. package/.next/standalone/sdk/typescript/test/copies.test.ts +204 -0
  270. package/.next/standalone/sdk/typescript/test/edge.test.ts +183 -0
  271. package/.next/standalone/sdk/typescript/test/evaluator-client.test.ts +234 -0
  272. package/.next/standalone/sdk/typescript/test/evaluator-protocol.test.ts +225 -0
  273. package/.next/standalone/sdk/typescript/test/events.test.ts +193 -0
  274. package/.next/standalone/sdk/typescript/test/expression.test.ts +181 -0
  275. package/.next/standalone/sdk/typescript/test/global-setup.ts +26 -0
  276. package/.next/standalone/sdk/typescript/test/helpers.ts +130 -0
  277. package/.next/standalone/sdk/typescript/test/integrations.test.ts +369 -0
  278. package/.next/standalone/sdk/typescript/test/langchain-copies.test.ts +204 -0
  279. package/.next/standalone/sdk/typescript/test/langchain.test.ts +999 -0
  280. package/.next/standalone/sdk/typescript/test/llamaindex.test.ts +1760 -0
  281. package/.next/standalone/sdk/typescript/test/mastra-coverage.test.ts +501 -0
  282. package/.next/standalone/sdk/typescript/test/mastra-lifecycle.test.ts +479 -0
  283. package/.next/standalone/sdk/typescript/test/mastra.test.ts +285 -0
  284. package/.next/standalone/sdk/typescript/test/next.test.ts +109 -0
  285. package/.next/standalone/sdk/typescript/test/packaging.test.ts +312 -0
  286. package/.next/standalone/sdk/typescript/test/redaction.test.ts +171 -0
  287. package/.next/standalone/sdk/typescript/test/runtimes.test.ts +101 -0
  288. package/.next/standalone/sdk/typescript/test/sandbox.test.ts +189 -0
  289. package/.next/standalone/sdk/typescript/test/scopes.test.ts +271 -0
  290. package/.next/standalone/sdk/typescript/test/setup.ts +19 -0
  291. package/.next/standalone/sdk/typescript/test/skill-snippets.test.ts +73 -0
  292. package/.next/standalone/sdk/typescript/test/spool-contract.test.ts +124 -0
  293. package/.next/standalone/sdk/typescript/test/tracker-bounds.test.ts +191 -0
  294. package/.next/standalone/sdk/typescript/test/wire-format.test.ts +214 -0
  295. package/.next/standalone/sdk/typescript/test/writer.test.ts +407 -0
  296. package/.next/standalone/sdk/typescript/tsconfig.build.json +15 -0
  297. package/.next/standalone/sdk/typescript/tsconfig.cjs.json +19 -0
  298. package/.next/standalone/sdk/typescript/tsconfig.json +28 -0
  299. package/.next/standalone/sdk/typescript/vitest.config.ts +33 -0
  300. package/.next/standalone/sdk/typescript/vitest.integration.config.ts +23 -0
  301. package/.next/standalone/server.js +1 -1
  302. package/README.md +2 -2
  303. package/dist/cli.mjs +225 -30
  304. package/dist/worker.mjs +120 -14
  305. package/package.json +10 -10
  306. package/scripts/build-policy-pack.mjs +14 -0
  307. package/src/audit/features.ts +3 -2
  308. package/src/hooks/builtin-policies.ts +156 -5
  309. package/src/hooks/jev-cli.ts +57 -1
  310. package/src/hooks/manager.ts +1 -1
  311. package/src/hooks/pack-cli.ts +191 -24
  312. package/src/hooks/pack-store.ts +1 -1
  313. package/src/hooks/policy-catalog.ts +148 -9
  314. package/src/hooks/types.ts +1 -1
  315. package/.next/standalone/.next/static/chunks/15heikmy3yjzc.js +0 -1
  316. package/.next/standalone/.next/static/chunks/285spx855h_3r.css +0 -2
  317. package/.next/standalone/.next/static/chunks/2plg9qae1yejv.js +0 -69
  318. /package/.next/standalone/.next/static/{qbVI48kgBOf9CTOKcFIk2 → gbEOjBgZAxF2UIUwZVHNu}/_buildManifest.js +0 -0
  319. /package/.next/standalone/.next/static/{qbVI48kgBOf9CTOKcFIk2 → gbEOjBgZAxF2UIUwZVHNu}/_clientMiddlewareManifest.js +0 -0
  320. /package/.next/standalone/.next/static/{qbVI48kgBOf9CTOKcFIk2 → gbEOjBgZAxF2UIUwZVHNu}/_ssgManifest.js +0 -0
@@ -44,9 +44,9 @@ import {
44
44
  import type { PolicyEffect } from "./cloud-managed-policies";
45
45
  import { loadCustomHooks } from "./custom-hooks-loader";
46
46
  import { getSemanticRegistrations } from "./custom-hooks-registry";
47
- import { authorityFieldsOf, authorityProblem } from "./policy-authority";
48
- import type { SemanticPolicyDeclaration } from "./policy-types";
49
- import type { MultiChoice, TTYIn, TTYOut } from "./tui";
47
+ import { authorityFieldsOf, authorityProblem, resolvePolicyAuthority } from "./policy-authority";
48
+ import type { PolicyCatalogEntry, SemanticPolicyDeclaration } from "./policy-types";
49
+ import type { MultiChoice, RenderOpts, TTYIn, TTYOut } from "./tui";
50
50
  import {
51
51
  chip,
52
52
  emptyState,
@@ -342,10 +342,10 @@ async function build(rest: string[]): Promise<PackCliResult> {
342
342
  // Refused rather than bundled: see the note above. A relative specifier is the
343
343
  // only kind that would be rewritten by the loader and left outside the digest.
344
344
  const source = readFileSync(entryPath, "utf8");
345
- const localImport = /(?:^|\n)\s*(?:import|export)[^;\n]*from\s+["'](\.[^"']*)["']/.exec(source);
345
+ const localImport = firstRelativeSpecifier(source);
346
346
  if (localImport) {
347
347
  return fail([
348
- `${entryPath} imports ${localImport[1]}, and only the entry file is digest-pinned.`,
348
+ `${entryPath} imports ${localImport}, and only the entry file is digest-pinned.`,
349
349
  "Bundle it to a single file first (esbuild, bun build, rollup), then build the pack from that.",
350
350
  ]);
351
351
  }
@@ -469,7 +469,7 @@ async function build(rest: string[]): Promise<PackCliResult> {
469
469
  // out was not cosmetic: `registerPolicy` takes a pack policy's schema from the
470
470
  // MANIFEST by name, so a pack published without it evaluates every one of its
471
471
  // policies with `ctx.params = {}` — which discards the user's own configured
472
- // values too, not just the defaults. Of the 38 builtins, 19 carry a schema:
472
+ // values too, not just the defaults. Of the 39 builtins, 20 carry a schema:
473
473
  // `prefer-package-manager` would have been inert, and `block-sudo`'s
474
474
  // `allowPatterns`, `block-rm-rf`'s and `block-read-outside-cwd`'s `allowPaths`
475
475
  // would all have stopped working — every one of them failing silently
@@ -1878,6 +1878,44 @@ const PUBLISH_VALUE_FLAGS = new Set([
1878
1878
  "--repo", "--version", "--id", "--tag", "--notes", "--out", "--effect", "--entry", "--init",
1879
1879
  "--commit", "--min-cli-version",
1880
1880
  ]);
1881
+ /**
1882
+ * The first relative specifier an entry imports, or null.
1883
+ *
1884
+ * Two callers read this and they must agree, because between them they are the
1885
+ * only two outcomes: `publish` bundles a multi-file entry into the one artifact
1886
+ * a pack has to be, and `build` REFUSES one, since only the entry file is
1887
+ * digest-pinned. A shape that neither recognises gets bundled by neither and
1888
+ * refused by neither, and the author sees whatever the loader's rewrite makes of
1889
+ * it — which is an esbuild parse error naming a token, not a file.
1890
+ *
1891
+ * Both sites previously used `[^;\n]*` between `import` and `from`, which cannot
1892
+ * cross a newline and requires a `from` clause to exist. So both missed:
1893
+ *
1894
+ * import "./policies/regex" // side-effect only: there is no `from`
1895
+ * import {
1896
+ * aLongList,
1897
+ * } from "./shared" // the `from` is on another line
1898
+ *
1899
+ * and a pack entry written either way — the natural way to write one whose
1900
+ * halves register at module scope — failed to publish with `Expected "from" but
1901
+ * found "{"`. Now `[^;]*?` spans newlines and stops at a statement end, and the
1902
+ * bare form is matched on its own. Over-reaching to a later `from` is harmless:
1903
+ * the answer is only ever used as "is there a relative import, and name one".
1904
+ */
1905
+ export function firstRelativeSpecifier(source: string): string | null {
1906
+ const patterns = [
1907
+ /(?:^|\n)\s*(?:import|export)\b[^;]*?\bfrom\s*["'](\.[^"']*)["']/,
1908
+ /(?:^|\n)\s*import\s*["'](\.[^"']*)["']/,
1909
+ /\bimport\s*\(\s*["'](\.[^"']*)["']\s*\)/,
1910
+ /\brequire\s*\(\s*["'](\.[^"']*)["']\s*\)/,
1911
+ ];
1912
+ for (const re of patterns) {
1913
+ const m = re.exec(source);
1914
+ if (m) return m[1];
1915
+ }
1916
+ return null;
1917
+ }
1918
+
1881
1919
  function publishEntryArg(rest: string[]): string | undefined {
1882
1920
  const consumed = new Set<number>();
1883
1921
  for (let i = 0; i < rest.length; i += 1) {
@@ -2255,10 +2293,7 @@ async function publish(rest: string[]): Promise<PackCliResult> {
2255
2293
  // a bundler for a step this tool already performs for its own pack.
2256
2294
  let entryToBuild = entry;
2257
2295
  const needsBundle =
2258
- discovered.length > 1 ||
2259
- /(?:^|\n)\s*(?:import|export)[^;\n]*from\s+["']\.[^"']*["']/.test(
2260
- readFileSync(entry, "utf8"),
2261
- );
2296
+ discovered.length > 1 || firstRelativeSpecifier(readFileSync(entry, "utf8")) !== null;
2262
2297
  if (needsBundle) {
2263
2298
  const sources = discovered.length > 1 ? discovered : [entry];
2264
2299
  const bundled = bundleEntry(sources, outDirEarly);
@@ -2658,7 +2693,7 @@ async function add(rest: string[]): Promise<PackCliResult> {
2658
2693
  ];
2659
2694
  const skipped = result.available.filter((n) => !result.enabled.includes(n));
2660
2695
 
2661
- // Say WHY this set is on. Without it, "10 of 38 enabled" reads like
2696
+ // Say WHY this set is on. Without it, "10 of 39 enabled" reads like
2662
2697
  // something went wrong rather than like the pack's own recommendation.
2663
2698
  const why = {
2664
2699
  defaults: "the pack's defaults",
@@ -2952,6 +2987,147 @@ function relativeAge(iso: string): string {
2952
2987
  return `${value} ${label}${value === 1 ? "" : "s"} ago`;
2953
2988
  }
2954
2989
 
2990
+ /**
2991
+ * Which of a pack's OWN regex policies each of its Jev checks can clear, keyed
2992
+ * by check name and empty for a check nothing names.
2993
+ *
2994
+ * INVERTED out of the same manifest's `reviewedBy` rather than declared beside
2995
+ * the checks. A semantic entry says nothing about the policies that name it, so
2996
+ * the only other way to show this column is a second list kept by hand — which
2997
+ * is wrong the first time a publisher adds a reviewer to one policy, and wrong
2998
+ * in the direction that overstates what Jev may clear.
2999
+ *
3000
+ * Judged with `resolvePolicyAuthority` against the pack's OWN check names,
3001
+ * because that is the rule the installing machine applies: a pack declaring
3002
+ * semantic entries replaces the compiled-in set (`effectiveReviewerNames`), so
3003
+ * its `reviewedBy` may name only its own checks, and a declaration that names
3004
+ * anything else — or one sitting under `authority: "hard"`, which a manifest may
3005
+ * carry because the two fields are parsed independently — registers HARD. A
3006
+ * policy in either state can never be cleared, so naming it under a check would
3007
+ * promise a clear that cannot happen.
3008
+ */
3009
+ function reviewersByCheck(
3010
+ policies: ReadonlyArray<PolicyCatalogEntry>,
3011
+ semantic: ReadonlyArray<SemanticManifestEntry>,
3012
+ ): Map<string, string[]> {
3013
+ const ownChecks = new Set(semantic.map((s) => s.name));
3014
+ const byCheck = new Map<string, string[]>(semantic.map((s) => [s.name, []]));
3015
+ for (const policy of policies) {
3016
+ const { authority, reviewedBy } = resolvePolicyAuthority(policy, ownChecks);
3017
+ if (authority !== "reviewable") continue;
3018
+ for (const check of reviewedBy ?? []) byCheck.get(check)?.push(policy.name);
3019
+ }
3020
+ return byCheck;
3021
+ }
3022
+
3023
+ /** Reviewers named in full. Past this the cell names two and counts the rest. */
3024
+ const REVIEWERS_LISTED = 3;
3025
+
3026
+ /**
3027
+ * A check's reviewers as one cell.
3028
+ *
3029
+ * The question a reader brings to this column is "can this check clear anything
3030
+ * of mine", which two names and a count answer as well as ten do — and ten
3031
+ * names in a cell push the column past the terminal, where `table` cuts one of
3032
+ * them mid-word and the row stops being readable at all.
3033
+ */
3034
+ function reviewersCell(names: ReadonlyArray<string>): string {
3035
+ if (names.length <= REVIEWERS_LISTED) return names.join(", ");
3036
+ return `${names.slice(0, 2).join(", ")}, +${names.length - 2}`;
3037
+ }
3038
+
3039
+ /**
3040
+ * Why a check that no policy names is in the pack at all — and the two answers
3041
+ * are different facts, so the row has to tell them apart.
3042
+ *
3043
+ * A `deny` check with no reviewer is a concern the pack's regex half does not
3044
+ * cover: it can only ever ADD a deny, never clear one, and that is a gap in the
3045
+ * regex tier rather than a mistake in the manifest. An `instruct` check can
3046
+ * never answer deny, so every conjunction naming it has one reachable outcome —
3047
+ * a clear — which is why nothing names it and why nothing should (the
3048
+ * `block-work-on-main` entry in CHANGELOG 1.0.7-beta.1 is that bug, shipped).
3049
+ */
3050
+ function unreviewedCell(mode: SemanticManifestEntry["mode"], policies: number): string {
3051
+ if (mode === "instruct") return "instruct-only — it can never deny";
3052
+ // "the 38" borrows the count from the heading above, where it has just been
3053
+ // read. The other two spellings exist because that sentence has no grammatical
3054
+ // form at one or zero — and a pack of Jev checks alone, with no regex half at
3055
+ // all, is a legitimate thing to publish.
3056
+ if (policies === 0) return "this pack has no policies to clear";
3057
+ if (policies === 1) return "the one policy here does not cover this";
3058
+ return `nothing in the ${policies} covers this`;
3059
+ }
3060
+
3061
+ /**
3062
+ * A pack's Jev checks as a section of rows — the shape the category sections
3063
+ * use, deliberately NOT their columns.
3064
+ *
3065
+ * It replaces a prose paragraph that listed sixteen names comma-separated above
3066
+ * a screen where everything else was a scannable row. The rows are not policy
3067
+ * rows and must not read as ones: there is no on/off chip, because nothing
3068
+ * toggles a check, `--policy` cannot name one, and none of them appears in
3069
+ * `failproofai policies`. What the columns carry instead is the pair of facts
3070
+ * that decide what a check does on a real machine — its mode, and which of this
3071
+ * pack's own policies it can clear.
3072
+ *
3073
+ * Null when the pack declares none, so a pack with no semantic half prints no
3074
+ * section rather than an empty one.
3075
+ */
3076
+ export function jevChecksSection(
3077
+ pack: {
3078
+ policies: ReadonlyArray<PolicyCatalogEntry>;
3079
+ semantic: ReadonlyArray<SemanticManifestEntry>;
3080
+ },
3081
+ opts?: RenderOpts,
3082
+ ): string[] | null {
3083
+ if (pack.semantic.length === 0) return null;
3084
+ const reviewers = reviewersByCheck(pack.policies, pack.semantic);
3085
+ const rows = pack.semantic.map((check) => {
3086
+ const named = reviewers.get(check.name) ?? [];
3087
+ // `reviews` and `—` lead the same cell rather than sitting in a column of
3088
+ // their own. A fourth column would pad every `—` out to the width of
3089
+ // `reviews`, which costs nine characters of the only column allowed to
3090
+ // shrink — enough to ellipsize the reason on an 80-column terminal, where
3091
+ // this way everything fits whole.
3092
+ return [
3093
+ check.mode,
3094
+ check.name,
3095
+ named.length > 0
3096
+ ? `reviews ${reviewersCell(named)}`
3097
+ : `— ${unreviewedCell(check.mode, pack.policies.length)}`,
3098
+ ];
3099
+ });
3100
+ return [
3101
+ // The count is on the heading rather than in a row, the way every other
3102
+ // section on this screen carries its own total.
3103
+ ...rule(
3104
+ `Jev checks — ${pack.semantic.length} · not selectable · only where Jev is configured`,
3105
+ opts,
3106
+ ),
3107
+ // The reviewers column is the only one allowed to shrink: a mode or a check
3108
+ // name cut in half is a fact nobody can act on, while a cut reviewer list is
3109
+ // one that was already abbreviated.
3110
+ ...table({ head: ["", "", ""], rows, protect: [0, 1] }, opts),
3111
+ "",
3112
+ ...note(
3113
+ "Nothing toggles them: `--policy` cannot name one, `failproofai policies` never lists them, " +
3114
+ "and a pack's checks replace the ones this build ships with.",
3115
+ opts,
3116
+ ),
3117
+ ...note(
3118
+ // A pack of Jev checks alone has no regex half for the column to be about,
3119
+ // so the sentence says what IS true of it rather than "its own 0 policies".
3120
+ pack.policies.length === 0
3121
+ ? "This pack ships no regex policies, so none of these checks clears anything here: a deny " +
3122
+ "check can only ADD a deny, and an instruct check only ever warns."
3123
+ : `\`reviews\` is which of this pack's own ${pack.policies.length} policies each check can clear. ` +
3124
+ "A deny check that reviews nothing can only ever ADD a deny; an instruct check never answers " +
3125
+ "deny, so nothing pairs with one.",
3126
+ opts,
3127
+ ),
3128
+ ];
3129
+ }
3130
+
2955
3131
  async function listRemote(source: string): Promise<PackCliResult> {
2956
3132
  const opts = optsFor(process.stdout);
2957
3133
  let preview;
@@ -2994,22 +3170,13 @@ async function listRemote(source: string): Promise<PackCliResult> {
2994
3170
  (preview.effect === "observe" ? " This pack OBSERVES — it records and blocks nothing." : ""),
2995
3171
  opts,
2996
3172
  ),
2997
- // The half that is not in the table below, said in words. It is not
2998
- // selectable, so it has no rows; and it REPLACES this build's own question
2999
- // set rather than adding to it, which is the part worth knowing before
3000
- // installing rather than after.
3001
- preview.semantic.length > 0
3002
- ? note(
3003
- `It also carries ${semanticPhrase(preview.semantic.length)} — ${preview.semantic
3004
- .map((s) => s.name)
3005
- .join(", ")}. They are not selectable, they apply only where you configured Jev, and they ` +
3006
- "replace the checks this build ships with.",
3007
- opts,
3008
- )
3009
- : null,
3010
3173
  preview.minCliVersion ? note(`Requires failproofai ${preview.minCliVersion} or newer.`, opts) : null,
3011
3174
  preview.resolvedFromLatest ? note(`Newest release: ${preview.source}`, opts) : null,
3012
3175
  table({ head: ["", "", ""], rows }, opts),
3176
+ // The half the table above cannot hold: its own section, under the
3177
+ // policies rather than above them, because a check is read against the
3178
+ // policies it can clear and those are the rows just passed.
3179
+ jevChecksSection(preview, opts),
3013
3180
  nextStep(`failproofai policies add ${source}`, "Install the defaults with:", opts),
3014
3181
  note("Or take part of it: --policy <a,b>, --category <x,y>, --all", opts),
3015
3182
  ),
@@ -814,7 +814,7 @@ export function slugifyCategory(category: string): string {
814
814
  *
815
815
  * The default is the pack's OWN `defaultEnabled` set, not everything. A pack
816
816
  * carries an opinion about which of its policies are safe to switch on
817
- * unattended — for the builtins that is 10 of 38 — and installing the whole
817
+ * unattended — for the builtins that is 10 of 39 — and installing the whole
818
818
  * thing overrode that opinion with one nobody held. `block-kubectl`,
819
819
  * `block-terraform` and `require-ci-green-before-stop` are off by default in the
820
820
  * npm package precisely because they interrupt legitimate work.
@@ -37,6 +37,30 @@
37
37
  */
38
38
  import type { PolicyCatalogEntry, PolicyParamsSchema } from "./policy-types";
39
39
 
40
+ /**
41
+ * ── On `authority` and `reviewedBy` in this file ──
42
+ *
43
+ * `reviewable` means Jev may CLEAR this policy's verdict, and only through the
44
+ * semantic checks named here — every one of which must have been asked.
45
+ *
46
+ * Both ways of getting a pairing wrong are silent, and the asymmetry between
47
+ * them is what decides these rows:
48
+ *
49
+ * - a check that is never ASKED never clears, so the block becomes permanent
50
+ * - a check that is asked and does not FIRE answers "no concern", and no
51
+ * concern CLEARS — so naming a check that does not model this policy's
52
+ * shapes does not review the policy, it switches it off for exactly the
53
+ * inputs that check does not understand
54
+ *
55
+ * And an `instruct`-mode check can never answer deny. So the test is not "can
56
+ * the named reviewer keep this block" but "is there anything left that can
57
+ * deny": a deny-mode name in the conjunction, or a deny-mode check covering the
58
+ * same concern independently, or a policy that never denied in the first place.
59
+ * `block-work-on-main` fails all three and is hard for that reason.
60
+ *
61
+ * Each row's own comment says which of those applies. The reasoning was worked
62
+ * out policy by policy in FailproofAI/jev-policies' DECISIONS.md.
63
+ */
40
64
  export const POLICY_CATALOG: PolicyCatalogEntry[] = [
41
65
  {
42
66
  name: "sanitize-jwt",
@@ -143,6 +167,17 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
143
167
  // PermissionRequest is Codex's escalation-approval event; fire the same
144
168
  // sudo guard there so Codex sandbox bypasses are blocked too.
145
169
  match: { events: ["PreToolUse", "PermissionRequest"], toolNames: ["Bash"] },
170
+ // Hard, although `privilege-escalation` is deny-mode and its probe is a strict superset
171
+ // of this matcher — so the pairing would pass the "is there anything left that can
172
+ // deny" test. The reason it stays hard is the OTHER clearing path: that check is
173
+ // `userCanOverride: true`, so a human naming the operation clears it, and this policy
174
+ // is `defaultEnabled: true`. Reviewable would therefore turn "sudo is blocked" into
175
+ // "sudo is blocked unless you asked for it" on every machine with Jev configured.
176
+ // Measured against what that buys: the false-block reduction on the labelled corpus
177
+ // came from `block-read-outside-cwd`, `protect-env-vars` and `block-env-files`, which
178
+ // were already reviewable. Sudo contributed nothing to it, so the trade is a headline
179
+ // guarantee for no measured gain. The nine opt-in policies that ARE reviewable here
180
+ // reach only people who switched them on deliberately.
146
181
  authority: "hard",
147
182
  defaultEnabled: true,
148
183
  category: "Dangerous Commands",
@@ -160,6 +195,12 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
160
195
  impact: "`curl ... | sh` runs unverified remote code on your machine.",
161
196
  description: "Block piping downloads to shell",
162
197
  match: { events: ["PreToolUse"], toolNames: ["Bash"] },
198
+ // Hard, for the same reason as `block-sudo` above: the `remote-code-execution` pairing is
199
+ // sound, but the check is overridable by an explicit request and this policy is on by
200
+ // default, so reviewable would mean "piping a download to a shell is blocked unless you
201
+ // asked for it". The substring false positive it has — `grep -rn "curl x | sh"` is
202
+ // denied — is real and is the argument for pairing it; it is also rare enough not to
203
+ // pay for weakening the default.
163
204
  authority: "hard",
164
205
  defaultEnabled: true,
165
206
  category: "Dangerous Commands",
@@ -170,7 +211,13 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
170
211
  impact: "Catches catastrophic `rm -rf /` and Windows equivalents.",
171
212
  description: "Prevent catastrophic deletions",
172
213
  match: { events: ["PreToolUse"], toolNames: ["Bash"] },
173
- authority: "hard",
214
+ // Reviewable: `destructive-deletion` is deny-mode, and its second probe is this
215
+ // policy's path-depth heuristic done properly — `irreplaceable`'s false criteria
216
+ // (build output, dist/, caches, node_modules, virtualenvs, coverage, temp files) is
217
+ // exactly this heuristic's error term. `rm -rf /` keeps both probes true and stays
218
+ // denied; `rm -rf node_modules` is the false block this pairing exists to remove.
219
+ authority: "reviewable",
220
+ reviewedBy: ["destructive-deletion"],
174
221
  defaultEnabled: false,
175
222
  category: "Dangerous Commands",
176
223
  params: {
@@ -209,7 +256,12 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
209
256
  impact: "kubectl can change live cluster state — gated unless allow-listed.",
210
257
  description: "Block kubectl commands (Kubernetes cluster mutations)",
211
258
  match: { events: ["PreToolUse"], toolNames: ["Bash"] },
212
- authority: "hard",
259
+ // Reviewable: `production-infra-change` is deny-mode and names kubectl explicitly. This
260
+ // policy denies the whole CLI, read-only subcommands included; the probe's false
261
+ // criteria is the split a regex cannot make — get, list, describe, logs, status,
262
+ // plan, diff, validate, whoami, --dry-run.
263
+ authority: "reviewable",
264
+ reviewedBy: ["production-infra-change"],
213
265
  defaultEnabled: false,
214
266
  category: "Infra Commands",
215
267
  params: {
@@ -226,7 +278,10 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
226
278
  impact: "Terraform mutates real infrastructure — gated unless allow-listed.",
227
279
  description: "Block terraform and tofu (OpenTofu) commands",
228
280
  match: { events: ["PreToolUse"], toolNames: ["Bash"] },
229
- authority: "hard",
281
+ // Reviewable: same pairing as `block-kubectl`; the probe names terraform and tofu, and
282
+ // clears `terraform plan` and `terraform validate`.
283
+ authority: "reviewable",
284
+ reviewedBy: ["production-infra-change"],
230
285
  defaultEnabled: false,
231
286
  category: "Infra Commands",
232
287
  params: {
@@ -243,7 +298,10 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
243
298
  impact: "AWS CLI can spend money or break prod — gated.",
244
299
  description: "Block aws CLI commands",
245
300
  match: { events: ["PreToolUse"], toolNames: ["Bash"] },
246
- authority: "hard",
301
+ // Reviewable: same pairing; the probe names aws, and clears `aws sts
302
+ // get-caller-identity` and `aws s3 ls`.
303
+ authority: "reviewable",
304
+ reviewedBy: ["production-infra-change"],
247
305
  defaultEnabled: false,
248
306
  category: "Infra Commands",
249
307
  params: {
@@ -260,7 +318,10 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
260
318
  impact: "gcloud can spend money or break prod — gated.",
261
319
  description: "Block gcloud (Google Cloud) CLI commands",
262
320
  match: { events: ["PreToolUse"], toolNames: ["Bash"] },
263
- authority: "hard",
321
+ // Reviewable: same pairing; the probe names gcloud, and clears `gcloud auth list` and
322
+ // `gcloud config list`.
323
+ authority: "reviewable",
324
+ reviewedBy: ["production-infra-change"],
264
325
  defaultEnabled: false,
265
326
  category: "Infra Commands",
266
327
  params: {
@@ -277,7 +338,9 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
277
338
  impact: "az can spend money or break prod — gated.",
278
339
  description: "Block az (Azure) CLI commands",
279
340
  match: { events: ["PreToolUse"], toolNames: ["Bash"] },
280
- authority: "hard",
341
+ // Reviewable: same pairing; the probe names az, and clears `az account show`.
342
+ authority: "reviewable",
343
+ reviewedBy: ["production-infra-change"],
281
344
  defaultEnabled: false,
282
345
  category: "Infra Commands",
283
346
  params: {
@@ -294,7 +357,10 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
294
357
  impact: "Helm releases mutate cluster state — gated.",
295
358
  description: "Block helm commands",
296
359
  match: { events: ["PreToolUse"], toolNames: ["Bash"] },
297
- authority: "hard",
360
+ // Reviewable: same pairing; the probe names helm, and clears `helm list` and
361
+ // `helm status`.
362
+ authority: "reviewable",
363
+ reviewedBy: ["production-infra-change"],
298
364
  defaultEnabled: false,
299
365
  category: "Infra Commands",
300
366
  params: {
@@ -328,7 +394,13 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
328
394
  impact: "Stops the agent from creating `.pem`, `id_rsa`, `credentials.json`, etc.",
329
395
  description: "Block writing secret key files",
330
396
  match: { events: ["PreToolUse"], toolNames: ["Write"] },
331
- authority: "hard",
397
+ // Reviewable: `secret-exposure` is deny-mode and `write` is in its `appliesTo`, so a
398
+ // real private key still comes back deny. What clears is this matcher's substring
399
+ // problem — `/credentials/` and `id_rsa` unanchored against a whole path, which
400
+ // catches `src/auth/credentials.ts`. `credential-exfiltration` would have been a
401
+ // dead name here: it applies to shell and network, and a file write is neither.
402
+ authority: "reviewable",
403
+ reviewedBy: ["secret-exposure"],
332
404
  defaultEnabled: false,
333
405
  category: "Dangerous Commands",
334
406
  params: {
@@ -362,7 +434,13 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
362
434
  impact: "Force-pushes rewrite history and can clobber teammates' work.",
363
435
  description: "Prevent force-pushing to any branch",
364
436
  match: { events: ["PreToolUse"], toolNames: ["Bash"] },
365
- authority: "hard",
437
+ // Reviewable: `git-history-rewrite` is deny-mode and its probe is a superset of this
438
+ // matcher — it counts `--force-with-lease` (which `isForcePushFlag` deliberately
439
+ // treats as safe), a `+refspec`, and a remote-branch delete, and says `git -C dir`
440
+ // and an absolute binary path change nothing. A real force-push stays blocked; what
441
+ // clears is the user asking to force-push their own branch.
442
+ authority: "reviewable",
443
+ reviewedBy: ["git-history-rewrite"],
366
444
  defaultEnabled: false,
367
445
  category: "Git",
368
446
  },
@@ -418,6 +496,67 @@ export const POLICY_CATALOG: PolicyCatalogEntry[] = [
418
496
  defaultEnabled: false,
419
497
  category: "Git",
420
498
  },
499
+ {
500
+ name: "warn-git-clean",
501
+ displayTitle: "Tried to delete untracked or ignored files with git clean",
502
+ impact: "`git clean -fdx` takes `.env`, local config and unstaged work — git never had a copy of any of it.",
503
+ description: "Warns before git clean deletes untracked directories (-d) or ignored files (-x / -X)",
504
+ match: { events: ["PreToolUse"], toolNames: ["Bash"] },
505
+ // Hard, and deliberately NOT `reviewable` through `destructive-deletion`,
506
+ // although that check is the one whose whole subject is deleting data that
507
+ // cannot be regenerated.
508
+ //
509
+ // Measured on a real machine, through the real hook, with a Jev config
510
+ // present, on `git clean -fdx`:
511
+ //
512
+ // jev: ok decision=allow applied=two-tier 495ms
513
+ // probes: destructive-deletion.destroys=0.94 beyond_task=0.79 task_step=0.78
514
+ //
515
+ // `destroys` came back 0.94 — the check sees the destruction; its own
516
+ // instructions name `git clean -fdx` by example. The policy still did not
517
+ // fire, because evidence is the MIN over a policy's probes and the partner
518
+ // probe `irreplaceable` came back low (it is absent from the probe line,
519
+ // which lists only what answered above the display floor). That is not a
520
+ // tuning accident: `git clean` carries NO path operand, so `facts.paths` is
521
+ // empty (measured — `extractPaths` skips `clean` as not path-like and
522
+ // `-fdx` as a flag), while `irreplaceable` is written to read
523
+ // `facts.paths[].relation` and to answer false for "only regenerable data
524
+ // inside the project: build output, dist/, caches, node_modules, …". With
525
+ // nothing to point at, the false branch is the honest answer to the
526
+ // question as written.
527
+ //
528
+ // A named check that is asked and does not fire answers "no concern", and
529
+ // that CLEARS (`combine.ts`, "A warning-level answer clears the deny"). So
530
+ // pairing this policy with `destructive-deletion` would not hand the
531
+ // decision to Jev — it would switch the policy off on every machine that
532
+ // configured Jev, which is exactly the `block-work-on-main` mistake. The
533
+ // test is "is there anything left that can DENY", and no other deny-mode
534
+ // semantic check covers untracked-file deletion, so a clear would leave the
535
+ // concern enforced by nothing. Hard until the probe is recalibrated against
536
+ // the corpus; the proposed wording and why it needs a replay are in
537
+ // `PROBE-FOLLOWUP.md`.
538
+ authority: "hard",
539
+ // Off by default, and `instruct` rather than `deny`, because `git clean
540
+ // -fdx` is a command developers run on purpose and often — it is the
541
+ // standard way to get a genuinely clean tree before a build. A default-on
542
+ // deny would fire on ordinary work, and a guard people switch off protects
543
+ // nothing; every policy in this category except `block-push-master` is
544
+ // default-off for the same reason, and `block-read-outside-cwd` was
545
+ // demoted out of the audit's archetype signal for being exactly this kind
546
+ // of ambient. What IS worth saying every time it is enabled is that the
547
+ // blast radius is wider than the operator usually means, so the policy
548
+ // warns and names what goes.
549
+ defaultEnabled: false,
550
+ category: "Git",
551
+ params: {
552
+ destructiveFlags: {
553
+ type: "string[]",
554
+ description:
555
+ "git clean flag letters that make it worth warning about, checked alongside --force. Narrow to ['x','X'] to allow `git clean -fd`, or widen with 'f' to warn on a bare `git clean -f`.",
556
+ default: ["d", "x", "X"],
557
+ },
558
+ } satisfies PolicyParamsSchema,
559
+ },
421
560
  {
422
561
  name: "warn-all-files-staged",
423
562
  displayTitle: "Staged all files with git add -A / .",
@@ -1059,7 +1059,7 @@ export type HookEventType = (typeof HOOK_EVENT_TYPES)[number];
1059
1059
  *
1060
1060
  * It stays in `HOOK_EVENT_TYPES` because that list is the canonical set a
1061
1061
  * policy may subscribe to; this one governs what we write into settings.json.
1062
- * No builtin matches it (all 39 match only PreToolUse / PostToolUse /
1062
+ * No builtin matches it (all 40 match only PreToolUse / PostToolUse /
1063
1063
  * PermissionRequest / Stop), so nothing is lost by not registering.
1064
1064
  */
1065
1065
  export const CLAUDE_INSTALL_EVENT_TYPES = HOOK_EVENT_TYPES.filter(
@@ -1 +0,0 @@
1
- (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,64237,e=>{"use strict";var t=e.i(43476),a=e.i(71645),s=e.i(12344),n=e.i(29054);let l=/^[^\s@]+@[^\s@]+\.[^\s@]+$/;function i(e){if((0,n.isAbortError)(e))return"request timed out. check your network and try again.";let t=e instanceof Error?e.message:String(e);return`network error: ${t}`}e.s(["AuthDialog",0,function({open:e,headline:r="where to route the reminder?",subhead:o="we'll send a one-time code to confirm.",onClose:c,onAuthed:d,source:u="unknown"}){let{capture:h}=(0,s.usePostHog)(),[m,f]=(0,a.useState)({kind:"email",error:null}),[v,b]=(0,a.useState)(!1),p=(0,a.useRef)(!1),x=(0,a.useRef)(null),w=(0,a.useRef)(null);(0,a.useEffect)(()=>{e&&(f({kind:"email",error:null}),b(!1),p.current=!1,h("audit_auth_dialog_opened",{source:u}))},[h,e,u]);let j=(0,a.useRef)(!1);(0,a.useEffect)(()=>{if(e){j.current=!0;return}j.current&&!p.current&&h("audit_auth_dialog_dismissed",{source:u,step:m.kind}),j.current=!1},[h,e,u,m.kind]),(0,a.useEffect)(()=>{if(!e)return;let t=setTimeout(()=>{"email"===m.kind?x.current?.focus():"code"===m.kind&&w.current?.focus()},50);return()=>clearTimeout(t)},[e,m.kind]),(0,a.useEffect)(()=>{if(!e)return;let t=e=>{"Escape"!==e.key||v||c()};return window.addEventListener("keydown",t),()=>window.removeEventListener("keydown",t)},[e,v,c]);let g="code"===m.kind&&m.resendIn>0;(0,a.useEffect)(()=>{if(!g)return;let e=setInterval(()=>{f(e=>"code"===e.kind?{...e,resendIn:Math.max(0,e.resendIn-1)}:e)},1e3);return()=>clearInterval(e)},[g]);let y=(0,a.useCallback)(async(e,t={})=>{let{isResend:a=!1}=t,s=e=>{a?f(t=>"code"===t.kind?{...t,error:e}:t):f({kind:"email",error:e})};b(!0);try{let t=await (0,n.fetchWithTimeout)("/api/auth/login-request",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({email:e})}),a=await t.json().catch(()=>({}));if(!t.ok){let e=a.message??"could not send code.";"rate_limited"===a.code&&void 0!==a.retry_after_secs?e=`too many tries. wait ${a.retry_after_secs}s and try again.`:"upstream_unreachable"===a.code&&(e="api-server unreachable. check your network."),s(e);return}f({kind:"code",email:e,error:null,expiresIn:a.expires_in??600,resendIn:a.resend_available_in??30})}catch(e){s(i(e))}finally{b(!1)}},[]),k=(0,a.useCallback)(async(e,t)=>{b(!0);try{let a=await (0,n.fetchWithTimeout)("/api/auth/login-verify",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({email:e,code:t})}),s=await a.json().catch(()=>({}));if(!a.ok||!s.authenticated||!s.user){let e=s.message??"invalid code.";"invalid_code"===s.code&&(e="wrong code, or it expired. try again."),f(t=>"code"===t.kind?{...t,error:e}:t);return}p.current=!0,h("audit_auth_dialog_succeeded",{source:u}),f({kind:"done",user:s.user}),d(s.user)}catch(t){let e=i(t);f(t=>"code"===t.kind?{...t,error:e}:t)}finally{b(!1)}},[h,d,u]),N=(0,a.useCallback)(async e=>{if(e.preventDefault(),v||"email"!==m.kind)return;let t=String(new FormData(e.currentTarget).get("email")??"").trim().toLowerCase();l.test(t)?await y(t):f({kind:"email",error:"that doesn't look like an email."})},[v,m,y]),S=(0,a.useCallback)(async e=>{if(e.preventDefault(),v||"code"!==m.kind)return;let t=String(new FormData(e.currentTarget).get("code")??"").trim();t.length<4||t.length>12?f(e=>"code"===e.kind?{...e,error:"code is 4–12 characters."}:e):await k(m.email,t)},[v,m,k]),C=(0,a.useCallback)(async()=>{"code"!==m.kind||m.resendIn>0||v||await y(m.email,{isResend:!0})},[m,v,y]);return e?(0,t.jsx)("div",{className:"auth-dialog-backdrop",role:"dialog","aria-modal":"true","aria-labelledby":"auth-dialog-title",onClick:e=>{v||e.target!==e.currentTarget||c()},children:(0,t.jsxs)("div",{className:"auth-dialog",children:[(0,t.jsx)("button",{type:"button",className:"auth-close",onClick:c,disabled:v,"aria-label":"close",children:"×"}),(0,t.jsx)("h2",{id:"auth-dialog-title",className:"auth-headline",children:r}),"email"===m.kind&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("p",{className:"auth-sub",children:o}),(0,t.jsxs)("form",{onSubmit:N,className:"auth-form",children:[(0,t.jsx)("input",{ref:x,id:"auth-dialog-email",name:"email",type:"email",autoComplete:"email",inputMode:"email",spellCheck:!1,placeholder:"you@yourdomain.com",disabled:v,className:"auth-input",required:!0}),m.error&&(0,t.jsx)("div",{className:"auth-error",children:m.error}),(0,t.jsxs)("div",{className:"auth-actions",children:[(0,t.jsx)("button",{type:"submit",className:"auth-btn primary",disabled:v,children:v?"sending…":"send code"}),(0,t.jsx)("button",{type:"button",className:"auth-btn",onClick:c,disabled:v,children:"cancel"})]})]})]}),"code"===m.kind&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)("p",{className:"auth-sub",children:["code sent to ",(0,t.jsx)("span",{className:"auth-email",children:m.email}),". expires in ",Math.ceil(m.expiresIn/60)," min."]}),(0,t.jsxs)("form",{onSubmit:S,className:"auth-form",children:[(0,t.jsx)("input",{ref:w,id:"auth-dialog-code",name:"code",type:"text",inputMode:"numeric",autoComplete:"one-time-code",spellCheck:!1,placeholder:"123456",disabled:v,className:"auth-input auth-input-code",maxLength:12,required:!0}),m.error&&(0,t.jsx)("div",{className:"auth-error",children:m.error}),(0,t.jsxs)("div",{className:"auth-actions",children:[(0,t.jsx)("button",{type:"submit",className:"auth-btn primary",disabled:v,children:v?"verifying…":"verify"}),(0,t.jsx)("button",{type:"button",className:"auth-btn",onClick:C,disabled:v||m.resendIn>0,children:m.resendIn>0?`resend in ${m.resendIn}s`:"resend code"})]}),(0,t.jsx)("button",{type:"button",className:"auth-back",onClick:()=>f({kind:"email",error:null}),disabled:v,children:"← use a different email"})]})]}),"done"===m.kind&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)("p",{className:"auth-sub",children:[(0,t.jsx)("span",{className:"auth-ok",children:"✓"})," signed in as"," ",(0,t.jsx)("span",{className:"auth-email",children:m.user.email}),"."]}),(0,t.jsx)("div",{className:"auth-actions",children:(0,t.jsx)("button",{type:"button",className:"auth-btn primary",onClick:c,children:"continue"})})]})]})}):null}])},86616,e=>{"use strict";var t=e.i(29054);class a extends Error{kind;constructor(e,t){super(t),this.kind=e,this.name="RerunError"}}async function s(e){try{let s=await (0,t.fetchWithTimeout)("/api/audit/run",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({cli:e.cli.length>0?e.cli:void 0,since:"all"===e.since?void 0:e.since,noCache:!!e.noCache||void 0})});if(!s.ok&&409!==s.status){let e=await s.text().catch(()=>"");throw console.error("audit run failed:",s.status,e),new a("post_failed",`audit run failed (${s.status})`)}}catch(e){if(e instanceof a)throw e;throw console.error("audit run request failed:",e),new a((0,t.isAbortError)(e)?"timeout":"network","audit run request failed")}let s=0;for(;;){await new Promise(e=>setTimeout(e,1e3));let e=null;try{let a=await (0,t.fetchWithTimeout)("/api/audit/status",{cache:"no-store"});a.ok&&(e=await a.json())}catch{}if(null===e){if(++s>=10)throw new a("network","audit status poll lost the server");continue}if(s=0,!e.running){if(e.error)throw new a("post_failed",e.error);return}}}e.s(["RerunError",0,a,"triggerRun",0,s])},2917,e=>{"use strict";var t=e.i(43476),a=e.i(71645),s=e.i(95187);let n=(0,s.createServerReference)("00886d6fd442c1b095151f60d50b80218492349ea6",s.callServer,void 0,s.findSourceMapURL,"getJevSettingsAction"),l=(0,s.createServerReference)("0012aa49182201bcf73cdde878f5483546103b60f6",s.callServer,void 0,s.findSourceMapURL,"removeJevConfigAction"),i=(0,s.createServerReference)("40b77dfb7787b11b779dabc19334dcc7f9f73c174d",s.callServer,void 0,s.findSourceMapURL,"saveJevConfigAction");var r=e.i(55574);let o=[{value:"typesafe",label:"typesafe"},{value:"openrouter",label:"openrouter"},{value:"vercel",label:"vercel ai gateway"},{value:"cloudflare",label:"cloudflare workers ai"},{value:"custom",label:"custom endpoint"}],c=[{value:"enforce",label:"enforce — jev's verdict counts"},{value:"shadow",label:"shadow — log only, regex decides"}];function d(e){return{provider:e.provider??"typesafe",baseUrl:e.baseUrl,accountId:e.accountId,mode:e.mode}}function u({id:e,label:a,hint:s,children:n}){return(0,t.jsxs)("div",{className:"set-field",children:[(0,t.jsx)("label",{className:"set-field-label",htmlFor:e,children:a}),n,s?(0,t.jsx)("span",{className:"set-hint",children:s}):null]})}e.s(["default",0,function({initial:e}){var s,h;let m,[f,v]=(0,a.useState)(e),[b,p]=(0,a.useState)(e?d(e):{provider:"typesafe",baseUrl:"",accountId:"",mode:"enforce"}),[x,w]=(0,a.useState)(""),[j,g]=(0,a.useState)(!1),[y,k]=(0,a.useState)(null),[N,S]=(0,a.useState)(!1),C=(0,a.useRef)(!0),M=(0,a.useRef)(!1),$=(0,a.useCallback)(async()=>{try{let e=await n();if(!C.current)return;v(e),M.current||p(d(e))}catch{}},[]);(0,a.useEffect)(()=>(C.current=!0,$(),()=>{C.current=!1}),[$]),(0,a.useEffect)(()=>{let e=()=>void $();return window.addEventListener("focus",e),document.addEventListener("visibilitychange",e),()=>{window.removeEventListener("focus",e),document.removeEventListener("visibilitychange",e)}},[$]);let E=(0,a.useCallback)((e,t)=>{M.current=!0,p(a=>({...a,[e]:t}))},[]),A=(0,a.useCallback)(async()=>{g(!0),k(null);try{let e=await i({provider:b.provider,baseUrl:b.baseUrl,accountId:b.accountId,mode:b.mode,token:x});if(!e.ok){k(e.problem),S(!0===e.needsToken);return}M.current=!1,S(!1),w(""),v(e.view),p(d(e.view)),(0,r.toast)(e.view.on?"jev is on.":"saved.")}catch{k("could not save that.")}finally{g(!1)}},[b,x]),R=(0,a.useCallback)(async()=>{g(!0),k(null),S(!1);try{let e=await l();if(!e.ok)return void k(e.problem);M.current=!1,w(""),v(e.view),p(d(e.view)),(0,r.toast)("jev is off. hooks run the regex policies.")}catch{k("could not turn that off.")}finally{g(!1)}},[]),D=null!==f&&"absent"!==f.status,_=f?.token,I=N?"needed for this save — type the token for this endpoint":_?"env"===_.source?"configured, read from the environment — leave blank to keep it":_.hint?`configured, ending ${_.hint} — leave blank to keep it`:"configured — leave blank to keep it":f?.status==="key-missing"?"read from the environment, which is not set in this shell — leave blank to keep it that way":"sent as a bearer token; stored owner-only at 0600";return(0,t.jsxs)("div",{className:"set-cell set-jev",children:[(0,t.jsx)("h2",{className:"set-cell-title",children:"jev · semantic evaluation"}),(0,t.jsx)("div",{className:"set-row set-row-main",children:(0,t.jsxs)("div",{className:"set-row-copy",children:[(0,t.jsx)("span",{className:f?.on?"set-strong":"set-dim",children:null===f?"reading…":f.on?`on. every judged command is also asked of ${f.provider}.`:"off. hooks run the regex policies exactly as before."}),(0,t.jsx)("span",{className:"set-dim",children:f?.on?"shadow"===f.mode?"shadow: jev's answers are logged, the regex result is what gets enforced.":"enforce: jev's answers can clear a reviewable deny.":"a second opinion on the commands the regex policies flag. needs your own endpoint and token."})]})}),f&&D&&(0,t.jsxs)("dl",{className:"set-how-list",children:[f.endpoint&&(0,t.jsxs)("div",{className:"set-how-row",children:[(0,t.jsx)("dt",{className:"set-how-label",children:"endpoint"}),(0,t.jsx)("dd",{className:"set-how-body",children:f.endpoint})]}),(0,t.jsxs)("div",{className:"set-how-row",children:[(0,t.jsx)("dt",{className:"set-how-label",children:"model"}),(0,t.jsx)("dd",{className:"set-how-body",children:function(e){switch(e.kind){case"id":return e.id;case"withheld":return"set to something that is not a model id — not shown here, in case it is a key";default:return"the provider's default"}}(f.model)})]}),(0,t.jsxs)("div",{className:"set-how-row",children:[(0,t.jsx)("dt",{className:"set-how-label",children:"token"}),(0,t.jsx)("dd",{className:"set-how-body",children:_?"env"===_.source?"from FAILPROOFAI_JEV_API_KEY":_.hint?`configured, ending ${_.hint}`:"configured":"none stored"})]}),f.permissions&&(0,t.jsxs)("div",{className:"set-how-row",children:[(0,t.jsx)("dt",{className:"set-how-label",children:"file"}),(0,t.jsx)("dd",{className:"set-how-body",children:`${f.path} \xb7 ${f.permissions}`})]}),f.reviewable&&(0,t.jsxs)("div",{className:"set-how-row",children:[(0,t.jsx)("dt",{className:"set-how-label",children:"reviewable"}),(0,t.jsx)("dd",{className:"set-how-body",children:f.reviewable.summary})]}),f.stats&&f.stats.total>0&&(0,t.jsxs)("div",{className:"set-how-row",children:[(0,t.jsx)("dt",{className:"set-how-label",children:"fallbacks"}),(0,t.jsx)("dd",{className:"set-how-body",children:`${(s=f.stats.fallbackRate,`${Math.round(100*s)}%`)} of ${f.stats.total} calls in the last ${Number.isInteger(m=(h=f.stats.windowMs)/36e5)&&m>=1?m%24==0?`${m/24}d`:`${m}h`:`${Math.max(1,Math.round(h/6e4))}m`} fell back to the regex engine.`})]})]}),f?.problem&&(0,t.jsxs)("p",{className:"set-warn",children:[f.problem,f.fix?` — ${f.fix}`:""]}),f?.reviewable?.problem&&(0,t.jsx)("p",{className:"set-warn",children:f.reviewable.problem}),(0,t.jsx)("div",{className:"set-rule"}),(0,t.jsxs)("div",{className:"set-jev-fields",children:[(0,t.jsx)(u,{id:"jev-provider",label:"provider",children:(0,t.jsx)("select",{id:"jev-provider",className:"set-select",value:b.provider,disabled:j,onChange:e=>E("provider",e.target.value),children:o.map(e=>(0,t.jsx)("option",{value:e.value,children:e.label},e.value))})}),(0,t.jsx)(u,{id:"jev-url",label:"endpoint url",hint:"custom"===b.provider?"required — https, or http to localhost in shadow mode":"leave blank for the provider's own api",children:(0,t.jsx)("input",{id:"jev-url",type:"text",className:"set-text",inputMode:"url",autoComplete:"off",spellCheck:!1,placeholder:"custom"===b.provider?"https://…":"the provider's own api",value:b.baseUrl,disabled:j,onChange:e=>E("baseUrl",e.target.value)})}),"cloudflare"===b.provider&&(0,t.jsx)(u,{id:"jev-account",label:"account id",hint:"32 lowercase hex characters",children:(0,t.jsx)("input",{id:"jev-account",type:"text",className:"set-text",autoComplete:"off",spellCheck:!1,value:b.accountId,disabled:j,onChange:e=>E("accountId",e.target.value)})}),(0,t.jsx)(u,{id:"jev-token",label:"token",hint:I,children:(0,t.jsx)("input",{id:"jev-token",type:"password",className:"set-text",autoComplete:"off",spellCheck:!1,placeholder:_?"•••• kept":"",value:x,disabled:j,"aria-invalid":N||void 0,onChange:e=>{M.current=!0,w(e.target.value)}})}),(0,t.jsx)(u,{id:"jev-mode",label:"mode",children:(0,t.jsx)("select",{id:"jev-mode",className:"set-select",value:b.mode,disabled:j,onChange:e=>E("mode",e.target.value),children:c.map(e=>(0,t.jsx)("option",{value:e.value,children:e.label},e.value))})})]}),y&&(0,t.jsx)("p",{className:"set-warn",children:y}),(0,t.jsxs)("div",{className:"set-actions set-jev-actions",children:[(0,t.jsx)("button",{type:"button",className:"btn btn-press",disabled:j,onClick:()=>void A(),children:j?"[ saving… ]":D?"[ save changes ]":"[ turn jev on ]"}),D&&(0,t.jsx)("button",{type:"button",className:"set-link",disabled:j,onClick:()=>void R(),children:"turn jev off"})]})]})}],2917)},93237,e=>{"use strict";var t=e.i(43476),a=e.i(71645),s=e.i(95187);let n=(0,s.createServerReference)("00a4b4e13d3b765196cdd39a6bcc3adb9dc9dd1e39",s.callServer,void 0,s.findSourceMapURL,"getScheduledAuditAction"),l=(0,s.createServerReference)("40542c2caee97c1baa6587e21be9b4c5a3e5cb04a7",s.callServer,void 0,s.findSourceMapURL,"setAutoAuditAction"),i=(0,s.createServerReference)("40a98655ac2e11879113abd14dae3692129e3723f4",s.callServer,void 0,s.findSourceMapURL,"setAuditIntervalAction");var r=e.i(86616),o=e.i(64237),c=e.i(55574),d=e.i(34713);function u(e){return new Date(e).toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}function h(e,t){let a=e-t;if(a<=0)return"now";let s=Math.floor(a/864e5),n=Math.floor(a%864e5/36e5);return s>0?n>0?`${s}d ${n}h`:`${s}d`:n>0?`${n}h`:`${Math.max(1,Math.floor(a/6e4))}m`}function m(e){return e.toLocaleString("en-US")}function f({label:e,value:a,sub:s,tone:n}){return(0,t.jsxs)("div",{className:"set-stat",children:[(0,t.jsx)("div",{className:"set-stat-label",children:e}),(0,t.jsx)("div",{className:`set-stat-value${n?` ${n}`:""}`,children:a}),(0,t.jsx)("div",{className:"set-stat-sub",children:s??" "})]})}function v({lastRunAtMs:e,nextDueAtMs:a,now:s}){if(null==e||null==a||a<=e)return null;let n=Math.min(100,Math.max(0,(s-e)/(a-e)*100));return(0,t.jsxs)("div",{className:"tape","aria-hidden":"true",children:[(0,t.jsxs)("div",{className:"tape-rail",children:[(0,t.jsx)("div",{className:"tape-fill",style:{width:`${n}%`}}),(0,t.jsx)("div",{className:"tape-now",style:{left:`${n}%`}})]}),(0,t.jsxs)("div",{className:"tape-ends",children:[(0,t.jsxs)("span",{children:["last scan · ",u(e)]}),(0,t.jsxs)("span",{className:"tape-next",children:["next · ",h(a,s)]})]})]})}function b({enabled:e,onChange:a,disabled:s,label:n}){return(0,t.jsx)("button",{type:"button",role:"switch","aria-checked":e,"aria-label":n,disabled:s,onClick:a,className:"sw","data-on":e?"true":"false",children:(0,t.jsx)("span",{className:"sw-knob"})})}let p=[{label:"reads",body:"every session transcript on disk — your prompts, the files your agents read and wrote, and command output."},{label:"runs",body:"entirely on this machine. the transcripts never leave it."},{label:"sends",body:"counts, redacted examples, and this machine's name — and only when a scan finds something harmful."}];e.s(["default",0,function({initial:e,jevPanel:s}){let[x,w]=(0,a.useState)(e),[j,g]=(0,a.useState)(e?.auto??!1),[y,k]=(0,a.useState)(e?.intervalDays??7),[N,S]=(0,a.useState)(!1),[C,M]=(0,a.useState)(!1),[$,E]=(0,a.useState)(!1),[A,R]=(0,a.useState)(null===e),[D,_]=(0,a.useState)(0),I=(0,a.useRef)(!0),T=(0,a.useRef)(null!==e),L=(0,a.useCallback)(async()=>{try{let e=await n();if(!I.current)return;w(e),T.current=!0,g(e.auto),k(e.intervalDays),_(Date.now()),R(!1)}catch{I.current&&!T.current&&R(!0)}},[]);(0,a.useEffect)(()=>(I.current=!0,L(),()=>{I.current=!1}),[L]),(0,a.useEffect)(()=>{let e=()=>void L();return window.addEventListener("focus",e),document.addEventListener("visibilitychange",e),()=>{window.removeEventListener("focus",e),document.removeEventListener("visibilitychange",e)}},[L]);let U=x?.signedInAs??null,F=x?.daemon==="running",O=x?.daemon==="unsupported-platform",P=x?.schedule??null,q=x?.lastScan??null,J=P?.lastExitCode!=null&&0!==P.lastExitCode&&75!==P.lastExitCode,W=(0,a.useCallback)(async()=>{S(!0);try{let e=await l(!0);if(!e.ok){if(g(!1),"unreachable"===e.reason)return void(0,c.toast)("could not reach the server. check your connection and try again.");await L(),E(!0),(0,c.toast)("that sign-in expired. one more code and it's on.");return}g(e.auto),(0,c.toast)("scheduled audits on."),await L()}catch{g(!1),(0,c.toast)("could not turn that on.")}finally{S(!1)}},[L]),B=(0,a.useCallback)(async()=>{if(j){S(!0);try{let e=await l(!1);e.ok&&g(e.auto),(0,c.toast)("scheduled audits off."),await L()}catch{(0,c.toast)("could not turn that off.")}finally{S(!1)}return}U?await W():E(!0)},[j,W,L,U]),K=(0,a.useCallback)(async e=>{S(!0);try{let t=await i(e);k(t.intervalDays),w(e=>e?{...e,intervalDays:t.intervalDays}:e),(0,c.toast)(`scanning every ${t.intervalDays} day${1===t.intervalDays?"":"s"}.`)}catch{k(x?.intervalDays??7),(0,c.toast)("could not save that.")}finally{S(!1)}},[x?.intervalDays]),H=(0,a.useCallback)(async()=>{S(!0);try{await fetch("/api/auth/logout",{method:"POST"}),(0,c.toast)("signed out. scans continue; digests pause."),await L()}catch{(0,c.toast)("could not sign out.")}finally{S(!1)}},[L]),V=(0,a.useCallback)(async()=>{if(!C){M(!0);try{await (0,r.triggerRun)({cli:[],since:"all",noCache:!1}),(0,c.toast)("scan complete."),await L()}catch(e){(0,c.toast)(e instanceof r.RerunError&&"timeout"===e.kind?"the scan is taking a while — it will finish in the background.":"the scan could not be completed.")}finally{M(!1)}}},[L,C]),Y=(0,a.useCallback)(async e=>{E(!1),await L(),await W()},[W,L]),z=x?F?{value:"running",sub:null!=x.daemonStartedAtMs&&D>0?`up ${function(e){let t=Math.floor(e/864e5);if(t>0)return`${t}d`;let a=Math.floor(e/36e5);return a>0?`${a}h`:`${Math.max(1,Math.floor(e/6e4))}m`}(Math.max(0,D-x.daemonStartedAtMs))}`:"",tone:"ok"}:O?{value:"unavailable",sub:"not on this platform"}:"not-installed"===x.daemon?{value:"not installed",sub:"run failproofai config",tone:"warn"}:"unknown"===x.daemon?{value:"unknown",sub:"could not read it"}:{value:"stopped",sub:"run failproofai config",tone:"warn"}:{value:"…",sub:"reading"},G=j?P?.nextDueAtMs==null?{value:"pending",sub:"after the next scan"}:{value:D>0?h(P.nextDueAtMs,D):"—",sub:u(P.nextDueAtMs)}:{value:"off",sub:"nothing scheduled"},Q=q?{value:(0,d.formatRelativeTime)(Date.parse(q.finishedAt)),sub:null!=q.sessionsScanned?`${m(q.sessionsScanned)} sessions`:"scanned"}:{value:"none yet",sub:"run one below"},X=q?null==q.findings?{value:"—",sub:"unreadable"}:{value:m(q.findings),sub:"this scan",...q.findings>0?{tone:"warn"}:{}}:{value:"—",sub:"no scan yet"};return(0,t.jsxs)("main",{className:"report",children:[(0,t.jsxs)("section",{className:"section set-sec",children:[(0,t.jsxs)("div",{className:"set-mast",children:[(0,t.jsx)("h1",{className:"set-title",children:"settings"}),(0,t.jsx)("p",{className:"set-lede",children:"keeping watch, so you don't have to."})]}),A?(0,t.jsxs)("div",{className:"set-console",children:[(0,t.jsx)("div",{className:"set-cell",children:(0,t.jsxs)("p",{className:"set-warn",children:["could not read this machine's settings. check that the dashboard can reach ",(0,t.jsx)("code",{children:"~/.failproofai/config.json"}),"."]})}),s]}):(0,t.jsxs)("div",{className:"set-console",children:[(0,t.jsxs)("div",{className:"set-stats",children:[(0,t.jsx)(f,{label:"daemon",...z}),(0,t.jsx)(f,{label:"next scan",...G}),(0,t.jsx)(f,{label:"last scan",...Q}),(0,t.jsx)(f,{label:"findings",...X})]}),(0,t.jsxs)("div",{className:"set-cols",children:[(0,t.jsxs)("div",{className:"set-cell set-config",children:[(0,t.jsx)("h2",{className:"set-cell-title",children:"scheduled audit"}),(0,t.jsxs)("div",{className:"set-row set-row-main",children:[(0,t.jsx)(b,{enabled:j,disabled:N||null===x,onChange:()=>void B(),label:j?"turn off scheduled audits":"turn on scheduled audits"}),(0,t.jsxs)("div",{className:"set-row-copy",children:[(0,t.jsx)("span",{className:"set-strong",children:j?"scanning on a schedule.":"scan on a schedule."}),(0,t.jsx)("span",{className:"set-dim",children:j?"you'll get an email only when a scan finds something.":"off. nothing runs and nothing is sent."})]})]}),(0,t.jsxs)("div",{className:"set-row set-row-interval",children:[(0,t.jsx)("span",{className:"set-dim",children:"scan every"}),(0,t.jsx)("input",{type:"number",className:"set-num",min:1,max:90,value:y,disabled:N||null===x,"aria-label":"days between scheduled scans",onChange:e=>k(Number(e.target.value)),onBlur:e=>{let t=Number(e.target.value);Number.isFinite(t)?t!==x?.intervalDays&&K(t):k(x?.intervalDays??7)}}),(0,t.jsx)("span",{className:"set-dim",children:"days"}),(0,t.jsxs)("span",{className:"set-hint",children:[1,"–",90]})]}),(0,t.jsx)("div",{className:"set-rule"}),(0,t.jsx)("div",{className:"set-row set-row-identity",children:U?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("span",{className:"set-dim",children:"reports go to"}),(0,t.jsx)("span",{className:"set-email",children:U.email}),(0,t.jsx)("button",{type:"button",className:"set-link",disabled:N,onClick:()=>void H(),children:"sign out"})]}):j?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("span",{className:"set-warn",children:"signed out — scans continue, digests are paused."}),(0,t.jsx)("button",{type:"button",className:"set-link",disabled:N,onClick:()=>E(!0),children:"sign in to resume"})]}):(0,t.jsx)("span",{className:"set-dim",children:"turning this on asks for an email, so there is somewhere to send the report."})}),j&&x&&!F&&(0,t.jsx)("p",{className:"set-warn",children:O?"the background service isn't available on this platform, so scheduled scans can't run here. you can still run one now.":"not-installed"===x.daemon?"the background service isn't installed, so nothing will run on the timer. install it with `failproofai config`.":"the background service is stopped, so nothing will run until it starts. repair it with `failproofai config`."}),J&&(0,t.jsxs)("p",{className:"set-warn",children:["the last scheduled scan exited ",P?.lastExitCode,". the next one will still run."]}),(0,t.jsx)("div",{className:"set-actions",children:(0,t.jsx)("button",{type:"button",className:"btn btn-press",disabled:C,onClick:()=>void V(),children:C?"[ scanning… ]":"[ run a scan now ]"})})]}),(0,t.jsxs)("div",{className:"set-cell set-how",children:[(0,t.jsx)("h2",{className:"set-cell-title",children:"how it works"}),(0,t.jsx)("dl",{className:"set-how-list",children:p.map(e=>(0,t.jsxs)("div",{className:"set-how-row",children:[(0,t.jsx)("dt",{className:"set-how-label",children:e.label}),(0,t.jsx)("dd",{className:"set-how-body",children:e.body})]},e.label))})]})]}),s]}),j&&D>0&&(0,t.jsx)(v,{lastRunAtMs:P?.lastRunAtMs??null,nextDueAtMs:P?.nextDueAtMs??null,now:D})]}),(0,t.jsx)(o.AuthDialog,{open:$,source:"settings_scheduled_audit",headline:"where should the report go?",subhead:"we'll send a one-time code to confirm.",onClose:()=>E(!1),onAuthed:e=>void Y(e)})]})}],93237)},29054,e=>{"use strict";e.s(["fetchWithTimeout",0,function(e,t={},a=15e3){let s=AbortSignal.timeout(a),n=t.signal?AbortSignal.any([t.signal,s]):s;return fetch(e,{...t,signal:n})},"isAbortError",0,function(e){if(null===e||"object"!=typeof e)return!1;let t=e.name;return"AbortError"===t||"TimeoutError"===t}])},34713,e=>{"use strict";e.s(["formatDuration",0,function(e){if(e<1e3)return`${e}ms`;let t=Math.round(e/100);if(t<600)return`${(t/10).toFixed(1)}s`;let a=Math.round(e/1e3);if(a<3600){let e=Math.floor(a/60);return`${e}m ${a%60}s`}let s=Math.round(e/6e4),n=Math.floor(s/60);return`${n}h ${s%60}m`},"formatRelativeTime",0,function(e){let t=Date.now()-e;return t<6e4?`${Math.max(1,Math.floor(t/1e3))}s ago`:t<36e5?`${Math.floor(t/6e4)}m ago`:t<864e5?`${Math.floor(t/36e5)}h ago`:`${Math.floor(t/864e5)}d ago`}])}]);