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

@jtregunna/pi-lot

v0.3.2

Published

Retrieval-augmented context management for Pi coding agent — uses tree-sitter-language-pack for 305+ language support with AST-based symbol retrieval and multi-signal relevance scoring.

Downloads

559

Readme

Pi-lot — Retrieval-Augmented Context for Pi

A Pi extension that replaces linear context accumulation with retrieval-augmented context management.

Instead of sending every message to the LLM in order, Pilot:

  1. Builds a symbol index of the codebase on startup (functions, classes, interfaces, methods, types, variables)
  2. Tracks file edits via tool call events and updates the index incrementally
  3. Detects external changes via a merkle hash watcher (git checkout, IDE edits, new files)
  4. Reconstructs context on each LLM call from:
    • A short conversational window (last 12 turns) for intent and state
    • Precisely retrieved code snippets scored by relevance
  5. Provides a custom tool (pilot_query) for the LLM to search the index directly
  6. Records episodic project memory after successful edits/writes and retrieves relevant prior work on future turns

Installation

# Via Pi package manager
pi /packages add npm:@jtregunna/pi-lot

# Or add to settings.json
# .pi/settings.json → packages: ["npm:@jtregunna/pi-lot"]

# Or install directly in your project
npm install @jtregunna/pi-lot

Architecture

┌───────────────────────────────────────────────────┐
│  Pi Coding Agent                                  │
│                                                   │
│  ┌─────────────┐   ┌──────────────────────────┐   │
│  │ User Prompt │──▶│  context event handler   │   │
│  └─────────────┘   │                          │   │
│                    │  1. Merkle sync          │   │
│                    │     (detect ext changes) │   │
│                    │                          │   │
│                    │  2. Keep last 12 turns   │   │
│                    │     (conversational)     │   │
│                    │                          │   │
│                    │  3. Score all symbols    │   │
│                    │     by 7 relevance       │   │
│                    │     signals              │   │
│                    │                          │   │
│                    │  4. Inject top matches   │   │
│                    └──────────────────────────┘   │
│                               │                   │
│                               ▼                   │
│  ┌─────────────────────────────────────────────┐  │
│  │  Reconstructed Context:                     │  │
│  │  [Retrieval Message]                        │  │
│  │  ├─ Function A (score 3.8)                  │  │
│  │  ├─ Class B (score 2.1)                     │  │
│  │  ├─ ... (N snippets, token budget)          │  │
│  │  [Conversational Window]                    │  │
│  └─────────────────────────────────────────────┘  │
└───────────────────────────────────────────────────┘

Modules

| File | Description | |---|---| | code-index.ts | Multi-language symbol extraction using @kreuzberg/tree-sitter-language-pack. Supports 305+ languages (TypeScript, Python, Rust, Zig, Go, etc.). Uses tree-sitter AST queries for languages with extraction support, falls back to regex-based extraction for languages like Zig where queries are unavailable. Supports incremental file-level updates. | | scorer.ts | Multi-signal relevance scoring with reference chain expansion. Scores symbols against user prompts using 7 weighted signals. | | watcher.ts | Merkle hash-based file watcher that detects added, modified, and deleted files from external sources (git, IDE, manual edits). Uses detectLanguageFromPath() to filter only code files (excludes vimdoc, markdown, etc.). | | memory-store.ts | Local episodic memory store backed by .pilot/memories.jsonl, with keyword/tag/file/symbol retrieval and basic secret redaction. | | index.ts | Main extension entry point with event hooks, custom tool, footer widget, and slash commands. |

Relevance Signals

Each symbol is scored against the user's prompt using 7 weighted signals:

| Signal | Weight | Description | |---|---|---| | Exact name | 3.0 | Keyword exactly matches symbol name | | Fuzzy name | 1.0 | Keyword contained in or overlaps with symbol name | | Kind relevance | 0.5 | Symbol kind matches prompt intent (functions for actions, types for reading) | | Exported | 0.3 | Bonus for exported symbols | | File proximity | 0.8 | Symbol is in a recently edited file or same directory | | Doc comment | 0.5 | JSDoc contains prompt keywords | | Reference distance | 0.4 | Symbol is referenced by a high-scoring symbol (chain expansion up to depth 2) |

Configuration

Default settings:

| Setting | Default | Description | |---|---|---| | conversationalWindow | 12 | Number of recent turns kept as-is | | maxRetrievedTokens | 30,000 | Max tokens for retrieved code snippets | | maxTotalTokens | 60,000 | Max total tokens in reconstructed context | | memoryEnabled | true | Enable/disable episodic memory storage and retrieval | | expandReferences | 2 | Reference chain expansion depth |

Episodic Project Memory

Pilot stores lightweight memories of successful project edits in .pilot/memories.jsonl (JSON Lines). The directory is created automatically after a successful edit or write tool result.

On each context reconstruction, Pilot retrieves matching memories and injects them before code context as:

[Relevant Project Memory — N matches]

Memory ranking is local and deterministic. It scores overlap between the current prompt and stored episode fields, with signals from keywords, tags, files, symbols, confidence, recency, and recently edited files.

Privacy: memories stay on your machine in the project-local .pilot/ directory, which should be ignored by git (this repository's .gitignore includes it). Pilot applies basic redaction for common secrets and tokens before storage, but this is not exhaustive; avoid prompting or editing with sensitive values when possible.

Custom Tool: pilot_query

The LLM can query the code index directly:

pilot_query(query="getSymbols", limit=5, kind="function")

Returns ranked matches with file locations, preview text, and scoring info.

Commands

| Command | Description | |---|---| | /reindex | Rebuild the full code index | | /index-stats | Show index statistics (files, symbols, kinds) | | /watcher-sync | Manually sync the merkle watcher and update index | | /watcher-status | Show watcher snapshot info (files, tree hash) | | /index-status | Toggle context reconstruction on/off | | /memory-stats | Show memory enabled state, episode count, and storage path | | /memory-status | Toggle memory retrieval/storage on/off | | /memory-clear | Delete .pilot/memories.jsonl and clear loaded memories |

Footer Widget

The footer shows:

  • Left: Token usage (↑input ↓output)
  • Right: Index status (pilot:Ns), git branch, model name

Development

cd ~/Projects/pilot
npm install
just build      # Compile TypeScript to extensions/
just dev        # Run Pi with Pilot (loads TS via jiti)
just pi         # Run Pi with Pilot (loads compiled JS)
just watch      # Watch for changes
just pack       # Build + create npm tarball

Event Hooks

| Hook | Action | |---|---| | session_start | Builds full code index + initial merkle snapshot; sets up footer | | tool_call | Tracks file edits before they happen (MRU list) | | tool_result | Updates index incrementally and records memory after successful edits/writes | | context | Merkle sync (detects external changes), then reconstructs context | | before_agent_start | Augments system prompt with retrieval instructions | | session_compact | Updates footer status after compaction | | session_shutdown | Disposes the code index |

Merkle Watcher

The merkle watcher maintains a SHA-256 hash snapshot of all source files:

  • On session start: Builds initial snapshot after index build
  • On every context event: Compares current filesystem against snapshot, detecting:
    • added — new files not in previous snapshot
    • modified — files with changed content hash
    • deleted — files no longer on disk
  • Fast path: Checks mtime first; only computes hash for files with changed modification time
  • Covers: Git checkouts, IDE batch edits, manual file creation, bulk renames — anything fs.watch misses

Building for npm

The project compiles to extensions/ which is Pi's auto-discovery directory for npm packages:

npm run build    # tsc → extensions/
npm pack         # Create tarball
npm publish      # Publish to npm

Pi discovers extensions from the published package by finding extensions/index.js.

Troubleshooting

0 files, 0 symbols: The extension indexes from process.cwd(). Make sure you run Pi from within your project directory. The index excludes node_modules, dist, build, etc.

Extension not loading after npm install: Verify the package is in your packages array in settings.json: ["npm:@jtregunna/pi-lot"]

Slow indexing: The merkle watcher scans all source files on every turn. For large codebases (1000+ files), this adds ~100ms per turn. The mtime fast-path minimizes hash computation.