omp packages

pi-read-guard0.1.10

Pi extension that prevents massive unbudgeted full-file reads, steering the agent to offset/limit or search tools. Zero prompt tokens.

greenspand Published 4 days ago MIT ~1.3K downloads/mo

Untested on omp

This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.

Did it work for you?

Result

One report per person. A new report replaces your old one.

Reports 0

No reports yet.

Readme

pi-read-guard

npm npm downloads CI License: MIT

A pi extension that prevents massive unbudgeted full-file reads, steering the agent to offset/limit or search tools.

Enforcement lives in a tool_call hook, so it adds zero tokens to the system prompt.

The agent tries to read a 319-line file whole; pi-read-guard blocks it and the agent reads a 60-line slice instead

Rules

  • read on any file with more than maxReadLines (default 200) without offset or limit is blocked.
  • Images, PDFs and any binary file are never blocked (a NUL byte in the first 8 KB, or an image/PDF extension): their newline bytes are noise, and blocking them would break screenshots.
  • The model is steered to read a slice with offset/limit, or to search first (rg, codegraph_search).

Install

From npm:

pi install npm:pi-read-guard

Or from git:

pi install git:github.com/sorinirimies/pi-read-guard

Previews

Recorded from a real pi with only this plugin loaded; a small scripted mock model plays the agent, so you see the real guard reacting to real tool calls.

A full read of a large file is blocked, the agent reads a slice (60 lines instead of 319):

The read is blocked and the agent reads lines 1 to 60

No bypass by spelling: ~/… and @… paths (which pi expands before reading) are blocked just like the plain one:

Reading via ~/ and @ is blocked too

Commands: status and block count, off / on, and allow <path> for one deliberate full read:

/read-guard status, off, on and allow

Commands

  • /read-guard: status and block count
  • /read-guard off / on: disable / enable for this session
  • /read-guard allow <path>: allow one full read of <path> this session

Config (optional)

~/.pi/agent/read-guard.json:

{ "maxReadLines": 200, "ignore": ["*.md", "*.json"] }

Security notes

  • A token saver, not a sandbox. It guards pi's read tool. An agent can still read files through bash (cat); the guard keeps accidental full-file reads out of your context, nothing more.
  • Same path as the tool. Paths are resolved exactly like pi's own read (@file, ~/file, file://, Unicode spaces, Windows shell paths, and the macOS filename variants it falls back to), so those spellings can't slip past it. A contract test compares it with pi's real resolveToCwd.
  • Fails open. pi blocks a tool when a tool_call handler throws, so any unexpected error here means "allow".
  • Constant memory. Line counts are streamed (64 KB chunks, early exit), never the whole file.
  • No network access, no shell commands, zero runtime dependencies.

Development

bun install
just check          # typecheck + tests + pack check + nushell tests (what CI runs)
just test           # bun test only (with coverage)
just coverage       # tests + a coverage table
just push-all       # push main to every configured remote (origin + the Gitea instances); `just --list` has pull-all, push-tags-all, release-all, the *-force and sync-gitea-* variants

Coverage: every bun test collects coverage (bunfig.toml) and fails below 95% lines / 95% functions. CI shows the table on the run page and uploads lcov.info.

CI scripts are nushell (scripts/), the same ones locally and in GitHub / Gitea Actions. just --list shows every task.

Demo recordings

The GIFs above live in examples/vhs/generated/ and are stored with Git LFS (git lfs install once). They are recorded with VHS from a real pi that loads only this extension, on synthetic data (examples/vhs/fixture.sh), never from real files, sessions or credentials. The agent is a scripted mock model (examples/vhs/mock-llm.ts), so the recording is repeatable.

just vhs-all          # every tape (examples/vhs/*.tape): needs vhs, ttyd, ffmpeg, pi, bun, python3
just vhs-tape overview  # one tape
just vhs-list         # list the tapes
just demo             # try it yourself in a real pi on the same synthetic data

Releases (automatic)

Workflow When What
CI push / PR quality gate on Linux; tests on macOS and Windows
Auto-merge library updates CI finished on a Dependabot PR patch and minor updates (GitHub Actions) are merged automatically, but only after CI is green on that exact commit; a major update waits for you. Then it starts the nightly workflow so the update ships
Nightly Dependency Update every night (GitHub 02:00 UTC, Gitea 02:30) and after each auto-merge bun update within ranges, verify on all platforms, commit chore(deps); then build, tag and publish a new patch whenever a library was upgraded or merged, or feat/fix/perf commits are waiting since the last tag
Release tag vX.Y.Z validates the tag against package.json, runs the gate, npm publish (idempotent, with provenance), creates the release

So library updates need no human: they are merged once CI passes, built, versioned and published as a patch. A downgrade, a failing check, or a major update stops the chain and waits for review.

Manual release: just release patch (or minor / major / X.Y.Z) bumps, tags and pushes to GitHub; just release-all patch pushes to every configured remote; just push-release-all pushes an existing bump.

Secrets (repo settings): NPM_TOKEN is an npm granular access token with publish rights and "bypass 2FA" (required for CI publishing). Optional: GH_PAT (lets a tag push trigger the release itself), GITEA_TOKEN (Gitea).

Commits follow Conventional Commits; the changelog is generated by git-cliff.

Related plugins

Four small pi extensions that save tokens without adding anything to the system prompt:

Plugin What it does
pi-edit-first Blocks whole-file write rewrites and hand-written project manifests, steering the agent to targeted edit calls and scaffolders
pi-read-guard Blocks full reads of large files, steering the agent to offset/limit or search
pi-tokenburn Live token and cost counter in pi's footer, with charts and budgets
pi-context-diet Drops stale tool results from the context when the prompt cache is already cold, so long sessions cost less
pi install npm:pi-edit-first
pi install npm:pi-read-guard
pi install npm:pi-tokenburn
pi install npm:pi-context-diet

MIT