v0.8.0 — Correctness Overhaul + Symbol Graph v3
The biggest release yet: a deep correctness overhaul of the indexing pipeline, a redesigned and finally wired-in symbol graph, and a security fix. All 224 tests green, CI passing on Python 3.10–3.12.
🔒 Security
- BM25 index is now JSON (
.ai/bm25_index.json), never pickle. The old.pkllived inside the target project's.ai/dir, so unpickling it was an arbitrary-code-execution vector when indexing third-party repos. Legacy.pklfiles are cleaned up automatically.
🧬 Symbol Graph v3 — now actually wired in
- Symbols are keyed by qualified id (
path::Class.method) — same-named symbols across files no longer collapse into one node. - New MCP tools:
find_symbol(name)andget_symbol_relations(symbol, relation)— callers / callees / implementors / subclasses / bases / usages, answered in milliseconds without loading the embedding model. - New
L1_symbolsearch tier fuses symbol-name hits intoquery()results via RRF; the background indexer keeps the graph fresh. - Inheritance extraction now works for JS/TS/Java/Ruby (was Python-only); builtin-call noise is filtered; no more double attribution of method calls to their class.
🧹 Index hygiene
- Re-indexing a changed file deletes its previous chunks first; chunks of deleted files are removed from ChromaDB, BM25 and metadata — renamed/removed symbols no longer haunt search results forever.
- Failed upserts are no longer silent: metadata isn't saved, so affected files retry on the next run.
- Query cache is invalidated on every index change; chunk IDs include
line_startso same-named symbols in one file don't overwrite each other. - Three dead tools revived:
search_with_dependencies,search_for_errors,search_architectureread a metadata key that was never written — they silently returned empty results.
⚡ Performance
- Incremental BM25: small changes no longer trigger a full-ChromaDB fetch + full index rewrite.
- Import-graph tools use a precomputed reverse graph (was O(N²·E)).
- pylint runs as a subprocess (in-process runs risked corrupting the MCP stdio protocol).
🪟 Windows & robustness
memory.mdis always UTF-8 — Cyrillic (or any non-ASCII) notes survive round-trips; atomic writes no longer unlink the target first.- Python dotted/relative imports and multi-line JS/TS imports resolve correctly in the dependency graph.
- Thread-safety across the board: context init, tree-sitter parsing, BM25 swaps, background indexer; switching project roots cancels the running background job.
🧪 Testing honesty
- Coverage no longer omits the biggest modules (the old 80% gate measured a fraction of the code); 20+ new regression tests pin every fixed bug.
Full changelog: CHANGELOG.md