{"_id":"@arcjet/guard","_rev":"20-33a01ebc2d45d5a281261f70ef78b9c5","name":"@arcjet/guard","dist-tags":{"experimental":"0.1.0-experimental.2","rc":"1.10.0-rc.1","latest":"1.13.0"},"versions":{"0.1.0-experimental.0":{"name":"@arcjet/guard","version":"0.1.0-experimental.0","author":{"url":"https://arcjet.com","name":"Arcjet","email":"support@arcjet.com"},"license":"Apache-2.0","_id":"@arcjet/guard@0.1.0-experimental.0","maintainers":[{"name":"quinn-arcjet","email":"quinn@arcjet.com"},{"name":"davidmytton","email":"david@arcjet.com"}],"homepage":"https://arcjet.com","bugs":{"url":"https://github.com/arcjet/arcjet-js/issues","email":"support@arcjet.com"},"dist":{"shasum":"3a6d381cb6dbe432d55f6c16253f2acaf19fd9fb","tarball":"https://registry.npmjs.org/@arcjet/guard/-/guard-0.1.0-experimental.0.tgz","fileCount":25,"integrity":"sha512-vF8VfE3JlIibxOHe6RKLGymVGNwEKFVY0H8Y5a0gOKzgium37YG/DcMYvaOEh1hsraFJ8Ehb9ld6Ap3iBNEJqw==","signatures":[{"sig":"MEQCIDALKa/hhZJcFxpFqCNLJ2PsI1EuNQXQGfrnW3hEwQKMAiA1oiGPZDBa8Cpnp6+cURjE/ChJUrzV1X+3oPTu9Iibpg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":122124},"type":"module","engines":{"node":">=22.18.0"},"exports":{".":{"bun":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"default":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"workerd":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"edge-light":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"}},"./node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"./fetch":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"}},"gitHead":"75614527d701b3f9e5ffdc590985e44b6448d9b9","scripts":{"lint":"oxlint --tsconfig=tsconfig.lint.json","test":"npm run build && npm run lint && npm run test-unit","build":"rolldown -c rolldown.config.ts","format":"oxfmt","test-unit":"node --test --experimental-test-coverage --test-coverage-include=src/** --test-coverage-exclude=src/**/*.test.ts src/**/*.test.ts","typecheck":"tsgo --noEmit","format:check":"oxfmt --check","test-runtime-bun":"npm run build && bun test test/runtime/bun.test.ts","test-runtime-deno":"npm run build && deno test --no-check --allow-all test/runtime/deno.test.ts","test-runtime-node":"npm run build && node --test test/runtime/node.test.ts","test-runtime-fetch":"npm run build && node --test test/runtime/fetch.test.ts","test-runtime-cloudflare":"npm run build && node --test test/runtime/cloudflare/cloudflare.test.ts"},"_npmUser":{"name":"quinn-arcjet","email":"quinn@arcjet.com"},"repository":{"url":"git+https://github.com/arcjet/arcjet-js.git","type":"git","directory":"arcjet-guard"},"_npmVersion":"10.9.4","description":"Arcjet Guards SDK — AI guardrails for rate limiting, prompt injection detection, and sensitive info detection","directories":{},"_nodeVersion":"22.22.1","dependencies":{"@arcjet/analyze":"1.3.1","@bufbuild/protobuf":"^2.0.0","@connectrpc/connect":"^2.0.0","@connectrpc/connect-web":"^2.0.0","@connectrpc/connect-node":"^2.0.0"},"publishConfig":{"tag":"experimental","access":"public"},"_hasShrinkwrap":false,"devDependencies":{"oxfmt":"0.43.0","oxlint":"1.58.0","rolldown":"1.0.0-rc.12","miniflare":"4.20260329.0","@types/node":"22.19.15","oxlint-tsgolint":"0.18.1","rolldown-plugin-dts":"0.23.2","@typescript/native-preview":"7.0.0-dev.20260331.1"},"_npmOperationalInternal":{"tmp":"tmp/guard_0.1.0-experimental.0_1774975629283_0.5117240703754928","host":"s3://npm-registry-packages-npm-production"}},"0.1.0-experimental.1":{"name":"@arcjet/guard","version":"0.1.0-experimental.1","author":{"url":"https://arcjet.com","name":"Arcjet","email":"support@arcjet.com"},"license":"Apache-2.0","_id":"@arcjet/guard@0.1.0-experimental.1","maintainers":[{"name":"quinn-arcjet","email":"quinn@arcjet.com"},{"name":"davidmytton","email":"david@arcjet.com"}],"homepage":"https://arcjet.com","bugs":{"url":"https://github.com/arcjet/arcjet-js/issues","email":"support@arcjet.com"},"dist":{"shasum":"4b1399a0979e821ec1986d26936ad0e7f750b844","tarball":"https://registry.npmjs.org/@arcjet/guard/-/guard-0.1.0-experimental.1.tgz","fileCount":27,"integrity":"sha512-zqSyqxSabzgY+KWYrmngIT6IfUg90cGbQcMLmAnW8XypLrTVqhCTMQlzyDpSiZTWftcQ2JN/mUX/+oEdvVJLFA==","signatures":[{"sig":"MEYCIQC1Uj0SJFlDFIO5ZDSqtaKguzIvqPWKsWGQ+KqbnfgkvgIhAOeAVXjpOsgItWa2fHjlNMxNiz1BbjFcKnvu/M52JPaz","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":152150},"type":"module","engines":{"node":">=22.18.0"},"exports":{".":{"bun":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"default":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"workerd":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"edge-light":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"}},"./node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"./fetch":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"}},"gitHead":"a77c07724bacf65da3af52cd60e56132f99cc4de","scripts":{"lint":"oxlint --tsconfig=tsconfig.lint.json","test":"npm run build && npm run lint && npm run test-unit","build":"rolldown -c rolldown.config.ts","format":"oxfmt","test-unit":"node --test --experimental-test-coverage --test-coverage-include=src/** --test-coverage-exclude=src/**/*.test.ts src/**/*.test.ts","typecheck":"tsgo --noEmit","format:check":"oxfmt --check","test-runtime-bun":"npm run build && bun test test/runtime/bun.test.ts","test-runtime-deno":"npm run build && deno test --no-check --allow-all test/runtime/deno.test.ts","test-runtime-node":"npm run build && node --test test/runtime/node.test.ts","test-runtime-fetch":"npm run build && node --test test/runtime/fetch.test.ts","test-runtime-cloudflare":"npm run build && node --test test/runtime/cloudflare/cloudflare.test.ts"},"_npmUser":{"name":"quinn-arcjet","email":"quinn@arcjet.com"},"repository":{"url":"git+https://github.com/arcjet/arcjet-js.git","type":"git","directory":"arcjet-guard"},"_npmVersion":"10.9.4","description":"Arcjet Guards SDK — AI guardrails for rate limiting, prompt injection detection, and sensitive info detection","directories":{},"_nodeVersion":"22.22.1","dependencies":{"@arcjet/analyze":"1.3.1","@bufbuild/protobuf":"^2.0.0","@connectrpc/connect":"^2.0.0","@connectrpc/connect-web":"^2.0.0","@connectrpc/connect-node":"^2.0.0"},"publishConfig":{"tag":"experimental","access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"oxfmt":"0.43.0","oxlint":"1.58.0","rolldown":"1.0.0-rc.12","miniflare":"4.20260329.0","@types/node":"22.19.15","oxlint-tsgolint":"0.18.1","rolldown-plugin-dts":"0.23.2","@typescript/native-preview":"7.0.0-dev.20260331.1"},"_npmOperationalInternal":{"tmp":"tmp/guard_0.1.0-experimental.1_1775499588703_0.7181644378026779","host":"s3://npm-registry-packages-npm-production"}},"0.1.0-experimental.2":{"name":"@arcjet/guard","version":"0.1.0-experimental.2","author":{"url":"https://arcjet.com","name":"Arcjet","email":"support@arcjet.com"},"license":"Apache-2.0","_id":"@arcjet/guard@0.1.0-experimental.2","maintainers":[{"name":"quinn-arcjet","email":"quinn@arcjet.com"},{"name":"davidmytton","email":"david@arcjet.com"}],"homepage":"https://arcjet.com","bugs":{"url":"https://github.com/arcjet/arcjet-js/issues","email":"support@arcjet.com"},"dist":{"shasum":"0946b14a9d287b9eb96f0f8b7f4502cc6988d5f9","tarball":"https://registry.npmjs.org/@arcjet/guard/-/guard-0.1.0-experimental.2.tgz","fileCount":27,"integrity":"sha512-VCHn2DpHs+O6/kYw+1Uzfa3a7wjSYFi2rsjzElhTha7oLu7ZnodpD1+P3CezQxPRm3BKwt36fmHJeFXgjvNHow==","signatures":[{"sig":"MEUCIG+32HAfuTlHwPyQ4BVZvCQOnd2UXAmHOJekPqhYR/rEAiEArWG2YWgRiQRQHgNjYlEVIWxpd99R6GXU6nFKBSHcBI0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":175263},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.18.0"},"exports":{".":{"bun":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"default":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"workerd":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"edge-light":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"}},"./node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"./fetch":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"}},"gitHead":"16a6efed895a5bba02acca926ba1cfb810946562","scripts":{"lint":"oxlint --tsconfig=tsconfig.lint.json","test":"npm run build && npm run lint && npm run test-unit","build":"rolldown -c rolldown.config.ts","format":"oxfmt","test-unit":"node --test --experimental-test-coverage --test-coverage-include=src/** --test-coverage-exclude=src/**/*.test.ts src/**/*.test.ts","typecheck":"tsgo --noEmit && tsgo --project tsconfig.lint.json --noEmit","format:check":"oxfmt --check","test-runtime-bun":"npm run build && bun test test/runtime/bun.test.ts","test-runtime-deno":"npm run build && deno test --no-check --allow-all test/runtime/deno.test.ts","test-runtime-node":"npm run build && node --test test/runtime/node.test.ts","test-runtime-fetch":"npm run build && node --test test/runtime/fetch.test.ts","test-runtime-cloudflare":"npm run build && node --test test/runtime/cloudflare/cloudflare.test.ts"},"_npmUser":{"name":"quinn-arcjet","email":"quinn@arcjet.com"},"repository":{"url":"git+https://github.com/arcjet/arcjet-js.git","type":"git","directory":"arcjet-guard"},"_npmVersion":"10.9.4","description":"Arcjet Guards SDK — AI guardrails for rate limiting, prompt injection detection, and sensitive info detection","directories":{},"_nodeVersion":"22.22.1","dependencies":{"@arcjet/analyze":"1.3.1","@bufbuild/protobuf":"^2.0.0","@connectrpc/connect":"^2.0.0","@connectrpc/connect-web":"^2.0.0","@connectrpc/connect-node":"^2.0.0"},"publishConfig":{"tag":"experimental","access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"oxfmt":"0.43.0","oxlint":"1.58.0","rolldown":"1.0.0-rc.12","miniflare":"4.20260329.0","@types/node":"22.19.15","oxlint-tsgolint":"0.18.1","rolldown-plugin-dts":"0.23.2","@typescript/native-preview":"7.0.0-dev.20260331.1"},"_npmOperationalInternal":{"tmp":"tmp/guard_0.1.0-experimental.2_1775597052128_0.3551048912619821","host":"s3://npm-registry-packages-npm-production"}},"1.4.0":{"name":"@arcjet/guard","version":"1.4.0","author":{"url":"https://arcjet.com","name":"Arcjet","email":"support@arcjet.com"},"license":"Apache-2.0","_id":"@arcjet/guard@1.4.0","maintainers":[{"name":"quinn-arcjet","email":"quinn@arcjet.com"},{"name":"davidmytton","email":"david@arcjet.com"}],"homepage":"https://arcjet.com","bugs":{"url":"https://github.com/arcjet/arcjet-js/issues","email":"support@arcjet.com"},"dist":{"shasum":"8e7e69213bab2f54f3bf864ee2b995c29a117be4","tarball":"https://registry.npmjs.org/@arcjet/guard/-/guard-1.4.0.tgz","fileCount":27,"integrity":"sha512-iQv2b1kFLxwzKuogFnLGqL0vGoQx/gq4LiOGfZKJnCY/QpLY8zpjMRe6UUNxUsy6mtmZju11tgDUcEshqpQ1lA==","signatures":[{"sig":"MEUCIFy3qKc4kso9wccAivfx9ykK6p0T+GbSlLvqsKuK4D2AAiEA9xhhRHdQBQl9x92tarEaudypiGtZHvumtQstvKZURuw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":174835},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.18.0"},"exports":{".":{"bun":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"default":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"workerd":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"edge-light":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"}},"./node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"./fetch":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"}},"gitHead":"b4337ec9aa8574e422f37fbf974765f1177fc4eb","scripts":{"lint":"oxlint --tsconfig=tsconfig.lint.json","test":"npm run build && npm run lint && npm run test-unit","build":"rolldown -c rolldown.config.ts","format":"oxfmt","test-unit":"node --test --experimental-test-coverage --test-coverage-include=src/** --test-coverage-exclude=src/**/*.test.ts src/**/*.test.ts","typecheck":"tsgo --noEmit && tsgo --project tsconfig.lint.json --noEmit","format:check":"oxfmt --check","test-runtime-bun":"npm run build && bun test test/runtime/bun.test.ts","test-runtime-deno":"npm run build && deno test --no-check --allow-all test/runtime/deno.test.ts","test-runtime-node":"npm run build && node --test test/runtime/node.test.ts","test-runtime-fetch":"npm run build && node --test test/runtime/fetch.test.ts","test-runtime-cloudflare":"npm run build && node --test test/runtime/cloudflare/cloudflare.test.ts"},"_npmUser":{"name":"quinn-arcjet","email":"quinn@arcjet.com"},"repository":{"url":"git+https://github.com/arcjet/arcjet-js.git","type":"git","directory":"arcjet-guard"},"_npmVersion":"10.9.4","description":"Arcjet Guards SDK — AI guardrails for rate limiting, prompt injection detection, and sensitive info detection","directories":{},"_nodeVersion":"22.22.1","dependencies":{"@arcjet/analyze":"1.4.0","@bufbuild/protobuf":"^2.0.0","@connectrpc/connect":"^2.0.0","@connectrpc/connect-web":"^2.0.0","@connectrpc/connect-node":"^2.0.0"},"publishConfig":{"tag":"latest","access":"public"},"_hasShrinkwrap":false,"devDependencies":{"oxfmt":"0.43.0","oxlint":"1.58.0","rolldown":"1.0.0-rc.12","miniflare":"4.20260329.0","@types/node":"22.19.15","oxlint-tsgolint":"0.18.1","rolldown-plugin-dts":"0.23.2","@typescript/native-preview":"7.0.0-dev.20260331.1"},"_npmOperationalInternal":{"tmp":"tmp/guard_1.4.0_1776197114434_0.609665449715888","host":"s3://npm-registry-packages-npm-production"}},"1.5.0":{"name":"@arcjet/guard","version":"1.5.0","author":{"url":"https://arcjet.com","name":"Arcjet","email":"support@arcjet.com"},"license":"Apache-2.0","_id":"@arcjet/guard@1.5.0","maintainers":[{"name":"quinn-arcjet","email":"quinn@arcjet.com"},{"name":"davidmytton","email":"david@arcjet.com"}],"homepage":"https://arcjet.com","bugs":{"url":"https://github.com/arcjet/arcjet-js/issues","email":"support@arcjet.com"},"dist":{"shasum":"97e4089ae31dfb9b81bdfb7d38f10a1a3dcfd747","tarball":"https://registry.npmjs.org/@arcjet/guard/-/guard-1.5.0.tgz","fileCount":27,"integrity":"sha512-DYKRaTCIfnCBZlyZ0m/icJa6w45uHx5tQWly0ldL49HeDd1C2wQhKh3zuCc+s30spNvsZxnWSaivZohuZ2Dbnw==","signatures":[{"sig":"MEQCIEnQvQs+bYbU5O8pKBxt7qIxAk3//bXelNKivWJYrhDqAiBzR6DHhsiDQNKCNuvDYmmefW+yVvta0Bnv9+ZW6sE/iw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@arcjet%2fguard@1.5.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":177159},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.18.0"},"exports":{".":{"bun":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"default":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"workerd":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"edge-light":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"}},"./node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"./fetch":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"}},"gitHead":"e4350079f67abc66fb7e6530ca5864d7275221e0","scripts":{"lint":"oxlint --tsconfig=tsconfig.lint.json","test":"npm run build && npm run lint && npm run test-unit","build":"rolldown -c rolldown.config.ts","format":"oxfmt","test-unit":"node --test --experimental-test-coverage --test-coverage-include=src/** --test-coverage-exclude=src/**/*.test.ts src/**/*.test.ts","typecheck":"tsgo --noEmit && tsgo --project tsconfig.lint.json --noEmit","format:check":"oxfmt --check","test-runtime-bun":"npm run build && bun test test/runtime/bun.test.ts","test-runtime-deno":"npm run build && deno test --no-check --allow-all test/runtime/deno.test.ts","test-runtime-node":"npm run build && node --test test/runtime/node.test.ts","test-runtime-fetch":"npm run build && node --test test/runtime/fetch.test.ts","test-runtime-cloudflare":"npm run build && node --test test/runtime/cloudflare/cloudflare.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:fc452f67-a66e-4659-85d9-ec27e436e544"}},"repository":{"url":"git+https://github.com/arcjet/arcjet-js.git","type":"git","directory":"arcjet-guard"},"_npmVersion":"11.13.0","description":"Arcjet Guards SDK — AI guardrails for rate limiting, prompt injection detection, and sensitive info detection","directories":{},"_nodeVersion":"24.16.0","dependencies":{"@arcjet/analyze":"1.5.0","@bufbuild/protobuf":"^2.0.0","@connectrpc/connect":"^2.0.0","@connectrpc/connect-web":"^2.0.0","@connectrpc/connect-node":"^2.0.0"},"publishConfig":{"tag":"latest","access":"public"},"_hasShrinkwrap":false,"devDependencies":{"oxfmt":"0.53.0","oxlint":"1.58.0","rolldown":"1.0.3","miniflare":"4.20260529.0","@types/node":"22.19.19","oxlint-tsgolint":"0.18.1","rolldown-plugin-dts":"0.25.2","@typescript/native-preview":"7.0.0-dev.20260602.1"},"_npmOperationalInternal":{"tmp":"tmp/guard_1.5.0_1781022252390_0.21353935533842883","host":"s3://npm-registry-packages-npm-production"}},"1.6.0":{"name":"@arcjet/guard","version":"1.6.0","author":{"url":"https://arcjet.com","name":"Arcjet","email":"support@arcjet.com"},"license":"Apache-2.0","_id":"@arcjet/guard@1.6.0","maintainers":[{"name":"quinn-arcjet","email":"quinn@arcjet.com"},{"name":"davidmytton","email":"david@arcjet.com"}],"homepage":"https://arcjet.com","bugs":{"url":"https://github.com/arcjet/arcjet-js/issues","email":"support@arcjet.com"},"dist":{"shasum":"f07139951d71938a9728aa7fa9e3568ad41b5aae","tarball":"https://registry.npmjs.org/@arcjet/guard/-/guard-1.6.0.tgz","fileCount":35,"integrity":"sha512-cTPjRr+YwRz4UthYzJEYixCzRe5hdOporSOFLz/jwjOiuPWx8n53S3fCFUT76pNUBicO8lPGoBK7rR9hOgrumQ==","signatures":[{"sig":"MEUCIQDriyJCtjK8jNCqcN658grgHzRvJ4/2IZW/CAj1VEy29gIgG/bQ8FbnH1gi09vl9wCH6Nzy28VH5aBKBwv+7Th4xPE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@arcjet%2fguard@1.6.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":228974},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.21.0 <23 || >=24.5.0"},"exports":{".":{"bun":{"types":"./dist/bun.d.ts","import":"./dist/bun.js"},"deno":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"default":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"workerd":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"edge-light":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"}},"./bun":{"types":"./dist/bun.d.ts","import":"./dist/bun.js"},"./node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"./fetch":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"}},"gitHead":"b9a0809f685ea62068cedce480a81addfe76c589","scripts":{"lint":"oxlint --tsconfig=tsconfig.lint.json","test":"npm run build && npm run lint && npm run test-unit","build":"rolldown -c rolldown.config.ts","format":"oxfmt","test-unit":"node --test --experimental-test-coverage --test-coverage-include=src/** --test-coverage-exclude=src/**/*.test.ts src/**/*.test.ts","typecheck":"tsgo --noEmit && tsgo --project tsconfig.lint.json --noEmit","format:check":"oxfmt --check","test-runtime-bun":"npm run build && bun test test/runtime/bun.test.ts","test-runtime-deno":"npm run build && deno test --no-check --allow-all test/runtime/deno.test.ts","test-runtime-node":"npm run build && node --test test/runtime/node.test.ts","test-runtime-fetch":"npm run build && node --test test/runtime/fetch.test.ts","test-runtime-cloudflare":"npm run build && node --test test/runtime/cloudflare/cloudflare.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:fc452f67-a66e-4659-85d9-ec27e436e544"}},"repository":{"url":"git+https://github.com/arcjet/arcjet-js.git","type":"git","directory":"arcjet-guard"},"_npmVersion":"11.13.0","description":"Arcjet Guards SDK — AI guardrails for rate limiting, prompt injection detection, and sensitive info detection","directories":{},"_nodeVersion":"24.17.0","dependencies":{"@arcjet/analyze":"1.6.0","@bufbuild/protobuf":"^2.0.0","@connectrpc/connect":"^2.0.0","@connectrpc/connect-web":"^2.0.0","@connectrpc/connect-node":"^2.0.0"},"publishConfig":{"tag":"latest","access":"public"},"_hasShrinkwrap":false,"devDependencies":{"oxfmt":"0.55.0","oxlint":"1.70.0","rolldown":"1.1.2","miniflare":"4.20260617.1","@types/node":"22.19.21","oxlint-tsgolint":"0.23.0","rolldown-plugin-dts":"0.26.0","@typescript/native-preview":"7.0.0-dev.20260602.1"},"_npmOperationalInternal":{"tmp":"tmp/guard_1.6.0_1782848320258_0.19722419928350177","host":"s3://npm-registry-packages-npm-production"}},"1.6.1":{"name":"@arcjet/guard","version":"1.6.1","author":{"url":"https://arcjet.com","name":"Arcjet","email":"support@arcjet.com"},"license":"Apache-2.0","_id":"@arcjet/guard@1.6.1","maintainers":[{"name":"quinn-arcjet","email":"quinn@arcjet.com"},{"name":"davidmytton","email":"david@arcjet.com"}],"homepage":"https://arcjet.com","bugs":{"url":"https://github.com/arcjet/arcjet-js/issues","email":"support@arcjet.com"},"dist":{"shasum":"ecaa99d89393eab16be9ef26365108f980ba19f1","tarball":"https://registry.npmjs.org/@arcjet/guard/-/guard-1.6.1.tgz","fileCount":35,"integrity":"sha512-vRfydLQ2cZPnM9GehWrRlrB77YcIHaP9HK18F6MckpT5TPPKQjYI+ODqRzobgnpt+lJwHhnhbYr94L0pUQPUEg==","signatures":[{"sig":"MEUCIQDsJ7HalT00Ncwe3KQvV8UC1tdlOS177LXT5jmtQi1YjQIgaUBr8YMkn3/Ee3fuNTkq/qqIoXtibpUweDoELCa+zVo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@arcjet%2fguard@1.6.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":228974},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.21.0 <23 || >=24.5.0"},"exports":{".":{"bun":{"types":"./dist/bun.d.ts","import":"./dist/bun.js"},"deno":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"default":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"workerd":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"edge-light":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"}},"./bun":{"types":"./dist/bun.d.ts","import":"./dist/bun.js"},"./node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"./fetch":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"}},"gitHead":"2bf038bdeaa512b6ba1e531b75ebcedb274ae4e8","scripts":{"lint":"oxlint --tsconfig=tsconfig.lint.json","test":"npm run build && npm run lint && npm run test-unit","build":"rolldown -c rolldown.config.ts","format":"oxfmt","test-unit":"node --test --experimental-test-coverage --test-coverage-include=src/** --test-coverage-exclude=src/**/*.test.ts src/**/*.test.ts","typecheck":"tsgo --noEmit && tsgo --project tsconfig.lint.json --noEmit","format:check":"oxfmt --check","test-runtime-bun":"npm run build && bun test test/runtime/bun.test.ts","test-runtime-deno":"npm run build && deno test --no-check --allow-all test/runtime/deno.test.ts","test-runtime-node":"npm run build && node --test test/runtime/node.test.ts","test-runtime-fetch":"npm run build && node --test test/runtime/fetch.test.ts","test-runtime-cloudflare":"npm run build && node --test test/runtime/cloudflare/cloudflare.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:fc452f67-a66e-4659-85d9-ec27e436e544"}},"repository":{"url":"git+https://github.com/arcjet/arcjet-js.git","type":"git","directory":"arcjet-guard"},"_npmVersion":"11.13.0","description":"Arcjet Guards SDK — AI guardrails for rate limiting, prompt injection detection, and sensitive info detection","directories":{},"_nodeVersion":"24.17.0","dependencies":{"@arcjet/analyze":"1.6.1","@bufbuild/protobuf":"^2.0.0","@connectrpc/connect":"^2.0.0","@connectrpc/connect-web":"^2.0.0","@connectrpc/connect-node":"^2.0.0"},"publishConfig":{"tag":"latest","access":"public"},"_hasShrinkwrap":false,"devDependencies":{"oxfmt":"0.55.0","oxlint":"1.70.0","rolldown":"1.1.2","miniflare":"4.20260617.1","@types/node":"22.19.21","oxlint-tsgolint":"0.23.0","rolldown-plugin-dts":"0.26.0","@typescript/native-preview":"7.0.0-dev.20260602.1"},"_npmOperationalInternal":{"tmp":"tmp/guard_1.6.1_1782856642578_0.9807484577989005","host":"s3://npm-registry-packages-npm-production"}},"1.7.0-rc.0":{"name":"@arcjet/guard","version":"1.7.0-rc.0","author":{"url":"https://arcjet.com","name":"Arcjet","email":"support@arcjet.com"},"license":"Apache-2.0","_id":"@arcjet/guard@1.7.0-rc.0","maintainers":[{"name":"quinn-arcjet","email":"quinn@arcjet.com"},{"name":"davidmytton","email":"david@arcjet.com"}],"homepage":"https://arcjet.com","bugs":{"url":"https://github.com/arcjet/arcjet-js/issues","email":"support@arcjet.com"},"dist":{"shasum":"f8453bb3d53b2da8c99a8d8b4386b5a24faa045a","tarball":"https://registry.npmjs.org/@arcjet/guard/-/guard-1.7.0-rc.0.tgz","fileCount":35,"integrity":"sha512-fxlxha3SVTeQMcUdyydyfQO5T4zz69c68d2ExdUNg1sVV3/0Y6PJTZLUPZHKo5Qu+/1PMWnTacVewwgUoakRJA==","signatures":[{"sig":"MEUCIGjdzRne7iICyrehXWhTXDaA+NN4S4pQnA3LGzUITsWtAiEAtoC554IKQklcH/mvRt1G1cSYpCwRV+UWdAiXfMcX718=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@arcjet%2fguard@1.7.0-rc.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":240770},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.21.0 <23 || >=24.5.0"},"exports":{".":{"bun":{"types":"./dist/bun.d.ts","import":"./dist/bun.js"},"deno":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"default":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"workerd":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"edge-light":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"}},"./bun":{"types":"./dist/bun.d.ts","import":"./dist/bun.js"},"./node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"./fetch":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"}},"gitHead":"ccad92b3403ca38b9fb571b3751faa9a748076dc","scripts":{"lint":"oxlint --tsconfig=tsconfig.lint.json","test":"npm run build && npm run lint && npm run test-unit","build":"tsdown","format":"oxfmt","test-unit":"node --test --experimental-test-coverage --test-coverage-include=src/** --test-coverage-exclude=src/**/*.test.ts src/**/*.test.ts","typecheck":"tsgo --noEmit && tsgo --project tsconfig.lint.json --noEmit","format:check":"oxfmt --check","test-runtime-bun":"npm run build && bun test test/runtime/bun.test.ts","test-runtime-deno":"npm run build && deno test --no-check --allow-all test/runtime/deno.test.ts","test-runtime-node":"npm run build && node --test test/runtime/node.test.ts","test-runtime-fetch":"npm run build && node --test test/runtime/fetch.test.ts","test-runtime-cloudflare":"npm run build && node --test test/runtime/cloudflare/cloudflare.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:fc452f67-a66e-4659-85d9-ec27e436e544"}},"repository":{"url":"git+https://github.com/arcjet/arcjet-js.git","type":"git","directory":"arcjet-guard"},"_npmVersion":"11.16.0","description":"Arcjet Guards SDK — AI guardrails for rate limiting, prompt injection detection, and sensitive info detection","directories":{},"_nodeVersion":"24.18.0","dependencies":{"@arcjet/analyze":"1.7.0-rc.0","@bufbuild/protobuf":"^2.0.0","@connectrpc/connect":"^2.0.0","@connectrpc/connect-web":"^2.0.0","@connectrpc/connect-node":"^2.0.0"},"publishConfig":{"tag":"latest","access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"oxfmt":"0.55.0","oxlint":"1.70.0","tsdown":"0.22.3","miniflare":"4.20260617.1","@types/node":"22.19.21","oxlint-tsgolint":"0.23.0","@typescript/native-preview":"7.0.0-dev.20260602.1"},"_npmOperationalInternal":{"tmp":"tmp/guard_1.7.0-rc.0_1783120157228_0.6143337037642158","host":"s3://npm-registry-packages-npm-production"}},"1.7.0-rc.1":{"name":"@arcjet/guard","version":"1.7.0-rc.1","author":{"url":"https://arcjet.com","name":"Arcjet","email":"support@arcjet.com"},"license":"Apache-2.0","_id":"@arcjet/guard@1.7.0-rc.1","maintainers":[{"name":"quinn-arcjet","email":"quinn@arcjet.com"},{"name":"davidmytton","email":"david@arcjet.com"}],"homepage":"https://arcjet.com","bugs":{"url":"https://github.com/arcjet/arcjet-js/issues","email":"support@arcjet.com"},"dist":{"shasum":"7e4467925008701f78b5425e0cef245064fca4b4","tarball":"https://registry.npmjs.org/@arcjet/guard/-/guard-1.7.0-rc.1.tgz","fileCount":35,"integrity":"sha512-z3lrefGDxvQYfI9mAm3FUQy2CZR5XD1KmSbP4urOsGZSuoLY92cWoZv6LGt2uw/7Bu5o9R5vA6uviYKkmeN4Fw==","signatures":[{"sig":"MEUCIFBzwNGBQwX/NZHmCVBByRMnMyAcZUY7d10GsSUbTh2/AiEAhM9wpF9WSGw15pi3YfLT9jMMSdU61JmdTEcCAlHZC9c=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@arcjet%2fguard@1.7.0-rc.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":240767},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.21.0 <23 || >=24.5.0"},"exports":{".":{"bun":{"types":"./dist/bun.d.ts","import":"./dist/bun.js"},"deno":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"default":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"workerd":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"edge-light":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"}},"./bun":{"types":"./dist/bun.d.ts","import":"./dist/bun.js"},"./node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"./fetch":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"}},"gitHead":"f6e9f56e1ff7e9e802b9635c4c25656e397bfc8f","scripts":{"lint":"oxlint --tsconfig=tsconfig.lint.json","test":"npm run build && npm run lint && npm run test-unit","build":"tsdown","format":"oxfmt","test-unit":"node --test --experimental-test-coverage --test-coverage-include=src/** --test-coverage-exclude=src/**/*.test.ts src/**/*.test.ts","typecheck":"tsgo --noEmit && tsgo --project tsconfig.lint.json --noEmit","format:check":"oxfmt --check","test-runtime-bun":"npm run build && bun test test/runtime/bun.test.ts","test-runtime-deno":"npm run build && deno test --no-check --allow-all test/runtime/deno.test.ts","test-runtime-node":"npm run build && node --test test/runtime/node.test.ts","test-runtime-fetch":"npm run build && node --test test/runtime/fetch.test.ts","test-runtime-cloudflare":"npm run build && node --test test/runtime/cloudflare/cloudflare.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:fc452f67-a66e-4659-85d9-ec27e436e544"}},"repository":{"url":"git+https://github.com/arcjet/arcjet-js.git","type":"git","directory":"arcjet-guard"},"_npmVersion":"11.16.0","description":"Arcjet Guards SDK — AI guardrails for rate limiting, prompt injection detection, and sensitive info detection","directories":{},"_nodeVersion":"24.18.0","dependencies":{"@arcjet/analyze":"1.7.0-rc.1","@bufbuild/protobuf":"^2.0.0","@connectrpc/connect":"^2.0.0","@connectrpc/connect-web":"^2.0.0","@connectrpc/connect-node":"^2.0.0"},"publishConfig":{"tag":"latest","access":"public"},"_hasShrinkwrap":false,"devDependencies":{"oxfmt":"0.55.0","oxlint":"1.70.0","tsdown":"0.22.3","miniflare":"4.20260617.1","@types/node":"22.19.21","oxlint-tsgolint":"0.23.0","@typescript/native-preview":"7.0.0-dev.20260602.1"},"_npmOperationalInternal":{"tmp":"tmp/guard_1.7.0-rc.1_1783355002934_0.4883399235221493","host":"s3://npm-registry-packages-npm-production"}},"1.7.0":{"name":"@arcjet/guard","version":"1.7.0","author":{"url":"https://arcjet.com","name":"Arcjet","email":"support@arcjet.com"},"license":"Apache-2.0","_id":"@arcjet/guard@1.7.0","maintainers":[{"name":"quinn-arcjet","email":"quinn@arcjet.com"},{"name":"davidmytton","email":"david@arcjet.com"}],"homepage":"https://arcjet.com","bugs":{"url":"https://github.com/arcjet/arcjet-js/issues","email":"support@arcjet.com"},"dist":{"shasum":"5b879e0ce605c10d2a7825d662b88de6dcdd3ffa","tarball":"https://registry.npmjs.org/@arcjet/guard/-/guard-1.7.0.tgz","fileCount":35,"integrity":"sha512-x0znHG4PbALojkX8ofaNyXyxub48Q7Ju8HDYlbpFHVJZCUZappgZaaEU9/H0x/55/0T32K9zjBz9duYI0vVXag==","signatures":[{"sig":"MEYCIQC5iAPCq9ZyOPxNNTJJ7G6OZBcSuEclQuODfdg8/ItzFAIhALAp5r6XFXyk6eZPk6NLqVd3kge2PJyN85+clr4LOFeQ","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@arcjet%2fguard@1.7.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":228974},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.21.0 <23 || >=24.5.0"},"exports":{".":{"bun":{"types":"./dist/bun.d.ts","import":"./dist/bun.js"},"deno":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"default":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"workerd":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"edge-light":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"}},"./bun":{"types":"./dist/bun.d.ts","import":"./dist/bun.js"},"./node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"./fetch":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"}},"gitHead":"2b2f5a9b7e179a609eb5c83d28f19a5a45eefa9e","scripts":{"lint":"oxlint --tsconfig=tsconfig.lint.json","test":"npm run build && npm run lint && npm run test-unit","build":"rolldown -c rolldown.config.ts","format":"oxfmt","test-unit":"node --test --experimental-test-coverage --test-coverage-include=src/** --test-coverage-exclude=src/**/*.test.ts src/**/*.test.ts","typecheck":"tsgo --noEmit && tsgo --project tsconfig.lint.json --noEmit","format:check":"oxfmt --check","test-runtime-bun":"npm run build && bun test test/runtime/bun.test.ts","test-runtime-deno":"npm run build && deno test --no-check --allow-all test/runtime/deno.test.ts","test-runtime-node":"npm run build && node --test test/runtime/node.test.ts","test-runtime-fetch":"npm run build && node --test test/runtime/fetch.test.ts","test-runtime-cloudflare":"npm run build && node --test test/runtime/cloudflare/cloudflare.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:fc452f67-a66e-4659-85d9-ec27e436e544"}},"repository":{"url":"git+https://github.com/arcjet/arcjet-js.git","type":"git","directory":"arcjet-guard"},"_npmVersion":"11.16.0","description":"Arcjet Guards SDK — AI guardrails for rate limiting, prompt injection detection, and sensitive info detection","directories":{},"_nodeVersion":"24.18.0","dependencies":{"@arcjet/analyze":"1.7.0","@bufbuild/protobuf":"^2.0.0","@connectrpc/connect":"^2.0.0","@connectrpc/connect-web":"^2.0.0","@connectrpc/connect-node":"^2.0.0"},"publishConfig":{"tag":"latest","access":"public"},"_hasShrinkwrap":false,"devDependencies":{"oxfmt":"0.55.0","oxlint":"1.70.0","rolldown":"1.1.2","miniflare":"4.20260617.1","@types/node":"22.19.21","oxlint-tsgolint":"0.23.0","rolldown-plugin-dts":"0.26.0","@typescript/native-preview":"7.0.0-dev.20260602.1"},"_npmOperationalInternal":{"tmp":"tmp/guard_1.7.0_1783357640484_0.254370868267654","host":"s3://npm-registry-packages-npm-production"}},"1.8.0-rc.0":{"name":"@arcjet/guard","version":"1.8.0-rc.0","author":{"url":"https://arcjet.com","name":"Arcjet","email":"support@arcjet.com"},"license":"Apache-2.0","_id":"@arcjet/guard@1.8.0-rc.0","maintainers":[{"name":"quinn-arcjet","email":"quinn@arcjet.com"},{"name":"davidmytton","email":"david@arcjet.com"}],"homepage":"https://arcjet.com","bugs":{"url":"https://github.com/arcjet/arcjet-js/issues","email":"support@arcjet.com"},"dist":{"shasum":"cb53d069d59171cb8ffbb349e08f91c11510c75c","tarball":"https://registry.npmjs.org/@arcjet/guard/-/guard-1.8.0-rc.0.tgz","fileCount":35,"integrity":"sha512-EXEiruYXRZUsY0A2gbuXsGnQz2npr/gMdYgwW+Lb/o4rSdYYorqZwUw3hhET5BEg+GlGwf5VQWy1qCsJAGAsKA==","signatures":[{"sig":"MEQCIEwlARg31Heb4Gp/pBMqBctUkqKn/A9pqDR4vHERbv38AiAJFSBAfawAoYhJzv2Xh54c/abD6AQKNbtqYHKKzpxPJA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@arcjet%2fguard@1.8.0-rc.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":240767},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.21.0 <23 || >=24.5.0"},"exports":{".":{"bun":{"types":"./dist/bun.d.ts","import":"./dist/bun.js"},"deno":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"default":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"workerd":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"edge-light":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"}},"./bun":{"types":"./dist/bun.d.ts","import":"./dist/bun.js"},"./node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"./fetch":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"}},"gitHead":"01e1e10bed5a7e0e0d2dd381d5b7736402da2326","scripts":{"lint":"oxlint --tsconfig=tsconfig.lint.json","test":"npm run build && npm run lint && npm run test-unit","build":"tsdown","format":"oxfmt","test-unit":"node --test --experimental-test-coverage --test-coverage-include=src/** --test-coverage-exclude=src/**/*.test.ts src/**/*.test.ts","typecheck":"tsgo --noEmit && tsgo --project tsconfig.lint.json --noEmit","format:check":"oxfmt --check","test-runtime-bun":"npm run build && bun test test/runtime/bun.test.ts","test-runtime-deno":"npm run build && deno test --no-check --allow-all test/runtime/deno.test.ts","test-runtime-node":"npm run build && node --test test/runtime/node.test.ts","test-runtime-fetch":"npm run build && node --test test/runtime/fetch.test.ts","test-runtime-cloudflare":"npm run build && node --test test/runtime/cloudflare/cloudflare.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:fc452f67-a66e-4659-85d9-ec27e436e544"}},"repository":{"url":"git+https://github.com/arcjet/arcjet-js.git","type":"git","directory":"arcjet-guard"},"_npmVersion":"11.16.0","description":"Arcjet Guards SDK — AI guardrails for rate limiting, prompt injection detection, and sensitive info detection","directories":{},"_nodeVersion":"24.18.0","dependencies":{"@arcjet/analyze":"1.8.0-rc.0","@bufbuild/protobuf":"^2.0.0","@connectrpc/connect":"^2.0.0","@connectrpc/connect-web":"^2.0.0","@connectrpc/connect-node":"^2.0.0"},"publishConfig":{"tag":"latest","access":"public"},"_hasShrinkwrap":false,"devDependencies":{"oxfmt":"0.55.0","oxlint":"1.70.0","tsdown":"0.22.3","miniflare":"4.20260617.1","@types/node":"22.19.21","oxlint-tsgolint":"0.23.0","@typescript/native-preview":"7.0.0-dev.20260602.1"},"_npmOperationalInternal":{"tmp":"tmp/guard_1.8.0-rc.0_1783446973591_0.8225168507780778","host":"s3://npm-registry-packages-npm-production"}},"1.8.0":{"name":"@arcjet/guard","version":"1.8.0","author":{"url":"https://arcjet.com","name":"Arcjet","email":"support@arcjet.com"},"license":"Apache-2.0","_id":"@arcjet/guard@1.8.0","maintainers":[{"name":"quinn-arcjet","email":"quinn@arcjet.com"},{"name":"davidmytton","email":"david@arcjet.com"}],"homepage":"https://arcjet.com","bugs":{"url":"https://github.com/arcjet/arcjet-js/issues","email":"support@arcjet.com"},"dist":{"shasum":"ea353ec2ba29951b573301d800e0bca1f7ca1228","tarball":"https://registry.npmjs.org/@arcjet/guard/-/guard-1.8.0.tgz","fileCount":35,"integrity":"sha512-+FaETpsBFvYljLQ2z+t2qETU8RfsFIxkDcIDwSlruREgxAmBz6VxKaDb6FAKaqbZzT8R3ipiz51IvLpQj/rLOQ==","signatures":[{"sig":"MEMCIAlVAJT5Bez2497YnI86p/PO15Rs2lVEavqMCEocaD0BAh9DS7e9+cmdJf7n8iWK0Zo4Fs1UFd3dsMOQ3d2qqZtn","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@arcjet%2fguard@1.8.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":240747},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.21.0 <23 || >=24.5.0"},"exports":{".":{"bun":{"types":"./dist/bun.d.ts","import":"./dist/bun.js"},"deno":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"default":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"workerd":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"edge-light":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"}},"./bun":{"types":"./dist/bun.d.ts","import":"./dist/bun.js"},"./node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"./fetch":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"}},"gitHead":"644d8d7133ed1023751451590228de6c0090cc07","scripts":{"lint":"oxlint --tsconfig=tsconfig.lint.json","test":"npm run build && npm run lint && npm run test-unit","build":"tsdown","format":"oxfmt","test-unit":"node --test --experimental-test-coverage --test-coverage-include=src/** --test-coverage-exclude=src/**/*.test.ts src/**/*.test.ts","typecheck":"tsgo --noEmit && tsgo --project tsconfig.lint.json --noEmit","format:check":"oxfmt --check","test-runtime-bun":"npm run build && bun test test/runtime/bun.test.ts","test-runtime-deno":"npm run build && deno test --no-check --allow-all test/runtime/deno.test.ts","test-runtime-node":"npm run build && node --test test/runtime/node.test.ts","test-runtime-fetch":"npm run build && node --test test/runtime/fetch.test.ts","test-runtime-cloudflare":"npm run build && node --test test/runtime/cloudflare/cloudflare.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:fc452f67-a66e-4659-85d9-ec27e436e544"}},"repository":{"url":"git+https://github.com/arcjet/arcjet-js.git","type":"git","directory":"arcjet-guard"},"_npmVersion":"11.16.0","description":"Arcjet Guards SDK — AI guardrails for rate limiting, prompt injection detection, and sensitive info detection","directories":{},"_nodeVersion":"24.18.0","dependencies":{"@arcjet/analyze":"1.8.0","@bufbuild/protobuf":"^2.0.0","@connectrpc/connect":"^2.0.0","@connectrpc/connect-web":"^2.0.0","@connectrpc/connect-node":"^2.0.0"},"publishConfig":{"tag":"latest","access":"public"},"_hasShrinkwrap":false,"devDependencies":{"oxfmt":"0.55.0","oxlint":"1.70.0","tsdown":"0.22.3","miniflare":"4.20260617.1","@types/node":"22.19.21","oxlint-tsgolint":"0.23.0","@typescript/native-preview":"7.0.0-dev.20260602.1"},"_npmOperationalInternal":{"tmp":"tmp/guard_1.8.0_1783448570834_0.016959253223946202","host":"s3://npm-registry-packages-npm-production"}},"1.9.0":{"name":"@arcjet/guard","version":"1.9.0","author":{"url":"https://arcjet.com","name":"Arcjet","email":"support@arcjet.com"},"license":"Apache-2.0","_id":"@arcjet/guard@1.9.0","maintainers":[{"name":"quinn-arcjet","email":"quinn@arcjet.com"},{"name":"davidmytton","email":"david@arcjet.com"}],"homepage":"https://arcjet.com","bugs":{"url":"https://github.com/arcjet/arcjet-js/issues","email":"support@arcjet.com"},"dist":{"shasum":"66547d7984dbba90789fad1fc388afc620e8ef6b","tarball":"https://registry.npmjs.org/@arcjet/guard/-/guard-1.9.0.tgz","fileCount":37,"integrity":"sha512-dmP3KDoFsArcBaRfVHvcnaA2i/zW20p1qvcJs+QLUsNf8uVU+SeiaOGIbpMzZ1jrf94W+35f5U7QjsU4KoqS8A==","signatures":[{"sig":"MEUCIQDuhdx9zt0JhAMf5OhRcsniRHxgCHUr0qBAYLDCjFKlZwIgBwTE6YGkWq7szyGhZ9pUfzx6kHTBtvIGvrsZoUzfJFI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@arcjet%2fguard@1.9.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":261701},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.21.0 <23 || >=24.5.0"},"exports":{".":{"bun":{"types":"./dist/bun.d.ts","import":"./dist/bun.js"},"deno":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"default":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"workerd":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"edge-light":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"}},"./bun":{"types":"./dist/bun.d.ts","import":"./dist/bun.js"},"./node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"./fetch":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"}},"gitHead":"39d8b5ce571b42f0180295e43e0a557bcd2b3ea8","scripts":{"lint":"oxlint --tsconfig=tsconfig.lint.json","test":"npm run build && npm run lint && npm run test-unit","build":"tsdown","format":"oxfmt","test-unit":"node --test --experimental-test-coverage --test-coverage-include=src/** --test-coverage-exclude=src/**/*.test.ts src/**/*.test.ts","typecheck":"tsgo --noEmit && tsgo --project tsconfig.lint.json --noEmit","format:check":"oxfmt --check","test-runtime-bun":"npm run build && bun test test/runtime/bun.test.ts","test-runtime-deno":"npm run build && deno test --no-check --allow-all test/runtime/deno.test.ts","test-runtime-node":"npm run build && node --test test/runtime/node.test.ts","test-runtime-fetch":"npm run build && node --test test/runtime/fetch.test.ts","test-runtime-cloudflare":"npm run build && node --test test/runtime/cloudflare/cloudflare.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:fc452f67-a66e-4659-85d9-ec27e436e544"}},"repository":{"url":"git+https://github.com/arcjet/arcjet-js.git","type":"git","directory":"arcjet-guard"},"_npmVersion":"11.16.0","description":"Arcjet Guards SDK — AI guardrails for rate limiting, prompt injection detection, and sensitive info detection","directories":{},"_nodeVersion":"24.18.0","dependencies":{"@arcjet/analyze":"1.9.0","@bufbuild/protobuf":"^2.0.0","@connectrpc/connect":"^2.0.0","@connectrpc/connect-web":"^2.0.0","@connectrpc/connect-node":"^2.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"oxfmt":"0.55.0","oxlint":"1.70.0","tsdown":"0.22.3","miniflare":"4.20260617.1","@types/node":"22.19.21","oxlint-tsgolint":"0.23.0","@typescript/native-preview":"7.0.0-dev.20260602.1"},"_npmOperationalInternal":{"tmp":"tmp/guard_1.9.0_1784152629866_0.6308626438572771","host":"s3://npm-registry-packages-npm-production"}},"1.9.1":{"name":"@arcjet/guard","version":"1.9.1","author":{"url":"https://arcjet.com","name":"Arcjet","email":"support@arcjet.com"},"license":"Apache-2.0","_id":"@arcjet/guard@1.9.1","maintainers":[{"name":"quinn-arcjet","email":"quinn@arcjet.com"},{"name":"davidmytton","email":"david@arcjet.com"}],"homepage":"https://arcjet.com","bugs":{"url":"https://github.com/arcjet/arcjet-js/issues","email":"support@arcjet.com"},"dist":{"shasum":"2a28efc010d49432996b13e360b57f836fd62beb","tarball":"https://registry.npmjs.org/@arcjet/guard/-/guard-1.9.1.tgz","fileCount":37,"integrity":"sha512-k8lr5SfhL7IXwMZRJRXlU0DPHJrTy1DYUFPWv6OFTIObd42znHZUlH7b9XGZUH3rzeem39K70XuT2owdfRKZgQ==","signatures":[{"sig":"MEUCIGGSIyC6dRGyGJYCXRGyWW0DkTTapodqtn+C7b+5Rd36AiEAjmDAQY5MvoL7yaFOvobUkvCQ9VMpjqqy2fBc0hfboFo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@arcjet%2fguard@1.9.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":261701},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.21.0 <23 || >=24.5.0"},"exports":{".":{"bun":{"types":"./dist/bun.d.ts","import":"./dist/bun.js"},"deno":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"default":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"workerd":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"edge-light":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"}},"./bun":{"types":"./dist/bun.d.ts","import":"./dist/bun.js"},"./node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"./fetch":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"}},"gitHead":"a3cda8246ffe9c6e844c5efa89ffe9b97c8e7823","scripts":{"lint":"oxlint --tsconfig=tsconfig.lint.json","test":"npm run build && npm run lint && npm run test-unit","build":"tsdown","format":"oxfmt","test-unit":"node --test --experimental-test-coverage --test-coverage-include=src/** --test-coverage-exclude=src/**/*.test.ts src/**/*.test.ts","typecheck":"tsgo --noEmit && tsgo --project tsconfig.lint.json --noEmit","format:check":"oxfmt --check","test-runtime-bun":"npm run build && bun test test/runtime/bun.test.ts","test-runtime-deno":"npm run build && deno test --no-check --allow-all test/runtime/deno.test.ts","test-runtime-node":"npm run build && node --test test/runtime/node.test.ts","test-runtime-fetch":"npm run build && node --test test/runtime/fetch.test.ts","test-runtime-cloudflare":"npm run build && node --test test/runtime/cloudflare/cloudflare.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:fc452f67-a66e-4659-85d9-ec27e436e544"}},"repository":{"url":"git+https://github.com/arcjet/arcjet-js.git","type":"git","directory":"arcjet-guard"},"_npmVersion":"11.16.0","description":"Arcjet Guards SDK — AI guardrails for rate limiting, prompt injection detection, and sensitive info detection","directories":{},"_nodeVersion":"24.18.0","dependencies":{"@arcjet/analyze":"1.9.1","@bufbuild/protobuf":"^2.0.0","@connectrpc/connect":"^2.0.0","@connectrpc/connect-web":"^2.0.0","@connectrpc/connect-node":"^2.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"oxfmt":"0.55.0","oxlint":"1.70.0","tsdown":"0.22.3","miniflare":"4.20260617.1","@types/node":"22.19.21","oxlint-tsgolint":"0.23.0","@typescript/native-preview":"7.0.0-dev.20260602.1"},"_npmOperationalInternal":{"tmp":"tmp/guard_1.9.1_1784156729542_0.10101331940733593","host":"s3://npm-registry-packages-npm-production"}},"1.10.0-rc.0":{"name":"@arcjet/guard","version":"1.10.0-rc.0","author":{"url":"https://arcjet.com","name":"Arcjet","email":"support@arcjet.com"},"license":"Apache-2.0","_id":"@arcjet/guard@1.10.0-rc.0","maintainers":[{"name":"quinn-arcjet","email":"quinn@arcjet.com"},{"name":"davidmytton","email":"david@arcjet.com"}],"homepage":"https://arcjet.com","bugs":{"url":"https://github.com/arcjet/arcjet-js/issues","email":"support@arcjet.com"},"dist":{"shasum":"f9d0c6ea583baa5db72783ee4ed051b8ed78b8e1","tarball":"https://registry.npmjs.org/@arcjet/guard/-/guard-1.10.0-rc.0.tgz","fileCount":66,"integrity":"sha512-r1zGQcnYyJrKHSw0ywZ5zc+iZGCsYkIWHnR6CBuiklENFfNvxAE8pNLIT3vmnWR50owTPoY145i10wRFRBoCCw==","signatures":[{"sig":"MEUCIQCxl+kPDCynOftDwBiBWw3ek8fFBqXjoFCXXXd1S/PnrwIgMeePCgcWvihPZYA82tKDQg4K9tsp1Z+huG3dSKmdB4g=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@arcjet%2fguard@1.10.0-rc.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":403211},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.21.0 <23 || >=24.5.0"},"exports":{".":{"bun":{"types":"./dist/bun.d.ts","import":"./dist/bun.js"},"deno":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"default":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"workerd":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"edge-light":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"}},"./bun":{"types":"./dist/bun.d.ts","import":"./dist/bun.js"},"./node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"./fetch":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"./vercel-ai/v7":{"types":"./dist/vercel-ai/v7/index.d.ts","import":"./dist/vercel-ai/v7/index.js"}},"gitHead":"57f76b7d4b0166c8a38e03077cb85076df930024","scripts":{"lint":"oxlint --tsconfig=tsconfig.lint.json","test":"npm run build && npm run lint && npm run test-unit","build":"tsdown","format":"oxfmt","test-unit":"node --test --experimental-test-coverage '--test-coverage-include=src/**' '--test-coverage-exclude=src/**/*.test.ts' 'src/**/*.test.ts'","typecheck":"tsc --noEmit && tsc --project tsconfig.lint.json --noEmit","format:check":"oxfmt --check","test-runtime-bun":"npm run build && bun test test/runtime/bun.test.ts","test-runtime-deno":"npm run build && deno test --no-check --allow-all test/runtime/deno.test.ts","test-runtime-node":"npm run build && node --test test/runtime/node.test.ts","test-runtime-fetch":"npm run build && node --test test/runtime/fetch.test.ts","test-runtime-cloudflare":"npm run build && node --test test/runtime/cloudflare/cloudflare.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:fc452f67-a66e-4659-85d9-ec27e436e544"}},"repository":{"url":"git+https://github.com/arcjet/arcjet-js.git","type":"git","directory":"arcjet-guard"},"_npmVersion":"12.0.1","description":"Arcjet Guards SDK — AI guardrails for rate limiting, prompt injection detection, and sensitive info detection","directories":{},"_nodeVersion":"24.18.0","dependencies":{"@arcjet/logger":"1.10.0-rc.0","@arcjet/analyze":"1.10.0-rc.0","@bufbuild/protobuf":"2.12.1","@connectrpc/connect":"2.1.2","@connectrpc/connect-web":"2.1.2","@connectrpc/connect-node":"2.1.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"ai":"7.0.36","tsdown":"0.22.7","miniflare":"4.20260708.1","typescript":"7.0.2","@types/node":"22.20.1","oxlint-tsgolint":"0.24.0","@ai-sdk/provider-utils":"5.0.12"},"peerDependencies":{"ai":">=7 <8","@ai-sdk/provider-utils":">=5 <6"},"peerDependenciesMeta":{"ai":{"optional":true},"@ai-sdk/provider-utils":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/guard_1.10.0-rc.0_1785871762321_0.047715667428214426","host":"s3://npm-registry-packages-npm-production"}},"1.10.0-rc.1":{"name":"@arcjet/guard","version":"1.10.0-rc.1","author":{"url":"https://arcjet.com","name":"Arcjet","email":"support@arcjet.com"},"license":"Apache-2.0","_id":"@arcjet/guard@1.10.0-rc.1","maintainers":[{"name":"quinn-arcjet","email":"quinn@arcjet.com"},{"name":"davidmytton","email":"david@arcjet.com"}],"homepage":"https://arcjet.com","bugs":{"url":"https://github.com/arcjet/arcjet-js/issues","email":"support@arcjet.com"},"dist":{"shasum":"f4c94d5162f793acf38db54bd1910c421d20250e","tarball":"https://registry.npmjs.org/@arcjet/guard/-/guard-1.10.0-rc.1.tgz","fileCount":99,"integrity":"sha512-qNaa0aN1GFuB8yDKfjezEos3/lTStY3kM5N+SKWsi3KdNto/8mDxK946joVULfKa2QVIbpUkS6Hivz1PbAIIlg==","signatures":[{"sig":"MEUCIQCSa373EzVLh+8bn5PYbX/OKXeMKBTdEiN31c28nfJKqAIgB6v8oePAivOPlivuZFurh7Tffd7osIO2CatvoR9ZVEI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@arcjet%2fguard@1.10.0-rc.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":617470},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.21.0 <23 || >=24.5.0"},"exports":{".":{"bun":{"types":"./dist/bun.d.ts","import":"./dist/bun.js"},"deno":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"default":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"workerd":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"edge-light":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"}},"./bun":{"types":"./dist/bun.d.ts","import":"./dist/bun.js"},"./node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"./fetch":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"./testing":{"types":"./dist/testing/index.d.ts","import":"./dist/testing/index.js"},"./vercel-ai/v7":{"types":"./dist/vercel-ai/v7/index.d.ts","import":"./dist/vercel-ai/v7/index.js"},"./vercel-eve/v0":{"types":"./dist/vercel-eve/v0/index.d.ts","import":"./dist/vercel-eve/v0/index.js"}},"gitHead":"bb916156cbb94ec6f730ade5fc77f837d8f7b795","scripts":{"lint":"oxlint --tsconfig=tsconfig.lint.json","test":"npm run build && npm run lint && npm run test-unit","build":"tsdown","format":"oxfmt","test-unit":"node --test --experimental-test-coverage '--test-coverage-include=src/**' '--test-coverage-exclude=src/**/*.test.ts' 'src/**/*.test.ts'","typecheck":"tsc --noEmit && tsc --project tsconfig.lint.json --noEmit","format:check":"oxfmt --check","test-runtime-bun":"npm run build && bun test test/runtime/bun.test.ts","test-runtime-deno":"npm run build && deno test --no-check --allow-all test/runtime/deno.test.ts","test-runtime-node":"npm run build && node --test test/runtime/node.test.ts","test-runtime-fetch":"npm run build && node --test test/runtime/fetch.test.ts","test-runtime-cloudflare":"npm run build && node --test test/runtime/cloudflare/cloudflare.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:fc452f67-a66e-4659-85d9-ec27e436e544"}},"repository":{"url":"git+https://github.com/arcjet/arcjet-js.git","type":"git","directory":"arcjet-guard"},"_npmVersion":"12.0.1","description":"Arcjet Guards SDK — AI guardrails for rate limiting, prompt injection detection, and sensitive info detection","directories":{},"_nodeVersion":"24.18.0","dependencies":{"@arcjet/logger":"1.10.0-rc.1","@arcjet/analyze":"1.10.0-rc.1","@bufbuild/protobuf":"2.12.1","@connectrpc/connect":"2.1.2","@connectrpc/connect-web":"2.1.2","@connectrpc/connect-node":"2.1.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"ai":"7.0.38","eve":"0.31.0","tsdown":"0.22.7","miniflare":"4.20260708.1","typescript":"7.0.2","@types/node":"22.20.1","oxlint-tsgolint":"0.24.0","@ai-sdk/provider-utils":"5.0.13"},"peerDependencies":{"ai":">=7 <8","eve":">=0.25.1 <1","@ai-sdk/provider-utils":">=5 <6"},"peerDependenciesMeta":{"ai":{"optional":true},"eve":{"optional":true},"@ai-sdk/provider-utils":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/guard_1.10.0-rc.1_1786129638778_0.8867191344823384","host":"s3://npm-registry-packages-npm-production"}},"1.10.0":{"name":"@arcjet/guard","version":"1.10.0","author":{"url":"https://arcjet.com","name":"Arcjet","email":"support@arcjet.com"},"license":"Apache-2.0","_id":"@arcjet/guard@1.10.0","maintainers":[{"name":"quinn-arcjet","email":"quinn@arcjet.com"},{"name":"davidmytton","email":"david@arcjet.com"}],"homepage":"https://arcjet.com","bugs":{"url":"https://github.com/arcjet/arcjet-js/issues","email":"support@arcjet.com"},"dist":{"shasum":"e814dbf406dae8982692b0ed39222da1d45cbe8b","tarball":"https://registry.npmjs.org/@arcjet/guard/-/guard-1.10.0.tgz","fileCount":99,"integrity":"sha512-lQv0Qy46GQozCFWHcqn1XngY/3uSa3H3G17kaIfWXjTah5Bn68KI+xS+qzaMN+saYbhG1h8idknJqERjd2LBqw==","signatures":[{"sig":"MEQCICnn7rYWOpQO8jwy2d06FrzUOfM+Nheqm1PVvyld/7ryAiBl9wUNrIXG+PC800bgRu+e4HtjWG1YZipGeOluL6RJEQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@arcjet%2fguard@1.10.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":627795},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.21.0 <23 || >=24.5.0"},"exports":{".":{"bun":{"types":"./dist/bun.d.ts","import":"./dist/bun.js"},"deno":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"default":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"workerd":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"edge-light":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"}},"./bun":{"types":"./dist/bun.d.ts","import":"./dist/bun.js"},"./node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"./fetch":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"./testing":{"types":"./dist/testing/index.d.ts","import":"./dist/testing/index.js"},"./vercel-ai/v7":{"types":"./dist/vercel-ai/v7/index.d.ts","import":"./dist/vercel-ai/v7/index.js"},"./vercel-eve/v0":{"types":"./dist/vercel-eve/v0/index.d.ts","import":"./dist/vercel-eve/v0/index.js"}},"gitHead":"a370d371a655f37392c22bbd78f93468ea819558","scripts":{"lint":"oxlint --tsconfig=tsconfig.lint.json","test":"npm run build && npm run lint && npm run test-unit","build":"tsdown","format":"oxfmt","test-unit":"node --test --experimental-test-coverage '--test-coverage-include=src/**' '--test-coverage-exclude=src/**/*.test.ts' 'src/**/*.test.ts'","typecheck":"tsc --noEmit && tsc --project tsconfig.lint.json --noEmit","format:check":"oxfmt --check","test-runtime-bun":"npm run build && bun test test/runtime/bun.test.ts","test-runtime-deno":"npm run build && deno test --no-check --allow-all test/runtime/deno.test.ts","test-runtime-node":"npm run build && node --test test/runtime/node.test.ts","test-runtime-fetch":"npm run build && node --test test/runtime/fetch.test.ts","test-runtime-cloudflare":"npm run build && node --test test/runtime/cloudflare/cloudflare.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:fc452f67-a66e-4659-85d9-ec27e436e544"}},"repository":{"url":"git+https://github.com/arcjet/arcjet-js.git","type":"git","directory":"arcjet-guard"},"_npmVersion":"12.0.1","description":"Arcjet Guards SDK — AI guardrails for rate limiting, prompt injection detection, and sensitive info detection","directories":{},"_nodeVersion":"24.18.0","dependencies":{"@arcjet/logger":"1.10.0","@arcjet/analyze":"1.10.0","@bufbuild/protobuf":"2.12.1","@connectrpc/connect":"2.1.2","@connectrpc/connect-web":"2.1.2","@connectrpc/connect-node":"2.1.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ai":"7.0.38","eve":"0.31.0","tsdown":"0.22.7","miniflare":"4.20260708.1","typescript":"7.0.2","@types/node":"22.20.1","oxlint-tsgolint":"0.24.0","@ai-sdk/provider-utils":"5.0.13"},"peerDependencies":{"ai":">=7 <8","eve":">=0.25.1 <1","@ai-sdk/provider-utils":">=5 <6"},"peerDependenciesMeta":{"ai":{"optional":true},"eve":{"optional":true},"@ai-sdk/provider-utils":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/guard_1.10.0_1786475757027_0.4444483207622756","host":"s3://npm-registry-packages-npm-production"}},"1.11.0":{"name":"@arcjet/guard","version":"1.11.0","author":{"url":"https://arcjet.com","name":"Arcjet","email":"support@arcjet.com"},"license":"Apache-2.0","_id":"@arcjet/guard@1.11.0","maintainers":[{"name":"quinn-arcjet","email":"quinn@arcjet.com"},{"name":"davidmytton","email":"david@arcjet.com"}],"homepage":"https://arcjet.com","bugs":{"url":"https://github.com/arcjet/arcjet-js/issues","email":"support@arcjet.com"},"dist":{"shasum":"9957da5d3520abfdb93d1f0b3be29f4ed77c7fc2","tarball":"https://registry.npmjs.org/@arcjet/guard/-/guard-1.11.0.tgz","fileCount":168,"integrity":"sha512-NuCf2XCIcKWqCkTuR/8ZpN9/TSvFjh9xINeShBZg6p/inXlTDigaEwVWLMzjnkW6KeBqQZ+aM4Umc71Q9UE+MQ==","signatures":[{"sig":"MEYCIQDM1dkJ2Tr6WjLRXmbjsKhF7ythAzu0EbAt8vntuXB+bQIhAOO2lYI2R2gXE033ns3ZeinNcexuSZt8RshZsnTWv8RL","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@arcjet%2fguard@1.11.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1003555},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.21.0 <23 || >=24.5.0"},"exports":{".":{"bun":{"types":"./dist/bun.d.ts","import":"./dist/bun.js"},"deno":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"default":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"workerd":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"edge-light":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"}},"./bun":{"types":"./dist/bun.d.ts","import":"./dist/bun.js"},"./node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"./fetch":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"./testing":{"types":"./dist/testing/index.d.ts","import":"./dist/testing/index.js"},"./genkit/v1":{"types":"./dist/genkit/v1/index.d.ts","import":"./dist/genkit/v1/index.js"},"./mastra/v1":{"types":"./dist/mastra/v1/index.d.ts","import":"./dist/mastra/v1/index.js"},"./langchain/v1":{"types":"./dist/langchain/v1/index.d.ts","import":"./dist/langchain/v1/index.js"},"./langgraph/v1":{"types":"./dist/langgraph/v1/index.d.ts","import":"./dist/langgraph/v1/index.js"},"./package.json":"./package.json","./vercel-ai/v7":{"types":"./dist/vercel-ai/v7/index.d.ts","import":"./dist/vercel-ai/v7/index.js"},"./vercel-eve/v0":{"types":"./dist/vercel-eve/v0/index.d.ts","import":"./dist/vercel-eve/v0/index.js"},"./openai-agents/v0":{"types":"./dist/openai-agents/v0/index.d.ts","import":"./dist/openai-agents/v0/index.js"},"./strands-agents/v1":{"types":"./dist/strands-agents/v1/index.d.ts","import":"./dist/strands-agents/v1/index.js"},"./claude-agent-sdk/v0":{"types":"./dist/claude-agent-sdk/v0/index.d.ts","import":"./dist/claude-agent-sdk/v0/index.js"}},"gitHead":"a7f6e95bd6780213facaa8f37bc96984f2993368","scripts":{"lint":"oxlint --tsconfig=tsconfig.lint.json","test":"npm run build && npm run lint && npm run test-unit","build":"tsdown","format":"oxfmt","test-unit":"node --test --experimental-test-coverage '--test-coverage-include=src/**' '--test-coverage-exclude=src/**/*.test.ts' 'src/**/*.test.ts' 'test/genkit/**/*.test.ts' 'test/langchain/**/*.test.ts' 'test/langgraph/**/*.test.ts' 'test/mastra/**/*.test.ts' 'test/openai-agents/**/*.test.ts' 'test/strands-agents/**/*.test.ts'","typecheck":"tsc --noEmit && tsc --project tsconfig.lint.json --noEmit","format:check":"oxfmt --check","test-runtime-bun":"npm run build && bun test test/runtime/bun.test.ts","test-peers-absent":"node scripts/test-peers-absent.mjs","test-runtime-deno":"npm run build && deno test --no-check --allow-all test/runtime/deno.test.ts","test-runtime-node":"npm run build && node --test test/runtime/node.test.ts","test-runtime-fetch":"npm run build && node --test test/runtime/fetch.test.ts","test-runtime-cloudflare":"npm run build && node --test test/runtime/cloudflare/cloudflare.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:fc452f67-a66e-4659-85d9-ec27e436e544"}},"repository":{"url":"git+https://github.com/arcjet/arcjet-js.git","type":"git","directory":"arcjet-guard"},"_npmVersion":"12.0.1","description":"Arcjet Guards SDK — AI guardrails for rate limiting, prompt injection detection, and sensitive info detection","directories":{},"_nodeVersion":"24.19.0","dependencies":{"@arcjet/logger":"1.11.0","@arcjet/analyze":"1.11.0","@bufbuild/protobuf":"2.14.0","@connectrpc/connect":"2.1.2","@connectrpc/connect-web":"2.1.2","@connectrpc/connect-node":"2.1.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ai":"7.0.58","eve":"0.39.0","genkit":"1.41.0","tsdown":"0.22.14","langchain":"1.5.10","miniflare":"4.20260730.0","typescript":"7.0.2","@types/node":"22.20.1","@mastra/core":"1.59.0","@openai/agents":"0.17.0","@langchain/core":"1.2.9","oxlint-tsgolint":"0.24.0","@strands-agents/sdk":"1.14.0","@langchain/langgraph":"1.4.10","@ai-sdk/provider-utils":"5.0.25","@anthropic-ai/claude-agent-sdk":"0.3.233"},"peerDependencies":{"ai":">=7 <8","eve":">=0.34.0 <1","genkit":">=1.0.0 <2","langchain":">=1.2.0 <2","@mastra/core":">=1 <2","@openai/agents":">=0.17.0 <1","@langchain/core":">=1 <2","@strands-agents/sdk":">=1.1.0 <2","@langchain/langgraph":">=1 <2","@ai-sdk/provider-utils":">=5 <6","@anthropic-ai/claude-agent-sdk":">=0.1.0 <1"},"peerDependenciesMeta":{"ai":{"optional":true},"eve":{"optional":true},"genkit":{"optional":true},"langchain":{"optional":true},"@mastra/core":{"optional":true},"@openai/agents":{"optional":true},"@langchain/core":{"optional":true},"@strands-agents/sdk":{"optional":true},"@langchain/langgraph":{"optional":true},"@ai-sdk/provider-utils":{"optional":true},"@anthropic-ai/claude-agent-sdk":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/guard_1.11.0_1787767129473_0.2668959229015877","host":"s3://npm-registry-packages-npm-production"}},"1.12.0":{"name":"@arcjet/guard","version":"1.12.0","keywords":["ai","arcjet","guard","security","tanstack-intent"],"author":{"url":"https://arcjet.com","name":"Arcjet","email":"support@arcjet.com"},"license":"Apache-2.0","_id":"@arcjet/guard@1.12.0","maintainers":[{"name":"quinn-arcjet","email":"quinn@arcjet.com"},{"name":"davidmytton","email":"david@arcjet.com"}],"homepage":"https://arcjet.com","bugs":{"url":"https://github.com/arcjet/arcjet-js/issues","email":"support@arcjet.com"},"dist":{"shasum":"911521a396266d6cf31d9b29f7cd3526e5977b99","tarball":"https://registry.npmjs.org/@arcjet/guard/-/guard-1.12.0.tgz","fileCount":195,"integrity":"sha512-9Jc6wUg1IwNR6qq0GmDMAYI/kxy3eAvp0fojsrz3CmJ42SUA+HkDWQnkXyatyCxmYADGpjC9cAeqLrwwtQoLNw==","signatures":[{"sig":"MEYCIQD4dfPfKoZCG9L6WUbhIrk4POb8h3cq3F2AahlNkoQbXwIhAJDtU5QxYmmfJm6OD/5xOBDy7xpOsfJaFcxIYZSztJP3","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1145867},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.21.0 <23 || >=24.5.0"},"exports":{".":{"bun":{"types":"./dist/bun.d.ts","import":"./dist/bun.js"},"deno":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"default":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"workerd":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"edge-light":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"}},"./bun":{"types":"./dist/bun.d.ts","import":"./dist/bun.js"},"./node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"./fetch":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"./testing":{"types":"./dist/testing/index.d.ts","import":"./dist/testing/index.js"},"./genkit/v1":{"types":"./dist/genkit/v1/index.d.ts","import":"./dist/genkit/v1/index.js"},"./mastra/v1":{"types":"./dist/mastra/v1/index.d.ts","import":"./dist/mastra/v1/index.js"},"./langchain/v1":{"types":"./dist/langchain/v1/index.d.ts","import":"./dist/langchain/v1/index.js"},"./langgraph/v1":{"types":"./dist/langgraph/v1/index.d.ts","import":"./dist/langgraph/v1/index.js"},"./package.json":"./package.json","./vercel-ai/v7":{"types":"./dist/vercel-ai/v7/index.d.ts","import":"./dist/vercel-ai/v7/index.js"},"./google-adk/v2":{"types":"./dist/google-adk/v2/index.d.ts","import":"./dist/google-adk/v2/index.js"},"./vercel-eve/v0":{"types":"./dist/vercel-eve/v0/index.d.ts","import":"./dist/vercel-eve/v0/index.js"},"./tanstack-ai/v0":{"types":"./dist/tanstack-ai/v0/index.d.ts","import":"./dist/tanstack-ai/v0/index.js"},"./openai-agents/v0":{"types":"./dist/openai-agents/v0/index.d.ts","import":"./dist/openai-agents/v0/index.js"},"./strands-agents/v1":{"types":"./dist/strands-agents/v1/index.d.ts","import":"./dist/strands-agents/v1/index.js"},"./claude-agent-sdk/v0":{"types":"./dist/claude-agent-sdk/v0/index.d.ts","import":"./dist/claude-agent-sdk/v0/index.js"},"./claude-managed-agents/v0":{"types":"./dist/claude-managed-agents/v0/index.d.ts","import":"./dist/claude-managed-agents/v0/index.js"}},"scripts":{"lint":"oxlint --tsconfig=tsconfig.lint.json","test":"npm run build && npm run lint && npm run test-unit","build":"tsdown","format":"oxfmt","test-unit":"node --test --experimental-test-coverage '--test-coverage-include=src/**' '--test-coverage-exclude=src/**/*.test.ts' 'src/**/*.test.ts' 'test/genkit/**/*.test.ts' 'test/google-adk/**/*.test.ts' 'test/langchain/**/*.test.ts' 'test/langgraph/**/*.test.ts' 'test/mastra/**/*.test.ts' 'test/openai-agents/**/*.test.ts' 'test/strands-agents/**/*.test.ts' 'test/tanstack-ai/**/*.test.ts'","typecheck":"tsc --noEmit && tsc --project tsconfig.lint.json --noEmit","format:check":"oxfmt --check","stale-skills":"node ../.github/scripts/intent-cli.mjs stale --json","validate-skills":"node ../.github/scripts/intent-cli.mjs validate","test-runtime-bun":"npm run build && bun test test/runtime/bun.test.ts","test-peers-absent":"node scripts/test-peers-absent.mjs","test-runtime-deno":"npm run build && deno test --no-check --allow-all test/runtime/deno.test.ts","test-runtime-node":"npm run build && node --test test/runtime/node.test.ts","test-runtime-fetch":"npm run build && node --test test/runtime/fetch.test.ts","test-runtime-cloudflare":"npm run build && node --test test/runtime/cloudflare/cloudflare.test.ts"},"_npmUser":{"name":"quinn-arcjet","email":"quinn@arcjet.com"},"repository":{"url":"git+https://github.com/arcjet/arcjet-js.git","type":"git","directory":"arcjet-guard"},"_npmVersion":"12.0.1","description":"Arcjet Guards SDK — AI guardrails for rate limiting, prompt injection detection, and sensitive info detection","directories":{},"_nodeVersion":"24.20.0","dependencies":{"@arcjet/logger":"1.12.0","@arcjet/analyze":"1.12.0","@arcjet/transport":"1.12.0","@bufbuild/protobuf":"2.14.0","@connectrpc/connect":"2.1.2","@connectrpc/connect-web":"2.1.2","@connectrpc/connect-node":"2.1.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ai":"7.0.58","eve":"0.46.0","genkit":"1.41.0","tsdown":"0.22.14","langchain":"1.5.10","miniflare":"4.20260730.0","typescript":"7.0.2","@google/adk":"2.0.0","@types/node":"22.20.1","@mastra/core":"1.59.0","@tanstack/ai":"0.52.0","@openai/agents":"0.17.0","@langchain/core":"1.2.9","oxlint-tsgolint":"0.24.0","@tanstack/intent":"0.3.8","@anthropic-ai/sdk":"0.123.0","@strands-agents/sdk":"1.14.0","@langchain/langgraph":"1.4.10","@ai-sdk/provider-utils":"5.0.25","@modelcontextprotocol/sdk":"1.30.0","@anthropic-ai/claude-agent-sdk":"0.3.233"},"peerDependencies":{"ai":">=7 <8","eve":">=0.34.0 <1","genkit":">=1.0.0 <2","langchain":">=1.2.0 <2","@google/adk":">=2 <3","@mastra/core":">=1 <2","@tanstack/ai":">=0.8.0 <1","@openai/agents":">=0.17.0 <1","@langchain/core":">=1 <2","@anthropic-ai/sdk":">=0.86.0 <1","@strands-agents/sdk":">=1.1.0 <2","@langchain/langgraph":">=1 <2","@ai-sdk/provider-utils":">=5 <6","@anthropic-ai/claude-agent-sdk":">=0.1.0 <1"},"peerDependenciesMeta":{"ai":{"optional":true},"eve":{"optional":true},"genkit":{"optional":true},"langchain":{"optional":true},"@google/adk":{"optional":true},"@mastra/core":{"optional":true},"@tanstack/ai":{"optional":true},"@openai/agents":{"optional":true},"@langchain/core":{"optional":true},"@anthropic-ai/sdk":{"optional":true},"@strands-agents/sdk":{"optional":true},"@langchain/langgraph":{"optional":true},"@ai-sdk/provider-utils":{"optional":true},"@anthropic-ai/claude-agent-sdk":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/guard_1.12.0_1788888125339_0.10880475279503665","host":"s3://npm-registry-packages-npm-production"}},"1.13.0":{"name":"@arcjet/guard","version":"1.13.0","description":"Arcjet Guards SDK — AI guardrails for rate limiting, prompt injection detection, and sensitive info detection","keywords":["ai","arcjet","guard","security","tanstack-intent"],"homepage":"https://arcjet.com","bugs":{"url":"https://github.com/arcjet/arcjet-js/issues","email":"support@arcjet.com"},"license":"Apache-2.0","author":{"name":"Arcjet","email":"support@arcjet.com","url":"https://arcjet.com"},"repository":{"type":"git","url":"git+https://github.com/arcjet/arcjet-js.git","directory":"arcjet-guard"},"type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"bun":{"types":"./dist/bun.d.ts","import":"./dist/bun.js"},"edge-light":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"workerd":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"deno":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"default":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"}},"./node":{"types":"./dist/node.d.ts","import":"./dist/node.js"},"./bun":{"types":"./dist/bun.d.ts","import":"./dist/bun.js"},"./fetch":{"types":"./dist/fetch.d.ts","import":"./dist/fetch.js"},"./testing":{"types":"./dist/testing/index.d.ts","import":"./dist/testing/index.js"},"./vercel-ai/v7":{"types":"./dist/vercel-ai/v7/index.d.ts","import":"./dist/vercel-ai/v7/index.js"},"./vercel-eve/v0":{"types":"./dist/vercel-eve/v0/index.d.ts","import":"./dist/vercel-eve/v0/index.js"},"./mastra/v1":{"types":"./dist/mastra/v1/index.d.ts","import":"./dist/mastra/v1/index.js"},"./claude-agent-sdk/v0":{"types":"./dist/claude-agent-sdk/v0/index.d.ts","import":"./dist/claude-agent-sdk/v0/index.js"},"./claude-managed-agents/v0":{"types":"./dist/claude-managed-agents/v0/index.d.ts","import":"./dist/claude-managed-agents/v0/index.js"},"./langchain/v1":{"types":"./dist/langchain/v1/index.d.ts","import":"./dist/langchain/v1/index.js"},"./langgraph/v1":{"types":"./dist/langgraph/v1/index.d.ts","import":"./dist/langgraph/v1/index.js"},"./openai-agents/v0":{"types":"./dist/openai-agents/v0/index.d.ts","import":"./dist/openai-agents/v0/index.js"},"./genkit/v1":{"types":"./dist/genkit/v1/index.d.ts","import":"./dist/genkit/v1/index.js"},"./google-adk/v2":{"types":"./dist/google-adk/v2/index.d.ts","import":"./dist/google-adk/v2/index.js"},"./strands-agents/v1":{"types":"./dist/strands-agents/v1/index.d.ts","import":"./dist/strands-agents/v1/index.js"},"./tanstack-ai/v0":{"types":"./dist/tanstack-ai/v0/index.d.ts","import":"./dist/tanstack-ai/v0/index.js"},"./package.json":"./package.json"},"publishConfig":{"access":"public"},"scripts":{"build":"tsdown","typecheck":"tsc --noEmit && tsc --project tsconfig.lint.json --noEmit","lint":"oxlint --tsconfig=tsconfig.lint.json","format":"oxfmt","format:check":"oxfmt --check","test":"npm run build && npm run lint && npm run test-unit","test-unit":"node --test --experimental-test-coverage '--test-coverage-include=src/**' '--test-coverage-exclude=src/**/*.test.ts' 'src/**/*.test.ts' 'test/genkit/**/*.test.ts' 'test/google-adk/**/*.test.ts' 'test/langchain/**/*.test.ts' 'test/langgraph/**/*.test.ts' 'test/mastra/**/*.test.ts' 'test/openai-agents/**/*.test.ts' 'test/strands-agents/**/*.test.ts' 'test/tanstack-ai/**/*.test.ts'","validate-skills":"node ../.github/scripts/intent-cli.mjs validate","stale-skills":"node ../.github/scripts/intent-cli.mjs stale --json","test-peers-absent":"node scripts/test-peers-absent.mjs","test-runtime-node":"npm run build && node --test test/runtime/node.test.ts","test-runtime-fetch":"npm run build && node --test test/runtime/fetch.test.ts","test-runtime-deno":"npm run build && deno test --no-check --allow-all test/runtime/deno.test.ts","test-runtime-bun":"npm run build && bun test test/runtime/bun.test.ts","test-runtime-cloudflare":"npm run build && node --test test/runtime/cloudflare/cloudflare.test.ts"},"dependencies":{"@arcjet/analyze":"1.13.0","@arcjet/logger":"1.13.0","@arcjet/transport":"1.13.0","@bufbuild/protobuf":"2.14.1","@connectrpc/connect":"2.2.0","@connectrpc/connect-node":"2.2.0","@connectrpc/connect-web":"2.2.0"},"devDependencies":{"@ai-sdk/provider-utils":"5.0.25","@anthropic-ai/claude-agent-sdk":"0.3.233","@anthropic-ai/sdk":"0.123.0","@google/adk":"2.0.0","@langchain/core":"1.2.9","@langchain/langgraph":"1.4.10","@mastra/core":"1.59.0","@modelcontextprotocol/sdk":"1.30.0","@openai/agents":"0.17.0","@strands-agents/sdk":"1.14.0","@tanstack/ai":"0.52.0","@tanstack/intent":"0.4.0","@types/node":"22.20.1","ai":"7.0.58","eve":"0.46.0","genkit":"1.41.0","langchain":"1.5.10","miniflare":"4.20260730.0","oxlint-tsgolint":"7.0.2001","tsdown":"0.23.0","typescript":"7.0.2"},"peerDependencies":{"@ai-sdk/provider-utils":">=5 <6","@anthropic-ai/claude-agent-sdk":">=0.1.0 <1","@anthropic-ai/sdk":">=0.86.0 <1","@google/adk":">=2 <3","@langchain/core":">=1 <2","@langchain/langgraph":">=1 <2","@mastra/core":">=1 <2","@openai/agents":">=0.17.0 <1","@strands-agents/sdk":">=1.1.0 <2","@tanstack/ai":">=0.8.0 <1","ai":">=7 <8","eve":">=0.34.0 <1","genkit":">=1.0.0 <2","langchain":">=1.2.0 <2"},"peerDependenciesMeta":{"@ai-sdk/provider-utils":{"optional":true},"ai":{"optional":true},"eve":{"optional":true},"@mastra/core":{"optional":true},"@anthropic-ai/claude-agent-sdk":{"optional":true},"@anthropic-ai/sdk":{"optional":true},"@google/adk":{"optional":true},"@langchain/core":{"optional":true},"@langchain/langgraph":{"optional":true},"langchain":{"optional":true},"@openai/agents":{"optional":true},"genkit":{"optional":true},"@strands-agents/sdk":{"optional":true},"@tanstack/ai":{"optional":true}},"engines":{"node":">=22.21.0 <23 || >=24.5.0"},"gitHead":"894bb9d3741f19b3306b986e869ca4ea8e42be71","_id":"@arcjet/guard@1.13.0","_nodeVersion":"24.20.0","_npmVersion":"12.0.2","dist":{"integrity":"sha512-qjzsh1dRFEt84EC9fPFUg1Uhx75k2rcstPw26cpwcoewgM48f3AsILkYbWo9AKiWPHpMUI6ddOHcpgZTmXNb3w==","shasum":"ffcd56f29ce079e93715c8ea9ffcf0cd9f7e4e9f","tarball":"https://registry.npmjs.org/@arcjet/guard/-/guard-1.13.0.tgz","fileCount":398,"unpackedSize":2153996,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@arcjet%2fguard@1.13.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIE4lWHHxPz9JvvU/R8ATgU77tY1yp0FEZTZ85ueQDJG5AiBt/fYQ77dR1B/1GSGawahh8ckJt62mJ5moX/6/6dMa8Q=="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:fc452f67-a66e-4659-85d9-ec27e436e544"}},"directories":{},"maintainers":[{"name":"quinn-arcjet","email":"quinn@arcjet.com"},{"name":"davidmytton","email":"david@arcjet.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/guard_1.13.0_1789601306507_0.147701559790411"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-31T16:47:09.154Z","modified":"2026-09-16T23:28:26.990Z","0.1.0-experimental.0":"2026-03-31T16:47:09.443Z","0.1.0-experimental.1":"2026-04-06T18:19:48.854Z","0.1.0-experimental.2":"2026-04-07T21:24:12.276Z","1.4.0":"2026-04-14T20:05:14.597Z","1.5.0":"2026-06-09T16:24:12.526Z","1.6.0":"2026-06-30T19:38:40.395Z","1.6.1":"2026-06-30T21:57:22.739Z","1.7.0-rc.0":"2026-07-03T23:09:17.361Z","1.7.0-rc.1":"2026-07-06T16:23:23.091Z","1.7.0":"2026-07-06T17:07:20.650Z","1.8.0-rc.0":"2026-07-07T17:56:13.740Z","1.8.0":"2026-07-07T18:22:50.972Z","1.9.0":"2026-07-15T21:57:10.009Z","1.9.1":"2026-07-15T23:05:29.702Z","1.10.0-rc.0":"2026-08-04T19:29:22.475Z","1.10.0-rc.1":"2026-08-07T19:07:18.976Z","1.10.0":"2026-08-11T19:15:57.222Z","1.11.0":"2026-08-26T17:58:49.685Z","1.12.0":"2026-09-08T17:22:05.494Z","1.13.0":"2026-09-16T23:28:26.691Z"},"bugs":{"url":"https://github.com/arcjet/arcjet-js/issues","email":"support@arcjet.com"},"author":{"name":"Arcjet","email":"support@arcjet.com","url":"https://arcjet.com"},"license":"Apache-2.0","homepage":"https://arcjet.com","keywords":["ai","arcjet","guard","security","tanstack-intent"],"repository":{"type":"git","url":"git+https://github.com/arcjet/arcjet-js.git","directory":"arcjet-guard"},"description":"Arcjet Guards SDK — AI guardrails for rate limiting, prompt injection detection, and sensitive info detection","maintainers":[{"name":"quinn-arcjet","email":"quinn@arcjet.com"},{"name":"davidmytton","email":"david@arcjet.com"}],"readme":"<a href=\"https://arcjet.com\" target=\"_arcjet-home\">\n  <picture>\n    <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://arcjet.com/logo/arcjet-dark-lockup-voyage-horizontal.svg\">\n    <img src=\"https://arcjet.com/logo/arcjet-light-lockup-voyage-horizontal.svg\" alt=\"Arcjet Logo\" height=\"128\" width=\"auto\">\n  </picture>\n</a>\n\n# `@arcjet/guard`\n\n<p>\n  <a href=\"https://www.npmjs.com/package/@arcjet/guard\">\n    <picture>\n      <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://img.shields.io/npm/v/%40arcjet%2Fguard?style=flat-square&label=%E2%9C%A6Aj&labelColor=000000&color=5C5866\">\n      <img alt=\"npm badge\" src=\"https://img.shields.io/npm/v/%40arcjet%2Fguard?style=flat-square&label=%E2%9C%A6Aj&labelColor=ECE6F0&color=ECE6F0\">\n    </picture>\n  </a>\n</p>\n\n[Arcjet][arcjet] is the runtime security platform that ships in your AI code. Detect prompt injection, authorize agent tool calls, redact sensitive data, and block bots and abuse. Real-time security building blocks you call inside your app, before an action happens.\n\nThis is the [Arcjet][arcjet] Guards SDK for **non-request protection** — use it\nfor AI agent tool calls, MCP server handlers, queue workers, background jobs,\nand anything else that doesn't have an HTTP request object. If you're protecting\nHTTP routes, use a [framework SDK](https://github.com/arcjet/arcjet-js#sdks)\nlike `@arcjet/next` or `@arcjet/node` instead.\n\n## Why Arcjet?\n\nYour app's AI features and agents take real actions, calling tools, reading data, hitting APIs. Arcjet runs inside that code and lets you enforce security on each action in real time, then audit what happened\n\n## Getting started\n\n### Quick setup with an AI agent\n\n1. Log in with the CLI:\n   ```sh\n   npx @arcjet/cli auth login\n   ```\n2. Install versioned Agent Skills so your coding agent matches this SDK:\n   ```sh\n   npx @tanstack/intent@latest install\n   ```\n3. Tell your agent what to protect — it handles the rest.\n\n### Manual setup\n\n1. **Log in** with the CLI (or at [`app.arcjet.com`](https://app.arcjet.com?utm_campaign=arcjet-js)):\n   ```sh\n   npx @arcjet/cli auth login\n   ```\n2. `npm install @arcjet/guard`\n3. Pass your key to `launchArcjet({ key: process.env.ARCJET_KEY! })`\n4. Add a guard to your code — see the [quick start](#quick-start) below\n\n[npm package](https://www.npmjs.com/package/@arcjet/guard) |\n[GitHub source](https://github.com/arcjet/arcjet-js/tree/main/arcjet-guard) |\n[Other SDKs][sdks-github]\n\n## Features\n\nGuards share some features with the request SDKs but are designed for\nnon-HTTP contexts. Here's what's available where:\n\n| Feature                         | Request SDKs | `@arcjet/guard` |\n| ------------------------------- | :----------: | :-------------: |\n| Rate Limiting                   |      ✅      |       ✅        |\n| Prompt Injection Detection      |      ✅      |       ✅        |\n| Content Moderation              |      —       |       ✅        |\n| Sensitive Information Detection |      ✅      |       ✅        |\n| Custom Rules                    |      —       |       ✅        |\n| Bot Protection                  |      ✅      |        —        |\n| Shield WAF                      |      ✅      |        —        |\n| Email Validation                |      ✅      |        —        |\n| Request Filters                 |      ✅      |        —        |\n| IP Analysis                     |      ✅      |        —        |\n\n- 🪣 [Rate Limiting](#rate-limiting) — token bucket, fixed window, and sliding\n  window algorithms; model AI token budgets per user.\n- 🛡️ [Prompt Injection Detection](#prompt-injection-detection) — detect and\n  block prompt injection attacks before they reach your LLM.\n- 🧹 [Content Moderation](#content-moderation) — detect and block harmful\n  content in user text, tool results, or model outputs.\n- 🕵️ [Sensitive Information Detection](#sensitive-information-detection) —\n  block PII, credit cards, and custom patterns from entering your AI pipeline.\n- 🔧 [Custom Rules](#custom-rules) — define your own local evaluation logic\n  with arbitrary data.\n\n## Quick start\n\nThis example protects an AI tool call with token bucket rate limiting and\nprompt injection detection.\n\n```ts\nimport { launchArcjet, tokenBucket, detectPromptInjection, policyInput } from \"@arcjet/guard\";\n\n// Create the Arcjet client once at module scope\nconst arcjet = launchArcjet({ key: process.env.ARCJET_KEY! });\n\n// Configure reusable rules\nconst limitRule = tokenBucket({ refillRate: 10, intervalSeconds: 60, maxTokens: 100 });\nconst piRule = detectPromptInjection();\n\n// Per request — create rule inputs each time\nconst rl = limitRule({ key: userId, requested: tokenCount });\nconst decision = await arcjet.guard({\n  label: \"tools.weather\",\n  rules: [rl, piRule(userMessage)],\n});\n\n// Overall decision\nif (decision.conclusion === \"DENY\") {\n  if (decision.reason === \"RATE_LIMIT\") {\n    throw new Error(\"Rate limited — try again later\");\n  }\n  if (decision.reason === \"PROMPT_INJECTION\") {\n    throw new Error(\"Prompt injection detected — please rephrase\");\n  }\n  throw new Error(\"Request denied\");\n}\n\n// Check for failures (fail-open — errors don't cause denials). hasFailedOpen()\n// is true only when the conclusion is ALLOW because a rule or the decision\n// could not be processed — gate a fail-closed policy on it.\nif (decision.hasFailedOpen()) {\n  console.warn(\"Allowed only because evaluation failed open\", decision.errorResults());\n}\n\n// Remotely configured policies use explicit typed inputs. SERVER values are\n// evaluated and retained by Arcjet; LOCAL values remain in SDK memory.\nconst policyDecision = await arcjet.guard({\n  label: \"email.sent\",\n  actor: userId,\n  inputs: {\n    recipient: policyInput.server.string(to),\n    subject: policyInput.local.string(subject),\n  },\n});\n\n// Remote results are keyed by policy/rule identity and remain separate from\n// positional SDK rule results.\nconsole.log(policyDecision.policyEvaluation, policyDecision.policyResults);\n\n// Decision-level diagnostics (e.g. an invalid metadata key that was stripped).\n// Warnings never change the conclusion.\nfor (const warning of decision.warnings) {\n  console.warn(`${warning.code}: ${warning.message}`);\n}\n\n// From a RuleWithInput — result for this specific submission\nconst r = rl.result(decision);\nif (r) {\n  console.log(r.remainingTokens, r.maxTokens);\n}\n\n// From a RuleWithConfig — first denied result across all submissions\nconst denied = limitRule.deniedResult(decision);\nif (denied) {\n  console.log(denied.remainingTokens); // 0\n}\n\n// Proceed with your AI tool call...\n```\n\n## Rate limiting\n\n### Token bucket\n\nUse this when requests have variable cost — for example, an LLM endpoint\nwhere each call consumes a different number of tokens. The bucket refills at\na steady rate and allows bursts up to `maxTokens`.\n\n```ts\nimport { launchArcjet, tokenBucket } from \"@arcjet/guard\";\n\nconst arcjet = launchArcjet({ key: process.env.ARCJET_KEY! });\n\nconst limitRule = tokenBucket({\n  bucket: \"user-tokens\", // Optional — defaults to \"default-token-bucket\"\n  refillRate: 2_000, // Refill 2,000 tokens per interval\n  intervalSeconds: 3600, // Refill every hour\n  maxTokens: 5_000, // Maximum 5,000 tokens in the bucket\n});\n\nconst decision = await arcjet.guard({\n  label: \"tools.chat\",\n  rules: [limitRule({ key: userId, requested: tokenEstimate })],\n});\n\nif (decision.conclusion === \"DENY\" && decision.reason === \"RATE_LIMIT\") {\n  throw new Error(\"Rate limit exceeded\");\n}\n```\n\n### Fixed window\n\nUse this when you need a hard cap per time period — the counter resets at\nthe end of each window. Simple to reason about, but allows bursts at\nwindow boundaries. If that matters, use sliding window instead.\n\n```ts\nimport { launchArcjet, fixedWindow } from \"@arcjet/guard\";\n\nconst arcjet = launchArcjet({ key: process.env.ARCJET_KEY! });\n\nconst limitRule = fixedWindow({\n  bucket: \"page-views\", // Optional — defaults to \"default-fixed-window\"\n  maxRequests: 1000, // Maximum requests per window\n  windowSeconds: 3600, // 1-hour window\n});\n\nconst decision = await arcjet.guard({\n  label: \"api.search\",\n  rules: [limitRule({ key: teamId })],\n});\n```\n\n### Sliding window\n\nUse this when you need smooth rate limiting without the burst-at-boundary\nproblem of fixed windows. The server interpolates between the previous and\ncurrent window, so limits are enforced across any rolling time span. Good\ndefault choice for API rate limits.\n\n```ts\nimport { launchArcjet, slidingWindow } from \"@arcjet/guard\";\n\nconst arcjet = launchArcjet({ key: process.env.ARCJET_KEY! });\n\nconst limitRule = slidingWindow({\n  bucket: \"event-writes\", // Optional — defaults to \"default-sliding-window\"\n  maxRequests: 500, // Maximum requests per interval\n  intervalSeconds: 60, // 1-minute rolling window\n});\n\nconst decision = await arcjet.guard({\n  label: \"api.events\",\n  rules: [limitRule({ key: userId })],\n});\n```\n\n## Prompt injection detection\n\nDetect and block prompt injection attacks — attempts to override your AI\nmodel's instructions — before they reach your model. Also useful for\nscanning tool call results that contain untrusted input (e.g. a \"fetch\"\ntool that loads a webpage which could embed injected instructions).\n\n```ts\nimport { launchArcjet, detectPromptInjection } from \"@arcjet/guard\";\n\nconst arcjet = launchArcjet({ key: process.env.ARCJET_KEY! });\n\nconst piRule = detectPromptInjection();\n\nconst decision = await arcjet.guard({\n  label: \"tools.chat\",\n  rules: [piRule(userMessage)],\n});\n\nif (decision.conclusion === \"DENY\" && decision.reason === \"PROMPT_INJECTION\") {\n  throw new Error(\"Prompt injection detected — please rephrase your message\");\n}\n\nconst result = piRule.result(decision);\n// Billing is undefined when the service does not report usage. Prompt\n// injection uses model tokens; content moderation uses text_units.\nconsole.log(result?.billing?.unit, result?.billing?.count);\n\n// Forward to your AI model...\n```\n\n## Content moderation\n\nDetect and block harmful content in user-supplied text before it is stored,\ndisplayed, or forwarded to another service. Also useful for scanning tool\ncall results or model outputs.\n\n```ts\nimport { launchArcjet, moderateContent } from \"@arcjet/guard\";\n\nconst arcjet = launchArcjet({ key: process.env.ARCJET_KEY! });\n\nconst moderate = moderateContent();\n\nconst decision = await arcjet.guard({\n  label: \"tools.chat\",\n  rules: [moderate(userMessage)],\n});\n\nif (decision.conclusion === \"DENY\" && decision.reason === \"MODERATE_CONTENT\") {\n  throw new Error(\"Harmful content detected — please rephrase your message\");\n}\n\nconst result = moderate.result(decision);\n// `detected` is true when harmful content was found. Billing is undefined\n// when the service does not report usage. Content moderation uses text_units.\nconsole.log(result?.detected, result?.billing?.unit, result?.billing?.count);\n```\n\n## Sensitive information detection\n\nDetect and block PII in text content. Use `allow` / `deny` to filter which\nentity types trigger a denial. Built-in entity types are\n`CREDIT_CARD_NUMBER`, `EMAIL`, `PHONE_NUMBER`, and `IP_ADDRESS`.\n\n```ts\nimport { launchArcjet, localDetectSensitiveInfo } from \"@arcjet/guard\";\n\nconst arcjet = launchArcjet({ key: process.env.ARCJET_KEY! });\n\nconst si = localDetectSensitiveInfo({\n  deny: [\"CREDIT_CARD_NUMBER\", \"PHONE_NUMBER\"],\n});\n\nconst decision = await arcjet.guard({\n  label: \"tools.summary\",\n  rules: [si(userMessage)],\n});\n\nif (decision.conclusion === \"DENY\" && decision.reason === \"SENSITIVE_INFO\") {\n  throw new Error(\"Sensitive information detected\");\n}\n```\n\n### On-device detection with additional entity types\n\nThe default backend detects the four built-in types locally with pattern\nmatching. To detect additional types — names, addresses, and government or\nfinancial identifiers — pass a `backend` such as\n[`@arcjet/sensitive-info-rampart`](https://www.npmjs.com/package/@arcjet/sensitive-info-rampart),\nwhich runs an on-device NER model. Detection still happens entirely locally;\nonly a SHA-256 hash of the text is sent to Arcjet.\n\n```ts\nimport { launchArcjet, localDetectSensitiveInfo } from \"@arcjet/guard\";\nimport { rampart } from \"@arcjet/sensitive-info-rampart\";\n\nconst arcjet = launchArcjet({ key: process.env.ARCJET_KEY! });\n\nconst si = localDetectSensitiveInfo({\n  deny: [\"GIVEN_NAME\", \"SURNAME\", \"EMAIL\", \"SSN\"],\n  backend: rampart(),\n});\n\nconst decision = await arcjet.guard({\n  label: \"tools.summary\",\n  rules: [si(userMessage)],\n});\n```\n\n## Custom rules\n\nDefine your own local evaluation logic with arbitrary key-value data. When\n`evaluate` is provided, the SDK calls it locally before sending the request.\nThe function receives `(config, input, { signal })` and must return\n`{ conclusion: \"ALLOW\" | \"DENY\" }`.\n\n```ts\nimport { launchArcjet, defineCustomRule } from \"@arcjet/guard\";\n\nconst arcjet = launchArcjet({ key: process.env.ARCJET_KEY! });\n\nconst topicBlock = defineCustomRule<\n  { blockedTopic: string },\n  { topic: string },\n  { matched: string }\n>({\n  evaluate: (config, input) => {\n    if (input.topic === config.blockedTopic) {\n      return { conclusion: \"DENY\", data: { matched: input.topic } };\n    }\n    return { conclusion: \"ALLOW\" };\n  },\n});\n\nconst rule = topicBlock({ data: { blockedTopic: \"politics\" } });\n\nconst decision = await arcjet.guard({\n  label: \"tools.chat\",\n  rules: [rule({ data: { topic: userTopic } })],\n});\n```\n\n## Capture\n\nUse `capture()` to record a fact about what your application did. Captures are\nvisibility data, never security decisions:\n\n```ts\narcjet.capture({\n  action: \"refund.issued\",\n  correlationId: runId,\n  decisionId: decision.id,\n  metadata: {\n    invoice: { id: \"inv_123\", amount: 4200 },\n    refunded: true,\n  },\n});\n```\n\nCapture is best-effort and never blocks or throws into application code. The SDK\nkeeps a bounded in-memory queue, sends batches on size or delay, drops the newest\nevent when the queue is full, and never retries a failed batch.\n\nA platform `waitUntil` hook does not change any of that. Events still batch; the\nhook is handed a promise that settles once they have been sent, so the runtime\nkeeps the invocation alive long enough for the batch to go out.\n\n### Serverless and edge runtimes\n\nA runtime that freezes or terminates between invocations can lose whatever is\nstill batched, so it needs telling that background work is outstanding. That is\nall `waitUntil` does — it extends the invocation, it does not disable batching.\nThirty tool calls in one agent turn stay one request, not thirty, which matters\nagainst a Worker's subrequest budget.\n\nPass `waitUntil` per call:\n\n```ts\nexport default {\n  async fetch(request, env, ctx) {\n    arcjet.capture({\n      action: \"refund.issued\",\n      waitUntil: (promise) => ctx.waitUntil(promise),\n    });\n    return new Response(\"ok\");\n  },\n};\n```\n\nArcjet discovers Vercel's request context on its own, so `waitUntil` is not\nneeded there. Every other per-invocation hook — Cloudflare's `ExecutionContext`\nincluded — has to be passed in, because a module-scoped client cannot reach it.\n\nWhere `capture()` is called too deep to reach the platform context, `flush()` at\nthe end of the handler instead:\n\n```ts\nexport default {\n  async fetch(request, env, ctx) {\n    const response = await handle(request);\n    ctx.waitUntil(arcjet.flush());\n    return response;\n  },\n};\n```\n\n### Draining\n\nCall `flush()` during graceful shutdown to avoid losing the final batch:\n\n```ts\nawait arcjet.flush(); // one-second deadline by default\nawait arcjet.flush(250); // custom deadline in milliseconds\n```\n\n`flush()` is optional, repeatable, and does not close the client. If its deadline\nexpires, remaining events are dropped and the client stays usable.\n\nLocal failures use stable `AJxxxx` diagnostics. Pass a logger to receive every\ndiagnostic; without one, Arcjet logs once per code:\n\n```ts\nconst arcjet = launchArcjet({\n  key: process.env.ARCJET_KEY!,\n  logger: {\n    // `@arcjet/logger` shape: the merging object comes first, the message\n    // second. `fields` carries `{ code, count? }`.\n    warn(fields, message) {\n      applicationLogger.warn(fields, message);\n    },\n  },\n});\n```\n\nMetadata has the same nested-JSON shape and limits as `guard()`. A key the SDK\ncannot encode is reported locally as `AJ1017` and also travels with that event in\n`local_warnings`. A queue-full event or failed batch never reaches the server, so\nthose drops can only be reported locally.\n\n## Registering a client (optional)\n\nPassing the client explicitly is the recommended path, and everything above does\nexactly that. Registration is a shortcut for the case it cannot cover: code too\ndeep in an application to be handed a client, where `capture()` is often most\nuseful.\n\n`launchArcjet()` never touches global state. Registering is always a separate,\nexplicit call:\n\n```ts\n// instrumentation.ts, or whatever runs at startup\nimport { launchArcjet, registerArcjet } from \"@arcjet/guard\";\n\nconst arcjet = launchArcjet({ key: process.env.ARCJET_KEY! });\n\nregisterArcjet(arcjet); // now, and only now, something is global\n```\n\n`guard()`, `capture()` and `flush()` are then importable on their own, and reach\nthe registered client:\n\n```ts\n// deep in application code — nothing was passed down here\nimport { capture } from \"@arcjet/guard\";\n\nexport async function refund(id: string): Promise<void> {\n  await issueRefund(id);\n  capture({ action: \"refund.issued\", metadata: { invoice: id } });\n}\n```\n\n### What happens with nothing registered\n\n`guard()` returns a fail-open `ALLOW` carrying an error result, so\n`decision.hasFailedOpen()` is `true`. It does not throw — these functions behave\nexactly like the client methods they forward to, and the never-throw contract\nholds.\n\n```ts\nconst decision = await guard({ label: \"refund\", rules: [limit(input)] });\n\nif (decision.hasFailedOpen()) {\n  // No rule was evaluated. Treat this as \"policy did not run\", not as a pass.\n}\n```\n\n`capture()` drops the event silently, and `flush()` resolves immediately.\nNothing is logged: the client that would have carried a logger is the thing\nthat is missing, so the only available sink would be an unconfigurable console\nwarning on a request path — noise an application cannot turn off. The decision\nreturned by `guard()` is the observable signal, and making the `capture()` case\nobservable is planned as an opt-in on the call itself.\n\n### Registering twice, and unregistering\n\nRegistration is version-checked. The slot is shared by every copy of\n`@arcjet/guard` in the process, so a registration is only used by the exact\nbuild that wrote it — the stored value is a live object whose internals are\nguaranteed within one build and not across them. A copy that finds a\nregistration from another version leaves it alone and fails open, exactly as if\nnothing were registered, and reports `AJ3006` on its own logger. Two versions\nin one process therefore do not share a client.\n\nRegistration is also guarded. A second client does not displace the first — the\nattempt is reported as `AJ3004` on the **incumbent's** logger, so a library or a\nstray second `launchArcjet()` cannot quietly redirect an application's telemetry\nto a different key. Registering the client that is already registered is a\nsilent no-op.\n\n```ts\nregisterArcjet(a); // registered: a\nregisterArcjet(b); // warns; a stays registered\nunregisterArcjet(); // nothing registered\n```\n\n`unregisterArcjet()` takes no argument and clears whatever is there. That\nasymmetry is deliberate: requiring the client back would mean every teardown has\nto keep hold of it, which is the problem registration exists to avoid. The cost\nis that anything calling it clears the application's client and every free call\nafterwards fails open — so **libraries should not call it**. Libraries take a\nclient explicitly. That is a convention, not something the SDK enforces.\n\nAn explicitly passed client always wins; the registered one is only consulted\nwhen none was passed.\n\n### Testing\n\n`@arcjet/guard/testing` registers an in-memory client that records calls and\ntalks to nothing:\n\n```ts\nimport { registerTestClient } from \"@arcjet/guard/testing\";\nimport { refund } from \"./refund.ts\";\n\ntest(\"refund captures an event\", async () => {\n  using arcjet = registerTestClient();\n\n  await refund(\"inv_1\");\n\n  assert.equal(arcjet.captures[0]?.action, \"refund.issued\");\n});\n```\n\n`using` unregisters the client at the end of the block, including when the test\nfails part-way through. Note the `await`: the capture happens wherever the code\nunder test reaches it, so a test that forgets to await an async function asserts\nbefore the event exists.\n\n<details>\n<summary>Without <code>using</code> — Node.js 22, or no TypeScript compile step</summary>\n\nThe `using` _syntax_ needs Node.js 24 to run natively, or compilation through\nTypeScript. Node.js 22 defines `Symbol.dispose` but cannot parse `using`. Call\n`unregister()` from a `finally` instead:\n\n```ts\ntest(\"refund captures an event\", async () => {\n  const arcjet = registerTestClient();\n  try {\n    await refund(\"inv_1\");\n\n    assert.equal(arcjet.captures[0]?.action, \"refund.issued\");\n  } finally {\n    arcjet.unregister();\n  }\n});\n```\n\n`unregister()` and `[Symbol.dispose]` are the same function under two names, so\nneither can drift from the other. It is safe to call twice, so it also works\nfrom an `afterEach`.\n\nOne related caveat: because `[Symbol.dispose]` appears in the published types, a\nproject compiling with `skipLibCheck: false` needs `esnext.disposable` in its\n`lib` even if it never writes `using`. `unregister()` is unaffected either way.\n\n</details>\n\nIt throws if a client is already registered, which surfaces a leak from an\nearlier test rather than letting this one assert against the wrong recorder.\n\nEach recorded capture goes through the same validation and metadata encoding as\na real `capture()`, so a call the real client would drop is not recorded here\neither. Recording itself is synchronous — once the code under test reaches\n`capture()`, the event is there with no flushing or waiting.\n\n`guard()` on the test client records the call and returns a fail-open `ALLOW`,\nbecause no rule actually ran. It is not a mock server and does not let you stub\nper-rule verdicts. One consequence worth knowing: helpers that fail closed on a\nfailed-open decision — `guardTool`, `guardAction` — will therefore **deny**\nagainst this client.\n\n## Metadata\n\n`guard()` and every rule accept `metadata`: an object of string keys mapped to\n**any JSON-serializable value**, including nested objects and arrays. It is\nattached to the decision for correlation and analytics.\n\n```ts\nconst decision = await arcjet.guard({\n  label: \"tools.weather\",\n  rules: [limitRule({ key: userId })],\n  metadata: {\n    user: { id: userId, plan: \"pro\" },\n    toolName: \"get_weather\",\n    durationMs: 160,\n    success: true,\n  },\n});\n```\n\nEach top-level value is JSON-encoded by the SDK and stored verbatim.\nServer-enforced limits:\n\n| Limit                    | Value                          | Over the limit     |\n| ------------------------ | ------------------------------ | ------------------ |\n| Top-level keys           | 128                            | Extra keys dropped |\n| Serialized bytes / value | 4 KiB                          | That key dropped   |\n| Nesting depth / value    | 10                             | That key dropped   |\n| Key names                | letters, digits, `-`, `.`, `_` | That key dropped   |\n\nNothing here can fail a call or change a decision — metadata is excluded from\nfingerprinting. Every dropped key is reported on `decision.warnings`: the server\nwarns once per key it drops, and the SDK adds a single warning naming every key\nit could not encode (`undefined`, a function, a `BigInt`, a circular reference). A\n`metadata` that is not a plain object is ignored entirely.\n\nMetadata is untrusted and is not redacted — do not put secrets or PII in it.\n\nTwo JavaScript-specific notes:\n\n- Numbers are IEEE-754 doubles, so an integer above `Number.MAX_SAFE_INTEGER`\n  loses precision before it reaches the wire. Pass such values as strings.\n- `BigInt` cannot be JSON-encoded, so it is dropped with a warning. Convert it\n  yourself.\n\nRule-level metadata is merged with `guard()`-level metadata shallowly: a\nduplicate key's whole value is replaced, never deep-merged.\n\nSome limits are the SDK's own, not the server's. The SDK drops keys once one\nrequest's metadata exceeds 768 KiB in total (keys plus JSON-encoded values,\ncounted before compression). That ceiling sits well above anything the server\nwould accept — its own caps allow roughly 512 KiB in a single map — and exists\nonly so oversized metadata cannot push a request past the 1 MiB protocol limit,\nwhere it would be rejected outright and fail open.\n\nObjects with a `toJSON()` method, including `Date`, are serialized by their\n`toJSON()` result. The Python SDK has no equivalent protocol and drops such values\nwith a warning, so convert explicitly if both SDKs must agree on a value.\n\n## Decision inspection\n\nEvery `.guard()` call returns a `Decision` object. You can inspect it at\nthree levels of detail:\n\n```ts\nconst rl = limitRule({ key: userId, requested: tokenCount });\nconst decision = await arcjet.guard({\n  label: \"tools.weather\",\n  rules: [rl, piRule(userMessage)],\n});\n\n// Overall decision\ndecision.conclusion; // \"ALLOW\" | \"DENY\"\ndecision.reason; // \"RATE_LIMIT\" | \"PROMPT_INJECTION\" | ... (only on DENY)\n\n// Failure check (fail-open — errors don't cause denials)\ndecision.hasFailedOpen(); // true if ALLOW only because a rule/decision could not be processed\ndecision.errorResults(); // the results that errored\ndecision.warnings; // decision-level request-validation diagnostics\n\n// Per-rule results — iterate all\nfor (const result of decision.results) {\n  console.log(result.type, result.conclusion);\n}\n\n// From a RuleWithInput — this specific submission's result\nconst r = rl.result(decision);\nif (r) {\n  console.log(r.remainingTokens, r.maxTokens);\n}\n\n// From a RuleWithConfig — first denied result across all submissions\nconst denied = limitRule.deniedResult(decision);\nif (denied) {\n  console.log(denied.remainingTokens); // 0\n}\n```\n\nMethods available on both `RuleWithConfig` and `RuleWithInput`:\n\n| Method                   | `RuleWithConfig` (e.g. `limit`) | `RuleWithInput` (e.g. `rl`)        |\n| ------------------------ | ------------------------------- | ---------------------------------- |\n| `results(decision)`      | All results for this config     | Single-element or empty array      |\n| `result(decision)`       | First result (any conclusion)   | This submission's result           |\n| `deniedResult(decision)` | First denied result             | This submission's result if denied |\n\n## Best practices\n\n- **Create the client and rule configs once** at module scope, not per\n  request. The client holds a persistent connection (HTTP/2 on Node.js);\n  rule configs carry stable IDs used for server-side aggregation.\n\n  ```ts\n  // Create the client once at module scope\n  const arcjet = launchArcjet({ key: process.env.ARCJET_KEY! });\n\n  // Configure reusable rules (also at module scope)\n  const limitRule = tokenBucket({ refillRate: 10, intervalSeconds: 60, maxTokens: 100 });\n\n  // Per request — created each time\n  const decision = await arcjet.guard({\n    label: \"tools.weather\",\n    rules: [limitRule({ key: userId })],\n  });\n  ```\n\n- **Don't wrap `launchArcjet()` in a helper function.** This defeats\n  connection reuse. Bad — creates a new client every call:\n\n  ```ts\n  function getArcjet() {\n    return launchArcjet({ key: process.env.ARCJET_KEY! });\n  }\n  const decision = await getArcjet().guard({\n    label: \"tools.chat\",\n    rules: [\n      tokenBucket({ refillRate: 10, intervalSeconds: 60, maxTokens: 100 })({\n        key: userId,\n        requested: 1,\n      }),\n    ],\n  });\n  ```\n\n  Good — reuses the client:\n\n  ```ts\n  const arcjet = launchArcjet({ key: process.env.ARCJET_KEY! });\n  const decision = await arcjet.guard({\n    label: \"tools.chat\",\n    rules: [\n      tokenBucket({ refillRate: 10, intervalSeconds: 60, maxTokens: 100 })({\n        key: userId,\n        requested: 1,\n      }),\n    ],\n  });\n  ```\n\n- **Start rules in `DRY_RUN` mode** to observe behavior before switching to\n  `LIVE`. This lets you tune thresholds without affecting real traffic:\n\n  ```ts\n  const limitRule = tokenBucket({\n    mode: \"DRY_RUN\",\n    refillRate: 10,\n    intervalSeconds: 60,\n    maxTokens: 100,\n  });\n  ```\n\n- **Handle failures explicitly.** The SDK fails open — an errored rule does not\n  cause a denial. Check `decision.hasFailedOpen()` to detect when a decision\n  returned `ALLOW` only because a rule or the decision could not be processed,\n  and inspect `decision.errorResults()` for the details. Gate a fail-closed\n  policy on it:\n\n  ```ts\n  if (decision.hasFailedOpen()) {\n    // Evaluation degraded — decide whether to proceed or deny.\n    console.error(\"Guard failed open\", decision.errorResults());\n  }\n  ```\n\n  `decision.hasError()` still works but is deprecated: it conflated request\n  diagnostics with errors. Use `decision.warnings` for diagnostics and\n  `decision.errorResults()` / `decision.hasFailedOpen()` for errors.\n\n- **Use labels** to identify protection boundaries. Labels appear in the\n  Arcjet dashboard and help correlate decisions with specific tool calls or\n  API endpoints.\n\n- **Use `bucket`** on rate limit rules to name your counters in the\n  dashboard. Different configs sharing the same bucket name still get\n  independent counters — a config hash is appended server-side.\n\n## SDK namespaces: core and integrations\n\n`@arcjet/guard` exposes two import layers, plus `@arcjet/guard/testing` for the\nin-memory test client:\n\n### Core guard (`@arcjet/guard`)\n\nThe fundamental client and rule builders. Use this to evaluate guards without\nany AI SDK integration:\n\n```ts\nimport { launchArcjet, tokenBucket, detectPromptInjection } from \"@arcjet/guard\";\n\nconst arcjet = launchArcjet({ key: process.env.ARCJET_KEY! });\nconst decision = await arcjet.guard({\n  label: \"tools.chat\",\n  rules: [\n    tokenBucket({ refillRate: 10, intervalSeconds: 60, maxTokens: 100 })({\n      key: userId,\n      requested: 1,\n    }),\n    detectPromptInjection()(userMessage),\n  ],\n});\n```\n\n### Vendor SDK integration (`@arcjet/guard/<vendor-sdk>/v<major>`)\n\nVendor-specific wrappers that integrate with particular SDKs, plus every agent\nhelper. Every wrapper policy accepts optional `actor` and `inputs` — static\nvalues or resolvers over that adapter's native call (parsed input plus the\nframework's trusted runtime or context, the same idea as Vercel AI's\n`(input, ctx)`). Build each input with\n`policyInput` so a remote Guard policy that declares those names can evaluate.\nOmit them and the remote policy has nothing to read, so its rules do not fire.\n\nCurrently available:\n\n- **`@arcjet/guard/vercel-ai/v7`** — Vercel AI SDK v7 integration. Exports\n  `guardTool` and `aiToolsContext` for tool wrapping, alongside the helpers\n  that are not tied to any SDK — `createAgentContext`, `guardAction`,\n  `captureAction`, and `securityMetadata`:\n\n  ```ts\n  import {\n    guardTool,\n    aiToolsContext,\n    createAgentContext,\n    guardAction,\n    captureAction,\n    securityMetadata,\n  } from \"@arcjet/guard/vercel-ai/v7\";\n  import { policyInput } from \"@arcjet/guard\";\n\n  const ctx = createAgentContext({\n    correlationId: requestId,\n    metadata: securityMetadata({ user: userId }),\n  });\n\n  const tools = {\n    getData: guardTool(arcjet, getDataTool, {\n      action: \"data.fetched\",\n      onGuardError: \"deny\", // default — blocks the call if Arcjet is unreachable\n      actor: (_input, context) => String(context?.metadata?.userId),\n      inputs: (input) => ({ query: policyInput.server.string(input.query) }),\n      rules: [dataLimit({ key: userId, requested: 1 })],\n    }),\n  };\n\n  const result = await generateText({\n    // ...\n    tools,\n    toolsContext: aiToolsContext(ctx, tools),\n  });\n\n  await guardAction(\n    arcjet,\n    ctx,\n    {\n      action: \"data.updated\",\n      onGuardError: \"deny\", // default — blocks the call if Arcjet is unreachable\n      rules: [updateLimit({ key: userId })],\n    },\n    () => updateData(),\n  );\n  captureAction(arcjet, ctx, { action: \"audit.logged\" });\n  ```\n\n- **`@arcjet/guard/vercel-eve/v0`** — Vercel Eve v0 integration. Exports\n  `guardTool`, `guardApproval`, `guardInbound`, and `arcjetHooks` for Eve's four\n  guard surfaces, alongside the `eveAgentContext` helper that derives context\n  from Eve's session:\n\n  ```ts\n  import { launchArcjet, tokenBucket } from \"@arcjet/guard\";\n  import { guardApproval, arcjetHooks } from \"@arcjet/guard/vercel-eve/v0\";\n  import { defineOpenAPIConnection } from \"eve/connections\";\n  import { defineHook } from \"eve/hooks\";\n\n  const arcjet = launchArcjet({ key: process.env.ARCJET_KEY! });\n  const limit = tokenBucket({\n    refillRate: 10,\n    intervalSeconds: 60,\n    maxTokens: 10,\n  });\n\n  // Gate a connection's operations\n  export const ordersConnection = defineOpenAPIConnection({\n    description: \"Orders API\",\n    spec: {/* ... */},\n    approval: guardApproval(arcjet, {\n      action: \"orders-api.read\",\n      onGuardError: \"deny\", // default — blocks the call if Arcjet is unreachable\n      rules: (ctx) => [limit({ key: ctx.session.id, requested: 1 })],\n    }),\n    operations: { allow: [\"GetOrder\"] },\n  });\n\n  // Record agent lifecycle events\n  export default defineHook(arcjetHooks(arcjet));\n  ```\n\n- **`@arcjet/guard/claude-agent-sdk/v0`** — Claude Agent SDK v0 integration.\n  Exports `guardTool`, `guardHooks`, and `claudeAgentContext`. There is no\n  `guardInbound` (inbound is `UserPromptSubmit` on `guardHooks`) and no\n  `canUseTool` helper (`canUseTool` is skipped by `allowedTools`, allow\n  rules, and `bypassPermissions` / `acceptEdits`):\n\n  ```ts\n  import { launchArcjet, detectPromptInjection, tokenBucket } from \"@arcjet/guard\";\n  import { guardTool, guardHooks } from \"@arcjet/guard/claude-agent-sdk/v0\";\n  import { query, tool, createSdkMcpServer } from \"@anthropic-ai/claude-agent-sdk\";\n  import { z } from \"zod\";\n\n  const arcjet = launchArcjet({ key: process.env.ARCJET_KEY! });\n  const limit = tokenBucket({\n    refillRate: 10,\n    intervalSeconds: 60,\n    maxTokens: 10,\n  });\n\n  const lookupOrder = guardTool(\n    arcjet,\n    tool(\n      \"lookup_order\",\n      \"Look up an order\",\n      { orderNumber: z.string() },\n      async ({ orderNumber }) => ({\n        content: [{ type: \"text\", text: `${orderNumber}: shipped` }],\n      }),\n    ),\n    {\n      action: \"order.looked-up\",\n      onGuardError: \"deny\",\n      rules: (input) => [limit({ key: input.orderNumber, requested: 1 })],\n    },\n  );\n\n  // The Claude CLI requires `sessionId` to be a UUID and refuses to create the\n  // same one twice: a non-UUID exits with \"Invalid session ID\", and reusing an\n  // id on a second `query()` exits with \"already in use\". So mint a UUID for\n  // the conversation, then continue it with `resume` — which keeps the id the\n  // adapter reads, so every turn lands on one Sequence.\n  const sessionId = conversationId; // a UUID, e.g. crypto.randomUUID()\n\n  for await (const message of query({\n    prompt: userText,\n    options: {\n      // First turn: `sessionId`. Later turns in the same conversation:\n      // `resume: sessionId` instead.\n      sessionId,\n      mcpServers: {\n        app: createSdkMcpServer({ name: \"app\", tools: [lookupOrder] }),\n      },\n      hooks: guardHooks(arcjet, {\n        sessionId,\n        // `lookupOrder` guards itself through `guardTool`, so exclude it here\n        // or PreToolUse gates it a second time — two round trips, two quota\n        // units, for one invocation. Naming the server keeps the match exact,\n        // so another server's tool of the same name stays gated.\n        exclude: [{ server: \"app\", name: \"lookup_order\" }],\n        inbound: {\n          action: \"message.received\",\n          rules: ({ prompt }) => [detectPromptInjection()(prompt)],\n        },\n      }),\n    },\n  })) {\n    void message;\n  }\n  ```\n\n- **`@arcjet/guard/claude-managed-agents/v0`** — Claude Managed Agents\n  (hosted REST+SSE, beta `managed-agents-2026-04-01`). Exports\n  `guardEvents`, `guardCustomTool`, and `claudeManagedAgentsContext`.\n  Anthropic runs the tool loop. There is **no PreToolUse**. This is\n  **not** `@arcjet/guard/claude-agent-sdk/v0` — do not reuse that\n  adapter, its hooks, or `guardTool`. There is no `guardInbound`\n  (inbound is `guardEvents` before `sessions.events.send`) and no\n  confirmation helper (`user.tool_confirmation` / `always_ask` is HITL,\n  not policy). Default `always_allow` **cannot** be gated:\n  Anthropic-cloud bash/read/write and `web_search` / `web_fetch` run on\n  Anthropic. MCP: Anthropic is the client; Guard custom tools and MCP\n  servers **you** host. Docs live at\n  [`/guards/claude-managed-agents/`](https://docs.arcjet.com/guards/claude-managed-agents/)\n  (shared JS+Python page).\n\n  Correlation is caller-owned. Never mint. Never treat Anthropic\n  session/event ids as if we created them. Never `traceId`.\n\n  ```ts\n  import { launchArcjet, detectPromptInjection, tokenBucket } from \"@arcjet/guard\";\n  import {\n    claudeManagedAgentsContext,\n    guardCustomTool,\n    guardEvents,\n  } from \"@arcjet/guard/claude-managed-agents/v0\";\n\n  const arcjet = launchArcjet({ key: process.env.ARCJET_KEY! });\n  const ctx = claudeManagedAgentsContext({ correlationId: conversationId });\n  const limit = tokenBucket({\n    refillRate: 10,\n    intervalSeconds: 60,\n    maxTokens: 10,\n  });\n\n  const verdict = await guardEvents(\n    arcjet,\n    {\n      events: [{ type: \"user.message\", content: [{ type: \"text\", text: userText }] }],\n      inbound: {\n        action: \"message.received\",\n        rules: ({ text }) => [detectPromptInjection()(text)],\n      },\n      context: ctx,\n    },\n    (body) => client.beta.sessions.events.send(session.id, body),\n  );\n\n  if (!verdict.allowed) {\n    throw new Error(verdict.message);\n  }\n\n  if (event.type === \"agent.custom_tool_use\") {\n    const gated = await guardCustomTool(\n      arcjet,\n      {\n        event,\n        execute: (input) => lookupOrder(input),\n        send: (result) => client.beta.sessions.events.send(session.id, { events: [result] }),\n      },\n      {\n        action: \"order.looked-up\",\n        onGuardError: \"deny\",\n        rules: (input) => [limit({ key: String(input[\"orderNumber\"]), requested: 1 })],\n        context: ctx,\n      },\n    );\n    if (gated.allowed) {\n      await client.beta.sessions.events.send(session.id, {\n        events: [\n          {\n            type: \"user.custom_tool_result\",\n            custom_tool_use_id: event.id,\n            content: [{ type: \"text\", text: JSON.stringify(gated.output) }],\n          },\n        ],\n      });\n    }\n  }\n  ```\n\n- **`@arcjet/guard/mastra/v1`** — Mastra v1 integration. Exports `guardTool`,\n  `guardProcessor`, `guardHooks`, and `mastraAgentContext`. There is no\n  `guardInbound` (channels already hit `processInput`) and no `guardApproval`\n  (Mastra `requireApproval` is human HITL, not policy):\n\n  ```ts\n  import { launchArcjet, detectPromptInjection, tokenBucket } from \"@arcjet/guard\";\n  import { guardTool, guardProcessor, guardHooks } from \"@arcjet/guard/mastra/v1\";\n  import { Agent } from \"@mastra/core/agent\";\n  import { createTool } from \"@mastra/core/tools\";\n  import { z } from \"zod\";\n\n  const arcjet = launchArcjet({ key: process.env.ARCJET_KEY! });\n  const limit = tokenBucket({\n    refillRate: 10,\n    intervalSeconds: 60,\n    maxTokens: 10,\n  });\n\n  const lookupOrder = guardTool(\n    arcjet,\n    createTool({\n      id: \"lookup-order\",\n      description: \"Look up an order\",\n      inputSchema: z.object({ orderNumber: z.string() }),\n      execute: async ({ orderNumber }) => ({ orderNumber, status: \"shipped\" }),\n    }),\n    {\n      action: \"order.looked-up\",\n      onGuardError: \"deny\",\n      rules: (input) => [limit({ key: input.orderNumber, requested: 1 })],\n    },\n  );\n\n  export const agent = new Agent({\n    id: \"support-agent\",\n    name: \"support-agent\",\n    instructions: \"Help the user.\",\n    model: \"openai/gpt-4o\",\n    tools: { lookupOrder },\n    inputProcessors: [\n      guardProcessor(arcjet, {\n        action: \"message.received\",\n        rules: ({ text }) => [detectPromptInjection()(text)],\n      }),\n    ],\n    hooks: guardHooks(arcjet),\n  });\n  ```\n\n- **`@arcjet/guard/langgraph/v1`** — LangGraph Graph API (`StateGraph` +\n  `ToolNode`) integration. Exports `guardTool`, `guardToolNode`, and\n  `langgraphAgentContext`. This is **not** LangChain `createAgent` /\n  `wrapToolCall` — that is `@arcjet/guard/langchain/v1` — and\n  `createReactAgent` is deprecated in LangGraph JS v1 — do not build on\n  it. There is no `guardInbound` (screen before `invoke` or at the first\n  graph node) and no `guardInterrupt` / `guardApproval` (`interrupt()`\n  is human HITL, not policy).\n\n  On DENY a guarded tool does not run and does not throw: it returns a\n  structured `ArcjetDenialResult`, which `ToolNode` turns into a real\n  `ToolMessage` the model reads. Because the tool did not throw, that\n  message's `status` is `success` — the denial is in the payload\n  (`arcjetDenied: true`), not the envelope. `guardToolNode` guards a\n  `ToolNode`'s tools **in place** and returns the same node, because\n  `ToolNode` resolves its tools through a closure captured when it was\n  constructed:\n\n  ```ts\n  import { launchArcjet, tokenBucket } from \"@arcjet/guard\";\n  import { guardTool, guardToolNode } from \"@arcjet/guard/langgraph/v1\";\n  import { ToolNode } from \"@langchain/langgraph/prebuilt\";\n  import { tool } from \"@langchain/core/tools\";\n  import { z } from \"zod\";\n\n  const arcjet = launchArcjet({ key: process.env.ARCJET_KEY! });\n  const limit = tokenBucket({\n    refillRate: 10,\n    intervalSeconds: 60,\n    maxTokens: 10,\n  });\n\n  const lookupOrder = guardTool(\n    arcjet,\n    tool(async ({ orderNumber }) => ({ orderNumber, status: \"shipped\" }), {\n      name: \"lookup_order\",\n      description: \"Look up an order\",\n      schema: z.object({ orderNumber: z.string() }),\n    }),\n    {\n      action: \"order.looked-up\",\n      onGuardError: \"deny\",\n      rules: (input) => [limit({ key: input.orderNumber, requested: 1 })],\n    },\n  );\n\n  export const tools = guardToolNode(arcjet, new ToolNode([lookupOrder]));\n  ```\n\n#### Screen inbound before `invoke` (or at the first graph node)\n\nLangGraph has no first-class inbound channel, so there is no\n`guardInbound`. Put prompt-injection (and other inbound rules) in the\napplication before `graph.invoke`, or in the graph's first node.\n\n#### `interrupt()` is not a policy gate\n\n`interrupt()` / `interrupt_before=[\"tools\"]` is human-in-the-loop, not\npolicy. Same trap as Mastra `requireApproval` and Claude `canUseTool`.\nThere is no `guardInterrupt`.\n\n#### `ToolNode` is the deny point for tools; hooks / HITL cannot enforce\n\nUnwrapped and MCP tools run inside `ToolNode`. Graph hooks and HITL\npauses cannot stop `tool.invoke`. Use `guardToolNode` (or `guardTool` for\nauthored tools you invoke yourself).\n\n`guardToolNode` guards the node's tools in place and hands the same node\nback. That is not an optimisation: `ToolNode`'s constructor captures\n`func: (input, config) => this.run(input, config)`, and `run` reads\n`this.tools`, so a copy holding a fresh tools array would leave the original\nnode executing unguarded tools. Guarding in place also means a caller that\nstill holds the pre-wrap node cannot bypass Guard. Passing an array of tools\ninstead returns guarded copies and leaves your array untouched. Tools\nappended after wrapping — MCP discovered mid-run — are guarded on the next\n`invoke`.\n\nIf you invoke a guarded tool yourself rather than through `ToolNode`, read\nthe denial and build your own `ToolMessage`; do not push the denial object\nstraight into `messages`, because the graph's message reducer only accepts\nreal messages.\n\n- **`@arcjet/guard/langchain/v1`** — LangChain JS `createAgent` +\n  `createMiddleware({ wrapToolCall })` integration. Exports `guardTool`,\n  `guardMiddleware`, and `langchainContext`. This is **not** LangGraph\n  Graph API (`StateGraph` + `ToolNode`) — that is\n  `@arcjet/guard/langgraph/v1` — and not `vercel-ai/v7`. There is no\n  `guardInbound` (screen before `agent.invoke`; SDK middleware that is\n  not `wrapToolCall` is not Guard) and no `guardApproval`\n  (`humanInTheLoopMiddleware` / `interrupt()` is human HITL, not\n  policy). Policy sits on `wrapToolCall` only — do not deny in\n  `afterModel`. Server-side provider tools and headless `.implement()`\n  tools are out of scope. Docs live at\n  [`/guards/langchain-js/`](https://docs.arcjet.com/guards/langchain-js/);\n  do not overwrite [`/guards/langchain/`](https://docs.arcjet.com/guards/langchain/)\n  (the live Python page).\n\n  Two denial envelopes — do not collapse them. `guardTool` returns a\n  plain `ArcjetDenialResult`; it does not throw and does not fabricate\n  a `ToolMessage`. `createAgent`'s `baseHandler` wraps a non-ToolMessage\n  in a success `ToolMessage`. `guardMiddleware` `wrapToolCall` MUST\n  return a real `ToolMessage` (`content` = JSON of the payload,\n  `tool_call_id` = `request.toolCall.id`, `name` =\n  `request.toolCall.name`). wrapToolCall's return is **not** passed\n  through `baseHandler`; a bare object is the messages-reducer crash.\n  Do not set `status: \"error\"`. Do not throw (throws bubble and drop\n  `arcjetDenied`). Already-branded tools are skipped so Guard is not\n  double-called:\n\n  ```ts\n  import { launchArcjet, detectPromptInjection, tokenBucket } from \"@arcjet/guard\";\n  import { guardTool, guardMiddleware, langchainContext } from \"@arcjet/guard/langchain/v1\";\n  import { createAgent } from \"langchain\";\n  import { tool } from \"@langchain/core/tools\";\n  import { z } from \"zod\";\n\n  const arcjet = launchArcjet({ key: process.env.ARCJET_KEY! });\n  const limit = tokenBucket({\n    refillRate: 10,\n    intervalSeconds: 60,\n    maxTokens: 10,\n  });\n\n  const lookupOrder = guardTool(\n    arcjet,\n    tool(async ({ orderNumber }) => ({ orderNumber, status: \"shipped\" }), {\n      name: \"lookup_order\",\n      description: \"Look up an order\",\n      schema: z.object({ orderNumber: z.string() }),\n    }),\n    {\n      action: \"order.looked-up\",\n      onGuardError: \"deny\",\n      rules: (input) => [limit({ key: input.orderNumber, requested: 1 })],\n    },\n  );\n\n  const inbound = detectPromptInjection();\n  const decision = await arcjet.guard({\n    label: \"message.received\",\n    rules: [inbound(userText)],\n    ...langchainContext({ configurable: { thread_id: conversationId } }),\n  });\n\n  if (decision.conclusion === \"DENY\") {\n    throw new Error(\"message blocked\");\n  }\n  if (decision.hasFailedOpen()) {\n    throw new Error(\"inbound screening failed open\");\n  }\n\n  const agent = createAgent({\n    model,\n    tools: [lookupOrder],\n    middleware: [guardMiddleware(arcjet, { sessionId: conversationId })],\n  });\n  await agent.invoke(\n    { messages: [{ role: \"user\", content: userText }] },\n    { configurable: { thread_id: conversationId } },\n  );\n  ```\n\n#### Screen inbound before `agent.invoke` — there is no inbound hook. SDK middleware that is not `wrapToolCall` is not Guard.\n\nLangChain `createAgent` has no first-class inbound channel, so there\nis no `guardInbound`. Put prompt-injection (and other inbound rules)\nin the application before `agent.invoke`. `wrapModelCall` /\n`beforeModel` / `afterModel` intercept the model call, not user text.\nThey are not this policy gate.\n\n#### `humanInTheLoopMiddleware` / `interrupt` is HITL, not a policy gate.\n\n`humanInTheLoopMiddleware` / `interrupt()` / approve-edit-reject-respond\nis human-in-the-loop, not policy. Same trap as Mastra `requireApproval`,\nClaude `canUseTool`, LangGraph `interrupt()`, Genkit `toolApproval`,\nand OpenAI Agents `needsApproval`. There is no `guardApproval`. Policy\nsits on `wrapToolCall` only — do not deny in `afterModel`.\n\n#### Deny inside `tool()` (and `guardMiddleware`'s `wrapToolCall`). MCP and unwrapped tools skip an unwrapped handler.\n\nThe authored `tool()` handler is the deny point for tools you own.\nMCP tools, runtime-discovered tools, and anything not wrapped with\n`guardTool` skip that handler. `guardMiddleware` is the invoke()-wide\ngate for those — its `wrapToolCall` denies by returning a real\n`ToolMessage` without calling `handler`. wrapToolCall only sees\n`runtime.configurable.thread_id` as of langchain 1.2.34.\n\n- **`@arcjet/guard/openai-agents/v0`** — OpenAI Agents text `Agent` +\n  `run()` / `Runner` integration. Exports `guardTool` and\n  `openaiAgentsContext`. This is **not** Realtime, Sandbox, hosted tools,\n  computer / shell / apply_patch, MCP, or `agent.asTool()`. There is no\n  `guardInbound` (screen before `run()`; SDK `inputGuardrails` are not\n  Arcjet), no `guardApproval` (`needsApproval` is human HITL, not\n  policy), and no `guardHooks` / `guardToolNode` (there is no ToolNode;\n  hosted / MCP / handoffs skip authored `execute`).\n\n  On DENY a guarded tool does not run and does not throw: it returns a\n  structured `ArcjetDenialResult`. The runner stringifies that object\n  onto a `function_call_result` with `status: \"completed\"` — the denial\n  is in the payload (`arcjetDenied: true`), not a fabricated envelope.\n  Throwing would hit the SDK `errorFunction` (a generic string, or\n  `ToolCallError` when `outputSchema` / `errorFunction: null`).\n  `RunContext` has no session / conversation id; put the id you already\n  have on `run(..., { context })`:\n\n  ```ts\n  import { launchArcjet, detectPromptInjection, tokenBucket } from \"@arcjet/guard\";\n  import { guardTool, openaiAgentsContext } from \"@arcjet/guard/openai-agents/v0\";\n  import { Agent, run, tool } from \"@openai/agents\";\n  import { z } from \"zod\";\n\n  const arcjet = launchArcjet({ key: process.env.ARCJET_KEY! });\n  const limit = tokenBucket({\n    refillRate: 10,\n    intervalSeconds: 60,\n    maxTokens: 10,\n  });\n\n  const lookupOrder = guardTool(\n    arcjet,\n    tool({\n      name: \"lookup_order\",\n      description: \"Look up an order\",\n      parameters: z.object({ orderNumber: z.string() }),\n      execute: async ({ orderNumber }) => ({ orderNumber, status: \"shipped\" }),\n    }),\n    {\n      action: \"order.looked-up\",\n      onGuardError: \"deny\",\n      rules: (input: { orderNumber: string }) => [limit({ key: input.orderNumber, requested: 1 })],\n    },\n  );\n\n  const agent = new Agent({\n    name: \"support-agent\",\n    instructions: \"Help the user.\",\n    tools: [lookupOrder],\n  });\n\n  const appContext = { sessionId: conversationId };\n  const inbound = detectPromptInjection();\n  const decision = await arcjet.guard({\n    label: \"message.received\",\n    rules: [inbound(userText)],\n    ...openaiAgentsContext({ context: appContext, conversationId }),\n  });\n\n  if (decision.conclusion === \"DENY\") {\n    throw new Error(\"message blocked\");\n  }\n  // `guard()` fails open, so an ALLOW is not proof the rules ran. Gate on\n  // `decision.hasFailedOpen()` here if this call site must fail closed; the\n  // agent helpers below already default to that.\n  await run(agent, userText, { context: appContext });\n  ```\n\n#### Screen inbound before `run()` (SDK `inputGuardrails` are not Arcjet)\n\nOpenAI Agents has no first-class inbound channel, so there is no\n`guardInbound`. Put prompt-injection (and other inbound rules) in the\napplication before `run()`. SDK `inputGuardrails` / `outputGuardrails` /\n`defineToolInputGuardrail` / `defineToolOutputGuardrail` are the SDK's\nown tripwires, not this policy gate.\n\n#### `needsApproval` is not a policy gate\n\n`needsApproval` / `requireApproval` / `onApproval` is human-in-the-loop,\nnot policy. The run pauses; `result.state.approve` / `reject`. Same trap\nas Mastra `requireApproval`, Claude `canUseTool`, and LangGraph\n`interrupt()`. There is no `guardApproval`.\n\n#### `tool()` execute is the deny point; hosted, MCP, and handoffs are not on that path\n\nThe runner executes authored function tools in `toolExecution.ts` via\n`invoke`. Hosted tools, handoffs, computer / shell / apply_patch, and\nMCP (`mcpServers` → `mcpToFunctionTool`) skip that authored-`execute`\npath. `agent_tool_start` / `agent_tool_end` are void observe-only hooks;\nthey are not a deny. There is no `guardHooks` and no `guardToolNode`.\n\n- **`@arcjet/guard/genkit/v1`** — Genkit JS `genkit()` + `ai.defineTool` +\n  `ai.generate` integration. Exports `guardTool`, `guardMiddleware`, and\n  `genkitContext`. This is **not** Go / Python Genkit. There is no\n  `guardInbound` (screen before `generate()` / `chat.send()`; middleware\n  `model` is not Guard), no `guardApproval` (`interrupt()` /\n  `defineInterrupt` / `toolApproval` is human HITL, not policy). Do not\n  also wrap the same tool with `@arcjet/guard/vercel-ai/v7`.\n\n  On DENY a guarded tool does not run and does not throw: it returns a\n  structured `ArcjetDenialResult` as a completed `toolResponse.output`.\n  `interrupt()` / `ToolInterruptError` is HITL — a denial is not\n  `finishReason: \"interrupted\"`. Wrapping the `ToolAction` (not the\n  inner handler) is what keeps a denial off `outputSchema` validation,\n  so a schema-mismatched `ArcjetDenialResult` still reaches the model.\n  `guardMiddleware` is the generate()-wide gate for filesystem / MCP /\n  unwrapped tools:\n\n  ```ts\n  import { launchArcjet, detectPromptInjection, tokenBucket } from \"@arcjet/guard\";\n  import { guardTool, guardMiddleware, genkitContext } from \"@arcjet/guard/genkit/v1\";\n  import { genkit, z } from \"genkit\";\n\n  const ai = genkit({/* plugins, default model */});\n  const arcjet = launchArcjet({ key: process.env.ARCJET_KEY! });\n  const limit = tokenBucket({\n    refillRate: 10,\n    intervalSeconds: 60,\n    maxTokens: 10,\n  });\n\n  const lookupOrder = guardTool(\n    arcjet,\n    ai.defineTool(\n      {\n        name: \"lookup_order\",\n        description: \"Look up an order\",\n        inputSchema: z.object({ orderNumber: z.string() }),\n      },\n      async ({ orderNumber }) => ({ orderNumber, status: \"shipped\" }),\n    ),\n    {\n      action: \"order.looked-up\",\n      onGuardError: \"deny\",\n      rules: (input) => [limit({ key: input.orderNumber, requested: 1 })],\n    },\n  );\n\n  const appContext = { sessionId: conversationId };\n  const inbound = detectPromptInjection();\n  const decision = await arcjet.guard({\n    label: \"message.received\",\n    rules: [inbound(userText)],\n    ...genkitContext({ context: appContext }),\n  });\n\n  if (decision.conclusion === \"DENY\") {\n    throw new Error(\"message blocked\");\n  }\n  await ai.generate({\n    prompt: userText,\n    tools: [lookupOrder],\n    use: [guardMiddleware(arcjet, { sessionId: conversationId })],\n    context: appContext,\n  });\n  ```\n\n#### Screen user text before `generate()` — there is no inbound hook. Middleware `model` is not Guard.\n\nGenkit has no first-class inbound channel, so there is no\n`guardInbound`. Put prompt-injection (and other inbound rules) in the\napplication before `ai.generate()` / `chat.send()`. The middleware\n`model` hook intercepts the model call, not user text. It is not this\npolicy gate.\n\n#### `interrupt()` / `defineInterrupt` / `toolApproval` are HITL, not a policy gate.\n\n`interrupt()` / `defineInterrupt` / `@genkit-ai/middleware`\n`toolApproval` / `restartTool` / `finishReason === \"interrupted\"` is\nhuman-in-the-loop, not policy. The run pauses; you `restartTool` or\n`respond`. Same trap as Mastra `requireApproval`, Claude `canUseTool`,\nLangGraph `interrupt()`, and OpenAI Agents `needsApproval`. There is no\n`guardApproval`.\n\n#### Deny inside `defineTool` (and `guardMiddleware`'s `tool` hook). MCP and filesystem-injected tools skip an unwrapped handler.\n\nThe authored `defineTool` handler is the deny point for tools you own.\nFilesystem middleware tools, MCP tools, and anything not wrapped with\n`guardTool` skip that handler. `guardMiddleware` is the generate()-wide\ngate for those — its `tool` hook denies by returning a completed\n`ToolResponsePart` without calling `next()`. `returnToolRequests: true`\nmeans the app calls the tool itself; `guardTool` on the defineTool\nhandler still gates that. `guardMiddleware` does not run if they never\n`generate()` the tool.\n\n`generate({ context })` is delivered to the authored handler via ALS.\nThe tool wrapper and middleware hook see `options.context` /\n`ctx.context` when the caller passed it explicitly; put the same id on\n`policy.sessionId` when you need tool-time correlation through the hook.\nNever mint. Never use `traceId`. Never treat `interrupt` / `resumed` as\ncorrelation.\n\n- **`@arcjet/guard/strands-agents/v1`** — Strands Agents JS\n  `@strands-agents/sdk` `Agent` + `tool({ callback })` + Plugin /\n  `addHook` integration. Exports `guardTool`, `guardHooks`, and\n  `strandsAgentContext`. This is **not** the Python SDK. There is no\n  `guardInbound` (screen before `invoke()` / `stream()`), no\n  `guardApproval` / `guardInterrupt` (`event.interrupt()` is human HITL,\n  not policy). Do not also wrap the same tool with\n  `@arcjet/guard/vercel-ai/v7` or `@arcjet/guard/langgraph/v1`.\n\n  On DENY a guarded tool does not run and does not throw: it returns a\n  plain `ArcjetDenialResult` from the authored `callback`.\n  `FunctionTool` wraps that object in a `JsonBlock`. This helper does\n  not fabricate a `ToolResultBlock`. `guardHooks` is the invoke-wide\n  gate for MCP / unwrapped / vended tools:\n\n  ```ts\n  import { launchArcjet, detectPromptInjection, tokenBucket } from \"@arcjet/guard\";\n  import { guardTool, guardHooks, strandsAgentContext } from \"@arcjet/guard/strands-agents/v1\";\n  import { Agent, tool } from \"@strands-agents/sdk\";\n  import { z } from \"zod\";\n\n  const arcjet = launchArcjet({ key: process.env.ARCJET_KEY! });\n  const limit = tokenBucket({\n    refillRate: 10,\n    intervalSeconds: 60,\n    maxTokens: 10,\n  });\n\n  const lookupOrder = guardTool(\n    arcjet,\n    tool({\n      name: \"lookup_order\",\n      description: \"Look up an order\",\n      inputSchema: z.object({ orderNumber: z.string() }),\n      callback: async ({ orderNumber }) => ({ orderNumber, status: \"shipped\" }),\n    }),\n    {\n      action: \"order.looked-up\",\n      onGuardError: \"deny\",\n      rules: (input) => [limit({ key: input.orderNumber, requested: 1 })],\n    },\n  );\n\n  const invocationState = { sessionId: conversationId };\n  const inbound = detectPromptInjection();\n  const decision = await arcjet.guard({\n    label: \"message.received\",\n    rules: [inbound(userText)],\n    ...strandsAgentContext({ invocationState }),\n  });\n\n  if (decision.conclusion === \"DENY\") {\n    throw new Error(\"message blocked\");\n  }\n  const agent = new Agent({\n    tools: [lookupOrder],\n    plugins: [guardHooks(arcjet, { sessionId: conversationId })],\n  });\n  await agent.invoke(userText, { invocationState });\n  ```\n\n#### Screen inbound before `invoke()` / `stream()` — there is no inbound hook.\n\nStrands Agents has no first-class inbound channel, so there is no\n`guardInbound`. Put prompt-injection (and other inbound rules) in the\napplication before `agent.invoke()` / `stream()`. Middleware / model\nhooks are not this policy gate.\n\n#### `interrupt()` is not a policy gate.\n\n`event.interrupt()` is human-in-the-loop, not policy. Same trap as\nMastra `requireApproval`, Claude `canUseTool`, LangGraph `interrupt()`,\nOpenAI Agents `needsApproval`, and LangChain\n`humanInTheLoopMiddleware`. There is no `guardApproval` /\n`guardInterrupt`.\n\n#### Deny with `BeforeToolCallEvent.cancel` (and `guardTool` on authored callbacks). `BeforeToolsEvent.cancel` skips per-tool hooks — do not use it.\n\nThe authored `callback` is the deny point for tools you own. MCP,\nvended tools, and anything not wrapped with `guardTool` skip that\ncallback. `guardHooks` is the invoke-wide gate for those. Official:\nset `event.cancel` to a string; `tool.stream()` does not run;\n`AfterToolCallEvent` still fires. Do not use `BeforeToolsEvent.cancel`\n— a truthy value skips `_toolExecutor.execute()`, so per-tool hooks\nnever run.\n\nCorrelation is a field the integrator puts on `invocationState`\n(`correlationId`, then `sessionId`, then `requestId`). Never mint.\nNever read `traceId`. Never use `SessionManager` or `agent.id`.\n\n- **`@arcjet/guard/tanstack-ai/v0`** — TanStack AI `chat({ middleware })` +\n  `ChatMiddleware.onBeforeToolCall` integration. Exports `guardMiddleware`\n  and `tanstackAiContext`. This is **not** the Vercel AI SDK — do not also\n  wrap with `@arcjet/guard/vercel-ai/v7`. There is no `guardTool` (a throw\n  from `execute` is swallowed into `{ error }` and is not a usable deny\n  envelope), no `guardInbound` (screen with `guard()` before `chat()`;\n  `guard()` fails open — check `hasFailedOpen()`), and no `guardApproval`\n  (`needsApproval` / `defineInterrupt` / `onInterruptBoundary` is human\n  HITL, not policy). After a human yes, Guard still runs. Do not name\n  anything `contentGuardMiddleware` (TanStack already has that name). Docs\n  live at\n  [`/guards/tanstack-ai/`](https://docs.arcjet.com/guards/tanstack-ai/).\n\n  Put Arcjet **first** in the middleware array. `onBeforeToolCall` is\n  first-win; if `toolCacheMiddleware` (or anything else) skips first,\n  Guard never runs. Default DENY is `{ type: \"skip\", result:\nArcjetDenialResult }` so the tool never runs and the model sees the\n  payload. Optional `onDeny: \"abort\"` stops the run with a reason\n  string — the model does not get `ArcjetDenialResult`. The hook\n  does not throw. Tools already branded by a sibling `guardTool`\n  are skipped so Guard is not double-called. Inbound `guard()`\n  before `chat()` does not brand tools and does not skip this\n  gate. Correlation is a caller-owned id\n  from helper options or `chat({ context })`. Never mint. Never\n  `ctx.threadId`. Never `traceId` / `requestId` / `streamId`. Client\n  tools and provider-native tools with no local `execute` are out of\n  scope.\n\n  ```ts\n  import { launchArcjet, detectPromptInjection, tokenBucket } from \"@arcjet/guard\";\n  import { guardMiddleware, tanstackAiContext } from \"@arcjet/guard/tanstack-ai/v0\";\n  import { chat } from \"@tanstack/ai\";\n\n  const arcjet = launchArcjet({ key: process.env.ARCJET_KEY! });\n  const limit = tokenBucket({\n    refillRate: 10,\n    intervalSeconds: 60,\n    maxTokens: 10,\n  });\n\n  const appContext = { sessionId: conversationId };\n  const inbound = detectPromptInjection();\n  const decision = await arcjet.guard({\n    label: \"message.received\",\n    rules: [inbound(userText)],\n    ...tanstackAiContext({ context: appContext }),\n  });\n\n  if (decision.conclusion === \"DENY\") {\n    throw new Error(\"message blocked\");\n  }\n  if (decision.hasFailedOpen()) {\n    throw new Error(\"inbound screening failed open\");\n  }\n\n  const stream = chat({\n    adapter,\n    messages,\n    tools: [lookupOrder],\n    context: appContext,\n    middleware: [\n      guardMiddleware(arcjet, {\n        action: ({ toolName }) => `${toolName}.invoked`,\n        rules: ({ toolName }) => [limit({ key: toolName, requested: 1 })],\n        sessionId: conversationId,\n      }),\n    ],\n  });\n  ```\n\n#### Screen inbound before `chat()` — there is no inbound hook.\n\nTanStack AI has no first-class inbound channel, so there is no\n`guardInbound`. Put prompt-injection (and other inbound rules) in the\napplication before `chat()`. Call `guard()` directly. `guard()` fails\nopen — callers must check `hasFailedOpen()`. TanStack's\n`contentGuardMiddleware` redacts the stream; it is not this policy\ngate.\n\n#### `needsApproval` / `defineInterrupt` / `onInterruptBoundary` is HITL, not a policy gate.\n\n`needsApproval` / `defineInterrupt` / `onInterruptBoundary` is\nhuman-in-the-loop, not policy. After a human yes, Guard still runs\non the tool call. Same trap as Mastra `requireApproval`, Claude\n`canUseTool`, LangGraph `interrupt()`, Genkit `toolApproval`, OpenAI\nAgents `needsApproval`, and LangChain `humanInTheLoopMiddleware`.\nThere is no `guardApproval`.\n\n#### Deny inside `guardMiddleware`'s `onBeforeToolCall`. There is no `guardTool`.\n\n`onBeforeToolCall` is the deny point. Default DENY is\n`{ type: \"skip\", result: ArcjetDenialResult }`. Optional\n`onDeny: \"abort\"` returns `{ type: \"abort\", reason }` (the denial\n`message` string) and stops the run — the model does not get\n`ArcjetDenialResult`. `onDeny: \"abort\"` applies to real DENY only;\nunavailable stays skip. Do not throw from the hook. Put Arcjet\nfirst — first-win composition means a preceding\n`toolCacheMiddleware` skip skips Guard too. Sibling `guardTool`\nbrands are skipped; inbound `guard()` is a separate call and does\nnot skip this gate.\n\n- **`@arcjet/guard/google-adk/v2`** — Google ADK JS `@google/adk`\n  `Runner` + `BasePlugin.beforeToolCallback` integration. Exports\n  `guardPlugin` and `googleAdkContext`. This is **not** `@google/genai`\n  and **not** the Python google-adk SDK. There is no `guardTool`\n  (skip is the plugin return, not throw-from-execute), no\n  `guardInbound` (screen with `guard()` before `Runner.runAsync`;\n  `guard()` fails open — check `hasFailedOpen()`), and no\n  `guardApproval` (`requireConfirmation` / `requestConfirmation` /\n  `SecurityPlugin` CONFIRM is human HITL, not policy). After a human\n  yes, Guard still runs. Do not use ADK `SecurityPlugin` as the\n  Arcjet policy gate. Docs live at\n  [`/guards/google-adk/`](https://docs.arcjet.com/guards/google-adk/).\n\n  Put Arcjet **first** in `new Runner({ plugins })`. PluginManager\n  is first-win; if another plugin returns a value first, Guard never\n  runs. DENY is a dictionary (`ArcjetDenialResult`) so ADK skips\n  `runAsync` and the model sees the payload. `undefined` lets the\n  tool execute. The callback does not throw — PluginManager treats a\n  throw as a plugin error, not skip. On Guard error this helper\n  fail-closes: it ALWAYS returns a deny dict, never `undefined`\n  (unless `onGuardError: \"allow\"`). Tools already branded by a\n  sibling `guardTool` are skipped so Guard is not double-called.\n  Inbound `guard()` before `Runner.runAsync` does not b","readmeFilename":"README.md"}