原始内容
@kaiserlich-dev/pi-session-search
Full-text search across all pi sessions with a SQLite FTS5 index and overlay UI.
Install
npm (recommended)
pi install npm:@kaiserlich-dev/pi-session-search
git (alternative)
pi install git:github.com/kaiserlich-dev/pi-session-search
By default this writes to
~/.pi/agent/settings.json. Use-lto install into.pi/settings.jsonfor a project.
Then restart pi or run /reload.
To configure OpenRouter for session summaries, run:
/session-search-register-key
Features
- FTS5 index — indexes user messages, assistant responses, tool results, and session metadata. A session-level index finds matching sessions; a chunk-level index powers snippets/previews.
- Browse recent sessions — opening search shows your most recent sessions immediately, no typing required.
- Incremental indexing — only processes new/changed sessions. Runs async in background on startup with cooperative yielding.
- Overlay search palette — theme-aware UI matching pi-skill-picker / pi-queue-picker style.
- Preview — see matched snippets with highlighted search terms before deciding.
- Resume — switch to a found session directly from the preview.
- Summarize & inject — ask the LLM to read the full session and inject a summary into your current context.
- Custom focus prompt — optionally provide a focus (e.g. "focus on the auth decisions") before summarizing, so the summary targets what you care about.
- New session with context — start a fresh session with summarized context from a previous one, seeded directly into the new session.
- Smart project names — resolves
~/code/owner/repopaths into readableowner/repoproject labels.
Usage
| Shortcut / Command | Action |
|---|---|
Ctrl+Shift+F |
Open search overlay |
/search |
Open search overlay |
/session-search-register-key |
Prompt locally for the OpenRouter API key used for summaries |
/search resume "<sessionPath>" |
Resume a specific session by file path |
/search new-context "<sessionPath>" ["focus prompt"] |
Start a fresh session seeded with summary context from a prior session |
/search reindex |
Clear and rebuild index from scratch |
/search stats |
Show index statistics |
Search screen
| Key | Action |
|---|---|
| Type | Search query (debounced) |
← / → |
Move cursor within query |
Home / Ctrl+A |
Jump to start of query |
End / Ctrl+E |
Jump to end of query |
Delete |
Delete character after cursor |
Ctrl+W / Alt+Backspace |
Delete word before cursor |
| Paste | Insert clipboard text at cursor |
↑ / ↓ |
Navigate results |
Ctrl+R |
Toggle newest matches / best matches |
Enter |
Open preview for selected result |
Esc |
Close |
When opened with an empty query, recent sessions are shown (most recent first). The current session is hidden from the palette so recovery searches do not immediately match the conversation where you are asking about the lost session.
With a search query, results default to newest matching sessions first — optimized for recovering a lost session from one or two remembered keywords. Multi-word queries prefer exact phrase matches first (ghost drift before unrelated ghost + drift). Press Ctrl+R to toggle to best matches first (BM25 relevance).
Preview screen
| Key | Action |
|---|---|
Tab / ← → |
Cycle actions: Resume · Summarize · New + Context · Back |
Enter |
Execute selected action |
Esc |
Back to search |
Summary Focus screen
When choosing Summarize or New + Context, a prompt screen appears:
| Key | Action |
|---|---|
Enter |
Use default summary (no custom focus) |
Type + Enter |
Summarize with custom focus prompt |
Esc |
Back to preview |
The custom focus is passed to the LLM alongside the session content, steering the summary toward what matters to you.
When calling /search subcommands manually, use double-quoted arguments:
/search resume "<sessionPath>"/search new-context "<sessionPath>" ["focus prompt"]
Summary model setup
/session-search-register-key stores your OpenRouter key in:
~/.session-search/secrets.json
with this shape:
{
"apiKey": "YOUR_OPENROUTER_API_KEY"
}
The command prompts locally, so you do not need to paste the key into a normal LLM prompt.
How it works
- On
session_start, the indexer scans~/.pi/agent/sessions/for JSONL files. - Files with a newer
mtimethan last indexed are parsed — user messages, assistant text (no thinking blocks), and tool results are extracted. - Text is stored in two SQLite FTS5 indexes with Porter stemming: one row per session for retrieval/sorting, plus ~4KB chunks for previews.
- Searches use the session-level FTS table, sorted by either session date (
newest) or BM25 rank (best). Preview snippets come from the chunk index. - The index lives at
~/.pi-session-search/index.db. - Summaries are generated via OpenRouter (Gemini Flash) and injected as assistant messages.
Environment
PI_SESSION_SEARCH_DIRS/PI_SESSION_SEARCH_DIR— override session roots; use:-separated paths for multiple roots.PI_SESSION_SEARCH_INDEX_DIR— override the SQLite index directory.
Development
# Run checks, unit tests, and the synthetic search perf test
npm test
# Run only the search latency benchmark-style test
npm run test:perf
# Run locally without installing
pi -e ./extensions/index.ts
For isolated tests and benchmarks, the indexer honors:
PI_SESSION_SEARCH_INDEX_DIR— override the SQLite index directoryPI_SESSION_SEARCH_SESSIONS_DIR— override the pi sessions directory