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

@chatpanel/gateway

v0.6.31

Published

Local privacy gateway — redacts PII out of OpenAI/Anthropic API traffic before it reaches a model, then restores it in the reply. Point opencode, codex, aider, Claude Code, etc. at it.

Readme

ChatPanel Privacy Gateway

A localhost server that puts ChatPanel's PII redaction / pseudonymization in the middle of two CLI agents — so you can use the privacy features outside the ChatPanel extension. Point opencode / pi at the gateway, and it drives codex / Claude Code behind your existing subscription login (via the bridge), redacting on the way out and restoring on the way back. The model only ever sees opaque placeholders like [[PERSON_1]] / [[EMAIL_2]]the real values never leave your machine.

  opencode / pi   (configured with a custom provider → the gateway)
        │   baseURL → http://127.0.0.1:4320/v1
        ▼
  ┌──────────────────────────────────────────────┐
  │  ChatPanel Privacy Gateway                    │
  │   1. detect + redact   →  [[PERSON_1]] …       │
  │   2. drive the agent behind your login        │
  │   3. restore placeholders in the reply         │
  └──────────────────────────────────────────────┘
        │   POST /chat  (bridge: subscription-authed CLI)
        ▼
  chatpanel-bridge ──spawns──▶ codex / claude   (your ChatGPT / enterprise / Claude login)

Two backends (config backend):

  • bridge (default) — drive the bridge's subscription-authed CLI agents (codex / claude / opencode / pi). No API keys, uses your login. This is the "privacy bridge between two agents" path above.
  • api — forward redacted traffic to a native OpenAI/Anthropic-compatible endpoint (local models, BYO keys). The client's own auth header passes through; the gateway stores no keys.

The redaction engine is the same code the ChatPanel extension runs — the @chatpanel/pii package is the single source of truth, so a privacy feature added once is shared everywhere.

Quick start (bridge backend)

You need the ChatPanel bridge running and logged into codex/claude (the same bridge the extension uses).

# Standalone binary — no Node.js required:
curl -fsSL https://dl.chatpanel.net/gateway/install.sh | bash   # macOS / Linux
#   Windows (PowerShell):  irm https://dl.chatpanel.net/gateway/install.ps1 | iex

# Or via npm (needs Node):
npm install -g @chatpanel/gateway
chatpanel-gateway
# → ChatPanel Privacy Gateway on http://127.0.0.1:4320
#     backend  : bridge (agent: codex, via http://127.0.0.1:4319)

Binary vs. npm — same features, very different local-AI speed. Both run identical redaction/routing. But the standalone binary runs the local models (speech-to-text, diarization, NER) on the WASM runtime — fp32-only, single-threaded, slow. The npm install uses the native runtime with quantized (q8) models — in our tests ~10× faster speech-to-text (real-time even on larger, more accurate models). If you'll use voice/meeting features, install via npm. Don't run both — they can shadow each other on PATH; check GET /healthstt.runtime (native vs wasm).

Then point your front-end agent at it. opencode (opencode.json):

{
  "provider": {
    "chatpanel": {
      "npm": "@ai-sdk/openai-compatible",
      "options": { "baseURL": "http://127.0.0.1:4320/v1" },
      "models": { "codex": {}, "claude": {} }   // selects the agent behind the gateway
    }
  }
}

Now opencode talks to codex through the gateway — every prompt is redacted before codex sees it, and the reply is restored before opencode renders it. The request's model (codex/claude/opencode/pi) picks which agent the bridge drives; otherwise the configured default (codex) is used.

Quick start (api backend — no bridge)

If all you want is the gateway as a redacting proxy in front of an API model, you do not need the bridge. Set backend: "api" and (optionally) point the gateway's upstream at your provider — in ~/.chatpanel/gateway.config.json:

{
  "backend": "api",
  "upstreams": {
    "openai":    { "baseUrl": "https://api.openai.com" },
    "anthropic": { "baseUrl": "https://api.anthropic.com" }
  }
}

Then point your client at the gateway and send your own API key — the gateway redacts, forwards to the provider with your key (it stores none), and restores the reply:

# In your CLIENT's environment (NOT the gateway's — see the footgun below):
export OPENAI_BASE_URL=http://127.0.0.1:4320/v1     # OpenAI-compatible: codex / aider / cursor / SDKs
export ANTHROPIC_BASE_URL=http://127.0.0.1:4320     # Claude Code / Anthropic SDK

To target a non-OpenAI provider (a local model, OpenRouter, Azure, …) change the gateway's upstreams.*.baseUrl in the config above — that's where the gateway forwards to. Flow: client → gateway (redact) → provider (your key) → gateway (restore) → client.

⚠️ Footgun: OPENAI_BASE_URL means two different things — for your client it's "where the gateway is", for the gateway it's "where my upstream is". Don't set OPENAI_BASE_URL=…:4320 in the gateway's own environment, or it forwards to itself (the loop guard returns 508). Set the gateway's upstream in the config file; use the env var only in the client's shell.

Name/org redaction is built in (in-process NER, no Python)

Deterministic redaction (emails, phones, cards, SSNs, API keys, IPs) needs no setup. To also blind names, organizations and locations, the gateway runs an in-process entity detector — an ONNX transformer model via transformers.js — with ner.autostart on (the default). There's no Python, no second port, no separate process: the same model runs identically on macOS / Windows / Linux. The model loads from ~/.chatpanel/models and is downloaded once on first run if absent (set ner.allowDownload: false to require it be pre-placed). It's fail-open, so if the model can't load the gateway just runs deterministic-only. Once the detector is ready, redaction switches to the full tier automatically.

The default model (Xenova/bert-base-NER) matches or beats spaCy's small model on people/orgs/locations. Larger or alternative models can be installed from the ChatPanel extension's Gateway settings.

Prefer a local LLM or your own external NER service? Set redaction.detection yourself and the gateway won't load the bundled one (yours takes precedence).

Configuration

Precedence: defaults < gateway.config.json (or $CHATPANEL_GATEWAY_CONFIG) < env vars. See gateway.config.example.json.

| Key | Env | Default | Meaning | |-----|-----|---------|---------| | backend | — | bridge | bridge (drive CLI agents via login) or api (forward to a provider) | | bridge.url | — | http://127.0.0.1:4319 | the ChatPanel bridge | | bridge.agent | — | codex | default agent the bridge drives | | bridge.token | — | (auto) | bridge bearer token; empty = read ~/.chatpanel/bridge-token | | host / port | CHATPANEL_GATEWAY_HOST / _PORT | 127.0.0.1 / 4320 | bind address | | upstreams.openai.baseUrl | OPENAI_BASE_URL | https://api.openai.com | api backend only | | upstreams.anthropic.baseUrl | ANTHROPIC_BASE_URL | https://api.anthropic.com | api backend only | | redaction.tier | CHATPANEL_REDACTION_TIER | basic | basic (regex) or full (+ NER + dictionary) | | redaction.detection | — | (off → bundled engine) | external detector; set to override the bundled in-process one | | redaction.dictionary | — | [] | custom { value\|pattern, type, alias? } entries | | ner.autostart | — | true | load the bundled in-process NER on startup | | ner.model | — | Xenova/bert-base-NER | model id under ~/.chatpanel/models | | ner.allowDownload | — | true | download the model on first run if absent |

Endpoints

| Route | Behavior | |-------|----------| | GET /health | { ok, version, backend, tier } | | GET /v1/models | the agent(s) this gateway exposes | | POST /v1/chat/completions | OpenAI protocol — redact → backend → restore | | POST /v1/responses | OpenAI Responses protocol (Codex) | | POST /v1/messages | Anthropic protocol (Claude Code) |

Streaming (SSE) is supported on all three: placeholders are restored on the fly, holding back a tail so a token split across chunks ([[PERSON_1]]) still restores cleanly.

How it fits with ChatPanel

The extension redacts inside the browser; the bridge lets the browser drive local CLI agents. This gateway reuses the bridge to put the same redaction engine (@chatpanel/pii) in front of any agent — so non-browser tools get the privacy too, and the agent's own multi-turn loop is blinded, not just the first prompt.

Caveats

  • Reversibility is best-effort: if the model paraphrases a placeholder instead of echoing it, that one reference shows the token. The privacy guarantee (the real value never left the device) always holds.
  • A dictionary alias is a permanent pseudonym — the agent sees the alias, not the original, by design.
  • Code edits: redacting values that appear inside source can affect round-trip edits. The default tier touches only structured secrets and (in full) detected entities — keep your dictionary prose-focused.

License

Source-available under the same license as the ChatPanel extension and bridge — see LICENSE.