Reference¶
Operational reference for muundo-core, the Python module, muundo-analyze
and muundo-server. For a first run, see
Getting Started; for what Muundo deliberately does not
do, see Design decisions.
Languages¶
Thirteen tree-sitter grammars, twelve languages — typescript and tsx are
separate grammars for the same language:
Those are the exact strings the languages option accepts. The authoritative
list is what your build reports:
Ada and C are not decoration. They are what avionics, rail and medical device code is written in, and they are usually the languages an analysis tool skips.
What a report carries¶
| Field | What it is |
|---|---|
entities |
Functions, methods, types — with file, line and qualified name |
call_edges |
Caller → callee, resolved where the callee is unambiguous |
metrics_by_entity |
Cyclomatic complexity, fan-out, size, per entity |
dependencies |
Module and package edges |
reachable_from_entry |
What is actually reachable — dead code shows up as absence |
fragility, hotspots |
Composite risk scores over the graph |
bridge_nodes |
The joints between subsystems — PyO3 classes and methods bridging Rust and Python |
file_hashes, provenance |
What was read, and by which analyzer version |
partial_analysis |
What could NOT be parsed — reported, never silently dropped |
partial_analysis matters more than it looks. Read it before you quote a count
from the rest.
Python¶
The parse runs once per analyzer and is cached for its lifetime; the options are fixed at construction, so a fresh analysis means a new analyzer.
CLI — muundo-analyze¶
The binary is muundo-analyze. The crate that provides it is muundo-cli.
Every subcommand writes one JSON object — {"ok": true, "data": …}, or an
error.
| Subcommand | What it does |
|---|---|
analyze |
Full analysis of a tree |
metrics |
Metrics for one named entity |
fragility |
Fragility score for a tree |
hotspots |
The riskiest entities, most first |
verify |
Re-read a tree and check it against a report's file hashes |
info |
Version, accepted language names, and host information |
Global options:
| Option | Meaning |
|---|---|
-v, -vv, -vvv |
Verbosity: info, debug, trace |
--input FILE |
Read the JSON request from a file instead of the flags |
Per subcommand:
| Subcommand | Options |
|---|---|
analyze |
--root (default .), --languages (comma-separated), --output json\|pretty, --ts-stateflow-strategy |
metrics |
--root (default .), --entity |
fragility |
--root (default .) |
hotspots |
--root (default .), --top-n (default 10) |
verify |
--report, --root (default .) |
--languages left out means every grammar is tried. Naming the languages you
care about is faster and makes partial_analysis mean something.
HTTP — muundo-server¶
Three routes:
| Route | Method | What it does |
|---|---|---|
/health |
GET | {"status": "ok", "version": …} — liveness, no analysis |
/info |
GET | Version and accepted language names |
/analyze |
POST | An analysis; the only route that does work |
The /analyze body:
{
"root": "/path/to/tree",
"languages": ["rust", "python"],
"include_call_graph": true,
"include_doc_coverage": true
}
languages defaults to empty (every grammar). Both include_* default to
true.
Limits, and why they exist¶
/analyze reads a whole tree and builds a graph in memory, so it is the one
route that can be made to hurt. Its guards are configurable and default to:
| Variable | Default | What it bounds |
|---|---|---|
MUUNDO_ANALYZE_MAX_CONCURRENT |
4 | Analyses running at once |
MUUNDO_ANALYZE_TIMEOUT_SECS |
60 | Wall clock for producing a report |
MUUNDO_ANALYZE_BODY_IDLE_TIMEOUT_SECS |
60 | Silence while streaming the response |
MUUNDO_ANALYZE_BODY_TIMEOUT_SECS |
3600 | Total time to stream the response |
MUUNDO_MAX_SERVER_BYTES |
4 GiB | Bytes of source read for one analysis |
MUUNDO_MAX_ENCODED_REPORT_BYTES |
4 GiB | Size of the encoded report |
MUUNDO_MAX_FILE_COUNT, MUUNDO_MAX_FILE_SIZE, MUUNDO_MAX_TOTAL_BYTES |
— | Per-tree ceilings |
MUUNDO_MAX_SPOOL_BYTES |
derived | Disk used to spool a large report |
The idle timeout is the primary guard; the total one is deliberately generous, because a legitimate report over a very large tree takes a long time to send.
Other settings:
| Variable | What it does |
|---|---|
MUUNDO_API_KEY |
Requires callers to present it. Unset means no key is configured — never a key whose value is the empty string |
MUUNDO_BIND_ALL |
Listen on all interfaces instead of loopback |
MUUNDO_CORS_ORIGINS |
Allowed browser origins |
MUUNDO_WORKSPACE_BASE |
Confines an analysed root to a directory |
MUUNDO_TS_STATEFLOW_STRATEGY |
Default TypeScript state-flow extraction |
MUUNDO_WORKSPACE_BASE is the one to set before exposing the server: without
it, root is any path the process can read.
Building¶
cargo build --release --workspace # muundo-analyze, muundo-server
cd python && maturin build --release
Layout¶
muundo/
├── core/ # muundo-core — the parser, graph, metrics
├── cli/ # muundo-cli — provides the `muundo-analyze` binary
├── server/ # muundo-server — the HTTP API
├── python/ # the PyO3 module
├── docs/ # everything published; the site is built from here
└── tests/
Licence¶
Apache-2.0.