@eventmodelers/cli 0.0.39 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +116 -69
  2. package/cli.js +98 -32
  3. package/package.json +4 -2
  4. package/shared/build-kit/lib/adapters/pocketbase-realtime-adapter.js +29 -0
  5. package/shared/build-kit/lib/adapters/realtime-adapter.js +27 -0
  6. package/shared/build-kit/lib/adapters/supabase-realtime-adapter.js +24 -0
  7. package/shared/build-kit/lib/ralph.js +30 -31
  8. package/shared/build-kit/package.json +3 -1
  9. package/shared/build-kit/ralph-claude.js +63 -5
  10. package/shared/skills/connect/SKILL.md +54 -5
  11. package/shared/skills/learn-eventmodelers-api/SKILL.md +88 -3
  12. package/shared/skills/load-slice/SKILL.md +16 -0
  13. package/shared/skills/update-slice-status/SKILL.md +15 -5
  14. package/stacks/modeling-kit/templates/.claude/skills/add-next-slice/SKILL.md +86 -0
  15. package/stacks/modeling-kit/templates/.claude/skills/analyze-existing-model/SKILL.md +29 -1
  16. package/stacks/modeling-kit/templates/.claude/skills/attributes/SKILL.md +47 -5
  17. package/stacks/modeling-kit/templates/.claude/skills/discover-storyboard/SKILL.md +73 -59
  18. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-applying-conways-law/SKILL.md +1 -1
  19. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-brainstorming-events/SKILL.md +100 -14
  20. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-checking-completeness/SKILL.md +22 -2
  21. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-designing-event-models/SKILL.md +1 -1
  22. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-elaborating-scenarios/SKILL.md +30 -4
  23. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-inputs/SKILL.md +72 -12
  24. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-outputs/SKILL.md +66 -9
  25. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-integrating-legacy-systems/SKILL.md +1 -1
  26. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-orchestrating-event-modeling/SKILL.md +29 -5
  27. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-plotting-events/SKILL.md +9 -1
  28. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-slicing-event-models/SKILL.md +37 -3
  29. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-storyboarding-events/SKILL.md +114 -27
  30. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-translating-external-events/SKILL.md +1 -1
  31. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-validating-event-models/SKILL.md +15 -3
  32. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-validating-event-models-checklist/SKILL.md +13 -2
  33. package/stacks/modeling-kit/templates/.claude/skills/examples/SKILL.md +45 -7
  34. package/stacks/modeling-kit/templates/.claude/skills/handle-comment/SKILL.md +28 -1
  35. package/stacks/modeling-kit/templates/.claude/skills/html-screen/SKILL.md +45 -19
  36. package/stacks/modeling-kit/templates/.claude/skills/place-element/SKILL.md +172 -6
  37. package/stacks/modeling-kit/templates/.claude/skills/storyboard/SKILL.md +104 -25
  38. package/stacks/modeling-kit/templates/.claude/skills/storyboard-screen/SKILL.md +31 -17
  39. package/stacks/modeling-kit/templates/.claude/skills/timeline/SKILL.md +111 -12
  40. package/stacks/modeling-kit/templates/.claude/skills/update-prompt-status/SKILL.md +10 -1
  41. package/stacks/modeling-kit/templates/.claude/skills/wdyt/SKILL.md +24 -5
  42. package/stacks/modeling-kit/templates/kit/CLAUDE.md +12 -4
  43. package/stacks/node/templates/.claude/skills/build-state-view/SKILL.md +13 -7
  44. package/stacks/supabase/templates/.claude/skills/build-state-view/SKILL.md +13 -7
@@ -5,7 +5,9 @@ description: Place a COMMAND, READMODEL, EVENT, SCREEN, AUTOMATION, or SCENARIO
5
5
 
6
6
  # Place Element
7
7
 
8
- > **Before doing anything else**, invoke the `connect` skill to resolve `TOKEN`, `BOARD_ID`, and `BASE_URL`. Then invoke the `learn-eventmodelers-api` skill to load the full API reference. Do not proceed until both skills have been loaded.
8
+ > **Before doing anything else**, invoke the `connect` skill — if not already connected — to resolve `TOKEN`, `BOARD_ID`, and `BASE_URL`. Do not proceed until it has completed. Consult `learn-eventmodelers-api` only if you need to look up a specific endpoint or field this file doesn't cover don't load it eagerly.
9
+
10
+ Prefer `mcp__eventmodelers__*` tools when available (registered by the `connect` skill) — the curl blocks below are the fallback for sessions without MCP connected.
9
11
 
10
12
  Place a single element — COMMAND, READMODEL, EVENT, SCREEN, AUTOMATION, or SCENARIO spec node — onto an existing timeline on an eventmodelers board. Uses an existing column when a position is given; only creates a new column when appending.
11
13
  ---
@@ -34,8 +36,36 @@ Use `BOARD_ID` and `BASE_URL` from the `connect` skill. If a `boardId` argument
34
36
 
35
37
  ---
36
38
 
39
+ ## Prefer MCP — `place_element` (COMMAND / READMODEL / EVENT only)
40
+
41
+ **When `elementType` is `COMMAND`, `READMODEL`, or `EVENT` and `position` is either omitted or a plain numeric column index** (not `"after <title>"`, not an explicit `cellName`), skip Steps 2–7b entirely and make one call:
42
+
43
+ ```
44
+ mcp__eventmodelers__place_element {
45
+ "boardId": "<BOARD_ID>",
46
+ "timelineId": "<TIMELINE_ID>",
47
+ "elementType": "<COMMAND|READMODEL|EVENT>",
48
+ "title": "<title>",
49
+ "columnIndex": <position, if given>
50
+ }
51
+ ```
52
+
53
+ This tool finds or creates an empty cell in the correct lane and places the node in one call — it collapses the "resolve timeline → fetch columns → determine lane → check occupancy → create node" sequence (Steps 2–3, 4, 6, 7b below) into a single round trip. If `timelineId` is unknown, resolve it first via Step 2's MCP call. Go straight to Step 8 once it returns.
54
+
55
+ **This does not cover**: `SCREEN`/`AUTOMATION`/`SCENARIO` (see their dedicated steps below), the `"after <title>"` position form, or an explicit `cellName` fast path (Step 1) — `place_element` has no way to express either. For those cases, or when MCP isn't connected, fall through to the manual steps below.
56
+
57
+ ---
58
+
37
59
  ## Step 2 — Resolve the timeline
38
60
 
61
+ **Prefer MCP:**
62
+
63
+ ```
64
+ mcp__eventmodelers__get_nodes { "boardId": "<BOARD_ID>", "type": "CHAPTER" }
65
+ ```
66
+
67
+ **Fallback (no MCP):**
68
+
39
69
  If `timelineId` is not provided, discover chapters on the board:
40
70
 
41
71
  ```bash
@@ -50,7 +80,15 @@ curl -s "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?type=CHAPTER"
50
80
 
51
81
  ## Step 3 — Fetch existing columns and resolve position
52
82
 
53
- Always fetch the chapter node first to get the current timeline state:
83
+ Always fetch the chapter node first to get the current timeline state.
84
+
85
+ **Prefer MCP:**
86
+
87
+ ```
88
+ mcp__eventmodelers__get_node { "boardId": "<BOARD_ID>", "nodeId": "<TIMELINE_ID>" }
89
+ ```
90
+
91
+ **Fallback (no MCP):**
54
92
 
55
93
  ```bash
56
94
  curl -s "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/$TIMELINE_ID"
@@ -91,6 +129,21 @@ The `/scenarios` endpoint creates the SCENARIO spec node automatically if the sp
91
129
 
92
130
  After resolving `columnId` (from step 3, or from step 5 if a new column was just created), call:
93
131
 
132
+ **Prefer MCP:**
133
+
134
+ ```
135
+ mcp__eventmodelers__add_scenario {
136
+ "boardId": "<BOARD_ID>",
137
+ "timelineId": "<TL>",
138
+ "columnId": "<COL>",
139
+ "scenarios": [ /* same scenario objects as the curl body below */ ]
140
+ }
141
+ ```
142
+
143
+ Same rules apply (given=EVENTs only, when=at most one COMMAND or QUERY, then=EVENTs only or exactly one READMODEL, `expectError`+`errorDescription` for error cases). This auto-creates the spec node if the cell is empty, same as the curl endpoint.
144
+
145
+ **Fallback (no MCP):**
146
+
94
147
  ```bash
95
148
  curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/timelines/$TL/columns/$COL/scenarios" \
96
149
  -H "x-token: $TOKEN" -H "Content-Type: application/json" \
@@ -150,7 +203,15 @@ Once `/scenarios` returns `201`, proceed directly to **Step 8** — report back
150
203
 
151
204
  **Skip this step entirely** when `columnId` was already resolved in Step 3 (i.e. the user targeted an existing column).
152
205
 
153
- Only run this when position was omitted (append mode):
206
+ Only run this when position was omitted (append mode).
207
+
208
+ **Prefer MCP:**
209
+
210
+ ```
211
+ mcp__eventmodelers__add_column { "boardId": "<BOARD_ID>", "timelineId": "<TIMELINE_ID>" }
212
+ ```
213
+
214
+ **Fallback (no MCP):**
154
215
 
155
216
  ```bash
156
217
  curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/timelines/$TIMELINE_ID/columns" \
@@ -176,7 +237,11 @@ Using the `timelineData` already fetched in Step 3 (re-fetch if a column was jus
176
237
 
177
238
  Cell IDs are always `<rowId>-<columnId>` — no cell array search needed.
178
239
 
179
- **Check if the cell is already occupied**: query nodes in that cell:
240
+ **Check if the cell is already occupied.**
241
+
242
+ **No direct MCP equivalent**: `get_nodes` only filters by `type`, not `cellId` — there is no MCP tool that filters nodes by cell. Instead, use the `meta.timelineData.cells` you already fetched in Step 3 via `get_node` on the chapter/timeline node: `cells` is a sparse array, so a `nodeId` absent from the entry for `CELL_ID` means the cell is empty. Only fall back to the curl call below if you haven't already loaded `timelineData` (e.g. MCP wasn't used in Step 3 either):
243
+
244
+ **Fallback (no MCP):**
180
245
 
181
246
  ```bash
182
247
  curl -s "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?cellId=$CELL_ID"
@@ -193,6 +258,14 @@ curl -s "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?cellId=$CELL_ID"
193
258
 
194
259
  **Insert immediately after** means: create the new column with `index = currentColumnIndex + 1`, not by appending to the end. This keeps the read model visually adjacent to the event that drives it.
195
260
 
261
+ **Prefer MCP:**
262
+
263
+ ```
264
+ mcp__eventmodelers__add_column { "boardId": "<BOARD_ID>", "timelineId": "<TIMELINE_ID>", "index": <currentColumnIndex + 1> }
265
+ ```
266
+
267
+ **Fallback (no MCP):**
268
+
196
269
  ```bash
197
270
  curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/timelines/$TIMELINE_ID/columns" \
198
271
  -H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID" -H "x-user-id: agent" \
@@ -208,7 +281,56 @@ If no matching row is found, stop and report the error — the timeline may be m
208
281
 
209
282
  ### Step 7a — SCREEN only: create and render in one atomic call
210
283
 
211
- **Only applies when `elementType === "SCREEN"`.** Do not create the node via `/nodes/events` first and render the sketch onto it in a second call — that leaves a window where the node exists with no image (an empty "Board Image" placeholder if anything interrupts between the two calls). Design the sketch elements first (same grid language as `storyboard-screen`), then send a single call that creates the node, places it, and renders the sketch together:
284
+ **Only applies when `elementType === "SCREEN"`.** Do not create the node via `/nodes/events` first and render its content onto it in a second call — that leaves a window where the node exists with no image (an empty "Board Image" placeholder if anything interrupts between the two calls). Send a single call that creates the node, places it, and renders it together.
285
+
286
+ **Default — HTML (`contentType: "html"`, HTML_SCREEN node):** design the page(s) as real HTML/CSS (see the `html-screen` skill's page-design guidance).
287
+
288
+ **Prefer MCP:**
289
+
290
+ ```
291
+ mcp__eventmodelers__create_screen {
292
+ "boardId": "<BOARD_ID>",
293
+ "contentType": "html",
294
+ "nodeId": "<node-uuid>",
295
+ "chapterId": "<TIMELINE_ID>",
296
+ "cellId": "<CELL_ID>",
297
+ "pages": ["<div>...</div>"],
298
+ "description": "<title — what this screen shows>"
299
+ }
300
+ ```
301
+
302
+ **Fallback (no MCP):**
303
+
304
+ ```bash
305
+ curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/html-screen-nodes/<node-uuid>" \
306
+ -H "x-token: $TOKEN" \
307
+ -H "x-board-id: $BOARD_ID" \
308
+ -H "x-user-id: agent" \
309
+ -H "Content-Type: application/json" \
310
+ -d '{
311
+ "chapterId": "<TIMELINE_ID>",
312
+ "cellId": "<CELL_ID>",
313
+ "pages": ["<div>...</div>"]
314
+ }'
315
+ ```
316
+
317
+ **Sketch path (explicit request only) — `contentType: "sketch"`, plain SCREEN node:** only use this when the user explicitly asked for a "sketch"/"wireframe"/"low-fidelity mockup". Design the sketch elements first (same grid language as `storyboard-screen`):
318
+
319
+ **Prefer MCP:**
320
+
321
+ ```
322
+ mcp__eventmodelers__create_screen {
323
+ "boardId": "<BOARD_ID>",
324
+ "contentType": "sketch",
325
+ "nodeId": "<node-uuid>",
326
+ "chapterId": "<TIMELINE_ID>",
327
+ "cellId": "<CELL_ID>",
328
+ "elements": [...],
329
+ "description": "<title — what this screen shows>"
330
+ }
331
+ ```
332
+
333
+ **Fallback (no MCP):**
212
334
 
213
335
  ```bash
214
336
  curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/image-nodes/<node-uuid>/sketch" \
@@ -224,14 +346,36 @@ curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/image-nodes/<node-uu
224
346
  }'
225
347
  ```
226
348
 
227
- Pass whichever cell reference you already resolved — `CELL_ID` from Step 6, or `CELL_NAME` from Step 1's fast path (the endpoint accepts either `cellId` or `cellName` field). Expect `204`. On `400`, read the validation error, fix the payload, and retry once. Then skip the rest of Step 7 and go to Step 8.
349
+ Pass whichever cell reference you already resolved — `CELL_ID` from Step 6, or `CELL_NAME` from Step 1's fast path (either path accepts `cellId` or `cellName`). Expect success (MCP: `created: true`; curl: `204`). On failure, read the validation error, fix the payload, and retry once. Then skip the rest of Step 7 and go to Step 8.
228
350
 
229
351
  ### Step 7b — All other element types
230
352
 
231
353
  Include `x-token`, `x-board-id`, and `x-user-id: agent` on every call to `/nodes/events`.
232
354
 
355
+ This step applies to `SCREEN` (view/output conflict case), `AUTOMATION`, `SCENARIO`-adjacent cleanup, and to `COMMAND`/`READMODEL`/`EVENT` whenever the "Prefer MCP — `place_element`" fast path above doesn't apply (explicit `cellName`, `"after <title>"` positioning, or conflict-insertion cases resolved manually in Step 6).
356
+
233
357
  **Normal path** (position/lane resolved manually in Steps 3–6) — use `cellId`:
234
358
 
359
+ **Prefer MCP:**
360
+
361
+ ```
362
+ mcp__eventmodelers__submit_node_events {
363
+ "boardId": "<BOARD_ID>",
364
+ "events": [{
365
+ "eventType": "node:created",
366
+ "nodeId": "<node-uuid>",
367
+ "boardId": "<BOARD_ID>",
368
+ "timestamp": <Date.now()>,
369
+ "chapterId": "<TIMELINE_ID>",
370
+ "cellId": "<CELL_ID>",
371
+ "meta": { "type": "<ELEMENT_TYPE>", "title": "<title>" },
372
+ "node": { "data": { "title": "<title>" } }
373
+ }]
374
+ }
375
+ ```
376
+
377
+ **Fallback (no MCP):**
378
+
235
379
  ```bash
236
380
  curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/events" \
237
381
  -H "x-token: $TOKEN" \
@@ -255,6 +399,26 @@ curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/events" \
255
399
 
256
400
  **Fast path** (`cellName` given directly, e.g. `"A2"` — see the Step 1 shortcut) — pass `cellName` instead of `cellId` and let the backend resolve it; nothing else in the payload changes:
257
401
 
402
+ **Prefer MCP:**
403
+
404
+ ```
405
+ mcp__eventmodelers__submit_node_events {
406
+ "boardId": "<BOARD_ID>",
407
+ "events": [{
408
+ "eventType": "node:created",
409
+ "nodeId": "<node-uuid>",
410
+ "boardId": "<BOARD_ID>",
411
+ "timestamp": <Date.now()>,
412
+ "chapterId": "<TIMELINE_ID>",
413
+ "cellName": "<CELL_NAME>",
414
+ "meta": { "type": "<ELEMENT_TYPE>", "title": "<title>" },
415
+ "node": { "data": { "title": "<title>" } }
416
+ }]
417
+ }
418
+ ```
419
+
420
+ **Fallback (no MCP):**
421
+
258
422
  ```bash
259
423
  curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/events" \
260
424
  -H "x-token: $TOKEN" \
@@ -304,6 +468,8 @@ Timeline: <timelineId>
304
468
 
305
469
  ## Example — place an EVENT via curl
306
470
 
471
+ **This whole example is the curl fallback.** With MCP connected, the same result is one call: `mcp__eventmodelers__place_element { "boardId": "<BOARD_ID>", "timelineId": "<TIMELINE_ID>", "elementType": "EVENT", "title": "Order Placed" }` (see "Prefer MCP" above).
472
+
307
473
  Full working example placing an EVENT called "Order Placed" at the end of a timeline:
308
474
 
309
475
  ```bash
@@ -1,13 +1,17 @@
1
1
  ---
2
2
  name: storyboard
3
- description: Build a complete visual storyboard with AI-generated screens from a natural language description — creates a chapter, N columns, and N custom sketch screens
3
+ description: Build a complete visual storyboard with AI-generated screens from a natural language description — creates a chapter, N columns, and N custom HTML screens (wireframe sketches only if explicitly requested)
4
4
  ---
5
5
 
6
6
  # Storyboard Builder
7
7
 
8
- > **Before doing anything else**, invoke the `connect` skill to resolve `TOKEN`, `BOARD_ID`, and `BASE_URL`. Do not proceed until the connect skill has completed.
8
+ > **Before doing anything else**, invoke the `connect` skill — if not already connected — to resolve `TOKEN`, `BOARD_ID`, and `BASE_URL`. Do not proceed until the connect skill has completed.
9
9
 
10
- You are building a complete visual storyboard by calling the board HTTP API. You generate the screen designs yourself using the grid description language below, then create the storyboard structure via `curl`. Only SCREEN nodes are created — no COMMAND or EVENT nodes.
10
+ Prefer `mcp__eventmodelers__*` tools when available (registered by the `connect` skill) the curl blocks below are the fallback for sessions without MCP connected.
11
+
12
+ > **HTML is the default content type**: every screen this skill creates is a real HTML/CSS mockup (`contentType: "html"`, HTML_SCREEN node) unless the user's request explicitly asks for a "sketch", "wireframe", or "low-fidelity mockup" — only then does a screen use the sketch path (`contentType: "sketch"`, plain SCREEN node) described under "Sketch path (explicit request only)" below. Decide this once per storyboard, before Step 2 — do not mix content types across screens in the same storyboard unless the user asked for that mix.
13
+
14
+ You are building a complete visual storyboard by calling the board API. You generate the screen designs yourself — HTML pages by default (see "HTML page design" below), or grid elements only when the sketch path applies — then create the storyboard structure via `mcp__eventmodelers__*` tools (or `curl` as a fallback — see each step below). Only SCREEN/HTML_SCREEN nodes are created — no COMMAND or EVENT nodes.
11
15
 
12
16
  ## Step 1 — Parse arguments
13
17
 
@@ -29,12 +33,27 @@ If `chapterId` is provided, skip chapter creation and go straight to Step 4.
29
33
  Before making any API calls, plan all N screens. For each screen, decide:
30
34
 
31
35
  - `screenTitle` — human-readable name (e.g. "Enter Credentials")
32
- - `elements` — a minimal list of grid elements (see language below, aim for 5–8 elements)
36
+ - `pages` (default) — one or more complete HTML/CSS fragments for this screen (see "HTML page design" below), or `elements` — a minimal list of grid elements (see "Sketch path" below, aim for 5–8 elements) **only** when the sketch path applies for this storyboard
33
37
  - `visualDescription` — a prose description of the screen's visual layout and content (2–4 sentences) that lets someone who cannot see the image understand what is shown: what UI sections appear, what text/labels are visible, where buttons and inputs are placed, and the overall purpose of the screen
34
38
 
35
39
  Then **create one task per screen** using TaskCreate, naming each task after the screen title. This gives you a visible queue of work. Create the screens directly after each task has been planned.
36
40
 
37
- ## Grid description language
41
+ ## HTML page design (default)
42
+
43
+ Write normal, full-size HTML/CSS for each screen — as if designing a real webpage, not a tiny thumbnail. The canvas node renders this at a real page width and visually scales it down to fit, so there is no need to shrink font sizes or padding.
44
+
45
+ - Each page is one complete, standalone HTML fragment — not a `data-step` div nested inside a shared blob. A multi-step flow is multiple pages, each fully self-contained.
46
+ - Inline styles (`style="..."`) are the simplest way to keep each page self-contained.
47
+ - No `<script>` tags, no inline event handlers (`onclick`, `onload`, ...), no `javascript:` URIs — these are stripped server-side before persisting. This is a static visual mockup, not an interactive prototype.
48
+ - A real page background (e.g. a light gray full-bleed background behind a centered white card) reads more realistically than a bare form floating on white.
49
+ - Don't add `<html>`/`<head>`/`<body>` tags — every page is a body-only fragment; the canvas wraps it at render time.
50
+ - Bulma CSS (0.9.4) is loaded by default — classes like `title`, `button`, `is-primary`, `field`/`control`/`input` etc. all work out of the box. Headings need a size modifier too, e.g. `class="title is-1"`.
51
+
52
+ ## Sketch path (explicit request only)
53
+
54
+ Only use this path when the user's request explicitly asked for a "sketch", "wireframe", or "low-fidelity mockup" for this storyboard. Otherwise skip straight to the HTML page design above.
55
+
56
+ ### Grid description language
38
57
 
39
58
  Canvas: **50 × 40 grid units** (1000 × 800 px, 1 unit = 20 px).
40
59
 
@@ -86,7 +105,15 @@ Keep all coordinates within bounds: gridX 0–50, gridY 0–40.
86
105
 
87
106
  **If `chapterId` was provided in Step 1** — set `CHAPTER_ID = chapterId` and skip to Step 4. Do not make any API call here.
88
107
 
89
- **If `chapterId` was NOT provided** — create a new chapter (exactly once):
108
+ **If `chapterId` was NOT provided** — create a new chapter (exactly once).
109
+
110
+ **Prefer MCP:**
111
+
112
+ ```
113
+ mcp__eventmodelers__create_chapter { "boardId": "<BOARD_ID>", "x": 0, "y": 0 }
114
+ ```
115
+
116
+ **Fallback (no MCP):**
90
117
 
91
118
  ```bash
92
119
  curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/chapters" \
@@ -100,6 +127,14 @@ Extract `id` from the response → `CHAPTER_ID`.
100
127
 
101
128
  ### Step 4 — Fetch chapter state and build empty-column queue
102
129
 
130
+ **Prefer MCP:**
131
+
132
+ ```
133
+ mcp__eventmodelers__get_node { "boardId": "<BOARD_ID>", "nodeId": "<CHAPTER_ID>" }
134
+ ```
135
+
136
+ **Fallback (no MCP):**
137
+
103
138
  ```bash
104
139
  curl -s "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/$CHAPTER_ID"
105
140
  ```
@@ -117,9 +152,9 @@ Build an **empty-column queue**: for each column (in order), compute `actorCellI
117
152
 
118
153
  ---
119
154
 
120
- ## SCREEN LOOP — repeat Steps 5a–5d once per screen (N iterations total)
155
+ ## SCREEN LOOP — repeat Steps 5a–5c once per screen (N iterations total)
121
156
 
122
- Process screens **one at a time**. Do not start the next screen until the current one is fully complete (node created + sketch rendered + verified).
157
+ Process screens **one at a time**. Do not start the next screen until the current one is fully complete (node created + sketch rendered).
123
158
 
124
159
  **You have ONE chapter (`CHAPTER_ID`). All screens go into this same chapter. Do NOT call the chapter creation endpoint again inside this loop.**
125
160
 
@@ -129,7 +164,15 @@ Only SCREEN nodes are created. COMMAND and EVENT nodes are not created.
129
164
 
130
165
  **If the empty-column queue is non-empty** — pop the first entry. Use its `actorCellId` directly, proceed to Step 5b.
131
166
 
132
- **If the empty-column queue is empty** — add a new column (this does NOT create a new chapter):
167
+ **If the empty-column queue is empty** — add a new column (this does NOT create a new chapter).
168
+
169
+ **Prefer MCP:**
170
+
171
+ ```
172
+ mcp__eventmodelers__add_column { "boardId": "<BOARD_ID>", "timelineId": "<CHAPTER_ID>" }
173
+ ```
174
+
175
+ **Fallback (no MCP):**
133
176
 
134
177
  ```bash
135
178
  curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/timelines/$CHAPTER_ID/columns" \
@@ -145,12 +188,30 @@ Extract `columnId` from the response. Compute the actor cell ID directly:
145
188
 
146
189
  **In both cases**, generate a node UUID: `SCREEN_NODE_ID`.
147
190
 
148
- ### Step 5b — Create the node and render the sketch in one atomic call
191
+ ### Step 5b — Create the node and render it in one atomic call
192
+
193
+ Build the payload, then send a single call that creates the screen node, places it into the actor cell, and renders its content — all in one request. There is no intermediate state where the node exists without content or without a cell.
194
+
195
+ **Default — HTML (`contentType: "html"`, HTML_SCREEN node):**
149
196
 
150
- Build the payload, then send a single call that creates the SCREEN node, places it into the actor cell, and renders the sketch — all in one request. There is no intermediate state where the node exists without an image or without a cell:
197
+ **Prefer MCP:**
198
+
199
+ ```
200
+ mcp__eventmodelers__create_screen {
201
+ "boardId": "<BOARD_ID>",
202
+ "contentType": "html",
203
+ "nodeId": "<SCREEN_NODE_ID>",
204
+ "chapterId": "<CHAPTER_ID>",
205
+ "cellId": "<actorCellId>",
206
+ "pages": ["<div>...</div>"],
207
+ "description": "<screenTitle — what this screen shows>"
208
+ }
209
+ ```
210
+
211
+ **Fallback (no MCP):**
151
212
 
152
213
  ```bash
153
- curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/image-nodes/$SCREEN_NODE_ID/sketch" \
214
+ curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/html-screen-nodes/$SCREEN_NODE_ID" \
154
215
  -H "x-token: $TOKEN" \
155
216
  -H "x-board-id: $BOARD_ID" \
156
217
  -H "x-user-id: agent" \
@@ -158,29 +219,47 @@ curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/image-nodes/$SCREEN_
158
219
  -d '{
159
220
  "chapterId": "<CHAPTER_ID>",
160
221
  "cellId": "<actorCellId>",
161
- "description": {"elements": [...]},
162
- "semanticDescription": "<screenTitle — what this screen shows>"
222
+ "pages": ["<div>...</div>"]
163
223
  }'
164
224
  ```
165
225
 
166
- Pass the already-computed `actorCellId` directly as `cellId` (the endpoint accepts either `cellId` or `cellName`). Expect `204`. On `400`, read the validation error, fix the payload, and retry once before reporting failure.
226
+ **Sketch path (explicit request only) `contentType: "sketch"`, plain SCREEN node:**
227
+
228
+ **Prefer MCP:**
167
229
 
168
- ### Step 5c — Verify the screen
230
+ ```
231
+ mcp__eventmodelers__create_screen {
232
+ "boardId": "<BOARD_ID>",
233
+ "contentType": "sketch",
234
+ "nodeId": "<SCREEN_NODE_ID>",
235
+ "chapterId": "<CHAPTER_ID>",
236
+ "cellId": "<actorCellId>",
237
+ "elements": [...],
238
+ "description": "<screenTitle — what this screen shows>"
239
+ }
240
+ ```
169
241
 
170
- Confirm the node and its rendered image both actually exist before moving on:
242
+ **Fallback (no MCP):**
171
243
 
172
244
  ```bash
173
- curl -s "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/screens/$SCREEN_NODE_ID/verify" \
174
- -H "x-token: $TOKEN"
245
+ curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/image-nodes/$SCREEN_NODE_ID/sketch" \
246
+ -H "x-token: $TOKEN" \
247
+ -H "x-board-id: $BOARD_ID" \
248
+ -H "x-user-id: agent" \
249
+ -H "Content-Type: application/json" \
250
+ -d '{
251
+ "chapterId": "<CHAPTER_ID>",
252
+ "cellId": "<actorCellId>",
253
+ "description": {"elements": [...]},
254
+ "semanticDescription": "<screenTitle — what this screen shows>"
255
+ }'
175
256
  ```
176
257
 
177
- Check the `valid` field in the response:
178
- - **`valid: true`** — proceed to marking the task complete.
179
- - **`valid: false`** — read the `error` field and retry Step 5b once. If it fails verification again, log the error for this screen in the final report and move on to the next screen — do not get stuck retrying indefinitely.
258
+ Pass the already-computed `actorCellId` directly as `cellId` in either path. Expect success (MCP: `created: true`; curl: `204`). On failure, read the validation error, fix the payload, and retry once before reporting failure.
180
259
 
181
- ### Step 5d — Mark the task complete
260
+ ### Step 5c — Mark the task complete
182
261
 
183
- After the node, sketch, and verification all succeed, mark the task for this screen as completed using TaskUpdate.
262
+ After the node and sketch succeed, mark the task for this screen as completed using TaskUpdate.
184
263
 
185
264
  ---
186
265
 
@@ -189,4 +268,4 @@ After the node, sketch, and verification all succeed, mark the task for this scr
189
268
  After all screens are done, summarise:
190
269
  - Chapter ID
191
270
  - Numbered list: screen title
192
- - Any errors (with status codes), including screens that failed the Step 5c verification
271
+ - Any errors (with status codes)
@@ -1,13 +1,17 @@
1
1
  ---
2
2
  name: storyboard-screen
3
- description: Design and render a single AI-generated wireframe screen onto an existing SCREEN node using the sketch API
3
+ description: Design and render a single AI-generated wireframe sketch screen onto an existing SCREEN node using the sketch API — use only when the user explicitly asks for a wireframe/sketch; html-screen is the default for ordinary screen requests
4
4
  ---
5
5
 
6
6
  # Storyboard Screen Designer
7
7
 
8
- > **Before doing anything else**, invoke the `connect` skill to resolve `TOKEN`, `BOARD_ID`, and `BASE_URL`. Do not proceed until the connect skill has completed.
8
+ > **Before doing anything else**, invoke the `connect` skill — if not already connected — to resolve `TOKEN`, `BOARD_ID`, and `BASE_URL`. Do not proceed until the connect skill has completed.
9
9
 
10
- > **MANDATORY RENDER + VERIFY**: The sketch API call in Step 4 and the verification in Step 5 are **not optional**. This skill exists solely to produce a rendered wireframe. A SCREEN node without a rendered sketch is an empty placeholder that adds no value to the model. If the sketch API call is skipped or fails, or verification reports `valid: false`, the task is incomplete retry or report the error.
10
+ Prefer `mcp__eventmodelers__*` tools when available (registered by the `connect` skill) the curl blocks below are the fallback for sessions without MCP connected.
11
+
12
+ > **EXPLICIT USE ONLY**: Do not reach for this skill on an ordinary "design a screen" / "storyboard this" request — the default is `html-screen`, which renders a real HTML/CSS mockup onto an HTML_SCREEN node. Use this skill **only** when the user explicitly asks for a "sketch", a "wireframe", a "low-fidelity mockup", or names the SCREEN node type directly.
13
+
14
+ > **MANDATORY RENDER**: The sketch API call in Step 4 is **not optional**. This skill exists solely to produce a rendered wireframe. A SCREEN node without a rendered sketch is an empty placeholder that adds no value to the model. If the sketch API call is skipped or fails, the task is incomplete — retry or report the error.
11
15
 
12
16
  Design a single wireframe screen and render it onto an existing SCREEN node. Use this to redesign a screen, add detail to a placeholder, or update a screen after a flow changes.
13
17
 
@@ -26,7 +30,15 @@ If `nodeId` is missing, ask for it before doing anything. `BOARD_ID` and `BASE_U
26
30
 
27
31
  ## Step 2 — If updating an existing screen, load its current description first
28
32
 
29
- If `nodeId` refers to a screen that has already been rendered (i.e. this is an adjustment/tweak, not a brand-new screen), **do not design from scratch**. First load the existing sketch description so the edit preserves the rest of the layout:
33
+ If `nodeId` refers to a screen that has already been rendered (i.e. this is an adjustment/tweak, not a brand-new screen), **do not design from scratch**. First load the existing sketch description so the edit preserves the rest of the layout.
34
+
35
+ **Prefer MCP:**
36
+
37
+ ```
38
+ mcp__eventmodelers__get_image_snapshot_description { "boardId": "<BOARD_ID>", "nodeId": "<NODE_ID>" }
39
+ ```
40
+
41
+ **Fallback (no MCP):**
30
42
 
31
43
  ```bash
32
44
  curl -s "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/images/$NODE_ID/description" \
@@ -93,6 +105,19 @@ Keep all coordinates within bounds: gridX 0–50, gridY 0–40.
93
105
 
94
106
  ## Step 4 — Render the sketch
95
107
 
108
+ **Prefer MCP:**
109
+
110
+ ```
111
+ mcp__eventmodelers__render_screen {
112
+ "boardId": "<BOARD_ID>",
113
+ "nodeId": "<NODE_ID>",
114
+ "elements": [...],
115
+ "description": "<what this screen shows>"
116
+ }
117
+ ```
118
+
119
+ **Fallback (no MCP):**
120
+
96
121
  ```bash
97
122
  curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/images/$NODE_ID/sketch" \
98
123
  -H "x-token: $TOKEN" \
@@ -104,20 +129,9 @@ curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/images/$NODE_ID/sket
104
129
 
105
130
  Expect `204 No Content` on success.
106
131
 
107
- ## Step 5 — Verify the screen
108
-
109
- Confirm the node and its rendered image both actually exist:
110
-
111
- ```bash
112
- curl -s "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/screens/$NODE_ID/verify" \
113
- -H "x-token: $TOKEN"
114
- ```
115
-
116
- If `valid` is `false`, read the `error` field and retry the failing step (Step 4 if `imageExists` is `false`) once before reporting failure.
117
-
118
- ## Step 6 — Report back
132
+ ## Step 5 — Report back
119
133
 
120
134
  Tell the user:
121
135
  - The node ID that was updated
122
- - Whether the render succeeded (HTTP 204) and verification passed (`valid: true`)
136
+ - Whether the render succeeded (HTTP 204)
123
137
  - Any errors