Loregrep
Structural code intelligence for AI coding agents.
Loregrep parses a repository with tree-sitter into a fast in-memory index and exposes it as a small set of tools an agent can call — returning precise, structured JSON (names, signatures, callers, imports, line numbers) instead of raw text matches. It's the context engine an agent calls; it is not an AI itself.
Ask "where is
parse_configdefined", "what calls it", "what does this file export", or "give me a map of this repo" — and get exact answers, cheaper on tokens than grepping and reading files.
Languages: Rust · Python · TypeScript/TSX (Go, JavaScript planned)
flowchart TB
A(["🤖 Coding agent"]):::agent
subgraph IF["Interfaces"]
direction LR
S["Claude Code skill"]:::iface
P["pi extension"]:::iface
C["exec-tool CLI"]:::iface
end
subgraph ENG["loregrep engine"]
direction LR
SC["Scanner<br/>gitignore-aware"]:::eng
AN["Tree-sitter analyzers<br/>Rust · Python · TS / TSX"]:::eng
IX[("Index · RepoMap<br/>persistent cache")]:::index
SC --> AN --> IX
end
T["6 structural tools"]:::tools
J(["Structured JSON<br/>names · signatures · lines"]):::out
A -->|invoke| IF
IF -->|exec-tool| ENG
IX --> T
T --> J
J -->|precise context| A
classDef agent fill:#6366f1,stroke:#4338ca,color:#ffffff,font-weight:bold
classDef iface fill:#8b5cf6,stroke:#6d28d9,color:#ffffff
classDef eng fill:#0284c7,stroke:#075985,color:#ffffff
classDef index fill:#f59e0b,stroke:#b45309,color:#1f2937,font-weight:bold
classDef tools fill:#14b8a6,stroke:#0f766e,color:#ffffff
classDef out fill:#10b981,stroke:#047857,color:#ffffff,font-weight:bold
Why
A coding agent that greps and reads whole files burns tokens on noise and still misses cross-file structure. Loregrep gives it structured, symbol-level access:
- Precise, not textual — definitions and call sites, with signatures and line numbers, not every string match.
- Token-cheap — compact JSON results instead of file dumps.
- Fast & cached — parse once; a persistent index makes repeated queries instant, and edits auto-invalidate it.
- Agent-native — one command per tool, JSON on stdout; ships as a Claude Code skill and a pi extension.
- Embeddable — a Rust crate and a Python wheel with the same tool API.
Install
Use it three ways
1. As an agent tool (CLI)
exec-tool runs one analysis tool and prints JSON to stdout (diagnostics go to stderr):
The index is cached in your user cache directory (~/Library/Caches/… on macOS,
$XDG_CACHE_HOME on Linux), keyed by the repository's canonical path — never inside the
repository being analyzed, so querying a tree never modifies it. Repeated calls are instant;
editing a source file invalidates the cache automatically. Set LOREGREP_CACHE_PATH to
relocate it, or LOREGREP_CACHE_ENABLED=false to disable caching entirely.
2. Inside your coding agent (skill / extension)
- Claude Code — the
loregrepskill teaches the agent when and how to call these tools. - pi — install the
loregrep-piextension:pi install npm:loregrep-pi.
Both wrap the same six tools, so your agent reaches for structural search instead of grep.
3. As a library
Rust:
use LoreGrep;
async
Python:
= # Rust + Python + TypeScript
await
= await
Tools
| Tool | Purpose | Required params |
|---|---|---|
search_functions |
Find functions by name/regex | pattern |
search_structs |
Find structs/classes/interfaces by name/regex | pattern |
find_callers |
All call sites of a function | function_name |
get_dependencies |
A file's imports/exports | file_path |
analyze_file |
A file's skeleton (functions/structs/imports/calls) | file_path |
get_repository_tree |
Repository overview / tree | — |
Optional: limit, language (rust/python/typescript), include_content,
include_file_details, max_depth. Get machine-readable schemas with
LoreGrep::get_tool_definitions().
Language support
| Language | Functions | Structs/Classes | Imports/Exports | Calls |
|---|---|---|---|---|
| Rust | ✅ | ✅ | ✅ | ✅ |
| Python | ✅ | ✅ | ✅ | ✅ |
| TypeScript / TSX | ✅ | ✅ | ✅ | ✅ |
| JavaScript, Go | planned |
Adding a language is a drop-in contribution: implement one trait in one file — see docs/adding-a-language.md.
How it works
The registry dispatches by language, so analyzers are additive; the scanner is gitignore-aware, and the index persists to disk and re-scans only when files change (see the diagram above). Full design in ARCHITECTURE.md.
Contributing
Contributions — especially new language analyzers — are welcome. See
CONTRIBUTING.md and
docs/adding-a-language.md.
CI runs cargo fmt, cargo test, and the Python binding tests on every PR.
License
Dual-licensed under either MIT or Apache-2.0, at your option.