|
| 1 | +--- |
| 2 | +name: architecture-diagram |
| 3 | +description: > |
| 4 | + Generate professional C4 architecture diagrams of the Ansible Dev Tools |
| 5 | + ecosystem by cloning and introspecting actual repos. Produces PNG output |
| 6 | + for the AAP Miro board. Use when the user says 'architecture diagram', |
| 7 | + 'C4 diagram', 'generate diagram', 'update architecture', or references |
| 8 | + AAP-77196. |
| 9 | +argument-hint: "[level=context|container|component|all]" |
| 10 | +user-invocable: true |
| 11 | +type: workflow |
| 12 | +mandatory: false |
| 13 | +triggers: |
| 14 | + - "architecture diagram" |
| 15 | + - "C4 diagram" |
| 16 | + - "generate diagram" |
| 17 | + - "update architecture" |
| 18 | + - "AAP-77196" |
| 19 | +metadata: |
| 20 | + author: Ansible DevTools Team |
| 21 | + version: 1.0.0 |
| 22 | +--- |
| 23 | + |
| 24 | +# Architecture Diagram Generator |
| 25 | + |
| 26 | +Generate professional C4 architecture diagrams of the Ansible Dev Tools |
| 27 | +ecosystem. Diagrams are built from **actual repo introspection** — not |
| 28 | +documentation — to ensure accuracy. |
| 29 | + |
| 30 | +## Prerequisites |
| 31 | + |
| 32 | +Before running, ensure these are available: |
| 33 | + |
| 34 | +```bash |
| 35 | +python3 --version # >= 3.10 |
| 36 | +java -version # or: plantuml --version |
| 37 | +git --version |
| 38 | +pip show c4-diagrams # >= 0.5.2, install with: pip install c4-diagrams |
| 39 | +``` |
| 40 | + |
| 41 | +If `c4-diagrams` is not installed: |
| 42 | + |
| 43 | +```bash |
| 44 | +pip install c4-diagrams |
| 45 | +``` |
| 46 | + |
| 47 | +PlantUML rendering requires Java. If Java is not present: |
| 48 | + |
| 49 | +```bash |
| 50 | +# Fedora / RHEL |
| 51 | +sudo dnf install java-17-openjdk |
| 52 | +# macOS |
| 53 | +brew install plantuml |
| 54 | +``` |
| 55 | + |
| 56 | +## Workflow |
| 57 | + |
| 58 | +### Step 1: Clone and crawl repos |
| 59 | + |
| 60 | +Clone all ADT ecosystem repos fresh into `/tmp` and introspect their |
| 61 | +actual dependency files. This is the foundation — never skip it. |
| 62 | + |
| 63 | +```bash |
| 64 | +python3 scripts/crawl_repos.py --clone-dir /tmp/adt-c4-repos --output .architecture-diagrams/dependencies.json |
| 65 | +``` |
| 66 | + |
| 67 | +This clones 19 repos (shallow, default branch) and reads: |
| 68 | +- `pyproject.toml` for Python inter-project dependencies |
| 69 | +- `package.json` for TypeScript/Node dependencies |
| 70 | +- `Containerfile` / `Dockerfile` for container image builds |
| 71 | +- `.github/workflows/*.yml` for container publishing and reusable workflows |
| 72 | +- Source code (vscode-ansible) for Python CLI tool spawns, language server, MCP server |
| 73 | + |
| 74 | +Output: `.architecture-diagrams/dependencies.json` |
| 75 | + |
| 76 | +### Step 2: Review crawl results |
| 77 | + |
| 78 | +Read `.architecture-diagrams/dependencies.json` and validate: |
| 79 | + |
| 80 | +1. Are all expected inter-project dependencies captured? |
| 81 | +2. Were container builds discovered in GitHub Actions workflows? |
| 82 | +3. Did the vscode-ansible crawl find the language server and MCP server? |
| 83 | +4. Did the abbenay crawl discover all sub-packages? |
| 84 | +5. Did the APME crawl find the Abbenay dependency? |
| 85 | + |
| 86 | +If the crawler missed a known relationship, the agent should note it for |
| 87 | +manual addition to the generated diagram code before rendering. |
| 88 | + |
| 89 | +### Step 3: Generate diagram code |
| 90 | + |
| 91 | +```bash |
| 92 | +python3 scripts/generate_diagram.py --input .architecture-diagrams/dependencies.json --output-dir .architecture-diagrams --level all |
| 93 | +``` |
| 94 | + |
| 95 | +Levels: |
| 96 | +- `context` — L1 System Context (personas, systems, external deps) |
| 97 | +- `container` — L2 Container (individual projects with dependency arrows) |
| 98 | +- `component` — L3 Component (per-repo deep dive) |
| 99 | +- `all` — generate all levels |
| 100 | + |
| 101 | +For a single repo's component diagram: |
| 102 | + |
| 103 | +```bash |
| 104 | +python3 scripts/generate_diagram.py --level component --component-repo ansible/vscode-ansible |
| 105 | +``` |
| 106 | + |
| 107 | +### Step 4: Review and refine diagram code |
| 108 | + |
| 109 | +Before rendering, the agent SHOULD review the generated `.py` files in |
| 110 | +`.architecture-diagrams/` and make refinements: |
| 111 | + |
| 112 | +- Adjust layout by changing `Rel` to `RelDown`, `RelRight`, etc. |
| 113 | +- Add missing relationships the crawler could not infer |
| 114 | +- Improve labels and descriptions |
| 115 | +- Ensure the provenance footer is present |
| 116 | + |
| 117 | +### Step 5: Render to PNG |
| 118 | + |
| 119 | +```bash |
| 120 | +python3 scripts/render.py --input-dir .architecture-diagrams --renderer plantuml |
| 121 | +``` |
| 122 | + |
| 123 | +Output: PNG files in `.architecture-diagrams/` |
| 124 | + |
| 125 | +### Step 6: Present results |
| 126 | + |
| 127 | +Show the user the PNG file paths. The user can then paste them into the |
| 128 | +Miro board or include them in documentation. |
| 129 | + |
| 130 | +--- |
| 131 | + |
| 132 | +## Repos Crawled |
| 133 | + |
| 134 | +### ADT Primary Projects (10 repos) |
| 135 | + |
| 136 | +| Repo | Language | Notes | |
| 137 | +|------|----------|-------| |
| 138 | +| `ansible/ansible-dev-tools` | Python | Meta-package + container image builds | |
| 139 | +| `ansible/ansible-lint` | Python | Linter | |
| 140 | +| `ansible/ansible-compat` | Python | Shared compatibility library | |
| 141 | +| `ansible/ansible-navigator` | Python | TUI for execution environments | |
| 142 | +| `ansible/ansible-dev-environment` | Python | Virtual env manager (ade) | |
| 143 | +| `ansible/ansible-creator` | Python | Scaffolding tool | |
| 144 | +| `ansible/ansible-sign` | Python | Content signing | |
| 145 | +| `ansible/molecule` | Python | Functional test runner | |
| 146 | +| `ansible/vscode-ansible` | TypeScript | VS Code extension (see special handling below) | |
| 147 | +| `ansible/team-devtools` | Mixed | Meta-repo (shared CI, skills, config) | |
| 148 | + |
| 149 | +### ADT Experimental / Testing / Community (5 repos) |
| 150 | + |
| 151 | +| Repo | Notes | |
| 152 | +|------|-------| |
| 153 | +| `ansible/pytest-ansible` | Pytest plugin | |
| 154 | +| `ansible/tox-ansible` | Tox plugin | |
| 155 | +| `ansible/actions` | Shared GitHub Actions | |
| 156 | +| `ansible/ansible-content-actions` | Marketplace actions | |
| 157 | +| `ansible/mkdocs-ansible` | MkDocs theme | |
| 158 | + |
| 159 | +### AAP Downstream Container Repos (2 repos) |
| 160 | + |
| 161 | +| Repo | Notes | |
| 162 | +|------|-------| |
| 163 | +| `ansible-automation-platform/ansible-devtools-container` | Downstream devtools container — packages ADT web server | |
| 164 | +| `ansible-automation-platform/ansible-devspaces-container` | Downstream devspaces container | |
| 165 | + |
| 166 | +### Abbenay — AI Daemon (1 repo) |
| 167 | + |
| 168 | +| Repo | Notes | |
| 169 | +|------|-------| |
| 170 | +| `redhat-developer/abbenay` | Unified AI daemon and library for LLM providers | |
| 171 | + |
| 172 | +Abbenay is a TypeScript monorepo producing: |
| 173 | +- `@abbenay/core` — LLM engine abstraction library |
| 174 | +- `@abbenay/daemon` — gRPC server, web dashboard, CLI, VS Code backchannel |
| 175 | +- VS Code extension (in `packages/vscode/`) |
| 176 | +- Python gRPC client (in `packages/python/`) |
| 177 | +- Containerized deployment (root `Containerfile`) |
| 178 | + |
| 179 | +**Key relationship:** APME depends on Abbenay for AI-assisted remediation. |
| 180 | + |
| 181 | +### AAP Portal — External Consumer (not crawled) |
| 182 | + |
| 183 | +The AAP Portal is a custom Backstage instance for AAP self-service. It is |
| 184 | +NOT a devtools-owned project and is not included in the repo manifest. It |
| 185 | +appears in diagrams as an external system (`SystemExt`/`ContainerExt`) with |
| 186 | +two key relationships: |
| 187 | +- Consumes the ADT web server packaged in the downstream devtools container |
| 188 | +- Consumes the ADT Python packages' REST API |
| 189 | + |
| 190 | +### APME — Adjacent Consumer (1 repo) |
| 191 | + |
| 192 | +| Repo | Notes | |
| 193 | +|------|-------| |
| 194 | +| `ansible/apme` | Multi-validator static analysis platform for Ansible content | |
| 195 | + |
| 196 | +APME is NOT owned by DevTools but is a significant consumer: |
| 197 | +- Depends on Abbenay for AI-assisted remediation (Tier 2 escalation) |
| 198 | +- Likely depends on ansible-lint (confirm from `pyproject.toml`) |
| 199 | +- Components: CLI, engine, validators, daemon, gateway, Galaxy Proxy, React frontend |
| 200 | +- Has own containers, Helm chart, bootc VM deployment |
| 201 | + |
| 202 | +--- |
| 203 | + |
| 204 | +## Special Crawling Instructions |
| 205 | + |
| 206 | +### vscode-ansible |
| 207 | + |
| 208 | +The VS Code extension is the most architecturally complex single repo. |
| 209 | +The crawler MUST discover: |
| 210 | + |
| 211 | +1. **Python CLI tool dependencies** — the extension spawns: `ansible-lint`, |
| 212 | + `ansible-navigator`, `ansible-creator`, `ansible-dev-environment`, and |
| 213 | + potentially others. The crawler searches source code for process spawn |
| 214 | + calls, command references, and configuration settings. |
| 215 | + |
| 216 | +2. **Language Server** — the extension contains an integrated Ansible Language |
| 217 | + Server (previously `ansible/ansible-language-server`, now merged). Find |
| 218 | + `LanguageClient`, `createConnection`, or `LanguageServer` references. |
| 219 | + |
| 220 | +3. **MCP Server** (`packages/ansible-mcp-server/`) — the extension ships |
| 221 | + a bundled MCP server (`@ansible/ansible-mcp-server`) that wraps ADT CLI |
| 222 | + tools for AI agent consumption. The crawler inspects its `src/tools/` |
| 223 | + directory for spawned Python CLI tools (e.g., `ansible-lint`, |
| 224 | + `ansible-navigator`, `ansible-creator`, `ade`, `ansible-builder`). |
| 225 | + |
| 226 | +4. **Package dependencies** — `package.json` deps that map to other ADT projects. |
| 227 | + |
| 228 | +### Abbenay |
| 229 | + |
| 230 | +Crawl `packages/` monorepo structure for sub-packages. Each directory |
| 231 | +under `packages/` with a `package.json` is a separate component. Also |
| 232 | +discover the root `Containerfile` and `proto/` gRPC definitions. |
| 233 | + |
| 234 | +Note: Abbenay does NOT consume the downstream devtools container. That |
| 235 | +relationship belongs to the AAP Portal (Backstage), which is a separate |
| 236 | +external system. |
| 237 | + |
| 238 | +### APME |
| 239 | + |
| 240 | +Crawl `pyproject.toml` for Python deps (especially abbenay, ansible-lint). |
| 241 | +Discover components from the project structure: |
| 242 | +- `src/apme_engine/` — CLI, engine, validators, daemon, remediation |
| 243 | +- `src/apme_gateway/` — FastAPI API gateway |
| 244 | +- `src/galaxy_proxy/` — Galaxy PEP 503 proxy |
| 245 | +- `frontend/` — React operator UI |
| 246 | +- `containers/` — container topology |
| 247 | +- `proto/` — gRPC service definitions |
| 248 | + |
| 249 | +--- |
| 250 | + |
| 251 | +## Diagram Provenance |
| 252 | + |
| 253 | +Every generated diagram includes a footer/subtitle: |
| 254 | + |
| 255 | +> Generated by architecture-diagram skill — |
| 256 | +> https://github.com/ansible/team-devtools/tree/main/.agents/skills/architecture-diagram |
| 257 | +
|
| 258 | +This tells anyone viewing the diagram on the Miro board where to find |
| 259 | +the source for updates or regeneration. |
| 260 | + |
| 261 | +--- |
| 262 | + |
| 263 | +## Output Directory |
| 264 | + |
| 265 | +All output goes to `.architecture-diagrams/` in the workspace root: |
| 266 | + |
| 267 | +```text |
| 268 | +.architecture-diagrams/ |
| 269 | +├── dependencies.json # Crawl results (intermediate) |
| 270 | +├── l1_system_context.py # L1 diagram source |
| 271 | +├── l1_system_context.png # L1 rendered |
| 272 | +├── l2_container.py # L2 diagram source |
| 273 | +├── l2_container.png # L2 rendered |
| 274 | +├── l3_component_*.py # L3 diagram sources (per-repo) |
| 275 | +└── l3_component_*.png # L3 rendered |
| 276 | +``` |
| 277 | + |
| 278 | +Add `.architecture-diagrams/` to `.gitignore` if not already present. |
| 279 | + |
| 280 | +## Scripts |
| 281 | + |
| 282 | +| File | Purpose | |
| 283 | +|------|---------| |
| 284 | +| `scripts/arch_models.py` | Data classes, repo manifest, package name mappings | |
| 285 | +| `scripts/crawl_repos.py` | Clone + introspect repos, output `dependencies.json` | |
| 286 | +| `scripts/generate_diagram.py` | Consume crawl data, produce C4 diagram `.py` files | |
| 287 | +| `scripts/render.py` | Render diagram `.py` files to PNG via `c4 export` | |
0 commit comments