Fix skill origin metadata and macOS source-importer portability
diagrams-drawio
TypeScript tools for deterministic Diagram IR-to-Draw.io generation, loss-aware round trips, transactional editing, semantic analysis, synchronization, offline publishing, and visual verification.
Built with TypeScript using @maxgraph/core — 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
cd scripts
pnpm install
Build
cd scripts
task build # or: pnpm run build
# compiled output → scripts/dist/
Usage
cd scripts
task run -- --file="diagram.drawio" --action=<action> [--page <index>]
# or directly:
node dist/cli/commands.js --file diagram.drawio --action <action> [--page <index>]
# Build from semantic YAML/JSON Diagram IR:
node dist/cli/commands.js --action build --file architecture.yaml --output architecture.drawio
# Loss-aware import and transactional edit:
node dist/cli/commands.js --action import --file architecture.drawio --output architecture.yaml
node dist/cli/commands.js --action edit --file architecture.yaml --spec ../examples/edit-batch.yaml --output edited.drawio
Output is always YAML to stdout.
Actions
Authoring
build
Validates a versioned YAML Diagram IR and emits deterministic native Draw.io XML.
- v1 remains supported for single-page linear diagrams.
- v2 adds multiple pages, containers and semantic kinds, explicit geometry, edge waypoints, provenance/properties/extensions, and typed layout options.
linear,layered,tree,grid, andmanuallayouts are supported. Layered/tree layouts use deterministic dependency-aware placement.- Generated connectors receive deterministic obstacle-aware orthogonal waypoints when a clear route is available.
- Duplicate/reserved IDs, invalid dimensions, unknown parents, and unknown edge endpoints fail before output is written.
See examples/platform-v2.yaml and schemas/diagram-ir-v2.schema.json.
Semantic lifecycle
| Action | Purpose | Key options |
|---|---|---|
import |
Loss-aware Draw.io to Diagram IR v2 | `--output model.yaml |
edit |
Atomic stable-ID edit batch | --spec, --output, --dry-run |
views |
Linked executive/system/deployment/dataflow/security views | --views, --output |
query |
Kind/property filtering and deterministic shortest paths | --kind, --property, --from, --to |
test |
Seven built-in architecture policies | --spec, --strict |
what-if |
Failure propagation with isolation boundaries | --fail |
sync |
Three-way synchronization preserving manual presentation | --base, --spec, --output, --prune, --dry-run |
story |
Self-contained accessible offline HTML | --output, optional --fail |
doctor |
Report optional backend availability without launching it | no --file required |
Commands fail closed on ambiguous identities, invalid view/policy names, input/output aliases, and malformed operations. See references/semantic-lifecycle.md for complete contracts and examples.
Native service libraries
The combined package also exposes tested TypeScript service APIs for capabilities that are not registered as CLI actions:
| Family | Implemented native services |
|---|---|
| Safe source importers | Python, JavaScript/TypeScript, Go, Rust, Terraform, Kubernetes, Docker Compose, SQL, OpenAPI, and CI job DAG subsets |
| Toolbox | Five themes, generic offline shape search, Mermaid and Markdown reverse transforms, semantic diff, strict relabeling, and accessible metric heatmaps |
| Specialized profiles | C4, sequence, tube map, executive compression, runbook HTML, timelapse, and dependency-ordered build-up |
These are conservative, bounded service contracts rather than claims of complete language parsers or peer-compatible command-line interfaces. See references/agents365-capability-coverage.md for the strict 42-tool comparison and remaining gaps.
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
quality
Runs objective visual-quality checks across every page: page clipping, likely text overflow, placeholder text, external image URLs, palette spread, page density, and edge density. Findings have explicit error or warning severity; the action never invents a minimum defect count.
Output: summary (pages, shapes, edges, errors, warnings), issues[]
page-connectors-validation
Detects two categories of layout defects on the first page:
- Connector-shape overlaps — a connector segment passes through a shape it is not connected to
- 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:
- empty_label — shape has no label (whitespace counts as empty)
- duplicate_label — two or more shapes share the same label
- 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:
- isolated_shape — shape with no edges connected to it
- 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)- Loss-aware semantic import preserves unknown wrapper/page/model XML in explicit
$drawioenvelopes for deterministic round trips