@eventmodelers/cli 1.0.36 → 1.0.38
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 +1 -1
- package/shared/skills/learn-eventmodelers-api/SKILL.md +22 -13
- package/stacks/modeling-kit/templates/.claude/skills/add-next-slice/SKILL.md +2 -23
- package/stacks/modeling-kit/templates/.claude/skills/add-next-slice/references/api-fallback.md +11 -0
- package/stacks/modeling-kit/templates/.claude/skills/analyze-existing-model/SKILL.md +6 -57
- package/stacks/modeling-kit/templates/.claude/skills/analyze-existing-model/references/api-fallback.md +68 -0
- package/stacks/modeling-kit/templates/.claude/skills/attributes/SKILL.md +4 -61
- package/stacks/modeling-kit/templates/.claude/skills/attributes/references/api-fallback.md +39 -0
- package/stacks/modeling-kit/templates/.claude/skills/discover-storyboard/SKILL.md +9 -53
- package/stacks/modeling-kit/templates/.claude/skills/discover-storyboard/references/api-fallback.md +63 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-applying-conways-law/SKILL.md +12 -380
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-applying-conways-law/references/examples.md +329 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-brainstorming-events/SKILL.md +45 -290
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-brainstorming-events/references/api-fallback.md +97 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-brainstorming-events/references/examples.md +35 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-checking-completeness/SKILL.md +15 -410
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-checking-completeness/references/api-fallback.md +22 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-checking-completeness/references/examples.md +397 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-core-rules/SKILL.md +182 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-designing-automation-chains/SKILL.md +148 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-designing-automation-chains/references/api-fallback.md +21 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-designing-event-models/SKILL.md +48 -448
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-designing-event-models/references/examples.md +167 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-elaborating-scenarios/SKILL.md +31 -380
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-elaborating-scenarios/references/api-fallback.md +31 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-elaborating-scenarios/references/examples.md +216 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-inputs/SKILL.md +33 -393
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-inputs/references/api-fallback.md +79 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-inputs/references/examples.md +282 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-outputs/SKILL.md +54 -454
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-outputs/references/api-fallback.md +67 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-outputs/references/examples.md +273 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-interview-protocol/SKILL.md +31 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-optimizing-stream-design/SKILL.md +37 -184
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-optimizing-stream-design/references/domain-patterns.md +58 -99
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-optimizing-stream-design/references/patterns.md +82 -163
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-orchestrating-event-modeling/SKILL.md +86 -78
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-orchestrating-event-modeling/references/api-fallback.md +51 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-plotting-events/SKILL.md +5 -5
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-plotting-events/references/api-fallback.md +10 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-slicing-event-models/SKILL.md +22 -51
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-slicing-event-models/references/api-fallback.md +41 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-slicing-event-models/references/examples.md +12 -9
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-slicing-event-models/references/patterns.md +1 -10
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-storyboarding-events/SKILL.md +29 -382
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-storyboarding-events/references/api-fallback.md +77 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-storyboarding-events/references/examples.md +271 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-translating-external-events/SKILL.md +12 -349
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-translating-external-events/references/examples.md +306 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-validating-event-models/SKILL.md +69 -107
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-validating-event-models/references/api-fallback.md +14 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-validating-event-models-checklist/SKILL.md +75 -160
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-validating-event-models-checklist/references/api-fallback.md +14 -0
- package/stacks/modeling-kit/templates/.claude/skills/examples/SKILL.md +3 -110
- package/stacks/modeling-kit/templates/.claude/skills/examples/references/api-fallback.md +118 -0
- package/stacks/modeling-kit/templates/.claude/skills/handle-comment/SKILL.md +5 -25
- package/stacks/modeling-kit/templates/.claude/skills/handle-comment/references/api-fallback.md +35 -0
- package/stacks/modeling-kit/templates/.claude/skills/html-screen/SKILL.md +9 -44
- package/stacks/modeling-kit/templates/.claude/skills/html-screen/references/api-fallback.md +51 -0
- package/stacks/modeling-kit/templates/.claude/skills/place-element/SKILL.md +34 -180
- package/stacks/modeling-kit/templates/.claude/skills/place-element/references/api-fallback.md +203 -0
- package/stacks/modeling-kit/templates/.claude/skills/storyboard/SKILL.md +14 -81
- package/stacks/modeling-kit/templates/.claude/skills/storyboard/references/api-fallback.md +74 -0
- package/stacks/modeling-kit/templates/.claude/skills/storyboard-screen/SKILL.md +4 -45
- package/stacks/modeling-kit/templates/.claude/skills/storyboard-screen/references/api-fallback.md +44 -0
- package/stacks/modeling-kit/templates/.claude/skills/timeline/SKILL.md +19 -88
- package/stacks/modeling-kit/templates/.claude/skills/timeline/references/api-fallback.md +91 -0
- package/stacks/modeling-kit/templates/.claude/skills/update-prompt-status/SKILL.md +1 -9
- package/stacks/modeling-kit/templates/.claude/skills/update-prompt-status/references/api-fallback.md +14 -0
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-integrating-legacy-systems/SKILL.md +0 -674
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-optimizing-stream-design/references/snapshotting.md +0 -204
|
@@ -7,7 +7,7 @@ description: Place a COMMAND, READMODEL, EVENT, SCREEN, AUTOMATION, or SCENARIO
|
|
|
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 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.
|
|
9
9
|
|
|
10
|
-
Prefer `mcp__eventmodelers__*` tools when available (registered by the `connect` skill) — the curl
|
|
10
|
+
Prefer `mcp__eventmodelers__*` tools when available (registered by the `connect` skill) — `references/api-fallback.md` has the curl fallback for every MCP call below, for sessions without MCP connected.
|
|
11
11
|
|
|
12
12
|
Place a single element — COMMAND, READMODEL, EVENT, SCREEN, AUTOMATION, or SCENARIO spec node — onto an existing timeline on an eventmodelers board. Uses an existing column when a position is given; only creates a new column when appending.
|
|
13
13
|
---
|
|
@@ -50,7 +50,7 @@ mcp__eventmodelers__place_element {
|
|
|
50
50
|
}
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
-
This tool finds or creates an empty cell in the correct lane and places the node in one call — it collapses the "resolve timeline → fetch columns → determine lane → check occupancy → create node" sequence (Steps 2–3, 4, 6, 7b below) into a single round trip. If `timelineId` is unknown, resolve it first via Step 2's MCP call. Go straight to Step 8 once it returns.
|
|
53
|
+
This tool finds or creates an empty cell in the correct lane and places the node in one call — it collapses the "resolve timeline → fetch columns → determine lane → check occupancy → create node" sequence (Steps 2–3, 4, 6, 7b below) into a single round trip. A `columnIndex` past the timeline's current column count is handled automatically (columns are added to reach it) — no need to pre-check the column count or catch an out-of-range error yourself. If `timelineId` is unknown, resolve it first via Step 2's MCP call. Pass `compact: true` for a smaller `{nodeId, cellName, columnIndex}` response (plus `connectedCount` if auto-connect wired an edge) when you don't need the full `lane`/`elementType`/`title`/`autoConnected` detail back. Go straight to Step 8 once it returns.
|
|
54
54
|
|
|
55
55
|
**This does not cover**: `SCREEN`/`AUTOMATION`/`SCENARIO` (see their dedicated steps below), the `"after <title>"` position form, or an explicit `cellName` fast path (Step 1) — `place_element` has no way to express either. For those cases, or when MCP isn't connected, fall through to the manual steps below.
|
|
56
56
|
|
|
@@ -64,13 +64,7 @@ This tool finds or creates an empty cell in the correct lane and places the node
|
|
|
64
64
|
mcp__eventmodelers__get_nodes { "boardId": "<BOARD_ID>", "type": "CHAPTER" }
|
|
65
65
|
```
|
|
66
66
|
|
|
67
|
-
**Fallback (no MCP):**
|
|
68
|
-
|
|
69
|
-
If `timelineId` is not provided, discover chapters on the board:
|
|
70
|
-
|
|
71
|
-
```bash
|
|
72
|
-
curl -s "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?type=CHAPTER"
|
|
73
|
-
```
|
|
67
|
+
**Fallback (no MCP):** see `references/api-fallback.md` — "Step 2 — Discover chapters". If `timelineId` is not provided, this discovers chapters on the board.
|
|
74
68
|
|
|
75
69
|
- **Exactly one chapter** → use it automatically, tell the user which one was selected.
|
|
76
70
|
- **Multiple chapters** → list them by name/ID and ask the user which to target.
|
|
@@ -80,21 +74,17 @@ curl -s "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?type=CHAPTER"
|
|
|
80
74
|
|
|
81
75
|
## Step 3 — Fetch existing columns and resolve position
|
|
82
76
|
|
|
83
|
-
Always fetch the chapter node first to get the current timeline state.
|
|
77
|
+
Always fetch the chapter node first to get the current timeline state — `projection: "cells"` returns just `{rows, columns, cells}`, not the whole chapter node.
|
|
84
78
|
|
|
85
79
|
**Prefer MCP:**
|
|
86
80
|
|
|
87
81
|
```
|
|
88
|
-
mcp__eventmodelers__get_node { "boardId": "<BOARD_ID>", "nodeId": "<TIMELINE_ID>" }
|
|
82
|
+
mcp__eventmodelers__get_node { "boardId": "<BOARD_ID>", "nodeId": "<TIMELINE_ID>", "projection": "cells" }
|
|
89
83
|
```
|
|
90
84
|
|
|
91
|
-
**Fallback (no MCP):**
|
|
85
|
+
**Fallback (no MCP):** see `references/api-fallback.md` — "Step 3 — Fetch the chapter node".
|
|
92
86
|
|
|
93
|
-
|
|
94
|
-
curl -s "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/$TIMELINE_ID"
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
From `meta.timelineData`, read `columns` (ordered array of column objects with `id` and `index`) and `cells`.
|
|
87
|
+
Read `columns` (ordered array of column objects with `id` and `index`) and `cells` (from the result directly via MCP, or from `meta.timelineData` via the REST fallback).
|
|
98
88
|
|
|
99
89
|
Then resolve `position`:
|
|
100
90
|
|
|
@@ -142,31 +132,7 @@ mcp__eventmodelers__add_scenario {
|
|
|
142
132
|
|
|
143
133
|
Same rules apply (given=EVENTs only, when=at most one COMMAND or QUERY, then=EVENTs only or exactly one READMODEL, `expectError`+`errorDescription` for error cases). This auto-creates the spec node if the cell is empty, same as the curl endpoint.
|
|
144
134
|
|
|
145
|
-
**Fallback (no MCP):**
|
|
146
|
-
|
|
147
|
-
```bash
|
|
148
|
-
curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/timelines/$TL/columns/$COL/scenarios" \
|
|
149
|
-
-H "x-token: $TOKEN" -H "Content-Type: application/json" \
|
|
150
|
-
-d '[
|
|
151
|
-
{
|
|
152
|
-
"id": "<scenario-uuid>",
|
|
153
|
-
"title": "Happy path",
|
|
154
|
-
"given": [{"id":"<eventNodeId>","title":"OrderPlaced","type":"EVENT"}],
|
|
155
|
-
"when": [{"id":"<commandNodeId>","title":"PlaceOrder","type":"COMMAND"}],
|
|
156
|
-
"then": [{"id":"<eventNodeId2>","title":"OrderConfirmed","type":"EVENT"}]
|
|
157
|
-
},
|
|
158
|
-
{
|
|
159
|
-
"id": "<scenario-uuid>",
|
|
160
|
-
"title": "Insufficient stock",
|
|
161
|
-
"given": [{"id":"<eventNodeId>","title":"OrderPlaced","type":"EVENT"}],
|
|
162
|
-
"when": [{"id":"<commandNodeId>","title":"PlaceOrder","type":"COMMAND"}],
|
|
163
|
-
"then": [],
|
|
164
|
-
"expectError": true,
|
|
165
|
-
"errorDescription": "Stock below requested quantity"
|
|
166
|
-
}
|
|
167
|
-
]'
|
|
168
|
-
# → 201 { specNodeId, scenarios (all), added (count), isNewNode }
|
|
169
|
-
```
|
|
135
|
+
**Fallback (no MCP):** see `references/api-fallback.md` — "Step 4a — SCENARIO: append scenarios via the spec endpoint" for the full curl call and example payload.
|
|
170
136
|
|
|
171
137
|
**Scenario object shapes:**
|
|
172
138
|
|
|
@@ -211,18 +177,7 @@ Only run this when position was omitted (append mode).
|
|
|
211
177
|
mcp__eventmodelers__add_column { "boardId": "<BOARD_ID>", "timelineId": "<TIMELINE_ID>" }
|
|
212
178
|
```
|
|
213
179
|
|
|
214
|
-
**Fallback (no MCP):**
|
|
215
|
-
|
|
216
|
-
```bash
|
|
217
|
-
curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/timelines/$TIMELINE_ID/columns" \
|
|
218
|
-
-H "x-token: $TOKEN" \
|
|
219
|
-
-H "x-board-id: $BOARD_ID" \
|
|
220
|
-
-H "x-user-id: agent" \
|
|
221
|
-
-H "Content-Type: application/json" \
|
|
222
|
-
-d '{}'
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
Response: `{ "columnId": "<uuid>", "index": <n>, "totalColumns": <n> }`
|
|
180
|
+
**Fallback (no MCP):** see `references/api-fallback.md` — "Step 5 — Create a column when appending".
|
|
226
181
|
|
|
227
182
|
Save `columnId` from the response.
|
|
228
183
|
|
|
@@ -241,42 +196,45 @@ Cell IDs are always `<rowId>-<columnId>` — no cell array search needed.
|
|
|
241
196
|
|
|
242
197
|
**Same swimlane for events emitted by the same command.** When one command emits more than one event, each event still gets its own column (per the hard rule above), but all of them belong in the *same* swimlane row, placed in adjacent columns immediately after the command. Do not scatter a command's sibling events across different swimlane rows — one command producing multiple events is one system doing multiple things in sequence, not several systems reacting independently.
|
|
243
198
|
|
|
199
|
+
**One COMMAND / READMODEL / SCREEN / AUTOMATION per column — server-enforced, not just a heuristic.** Unlike the EVENT rule above (which this skill has to check for itself), the server itself rejects a second `COMMAND`, `READMODEL`, `SCREEN`/`HTML_SCREEN`, or `AUTOMATION` landing in a column that already has one of that type — across *every* row of the relevant lane (`interaction` for COMMAND/READMODEL, `actor` for SCREEN/AUTOMATION), not only the exact target cell. A board can have several separate `interaction` or `actor` rows, so the target cell itself can be empty and the placement will still fail with a `ValidationError` ("Column already has a … node … — only one … is allowed per column"). Treat that rejection exactly like a same-cell conflict in the table below — insert a new column rather than retrying the same one.
|
|
200
|
+
|
|
244
201
|
**Check if the cell is already occupied.**
|
|
245
202
|
|
|
246
|
-
**
|
|
203
|
+
**Fastest path**: use the `cells` array you already fetched in Step 3 via `get_node` (`projection: "cells"`) on the chapter/timeline node — `cells` is a sparse array, so a `nodeId` absent from the entry for `CELL_ID` means the cell is empty. Also scan it for the column-wide conflict from the rule above: any entry with `colId === columnId` and `nodeType === elementType` (for COMMAND/READMODEL/SCREEN/AUTOMATION) means the column is occupied even though `CELL_ID` itself is free. This avoids an extra round-trip, but can be stale if a column was just created in Step 5 — re-fetch first in that case.
|
|
247
204
|
|
|
248
|
-
**
|
|
205
|
+
**No direct MCP equivalent** for querying by cell/column: `get_nodes` only filters by `type`. The REST API does support it directly though — `GET /nodes` takes `cellId` **or** `colId`, both requiring `timelineId`:
|
|
249
206
|
|
|
250
207
|
```bash
|
|
251
|
-
|
|
208
|
+
# Same-cell occupancy — returns [] if empty, or [nodeRecord] if occupied
|
|
209
|
+
curl -s "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?cellId=$CELL_ID&timelineId=$TIMELINE_ID"
|
|
210
|
+
|
|
211
|
+
# Column-wide occupancy (any row) — optionally add &type=READMODEL to narrow to one element type
|
|
212
|
+
curl -s "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?colId=$COLUMN_ID&timelineId=$TIMELINE_ID"
|
|
252
213
|
```
|
|
253
214
|
|
|
215
|
+
Use this REST call (see the curl fallback below) when you don't already have fresh `timelineData` loaded, instead of re-fetching the whole chapter node just to check occupancy.
|
|
216
|
+
|
|
217
|
+
**Fallback (no MCP):** see `references/api-fallback.md` — "Step 6 — Check cell occupancy".
|
|
218
|
+
|
|
254
219
|
**If the cell is occupied**, the behaviour depends on the element type being placed:
|
|
255
220
|
|
|
256
221
|
| Element type | Occupant type in same cell | Action |
|
|
257
222
|
|---|---|---|
|
|
258
|
-
| `READMODEL` | `COMMAND` (state-change slice already owns this column) | Insert a **new column immediately after** the current column (not at the end) and use that new column as the target. |
|
|
259
|
-
| `SCREEN` (view/output screen) | any |
|
|
223
|
+
| `READMODEL` | `COMMAND` (state-change slice already owns this column) | Insert a **new column immediately after** the current column (not at the end) and use that new column as the target. This row covers positioning the read model relative to its **source EVENT's** column. If instead you're placing the read model to share a column with an **already-placed view SCREEN** it feeds (`eventmodeling-identifying-outputs`'s Step 5g scenario) and that column is unavailable, do the opposite: insert the new column immediately **before** the screen — the screen's own position must never move to resolve this. |
|
|
224
|
+
| `SCREEN` (view/output screen) | any | Insert immediately after (this is placing a brand-new screen, not repositioning one relative to an existing read model). |
|
|
260
225
|
| `EVENT` | `EVENT` in **any other swimlane row of the same column** | Insert a new column immediately after — an EVENT never shares a column with another EVENT, even across different swimlanes. |
|
|
261
226
|
| Any | Same element type | Stop and tell the user — true conflict, no safe default. |
|
|
262
227
|
| Any | Different type but not a known pairing | Stop and tell the user. |
|
|
263
228
|
|
|
264
|
-
**Insert immediately after** means: create the new column
|
|
229
|
+
**Insert immediately after** means: create the new column right after the current one, not by appending to the end. This keeps the read model visually adjacent to the event that drives it.
|
|
265
230
|
|
|
266
|
-
**Prefer MCP
|
|
231
|
+
**Prefer MCP** — pass `afterNodeId` set to the occupying node's id (found in Step 6's cell-occupancy check) and let the tool resolve the index itself, instead of computing `currentColumnIndex + 1` by hand:
|
|
267
232
|
|
|
268
233
|
```
|
|
269
|
-
mcp__eventmodelers__add_column { "boardId": "<BOARD_ID>", "timelineId": "<TIMELINE_ID>", "
|
|
234
|
+
mcp__eventmodelers__add_column { "boardId": "<BOARD_ID>", "timelineId": "<TIMELINE_ID>", "afterNodeId": "<occupyingNodeId>" }
|
|
270
235
|
```
|
|
271
236
|
|
|
272
|
-
**Fallback (no MCP):**
|
|
273
|
-
|
|
274
|
-
```bash
|
|
275
|
-
curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/timelines/$TIMELINE_ID/columns" \
|
|
276
|
-
-H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID" -H "x-user-id: agent" \
|
|
277
|
-
-H "Content-Type: application/json" \
|
|
278
|
-
-d '{"index": <currentColumnIndex + 1>}'
|
|
279
|
-
```
|
|
237
|
+
**Fallback (no MCP):** see `references/api-fallback.md` — "Step 6 — Insert a column at a specific index" (no relative-insertion equivalent over REST; the index is computed by hand).
|
|
280
238
|
|
|
281
239
|
If no matching row is found, stop and report the error — the timeline may be missing the required lane type.
|
|
282
240
|
|
|
@@ -292,7 +250,7 @@ Instead, create a **linked copy**: place the new node normally (Step 7, same tit
|
|
|
292
250
|
mcp__eventmodelers__link_element { "boardId": "<BOARD_ID>", "nodeId": "<origin-node-id>", "targetNodeId": "<newly-placed-node-id>" }
|
|
293
251
|
```
|
|
294
252
|
|
|
295
|
-
(REST fallback: `
|
|
253
|
+
(REST fallback: see `references/api-fallback.md` — "Step 6a — Link a node to an origin on a different timeline".) This replaces the new node's meta with a full copy of the origin's, sets `meta.linkedTo`, and only works for COMMAND/EVENT/READMODEL. Once linked, wire the local copy to its neighbors with normal same-timeline `set_connection`/auto-connect calls. `eventmodeling-checking-completeness` treats any `linkedTo`-marked node it finds as this intentional pattern, never a duplicate to flag.
|
|
296
254
|
|
|
297
255
|
---
|
|
298
256
|
|
|
@@ -318,20 +276,7 @@ mcp__eventmodelers__create_screen {
|
|
|
318
276
|
}
|
|
319
277
|
```
|
|
320
278
|
|
|
321
|
-
**Fallback (no MCP):**
|
|
322
|
-
|
|
323
|
-
```bash
|
|
324
|
-
curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/html-screen-nodes/<node-uuid>" \
|
|
325
|
-
-H "x-token: $TOKEN" \
|
|
326
|
-
-H "x-board-id: $BOARD_ID" \
|
|
327
|
-
-H "x-user-id: agent" \
|
|
328
|
-
-H "Content-Type: application/json" \
|
|
329
|
-
-d '{
|
|
330
|
-
"chapterId": "<TIMELINE_ID>",
|
|
331
|
-
"cellId": "<CELL_ID>",
|
|
332
|
-
"pages": ["<div>...</div>"]
|
|
333
|
-
}'
|
|
334
|
-
```
|
|
279
|
+
**Fallback (no MCP):** see `references/api-fallback.md` — "Step 7a — SCREEN: create and render (HTML path)".
|
|
335
280
|
|
|
336
281
|
**Sketch path (explicit request only) — `contentType: "sketch"`, plain SCREEN node:** only use this when the user explicitly asked for a "sketch"/"wireframe"/"low-fidelity mockup". Design the sketch elements first (same grid language as `storyboard-screen`):
|
|
337
282
|
|
|
@@ -349,21 +294,7 @@ mcp__eventmodelers__create_screen {
|
|
|
349
294
|
}
|
|
350
295
|
```
|
|
351
296
|
|
|
352
|
-
**Fallback (no MCP):**
|
|
353
|
-
|
|
354
|
-
```bash
|
|
355
|
-
curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/image-nodes/<node-uuid>/sketch" \
|
|
356
|
-
-H "x-token: $TOKEN" \
|
|
357
|
-
-H "x-board-id: $BOARD_ID" \
|
|
358
|
-
-H "x-user-id: agent" \
|
|
359
|
-
-H "Content-Type: application/json" \
|
|
360
|
-
-d '{
|
|
361
|
-
"chapterId": "<TIMELINE_ID>",
|
|
362
|
-
"cellId": "<CELL_ID>",
|
|
363
|
-
"description": {"elements": [...]},
|
|
364
|
-
"semanticDescription": "<title — what this screen shows>"
|
|
365
|
-
}'
|
|
366
|
-
```
|
|
297
|
+
**Fallback (no MCP):** see `references/api-fallback.md` — "Step 7a — SCREEN: create and render (sketch path, explicit request only)".
|
|
367
298
|
|
|
368
299
|
Pass whichever cell reference you already resolved — `CELL_ID` from Step 6, or `CELL_NAME` from Step 1's fast path (either path accepts `cellId` or `cellName`). Expect success (MCP: `created: true`; curl: `204`). On failure, read the validation error, fix the payload, and retry once. Then skip the rest of Step 7 and go to Step 8.
|
|
369
300
|
|
|
@@ -393,28 +324,7 @@ mcp__eventmodelers__submit_node_events {
|
|
|
393
324
|
}
|
|
394
325
|
```
|
|
395
326
|
|
|
396
|
-
**Fallback (no MCP):**
|
|
397
|
-
|
|
398
|
-
```bash
|
|
399
|
-
curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/events" \
|
|
400
|
-
-H "x-token: $TOKEN" \
|
|
401
|
-
-H "x-board-id: $BOARD_ID" \
|
|
402
|
-
-H "x-user-id: agent" \
|
|
403
|
-
-H "Content-Type: application/json" \
|
|
404
|
-
-d '[{
|
|
405
|
-
"eventType": "node:created",
|
|
406
|
-
"nodeId": "<node-uuid>",
|
|
407
|
-
"boardId": "<BOARD_ID>",
|
|
408
|
-
"timestamp": <Date.now()>,
|
|
409
|
-
"chapterId": "<TIMELINE_ID>",
|
|
410
|
-
"cellId": "<CELL_ID>",
|
|
411
|
-
"meta": {
|
|
412
|
-
"type": "<ELEMENT_TYPE>",
|
|
413
|
-
"title": "<title>"
|
|
414
|
-
},
|
|
415
|
-
"node": { "data": { "title": "<title>" } }
|
|
416
|
-
}]'
|
|
417
|
-
```
|
|
327
|
+
**Fallback (no MCP):** see `references/api-fallback.md` — "Step 7b — Create any other node type (normal path, `cellId`)".
|
|
418
328
|
|
|
419
329
|
**Fast path** (`cellName` given directly, e.g. `"A2"` — see the Step 1 shortcut) — pass `cellName` instead of `cellId` and let the backend resolve it; nothing else in the payload changes:
|
|
420
330
|
|
|
@@ -436,28 +346,7 @@ mcp__eventmodelers__submit_node_events {
|
|
|
436
346
|
}
|
|
437
347
|
```
|
|
438
348
|
|
|
439
|
-
**Fallback (no MCP):**
|
|
440
|
-
|
|
441
|
-
```bash
|
|
442
|
-
curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/events" \
|
|
443
|
-
-H "x-token: $TOKEN" \
|
|
444
|
-
-H "x-board-id: $BOARD_ID" \
|
|
445
|
-
-H "x-user-id: agent" \
|
|
446
|
-
-H "Content-Type: application/json" \
|
|
447
|
-
-d '[{
|
|
448
|
-
"eventType": "node:created",
|
|
449
|
-
"nodeId": "<node-uuid>",
|
|
450
|
-
"boardId": "<BOARD_ID>",
|
|
451
|
-
"timestamp": <Date.now()>,
|
|
452
|
-
"chapterId": "<TIMELINE_ID>",
|
|
453
|
-
"cellName": "<CELL_NAME>",
|
|
454
|
-
"meta": {
|
|
455
|
-
"type": "<ELEMENT_TYPE>",
|
|
456
|
-
"title": "<title>"
|
|
457
|
-
},
|
|
458
|
-
"node": { "data": { "title": "<title>" } }
|
|
459
|
-
}]'
|
|
460
|
-
```
|
|
349
|
+
**Fallback (no MCP):** see `references/api-fallback.md` — "Step 7b — Create any other node type (fast path, `cellName`)".
|
|
461
350
|
|
|
462
351
|
Response: `{ "hashes": { "<event-uuid>": "<hash>" } }`
|
|
463
352
|
|
|
@@ -513,39 +402,4 @@ Timeline: <timelineId>
|
|
|
513
402
|
|
|
514
403
|
## Example — place an EVENT via curl
|
|
515
404
|
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
Full working example placing an EVENT called "Order Placed" at the end of a timeline:
|
|
519
|
-
|
|
520
|
-
```bash
|
|
521
|
-
# 1. Add a column (append at end)
|
|
522
|
-
curl -s -X POST "http://localhost:3000/api/org/<ORG_ID>/boards/<BOARD_ID>/timelines/<TIMELINE_ID>/columns" \
|
|
523
|
-
-H "Content-Type: application/json" \
|
|
524
|
-
-d '{}'
|
|
525
|
-
|
|
526
|
-
# 2. Fetch chapter to find the target lane cell for the new column
|
|
527
|
-
curl -s -H "x-user-id: place-element-skill" \
|
|
528
|
-
"http://localhost:3000/api/org/<ORG_ID>/boards/<BOARD_ID>/nodes/<TIMELINE_ID>"
|
|
529
|
-
|
|
530
|
-
# 3. Create the EVENT node
|
|
531
|
-
|
|
532
|
-
Do not skip the User-ID.
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
curl -s -X POST "http://localhost:3000/api/org/<ORG_ID>/boards/<BOARD_ID>/nodes/events" \
|
|
536
|
-
-H "Content-Type: application/json" \
|
|
537
|
-
-H "x-user-id: place-element-skill" \
|
|
538
|
-
-d '[{
|
|
539
|
-
"id": "<event-uuid>",
|
|
540
|
-
"eventType": "node:created",
|
|
541
|
-
"nodeId": "<node-uuid>",
|
|
542
|
-
"boardId": "<BOARD_ID>",
|
|
543
|
-
"timestamp": 1714900000000,
|
|
544
|
-
"chapterId": "<TIMELINE_ID>",
|
|
545
|
-
"cellId": "<CELL_ID>",
|
|
546
|
-
"meta": { "type": "EVENT", "title": "Order Placed" },
|
|
547
|
-
"node": { "id": "<node-uuid>", "data": { "title": "Order Placed" } }
|
|
548
|
-
}]'
|
|
549
|
-
```
|
|
550
|
-
|
|
551
|
-
Replace `<TIMELINE_ID>`, `<BOARD_ID>`, `<CELL_ID>`, `<event-uuid>`, and `<node-uuid>` with real UUIDs. Use `Date.now()` or a current unix-ms timestamp for `timestamp`.
|
|
405
|
+
A full worked example (add column → fetch chapter → create node) placing an EVENT called "Order Placed" at the end of a timeline lives in `references/api-fallback.md`'s "Full worked example" section. With MCP connected, the same result is one call: `mcp__eventmodelers__place_element { "boardId": "<BOARD_ID>", "timelineId": "<TIMELINE_ID>", "elementType": "EVENT", "title": "Order Placed" }` (see "Prefer MCP" above).
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
# Place Element — curl Fallback Calls
|
|
2
|
+
|
|
3
|
+
Only needed when MCP is not connected. Every call below has an MCP equivalent in the main SKILL.md — always prefer that.
|
|
4
|
+
|
|
5
|
+
## Step 2 — Discover chapters
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
curl -s "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?type=CHAPTER"
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Step 3 — Fetch the chapter node (columns + cells)
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
curl -s "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/$TIMELINE_ID"
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Step 4a — SCENARIO: append scenarios via the spec endpoint
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/timelines/$TL/columns/$COL/scenarios" \
|
|
21
|
+
-H "x-token: $TOKEN" -H "Content-Type: application/json" \
|
|
22
|
+
-d '[
|
|
23
|
+
{
|
|
24
|
+
"id": "<scenario-uuid>",
|
|
25
|
+
"title": "Happy path",
|
|
26
|
+
"given": [{"id":"<eventNodeId>","title":"OrderPlaced","type":"EVENT"}],
|
|
27
|
+
"when": [{"id":"<commandNodeId>","title":"PlaceOrder","type":"COMMAND"}],
|
|
28
|
+
"then": [{"id":"<eventNodeId2>","title":"OrderConfirmed","type":"EVENT"}]
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"id": "<scenario-uuid>",
|
|
32
|
+
"title": "Insufficient stock",
|
|
33
|
+
"given": [{"id":"<eventNodeId>","title":"OrderPlaced","type":"EVENT"}],
|
|
34
|
+
"when": [{"id":"<commandNodeId>","title":"PlaceOrder","type":"COMMAND"}],
|
|
35
|
+
"then": [],
|
|
36
|
+
"expectError": true,
|
|
37
|
+
"errorDescription": "Stock below requested quantity"
|
|
38
|
+
}
|
|
39
|
+
]'
|
|
40
|
+
# → 201 { specNodeId, scenarios (all), added (count), isNewNode }
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Step 5 — Create a column when appending
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/timelines/$TIMELINE_ID/columns" \
|
|
47
|
+
-H "x-token: $TOKEN" \
|
|
48
|
+
-H "x-board-id: $BOARD_ID" \
|
|
49
|
+
-H "x-user-id: agent" \
|
|
50
|
+
-H "Content-Type: application/json" \
|
|
51
|
+
-d '{}'
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Response: `{ "columnId": "<uuid>", "index": <n>, "totalColumns": <n> }`
|
|
55
|
+
|
|
56
|
+
## Step 6 — Check cell occupancy
|
|
57
|
+
|
|
58
|
+
`GET /nodes` takes `cellId` **or** `colId`, both requiring `timelineId` — no need to re-fetch and parse the whole chapter node just for this:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
# Same-cell occupancy — [] if empty, [nodeRecord] if occupied
|
|
62
|
+
curl -s "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?cellId=$CELL_ID&timelineId=$TIMELINE_ID"
|
|
63
|
+
|
|
64
|
+
# Same-column occupancy, across every row of the timeline — add &type=<elementType> to narrow
|
|
65
|
+
# (the server enforces one COMMAND/READMODEL/SCREEN/HTML_SCREEN/AUTOMATION per column even when
|
|
66
|
+
# the target cell itself is empty — see SKILL.md)
|
|
67
|
+
curl -s "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes?colId=$COLUMN_ID&timelineId=$TIMELINE_ID"
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
If you already have fresh `timelineData` loaded from Step 3, reading its `cells` array directly (sparse — an entry only exists once something has been placed there) avoids the extra round-trip; use the calls above otherwise, or when `timelineData` might be stale (e.g. a column was just created).
|
|
71
|
+
|
|
72
|
+
## Step 6 — Insert a column at a specific index (conflict resolution)
|
|
73
|
+
|
|
74
|
+
No relative-insertion equivalent over REST (unlike MCP's `afterNodeId`) — compute the index by hand:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/timelines/$TIMELINE_ID/columns" \
|
|
78
|
+
-H "x-token: $TOKEN" -H "x-board-id: $BOARD_ID" -H "x-user-id: agent" \
|
|
79
|
+
-H "Content-Type: application/json" \
|
|
80
|
+
-d '{"index": <currentColumnIndex + 1>}'
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Step 6a — Link a node to an origin on a different timeline
|
|
84
|
+
|
|
85
|
+
`POST .../nodes/:nodeId/link` with `{ "targetNodeId": "<newly-placed-node-id>" }` — see `learn-eventmodelers-api` §3.
|
|
86
|
+
|
|
87
|
+
## Step 7a — SCREEN: create and render (HTML path)
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/html-screen-nodes/<node-uuid>" \
|
|
91
|
+
-H "x-token: $TOKEN" \
|
|
92
|
+
-H "x-board-id: $BOARD_ID" \
|
|
93
|
+
-H "x-user-id: agent" \
|
|
94
|
+
-H "Content-Type: application/json" \
|
|
95
|
+
-d '{
|
|
96
|
+
"chapterId": "<TIMELINE_ID>",
|
|
97
|
+
"cellId": "<CELL_ID>",
|
|
98
|
+
"pages": ["<div>...</div>"]
|
|
99
|
+
}'
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Step 7a — SCREEN: create and render (sketch path, explicit request only)
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/image-nodes/<node-uuid>/sketch" \
|
|
106
|
+
-H "x-token: $TOKEN" \
|
|
107
|
+
-H "x-board-id: $BOARD_ID" \
|
|
108
|
+
-H "x-user-id: agent" \
|
|
109
|
+
-H "Content-Type: application/json" \
|
|
110
|
+
-d '{
|
|
111
|
+
"chapterId": "<TIMELINE_ID>",
|
|
112
|
+
"cellId": "<CELL_ID>",
|
|
113
|
+
"description": {"elements": [...]},
|
|
114
|
+
"semanticDescription": "<title — what this screen shows>"
|
|
115
|
+
}'
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Step 7b — Create any other node type (normal path, `cellId`)
|
|
119
|
+
|
|
120
|
+
Include `x-token`, `x-board-id`, and `x-user-id: agent` on every call to `/nodes/events`.
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/events" \
|
|
124
|
+
-H "x-token: $TOKEN" \
|
|
125
|
+
-H "x-board-id: $BOARD_ID" \
|
|
126
|
+
-H "x-user-id: agent" \
|
|
127
|
+
-H "Content-Type: application/json" \
|
|
128
|
+
-d '[{
|
|
129
|
+
"eventType": "node:created",
|
|
130
|
+
"nodeId": "<node-uuid>",
|
|
131
|
+
"boardId": "<BOARD_ID>",
|
|
132
|
+
"timestamp": <Date.now()>,
|
|
133
|
+
"chapterId": "<TIMELINE_ID>",
|
|
134
|
+
"cellId": "<CELL_ID>",
|
|
135
|
+
"meta": {
|
|
136
|
+
"type": "<ELEMENT_TYPE>",
|
|
137
|
+
"title": "<title>"
|
|
138
|
+
},
|
|
139
|
+
"node": { "data": { "title": "<title>" } }
|
|
140
|
+
}]'
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Step 7b — Create any other node type (fast path, `cellName`)
|
|
144
|
+
|
|
145
|
+
Same as above, but `cellName` replaces `cellId` — nothing else in the payload changes:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/events" \
|
|
149
|
+
-H "x-token: $TOKEN" \
|
|
150
|
+
-H "x-board-id: $BOARD_ID" \
|
|
151
|
+
-H "x-user-id: agent" \
|
|
152
|
+
-H "Content-Type: application/json" \
|
|
153
|
+
-d '[{
|
|
154
|
+
"eventType": "node:created",
|
|
155
|
+
"nodeId": "<node-uuid>",
|
|
156
|
+
"boardId": "<BOARD_ID>",
|
|
157
|
+
"timestamp": <Date.now()>,
|
|
158
|
+
"chapterId": "<TIMELINE_ID>",
|
|
159
|
+
"cellName": "<CELL_NAME>",
|
|
160
|
+
"meta": {
|
|
161
|
+
"type": "<ELEMENT_TYPE>",
|
|
162
|
+
"title": "<title>"
|
|
163
|
+
},
|
|
164
|
+
"node": { "data": { "title": "<title>" } }
|
|
165
|
+
}]'
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Response: `{ "hashes": { "<event-uuid>": "<hash>" } }`
|
|
169
|
+
|
|
170
|
+
## Full worked example — place an EVENT via curl, start to finish
|
|
171
|
+
|
|
172
|
+
With MCP connected, the same result is one call: `mcp__eventmodelers__place_element { "boardId": "<BOARD_ID>", "timelineId": "<TIMELINE_ID>", "elementType": "EVENT", "title": "Order Placed" }`.
|
|
173
|
+
|
|
174
|
+
Placing an EVENT called "Order Placed" at the end of a timeline, over curl:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
# 1. Add a column (append at end)
|
|
178
|
+
curl -s -X POST "http://localhost:3000/api/org/<ORG_ID>/boards/<BOARD_ID>/timelines/<TIMELINE_ID>/columns" \
|
|
179
|
+
-H "Content-Type: application/json" \
|
|
180
|
+
-d '{}'
|
|
181
|
+
|
|
182
|
+
# 2. Fetch chapter to find the target lane cell for the new column
|
|
183
|
+
curl -s -H "x-user-id: place-element-skill" \
|
|
184
|
+
"http://localhost:3000/api/org/<ORG_ID>/boards/<BOARD_ID>/nodes/<TIMELINE_ID>"
|
|
185
|
+
|
|
186
|
+
# 3. Create the EVENT node — do not skip the x-user-id header
|
|
187
|
+
curl -s -X POST "http://localhost:3000/api/org/<ORG_ID>/boards/<BOARD_ID>/nodes/events" \
|
|
188
|
+
-H "Content-Type: application/json" \
|
|
189
|
+
-H "x-user-id: place-element-skill" \
|
|
190
|
+
-d '[{
|
|
191
|
+
"id": "<event-uuid>",
|
|
192
|
+
"eventType": "node:created",
|
|
193
|
+
"nodeId": "<node-uuid>",
|
|
194
|
+
"boardId": "<BOARD_ID>",
|
|
195
|
+
"timestamp": 1714900000000,
|
|
196
|
+
"chapterId": "<TIMELINE_ID>",
|
|
197
|
+
"cellId": "<CELL_ID>",
|
|
198
|
+
"meta": { "type": "EVENT", "title": "Order Placed" },
|
|
199
|
+
"node": { "id": "<node-uuid>", "data": { "title": "Order Placed" } }
|
|
200
|
+
}]'
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Replace `<TIMELINE_ID>`, `<BOARD_ID>`, `<CELL_ID>`, `<event-uuid>`, and `<node-uuid>` with real UUIDs. Use `Date.now()` or a current unix-ms timestamp for `timestamp`.
|