agentsclimarketplace

Bpmn xml generator

Skill stateway-io/bpmn-xml-generator/.claude/skills/bpmn-xml-generator

AI agent code skill to generate valid BPMN XML files.

Install
npx -y skills add stateway-io/bpmn-xml-generator --skill bpmn-xml-generator

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Generate well-formed, valid BPMN 2.0 XML files compatible with BPMN 2.0-compliant process engines. Use this skill whenever the user asks to create, write, design, model, or define a business process, workflow, or BPMN diagram — even if they just describe a flow in plain language ("I need a process that does X then Y..."). Also use it when asked to convert YAML/JSON process definitions to BPMN, or to edit/fix an existing BPMN file. The skill guides information gathering when the request is incomplete, produces schema-valid XML, and enforces schema and compatibility constraints.

SKILL.md

15.0 KB, as published. Nobody here has run it

BPMN Authoring

Produces valid BPMN 2.0 XML parseable by bpmn-moddle and executable by BPMN 2.0-compliant process engines.


0. Orientation: what you are building

This skill targets engines that parse BPMN via bpmn-moddle (the bpmn-io library), such as Camunda and Flowable-compatible engines.
Key facts that govern every file you generate:

FactDetail
Root namespacexmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
Root element<definitions> with mandatory id and targetNamespace (any valid URI; not read by the engine — it is required by the BPMN 2.0 XML schema only)
Each process<process id="..." isExecutable="true">
Conditions on flows<conditionExpression>{{expression}}</conditionExpression> (engine-specific; verify with your engine — FEEL is the BPMN-standard alternative)
Assignees / dynamic values{{variables.fieldName}} inside string attributes
DMN integration<businessRuleTask camunda:decisionRef="decision-id">decisionRef must match the id of a DMN definition already registered in the engine
IDsAll elements must have a unique id attribute. Convention: snake_case or PascalCase_N
isExecutableAlways true for processes intended for execution

1. Information gathering — ask before writing

Never generate a BPMN file from an incomplete description. If the user's prompt is missing any of the items below, ask them before proceeding. Ask all missing items in a single response (not one at a time).

1.1 Always required

  • Process key — the logical identifier (e.g., order-approval). Must be URL-safe, lowercase, hyphen-separated.
  • Process name — human-readable label.
  • Happy-path steps — the sequence of activities from start to end (at least one activity).
  • Human tasks — which steps require human action? Who is the assignee or candidateGroup?
  • Service tasks — which steps call external systems? What is the implementation type? (webhook or http)
  • Gateways — are there any conditional branches? What are the conditions?

1.2 Ask when relevant

  • Timer events — any steps that wait for a time or duration? (ISO 8601: PT1H, 2026-12-01T09:00:00Z, R3/PT24H)
  • Message / Signal events — any steps that wait for or emit an external message?
  • Error / boundary events — any error handling on tasks?
  • Sub-processes — any embedded sub-flows?
  • DMN decisions — does any step evaluate a decision table? If so, what is the id of the DMN definition that must already exist in the engine? (That id goes in camunda:decisionRef.)
  • Variable names — what process variables are used? (needed for expressions and dataInputAssociation)
  • Data visibility — for each userTask, which variables should the frontend see? (maps to dataInput/dataOutput in ioSpecification)
  • Process-level variables — are there default/initial variable values?
  • Diagram layout — do you want the output to include a visual layout (BPMNDiagram section), required by tools like bpmn.io? If yes, bpmn-auto-layout will be run automatically after saving (requires Node.js ≥ 18 and internet access for npx).

1.3 Clarify ambiguity

If the user describes a flow like "approve or reject", confirm:

  • Is this an exclusiveGateway (XOR — one path only)?
  • Are both outcomes leading to different end states?
  • What is the condition expression for each outgoing flow?

2. Supported BPMN elements

Read references/elements.md for the full attribute list of each element.
Below is the complete list of supported types — do not use any element not on this list.

Events

XML elementTypeNotes
<startEvent>startEventNone, Timer, Message, Signal, Conditional
<endEvent>endEventNone, Terminate, Message, Signal, Error, Escalation
<intermediateCatchEvent>intermediateCatchEventTimer, Message, Signal, Conditional
<intermediateThrowEvent>intermediateThrowEventMessage, Signal, Escalation
<boundaryEvent>boundaryEventTimer (interrupting/non), Error, Message, Signal, Escalation

Activities

XML elementTypeNotes
<task>generic taskpasses through immediately
<userTask>userTaskassignee, candidateGroups, formKey, dueDate
<serviceTask>serviceTaskimplementation="webhook" or "http"
<scriptTask>scriptTaskexpression evaluated against variables
<sendTask>sendTaskdispatches message/webhook
<receiveTask>receiveTaskwaits for correlated message
<businessRuleTask>businessRuleTaskcamunda:decisionRef must contain the id of a previously registered DMN definition
<callActivity>callActivitycalls another process definition
<subProcess>subProcessembedded sub-flow

Gateways

XML elementBehavior
<exclusiveGateway>XOR — exactly one outgoing flow taken
<parallelGateway>AND — all flows activated (join requires all tokens)
<inclusiveGateway>OR — one or more flows based on conditions
<eventBasedGateway>race — first event wins

Connectors

XML elementNotes
<sequenceFlow>sourceRef, targetRef, optional <conditionExpression>

Not commonly supported by BPMN process engines

CMMN, Choreography, Conversation, DataStore, Association (rendered only).


3. XML structure template

<?xml version="1.0" encoding="UTF-8"?>
<definitions
  xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
  xmlns:di="http://www.omg.org/spec/DD/20100524/DI"
  xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
  xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL
                      http://www.omg.org/spec/BPMN/2.0/20100501/BPMN20.xsd"
  id="Definitions_{process-key}"
  targetNamespace="http://bpmn.io/schema/bpmn" <!-- any valid URI; this value is not used by the engine -->
  exporter="bpmn-xml-generator"
  exporterVersion="1.0">

  <process id="{process-key}" name="{Process Name}" isExecutable="true">

    <!-- ═══ START ═══ -->
    <startEvent id="start" name="Start">
      <outgoing>flow_start_to_first</outgoing>
    </startEvent>

    <!-- ═══ ACTIVITIES ═══ -->
    <!-- ... -->

    <!-- ═══ GATEWAYS ═══ -->
    <!-- ... -->

    <!-- ═══ END ═══ -->
    <endEvent id="end" name="End"/>

    <!-- ═══ SEQUENCE FLOWS ═══ -->
    <!-- List ALL flows at the bottom for readability -->
    <sequenceFlow id="flow_start_to_first" sourceRef="start" targetRef="..."/>

  </process>

</definitions>

4. Element patterns — copy-paste ready

userTask with assignee and data visibility

<userTask id="review_task" name="Review Request"
          camunda:assignee="{{variables.manager}}"
          camunda:candidateGroups="approvers">
  <extensionElements>
    <camunda:formData>
      <camunda:formField id="approved" label="Approved?" type="boolean"/>
      <camunda:formField id="comment"  label="Comment"   type="string"/>
    </camunda:formData>
  </extensionElements>
  <ioSpecification>
    <dataInput  id="in_amount"  name="amount"/>
    <dataInput  id="in_reason"  name="reason"/>
    <dataOutput id="out_approved" name="approved"/>
    <dataOutput id="out_comment"  name="comment"/>
  </ioSpecification>
  <incoming>flow_to_review</incoming>
  <outgoing>flow_from_review</outgoing>
</userTask>

serviceTask (webhook)

<serviceTask id="notify_erp" name="Notify ERP"
             implementation="webService">
  <extensionElements>
    <camunda:connector>
      <camunda:connectorId>webhook</camunda:connectorId>
    </camunda:connector>
  </extensionElements>
  <incoming>flow_to_notify</incoming>
  <outgoing>flow_from_notify</outgoing>
</serviceTask>

exclusiveGateway with conditions

<exclusiveGateway id="gw_approval" name="Approved?">
  <incoming>flow_to_gw</incoming>
  <outgoing>flow_approved</outgoing>
  <outgoing>flow_rejected</outgoing>
</exclusiveGateway>

<sequenceFlow id="flow_approved" sourceRef="gw_approval" targetRef="notify_approved">
  <conditionExpression xsi:type="tFormalExpression">{{variables.approved == true}}</conditionExpression>
</sequenceFlow>

<sequenceFlow id="flow_rejected" sourceRef="gw_approval" targetRef="end_rejected">
  <conditionExpression xsi:type="tFormalExpression">{{variables.approved == false}}</conditionExpression>
</sequenceFlow>

timerEvent (intermediate catch — wait N hours)

<intermediateCatchEvent id="wait_24h" name="Wait 24h">
  <incoming>flow_to_timer</incoming>
  <outgoing>flow_from_timer</outgoing>
  <timerEventDefinition>
    <timeDuration xsi:type="tFormalExpression">PT24H</timeDuration>
  </timerEventDefinition>
</intermediateCatchEvent>

boundaryEvent (timer, interrupting)

<boundaryEvent id="timeout_boundary" name="Timeout"
               attachedToRef="review_task"
               cancelActivity="true">
  <outgoing>flow_timeout</outgoing>
  <timerEventDefinition>
    <timeDuration xsi:type="tFormalExpression">PT48H</timeDuration>
  </timerEventDefinition>
</boundaryEvent>

businessRuleTask (DMN decision)

<!-- 'credit-score-decision' must be the id of a DMN definition already registered in the engine -->
<businessRuleTask id="credit_check" name="Credit Score Check"
                  camunda:decisionRef="credit-score-decision">
  <extensionElements>
    <camunda:in  variables="all"/>
    <camunda:out variables="all"/>
  </extensionElements>
  <incoming>flow_to_credit</incoming>
  <outgoing>flow_from_credit</outgoing>
</businessRuleTask>

messageStartEvent / messageCatchEvent

<!-- Start on external message -->
<startEvent id="start_on_message" name="Payment Received">
  <messageEventDefinition messageRef="msg_payment"/>
</startEvent>
<message id="msg_payment" name="payment_received"/>

<!-- Intermediate wait for message -->
<intermediateCatchEvent id="wait_payment" name="Wait for Payment">
  <incoming>flow_to_wait</incoming>
  <outgoing>flow_after_payment</outgoing>
  <messageEventDefinition messageRef="msg_payment"/>
</intermediateCatchEvent>

5. Expression syntax

This skill uses {{expression}} as the default condition syntax — not FEEL (#{}) and not UEL (${}). Expression syntax is engine-dependent; verify with your engine.

{{variables.amount > 1000}}                         → boolean condition
{{variables.status == 'approved'}}                  → string equality
{{variables.items.length > 0}}                      → array check
{{variables.manager || '[email protected]'}}      → fallback
{{variables.score >= 700 && variables.debt < 5000}} → compound

Use in:

  • <conditionExpression> on sequence flows
  • camunda:assignee attribute on userTask
  • Timer expressions only use ISO 8601 (no {{}} in timer values)

6. Validation checklist

Before outputting the final XML, verify every item:

  • Every element has a unique id
  • Every <sequenceFlow> has sourceRef and targetRef pointing to existing element IDs
  • Every element except end events has at least one <outgoing> child
  • Every element except start events has at least one <incoming> child
  • <exclusiveGateway> outgoing flows all have <conditionExpression> (except a default flow if default attribute is set)
  • <parallelGateway> used for both split AND join — the join must have multiple <incoming> matching the split's <outgoing>
  • <boundaryEvent> has attachedToRef pointing to a valid activity
  • Timer expressions are valid ISO 8601: durations start with P, dates are full UTC timestamps
  • isExecutable="true" on <process>
  • targetNamespace is set on <definitions>
  • No CMMN, Choreography, or DataStore elements (rarely supported by BPMN process engines)

7. Output format

  1. Always output the complete XML (never truncate with <!-- ... rest of process -->)

  2. Use consistent 2-space indentation

  3. Group flows at the end of the process element, after all nodes

  4. Add a brief inline comment above each logical section (START, ACTIVITIES, GATEWAYS, END, FLOWS)

  5. If the file is longer than ~150 lines, offer to also write a summary table of elements and flows

  6. After outputting the XML, remind the user to validate and upload it according to their engine's API.

  7. If the user requested a diagram layout, after writing the BPMN file apply layout via the reusable runner at /tmp/bpmn-layout-runner/layout.mjs:

    node /tmp/bpmn-layout-runner/layout.mjs <output-file> <output-file>
    

    If /tmp/bpmn-layout-runner/ does not exist yet, set it up first:

    mkdir -p /tmp/bpmn-layout-runner && \
    cd /tmp/bpmn-layout-runner && \
    npm init -y > /dev/null && \
    npm install bpmn-auto-layout && \
    node -e "
    import { readFileSync, writeFileSync } from 'fs';
    import { layoutProcess } from 'bpmn-auto-layout';
    const [,,i,o] = process.argv;
    writeFileSync(o||i, await layoutProcess(readFileSync(i,'utf8')), 'utf8');
    console.log('Layout applied.');
    " > layout.mjs
    

    Actually: write layout.mjs with the Write tool (see below), then run npm install bpmn-auto-layout inside /tmp/bpmn-layout-runner/.

    layout.mjs content:

    import { readFileSync, writeFileSync } from 'fs';
    import { layoutProcess } from 'bpmn-auto-layout';
    const [,, input, output] = process.argv;
    const xml = readFileSync(input, 'utf8');
    const layouted = await layoutProcess(xml);
    writeFileSync(output || input, layouted, 'utf8');
    console.log('Layout applied successfully.');
    

    This overwrites the file in-place, adding a <bpmndi:BPMNDiagram> section with auto-computed shapes and edges. Confirm to the user that layout was applied and the file is ready for bpmn.io.


8. Reference files

Read these when you need deeper detail — do not load them all at once:

FileWhen to read
references/elements.mdFull attribute reference for each element type
references/examples.md4 complete end-to-end BPMN examples (approval, onboarding, timer escalation, message correlation)
references/validation-errors.mdCommon bpmn-moddle parse errors and how to fix them

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.