Draw.io diagram generation and analysis skill: mandatory layout and style rules, XML reference, negative-space companion diagrams, and the drawio-tools TypeScript CLI with 12 analysis/validation actions. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
140 lines
4.4 KiB
Markdown
140 lines
4.4 KiB
Markdown
# drawio-main
|
||
|
||
CLI tools for programmatic analysis and verification of `.drawio` files.
|
||
|
||
Built with TypeScript using [`@maxgraph/core`](https://github.com/maxGraph/maxGraph) — the official TypeScript successor to mxGraph (the library draw.io is built on) — for accurate XML parsing and absolute coordinate resolution.
|
||
|
||
## Stack
|
||
|
||
| Concern | Choice |
|
||
|---|---|
|
||
| Language | TypeScript (ESM, `NodeNext`) |
|
||
| Package manager | pnpm |
|
||
| XML / model parsing | `@maxgraph/core` v0.23 |
|
||
| Node.js DOM polyfill | `jsdom` |
|
||
| `<mxfile>` decoding | `pako` (base64 + deflate) |
|
||
| Output | YAML (via `js-yaml`) |
|
||
|
||
## Install
|
||
|
||
```bash
|
||
pnpm install
|
||
```
|
||
|
||
## Build
|
||
|
||
```bash
|
||
pnpm run build
|
||
# compiled output → dist/
|
||
```
|
||
|
||
## Usage
|
||
|
||
```bash
|
||
node dist/cli/commands.js --file diagram.drawio --action <action> [--page <index>]
|
||
|
||
# or via tsx (no build step)
|
||
pnpm dev --file diagram.drawio --action <action>
|
||
```
|
||
|
||
Output is always YAML to stdout.
|
||
|
||
## Actions
|
||
|
||
### Inventory
|
||
|
||
#### `summary`
|
||
|
||
Parses **all pages (tabs)** in the `.drawio` file and returns a full inventory of shapes and edges per page. Delegates per-page data to the same logic as `page-summary`.
|
||
|
||
**Output:** `pageCount`, `pages[]` (each page has the same structure as `page-summary`)
|
||
|
||
---
|
||
|
||
#### `page-summary`
|
||
|
||
Parses a **single page**. Use `--page <index>` (0-based, default `0`).
|
||
|
||
**Output:** `pageCount`, `pageIndex`, `pageName`, `page` (width/height), `summary` (shapeCount, edgeCount, contentRight, contentBottom), `shapes[]`, `edges[]`
|
||
|
||
---
|
||
|
||
#### `page-hierarchy`
|
||
|
||
Reads `parentId` from each shape and builds a **recursive containment tree**:
|
||
- Depth 0 — layers / top-level containers (direct children of the canvas)
|
||
- Depth 1 — subsystems / groups inside a layer
|
||
- Depth 2+ — leaf components and nested elements
|
||
|
||
**Output:** `summary` (totalShapes, maxDepth, depthCounts), `tree[]` (recursive: id, label, depth, childCount, children[])
|
||
|
||
---
|
||
|
||
#### `page-connectors-summary`
|
||
|
||
Returns a summary of all **connectors (edges)** on the page, classified by type and connectivity.
|
||
|
||
Connector types: `directed` (both endpoints connected), `partial` (one missing), `floating` (both missing)
|
||
|
||
**Output:** `summary` (total, directed, partial, floating, labelled, unlabelled, withWaypoints, straight), `connectors[]` (id, label, sourceId, sourceLabel, targetId, targetLabel, waypointCount, type)
|
||
|
||
---
|
||
|
||
### Validation
|
||
|
||
#### `page-connectors-validation`
|
||
|
||
Detects two categories of layout defects on the first page:
|
||
1. **Connector-shape overlaps** — a connector segment passes through a shape it is not connected to
|
||
2. **Connector crossings** — two connectors intersect at an interior point
|
||
|
||
Uses 2 px tolerance. **Output:** `summary` (connectorShapeOverlaps, connectorCrossings, totalIssues), `issues[]`
|
||
|
||
---
|
||
|
||
#### `page-labels-validation`
|
||
|
||
Validates shape labels and flags:
|
||
1. **empty_label** — shape has no label (whitespace counts as empty)
|
||
2. **duplicate_label** — two or more shapes share the same label
|
||
3. **long_label** — label exceeds 80 characters
|
||
|
||
Edges/connectors are excluded. **Output:** `config` (maxLabelLength), `summary` (emptyLabels, duplicateLabels, longLabels, totalIssues), `issues[]`
|
||
|
||
---
|
||
|
||
#### `page-shape-bbox-validation`
|
||
|
||
Detects shapes whose **bounding boxes overlap** each other. Parent-child containment is intentional and is **not** flagged. Uses 2 px tolerance.
|
||
|
||
**Output:** `summary` (totalShapes, overlappingPairs), `issues[]` (shapeAId, shapeALabel, shapeBId, shapeBLabel, overlapX, overlapY)
|
||
|
||
---
|
||
|
||
#### `page-orphans`
|
||
|
||
Finds disconnected elements:
|
||
1. **isolated_shape** — shape with no edges connected to it
|
||
2. **dangling_connector** — edge missing its source and/or target shape
|
||
|
||
**Output:** `summary` (isolatedShapes, danglingConnectors, totalIssues), `issues[]`
|
||
|
||
---
|
||
|
||
### Layout
|
||
|
||
#### `page-recommendations`
|
||
|
||
Computes the bounding box of all shapes and recommends the smallest standard landscape page size that fits with an 80 px margin (first page).
|
||
|
||
Standard sizes: A4 (1169×827), A3 (1654×1169), A2 (2339×1654), A1 (3307×2339). Falls back to custom rounded size.
|
||
|
||
**Output:** `currentPage` (width, height, orientation), `contentBbox`, `required` (min size needed), `recommendedPage` (name, width, height), `checks` (contentFitsCurrentPage, hasAdequateMargin, isLandscape)
|
||
|
||
---
|
||
|
||
## Supported file formats
|
||
|
||
- Bare `<mxGraphModel>` XML files
|
||
- `<mxfile><diagram>…</diagram></mxfile>` wrappers (draw.io desktop format, base64+deflate encoded, multi-page supported)
|