pi-redactor

Pi extension that redacts sensitive strings from user input, tool results, and context before the LLM sees them.

Installation

pi install npm:pi-redactor

Or from a local path:

pi install /path/to/pi-redactor

How It Works

The extension intercepts messages at three points:

  1. input — rewrites your message before it reaches the LLM.
  2. tool_result — redacts tool output (file reads, command output, etc.) before it enters the conversation.
  3. context — scans the full message history immediately before each LLM call, catching secrets in historical context, assistant echoes, or custom messages.

All configured patterns are applied using a single-pass regex with longest-match-first semantics. The transformed text is sent instead of the original.

The LLM never sees the original sensitive strings.

If redaction fails at runtime (e.g., a malformed pattern), the extension fails closed: user messages are blocked, tool results are replaced with an error, and context is emptied. An error notification is displayed in each case. Disable the redactor with /redact off to bypass.

Commands

Command Description
/redact Show help and usage
/redact add <string> Add pattern; replaces with [REDACTED]
/redact add <string> as <label> Add pattern with custom replacement label
/redact remove <string> Remove pattern by its original string
/redact list Show all active patterns
/redact clear Remove all patterns (prompts for confirmation)
/redact on Enable redaction
/redact off Disable redaction
/redact limit <n> Set max pattern count (default 100, max 1000)

Parsing Rule

The delimiter ` as ` splits original from label. The last occurrence of ` as ` is used, so:

/redact add John Smith as CEO as [PERSON]

Redacts John Smith as CEO[PERSON].

Example

/redact add John Smith as [CLIENT]
/redact add acct_12345

Input: "Contact John Smith about acct_12345."

LLM receives: "Contact [CLIENT] about [REDACTED]."

Notification: 🔒 Redacted 2 occurrence(s) from your message

Behavior

Status Bar

State Display
Enabled, N patterns (N > 0) 🔒 Redactor: N pattern(s)
Enabled, 0 patterns 🔒 Redactor: no patterns
Disabled 🔓 Redactor: off

Configuration

Patterns persist to a platform-specific state directory that is outside of typical version-controlled dotfile paths:

Platform Path
Linux ~/.local/state/pi-redactor/config.json
macOS ~/.local/state/pi-redactor/config.json
Windows %LOCALAPPDATA%\pi-redactor\config.json

The XDG_STATE_HOME environment variable is respected on Linux/macOS. On Windows, LOCALAPPDATA is used.

On-Disk Format

The file uses an envelope format with integrity checking:

{
  "version": 1,
  "configVersion": 3,
  "checksum": "<sha256-hex-of-serialized-data>",
  "data": {
    "enabled": true,
    "maxPatterns": 100,
    "patterns": [
      {
        "original": "John Smith",
        "replacement": "[CLIENT]",
        "createdAt": 1710000000000
      }
    ]
  }
}
Field Description
version Envelope schema version. Currently 1.
configVersion Monotonically incrementing counter for concurrency control.
checksum SHA-256 hex digest of JSON.stringify(data). Used for tamper detection.
data.enabled Whether redaction is active.
data.maxPatterns Maximum number of patterns allowed. Default 100, max 1000.
data.patterns[].original The original string to redact.
data.patterns[].replacement The replacement label.
data.patterns[].createdAt Unix timestamp in milliseconds when the pattern was added.

Integrity and Concurrency

Limitations

Development Disclosure

This package was developed predominantly using an AI coding agent. All code, tests, and documentation were reviewed, validated, and approved by me.

License

MIT