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:

  1. Discovery of Registered Repositories – The extension loads the complete list of tracked repositories from the global registry configuration.

  2. Reader Instantiation – For each repository entry, the backend creates a SqliteReader instance defined in src/backend/sqlite.ts. Each reader maintains an open connection to its respective SQLite file and exposes the searchNodes method for fast queries.

  3. Distributed Query Execution – The search command in src/features/search.ts iterates over all reader instances, calling reader.searchNodes(query, 20) to retrieve up to 20 matches per repository using optimized SQL LIKE clauses.

  4. 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.

  5. UI Rendering – The aggregated list travels to the webview layer (src/webview/graph.ts and src/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 SqliteReader class in src/backend/sqlite.ts.
  • Query Mechanism: Searches execute SQL LIKE queries against name and qualified_name columns 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.search command in src/features/search.ts orchestrates 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →