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

pi-readcache

v0.2.0

Published

🧠 Pi extension that optimizes read tool calls with replay-aware caching and compaction-safe trust reconstruction

Downloads

399

Readme

🧠 pi-readcache

pi coding agent npm version license

A pi extension that overrides the built-in read tool with hash-based, replay-aware caching.

It reduces token usage and context bloat from repeated file reads while preserving correctness as session state evolves.

Correctness is maintained across:

  • range reads (path:START-END)
  • tree navigation (/tree)
  • compaction boundaries
  • restart/resume replay

What you get

pi-readcache runs automatically in the background by overriding read and managing replay trust for you. Refresh/invalidation can also be triggered by the model itself via the readcache_refresh tool when it decides a fresh baseline is needed. You can still run /readcache-refresh manually for explicit control.

When the extension is active, read may return:

  • full content (mode: full)
  • unchanged marker (mode: unchanged)
  • unchanged range marker (mode: unchanged_range)
  • unified diff for full-file reads (mode: diff)
  • baseline fallback (mode: baseline_fallback)

Plus:

  • /readcache-status to inspect replay/coverage/savings
  • /readcache-refresh <path> [start-end] to invalidate trust for next read
  • readcache_refresh tool (same semantics as command)

Install

Preferred (npm):

pi install npm:pi-readcache

Alternative (git):

pi install git:https://github.com/Gurpartap/pi-readcache

After installation, you can use pi normally. If pi is already running when you install or update, run /reload in that session.

Day-to-day usage

| Action | Command | Expected result | |---|---|---| | Baseline read | read src/foo.ts | mode: full or mode: baseline_fallback | | Repeat read (no file change) | read src/foo.ts | [readcache: unchanged, ...] | | Range read | read src/foo.ts:1-120 | mode: full, baseline_fallback, or unchanged_range | | Inspect replay/cache state | /readcache-status | tracked scopes, replay window, mode counts, estimated savings | | Invalidate full scope | /readcache-refresh src/foo.ts | next full read re-anchors | | Invalidate range scope | /readcache-refresh src/foo.ts 1-120 | next range read re-anchors |

Important behavior notes

  • Sensitive-path bypass: readcache does not cache/diff these patterns and falls back to baseline read output: .env*, *.pem, *.key, *.p12, *.pfx, *.crt, *.cer, *.der, *.pk8, id_rsa, id_ed25519, .npmrc, .netrc.
  • Compaction is a strict replay barrier for trust reconstruction:
    • replay starts at the latest active compaction + 1.
    • pre-compaction trust is not used after that barrier.
  • First read after that barrier for a path/scope will re-anchor with baseline (full/baseline_fallback).
  • For exact current file text, the assistant should still perform an actual read in current context.

Diff usefulness gate (why you sometimes get full content instead of a diff)

For full-file reads, mode: diff is emitted only when the generated patch is clearly more useful than baseline text.

Current defaults:

  • MAX_DIFF_TO_BASE_RATIO = 0.9
    • if diffBytes >= selectedBytes * 0.9, diff is considered not useful and falls back to baseline (mode: baseline_fallback)
  • MAX_DIFF_TO_BASE_LINE_RATIO = 0.85
    • if patch line count is greater than selectedRequestedLines * 0.85, diff is considered too large/noisy and falls back to baseline

Why these defaults:

  • avoids near-full-file patch spam on high-churn edits
  • improves readability for the model versus very large hunks
  • keeps token savings meaningful when diff mode is used

For extension developers (and curious cats)

Design docs

High-level architecture

flowchart TD
  A[LLM calls read] --> B[read override tool]
  B --> C[Run baseline built-in read]
  B --> D[Load current file bytes/text + sha256]
  B --> E[Rebuild replay knowledge for active leaf]
  E --> F{base trust exists?}
  F -- no --> G[mode=full, attach metadata]
  F -- yes + same hash --> H[mode=unchanged/unchanged_range]
  F -- yes + full scope + useful diff --> I[mode=diff]
  F -- otherwise --> J[mode=baseline_fallback]
  G --> K[persist object + overlay trust]
  H --> K
  I --> K
  J --> K
  K --> L[tool result + readcache metadata]

Runtime model

  • Trust key: (pathKey, scopeKey) where scope is:
    • full
    • r:<start>:<end>
  • Trust value: { hash, seq }
  • Replay source:
    • prior read tool result metadata (details.readcache)
    • custom invalidation entries (customType: "pi-readcache")
  • Overlay:
    • in-memory, per (sessionId, leafId), high seq namespace for same-turn freshness

Compaction/tree semantics

flowchart LR
  R[root] --> C1[compaction #1]
  C1 --> N1[reads...]
  N1 --> C2[compaction #2]
  C2 --> L[active leaf]

  B[replay start] --> S[latest compaction + 1 on active path]

Rules:

  • replay boundary = latest compaction on active branch path + 1
  • if no compaction on path, replay starts at root
  • tree/fork/switch/compact/shutdown clear in-memory memo/overlay caches

File map

  • index.ts - extension entrypoint + lifecycle reset hooks
  • src/tool.ts - read override decision engine
  • src/replay.ts - replay reconstruction, trust transitions, overlay
  • src/meta.ts - metadata/invalidation validators and extractors
  • src/commands.ts - /readcache-status, /readcache-refresh, readcache_refresh
  • src/object-store.ts - content-addressed storage (.pi/readcache/objects)
  • src/diff.ts - unified diff creation + usefulness gating
  • src/path.ts - path/range parsing and normalization
  • src/telemetry.ts - replay window/mode/savings reporting

Tool-override compatibility contract

Because this overrides built-in read, it must preserve:

  • same tool name + parameters (path, offset?, limit?)
  • baseline-compatible content shapes (including image passthrough)
  • truncation behavior and details.truncation compatibility

Development

npm install
npm run typecheck
npm test

Targeted suites:

npm test -- test/unit/replay.test.ts
npm test -- test/integration/compaction-boundary.test.ts
npm test -- test/integration/tree-navigation.test.ts
npm test -- test/integration/selective-range.test.ts
npm test -- test/integration/refresh-invalidation.test.ts
npm test -- test/integration/restart-resume.test.ts

License

MIT © 2026 Gurpartap Singh (https://x.com/Gurpartap)