@eventmodelers/cli 1.0.22 → 1.0.24

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eventmodelers/cli",
3
- "version": "1.0.22",
3
+ "version": "1.0.24",
4
4
  "description": "Eventmodelers CLI — real-time Claude agent + skills for Claude Code, for any stack (Node, Supabase, Axon, Cratis, or modeling-only)",
5
5
  "type": "module",
6
6
  "bin": {
@@ -346,7 +346,9 @@ Does not produce commands (info-only)
346
346
 
347
347
  ## Output Format
348
348
 
349
- Instead of writing a markdown document, **place each READMODEL (and any missing AUTOMATION) on the board** using the `node:created` API. Screens are typically already placed from Step 3 (storyboarding) — do not re-place them unless one is clearly missing. Automations are placed here when analysis reveals a processor that reads state and issues commands but is not yet on the board.
349
+ Instead of writing a markdown document, **place each READMODEL (and any missing AUTOMATION) on the board** using the `node:created` API. Screens are typically already placed from Step 3 (storyboarding) as one plain screen per screen state Step 3 does not pre-split anything, so working out how many components a screen actually has is this step's job (Step 5a below), not something to re-derive from storyboarding's output. Do not re-place an existing screen unless one is clearly missing. Automations are placed here when analysis reveals a processor that reads state and issues commands but is not yet on the board.
350
+
351
+ This step proceeds as a sequence of lettered sub-steps: identify each screen's components (5a), break multi-component screens apart into copies (5b), then design and place one read model per component (5c onward).
350
352
 
351
353
  > **CRITICAL: Every READMODEL node MUST include `meta.fields` with a `mapping` on every field.** A read model without fields — or with fields that lack `mapping` — has no data lineage and cannot be traced back to its source events.
352
354
 
@@ -372,19 +374,39 @@ READ MODEL → AUTOMATION → COMMAND → EVENT
372
374
 
373
375
  Treat any screen or automation without an incoming read model as a gap unless it provably needs no prior state at all (e.g., a blank registration form).
374
376
 
375
- ### Read models serve existing screens and automations
377
+ ### Step 5a Enumerate consumers and identify components
376
378
 
377
- **Before designing any read model, enumerate every SCREEN and AUTOMATION already placed on the board** (from Step 3 — Storyboarding). Read models exist to serve those elements:
379
+ **Before designing any read model, enumerate every SCREEN and AUTOMATION already placed on the board** (from Step 3 — Storyboarding). Storyboarding hands off one plain screen per screen state and does not pre-split anything — deciding how many components a screen actually has is this step's decision, because a component is defined by its read model: **one component in a screen resembles one read model.**
378
380
 
381
+ Read models exist to serve the elements already on the board:
379
382
  - Every **view screen** (output/read model screen) needs at least one read model to supply its data.
380
383
  - Every **automation** that makes a decision based on system state needs at least one read model to read from.
381
384
  - Every **command/input screen** needs a read model unless it is a blank creation form with no prior state to display (this is the rare exception, not the rule).
382
385
 
383
- After the step is done, **every SCREEN and every AUTOMATION on the board must be connected to at least one read model** via a `READMODEL SCREEN` or `READMODEL AUTOMATION` connection. If a screen or automation has no incoming read model connection, it is a gapeither a read model is missing or the connection arrow is missing.
386
+ For each SCREEN node, look at its rendered layout and its `meta.fields` and identify its components groups of fields/UI elements a user would perceive as one area: a stats tile, a list below it, a summary card, a detail panel, a status column in a table, etc. **Most screens genuinely have exactly one componentdo not force a split.** A screen has more than one component only when a user would point at two separate areas and describe them as different things.
387
+
388
+ A single homogeneous list/table is still one component, even when its rows draw on many different event types (e.g. a catalog whose per-row status is set by many different lifecycle events scattered across the timeline). Splitting is about visually distinct *areas* of a screen, not about how many event types feed one area — don't split a table by row or by source event. Flag this kind of component as a **roll-up component**: its read model will legitimately need wide fan-in (many `EVENT → READMODEL` connections spanning much of the timeline) because it projects current state across an entity's full lifecycle rather than from one recent slice. This is expected, not a modeling error — but treat calling it a roll-up component as an **assumption**, not a fact, and document it as one: use the orchestrating skill's "Documenting decisions inline, at any step" mechanic (a MARKDOWN note in the feedback lane, placed in the component's column) to record explicitly *why* you concluded this is a legitimate single roll-up rather than an unsplit multi-component screen — e.g. "CopyAvailabilityView treated as one roll-up component: availability is a single per-copy status derived across that copy's full lifecycle (repair, loss, reservation, return), not several screen areas bundled together." That note is what lets a later reader (or reviewer) tell a deliberate roll-up apart from a missed split, instead of re-litigating or silently re-flagging it as a god read model.
389
+
390
+ After this step is done, **every SCREEN and every AUTOMATION on the board must be connected to at least one read model** via a `READMODEL → SCREEN` or `READMODEL → AUTOMATION` connection, and every screen identified above as having 2+ components must have been broken apart per Step 5b before any read model is placed. If a screen or automation has no incoming read model connection, it is a gap — either a read model is missing or the connection arrow is missing.
384
391
 
385
392
  > **Placement rule**: A read model must be placed in a column that already contains a SCREEN or AUTOMATION it serves. Do not place read models in columns with no screen or automation — doing so creates orphaned read models that will never have a consumer.
386
393
 
387
- ### Pull field mappings from Step 3they are the spec, not a guess
394
+ ### Step 5bBreak apart multi-component screens into copies
395
+
396
+ **Do not default to a single monolithic read model that supplies an entire screen.** For every screen identified in Step 5a as having 2+ components, break it apart into one screen copy per component before designing its read models:
397
+
398
+ - Each copy is the **same page**, so it **keeps the same screen name/title** — do not rename copies after their component (e.g. don't title one copy `"Librarian Dashboard — Statistics"` and another `"Librarian Dashboard — Recently Added"`; both stay `"Librarian Dashboard"`).
399
+ - Distinguish copies visually, not by name: **mark/highlight the one component each copy is about**, using the same CSS technique used throughout this workflow — de-emphasize every non-relevant component (`filter: blur(3px); opacity: 0.45; pointer-events: none;` on its wrapper) and leave the component of interest crisp, optionally with a highlight border class on it.
400
+ - Use the `html-screen` skill to produce each copy: pass it the original screen's markup plus which component to keep crisp. This is the skill's job — don't hand-roll the markup here.
401
+ - Place each copy in its own column, one column to the right of the read model that will feed it — this is normally a different column per copy, since each component typically has a different natural source event.
402
+
403
+ Why this matters, beyond tidiness:
404
+ - **It prevents backward arrows.** A single screen-wide read model is forced to aggregate from whatever events each of its components needs, which often means reaching back across many columns to events scattered throughout the timeline — and the read model can only sit in one column, so some of those connections end up spanning a wide gap or, worse, pushing the read model's column later than some of its screen's other consumers require. Splitting by component lets each narrower read model sit close to its own natural source event(s), keeping every `EVENT → READMODEL` arrow short and forward.
405
+ - **Components evolve independently.** A stats tile and a "recently added" list are driven by different events, change at different rates, and are typically owned by different slices in implementation. Bundling them into one read model couples their release/change cadence for no reason.
406
+
407
+ Before finalizing any read model, ask: "does this screen contain more than one component?" If yes and it wasn't already broken apart, do it now — don't ask whether it's worth the extra columns, it always is at this scale, since the alternative is a hidden coupling and a higher chance of a backward-arrow layout error.
408
+
409
+ ### Step 5c — Pull field mappings from Step 3 — they are the spec, not a guess
388
410
 
389
411
  **Do not re-derive read model needs from a screen's title or description alone, and do not rely on the orchestrator's phase-summary handoff for this** — if you arrived here via `eventmodeling-orchestrating-event-modeling`, the handoff after Step 3 is a short hand-written prose summary (`.trogonai/interviews/.../EVENTMODELING.md`), not the actual field data. It will not reliably carry the per-field mappings forward. Go back to the board itself:
390
412
 
@@ -394,7 +416,7 @@ For every SCREEN node, fetch it directly (`get_node`/`get_nodes`, never from mem
394
416
  - If a field's `mapping` names a read model that isn't `"<CommandTitle>.<fieldName>"` or `"session:..."` or `"derived:..."`, it is a read-model reference — treat it as a requirement, not a suggestion.
395
417
  - A screen with no fields, or with fields that carry no read-model-shaped mapping, is **not** evidence that it needs no read model. Re-check it against the three rules above (view screen / automation / command screen showing prior state) before concluding it's the rare blank-form exception — and say explicitly why it qualifies.
396
418
 
397
- ### Field data lineage — the `mapping` attribute on READMODEL fields
419
+ ### Step 5d — Field data lineage — the `mapping` attribute on READMODEL fields
398
420
 
399
421
  Every field on a READMODEL must carry a `mapping` that says exactly which event (or command) field it is projected from. Use one of these forms:
400
422
 
@@ -434,7 +456,7 @@ Read models go in the `interaction` lane — **in the same column as the SCREEN
434
456
 
435
457
  > **Timeline alignment rule**: Place the read model in the same column as its consumer screen/automation. If that column already holds a COMMAND (state-change slice occupies the interaction row), insert a new column immediately after (`{"index": N+1}`) and place both the READMODEL and any new SCREEN there. Do not append read model columns to the end of the timeline — doing so severs the visual left→right flow from data projection to UI consumption.
436
458
 
437
- ### Placing READMODEL and AUTOMATION nodes with `cellId` (Mandatory)
459
+ ### Step 5e — Placing READMODEL and AUTOMATION nodes with `cellId` (Mandatory)
438
460
 
439
461
  **Every `node:created` call MUST include `cellId`.** Without it the node has no cell reference and will appear stranded at position 0,0 — not in any timeline column.
440
462
 
@@ -510,7 +532,7 @@ mcp__eventmodelers__get_node { "boardId": "<BOARD_ID>", "nodeId": "<CHAPTER_ID>"
510
532
 
511
533
  > **Never call `drop` after using `cellId` in `node:created`.** The drop endpoint adds a second cell reference without removing the first. `node:created + cellId` is the only placement step needed.
512
534
 
513
- ### Preventing backward arrows (mandatory pre-placement check)
535
+ ### Step 5f — Preventing backward arrows (mandatory pre-placement check)
514
536
 
515
537
  The timeline must always progress left-to-right. A `READMODEL → SCREEN` connection going right-to-left is a layout error.
516
538
 
@@ -532,7 +554,7 @@ For each view screen S that queries this read model:
532
554
 
533
555
  **View screens go in the column immediately to the right of the read model they display** — either because they were placed there in Step 3, or because you move them here now.
534
556
 
535
- ### Wire connections after placing each READMODEL (and its SCREEN)
557
+ ### Step 5g — Wire connections after placing each READMODEL (and its SCREEN)
536
558
 
537
559
  After `place-element` returns the READMODEL node ID, create the arrows that complete the slice:
538
560
 
@@ -592,13 +614,14 @@ After `place-element` returns the READMODEL node ID, create the arrows that comp
592
614
 
593
615
  Skip a connection silently if the target cell is empty. Log each created arrow: `→ connected EVENT→READMODEL "OrderPlaced"→"OrderStatusView"`, `→ connected READMODEL→SCREEN "OrderStatusView"→"Order Status Screen"`, or `→ connected READMODEL→AUTOMATION "OrderStatusView"→"Fulfillment Processor"`.
594
616
 
595
- ### Mandatory per-node verification (run before declaring this step done)
617
+ ### Step 5h — Mandatory per-node verification (run before declaring this step done)
596
618
 
597
619
  Do not declare Step 5 complete on the strength of the read models you happened to design. Instead, **re-fetch every SCREEN and AUTOMATION node on the board** (`get_nodes` per type — don't rely on the list built earlier in this step, the board may have moved on) and check each one individually:
598
620
 
599
621
  1. Does it now have an incoming `READMODEL → SCREEN` or `READMODEL → AUTOMATION` connection?
600
622
  2. If not — is it a provably blank creation form with no prior state? State the reason in one line (e.g. `"Register Account" screen: blank form, no prior state — exempt`).
601
623
  3. If it's neither connected nor exempt, it is an **unresolved gap**. Fix it now: design the missing read model (pulling from its `meta.fields`/`mapping` as above) and wire the connection. Do not move to Step 6 with an unresolved gap silently carried forward — either fix it or explicitly flag it to the user as accepted debt.
624
+ 4. Does any screen still carry more than one component undivided (a Step 5a/5b miss)? If so, break it apart now per Step 5b before counting it as resolved.
602
625
 
603
626
  List the result of this pass (connected / exempt / fixed) for every screen and automation checked — this list is the evidence the orchestrator's Step 5 gate ("every screen data need is satisfied by a read model") actually holds, not just an assumption.
604
627
 
@@ -717,6 +740,9 @@ Identify UI needs without event sources:
717
740
  - [ ] **Every SCREEN from storyboarding is connected to at least one read model** (via `READMODEL → SCREEN`); only blank creation forms may be exempt — verified via the mandatory per-node pass above, not assumed
718
741
  - [ ] **Every AUTOMATION from storyboarding is connected to at least one read model** (via `READMODEL → AUTOMATION`) — same per-node verification
719
742
  - [ ] **No read model is placed without a connected SCREEN or AUTOMATION consumer**
743
+ - [ ] **No read model spans more than one component** — a screen with N distinct components gets N read models and N highlighted screen copies (same screen name, one component crisp per copy), not one screen-wide read model
744
+ - [ ] **Every multi-component screen was broken apart in Step 5b** — each copy keeps the original screen's name, differs only in which component is marked/highlighted
745
+ - [ ] **Roll-up components are flagged, not force-split** — a single homogeneous list/table with wide event fan-in is documented as an explicit assumption (inline MARKDOWN note, per "Documenting decisions inline"), not silently accepted or mistaken for an unsplit multi-component screen
720
746
  - [ ] Every read model has clear purpose
721
747
  - [ ] Every data field has event source
722
748
  - [ ] Update logic for each event is explicit
@@ -35,6 +35,13 @@ These rules govern how every element is placed on the board. Enforce them throug
35
35
  ### Never stack read models at the end
36
36
  Placing all read models in new columns at the very end of the timeline severs the visual connection to the events they're derived from. The board must show a coherent left-to-right narrative where each slice is self-contained.
37
37
 
38
+ ### One read model per component, not one read model per screen
39
+ A read model does not necessarily serve a whole screen — **one component in a screen resembles one read model.** Storyboarding (Step 3) only produces a plain screen per screen state; it does not decide components. That decision, and the work of breaking a multi-component screen apart into copies, happens in Step 5 (Identifying Outputs), because a component is defined by its read model.
40
+
41
+ A screen-wide read model that has to aggregate from events scattered across many columns is the most common source of unnecessary coupling — a "god read model." A screen with a stats row and a list below it is two components: two read models and two screen copies of the *same page* (same screen name on both copies; the copies differ only in which component is marked/highlighted crisp while the other is blurred/dimmed), not one screen-wide read model. Each narrower read model then sits naturally close to its own source event, and the `EVENT → READMODEL → SCREEN` chain for each component stays short and forward. See `eventmodeling-identifying-outputs`'s "Step 5a — Enumerate consumers and identify components" and "Step 5b — Break apart multi-component screens into copies" for the mechanics — apply this during Step 5, before the placement problem exists, rather than reordering columns to patch it afterward.
42
+
43
+ Not every wide fan-in is this problem, though: a single homogeneous list/table (e.g. a catalog whose per-row status comes from many different lifecycle events) is still **one** component, and its read model legitimately needs to subscribe to many events spread across the timeline — that's a "roll-up" component, not a god read model. Treat that classification as an assumption, not a given: `eventmodeling-identifying-outputs` Step 5a records it as an inline MARKDOWN note (per "Documenting decisions inline" above) explaining why the component is one roll-up rather than several bundled ones, instead of force-splitting it or letting it pass unremarked.
44
+
38
45
  ### No unplaced elements (0,0 nodes)
39
46
 
40
47
  After each step that creates elements (Steps 1–5), scan for any nodes that have no cell reference and are stranded at the default canvas position (0,0). These arise when `node:created` is called without `cellId`.
@@ -245,11 +252,13 @@ role or system processor.
245
252
 
246
253
  Invoke `eventmodeling-identifying-outputs`.
247
254
 
248
- **Input**: Event list + Commands from Step 4.
255
+ **Input**: Event list + Commands from Step 4 + the plain screens placed in Step 3.
249
256
  **Output to carry forward**: Read model definitions — projections of events
250
- optimized for UI and processor queries.
257
+ optimized for UI and processor queries — one per screen component, with any
258
+ multi-component screen already broken apart into same-named, highlighted
259
+ screen copies (this step's Step 5a/5b, not Step 3's job).
251
260
  **Gate**: Every screen data need from the storyboards is satisfied by a read
252
- model.
261
+ model, and no read model spans more than one component.
253
262
 
254
263
  ---
255
264
 
@@ -559,6 +559,10 @@ When placing screens on the board, follow these alignment rules:
559
559
 
560
560
  > **Do not create standalone screen columns that are disconnected from commands or read models.** Every screen must either share its column with the command it submits, or be placed one column to the right of the read model it displays.
561
561
 
562
+ ### Multi-component screens are broken apart in Step 5, not here
563
+
564
+ Storyboarding renders **one plain screen per screen state** — do not pre-split a screen into per-component copies here. Deciding how many components a view screen actually has, and breaking it apart into one highlighted copy per component, is `eventmodeling-identifying-outputs`'s job (its "Step 5a — Enumerate consumers and identify components" and "Step 5b — Break apart multi-component screens into copies"), because a component is defined by its read model and read models aren't designed until Step 5. During storyboarding, just place the single screen one column to the right of where its read model will end up (per the table above); document which read model it will query even before that read model exists.
565
+
562
566
  ### Placing Automations
563
567
 
564
568
  When a processor or system actor reacts to events automatically (no human interaction), place an **AUTOMATION** node in the actor row instead of a SCREEN. Automations go in the same column as the COMMAND they trigger and the READMODEL that feeds them.