# How to Perform Cross-Repository Search Across Multiple Registered Repositories

> Learn how to perform cross-repo search with the code-review-graph VS Code extension. Effortlessly query files across all your registered repositories with a unified knowledge graph.

- Repository: [Tirth Kanani/code-review-graph](https://github.com/tirth8205/code-review-graph)
- Tags: how-to-guide
- Published: 2026-07-21

---

**The code-review-graph VS Code extension enables unified cross-repository search by maintaining a SQLite-backed knowledge graph that indexes all files from registered workspaces, allowing single queries to aggregate results across every added repository.**

The code-review-graph extension transforms scattered codebases into a unified, searchable knowledge graph directly inside VS Code. By registering multiple repositories in your workspace, you unlock the ability to perform cross-repo search across all of them simultaneously without switching contexts. This article explains the architecture and implementation details of this feature based on the actual source code in `tirth8205/code-review-graph`.

## Architecture of the Cross-Repository Search System

### The Unified SQLite Knowledge Graph

At the core of the search capability lies a local **SQLite database** managed by [`src/backend/sqlite.ts`](https://github.com/tirth8205/code-review-graph/blob/main/src/backend/sqlite.ts). When a repository is opened, the extension stores a parsed representation of each file, tagging every entry with a unique **repository identifier** (`repo_id`). This design allows the system to distinguish which files belong to which registered repositories while maintaining a single, queryable index.

### Repository Registration via the Onboarding Flow

Before a repository becomes searchable, it must be registered through the onboarding system implemented in [`src/onboarding/installer.ts`](https://github.com/tirth8205/code-review-graph/blob/main/src/onboarding/installer.ts). The installer records the absolute path of each repository in the `repos` table and triggers an initial indexing run. Only repositories present in this table are considered during cross-repo search operations.

```typescript
export async function registerRepo(rootPath: string) {
  const db = await getDb();
  db.run('INSERT OR IGNORE INTO repos (path, name) VALUES (?, ?)', [rootPath, path.basename(rootPath)]);
  // Kick off an initial indexing run
  await indexRepository(rootPath);
}

```

## Executing Cross-Repository Search Queries

### The Search Implementation in search.ts

The actual query logic resides in [`src/features/search.ts`](https://github.com/tirth8205/code-review-graph/blob/main/src/features/search.ts). When a user submits a search term, the backend executes a SQL query that filters the `files` table based on the `repo_id` column, ensuring results are aggregated only from currently registered repositories.

```typescript
export async function searchAcrossRepos(query: string): Promise<SearchResult[]> {
  // The SQLite helper lives in src/backend/sqlite.ts
  const db = await getDb();
  const stmt = db.prepare(`
    SELECT file_path AS filePath, repo_name AS repoName
    FROM files
    WHERE repo_id IN (SELECT id FROM repos)   -- all registered repos
      AND content LIKE ?
    LIMIT 100
  `);
  return stmt.all(`%${query}%`);
}

```

### Triggering Search from the VS Code Interface

The extension exposes a command palette entry that invokes the search functionality. This command collects the user input and routes it to the backend via the extension's RPC channel, as implemented in [`src/features/search.ts`](https://github.com/tirth8205/code-review-graph/blob/main/src/features/search.ts).

```typescript
// Triggered by the command palette entry "Code Review Graph: Search"
vscode.commands.registerCommand('codeReviewGraph.search', async () => {
  const query = await vscode.window.showInputBox({ prompt: 'Search all registered repos' });
  if (!query) { return; }

  // Send query to the backend (handled in src/features/search.ts)
  const results = await vscode.window.withProgress(
    { location: vscode.ProgressLocation.Notification, title: `Searching for "${query}"` },
    () => rpc.invoke('searchAcrossRepos', query)
  );

  // Show results in a quick‑pick list
  const item = await vscode.window.showQuickPick(
    results.map(r => ({ label: r.filePath, description: r.repoName }))
  );
  if (item) { vscode.workspace.openTextDocument(item.label).then(doc => vscode.window.showTextDocument(doc)); }
});

```

## Maintaining the Search Index Across Repositories

### Real-Time Updates with the File Watcher

To keep search results current without full re-scans, [`src/backend/watcher.ts`](https://github.com/tirth8205/code-review-graph/blob/main/src/backend/watcher.ts) monitors the file system for changes within all registered repositories. When files are modified, added, or deleted, the watcher incrementally updates the SQLite index, ensuring the cross-repo search reflects the latest codebase state.

### Performance Optimizations

The extension creates a database index on the (`repo_id`, `content`) columns to accelerate cross-repo look-ups. This indexing strategy allows the SQL engine to quickly narrow down results to specific repositories before performing content matching, significantly improving query performance across large multi-repository workspaces.

## Summary

- The extension stores file metadata and content in a local SQLite database ([`src/backend/sqlite.ts`](https://github.com/tirth8205/code-review-graph/blob/main/src/backend/sqlite.ts)) tagged with repository identifiers.
- Repositories must be registered via [`src/onboarding/installer.ts`](https://github.com/tirth8205/code-review-graph/blob/main/src/onboarding/installer.ts) to be included in the searchable graph.
- Cross-repo queries are executed in [`src/features/search.ts`](https://github.com/tirth8205/code-review-graph/blob/main/src/features/search.ts) using SQL that filters by registered repository IDs.
- Real-time synchronization is handled by [`src/backend/watcher.ts`](https://github.com/tirth8205/code-review-graph/blob/main/src/backend/watcher.ts) through incremental indexing.
- Database indexing on (`repo_id`, `content`) ensures fast search performance across multiple registered repositories.

## Frequently Asked Questions

### How do I add a new repository to the cross-repo search?

To include a new repository, use the onboarding command provided by the extension. The `registerRepo` function in [`src/onboarding/installer.ts`](https://github.com/tirth8205/code-review-graph/blob/main/src/onboarding/installer.ts) inserts the repository path into the database and triggers an initial indexing run, making it immediately searchable alongside your other registered repositories.

### Does the search index update automatically when files change?

Yes. The [`src/backend/watcher.ts`](https://github.com/tirth8205/code-review-graph/blob/main/src/backend/watcher.ts) module monitors all registered repositories for file system events. It incrementally updates the SQLite index when files are modified, added, or removed, ensuring cross-repo search results remain current without requiring manual refreshes.

### What happens if I have ten repositories registered? Will search be slow?

The extension optimizes for multi-repository workflows by creating a composite index on (`repo_id`, `content`). This allows the query engine to first filter by repository ID before scanning content, maintaining fast performance even when searching across numerous large codebases.

### Can I search using regular expressions or just simple text matching?

Based on the current implementation in [`src/features/search.ts`](https://github.com/tirth8205/code-review-graph/blob/main/src/features/search.ts), the search utilizes SQL `LIKE` patterns for content matching. While the architecture supports extending to full-text search indexes, the default behavior uses wildcard matching against the indexed content column.