failproofai 1.0.7-beta.1 → 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.
- package/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/build-manifest.json +3 -3
- package/.next/standalone/.next/prerender-manifest.json +3 -3
- package/.next/standalone/.next/required-server-files.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_global-error.html +1 -1
- package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
- package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +6 -6
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
- package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +1 -1
- package/.next/standalone/.next/server/app/_not-found.rsc +15 -15
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +15 -15
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +14 -14
- package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/audit/status/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
- package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/index.html +1 -1
- package/.next/standalone/.next/server/app/index.rsc +15 -15
- package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +14 -14
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
- package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +14 -14
- package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +7 -7
- package/.next/standalone/.next/server/app/settings/page.js +2 -2
- package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0l3yhx4._.js +2 -2
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o07qi9._.js +1 -1
- package/.next/standalone/.next/server/chunks/_0tovk6q._.js +1 -1
- package/.next/standalone/.next/server/chunks/_0trp3yc._.js +1 -1
- package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_09z9-p7._.js +1 -1
- package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
- package/.next/standalone/.next/server/chunks/src_hooks_18qtd42._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__04usis8._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__056wjo4._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0yxwl6j._.js → [root-of-the-server]__0l44ual._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0n0xg95._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0rwtwpm._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0s_yomn._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__11mayhe._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1pprgri._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1q4p5b8._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_042cgl1._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_08x1r5t._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_0bqoto4._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{_214wgrp._.js → _1mel6y1._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{_0bn2oo8._.js → _1v-jvrv._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_1zopuov._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_next-internal_server_app_policies_page_actions_1sp2-yo.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/app_actions_get-scheduled-audit_ts_0ei9sni._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_settings_02tf1h4._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_15t8kqj._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_1fm2w5z._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_1j0zy3v._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_builtin-policies_ts_09j2ndl._.js +1 -1
- package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
- package/.next/standalone/.next/server/pages/404.html +1 -1
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +22 -22
- package/.next/standalone/.next/static/chunks/043j99m8ykg__.css +2 -0
- package/.next/standalone/.next/static/chunks/0fqd7m_u81mi5.js +1 -0
- package/.next/standalone/.next/static/chunks/129ag2bw93bdh.js +1 -0
- package/.next/standalone/.next/static/chunks/{29fql3nbnfc9q.js → 1qd741hzlmjbo.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0vmd180qfntfb.js → 2_pltstd8-xgs.js} +1 -1
- package/.next/standalone/.next/static/chunks/{1u5zsejmgrir_.js → 2c8j9l6j_b1ci.js} +1 -1
- package/.next/standalone/.next/static/chunks/3-k569wzcli8q.js +1 -0
- package/.next/standalone/.next/static/chunks/{258668t68du6b.js → 3brze37td_wnc.js} +1 -1
- package/.next/standalone/.next/static/chunks/3otmypm6j_xfo.js +6 -0
- package/.next/standalone/.next/static/chunks/{12tvm75t5ffui.js → 3ugmd_7dyn0id.js} +1 -1
- package/.next/standalone/.next/static/chunks/3yxro_r2_o9ad.js +69 -0
- package/.next/standalone/PROBE-FOLLOWUP.md +186 -0
- package/.next/standalone/app/actions/get-jev-config.ts +38 -23
- package/.next/standalone/app/actions/update-jev-config.ts +1 -1
- package/.next/standalone/app/settings/jev-panel.tsx +33 -29
- package/.next/standalone/package.json +10 -10
- package/.next/standalone/sdk/python/skill/SKILL.md +60 -14
- package/.next/standalone/sdk/python/skill/agents/openai.yaml +2 -1
- package/.next/standalone/sdk/python/skill/references/evaluator.md +255 -0
- package/.next/standalone/sdk/python/skill/references/events.md +17 -8
- package/.next/standalone/sdk/python/skill/references/frameworks.md +3 -0
- package/.next/standalone/sdk/python/skill/references/install.md +3 -0
- package/.next/standalone/sdk/python/skill/references/integration.md +6 -2
- package/.next/standalone/sdk/python/skill/references/typescript.md +568 -0
- package/.next/standalone/sdk/typescript/CHANGELOG.md +119 -0
- package/.next/standalone/sdk/typescript/LICENSE +42 -0
- package/.next/standalone/sdk/typescript/README.md +552 -0
- package/.next/standalone/sdk/typescript/eslint.config.mjs +59 -0
- package/.next/standalone/sdk/typescript/examples/research-agent.ts +197 -0
- package/.next/standalone/sdk/typescript/integration/ai.test.ts +920 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/agent.ts +337 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/package-lock.json +281 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/package.json +13 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/surfaces.ts +605 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-4/tsconfig.surfaces.json +4 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/agent.ts +342 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/package-lock.json +168 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/package.json +13 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/surfaces.ts +628 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-5/tsconfig.surfaces.json +4 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-6/agent.ts +346 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-6/package-lock.json +156 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-6/package.json +13 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-6/surfaces.ts +651 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-6/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-6/tsconfig.surfaces.json +4 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-7/agent.ts +350 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-7/package-lock.json +153 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-7/package.json +13 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-7/surfaces.ts +651 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-7/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/ai-7/tsconfig.surfaces.json +4 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-0.3/agent.ts +623 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-0.3/package-lock.json +463 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-0.3/package.json +15 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-0.3/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-1/agent-v1.ts +99 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-1/agent.ts +623 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-1/package-lock.json +336 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-1/package.json +15 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-1/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/agent.ts +96 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/package-lock.json +579 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/package.json +15 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/vendor/lc-weather-provider/index.cjs +53 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/vendor/lc-weather-provider/index.mjs +55 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/langchain-dup-core/vendor/lc-weather-provider/package.json +18 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.11/agent.ts +659 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.11/package-lock.json +635 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.11/package.json +15 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.11/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.12/agent.ts +659 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.12/package-lock.json +553 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.12/package.json +15 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/llamaindex-0.12/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-0/agent.ts +877 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-0/mcp-server.mjs +66 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-0/package-lock.json +6417 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-0/package.json +15 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-0/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-1/agent.ts +872 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-1/mcp-server.mjs +66 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-1/package-lock.json +2540 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-1/package.json +15 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/mastra-1/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/actions.ts +18 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/api/ai/route.ts +42 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/api/edge/route.ts +29 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/api/langgraph/route.ts +21 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/api/llamaindex/route.ts +11 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/api/mastra/route.ts +19 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/api/status/route.ts +7 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/layout.tsx +9 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/app/page.tsx +15 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/instrumentation.ts +15 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/lib/ai.ts +61 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/lib/langgraph.ts +68 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/lib/llamaindex.ts +98 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/lib/mastra.ts +90 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/next.config.ts +52 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/package-lock.json +4343 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/nextjs/package.json +28 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/runtimes/agent.ts +51 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/runtimes/deno-npm.ts +76 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/runtimes/package-lock.json +484 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/runtimes/package.json +15 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/types/agent.ts +79 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/types/package-lock.json +740 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/types/package.json +11 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/vanilla/agent.ts +197 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/vanilla/package-lock.json +70 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/vanilla/package.json +12 -0
- package/.next/standalone/sdk/typescript/integration/fixtures/vanilla/tsconfig.json +12 -0
- package/.next/standalone/sdk/typescript/integration/global-setup.ts +29 -0
- package/.next/standalone/sdk/typescript/integration/harness.ts +451 -0
- package/.next/standalone/sdk/typescript/integration/langchain.test.ts +682 -0
- package/.next/standalone/sdk/typescript/integration/llamaindex.test.ts +709 -0
- package/.next/standalone/sdk/typescript/integration/mastra-coverage.test.ts +386 -0
- package/.next/standalone/sdk/typescript/integration/mastra.test.ts +311 -0
- package/.next/standalone/sdk/typescript/integration/nextjs.test.ts +341 -0
- package/.next/standalone/sdk/typescript/integration/runtime-parity.ts +180 -0
- package/.next/standalone/sdk/typescript/integration/runtimes.bun.test.ts +15 -0
- package/.next/standalone/sdk/typescript/integration/runtimes.core.test.ts +113 -0
- package/.next/standalone/sdk/typescript/integration/runtimes.deno.test.ts +19 -0
- package/.next/standalone/sdk/typescript/integration/types.test.ts +141 -0
- package/.next/standalone/sdk/typescript/integration/vanilla.test.ts +255 -0
- package/.next/standalone/sdk/typescript/package-lock.json +2640 -0
- package/.next/standalone/sdk/typescript/package.json +401 -0
- package/.next/standalone/sdk/typescript/scripts/finalize-build.mjs +123 -0
- package/.next/standalone/sdk/typescript/scripts/release.mjs +177 -0
- package/.next/standalone/sdk/typescript/src/clock.ts +58 -0
- package/.next/standalone/sdk/typescript/src/context.ts +214 -0
- package/.next/standalone/sdk/typescript/src/edge/adapter.ts +18 -0
- package/.next/standalone/sdk/typescript/src/edge/ai.ts +116 -0
- package/.next/standalone/sdk/typescript/src/edge/index.ts +238 -0
- package/.next/standalone/sdk/typescript/src/edge/langchain.ts +18 -0
- package/.next/standalone/sdk/typescript/src/edge/llamaindex.ts +12 -0
- package/.next/standalone/sdk/typescript/src/edge/mastra.ts +17 -0
- package/.next/standalone/sdk/typescript/src/edge/notice.ts +33 -0
- package/.next/standalone/sdk/typescript/src/environment.ts +75 -0
- package/.next/standalone/sdk/typescript/src/evaluator/authoring.ts +480 -0
- package/.next/standalone/sdk/typescript/src/evaluator/cli.ts +96 -0
- package/.next/standalone/sdk/typescript/src/evaluator/client.ts +421 -0
- package/.next/standalone/sdk/typescript/src/evaluator/expression.ts +1292 -0
- package/.next/standalone/sdk/typescript/src/evaluator/index.ts +144 -0
- package/.next/standalone/sdk/typescript/src/evaluator/protocol.ts +747 -0
- package/.next/standalone/sdk/typescript/src/evaluator/runtime.ts +930 -0
- package/.next/standalone/sdk/typescript/src/evaluator/sandbox-worker.ts +171 -0
- package/.next/standalone/sdk/typescript/src/evaluator/source-limits.ts +27 -0
- package/.next/standalone/sdk/typescript/src/evaluator/source.ts +509 -0
- package/.next/standalone/sdk/typescript/src/events.ts +879 -0
- package/.next/standalone/sdk/typescript/src/exit.ts +117 -0
- package/.next/standalone/sdk/typescript/src/index.ts +186 -0
- package/.next/standalone/sdk/typescript/src/integrations/ai.ts +1566 -0
- package/.next/standalone/sdk/typescript/src/integrations/compat.ts +322 -0
- package/.next/standalone/sdk/typescript/src/integrations/core.ts +1321 -0
- package/.next/standalone/sdk/typescript/src/integrations/index.ts +355 -0
- package/.next/standalone/sdk/typescript/src/integrations/langchain.ts +2340 -0
- package/.next/standalone/sdk/typescript/src/integrations/llamaindex.ts +2111 -0
- package/.next/standalone/sdk/typescript/src/integrations/mastra.ts +1802 -0
- package/.next/standalone/sdk/typescript/src/logger.ts +98 -0
- package/.next/standalone/sdk/typescript/src/next.ts +115 -0
- package/.next/standalone/sdk/typescript/src/node-require.ts +446 -0
- package/.next/standalone/sdk/typescript/src/redact.ts +305 -0
- package/.next/standalone/sdk/typescript/src/resolver.ts +120 -0
- package/.next/standalone/sdk/typescript/src/runtime.ts +29 -0
- package/.next/standalone/sdk/typescript/src/schema.ts +410 -0
- package/.next/standalone/sdk/typescript/src/scopes.ts +701 -0
- package/.next/standalone/sdk/typescript/src/shared.ts +33 -0
- package/.next/standalone/sdk/typescript/src/version.ts +5 -0
- package/.next/standalone/sdk/typescript/src/writer.ts +934 -0
- package/.next/standalone/sdk/typescript/test/adapters.test.ts +397 -0
- package/.next/standalone/sdk/typescript/test/ai.test.ts +1076 -0
- package/.next/standalone/sdk/typescript/test/copies.test.ts +204 -0
- package/.next/standalone/sdk/typescript/test/edge.test.ts +183 -0
- package/.next/standalone/sdk/typescript/test/evaluator-client.test.ts +234 -0
- package/.next/standalone/sdk/typescript/test/evaluator-protocol.test.ts +225 -0
- package/.next/standalone/sdk/typescript/test/events.test.ts +193 -0
- package/.next/standalone/sdk/typescript/test/expression.test.ts +181 -0
- package/.next/standalone/sdk/typescript/test/global-setup.ts +26 -0
- package/.next/standalone/sdk/typescript/test/helpers.ts +130 -0
- package/.next/standalone/sdk/typescript/test/integrations.test.ts +369 -0
- package/.next/standalone/sdk/typescript/test/langchain-copies.test.ts +204 -0
- package/.next/standalone/sdk/typescript/test/langchain.test.ts +999 -0
- package/.next/standalone/sdk/typescript/test/llamaindex.test.ts +1760 -0
- package/.next/standalone/sdk/typescript/test/mastra-coverage.test.ts +501 -0
- package/.next/standalone/sdk/typescript/test/mastra-lifecycle.test.ts +479 -0
- package/.next/standalone/sdk/typescript/test/mastra.test.ts +285 -0
- package/.next/standalone/sdk/typescript/test/next.test.ts +109 -0
- package/.next/standalone/sdk/typescript/test/packaging.test.ts +312 -0
- package/.next/standalone/sdk/typescript/test/redaction.test.ts +171 -0
- package/.next/standalone/sdk/typescript/test/runtimes.test.ts +101 -0
- package/.next/standalone/sdk/typescript/test/sandbox.test.ts +189 -0
- package/.next/standalone/sdk/typescript/test/scopes.test.ts +271 -0
- package/.next/standalone/sdk/typescript/test/setup.ts +19 -0
- package/.next/standalone/sdk/typescript/test/skill-snippets.test.ts +73 -0
- package/.next/standalone/sdk/typescript/test/spool-contract.test.ts +124 -0
- package/.next/standalone/sdk/typescript/test/tracker-bounds.test.ts +191 -0
- package/.next/standalone/sdk/typescript/test/wire-format.test.ts +214 -0
- package/.next/standalone/sdk/typescript/test/writer.test.ts +407 -0
- package/.next/standalone/sdk/typescript/tsconfig.build.json +15 -0
- package/.next/standalone/sdk/typescript/tsconfig.cjs.json +19 -0
- package/.next/standalone/sdk/typescript/tsconfig.json +28 -0
- package/.next/standalone/sdk/typescript/vitest.config.ts +33 -0
- package/.next/standalone/sdk/typescript/vitest.integration.config.ts +23 -0
- package/.next/standalone/server.js +1 -1
- package/README.md +2 -2
- package/dist/cli.mjs +208 -27
- package/dist/worker.mjs +120 -14
- package/package.json +10 -10
- package/scripts/build-policy-pack.mjs +14 -0
- package/src/audit/features.ts +3 -2
- package/src/hooks/builtin-policies.ts +156 -5
- package/src/hooks/jev-cli.ts +57 -1
- package/src/hooks/manager.ts +1 -1
- package/src/hooks/pack-cli.ts +150 -18
- package/src/hooks/pack-store.ts +1 -1
- package/src/hooks/policy-catalog.ts +148 -9
- package/src/hooks/types.ts +1 -1
- package/.next/standalone/.next/static/chunks/0cd-_8-c-m1ea.js +0 -6
- package/.next/standalone/.next/static/chunks/0qrbdkv9qmvli.js +0 -69
- package/.next/standalone/.next/static/chunks/0uldbut9y2-e8.js +0 -1
- package/.next/standalone/.next/static/chunks/285spx855h_3r.css +0 -2
- package/.next/standalone/.next/static/chunks/2vkvu9-opa_1z.js +0 -1
- package/.next/standalone/.next/static/chunks/37lhv7wa3ywt6.js +0 -1
- /package/.next/standalone/.next/static/{T8YAYM9h_64fKv705vug7 → gbEOjBgZAxF2UIUwZVHNu}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{T8YAYM9h_64fKv705vug7 → gbEOjBgZAxF2UIUwZVHNu}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{T8YAYM9h_64fKv705vug7 → gbEOjBgZAxF2UIUwZVHNu}/_ssgManifest.js +0 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "failproofai",
|
|
3
|
-
"version": "1.0.7-beta.
|
|
4
|
-
"description": "Observability and enforcement for AI agent harnesses.
|
|
3
|
+
"version": "1.0.7-beta.2",
|
|
4
|
+
"description": "Observability and enforcement for AI agent harnesses. 40 built-in policies hooked into 12 of them — Claude Code, Codex, Cursor, Hermes, OpenClaw and more — blocking the tool call before it runs. Local dashboard included, no account needed.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"failproofai": "./dist/cli.mjs",
|
|
7
7
|
"failproofaid": "./bin/failproofaid-shim.mjs"
|
|
@@ -122,15 +122,15 @@
|
|
|
122
122
|
"browserslist": "4.28.8"
|
|
123
123
|
},
|
|
124
124
|
"optionalDependencies": {
|
|
125
|
-
"@failproofai/failproofaid-linux-x64": "1.0.7-beta.
|
|
126
|
-
"@failproofai/failproofaid-linux-arm64": "1.0.7-beta.
|
|
127
|
-
"@failproofai/failproofaid-darwin-x64": "1.0.7-beta.
|
|
128
|
-
"@failproofai/failproofaid-darwin-arm64": "1.0.7-beta.
|
|
125
|
+
"@failproofai/failproofaid-linux-x64": "1.0.7-beta.2",
|
|
126
|
+
"@failproofai/failproofaid-linux-arm64": "1.0.7-beta.2",
|
|
127
|
+
"@failproofai/failproofaid-darwin-x64": "1.0.7-beta.2",
|
|
128
|
+
"@failproofai/failproofaid-darwin-arm64": "1.0.7-beta.2"
|
|
129
129
|
},
|
|
130
130
|
"failproofaidBinaries": {
|
|
131
|
-
"linux-x64": "
|
|
132
|
-
"linux-arm64": "
|
|
133
|
-
"darwin-x64": "
|
|
134
|
-
"darwin-arm64": "
|
|
131
|
+
"linux-x64": "5362ab6a4cfb23d1eee598aac67aedd9e43351e62724ee1c6b40c4fc8021c08f",
|
|
132
|
+
"linux-arm64": "f14a2548b41e14ad32b7fdd03a27ffe7160da1046e422e1f651099371b0d27e5",
|
|
133
|
+
"darwin-x64": "14189cade04f17cf5278bd8061a5ec0c2a2381aa21944ae0d05e8c35b98c2816",
|
|
134
|
+
"darwin-arm64": "4ba9f5c321894d953407efa3404f0deec07dccfd7db7bc2511bb35226816b583"
|
|
135
135
|
}
|
|
136
136
|
}
|
|
@@ -114,6 +114,20 @@ for (const policy of BUILTIN_POLICIES) {
|
|
|
114
114
|
defaultEnabled: policy.defaultEnabled === true,
|
|
115
115
|
match: policy.match,
|
|
116
116
|
fn: policy.fn,
|
|
117
|
+
// The parameter schema. It has to be registered here as well as written
|
|
118
|
+
// into the manifest this script builds, because there are TWO manifest
|
|
119
|
+
// producers for this pack and they have to agree: this script builds one
|
|
120
|
+
// from POLICY_CATALOG, and the publish command rebuilds one by importing
|
|
121
|
+
// the entry and reading back what it registered. A field the entry does
|
|
122
|
+
// not register is a field the second producer cannot know about.
|
|
123
|
+
//
|
|
124
|
+
// params is the one that fails silently STRICTER. Registration reads a
|
|
125
|
+
// pack policy's schema from the manifest, so an absent schema means the
|
|
126
|
+
// policy sees empty params: block-sudo's allowPatterns, and block-rm-rf's
|
|
127
|
+
// and block-read-outside-cwd's allowPaths, stop applying -- taking the
|
|
128
|
+
// user's own configured values with them. No backticks in this comment:
|
|
129
|
+
// see the note above entrySource.
|
|
130
|
+
...(policy.params !== undefined ? { params: policy.params } : {}),
|
|
117
131
|
// Whether Jev may clear it; see the note on authority at the top.
|
|
118
132
|
...(policy.authority !== undefined ? { authority: policy.authority } : {}),
|
|
119
133
|
...(policy.reviewedBy !== undefined ? { reviewedBy: policy.reviewedBy } : {}),
|
package/src/audit/features.ts
CHANGED
|
@@ -69,13 +69,13 @@ export const ARCHITECT_CAUTION_SIGNALS = new Set(["reread-after-edit", "redundan
|
|
|
69
69
|
|
|
70
70
|
/**
|
|
71
71
|
* Mapping from policy/detector short-name → which archetype its hits feed,
|
|
72
|
-
* and how heavily (intensity within the cluster). Every one of the
|
|
72
|
+
* and how heavily (intensity within the cluster). Every one of the 40 builtin
|
|
73
73
|
* policies and 8 audit-only detectors maps exactly once — no overlaps, full
|
|
74
74
|
* coverage. Weights express *severity within* a persona; cross-persona
|
|
75
75
|
* fairness is handled later by lift normalisation, not by these numbers.
|
|
76
76
|
*/
|
|
77
77
|
export const SIGNAL_MAP: Record<string, { archetype: ArchetypeKey; weight: number }> = {
|
|
78
|
-
// ── cowboy ── destructive / forceful / bypasses guardrails (
|
|
78
|
+
// ── cowboy ── destructive / forceful / bypasses guardrails (21) ───────────
|
|
79
79
|
"block-rm-rf": { archetype: "cowboy", weight: 2.0 },
|
|
80
80
|
"block-failproofai-commands":{ archetype: "cowboy", weight: 2.0 },
|
|
81
81
|
"block-sudo": { archetype: "cowboy", weight: 1.5 },
|
|
@@ -88,6 +88,7 @@ export const SIGNAL_MAP: Record<string, { archetype: ArchetypeKey; weight: numbe
|
|
|
88
88
|
"git-commit-no-verify": { archetype: "cowboy", weight: 1.5 },
|
|
89
89
|
"warn-git-amend": { archetype: "cowboy", weight: 0.8 },
|
|
90
90
|
"warn-git-stash-drop": { archetype: "cowboy", weight: 1.0 },
|
|
91
|
+
"warn-git-clean": { archetype: "cowboy", weight: 1.0 },
|
|
91
92
|
"warn-all-files-staged": { archetype: "cowboy", weight: 0.6 },
|
|
92
93
|
"block-kubectl": { archetype: "cowboy", weight: 1.5 },
|
|
93
94
|
"block-terraform": { archetype: "cowboy", weight: 1.5 },
|
|
@@ -623,8 +623,15 @@ const GIT_DESTRUCTIVE_SUBCOMMANDS = new Set([
|
|
|
623
623
|
*/
|
|
624
624
|
const GIT_FLAGS_WITH_OPERANDS = new Set(["-C", "-c", "--git-dir", "--work-tree", "--namespace", "--exec-path"]);
|
|
625
625
|
|
|
626
|
-
/**
|
|
627
|
-
|
|
626
|
+
/**
|
|
627
|
+
* Where the `git` subcommand sits in `args`, with git's own global options
|
|
628
|
+
* walked off first, or `-1` when there is no subcommand at all.
|
|
629
|
+
*
|
|
630
|
+
* The index rather than the value, because a caller that wants to read the
|
|
631
|
+
* SUBCOMMAND's flags (`warnGitClean`) needs to know where they start, and
|
|
632
|
+
* `args.indexOf("clean")` would land on a `-C clean` operand instead.
|
|
633
|
+
*/
|
|
634
|
+
function gitSubcommandIndex(args: string[]): number {
|
|
628
635
|
for (let i = 0; i < args.length; i++) {
|
|
629
636
|
const arg = args[i];
|
|
630
637
|
if (GIT_FLAGS_WITH_OPERANDS.has(arg)) {
|
|
@@ -632,9 +639,15 @@ function gitSubcommand(args: string[]): string | undefined {
|
|
|
632
639
|
continue;
|
|
633
640
|
}
|
|
634
641
|
if (arg.startsWith("-")) continue;
|
|
635
|
-
return
|
|
642
|
+
return i;
|
|
636
643
|
}
|
|
637
|
-
return
|
|
644
|
+
return -1;
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
/** The `git` subcommand, with git's own global options walked off first. */
|
|
648
|
+
function gitSubcommand(args: string[]): string | undefined {
|
|
649
|
+
const i = gitSubcommandIndex(args);
|
|
650
|
+
return i < 0 ? undefined : args[i];
|
|
638
651
|
}
|
|
639
652
|
|
|
640
653
|
/**
|
|
@@ -1379,6 +1392,48 @@ const GIT_AMEND_RE = /\bgit\s+commit\b.*--amend\b/;
|
|
|
1379
1392
|
// warnGitStashDrop
|
|
1380
1393
|
const GIT_STASH_DROP_RE = /\bgit\s+stash\s+(?:drop|clear)\b/;
|
|
1381
1394
|
|
|
1395
|
+
// warnGitClean
|
|
1396
|
+
/**
|
|
1397
|
+
* `git`, however the command line spells it. Same shape as {@link RM_CMD_RE}:
|
|
1398
|
+
* an absolute path to the binary does not change what it does.
|
|
1399
|
+
*/
|
|
1400
|
+
const GIT_CMD_RE = /^(?:\/\S*\/)?git$/;
|
|
1401
|
+
|
|
1402
|
+
/** A short-flag cluster: `-f`, `-fdx`, `-xdf`. */
|
|
1403
|
+
const SHORT_FLAG_CLUSTER_RE = /^-[A-Za-z]+$/;
|
|
1404
|
+
|
|
1405
|
+
/**
|
|
1406
|
+
* `clean.requireForce=false`, the config that makes `git clean` delete with no
|
|
1407
|
+
* `-f` at all — and settable per invocation as `git -c
|
|
1408
|
+
* clean.requireForce=false clean -xd`. Reading the subcommand's flags alone
|
|
1409
|
+
* would call that "no force, no warning" on the one spelling that needs none.
|
|
1410
|
+
*/
|
|
1411
|
+
const GIT_CLEAN_FORCE_WAIVED_RE = /^clean\.requireforce=(?:false|0|no|off)$/i;
|
|
1412
|
+
|
|
1413
|
+
/**
|
|
1414
|
+
* The default `destructiveFlags`, and why the condition is these three letters
|
|
1415
|
+
* rather than "any `git clean`".
|
|
1416
|
+
*
|
|
1417
|
+
* `git clean` deletes nothing without `-f` / `--force` (or the config above),
|
|
1418
|
+
* and `-n` / `--dry-run` only prints — so force is the precondition and
|
|
1419
|
+
* dry-run is the exemption. What force ALONE removes is untracked files in the
|
|
1420
|
+
* current directory: the narrowest spelling, and the one people mean when they
|
|
1421
|
+
* tidy up. These are the letters that widen the blast radius past that:
|
|
1422
|
+
*
|
|
1423
|
+
* - `-x` also removes IGNORED files — `.env`, local config, editor state,
|
|
1424
|
+
* scratch work. That is the data that genuinely cannot be rebuilt by running
|
|
1425
|
+
* a command, and it is what makes `git clean -fdx` the severe spelling.
|
|
1426
|
+
* - `-X` removes ONLY ignored files: the same loss, tracked tree untouched.
|
|
1427
|
+
* - `-d` also removes untracked DIRECTORIES — whole new subtrees git has never
|
|
1428
|
+
* had a copy of.
|
|
1429
|
+
*
|
|
1430
|
+
* A bare `git clean -f` is deliberately absent. It has the smallest radius and
|
|
1431
|
+
* by far the most traffic, and a guard that fires on the ordinary spelling is
|
|
1432
|
+
* one people switch off — which would cost them the `-fdx` warning too. Add
|
|
1433
|
+
* `"f"` to `destructiveFlags` to opt into it.
|
|
1434
|
+
*/
|
|
1435
|
+
const GIT_CLEAN_DESTRUCTIVE_FLAGS = ["d", "x", "X"];
|
|
1436
|
+
|
|
1382
1437
|
// warnAllFilesStaged
|
|
1383
1438
|
const GIT_ADD_ALL_RE = /\bgit\s+add\s+(?:-A\b|--all\b|\.(?:\s|$|;|&&|\|\|))/;
|
|
1384
1439
|
|
|
@@ -2528,6 +2583,101 @@ function warnGitStashDrop(ctx: PolicyContext): PolicyResult {
|
|
|
2528
2583
|
return allow();
|
|
2529
2584
|
}
|
|
2530
2585
|
|
|
2586
|
+
/** What one `git clean` argument list asks for. */
|
|
2587
|
+
interface GitCleanFlags {
|
|
2588
|
+
force: boolean;
|
|
2589
|
+
dryRun: boolean;
|
|
2590
|
+
/** Short-flag letters, with `--force` counted as `f` so widening works either way. */
|
|
2591
|
+
letters: Set<string>;
|
|
2592
|
+
}
|
|
2593
|
+
|
|
2594
|
+
/**
|
|
2595
|
+
* Read `git clean`'s own options: clusters (`-fdx`) and the two long forms
|
|
2596
|
+
* that matter (`--force`, `--dry-run`).
|
|
2597
|
+
*
|
|
2598
|
+
* Everything after `--` is a pathspec, not a flag — `git clean -n -- -fdx`
|
|
2599
|
+
* asks about a file literally called `-fdx` and deletes nothing.
|
|
2600
|
+
*/
|
|
2601
|
+
function readGitCleanFlags(args: string[]): GitCleanFlags {
|
|
2602
|
+
const letters = new Set<string>();
|
|
2603
|
+
let force = false;
|
|
2604
|
+
let dryRun = false;
|
|
2605
|
+
let sawEndOfOptions = false;
|
|
2606
|
+
for (const token of args) {
|
|
2607
|
+
if (token === "--") {
|
|
2608
|
+
sawEndOfOptions = true;
|
|
2609
|
+
continue;
|
|
2610
|
+
}
|
|
2611
|
+
if (sawEndOfOptions) continue;
|
|
2612
|
+
if (token === "--force") {
|
|
2613
|
+
force = true;
|
|
2614
|
+
continue;
|
|
2615
|
+
}
|
|
2616
|
+
if (token === "--dry-run") {
|
|
2617
|
+
dryRun = true;
|
|
2618
|
+
continue;
|
|
2619
|
+
}
|
|
2620
|
+
if (token.startsWith("--")) continue;
|
|
2621
|
+
if (!SHORT_FLAG_CLUSTER_RE.test(token)) continue;
|
|
2622
|
+
for (const letter of token.slice(1)) {
|
|
2623
|
+
if (letter === "f") force = true;
|
|
2624
|
+
if (letter === "n") dryRun = true;
|
|
2625
|
+
letters.add(letter);
|
|
2626
|
+
}
|
|
2627
|
+
}
|
|
2628
|
+
if (force) letters.add("f");
|
|
2629
|
+
return { force, dryRun, letters };
|
|
2630
|
+
}
|
|
2631
|
+
|
|
2632
|
+
/** True when git's own `-c key=value` options waive `clean.requireForce`. */
|
|
2633
|
+
function gitCleanForceWaived(globalOptions: string[]): boolean {
|
|
2634
|
+
for (let i = 0; i < globalOptions.length; i++) {
|
|
2635
|
+
const token = globalOptions[i];
|
|
2636
|
+
const value =
|
|
2637
|
+
token === "-c" ? globalOptions[i + 1] : token.startsWith("-c") ? token.slice(2) : undefined;
|
|
2638
|
+
if (value !== undefined && GIT_CLEAN_FORCE_WAIVED_RE.test(value)) return true;
|
|
2639
|
+
}
|
|
2640
|
+
return false;
|
|
2641
|
+
}
|
|
2642
|
+
|
|
2643
|
+
/**
|
|
2644
|
+
* The gap this closes: `git clean -fdx` was caught by NEITHER tier — no regex
|
|
2645
|
+
* builtin matched the string at all, and the semantic check that covers
|
|
2646
|
+
* unrecoverable deletion cannot fire on it. See the note on the catalog entry
|
|
2647
|
+
* for the measurement and for why this policy is `hard`.
|
|
2648
|
+
*/
|
|
2649
|
+
function warnGitClean(ctx: PolicyContext): PolicyResult {
|
|
2650
|
+
if (ctx.toolName !== "Bash") return allow();
|
|
2651
|
+
const destructiveFlags = ((ctx.params?.destructiveFlags ?? GIT_CLEAN_DESTRUCTIVE_FLAGS) as string[]);
|
|
2652
|
+
if (destructiveFlags.length === 0) return allow();
|
|
2653
|
+
|
|
2654
|
+
for (const segment of shellSegments(getCommand(ctx))) {
|
|
2655
|
+
const tokens = parseArgvTokens(segment);
|
|
2656
|
+
// `findIndex`, not `tokens[0]`, so an env prefix (`GIT_DIR=x git clean …`)
|
|
2657
|
+
// and an absolute binary path both still resolve to the git invocation.
|
|
2658
|
+
const gitIdx = tokens.findIndex((t) => GIT_CMD_RE.test(t));
|
|
2659
|
+
if (gitIdx < 0) continue;
|
|
2660
|
+
const args = tokens.slice(gitIdx + 1);
|
|
2661
|
+
const subIdx = gitSubcommandIndex(args);
|
|
2662
|
+
if (subIdx < 0 || args[subIdx] !== "clean") continue;
|
|
2663
|
+
|
|
2664
|
+
const flags = readGitCleanFlags(args.slice(subIdx + 1));
|
|
2665
|
+
// `-n` / `--dry-run` prints what would go and removes nothing, whatever
|
|
2666
|
+
// else is on the line — the safe inspection form, never a warning.
|
|
2667
|
+
if (flags.dryRun) continue;
|
|
2668
|
+
if (!flags.force && !gitCleanForceWaived(args.slice(0, subIdx))) continue;
|
|
2669
|
+
if (!destructiveFlags.some((f) => flags.letters.has(f))) continue;
|
|
2670
|
+
|
|
2671
|
+
return instruct(
|
|
2672
|
+
"STOP: This command deletes untracked files from the working tree (git clean). Git has no copy of " +
|
|
2673
|
+
"untracked or ignored files, so nothing it removes can be recovered: -d takes whole untracked " +
|
|
2674
|
+
"directories, and -x / -X also take .gitignore'd files such as .env, local config and scratch work. " +
|
|
2675
|
+
"Re-run it with --dry-run and confirm the exact paths with the user before executing.",
|
|
2676
|
+
);
|
|
2677
|
+
}
|
|
2678
|
+
return allow();
|
|
2679
|
+
}
|
|
2680
|
+
|
|
2531
2681
|
function warnAllFilesStaged(ctx: PolicyContext): PolicyResult {
|
|
2532
2682
|
if (ctx.toolName !== "Bash") return allow();
|
|
2533
2683
|
const cmd = getCommand(ctx);
|
|
@@ -3090,7 +3240,7 @@ function requireCiGreenBeforeStop(ctx: PolicyContext): PolicyResult {
|
|
|
3090
3240
|
* Each value is the identical hoisted function object, never a wrapper. Two
|
|
3091
3241
|
* things depend on that and neither fails loudly: `audit/cache.ts` hashes
|
|
3092
3242
|
* `fn.toString()` into the audit cache's `engineVersion`, so wrapping every
|
|
3093
|
-
* entry would collapse
|
|
3243
|
+
* entry would collapse 40 distinct hashes into one and freeze the key — stale
|
|
3094
3244
|
* audit results would then be served for the full 30-day TTL with no symptom;
|
|
3095
3245
|
* and `gitBranchCache` is module-scoped, so a per-call factory would silently
|
|
3096
3246
|
* reset it on every hook event.
|
|
@@ -3121,6 +3271,7 @@ const POLICY_IMPLEMENTATIONS: Record<string, PolicyFunction> = {
|
|
|
3121
3271
|
"block-work-on-main": blockWorkOnMain,
|
|
3122
3272
|
"warn-git-amend": warnGitAmend,
|
|
3123
3273
|
"warn-git-stash-drop": warnGitStashDrop,
|
|
3274
|
+
"warn-git-clean": warnGitClean,
|
|
3124
3275
|
"warn-all-files-staged": warnAllFilesStaged,
|
|
3125
3276
|
"warn-destructive-sql": warnDestructiveSql,
|
|
3126
3277
|
"warn-schema-alteration": warnSchemaAlteration,
|
package/src/hooks/jev-cli.ts
CHANGED
|
@@ -345,6 +345,29 @@ function providerForUrl(url: string): JevProviderKind {
|
|
|
345
345
|
}
|
|
346
346
|
}
|
|
347
347
|
|
|
348
|
+
/**
|
|
349
|
+
* The account id a Cloudflare URL already carries, or null.
|
|
350
|
+
*
|
|
351
|
+
* Cloudflare's run endpoint IS per-account — `…/client/v4/accounts/<id>/ai/run`
|
|
352
|
+
* — so the id is in the canonical URL, and asking for it again as a flag asks
|
|
353
|
+
* for something the person has already typed. The first real attempt to
|
|
354
|
+
* configure Cloudflare pasted exactly that URL and was refused with "pass the
|
|
355
|
+
* account id as well", with the id visible in the string being rejected.
|
|
356
|
+
*
|
|
357
|
+
* Read from the path only, never from a query or fragment, and only on a host
|
|
358
|
+
* this build already recognises as Cloudflare's, so nothing else can inject one.
|
|
359
|
+
*/
|
|
360
|
+
export function accountIdFromUrl(url: string): string | null {
|
|
361
|
+
try {
|
|
362
|
+
const parsed = new URL(url);
|
|
363
|
+
if (PROVIDER_BY_HOST[parsed.hostname.toLowerCase()] !== "cloudflare") return null;
|
|
364
|
+
const m = /\/accounts\/([0-9a-f]{32})(?:\/|$)/i.exec(parsed.pathname);
|
|
365
|
+
return m ? m[1].toLowerCase() : null;
|
|
366
|
+
} catch {
|
|
367
|
+
return null;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
348
371
|
/** Whether a validated URL is exactly where this provider's requests already go. */
|
|
349
372
|
function isProviderDefaultUrl(kind: JevProviderKind, url: string): boolean {
|
|
350
373
|
const base = JEV_PROVIDER_DEFAULTS[kind].baseUrl;
|
|
@@ -468,6 +491,34 @@ async function setup(argv: string[], deps: JevCliDeps, opts: RenderOpts): Promis
|
|
|
468
491
|
}
|
|
469
492
|
const kind = explicit ?? urlProvider.kind;
|
|
470
493
|
if (explicit === null) values.set("--provider", kind);
|
|
494
|
+
// Cloudflare's endpoint IS per-account, so the run URL copied out of the
|
|
495
|
+
// dashboard already names the account. Read it from there rather than
|
|
496
|
+
// demanding a value that is sitting in the string being read — the first
|
|
497
|
+
// person to configure Cloudflare pasted exactly that URL and was told to
|
|
498
|
+
// "pass the account id as well", with the id visible in the refusal.
|
|
499
|
+
//
|
|
500
|
+
// Set into `values` here, while the URL is still in scope, because the
|
|
501
|
+
// block below deletes `--url` once it has moved the address to
|
|
502
|
+
// `--base-url`. Everything downstream then treats it as a flag that was
|
|
503
|
+
// given, including the 32-hex validation.
|
|
504
|
+
if (kind === "cloudflare") {
|
|
505
|
+
const fromUrl = accountIdFromUrl(normalized);
|
|
506
|
+
const given = values.get("--account-id");
|
|
507
|
+
if (fromUrl !== null && given === undefined) {
|
|
508
|
+
values.set("--account-id", fromUrl);
|
|
509
|
+
} else if (fromUrl !== null && given !== undefined && given.toLowerCase() !== fromUrl) {
|
|
510
|
+
// Preferring either one silently would send every request to an account
|
|
511
|
+
// the person did not name on the line they are looking at.
|
|
512
|
+
return fail([
|
|
513
|
+
"Not saved: --account-id and the account id in --url are different.",
|
|
514
|
+
` --url names ${fromUrl}`,
|
|
515
|
+
` --account-id names ${given.toLowerCase()}`,
|
|
516
|
+
"Drop one of them.",
|
|
517
|
+
"",
|
|
518
|
+
"Nothing was written.",
|
|
519
|
+
]);
|
|
520
|
+
}
|
|
521
|
+
}
|
|
471
522
|
// The provider's own API is where its key belongs anyway, so a URL naming
|
|
472
523
|
// it clears the override instead of writing the same address into the file
|
|
473
524
|
// (`custom` has no API of its own — its URL is the whole address).
|
|
@@ -546,9 +597,14 @@ async function setup(argv: string[], deps: JevCliDeps, opts: RenderOpts): Promis
|
|
|
546
597
|
// host with another provider asked for is settled above, and nothing here
|
|
547
598
|
// demands an id the file would not keep.
|
|
548
599
|
if (kind === "cloudflare" && urlProvider?.kind === "cloudflare" && typeof next.accountId !== "string") {
|
|
600
|
+
// Reached only when the URL did not carry one either — a bare
|
|
601
|
+
// `/client/v4`, say. The URL form is named as well as the flag, because it
|
|
602
|
+
// is the address the dashboard hands out.
|
|
549
603
|
return fail([
|
|
550
604
|
`Not saved: ${urlProvider.host} is Cloudflare Workers AI, whose endpoint is per-account.`,
|
|
551
|
-
"Pass the account id as well: --account-id <32 hex characters
|
|
605
|
+
"Pass the account id as well: --account-id <32 hex characters>,",
|
|
606
|
+
"or give the full run URL, which already contains it:",
|
|
607
|
+
" https://api.cloudflare.com/client/v4/accounts/<id>/ai/run",
|
|
552
608
|
"",
|
|
553
609
|
"Nothing was written.",
|
|
554
610
|
]);
|
package/src/hooks/manager.ts
CHANGED
|
@@ -1108,7 +1108,7 @@ export async function listHooks(cwd?: string): Promise<void> {
|
|
|
1108
1108
|
// `packCount` counts ENABLED policies, so a pack installed with everything
|
|
1109
1109
|
// switched off reaches zero the same way an empty machine does — and the
|
|
1110
1110
|
// advice for the two could not be more different. Telling somebody who has
|
|
1111
|
-
// just unticked all
|
|
1111
|
+
// just unticked all 39 to `policies add FailproofAI/policies` sends them to
|
|
1112
1112
|
// install what they already have, and doing it would change nothing: the
|
|
1113
1113
|
// selection is what is empty, not the shelf.
|
|
1114
1114
|
const packsInstalled = (() => {
|
package/src/hooks/pack-cli.ts
CHANGED
|
@@ -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,
|
|
@@ -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
|
|
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
|
|
@@ -2693,7 +2693,7 @@ async function add(rest: string[]): Promise<PackCliResult> {
|
|
|
2693
2693
|
];
|
|
2694
2694
|
const skipped = result.available.filter((n) => !result.enabled.includes(n));
|
|
2695
2695
|
|
|
2696
|
-
// Say WHY this set is on. Without it, "10 of
|
|
2696
|
+
// Say WHY this set is on. Without it, "10 of 39 enabled" reads like
|
|
2697
2697
|
// something went wrong rather than like the pack's own recommendation.
|
|
2698
2698
|
const why = {
|
|
2699
2699
|
defaults: "the pack's defaults",
|
|
@@ -2987,6 +2987,147 @@ function relativeAge(iso: string): string {
|
|
|
2987
2987
|
return `${value} ${label}${value === 1 ? "" : "s"} ago`;
|
|
2988
2988
|
}
|
|
2989
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
|
+
|
|
2990
3131
|
async function listRemote(source: string): Promise<PackCliResult> {
|
|
2991
3132
|
const opts = optsFor(process.stdout);
|
|
2992
3133
|
let preview;
|
|
@@ -3029,22 +3170,13 @@ async function listRemote(source: string): Promise<PackCliResult> {
|
|
|
3029
3170
|
(preview.effect === "observe" ? " This pack OBSERVES — it records and blocks nothing." : ""),
|
|
3030
3171
|
opts,
|
|
3031
3172
|
),
|
|
3032
|
-
// The half that is not in the table below, said in words. It is not
|
|
3033
|
-
// selectable, so it has no rows; and it REPLACES this build's own question
|
|
3034
|
-
// set rather than adding to it, which is the part worth knowing before
|
|
3035
|
-
// installing rather than after.
|
|
3036
|
-
preview.semantic.length > 0
|
|
3037
|
-
? note(
|
|
3038
|
-
`It also carries ${semanticPhrase(preview.semantic.length)} — ${preview.semantic
|
|
3039
|
-
.map((s) => s.name)
|
|
3040
|
-
.join(", ")}. They are not selectable, they apply only where you configured Jev, and they ` +
|
|
3041
|
-
"replace the checks this build ships with.",
|
|
3042
|
-
opts,
|
|
3043
|
-
)
|
|
3044
|
-
: null,
|
|
3045
3173
|
preview.minCliVersion ? note(`Requires failproofai ${preview.minCliVersion} or newer.`, opts) : null,
|
|
3046
3174
|
preview.resolvedFromLatest ? note(`Newest release: ${preview.source}`, opts) : null,
|
|
3047
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),
|
|
3048
3180
|
nextStep(`failproofai policies add ${source}`, "Install the defaults with:", opts),
|
|
3049
3181
|
note("Or take part of it: --policy <a,b>, --category <x,y>, --all", opts),
|
|
3050
3182
|
),
|
package/src/hooks/pack-store.ts
CHANGED
|
@@ -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
|
|
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.
|