--- name: drillflow-diagrams description: Generate hierarchical, drill-down diagrams as DrillFlow documents — a process or system modelled across several levels, where a node opens into its own sub-diagram. Use when the user asks for a nested/multi-level flowchart, wants to break a step down into sub-steps, or asks for a diagram they can open, edit and share as a link. Produces Mermaid for import or native JSON, and can publish a read-only link. --- # Generating DrillFlow diagrams DrillFlow is a diagram editor whose defining feature is **drill-down**: a node can own a whole sub-diagram, and the reader navigates *into* it as its own canvas, with breadcrumbs and a tree, to any depth. That is what this skill is for — if the diagram is flat, plain Mermaid in the reply is a better answer than this skill. Canonical format reference: JSON Schema: ## Choose a path **Mermaid (default).** Write a `flowchart`, put each level in a `subgraph`, and let DrillFlow's importer turn every subgraph into a real subflow. Ids, sizes and layout are handled for you. Use this unless you need something below. **Native JSON.** Required for colours, layers, rotation, waypoints, notes, images or freehand ink, and for publishing a link directly. Lossless. **If the user asked for a link, you must use JSON.** Publishing takes a DrillFlow document, and the Mermaid importer runs only in the user's browser — so Mermaid always ends with them pasting it in themselves. Answer with Mermaid when they want a diagram to look over; answer with JSON when they want something they can open or send. ## Path 1 — Mermaid ``` flowchart TD A[Take order] --> B{In stock?} B -->|yes| C[Ship] B -->|no| D[Backorder] subgraph A[Take order] A1[Check customer] --> A2[Validate items] end subgraph C[Ship] C1[Pick] --> C2[Pack] --> C3[Hand to carrier] end ``` Each `subgraph` becomes a node in the parent diagram that owns a sub-diagram. Nest them as deep as the subject deserves. If a subgraph id was already used as a plain node, that node is promoted into the container rather than duplicated — which is why `A[Take order]` above appears both as a step and as a subgraph. Tell the user to import it with **☰ menu → Import → Mermaid…** at (paste, or open a `.mmd` file). ### Constraints that actually bite - Node ids must match `[A-Za-z0-9_]+`. No hyphens, dots, spaces or accents — put those in the label. - Shapes: `[x]` `(x)` `([x])` `[[x]]` `[(x)]` `[/x/]` `[\x\]` `>x]` all become a rectangle; `((x))` a circle; `{x}` and `{{x}}` a diamond. There is no separate hexagon or stadium shape. - **You cannot produce a dashed edge.** A connector containing `.` is dotted; everything else, including `==>`, is solid. - `style`, `classDef`, `class` and `click` are ignored — **no colours or links survive the import**. If the user asked for colour, use Path 2. - An edge between two different subgraphs is lifted to the nearest diagram containing both, or dropped if there isn't one. Keep edges within a level and connect *containers* to each other, not their innards. - Not understood: `~~~`, edge ids (`e1@-->`), `A@{ shape: … }`, animations. ## Path 2 — native JSON Read the format reference first. The shape, in one breath: one JSON object with `id`, `title`, `rootDiagramId`, `createdAt`, `updatedAt` (epoch **milliseconds**) and a flat `diagrams` map; each diagram has `id`, `title`, `nodes`, `edges`; a node has `id`, `type`, `label` — and optionally `x`/`y`, which you can leave out entirely (see the rules below). Hierarchy is two references, both required: ```json { "id": "n1", "type": "rect", "label": "Take order", "x": 0, "y": 0, "childDiagramId": "d2" } ``` ```json { "id": "d2", "title": "Take order", "parentNodeId": "n1", "nodes": [], "edges": [] } ``` `examples/minimal.json` in this skill is a complete two-level document to copy. ### Rules to hold in mind while writing - `diagrams` is a **flat map**. Nesting is by reference; never nest the JSON. - Node ids are unique **within their diagram**, not globally. - **Both endpoints of an edge must be in the same diagram.** There are no cross-diagram edges. - Omit `anchorDeg` — edges float and re-attach themselves correctly. That is what you want. (`anchorRel` exists for one thing only: pointing at a spot *inside* an `image`. You will not need it either.) - `text` and `pin` nodes cannot own a subflow. - **Leave `x`/`y` out and DrillFlow arranges the diagram for you**, top-down, following your edges — the same layout an imported Mermaid flowchart gets. Prefer this: you know the structure, and the geometry is the one part you cannot check from where you are. All or nothing per diagram, though: position every node of a diagram or none of them, or it is rejected. Place things yourself only when the arrangement carries meaning — swimlanes, a deliberate reading order. Then `x`/`y` are top-left corners in px, y downward, with roughly 80 px between rows and 48 px between siblings. The layout orders each row to keep related branches together and routes long edges around the shapes they pass, but it minimises crossings rather than promising none — a densely cross-linked diagram may still show a few. - **Omit `w`/`h` and DrillFlow sizes each shape to its own label**, corners included. Prefer this for the same reason you leave `x`/`y` out: you cannot see your output, so a size you guessed is a size nobody checked. (Sizes only fall back to the flat defaults — rect 140×60, circle/diamond 100×100, text 140×40, image 200×150 — when there is no label to measure.) - If you *do* set them, remember a `diamond` needs **twice** the text block on both axes and a `circle` about **1.4×**: a question that fits a 140×60 rect hangs out of a 100×100 diamond at the top and bottom. Size decision nodes generously or leave them unsized. - Node `lineStyle` allows `double`/`none`; edge `lineStyle` does not. - **Never write `portOf` or `showPorts` yourself.** A node with `portOf` is a *boundary port*: the editor puts it inside a subflow to stand for one edge on the level above, so an arrow inside can dock to what crosses the boundary. If you are editing a document that already has them, copy them through untouched, including their size and position — and leave them out of any summary you write, they are the boundary showing through, not steps somebody drew. - Image `src` must be an inline `data:image/…` URI; a remote URL is rejected, as is any colour containing `url(...)`. ### Validate before you hand it over Check against the JSON Schema if you can run a validator. Otherwise walk this list — the editor refuses the whole document on the first failure. (It does complete a few omissions rather than refuse them — an edge's `id`, a node's `type` and `label`, the titles — and `POST /api/doc` returns them in a `warnings` array. Write them anyway: the ones below are not on that list.) 1. `diagrams[rootDiagramId]` exists. 2. Every `childDiagramId` is a key of `diagrams`, and that diagram's `parentNodeId` names the owning node. 3. Every edge's `from.nodeId` and `to.nodeId` exist **in that same diagram**. (An endpoint naming a node that is not there is dropped with the edge rather than refused — but a diagram missing the arrows you meant to draw is still a diagram you got wrong.) 4. Node ids are unique per diagram. Within one diagram, either every node has numeric `x` and `y`, or none does — never a mix. 5. `draw` nodes have at least one ink point; `image` nodes have a `data:image/…` src. 6. Every `layerId` names a layer of the same diagram, and an edge's layer is not earlier than its endpoints'. 7. `createdAt`/`updatedAt` are milliseconds. ## Publishing a link (optional) If the user wants a link rather than a file, publish the JSON document: ```bash curl -X POST https://api.drillflow.de/api/doc \ -H 'Content-Type: application/json' \ -d '{"data": { ...document... }}' ``` Returns `{"slug": "...", "url": "https://app.drillflow.de/view/"}` — a read-only canvas with working drill-down, no account or install needed. If you are running with tools rather than a shell, there is an MCP server for exactly this — `npx -y drillflow-mcp` (free, MIT), with `publish_diagram`, `publish_mermaid` and `read_diagram`. It carries the same rules as below. Say these out loud to the user rather than burying them: - **Anonymous links expire 90 days after creation.** Signing in at app.drillflow.de before sharing makes a link permanent and revocable. An account on a paid plan can mint an API token there and publish with `-H 'Authorization: Bearer dfp_…'` — the link then belongs to that account, listable and revocable, with no expiry. A token that has been revoked or has expired answers 401; it never falls back to an anonymous link. - The link is **public to anyone holding it**. Do not publish anything confidential without asking first. - Limits: 10 publishes per minute per IP, 2 MB per document (8 MB on a paid plan; paid plans are not on sale yet). Publishing is a network write of the user's content — ask before doing it, and prefer handing over the file when the user did not ask for a link. ## Files in this skill | File | What it is | |---|---| | `examples/minimal.json` | Smallest complete document: two levels, one subflow. | | `examples/order-handling.mmd` | Mermaid with nested subgraphs; the Path 1 example. | | `examples/order-handling.json` | The same diagram as native JSON. Three levels on the longest path: root → Ship → Pack. | ("Levels" counts canvases, so a root diagram with no subflows is one level.)