You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(config): let one config name a whole multi-repo cluster (#156)
Cross-repo linking was reachable only from an MCP session: `append` is a
generate_snapshot tool parameter and both CLIs hardcoded false, so a CI job or a
developer not driving an agent saw only the single-repo subset — no service nodes,
no cross-repo edges, no coverage_report, no unused-routes.
A config may now name the cluster, and one --generate run indexes it, first
repository fresh and the rest appended:
repos:
- ../api
- ../web
- ../sdk
Entries resolve against the config file's own directory rather than the working
directory, so a checked-in cluster config means the same thing on a laptop and in
CI; `repo:` keeps its cwd-relative behaviour. Order is semantic and duplicates are
dropped — a repository listed twice would be indexed twice, the second pass
appending a duplicate of every fact the first contributed.
--explain takes a cluster config too. Its positional argument was previously always
a repository path, so `--explain cluster.yaml` analysed the YAML file as if it were
a repo. A repository is a directory and a config is a file, which separates them
without a flag.
Copy file name to clipboardExpand all lines: ARCHITECTURE.md
+7-1Lines changed: 7 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -664,6 +664,11 @@ The config file is **optional**. Every field has a built-in default (see `config
664
664
665
665
```yaml
666
666
repo: "."
667
+
# …or name a whole cluster instead, resolved relative to THIS file:
668
+
# repos:
669
+
# - ../api
670
+
# - ../web
671
+
# - ../sdk
667
672
ignore:
668
673
- "vendor/**"
669
674
- "node_modules/**"
@@ -711,7 +716,8 @@ The bundled [`mcp-arch.yaml`](mcp-arch.yaml) ships a much fuller `ignore` list (
711
716
712
717
| Field | Description | Default |
713
718
|-------|-------------|---------|
714
-
| `repo` | Repository root path | `"."` |
719
+
| `repo` | Repository root path, relative to the **working directory** | `"."` |
720
+
| `repos` | Ordered list of repository roots forming a multi-repo cluster; supersedes `repo`. One `--generate` run indexes them all (the first fresh, the rest appended), producing the service nodes and cross-repo edges a single-repo snapshot cannot have. Entries resolve relative to the **config file's own directory**, so a checked-in cluster config means the same thing wherever it is run from. Order is semantic; duplicates are dropped | *(unset)* |
Copy file name to clipboardExpand all lines: README.md
+23-2Lines changed: 23 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -433,6 +433,22 @@ enola --generate [config_path] # config_path is optional; defaults to mcp-arch
433
433
434
434
Artifacts are written to the configured `output.dir` (default `.enola/`). The config file is optional - see **[ARCHITECTURE.md → Configuration](ARCHITECTURE.md#configuration)** for the full field reference and defaults.
435
435
436
+
**Indexing a whole cluster in one command.** Cross-repo linking needs several repositories in one graph. Name them with `repos:` and a single run indexes them all - the first fresh, the rest appended - producing the service nodes, cross-repo edges, `coverage_report` and unused-route findings that a single-repo snapshot cannot have:
437
+
438
+
```yaml
439
+
# ci/cluster.yaml
440
+
repos:
441
+
- ../api
442
+
- ../web
443
+
- ../sdk
444
+
```
445
+
446
+
```bash
447
+
enola --generate ci/cluster.yaml
448
+
```
449
+
450
+
Entries resolve **relative to the config file**, not to your working directory, so a cluster config can be checked in and means the same thing on a laptop and in CI. (`repo:` is unchanged: a single repository, relative to the working directory.) Order matters - the first entry resets the graph and the rest are added to it.
451
+
436
452
---
437
453
438
454
## Explain a repository at a glance
@@ -453,8 +469,13 @@ enola --explain
453
469
454
470
# Analyze a specific repository path
455
471
enola --explain /path/to/repo
472
+
473
+
# Report over a whole cluster, from a config that names it with `repos:`
474
+
enola --explain ci/cluster.yaml
456
475
```
457
476
477
+
The argument is a **repository** when it is a directory and a **config file** when it is a file, so both forms work without a flag to tell them apart.
478
+
458
479
**The report covers nine sections:**
459
480
-**Overview** - path, analysis time, active languages, total fact count
@@ -589,8 +610,8 @@ Run `enola --help` for the full text. With no flags, enola starts the MCP server
589
610
590
611
| Flag | What it does |
591
612
|------|--------------|
592
-
|`--generate [config_path]`| Generate a snapshot and exit - no MCP server. Artifacts go to `output.dir` (default `.enola/`). |
593
-
|`--explain [repo_path]`| Print the statistics report above and exit. Read-only: nothing is written to `.enola/`. |
613
+
|`--generate [config_path]`| Generate a snapshot and exit - no MCP server. Artifacts go to `output.dir` (default `.enola/`). With `repos:` in the config, indexes the whole cluster in one run. |
614
+
|`--explain [repo_path\|config_path]`| Print the statistics report above and exit. Read-only: nothing is written to `.enola/`. A directory is a repository; a file is a config, so a `repos:` config reports over the whole cluster. |
594
615
|`--list`| List the MCP tools this build serves, with one-line summaries. |
595
616
|`--status`| List every enola server running right now - PID, repos, uptime, calls, dashboard URL - plus per-tool call counts and an estimate of the reconstruction those calls saved, in time and tokens. |
596
617
|`--status --all`| The same usage, broken down per repository. |
0 commit comments