repo2graph
Point it at a codebase and it draws the map: a queryable graph of who calls what, plus chunks ready for a RAG pipeline.
- 01Parsing
- 02Zero-dependency graph model
- 03Co-change edges
- 04Chunking for retrieval
- 05Built-in retriever
- 06Outputs, split two ways
- 07Published as a Marketplace Action
- 08Parallel parsing
Architecture Overview
Point it at a codebase and it draws the map. Every folder, file, function, class and import becomes a node, and every containment, call, import, inheritance and co-change becomes an edge. Plain text search finds the files that mention login; the graph finds the function that does the login and hands you its callers and callees with it. It also cuts the code into retrieval chunks that each carry that neighbourhood in their header, which is usually the thing a RAG pipeline was missing.
How it works
Core mechanics, failure recovery paths, and system design decisions.
Parsing
tree-sitter reads real code structure rather than guessing from words, so a repo it has never seen needs no configuration. Sixteen languages get full symbol and call extraction, and every other file still lands on the map in its folder, so nothing goes missing.
Zero-dependency graph model
CONTAINS, DEFINES, IMPORTS, CALLS, CALLS_EXTERNAL, INHERITS and CO_CHANGE, across repo, directory, file, symbol, module and external nodes. Built with pure-Python structures that drop external graph packages like networkx, writing directly to JSONL, GraphML, Cypher, and interactive HTML.
Co-change edges
Reading the last N commits links the files that keep being edited together, which is surprisingly good at exposing coupling nothing in the code makes obvious.
Chunking for retrieval
Roughly one chunk per function or class, each opening with its callers, its callees and its docstring, cut at about 4,000 characters with a few lines of overlap so nothing is lost at a seam.
Built-in retriever
Lexical scoring plus a one-hop walk across the graph, so the surrounding code comes along with every hit. No embedding model, no vector database and no API key needed to start.
Outputs, split two ways
human/ holds a single self-contained graph.html, an overview written to be read first, and a pre-laid-out GraphML for yEd or Gephi. agent/ holds the JSONL nodes, edges and chunks, an idempotent Cypher script for Neo4j, and a manifest that describes every other file — so a program needs nothing else to make sense of the folder.
Published as a Marketplace Action
Srinivasan-78/repo2graph@v1 is one step in any workflow: point it at the checkout or at another repo, and it uploads the graph as an artifact, writes the first 40 lines of the overview into the job summary, and exposes node, edge and chunk counts as outputs. commit-branch force-pushes the result to an orphan branch, so a pipeline can curl a current chunks.jsonl instead of rebuilding one.
Parallel parsing
Files are read one per processor core, capped at eight, so a large repository finishes in a minute or two. The number of workers changes only the wall clock: the graph that comes out is identical either way.
Engineering Highlights
- •Sixteen languages parsed with tree-sitter, zero configuration
- •Zero external graph dependencies: pure Python models eliminate networkx bloat
- •Chunks carry their graph neighbourhood, so retrieval lands on the right code
- •graph.html is one file: no server, no install, drag, zoom and search in a browser
- •Honest about approximation: name-matched calls carry a confidence score, and a missing edge never proves a missing call
- •Entrypoints are marked and ranked by reach, so the main paths through a project are findable
- •On the GitHub Marketplace at v1, so keeping a fresh graph beside your own code is three lines of YAML
- •It indexes itself: a workflow re-runs on every push to main and weekly, and publishes the graph to a branch