@eventmodelers/cli 1.0.9 → 1.0.11
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
|
@@ -29,7 +29,8 @@ Server name: `eventmodelers`. Every tool takes `boardId` explicitly; none need `
|
|
|
29
29
|
| `delete_node` | `boardId`, `nodeId` | Delete a node. Deleting a chapter (timeline) cascades — every node placed in one of its cells, plus any node parented to it (e.g. SLICE_BORDER), is deleted too, along with all their edges | (via `node:deleted` event, §3) |
|
|
30
30
|
| `create_drawing` | `boardId`, `kind`, `x`, `y`, `width`, `height`, ... | Freehand canvas annotation (path/rect/text) — never placed in a cell | — (no REST equivalent; MCP-only) |
|
|
31
31
|
| `find_nodes_in_drawing` | `boardId`, `drawingId` | Nodes fully contained inside a drawing's bounding box | — (no REST equivalent; MCP-only) |
|
|
32
|
-
| `create_chapter` | `boardId`, `x?`, `y?` | Create a timeline | §2 `POST .../chapters` |
|
|
32
|
+
| `create_chapter` | `boardId`, `x?`, `y?` | Create a timeline. Omitting `x`/`y` auto-stacks it below the lowest existing chapter (by its *actual current* row-height total, not the height it was created with — safe even after `add_lane` growth), plus a fixed margin | §2 `POST .../chapters` |
|
|
33
|
+
| `get_chapter_bounds` | `boardId` | Absolute canvas bounding box `{id, title, x, y, width, height}` of every chapter on the board — width/height derived from each chapter's current row/column layout, not a guessed default. Use before picking explicit `x`/`y` for `create_chapter` (e.g. placing below the chapter with the largest `y + height`) to avoid overlapping one that grew since it was created | §2 `GET .../chapters/bounds` |
|
|
33
34
|
| `add_column` | `boardId`, `timelineId`, `index?` | Add a column | §2 `POST .../timelines/:id/columns` |
|
|
34
35
|
| `delete_column` | `boardId`, `timelineId`, `columnId` | Delete a column | §2 `DELETE .../columns/:columnId` |
|
|
35
36
|
| `add_lane` | `boardId`, `timelineId`, `type`, `label?`, `index?` | Add a lane/row | §2 `POST .../timelines/:id/lanes` |
|
|
@@ -47,6 +48,7 @@ Server name: `eventmodelers`. Every tool takes `boardId` explicitly; none need `
|
|
|
47
48
|
| `get_slice_data` | `boardId`, `contextName?`, `contextId?`, `sliceId?` | Full element graph for slices in a context | §8 `GET /slicedata` |
|
|
48
49
|
| `get_spec_info` | `boardId`, `timelineId` | EVENT/COMMAND/READMODEL nodes valid in GWT steps | §6 `GET .../spec-info` |
|
|
49
50
|
| `add_scenario` | `boardId`, `timelineId`, `columnId`, `scenarios[]` | Append GWT scenario(s) to a column's spec node | §6 `POST .../scenarios` |
|
|
51
|
+
| `add_storyline` | `boardId`, `timelineId`, `columnId`, `storylines[]` | **Experimental — only use when explicitly asked for a storyline/walkthrough.** Append storyline(s) (ordered, branchable beats over existing elements) to a column's spec node | §6 `POST .../storylines` |
|
|
50
52
|
| `set_connection` | `boardId`, `source`, `target`, `action` (`'connect'\|'remove'`) | Add or remove a type-checked directed edge | — (via `edges` on §3 events) |
|
|
51
53
|
| `auto_connect_node` | `boardId`, `nodeId` | Re-run auto-connect for a node | §3 `POST .../nodes/:nodeId/auto-connect` |
|
|
52
54
|
| `add_comment` | `boardId`, `nodeId`, `text`, `type?` (`'COMMENT'\|'TASK'\|'QUESTION'`), `author?` | Add a comment — `QUESTION` flags gaps/edge cases during review | — (via comment events) |
|
|
@@ -217,6 +219,15 @@ Create a chapter node.
|
|
|
217
219
|
**Request body**: `{ position?: { x: number, y: number } }`
|
|
218
220
|
**Response**: `200` — chapter data
|
|
219
221
|
|
|
222
|
+
Omitting `position` auto-stacks the new chapter below the lowest existing chapter on the board, using each existing chapter's *actual current* row-height total (not the height it was created with) plus a fixed margin — so a chapter that grew via `add_lane`/`add_column` after another was stacked below it won't get overlapped by yet another auto-stacked chapter.
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
### GET `/api/org/:orgId/boards/:boardId/chapters/bounds`
|
|
227
|
+
Get the absolute canvas bounding box of every chapter on the board — the same real-current-size derivation `create_chapter`'s auto-stacking uses internally, exposed for callers who want to compute a placement themselves (e.g. an explicit `x`/`y`, or a position relative to a specific chapter rather than "below everything").
|
|
228
|
+
|
|
229
|
+
**Response**: `200` — `{ chapters: Array<{ id: string, title?: string, x: number, y: number, width: number, height: number }> }`
|
|
230
|
+
|
|
220
231
|
---
|
|
221
232
|
|
|
222
233
|
### POST `/api/org/:orgId/boards/:boardId/timelines/:timelineId/columns`
|
|
@@ -513,6 +524,48 @@ Get valid elements for a specific slice.
|
|
|
513
524
|
|
|
514
525
|
---
|
|
515
526
|
|
|
527
|
+
### Storylines (experimental)
|
|
528
|
+
|
|
529
|
+
> **Only create a storyline when the user's request explicitly asks for one** — the word
|
|
530
|
+
> "storyline", "walkthrough", or "narrative" (or equivalent) must appear in what they asked for.
|
|
531
|
+
> Otherwise keep creating normal GWT scenarios via `add_scenario`/`POST .../scenarios` as before.
|
|
532
|
+
|
|
533
|
+
An ordered, branchable walkthrough of existing board elements ("beats"), stored alongside GWT
|
|
534
|
+
scenarios on the same SCENARIO spec node, in a sibling `meta.storylines` collection.
|
|
535
|
+
|
|
536
|
+
### POST `/api/org/:orgId/boards/:boardId/timelines/:timelineId/columns/:columnId/storylines`
|
|
537
|
+
Append one or more storylines to a column's spec node. The spec node is auto-created if missing
|
|
538
|
+
(shared with scenarios).
|
|
539
|
+
|
|
540
|
+
**Request body**: a single storyline object or an array:
|
|
541
|
+
```typescript
|
|
542
|
+
{
|
|
543
|
+
id: string
|
|
544
|
+
title: string // must be unique within the spec node
|
|
545
|
+
description?: string
|
|
546
|
+
layout?: 'horizontal' | 'vertical'
|
|
547
|
+
beats: Array<{
|
|
548
|
+
instanceId: string // unique per beat, even when refId repeats
|
|
549
|
+
refId: string // board node id — must belong to the same timeline
|
|
550
|
+
type?: string
|
|
551
|
+
title?: string
|
|
552
|
+
isError?: boolean // marks an alternate/error branch off the previous beat
|
|
553
|
+
fields?: unknown[]
|
|
554
|
+
expectEmptyList?: boolean
|
|
555
|
+
exampleMode?: string
|
|
556
|
+
examples?: unknown[]
|
|
557
|
+
}>
|
|
558
|
+
}
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
**Response**:
|
|
562
|
+
- `201` — `{ specNodeId, storylines, added, isNewNode }`
|
|
563
|
+
- `400` — validation error
|
|
564
|
+
- `404` — timeline, column, or referenced node not found
|
|
565
|
+
- `409` — duplicate storyline title
|
|
566
|
+
|
|
567
|
+
---
|
|
568
|
+
|
|
516
569
|
## 7. Config Import
|
|
517
570
|
|
|
518
571
|
**File**: `src/slices/change/config-import/routes.ts`
|
package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-elaborating-scenarios/SKILL.md
CHANGED
|
@@ -13,6 +13,61 @@ allowed-tools:
|
|
|
13
13
|
|
|
14
14
|
Prefer `mcp__eventmodelers__*` tools when available (registered by the `connect` skill) — the curl blocks below are the fallback for sessions without MCP connected.
|
|
15
15
|
|
|
16
|
+
## Storylines — an On-Demand Alternative to GWT Scenarios (Experimental)
|
|
17
|
+
|
|
18
|
+
**By default, this skill always produces GWT scenarios.** Storylines are a separate, experimental
|
|
19
|
+
artifact — only build one when the user's request explicitly asks for a "storyline", "walkthrough",
|
|
20
|
+
or "narrative". Never generate a storyline as a side effect of ordinary scenario elaboration.
|
|
21
|
+
|
|
22
|
+
A GWT scenario asserts one isolated transition: a single precondition, a single action, a single
|
|
23
|
+
resulting outcome. A storyline instead narrates one specific use case as an ordered sequence of
|
|
24
|
+
**beats**, where the *same* element (usually a read model) is walked through multiple states across
|
|
25
|
+
one flow — something no single GWT scenario can express, since GWT only ever asserts one
|
|
26
|
+
before/after pair at a time.
|
|
27
|
+
|
|
28
|
+
**Example** — a customer-activation walkthrough of a Todos read model:
|
|
29
|
+
1. **Beat 1** — the Todos read model, starting empty.
|
|
30
|
+
2. **Beat 2** — after a `CustomerRegistered` event, the same Todos read model now shows one entry
|
|
31
|
+
(an "activate your account" todo).
|
|
32
|
+
3. **Beat 3** — after a `CustomerActivated` event, the same Todos read model is empty again (the
|
|
33
|
+
todo was completed and removed).
|
|
34
|
+
|
|
35
|
+
Three separate GWT scenarios could each assert one of those transitions in isolation, but a
|
|
36
|
+
storyline threads all three together as one narrated walkthrough of the read model's lifecycle —
|
|
37
|
+
useful for a stakeholder-facing walkthrough of a use case, not for exhaustive GWT coverage. Keep
|
|
38
|
+
producing ordinary Given/When/Then scenarios for everything else.
|
|
39
|
+
|
|
40
|
+
### Storyline data shape
|
|
41
|
+
|
|
42
|
+
```json
|
|
43
|
+
{
|
|
44
|
+
"id": "<uuid>",
|
|
45
|
+
"title": "Customer activation walkthrough",
|
|
46
|
+
"description": "Optional narrative summary",
|
|
47
|
+
"layout": "horizontal",
|
|
48
|
+
"beats": [
|
|
49
|
+
{ "instanceId": "<uuid>", "refId": "<readmodel-node-id>", "type": "READMODEL", "title": "Todos", "exampleMode": "list", "expectEmptyList": true, "examples": [] },
|
|
50
|
+
{ "instanceId": "<uuid>", "refId": "<event-node-id>", "type": "EVENT", "title": "CustomerRegistered" },
|
|
51
|
+
{ "instanceId": "<uuid>", "refId": "<readmodel-node-id>", "type": "READMODEL", "title": "Todos", "exampleMode": "list", "examples": [{"task": "Activate your account"}] },
|
|
52
|
+
{ "instanceId": "<uuid>", "refId": "<event-node-id-2>", "type": "EVENT", "title": "CustomerActivated" },
|
|
53
|
+
{ "instanceId": "<uuid>", "refId": "<readmodel-node-id>", "type": "READMODEL", "title": "Todos", "exampleMode": "list", "expectEmptyList": true, "examples": [] }
|
|
54
|
+
]
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
- `layout`: `"horizontal"` or `"vertical"` — how the beats are laid out in the storyline editor.
|
|
59
|
+
- Each beat has an `instanceId` (unique per beat, even when the same `refId` repeats — this is what
|
|
60
|
+
lets the *same* element, like the Todos read model above, appear multiple times across the
|
|
61
|
+
walkthrough, once per state) and a `refId` (the board node this beat walks through — any element
|
|
62
|
+
type, not just EVENT/COMMAND/READMODEL — e.g. a SCREEN beat to show the resulting UI).
|
|
63
|
+
- `isError` marks a beat as an alternate/error branch off the previous beat.
|
|
64
|
+
- `fields`, `expectEmptyList`, `exampleMode`, `examples` mirror the same fields GWT scenario steps
|
|
65
|
+
use, letting a beat show concrete example data the same way a "then" readmodel step does.
|
|
66
|
+
|
|
67
|
+
Post storylines via `POST .../timelines/:tl/columns/:col/storylines` (see `learn-eventmodelers-api`
|
|
68
|
+
for the full endpoint contract) — the same auto-create-if-missing SCENARIO spec node scenarios use,
|
|
69
|
+
in a sibling `meta.storylines` collection.
|
|
70
|
+
|
|
16
71
|
## Interview Phase (Optional)
|
|
17
72
|
|
|
18
73
|
**When to Interview**: Skip if the user has already specified: scenario coverage depth (happy path + validation + state violations), known edge cases to include, and stakeholders available for review. Interview when coverage goals are unclear or edge cases haven't been identified.
|