source-recall
Fast code and document search. Indexes repositories with tree-sitter parsing, embeds chunks with a local model, and retrieves via hybrid BM25 + vector search with reciprocal rank fusion.
Requirements
- Python ≥ 3.12 (3.13 recommended)
- uv for installs (or any PEP 517 installer)
- mise optional but recommended — pins Python,
uv, and just to known-good versions (run
mise installafter cloning)
Install
From PyPI (the distribution is dungle-scrubs-source-recall):
# FTS-only: no model download, instant startup, keyword search only
uv tool install dungle-scrubs-source-recall
# Full: vector search and reranking, ~2 GB model deps
uv tool install "dungle-scrubs-source-recall[embed]"
From a checkout (development):
uv tool install -e .[embed]
This gives you the sr CLI globally.
Quick Start
# Index a repository
sr index ~/dev/my-project
# Search
sr ask "how does authentication work" ~/dev/my-project
# Start persistent server (typically <100ms warm queries vs ~12s cold)
sr serve ~/dev/my-project
CLI Commands
sr index [PATH]
Build or rebuild the full index. Parses source files with tree-sitter, splits into semantic chunks, embeds with CodeRankEmbed, and stores in SQLite.
sr index . # index current directory
sr index ~/dev/project # index a specific repo
SR_EMBED_ENABLED=false sr index . # skip embeddings (FTS only)
sr ask QUESTION [PATH]
Search the index. Returns ranked code chunks.
sr ask "payment processing"
sr ask "UserModel" ~/dev/api
sr ask --json "auth" # JSON output
sr ask --plain "config" | llm # pipe to LLM
sr ask --files "database" # file paths only
sr serve [PATHS...]
Start a persistent HTTP query server. Loads the embedding model once on startup (~12s), then serves warm queries in <100ms.
sr serve . # single repo
sr serve ~/dev/api ~/dev/frontend # multiple repos
sr serve ~/dev/api --port 7249 --host 0.0.0.0 # custom bind
Endpoints:
| Method | Path | Description |
|---|---|---|
GET |
/health |
Liveness check ({ok, repos, uptime_s}) |
GET |
/repos |
List loaded repos with stats |
POST |
/query |
Search ({question, top_k?, repo?}) |
GET |
/status |
Index metrics |
POST |
/refresh |
Incremental re-index |
When serving multiple repos, include "repo": "name" in query
requests. With a single repo, the repo field is optional.
# Query the server
curl -X POST http://localhost:7249/query \
-H "Content-Type: application/json" \
-d '{"question": "authentication", "top_k": 5}'
sr status [PATH]
Show index metrics: file count, chunk count, vector coverage, database size.
Configuration
Configuration is resolved in order (first wins):
- Environment variables (
SR_prefix) - Repo-local
.source-recall.toml - Built-in defaults
Environment Variables
| Variable | Default | Description |
|---|---|---|
SR_MAX_FILE_SIZE |
100000 |
Skip files larger than this (bytes) |
SR_TOP_K |
8 |
Default number of results |
SR_CHUNK_MAX_CHARS |
6000 |
Max characters per chunk before sub-chunking |
SR_AUTO_REFRESH |
true |
Auto-refresh stale indexes before queries |
SR_EMBED_ENABLED |
true |
Enable vector embeddings (set false for FTS-only). Requires the embed install extra. |
SR_EMBED_BATCH_SIZE |
32 |
Chunks per embedding batch |
SR_RERANK_ENABLED |
false |
Enable cross-encoder reranking (slower, more accurate) |
TOML Config
Create .source-recall.toml in your repo root:
[source-recall]
top_k = 10
max_file_size = 200000
embed_enabled = true
rerank_enabled = true
exclude_patterns = ["node_modules/", "dist/", ".git/"]
Config Reference
| Field | Type | Default | Notes |
|---|---|---|---|
max_file_size |
int | 100,000 | Bytes. Files above this are skipped. |
top_k |
int | 8 | Results per query (1–100). |
chunk_max_chars |
int | 6,000 | Sub-chunk threshold. |
auto_refresh |
bool | true | Re-index changed files before querying. |
embed_enabled |
bool | true | false disables vector search entirely. Requires the embed install extra. |
embed_batch_size |
int | 32 | Tune for memory vs speed (1–512). |
rerank_enabled |
bool | false | Cross-encoder reranking over top candidates. Adds ~100ms per query but improves relevance. |
exclude_patterns |
list | see below | Glob patterns to skip during indexing. |
Default excludes: node_modules/, dist/, build/, .git/,
__pycache__/, *.pyc, .venv/, venv/, .tox/,
.mypy_cache/, .pytest_cache/, .ruff_cache/.
Supported Content
| Type | Strategy | Extensions |
|---|---|---|
| Python | tree-sitter AST | .py |
| TypeScript/JavaScript | tree-sitter AST | .ts, .tsx, .js, .jsx |
| PHP | tree-sitter AST | .php, .phtml |
| Vue SFC | tree-sitter AST per block; <script> via the TS strategy |
.vue |
| Blade | Block-directive boundaries (@section, @push, …) |
.blade.php |
| Bash | Regex (function boundaries) | .sh, .bash |
| Markdown | Heading-based sections | .md, .mdx, .markdown |
| Page-level text extraction (pymupdf) | .pdf |
|
| Plain text | Sentence-boundary sliding window | .txt, .text, .rst, .log |
| Everything else | Blank-line splitting | * |
Retrieval Pipeline
Query
→ FTS5 BM25 search (top 30)
→ Vector cosine search (top 30)
→ Symbol exact match (if query looks like a symbol)
→ RRF merge (k=15)
→ Cross-encoder rerank (if enabled, top 3x top_k candidates)
→ Graph expansion (top 5 → follow refs → resolve symbols)
→ Return top_k
Reranking uses cross-encoder/ms-marco-MiniLM-L-6-v2 (22M
params, ~90MB). It scores query-document pairs jointly, which is
more accurate than bi-encoder cosine similarity. Adds ~100ms.
Enable with SR_RERANK_ENABLED=true.
Graph expansion follows cross-references (imports, inheritance, decorators) from the top results and pulls in the referenced definitions. This surfaces related code without the user explicitly asking for it.
Embedding Model
CodeRankEmbed (nomic-ai/CodeRankEmbed, 137M params, 768d,
MIT license). Runs locally via sentence-transformers + ONNX
Runtime. Downloads ~522MB on first run (cached in
~/.cache/huggingface/).
Disable with SR_EMBED_ENABLED=false for pure FTS keyword
search (no model download, instant startup).
Auto-Start (macOS)
The daemon can run as a launchd service that auto-starts at login and
restarts on crash. sr daemon start generates a plist dynamically
(with resolved paths from your environment) and loads it — no manual
editing required:
# Configure which repos the daemon serves
sr add ~/dev/my-project
# Generate the plist and start the service
sr daemon start
# Check status
sr daemon status
# View logs
sr daemon logs
# Stop
sr daemon stop
Other platforms (systemd on Linux, Task Scheduler on Windows) are not
yet automated; run sr daemon run in your platform's service manager.
Justfile
just test # run tests
just t # run tests (short output)
just lint # check lint + format
just fix # auto-fix lint + format
just serve # start server (current dir)
just query "auth" # query running server
just health # server health check
just repos # list served repos
just status # server index status
just install # install sr globally
Dependencies
| Package | Size | Purpose |
|---|---|---|
| sentence-transformers | ~2GB (includes torch) | Embedding + reranking models |
| sqlite-vec | ~5MB | Vector search in SQLite |
| pymupdf | ~15MB | PDF text extraction |
| tree-sitter + grammars | ~10MB | AST parsing |
| fastapi + uvicorn | ~5MB | Query server |
| apsw | ~5MB | SQLite extension loading on macOS |
Development
See CONTRIBUTING.md for the full guide. The
short version:
# Setup
mise install
uv sync
# Run tests (fast, skips model-loading tests)
uv run pytest -m "not slow"
# Run all tests including slow model tests
uv run pytest
# Lint
uv run ruff check src/ tests/
This repo uses mise to pin the local Python, uv, and just versions.
Run mise install after cloning, then use the existing uv and just
commands normally.
Support
- Bugs and feature requests: GitHub Issues
- Security vulnerabilities: see
SECURITY.md— do not open a public issue; use a private GitHub Security Advisory. - Code of conduct:
CODE_OF_CONDUCT.md
Metadata
Release files for dungle-scrubs-source-recall 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| dungle_scrubs_source_recall-0.1.1.tar.gz | 121.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| dungle_scrubs_source_recall-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 252.4 kB
Release files / dungle_scrubs_source_recall-0.1.1.tar.gz
| Download URL | dungle_scrubs_source_recall-0.1.1.tar.gz |
|---|---|
| Size | 121.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
63836331f67b12277065a9b37b92f4b758f39fc251f026e37b3fd9fcb166a4ad
|
|
BLAKE2b-256 checksum How to use checksums |
c2c05f5daf186bec79f6d9e8424f40a2aecd5614cf34e6e969845769d7c7713d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.11.25 {"installer":{"name":"uv","version":"0.11.25","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 9, 2026.
Transparency logRelease files / dungle_scrubs_source_recall-0.1.1-py3-none-any.whl
| Download URL | dungle_scrubs_source_recall-0.1.1-py3-none-any.whl |
|---|---|
| Size | 130.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
dc3eb8e604cb9cd975c24e1f61017082c4f80bb6f93a962e9851f8f79570461e
|
|
BLAKE2b-256 checksum How to use checksums |
9772505a1223acfbee28c221fe85d16716ee9e3d97141ee63ffff9f0bd1fac98
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.11.25 {"installer":{"name":"uv","version":"0.11.25","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 9, 2026.
Transparency log