Add drawio-main skill (renamed from drawio-main-v1)

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>
This commit is contained in:
2026-07-24 15:52:39 +03:00
co-authored by Claude Fable 5
parent 2b69cce629
commit 99f1fd07e3
33 changed files with 7044 additions and 1 deletions
+138 -1
View File
@@ -1,2 +1,139 @@
# drawio-main
Agent Skill for creating and validating draw.io diagrams via layout rules and a validation CLI.
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)