failproofai 1.0.7 → 1.0.8

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 (268) 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 +4 -4
  7. package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  8. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  10. package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
  11. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +6 -6
  12. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
  13. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  14. package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  15. package/.next/standalone/.next/server/app/_not-found/page.js +4 -4
  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 +1 -1
  19. package/.next/standalone/.next/server/app/_not-found.rsc +15 -15
  20. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +15 -15
  21. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +14 -14
  22. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  23. package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -1
  24. package/.next/standalone/.next/server/app/api/audit/run/route.js +8 -7
  25. package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
  26. package/.next/standalone/.next/server/app/api/audit/status/route.js.nft.json +1 -1
  27. package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
  28. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
  29. package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
  30. package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
  31. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
  32. package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
  33. package/.next/standalone/.next/server/app/audit/page.js +9 -7
  34. package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
  35. package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
  36. package/.next/standalone/.next/server/app/index.html +1 -1
  37. package/.next/standalone/.next/server/app/index.rsc +15 -15
  38. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +14 -14
  39. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
  40. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  41. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
  42. package/.next/standalone/.next/server/app/page.js +6 -6
  43. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  44. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  45. package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +14 -14
  46. package/.next/standalone/.next/server/app/policies/page.js +11 -10
  47. package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
  48. package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
  49. package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
  50. package/.next/standalone/.next/server/app/project/[name]/page.js +8 -7
  51. package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
  52. package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
  53. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
  54. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
  55. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js +6 -6
  56. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
  57. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
  58. package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
  59. package/.next/standalone/.next/server/app/projects/page.js +7 -6
  60. package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
  61. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  62. package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +52 -8
  63. package/.next/standalone/.next/server/app/settings/page.js +12 -7
  64. package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
  65. package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  66. package/.next/standalone/.next/server/chunks/{[externals]__1msfs-h._.js → [externals]__19_pzeq._.js} +1 -1
  67. package/.next/standalone/.next/server/chunks/{[externals]__1_bftcl._.js → [externals]__20kzpkf._.js} +1 -1
  68. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o07qi9._.js +1 -1
  69. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1ttrwnd._.js +22 -0
  70. package/.next/standalone/.next/server/chunks/_09dz7xv._.js +21 -21
  71. package/.next/standalone/.next/server/chunks/_0tovk6q._.js +1 -1
  72. package/.next/standalone/.next/server/chunks/_0trp3yc._.js +1 -1
  73. package/.next/standalone/.next/server/chunks/_1ek68ln._.js +16 -16
  74. package/.next/standalone/.next/server/chunks/{_1c3k-8x._.js → _1q5i8mb._.js} +2 -2
  75. package/.next/standalone/.next/server/chunks/lib_16xa545._.js +3 -0
  76. package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
  77. package/.next/standalone/.next/server/chunks/src_hooks_1aveq0u._.js +5 -0
  78. package/.next/standalone/.next/server/chunks/src_hooks_1eem5a7._.js +3 -0
  79. package/.next/standalone/.next/server/chunks/src_hooks_custom-hooks-loader_ts_0lnb3n3._.js +4 -2
  80. package/.next/standalone/.next/server/chunks/ssr/[externals]__0ohnuzs._.js +3 -0
  81. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__01bmjsj._.js +3 -0
  82. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__04usis8._.js +4 -0
  83. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__02npjtd._.js → [root-of-the-server]__056wjo4._.js} +3 -3
  84. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__059yza8._.js +3 -0
  85. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__06pflha._.js +3 -0
  86. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0eip4_k._.js +22 -0
  87. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0p-5p8u._.js → [root-of-the-server]__0n0xg95._.js} +3 -3
  88. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qcb0mg._.js +3 -0
  89. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__013jr2b._.js → [root-of-the-server]__0rwtwpm._.js} +3 -3
  90. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0yrsbd_._.js +3 -0
  91. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0da85px._.js → [root-of-the-server]__11mayhe._.js} +3 -3
  92. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__12e7nhs._.js +3 -0
  93. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__13d-wb6._.js +3 -0
  94. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__13t1zkw._.js +3 -0
  95. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__15578wp._.js +4 -0
  96. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__19evfi8._.js +3 -0
  97. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1dinjii._.js +3 -0
  98. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1m_svbe._.js +4 -0
  99. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0cxe_2_._.js → [root-of-the-server]__1mf3zp6._.js} +3 -3
  100. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0ftmoxc._.js → [root-of-the-server]__1pprgri._.js} +3 -3
  101. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1p2otjt._.js → [root-of-the-server]__1q4p5b8._.js} +3 -3
  102. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1qiz0e4._.js +3 -0
  103. package/.next/standalone/.next/server/chunks/ssr/{_166t73i._.js → _0-vcssj._.js} +1 -1
  104. package/.next/standalone/.next/server/chunks/ssr/_042cgl1._.js +3 -0
  105. package/.next/standalone/.next/server/chunks/ssr/_08x1r5t._.js +1 -1
  106. package/.next/standalone/.next/server/chunks/ssr/_0bqoto4._.js +3 -0
  107. package/.next/standalone/.next/server/chunks/ssr/_0uyu3jf._.js +3 -0
  108. package/.next/standalone/.next/server/chunks/ssr/_13kfn90._.js +23 -0
  109. package/.next/standalone/.next/server/chunks/ssr/{_1es2j7i._.js → _1gb0ifp._.js} +5 -5
  110. package/.next/standalone/.next/server/chunks/ssr/{_1_qswah._.js → _1q46vxx._.js} +2 -2
  111. package/.next/standalone/.next/server/chunks/ssr/_1zopuov._.js +1 -1
  112. package/.next/standalone/.next/server/chunks/ssr/_next-internal_server_app_policies_page_actions_1sp2-yo.js +13 -13
  113. package/.next/standalone/.next/server/chunks/ssr/app_actions_get-scheduled-audit_ts_0ei9sni._.js +3 -0
  114. package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +1 -1
  115. package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
  116. package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +2 -2
  117. package/.next/standalone/.next/server/chunks/ssr/app_settings_02tf1h4._.js +3 -0
  118. package/.next/standalone/.next/server/chunks/ssr/{node_modules_next_dist_0drixxt._.js → node_modules_next_dist_0w6mzq5._.js} +4 -4
  119. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_18_d8l1._.js +151 -0
  120. package/.next/standalone/.next/server/chunks/ssr/src_hooks_0-q0umm._.js +3 -0
  121. package/.next/standalone/.next/server/chunks/ssr/src_hooks_06kzv9d._.js +12 -0
  122. package/.next/standalone/.next/server/chunks/ssr/src_hooks_0g194sy._.js +3 -0
  123. package/.next/standalone/.next/server/chunks/ssr/src_hooks_1cv9_c4._.js +4 -2
  124. package/.next/standalone/.next/server/chunks/ssr/src_hooks_1kx9e0d._.js +3 -0
  125. package/.next/standalone/.next/server/chunks/ssr/src_hooks_effective-reviewers_ts_1h4wtvo._.js +5 -0
  126. package/.next/standalone/.next/server/chunks/ssr/src_hooks_fp-config_ts_04t589g._.js +1 -1
  127. package/.next/standalone/.next/server/chunks/ssr/src_hooks_fp-home_ts_0je3xkv._.js +1 -1
  128. package/.next/standalone/.next/server/chunks/ssr/src_hooks_pack-cli_ts_0t7me65._.js +1 -1
  129. package/.next/standalone/.next/server/chunks/ssr/src_hooks_semantic_pack-policies_ts_0gh_bu_._.js +3 -0
  130. package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
  131. package/.next/standalone/.next/server/pages/404.html +1 -1
  132. package/.next/standalone/.next/server/pages/500.html +1 -1
  133. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  134. package/.next/standalone/.next/server/server-reference-manifest.json +67 -23
  135. package/.next/standalone/.next/static/chunks/06dnzbolj00mc.js +6 -0
  136. package/.next/standalone/.next/static/chunks/0bhidk90e-07f.css +2 -0
  137. package/.next/standalone/.next/static/chunks/{2mdh397ghgnvv.js → 0m-9d6yn9hx4j.js} +1 -1
  138. package/.next/standalone/.next/static/chunks/{0__8a7m868fvf.js → 0wbjy0zo-m7is.js} +1 -1
  139. package/.next/standalone/.next/static/chunks/16f3fa-lx38hk.js +1 -0
  140. package/.next/standalone/.next/static/chunks/{0o6qlkgubtoex.js → 21uv-uusw329x.js} +1 -1
  141. package/.next/standalone/.next/static/chunks/2g2tki08kdhie.js +1 -0
  142. package/.next/standalone/.next/static/chunks/2qdpj67x6ifk_.js +69 -0
  143. package/.next/standalone/.next/static/chunks/2qv4hshejedtx.css +1 -0
  144. package/.next/standalone/.next/static/chunks/3-nbtkhg9y-1j.js +1 -0
  145. package/.next/standalone/.next/static/chunks/355km0ihuqo1p.js +1 -0
  146. package/.next/standalone/.next/static/chunks/{13i7-9is-vhys.js → 3c3qbmosdjl6w.js} +1 -1
  147. package/.next/standalone/PROBE-FOLLOWUP.md +186 -0
  148. package/.next/standalone/app/actions/get-jev-config.ts +604 -0
  149. package/.next/standalone/app/actions/pack-actions.ts +12 -0
  150. package/.next/standalone/app/actions/update-jev-config.ts +569 -0
  151. package/.next/standalone/app/components/jev-notices.tsx +96 -0
  152. package/.next/standalone/app/policies/hooks-client.tsx +14 -3
  153. package/.next/standalone/app/settings/jev-panel.tsx +630 -0
  154. package/.next/standalone/app/settings/page.tsx +20 -1
  155. package/.next/standalone/app/settings/settings-client.tsx +27 -1
  156. package/.next/standalone/app/settings/settings.css +79 -0
  157. package/.next/standalone/fp-cloud-cli/CHANGELOG.md +22 -4
  158. package/.next/standalone/fp-cloud-cli/fp_cli/client.py +14 -1
  159. package/.next/standalone/fp-cloud-cli/fp_cli/commands/keys_cmds.py +17 -3
  160. package/.next/standalone/fp-cloud-cli/fp_cli/commands/policies_cmds.py +3 -0
  161. package/.next/standalone/fp-cloud-cli/fp_cli/permissions.py +22 -0
  162. package/.next/standalone/fp-cloud-cli/fp_cli/policy_check.py +169 -0
  163. package/.next/standalone/fp-cloud-cli/skill/references/commands.md +1 -1
  164. package/.next/standalone/fp-cloud-cli/tests/test_keys_queries.py +65 -0
  165. package/.next/standalone/fp-cloud-cli/tests/test_policy_check.py +61 -0
  166. package/.next/standalone/package.json +10 -10
  167. package/.next/standalone/sdk/python/CHANGELOG.md +7 -0
  168. package/.next/standalone/sdk/python/failproofai_sdk/_version.py +1 -1
  169. package/.next/standalone/sdk/typescript/CHANGELOG.md +18 -1
  170. package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/package-lock.json +0 -274
  171. package/.next/standalone/sdk/typescript/scripts/release.mjs +30 -0
  172. package/.next/standalone/server.js +1 -1
  173. package/README.md +3 -2
  174. package/bin/failproofai.mjs +148 -4
  175. package/dist/cli.mjs +18599 -9478
  176. package/dist/index.js +19 -1
  177. package/dist/worker.mjs +10500 -3773
  178. package/package.json +10 -10
  179. package/pi-extension/index.ts +11 -0
  180. package/scripts/build-policy-pack.mjs +53 -2
  181. package/src/audit/features.ts +3 -2
  182. package/src/hooks/builtin-policies.ts +195 -8
  183. package/src/hooks/cloud-connection.ts +190 -1
  184. package/src/hooks/cloud-enrollment-cli.ts +57 -8
  185. package/src/hooks/cloud-introspect.ts +6 -0
  186. package/src/hooks/cloud-managed-policies.ts +22 -0
  187. package/src/hooks/configure-wizard.ts +26 -6
  188. package/src/hooks/custom-hooks-loader.ts +98 -10
  189. package/src/hooks/custom-hooks-registry.ts +45 -1
  190. package/src/hooks/effective-reviewers.ts +243 -0
  191. package/src/hooks/first-run-gate.ts +5 -0
  192. package/src/hooks/flush-cli.ts +35 -8
  193. package/src/hooks/fp-config.ts +266 -1
  194. package/src/hooks/fp-home.ts +23 -0
  195. package/src/hooks/fp-reset.ts +22 -4
  196. package/src/hooks/handler.ts +303 -7
  197. package/src/hooks/hook-activity-store.ts +118 -6
  198. package/src/hooks/hook-telemetry.ts +41 -0
  199. package/src/hooks/jev-activity.ts +385 -0
  200. package/src/hooks/jev-cli.ts +2172 -0
  201. package/src/hooks/jev-cloud-connection.ts +392 -0
  202. package/src/hooks/loader-utils.ts +6 -0
  203. package/src/hooks/manager.ts +45 -7
  204. package/src/hooks/pack-cli.ts +568 -37
  205. package/src/hooks/pack-failclosed.ts +3 -0
  206. package/src/hooks/pack-manifest.ts +489 -7
  207. package/src/hooks/pack-store.ts +194 -11
  208. package/src/hooks/policy-authority.ts +386 -0
  209. package/src/hooks/policy-catalog.ts +206 -0
  210. package/src/hooks/policy-evaluator.ts +963 -796
  211. package/src/hooks/policy-registry.ts +27 -1
  212. package/src/hooks/policy-reviewability.ts +258 -0
  213. package/src/hooks/policy-types.ts +128 -0
  214. package/src/hooks/semantic/combine.ts +581 -0
  215. package/src/hooks/semantic/compile.ts +176 -0
  216. package/src/hooks/semantic/decide.ts +513 -0
  217. package/src/hooks/semantic/envelope.ts +1255 -0
  218. package/src/hooks/semantic/evaluator.ts +556 -0
  219. package/src/hooks/semantic/facts.ts +387 -0
  220. package/src/hooks/semantic/intent.ts +1190 -0
  221. package/src/hooks/semantic/jev-client.ts +1155 -0
  222. package/src/hooks/semantic/jev-config.ts +1142 -0
  223. package/src/hooks/semantic/jev-review.ts +389 -0
  224. package/src/hooks/semantic/jev-stats.ts +289 -0
  225. package/src/hooks/semantic/jev-throttle.ts +427 -0
  226. package/src/hooks/semantic/pack-policies.ts +294 -0
  227. package/src/hooks/semantic/policies.ts +597 -0
  228. package/src/hooks/semantic/precondition-names.ts +60 -0
  229. package/src/hooks/semantic/preconditions.ts +58 -0
  230. package/src/hooks/semantic/redact.ts +2937 -0
  231. package/src/hooks/semantic/session-root.ts +116 -0
  232. package/src/hooks/semantic/types.ts +162 -0
  233. package/src/hooks/semver-precedence.ts +128 -0
  234. package/src/hooks/tui.ts +4 -0
  235. package/src/hooks/types.ts +1 -1
  236. package/src/hooks/worker-server.ts +121 -27
  237. package/src/index.ts +6 -0
  238. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0cuho4x._.js +0 -3
  239. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1_r2rbg._.js +0 -24
  240. package/.next/standalone/.next/server/chunks/src_hooks_0iu54mz._.js +0 -3
  241. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0-_ki57._.js +0 -4
  242. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__01wy8d-._.js +0 -4
  243. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0bd3mje._.js +0 -3
  244. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0cg-bgc._.js +0 -5
  245. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0cpu_mj._.js +0 -3
  246. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0u3w0ll._.js +0 -22
  247. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__17d_ffl._.js +0 -3
  248. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__19d9tgz._.js +0 -5
  249. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1ctpynv._.js +0 -3
  250. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1jiwfsj._.js +0 -3
  251. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1phc187._.js +0 -3
  252. package/.next/standalone/.next/server/chunks/ssr/_06imw3p._.js +0 -5
  253. package/.next/standalone/.next/server/chunks/ssr/_0h_douw._.js +0 -3
  254. package/.next/standalone/.next/server/chunks/ssr/_1-i_gzc._.js +0 -23
  255. package/.next/standalone/.next/server/chunks/ssr/_1u8-lu2._.js +0 -3
  256. package/.next/standalone/.next/server/chunks/ssr/app_settings_settings-client_tsx_20lq-mq._.js +0 -3
  257. package/.next/standalone/.next/server/chunks/ssr/src_hooks_builtin-policies_ts_09j2ndl._.js +0 -3
  258. package/.next/standalone/.next/static/chunks/094xgi4owxaqf.js +0 -1
  259. package/.next/standalone/.next/static/chunks/1rz20_pz828f3.js +0 -6
  260. package/.next/standalone/.next/static/chunks/2k9f4tyv04809.css +0 -1
  261. package/.next/standalone/.next/static/chunks/2klitrtzpaoe0.js +0 -1
  262. package/.next/standalone/.next/static/chunks/2rshywgeqsyzk.css +0 -2
  263. package/.next/standalone/.next/static/chunks/3pzx4chkhko9k.js +0 -1
  264. package/.next/standalone/.next/static/chunks/3rh5o7e16irrm.js +0 -69
  265. package/.next/standalone/.next/static/chunks/43ufqrz8qo3h-.js +0 -1
  266. /package/.next/standalone/.next/static/{PgeWCHmyVbjRznv2VO7KF → 5yKM8NoTOpUI0MoQl8eo5}/_buildManifest.js +0 -0
  267. /package/.next/standalone/.next/static/{PgeWCHmyVbjRznv2VO7KF → 5yKM8NoTOpUI0MoQl8eo5}/_clientMiddlewareManifest.js +0 -0
  268. /package/.next/standalone/.next/static/{PgeWCHmyVbjRznv2VO7KF → 5yKM8NoTOpUI0MoQl8eo5}/_ssgManifest.js +0 -0
@@ -0,0 +1,387 @@
1
+ /**
2
+ * Deterministic facts about a tool call, computed locally before Jev is asked.
3
+ *
4
+ * TypeSafe's own jaggedness notes say Jev cannot count, resolve paths or do
5
+ * arithmetic, and answers the question you wrote rather than the one you
6
+ * meant. So anything with one right answer — which directory `*` expands in
7
+ * after a `cd`, whether a path is inside the project, which branch is checked
8
+ * out — is worked out here and handed to Jev as a fact rather than a question.
9
+ *
10
+ * Everything in this file is linear in the input and never spawns a process:
11
+ * it runs on the hook's hot path, inside the daemon worker's serialised chain.
12
+ */
13
+ import { existsSync, readFileSync, statSync } from "node:fs";
14
+ import { homedir } from "node:os";
15
+ import { dirname, isAbsolute, resolve } from "node:path";
16
+ import type { Facts, PathFact, ToolClass } from "./types";
17
+
18
+ const SHELL_TOOLS = new Set(["Bash", "BashOutput"]);
19
+ const WRITE_TOOLS = new Set(["Write", "Edit", "MultiEdit", "NotebookEdit"]);
20
+ const READ_TOOLS = new Set(["Read", "Glob", "Grep", "LS"]);
21
+ const NETWORK_TOOLS = new Set(["WebFetch", "WebSearch"]);
22
+ /** Known tools with no side effects worth judging. They never cost a Jev call. */
23
+ const INERT_TOOLS = new Set([
24
+ "TodoWrite", "TodoRead", "ExitPlanMode", "EnterPlanMode", "Task", "Agent",
25
+ "AskUserQuestion", "ToolSearch", "KillShell", "SlashCommand", "Skill",
26
+ ]);
27
+
28
+ export function classifyTool(toolName: string): { toolClass: ToolClass; toolIsKnown: boolean } {
29
+ if (SHELL_TOOLS.has(toolName)) return { toolClass: "shell", toolIsKnown: true };
30
+ if (WRITE_TOOLS.has(toolName)) return { toolClass: "write", toolIsKnown: true };
31
+ if (READ_TOOLS.has(toolName)) return { toolClass: "read", toolIsKnown: true };
32
+ if (NETWORK_TOOLS.has(toolName)) return { toolClass: "network", toolIsKnown: true };
33
+ if (INERT_TOOLS.has(toolName)) return { toolClass: "other", toolIsKnown: true };
34
+ // MCP tools (`mcp__server__tool`), skills that shell out, and anything a
35
+ // harness names that no canonical map covers. These are exactly the calls
36
+ // the regex engine never sees, because every builtin opens with a toolName
37
+ // check.
38
+ return { toolClass: "other", toolIsKnown: false };
39
+ }
40
+
41
+ /** Upper bound on command text the scanner will look at. Linear, but bounded. */
42
+ export const MAX_SCAN_CHARS = 8_192;
43
+
44
+ export interface ScannedCommand {
45
+ /** Simple-command segments, split on `&&`, `||`, `;`, `|` and newlines. */
46
+ segments: string[][];
47
+ /** The command with shell comments removed (quote-aware). */
48
+ withoutComments: string;
49
+ commentsRemoved: boolean;
50
+ /** The removed comment text, so the injection probe can still see it. */
51
+ comments: string[];
52
+ /**
53
+ * False when the scan may not have seen every word bash would run: the
54
+ * command was longer than `MAX_SCAN_CHARS`, or it uses syntax this scanner
55
+ * does not model (see {@link scanCommand}). Then `segments` is a GUESS — a
56
+ * `#` it read as a comment may not be one, and a word it never reached may be
57
+ * a target — and a caller must not rest a clear on what the segments omit.
58
+ */
59
+ complete: boolean;
60
+ }
61
+
62
+ /** Shells whose `-c` argument is a second command line this scan does not parse. */
63
+ const NESTED_SHELLS = new Set(["sh", "bash", "zsh", "dash", "ksh", "ash", "fish"]);
64
+
65
+ /**
66
+ * A `$` followed by this starts an expansion bash performs outside single
67
+ * quotes: `$NAME`, `$1`, `$@ $* $# $? $$ $! $-`, `${…}`, `$(…)` and `$((…))`.
68
+ * The scan does not resolve any of them — `DANGER=/critical; rm -rf $DANGER`
69
+ * names `/critical` only through the variable — so each makes it incomplete.
70
+ * A `$` before anything else (a space, `/`, the end) is a literal dollar.
71
+ */
72
+ const EXPANSION_START = /[A-Za-z_0-9@*#?$!\-({]/;
73
+
74
+ /** A segment that hands a string to a shell to parse again: `eval …`, `bash -c …`, `sudo sh -lc …`. */
75
+ function runsNestedShell(tokens: string[]): boolean {
76
+ // One pass, so a segment of ten thousand `sh` words stays linear.
77
+ let shellSeen = false;
78
+ for (const tok of tokens) {
79
+ if (shellSeen && /^-[a-z]*c[a-z]*$/i.test(tok)) return true;
80
+ const base = tok.slice(tok.lastIndexOf("/") + 1);
81
+ if (base === "eval") return true;
82
+ if (NESTED_SHELLS.has(base)) shellSeen = true;
83
+ }
84
+ return false;
85
+ }
86
+
87
+ /**
88
+ * A single left-to-right pass over a shell command: quote-aware tokenising,
89
+ * operator splitting and comment removal. It is deliberately not a full shell
90
+ * parser — it only needs to find words, segment boundaries and comments, and
91
+ * it must stay linear no matter what the agent sends.
92
+ *
93
+ * Because it is not bash, it says when it may be wrong: `complete` is false on
94
+ * any construct whose quoting or word boundaries it does not follow — `$'…'`
95
+ * and `$"…"`, any parameter expansion (`$NAME`, `$1`, `$@`, `${…}`, `$((…))`),
96
+ * `$(…)` and backticks, unquoted brace expansion (`{a,b}`, `{1..3}`) and
97
+ * globs (`*`, `?`, `[…]`), `<(…)` / `>(…)`, heredocs and
98
+ * here-strings (`<<`), a backslash-newline, a quote left open at the end,
99
+ * `eval` or a shell's `-c` string, and a command cut at `MAX_SCAN_CHARS`.
100
+ * Each of those can put a `#` where the scan sees a comment and bash does not
101
+ * (`echo $'x\' # '; rm -rf /critical` scans as `echo x`), or put a command
102
+ * where the scan sees one word. The flag costs one comparison per character.
103
+ */
104
+ export function scanCommand(command: string): ScannedCommand {
105
+ const text = command.length > MAX_SCAN_CHARS ? command.slice(0, MAX_SCAN_CHARS) : command;
106
+ const segments: string[][] = [];
107
+ let tokens: string[] = [];
108
+ let word = "";
109
+ let inWord = false;
110
+ let quote: "'" | '"' | null = null;
111
+ let out = "";
112
+ let commentsRemoved = false;
113
+ const comments: string[] = [];
114
+ let complete = command.length <= MAX_SCAN_CHARS;
115
+ // Per-word, unquoted: an open `{` not yet closed, whether a `,` or `..`
116
+ // followed it, and an open `[`. Enough to spot brace expansion and globs.
117
+ let braceDepth = 0;
118
+ let braceSep = false;
119
+ let bracketOpen = false;
120
+
121
+ const endWord = () => {
122
+ if (inWord) tokens.push(word);
123
+ word = "";
124
+ inWord = false;
125
+ braceDepth = 0;
126
+ braceSep = false;
127
+ bracketOpen = false;
128
+ };
129
+ const endSegment = () => {
130
+ endWord();
131
+ if (tokens.length > 0) {
132
+ if (complete && runsNestedShell(tokens)) complete = false;
133
+ segments.push(tokens);
134
+ }
135
+ tokens = [];
136
+ };
137
+
138
+ for (let i = 0; i < text.length; i++) {
139
+ const c = text[i];
140
+ if (quote) {
141
+ out += c;
142
+ // Inside "…", bash still expands `$NAME`, `$(…)`, `${…}` and backticks,
143
+ // and a backslash-newline is a continuation: none of that is followed here.
144
+ if (quote === '"' && (c === "`" || (c === "$" && EXPANSION_START.test(text[i + 1] ?? "")) || (c === "\\" && text[i + 1] === "\n"))) {
145
+ complete = false;
146
+ }
147
+ if (c === quote) {
148
+ quote = null;
149
+ } else if (c === "\\" && quote === '"' && i + 1 < text.length) {
150
+ word += text[++i];
151
+ out += text[i];
152
+ } else {
153
+ word += c;
154
+ }
155
+ continue;
156
+ }
157
+ // Unquoted constructs whose contents the scan does not parse as bash does.
158
+ if (
159
+ c === "`" ||
160
+ (c === "$" && (text[i + 1] === "'" || text[i + 1] === '"' || EXPANSION_START.test(text[i + 1] ?? ""))) ||
161
+ ((c === "<" || c === ">") && text[i + 1] === "(") ||
162
+ (c === "<" && text[i + 1] === "<") ||
163
+ (c === "\\" && text[i + 1] === "\n")
164
+ ) {
165
+ complete = false;
166
+ }
167
+ if (c === "'" || c === '"') {
168
+ quote = c;
169
+ inWord = true;
170
+ out += c;
171
+ continue;
172
+ }
173
+ if (c === "\\" && i + 1 < text.length) {
174
+ word += text[i + 1];
175
+ inWord = true;
176
+ out += c + text[++i];
177
+ continue;
178
+ }
179
+ if (c === "#" && !inWord) {
180
+ // A comment runs to end of line. Classic place to hide "approved by
181
+ // security" in a command that is about to be judged by a language model.
182
+ const nl = text.indexOf("\n", i);
183
+ commentsRemoved = true;
184
+ comments.push(text.slice(i, nl === -1 ? text.length : nl));
185
+ if (nl === -1) break;
186
+ i = nl - 1;
187
+ continue;
188
+ }
189
+ if (c === "\n" || c === ";") {
190
+ endSegment();
191
+ out += c;
192
+ continue;
193
+ }
194
+ if (c === "&" || c === "|") {
195
+ endSegment();
196
+ out += c;
197
+ if (text[i + 1] === c) out += text[++i];
198
+ continue;
199
+ }
200
+ if (c === " " || c === "\t") {
201
+ endWord();
202
+ out += c;
203
+ continue;
204
+ }
205
+ // Brace expansion and globs, unquoted: bash turns `{build,/critical}` and
206
+ // `/crit*` into words this scan never sees. A `{` or `}` word on its own
207
+ // (`{ ls; }`, `-exec rm {} \;`) and `{}` are not expansions.
208
+ if (c === "{") {
209
+ braceDepth++;
210
+ } else if (braceDepth > 0 && (c === "," || (c === "." && text[i + 1] === "."))) {
211
+ braceSep = true;
212
+ } else if (c === "}" && braceDepth > 0) {
213
+ braceDepth--;
214
+ if (braceSep) complete = false;
215
+ } else if (c === "*" || c === "?") {
216
+ complete = false;
217
+ } else if (c === "[") {
218
+ bracketOpen = true;
219
+ } else if (c === "]" && bracketOpen) {
220
+ complete = false;
221
+ }
222
+ word += c;
223
+ inWord = true;
224
+ out += c;
225
+ }
226
+ endSegment();
227
+ if (quote) complete = false;
228
+ return { segments, withoutComments: out.trimEnd(), commentsRemoved, comments, complete };
229
+ }
230
+
231
+ const PATH_LIKE = /^(?:\/|~|\.\.?(?:\/|$)|[^:]*\/)/;
232
+ const GLOB_CHARS = /[*?[]/;
233
+
234
+ function expandHome(token: string, home: string): string {
235
+ if (token === "~") return home;
236
+ if (token.startsWith("~/")) return home + token.slice(1);
237
+ if (token.startsWith("$HOME/")) return home + token.slice(5);
238
+ if (token === "$HOME") return home;
239
+ return token;
240
+ }
241
+
242
+ function relationOf(resolved: string, projectRoot: string | null, home: string): PathFact["relation"] {
243
+ if (resolved === "/") return "root";
244
+ if (projectRoot) {
245
+ if (resolved === projectRoot) return "project_root";
246
+ if (resolved.startsWith(projectRoot + "/")) return "inside_project";
247
+ }
248
+ if (resolved === home) return "home_root";
249
+ if (resolved.startsWith(home + "/")) return "outside_project_in_home";
250
+ return "system";
251
+ }
252
+
253
+ function pathFact(token: string, base: string, projectRoot: string | null, home: string): PathFact | null {
254
+ if (token.includes("://")) return null;
255
+ let t = expandHome(token, home);
256
+ // A glob names the contents of its directory: `*` after `cd /` is the root.
257
+ if (GLOB_CHARS.test(t)) {
258
+ const slash = t.lastIndexOf("/");
259
+ t = slash === -1 ? "." : slash === 0 ? "/" : t.slice(0, slash);
260
+ }
261
+ const resolved = isAbsolute(t) ? resolve(t) : resolve(base, t);
262
+ return { asWritten: token, resolved, relation: relationOf(resolved, projectRoot, home) };
263
+ }
264
+
265
+ const MAX_PATHS = 12;
266
+
267
+ /** Paths a tool call touches, resolved against the cwd and any `cd` along the way. */
268
+ export function extractPaths(
269
+ toolInput: Record<string, unknown>,
270
+ cwd: string | null,
271
+ projectRoot: string | null,
272
+ scanned: ScannedCommand | null,
273
+ home: string = homedir(),
274
+ ): PathFact[] {
275
+ const base0 = cwd ?? home;
276
+ const facts: PathFact[] = [];
277
+ const seen = new Set<string>();
278
+ const add = (f: PathFact | null) => {
279
+ if (!f || seen.has(f.resolved + "\0" + f.asWritten) || facts.length >= MAX_PATHS) return;
280
+ seen.add(f.resolved + "\0" + f.asWritten);
281
+ facts.push(f);
282
+ };
283
+
284
+ for (const key of ["file_path", "path", "notebook_path"]) {
285
+ const v = toolInput[key];
286
+ if (typeof v === "string" && v.length > 0) add(pathFact(v, base0, projectRoot, home));
287
+ }
288
+
289
+ if (scanned) {
290
+ let base = base0;
291
+ for (const seg of scanned.segments) {
292
+ if (seg[0] === "cd") {
293
+ // A `cd` does two things and only one of them used to be recorded. Its
294
+ // target rebases every relative path after it — that is the `base`
295
+ // assignment, unchanged — but it is also a directory the call names in
296
+ // its own right. Consuming it silently left `facts.paths` empty on
297
+ // `cd ../other-repo && ./node_modules/.bin/tsc`, while the regex
298
+ // partner reads the same text, resolves the target against the session
299
+ // cwd and denies it. A deny whose paired question was never asked can
300
+ // never clear, so the target is emitted as a path too.
301
+ const written = seg[1];
302
+ const f = pathFact(written ?? "~", base, projectRoot, home);
303
+ if (!f) continue;
304
+ base = f.resolved;
305
+ // Only when the agent wrote a target. A bare `cd` (or `cd -`) leaves
306
+ // the partner no token to deny, so there is no verdict to pair with,
307
+ // and naming a directory nobody wrote would ask about it for nothing.
308
+ if (written !== undefined && !written.startsWith("-")) add(f);
309
+ continue;
310
+ }
311
+ // Skip argv[0]: `/usr/local/bin/kubectl` is the program, not its target.
312
+ for (const tok of seg.slice(1)) {
313
+ if (tok.startsWith("-")) continue;
314
+ if (tok === "*" || tok === "." || tok === ".." || PATH_LIKE.test(tok) || tok.startsWith("$HOME")) {
315
+ add(pathFact(tok, base, projectRoot, home));
316
+ }
317
+ }
318
+ }
319
+ }
320
+ return facts;
321
+ }
322
+
323
+ function findGitDir(start: string): string | null {
324
+ let dir = start;
325
+ for (let i = 0; i < 40; i++) {
326
+ const candidate = resolve(dir, ".git");
327
+ if (existsSync(candidate)) return candidate;
328
+ const parent = dirname(dir);
329
+ if (parent === dir) return null;
330
+ dir = parent;
331
+ }
332
+ return null;
333
+ }
334
+
335
+ export function findProjectRoot(cwd: string | null): string | null {
336
+ if (!cwd) return null;
337
+ const gitDir = findGitDir(cwd);
338
+ return gitDir ? dirname(gitDir) : cwd;
339
+ }
340
+
341
+ /** Current branch from `.git/HEAD`, following a worktree's `gitdir:` pointer. No subprocess. */
342
+ export function readCurrentBranch(cwd: string | null): string | null {
343
+ if (!cwd) return null;
344
+ try {
345
+ const gitPath = findGitDir(cwd);
346
+ if (!gitPath) return null;
347
+ let headFile = resolve(gitPath, "HEAD");
348
+ if (statSync(gitPath).isFile()) {
349
+ const pointer = readFileSync(gitPath, "utf8").trim();
350
+ const m = /^gitdir:\s*(.+)$/.exec(pointer);
351
+ if (!m) return null;
352
+ headFile = resolve(dirname(gitPath), m[1], "HEAD");
353
+ }
354
+ const head = readFileSync(headFile, "utf8").trim();
355
+ const ref = /^ref:\s*refs\/heads\/(.+)$/.exec(head);
356
+ return ref ? ref[1] : null;
357
+ } catch {
358
+ return null;
359
+ }
360
+ }
361
+
362
+ export function computeFacts(
363
+ toolName: string,
364
+ toolInput: Record<string, unknown>,
365
+ cwd: string | null,
366
+ permissionMode: string | null,
367
+ scanned: ScannedCommand | null,
368
+ /**
369
+ * The session's pinned root (`session-root.ts`). The live `cwd` drifts with
370
+ * every `cd`; the project the human opened does not. Omitted by replays and
371
+ * `jev test`, which have no session and keep the old derivation.
372
+ */
373
+ pinnedProjectRoot: string | null = null,
374
+ ): Facts {
375
+ const { toolClass, toolIsKnown } = classifyTool(toolName);
376
+ const projectRoot = pinnedProjectRoot ?? findProjectRoot(cwd);
377
+ return {
378
+ toolName,
379
+ toolClass,
380
+ toolIsKnown,
381
+ cwd,
382
+ projectRoot,
383
+ currentGitBranch: readCurrentBranch(cwd),
384
+ paths: extractPaths(toolInput, cwd, projectRoot, scanned),
385
+ permissionMode,
386
+ };
387
+ }