How Cross-Repository Search Works in Code Review Graph: A Complete Technical Guide
Cross-repository search aggregates results from SQLite indexes across every registered repository by iterating over a global registry, executing parallel LIKE queries, and deduplicating matches before displaying them in the VS Code interface.
The Code Review Graph VS Code extension maintains a centralized registry of repositories, each indexed in a lightweight SQLite database storing code graph nodes. When you invoke the search command, the extension transparently queries all registered repositories and unifies the results, enabling seamless navigation across your entire codebase.
The Registry and Indexing Architecture
The foundation of cross-repo search lies in a persistent registry located at ~/.code-review-graph/registry.json. This file tracks every repository added to your workspace. For each registered entry, the extension maintains a separate SQLite index file containing graph nodes—functions, classes, and tests—complete with their fully-qualified names and repository identifiers.
Each repository index follows a consistent schema storing name, qualified_name, and repo_id columns. This structure enables fast text lookups using standard SQL LIKE patterns rather than heavy in-memory processing.
The Five-Step Search Execution Flow
When you trigger a search via the VS Code Command Palette (Search command) or the webview input, the extension executes a precise five-phase pipeline:
-
Discovery of Registered Repositories – The extension loads the complete list of tracked repositories from the global registry configuration.
-
Reader Instantiation – For each repository entry, the backend creates a
SqliteReaderinstance defined insrc/backend/sqlite.ts. Each reader maintains an open connection to its respective SQLite file and exposes thesearchNodesmethod for fast queries. -
Distributed Query Execution – The search command in
src/features/search.tsiterates over all reader instances, callingreader.searchNodes(query, 20)to retrieve up to 20 matches per repository using optimized SQLLIKEclauses. -
Result Aggregation – The command concatenates results from all readers into a single array, applies a global limit of 30 results, and removes duplicates that may appear across multiple repositories.
-
UI Rendering – The aggregated list travels to the webview layer (
src/webview/graph.tsandsrc/views/graphWebview.ts), where the interface highlights matching nodes and enables navigation to specific definitions in the appropriate repository.
Core Implementation: SQLite and Aggregation Logic
The SqliteReader class in src/backend/sqlite.ts implements the low-level search functionality. The searchNodes method constructs a parameterized SQL query targeting both simple names and fully-qualified names:
// src/backend/sqlite.ts
searchNodes(query: string, limit: number = 20): GraphNode[] {
const stmt = this.db.prepare(
`SELECT * FROM nodes WHERE name LIKE ? OR qualified_name LIKE ? LIMIT ?`
);
return stmt.all(`%${query}%`, `%${query}%`, limit);
}
This implementation supports SQL wildcard patterns (% for any sequence of characters, _ for single characters), allowing flexible substring matching without loading entire datasets into memory.
The cross-repo aggregation logic resides in src/features/search.ts. The command iterates through all repository readers, collects partial results, and applies global result limits:
// src/features/search.ts
const results = [];
for (const reader of readers) {
results.push(...reader.searchNodes(value, 20));
}
// Trim to global limit & de‑duplicate
const unique = dedupe(results).slice(0, 30);
Note the dual limiting strategy: each repository contributes a maximum of 20 results, while the final user-facing list caps at 30 unique entries total.
VS Code Integration and Command Registration
The extension entry point in src/extension.ts wires the search functionality to the VS Code command palette and UI components:
// src/extension.ts
vscode.commands.registerCommand('codeReviewGraph.search', async () => {
const query = await vscode.window.showInputBox({ prompt: 'Search nodes...' });
if (query) {
const results = sqliteReader.searchNodes(query);
// UI handling …
}
});
For live filtering within the graph visualization, src/views/graphWebview.ts provides the HTML input element that captures keystrokes and forwards them through the same backend pipeline.
Programmatic Usage and CLI Access
You can trigger cross-repo search programmatically from within your own extension scripts by importing the reader factory:
import { getRegisteredRepoReaders } from './backend/sqlite';
async function crossRepoSearch(term: string, limit = 30) {
const readers = await getRegisteredRepoReaders(); // loads all repo readers
const allMatches = [];
for (const r of readers) {
allMatches.push(...r.searchNodes(term, limit));
}
// optional: sort, dedupe, rank
return allMatches.slice(0, limit);
}
The extension also exposes a command-line interface for terminal-based workflows:
code-review-graph search "authService"
# → prints matching nodes from every registered repository
Summary
- Registry Location: Repository metadata persists in
~/.code-review-graph/registry.json. - Per-Repository Index: Each repo uses a dedicated SQLite file accessed via the
SqliteReaderclass insrc/backend/sqlite.ts. - Query Mechanism: Searches execute SQL
LIKEqueries againstnameandqualified_namecolumns supporting wildcard patterns. - Result Limits: Individual repositories return maximum 20 results; the global view limits output to 30 unique entries after deduplication.
- Command Path: The
codeReviewGraph.searchcommand insrc/features/search.tsorchestrates the aggregation loop across all registered readers.
Frequently Asked Questions
Where is the repository registry stored?
The extension maintains a global registry at ~/.code-review-graph/registry.json in your home directory. This JSON file tracks all repositories added to the workspace, including paths to their individual SQLite index files.
How does the search handle duplicate nodes across repositories?
The aggregation logic in src/features/search.ts concatenates results from all repository readers, then applies a dedupe() function to remove entries that may appear in multiple repos (such as shared libraries or forked code), finally slicing the array to the global limit of 30 results.
Can I adjust the number of results returned per repository?
The searchNodes method in src/backend/sqlite.ts accepts a limit parameter defaulting to 20. While the default VS Code command uses this value, you can modify the call site in src/features/search.ts or use the programmatic API to request different per-repository limits when building custom workflows.
Does cross-repo search support regular expressions?
No, the current implementation uses SQL LIKE syntax only, supporting % (wildcard for any character sequence) and _ (single character wildcard). The query wraps your search term with % wildcards automatically: %${query}%. Full regular expression support would require modifying the SQL query construction in SqliteReader.searchNodes.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →