How Watch Mode Keeps the Code Review Graph Updated in VS Code

The VS Code extension maintains a real-time code review graph by combining auto-update triggers on file saves with file-system watchers that monitor the SQLite database for incremental changes.

The tirth8205/code-review-graph repository implements a coordinated watch mode that synchronizes your workspace edits with the persisted code review visualization. By layering event listeners with strategic debouncing, the extension ensures the graph remains current without overwhelming system resources. This architecture creates a continuous feedback loop between source code changes and the UI representation.

Layer 1: Auto-Updating on File Saves

The primary synchronization mechanism reacts to file save operations within the workspace.

The setupAutoUpdate Listener

In code-review-graph-vscode/src/extension.ts, the extension registers a workspace.onDidSaveTextDocument listener that intercepts every file save event. Before triggering an update, the system validates the codeReviewGraph.autoUpdate setting to respect user preferences.

To prevent performance degradation during rapid editing, the implementation employs a 2-second debounce timer:

// Auto-update on file save (extension.ts)
const onSave = vscode.workspace.onDidSaveTextDocument(() => {
  const config = vscode.workspace.getConfiguration("codeReviewGraph");
  if (!config.get<boolean>("autoUpdate", true)) return;

  if (autoUpdateTimer) clearTimeout(autoUpdateTimer);
  autoUpdateTimer = setTimeout(async () => {
    const wsRoot = getWorkspaceRoot();
    if (!wsRoot || !sqliteReader) return;
    await cli.updateGraph(wsRoot);
  }, 2000);
});
context.subscriptions.push(onSave);

When the debounce timer expires, the extension invokes cli.updateGraph(), which executes the CLI's update operation to incrementally modify the graph.db file based on the latest source changes.

Layer 2: Monitoring Database Changes

While Layer 1 pushes updates to the database, Layer 2 ensures the UI immediately reflects those changes by watching the graph.db file itself.

The watchGraphDb FileSystemWatcher

Also defined in code-review-graph-vscode/src/extension.ts, the watchGraphDb function creates a FileSystemWatcher targeting **/.code-review-graph/graph.db. This watcher handles three distinct file events to maintain UI consistency:

  • onDidChange: Closes the current SqliteReader, reinitializes it with the updated database path, and triggers a tree view refresh via codeReviewGraph.codeGraph.refresh
  • onDidCreate: Instantiates a new SqliteReader when the database file appears for the first time
  • onDidDelete: Disposes the reader and nullifies internal references to prevent memory leaks
// Reload UI when graph.db changes (extension.ts)
function watchGraphDb(context: vscode.ExtensionContext): void {
  const watcher = vscode.workspace.createFileSystemWatcher(
    "**/.code-review-graph/graph.db"
  );

  watcher.onDidChange(() => {
    if (sqliteReader && dbPathRef.current) {
      sqliteReader.close();
      sqliteReader = new SqliteReader(dbPathRef.current);
      vscode.commands.executeCommand("codeReviewGraph.codeGraph.refresh");
    }
  });

  // Create / Delete handlers omitted for brevity
  context.subscriptions.push(watcher);
}

This mechanism creates a reactive pipeline: source changes → auto-update → CLI updates graph.db → file-system watcher → Extension reloads UI.

Layer 3: CLI-Level Debounced Watching

For command-line watch scenarios, the repository provides a dedicated GraphWatcher class that operates independently of the extension UI.

The GraphWatcher Implementation

Located in code-review-graph-vscode/src/backend/watcher.ts, the GraphWatcher class wraps VS Code's FileSystemWatcher with an additional 500ms debounce to protect against rapid successive file events:

// GraphWatcher – low-level debounced watcher (watcher.ts)
export class GraphWatcher implements vscode.Disposable {
  private readonly watcher: vscode.FileSystemWatcher;
  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 debouncedOnChanged = debounce(onChanged, 500);
    this.disposables.push(
      this.watcher.onDidChange(() => debouncedOnChanged()),
      this.watcher.onDidCreate(() => debouncedOnChanged()),
      this.watcher
    );
  }
  // …dispose implementation…
}

This lower-level watcher is primarily consumed by the CLI's watch command, providing efficient file monitoring for headless or terminal-based workflows.

Summary

  • Auto-update on save: The workspace.onDidSaveTextDocument listener in src/extension.ts triggers debounced CLI updates (2000ms) to balance responsiveness with system performance.
  • Database change detection: A dedicated FileSystemWatcher monitors graph.db modifications, automatically reloading the SqliteReader and refreshing the tree view when the underlying data changes.
  • Configurable debouncing: The extension uses a 2-second debounce for save operations, while the CLI GraphWatcher applies a 500ms debounce for direct file-system monitoring.
  • Resource cleanup: Both the extension and CLI watchers properly dispose of SqliteReader instances and file handles when databases are deleted or the extension deactivates.

Frequently Asked Questions

How do I disable auto-update in watch mode?

Set the codeReviewGraph.autoUpdate configuration to false in your VS Code settings. When disabled, the workspace.onDidSaveTextDocument listener returns early without scheduling the debounced update call, requiring manual graph refreshes via the command palette instead.

Why is there a delay after saving files before the graph updates?

The extension implements a 2-second debounce in the setupAutoUpdate function to prevent redundant CLI executions during rapid editing. This timer resets with each subsequent save, ensuring the graph only updates once you have paused typing for two seconds.

What happens to the UI if the graph.db file is deleted?

The watchGraphDb function includes an onDidDelete handler that disposes the current SqliteReader instance and clears internal references. This prevents memory leaks and allows the extension to gracefully handle the missing database until it is regenerated by the next update cycle.

Where is the debounce logic implemented for CLI watching?

The CLI uses the GraphWatcher class defined in src/backend/watcher.ts, which wraps VS Code's FileSystemWatcher with a 500-millisecond debounce. This protects against rapid successive file events that could otherwise trigger redundant graph processing operations in terminal-based workflows.

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 →