@eventmodelers/cli 1.0.62 → 1.0.63
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.
|
|
3
|
+
"version": "1.0.63",
|
|
4
4
|
"description": "Eventmodelers CLI — real-time Claude agent + skills for Claude Code, for any stack (Node, Supabase, Axon, Cratis, OpenCQRS, UmaDB, Kurrent, or modeling-only)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -48,6 +48,7 @@ Server name: `eventmodelers`. Every tool takes `boardId` explicitly; none need `
|
|
|
48
48
|
| `get_slice_data` | `boardId`, `contextName?`, `contextId?`, `sliceId?` | Full element graph for slices in a context | §8 `GET /slicedata` |
|
|
49
49
|
| `get_spec_info` | `boardId`, `timelineId`, `elementTypes?` | EVENT/COMMAND/READMODEL nodes valid in GWT steps. Pass `elementTypes` (subset of `EVENT`/`COMMAND`/`READMODEL`) to avoid pulling the full element list when only one or two types are needed — filtered server-side, not just after a full fetch | §6 `GET .../spec-info` |
|
|
50
50
|
| `get_board_outline` | `boardId`, `chapterId` | One chapter's structure, compact: per-column node lists (`{id, type, title, lane}`) + a flat edge list, no HTML pages / field bodies / meta. The cheap "what is where and how is it wired" read — prefer over `get_nodes` (no projection) for orientation checks | — (MCP-only convenience) |
|
|
51
|
+
| `get_connected_nodes` | `boardId`, `nodeId`, `chapterId?`, `direction?` (`inbound`/`outbound`/`both`), `depth?`, `types?`, `includeFields?` | Neighbours of **one** node — what feeds it and what it feeds. Answers from a single anchor, unlike `get_attribute_chain` (which needs both ends of the chain as cell names up front). `depth` follows a whole chain; `types` filters the result only, never the traversal. Each neighbour carries `via`: `"edge"` for a real connection, `"layout"` when the node has none in that direction and the neighbour was inferred from the grid using auto-connect's own window (own column + adjacent one, forward-only pairs). Real edges always win. The `layout` fallback is what makes hand-built/imported chapters — which routinely carry **zero** edges — readable instead of falsely empty | — (MCP-only convenience) |
|
|
51
52
|
| `validate_model` | `boardId`, `chapterId`, `checks?[]` | Server-side Event Modeling structural checklist over one chapter — compact `findings` only. Checks: unplaced nodes, backward arrows (with the todo-list `EVENT→READMODEL` exception), zero/multi-issuer commands, sourceless read models, two-screens-in-a-column, missing scenarios. Replaces the manual per-type `get_nodes` + `get_node projection=edges` validation pass | — (MCP-only convenience) |
|
|
52
53
|
| `add_scenario` | `boardId`, `timelineId`, `columnId`, `scenarios[]`, `compact?` | Append GWT scenario(s) to a column's spec node. `compact: true` returns `{specNodeId, added, scenarioCount, isNewNode}` instead of echoing every scenario back | §6 `POST .../scenarios` |
|
|
53
54
|
| `add_storyline` | `boardId`, `timelineId`, `columnId`, `storylines[]`, `compact?` | Append storyline(s) (ordered, branchable beats over existing elements) to a column's spec node. Use whenever `eventmodeling-elaborating-scenarios`'s GWT-vs-storyline decision rule calls for one (e.g. a todo list's open→close lifecycle) — not only when a user explicitly names "storyline"; that skill's own per-read-model judgment is the trigger, this catalog entry isn't a stricter gate on top of it. `compact: true` suppresses the full storyline echo | §6 `POST .../storylines` |
|
|
@@ -61,16 +61,30 @@ edges: [{ id, source, target, sourceHandle, targetHandle }]
|
|
|
61
61
|
```
|
|
62
62
|
An **inbound** edge is one where `edge.target === currentNode.id`.
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
**Prefer `get_connected_nodes`** — it does this entire walk server-side, in one call, from the target alone:
|
|
65
|
+
```
|
|
66
|
+
mcp__eventmodelers__get_connected_nodes {
|
|
67
|
+
"boardId": "$BOARD_ID",
|
|
68
|
+
"nodeId": "<TARGET_NODE.id>",
|
|
69
|
+
"direction": "inbound",
|
|
70
|
+
"depth": 10,
|
|
71
|
+
"includeFields": true
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
The result is already ordered by `hops` (nearest first) and carries each node's `cellName` and `fields[]`, which is everything Step 4 needs — so this replaces both the edge walk and the per-node field fetch. Stop at the node matching `SOURCE_NODE`; anything beyond it is outside the requested chain.
|
|
75
|
+
|
|
76
|
+
Each neighbour reports `via`. `"edge"` means a real connection. `"layout"` means that node had no edge in that direction and the neighbour was inferred from the grid — correct, but worth a line in your Step 5 report so the user knows the chain was read off the layout rather than off wiring. A `chapterHasEdges: false` in the summary means the whole chapter is unwired.
|
|
65
77
|
|
|
66
|
-
Reach for a single-node fetch only for a node genuinely outside
|
|
78
|
+
Reach for a single-node fetch only for a node genuinely outside the anchor's chapter:
|
|
67
79
|
```
|
|
68
80
|
mcp__eventmodelers__get_node { "boardId": "$BOARD_ID", "nodeId": "$EDGE_SOURCE_ID", "projection": "edges" }
|
|
69
81
|
```
|
|
70
82
|
|
|
71
|
-
**Fallback (no MCP):** see `references/api-fallback.md` — "3a — Use Node Edges".
|
|
83
|
+
**Fallback (no MCP):** see `references/api-fallback.md` — "3a — Use Node Edges". Resolve the walk from **one** chapter-scoped read rather than a `get_node` per hop: `GET .../nodes?chapterId=` returns every node with full `meta`, `node.position` and `node.parentId` in a single response — index it and walk it locally.
|
|
72
84
|
|
|
73
85
|
### 3b — Column-based fallback (if no edges)
|
|
86
|
+
Only needed without MCP; `get_connected_nodes` already applies this rule itself and labels the result `via: "layout"`.
|
|
87
|
+
|
|
74
88
|
Hand-built or imported chapters frequently have **no edges at all** — every node comes back with `edges: []` and `get_board_outline`'s edge list is empty. That is not an error and not a reason to stop: in that case grid geometry *is* the chain. Use the chapter cell layout (already in memory from 3a) to find inbound neighbours:
|
|
75
89
|
|
|
76
90
|
In a standard event modeling layout:
|
|
@@ -7,6 +7,8 @@ description: Business analyst exploration of an event model board. Reads all sli
|
|
|
7
7
|
|
|
8
8
|
> **Before doing anything else**, invoke the `connect` skill — if not already connected — to resolve `TOKEN`, `BOARD_ID`, and `BASE_URL`. Do not proceed until the connect skill has completed.
|
|
9
9
|
|
|
10
|
+
Prefer `mcp__eventmodelers__*` tools when available (registered by the `connect` skill) — the REST calls below are the fallback for sessions without MCP connected.
|
|
11
|
+
|
|
10
12
|
This step applies the shared element rules in **`eventmodeling-core-rules`** — read it once per session if you haven't already; it defines what a COMMAND/EVENT/READMODEL/SCREEN/AUTOMATION is, the anti-patterns to reject, and the four Structural Shapes (Category I below), so this step doesn't restate them.
|
|
11
13
|
|
|
12
14
|
You are a **sharp business analyst** reviewing an event model. You don't know the domain yet — you're seeing it fresh. Your job is to read the model, understand the intended flows, and ask the hard questions that developers and domain experts tend to overlook because they're too close to the problem.
|
|
@@ -26,17 +28,27 @@ If the user already provided context name in their message, use it directly.
|
|
|
26
28
|
|
|
27
29
|
## Step 2 — Load the model
|
|
28
30
|
|
|
29
|
-
**
|
|
31
|
+
**Prefer MCP — one call loads the whole context.** `sliceId` is optional; omitting it returns the full element graph for *every* slice in the context at once. Do **not** list slices and then fetch them one by one:
|
|
32
|
+
|
|
30
33
|
```
|
|
31
|
-
|
|
34
|
+
mcp__eventmodelers__get_slice_data {
|
|
35
|
+
"boardId": "$BOARD_ID",
|
|
36
|
+
"contextName": "<context name from Step 1>",
|
|
37
|
+
"format": "textual"
|
|
38
|
+
}
|
|
32
39
|
```
|
|
33
|
-
This returns `{ slices: [{ id, title, status }] }`.
|
|
34
40
|
|
|
35
|
-
|
|
41
|
+
`format` matters here because this skill reads the entire model before it writes anything. `"textual"` is a compact markdown dump and `"toon"` a token-efficient tabular encoding — both carry the same graph as `"json"` in a fraction of the tokens. Use `"json"` only when you need to read exact `x`/`y`/`width`/`height` values for the drawings in Step 4.2.
|
|
42
|
+
|
|
43
|
+
Each response contains screens, commands, events, read models, specs, scenarios, actors, automations, and the edges between them.
|
|
44
|
+
|
|
45
|
+
`mcp__eventmodelers__list_slices { "boardId": "$BOARD_ID" }` is only needed when you must scope to **one** slice and don't know its id, or to read slice statuses — not as a precursor to loading the model.
|
|
46
|
+
|
|
47
|
+
**Fallback (no MCP):**
|
|
36
48
|
```
|
|
37
|
-
GET /api/org/{orgId}/boards/{boardId}/slicedata?contextName={contextName}
|
|
49
|
+
GET /api/org/{orgId}/boards/{boardId}/slicedata?contextName={contextName}
|
|
38
50
|
```
|
|
39
|
-
|
|
51
|
+
Same shape — the whole context in one request. `&sliceId={sliceId}` narrows it to one slice; `GET .../slicedata/slices` lists `{ slices: [{ id, title, status }] }`.
|
|
40
52
|
|
|
41
53
|
Keep track of:
|
|
42
54
|
- All slice titles and their element types
|
|
@@ -132,10 +144,30 @@ Only post questions that are **genuinely unclear or missing** — don't post obs
|
|
|
132
144
|
|
|
133
145
|
### 4.2 Drawings (every relational or clustered finding, always)
|
|
134
146
|
|
|
135
|
-
|
|
147
|
+
**Prefer MCP:** `mcp__eventmodelers__create_drawing` — one call per drawing, no auth headers needed.
|
|
148
|
+
|
|
149
|
+
**Fallback (no MCP):** `POST /api/org/{orgId}/boards/{boardId}/drawing/draw` (auth headers same as every other call — `x-token`, `x-board-id`, `x-user-id: wdyt`). Same fields as the tool args below.
|
|
136
150
|
|
|
137
|
-
|
|
138
|
-
|
|
151
|
+
There are two kinds — no text-callout kind; a drawing never carries the question itself, only the shape of the concern:
|
|
152
|
+
|
|
153
|
+
- **Arrow** (`kind: "path"`, `arrowEnd: true`) — the concern is about a missing or unclear relationship *between two elements* (e.g. "does this event actually reach this automation?"). Draw a straight line from one element's position to the other's. `path` is `M 0 0 L <dx> <dy>` in the box's own local coordinates; `x`/`y`/`width`/`height` describe that box in canvas space (so `width`/`height` = the delta between the two elements' positions).
|
|
154
|
+
```
|
|
155
|
+
mcp__eventmodelers__create_drawing {
|
|
156
|
+
"boardId": "$BOARD_ID", "kind": "path",
|
|
157
|
+
"x": <sourceX>, "y": <sourceY>, "width": <dx>, "height": <dy>,
|
|
158
|
+
"path": "M 0 0 L <dx> <dy>", "arrowEnd": true
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
Get element positions from the slice data already loaded in Step 2. If a position is missing, fetch the nodes you need in **one** call — `mcp__eventmodelers__get_nodes { "boardId": "$BOARD_ID", "nodeIds": [<the ids>] }` — not `get_node` per element.
|
|
162
|
+
- **Group loop** (`kind: "rect"`, drawn around a computed bounding box) — the concern spans a *cluster* of elements together (e.g. "this whole flow assumes nothing ever fails"). There's no dedicated group endpoint — union the elements' own `x`/`y`/`width`/`height` (plus some padding) yourself and draw one `rect` around that box:
|
|
163
|
+
```
|
|
164
|
+
mcp__eventmodelers__create_drawing {
|
|
165
|
+
"boardId": "$BOARD_ID", "kind": "rect",
|
|
166
|
+
"x": <minX - pad>, "y": <minY - pad>,
|
|
167
|
+
"width": <maxX - minX + 2*pad>, "height": <maxY - minY + 2*pad>
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
This is a visual grouping only — unrelated to the `MODEL_CONTEXT` node type; never touch a `modelContext` field to satisfy this.
|
|
139
171
|
|
|
140
172
|
Every arrow/group loop is paired with a comment on the relevant node(s) from 4.1 — the drawing makes the concern visible at a glance on the canvas itself, the comment carries the actual worded question. Post both; neither replaces the other.
|
|
141
173
|
|