@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
package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-storyboarding-events/SKILL.md
CHANGED
|
@@ -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`.
|
|
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
|
|
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
|
|
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
|
|
320
|
+
## Mandatory Field Definitions on Screen Nodes
|
|
310
321
|
|
|
311
|
-
> **CRITICAL: Every
|
|
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": "
|
|
351
|
+
"type": "HTML_SCREEN",
|
|
341
352
|
"title": "Reserve a Bike",
|
|
342
353
|
"fields": [
|
|
343
|
-
{"name": "bikeId", "type": "String",
|
|
344
|
-
{"name": "stationId", "type": "String",
|
|
345
|
-
{"name": "startTime", "type": "
|
|
346
|
-
{"name": "endTime", "type": "
|
|
347
|
-
{"name": "bikeCategory","type": "String",
|
|
348
|
-
{"name": "dailyRate", "type": "
|
|
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": "
|
|
368
|
+
"type": "HTML_SCREEN",
|
|
358
369
|
"title": "Reservation Confirmed",
|
|
359
370
|
"fields": [
|
|
360
|
-
{"name": "reservationId", "type": "String",
|
|
361
|
-
{"name": "bikeName", "type": "String",
|
|
362
|
-
{"name": "stationName", "type": "String",
|
|
363
|
-
{"name": "startTime", "type": "
|
|
364
|
-
{"name": "expiresAt", "type": "
|
|
365
|
-
{"name": "estimatedCost", "type": "
|
|
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
|
|
397
|
+
## Mandatory Screen Rendering
|
|
387
398
|
|
|
388
|
-
Every
|
|
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
|
|
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.
|
|
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
|
|
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`.
|
|
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
|
|
package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-validating-event-models/SKILL.md
CHANGED
|
@@ -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`.
|
|
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`.
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 —
|
|
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
|
-
|
|
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
|
-
> **
|
|
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
|
|
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)
|
|
128
|
+
- Whether the render succeeded (HTTP 204)
|
|
103
129
|
- Any errors
|