Understand Codebase
Turn an unfamiliar codebase into a navigable map. A bundled script
(scripts/codemap.py, stdlib only, no new dependencies) does exhaustive extraction
and emits raw Mermaid; you then prune it to the legible core and explain it in prose.
Output is a Markdown code map saved under ./codemap/.
Three languages: Python via ast, C/C++/HIP via a source scan that needs no compiler,
and CMake for the build graph. A mixed repo is normal — --lang auto maps everything it
finds, which is how the Python/C++ boundary becomes visible.
Quick start
- Resolve the target source root. Default to the repo's
src/; ask only if ambiguous.
- Run the overview first to get the lay of the land:
python3 ~/.cursor/skills/understand-codebase/scripts/codemap.py --root <src> --mode overview
- Run class structure:
--mode classes (inheritance trees) or --mode classes --focus <Class>.
- For call graphs:
--mode callgraph --focus <Class|func|module> --depth <N>.
- For a CMake project:
--mode targets (add --lang cmake when the root also holds source).
- Curate the raw output into focused diagrams + prose, then save under
./codemap/.
Add --lang {python,cpp,cmake} to restrict a mixed root to one language. The default
auto detects every language present and reports each on its own info: line.
On a Slurm host, route the python3 invocations through srun --jobid=$JOBID per the
slurm skill.
Modes
| Mode |
Emits |
Use for |
overview |
graph TD of packages → modules + cross-package edges (Python imports, C++ local includes); add_subdirectory tree for CMake |
whole-codebase map, "how is this organized" |
classes |
inheritance graph TD (no focus) or classDiagram (with --focus) |
base/subclass trees, one class's methods+attrs |
callgraph |
flowchart TD of caller → callee, BFS from --focus |
"what does X call", tracing a flow |
targets |
flowchart TD of CMake target → linked target |
build layout, "what links against what" |
Key flags: --lang {auto,python,cpp,cmake}, --focus <dotted.name | Class | func | module | target>,
--depth N (call BFS, default 2), --format {mermaid,json}, --max-nodes N
(renderability cap, default 200). See REFERENCE.md for the full flag list
and per-language resolution caveats.
Curation rule (the agent's job)
The script is exhaustive and blunt; raw whole-codebase graphs are too dense to read.
Always curate before saving:
- Start from overview, then drill down with
--focus per subsystem.
- Prune to the spine: collapse leaf/utility nodes, keep the structural backbone.
- Group nodes by subsystem; rename cryptic ids to readable labels where helpful.
- Explain every diagram in surrounding prose — never drop an unexplained diagram.
- State the resolution caveat for the language you mapped. Call edges are best-effort
static analysis everywhere; the script reports unresolved counts per language on
stderr, so cite the number rather than implying the graph is complete.
- Python: dynamic dispatch and
importlib indirection are missed.
- C++: no preprocessor evaluation, macro-generated declarations are invisible, and
virtual dispatch resolves to the static name.
- CMake:
file(GLOB) sources appear as a pattern, and a target name built from an
unresolvable variable keeps its literal ${...} text.
- On a mixed repo, say which languages you mapped and which you left out. A C++ map of a
repo that is half Python is a partial map, and the reader needs to know that.
Output rules
- Ensure
./codemap/ exists at the repo root; create it if missing.
- Save as
./codemap/<name>.md (kebab-case, e.g. rocprofiler-compute.md).
- If the filename exists, auto-suffix
-v2, -v3, … rather than overwriting.
- Echo the saved path in the final response.
Document skeleton: Overview (what was mapped, which languages, caveats) → Package
map (overview diagram + prose) → Build layout (CMake targets diagram, when the
project has one) → Class structure (inheritance trees + key class diagrams) → Key
call graphs (one per important flow) → Notes / limitations.
Pre-save self-check
Out of scope
- Forward-looking architecture you intend to build →
write-design.
- Executable planning from the code map →
plan-feature for planning only,
build-feature for full delivery, implement-feature for one exact approved plan or a
released plan_ready state. Bare implementation without an approved plan or state:
stop and offer plan-feature or build-feature, and start neither automatically.
- Languages other than Python, C/C++/HIP, and CMake. Rust, Go, and CUDA-only
.cu files
outside a C++ tree have no extractor here.
- Configure-time build state: generator expressions,
file(GLOB) expansion, and
toolchain-conditional targets are reported as-written, not evaluated.
- Semantic C++ questions a scan cannot answer — overload resolution, template
instantiation, and which virtual override actually runs.
Additional resources
- REFERENCE.md — script flags, resolution behavior, Mermaid cheat-sheet, pruning heuristics.
- EXAMPLES.md — worked overview and drill-down invocations.
- writing style — normative prose rules and the pre-save self-check for
every human-read artifact this skill produces.
1---2name: understand-codebase3description: Maps a Python, C/C++/HIP, or CMake codebase into curated Mermaid diagrams saved as a code map under `./codemap/`. Use when a user wants to understand a codebase, map the code, see the call graph, draw a class diagram, show the build graph or CMake targets, or onboard onto an unfamiliar repo.4---56# Understand Codebase78Turn an unfamiliar codebase into a navigable map. A bundled script9(`scripts/codemap.py`, stdlib only, no new dependencies) does exhaustive extraction10and emits raw Mermaid; you then prune it to the legible core and explain it in prose.11Output is a Markdown code map saved under `./codemap/`.1213Three languages: Python via `ast`, C/C++/HIP via a source scan that needs no compiler,14and CMake for the build graph. A mixed repo is normal — `--lang auto` maps everything it15finds, which is how the Python/C++ boundary becomes visible.1617## Quick start18191. Resolve the target source root. Default to the repo's `src/`; ask only if ambiguous.202. Run the overview first to get the lay of the land:21 `python3 ~/.cursor/skills/understand-codebase/scripts/codemap.py --root <src> --mode overview`223. Run class structure: `--mode classes` (inheritance trees) or `--mode classes --focus <Class>`.234. For call graphs: `--mode callgraph --focus <Class|func|module> --depth <N>`.245. For a CMake project: `--mode targets` (add `--lang cmake` when the root also holds source).256. Curate the raw output into focused diagrams + prose, then save under `./codemap/`.2627Add `--lang {python,cpp,cmake}` to restrict a mixed root to one language. The default28`auto` detects every language present and reports each on its own `info:` line.2930On a Slurm host, route the `python3` invocations through `srun --jobid=$JOBID` per the31`slurm` skill.3233## Modes3435| Mode | Emits | Use for |36|---|---|---|37| `overview` | `graph TD` of packages → modules + cross-package edges (Python imports, C++ local includes); `add_subdirectory` tree for CMake | whole-codebase map, "how is this organized" |38| `classes` | inheritance `graph TD` (no focus) or `classDiagram` (with `--focus`) | base/subclass trees, one class's methods+attrs |39| `callgraph` | `flowchart TD` of caller → callee, BFS from `--focus` | "what does X call", tracing a flow |40| `targets` | `flowchart TD` of CMake target → linked target | build layout, "what links against what" |4142Key flags: `--lang {auto,python,cpp,cmake}`, `--focus <dotted.name | Class | func | module | target>`,43`--depth N` (call BFS, default 2), `--format {mermaid,json}`, `--max-nodes N`44(renderability cap, default 200). See [REFERENCE.md](REFERENCE.md) for the full flag list45and per-language resolution caveats.4647## Curation rule (the agent's job)4849The script is exhaustive and blunt; raw whole-codebase graphs are too dense to read.50Always curate before saving:51521. Start from overview, then drill down with `--focus` per subsystem.532. Prune to the spine: collapse leaf/utility nodes, keep the structural backbone.543. Group nodes by subsystem; rename cryptic ids to readable labels where helpful.554. Explain every diagram in surrounding prose — never drop an unexplained diagram.565. State the resolution caveat for the language you mapped. Call edges are best-effort57 static analysis everywhere; the script reports unresolved counts per language on58 stderr, so cite the number rather than implying the graph is complete.59 - Python: dynamic dispatch and `importlib` indirection are missed.60 - C++: no preprocessor evaluation, macro-generated declarations are invisible, and61 virtual dispatch resolves to the static name.62 - CMake: `file(GLOB)` sources appear as a pattern, and a target name built from an63 unresolvable variable keeps its literal `${...}` text.646. On a mixed repo, say which languages you mapped and which you left out. A C++ map of a65 repo that is half Python is a partial map, and the reader needs to know that.6667## Output rules68691. Ensure `./codemap/` exists at the repo root; create it if missing.702. Save as `./codemap/<name>.md` (kebab-case, e.g. `rocprofiler-compute.md`).713. If the filename exists, auto-suffix `-v2`, `-v3`, … rather than overwriting.724. Echo the saved path in the final response.7374Document skeleton: **Overview** (what was mapped, which languages, caveats) → **Package75map** (overview diagram + prose) → **Build layout** (CMake `targets` diagram, when the76project has one) → **Class structure** (inheritance trees + key class diagrams) → **Key77call graphs** (one per important flow) → **Notes / limitations**.7879## Pre-save self-check8081- [ ] Every embedded Mermaid block parses (balanced `subgraph`/`end`, valid arrows).82- [ ] Every diagram is referenced by the surrounding prose.83- [ ] The best-effort/unresolved-edges caveat is stated for each language mapped.84- [ ] The languages covered — and any deliberately skipped — are named.85- [ ] Diagrams are curated, not raw dumps exceeding the node cap.8687## Out of scope8889- Forward-looking architecture you intend to build → `write-design`.90- Executable planning from the code map → `plan-feature` for planning only,91 `build-feature` for full delivery, `implement-feature` for one exact approved plan or a92 released `plan_ready` state. Bare implementation without an approved plan or state:93 stop and offer `plan-feature` or `build-feature`, and start neither automatically.94- Languages other than Python, C/C++/HIP, and CMake. Rust, Go, and CUDA-only `.cu` files95 outside a C++ tree have no extractor here.96- Configure-time build state: generator expressions, `file(GLOB)` expansion, and97 toolchain-conditional targets are reported as-written, not evaluated.98- Semantic C++ questions a scan cannot answer — overload resolution, template99 instantiation, and which virtual override actually runs.100101## Additional resources102103- [REFERENCE.md](REFERENCE.md) — script flags, resolution behavior, Mermaid cheat-sheet, pruning heuristics.104- [EXAMPLES.md](EXAMPLES.md) — worked overview and drill-down invocations.105- [writing style](../_shared/WRITING-STYLE.md) — normative prose rules and the pre-save self-check for106 every human-read artifact this skill produces.