Install
$ agentstack add skill-stateway-io-bpmn-xml-generator-bpmn-xml-generator ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ● Filesystem access Used
- ● Shell / process execution Used
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
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:
| Fact | Detail | |---|---| | Root namespace | xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" | | Root element | ` 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 | | | Conditions on flows | {{expression}} (engine-specific; verify with your engine — FEEL is the BPMN-standard alternative) | | Assignees / dynamic values | {{variables.fieldName}} inside string attributes | | DMN integration | — decisionRef must match the id of a DMN definition already registered in the engine | | IDs | All elements **must** have a unique id attribute. Convention: snakecase or PascalCaseN | | isExecutable | Always 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
implementationtype? (webhookorhttp) - [ ] 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
idof the DMN definition that must already exist in the engine? (Thatidgoes incamunda: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 todataInput/dataOutputinioSpecification) - [ ] Process-level variables — are there default/initial variable values?
- [ ] Diagram layout — do you want the output to include a visual layout (
BPMNDiagramsection), required by tools like bpmn.io? If yes,bpmn-auto-layoutwill be run automatically after saving (requires Node.js ≥ 18 and internet access fornpx).
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 element | Type | Notes | |---|---|---| | ` | startEvent | None, Timer, Message, Signal, Conditional | | | endEvent | None, Terminate, Message, Signal, Error, Escalation | | | intermediateCatchEvent | Timer, Message, Signal, Conditional | | | intermediateThrowEvent | Message, Signal, Escalation | | | boundaryEvent` | Timer (interrupting/non), Error, Message, Signal, Escalation |
Activities
| XML element | Type | Notes | |---|---|---| | ` | generic task | passes through immediately | | | userTask | assignee, candidateGroups, formKey, dueDate | | | serviceTask | implementation="webhook" or "http" | | | scriptTask | expression evaluated against variables | | | sendTask | dispatches message/webhook | | | receiveTask | waits for correlated message | | | businessRuleTask | camunda:decisionRef must contain the id of a previously registered DMN definition | | | callActivity | calls another process definition | | | subProcess` | embedded sub-flow |
Gateways
| XML element | Behavior | |---|---| | ` | XOR — exactly one outgoing flow taken | | | AND — all flows activated (join requires all tokens) | | | OR — one or more flows based on conditions | | ` | race — first event wins |
Connectors
| XML element | Notes | |---|---| | ` | sourceRef, targetRef, optional ` |
Not commonly supported by BPMN process engines
CMMN, Choreography, Conversation, DataStore, Association (rendered only).
3. XML structure template
flow_start_to_first
4. Element patterns — copy-paste ready
userTask with assignee and data visibility
flow_to_review
flow_from_review
serviceTask (webhook)
webhook
flow_to_notify
flow_from_notify
exclusiveGateway with conditions
flow_to_gw
flow_approved
flow_rejected
{{variables.approved == true}}
{{variables.approved == false}}
timerEvent (intermediate catch — wait N hours)
flow_to_timer
flow_from_timer
PT24H
boundaryEvent (timer, interrupting)
flow_timeout
PT48H
businessRuleTask (DMN decision)
flow_to_credit
flow_from_credit
messageStartEvent / messageCatchEvent
flow_to_wait
flow_after_payment
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 || 'default@company.com'}} → fallback
{{variables.score >= 700 && variables.debt ` 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 `` has `sourceRef` and `targetRef` pointing to existing element IDs
- [ ] Every element except end events has at least one `` child
- [ ] Every element except start events has at least one `` child
- [ ] `` outgoing flows all have `` (except a default flow if `default` attribute is set)
- [ ] `` used for both split AND join — the join must have multiple `` matching the split's ``
- [ ] `` 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 ``
- [ ] `targetNamespace` is set on ``
- [ ] No CMMN, Choreography, or DataStore elements (rarely supported by BPMN process engines)
---
## 7. Output format
1. Always output the complete XML (never truncate with ``)
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
```
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:**
```js
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 `` 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:
| File | When to read |
|---|---|
| `references/elements.md` | Full attribute reference for each element type |
| `references/examples.md` | 4 complete end-to-end BPMN examples (approval, onboarding, timer escalation, message correlation) |
| `references/validation-errors.md` | Common bpmn-moddle parse errors and how to fix them |
## Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- **Author:** [stateway-io](https://github.com/stateway-io)
- **Source:** [stateway-io/bpmn-xml-generator](https://github.com/stateway-io/bpmn-xml-generator)
- **License:** Apache-2.0
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.