llmgrep 3.2.0

Smart grep over Magellan code maps with schema-aligned JSON output
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [3.2.0] - 2026-05-06

### Added
- **FTS5 OR Query Mode** — Multi-word searches now use OR semantics instead of AND:
  - `"Mutex RwLock"` matches symbols containing either word (previously required both in exact order)
  - Auto-detects `symbol_fts` table availability; falls back to `LIKE` when absent
  - Tokens are double-quoted to prevent FTS5 special-character misinterpretation
  - Verified: `"test print"` returns 744 results vs 0 with previous LIKE behavior

### Changed
- Updated Magellan dependency to `3.2.0`.

## [3.1.8] - 2026-05-06

### Changed
- Updated Magellan dependency to `3.2.0`.

## [3.1.7] - 2026-05-04

### Changed
- Updated Magellan dependency to `3.1.9`.
- Removed local path patch for Magellan; now uses published crate from crates.io.

## [3.1.6] - 2026-04-27

### Changed
- Updated Magellan dependency to `3.1.7`.
- Geometric backend builds against published `geographdb-core`.
- Removed active native-v2/native-v3 backend wiring from public configuration.

### Fixed
- SQLite backend lookup and completion paths now use implemented queries instead of stubs.
- Search scoring now uses query-aware scoring in geometric paths.
- Multi-kind and class alias filters work across supported languages.

## [3.1.4] - 2026-04-23

### Security
- **Parameterized SQL queries in AST context retrieval**
  - Replaced string-interpolated SQL with `rusqlite` parameterized queries in `src/ast.rs`
  - All `byte_start`, `byte_end`, and `preferred_kinds` values are now bound as parameters
  - Eliminates SQL injection risk from user-provided `--ast-kind` values
  - Location: `src/ast.rs`

### Fixed
- **Eliminated panic vectors in production code**
  - Removed `.expect()` in CLI path validation (`src/main.rs:808`)
  - Removed `.unwrap()` in `SearchResult::from_symbols` (`src/backend/magellan_adapter.rs:63`)
  - Replaced silent `.unwrap_or_default()` on JSON serialization with proper error propagation (`src/watch_cmd.rs:240,295,301`)
  - Fixed negative `i64` to `u64` cast that produced huge values on corrupted data (`src/backend/native_v3.rs:345-347`)
  - Fixed `.unwrap_or(false)` masking database errors in table existence checks (`src/backend/sqlite.rs:75,149`)

### Changed
- **Watch mode delta computation is now O(n+m)**
  - Replaced nested O(n×m) loops with `HashSet` lookups in `format_delta`
  - Significantly faster for large result sets in watch mode
  - Location: `src/watch_cmd.rs:254-265`

### Added
- **Compile-time `Send` assertion for `RetiredBinaryBackendBackend`**
  - Added `const _: ()` assertion verifying `CodeGraph: Send` before `unsafe impl Send`
  - Fails at compile time if the invariant is violated
  - Location: `src/backend/native_v3.rs:179`
- **`is_geometric_extension()` helper**
  - Extracted duplicated extension check logic into shared helper
  - Eliminates drift between `cfg(feature)` and `cfg(not(feature))` blocks
  - Location: `src/backend/mod.rs`

## [3.1.3] - 2026-03-20

### Fixed
- **Auto-detect regex patterns for `--query ".*"`**
  - Added `looks_like_regex()` function to detect common regex patterns
  - Auto-enables `--regex` mode with warning when regex patterns detected
  - Patterns detected: `.*`, `.+`, `^...$`, character classes, quantifiers, escaped chars
  - Location: `src/main.rs`

- **`--paths-from` version parsing and JSON handling**
  - Fixed `spawn()` + `try_wait()` + `wait_with_output()` race condition that lost stdout
  - Replaced with simple `Command::output()` which handles pipe management correctly
  - Fixed JSON parsing to look for `data.matches` instead of `matches` (Magellan API change)
  - Location: `src/algorithm.rs`

## [3.1.2] - 2026-03-19

### Fixed
- **Compiler warnings** - Fixed unreachable pattern warning in `require_native_v3()`
  - Reorganized match arms to handle all backend variants properly
  - Removed redundant fallback arm when geometric-backend is enabled
  - Location: `src/main.rs:1995`

## [3.1.1] - 2026-03-15

### Fixed
- **SQLite backend compatibility** - Fixed schema mismatches with Magellan 3.1.1
  - Fixed `files` table query to use `graph_entities` with `kind = 'File'` filter
  - Updated SQL queries to match Magellan's actual schema
  - Fixed test database schema to include `name` and `file_path` columns

### Changed
- **Cross-database compatibility** - Now fully compatible with Magellan 3.1.1 SQLite databases

## [3.1.0] - 2026-03-10 (Release Freeze)

### Changed
- **Magellan integration:**
  - Updated to Magellan v3.0.0+ with Geometric (.geo) backend support
  - Fixed `debug_print!` macro compatibility with Rust 1.83+ (removed trailing semicolon)
  - Added `retired-binary-backend` feature definition to silence cfg warnings (feature reserved, currently disabled)

### Fixed
- **Zero compile warnings:**
  - Removed unused `SearchParams::from_command` method
  - Removed unused imports (`std::sync::atomic::AtomicBool`, `std::sync::Arc`) from main.rs
  - All llmgrep lib and bin code now compiles with zero warnings

### Added
- **Geometric backend integration:**
  - `GeometricBackend` wrapper for Magellan's .geo format
  - `normalize_path_for_query()` helper for consistent path handling
  - `paths_equivalent()` for normalized path comparison
  - `lookup_symbol_by_path_and_name()` with ambiguity handling
  - `apply_path_filter()` with normalized comparison
  - `get_chunks_for_symbol()` for chunk retrieval from .geo files

### Documentation
- Updated README.md with current Magellan v3.0.0+ integration truth
- Created API_INTEGRATION.md documenting Magellan contract
- Created INVARIANTS.md documenting path normalization and ambiguity behavior
- Updated CHANGELOG.md with complete version history

## [3.0.11] - 2026-03-02

### Changed
- **Magellan dependency:** Updated to local path dependency for v3.0.0 development

### Added
- **Geometric backend module:** `src/backend/geometric.rs` with .geo file support
- **Magellan adapter module:** `src/backend/magellan_adapter.rs` for contract-aware integration
- **Path normalization:** Consistent path handling across all queries
- **Ambiguity handling:** Explicit `SymbolLookupResult` and `SearchResult` types
- **Code chunk support:** `CodeChunk` and `ChunkLookupResult` types for .geo chunk retrieval

## [3.0.10] - 2026-02-22

### Changed
- **Dependencies:** Updated sqlitegraph from 2.0.5 to 2.0.7

## [3.0.9] - 2026-02-20

### Updated
- Update sqlitegraph from 2.0.5 to 2.0.7 (bug fixes)

## [3.0.8] - 2026-02-16

### Changed
- **Dependencies:**
  - magellan: 2.4.3 → 2.4.5 (V3 backend persistence fix)
  - sqlitegraph: 2.0.3 → 2.0.5 (V3 backend persistence fix)

### Fixed
- **V3 Backend Persistence:**
  - V3 databases now properly persist and reload across process restarts
  - Previous: databases created by magellan/llmgrep would lose nodes on reopen
  - Now: full V3 persistence working - create, close, reopen, query all work correctly
  - Requires sqlitegraph 2.0.5+ which fixes NodeStore root_page_id sync issue
- **Updated for magellan 2.4.5 API:**
  - Changed `Rc<dyn GraphBackend>` to `Arc<dyn GraphBackend>` in native_v3.rs
  - Matches magellan's thread-safety improvement from 2.4.4

## [3.0.7] - 2026-02-14

### Changed
- **Dependencies:**
  - magellan: 2.4.2 → 2.4.3 (`get_symbol_by_entity_id()` for full symbol details)

### Fixed
- **V3 Backend:** Completed V3 backend implementations
  - `lookup()` - Properly extracts file path from `canonical_fqn`, returns complete `SymbolMatch`
  - `search_by_label()` - Properly extracts file path from `canonical_fqn`, returns complete `SymbolMatch`
  - Both methods now use `get_symbol_by_entity_id()` to fetch full symbol details from entity IDs

### Improved
- **Documentation:** Updated README with accurate retired binary backend feature descriptions
- **Repository:** Removed `.planning/` folder from git tracking (development docs only)

## [3.0.6] - 2026-02-14

### Changed
- **Dependencies:**
  - magellan: 2.4.1 → 2.4.2 (V3 KV operations for llmgrep integration)

### Fixed
- **V3 Backend:** Implemented V3-exclusive methods using new magellan KV APIs
  - `complete()` - now uses `CodeGraph::complete_fqn()`
  - `lookup()` - now uses `CodeGraph::lookup_symbol_by_fqn()`
  - `search_by_label()` - now uses `CodeGraph::get_symbols_by_label_kv()`

## [3.0.5] - 2026-02-14

### Changed
- **Dependencies:**
  - magellan: 2.3.1 → 2.4.1 (full V3 backend feature parity)
  - sqlitegraph: 2.0.1 → 2.0.3 (kv_prefix_scan_v3 support)

### Fixed
- **Test Suite:** Updated test references from native-v2 to retired-binary-backend feature
  - Fixed backend detection tests with proper 16-byte headers
  - Renamed test files to reflect retired-binary-backend naming

## [3.0.2] - 2026-02-14

### Changed

- **retired binary backend Backend Support:**
  - Migrated from native-v2 to retired-binary-backend backend (magellan 2.3.0)
  - V3 uses high-performance binary format with KV store side tables
  - Single `.db` file contains all data (graph + side tables)
  - Zero SQLite dependency when using V3 backend
  - Feature flag changed from `native-v2` to `retired-binary-backend`

- **Dependencies:**
  - magellan: 2.2.1 → 2.3.0
  - sqlitegraph: 1.5.7 → 2.0.1

## [3.0.1] - 2026-02-10

### Fixed

**KV Data Persistence (Critical Fix):**
- Fixed KV index data not being persisted across process restarts
  - Updated magellan to 2.2.1 (includes WAL buffer flush fix)
  - Updated sqlitegraph to 1.5.7 (includes `flush()` method)
  - `complete` and `lookup` commands now work reliably after magellan exits
  - WAL file properly contains KV data (1.4MB with 1000+ entries)

### Changed

- **Dependencies:**
  - magellan: 2.2.0 → 2.2.1
  - sqlitegraph: 1.5.6 → 1.5.7

### Verified

- Cross-process KV communication works (magellan → llmgrep)
- `complete` command returns 1000+ FQN entries
- `lookup` command finds symbols by exact FQN
- WAL persists at 1.4MB after magellan exits

---

## [3.0.0] - 2026-02-10

### Native-V2 Backend Support

**Major release adding dual backend support with Magellan's native-v2 storage.**

**New commands (native-v2 exclusive):**
- `llmgrep complete --db <DB> --prefix <PREFIX>` — FQN autocomplete via KV prefix scan
  - O(1) prefix-based autocomplete using `magellan::kv::kv_prefix_scan()`
  - Supports `--limit <N>` for result limiting
  - Human output (one FQN per line) and JSON formats
- `llmgrep lookup --db <DB> --fqn <FQN>` — O(1) exact symbol lookup
  - Two-phase lookup: KV store for SymbolId, SQL for full metadata
  - Returns `SymbolNotFound` error (SPL-E112) with helpful hints

**New search features:**
- `--mode label` flag — Purpose-based label search
  - Search by purpose label: `test`, `entry_point`, `public_api`
  - Uses `magellan::kv::label_key()` for O(1) label lookups
  - Default label: `test` when `--label` not specified

**Performance instrumentation:**
- `--show-metrics` global flag — Display timing breakdown
  - Three-phase timing: backend detection, query execution, output formatting
  - Metrics printed to stderr (human) or included in JSON output
  - Helps identify bottlenecks in query pipelines

**Backend architecture:**
- **Dual backend support:** SQLite (rusqlite) + Native-V2 (Magellan CodeGraph API)
- **Runtime detection:** Automatic backend format detection (no `--backend` flag needed)
- **Graceful fallback:** Native-v2 commands return `RequiresNativeV2Backend` error (SPL-E111) on SQLite databases
- **Feature flag:** Native-v2 support requires `--features native-v2` at compile time

**New error codes:**
- `SPL-E109`: NativeV2BackendNotSupported — native-v2 database detected but llmgrep built without native-v2 feature
- `SPL-E110`: BackendDetectionFailed — unable to determine database format
- `SPL-E111`: RequiresNativeV2Backend — native-v2-only command run on SQLite database
- `SPL-E112`: SymbolNotFound — exact FQN lookup failed with suggestions

**Test coverage:**
- 30 new integration tests for native-v2 exclusive features
- Total: 371 tests passing (zero regressions)

**Dependencies:**
- Updated magellan to 2.2.0+
- Updated sqlitegraph to 1.5.5+
- Added native-v2 feature flag (`--features native-v2`)

**Documentation:**
- Updated README.md with v3.0 features
- Updated CHANGELOG.md with v3.0.0 entry
- All Phase 17-21 planning artifacts in `.planning/phases/`

**Migration from v2.1.x:**
- SQLite backend continues to work without changes
- Native-v2 features are opt-in via feature flag
- No breaking changes to existing commands
- Rebuild with `--features native-v2` to enable native-v2 support

**Compatibility:**
- Magellan 2.2.0+ recommended for native-v2 features
- SQLite databases continue to work with rusqlite backend
- Native-v2 storage provides O(1) KV lookups and smaller file sizes

---

## [2.1.1] - 2026-02-04

### Added
- **Windows Support:** Full cross-platform compatibility via explicit feature flag
  - Use `--features windows` to enable Windows builds
  - Default: `--features unix` (Linux/macOS)
  - Platform detection centralized in `platform.rs` module
  - llmgrep is fully functional on Windows (read-only tool, no background processes)

### Changed
- Feature model: `default = ["unix"]`, `windows` opt-in
- Updated magellan dependency to 2.1.1

**One sentence for the docs:**
> Windows support is opt-in via `--features windows`. Fully supported — llmgrep is a read-only tool.

## [2.1.0] - 2026-02-04

### Added

**New commands:**
- `llmgrep ast --db <DB> --file <PATH>` — Query raw AST tree for a file
  - `--position <OFFSET>` flag for node-at-position query
  - `--limit <N>` flag for output limiting
- `llmgrep find-ast --db <DB> --kind <KIND>` — Find AST nodes by kind

**New search flags:**
- `--condense` — Filter to symbols in strongly connected components (SCCs)
- `--paths-from <SYMBOL>` — Filter by execution paths from start symbol
- `--paths-to <SYMBOL>` — Optional end symbol for path filtering

**Algorithm integration:**
- `parse_condense_output()` — Parse magellan condense JSON output
- `parse_paths_output()` — Parse magellan paths JSON output with bounded detection
- `run_ast()` — Shell-out helper for magellan ast command
- `run_find_ast()` — Shell-out helper for magellan find-ast command

**Dependencies:**
- Updated magellan to 2.1.0
- Updated sqlitegraph to 1.3.0

**Error handling:**
- Magellan availability check before algorithm commands (version 2.1.0+ required)
- Clear error messages with installation hints when Magellan not found

**New tests:**
- 18 new tests for ast command (file mode, position mode, limit, validation)
- 2 new tests for find-ast command (basic, various kinds)
- Total: 320 tests passing

**Documentation:**
- Updated README.md with toolset context (Magellan, Mirage, Splice, sqlitegraph)
- Updated MANUAL.md with ast and find-ast commands
- Added v2.1.0 entry to CHANGELOG.md

### Changed

- Documentation now emphasizes llmgrep is part of the sqlitegraph toolset
- All documentation updated to clarify llmgrep only works in conjunction with Magellan

### Compatibility

- Magellan 2.1.0 or later required for algorithm features
- sqlitegraph 1.3.0 or later required

## [1.4.0] - 2026-02-03

### Added

**Magellan 2.0 Algorithm Integration:**
- `--from-symbol-set <FILE>` flag — Load pre-computed SymbolSet from JSON file for filtering
- `--reachable-from <SYMBOL>` flag — One-shot filter: find symbols reachable from specified symbol
- `--dead-code-in <SYMBOL>` flag — One-shot filter: find dead code (unreachable symbols)
- `--in-cycle <SYMBOL>` flag — One-shot filter: find symbols in dependency cycles
- `--slice-backward-from <SYMBOL>` flag — One-shot filter: backward slice (code affecting target)
- `--slice-forward-from <SYMBOL>` flag — One-shot filter: forward slice (code affected by target)

**SymbolSet module (src/algorithm.rs):**
- SymbolSet type with JSON serialization/deserialization
- `run_magellan_algorithm()` — Shell-out helper for Mag CLI algorithms
- `parse_symbol_set_file()` — Load and validate SymbolSet JSON files
- `resolve_fqn_to_symbol_id()` — FQN to SymbolId resolution via `magellan find`
- Temporary table optimization for large SymbolSets (>1000 items)

**SQL filtering extensions:**
- `WHERE symbol_id IN (...)` clause for small SymbolSets
- Temporary table JOIN strategy for large SymbolSets
- `apply_algorithm_filters()` — Orchestrates pre-computed and one-shot filters

**Error codes (SPL-E1xx series):**
- `SPL-E105`: Magellan CLI not found
- `SPL-E106`: Ambiguous symbol name
- `SPL-E107`: Magellan version mismatch
- `SPL-E108`: Magellan algorithm execution failed

**New tests:**
- 33 new algorithm integration tests (561 lines) covering all algorithm types
- Tests for SymbolSet parsing, validation, FQN resolution, and error handling
- Total: 310 tests passing (up from 277)

**Documentation:**
- README.md updated with Magellan Algorithm Integration examples
- MANUAL.md updated with complete algorithm flag reference and composed workflow
- SymbolSet file format documented

**Changed**
- Updated Magellan dependency to support algorithm commands
- Updated Magellan CLI integration for `--output json` format parsing

**Compatibility**
- Magellan 2.0.0 or later recommended for algorithm features
- Backward compatible with v1.3 databases (graceful degradation for missing ast_nodes)
- SymbolSet file format: `{"symbol_ids": ["abc123...", ...]}`

## [1.3.0] - 2026-02-03

### Added

**Structural search features:**
- `--inside <KIND>` flag to find symbols within a parent of specific kind
- `--contains <KIND>` flag to find symbols containing specific children

### Changed

**Documentation updates:**
- Added structural search examples to MANUAL.md
- Added structural search examples to README.md
- Fixed compiler warnings (unused variables prefixed with underscore)

## [1.2.0] - 2026-02-01

### Added

**AST filtering features:**
- `--ast-kind <KIND>` flag to filter search results by AST node kind
- `--with-ast-context` flag to include enriched AST context in results
- `--min-depth <N>` flag to filter by minimum nesting depth
- `--max-depth <N>` flag to filter by maximum nesting depth

## [1.1.1] - 2026-01-31

### Bug Fixes

**Critical: Metrics not returned in search results**
- Fixed JOIN condition in `build_symbol_query()` (line 1237)
- Root cause: Compared SHA hash string to INTEGER row ID

## [1.1.0] - 2026-01-31

### Magellan 1.8.0 Integration

**Added**
- Magellan v1.8.0 dependency for safe UTF-8 content extraction
- Chunk-based snippet retrieval from `code_chunks` table
- Metrics-based filtering and sorting
- SymbolId-based lookups via `--symbol-id` flag
- FQN filtering and ambiguity detection
- Language filtering via `--language` flag

## [1.0.0] - 2026-01-25

### Stable CLI

**Initial release with comprehensive error handling, security hardening, code quality improvements, test coverage, and developer experience enhancements.**

[Unreleased]: Initial llmgrep CLI with Magellan DB search