From threadline-ai
Use this skill when the user wants to produce an Excalidraw flow diagram from a use case or set of use cases. Triggers include 'generate an excalidraw file', 'make a flow diagram for this use case', 'visualise this use case', 'create a swim lane diagram', 'export this to excalidraw'. Also use automatically in the agentic pipeline after screen-inventory and before stakeholder review. Output is always a valid .excalidraw JSON file written to disk. Do NOT use for Figma files, wireframes, or high-fidelity design - this skill produces rough flow diagrams only.
How this skill is triggered — by the user, by Claude, or both
Slash command
/threadline-ai:excalidraw-generatorThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Produces valid `.excalidraw` JSON files from use cases. Each file contains swim lanes, the happy path, extension branches, rough screen mockups, and a legend.
Produces valid .excalidraw JSON files from use cases. Each file contains swim lanes, the happy path, extension branches, rough screen mockups, and a legend.
Excalidraw files are plain JSON with a .excalidraw extension. The file is opened by dragging it onto the canvas at excalidraw.com. The format is well-suited to AI generation because it is declarative: every element has an explicit position, size, and style.
Always write the file to disk. Do not output the JSON in the chat.
Every Excalidraw file has this top-level structure:
{
"type": "excalidraw",
"version": 2,
"source": "https://excalidraw.com",
"elements": [...],
"appState": {
"gridSize": null,
"viewBackgroundColor": "#ffffff"
},
"files": {}
}
All content lives in the elements array. Every element requires these base fields:
{
"id": "<unique 16-char alphanumeric string>",
"type": "<element type>",
"x": 0, "y": 0, "width": 0, "height": 0,
"angle": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"strokeStyle": "solid",
"roughness": 1,
"opacity": 100,
"groupIds": [],
"frameId": null,
"roundness": null,
"seed": <random integer>,
"version": 1,
"versionNonce": <random integer>,
"isDeleted": false,
"boundElements": null,
"updated": 1,
"link": null,
"locked": false
}
{
"type": "rectangle",
"roundness": { "type": 3 }
}
Set roughness: 1 for the hand-drawn aesthetic. Set roughness: 0 for lane backgrounds.
{
"type": "text",
"text": "Label text\nwith newlines",
"fontSize": 13,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "top",
"roundness": null
}
Every rectangle that needs a label requires a separate text element positioned inside it. Text elements do not inherit the parent rectangle's position — position them explicitly.
{
"type": "arrow",
"points": [[0, 0], [dx, dy]],
"startArrowhead": null,
"endArrowhead": "arrow",
"startBinding": null,
"endBinding": null,
"roundness": { "type": 2 }
}
Arrow x and y are the start point. points defines the path relative to the start. [dx, dy] is the displacement to the end point — calculate this from the target element's position.
Use a consistent layout across all use case diagrams so diagrams can be read as a set.
#888888One lane per actor. Lane backgrounds use roughness: 0 and roundness: null.
| Actor type | Background colour | Border colour |
|---|---|---|
| Human actor (primary) | #ddeeff | #aaccee |
| System | #f0f0f0 | #cccccc |
| Human actor (secondary) | #eeffee | #aaddaa |
Lane labels: text element at x=28, vertically centred in the lane, font size 13.
#ffffff, dark border #1e1e1e, roughness 1, rounded cornersstrokeStyle: "solid", color #1e1e1estrokeStyle: "dashed"#c8860a (amber)#1a7a36 (green)#fff3cd, border: #c8860a#d4edda, border: #1a7a36Rough UI sketches above the top actor lane (y = -120 relative to lane top).
Structure each mockup as:
#fafafa, border #666666, roughness 1#e0e0e0, border #666666, font size 10#eeeeee, border #cccccc, font size 9, stacked with 22px gapConnect mockups to their steps with dotted arrows (strokeStyle: "dotted", color #aaaaaa).
Place in the bottom-left corner, below all extension boxes:
──► happy path
- -► extension (alt/error)
····► screen reference
Three text elements, y spaced 18px apart, color #333333, font size 11.
.excalidraw file named UC-XX-[slug].excalidrawUse Python to generate the JSON. This avoids manual coordinate errors:
import json, random
def make_id():
return ''.join(random.choices('abcdefghijklmnopqrstuvwxyz0123456789', k=16))
def base_element(**kwargs):
el = {
"id": make_id(), "angle": 0, "fillStyle": "solid",
"strokeWidth": 2, "strokeStyle": "solid", "roughness": 1,
"opacity": 100, "groupIds": [], "frameId": None,
"seed": random.randint(1, 99999), "version": 1,
"versionNonce": random.randint(1, 99999),
"isDeleted": False, "boundElements": None,
"updated": 1, "link": None, "locked": False
}
el.update(kwargs)
return el
Build rectangle, text, and arrow helper functions on top of this base. Calculate all positions programmatically from the step count and lane count — do not hardcode coordinates.
Save to: /mnt/user-data/outputs/UC-XX-[title-slug].excalidraw
Confirm: "File written: UC-XX-[title-slug].excalidraw — open at excalidraw.com by dragging the file onto the canvas."
npx claudepluginhub bflandev/threadline-aiProvides UI/UX resources: 50+ styles, color palettes, font pairings, guidelines, charts for web/mobile across React, Next.js, Vue, Svelte, Tailwind, React Native, Flutter. Aids planning, building, reviewing interfaces.
Fetches up-to-date documentation from Context7 for libraries and frameworks like React, Next.js, Prisma. Use for setup questions, API references, and code examples.