Semantic search across Claude Code sessions. Find past conversations by intent, not just keywords.
Project description
claude-code-recall
Find any Claude Code session instantly. Semantic search with cross-encoder reranking and a knowledge graph across all your past conversations.
pip install 'claude-code-recall[all]'
claude-code-recall "debugging the auth middleware"
The Problem
You accumulate hundreds of Claude Code sessions across dozens of projects. Built-in /resume only shows 10 recent sessions with basic name matching. You can't find the session where you debugged that auth issue, optimized the database, or set up CI/CD.
claude-code-recall indexes all your sessions and searches them with a 6-stage pipeline — keyword matching, semantic embeddings, cross-encoder reranking, and optional LLM-powered understanding. A knowledge graph connects sessions through shared files, branches, and commands so you can trace how work flows across sessions.
How It Works
graph LR
Q["Your Query"] --> FTS["FTS5 Keyword\n(BM25, weighted)"]
Q --> SEM["Semantic Search\n(bge-small, 384d)"]
Q --> KG["Knowledge Graph\n(3,124 edges)"]
FTS --> RRF["Reciprocal Rank\nFusion"]
SEM --> RRF
KG --> RRF
RRF --> CE["Cross-Encoder\nReranking (18ms)"]
CE --> LLM["LLM Reranking\n(claude -p haiku)"]
LLM --> R["Ranked\nResults"]
style Q fill:#7c3aed,color:#fff,stroke:none
style R fill:#059669,color:#fff,stroke:none
style FTS fill:#1e40af,color:#fff,stroke:none
style SEM fill:#1e40af,color:#fff,stroke:none
style KG fill:#1e40af,color:#fff,stroke:none
style RRF fill:#b45309,color:#fff,stroke:none
style CE fill:#b45309,color:#fff,stroke:none
style LLM fill:#b45309,color:#fff,stroke:none
| Stage | What it does | Speed |
|---|---|---|
| FTS5 | BM25 keyword search across summary, prompts, messages, project path. Weighted columns (summary 5x, project 4x). Stop word filtering, prefix matching. | < 5ms |
| Semantic | Bi-encoder embeddings (bge-small-en-v1.5, ONNX, local). Searches 6,876 conversation chunks via sqlite-vec cosine similarity. Maps subagent matches to parent sessions. | < 20ms |
| Knowledge Graph | 3,124 edges connecting sessions through 603 shared files, commands, and branches. Surfaces related sessions even when text doesn't match. | < 5ms |
| RRF Fusion | Merges keyword + semantic + graph signals via Reciprocal Rank Fusion. Adapts weighting based on how many FTS results were found. | < 1ms |
| Cross-Encoder | ms-marco-MiniLM-L-6-v2 reranks top candidates with full query-document cross-attention. Much more accurate than bi-encoder similarity. | ~18ms |
| LLM Rerank | Enabled via search_mode = llm. Pipes candidates through Claude Haiku for intent understanding. |
~8s |
| Cutoff | Drops results below 40% of top score, but keeps same-project results. Mild depth boost for longer sessions. | < 1ms |
The Key Insight: Subagent Content Bubbling
Claude Code spawns subagents for complex tasks. A session about building an iOS app might have 15 subagents doing the actual work. The parent session's first message might just be "let's build this."
The real keywords live in subagent sessions. We solve this:
- At index time — Parent sessions are enriched with subagent first prompts
- At search time — Semantic matches on subagent chunks map back to the parent session
- Orphan subagents — Projects with no parent JSONL on disk (subagent-only) are auto-promoted so they remain searchable
This is why searching "an app that captures screenshots" finds a session whose first prompt is "let's build automations" — the subagents contain the screenshot-related content.
Knowledge Graph
Sessions don't exist in isolation. The knowledge graph tracks relationships between sessions based on shared files, commands, and branches — building a web of connections across your entire coding history.
graph TD
subgraph "Knowledge Graph (3,124 edges)"
S1["Session A\n'fix auth bug'"] -->|"shared: auth.py"| S2["Session B\n'add OAuth flow'"]
S2 -->|"shared: auth.py\nshared: users.py"| S3["Session C\n'user permissions'"]
S1 -->|"same branch:\nfeature/auth"| S3
S4["Session D\n'CI pipeline'"] -->|"shared: Dockerfile"| S5["Session E\n'deploy script'"]
end
subgraph "Stats"
E["3,124 edges"]
F["603 unique files"]
SC["106 session chains"]
end
style S1 fill:#7c3aed,color:#fff,stroke:none
style S2 fill:#7c3aed,color:#fff,stroke:none
style S3 fill:#7c3aed,color:#fff,stroke:none
style S4 fill:#1e40af,color:#fff,stroke:none
style S5 fill:#1e40af,color:#fff,stroke:none
style E fill:#b45309,color:#fff,stroke:none
style F fill:#b45309,color:#fff,stroke:none
style SC fill:#b45309,color:#fff,stroke:none
The knowledge graph powers two features:
- Related sessions in the preview panel — When you select a session, the preview panel shows other sessions that touched the same files. No text matching needed; if two sessions both edited
auth.py, they're related. - Session chains — Groups of sessions linked by project + branch + time proximity. 106 chains capture multi-session workflows like "started a feature, continued the next day, fixed a bug the day after." Chains give you the full story of a piece of work, not just individual sessions.
Install
pip (recommended)
# Everything
pip install 'claude-code-recall[all]'
# Or pick what you need
pip install claude-code-recall # keyword search only (zero deps)
pip install 'claude-code-recall[semantic]' # + embeddings + reranking
pip install 'claude-code-recall[tui]' # + interactive terminal UI
uv
uv tool install claude-code-recall --with textual --with fastembed --with sqlite-vec
From source
git clone https://github.com/lupuletic/claude-code-recall
cd claude-code-recall
uv venv && source .venv/bin/activate
uv pip install -e ".[all]"
Usage
# Interactive TUI — starts with recent sessions; type to search
claude-code-recall
# Direct search
claude-code-recall "debugging auth middleware"
claude-code-recall "database migration script"
claude-code-recall "setting up 2 git accounts"
# Structured search prefixes
claude-code-recall "file:auth.py" # find sessions that touched a specific file
claude-code-recall "cmd:docker build" # find sessions that ran a specific command
claude-code-recall "branch:feature/oauth" # find sessions on a specific branch
# Combine prefixes with regular queries
claude-code-recall "file:schema.prisma migration"
claude-code-recall "branch:main deploy"
# Filters
claude-code-recall "optimization" --project myapp
claude-code-recall "migration" --after 2026-01-01
# Output formats
claude-code-recall "query" --no-tui # plain text
claude-code-recall "query" --json # JSON for scripting
# Updates
claude-code-recall update # show latest version and upgrade command
claude-code-recall update --yes # run the detected upgrade command
Structured Search Prefixes
| Prefix | What it searches | Example |
|---|---|---|
file: |
Sessions that read/wrote a specific file | file:docker-compose.yml |
cmd: |
Sessions that ran a specific command | cmd:pytest |
branch: |
Sessions on a specific git branch | branch:feature/auth |
Prefixes query the knowledge graph directly — no fuzzy matching, just exact lookups against the 603 tracked files, commands, and branches. Combine them with free-text queries for precise filtering.
TUI Controls
| Key | Action |
|---|---|
| Type | Search as you type (debounced) |
↓ / ↑ |
Navigate between search bar and results |
Enter |
Focus results / Resume selected session |
Ctrl+P |
Toggle preview panel |
Ctrl+O |
Open settings |
Ctrl+W |
Delete last word |
Cmd+⌫ |
Clear entire search |
Esc |
Quit |
With an empty search box, the TUI shows your most recent sessions across all indexed projects. The preview panel shows session details including related sessions — other sessions that share files with the selected one, powered by the knowledge graph. This lets you trace work across sessions without searching.
When you resume a session, claude-code-recall cds to the original project directory and runs claude --resume — you land right back where you left off.
Settings
claude-code-recall config # view settings
claude-code-recall config search_mode hybrid # keyword + semantic + reranking (default)
claude-code-recall config search_mode llm # + Claude LLM reranking (best, ~10s)
claude-code-recall config search_mode keyword # FTS only (fastest, no deps)
claude-code-recall config limit 20 # more results
Or press Ctrl+O in the TUI for a visual settings panel with search mode, limits, and toggles.
Search Quality
Benchmarked against 50 realistic "vague memory" queries — the kind of thing developers type when they can't remember which session they need:
| Category | Score | Description |
|---|---|---|
| Exact project names | 7/7 | "reshot", "skywatcher", "clawdbot", "grey residence" |
| Describing work done | 8/9 | "fixing bugs on marketing site", "email setup with microsoft 365" |
| Semantic / conceptual | 6/6 | "iOS app that captures screenshots", "session about telescope electronics" |
| Technology queries | 6/6 | "docker container issues", "telegram webhook setup" |
| Last message context | 2/2 | "use godaddy now", "push the latest to remote" |
| Overall | 29/30 (93%) | 60ms/query average |
Remaining failures are from sessions whose parent JSONL was never saved to disk (subagent-only projects) — a Claude Code limitation, not a search limitation.
Index Stats
| Metric | Count |
|---|---|
| Sessions indexed | 2,003 |
| Conversation chunks | 6,876 |
| Projects | 79 |
| Knowledge graph edges | 3,124 |
| Unique files tracked | 603 |
| Session chains | 106 |
Architecture
graph TD
subgraph "Data Source"
JSONL["~/.claude/projects/*/*.jsonl"]
end
subgraph "Indexer"
PARSE["Parse JSONL sessions"]
CHUNK["Chunk into 5-turn windows\n(user + assistant)"]
ENRICH["Enrich parents with\nsubagent content"]
FTS_IDX["FTS5 Index\n(5 weighted columns)"]
VEC_IDX["Embedding Index\n(384d cosine, sqlite-vec)"]
KG_IDX["Knowledge Graph\n(files, commands, branches)"]
end
subgraph "Search"
QUERY["User Query"]
PREFIX["Structured Prefix\nParsing (file:, cmd:, branch:)"]
PIPELINE["7-Stage Pipeline"]
RESULTS["Ranked Results"]
end
JSONL --> PARSE --> CHUNK --> VEC_IDX
PARSE --> ENRICH --> FTS_IDX
PARSE --> KG_IDX
QUERY --> PREFIX --> PIPELINE --> RESULTS
style JSONL fill:#374151,color:#fff,stroke:none
style QUERY fill:#7c3aed,color:#fff,stroke:none
style RESULTS fill:#059669,color:#fff,stroke:none
style KG_IDX fill:#b45309,color:#fff,stroke:none
style PREFIX fill:#7c3aed,color:#fff,stroke:none
Conversation Chunking
Sessions are split into sliding windows of 5 user+assistant turn pairs with 1-turn overlap. Both sides are included — assistant responses anchor what was actually discussed. Each chunk is embedded separately (6,591 vectors), and search returns the parent session (parent-child retrieval).
Why Hybrid Search?
Embeddings alone miss exact matches. Searching a project name should match instantly — that's a keyword hit. Our hybrid approach:
- Keywords for exact terms, project names, error messages
- Embeddings for conceptual queries ("app that analyses screenshots")
- Knowledge graph for structural queries ("sessions that touched this file")
- Cross-encoder for precise relevance scoring
- LLM for understanding intent behind vague queries
Comparison
| Feature | claude-code-recall | recall | search-sessions | claude-history |
|---|---|---|---|---|
| Keyword search | FTS5 + weighted BM25 | FTS5 + BM25 | ripgrep | Fuzzy |
| Semantic search | Local embeddings | - | - | - |
| Cross-encoder rerank | 18ms | - | - | - |
| LLM reranking | claude -p | - | - | - |
| Knowledge graph | 3,124 edges | - | - | - |
| Structured prefixes | file:, cmd:, branch: | - | - | - |
| Session chains | 106 chains | - | - | - |
| Related sessions | Via shared files | - | - | - |
| Subagent bubbling | Yes | - | - | - |
| Conversation chunking | 5-turn windows | Full text | - | - |
| Interactive TUI | Textual | - | - | ratatui |
| Settings UI | Ctrl+O | - | - | - |
| Auto-index hooks | SessionEnd | - | - | - |
| cd to project dir | Yes | - | - | - |
| Search accuracy | 93% | - | - | - |
| API keys needed | No | No | No | No |
First Run
On first run, claude-code-recall:
- Builds a keyword index of all sessions (~8 seconds)
- Shows results immediately (keyword search works right away)
- Generates embeddings in the background (~2-3 minutes)
- Builds the knowledge graph (files, commands, branches, session chains)
- Auto-installs a SessionEnd hook so future sessions are indexed automatically
Development
git clone https://github.com/lupuletic/claude-code-recall
cd claude-code-recall
uv venv && source .venv/bin/activate
uv pip install -e ".[all,dev]"
python -m pytest tests/ -q # unit/integration tests
# Optional: benchmark against your own populated Claude Code index
CLAUDE_RECALL_RUN_QUALITY_TESTS=1 python -m pytest tests/test_search_quality.py -v
Release
Releases are tag driven. CI verifies the version declarations match before publishing. The release workflow builds distributions, publishes to PyPI through Trusted Publishing, and creates or updates the matching GitHub release.
Before the first release, configure a PyPI Trusted Publisher for this repository and the
pypi GitHub environment. The PyPI distribution name is claude-code-recall; the
installed command remains claude-code-recall.
Trusted Publisher fields:
| Field | Value |
|---|---|
| PyPI project name | claude-code-recall |
| Owner | lupuletic |
| Repository name | claude-code-recall |
| Workflow name | release.yml |
| Environment name | pypi |
uv run python scripts/check_version.py
uv run pytest -q
uv run python -m compileall -q src tests
uv build --no-sources
git tag v0.1.4
git push origin main --tags
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file claude_code_recall-0.1.4.tar.gz.
File metadata
- Download URL: claude_code_recall-0.1.4.tar.gz
- Upload date:
- Size: 167.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dae8da66798c8b5f68b410f8294dce366c714ae7bebb31a7e126233c6dfbd864
|
|
| MD5 |
4b8fb335d95e5240eec4af4dec68efd1
|
|
| BLAKE2b-256 |
e3c6f71c3860e8afa31d28c0150f0e699a28f35cada4bf41733fc2d019cc49e4
|
Provenance
The following attestation bundles were made for claude_code_recall-0.1.4.tar.gz:
Publisher:
release.yml on lupuletic/claude-code-recall
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
claude_code_recall-0.1.4.tar.gz -
Subject digest:
dae8da66798c8b5f68b410f8294dce366c714ae7bebb31a7e126233c6dfbd864 - Sigstore transparency entry: 1524600542
- Sigstore integration time:
-
Permalink:
lupuletic/claude-code-recall@38f12a307823bc4dfffce4d70454160488bb0bae -
Branch / Tag:
refs/tags/v0.1.4 - Owner: https://github.com/lupuletic
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@38f12a307823bc4dfffce4d70454160488bb0bae -
Trigger Event:
push
-
Statement type:
File details
Details for the file claude_code_recall-0.1.4-py3-none-any.whl.
File metadata
- Download URL: claude_code_recall-0.1.4-py3-none-any.whl
- Upload date:
- Size: 56.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
14854111ea769120ce437a90f0eafd6b8269b88fbc9b3cb7c241334c1b6f0958
|
|
| MD5 |
19681671c101400bbf52c769c3e4e8cf
|
|
| BLAKE2b-256 |
ec8293410c0e4a5cb051a7ce8f90b4e9e3406c48560ed4a1a80a29a98a6134a3
|
Provenance
The following attestation bundles were made for claude_code_recall-0.1.4-py3-none-any.whl:
Publisher:
release.yml on lupuletic/claude-code-recall
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
claude_code_recall-0.1.4-py3-none-any.whl -
Subject digest:
14854111ea769120ce437a90f0eafd6b8269b88fbc9b3cb7c241334c1b6f0958 - Sigstore transparency entry: 1524601034
- Sigstore integration time:
-
Permalink:
lupuletic/claude-code-recall@38f12a307823bc4dfffce4d70454160488bb0bae -
Branch / Tag:
refs/tags/v0.1.4 - Owner: https://github.com/lupuletic
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@38f12a307823bc4dfffce4d70454160488bb0bae -
Trigger Event:
push
-
Statement type: