@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.
- package/README.md +116 -69
- package/cli.js +98 -32
- package/package.json +4 -2
- package/shared/build-kit/lib/adapters/pocketbase-realtime-adapter.js +29 -0
- package/shared/build-kit/lib/adapters/realtime-adapter.js +27 -0
- package/shared/build-kit/lib/adapters/supabase-realtime-adapter.js +24 -0
- package/shared/build-kit/lib/ralph.js +30 -31
- package/shared/build-kit/package.json +3 -1
- package/shared/build-kit/ralph-claude.js +63 -5
- package/shared/skills/connect/SKILL.md +54 -5
- package/shared/skills/learn-eventmodelers-api/SKILL.md +88 -3
- package/shared/skills/load-slice/SKILL.md +16 -0
- package/shared/skills/update-slice-status/SKILL.md +15 -5
- package/stacks/modeling-kit/templates/.claude/skills/add-next-slice/SKILL.md +86 -0
- package/stacks/modeling-kit/templates/.claude/skills/analyze-existing-model/SKILL.md +29 -1
- package/stacks/modeling-kit/templates/.claude/skills/attributes/SKILL.md +47 -5
- package/stacks/modeling-kit/templates/.claude/skills/discover-storyboard/SKILL.md +73 -59
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-applying-conways-law/SKILL.md +1 -1
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-brainstorming-events/SKILL.md +100 -14
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-checking-completeness/SKILL.md +22 -2
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-designing-event-models/SKILL.md +1 -1
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-elaborating-scenarios/SKILL.md +30 -4
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-inputs/SKILL.md +72 -12
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-outputs/SKILL.md +66 -9
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-integrating-legacy-systems/SKILL.md +1 -1
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-orchestrating-event-modeling/SKILL.md +29 -5
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-plotting-events/SKILL.md +9 -1
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-slicing-event-models/SKILL.md +37 -3
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-storyboarding-events/SKILL.md +114 -27
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-translating-external-events/SKILL.md +1 -1
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-validating-event-models/SKILL.md +15 -3
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-validating-event-models-checklist/SKILL.md +13 -2
- package/stacks/modeling-kit/templates/.claude/skills/examples/SKILL.md +45 -7
- package/stacks/modeling-kit/templates/.claude/skills/handle-comment/SKILL.md +28 -1
- package/stacks/modeling-kit/templates/.claude/skills/html-screen/SKILL.md +45 -19
- package/stacks/modeling-kit/templates/.claude/skills/place-element/SKILL.md +172 -6
- package/stacks/modeling-kit/templates/.claude/skills/storyboard/SKILL.md +104 -25
- package/stacks/modeling-kit/templates/.claude/skills/storyboard-screen/SKILL.md +31 -17
- package/stacks/modeling-kit/templates/.claude/skills/timeline/SKILL.md +111 -12
- package/stacks/modeling-kit/templates/.claude/skills/update-prompt-status/SKILL.md +10 -1
- package/stacks/modeling-kit/templates/.claude/skills/wdyt/SKILL.md +24 -5
- package/stacks/modeling-kit/templates/kit/CLAUDE.md +12 -4
- package/stacks/node/templates/.claude/skills/build-state-view/SKILL.md +13 -7
- 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`.
|
|
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
|
|
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
|
|
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 (
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
##
|
|
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–
|
|
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
|
|
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
|
|
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
|
-
|
|
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/
|
|
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
|
-
"
|
|
162
|
-
"semanticDescription": "<screenTitle — what this screen shows>"
|
|
222
|
+
"pages": ["<div>...</div>"]
|
|
163
223
|
}'
|
|
164
224
|
```
|
|
165
225
|
|
|
166
|
-
|
|
226
|
+
**Sketch path (explicit request only) — `contentType: "sketch"`, plain SCREEN node:**
|
|
227
|
+
|
|
228
|
+
**Prefer MCP:**
|
|
167
229
|
|
|
168
|
-
|
|
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
|
-
|
|
242
|
+
**Fallback (no MCP):**
|
|
171
243
|
|
|
172
244
|
```bash
|
|
173
|
-
curl -s "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/
|
|
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
|
-
|
|
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
|
|
260
|
+
### Step 5c — Mark the task complete
|
|
182
261
|
|
|
183
|
-
After the node
|
|
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)
|
|
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
|
-
|
|
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 —
|
|
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)
|
|
136
|
+
- Whether the render succeeded (HTTP 204)
|
|
123
137
|
- Any errors
|