Beamscope.Search.LexicalSearch (Beamscope v0.1.1)

Copy Markdown View Source

Exact/literal-text search over a repo's files for identifier-like terms pulled out of a natural-language search_code query — an in-process grep (no subprocess), run alongside Beamscope.Search.Store's embedding search rather than instead of it.

Exists because semantic search alone loses to plain grep on every exact-name-style query tested in docs/search-benchmark-2026-07.md, across three independent codebases — "where is pop_messages defined" is an exact-match question, and probabilistic ranking is the wrong tool for a question that already has a literal string to match against. Beamscope.Repo.search/3 returns this alongside (not blended into) the semantic results, since an exact match and a cosine-similarity score aren't the same kind of signal.

Summary

Functions

Pulls the terms worth grepping for out of a natural-language query. Exposed for testing.

All literal matches across the repo for identifier-like terms in query — every file is scanned (no early cutoff), since capping the scan before ranking is exactly what let a real definition get buried behind less-relevant matches in practice; callers that want ranking-then-limit (e.g. Beamscope.Repo.search/3) apply :limit after sorting, not here.

Functions

extract_terms(query)

@spec extract_terms(String.t()) :: [String.t()]

Pulls the terms worth grepping for out of a natural-language query. Exposed for testing.

search(repo_path, query, opts \\ [])

@spec search(String.t(), String.t(), keyword()) :: [map()]

All literal matches across the repo for identifier-like terms in query — every file is scanned (no early cutoff), since capping the scan before ranking is exactly what let a real definition get buried behind less-relevant matches in practice; callers that want ranking-then-limit (e.g. Beamscope.Repo.search/3) apply :limit after sorting, not here.