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-prefix-stabilizer

v0.4.0

Published

Keep Pi's system prompt byte-stable for prefix-cache reuse.

Readme

pi-prefix-stabilizer

Keep Pi's provider request prefix byte-stable across turns, reloads, and resumes so a server-side prefix cache can reuse it.

The extension normalizes install paths inside the system prompt, sorts tool-schema lists by name, then fingerprints the normalized leading system text. It warns when that text changes during a session because one early changed token invalidates every cached block after it. System messages later in the conversation, which Pi sends to models with supportsMidConvoSystemMessages, extend the cached prefix and do not warn.

Drift is measured against the request as sent. Extension-section removals the extension already strips elsewhere never reach a model and cannot invalidate any cached block, so toggling or re-adding them is silent once those removals are recorded -- which is what keeps a background-task-notification cycle from repeatedly re-prefilling; trailing flips after the seeded prefix don't break it either. Only a change that reaches the model and alters the seeded prefix -- a real package/MCP server, rules/AGENTS.md, skill, cwd, or content edit -- emits the one-time re-prefill warning.

On Pi 0.99, a prompt that an extension returns from before_agent_start replaces the prompt for typed-prompt runs only. Runs started by extension messages, such as background-task notifications, use Pi's own prompt, so the leading prompt switches and the cache is lost twice per such run. When the returned prompt holds exactly Pi's own sections in a different order (pi-permission-system moves the tool list to the end, for example), the stabilizer drops it. A returned prompt that adds, removes or reorders any line within a section is left in place.

Pi 1.0 records prompt changes as system-message patches by section name. A run started by an extension message (a background-task notification, for example) skips before_agent_start, so the patch pi writes at that run's next turn records every extension-contributed section as removed (the hook simply did not run), and the next typed prompt adds the same text back. For models without supportsMidConvoSystemMessages pi folds the patches into the leading system message, so each flip rewrites the prompt head; for models with it, each flip adds a "Removed section" and an "Updated section" message. Before each request the stabilizer leaves out of the request copy:

  • removals of extension sections in patches written during a run that no typed prompt started (removals of pi's own sections, such as skills, are kept), and
  • patch entries that set a section to the text it already has, and the patches this leaves empty.

The session transcript is not changed. The stabilizer records each patch it leaves out as a pi-prefix-stabilizer custom entry when it first leaves it out, so a resume, /reload or /tree sends the same request. A fork copies only the branch up to the selected message, so forking from a follow-up that was queued in the same turn as a dropped patch loses that record. A run counts as typed only when its first request ends in the prompt before_agent_start saw. A session from before 0.3.0 is sent as pi recorded it. The trade-off: an extension section genuinely removed during a run that no typed prompt started stays in the request until a later patch changes that section.

External contract

The provider must offer content-addressed prefix caching whose cache key depends on the rendered request prefix. This extension stabilizes bytes; it does not enable or configure the server cache.

For path normalization, packagePathSuffix must identify the volatile suffix in the rendered prompt. stablePath is the replacement shown to the model. If tools or the model need that path to resolve on disk, create it yourself or opt into createSymlink.

If the contract is unmet

Without provider-side prefix caching, requests remain correct but receive no cache benefit. If the configured package suffix is absent, no path is rewritten; tool sorting and drift detection still run. A genuine normalized-prompt change emits a warning for that change, while identical repeats do not re-warn.

A mention of the package suffix is only ever treated as a volatile install path -- and so only ever rewritten to stablePath -- if it is absolute and actually exists on disk. A relative mention or an absolute-looking one that does not exist is left alone: it was never an install path, so rewriting it would change the text's meaning rather than stabilise a fact.

Symlink creation is off by default. If explicitly enabled and the link cannot be created, the failure is written to the configured log when logging is enabled and the turn continues. It also never replaces an existing symlink with a bad one: if the candidate install root does not exist on disk, whatever is already at stablePath is left untouched.

In pi's print (-p) and json modes there is no UI to notify, so the drift warning that would otherwise be silent there is written to stderr instead, once per process.

Load order

Load pi-prefix-stabilizer before pi-compaction-cache.

The stabilizer must normalize the ordinary provider payload before the compaction extension captures it as the live cache prefix.

List it after any extension whose reordered prompt it should drop. Pi runs before_agent_start handlers in load order, so the stabilizer only sees prompts returned by extensions loaded before it.

pi install npm:pi-prefix-stabilizer
pi install npm:pi-compaction-cache

Settings

The three JSON settings resolve from pi-prefix-stabilizer.json in the global Pi config directory, then from a trusted project's Pi config directory, then from the environment. Later sources win. Project settings are ignored when the project is untrusted.

| JSON key | Default | Environment override | Meaning | |---|---|---|---| | stablePath | $HOME/.pi/pi-home | PI_PREFIX_STABILIZER_STABLE_PATH | Stable replacement for a volatile package install path. | | packagePathSuffix | node_modules/@earendil-works/pi-coding-agent | PI_PREFIX_STABILIZER_PACKAGE_PATH_SUFFIX | Suffix used to find the absolute package root in prompt text. | | createSymlink | false | PI_PREFIX_STABILIZER_CREATE_SYMLINK=1 | Create or update stablePath to point at the discovered package root. |

Two environment-only controls preserve the original operational interface:

| Environment variable | Default | Meaning | |---|---|---| | PI_PREFIX_STABILIZER | enabled | Set to 0 to disable the extension. | | PI_PREFIX_STABILIZER_LOG | unset | Append JSON records for rewrites, drift, and symlink operations. |

Default installation performs no filesystem writes.

Measurements

Measured with a large-context model behind a prefix-caching server:

| request | prompt tokens | TTFT | cache hit | |---|---:|---:|---:| | cold prompt | about 132,000 | 145.33s | 0.00% | | byte-identical repeat | about 132,000 | 0.54s | 99.95% | | first four characters changed | about 132,000 | 144.68s | 0.00% |

The stable repeat was about 270 times faster to first token. In the incident that motivated the package, an install-path change diverged near token 2,649 of a 118,031-token request; 97.8% of the prompt had to be prefilled again, producing an observed 127.5–137.5s delay. At the measured 871-token/s prefill rate, the expected delay was 132.5s.

Reproduce the measurements

  1. Capture one rendered provider payload and the server's prompt-token, cached-token, and TTFT metrics.
  2. Send it cold, then repeat it byte-for-byte.
  3. Change a few characters early in the system prompt and send it again.
  4. Compare cached-token counts and TTFT across the three requests.
  5. Enable this extension, repeat the experiment across a package reinstall or other install-path change, and confirm that the normalized payload remains identical.
  6. Reorder tool discovery without changing the tools and confirm that normalization prevents a drift warning; then make a real system-prompt change and confirm one warning is shown.

Cache capacity and eviction policy remain server concerns; test them separately under the deployment's real concurrency and request mix.