@eventmodelers/cli 1.0.39 → 1.0.40

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.39",
3
+ "version": "1.0.40",
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": {
@@ -69,6 +69,7 @@ Slices are not placed directly — they're **derived** from a completed model. E
69
69
  - Invalid: `OrderSummaryProjector`, `InvoiceListRepository` — implementation detail leaking into the model
70
70
  - Optional — nothing requires a READMODEL to exist for a COMMAND or a downstream consumer.
71
71
  - Never drives COMMAND validation directly — a COMMAND is checked against its own documented preconditions, not a read model.
72
+ - **List-shaped read models**: when the whole READMODEL represents multiple rows (each row shaped by its defined fields), not a single projected record, set `meta.listElement: true` on the node itself — this is a node-level flag, distinct from a field's own `cardinality: "List"` (a single field holding multiple values). Every todo-list read model (see `eventmodeling-designing-automation-chains`) is list-shaped and always gets `listElement: true`; the same applies to any other READMODEL whose query naturally returns a set of rows (e.g. `ProductList`, `InvoiceList`). `eventmodeling-elaborating-scenarios` reads this flag to decide whether a scenario needs row-level `examples`/`expectEmptyList` instead of a single accumulated result.
72
73
 
73
74
  ### SCREEN
74
75
  - Represents what a user sees and can act on.
@@ -69,6 +69,8 @@ A todo-list read model's fields describe the pending item — the identity it's
69
69
 
70
70
  Every field must set a `mapping` per `eventmodeling-identifying-outputs`'s field data lineage rules (`"<EventTitle>.<fieldName>"`, `"latest:..."`, `"aggregate:..."`, `"derived:..."`), and `"cardinality"` (`"Single"` unless the field genuinely holds a list).
71
71
 
72
+ A todo-list read model is always list-shaped — it's a queue of pending items, never a single record — so it always gets **`meta.listElement: true`** on the node itself (see `eventmodeling-core-rules`'s READMODEL section). This is a node-level flag separate from any field's own `cardinality`.
73
+
72
74
  ## Placement — todo-list READMODEL, one column before its automation
73
75
 
74
76
  The todo-list read model goes in the interaction lane, **one column before** its automation (actor lane) — the automation's own column already holds the COMMAND it issues, so the read model can never share that column.
@@ -85,14 +87,14 @@ mcp__eventmodelers__place_element {
85
87
  "columnIndex": <automationColumnIndex - 1>
86
88
  }
87
89
  ```
88
- Then set `meta.fields` on the returned node id:
90
+ Then set `meta.fields` and `meta.listElement: true` on the returned node id:
89
91
  ```
90
92
  mcp__eventmodelers__submit_node_events {
91
93
  "boardId": "<BOARD_ID>",
92
94
  "events": [{
93
95
  "id": "<event-uuid>", "eventType": "node:changed", "nodeId": "<returned-node-id>",
94
96
  "boardId": "<BOARD_ID>", "timestamp": 1234567890,
95
- "meta": {"type": "READMODEL", "title": "NotificationsToSend", "fields": [...]}
97
+ "meta": {"type": "READMODEL", "title": "NotificationsToSend", "fields": [...], "listElement": true}
96
98
  }]
97
99
  }
98
100
  ```
@@ -145,4 +147,5 @@ List the result (connected / chain-resolved) for every automation checked — th
145
147
  - [ ] Every **worker**-stage todo-list read model's opening and closing events are identified, including the automation's own resulting event as a closing event
146
148
  - [ ] Every **translation**-stage todo-list read model has an opening event (the external EVENT) and **no closing event at all** — no backward arrow from its own internal EVENT back to its own todo list
147
149
  - [ ] No todo-list read model uses a `status` field instead of list membership
150
+ - [ ] Every todo-list read model has `meta.listElement: true` set on the node
148
151
  - [ ] Every todo-list read model sits one column before its automation, never sharing its column
@@ -386,7 +386,7 @@ Pass `compact: true` — you already hold every scenario object you sent, so the
386
386
 
387
387
  ### Step 4b — List-type readmodel scenario fields
388
388
 
389
- When `then` contains a READMODEL whose `listElement` property is `true`, add two fields **at the scenario level** (not inside `then`):
389
+ When `then` contains a READMODEL whose `listElement` property is `true` — set on the node when it was created, per `eventmodeling-core-rules`'s READMODEL section and `eventmodeling-identifying-outputs`/`eventmodeling-designing-automation-chains` — add two fields **at the scenario level** (not inside `then`):
390
390
 
391
391
  **`examples`** — one object per expected row, keyed by the readmodel's snake_case field names. Without this the spec node renders with no expected output and the scenario is unverifiable.
392
392
 
@@ -222,6 +222,8 @@ Set the field's `generated` property according to this table. Fields projected d
222
222
 
223
223
  Every field must also set `"cardinality"` — use `"Single"` unless the field genuinely holds a list of values (e.g. line items, a collection projected from multiple events), in which case use `"List"`. Default to `"Single"` when unsure. Include only the fields the consuming SCREEN or AUTOMATION actually displays or needs — do not add speculative fields; enrich later via `/attributes`.
224
224
 
225
+ If the READMODEL itself represents a set of rows rather than a single record — e.g. `InvoiceList`, `ProductList` — also set `meta.listElement: true` on the node (see `eventmodeling-core-rules`'s READMODEL section). This is separate from a field's `cardinality`: `listElement` says the whole read model is a list of elements shaped by its defined fields, `cardinality: "List"` says one field on an otherwise-single-record read model holds multiple values.
226
+
225
227
  ```json
226
228
  {
227
229
  "type": "READMODEL",
@@ -259,7 +261,7 @@ mcp__eventmodelers__place_element {
259
261
  "columnIndex": <consumerScreenColumnIndex> // or <automationColumnIndex - 1> for an AUTOMATION consumer
260
262
  }
261
263
  ```
262
- Then set `meta.fields` (with `mapping`/`generated`/`cardinality`) on the returned node id:
264
+ Then set `meta.fields` (with `mapping`/`generated`/`cardinality`) — and `meta.listElement: true` if this read model is list-shaped — on the returned node id:
263
265
  ```
264
266
  mcp__eventmodelers__submit_node_events {
265
267
  "boardId": "<BOARD_ID>",