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

@lapismd/agent-redaction

v0.1.1

Published

Portable fail-closed agent transcript sanitization

Readme

Agent redaction

npm version

Portable complete-block sanitization for observable agent transcripts. The core has no runtime effects. Explicit Node and Deno adapters add reviewed Secretlint detectors and granted secret discovery. This package does not sanitize external agent software, native VCS archives or data written before capture.

Install

npm install @lapismd/agent-redaction
# or
pnpm add @lapismd/agent-redaction

The Node adapter and executable require Node.js 22.13 or newer. The ESM package includes TypeScript declarations. Choose a public entry point for your runtime:

| Import | Purpose | | ------------------------------------- | -------------------------------------------------------------------------- | | @lapismd/agent-redaction | Portable scopes, complete-block buffering, result types and limits | | @lapismd/agent-redaction/node | Explicit Secretlint worker, synchronous adapter and granted secret loading | | @lapismd/agent-redaction/deno | Deno enforcement through its Node compatibility layer | | @lapismd/agent-redaction/secretlint | Explicit reviewed detector inventory |

Sanitize in Node.js

import { createNodeRedaction } from "@lapismd/agent-redaction/node";

const runtime = createNodeRedaction({
  secrets: ["demo-only-token"],
  roots: [{ kind: "workspace", path: "/srv/project", id: "project" }],
  destination: "public",
});

try {
  const result = await runtime.scope.text(
    "Loaded /srv/project/README.md with demo-only-token",
  );
  if (result.status === "sanitized") {
    console.log(result.value);
    // Loaded $WORKSPACE[project]/README.md with [REDACTED]
  } else {
    // Store or report only the fixed omission reason; never fall back to input.
    console.log(result.reason);
  }
} finally {
  runtime.dispose();
}

Use scope.value(plainJson) for structured records and scope.path(path) for logical path classification. Sensitive structured fields are removed; sanitized results are independent immutable values. Always handle both sanitized and omitted results. Keep real executable arguments separate from capture copies.

Environment and dotenv values are read only when explicitly granted:

import {
  createNodeRedaction,
  refreshNodeSecrets,
} from "@lapismd/agent-redaction/node";

const runtime = createNodeRedaction();
try {
  const ready = await refreshNodeSecrets(runtime.scope, {
    environment: ["API_TOKEN"],
  });
  if (!ready) throw new Error("Secret policy could not be loaded");
  const result = await runtime.scope.text("A complete captured message");
  // Deliver only result.value when result.status is "sanitized".
} finally {
  runtime.dispose();
}

Grant dotenvFiles separately using canonical absolute file paths. Refresh keeps previous secret values until disposal so rotation cannot expose earlier captures. There is no automatic file or environment discovery.

Portable and streamed captures

import { CompleteBlock, RedactionScope } from "@lapismd/agent-redaction";

const scope = new RedactionScope({ secrets: ["demo-only-token"] });
try {
  const block = new CompleteBlock(scope);
  block.append("Message with demo-");
  block.append("only-token");
  const result = await block.finish();
  // No text is released before finish() successfully scans the complete block.
} finally {
  scope.dispose();
}

The portable scope applies registered values, structured-field policy and path normalization; its coverage is portable. Construct the Node or Deno adapter to add the reviewed credential detectors (credential-detectors coverage). CompleteBlock accepts strings or UTF-8 byte chunks, but do not mix them within one block. Call block.cancel() when the capture is interrupted.

Text blocks are limited to 2 MiB; structured records to 4 MiB and depth 32. Overflow, invalid input and detector failures produce a fixed omission. A detector cannot recognize every secret; register sensitive values explicitly.

Deno

import { createDenoRedaction } from "npm:@lapismd/[email protected]/deno";

const runtime = createDenoRedaction({ secrets: ["demo-only-token"] });
try {
  const result = await runtime.scope.text("Message with demo-only-token");
} finally {
  runtime.dispose();
}

Run with the adapter's required permissions: deno run --allow-read --allow-env --allow-sys example.ts. Deno still enforces permissions; grant only the files and environment names your application authorizes. No worker starts on import.

Command-line transport

The executable reads one version-1 JSON request from stdin and writes one result to stdout. It does not accept raw text lines or an NDJSON stream.

printf '%s' '{"version":1,"value":"Message with demo-only-token","policy":{"secrets":["demo-only-token"],"destination":"public"}}' \
  | npx --yes --package=@lapismd/agent-redaction lapismd-agent-redaction

Provide actual capture data and secrets through your application's stdin pipe. The adapter keeps stderr empty, accepts at most 6 MiB of request data, and emits only sanitized results or fixed omissions.

Specification and development

Read the published specification, the canonical sanitization contract, and the verification record. The spec site is built from spec/src and deployed by GitHub Actions on main.

pnpm install --frozen-lockfile
pnpm spec:check
pnpm check
pnpm test
pnpm test:deno
pnpm build
pnpm publint

Specification builds require mdBook on PATH; Deno adapter tests require Deno. Package publication uses the separate protected release workflow.

Native Rust

The independent lapis-agent-redaction Rust crate preserves jj-store’s versioned Kingfisher privacy profiles. See native usage. It has no Node, Deno, JJ or agent-runtime dependency; the TypeScript policy remains separate.

Native checks use pnpm check:native and pnpm test:native, also included in the normal check/test lanes. Local source use does not publish the Cargo package.

pnpm release:native:prepare verifies the Cargo archive, notices, dependency licenses and an isolated consumer with serde_json/preserve_order enabled. CI runs native gates on Linux and Apple Silicon macOS. See the release procedure for independent npm and Cargo approvals, first-crate bootstrap and immutable publication recovery.