npx skills add smithery/rysweet --skill code-visualizer
rysweet/amplihack · Archived
code-visualizer
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.
Installation
npx skills add rysweet/amplihack --skill code-visualizer
Stronger alternatives
This repository is archived — consider an actively maintained alternative.
Analyzes events through cybersecurity lens using threat modeling, attack surface analysis, defe…
1.3K installsAnalyzes events through legal lens using statutory interpretation, case law analysis, legal rea…
682 installsAnalyzes events through psychological lens using cognitive psychology, social psychology, devel…
440 installsConverts architecture descriptions, module specs, or workflow docs into Mermaid diagrams. Use w…
425 installsSimilar popular skills
Related neighbors and high-traction skills in the same topics — useful to compare before installing.
Analyze Azure resource groups and generate detailed Mermaid architecture diagrams showing the r…
566.5K installsAnalyze Azure resource groups and generate detailed Mermaid architecture diagrams showing the r…
8.9K installsVisualize Rust project dependencies as ASCII art. Triggers on: /deps-viz, dependency graph, sho…
2.5K installsTransform text content into professional Mermaid diagrams for presentations and documentation.
1.6K installsThis skill should be used when working with CSV files to create interactive data visualizations…
1.3K installsExpert in Three.js, 3D graphics, and interactive 3D visualizations
657 installsAlso in this package
Other skills from rysweet/amplihack · top by installs.
npx skills add rysweet/amplihack
More details
Agent compatibility
Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.
Also listed on
Alternate registries and mirrors of this skill.
Repository health
main
Skill metadata
Parsed from SKILL.md frontmatter.
Package contents
Files included with this skill beyond the listing page.
-
skill md
SKILL.md16,859 B -
docs
SUMMARY.md456 B
History
- First seen on skills.sh
- First recorded snapshot · 240 installs
SKILL.md
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
--combinedview 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)
@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:
def normalize(paths: Iterable[Path]) -> Graph: ...
The function:
- Reads each file with
encoding="utf-8", errors="ignore". - Skips files larger than ~5 MB.
- Wraps parsing in
try/exceptand skips files that fail to parse. - Returns a
Graphwhoselanguagefield 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.
from scripts.dispatcher import analyze
graphs: dict[str, Graph] = analyze(target_path)
# {"python": Graph(...), "typescript": Graph(...)}
The dispatcher:
- Walks
target_pathwithos.walk(..., followlinks=False). - Skips
IGNOREDIRS(.git,nodemodules,.venv,venv,pycache,
dist, build, target, .mypycache, .pytestcache, .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:
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
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
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
Check freshness in CI
python amplifier-bundle/skills/code-visualizer/scripts/visualizer.py src/ \
--output docs/diagrams --check-staleness
# exits 1 if any per-language diagram is older than its source set
Generate for a single language
Provide a path that only contains files of one language; the dispatcher will detect a single language and emit a single .mmd:
python visualizer.py src/auth/ # Python-only -> architecture-python.mmd
Auto-Detection Rules
- The dispatcher walks
<path>, skippingIGNORE_DIRSand symlinks. - Files are bucketed by extension into one of the supported languages.
- A language is "detected" if at least one file matches.
- Each detected language is analyzed independently.
- With
--combined, the renderer composes one mermaid diagram with one
subgraph per detected language. Cross-language edges are not inferred in the MVP.
Example Output
For a repo with:
src/api.pyimportingsrc/auth.pyweb/index.tsimportingweb/utils.ts
architecture-python.mmd:
flowchart TD
src_api_py["src/api.py"]
src_auth_py["src/auth.py"]
src_api_py --> src_auth_py
architecture-typescript.mmd:
flowchart TD
web_index_ts["web/index.ts"]
web_utils_ts["web/utils.ts"]
web_index_ts --> web_utils_ts
architecture-combined.mmd:
flowchart TD
subgraph python ["python"]
src_api_py["src/api.py"]
src_auth_py["src/auth.py"]
src_api_py --> src_auth_py
end
subgraph typescript ["typescript"]
web_index_ts["web/index.ts"]
web_utils_ts["web/utils.ts"]
web_index_ts --> web_utils_ts
end
Note: the renderer emits the
subgraph <id> ["<label>"]form (space
between id and bracketed label), which is the Mermaid-documented syntax
accepted across recent Mermaid versions.testmermaidrenderer.pypins
the exact emitted form.
Extending: Adding a New Language
The skill follows the brick philosophy: a new language is a new self-contained module. There is no base class to subclass.
- Create
scripts/<lang>_analyzer.pywith the entry point:
``python from collections.abc import Iterable from pathlib import Path from graph import Edge, Graph, Node # sibling import; works under python visualizer.py`
def normalize(paths: Iterable[Path]) -> Graph: nodes: list[Node] = [] edges: list[Edge] = [] for p in paths: # parse file, append nodes/edges ... return Graph(language="<lang>", nodes=tuple(nodes), edges=tuple(edges)) ```
- Register the language in
scripts/dispatcher.py:
``python LANGUAGES = { "python": {"exts": {".py"}, "module": "pythonanalyzer"}, "typescript": {"exts": {".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"}, "module": "tsanalyzer"}, "rust": {"exts": {".rs"}, "module": "rustanalyzer"}, "go": {"exts": {".go"}, "module": "goanalyzer"}, # add here: "<lang>": {"exts": {".ext"}, "module": "<lang>_analyzer"}, } ``
- Add
tests/test<lang>analyzer.pywithtmp_pathfixtures asserting
nodes and edges produced by representative source snippets.
- Update the Supported Languages table above.
That's it. The renderer, dispatcher routing, staleness detector, and CLI all work without further changes because they consume the language-blind Graph data contract.
Testing
Tests live under amplifier-bundle/skills/code-visualizer/tests/ and run via pytest. The skill registers its tests/ directory in the repo's pytest.ini testpaths so CI picks them up automatically.
Test files:
| File | Purpose |
|---|---|
testpythonanalyzer.py |
AST-driven import extraction; verifies edges for import/from. |
testtsanalyzer.py |
import/require/dynamic import(); type-only and relative paths. |
test_dispatcher.py |
Mixed-language fixture; verifies correct routing per extension. |
testmermaidrenderer.py |
Empty graphs, non-empty graphs, ID/label sanitization. |
test_staleness.py |
Mtime comparison across multiple language extensions. |
testsmokerepo.py |
Runs dispatcher against the repo root; asserts non-empty mermaid |
| for both Python and TypeScript/JavaScript. |
Run only the skill's tests:
pytest amplifier-bundle/skills/code-visualizer/tests -q
Security Considerations
- No code execution: Analyzers only parse source. No
exec/eval/
subprocess on analyzed files.
- Path validation:
<path>and--outputare resolved with
Path.resolve() and rejected if non-existent or non-directory.
- Filename validation:
--basenamemust match^[A-Za-z0-9._-]+$. - Symlink safety:
os.walk(..., followlinks=False)plusIGNORE_DIRS
prevents loops and escape.
- Bounded reads: Per-file size cap (~5 MB); UTF-8 decode with
errors="ignore".
- Bounded regex: Anchored, no nested quantifiers; protects against ReDoS.
- Mermaid sanitization: Node IDs strip non-
[A-Za-z0-9_]; labels with
embedded quotes are escaped.
- Stdlib-only: Zero third-party runtime dependencies; no supply-chain
surface.
- Output containment: Writes are constrained to the resolved
--output
directory; source content is never logged.
Limitations
- Static heuristics: Regex-based extraction for TS/JS/Rust/Go misses some
edge syntax (TS type-only imports across multiple lines, Rust nested use {a, b::c}, Go cgo blocks). Documented per analyzer in source.
- No call graphs: Edges are import/use only. Runtime/dynamic imports
beyond import("...")/import are not modeled.
- External imports: Rendered as ghost target nodes inline; not resolved to
real files.
- Combined view: Cross-language edges are out of MVP scope.
- Shell scripts: Not first-class;
.shfiles are ignored. - Compiler-grade accuracy: Not a goal. The skill optimizes for "useful
diagram in seconds" over "perfect AST."
Philosophy Alignment
| Principle | How v2.0 follows it |
|---|---|
| Ruthless Simplicity | Stdlib-only; regex over tree-sitter; max-mtime over semantic diff. |
| Zero-BS | Real parsers (ast for Python, regex for others). Limitations documented honestly. |
| Modular Design | Each analyzer is a brick with a single normalize() stud. No inheritance. |
| Brick Composition | Renderer/dispatcher/staleness are independent bricks reusing only the data contract. |
Migration from 1.x
The 1.x skill was Python-only. Forward-compatibility notes (verify against your actual 1.x integration before relying on them):
- Diagrams previously named
<basename>.mmdare now
<basename>-python.mmd. Update any references in README.md / ARCHITECTURE.md.
- Staleness reports now include a per-language breakdown. CI scripts that
parsed the old single-line output should be updated to handle multiple languages.
- Any direct Python helper used in 1.x is superseded by
dispatcher.analyze(path) returning a dict[language, Graph]. Callers that only want Python can use dispatcher.analyze(path)["python"].
Remember
The skill automates what developers forget across all four supported languages: keeping diagrams in sync with code. It's not a compiler; it's a fast, honest, multi-language snapshot.