# 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` | | `` 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 [--page ] # or via tsx (no build step) pnpm dev --file diagram.drawio --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 ` (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 `` XML files - `…` wrappers (draw.io desktop format, base64+deflate encoded, multi-page supported)