| name | bpmn |
| description | Read, explain, create, and edit BPMN 2.0 business-process diagrams (.bpmn XML). Use this whenever the user opens, reviews, summarizes, models, or modifies a process/workflow as BPMN - including swimlanes, pools, lanes, gateways, tasks, events, sequence flows, or boundary events. Trigger even when the user does not say "BPMN" explicitly but works with a .bpmn file, a process model/diagram, a workflow description they want turned into a diagram, or Camunda/Zeebe/Flowable/ bpmn.io models. Produces valid BPMN 2.0 XML with a clean, auto-generated layout. |
| compatibility | Requires Node.js >= 18 and npm. On first use, run `npm install` in the skill folder to fetch bpmn-moddle and bpmn-auto-layout. |
BPMN 2.0: read and edit process diagrams
What this skill does
Helps you understand existing .bpmn files in plain language and produce new or
edited ones that are valid and visually clean when opened in any modeler
(Camunda Modeler, bpmn.io, Cawemo, etc.).
The job splits cleanly:
- You do the semantic reasoning: what the process means, what to add or change.
- The bundled script does the deterministic mechanics: parsing, regenerating
layout, and validating. Lean on it instead of hand-rolling these each time.
The one idea that makes BPMN tractable: two layers
A .bpmn file holds two layers in one XML document:
- Semantics - the actual process:
bpmn:process with tasks, gateways,
events, and sequenceFlows connecting them. This is the meaning.
- Diagram interchange (DI) -
bpmndi:BPMNDiagram with x/y coordinates for
every shape and waypoints for every edge. This is only the picture.
Editing DI by hand is where BPMN work goes wrong: coordinates drift, shapes
overlap, edges cross. So we never hand-write DI. You edit semantics; the
layout command owns the DI. That is exactly what makes the diagram "clear" - a
tidy left-to-right layout, generated deterministically.
layout is non-destructive by default, which is the rule that keeps you out
of trouble: on a file that already has a diagram it preserves the existing
layout and only syncs it to your edit (prune shapes for deleted elements, place
shapes for new ones). On a file with no DI it generates a fresh layout. It only
throws the whole diagram away and rebuilds from scratch when you pass
--rebuild. So the habit is simple: after editing semantics, always run
layout; it never destroys a good diagram.
Setup (once per machine)
The script needs two npm packages. From the skill's own directory:
npm install --prefix "<SKILL_DIR>"
<SKILL_DIR> is the folder containing this SKILL.md. After that, the four
commands below are available. If a run fails with "Cannot find package", the
install step was skipped - run it and retry.
Reading / explaining a diagram
-
Get a structured outline (don't try to read raw DI coordinates):
node "<SKILL_DIR>/scripts/bpmn-tool.mjs" summarize path/to/file.bpmn
This prints pools/lanes, start/end events, activities (with their type),
gateways (with direction), boundary events (host + interrupting?), and every
sequence flow as source -> target [condition]. Add --json if you want to
process it programmatically.
-
Explain it the way a person would understand the process: the happy path
first, then decision points (what each gateway branches on), parallel work,
and exception/boundary handling. Name real business steps, not element IDs.
Match the user's language.
The summarize output is your source of truth for "what does this diagram do" -
read from it rather than eyeballing the XML, especially for anything non-trivial.
To locate a specific element before an edit, use find <file> <term> (matches
name or type). To compare two diagrams - As-Is vs To-Be, or to show exactly
what an edit changed - use diff <a> <b>; it reports elements added, removed,
renamed, or retyped and any sequence flows that were rewired.
When the user wants a review ("is this correct?", "find the bug", "why does
it hang?"), also run lint. It catches control-flow bugs that are valid XML and
pass validate but are wrong behavior - the kind that are easy to miss by eye:
node "<SKILL_DIR>/scripts/bpmn-tool.mjs" lint path/to/file.bpmn
It flags: a parallel (AND) join fed by an exclusive (XOR) split (deadlock); a
parallel split merged by an exclusive join (runs twice); an exclusive gateway
whose conditions can all be false with no default (stuck token);
unreachable nodes; dead ends (non-end node, no outgoing); a missing
start/end; an implicit split (non-gateway node with several outgoing flows);
misdirected events (start with an incoming flow, end with an outgoing one); a
boundary event on a non-activity; a node in no lane when the process uses
lanes; and a message flow that stays inside one pool. Read its finding,
confirm it against the model, then explain it in plain terms.
Creating or editing a diagram
Before writing XML for a new process, think like a business analyst and pin
down the structure - it's what separates a clear model from a box-and-arrow
mess. If any of these is unclear from the request, ask:
- Trigger - what starts the process (and is it a plain start, a message, a
timer?).
- Participants - who does what. Multiple actors usually means lanes (one
pool) or pools + message flows (separate processes).
- Happy path - the main sequence of activities when nothing goes wrong.
- Decision points - where the path forks, on what condition, and which
gateway fits (exclusive = either/or, parallel = all, inclusive = one-or-more).
- Exceptions / alternatives - timeouts, rejections, errors; often boundary
events or extra branches.
- End states - the distinct ways the process can finish.
If the user is documenting current vs future state, treat As-Is and
To-Be as separate diagrams/files and label them as such.
The reliable loop is then edit semantics -> regenerate layout -> validate -> lint:
-
Write or change the semantics. For a new diagram, hand-author a
semantics-only document (no bpmndi: block) - it's compact and easy to get
right. For an edit, run summarize first to understand the current model,
then change the bpmn:process body. See references/bpmn-reference.md for
the skeleton, every element's XML shape, and copy-paste recipes (exclusive /
parallel / inclusive gateways, boundary events, pools, lanes, message flows).
-
Lay out. Sync the diagram to your edit:
node "<SKILL_DIR>/scripts/bpmn-tool.mjs" layout in.bpmn out.bpmn
Omit out.bpmn to rewrite the file in place. On a file that already has DI
this preserves the existing layout (hand-tuned positions, Camunda
multi-diagram sub-process pages) and only prunes/places shapes to match your
change. On a brand-new semantics-only file it generates a clean layout. Add
--rebuild only when the user explicitly wants the entire diagram re-laid-out
from scratch (this discards any manual positioning - say so).
-
Validate. Confirm it parses, every flow element got a shape, and no shapes
overlap:
node "<SKILL_DIR>/scripts/bpmn-tool.mjs" validate out.bpmn
Fix anything it flags (dangling refs surface as parse warnings; missing shapes
usually mean you skipped layout; overlaps are checked per diagram plane, so a
real overlap means a crowded layout - re-run layout --rebuild).
-
Lint the control flow - especially when you added or rewired gateways and
branches:
node "<SKILL_DIR>/scripts/bpmn-tool.mjs" lint out.bpmn
validate proves the file is well-formed; lint proves the logic is sound.
It catches the silent bugs: gateway split/join mismatches (deadlock, double
execution), stuck tokens, unreachable nodes, dead ends, missing start/end,
implicit splits, misdirected start/end events, boundary events on a
non-activity, unassigned lane nodes, and message flows that stay inside a pool.
Don't claim a diagram is done until validate and lint both pass - they're
quick and catch the mistakes (typo'd refs, missing layout, gateway deadlocks)
that make a file look broken or hang in a real engine.
Modeling for clarity, not just validity
Auto-layout handles placement; clarity also comes from how you model. A few
habits that make diagrams readable:
- Name things in business terms. Tasks as verb phrases ("Approve invoice"),
gateways as the question they answer ("Amount > 1000?"), and label the
outgoing flows with the answers ("yes" / "no").
- Keep one start and clear ends. Distinct end events for distinct outcomes
read better than one catch-all end.
- Pair your gateways. A diverging gateway usually needs a converging one;
give exclusive gateways a default/else so a token can't get stuck.
- Don't overload one diagram. If it sprawls, push detail into a sub-process.
Auto-layout: what it covers
layout handles the full range of everyday BPMN, not just single-pool flows:
- Collaborations: every pool is laid out, stacked vertically, with message
flows routed between them (not just the first participant).
- Lanes (swimlanes): nodes are placed in their lane's horizontal band and the
lane shapes are drawn.
- Sub-processes get their own drill-down diagram page (a separate
BPMNDiagram plane), exactly like a Camunda export: the sub-process shows as a
box on the main canvas, and you "open" it to see its inner steps laid out on
their own page. They are not flattened onto the main canvas and not
emptied. summarize shows the inner steps; a modeler reveals them on open.
- Data objects/stores, text annotations, associations get shapes/edges placed
next to the element they relate to.
Remaining limits, worth stating honestly when a request leans on them:
- Groups are not auto-placed (a group is a purely visual rectangle with no
membership in the model, so there's nothing to size it from). Add one in a
modeler if needed.
- Auto-placement of pools, lanes, data objects, and annotations is approximate
- clean and valid, but a user may want to nudge spacing in a modeler.
Details and workarounds are in references/bpmn-reference.md.
Bundled tools
| Command | Purpose |
|---|
summarize <file> [--json] | Structured outline of the process(es), for explaining or for understanding before an edit |
layout <in> [out] [--rebuild] | Sync the diagram to the semantics: preserve & update existing DI, or generate it if absent. --rebuild re-lays-out from scratch |
validate <file> | Parse, report warnings, flag any flow element missing a shape or any per-plane overlapping shapes |
lint <file> | Find control-flow / structural bugs: gateway split/join mismatches, stuck-token gateways, unreachable nodes, dead ends, missing start/end, implicit splits, misdirected events, bad boundary hosts, unassigned lane nodes, intra-pool message flows |
diff <a> <b> | Semantic + structural diff: elements added/removed/renamed/retyped and sequence flows rewired (e.g. As-Is vs To-Be, or reviewing an edit) |
find <file> <term> | List flow elements whose name or type contains term (case-insensitive) - quick lookup before an edit |
All four live in scripts/bpmn-tool.mjs. The deeper element reference,
recipes, and edge cases are in references/bpmn-reference.md - read it whenever
you need the exact XML for an element or pattern.