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:
@@ -0,0 +1,175 @@
|
||||
# drawio-main — Maintenance Guide
|
||||
|
||||
This document is for **developers** maintaining or extending the `drawio-tools` CLI.
|
||||
For agent usage instructions, see [SKILL.md](./SKILL.md).
|
||||
|
||||
---
|
||||
|
||||
## Tech stack
|
||||
|
||||
| Layer | Library / Tool | Version |
|
||||
|---|---|---|
|
||||
| Language | TypeScript ESM (`NodeNext`) | — |
|
||||
| Package manager | pnpm | v11.9+ |
|
||||
| XML model | `@maxgraph/core` | v0.23 |
|
||||
| DOM polyfill | `jsdom` | — |
|
||||
| Deflate decode | `pako` | — |
|
||||
| YAML output | `js-yaml` | — |
|
||||
| Build | `tsc` | — |
|
||||
| Dev runner | `tsx` | — |
|
||||
|
||||
`pnpm-workspace.yaml` must include:
|
||||
|
||||
```yaml
|
||||
allowBuilds:
|
||||
esbuild: true
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Install to `.agents/skills`
|
||||
|
||||
Always remove the previous installation first, then do a fresh copy and install:
|
||||
|
||||
```bash
|
||||
# 1. Remove previous installation
|
||||
rm -rf .agents/skills/drawio-main
|
||||
|
||||
# 2. Copy the full skill directory (source of truth)
|
||||
cp -r CogArch-drawio-2-cogarch/.skills/drawio-main .agents/skills/drawio-main
|
||||
|
||||
# 3. Install dependencies in the new location
|
||||
cd .agents/skills/drawio-main && pnpm install
|
||||
```
|
||||
|
||||
Verify the CLI works after installation:
|
||||
|
||||
```bash
|
||||
node .agents/skills/drawio-main/dist/cli/commands.js -f <diagram.drawio> -a summary
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Run the CLI
|
||||
|
||||
Single entry point — always builds first, then runs:
|
||||
|
||||
```bash
|
||||
cd CogArch-drawio-2-cogarch/.skills/drawio-main
|
||||
pnpm run cli -f <diagram.drawio> -a <action>
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
pnpm run cli -f ../../000-input/01-marketplace-system-context.drawio -a page-recommendations
|
||||
```
|
||||
|
||||
> Note: pass arguments directly after `cli` — do **not** use `--` separator.
|
||||
|
||||
---
|
||||
|
||||
## Build (development only)
|
||||
|
||||
Build only (no run):
|
||||
|
||||
```bash
|
||||
cd CogArch-drawio-2-cogarch/.skills/drawio-main
|
||||
pnpm run build # tsc → dist/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Source structure
|
||||
|
||||
```
|
||||
src/
|
||||
├── cli/
|
||||
│ └── commands.ts # parseArgs dispatcher → dynamic action imports
|
||||
├── services/
|
||||
│ ├── drawio-parser/
|
||||
│ │ ├── parser.ts # parseAllPages() / parseDiagram() — Shape, Edge, ParsedPage
|
||||
│ │ └── page-summary.ts # buildPageSummary() — shared per-page serialisation helper
|
||||
│ └── hierarchy-builder/
|
||||
│ └── hierarchy-builder.ts # buildHierarchy() — shared BFS depth map + containment tree
|
||||
└── actions/
|
||||
├── summary/ # all pages inventory
|
||||
├── page-summary/ # single page inventory (uses --page)
|
||||
├── page-hierarchy/ # containment tree from parentId
|
||||
├── page-connectors-summary/ # connector stats
|
||||
├── page-connectors-validation/ # overlap + crossing detection
|
||||
├── page-labels-validation/ # label quality checks
|
||||
├── page-shape-bbox-validation/ # bounding box overlap detection
|
||||
├── page-orphans/ # isolated shapes + dangling connectors
|
||||
├── page-recommendations/ # page size recommendation
|
||||
├── page-hierarchy-full/ # nesting levels with full shape geometry (x, y, width, height)
|
||||
└── validate/ # MANDATORY final gate — XML well-formedness + maxGraph compile + sanity check
|
||||
```
|
||||
|
||||
Each action exports `run(filePath: string, pageIndex?: number): Record<string, unknown>`.
|
||||
|
||||
### Key modules
|
||||
|
||||
**`src/services/drawio-parser/parser.ts`**
|
||||
- `parseAllPages(filePath)` — parses all `<diagram>` tabs in an mxfile, returns `ParsedPage[]`
|
||||
- `parseDiagram(filePath)` — backward-compat wrapper, returns first page only
|
||||
- Multi-page support: regex extracts all `<diagram>` blocks; each decoded separately (base64 + pako `inflateRaw`)
|
||||
- Uses `@maxgraph/core` `ModelXmlSerializer` + `GraphDataModel` with a `jsdom` DOM polyfill
|
||||
|
||||
**`src/services/drawio-parser/page-summary.ts`**
|
||||
- `buildPageSummary(page: ParsedPage): PageSummaryResult` — shared helper used by both `summary` and `page-summary` actions
|
||||
|
||||
**`src/services/hierarchy-builder/hierarchy-builder.ts`**
|
||||
- `buildHierarchy(page: ParsedPage): HierarchyResult` — shared BFS depth map + containment tree
|
||||
- Returns: `tree`, `allNodes`, `depthMap`, `childrenOf`, `maxDepth`, `totalLevels` (= maxDepth + 1), `depthCounts`
|
||||
- Used by `page-hierarchy` (tree output) and `page-hierarchy-full` (geometry per nesting level)
|
||||
|
||||
**`src/cli/commands.ts`**
|
||||
- `parseArgs` dispatcher → dynamic imports of action modules
|
||||
- Supports `--file` / `-f`, `--action` / `-a`, `--page` / `-p` (0-based, default 0), `--help` / `-h`
|
||||
- All output serialised to YAML on stdout; exit `0` success, `1` error
|
||||
|
||||
---
|
||||
|
||||
## Adding a new action
|
||||
|
||||
1. Create `src/actions/<name>/action.ts` exporting:
|
||||
```ts
|
||||
export async function run(filePath: string, pageIndex?: number): Promise<Record<string, unknown>>
|
||||
```
|
||||
2. Register it in `src/cli/commands.ts` under `ACTIONS`:
|
||||
```ts
|
||||
"my-action": () => import("../actions/my-action/action.js"),
|
||||
```
|
||||
3. Use `parseDiagram(filePath)` (first page) or `parseAllPages(filePath)` (all pages) from the parser
|
||||
4. Optionally import `buildPageSummary(page)` from `page-summary.ts` for standard shape/edge serialisation
|
||||
5. Return a plain object — the CLI serialises it to YAML automatically
|
||||
6. Run `pnpm run build` to compile and verify no TypeScript errors
|
||||
|
||||
### Naming convention
|
||||
|
||||
Actions follow `{object}-{action}` naming:
|
||||
|
||||
- `page-*` — operates on a single diagram page (uses `--page`, default 0)
|
||||
- `summary` — operates on all pages
|
||||
|
||||
---
|
||||
|
||||
## CLI action registration map
|
||||
|
||||
```typescript
|
||||
const ACTIONS: Record<string, () => Promise<ActionModule>> = {
|
||||
"summary": () => import("../actions/summary/action.js"),
|
||||
"page-summary": () => import("../actions/page-summary/action.js"),
|
||||
"page-hierarchy": () => import("../actions/page-hierarchy/action.js"),
|
||||
"page-connectors-summary": () => import("../actions/page-connectors-summary/action.js"),
|
||||
"page-connectors-validation": () => import("../actions/page-connectors-validation/action.js"),
|
||||
"page-labels-validation": () => import("../actions/page-labels-validation/action.js"),
|
||||
"page-shape-bbox-validation": () => import("../actions/page-shape-bbox-validation/action.js"),
|
||||
"page-orphans": () => import("../actions/page-orphans/action.js"),
|
||||
"page-recommendations": () => import("../actions/page-recommendations/action.js"),
|
||||
"page-hierarchy-full": () => import("../actions/page-hierarchy-full/action.js"),
|
||||
"page-negative-space-summary":() => import("../actions/page-negative-space-summary/action.js"),
|
||||
"validate": () => import("../actions/validate/action.js"),
|
||||
};
|
||||
```
|
||||
Reference in New Issue
Block a user