@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
@@ -9,7 +9,9 @@ allowed-tools:
9
9
 
10
10
  # Storyboarding Events
11
11
 
12
- > **Before doing anything else**, invoke the `connect` skill to resolve `TOKEN`, `BOARD_ID`, `ORG_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.
12
+ > **Before doing anything else**, invoke the `connect` skill — if not already connected — to resolve `TOKEN`, `BOARD_ID`, `ORG_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.
13
+
14
+ Prefer `mcp__eventmodelers__*` tools when available (registered by the `connect` skill) — the curl blocks below are the fallback for sessions without MCP connected.
13
15
 
14
16
  ## Interview Phase (Optional)
15
17
 
@@ -297,18 +299,27 @@ Solution: Every event includes timestamp
297
299
 
298
300
  ## Board Integration
299
301
 
300
- Before starting the analysis, read existing SCREEN nodes from the board to avoid designing screens that already exist:
302
+ Before starting the analysis, read existing screen nodes from the board to avoid designing screens that already exist. Screens created by this skill default to HTML_SCREEN, but older boards may still have plain SCREEN (sketch) nodes — check both types:
303
+
304
+ **Prefer MCP:**
305
+ ```
306
+ mcp__eventmodelers__get_nodes { "boardId": "$BOARD_ID", "type": "HTML_SCREEN" }
307
+ mcp__eventmodelers__get_nodes { "boardId": "$BOARD_ID", "type": "SCREEN" }
308
+ ```
301
309
 
310
+ **Fallback (no MCP):**
302
311
  ```bash
312
+ curl -s -H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID" \
313
+ "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?type=HTML_SCREEN"
303
314
  curl -s -H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID" \
304
315
  "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?type=SCREEN"
305
316
  ```
306
317
 
307
- After completing the screen analysis, use the `handle-comment` skill to post a QUESTION comment on any SCREEN node where data fields are unclear or missing sources are identified.
318
+ After completing the screen analysis, use the `handle-comment` skill to post a QUESTION comment on any screen node where data fields are unclear or missing sources are identified.
308
319
 
309
- ## Mandatory Field Definitions on SCREEN Nodes
320
+ ## Mandatory Field Definitions on Screen Nodes
310
321
 
311
- > **CRITICAL: Every SCREEN node MUST include `meta.fields` with a `mapping` on every field.** A screen without fields cannot show data lineage — it becomes impossible to verify that all displayed data has a source event or command.
322
+ > **CRITICAL: Every screen node MUST include `meta.fields` with a `mapping` on every field.** A screen without fields cannot show data lineage — it becomes impossible to verify that all displayed data has a source event or command. This applies regardless of which content type the screen renders as (HTML_SCREEN by default, or SCREEN when a sketch was explicitly requested).
312
323
 
313
324
  There are two types of screens, and each type has a different `mapping` source:
314
325
 
@@ -337,15 +348,15 @@ A **view screen** displays data read from a Read Model. Its fields map to the re
337
348
 
338
349
  ```json
339
350
  {
340
- "type": "SCREEN",
351
+ "type": "HTML_SCREEN",
341
352
  "title": "Reserve a Bike",
342
353
  "fields": [
343
- {"name": "bikeId", "type": "String", "example": "bike-17", "mapping": "ReserveBike.bikeId"},
344
- {"name": "stationId", "type": "String", "example": "stn-03", "mapping": "ReserveBike.stationId"},
345
- {"name": "startTime", "type": "Date", "example": "2026-06-01T09:00:00Z", "mapping": "ReserveBike.startTime"},
346
- {"name": "endTime", "type": "Date", "example": "2026-06-01T17:00:00Z", "mapping": "ReserveBike.endTime"},
347
- {"name": "bikeCategory","type": "String", "example": "City Bike", "mapping": "AvailableBikeView.category"},
348
- {"name": "dailyRate", "type": "Number", "example": "0.10", "mapping": "AvailableBikeView.ratePerMinute"}
354
+ {"name": "bikeId", "type": "String", "example": "bike-17", "mapping": "ReserveBike.bikeId"},
355
+ {"name": "stationId", "type": "String", "example": "stn-03", "mapping": "ReserveBike.stationId"},
356
+ {"name": "startTime", "type": "DateTime", "example": "2026-06-01T09:00:00Z", "mapping": "ReserveBike.startTime"},
357
+ {"name": "endTime", "type": "DateTime", "example": "2026-06-01T17:00:00Z", "mapping": "ReserveBike.endTime"},
358
+ {"name": "bikeCategory","type": "String", "example": "City Bike", "mapping": "AvailableBikeView.category"},
359
+ {"name": "dailyRate", "type": "Decimal", "example": "0.10", "mapping": "AvailableBikeView.ratePerMinute"}
349
360
  ]
350
361
  }
351
362
  ```
@@ -354,15 +365,15 @@ A **view screen** displays data read from a Read Model. Its fields map to the re
354
365
 
355
366
  ```json
356
367
  {
357
- "type": "SCREEN",
368
+ "type": "HTML_SCREEN",
358
369
  "title": "Reservation Confirmed",
359
370
  "fields": [
360
- {"name": "reservationId", "type": "String", "example": "res-001", "mapping": "ActiveReservationView.reservationId"},
361
- {"name": "bikeName", "type": "String", "example": "City Bike — Gazelle", "mapping": "ActiveReservationView.bikeName"},
362
- {"name": "stationName", "type": "String", "example": "Central Park East", "mapping": "ActiveReservationView.stationName"},
363
- {"name": "startTime", "type": "Date", "example": "2026-06-01T09:00:00Z", "mapping": "ActiveReservationView.startTime"},
364
- {"name": "expiresAt", "type": "Date", "example": "2026-06-01T09:30:00Z", "mapping": "ActiveReservationView.expiresAt"},
365
- {"name": "estimatedCost", "type": "Number", "example": "48.00", "mapping": "derived:durationHours × AvailableBikeView.ratePerMinute × 60"}
371
+ {"name": "reservationId", "type": "String", "example": "res-001", "mapping": "ActiveReservationView.reservationId"},
372
+ {"name": "bikeName", "type": "String", "example": "City Bike — Gazelle", "mapping": "ActiveReservationView.bikeName"},
373
+ {"name": "stationName", "type": "String", "example": "Central Park East", "mapping": "ActiveReservationView.stationName"},
374
+ {"name": "startTime", "type": "DateTime", "example": "2026-06-01T09:00:00Z", "mapping": "ActiveReservationView.startTime"},
375
+ {"name": "expiresAt", "type": "DateTime", "example": "2026-06-01T09:30:00Z", "mapping": "ActiveReservationView.expiresAt"},
376
+ {"name": "estimatedCost", "type": "Decimal", "example": "48.00", "mapping": "derived:durationHours × AvailableBikeView.ratePerMinute × 60"}
366
377
  ]
367
378
  }
368
379
  ```
@@ -383,14 +394,22 @@ Every field must also set `"cardinality"` — use `"Single"` unless the field ge
383
394
 
384
395
  A screen that only has a title and no fields is an empty placeholder — place the fields before moving on.
385
396
 
386
- ## Mandatory Sketch Rendering
397
+ ## Mandatory Screen Rendering
387
398
 
388
- Every SCREEN node requires a wireframe sketch. The correct order for every screen is:
399
+ Every screen node requires rendered content. **HTML_SCREEN (via the `html-screen` rendering path below) is the default for every screen** — render a real HTML/CSS mockup, not a wireframe sketch. Only use the sketch path (plain SCREEN node, grid elements) when the user's request explicitly asked for a "sketch", "wireframe", or "low-fidelity mockup". The correct order for every screen is:
389
400
 
390
401
  **Step A — Compute the cell ID.** Screens go in the **actor lane** of their target column.
391
402
 
392
403
  1. Determine the target column (same column as the event/command, OR one column to the right of the read model).
393
- 2. Fetch the chapter to find the actor row ID:
404
+ 2. Fetch the chapter to find the actor row ID.
405
+
406
+ **Prefer MCP:**
407
+ ```
408
+ mcp__eventmodelers__get_node { "boardId": "$BOARD_ID", "nodeId": "$CHAPTER_ID" }
409
+ # → meta.timelineData.rows — find the row where type === "actor"
410
+ ```
411
+
412
+ **Fallback (no MCP):**
394
413
  ```bash
395
414
  curl -s -H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID" \
396
415
  "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/$CHAPTER_ID"
@@ -398,7 +417,59 @@ Every SCREEN node requires a wireframe sketch. The correct order for every scree
398
417
  ```
399
418
  3. `cellId = actorRow.id + "-" + columnId`
400
419
 
401
- **Step B — Create the SCREEN node with `cellId`** (`node:created`) — the node is immediately placed in the correct cell:
420
+ **Step B (default) — Create the HTML_SCREEN node and render it in one atomic call.** Use `create_screen` with `contentType: "html"` — this creates the node, places it in `cellId`, and renders its pages together, so there is no window where the node exists without content:
421
+
422
+ **Prefer MCP:**
423
+ ```
424
+ mcp__eventmodelers__create_screen {
425
+ "boardId": "<BOARD_ID>",
426
+ "contentType": "html",
427
+ "nodeId": "<node-uuid>",
428
+ "chapterId": "<CHAPTER_ID>",
429
+ "cellId": "<actorRowId>-<columnId>",
430
+ "pages": ["<div>...</div>"],
431
+ "description": "<concise description of what this screen shows>"
432
+ }
433
+ ```
434
+
435
+ **Fallback (no MCP):**
436
+ ```bash
437
+ curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/html-screen-nodes/<node-uuid>" \
438
+ -H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID" -H "x-user-id: storyboarding-events" \
439
+ -H "Content-Type: application/json" \
440
+ -d '{
441
+ "chapterId": "<CHAPTER_ID>",
442
+ "cellId": "<actorRowId>-<columnId>",
443
+ "pages": ["<div>...</div>"]
444
+ }'
445
+ ```
446
+
447
+ Once the node is created, still set `meta.fields` on it (per "Mandatory Field Definitions" above) via `node:changed` — `create_screen`/the HTML endpoint owns page content, not the field-lineage metadata.
448
+
449
+ Design the page(s) as real HTML/CSS, following the `html-screen` skill's guidance: write full-size markup (16px body text, generous padding — the canvas scales it down, don't shrink it yourself), one complete self-contained fragment per page (no `<html>`/`<head>`/`<body>` wrapper — the canvas adds those), no `<script>`/inline handlers (stripped server-side), and Bulma CSS classes (`title`, `button`, `is-primary`, `field`/`control`/`input`, etc. — remember heading size modifiers like `class="title is-1"`) since Bulma 0.9.4 is loaded by default. Every page MUST include real field labels matching the actual event/command fields this screen captures or displays, and at least one primary action (submit/confirm button) for command screens.
450
+
451
+ > **CRITICAL: NEVER pass an empty `pages` array.** An empty pages array produces a blank placeholder and is always wrong. You MUST design and include actual page markup before calling the render API.
452
+
453
+ **Step B (sketch path, explicit request only) — Create the SCREEN node with `cellId`** (`node:created`) — only when the user explicitly asked for a wireframe/sketch:
454
+
455
+ **Prefer MCP:**
456
+ ```
457
+ mcp__eventmodelers__submit_node_events {
458
+ "boardId": "<BOARD_ID>",
459
+ "events": [{
460
+ "id": "<event-uuid>",
461
+ "eventType": "node:created",
462
+ "nodeId": "<node-uuid>",
463
+ "boardId": "<BOARD_ID>",
464
+ "timestamp": 1234567890,
465
+ "chapterId": "<CHAPTER_ID>",
466
+ "cellId": "<actorRowId>-<columnId>",
467
+ "meta": {"type": "SCREEN", "title": "<Screen Title>", "fields": [...]}
468
+ }]
469
+ }
470
+ ```
471
+
472
+ **Fallback (no MCP):**
402
473
  ```bash
403
474
  curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/events" \
404
475
  -H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID" -H "x-user-id: storyboarding-events" \
@@ -415,7 +486,7 @@ curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/events" \
415
486
  }]'
416
487
  ```
417
488
 
418
- **Step C — Render the wireframe sketch immediately** (`POST /images/$NODE_ID/sketch`).
489
+ **Step C (sketch path only) — Render the wireframe sketch immediately** (`POST /images/$NODE_ID/sketch`).
419
490
 
420
491
  > **Do NOT call `drop` after using `cellId` in `node:created`.** The drop endpoint adds a second cell reference without removing the first, causing the node to appear in two columns simultaneously. `node:created + cellId` is the single placement step — render the sketch right after.
421
492
 
@@ -423,6 +494,22 @@ curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/events" \
423
494
 
424
495
  Call the sketch API between node creation and cell placement, with a fully designed elements array:
425
496
 
497
+ **Prefer MCP:**
498
+ ```
499
+ mcp__eventmodelers__render_screen {
500
+ "boardId": "$BOARD_ID",
501
+ "nodeId": "$NODE_ID",
502
+ "description": "<concise description of what this screen shows>",
503
+ "elements": [
504
+ {"type":"rectangle","gridX":0,"gridY":0,"gridWidth":50,"gridHeight":40,"fill":"white"},
505
+ {"type":"rectangle","gridX":0,"gridY":0,"gridWidth":50,"gridHeight":3,"fill":"violet"},
506
+ {"type":"headline","gridX":2,"gridY":1,"text":"Screen Title","fontSize":16,"fill":"white","gridWidth":46},
507
+ ...more elements...
508
+ ]
509
+ }
510
+ ```
511
+
512
+ **Fallback (no MCP):**
426
513
  ```bash
427
514
  curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/images/$NODE_ID/sketch" \
428
515
  -H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID" -H "x-user-id: storyboarding-events" \
@@ -459,7 +546,7 @@ Every sketch MUST include at minimum:
459
546
  - Field labels that match the actual event/command fields this screen captures or displays
460
547
  - At least one primary action (submit button, confirm button, etc.) for command screens
461
548
 
462
- A screen node without a wireframe sketch is an empty placeholder. It must not be left unrendered.
549
+ A screen node without rendered content (HTML pages by default, or a wireframe sketch on the explicit-request path) is an empty placeholder. It must not be left unrendered.
463
550
 
464
551
  ## Timeline Placement Rules
465
552
 
@@ -497,7 +584,7 @@ Human roles get SCREEN nodes. System actors and processors get AUTOMATION nodes.
497
584
  ❌ Wrong: Member "My Loans" AND Librarian "Confirm Checkout" both in col 11
498
585
  ```
499
586
 
500
- If a second role also needs a screen related to the same event, insert a new column immediately after and place the second screen there. Use `POST /timelines/:tl/columns` with `{"index": N}` to insert at the correct position.
587
+ If a second role also needs a screen related to the same event, insert a new column immediately after and place the second screen there. Prefer `mcp__eventmodelers__add_column { "boardId": "$BOARD_ID", "timelineId": "$CHAPTER_ID", "index": N }`; fallback (no MCP) is `POST /timelines/:tl/columns` with `{"index": N}` to insert at the correct position.
501
588
 
502
589
  ---
503
590
 
@@ -593,7 +680,7 @@ Failure produces: [Event]
593
680
 
594
681
  ## Quality Checklist
595
682
 
596
- - [ ] **Every screen has a rendered wireframe sketch** (sketch API returned HTTP 204 — no exceptions)
683
+ - [ ] **Every screen has rendered content** — HTML pages by default (`create_screen`/`render_screen` with `contentType: "html"` returned success), or a wireframe sketch only when explicitly requested — no exceptions
597
684
  - [ ] **No column contains more than one SCREEN node** across all actor lanes
598
685
  - [ ] Every screen's wireframe shows real field labels matching the event/command fields
599
686
  - [ ] Every displayed field has a source event
@@ -9,7 +9,7 @@ allowed-tools:
9
9
 
10
10
  # Translating External Events
11
11
 
12
- > **Before doing anything else**, invoke the `connect` skill to resolve `TOKEN`, `BOARD_ID`, `ORG_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.
12
+ > **Before doing anything else**, invoke the `connect` skill — if not already connected — to resolve `TOKEN`, `BOARD_ID`, `ORG_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.
13
13
 
14
14
  ## Interview Phase (Optional)
15
15
 
@@ -8,7 +8,9 @@ allowed-tools:
8
8
 
9
9
  # Validating Event Models
10
10
 
11
- > **Before doing anything else**, invoke the `connect` skill to resolve `TOKEN`, `BOARD_ID`, `ORG_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.
11
+ > **Before doing anything else**, invoke the `connect` skill — if not already connected — to resolve `TOKEN`, `BOARD_ID`, `ORG_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.
12
+
13
+ Prefer `mcp__eventmodelers__*` tools when available (registered by the `connect` skill) — the curl blocks below are the fallback for sessions without MCP connected.
12
14
 
13
15
  For validation you treat the Event Model as read only. The only thing you are allowed to change is comments.
14
16
  For critical questions, add comments to elements.
@@ -21,7 +23,17 @@ The source can be also determined by looking at the defined Scenarios. Are all S
21
23
 
22
24
  ## Board Context
23
25
 
24
- Before starting, read the current board state to validate what is actually on the board:
26
+ Before starting, read the current board state to validate what is actually on the board.
27
+
28
+ Prefer MCP — call `mcp__eventmodelers__get_nodes` once per type (no header wiring needed, auth resolves from the connected session):
29
+
30
+ ```
31
+ mcp__eventmodelers__get_nodes { "boardId": "$BOARD_ID", "type": "EVENT" }
32
+ mcp__eventmodelers__get_nodes { "boardId": "$BOARD_ID", "type": "COMMAND" }
33
+ mcp__eventmodelers__get_nodes { "boardId": "$BOARD_ID", "type": "READMODEL" }
34
+ ```
35
+
36
+ **Fallback (no MCP):**
25
37
 
26
38
  ```bash
27
39
  curl -s -H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID" \
@@ -32,7 +44,7 @@ curl -s -H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID" \
32
44
  "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?type=READMODEL"
33
45
  ```
34
46
 
35
- After validation, use the `handle-comment` skill to post findings on the relevant nodes — `TASK` for critical violations that must be fixed, `QUESTION` for warnings and recommendations.
47
+ After validation, use the `handle-comment` skill to post findings on the relevant nodes — `TASK` for critical violations that must be fixed, `QUESTION` for warnings and recommendations. (That skill already handles the `add_comment` MCP-vs-curl choice internally — no separate rewrite needed here.)
36
48
 
37
49
  ## Purpose
38
50
  Ensures event-sourced models are complete, correct, and follow pure event sourcing principles (minimal per-command state).
@@ -8,7 +8,9 @@ allowed-tools:
8
8
 
9
9
  # Event Model Validation Checklist Skill
10
10
 
11
- > **Before doing anything else**, invoke the `connect` skill to resolve `TOKEN`, `BOARD_ID`, `ORG_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.
11
+ > **Before doing anything else**, invoke the `connect` skill — if not already connected — to resolve `TOKEN`, `BOARD_ID`, `ORG_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.
12
+
13
+ Prefer `mcp__eventmodelers__*` tools when available (registered by the `connect` skill) — the curl blocks below are the fallback for sessions without MCP connected.
12
14
 
13
15
  **Purpose**: Validate any event-sourced CQRS event model against 16 architectural checks across 7 phases. Identifies anti-patterns and confirms compliance with event sourcing principles.
14
16
 
@@ -35,6 +37,15 @@ allowed-tools:
35
37
 
36
38
  Read the current board state before running the checklist:
37
39
 
40
+ **Prefer MCP:** call `get_nodes` once per type, or pull the fuller graph in one shot with `get_slice_data` if you need events/commands/readmodels/screens/specs/actors together:
41
+
42
+ ```
43
+ mcp__eventmodelers__get_nodes { "boardId": "<BOARD_ID>", "type": "EVENT" }
44
+ mcp__eventmodelers__get_nodes { "boardId": "<BOARD_ID>", "type": "COMMAND" }
45
+ mcp__eventmodelers__get_nodes { "boardId": "<BOARD_ID>", "type": "READMODEL" }
46
+ ```
47
+
48
+ **Fallback (no MCP):**
38
49
  ```bash
39
50
  curl -s -H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID" \
40
51
  "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?type=EVENT"
@@ -44,7 +55,7 @@ curl -s -H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID" \
44
55
  "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?type=READMODEL"
45
56
  ```
46
57
 
47
- Use the board nodes as the model input. After the checklist, use `handle-comment` to post `TASK` comments on nodes that fail checks.
58
+ Use the board nodes as the model input. After the checklist, use `handle-comment` to post `TASK` comments on nodes that fail checks (that skill covers the MCP `add_comment`/curl choice for comment-posting itself).
48
59
 
49
60
  ## Validation Phases (Domain-Agnostic)
50
61
 
@@ -5,7 +5,9 @@ description: Find an element on an eventmodelers board by ID, name, or cell name
5
5
 
6
6
  # Examples
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
+
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
  You are adding or improving example data on an eventmodelers element. You find the element, read all linked elements for context, then generate realistic and consistent example values for every field that is missing one or has a weak example.
11
13
 
@@ -23,7 +25,27 @@ From `$ARGUMENTS`, extract:
23
25
 
24
26
  ---
25
27
 
26
- ## Step 2 — Resolve the element
28
+ ## Step 2 — Resolve and generate examples (prefer MCP)
29
+
30
+ `add_field_examples` is a whole-algorithm convenience tool: it resolves the node, loads linked neighbours for cross-element consistency, fills any empty field examples, and writes the result back — collapsing the entire "find node → find linked nodes → build examples → submit_node_events" flow (Steps 2–5 below) into one call. Call it with whichever identifier matches `target`:
31
+
32
+ - `target` is a UUID → pass `nodeId`
33
+ - `target` is a name → pass `name`
34
+ - `target` is a cell name (e.g. `B3`) → pass `cellName` + `timelineId` (the chapter id — if multiple chapters exist on the board, resolve which one first using 2c-fallback's chapter lookup, or `mcp__eventmodelers__get_nodes { "boardId": "$BOARD_ID", "type": "CHAPTER" }`, and ask the user if ambiguous)
35
+
36
+ ```
37
+ mcp__eventmodelers__add_field_examples { "boardId": "$BOARD_ID", "nodeId": "<target, if a UUID>" }
38
+ ```
39
+ ```
40
+ mcp__eventmodelers__add_field_examples { "boardId": "$BOARD_ID", "name": "<target, if a name>" }
41
+ ```
42
+ ```
43
+ mcp__eventmodelers__add_field_examples { "boardId": "$BOARD_ID", "cellName": "<target, if a cell name>", "timelineId": "$CHAPTER_ID" }
44
+ ```
45
+
46
+ If this succeeds, skip straight to Step 6 (report back), describing the fields the tool reports as changed. Use the manual fallback flow below (Steps 2–5) only if MCP isn't connected.
47
+
48
+ ### Fallback (no MCP) — Step 2: Resolve the element
27
49
 
28
50
  Try the resolution strategies in order until one succeeds.
29
51
 
@@ -70,7 +92,7 @@ From `meta.timelineData`, decode the cell name into a `cellId`:
70
92
  - Find the matching column in `columns` and the matching row in `rows`.
71
93
  - Compute: **`CELL_ID = row.id + "-" + column.id`** (cell IDs are always `<rowId>-<columnId>`).
72
94
 
73
- 3. **Always fetch the cell live** to get the current node list — do not rely on the `nodeId` in the chapter's cell data, as it may be stale:
95
+ 3. **Always fetch the cell live** to get the current node list — do not rely on the `nodeId` in the chapter's cell data, as it may be stale. No MCP equivalent: `get_nodes` only filters by `type`, not `cellId`:
74
96
 
75
97
  ```bash
76
98
  curl -s "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?cellId=$CELL_ID" \
@@ -85,7 +107,7 @@ Save the resolved node as `TARGET_NODE` (full JSON including `id`, `meta`, `edge
85
107
 
86
108
  ---
87
109
 
88
- ## Step 3 Load linked elements for context
110
+ ### Fallback (no MCP) — Step 3: Load linked elements for context
89
111
 
90
112
  Collect nearby elements to understand the domain context and generate consistent examples. **Never fetch all board nodes.** Only fetch specific nodes you already have IDs for.
91
113
 
@@ -116,7 +138,7 @@ For each neighbour element collected above (COMMAND, EVENT, READMODEL), extract
116
138
 
117
139
  ---
118
140
 
119
- ## Step 4 Generate improved examples
141
+ ### Fallback (no MCP) — Step 4: Generate improved examples
120
142
 
121
143
  For each field in `TARGET_NODE.meta.fields`:
122
144
 
@@ -143,9 +165,25 @@ Build the updated `fields` array: same structure as the original, only the `exam
143
165
 
144
166
  ---
145
167
 
146
- ## Step 5 Write the update
168
+ ### Fallback (no MCP) — Step 5: Write the update
169
+
170
+ **Prefer MCP** (only reachable if you did the resolve/generate steps manually but still have MCP available): same event body, passed as a tool arg instead of `-d`:
171
+ ```
172
+ mcp__eventmodelers__submit_node_events {
173
+ "boardId": "$BOARD_ID",
174
+ "events": [{
175
+ "id": "<uuid>",
176
+ "eventType": "node:changed",
177
+ "nodeId": "<TARGET_NODE.id>",
178
+ "boardId": "$BOARD_ID",
179
+ "timestamp": <epoch-ms>,
180
+ "changedAttributes": ["meta.fields"],
181
+ "meta": { "fields": "<updated-fields-array>" }
182
+ }]
183
+ }
184
+ ```
147
185
 
148
- Build the payload with Python to avoid shell JSON-escaping issues, then POST it:
186
+ **Fallback (no MCP at all)** — build the payload with Python to avoid shell JSON-escaping issues, then POST it:
149
187
 
150
188
  ```bash
151
189
  python3 - <<EOF > /tmp/examples_payload.json
@@ -5,7 +5,9 @@ description: Place, resolve, or delete a comment on an eventmodelers board node.
5
5
 
6
6
  # Handle Comment
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
+
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
  ---
11
13
 
@@ -29,6 +31,13 @@ Route to the matching section below based on `action`.
29
31
 
30
32
  ## Action: place
31
33
 
34
+ **Prefer MCP** — one call, `type` (`COMMENT`/`TASK`/`QUESTION`) passed straight through:
35
+
36
+ ```
37
+ mcp__eventmodelers__add_comment { "boardId": "$BOARD_ID", "nodeId": "$NODE_ID", "text": "<text>", "type": "<COMMENT|TASK|QUESTION>", "author": "<author>" }
38
+ ```
39
+
40
+ **Fallback (no MCP):**
32
41
  ```bash
33
42
  curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/$NODE_ID/comments" \
34
43
  -H "Authorization: Bearer $TOKEN" \
@@ -53,6 +62,12 @@ Type: <type> | Author: <author>
53
62
 
54
63
  **Step A — Resolve comment ID** (skip if `commentId` was provided directly):
55
64
 
65
+ **Prefer MCP:**
66
+ ```
67
+ mcp__eventmodelers__get_node_comments { "boardId": "$BOARD_ID", "nodeId": "$NODE_ID" }
68
+ ```
69
+
70
+ **Fallback (no MCP):**
56
71
  ```bash
57
72
  curl -s "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/$NODE_ID/comments" \
58
73
  -H "Authorization: Bearer $TOKEN"
@@ -62,6 +77,12 @@ Find the comment whose `text` contains the `text` argument (case-insensitive). I
62
77
 
63
78
  **Step B — Resolve:**
64
79
 
80
+ **Prefer MCP:**
81
+ ```
82
+ mcp__eventmodelers__update_comment { "boardId": "$BOARD_ID", "nodeId": "$NODE_ID", "commentId": "$COMMENT_ID", "action": "resolve" }
83
+ ```
84
+
85
+ **Fallback (no MCP):**
65
86
  ```bash
66
87
  curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/$NODE_ID/comments/$COMMENT_ID/resolve" \
67
88
  -H "Authorization: Bearer $TOKEN"
@@ -86,6 +107,12 @@ Wait for an explicit "yes". On any other response, stop: "Deletion cancelled."
86
107
 
87
108
  **Step C — Delete:**
88
109
 
110
+ **Prefer MCP:**
111
+ ```
112
+ mcp__eventmodelers__update_comment { "boardId": "$BOARD_ID", "nodeId": "$NODE_ID", "commentId": "$COMMENT_ID", "action": "delete" }
113
+ ```
114
+
115
+ **Fallback (no MCP):**
89
116
  ```bash
90
117
  curl -s -X DELETE "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/$NODE_ID/comments/$COMMENT_ID" \
91
118
  -H "Authorization: Bearer $TOKEN"
@@ -1,15 +1,17 @@
1
1
  ---
2
2
  name: html-screen
3
- description: Design and render a single real HTML/CSS screen (one or more pages) onto an HTML_SCREEN node — use only when the user explicitly asks for an HTML screen; sketches (storyboard-screen) remain the default for ordinary screen requests
3
+ description: Design and render a single real HTML/CSS screen (one or more pages) onto an HTML_SCREEN node — this is the default skill for any "design a screen" / "storyboard this" request; wireframe sketches (storyboard-screen) are used only when the user explicitly asks for one
4
4
  ---
5
5
 
6
6
  # HTML Screen Designer
7
7
 
8
- > **Before doing anything else**, invoke the `connect` skill to resolve `TOKEN`, `BOARD_ID`, `ORG_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`, `ORG_ID`, and `BASE_URL`. Do not proceed until the connect skill has completed.
9
9
 
10
- > **EXPLICIT USE ONLY**: Do not reach for this skill on an ordinary "design a screen" / "storyboard this" request that default remains `storyboard-screen`, which renders a wireframe sketch onto a SCREEN node. Use this skill **only** when the user explicitly asks for an "HTML screen", a "real webpage", a "coded/HTML mockup", or names the HTML_SCREEN node type directly.
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
11
 
12
- > **MANDATORY RENDER + VERIFY**: The render call in Step 4 and the verification in Step 5 are **not optional**. This skill exists solely to produce rendered pages. An HTML_SCREEN node with no non-empty page is an empty placeholder that adds no value to the model. If the render call is skipped or fails, or verification reports `valid: false`, the task is incomplete — retry or report the error.
12
+ > **DEFAULT SCREEN SKILL**: Reach for this skill on any ordinary "design a screen" / "storyboard this" request it is the default, rendering a real HTML/CSS mockup onto an HTML_SCREEN node. Use `storyboard-screen` (a low-fidelity wireframe sketch onto a plain SCREEN node) **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 render call in Step 4 is **not optional**. This skill exists solely to produce rendered pages. An HTML_SCREEN node with no non-empty page is an empty placeholder that adds no value to the model. If the render call is skipped or fails, the task is incomplete — retry or report the error.
13
15
 
14
16
  Design one or more HTML/CSS pages and render them onto an HTML_SCREEN node — creating the node if it doesn't exist yet, or updating it in place if it does. Use this to build a realistic, styled mockup (forms, tables, real page layout) rather than a wireframe sketch. Each page is a separate, standalone piece of markup — e.g. a multi-step form is one page per step, not one blob with hidden sections.
15
17
 
@@ -30,7 +32,15 @@ If neither `nodeId` nor (`chapterId` + `cellName`) can be resolved, ask the user
30
32
 
31
33
  ## Step 2 — If updating an existing screen, load its current pages first
32
34
 
33
- If `nodeId` refers to a screen that already has pages (i.e. this is an adjustment/tweak, or "add a page" to an existing screen — not a brand-new screen), **do not design from scratch**. Load the node and inspect `meta.pages`:
35
+ If `nodeId` refers to a screen that already has pages (i.e. this is an adjustment/tweak, or "add a page" to an existing screen — not a brand-new screen), **do not design from scratch**. Load the node and inspect `meta.pages`.
36
+
37
+ **Prefer MCP:**
38
+
39
+ ```
40
+ mcp__eventmodelers__get_node { "boardId": "<BOARD_ID>", "nodeId": "<NODE_ID>" }
41
+ ```
42
+
43
+ **Fallback (no MCP):**
34
44
 
35
45
  ```bash
36
46
  curl -s "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/$NODE_ID" \
@@ -60,6 +70,18 @@ Guidelines:
60
70
 
61
71
  **Updating an existing node** (`nodeId` was given) — always sends the **complete** pages array, not just the changed/new entry:
62
72
 
73
+ **Prefer MCP:**
74
+
75
+ ```
76
+ mcp__eventmodelers__render_screen {
77
+ "boardId": "<BOARD_ID>",
78
+ "nodeId": "<NODE_ID>",
79
+ "pages": ["<div>...</div>", "<div>...</div>"]
80
+ }
81
+ ```
82
+
83
+ **Fallback (no MCP):**
84
+
63
85
  ```bash
64
86
  curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/html-screens/$NODE_ID" \
65
87
  -H "x-token: $TOKEN" \
@@ -71,6 +93,21 @@ curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/html-screens/$NODE_I
71
93
 
72
94
  **Creating a new node** (no `nodeId` — one is generated and placed into `chapterId`/`cellName`):
73
95
 
96
+ **Prefer MCP:**
97
+
98
+ ```
99
+ mcp__eventmodelers__create_screen {
100
+ "boardId": "<BOARD_ID>",
101
+ "contentType": "html",
102
+ "nodeId": "<generated-uuid>",
103
+ "chapterId": "<CHAPTER_ID>",
104
+ "cellName": "<CELL_NAME>",
105
+ "pages": ["<div>...</div>"]
106
+ }
107
+ ```
108
+
109
+ **Fallback (no MCP):**
110
+
74
111
  ```bash
75
112
  NODE_ID=$(uuidgen)
76
113
  curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/html-screen-nodes/$NODE_ID" \
@@ -81,23 +118,12 @@ curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/html-screen-nodes/$N
81
118
  -d '{"chapterId": "'"$CHAPTER_ID"'", "cellName": "'"$CELL_NAME"'", "pages": ["<div>...</div>"]}'
82
119
  ```
83
120
 
84
- Expect `204 No Content` on success from either call.
85
-
86
- ## Step 5 — Verify the screen
87
-
88
- Confirm the node exists, is type HTML_SCREEN, and has at least one non-empty page:
89
-
90
- ```bash
91
- curl -s "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/html-screens/$NODE_ID/verify" \
92
- -H "x-token: $TOKEN"
93
- ```
94
-
95
- If `valid` is `false`, read the `error` field and retry the failing step once before reporting failure.
121
+ Expect `204 No Content` on success from either curl call.
96
122
 
97
- ## Step 6 — Report back
123
+ ## Step 5 — Report back
98
124
 
99
125
  Tell the user:
100
126
  - The node ID that was created or updated
101
127
  - How many pages the screen now has
102
- - Whether the render succeeded (HTTP 204) and verification passed (`valid: true`)
128
+ - Whether the render succeeded (HTTP 204)
103
129
  - Any errors