@eventmodelers/cli 1.0.80 → 1.0.84
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/cli.js +2 -2
- package/package.json +1 -1
- package/shared/skills/connect/SKILL.md +6 -4
- package/shared/skills/learn-eventmodelers-api/SKILL.md +24 -21
- package/shared/skills/request-feedback/SKILL.md +0 -2
- package/shared/skills/update-slice-status/SKILL.md +0 -2
- package/stacks/modeling-kit/templates/.claude/skills/attributes/SKILL.md +2 -2
- package/stacks/modeling-kit/templates/.claude/skills/attributes/references/api-fallback.md +1 -3
- package/stacks/modeling-kit/templates/.claude/skills/discover-storyboard/SKILL.md +19 -17
- package/stacks/modeling-kit/templates/.claude/skills/discover-storyboard/references/api-fallback.md +0 -2
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-brainstorming-events/SKILL.md +0 -4
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-brainstorming-events/references/api-fallback.md +0 -4
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-designing-automation-chains/SKILL.md +9 -8
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-designing-automation-chains/references/api-fallback.md +0 -1
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-inputs/SKILL.md +9 -9
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-inputs/references/api-fallback.md +0 -2
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-outputs/SKILL.md +10 -9
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-outputs/references/api-fallback.md +0 -2
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-orchestrating-event-modeling/SKILL.md +14 -13
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-orchestrating-event-modeling/references/api-fallback.md +4 -4
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-slicing-event-models/SKILL.md +2 -2
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-slicing-event-models/references/examples.md +2 -2
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-storyboarding-events/SKILL.md +11 -11
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-storyboarding-events/references/api-fallback.md +0 -2
- package/stacks/modeling-kit/templates/.claude/skills/examples/SKILL.md +1 -3
- package/stacks/modeling-kit/templates/.claude/skills/examples/references/api-fallback.md +1 -3
- package/stacks/modeling-kit/templates/.claude/skills/handle-comment/SKILL.md +2 -2
- package/stacks/modeling-kit/templates/.claude/skills/html-screen/SKILL.md +8 -8
- package/stacks/modeling-kit/templates/.claude/skills/html-screen/references/api-fallback.md +0 -1
- package/stacks/modeling-kit/templates/.claude/skills/place-element/SKILL.md +31 -26
- package/stacks/modeling-kit/templates/.claude/skills/place-element/references/api-fallback.md +5 -9
- package/stacks/modeling-kit/templates/.claude/skills/storyboard/SKILL.md +18 -15
- package/stacks/modeling-kit/templates/.claude/skills/storyboard/references/api-fallback.md +0 -1
- package/stacks/modeling-kit/templates/.claude/skills/storyboard-screen/SKILL.md +0 -1
- package/stacks/modeling-kit/templates/.claude/skills/storyboard-screen/references/api-fallback.md +0 -1
- package/stacks/modeling-kit/templates/.claude/skills/timeline/SKILL.md +4 -8
- package/stacks/modeling-kit/templates/.claude/skills/timeline/references/api-fallback.md +1 -7
- package/stacks/modeling-kit/templates/.claude/skills/wdyt/SKILL.md +19 -7
- package/stacks/modeling-kit/templates/kit/AGENTS.md +2 -1
- package/stacks/modeling-kit/templates/kit/CLAUDE.md +1 -1
|
@@ -110,7 +110,7 @@ For each returned node, check whether it has a valid cell assignment. A node wit
|
|
|
110
110
|
|
|
111
111
|
**Prefer MCP:**
|
|
112
112
|
```
|
|
113
|
-
mcp__eventmodelers__delete_node { "boardId": "$BOARD_ID", "
|
|
113
|
+
mcp__eventmodelers__delete_node { "boardId": "$BOARD_ID", "nodeIds": ["<nodeId>"] }
|
|
114
114
|
```
|
|
115
115
|
|
|
116
116
|
**Fallback (no MCP):** see `references/api-fallback.md` — "No unplaced elements (0,0 nodes) — Delete an orphaned node".
|
|
@@ -135,18 +135,20 @@ Screens placed during Step 3 (Storyboarding) are provisional positions. Steps 4
|
|
|
135
135
|
### Column insertion
|
|
136
136
|
Use `add_column` with `{"index": N}` to insert a column at a specific position (shifts existing columns right) — or, when the insertion point is "immediately before/after a node already on the board" rather than a numeric position you'd otherwise have to compute, pass `beforeNodeId`/`afterNodeId` instead and let the tool resolve the index itself. Do not use no position at all (append) when placing read models or view screens — always target the correct position.
|
|
137
137
|
|
|
138
|
-
**Suppress auto-connect when inserting into an existing chain.** When you insert columns next to nodes that are *not* meant to connect to what you're about to place — e.g. slotting an output read model's column in beside an automation-chain column — the node placement's default auto-connect will wire the new node to whatever type-compatible node happens to sit in its own or the previous column (the "nearest event to the left"). That is the source of the recurring stray-edge cleanup. When the placement you're about to make should be wired only by your own explicit `
|
|
138
|
+
**Suppress auto-connect when inserting into an existing chain.** When you insert columns next to nodes that are *not* meant to connect to what you're about to place — e.g. slotting an output read model's column in beside an automation-chain column — the node placement's default auto-connect will wire the new node to whatever type-compatible node happens to sit in its own or the previous column (the "nearest event to the left"). That is the source of the recurring stray-edge cleanup. When the placement you're about to make should be wired only by your own explicit `set_connection` batch, pass `autoConnect: false` on the placing call (`submit_node_events`, `place_element`, `create_screen`) and then wire every edge yourself. Keep the default (auto-connect on) for Steps 1/3/4 where same-column neighbors are exactly the intended wiring.
|
|
139
139
|
|
|
140
|
-
###
|
|
140
|
+
### Every write tool takes an array — fill it
|
|
141
141
|
|
|
142
|
-
|
|
142
|
+
Each write tool takes its items as an array, so handling several in one pass is one call rather than a loop. Entries are applied in order — which matters where a later one depends on an earlier one, e.g. wiring a READMODEL→AUTOMATION edge before the backward EVENT→READMODEL edge that needs it — every entry reports its own outcome or error in `results`, and one failure does not stop the rest. Whenever a step's instructions below show a one-entry call and more than one item is being processed in the same pass, extend the array instead of repeating the call:
|
|
143
143
|
|
|
144
|
-
- `
|
|
145
|
-
- `
|
|
146
|
-
- `
|
|
147
|
-
- `
|
|
148
|
-
- `
|
|
149
|
-
- `
|
|
144
|
+
- `set_connection`'s `connections` — wiring multiple edges
|
|
145
|
+
- `auto_connect_node`'s `nodeIds` — auto-connecting multiple freshly-placed nodes
|
|
146
|
+
- `create_slice_definition`'s `slices` — defining multiple slices
|
|
147
|
+
- `create_screen`'s `screens` — creating multiple screens
|
|
148
|
+
- `place_element`'s `elements` — laying out a whole slice or column run, each entry seeing the columns the previous one added
|
|
149
|
+
- `move_node_in_timeline`'s `moves` — moving multiple already-placed nodes within one timeline
|
|
150
|
+
- `delete_node`'s `nodeIds` / `delete_column`'s `columnIds` — removing multiple nodes or columns, e.g. a corrective cleanup after a modeling mistake
|
|
151
|
+
- `add_comment`'s `comments`, `create_drawing`'s `drawings`, `add_lane`'s `lanes` — same shape
|
|
150
152
|
- `add_column`'s `count` param (not `add_column` repeated) — appending or inserting several columns at once; `beforeNodeId`/`afterNodeId` resolve the insertion point from an already-placed node instead of a computed index
|
|
151
153
|
- `create_chapter`'s `columns` param — when the chapter's initial column count is already known, instead of creating the default 3 and appending more after
|
|
152
154
|
|
|
@@ -156,7 +158,7 @@ For a "what is on the board and how is it wired right now" check between steps
|
|
|
156
158
|
|
|
157
159
|
**Structural validation is one call, not a scan.** `validate_model` (`{boardId, chapterId}`) runs the whole structural checklist server-side — unplaced nodes, backward arrows (todo-list exception applied), zero/multi-issuer commands, sourceless read models, two-screens-in-a-column, missing scenarios — and returns only `findings`. Use it for the mandatory post-step unplaced check and as the first move in Step 9, instead of per-type `get_nodes` loops and `get_node` `projection: "edges"` spot-checks.
|
|
158
160
|
|
|
159
|
-
**Ask echo-heavy write tools for less.** `add_scenario`, `add_storyline`, `
|
|
161
|
+
**Ask echo-heavy write tools for less.** `add_scenario`, `add_storyline`, `set_connection` and `submit_node_events` each accept `compact: true`, which drops the full-object echo from the response (returning `{specNodeId, added, count, isNewNode}`, a `{connected, existed, removed, notFound, failed, errors}` tally, or `{persisted: <count>}` respectively). Pass it whenever you're not going to read individual fields back off the response — which is almost always for a large `set_connection` batch or a bulk scenario post.
|
|
160
162
|
|
|
161
163
|
### Documenting decisions inline, at any step
|
|
162
164
|
|
|
@@ -416,7 +418,7 @@ Not delegated to a separate skill — performed directly by this orchestrating s
|
|
|
416
418
|
|
|
417
419
|
**Prefer MCP:**
|
|
418
420
|
```
|
|
419
|
-
mcp__eventmodelers__add_lane { "boardId": "$BOARD_ID", "timelineId": "$CHAPTER_ID", "type": "feedback", "label": "Notes" }
|
|
421
|
+
mcp__eventmodelers__add_lane { "boardId": "$BOARD_ID", "timelineId": "$CHAPTER_ID", "lanes": [{ "type": "feedback", "label": "Notes" }] }
|
|
420
422
|
```
|
|
421
423
|
|
|
422
424
|
**Fallback (no MCP):** see `references/api-fallback.md` — "Step 11 — Document Reasoning — Add a feedback lane".
|
|
@@ -431,7 +433,6 @@ Not delegated to a separate skill — performed directly by this orchestrating s
|
|
|
431
433
|
"boardId": "$BOARD_ID",
|
|
432
434
|
"events": [{
|
|
433
435
|
"id": "<event-uuid>", "eventType": "node:created", "nodeId": "<node-uuid>",
|
|
434
|
-
"boardId": "$BOARD_ID", "timestamp": 1234567890,
|
|
435
436
|
"chapterId": "$CHAPTER_ID", "cellId": "<feedbackLaneId>-<firstColumnId>",
|
|
436
437
|
"meta": { "type": "MARKDOWN", "title": "Modeling Reasoning — <Chapter Name>", "description": "<full markdown body>" }
|
|
437
438
|
}]
|
|
@@ -17,8 +17,8 @@ done
|
|
|
17
17
|
curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/events" \
|
|
18
18
|
-H "x-token: $TOKEN" -H "x-user-id: orchestrator" \
|
|
19
19
|
-H "Content-Type: application/json" \
|
|
20
|
-
-d '[{"id":"<uuid>","eventType":"node:changed","nodeId":"<nodeId>",
|
|
21
|
-
"
|
|
20
|
+
-d '[{"id":"<event-uuid>","eventType":"node:changed","nodeId":"<nodeId>",
|
|
21
|
+
"chapterId":"<chapterId>","cellId":"<rowId>-<colId>",
|
|
22
22
|
"meta":{"type":"<TYPE>","title":"<title>"}}]'
|
|
23
23
|
```
|
|
24
24
|
|
|
@@ -45,7 +45,7 @@ curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/timelines/$CHAPTER_I
|
|
|
45
45
|
curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/events" \
|
|
46
46
|
-H "x-token: $TOKEN" -H "x-user-id: orchestrator" \
|
|
47
47
|
-H "Content-Type: application/json" \
|
|
48
|
-
-d '[{"id":"<event-uuid>","eventType":"node:created","nodeId":"<node-uuid>",
|
|
49
|
-
"
|
|
48
|
+
-d '[{"id":"<event-uuid>","eventType":"node:created","nodeId":"<node-uuid>",
|
|
49
|
+
"chapterId":"<CHAPTER_ID>","cellId":"<feedbackLaneId>-<firstColumnId>",
|
|
50
50
|
"meta":{"type":"MARKDOWN","title":"Modeling Reasoning — <Chapter Name>","description":"<full markdown body>"}}]'
|
|
51
51
|
```
|
package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-slicing-event-models/SKILL.md
CHANGED
|
@@ -99,7 +99,7 @@ For every column from Step 2 that doesn't already have a matching slice, mark ea
|
|
|
99
99
|
|
|
100
100
|
Prefer MCP:
|
|
101
101
|
```
|
|
102
|
-
|
|
102
|
+
mcp__eventmodelers__create_slice_definition { "boardId": "<BOARD_ID>", "timelineId": "<TL>", "slices": [
|
|
103
103
|
{ "columnId": "<colId1>", "title": "PlaceOrder" },
|
|
104
104
|
{ "columnId": "<colId2>", "title": "OrderStatusView" }
|
|
105
105
|
] }
|
|
@@ -112,7 +112,7 @@ mcp__eventmodelers__create_slice_definitions { "boardId": "<BOARD_ID>", "timelin
|
|
|
112
112
|
- READMODEL column → title = read model name (state-view slice)
|
|
113
113
|
- AUTOMATION column → title = automation name, or the command it issues (automation slice)
|
|
114
114
|
|
|
115
|
-
Use **`
|
|
115
|
+
Use **`create_slice_definition`/`slice-definitions`**, never `create_slice`/the plain **`slices`** endpoint here — `create_slice`/`slices` creates a brand-new column with its own swimlane/content nodes, which would duplicate the element already placed on the timeline. `create_slice_definition`/`slice-definitions` only adds a `SLICE_BORDER` node to each column you already resolved in Step 2. `title` always comes from the request body — it is never derived automatically from the command/read model/automation node.
|
|
116
116
|
|
|
117
117
|
**If Step 2 finds nothing to slice** (every COMMAND/READMODEL/AUTOMATION on the timeline already has a matching `SLICE_BORDER`), this skill's job is done — there is no existing element left to make explicit. Do not invent new model content here; that is out of scope for a skill whose whole design assumes the model is already complete. Invoke the `add-next-slice` skill instead — it owns deciding on and creating a genuinely new slice from scratch.
|
|
118
118
|
|
|
@@ -50,10 +50,10 @@ No slice depends on another slice directly — only on the events it produces.
|
|
|
50
50
|
|
|
51
51
|
## Creating These Slices via the API
|
|
52
52
|
|
|
53
|
-
These elements already exist on the timeline (from `spec-info`) — use `
|
|
53
|
+
These elements already exist on the timeline (from `spec-info`) — use `create_slice_definition`/`slice-definitions`, which only adds a `SLICE_BORDER` to each column's existing element. Never use `create_slice`/the plain `/slices` endpoint here: that endpoint creates a brand-new column with its own nodes, which would duplicate the element already on the board.
|
|
54
54
|
|
|
55
55
|
```
|
|
56
|
-
|
|
56
|
+
mcp__eventmodelers__create_slice_definition { "boardId": "<BOARD_ID>", "timelineId": "<TL>", "slices": [
|
|
57
57
|
{ "columnId": "<placeOrderColumnId>", "title": "PlaceOrder" },
|
|
58
58
|
{ "columnId": "<orderDetailViewColumnId>", "title": "OrderDetailView" },
|
|
59
59
|
{ "columnId": "<reserveInventoryOnPaymentColumnId>", "title": "ReserveInventoryOnPayment" }
|
package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-storyboarding-events/SKILL.md
CHANGED
|
@@ -122,7 +122,7 @@ After completing the screen analysis, use the `handle-comment` skill to post a c
|
|
|
122
122
|
|
|
123
123
|
**Prefer MCP:**
|
|
124
124
|
```
|
|
125
|
-
mcp__eventmodelers__add_lane { "boardId": "$BOARD_ID", "timelineId": "$CHAPTER_ID", "type": "actor", "label": "<Role Name>" }
|
|
125
|
+
mcp__eventmodelers__add_lane { "boardId": "$BOARD_ID", "timelineId": "$CHAPTER_ID", "lanes": [{ "type": "actor", "label": "<Role Name>" }] }
|
|
126
126
|
```
|
|
127
127
|
|
|
128
128
|
**Fallback (no MCP):** see `references/api-fallback.md` — "Resolve One Actor Lane Per Human Role — Step 3: Create a new actor lane".
|
|
@@ -226,13 +226,15 @@ Every screen node requires rendered content. **HTML_SCREEN (via the `html-screen
|
|
|
226
226
|
```
|
|
227
227
|
mcp__eventmodelers__create_screen {
|
|
228
228
|
"boardId": "<BOARD_ID>",
|
|
229
|
-
"
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
229
|
+
"screens": [{
|
|
230
|
+
"contentType": "html",
|
|
231
|
+
"nodeId": "<node-uuid>",
|
|
232
|
+
"chapterId": "<CHAPTER_ID>",
|
|
233
|
+
"cellId": "<actorRowId>-<columnId>",
|
|
234
|
+
"pages": ["<div>...</div>"],
|
|
235
|
+
"description": "<concise description of what this screen shows>",
|
|
236
|
+
"fields": [ /* per "Mandatory Field Definitions" below — set in this same call */ ]
|
|
237
|
+
}]
|
|
236
238
|
}
|
|
237
239
|
```
|
|
238
240
|
|
|
@@ -240,7 +242,7 @@ mcp__eventmodelers__create_screen {
|
|
|
240
242
|
|
|
241
243
|
The MCP `create_screen` call above already sets `meta.fields` (per "Mandatory Field Definitions" below) in the same call — no separate `node:changed` follow-up needed when using MCP.
|
|
242
244
|
|
|
243
|
-
A storyboard screen is placed at a *provisional* position — Steps 4 and 5 wire it to its COMMAND / READMODEL once those exist, and may move it first. Pass `autoConnect: false` on `create_screen`
|
|
245
|
+
A storyboard screen is placed at a *provisional* position — Steps 4 and 5 wire it to its COMMAND / READMODEL once those exist, and may move it first. Pass `autoConnect: false` on `create_screen` here so the placement doesn't pre-wire the screen to whatever happens to sit in the adjacent column; the real `SCREEN → COMMAND` and `READMODEL → SCREEN` edges are created deliberately in Steps 4 and 5. When creating several screens whose HTML is already authored, put them all in one `create_screen` call's `screens` array with `autoConnect: false`.
|
|
244
246
|
|
|
245
247
|
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.
|
|
246
248
|
|
|
@@ -256,8 +258,6 @@ mcp__eventmodelers__submit_node_events {
|
|
|
256
258
|
"id": "<event-uuid>",
|
|
257
259
|
"eventType": "node:created",
|
|
258
260
|
"nodeId": "<node-uuid>",
|
|
259
|
-
"boardId": "<BOARD_ID>",
|
|
260
|
-
"timestamp": 1234567890,
|
|
261
261
|
"chapterId": "<CHAPTER_ID>",
|
|
262
262
|
"cellId": "<actorRowId>-<columnId>",
|
|
263
263
|
"meta": {"type": "SCREEN", "title": "<Screen Title>", "fields": [...]}
|
|
@@ -52,8 +52,6 @@ curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/events" \
|
|
|
52
52
|
"id": "<event-uuid>",
|
|
53
53
|
"eventType": "node:created",
|
|
54
54
|
"nodeId": "<node-uuid>",
|
|
55
|
-
"boardId": "<BOARD_ID>",
|
|
56
|
-
"timestamp": 1234567890,
|
|
57
55
|
"chapterId": "<CHAPTER_ID>",
|
|
58
56
|
"cellId": "<actorRowId>-<columnId>",
|
|
59
57
|
"meta": {"type": "SCREEN", "title": "<Screen Title>", "fields": [...]}
|
|
@@ -43,7 +43,7 @@ A run that opens each element with its own `get_node` to "read existing examples
|
|
|
43
43
|
|
|
44
44
|
- `target` is a UUID → pass `nodeId`
|
|
45
45
|
- `target` is a name → pass `name`
|
|
46
|
-
- `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)
|
|
46
|
+
- `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). Only pass a cell name you were given or read back as a node's `cellName` (`get_board_outline`/`get_nodes`/`get_node` all report it) — if all you have is a node id or title, pass that instead rather than constructing an address.
|
|
47
47
|
|
|
48
48
|
```
|
|
49
49
|
mcp__eventmodelers__add_field_examples { "boardId": "$BOARD_ID", "nodeId": "<target, if a UUID>" }
|
|
@@ -105,8 +105,6 @@ mcp__eventmodelers__submit_node_events {
|
|
|
105
105
|
"id": "<uuid>",
|
|
106
106
|
"eventType": "node:changed",
|
|
107
107
|
"nodeId": "<TARGET_NODE.id>",
|
|
108
|
-
"boardId": "$BOARD_ID",
|
|
109
|
-
"timestamp": <epoch-ms>,
|
|
110
108
|
"changedAttributes": ["meta.fields"],
|
|
111
109
|
"meta": { "fields": "<updated-fields-array>" }
|
|
112
110
|
}]
|
|
@@ -94,13 +94,11 @@ Build the payload with Python to avoid shell JSON-escaping issues, then POST it:
|
|
|
94
94
|
|
|
95
95
|
```bash
|
|
96
96
|
python3 - <<EOF > /tmp/examples_payload.json
|
|
97
|
-
import json,
|
|
97
|
+
import json, uuid
|
|
98
98
|
payload = [{
|
|
99
99
|
"id": str(uuid.uuid4()),
|
|
100
100
|
"eventType": "node:changed",
|
|
101
101
|
"nodeId": "<TARGET_NODE.id>",
|
|
102
|
-
"boardId": "<BOARD_ID>",
|
|
103
|
-
"timestamp": int(time.time() * 1000),
|
|
104
102
|
"changedAttributes": ["meta.fields"],
|
|
105
103
|
"meta": {
|
|
106
104
|
"fields": <updated-fields-array as Python list>
|
|
@@ -43,7 +43,7 @@ Route to the matching section below based on `action`.
|
|
|
43
43
|
**Prefer MCP** — one call, `type` (`COMMENT`/`TASK`) passed straight through:
|
|
44
44
|
|
|
45
45
|
```
|
|
46
|
-
mcp__eventmodelers__add_comment { "boardId": "$BOARD_ID", "nodeId": "$NODE_ID", "text": "<text>", "type": "<COMMENT|TASK>", "author": "<author>" }
|
|
46
|
+
mcp__eventmodelers__add_comment { "boardId": "$BOARD_ID", "comments": [{ "nodeId": "$NODE_ID", "text": "<text>", "type": "<COMMENT|TASK>", "author": "<author>" }] }
|
|
47
47
|
```
|
|
48
48
|
|
|
49
49
|
**Fallback (no MCP):** see `references/api-fallback.md` — "Action: place".
|
|
@@ -58,7 +58,7 @@ curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/comments" \
|
|
|
58
58
|
{"nodeId":"<id2>","text":"<text2>","type":"QUESTION","author":"wdyt"}]'
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
-
Response: `201 {"results":[{"nodeId":"<id>","id":"<commentId>"}, …]}` in request order — an entry whose node doesn't exist reports `error` there without dropping the rest. Over MCP this is the `
|
|
61
|
+
Response: `201 {"results":[{"nodeId":"<id>","id":"<commentId>"}, …]}` in request order — an entry whose node doesn't exist reports `error` there without dropping the rest. Over MCP this is the `add_comment` tool's `comments` array.
|
|
62
62
|
|
|
63
63
|
**Report:**
|
|
64
64
|
```
|
|
@@ -97,7 +97,6 @@ mcp__eventmodelers__submit_node_events {
|
|
|
97
97
|
"boardId": "<BOARD_ID>",
|
|
98
98
|
"events": [{
|
|
99
99
|
"id": "<event-uuid>", "eventType": "node:changed", "nodeId": "<NODE_ID>",
|
|
100
|
-
"boardId": "<BOARD_ID>", "timestamp": <NOW_MS>,
|
|
101
100
|
"meta": {
|
|
102
101
|
"type": "HTML_SCREEN",
|
|
103
102
|
"title": "<Screen Title>",
|
|
@@ -136,12 +135,14 @@ mcp__eventmodelers__render_screen {
|
|
|
136
135
|
```
|
|
137
136
|
mcp__eventmodelers__create_screen {
|
|
138
137
|
"boardId": "<BOARD_ID>",
|
|
139
|
-
"
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
138
|
+
"screens": [{
|
|
139
|
+
"contentType": "html",
|
|
140
|
+
"nodeId": "<generated-uuid>",
|
|
141
|
+
"chapterId": "<CHAPTER_ID>",
|
|
142
|
+
"cellName": "<CELL_NAME>",
|
|
143
|
+
"pages": ["<div>...</div>"],
|
|
144
|
+
"fields": [ /* optional — set meta.fields here too (see Step 5) instead of a separate call */ ]
|
|
145
|
+
}]
|
|
145
146
|
}
|
|
146
147
|
```
|
|
147
148
|
|
|
@@ -174,7 +175,6 @@ mcp__eventmodelers__submit_node_events {
|
|
|
174
175
|
"boardId": "<BOARD_ID>",
|
|
175
176
|
"events": [{
|
|
176
177
|
"id": "<event-uuid>", "eventType": "node:changed", "nodeId": "<NODE_ID>",
|
|
177
|
-
"boardId": "<BOARD_ID>", "timestamp": <NOW_MS>,
|
|
178
178
|
"changedAttributes": ["meta.fields"],
|
|
179
179
|
"meta": { "type": "HTML_SCREEN", "fields": [
|
|
180
180
|
{"name": "status", "type": "String", "example": "confirmed", "mapping": "ActiveReservationView.status", "cardinality": "Single"}
|
|
@@ -39,7 +39,6 @@ curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/events" \
|
|
|
39
39
|
-H "Content-Type: application/json" \
|
|
40
40
|
-d '[{
|
|
41
41
|
"id": "<event-uuid>", "eventType": "node:changed", "nodeId": "<NODE_ID>",
|
|
42
|
-
"boardId": "<BOARD_ID>", "timestamp": <NOW_MS>,
|
|
43
42
|
"changedAttributes": ["meta.fields"],
|
|
44
43
|
"meta": { "type": "HTML_SCREEN", "fields": [
|
|
45
44
|
{"name": "status", "type": "String", "example": "confirmed", "mapping": "ActiveReservationView.status", "cardinality": "Single"}
|
|
@@ -44,14 +44,17 @@ Use `BOARD_ID` and `BASE_URL` from the `connect` skill. If a `boardId` argument
|
|
|
44
44
|
mcp__eventmodelers__place_element {
|
|
45
45
|
"boardId": "<BOARD_ID>",
|
|
46
46
|
"timelineId": "<TIMELINE_ID>",
|
|
47
|
-
"
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
47
|
+
"elements": [{
|
|
48
|
+
"elementType": "<COMMAND|READMODEL|EVENT>",
|
|
49
|
+
"title": "<title>",
|
|
50
|
+
"columnIndex": <position,
|
|
51
|
+
if given>,
|
|
52
|
+
"fields": [{ "name": "orderId", "type": "String", "example": "ord-1" }]
|
|
53
|
+
}]
|
|
51
54
|
}
|
|
52
55
|
```
|
|
53
56
|
|
|
54
|
-
Pass `fields` whenever the element's attributes are already known — they are written by this same call, so don't follow a placement with a `submit_node_events` just to set them. Placing **more than one** element is
|
|
57
|
+
Pass `fields` whenever the element's attributes are already known — they are written by this same call, so don't follow a placement with a `submit_node_events` just to set them. Placing **more than one** element is more entries in the same `elements` array, applied in order so each entry sees the columns the previous one added — one call for a whole slice's or column run's worth instead of one per element.
|
|
55
58
|
|
|
56
59
|
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.
|
|
57
60
|
|
|
@@ -274,13 +277,15 @@ mcp__eventmodelers__link_element { "boardId": "<BOARD_ID>", "nodeId": "<origin-n
|
|
|
274
277
|
```
|
|
275
278
|
mcp__eventmodelers__create_screen {
|
|
276
279
|
"boardId": "<BOARD_ID>",
|
|
277
|
-
"
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
280
|
+
"screens": [{
|
|
281
|
+
"contentType": "html",
|
|
282
|
+
"nodeId": "<node-uuid>",
|
|
283
|
+
"chapterId": "<TIMELINE_ID>",
|
|
284
|
+
"cellId": "<CELL_ID>",
|
|
285
|
+
"title": "<title>",
|
|
286
|
+
"pages": ["<div>...</div>"],
|
|
287
|
+
"description": "<title — what this screen shows>"
|
|
288
|
+
}]
|
|
284
289
|
}
|
|
285
290
|
```
|
|
286
291
|
|
|
@@ -293,13 +298,15 @@ mcp__eventmodelers__create_screen {
|
|
|
293
298
|
```
|
|
294
299
|
mcp__eventmodelers__create_screen {
|
|
295
300
|
"boardId": "<BOARD_ID>",
|
|
296
|
-
"
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
301
|
+
"screens": [{
|
|
302
|
+
"contentType": "sketch",
|
|
303
|
+
"nodeId": "<node-uuid>",
|
|
304
|
+
"chapterId": "<TIMELINE_ID>",
|
|
305
|
+
"cellId": "<CELL_ID>",
|
|
306
|
+
"title": "<title>",
|
|
307
|
+
"elements": [...],
|
|
308
|
+
"description": "<title — what this screen shows>"
|
|
309
|
+
}]
|
|
303
310
|
}
|
|
304
311
|
```
|
|
305
312
|
|
|
@@ -321,10 +328,9 @@ This step applies to `SCREEN` (view/output conflict case), `AUTOMATION`, `SCENAR
|
|
|
321
328
|
mcp__eventmodelers__submit_node_events {
|
|
322
329
|
"boardId": "<BOARD_ID>",
|
|
323
330
|
"events": [{
|
|
331
|
+
"id": "<event-uuid>",
|
|
324
332
|
"eventType": "node:created",
|
|
325
333
|
"nodeId": "<node-uuid>",
|
|
326
|
-
"boardId": "<BOARD_ID>",
|
|
327
|
-
"timestamp": <Date.now()>,
|
|
328
334
|
"chapterId": "<TIMELINE_ID>",
|
|
329
335
|
"cellId": "<CELL_ID>",
|
|
330
336
|
"meta": { "type": "<ELEMENT_TYPE>", "title": "<title>" },
|
|
@@ -343,10 +349,9 @@ mcp__eventmodelers__submit_node_events {
|
|
|
343
349
|
mcp__eventmodelers__submit_node_events {
|
|
344
350
|
"boardId": "<BOARD_ID>",
|
|
345
351
|
"events": [{
|
|
352
|
+
"id": "<event-uuid>",
|
|
346
353
|
"eventType": "node:created",
|
|
347
354
|
"nodeId": "<node-uuid>",
|
|
348
|
-
"boardId": "<BOARD_ID>",
|
|
349
|
-
"timestamp": <Date.now()>,
|
|
350
355
|
"chapterId": "<TIMELINE_ID>",
|
|
351
356
|
"cellName": "<CELL_NAME>",
|
|
352
357
|
"meta": { "type": "<ELEMENT_TYPE>", "title": "<title>" },
|
|
@@ -357,7 +362,7 @@ mcp__eventmodelers__submit_node_events {
|
|
|
357
362
|
|
|
358
363
|
**Fallback (no MCP):** see `references/api-fallback.md` — "Step 7b — Create any other node type (fast path, `cellName`)".
|
|
359
364
|
|
|
360
|
-
Response: `{ "hashes": { "<event-
|
|
365
|
+
Response: `{ "hashes": { "<event-id>": "<hash>" } }` — keyed by the `id` you sent on each event, which is how you match a hash back to the event that produced it.
|
|
361
366
|
|
|
362
367
|
> **`node:created` with `cellId`/`cellName` IS the placement** — do NOT also call the `drop` endpoint afterwards. The `drop` endpoint adds a second cell reference without removing the first, causing the node to appear in two columns simultaneously. Use `node:created` with `cellId` or `cellName` for all initial placements.
|
|
363
368
|
|
|
@@ -380,7 +385,7 @@ Count inbound edges where `target === COMMAND_NODE_ID` and the source node is ty
|
|
|
380
385
|
- **2 or more** → keep the edge whose source sits in the COMMAND's own column (the deliberate, same-slice issuer) and remove every other one:
|
|
381
386
|
|
|
382
387
|
```
|
|
383
|
-
mcp__eventmodelers__set_connection { "boardId": "<BOARD_ID>", "source": "<extra-issuer-node-id>", "target": "<COMMAND_NODE_ID>", "action": "remove" }
|
|
388
|
+
mcp__eventmodelers__set_connection { "boardId": "<BOARD_ID>", "connections": [{ "source": "<extra-issuer-node-id>", "target": "<COMMAND_NODE_ID>", "action": "remove" }] }
|
|
384
389
|
```
|
|
385
390
|
|
|
386
391
|
If it's not clear which edge is the deliberate one (e.g. neither source sits in the COMMAND's own column), do not guess — leave both edges and post a comment on the COMMAND node via `handle-comment` instead, describing the ambiguity.
|
|
@@ -411,4 +416,4 @@ Timeline: <timelineId>
|
|
|
411
416
|
|
|
412
417
|
## Example — place an EVENT via curl
|
|
413
418
|
|
|
414
|
-
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).
|
|
419
|
+
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>", "elements": [{ "elementType": "EVENT", "title": "Order Placed" }] }` (see "Prefer MCP" above).
|
package/stacks/modeling-kit/templates/.claude/skills/place-element/references/api-fallback.md
CHANGED
|
@@ -124,10 +124,9 @@ curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/events" \
|
|
|
124
124
|
-H "x-user-id: agent" \
|
|
125
125
|
-H "Content-Type: application/json" \
|
|
126
126
|
-d '[{
|
|
127
|
+
"id": "<event-uuid>",
|
|
127
128
|
"eventType": "node:created",
|
|
128
129
|
"nodeId": "<node-uuid>",
|
|
129
|
-
"boardId": "<BOARD_ID>",
|
|
130
|
-
"timestamp": <Date.now()>,
|
|
131
130
|
"chapterId": "<TIMELINE_ID>",
|
|
132
131
|
"cellId": "<CELL_ID>",
|
|
133
132
|
"meta": {
|
|
@@ -148,10 +147,9 @@ curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/events" \
|
|
|
148
147
|
-H "x-user-id: agent" \
|
|
149
148
|
-H "Content-Type: application/json" \
|
|
150
149
|
-d '[{
|
|
150
|
+
"id": "<event-uuid>",
|
|
151
151
|
"eventType": "node:created",
|
|
152
152
|
"nodeId": "<node-uuid>",
|
|
153
|
-
"boardId": "<BOARD_ID>",
|
|
154
|
-
"timestamp": <Date.now()>,
|
|
155
153
|
"chapterId": "<TIMELINE_ID>",
|
|
156
154
|
"cellName": "<CELL_NAME>",
|
|
157
155
|
"meta": {
|
|
@@ -162,11 +160,11 @@ curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/events" \
|
|
|
162
160
|
}]'
|
|
163
161
|
```
|
|
164
162
|
|
|
165
|
-
Response: `{ "hashes": { "<event-
|
|
163
|
+
Response: `{ "hashes": { "<event-id>": "<hash>" } }` — keyed by the `id` you sent on each event, which is how you match a hash back to the event that produced it.
|
|
166
164
|
|
|
167
165
|
## Full worked example — place an EVENT via curl, start to finish
|
|
168
166
|
|
|
169
|
-
With MCP connected, the same result is one call: `mcp__eventmodelers__place_element { "boardId": "<BOARD_ID>", "timelineId": "<TIMELINE_ID>", "elementType": "EVENT", "title": "Order Placed" }`.
|
|
167
|
+
With MCP connected, the same result is one call: `mcp__eventmodelers__place_element { "boardId": "<BOARD_ID>", "timelineId": "<TIMELINE_ID>", "elements": [{ "elementType": "EVENT", "title": "Order Placed" }] }`.
|
|
170
168
|
|
|
171
169
|
Placing an EVENT called "Order Placed" at the end of a timeline, over curl:
|
|
172
170
|
|
|
@@ -188,8 +186,6 @@ curl -s -X POST "http://localhost:3000/api/org/<ORG_ID>/boards/<BOARD_ID>/nodes/
|
|
|
188
186
|
"id": "<event-uuid>",
|
|
189
187
|
"eventType": "node:created",
|
|
190
188
|
"nodeId": "<node-uuid>",
|
|
191
|
-
"boardId": "<BOARD_ID>",
|
|
192
|
-
"timestamp": 1714900000000,
|
|
193
189
|
"chapterId": "<TIMELINE_ID>",
|
|
194
190
|
"cellId": "<CELL_ID>",
|
|
195
191
|
"meta": { "type": "EVENT", "title": "Order Placed" },
|
|
@@ -197,4 +193,4 @@ curl -s -X POST "http://localhost:3000/api/org/<ORG_ID>/boards/<BOARD_ID>/nodes/
|
|
|
197
193
|
}]'
|
|
198
194
|
```
|
|
199
195
|
|
|
200
|
-
Replace `<TIMELINE_ID>`, `<BOARD_ID>`, `<CELL_ID>`, `<event-uuid
|
|
196
|
+
Replace `<TIMELINE_ID>`, `<BOARD_ID>`, `<CELL_ID>`, `<event-uuid>` and `<node-uuid>` with real values — you mint two uuids here: the node's and the event's own `id`, which is required. `boardId`/`timestamp` are omitted on purpose: the server derives both from the request and ignores them if sent.
|
|
@@ -179,13 +179,15 @@ Build the payload, then send a single call that creates the screen node, places
|
|
|
179
179
|
```
|
|
180
180
|
mcp__eventmodelers__create_screen {
|
|
181
181
|
"boardId": "<BOARD_ID>",
|
|
182
|
-
"
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
182
|
+
"screens": [{
|
|
183
|
+
"contentType": "html",
|
|
184
|
+
"nodeId": "<SCREEN_NODE_ID>",
|
|
185
|
+
"chapterId": "<CHAPTER_ID>",
|
|
186
|
+
"cellId": "<actorCellId>",
|
|
187
|
+
"title": "<screenTitle>",
|
|
188
|
+
"pages": ["<div>...</div>"],
|
|
189
|
+
"description": "<screenTitle — what this screen shows>"
|
|
190
|
+
}]
|
|
189
191
|
}
|
|
190
192
|
```
|
|
191
193
|
|
|
@@ -198,13 +200,15 @@ mcp__eventmodelers__create_screen {
|
|
|
198
200
|
```
|
|
199
201
|
mcp__eventmodelers__create_screen {
|
|
200
202
|
"boardId": "<BOARD_ID>",
|
|
201
|
-
"
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
203
|
+
"screens": [{
|
|
204
|
+
"contentType": "sketch",
|
|
205
|
+
"nodeId": "<SCREEN_NODE_ID>",
|
|
206
|
+
"chapterId": "<CHAPTER_ID>",
|
|
207
|
+
"cellId": "<actorCellId>",
|
|
208
|
+
"title": "<screenTitle>",
|
|
209
|
+
"elements": [...],
|
|
210
|
+
"description": "<screenTitle — what this screen shows>"
|
|
211
|
+
}]
|
|
208
212
|
}
|
|
209
213
|
```
|
|
210
214
|
|
|
@@ -224,7 +228,6 @@ mcp__eventmodelers__submit_node_events {
|
|
|
224
228
|
"boardId": "<BOARD_ID>",
|
|
225
229
|
"events": [{
|
|
226
230
|
"id": "<event-uuid>", "eventType": "node:changed", "nodeId": "<SCREEN_NODE_ID>",
|
|
227
|
-
"boardId": "<BOARD_ID>", "timestamp": <NOW_MS>,
|
|
228
231
|
"changedAttributes": ["meta.fields"],
|
|
229
232
|
"meta": { "type": "HTML_SCREEN", "fields": [ /* planned fields */ ] }
|
|
230
233
|
}]
|
|
@@ -67,7 +67,6 @@ curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/events" \
|
|
|
67
67
|
-H "Content-Type: application/json" \
|
|
68
68
|
-d '[{
|
|
69
69
|
"id": "<event-uuid>", "eventType": "node:changed", "nodeId": "<SCREEN_NODE_ID>",
|
|
70
|
-
"boardId": "<BOARD_ID>", "timestamp": <NOW_MS>,
|
|
71
70
|
"changedAttributes": ["meta.fields"],
|
|
72
71
|
"meta": { "type": "HTML_SCREEN", "fields": [ /* planned fields */ ] }
|
|
73
72
|
}]'
|
|
@@ -122,7 +122,6 @@ mcp__eventmodelers__submit_node_events {
|
|
|
122
122
|
"boardId": "<BOARD_ID>",
|
|
123
123
|
"events": [{
|
|
124
124
|
"id": "<event-uuid>", "eventType": "node:changed", "nodeId": "<NODE_ID>",
|
|
125
|
-
"boardId": "<BOARD_ID>", "timestamp": <NOW_MS>,
|
|
126
125
|
"changedAttributes": ["meta.fields"],
|
|
127
126
|
"meta": { "type": "SCREEN", "fields": [
|
|
128
127
|
{"name": "status", "type": "String", "example": "confirmed", "mapping": "ActiveReservationView.status", "cardinality": "Single"}
|
package/stacks/modeling-kit/templates/.claude/skills/storyboard-screen/references/api-fallback.md
CHANGED
|
@@ -33,7 +33,6 @@ curl -s -X POST "$BASE_URL/api/org/$ORG_ID/boards/$BOARD_ID/nodes/events" \
|
|
|
33
33
|
-H "Content-Type: application/json" \
|
|
34
34
|
-d '[{
|
|
35
35
|
"id": "<event-uuid>", "eventType": "node:changed", "nodeId": "<NODE_ID>",
|
|
36
|
-
"boardId": "<BOARD_ID>", "timestamp": <NOW_MS>,
|
|
37
36
|
"changedAttributes": ["meta.fields"],
|
|
38
37
|
"meta": { "type": "SCREEN", "fields": [
|
|
39
38
|
{"name": "status", "type": "String", "example": "confirmed", "mapping": "ActiveReservationView.status", "cardinality": "Single"}
|
|
@@ -191,7 +191,7 @@ emptyColumns = [columnId, ...] // in column order, ready to reuse
|
|
|
191
191
|
|
|
192
192
|
**Prefer MCP:**
|
|
193
193
|
```
|
|
194
|
-
mcp__eventmodelers__delete_column { "boardId": "<BOARD_ID>", "timelineId": "<CHAPTER_ID>", "
|
|
194
|
+
mcp__eventmodelers__delete_column { "boardId": "<BOARD_ID>", "timelineId": "<CHAPTER_ID>", "columnIds": ["<columnId>"] }
|
|
195
195
|
```
|
|
196
196
|
|
|
197
197
|
**Fallback (no MCP):** see `references/api-fallback.md` — "Delete a column".
|
|
@@ -246,8 +246,6 @@ mcp__eventmodelers__submit_node_events {
|
|
|
246
246
|
"id": "<event-uuid>",
|
|
247
247
|
"eventType": "node:created",
|
|
248
248
|
"nodeId": "<node-uuid>",
|
|
249
|
-
"boardId": "<BOARD_ID>",
|
|
250
|
-
"timestamp": <Date.now()>,
|
|
251
249
|
"chapterId": "<CHAPTER_ID>",
|
|
252
250
|
"cellId": "<CELL_ID>",
|
|
253
251
|
"meta": { "type": "EVENT", "title": "<EventName>" },
|
|
@@ -262,7 +260,7 @@ mcp__eventmodelers__submit_node_events {
|
|
|
262
260
|
|
|
263
261
|
**Prefer MCP:** this whole "find/create a column, compute the cell, place the node" sequence collapses into one call:
|
|
264
262
|
```
|
|
265
|
-
mcp__eventmodelers__place_element { "boardId": "<BOARD_ID>", "timelineId": "<CHAPTER_ID>", "elementType": "EVENT", "title": "<EventName>", "columnIndex": <index> }
|
|
263
|
+
mcp__eventmodelers__place_element { "boardId": "<BOARD_ID>", "timelineId": "<CHAPTER_ID>", "elements": [{ "elementType": "EVENT", "title": "<EventName>", "columnIndex": <index> }] }
|
|
266
264
|
```
|
|
267
265
|
Extract `nodeId` and `columnId` directly from the tool result.
|
|
268
266
|
|
|
@@ -302,8 +300,6 @@ mcp__eventmodelers__submit_node_events {
|
|
|
302
300
|
"id": "<new-uuid>",
|
|
303
301
|
"eventType": "node:changed",
|
|
304
302
|
"nodeId": "<eventNodeId>",
|
|
305
|
-
"boardId": "<BOARD_ID>",
|
|
306
|
-
"timestamp": <Date.now()>,
|
|
307
303
|
"changedAttributes": ["meta.title"],
|
|
308
304
|
"meta": { "type": "EVENT", "title": "<NewTitle>" },
|
|
309
305
|
"node": { "id": "<eventNodeId>", "data": {} }
|
|
@@ -323,7 +319,7 @@ Two steps — delete the node, then delete the column:
|
|
|
323
319
|
|
|
324
320
|
**Prefer MCP:**
|
|
325
321
|
```
|
|
326
|
-
mcp__eventmodelers__delete_node { "boardId": "<BOARD_ID>", "
|
|
322
|
+
mcp__eventmodelers__delete_node { "boardId": "<BOARD_ID>", "nodeIds": ["<eventNodeId>"] }
|
|
327
323
|
```
|
|
328
324
|
|
|
329
325
|
**Fallback (no MCP):** see `references/api-fallback.md` — "Delete an event node".
|
|
@@ -332,7 +328,7 @@ mcp__eventmodelers__delete_node { "boardId": "<BOARD_ID>", "nodeId": "<eventNode
|
|
|
332
328
|
|
|
333
329
|
**Prefer MCP:**
|
|
334
330
|
```
|
|
335
|
-
mcp__eventmodelers__delete_column { "boardId": "<BOARD_ID>", "timelineId": "<CHAPTER_ID>", "
|
|
331
|
+
mcp__eventmodelers__delete_column { "boardId": "<BOARD_ID>", "timelineId": "<CHAPTER_ID>", "columnIds": ["<columnId>"] }
|
|
336
332
|
```
|
|
337
333
|
|
|
338
334
|
**Fallback (no MCP):** see `references/api-fallback.md` — "Delete a column".
|