npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

shroud-ai

v0.1.1

Published

Redact sensitive data (emails, phones, cards, secrets) before it reaches an AI model, and rehydrate it in the reply.

Downloads

328

Readme

Shroud

One-line PII & secret redaction for your AI SDK calls — redact on the way out, rehydrate on the way back.

shroud-ai wraps your existing OpenAI / Anthropic / Vercel AI client so sensitive values (emails, phone numbers, credit cards, API keys) are stripped out before a request leaves your process and restored in the model's reply — with one line of code, zero runtime dependencies, and no Python sidecar or hosted service. Pure TypeScript, runs in-process, MIT-licensed.

The redaction primitive isn't novel (see How it compares); the point is the drop-in ergonomics — wrap your client, change nothing else, and your PII never reaches the provider.

Status: pre-1.0 — the API below is implemented and tested (detection, redact/ rehydrate, and the three SDK wrappers). Minor changes are still possible before 1.0; see CHANGELOG.md.

Why

Sending raw user text to a third-party model can leak PII and secrets into logs, training pipelines, and prompt history. Shroud lets you keep the convenience of plain-text prompts while the values that matter never reach the provider:

You → Shroud → AI provider → Shroud → You
       redact                 rehydrate

Install

npm install shroud-ai

Quick start

import { redact, rehydrate } from "shroud-ai";

const original = "Email [email protected] or call 415-555-0132.";

const { text, mapping } = redact(original);
// text === "Email [SHROUD_EMAIL_1] or call [SHROUD_PHONE_1]."

// ...send `text` to your AI model, get a reply that echoes the placeholders...
const modelReply = `I've emailed [SHROUD_EMAIL_1] and called [SHROUD_PHONE_1].`;

const restored = rehydrate(modelReply, mapping);
// restored === "I've emailed [email protected] and called 415-555-0132."

What it detects

| Type | Placeholder | Notes | |---|---|---| | Email addresses | [SHROUD_EMAIL_n] | WHATWG/HTML5 pragmatic matcher (dotted domain required) | | Phone numbers | [SHROUD_PHONE_n] | North-American & E.164-style formats (best-effort) | | Credit-card numbers | [SHROUD_CARD_n] | 13–19 digits, Luhn + IIN/BIN-validated to cut false positives | | API keys / secrets | [SHROUD_SECRET_n] | distinctive provider key prefixes (OpenAI, AWS, GitHub, Google, Slack, Stripe) |

Detection is deterministic: the same value always maps to the same placeholder within a single redact() call, so a value that appears twice is redacted once and rehydrates everywhere.

Drop-in wrappers for AI SDKs

Shroud ships thin wrappers so you can protect existing code without restructuring it. The SDKs are optional peer dependencies — install only the one(s) you use.

OpenAI

import OpenAI from "openai";
import { wrapOpenAI } from "shroud-ai/openai";

const client = wrapOpenAI(new OpenAI());

const res = await client.chat.completions.create({
  model: "gpt-4o-mini",
  messages: [{ role: "user", content: "Email [email protected] a summary." }],
});
// outgoing message is redacted; res content is rehydrated for you

Anthropic

import Anthropic from "@anthropic-ai/sdk";
import { wrapAnthropic } from "shroud-ai/anthropic";

const client = wrapAnthropic(new Anthropic());

const res = await client.messages.create({
  model: "claude-haiku-4-5",
  max_tokens: 256,
  messages: [{ role: "user", content: "Call 415-555-0132 and confirm." }],
});

Vercel AI SDK

import { generateText } from "ai";
import { openai } from "@ai-sdk/openai";
import { withShroud } from "shroud-ai/ai";

const { text } = await withShroud(generateText)({
  model: openai("gpt-4o-mini"),
  prompt: "Draft a reply to [email protected].",
});

API

  • redact(text: string, options?: RedactOptions): RedactResult — returns { text, mapping }. options.types?: DetectionType[] restricts which detectors run (default: all four).
  • rehydrate(text: string, mapping: Mapping): string — restores originals from placeholders; unknown placeholders are left untouched.
  • Mapping is a plain Record<placeholder, original> — JSON-serializable, so you can store it or pass it alongside the request and rehydrate the reply elsewhere.
  • wrapOpenAI, wrapAnthropic, withShroud — SDK wrappers (subpath exports).

Restrict detection:

redact("email [email protected], call 415-555-0132", { types: ["EMAIL"] });
// only the email is redacted; the phone number is left as-is

See the public-API contract and docs/decisions/0002-redaction-architecture.md for the spec and design rationale.

Behavior & limits

  • Reversible round-trip: rehydrate(redact(t).text, redact(t).mapping) === t for any input that doesn't already contain a placeholder token (property-tested; see the edge case below).
  • Not a security boundary on its own. Detection is best-effort pattern matching; it reduces exposure, it does not guarantee zero leakage. Review the redacted text for your threat model. See SECURITY.md.
  • Literal-token edge case: if your input already contains a [SHROUD_<TYPE>_<n>] token, exact round-trip isn't guaranteed for that token (vanishingly rare in real prompts).
  • Phone detection is best-effort (regex, not full libphonenumber validation), and the free core detects only the distinctive API-key shapes — generic high-entropy secrets are out of scope for now.

How it compares

The reversible redact-then-rehydrate pattern and local TypeScript redaction already exist in the ecosystem — Shroud's distinct edge is the drop-in SDK wrappers (wrap your client, change nothing else) plus running fully in-process with no Python sidecar.

| | Shroud | openredaction / pii-vault | hai-guardrails | Presidio / LLM Guard | |---|---|---|---|---| | Language | TypeScript | TypeScript | TypeScript | Python | | Runs in your Node process | ✅ | ✅ | ✅ | ❌ (Docker / REST sidecar) | | Reversible (rehydrates the reply) | ✅ | ✅ | ❌ (one-way) | ✅ (LLM Guard) | | Drop-in openai/anthropic/ai wrappers | ✅ | ❌ | ❌ | ❌ | | Runtime dependencies | none | none | some | heavy |

Honest take: if you need the broadest PII coverage (names, addresses via ML/NER), reach for Presidio. If you want a zero-dependency TypeScript library that wraps your AI client in one line and restores the reply, that's Shroud. There's also Rehydra, a local proxy that redacts traffic from tools like Claude Code/Cursor — a different shape (a gateway, not a library).

Feedback

Shroud is new and we're listening. If you're using it — or looked and chose not to — please tell us in a GitHub issue: what you're building, which SDK, and whether a hosted or compliance-focused version would help. It genuinely shapes the roadmap.

Contributing

See CONTRIBUTING.md. This project is built to a senior-team quality bar from commit #1.

Acknowledgements

Detection patterns were informed by (not copied from) gitleaks (MIT), the WHATWG HTML email spec, and Microsoft Presidio (MIT). See NOTICE and docs/research/detection-prior-art.md; no third-party code is vendored.

License

MIT © The Shroud Authors