Skip to content

FoothillSolutions/CodeAtlas

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CodeAtlas

An interactive visual code review tool that analyzes merge request diffs, builds dependency graphs, and renders an interactive HTML5 Canvas for navigating code changes.

Two analysis modes:

  • Roslyn mode — C# repositories with a .sln file: resolves class/interface dependencies, constructor injection, method calls, and inheritance across projects using the Roslyn compiler platform.
  • Lite mode — Any repository (Python, TypeScript, JavaScript, etc.): detects import-based dependencies from source files without requiring a compiler.

Output is a single self-contained HTML file you can open in any browser.

Quick Start

# 1. Build the canvas UI (one-time)
cd canvas-ui && npm install && npm run build && cd ..

# 2. Analyze a single MR
dotnet run -- --mr 647 --repo /path/to/your-service

# 3. Or batch-process all MRs where you're a reviewer
bash run-codeatlas.sh

For first-time setup, see SETUP.md.

Prerequisites

  • .NET 9 SDK
  • Node.js 18+ and npm
  • glab CLI authenticated (glab auth login)
  • For Roslyn mode: a C# repository with a .sln file
  • For Lite mode: any repository with Python/TypeScript/JavaScript source files

Building the Canvas UI

The canvas frontend must be built before running the tool:

cd canvas-ui
npm install
npm run build

This produces canvas-ui/dist/index.html — the .NET tool embeds graph data into this template.

Usage

Single MR

dotnet run -- --mr <branch-or-mr-id> --repo <path-to-repo> [--target <branch>] [--sln <solution>] [--json]
Flag Description Default
--mr MR ID (numeric) or branch name required
--repo Path to the repository required
--target Target branch for diff comparison main
--sln Explicit path to .sln file auto-detected
--json Output JSON to stdout instead of HTML off

Mode selection is automatic: if a .sln file is found (or provided via --sln), Roslyn mode is used. Otherwise, Lite mode runs.

Examples:

# By MR ID (Roslyn mode — .sln auto-detected)
dotnet run -- --mr 647 --repo /path/to/csharp-service

# By branch name
dotnet run -- --mr feature/my-branch --repo /path/to/csharp-service

# Specific target branch
dotnet run -- --mr 52476 --repo /path/to/repo --target release/2.0

# Explicit solution file (when multiple .sln exist)
dotnet run -- --mr 52476 --repo /path/to/repo --sln /path/to/repo/App.sln

# Lite mode (Python/TS/JS repo — no .sln)
dotnet run -- --mr 123 --repo /path/to/python-service

# JSON output for debugging
dotnet run -- --mr 647 --repo /path/to/your-service --json

Output is written to output-codeatlas/<mr-id>.html.

Batch Mode

From this directory (tools/CodeAtlas):

# Process all MRs where you're a reviewer
bash run-codeatlas.sh

# Specify a GitLab group (overrides config)
bash run-codeatlas.sh --group=myorg/mygroup

# Start the AI chat proxy alongside analysis
bash run-codeatlas.sh --with-chat
Flag Description
--with-chat Start codeatlas-chat-proxy.py on port 7823 before processing
--group=<group> GitLab group to query (overrides gitlab_group in config)

The batch script:

  • Queries glab mr list for MRs where you're assigned as reviewer
  • Maps repo names to local paths using repos_parent_dir from codeatlas-config.json
  • Skips MRs whose output HTML is newer than the MR's updated_at timestamp
  • Skips repos not cloned locally
  • Applies repo_overrides for custom .sln paths

Configuration

CodeAtlas Config (codeatlas-config.json)

Copy from codeatlas-config.example.json:

{
  "repos_parent_dir": "/path/to/parent/folder/containing/all/repos",
  "gitlab_group": "myorg/mygroup",
  "repo_overrides": {
    "some-monorepo": {
      "sln": "/path/to/monorepo/SubDir/Solution.sln"
    }
  }
}
Key Description
repos_parent_dir Parent directory containing all cloned repos as direct children
gitlab_group GitLab group for batch MR queries (can be overridden with --group=)
repo_overrides Per-repo settings — currently supports sln for explicit solution file paths

Per-Repo Layout Config (.codeatlas.json)

Place in any repo root to customize the canvas layout:

{
  "nodeWidth": 520,
  "rankDirection": "LR",
  "defaultZoom": 0.8
}
Key Description Default
nodeWidth Card width in pixels 520
rankDirection LR (left-to-right) or TB (top-to-bottom) TB
defaultZoom Initial zoom level 1.0

Canvas Features

Navigation

  • Pan — drag empty space
  • Zoom — mouse wheel (zooms toward cursor)
  • Fit All / Reset — toolbar buttons or 0 key

Code Cards

  • Each changed file renders as a card with diff-highlighted code (green = additions, red = deletions)
  • Border colors: blue = changed, green = new, gray = unchanged dependency
  • Click to select, double-click or Enter to expand into full code viewer
  • Expanded viewer has collapsible diff sections, Tab / Shift+Tab to navigate between files

Dependency Edges

  • Roslyn mode: arrows show interface implementations, constructor injection, method calls, inheritance
  • Lite mode: arrows show import/require relationships between files
  • Hover an edge for a tooltip with dependency details
  • Selecting a node dims unrelated nodes/edges to highlight the dependency chain

Overlays

Stackable visual layers toggled via toolbar or keyboard:

  • Risk Heatmap (h) — colors nodes by risk score:

    risk = (additions + deletions) × (fanOut + fanIn + 1) × (isNew ? 2 : 1)
    
    • Critical (≥ 90th percentile) — red
    • High (≥ 75th) — amber
    • Medium (≥ 50th) — blue tint
    • Low (< 50th) — unchanged
  • Critical Paths (i) — thickens borders based on impact radius (transitive dependency count via BFS)

Both overlays can be active simultaneously.

Level of Detail (Semantic Zoom)

  • Full — complete code card with diff preview
  • Glyph — compact card showing class name + diff stats
  • Dot — minimal dot representation at far zoom
  • Auto-switches based on zoom level, or cycle manually with s key
  • Font scales inversely with zoom for readability

Review Tracking

  • Mark files as Reviewed (r), Flagged (f), or Unreviewed (u)
  • Also supports Needs Attention status (cycle with click)
  • Progress bar shows review completion
  • State persisted per-branch in localStorage
  • Filter canvas by review status via toolbar

AI Chat Panel

  • Toggle with a key or toolbar button
  • Sends the current graph context (files, diffs, dependencies) to Claude via the local chat proxy
  • Requires codeatlas-chat-proxy.py running on port 7823 (auto-started with --with-chat)

Search

  • / or toolbar search to filter nodes by filename
  • Matching nodes highlighted, non-matching dimmed

Keyboard Shortcuts

Key Action
Tab / Shift+Tab Select next / previous file
Enter Expand selected node
Escape Close expanded view / search / help
+ / - Zoom in / out
0 Fit all nodes in view
r / f / u Mark reviewed / flagged / unreviewed
s Cycle LOD mode: auto → glyph → full
h Toggle risk heatmap
i Toggle critical paths
a Toggle AI chat panel
Arrow keys Pan canvas
? Show shortcuts overlay

Architecture

CodeAtlas/
├── Program.cs                  # 3-line entry point
├── CliRunner.cs                # CLI argument parsing and orchestration
├── Defaults.cs                 # Shared constants (timeouts, defaults)
├── GitCommandRunner.cs         # Shared git/CLI command execution
├── MrAnalyzer.cs               # Roslyn analysis: loads .sln, resolves dependencies
├── MrAnalyzerLite.cs           # Lite analysis: import-based edges (no compiler)
├── ImportEdgeBuilder.cs        # Import/require edge detection (Python, TS, JS)
├── DiffParser.cs               # Git diff → structured sections
├── GraphHelpers.cs             # Shared utilities (file type detection, naming)
├── MrGraph.cs                  # Data models (MrGraph, MrFileNode, MrEdge, etc.)
├── MrHtmlRenderer.cs           # Embeds JSON graph data into canvas-ui HTML
├── WorktreeHelper.cs           # Git worktree management for MR branch checkout
├── CodeAtlas.csproj            # .NET 9 project
├── run-codeatlas.sh            # Batch runner for all reviewer MRs
├── codeatlas-chat-proxy.py     # HTTP proxy (port 7823) forwarding to Claude CLI
├── codeatlas-config.json       # Local config (git-ignored)
├── codeatlas-config.example.json
├── output-codeatlas/           # Generated HTML files (git-ignored)
└── canvas-ui/                  # Preact + TypeScript frontend
    ├── src/
    │   ├── main.tsx            # Entry point, graph initialization, ErrorBoundary
    │   ├── types.ts            # Shared TypeScript types (MrGraph, MrFileNode, etc.)
    │   ├── theme/
    │   │   └── tokens.ts       # Design tokens (colors, spacing)
    │   ├── state/              # @preact/signals-based state management
    │   │   ├── graph-store.ts  # Graph data, node positions, edges
    │   │   ├── ui-store.ts     # Zoom, pan, selection, overlays, filters, LOD
    │   │   ├── review-store.ts # Review status tracking (localStorage-persisted)
    │   │   ├── analysis-store.ts # Risk score computation
    │   │   └── chat-store.ts   # Chat panel state
    │   ├── canvas/             # Canvas rendering pipeline
    │   │   ├── canvas-renderer.ts  # Main render loop (reactive via signals)
    │   │   ├── node-painter.ts     # File card rendering (full + compact)
    │   │   ├── arrow-painter.ts    # Dependency edge rendering
    │   │   ├── project-painter.ts  # Project group backgrounds
    │   │   ├── label-painter.ts    # Text label rendering utilities
    │   │   ├── lod-fade-manager.ts # Level-of-detail transition animations
    │   │   └── interaction.ts      # Mouse/touch input handling
    │   ├── layout/             # Graph layout algorithms
    │   │   ├── dagre-layout.ts # Dagre-based hierarchical layout
    │   │   ├── arch-layout.ts  # Architecture view layout
    │   │   └── arrow-router.ts # Edge routing between nodes
    │   ├── ui/                 # Preact UI components
    │   │   ├── App.tsx         # Root application component
    │   │   ├── Toolbar.tsx     # Top toolbar (zoom, filters, overlays)
    │   │   ├── CodeCard.tsx    # Expanded code viewer
    │   │   ├── CodeLine.tsx    # Single line renderer with syntax highlighting
    │   │   ├── CardOverlay.tsx # Card action overlay (review status)
    │   │   ├── EdgeTooltip.tsx # Dependency edge tooltip
    │   │   ├── ChatPanel.tsx   # AI chat panel
    │   │   ├── ErrorBoundary.tsx   # Error boundary wrapper
    │   │   └── KeyboardShortcuts.tsx # Keyboard handler + help overlay
    │   ├── syntax/
    │   │   └── highlighter.ts  # Syntax highlighting engine
    │   └── utils/
    │       ├── diff-utils.ts   # Diff parsing utilities
    │       └── chat-context.ts # Chat context builder
    ├── package.json
    ├── tsconfig.json
    └── vite.config.ts          # Vite config (single-file HTML output via inlining)

Data Flow

  1. Program.cs → delegates to CliRunner which parses CLI arguments
  2. CliRunner → creates a git worktree for the MR branch via WorktreeHelper
  3. MrAnalyzer (Roslyn) or MrAnalyzerLite (import-based) → diffs against target branch, builds MrGraph containing files and dependency edges
  4. MrHtmlRenderer → serializes MrGraph to JSON, embeds into canvas-ui/dist/index.html
  5. Browsermain.tsx reads embedded JSON, runs dagre layout, starts reactive canvas render loop

Analysis Modes

Roslyn mode (C# repos with .sln):

  • Loads the solution via Microsoft.CodeAnalysis
  • Walks syntax trees to find class declarations, interface implementations, constructor parameters, method calls
  • Resolves cross-project references through the Roslyn compilation model
  • Produces typed edges: implements, injects, calls, inherits

Lite mode (all other repos):

  • Scans changed files for import/require/from statements
  • Resolves relative paths to match other changed files
  • Supports Python, TypeScript, and JavaScript
  • Produces imports edges

Chat Proxy

The codeatlas-chat-proxy.py script runs a local HTTP server on port 7823 that bridges the canvas UI's chat panel to the Claude CLI:

# Start manually
python3 codeatlas-chat-proxy.py

# Or auto-start via batch mode
bash run-codeatlas.sh --with-chat

The proxy accepts POST requests with the graph context and user message, forwards to claude CLI, and streams the response back.

Development

Frontend Dev Server

cd canvas-ui
npm run dev

Starts Vite dev server with hot reload. Note: graph data comes from the embedded JSON, so you'll need a previously generated HTML file's data for testing.

Building

# Backend
dotnet build

# Frontend
cd canvas-ui && npm run build

The Vite build produces a single inlined HTML file (all JS/CSS bundled inline) so the output is fully self-contained.

About

Interactive diff visualization with dagre-layout graph — supports any language via MrAnalyzerLite, C# semantic analysis via Roslyn, self-contained HTML output

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors