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.
1---2name: bpmn3description: 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.4---56# BPMN 2.0: read and edit process diagrams78## What this skill does910Helps you understand existing `.bpmn` files in plain language and produce new or11edited ones that are **valid and visually clean** when opened in any modeler12(Camunda Modeler, bpmn.io, Cawemo, etc.).1314The job splits cleanly:15- **You** do the semantic reasoning: what the process means, what to add or change.16- **The bundled script** does the deterministic mechanics: parsing, regenerating17 layout, and validating. Lean on it instead of hand-rolling these each time.1819## The one idea that makes BPMN tractable: two layers2021A `.bpmn` file holds two layers in one XML document:22231. **Semantics** - the actual process: `bpmn:process` with tasks, gateways,24 events, and `sequenceFlow`s connecting them. This is the meaning.252. **Diagram interchange (DI)** - `bpmndi:BPMNDiagram` with x/y coordinates for26 every shape and waypoints for every edge. This is only the picture.2728Editing DI by hand is where BPMN work goes wrong: coordinates drift, shapes29overlap, edges cross. **So we never hand-write DI.** You edit semantics; the30`layout` command owns the DI. That is exactly what makes the diagram "clear" - a31tidy left-to-right layout, generated deterministically.3233`layout` is **non-destructive by default**, which is the rule that keeps you out34of trouble: on a file that already has a diagram it *preserves* the existing35layout and only syncs it to your edit (prune shapes for deleted elements, place36shapes for new ones). On a file with no DI it generates a fresh layout. It only37throws the whole diagram away and rebuilds from scratch when you pass38`--rebuild`. So the habit is simple: **after editing semantics, always run39`layout`; it never destroys a good diagram.**4041## Setup (once per machine)4243The script needs two npm packages. From the skill's own directory:4445```bash46npm install --prefix "<SKILL_DIR>"47```4849`<SKILL_DIR>` is the folder containing this SKILL.md. After that, the four50commands below are available. If a run fails with "Cannot find package", the51install step was skipped - run it and retry.5253## Reading / explaining a diagram54551. Get a structured outline (don't try to read raw DI coordinates):56 ```bash57 node "<SKILL_DIR>/scripts/bpmn-tool.mjs" summarize path/to/file.bpmn58 ```59 This prints pools/lanes, start/end events, activities (with their type),60 gateways (with direction), boundary events (host + interrupting?), and every61 sequence flow as `source -> target [condition]`. Add `--json` if you want to62 process it programmatically.63642. Explain it the way a person would understand the process: the happy path65 first, then decision points (what each gateway branches on), parallel work,66 and exception/boundary handling. Name real business steps, not element IDs.67 Match the user's language.6869The summarize output is your source of truth for "what does this diagram do" -70read from it rather than eyeballing the XML, especially for anything non-trivial.7172To **locate** a specific element before an edit, use `find <file> <term>` (matches73name or type). To **compare** two diagrams - As-Is vs To-Be, or to show exactly74what an edit changed - use `diff <a> <b>`; it reports elements added, removed,75renamed, or retyped and any sequence flows that were rewired.7677When the user wants a **review** ("is this correct?", "find the bug", "why does78it hang?"), also run `lint`. It catches control-flow bugs that are valid XML and79pass `validate` but are wrong behavior - the kind that are easy to miss by eye:8081```bash82node "<SKILL_DIR>/scripts/bpmn-tool.mjs" lint path/to/file.bpmn83```8485It flags: a parallel (AND) join fed by an exclusive (XOR) split (**deadlock**); a86parallel split merged by an exclusive join (runs **twice**); an exclusive gateway87whose conditions can all be false with no default (**stuck token**);88**unreachable** nodes; **dead ends** (non-end node, no outgoing); a missing89start/end; an **implicit split** (non-gateway node with several outgoing flows);90**misdirected events** (start with an incoming flow, end with an outgoing one); a91boundary event on a **non-activity**; a node in **no lane** when the process uses92lanes; and a message flow that stays **inside one pool**. Read its finding,93confirm it against the model, then explain it in plain terms.9495## Creating or editing a diagram9697Before writing XML for a *new* process, think like a business analyst and pin98down the structure - it's what separates a clear model from a box-and-arrow99mess. If any of these is unclear from the request, ask:100101- **Trigger** - what starts the process (and is it a plain start, a message, a102 timer?).103- **Participants** - who does what. Multiple actors usually means lanes (one104 pool) or pools + message flows (separate processes).105- **Happy path** - the main sequence of activities when nothing goes wrong.106- **Decision points** - where the path forks, on what condition, and which107 gateway fits (exclusive = either/or, parallel = all, inclusive = one-or-more).108- **Exceptions / alternatives** - timeouts, rejections, errors; often boundary109 events or extra branches.110- **End states** - the distinct ways the process can finish.111112If the user is documenting current vs future state, treat **As-Is** and113**To-Be** as separate diagrams/files and label them as such.114115The reliable loop is then **edit semantics -> regenerate layout -> validate -> lint**:1161171. **Write or change the semantics.** For a new diagram, hand-author a118 semantics-only document (no `bpmndi:` block) - it's compact and easy to get119 right. For an edit, run `summarize` first to understand the current model,120 then change the `bpmn:process` body. See `references/bpmn-reference.md` for121 the skeleton, every element's XML shape, and copy-paste recipes (exclusive /122 parallel / inclusive gateways, boundary events, pools, lanes, message flows).1231242. **Lay out.** Sync the diagram to your edit:125 ```bash126 node "<SKILL_DIR>/scripts/bpmn-tool.mjs" layout in.bpmn out.bpmn127 ```128 Omit `out.bpmn` to rewrite the file in place. On a file that already has DI129 this *preserves* the existing layout (hand-tuned positions, Camunda130 multi-diagram sub-process pages) and only prunes/places shapes to match your131 change. On a brand-new semantics-only file it generates a clean layout. Add132 `--rebuild` only when the user explicitly wants the entire diagram re-laid-out133 from scratch (this discards any manual positioning - say so).1341353. **Validate.** Confirm it parses, every flow element got a shape, and no shapes136 overlap:137 ```bash138 node "<SKILL_DIR>/scripts/bpmn-tool.mjs" validate out.bpmn139 ```140 Fix anything it flags (dangling refs surface as parse warnings; missing shapes141 usually mean you skipped `layout`; overlaps are checked per diagram plane, so a142 real overlap means a crowded layout - re-run `layout --rebuild`).1431444. **Lint the control flow** - especially when you added or rewired gateways and145 branches:146 ```bash147 node "<SKILL_DIR>/scripts/bpmn-tool.mjs" lint out.bpmn148 ```149 `validate` proves the file is well-formed; `lint` proves the *logic* is sound.150 It catches the silent bugs: gateway split/join mismatches (deadlock, double151 execution), stuck tokens, unreachable nodes, dead ends, missing start/end,152 implicit splits, misdirected start/end events, boundary events on a153 non-activity, unassigned lane nodes, and message flows that stay inside a pool.154155Don't claim a diagram is done until `validate` and `lint` both pass - they're156quick and catch the mistakes (typo'd refs, missing layout, gateway deadlocks)157that make a file look broken or hang in a real engine.158159## Modeling for clarity, not just validity160161Auto-layout handles *placement*; clarity also comes from how you model. A few162habits that make diagrams readable:163164- **Name things in business terms.** Tasks as verb phrases ("Approve invoice"),165 gateways as the question they answer ("Amount > 1000?"), and label the166 outgoing flows with the answers ("yes" / "no").167- **Keep one start and clear ends.** Distinct end events for distinct outcomes168 read better than one catch-all end.169- **Pair your gateways.** A diverging gateway usually needs a converging one;170 give exclusive gateways a default/else so a token can't get stuck.171- **Don't overload one diagram.** If it sprawls, push detail into a sub-process.172173## Auto-layout: what it covers174175`layout` handles the full range of everyday BPMN, not just single-pool flows:176177- **Collaborations:** every pool is laid out, stacked vertically, with message178 flows routed between them (not just the first participant).179- **Lanes (swimlanes):** nodes are placed in their lane's horizontal band and the180 lane shapes are drawn.181- **Sub-processes** get their own **drill-down diagram page** (a separate182 `BPMNDiagram` plane), exactly like a Camunda export: the sub-process shows as a183 box on the main canvas, and you "open" it to see its inner steps laid out on184 their own page. They are **not** flattened onto the main canvas and **not**185 emptied. `summarize` shows the inner steps; a modeler reveals them on open.186- **Data objects/stores, text annotations, associations** get shapes/edges placed187 next to the element they relate to.188189Remaining limits, worth stating honestly when a request leans on them:190191- **Groups** are not auto-placed (a group is a purely visual rectangle with no192 membership in the model, so there's nothing to size it from). Add one in a193 modeler if needed.194- Auto-placement of pools, lanes, data objects, and annotations is **approximate**195 - clean and valid, but a user may want to nudge spacing in a modeler.196197Details and workarounds are in `references/bpmn-reference.md`.198199## Bundled tools200201| Command | Purpose |202|---|---|203| `summarize <file> [--json]` | Structured outline of the process(es), for explaining or for understanding before an edit |204| `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 |205| `validate <file>` | Parse, report warnings, flag any flow element missing a shape or any per-plane overlapping shapes |206| `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 |207| `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) |208| `find <file> <term>` | List flow elements whose name or type contains `term` (case-insensitive) - quick lookup before an edit |209210All four live in `scripts/bpmn-tool.mjs`. The deeper element reference,211recipes, and edge cases are in `references/bpmn-reference.md` - read it whenever212you need the exact XML for an element or pattern.