loregrep 0.6.0

Repository indexing library for AI coding assistants. Tree-sitter parsing, fast in-memory indexing, and tool APIs for LLM integration.
Documentation
# Changelog

Notable changes to loregrep. This file starts at 0.6.0; for earlier releases see
the [GitHub releases](https://github.com/Vasu014/loregrep/releases) and git history.

## 0.6.0 — unreleased

The theme is trustworthy paths and an index cache that stays out of your way. A
definition-parity eval corpus (real repositories indexed by `rust-analyzer scip`
and `scip-python`) was added first, and then found the bugs below.

### Breaking

- **The index cache no longer lives inside the repository it indexes.** It moved
  to your user cache directory (`~/Library/Caches/…` on macOS, `$XDG_CACHE_HOME`
  on Linux), keyed by a hash of the repository's canonical path. `exec-tool` used
  to write `<repo>/.loregrep/index.cache` into whatever tree it was pointed at,
  gated on nothing — a read-only query modified your working tree.

  **If you have automation that deletes `<repo>/.loregrep` to force a cold
  scan, it is now a silent no-op.** Force a cold scan by pointing
  `LOREGREP_CACHE_PATH` at a fresh directory, or set
  `LOREGREP_CACHE_ENABLED=false` to disable caching entirely. Old `.loregrep/`
  directories are left alone; they are inert and safe to delete.

- **Cache format v3.** Every previously written cache is rejected on load, by
  design and with no migration — the older formats could not prove which root
  they described. The first run after upgrading rescans.

- `LoreGrep::default_cache_path(root)` is replaced by
  `LoreGrep::cache_path_for(cache_root, repo_root)`, which rejects a relative
  cache root.

- `LoreGrepBuilder::cache_ttl` is removed. It set a field nothing ever read: a
  caller's value never reached `RepoMap`, so its hardcoded 300s applied and your
  setting was discarded silently. Index freshness is decided by content hashes.

- `LoreGrepBuilder::with_go_analyzer` is removed. It was a no-op that returned
  `self`, so calling it announced Go support and then skipped every Go file in
  silence. It returns when an analyzer honours it.

- The `scan` subcommand's `--include`, `--exclude` and `--follow-symlinks` flags
  are removed. They were parsed and discarded — nothing ever read them. Use the
  config file's `file_scanning.*` keys.

- The `cache.ttl_hours` config key is removed. Leaving it in an existing config
  file is harmless (unknown keys are ignored), and it never had an effect.

### Fixed

- `-d`/`--directory` applied only when the path argument was the default, so
  `loregrep -d /repo scan src` scanned nothing and cheerfully reported
  `Files scanned: 0`. All four subcommands now resolve paths by one rule:
  absolute arguments verbatim, relative arguments joined onto `-d`.
- `loregrep search` never loaded the persisted index. Since every process starts
  empty, it always answered "Repository not scanned. Run 'scan' first" — telling
  you to run the scan you had just run. It now loads-or-scans like `exec-tool`.
- Emitted paths varied with how `--path` was spelled, symlinked roots aliased to
  separate entries, and the index and file-set used two disagreeing key spaces.
  Paths are canonicalized once at the scanner boundary and emitted root-relative,
  with the canonical root reported as `analysis_root` on every tool response.
- `analyze_file` could read files outside the analysis root.
- A truncated index (hitting `max_files`) was cached and later reloaded as if it
  were a complete view of the repository. It is now refused for caching, refused
  on load, and reported in the response — absence of a symbol is not evidence
  that the repository lacks it.
- Cache freshness compared only the newest mtime, so a file added with a
  preserved older timestamp (`cp -p`, `rsync -a`, `tar -x`) stayed invisible.
- `scan()` was additive and never reset, so one instance scanning several roots
  accumulated symbols across repositories and answered queries from the wrong one.
- Several Rust and TypeScript parsing bugs found by the SCIP parity corpus,
  including TypeScript declarations being dropped after an unparseable construct.

### Added

- SCIP definition-parity eval corpus over ripgrep, flask and hono, scored
  against compiler-grade indexers.
- Python bindings for `get_stats`, `index_coverage`, `is_scanned`,
  `set_scan_root`, `first_missing_indexed_path` and `clear_index`; builder
  bindings for direct construction, `with_typescript_analyzer`, `max_files`,
  `include_patterns`, `follow_symlinks`, `unlimited_depth` and
  `configure_patterns_for_languages`. New `IndexCoverage` type so Python callers
  can detect a truncated index, and `ScanResult.languages` is now populated
  rather than silently dropped.
- `loregrep.__version__` is derived from the compiled extension instead of being
  hardcoded, so it can no longer report a version no code in the process
  implements.