Claude
Skills
Sign in
Back

code-visualizer

Included with Lifetime
$97 forever

Auto-generates code flow diagrams from multi-language module analysis. Detects when architecture diagrams become stale (code changed, diagram didn't). Supports Python, TypeScript/JavaScript, Rust, and Go out of the box. Use when: creating new modules, reviewing PRs for architecture impact, or checking diagram freshness across polyglot repositories. Generates mermaid diagrams showing imports, dependencies, and module relationships.

Backend & APIsscripts

What this skill does


# Code Visualizer Skill

## Purpose

Automatically generate and maintain visual code flow diagrams across multiple
programming languages. The skill auto-detects which languages are present in a
target path, analyzes each one with a dedicated analyzer, and emits one
mermaid diagram per language plus an optional combined high-level view. It
also detects when committed diagrams are stale relative to the source they
describe.

## What's New in 2.0.0

- **Multi-language support**: Python, TypeScript/JavaScript, Rust, and Go.
- **Language dispatcher**: Detects languages by file extension and routes to
  per-language analyzers.
- **Language-blind renderer**: A single mermaid renderer consumes a normalized
  graph; the renderer never inspects language semantics.
- **One diagram per language** plus an optional `--combined` view that places
  each language in its own mermaid `subgraph`.
- **Generalized staleness**: Walks all source files matching detected
  languages' extensions and compares max-mtime against the diagram mtime.
- **Brick-style architecture**: Each language analyzer is a self-contained
  module that exposes a single `normalize()` function. No shared inheritance.

## Supported Languages

| Language              | Extensions                                   | Analyzer          | Parser | Notes                                                            |
| --------------------- | -------------------------------------------- | ----------------- | ------ | ---------------------------------------------------------------- |
| Python                | `.py`                                        | `python_analyzer` | `ast`  | Extracts `import` and `from … import …`.                         |
| TypeScript/JavaScript | `.ts`, `.tsx`, `.js`, `.jsx`, `.mjs`, `.cjs` | `ts_analyzer`     | regex  | Extracts `import … from`, `require(...)`, dynamic `import(...)`. |
| Rust                  | `.rs`                                        | `rust_analyzer`   | regex  | Extracts `use crate::…`, `use super::…`, `mod …`.                |
| Go                    | `.go`                                        | `go_analyzer`     | regex  | Extracts single and grouped `import` declarations.               |

Languages outside this table are skipped silently. See **Extending** below to
add new ones.

## Architecture

```
amplifier-bundle/skills/code-visualizer/
├── SKILL.md
├── README.md
└── scripts/
    ├── __init__.py
    ├── graph.py              # Normalized data contract (Node, Edge, Graph)
    ├── python_analyzer.py    # normalize(paths) -> Graph
    ├── ts_analyzer.py        # normalize(paths) -> Graph
    ├── rust_analyzer.py      # normalize(paths) -> Graph
    ├── go_analyzer.py        # normalize(paths) -> Graph
    ├── dispatcher.py         # detect languages, route, return dict[lang, Graph]
    ├── mermaid_renderer.py   # render(graph) / render_combined(graphs)
    ├── staleness.py          # is_stale(target, diagram, languages)
    └── visualizer.py         # CLI entry point
```

### Data Contract (`graph.py`)

```python
@dataclass(frozen=True)
class Node:
    id: str           # mermaid-safe identifier
    label: str        # human-readable label (e.g. "src/auth/oauth.py")
    language: str     # "python" | "typescript" | "rust" | "go"
    file_path: str    # absolute path on disk

@dataclass(frozen=True)
class Edge:
    src: str          # Node.id of source
    dst: str          # Node.id of destination
    kind: str         # "import" | "require" | "use" | "mod" | "dynamic_import"

@dataclass(frozen=True)
class Graph:
    language: str
    nodes: tuple[Node, ...]
    edges: tuple[Edge, ...]
```

Analyzers may **import** these dataclasses but must not inherit from any
shared class. The data contract is the only coupling.

### Per-Language Analyzers

Each analyzer is a self-contained brick exposing exactly one entry point:

```python
def normalize(paths: Iterable[Path]) -> Graph: ...
```

The function:

1. Reads each file with `encoding="utf-8", errors="ignore"`.
2. Skips files larger than ~5 MB.
3. Wraps parsing in `try/except` and skips files that fail to parse.
4. Returns a `Graph` whose `language` field matches the analyzer.

### Dispatcher

The dispatcher uses a registry that maps language name → extensions + module
name (string). It loads analyzers lazily via `importlib.import_module` so
adding a new language never requires touching the dispatcher's import
statements.

```python
from scripts.dispatcher import analyze

graphs: dict[str, Graph] = analyze(target_path)
# {"python": Graph(...), "typescript": Graph(...)}
```

The dispatcher:

- Walks `target_path` with `os.walk(..., followlinks=False)`.
- Skips `IGNORE_DIRS` (`.git`, `node_modules`, `.venv`, `venv`, `__pycache__`,
  `dist`, `build`, `target`, `.mypy_cache`, `.pytest_cache`, `.tox`).
- Buckets files by extension into language groups.
- Calls each language's `normalize()` with its file list.
- Returns a `dict[language_name, Graph]` for languages that produced any
  files.

### Mermaid Renderer

The renderer is language-blind:

```python
from scripts.mermaid_renderer import render, render_combined

per_language: str = render(graph)            # one diagram for one language
combined: str = render_combined(graphs)      # one diagram, one subgraph/lang
```

Node IDs are sanitized (`[^A-Za-z0-9_] -> _`) and labels with quotes are
escaped to prevent diagram-syntax injection.

### Staleness Detection

```python
from scripts.staleness import is_stale

stale = is_stale(
    target_path=Path("src/"),
    diagram_path=Path("docs/architecture-python.mmd"),
    languages=["python"],
)
```

Returns `True` if any source file with a matching language extension has an
mtime newer than `diagram_path`. Generalizes the previous Python-only
behavior.

## CLI

The skill ships a single executable: `scripts/visualizer.py`.

```
python visualizer.py <path> [--output DIR] [--basename NAME]
                            [--check-staleness] [--combined]
```

| Flag                | Default        | Purpose                                                               |
| ------------------- | -------------- | --------------------------------------------------------------------- |
| `<path>`            | _required_     | Directory to analyze. Must exist and be a directory.                  |
| `--output DIR`      | `./diagrams`   | Output directory for `.mmd` files.                                    |
| `--basename NAME`   | `architecture` | Filename stem. Validated against `^[A-Za-z0-9._-]+$`.                 |
| `--check-staleness` | off            | Print staleness report for existing diagrams; exit non-zero if stale. |
| `--combined`        | off            | Also write `<basename>-combined.mmd` containing all languages.        |

### Output Files

| File                                          | Contents                                               |
| --------------------------------------------- | ------------------------------------------------------ |
| `<basename>-python.mmd`                       | Mermaid diagram for Python modules and their imports.  |
| `<basename>-typescript.mmd`                   | Mermaid diagram for TS/JS files and their imports.     |
| `<basename>-rust.mmd`                         | Mermaid diagram for Rust modules and `use` edges.      |
| `<basename>-go.mmd`                           | Mermaid diagram for Go packages and `import` edges.    |
| `<basename>-combined.mmd` (with `--combined`) | One diagram with one `subgraph` per detected language. |

Files are only written for languages that were actually detected.

## Quick Start

### Generate diagrams for a polyglot repo

```bash
python amplifier-bundle/skills/code-visualizer/scripts/visualizer.py . \
    --output docs/diagrams --combined
```

Output (for this repo, which contains Python and JS):

```
docs/diagrams/architecture-python.mmd
docs/diagrams/architecture-typescript.mmd
docs/diagrams/architecture-combined.mmd
```

### C

Related in Backend & APIs