How Flow Detection in code-review-graph Traces Execution Paths from Entry Points

Flow detection in code-review-graph performs a bidirectional breadth-first search from changed files, traversing call graphs and dependency relationships up to a configurable depth to map complete execution paths and identify impacted code.

The code-review-graph VS Code extension analyzes pull request impact by treating modified files as graph entry points and walking the codebase dependency graph stored in SQLite. This article examines the SqliteReader.getImpactRadius() implementation to explain how the system traces execution paths through function calls, imports, inheritance, and test relationships to surface the complete blast radius of any code change.

From Changed Files to Seed Nodes

Flow detection begins when the system identifies modified files in a pull request or working directory. In code-review-graph-vscode/src/backend/sqlite.ts, the algorithm initializes by converting these file paths into seed nodes—the qualified names of every function, class, and symbol defined within the changed files.

The getImpactRadius() method collects these seeds into a Set<string> to ensure uniqueness and O(1) lookups during traversal【L44-L48】. These seeds represent the entry points from which the algorithm will explore both downstream dependencies (functions called by the changed code) and upstream dependencies (functions that call the changed code).

Bidirectional BFS Traversal in getImpactRadius

The core traversal engine resides in SqliteReader.getImpactRadius() within sqlite.ts. The method implements a breadth-first search (BFS) that expands simultaneously in both directions through the dependency graph.

For each node in the current frontier, the algorithm queries the SQLite database for:

  • Outgoing edges via getEdgesBySource() to find downstream dependencies
  • Incoming edges via getEdgesByTarget() to find upstream dependents

Unvisited nodes discovered through either direction are added to the next frontier level and accumulated in the impacted set【L58-L76】. This bidirectional approach ensures the detection captures complete execution paths regardless of whether the change affects callers or callees.

Relationship Types That Drive Flow Detection

The BFS follows seven distinct relationship types defined in sqlite.ts that represent different execution and dependency paths【L45-L52】:

  • CALLS – Function and method invocations
  • IMPORTS_FROM – Module import dependencies
  • INHERITS – Class inheritance hierarchies
  • IMPLEMENTS – Interface implementations
  • CONTAINS – Parent-child relationships (classes containing methods)
  • TESTED_BY – Test coverage mappings
  • DEPENDS_ON – General dependency declarations

By traversing all edge types simultaneously, the algorithm constructs a comprehensive view of how changes propagate through runtime execution, static imports, object-oriented hierarchies, and test suites.

Bounding the Search with Maximum Depth

To maintain performance in large codebases, the algorithm accepts a maxDepth parameter that defaults to 2 levels【L40-L42】. This bounds the BFS to immediate neighbors and their direct connections, preventing exponential explosion while still capturing the most likely impact radius. When maxDepth is reached, the frontier expansion stops regardless of whether unvisited nodes remain in the queue.

Resolving Nodes and Building the Impact Graph

After completing the traversal, the system distinguishes between direct changes and transitive impacts. The raw impacted set is resolved back to full node objects, creating two distinct collections:

  • changedNodes – The original seed nodes representing code actually modified
  • impactedNodes – Transitively reached nodes excluding the seeds themselves【L82-L94】

The method then constructs the edges array containing only the relationships that connect nodes within the impact radius【L99-L103】. This filtered edge set allows the UI to render precise dependency graphs without visual noise from unrelated parts of the codebase.

Visualizing Flow Paths in the VS Code Interface

The impact radius data flows through three integration points in the extension:

Blast Radius View (blastRadius.ts): Invokes reader.getImpactRadius() and displays changed versus impacted nodes in a dedicated tree view, allowing developers to see at a glance which files require careful review【L13-L66】.

Graph Webview (graphWebview.ts): Renders the subgraph defined by the impact radius, showing only the nodes and edges returned by the BFS traversal when a specific file is selected【L150-L165】.

Extension Commands (extension.ts): Registers the "Code Graph: Show Impact" command palette entry that triggers flow detection for manually selected files【L162-L176】.

Practical Implementation Example

To programmatically trace execution paths from entry points in your own extensions or scripts:

import { SqliteReader } from './backend/sqlite';

async function analyzeChangeImpact(dbPath: string, changedFiles: string[]) {
  const reader = await SqliteReader.create(dbPath);
  
  // Traverse 2 levels deep through all relationship types
  const impact = reader.getImpactRadius(changedFiles, /*maxDepth=*/ 2);
  
  // Entry points (modified code)
  console.log('Changed:', impact.changedNodes.map(n => n.qualifiedName));
  
  // Execution paths discovered via BFS
  console.log('Impacted:', impact.impactedNodes.map(n => n.qualifiedName));
  
  // Files that may need review
  console.log('Files to review:', impact.impactedFiles);
}

When rendering the results, the UI filters the complete graph to show only the impact radius subset:

// Inside graphWebview.ts - filtering nodes for visualization
if (this.impactRadius) {
  const nodes = [
    ...this.impactRadius.changedNodes, 
    ...this.impactRadius.impactedNodes
  ];
  const edges = this.impactRadius.edges;
  // Send to webview renderer...
}

Summary

  • Flow detection in code-review-graph uses changed files as seed nodes to initialize a bidirectional BFS through the codebase dependency graph.
  • The getImpactRadius() method in sqlite.ts traverses seven relationship types including calls, imports, inheritance, and test relationships.
  • A configurable depth limit (default 2) bounds the search to maintain performance while capturing immediate blast radius.
  • The algorithm produces distinct sets of changedNodes (entry points) and impactedNodes (transitive dependencies) plus the specific edges connecting them.
  • Results are consumed by the Blast Radius view and Graph webview to visualize execution paths affected by code modifications.

Frequently Asked Questions

What is the default depth for flow detection in code-review-graph?

The default maxDepth is 2 levels, meaning the algorithm traverses from seed nodes to their immediate neighbors and one additional level of connections. This default is defined in code-review-graph-vscode/src/backend/sqlite.ts【L40-L42】 and balances comprehensiveness with performance, though developers can increase this value for deeper analysis at the cost of slower queries.

Which edge types does code-review-graph traverse during flow detection?

The BFS follows seven edge types defined in the SqliteReader class: CALLS, IMPORTS_FROM, INHERITS, IMPLEMENTS, CONTAINS, TESTED_BY, and DEPENDS_ON【L45-L52】. These relationships capture runtime execution flows, static dependencies, object-oriented hierarchies, and test coverage mappings to provide a complete picture of code interdependencies.

How does code-review-graph distinguish between changed nodes and impacted nodes?

The system maintains two separate collections: changedNodes containing the original seed symbols defined in modified files, and impactedNodes containing all nodes reached via BFS traversal that are not in the original seed set【L82-L94】. This separation allows the UI to highlight the actual modifications differently from the transitive dependencies that might be affected by those changes.

Can flow detection in code-review-graph trace backwards dependencies?

Yes. The getImpactRadius() method performs bidirectional traversal by querying both outgoing edges (getEdgesBySource) and incoming edges (getEdgesByTarget) for each node in the frontier【L58-L76】. This means it discovers not only what your changed code calls (downstream), but also what code calls your changes (upstream), ensuring both callers and callees are included in the impact analysis.

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 →