32
5
In review
Synced today
What it does
>
Skill profile
Claude Code · Codex · OpenClaw
Keep exploring
More options in Dev Tools.
JavaScript
Updated 8/10/2026
Agent compatibility
Compatibility has not been reviewed for this listing yet. Check the publisher documentation before installing.
Installation
npx skills add https://github.com/Stieges/bpmn-generator --skill rootReview source code and installation permissions before adding third-party tools to an agent.
bpmn-generator is organized in the Uncategorized category. Compare its source, install method, and compatibility before adding it to your workflow.
Third-party agent tools may access source code, credentials, or browser sessions. Read the source documentation and use the minimum permissions needed.
npx skills add https://github.com/Stieges/bpmn-generator --skill rootSKILL.md
---
name: bpmn-generator
description: >
Enterprise BPMN 2.0 diagram generator — converts natural language process descriptions into
OMG-compliant BPMN 2.0 XML files and SVG previews via a 4-phase pipeline:
Intent Extraction (LLM → JSON Logic-Core) → Validation (deadlock detection, structural soundness) →
ElkJS Auto-Layout → BPMN XML + SVG output.
Supports: multi-pool collaborations, message flows, boundary events (timer/error/signal),
loop/multi-instance markers, data objects, all gateway types with correct gatewayDirection,
and all BPMN 2.0 task types.
Use this skill whenever the user wants to create, generate, or model a BPMN diagram, process flow,
or workflow — even if they say "draw a process", "model this workflow", "make a BPMN for...",
"create a Prozessmodell", "visualize this process", or describe a business process in natural language.
Also use for editing or extending existing BPMN Logic-Core JSON.
---
# BPMN Generator Skill v2.0 — Enterprise Edition
Converts natural language process descriptions into **OMG BPMN 2.0.2 compliant** XML files and
SVG previews via a 4-phase pipeline. All visual rendering follows the bpmn-js reference implementation.
## Pipeline Overview
```
User Text
↓ [Phase 1] Intent Extraction (Claude LLM)
JSON Logic-Core
↓ [Phase 2] Validation (rules + deadlock detection + structural soundness)
Validated JSON
↓ [Phase 3] Auto-Layout (ElkJS Sugiyama layered algorithm)
JSON + Coordinates (edge endpoints clipped to shape boundaries)
↓ [Phase 4] Serialization (pipeline.js)
BPMN 2.0 XML + SVG
```
The LLM **never** handles coordinates. Layout is 100% algorithmic.
---
## Modes: Document (IST) vs. Optimize (Soll)
Two distinct intents — keep them separate:
- **Document mode (default, IST / as-is):** the user describes a process and wants it captured
**faithfully** as BPMN. No judgment, no improvement suggestions. This is the default for every entry
point (CLI, `runPipeline`, HTTP, MCP).
- **Optimize mode (Soll / to-be):** the user wants a **better** process. Enables the opt-in Optimization
Advisory layer, which flags graph-detectable redesign opportunities (Reijers 2005 heuristics + BABOK
Lean metrics) as **non-blocking `advisories`** — never auto-applied.
Select the mode consistently across entry points:
- CLI: `node bpmn/pipeline.js in.json out --optimize`
- Programmatic: `runPipeline(lc, { mode: 'optimize' })`
- HTTP: `{ "logicCore": {...}, "mode": "optimize" }` on `/api/v1/generate|validate|orchestrate`
- MCP: `mode: "optimize"` on `generate_bpmn` / `validate_bpmn` / `orchestrate_bpmn`
Advisories are review suggestions with trade-off tags (time/cost/quality/flexibility); they are heuristics,
not proofs — present them as options, never silently apply them. Each advisory is an object
`{ id, transform, targets, message, tradeoff, ref, judgment }` (see `references/api-reference.md`); `message`
is the human-readable line, `transform` names the matching intervention in the toolbox below.
### Redesign Toolbox
In `optimize` mode, an advisory's `transform` field names a concrete, mechanical intervention. The
interventions live in `scripts/bpmn/redesign.js`; each has a `preview*` function (what would be feasible, and why
not) and an `apply*` function that performs it:
- `parallelize` — puts a linear, same-lane task chain into a parallel-gateway split/join. **Tasks
only:** a chain containing a subprocess, a call activity, an intermediate event or a gateway is
refused, because parallelising a scope or a branch changes the process logic rather than the order
of its steps. This is also why **O04 never nominates a subprocess chain** — the detector
(`optimize.js`) is scoped to the same leaf-task set as the transform, so it cannot advise
something the toolbox is guaranteed to refuse. If you want such a chain parallelised, that starts
with a decision about the transform, not with the advisory
- `mergeTasks` — folds a linear task chain into one task; **requires an explicit `name`** — naming the
result is a judgment call the toolbox refuses to make for you
- `relane` — moves one node to a different lane
- `reorderKnockouts` — reorders a chain of exclusive-gateway "knock-out" checks; **requires an explicit
`order`** — it is never computed
- `isolateException` — turns an inline exception branch into a boundary event on the owning task;
**requires explicit `marker` and `cancelActivity`**, and, when the exception end has more than one
incoming edge, an **explicit `edgeIds`** naming which ones belong to this task — it refuses rather than
guess
**No-language-model guarantee:** the toolbox is purely deterministic. `scripts/bpmn/redesign-core.js` may not
import `agents/llm-provider.js`, directly or transitively — no LLM call, no API key. Verify with
`grep -rn "^import.*llm-provider" scripts/redesign*.js` (no hit; a plain `grep -rn "llm-provider"`
also matches the comment stating this rule, so it is not a useful check on its own).
**Rollback:** every `apply*` re-checks its result against a fixed, **profile-independent** soundness gate
(soundness + workflow-net layers, always on — `scripts/bpmn/redesign-core.js: SOUNDNESS_GATE`) and rolls back
(throws, writes nothing) on structural errors. Style warnings never block; they come back in the result's
`warnings` array instead.
**What it will not decide for you:** the toolbox never decides *whether* an intervention should happen —
that's the caller's call. Where a transform lacks the information to act safely (no proven data-independence
between two tasks, no supplied ordering, no supplied marker/`cancelActivity`, an ambiguous set of incoming
edges) it refuses with a specific reason instead of guessing. Not every transform currently has a matching
automatic advisory either: O01→`isolateException`, O02→`reorderKnockouts`, O03→`relane`, O04→`parallelize`
are detected by `optimize.js`; `mergeTasks` has no detector and is reachable only by direct/manual
invocation.
**Protection lists** (`policy.protectNodes` / `policy.protectLanes`) match a node or lane by id **and** by
display name, and resolve lane membership whether the model expresses it via `node.lane` or via
`Lane.nodeIds`. Transforms also **maintain** both representations: a transform that deletes a node
removes it from any `Lane.nodeIds`, and one that creates a node adds it — so the two never contradict
each other. Purely Format-A models are left untouched (no `nodeIds` arrays are introduced).
Every `apply*` returns a `change` record with three arrays — `added`, `removed`, `modified` — that together
name every element (node, edge, or lane) that differs between input and result.
CLI (preview is the default; nothing is written without `--apply`; a refusal exits non-zero and writes
nothing):
```bash
node bpmn/redesign-cli.js <input.json> <parallelize|mergeTasks|relane|reorderKnockouts|isolateException> \
[--nodes a,b,c] [--name "..."] [--lane X] [--order g2,g1] [--end xend] [--attach-to task] \
[--marker timer] [--cancel-activity true|false] [--edges j2,j5] [--policy '{"protectNodes":[...]}'] \
[--apply] [-o out.json]
```
---
## Reference Files
Read these when needed:
- `references/logic-core-schema.md` — Full JSON schema, type table, all examples → **read before extracting JSON**
- `references/prompt-template.md` — LLM prompt templates for extraction, review, amendment → **read before prompting**
---
## Supported BPMN 2.0 Elements
### Events
| Type | Markers | Notes |
|------|---------|-------|
| Start Event | None, Message, Timer, Signal, Conditional, Error, Escalation, Compensation | Thin circle (strokeWidth 2) |
| End Event | None, Message, Signal, Error, Escalation, Compensation, Cancel, Terminate, Multiple | Thick circle (strokeWidth 4) |
| Intermediate Catch | Message, Timer, Signal, Conditional, Link, Error, Escalation, Compensation, Cancel | Double circle |
| Intermediate Throw | Message, Signal, Link, Escalation, Compensation | Double circle, filled marker |
| Boundary Event | Timer, Error, Message, Signal, Escalation, Compensation, Cancel, Conditional | Attached to activity, interrupting/non-interrupting |
### Activities
| Type | Icon | Notes |
|------|------|-------|
| Task | — | Generic activity |
| User Task | 👤 | Human work item |
| Service Task | ⚙⚙ | System/API call |
| Script Task | 📄 | Script execution |
| Send Task | ✉ (filled) | Outgoing message |
| Receive Task | ✉ (outlined) | Incoming message |
| Manual Task | ✋ | Physical work |
| Business Rule Task | 📊 | DMN / rule engine |
| Sub-Process | [+] | Collapsed, with expand marker |
| Call Activity | thick border | Reusable called process |
### Activity Markers (bottom-center)
| Marker | Property | Visual |
|--------|----------|--------|
| Standard Loop | `loopType: "standard"` | ↻ circular arrow |
| MI Parallel | `multiInstance: "parallel"` | ⫴ three vertical bars |
| MI Sequential | `multiInstance: "sequential"` | ≡ three horizontal bars |
| Ad-Hoc | `isAdHoc: true` | ~ tilde |
| Compensation | `isCompensation: true` | ◁◁ double rewind |
### Gateways
| Type | Marker | Direction |
|------|--------|-----------|
| Exclusive (XOR) | ✕ | Diverging/Converging/Mixed |
| Parallel (AND) | + | Diverging/Converging/Mixed |
| Inclusive (OR) | ○ | Diverging/Converging/Mixed |
| Event-Based | ○+⬠ | Diverging |
| Complex | ✱ | Mixed |
### Data & Artifacts
| Type | Visual |
|------|--------|
| Data Object | Rectangle with folded corner |
| Data Store | Cylinder |
| Text Annotation | Open bracket [ with text |
| Group | Dashed rounded rectangle |
### Connections
| Type | Style | Source marker | Target marker |
|------|-------|---------------|---------------|
| Sequence Flow | Solid | — | Filled triangle |
| Default Flow | Solid | Diagonal slash | Filled triangle |
| Conditional Flow | Solid | Open diamond | Filled triangle |
| Message Flow | Dashed (10,12) | Open circle | Open triangle |
| Association | Dotted (0.5,5) | — | Open chevron (if directed) |
---
## When to use which mode
| Context | Mode |
|---------|------|
| User gives a process description in text | Full pipeline (all 4 phases) |
| User uploads/provides existing Logic-Core JSON | Skip Phase 1, start at Phase 2 |
| User wants to add/change something in existing diagram | Amendment flow |
| User describes multiple organizations interacting | Multi-pool mode |
| User is in Claude Code with Node.js | Use `scripts/bpmn/pipeline.js` |
| User is in Claude.ai (no script execution) | Inline mode: generate XML + SVG as artifacts |
---
## Phase 1 — Intent Extraction
**Read `references/logic-core-schema.md` and `references/prompt-template.md` first.**
Use the **Master Extraction Prompt** template. Key rules to enforce:
### Naming Conventions (BA-Quality)
- **Tasks**: `Objekt + Verb (Infinitiv)` — "Antrag prüfen" ✓ / "Prüfung" ✗
- **XOR Gateways**: Question form — "Antrag gültig?" ✓ / "Entscheidung" ✗
- **AND/OR Gateways**: Empty or brief label — "" ✓ (these are sync points)
- **Gateway edges**: Always labeled — "Ja"/"Nein", "genehmigt"/"abgelehnt"
- **Lanes**: Functional roles — "Sachbearbeiter" ✓ / "Max Müller" ✗
- **Events**: Noun phrase — "Antrag eingegangen" ✓
### Granularity Rules
- Max 7–10 nodes per level. Use `subProcess` for groups with >3 logical steps.
- Never create "God-Tasks" (a single task hiding a whole sub-process).
- Prefer more granular over too abstract.
### Happy Path
- Mark the main success flow edges with `"isHappyPath": true`
- ElkJS will lay these out on the horizontal axis (left→right)
- Exception/error paths branch vertically
### Gateway Direction (OMG spec §10.5.1)
- `has_join: true` → pipeline sets `gatewayDirection="Converging"` in XML
- Split gateways get `gatewayDirection="Diverging"` automatically
- Mixed (split+join) gateways get `gatewayDirection="Mixed"`
### Event Markers
- Set `marker` explicitly when the event type is clear from context
- If not set, pipeline infers from event name (e.g. "Frist abgelaufen" → timer)
---
## Phase 2 — Validation
The pipeline validates automatically. These checks run:
**Errors (block pipeline):**
- [ ] At least one `startEvent` exists per process
- [ ] At least one `endEvent` exists per process
- [ ] All `edge.source` and `edge.target` reference existing node IDs
- [ ] No XOR-split path merging at an AND-join (**deadlock detection**)
- [ ] Message flows reference valid node/pool IDs
**Warnings (report but continue):**
- [ ] XOR gateways not named as questions
- [ ] Tasks not following **Objekt + Verb (Infinitiv)** pattern (M01)
- [ ] Nodes with no edges (isolated)
- [ ] XOR gateway outgoing edges without labels
- [ ] Nodes with no outgoing flow (may not terminate)
Use the **Reviewer Agent Prompt** from `references/prompt-template.md` for additional automated review.
### Pre-Delivery Gate (MANDATORY — do not skip)
A first draft is expected to be wrong. **Never present a diagram as finished until it
passes this gate.** Warnings are not noise — they are the alarm.
1. **Read `references/logic-core-schema.md` first.** It is the field-by-field contract
(every node type, marker, edge, message flow, black-box pool). Fill the input file
against it — do not guess field names or values.
2. **Validate the draft against the schema and run it strictly:**
```bash
node bpmn/pipeline.js <input>.json <output> --strict
```
- The schema-gate (`references/input-schema.json`) rejects malformed structure with a
precise field path and exits non-zero — fix every reported field.
- `--strict` makes every warning fatal (exit non-zero, no files written), across three
independent checks: rule-engine warnings, diagram (DI) integrity, and BPMN
serialisation (the round trip of the generated XML through bpmn-moddle — this is what
catches an invalid element, e.g. an annotation carrying an illegal attribute).
3. **Resolve every warning** and re-run until `--strict` exits `0`. Delivering a diagram
with unresolved warnings is not allowed.
4. Only then present the output. If a warning is a deliberate, justified exception, say so
explicitly to the user — do not silently ship past it.
---
## Phase 3 + 4 — Script Execution (Claude Code)
### Setup (first time only)
```bash
cd scripts/
npm install # installs runtime + dev dependencies (see package.json)
```
### Run pipeline
```bash
# From JSON file:
node bpmn/pipeline.js my-process.json my-process
# From stdin (inline JSON):
echo '{ ... }' | node bpmn/pipeline.js - output
# Outputs:
# output.bpmn — BPMN 2.0 XML with full DI coordinates
# output.svg — SVG preview (open in browser)
```
### OMG Compliance Guarantees
The generated BPMN 2.0 XML ensures:
- Single `<laneSet>` per process (spec §10.5)
- Correct `gatewayDirection` attribute (Diverging/Converging/Mixed)
- `conditionExpression` as child element, not attribute (spec §10.3.1)
- `<incoming>` and `<outgoing>` references on all flow nodes
- Event definition child elements (messageEventDefinition, timerEventDefinition, etc.)
- Loop/multi-instance characteristics as child elements
- Boundary events with `attachedToRef` and `cancelActivity`
- Valid `isHorizontal="true"` on pool/lane shapes
- Edge endpoints clipped to actual shape boundaries
---
## Inline Mode (Claude.ai — no script execution)
When Claude Code is not available, generate outputs directly in the conversation:
1. Extract the Logic-Core JSON (show to user for confirmation)
2. Apply validation rules mentally (check for deadlocks, naming, completeness)
3. For the SVG: render as an **HTML artifact** using inline SVG
- Use the exact OMG dimensions: 36px events, 100×80 tasks, 50×50 gateways
- Use ElkJS-compatible manual positioning: elements spaced 60px between layers, 40px between nodes
- Apply stroke widths: 2 (start), 4 (end), 1.5 (intermediate), 2 (task), 5 (call activity)
4. For the BPMN XML: generate as a **code artifact** following all OMG compliance rules
Show the Logic-Core JSON to the user before generating final files.
**Note:** Inline mode coordinates are manually estimated. For production-quality layout, use Claude Code with the pipeline script.
---
## Amendment Flow (editing existing diagrams)
When user wants to modify an existing diagram:
1. Load the existing Logic-Core JSON
2. Use the **Amendment Prompt** from `references/prompt-template.md`
3. Apply only the atomic changes requested
4. Re-validate (Phase 2)
5. Re-run pipeline (Phase 3+4)
**Never** regenerate the entire Logic-Core from scratch for small edits — preserve all existing IDs.
---
## Two-Agent Pattern (production quality)
For enterprise output, run Modeler + Reviewer in loop:
```
Modeler (Claude): Text → Logic-Core JSON (draft)
↓
Reviewer (Claude): Logic-Core → Issues JSON
↓
No issues? → Run pipeline
Issues? → Modeler applies fixes → repeat (max 3 iterations)
```
Use prompts from `references/prompt-template.md` for both roles.
---
## Output Artifacts
| File | Purpose | Opens in |
|------|---------|----------|
| `*.bpmn` | BPMN 2.0 XML with DI | Camunda Modeler, bpmn.io, ADONIS, Signavio |
| `*.svg` | Vector preview | Browser, Confluence, Word/PowerPoint |
| `*_logic.json` | Logic-Core (save for amendments) | Text editor, version control |
---
## Error Handling
| Error | Cause | Fix |
|-------|-------|-----|
| `Missing startEvent` | No start node in JSON | Add startEvent node |
| `Missing endEvent` | No end node in JSON | Add endEvent node |
| `Unknown source/target` | Edge references non-existent node | Fix ID typo |
| `Deadlock: XOR-split feeds AND-join` | Structural error | Change AND-join to XOR-join or restructure |
| `ELK layout failed` | Disconnected graph | Fix isolated nodes |
| `npm install fails` | No network or Node.js missing | Ensure Node.js ≥20 |
---
## Quick-Reference: Node Types
| Type | Icon | Use for |
|------|------|---------|
| `startEvent` | ○ | Process trigger |
| `endEvent` | ⬤ | Process end |
| `intermediateCatchEvent` | ◎ | Wait for event mid-flow |
| `intermediateThrowEvent` | ◎● | Send event mid-flow |
| `boundaryEvent` | ◎→ | Timer/error on task |
| `userTask` | 👤 | Human work item |
| `serviceTask` | ⚙ | System/API call |
| `scriptTask` | 📄 | Script execution |
| `sendTask` | ✉● | Send message |
| `receiveTask` | ✉○ | Receive message |
| `businessRuleTask` | 📊 | DMN / rules |
| `manualTask` | ✋ | Physical work |
| `subProcess` | [+] | Collapsed complexity |
| `callActivity` | ▬▬ | Reusable process |
| `exclusiveGateway` | ◇✕ | One path (XOR) |
| `parallelGateway` | ◇+ | All paths (AND) |
| `inclusiveGateway` | ◇○ | One or more (OR) |
| `eventBasedGateway` | ◇◎ | First event wins |
| `complexGateway` | ◇✱ | Custom logic |
| `dataObjectReference` | 📋 | Document/data |
| `dataStoreReference` | 🗄 | Database |
| `textAnnotation` | [ | Explanatory note |
---
## Round-Tripping (BPMN Import)
Import existing BPMN 2.0 XML files to extract a Logic-Core JSON for editing.
### Claude Code
```bash
cd scripts/
node bpmn/import.js existing-diagram.bpmn extracted.json
```
### Workflow
```
Existing .bpmn file
↓ [import.js] Parse XML → extract nodes, edges, lanes, message flows
Logic-Core JSON
↓ [User/LLM edits] Amendment flow
Modified Logic-Core
↓ [pipeline.js] Layout + render
New .bpmn + .svg
```
**Supported on import:** Processes, collaborations, lanes, message flows,
collapsed pools, gateways (with direction), all task/event types,
boundary events, loop/MI markers, data objects, associations,
process documentation, default flows.
---
## Inline Mode (Claude.ai — with ElkJS)
When Claude Code is not available, use the **inline template** from
`references/inline-template.md` to create a self-contained HTML artifact:
1. Extract the Logic-Core JSON
2. Show to user for confirmation
3. Create an HTML artifact with the template
4. Replace `__LOGIC_CORE_JSON__` with the actual JSON
The template runs ElkJS from CDN in the browser — **no manual coordinate estimation**.
It produces orthogonal layouts with proper BPMN shapes.
**Note:** The inline renderer is simplified (no task type icons, no event markers).
For full rendering fidelity, use Claude Code with pipeline.js.
---
## Collapsed Pools (Black-Box Participants)
**Best Practice (Bruce Silver Method & Style):**
A diagram should have **one expanded pool** (your process in scope) and
collapsed pools for external participants (customers, suppliers, authorities).
### Schema
```json
{
"collapsedPools": [
{ "id": "Pool_Kunde", "name": "Versicherungsnehmer" },
{ "id": "Pool_Gutachter", "name": "Externer Gutachter" }
]
}
```
### Rendering
- SVG: Thin horizontal band (600×60) with centered label
- XML: `<participant>` without `processRef` (OMG spec §9.3)
- Message flows target the collapsed pool ID directly
---
## Associations (Data Objects + Annotations)
Connect Data Objects, Data Stores, and Text Annotations to flow nodes:
```json
{
"associations": [
{ "id": "assoc1", "source": "task_erfassen", "target": "do_akte", "directed": true },
{ "id": "assoc2", "source": "ann_hinweis", "target": "task_pruefen" }
]
}
```
- SVG: Dotted line (strokeDasharray `0.5,5`)
- XML: `<association>` element with `associationDirection`, placed in `<artifacts>` alongside any
TextAnnotation/Group it connects to — never in `<flowElements>` (§10.7). Endpoint resolution has
to look in both collections: an association's source or target is very often an artifact, not a
flow node.
---
## OMG Compliance Checklist (v3)
| Feature | Status | OMG Reference |
|---------|--------|---------------|
| Single `<laneSet>` per process | ✅ | §10.5 |
| `gatewayDirection` Diverging/Converging/Mixed | ✅ | §10.5.1 |
| `default` attribute on XOR gateways | ✅ | §10.5.1 |
| `conditionExpression` as child element | ✅ | §10.3.1 |
| `<incoming>`/`<outgoing>` on flow nodes | ✅ | §10.2.1 |
| Top-level `<message>`/`<signal>`/`<error>` definitions | ✅ | §8.4, §9 |
| Event definitions with `messageRef`/`errorRef` | ✅ | §10.4 |
| `<documentation>` on process and nodes | ✅ | §8.3.1 |
| `<association>` elements | ✅ | §7.2 |
| Artifacts (TextAnnotation, Group, Association) in `<artifacts>`, never `<flowElements>` | ✅ | §10.7 |
| TextAnnotation content as a `<text>` child element, never a `name` attribute | ✅ | §10.7.3 |
| Group label via `categoryValueRef` → a `Category`/`CategoryValue` root element, never a `name` attribute | ✅ | §10.7.2 |
| Collapsed pool (`<participant>` without `processRef`) | ✅ | §9.3 |
| DI Label Bounds with `<dc:Bounds>` | ✅ | §12.1 |
| Loop/MI characteristics as child elements | ✅ | §10.2.2 |
| Boundary events with `attachedToRef` | ✅ | §10.4.4 |
| Orthogonal edge routing | ✅ | Visual convention |
| Edge endpoint clipping to shape boundaries | ✅ | Visual convention |
| Pool width equalization | ✅ | Visual convention |
| Deadlock detection (XOR→AND) | ✅ | Structural soundness |
| Round-tripping (BPMN→JSON→BPMN) | ✅ | Interoperability |
**Why the three artifact rules above matter if you ever hand-write XML (inline mode):** an
Artifact (TextAnnotation, Group, Association) extends `BaseElement`, which declares only `id` —
`name` is introduced further down by `FlowElement`, and Artifacts never inherit from it. Most XML
libraries write the attribute anyway without complaint, so a `name` on a TextAnnotation produces
no error and an empty box in every real BPMN tool. This shipped once; see
`references/omg-compliance.md` §10.7 for the full mapping.
skill
mattpocock
Build a throwaway prototype to answer a design question. Use when the user wants to sanity-check whether a state model or logic feels right, or explore what a UI should look like.