From 14419b006c97dc2c63e2bf078bf268c752094d1e Mon Sep 17 00:00:00 2001 From: x1xhlol Date: Sun, 4 Oct 2026 18:27:07 +0000 Subject: [PATCH] Fix npm 12 release verification and prepare Shield 2.1.1 --- .github/workflows/ci.yml | 7 ++++++ CHANGELOG.md | 5 +++++ README.md | 2 +- package.json | 2 +- registry/README.md | 13 +++++++++-- registry/issue.md | 2 +- registry/pr.md | 13 +++++++++++ registry/vercel-ai.patch | 45 +++++++++++++++++++++++++++++++++++++++ scripts/verify-package.ts | 23 +++++++++++++++----- 9 files changed, 102 insertions(+), 10 deletions(-) create mode 100644 registry/pr.md create mode 100644 registry/vercel-ai.patch diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ae82ca5..868c86d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,6 +15,10 @@ jobs: steps: - uses: actions/checkout@v7 + - uses: actions/setup-node@v6 + with: + node-version: 24 + - uses: oven-sh/setup-bun@v2 with: bun-version: latest @@ -31,6 +35,9 @@ jobs: - name: Build run: bun run build + - name: Match npm publishing environment + run: npm install --global npm@latest + - name: Validate package contents run: npm pack --dry-run diff --git a/CHANGELOG.md b/CHANGELOG.md index b1327fe..a9d3fd8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## [2.1.1] - 2026-10-04 + +- Fixed release verification for npm 12's package metadata format while retaining compatibility with earlier npm versions. Packed package names and versions are checked against the manifest, and publish dry runs still create and install real test artifacts. +- First npm release of the AI SDK inspection tool. The 2.1.0 publication stopped during verification before uploading a package; this version includes all changes below. + ## [2.1.0] - 2026-10-04 - Added `shieldCheck` at `@zeroleaks/shield/ai-sdk/tools` for AI SDK 5, 6, and 7. It uses local detection by default, supports explicit hosted detection and async local detectors, and returns detection metadata without repeating input text or matching patterns. diff --git a/README.md b/README.md index f5a2a35..7bf1fad 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,7 @@ Pass `detect: shield.options()` to the other wrappers in the same way. Omitting ## AI SDK inspection tool -Shield 2.1.0 adds an inspection tool for AI SDK 5, 6, and 7: +Shield 2.1.1 adds an inspection tool for AI SDK 5, 6, and 7: ```typescript import { shieldCheck } from "@zeroleaks/shield/ai-sdk/tools"; diff --git a/package.json b/package.json index 9347ea5..e810b37 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@zeroleaks/shield", - "version": "2.1.0", + "version": "2.1.1", "description": "Runtime security for LLM apps and agents: prompt injection detection for user input and tool results, and leak, credential, PII, and exfiltration checks on model output", "main": "dist/index.js", "module": "dist/index.mjs", diff --git a/registry/README.md b/registry/README.md index 732ce6c..38aa36f 100644 --- a/registry/README.md +++ b/registry/README.md @@ -1,10 +1,10 @@ # AI SDK registry submission -`entry.ts` contains the proposed object for `vercel/ai`'s `content/tools-registry/registry.ts`. `issue.md` is a ready-to-submit documentation-addition request. Neither file submits anything upstream. +`entry.ts` contains the proposed object for `vercel/ai`'s `content/tools-registry/registry.ts`. `vercel-ai.patch` adds that object to the registry; it was formatted and type-checked against upstream commit `7c41e416b6d5ca630cc5f72b330e6c4743f82265`. `pr.md` contains the PR title and description, and `issue.md` is an optional documentation-addition request. These files do not submit anything upstream. The public integration guide is `https://zeroleaks.ai/docs/shield-sdk/providers/ai-sdk-tools`. Its main example must match `entry.ts` exactly. The ZeroLeaks app's package verifier checks that parity; Shield's isolated package verifier type-checks and executes the registry snippet. -Before submitting, confirm that npm serves `@zeroleaks/shield@2.1.0` and the integration guide is live. The source repository, README, public docs, and published package must describe the same exports and supported SDK versions. +Before submitting, confirm that npm serves `@zeroleaks/shield@2.1.1` and the integration guide is live. The source repository, README, public docs, and published package must describe the same exports and supported SDK versions. Run the release checks from the Shield repository: @@ -21,3 +21,12 @@ The package verifier uses isolated npm installations and mocked model/API respon The published entry should keep local detection as the default example and link directly to the AI SDK tool guide. An optional ZeroLeaks API key is documented on that page; it is not a prerequisite for the local tool. The model example requires `AI_GATEWAY_API_KEY`. Follow the current [contribution guide](https://github.com/vercel/ai/blob/main/contributing/add-new-tool-to-registry.md). An issue-first documentation request has recent precedent, but may cause their automation to open a PR. Hold both the issue and PR until submission is authorized. + +Once the prerequisites above are live and submission is authorized, apply the patch in a current `vercel/ai` checkout: + +```bash +git apply --check /path/to/shield/registry/vercel-ai.patch +git apply /path/to/shield/registry/vercel-ai.patch +``` + +Rebase the entry if upstream has changed, then use the repository's current formatting and validation commands before submitting. diff --git a/registry/issue.md b/registry/issue.md index a824d6c..aea58df 100644 --- a/registry/issue.md +++ b/registry/issue.md @@ -10,7 +10,7 @@ The package also provides `shieldLanguageModelMiddleware` to check user messages - Canonical repository: https://github.com/ZeroLeaks/shield - AI SDK integration guide: https://zeroleaks.ai/docs/shield-sdk/providers/ai-sdk-tools - Website: https://zeroleaks.ai/shield -- Version prepared and tested: `@zeroleaks/shield@2.1.0` +- Version prepared and tested: `@zeroleaks/shield@2.1.1` - Current SDK tested: `ai@7.0.127` - Additional supported SDKs tested: `ai@5.0.267`, `ai@6.0.292` diff --git a/registry/pr.md b/registry/pr.md new file mode 100644 index 0000000..a93c50b --- /dev/null +++ b/registry/pr.md @@ -0,0 +1,13 @@ +Title: feat(tools-registry): add zeroleaks-shield + +Adds [ZeroLeaks Shield](https://zeroleaks.ai/shield) to the tools registry with `shieldCheck` from [`@zeroleaks/shield`](https://www.npmjs.com/package/@zeroleaks/shield). It inspects text for prompt injection and jailbreaks locally by default, with hosted detection available on explicit opt-in. The example combines the tool with language model middleware that blocks detected injections before model calls. Model-invoked inspection is advisory; detection results do not authorize agent actions. + +The entry links directly to the [AI SDK integration guide](https://zeroleaks.ai/docs/shield-sdk/providers/ai-sdk-tools). Its example uses current AI SDK imports, AI Gateway, and `isStepCount`. Local detection needs no ZeroLeaks key; the Gateway model needs `AI_GATEWAY_API_KEY`. + +Validation for Shield 2.1.1: + +- 1,263 passing tests, with two optional model tests skipped. +- Isolated packed-package consumers on AI SDK 5.0.267, 6.0.292, and 7.0.127, covering generation, streaming, malformed inputs, hosted errors, and middleware blocking. +- Strict ESM and CommonJS consumer types; root and middleware imports without optional provider SDKs installed. +- Exact registry example type-checked and executed against a mocked Gateway for a two-step tool roundtrip, without live inference calls. +- Registry entry formatted and type-checked against the upstream `Tool` interface. diff --git a/registry/vercel-ai.patch b/registry/vercel-ai.patch new file mode 100644 index 0000000..f40632a --- /dev/null +++ b/registry/vercel-ai.patch @@ -0,0 +1,45 @@ +diff --git a/content/tools-registry/registry.ts b/content/tools-registry/registry.ts +index 7ba3c15..5c80363 100644 +--- a/content/tools-registry/registry.ts ++++ b/content/tools-registry/registry.ts +@@ -689,4 +689,40 @@ console.log(text);`, + websiteUrl: 'https://pushary.com/human-in-the-loop', + npmUrl: 'https://www.npmjs.com/package/@pushary/ai-sdk', + }, ++ { ++ slug: 'zeroleaks-shield', ++ name: 'ZeroLeaks Shield', ++ description: ++ 'Prompt injection and jailbreak detection for user messages, retrieved documents, web pages, and tool results. Inspect text with shieldCheck locally without an API key, or opt into the hosted Shield API. Pair it with Shield language model middleware to block detected injections before model calls.', ++ packageName: '@zeroleaks/shield', ++ tags: ['security', 'guardrails', 'prompt-injection', 'jailbreak'], ++ installCommand: { ++ pnpm: 'pnpm add @zeroleaks/shield ai zod', ++ npm: 'npm install @zeroleaks/shield ai zod', ++ yarn: 'yarn add @zeroleaks/shield ai zod', ++ bun: 'bun add @zeroleaks/shield ai zod', ++ }, ++ codeExample: `import { gateway, generateText, isStepCount, wrapLanguageModel } from 'ai'; ++import { shieldLanguageModelMiddleware } from '@zeroleaks/shield/ai-sdk'; ++import { shieldCheck } from '@zeroleaks/shield/ai-sdk/tools'; ++ ++const model = wrapLanguageModel({ ++ model: gateway('openai/gpt-5-mini'), ++ middleware: shieldLanguageModelMiddleware(), ++}); ++ ++const { text } = await generateText({ ++ model, ++ tools: { shieldCheck: shieldCheck() }, ++ stopWhen: isStepCount(3), ++ prompt: ++ 'Check this support note with shieldCheck, then summarize it: Our support desk opens at nine on Monday.', ++}); ++ ++console.info(text);`, ++ docsUrl: 'https://zeroleaks.ai/docs/shield-sdk/providers/ai-sdk-tools', ++ apiKeyUrl: 'https://zeroleaks.ai/dashboard/shield', ++ websiteUrl: 'https://zeroleaks.ai/shield', ++ npmUrl: 'https://www.npmjs.com/package/@zeroleaks/shield', ++ }, + ]; diff --git a/scripts/verify-package.ts b/scripts/verify-package.ts index d65e5a1..7d01253 100644 --- a/scripts/verify-package.ts +++ b/scripts/verify-package.ts @@ -7,12 +7,20 @@ import { join, resolve } from "node:path"; import { promisify } from "node:util"; import { shieldRegistryEntry } from "../registry/entry"; +interface PackMetadata { + filename: string; + name: string; + version: string; + files: { path: string }[]; +} + const execute = promisify(execFile); const directory = resolve(import.meta.dirname, ".."); const temporary = await mkdtemp(join(tmpdir(), "shield-package-")); const manifest = JSON.parse( await readFile(join(directory, "package.json"), "utf8") ) as { + name: string; version: string; exports: Record>; }; @@ -24,6 +32,8 @@ async function run( ): Promise { const { stdout } = await execute(command, args, { cwd, + // npm publish --dry-run must still pack and install real test artifacts. + env: { ...process.env, npm_config_dry_run: "false" }, timeout: 120_000, maxBuffer: 8 * 1024 * 1024, }); @@ -138,19 +148,22 @@ process.on('exit', () => assert.equal(calls, 2)); `; try { - const packed = JSON.parse( + const packOutput = JSON.parse( await run( "npm", ["pack", "--json", "--pack-destination", temporary], directory ) - ) as { - filename: string; - files: { path: string }[]; - }[]; + ) as PackMetadata[] | Record; + // npm 12 keys pack metadata by package name; earlier versions return an array. + const packed = Array.isArray(packOutput) + ? packOutput + : Object.values(packOutput); assert.equal(packed.length, 1); const artifact = packed[0]; assert.ok(artifact); + assert.equal(artifact.name, manifest.name); + assert.equal(artifact.version, manifest.version); const files = new Set(artifact.files.map((file) => file.path)); for (const [name, targets] of Object.entries(manifest.exports)) { for (const target of Object.values(targets)) {