@joshbochu/pi-recall
Fast, native full-text search and resume for Pi sessions
Package details
Install @joshbochu/pi-recall from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@joshbochu/pi-recall- Package
@joshbochu/pi-recall- Version
0.3.1- Published
- Jul 27, 2026
- Downloads
- 84/mo · 84/wk
- Author
- joshbochu
- License
- MIT
- Types
- extension
- Size
- 178.3 KB
- Dependencies
- 0 dependencies · 4 peers
Pi manifest JSON
{
"extensions": [
"./src/index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-recall
Fast full-text search and native session resume for Pi.
pi-recall is a hybrid TypeScript/Rust Pi extension. Pi supplies session parsing, the overlay, and
native ctx.switchSession() handling; a small Rust N-API addon supplies the Tantivy index and ranking
engine.
Prerequisites and install
pi install npm:@joshbochu/pi-recall
Installation uses a prebuilt addon for macOS (arm64, x64), Linux (x64, arm64, glibc) and
Windows (x64). On any other platform the addon is compiled during installation, which
requires Rust and Cargo; the installer says so rather than failing inside cargo.
For local development or installation from a checkout:
git clone https://github.com/joshbochu/pi-recall.git
cd pi-recall
npm install
pi install /absolute/path/to/pi-recall
Or try the checkout without installing it:
pi -e /absolute/path/to/pi-recall
Use
Open the Pi-native picker:
/recall
/recall staging deploy
/recall #codebase
/recall authentication #codebase
While it is open:
- Type to search.
- Up/Down changes the selected session.
- Tab switches between the current folder and all projects.
- Enter resumes through Pi's native session switch.
- Escape closes the picker.
The header reports displayed results against the searchable corpus, such as 50 of 120 sessions.
Force a clean rebuild with /recall-reindex; ordinary use automatically reconciles new, modified,
and deleted sessions.
The model also receives one recall tool with search, list, and read actions, allowing it to
retrieve prior Pi work without shelling out to a separate application.
Session tags
Tags belong to the current session and survive index rebuilds:
/recall tag #codebase #rust #search
/recall tags
/recall untag #search
/recall autotag
/recall autotag --all-untagged
Because those words are command names, use /recall search tag, /recall search tags, or similar
when you want to search for the literal command word.
/recall autotag generates tags for the current session. --all-untagged finds every searchable
session with no manual or generated tags, then shows an overlay containing the exact session count
and model before making any calls. Escape cancels the progress overlay. Manual tags are never
replaced by generated tags, and an explicitly removed tag is suppressed from later generation.
Auto-tagging uses Pi's currently selected model by default. To choose a model and tag count, create
~/.pi/agent/pi-recall/config.json:
{
"autoTags": {
"model": "provider/model-id",
"minimum": 3,
"maximum": 7
}
}
The model must exist in Pi's model registry and have configured credentials. Auto-tagging sends a
bounded excerpt of each selected session to that provider, so API usage and provider privacy terms
apply. PI_RECALL_DATA_DIR relocates the durable tag/config directory;
PI_RECALL_CONFIG_FILE can point at a specific config file.
Search behavior
The native search engine behaves as follows:
- One Tantivy document is indexed per normalized user/assistant message, plus one metadata document for each tagged session.
- Consecutive messages with the same role are joined before indexing.
- Message content and tag text are searchable; session IDs, names, and paths remain stored metadata.
- Tantivy's default
QueryParserhandles ordinary terms with OR semantics. Tag-text matches receive a 4x field boost. #tagis an exact session filter. Multiple hashtags use AND, and remaining words still use the normal content/tag query (for example,authentication #codebase).- Multi-token queries also receive a 10x exact-phrase query joined with the base query using OR.
- Search retrieves
limit * 10documents, groups them by session ID, and keeps one representative match per session. Cwd and exact-tag constraints become a nativeTermSetQuery, excluding irrelevant sessions before Tantivy collects its top documents. - When message scores are close, later message positions are preferred by
messageIndex * 0.01. - Final session ordering multiplies relevance by
1 + exp(-age / 7 days), giving current sessions up to a 2x boost. - Snippets come from Tantivy's
SnippetGeneratorwith a 200-character target. - The picker requests Recall's 50-session limit.
This is lexical search, not semantic retrieval. There is deliberately no prefix search, edit-distance typo matching, stemming, synonym expansion, or embedding model layered on top of the results.
Storage and incremental refresh
The native index lives under ~/.pi/agent/cache/pi-recall-tantivy-v3/. File signatures and Pi session
summaries live in ~/.pi/agent/cache/pi-recall-v3.json. Set PI_RECALL_CACHE_DIR to place both in a
different directory.
Tags live separately at ~/.pi/agent/pi-recall/tags-v1.json. This file is user data, not a cache, and
is intentionally preserved by /recall-reindex.
The Pi adapter uses millisecond file timestamps, cache-version validation, atomic state writes, corrupt-index recovery, and deletion reconciliation.
Only user and assistant text is indexed alongside tag metadata. Thinking blocks, tool calls, and tool output are excluded to avoid duplicated command output.
Development
npm run check
npm run check:native
npm test
npm test rebuilds the native addon incrementally before running integration tests. Both Node and Bun
load the generated N-API module.
See docs/architecture.md for the component boundaries, native bridge, data flow, and operational tradeoffs.
Publishing
Every push to main publishes a new package version via GitHub Actions (publish.yml).
The workflow chooses the next patch version from the greater of package.json and the
latest version on npm, runs the checks, builds and publishes one prebuilt addon package
per platform (@joshbochu/pi-recall-native-<target>), publishes the root package with
optionalDependencies pinned to those addons, then records release: vX.Y.Z and tag
vX.Y.Z on main. Release commits are skipped so the version bump does not republish.
You can also run the workflow manually with Actions → Publish to npm → Run workflow.
Before the first automated release, configure a GitHub Actions trusted publisher on npm for
@joshbochu/pi-recall and for each platform package
(@joshbochu/pi-recall-native-darwin-arm64, -darwin-x64, -linux-x64-gnu,
-linux-arm64-gnu, -win32-x64-msvc):
- Organization or user:
joshbochu - Repository:
pi-recall - Workflow filename:
publish.yml - Allowed action:
npm publish
The publish job uses OIDC trusted publishing by default (scripts/publish-npm.mjs). Do not set
an empty NODE_AUTH_TOKEN; that disables OIDC. Optionally set repository secret NPM_TOKEN when
you need to create brand-new platform package names (trusted publishing cannot create a package
that does not exist yet). After those packages exist and have trusted publishers, you can remove
the token. Until a platform package is on npm, the root publish still proceeds and postinstall
falls back to a local Cargo build for that platform.
npm run pack:platform -- <target> [cargo-target] builds one platform package locally into
npm/<target>/. node scripts/next-version.mjs prints the next publish version, and
npm run check:release verifies that any v* tag matches the package version and that
publish.yml builds exactly the platforms listed in scripts/native-targets.mjs.
optionalDependencies is not committed: a lock file cannot reference a version that has not
been published, so committing it would break npm ci. The workflow publishes the platform
packages first, then runs npm run stamp:prebuilt (with --published-only in CI), so the
published tarball only points at addons that exist.
Manual major/minor bumps still work: raise the version in package.json (and the lockfile)
above the latest npm release, merge to main, and the workflow publishes that version
instead of the next patch.
License
MIT. See THIRD_PARTY_NOTICES.md for required third-party notices.