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

opencode-log-sanitizer

v1.2.3

Published

Sanitizes pasted logs before sending them to AI by redacting long quoted strings, JWT tokens, bcrypt hashes, and base64 blobs to reduce token usage and remove irrelevant noise.

Readme

opencode-log-sanitizer

OpenCode plugin that automatically redacts JWT tokens, bcrypt hashes, base64 blobs, and long quoted strings from your prompts before they reach the AI — reducing token usage and removing irrelevant noise.

npm License: MIT

I built this for my own use — I got tired of JWTs and base64 blobs eating up my token budget every time I pasted a log. Figured it might be useful for you too.


Quick Start

Add this to your opencode.json:

{
  "plugin": ["opencode-log-sanitizer"]
}

Restart OpenCode. Done. Sensitive values in your prompts are redacted automatically before they reach the model.


What it does

When you paste a large log into OpenCode, the plugin sanitizes it before the AI sees it:

| Pattern | Example | Replacement | | -------------------------- | ------------------------------- | ---------------------------- | | JWT tokens | eyJhbGci...header.payload.sig | [redacted:jwt] | | bcrypt hashes | $2b$10$abc... | [redacted:bcrypt] | | base64 blobs ≥ 300 chars | iVBORw0KGgo....(900 chars) | [redacted:base64:984chars] | | Quoted strings ≥ 300 chars | "a very long token value..." | "redacted" |

No config needed. Works on any text you type or paste.


How it works

The plugin hooks into OpenCode's chat.message event. This hook fires just before the user message is forwarded to the LLM, and provides a mutable output.parts array. The plugin iterates over every TextPart and runs the sanitization pipeline on its .text field.

Why not tui.prompt.append?
tui.prompt.append fires when text is appended to the TUI input box. It is a notification event — mutating its output does not change what gets sent to the model. chat.message is the correct interception point.

The sanitization pipeline runs in this order:

  1. Extract <no-redact> blocks → replace with temporary placeholders
  2. Redact JWT tokens → [redacted:jwt]
  3. Redact bcrypt hashes → [redacted:bcrypt]
  4. Redact base64 blobs longer than maxStringLength[redacted:base64:Nchars]
  5. Redact quoted strings longer than maxStringLength"redacted" (linear-time scanner, no regex backtracking)
  6. Restore the <no-redact> placeholders

Installation

From npm (recommended)

Add the plugin to your opencode.json:

{
  "plugin": ["opencode-log-sanitizer"]
}

OpenCode installs npm plugins automatically using Bun at startup. Packages are cached in ~/.cache/opencode/node_modules/.

From a local file

Copy dist/index.js into .opencode/plugins/ in your project (or ~/.config/opencode/plugins/ globally). OpenCode loads all files in those directories at startup.


Configuration

All options are optional. Defaults work well out of the box.

{
  "plugin": [
    [
      "opencode-log-sanitizer",
      {
        "maxStringLength": 300,
        "enableJwtDetection": true,
        "enableBcryptDetection": true,
        "enableBase64Detection": true
      }
    ]
  ]
}

| Option | Type | Default | Description | | ----------------------- | --------- | ------- | ------------------------------------------------------------ | | maxStringLength | number | 300 | Quoted strings or base64 blobs longer than this are redacted | | enableJwtDetection | boolean | true | Redact JWT tokens (eyJ...header.payload.sig) | | enableBcryptDetection | boolean | true | Redact bcrypt hashes ($2a$, $2b$, $2y$) | | enableBase64Detection | boolean | true | Redact base64 blobs longer than maxStringLength chars |


The <no-redact> bypass

Need to include a specific value verbatim? Wrap it in <no-redact> tags:

I need you to decode this token exactly:
<no-redact>
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8U
</no-redact>

The rest of my log can be sanitized normally: ...

Anything inside <no-redact>…</no-redact> is never touched, regardless of length or content.


Before / After

Before (what you type):

{
  "email": "[email protected]",
  "passwordHash": "$2b$10$abcdefghijklmnopqrstuuABCDEFGHIJKLMNOPQRSTUVWXYZ01234",
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
  "avatar": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAKACAYAAAAMuvCsAAA....(900 more chars)...."
}

After (what the AI sees):

{
  "email": "[email protected]",
  "passwordHash": "[redacted:bcrypt]",
  "token": "[redacted:jwt]",
  "avatar": "[redacted:base64:984chars]"
}

Troubleshooting

My value isn't being redacted

  • Check maxStringLength — if the value is a bare (unquoted) string shorter than 300 chars, it won't be caught by the quoted-string rule. Wrap it manually or lower the threshold.
  • JWT detection requires the three-part header.payload.signature format starting with eyJ, with each segment ≥ 10 characters.
  • Base64 detection requires at least one + or / character in the blob. Pure alphanumeric strings (e.g. hex hashes, UUIDs) are intentionally not matched to avoid false positives.

A value is being redacted that I need

  • Wrap it in <no-redact>…</no-redact> tags.

Nothing seems to be happening

  • Make sure the plugin is listed in opencode.json under "plugin".
  • Restart OpenCode after config changes.

Contributing

Contributions are welcome!


Development

git clone https://github.com/errhythm/opencode-log-sanitizer.git
cd opencode-log-sanitizer
bun install
bun test          # 38 test cases
bun run build     # build dist/
bun run lint      # lint

License

MIT © Ehsanur Rahman Rhythm