How Watch Mode in code-review-graph Detects and Processes File Changes

Watch mode in code-review-graph uses a three-layer VS Code extension architecture that combines a CLI entry point, a FileSystemWatcher on the SQLite database, and a debounced GraphWatcher to automatically refresh the graph view when source files change.

The code-review-graph VS Code extension provides real-time code analysis through an intelligent watch mode that monitors your project's graph database. This feature automatically detects when the underlying SQLite database changes and updates the UI without manual intervention. Understanding how this mechanism works requires examining the tight integration between the extension's command layer, file-system watchers, and debounced event processing.

The Three-Layer Architecture

Watch mode operates through three tightly-coupled layers that handle command registration, file-system detection, and debounced processing.

CLI Entry Point and Command Registration

The watch mode initiates through the codeReviewGraph.watchGraph command registered in src/extension.ts. When a user selects "Watch Graph" from the command palette, the extension forwards the request to CliWrapper.watchGraph(workspaceRoot) to start the watch daemon.

// Command registration in extension.ts (lines 547-560)
vscode.commands.registerCommand(
  "codeReviewGraph.watchGraph",
  async () => {
    const result = await cli.watchGraph(workspaceRoot);
    // handle result …
  }
);

This entry point serves as the bridge between user interaction and the backend monitoring system.

File-System Watcher for the SQLite Database

The watchGraphDb function in src/extension.ts (lines 94-136) creates a VS Code FileSystemWatcher that listens for create, change, and delete events on the generated SQLite graph file at **/.code-review-graph/graph.db.

When an event fires, the watcher performs three critical actions:

  • Closes the existing SqliteReader connection
  • Opens a new reader pointing to the updated database file (if it exists)
  • Triggers a refresh via codeReviewGraph.codeGraph.refresh to update the graph view and SCM decorations
// File-system watcher implementation in extension.ts
function watchGraphDb(context: vscode.ExtensionContext): void {
  const watcher = vscode.workspace.createFileSystemWatcher(
    "**/.code-review-graph/graph.db"
  );

  // Re-open the DB on change
  watcher.onDidChange(() => {
    if (sqliteReader && dbPathRef.current) {
      sqliteReader.close();
      sqliteReader = new SqliteReader(dbPathRef.current);
      vscode.commands.executeCommand("codeReviewGraph.codeGraph.refresh");
    }
  });

  // Initialise on first creation
  watcher.onDidCreate(async () => {
    const wsRoot = getWorkspaceRoot();
    if (wsRoot && !sqliteReader) {
      const dbPath = findGraphDb(wsRoot);
      if (dbPath) {
        dbPathRef.current = dbPath;
        sqliteReader = new SqliteReader(dbPath);
        vscode.commands.executeCommand("codeReviewGraph.codeGraph.refresh");
      }
    }
  });

  // Clean up on delete
  watcher.onDidDelete(() => {
    sqliteReader?.close();
    sqliteReader = undefined;
    dbPathRef.current = "";
  });

  context.subscriptions.push(watcher);
}

Debounced DB Watcher Implementation

The GraphWatcher class in src/backend/watcher.ts (lines 25-60) provides a specialized wrapper around the FileSystemWatcher that focuses specifically on the graph.db file. This class implements a 500ms debounce on the onChanged callback to prevent rapid successive refreshes when the graph database is being rebuilt in quick succession.

// Debounced watcher in backend/watcher.ts
export class GraphWatcher implements vscode.Disposable {
  constructor(dbPath: string, onChanged: () => void) {
    const dir = path.dirname(dbPath);
    const filename = path.basename(dbPath);
    this.watcher = vscode.workspace.createFileSystemWatcher(
      new vscode.RelativePattern(vscode.Uri.file(dir), filename)
    );
    const debounced = debounce(onChanged, 500);
    this.disposables.push(
      this.watcher.onDidChange(() => debounced()),
      this.watcher.onDidCreate(() => debounced()),
      this.watcher
    );
  }
  
  dispose() { 
    // Cleanup logic for listeners
    this.disposables.forEach(d => d.dispose());
  }
}

The dispose method ensures proper cleanup of all listeners when the extension deactivates or the user stops watch mode.

Step-by-Step Processing Flow

When you enable watch mode, the following sequence occurs:

  1. User activation – The command palette triggers codeReviewGraph.watchGraph, which calls cli.watchGraph(workspaceRoot).

  2. Watcher initialization – The CLI invokes watchGraphDb, creating a FileSystemWatcher on the pattern **/.code-review-graph/graph.db.

  3. Change detection – When the underlying analysis tool rewrites the SQLite database, the watcher receives a change event from the file system.

  4. Database refresh – The event handler closes the current SqliteReader, instantiates a new one pointing at the updated file, and issues the codeReviewGraph.codeGraph.refresh command.

  5. Debounced processing – The GraphWatcher ensures that bursts of file writes only trigger a single refresh by debouncing the callback for 500 milliseconds.

  6. UI synchronization – After the refresh completes, the graph webview, SCM decorations, and output channel update to reflect the newest graph state.

Source File Reference

The watch mode implementation spans these key files in the tirth8205/code-review-graph repository:

File Role
src/extension.ts Registers the watch command, creates the high-level FileSystemWatcher, and refreshes UI components.
src/backend/watcher.ts Implements GraphWatcher, the low-level debounced watcher for the graph.db file.
src/backend/cli.ts Provides the watchGraph method exposed to the command palette.
src/backend/sqlite.ts Manages the SqliteReader lifecycle used by the watchers.

Summary

Watch mode in code-review-graph detects and processes file changes through:

  • Command-layer integration via codeReviewGraph.watchGraph in extension.ts
  • File-system monitoring using VS Code's FileSystemWatcher on the SQLite database path
  • Debounced event handling through the GraphWatcher class to optimize refresh frequency
  • Automatic UI synchronization that closes and reopens database connections when changes occur

Frequently Asked Questions

What specific file does watch mode monitor?

Watch mode monitors the **/.code-review-graph/graph.db file pattern using VS Code's FileSystemWatcher. This SQLite database contains the generated code graph data, and the watcher specifically tracks create, change, and delete events on this file to determine when to refresh the analysis view.

How does watch mode handle rapid successive file changes?

The system implements 500ms debouncing through the GraphWatcher class in src/backend/watcher.ts. When the underlying analysis tool performs multiple rapid writes to the database, the debounced callback ensures only a single refresh event fires after the burst of activity completes, preventing UI flickering and unnecessary database reconnections.

What triggers the graph refresh command during watch mode?

The refresh command codeReviewGraph.codeGraph.refresh triggers in three scenarios: when the graph.db file changes, when it is first created, or when the file is deleted. The watchGraphDb function in extension.ts handles these events by closing the old SqliteReader, opening a new connection (if the file exists), and then executing the refresh command to rebuild the tree view.

How is the watcher cleaned up when closing VS Code?

The extension pushes the FileSystemWatcher instance to context.subscriptions in extension.ts, ensuring automatic cleanup when the extension deactivates. Additionally, the GraphWatcher class implements the vscode.Disposable interface with a dispose method that explicitly cleans up all registered listeners and watchers, preventing memory leaks.

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 →