@eventmodelers/cli 1.0.123 → 1.0.125
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/README.md +1 -0
- package/package.json +1 -1
- package/shared/skills/learn-eventmodelers-api/SKILL.md +11 -2
- package/stacks/modeling-kit/templates/.claude/skills/detect-model-drift/SKILL.md +4 -6
- package/stacks/modeling-kit/templates/.claude/skills/discover-storyboard/SKILL.md +2 -1
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-brainstorming-events/SKILL.md +4 -2
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-designing-automation-chains/SKILL.md +6 -4
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-inputs/SKILL.md +6 -4
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-outputs/SKILL.md +7 -5
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-orchestrating-event-modeling/SKILL.md +3 -2
- package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-storyboarding-events/SKILL.md +2 -1
- package/stacks/modeling-kit/templates/.claude/skills/examples/SKILL.md +2 -1
- package/stacks/modeling-kit/templates/.claude/skills/html-screen/SKILL.md +4 -2
- package/stacks/modeling-kit/templates/.claude/skills/place-element/SKILL.md +10 -6
- package/stacks/modeling-kit/templates/.claude/skills/storyboard/SKILL.md +2 -1
- package/stacks/modeling-kit/templates/.claude/skills/storyboard-screen/SKILL.md +2 -1
- package/stacks/modeling-kit/templates/.claude/skills/timeline/SKILL.md +5 -3
- package/stacks/modeling-kit/templates/.claude/skills/walkthrough/SKILL.md +146 -0
- package/stacks/modeling-kit/templates/kit/CLAUDE.md +7 -0
package/README.md
CHANGED
|
@@ -106,6 +106,7 @@ Use skills in Claude Code with `/skill-name`:
|
|
|
106
106
|
| `/connect` | Set up board connection |
|
|
107
107
|
| `/timeline` | Live event storming facilitator |
|
|
108
108
|
| `/wdyt` | Business analyst review of your event model |
|
|
109
|
+
| `/walkthrough` | Step-by-step player through a process, or through everything a planned change touches |
|
|
109
110
|
| `/storyboard` | Build a full visual storyboard |
|
|
110
111
|
| `/html-screen` | Design individual real HTML/CSS screens (default) |
|
|
111
112
|
| `/storyboard-screen` | Design individual wireframe/sketch screens (explicit request only) |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eventmodelers/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.125",
|
|
4
4
|
"description": "Eventmodelers CLI — real-time Claude agent + skills for Claude Code, for any stack (Node, Supabase, Axon, OpenCQRS, UmaDB, Kurrent, or modeling-only)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -30,7 +30,7 @@ Write tools take their items as an array (`nodeIds[]`, `elements[]`, `connection
|
|
|
30
30
|
| `get_node` | `boardId`, `nodeId`, `projection?` (`"cells"` \| `"edges"`) | Get one node (no `cellName` — address it by `nodeId`; cell addresses come only from `get_board_outline`). `projection: "cells"` (CHAPTER nodes only) returns just `{rows, columns, cells}` instead of the full `timelineData` — use whenever only the grid/occupancy is needed, not the whole chapter; `projection: "edges"` returns just that node's inbound/outbound connections instead of `findNodeById`'s full record. Both are opt-in — omitting `projection` is the unchanged full response. An unknown id is a `NODE_NOT_FOUND` error | §3 `GET .../nodes/:nodeId` (REST returns the node as stored, without `cellName`; `404` carries `code: 'NODE_NOT_FOUND'`) |
|
|
31
31
|
| `get_node_comments` | `boardId`, `nodeId` | List comments on a node | §1 `GET .../nodes/:nodeId/comments` |
|
|
32
32
|
| `get_chat_attachment` | `boardId`, `sessionId`, `attachmentId` | The file a chat message came with — the message's `attachments` list `{id, type, ending}`. Images come back as images, a PDF as an embedded resource, csv / xml / txt / json as text. Only the agent the message was addressed to can read it (`CHAT_ATTACHMENT_NOT_FOUND`); needs the connection's `x-agent-id` (`CHAT_AGENT_REQUIRED`). Max 5 MB per file. | §15 `GET /api/org/:orgId/chat/sessions/:sessionId/attachments/:attachmentId` |
|
|
33
|
-
| `post_chat_message` | `boardId`, `text`, `replyTo?`, `sessionId?`, `preferUserId?`, `snippet?` | Write into a person's chat — a reply (`replyTo` marks their message answered) or a question you start (`preferUserId`). `text` ≤ 1000 characters. `snippet` attaches one interactive element under the text (confirm, poll, tasks, changes, link, image, code, report); the person's choice comes back as their next chat message. See §16 | §16 `POST /api/org/:orgId/boards/:boardId/chat/agent-messages` |
|
|
33
|
+
| `post_chat_message` | `boardId`, `text`, `replyTo?`, `sessionId?`, `preferUserId?`, `snippet?` | Write into a person's chat — a reply (`replyTo` marks their message answered) or a question you start (`preferUserId`). `text` ≤ 1000 characters. `snippet` attaches one interactive element under the text (confirm, poll, tasks, changes, link, image, code, report, walkthrough); the person's choice comes back as their next chat message. See §16 | §16 `POST /api/org/:orgId/boards/:boardId/chat/agent-messages` |
|
|
34
34
|
| `get_board_events` | `boardId`, `since?`, `seq?` | A page of at most 300 board events, oldest first, as `{events, pageSize, hasMore}`. Not the whole log: while `hasMore` is true, page on by passing the last event's `seq` as `since`. `seq` returns only the event of exactly that seq | §1 `GET .../events` |
|
|
35
35
|
| `submit_node_events` | `boardId`, `events[]`, `autoConnect?`, `compact?` | Create/update nodes (raw `NodeChangeEvent`/edge events). Every event property is described on the tool's own `events[]` schema — read that rather than this skill when all you need is the event shape. An event needs its own `id` (required — a fresh uuid per event, never the node id) and its `eventType`, plus the keys of its kind (`nodeId`/`meta`/`node`, or `edgeId`/`source`/`target`). The `id` keys the returned `hashes` map and makes a resubmit idempotent — the same event sent twice under one id writes a single board event. Don't send `boardId` or `timestamp` per event — the server takes the board from the call and stamps the time itself, and ignores both if sent. `autoConnect: false` places freshly-created nodes without wiring them to their own/previous-column neighbors (avoids a stray nearest-left edge); `compact: true` returns `{persisted: <count>}` instead of the per-node hash map | §3 `POST .../nodes/events` |
|
|
36
36
|
| `delete_node` | `boardId`, `nodeIds[]` | Delete nodes, applied in order — one failure doesn't stop the rest; answers `{results}`. 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) |
|
|
@@ -1120,8 +1120,9 @@ Rule of thumb: if you are about to write "Shall I…?", "Want me to…?", "A or
|
|
|
1120
1120
|
| to show a picture | `image` | nothing |
|
|
1121
1121
|
| to show a command or payload | `code` | nothing |
|
|
1122
1122
|
| to show numbers as a diagram (counts per slice, a trend, shares of a whole) | `report` | nothing |
|
|
1123
|
+
| to explain how a process works, or walk through what a planned change touches, step by step ("how does registration work?", "we need to add an email — walk me through it") | `walkthrough` | nothing — selecting a step pans the canvas |
|
|
1123
1124
|
|
|
1124
|
-
`confirm`, `poll`, `tasks` and `changes` are questions: a person answers once, then they show as answered. `link`, `image`, `code` and `
|
|
1125
|
+
`confirm`, `poll`, `tasks` and `changes` are questions: a person answers once, then they show as answered. `link`, `image`, `code`, `report` and `walkthrough` are display only and never wait for anything.
|
|
1125
1126
|
|
|
1126
1127
|
### Shapes
|
|
1127
1128
|
```typescript
|
|
@@ -1143,6 +1144,13 @@ Rule of thumb: if you are about to write "Shall I…?", "Want me to…?", "A or
|
|
|
1143
1144
|
labels: string[], // 1–50 points: x axis, or the pie slices
|
|
1144
1145
|
series: Array<{ name: string, values: number[] }>, // one number per label; bar/line up to 6 series, pie uses only the first (no negatives)
|
|
1145
1146
|
confirm?: { headline: string, yesLabel?: string, noLabel?: string } } // optional yes/no question under the diagram, like a confirm snippet
|
|
1147
|
+
{ kind: 'walkthrough', title: string, intro?: string, // a step-by-step player through a process
|
|
1148
|
+
steps: Array<{ title: string, // 1+, in the order the process runs
|
|
1149
|
+
description?: string, // what happens in this step, in business words
|
|
1150
|
+
nodeId?: string, // the element, slice (SLICE_BORDER) or scenario (SCENARIO) of this step — selecting the step zooms to it
|
|
1151
|
+
screenId?: string, // the SCREEN / HTML_SCREEN the person sees in this step
|
|
1152
|
+
rules?: string[], // business rules that apply in this step
|
|
1153
|
+
changes?: string[] }> } // for a planned change: what has to change here
|
|
1146
1154
|
```
|
|
1147
1155
|
|
|
1148
1156
|
### How to use them
|
|
@@ -1153,6 +1161,7 @@ Rule of thumb: if you are about to write "Shall I…?", "Want me to…?", "A or
|
|
|
1153
1161
|
- **Answers are text.** For a `tasks` answer, match the titles (or ids) back to your list; an element the person left unticked was declined, not forgotten. A `poll` option with a `message` of your own makes the answer unambiguous.
|
|
1154
1162
|
- `get_chat_session` shows your snippet on the message as `snippet`, and the person's answer is the user message after it, carrying `context.snippetReply.messageId` (your message's id) — useful to tell an answer to a snippet from a new message.
|
|
1155
1163
|
- **`report`** draws the numbers you send — it computes nothing, so aggregate first. A series whose length differs from `labels`, or a non-number, makes the whole snippet invisible. Keep `text` as a one-line summary of what the diagram shows. Add `confirm` when the diagram leads to a follow-up question ("Want me to look into the backward arrows?"): the answer comes back like a `confirm` answer, and without it the report is display only.
|
|
1164
|
+
- **`walkthrough`** answers "how does X work?" and "walk me through what changes for Y": the person steps back and forth through the process in the chat, each step zooming the canvas to its element, and **Play** opens it full-screen as a movie strip of the steps' screens with description and rules underneath. Build it from the board, never from memory — the `walkthrough` skill (modeling kit) has the procedure. Every `nodeId`/`screenId` must be a real id from this board; a step without a screen just shows its element. Keep `text` to one line naming the process and the number of steps.
|
|
1156
1165
|
- A snippet is shown exactly as you send it — keep secrets and tokens out of `code` and `image`.
|
|
1157
1166
|
|
|
1158
1167
|
---
|
|
@@ -65,11 +65,10 @@ Index the result in memory: per slice → commands, events, read models, screens
|
|
|
65
65
|
|
|
66
66
|
The code base is the directory resolved in Step 0 (`$EVENTMODELERS_CODE_DIR`, else the current directory) — every path below is relative to it, and it may hold any stack. Find out which, don't assume.
|
|
67
67
|
|
|
68
|
-
**With a `branch` other than the one checked out, read the code from git, never from the working tree:** `git ls-tree -r --name-only $REF [<dir>]` lists the files, `git show $REF:<path>` reads one. That applies to everything below — `.build-kit/CLAUDE.md`, the
|
|
68
|
+
**With a `branch` other than the one checked out, read the code from git, never from the working tree:** `git ls-tree -r --name-only $REF [<dir>]` lists the files, `git show $REF:<path>` reads one. That applies to everything below — `.build-kit/CLAUDE.md`, the slice folders. Never `git checkout`/`git switch`: the working tree may hold someone's uncommitted work. Without `branch`, or when it is the current branch, read the working tree as usual.
|
|
69
69
|
|
|
70
70
|
1. Read `.build-kit/CLAUDE.md` (and `.build-kit/AGENTS.md` if present) — its *Structure* section says where slices live and how they're named (e.g. `src/slices/{slice}/` for Node, `src/main/java/.../slices/{context}/{slice}/` for Axon).
|
|
71
|
-
2.
|
|
72
|
-
3. Without a build kit, infer the layout from the repo (folders named after slices, `*Command*`, `*Event*`, projection/read-model files, route/UI files). If you cannot find any slice structure, stop and tell the user what you looked at — do not fabricate a mapping.
|
|
71
|
+
2. Without a build kit, infer the layout from the repo (folders named after slices, `*Command*`, `*Event*`, projection/read-model files, route/UI files). If you cannot find any slice structure, stop and tell the user what you looked at — do not fabricate a mapping.
|
|
73
72
|
|
|
74
73
|
Build a **code inventory** per slice folder: the command type and its fields, the events it emits and their fields, read-model/projection types and fields, the screens/components/routes wired to it, tests and what they assert, and what each handler/projection/automation reads and writes.
|
|
75
74
|
|
|
@@ -109,9 +108,7 @@ For every finding, pick who should move:
|
|
|
109
108
|
|
|
110
109
|
| Evidence | Fix goes to | How it's done |
|
|
111
110
|
|----------|-------------|---------------|
|
|
112
|
-
|
|
|
113
|
-
| Board differs from the snapshot, code still equals it | **Code** — the model moved on | Set the slice back to `Planned` with `/update-slice-status` so the build kit picks it up again and diffs code against `slice.json` |
|
|
114
|
-
| Both moved, or no snapshot | **Judgement call** — present both options, recommend one | Recommend by which side is more specific/complete |
|
|
111
|
+
| A field, element, spec, screen or edge differs | **Judgement call** — present both options, recommend one | Recommend by which side is more specific/complete. Model fix: `/attributes` (fields), `/timeline` / `/place-element` (elements), `/eventmodeling-elaborating-scenarios` (specs), `/storyboard-screen` or `/html-screen` (screens — including updating every existing screen connected to a changed element, see below). Code fix: set the slice back to `Planned` with `/update-slice-status` so the build kit picks it up again |
|
|
115
112
|
| Slice only in code | **Model** | Add the slice, via `/eventmodeling-slicing-event-models` after placing its elements |
|
|
116
113
|
| Slice missing in code, board says `Done` | **Model status** (it isn't done) | `/update-slice-status` → `Planned` |
|
|
117
114
|
|
|
@@ -190,3 +187,4 @@ Omit empty sections. Say plainly when nothing drifted.
|
|
|
190
187
|
- Fixing drift on the model side means updating the existing screens connected to the changed elements too (pages and `meta.fields`), in place — not just the command/event/read model.
|
|
191
188
|
- `--branch` reads the code via `git ls-tree`/`git show` from that ref — never check it out, the working tree may hold someone's uncommitted work. No `--branch` = the working tree, as before.
|
|
192
189
|
- Always read the MARKDOWN note in the feedback lane of each chapter's first column first — it is the chapter's context, and differences it explains are not drift.
|
|
190
|
+
- `.build-kit/.slices` is no evidence for the direction of a fix: every fetch, `/load-slice` and runner loop rewrites it, so it holds the last fetch, not what the code was built from — reading it as "the build" recommends undoing board changes. The direction is a judgement call.
|
package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-brainstorming-events/SKILL.md
CHANGED
|
@@ -116,7 +116,8 @@ mcp__eventmodelers__submit_node_events {
|
|
|
116
116
|
"eventType": "node:changed",
|
|
117
117
|
"nodeId": "<chapterId>",
|
|
118
118
|
"meta": {"type": "CHAPTER", "title": "Reservation & Lending"}
|
|
119
|
-
}]
|
|
119
|
+
}],
|
|
120
|
+
"compact": true
|
|
120
121
|
}
|
|
121
122
|
```
|
|
122
123
|
|
|
@@ -219,7 +220,8 @@ mcp__eventmodelers__submit_node_events {
|
|
|
219
220
|
{"name": "reservedAt", "type": "DateTime", "example": "2026-05-29T10:00:00Z"}
|
|
220
221
|
]
|
|
221
222
|
}
|
|
222
|
-
}]
|
|
223
|
+
}],
|
|
224
|
+
"compact": true
|
|
223
225
|
}
|
|
224
226
|
```
|
|
225
227
|
|
|
@@ -88,7 +88,8 @@ mcp__eventmodelers__place_element {
|
|
|
88
88
|
"elementType": "READMODEL",
|
|
89
89
|
"title": "NotificationsToSend",
|
|
90
90
|
"columnIndex": <automationColumnIndex - 1>
|
|
91
|
-
}]
|
|
91
|
+
}],
|
|
92
|
+
"compact": true
|
|
92
93
|
}
|
|
93
94
|
```
|
|
94
95
|
Then set `meta.fields` and `meta.listElement: true` on the returned node id:
|
|
@@ -98,7 +99,8 @@ mcp__eventmodelers__submit_node_events {
|
|
|
98
99
|
"events": [{
|
|
99
100
|
"id": "<event-uuid>", "eventType": "node:changed", "nodeId": "<returned-node-id>",
|
|
100
101
|
"meta": {"type": "READMODEL", "title": "NotificationsToSend", "fields": [...], "listElement": true}
|
|
101
|
-
}]
|
|
102
|
+
}],
|
|
103
|
+
"compact": true
|
|
102
104
|
}
|
|
103
105
|
```
|
|
104
106
|
|
|
@@ -114,11 +116,11 @@ For a **translation-chain automation**, place its three columns left to right in
|
|
|
114
116
|
|
|
115
117
|
1. **READMODEL → AUTOMATION first** — the automation reads its own todo list. The closing connection below is only accepted once this edge exists.
|
|
116
118
|
```
|
|
117
|
-
mcp__eventmodelers__set_connection { "boardId": "<BOARD_ID>", "connections": [{ "source": "<readmodelNodeId>", "target": "<automationNodeId>", "action": "connect" }] }
|
|
119
|
+
mcp__eventmodelers__set_connection { "boardId": "<BOARD_ID>", "connections": [{ "source": "<readmodelNodeId>", "target": "<automationNodeId>", "action": "connect" }], "compact": true }
|
|
118
120
|
```
|
|
119
121
|
2. **Every opening EVENT → READMODEL.**
|
|
120
122
|
```
|
|
121
|
-
mcp__eventmodelers__set_connection { "boardId": "<BOARD_ID>", "connections": [{ "source": "<openingEventNodeId>", "target": "<readmodelNodeId>", "action": "connect" }] }
|
|
123
|
+
mcp__eventmodelers__set_connection { "boardId": "<BOARD_ID>", "connections": [{ "source": "<openingEventNodeId>", "target": "<readmodelNodeId>", "action": "connect" }], "compact": true }
|
|
122
124
|
```
|
|
123
125
|
3. **Every closing EVENT → READMODEL — worker-stage todo lists only.** Including the automation's own resulting event, even though that event is produced by the command this same automation issues. This is not a backward arrow: `EVENT → READMODEL` connections are exempt from column ordering when the read model already has a `READMODEL → AUTOMATION` edge (see `learn-eventmodelers-api` §3) — this todo-list read model qualifies because of the edge from step 1 above. A read model in this shape is a live projection, not a frozen snapshot — a later event closing an earlier-opened item is the normal case, not an exception to reach for only when convenient. **Do not add this edge for a translation automation's todo list** — it has no closing event at all (see the translation-chain rule above); wiring one back is a modeling error, not a convenience.
|
|
124
126
|
|
package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-inputs/SKILL.md
CHANGED
|
@@ -151,7 +151,8 @@ mcp__eventmodelers__place_element {
|
|
|
151
151
|
"elements": [{
|
|
152
152
|
"elementType": "COMMAND",
|
|
153
153
|
"title": "ReserveBike"
|
|
154
|
-
}]
|
|
154
|
+
}],
|
|
155
|
+
"compact": true
|
|
155
156
|
}
|
|
156
157
|
```
|
|
157
158
|
`place_element` finds/creates the empty cell in the interaction lane in the correct column and places the node. Pass each entry's `fields` in the same call when the attributes are already known; otherwise follow up with `submit_node_events` (`node:changed`) to set `meta.fields` (with `mapping`/`generated`/`cardinality` per the rules above) on the node it returned:
|
|
@@ -171,7 +172,8 @@ mcp__eventmodelers__submit_node_events {
|
|
|
171
172
|
{"name": "startTime", "type": "DateTime", "example": "2026-06-01T09:00:00Z","mapping": "user-input"}
|
|
172
173
|
]
|
|
173
174
|
}
|
|
174
|
-
}]
|
|
175
|
+
}],
|
|
176
|
+
"compact": true
|
|
175
177
|
}
|
|
176
178
|
```
|
|
177
179
|
|
|
@@ -203,7 +205,7 @@ After `place-element` returns the COMMAND node ID, create the arrows that comple
|
|
|
203
205
|
```
|
|
204
206
|
Read `cells["<actorRowId>-<columnId>"]` for the occupying node id (a cell id absent from that sparse array is empty — no SCREEN placed yet). Then connect with the type-checked edge tool, which auto-corrects direction and skips duplicates:
|
|
205
207
|
```
|
|
206
|
-
mcp__eventmodelers__set_connection { "boardId": "<BOARD_ID>", "connections": [{ "source": "<screenNodeId>", "target": "<commandNodeId>", "action": "connect" }] }
|
|
208
|
+
mcp__eventmodelers__set_connection { "boardId": "<BOARD_ID>", "connections": [{ "source": "<screenNodeId>", "target": "<commandNodeId>", "action": "connect" }], "compact": true }
|
|
207
209
|
```
|
|
208
210
|
If wiring more than one COMMAND in the same pass, put every SCREEN→COMMAND and COMMAND→EVENT pair across all of them into one `set_connection` call's `connections` array (see step 2 below) instead of one call per pair.
|
|
209
211
|
|
|
@@ -219,7 +221,7 @@ After `place-element` returns the COMMAND node ID, create the arrows that comple
|
|
|
219
221
|
```
|
|
220
222
|
Read `cells["<swimlaneRowId>-<columnId>"]` for the occupying node id, then:
|
|
221
223
|
```
|
|
222
|
-
mcp__eventmodelers__set_connection { "boardId": "<BOARD_ID>", "connections": [{ "source": "<commandNodeId>", "target": "<eventNodeId>", "action": "connect" }] }
|
|
224
|
+
mcp__eventmodelers__set_connection { "boardId": "<BOARD_ID>", "connections": [{ "source": "<commandNodeId>", "target": "<eventNodeId>", "action": "connect" }], "compact": true }
|
|
223
225
|
```
|
|
224
226
|
|
|
225
227
|
**Fallback (no MCP):** see `references/api-fallback.md` — "Wire connections — Step 2: COMMAND → EVENT".
|
package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-outputs/SKILL.md
CHANGED
|
@@ -260,7 +260,8 @@ mcp__eventmodelers__place_element {
|
|
|
260
260
|
"elementType": "READMODEL",
|
|
261
261
|
"title": "ActiveReservationView",
|
|
262
262
|
"columnIndex": <consumerScreenColumnIndex> // or <automationColumnIndex - 1> for an AUTOMATION consumer
|
|
263
|
-
}]
|
|
263
|
+
}],
|
|
264
|
+
"compact": true
|
|
264
265
|
}
|
|
265
266
|
```
|
|
266
267
|
Then set `meta.fields` (with `mapping`/`generated`/`cardinality`) — and `meta.listElement: true` if this read model is list-shaped — on the returned node id:
|
|
@@ -270,7 +271,8 @@ mcp__eventmodelers__submit_node_events {
|
|
|
270
271
|
"events": [{
|
|
271
272
|
"id": "<event-uuid>", "eventType": "node:changed", "nodeId": "<returned-node-id>",
|
|
272
273
|
"meta": {"type": "READMODEL", "title": "ActiveReservationView", "fields": [...]}
|
|
273
|
-
}]
|
|
274
|
+
}],
|
|
275
|
+
"compact": true
|
|
274
276
|
}
|
|
275
277
|
```
|
|
276
278
|
To determine the consumer's column index beforehand, or to check whether a specific interaction cell is already occupied (`get_nodes` filters by `type`, `name`, `chapterId` and `nodeIds`, but has no `cellId` filter — see the note under "Wire connections" below), fetch the chapter and read its cell map — `projection: "cells"` returns just `{rows, columns, cells}`, not the whole chapter node:
|
|
@@ -327,7 +329,7 @@ After `place-element` returns the READMODEL node ID, create the arrows that comp
|
|
|
327
329
|
```
|
|
328
330
|
mcp__eventmodelers__get_node { "boardId": "<BOARD_ID>", "nodeId": "<CHAPTER_ID>", "projection": "cells" }
|
|
329
331
|
# → read cells["<swimlaneRowId>-<columnId>"] for the occupying node id
|
|
330
|
-
mcp__eventmodelers__set_connection { "boardId": "<BOARD_ID>", "connections": [{ "source": "<eventNodeId>", "target": "<readmodelNodeId>", "action": "connect" }] }
|
|
332
|
+
mcp__eventmodelers__set_connection { "boardId": "<BOARD_ID>", "connections": [{ "source": "<eventNodeId>", "target": "<readmodelNodeId>", "action": "connect" }], "compact": true }
|
|
331
333
|
```
|
|
332
334
|
|
|
333
335
|
**Fallback (no MCP):** see `references/api-fallback.md` — "Step 5h.1 — Wire EVENT → READMODEL".
|
|
@@ -336,7 +338,7 @@ After `place-element` returns the READMODEL node ID, create the arrows that comp
|
|
|
336
338
|
|
|
337
339
|
**Prefer MCP:**
|
|
338
340
|
```
|
|
339
|
-
mcp__eventmodelers__set_connection { "boardId": "<BOARD_ID>", "connections": [{ "source": "<readmodelNodeId>", "target": "<screenNodeId>", "action": "connect" }] }
|
|
341
|
+
mcp__eventmodelers__set_connection { "boardId": "<BOARD_ID>", "connections": [{ "source": "<readmodelNodeId>", "target": "<screenNodeId>", "action": "connect" }], "compact": true }
|
|
340
342
|
```
|
|
341
343
|
|
|
342
344
|
**Fallback (no MCP):** see `references/api-fallback.md` — "Step 5h.2 — Wire READMODEL → SCREEN".
|
|
@@ -347,7 +349,7 @@ After `place-element` returns the READMODEL node ID, create the arrows that comp
|
|
|
347
349
|
|
|
348
350
|
**Prefer MCP:**
|
|
349
351
|
```
|
|
350
|
-
mcp__eventmodelers__set_connection { "boardId": "<BOARD_ID>", "connections": [{ "source": "<readmodelNodeId>", "target": "<automationNodeId>", "action": "connect" }] }
|
|
352
|
+
mcp__eventmodelers__set_connection { "boardId": "<BOARD_ID>", "connections": [{ "source": "<readmodelNodeId>", "target": "<automationNodeId>", "action": "connect" }], "compact": true }
|
|
351
353
|
```
|
|
352
354
|
|
|
353
355
|
**Fallback (no MCP):** see `references/api-fallback.md` — "Step 5h.3 — Wire READMODEL → AUTOMATION".
|
|
@@ -163,7 +163,7 @@ For a "what is on the board and how is it wired right now" check between steps
|
|
|
163
163
|
|
|
164
164
|
**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.
|
|
165
165
|
|
|
166
|
-
**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
|
|
166
|
+
**Ask echo-heavy write tools for less.** `place_element`, `add_scenario`, `add_storyline`, `set_connection` and `submit_node_events` each accept `compact: true`, which drops the full-object echo from the response (returning `{nodeId, cellName, columnIndex}` per placed node, `{specNodeId, added, count, isNewNode}`, a `{connected, existed, removed, notFound, failed, errors}` tally, or `{persisted: <count>}` respectively). Pass it by default — every example in these skills does — and drop it only when a later step reads a field the compact form leaves out (e.g. `place_element`'s `autoConnected` edge list). Failures are still reported in full either way.
|
|
167
167
|
|
|
168
168
|
### Documenting decisions inline, at any step
|
|
169
169
|
|
|
@@ -440,7 +440,8 @@ Not delegated to a separate skill — performed directly by this orchestrating s
|
|
|
440
440
|
"id": "<event-uuid>", "eventType": "node:created", "nodeId": "<node-uuid>",
|
|
441
441
|
"chapterId": "$CHAPTER_ID", "cellId": "<feedbackLaneId>-<firstColumnId>",
|
|
442
442
|
"meta": { "type": "MARKDOWN", "title": "Modeling Reasoning — <Chapter Name>", "description": "<full markdown body>" }
|
|
443
|
-
}]
|
|
443
|
+
}],
|
|
444
|
+
"compact": true
|
|
444
445
|
}
|
|
445
446
|
```
|
|
446
447
|
|
|
@@ -105,7 +105,8 @@ mcp__eventmodelers__submit_node_events {
|
|
|
105
105
|
"marks": [{"id": "em-abc123", "color": "#e74c3c", "pageIndex": 0, "blurOutside": true, "whiteOutside": false}],
|
|
106
106
|
"fields": [...]
|
|
107
107
|
}
|
|
108
|
-
}]
|
|
108
|
+
}],
|
|
109
|
+
"compact": true
|
|
109
110
|
}
|
|
110
111
|
```
|
|
111
112
|
|
|
@@ -181,7 +182,8 @@ mcp__eventmodelers__submit_node_events {
|
|
|
181
182
|
"meta": { "type": "HTML_SCREEN", "fields": [
|
|
182
183
|
{"name": "status", "type": "String", "example": "confirmed", "mapping": "ActiveReservationView.status", "cardinality": "Single"}
|
|
183
184
|
] }
|
|
184
|
-
}]
|
|
185
|
+
}],
|
|
186
|
+
"compact": true
|
|
185
187
|
}
|
|
186
188
|
```
|
|
187
189
|
|
|
@@ -50,7 +50,8 @@ mcp__eventmodelers__place_element {
|
|
|
50
50
|
"columnIndex": <position,
|
|
51
51
|
if given>,
|
|
52
52
|
"fields": [{ "name": "orderId", "type": "String", "example": "ord-1" }]
|
|
53
|
-
}]
|
|
53
|
+
}],
|
|
54
|
+
"compact": true
|
|
54
55
|
}
|
|
55
56
|
```
|
|
56
57
|
|
|
@@ -132,7 +133,8 @@ mcp__eventmodelers__add_scenario {
|
|
|
132
133
|
"boardId": "<BOARD_ID>",
|
|
133
134
|
"timelineId": "<TL>",
|
|
134
135
|
"columnId": "<COL>",
|
|
135
|
-
"scenarios": [ /* same scenario objects as the curl body below */ ]
|
|
136
|
+
"scenarios": [ /* same scenario objects as the curl body below */ ],
|
|
137
|
+
"compact": true
|
|
136
138
|
}
|
|
137
139
|
```
|
|
138
140
|
|
|
@@ -335,7 +337,8 @@ mcp__eventmodelers__submit_node_events {
|
|
|
335
337
|
"cellId": "<CELL_ID>",
|
|
336
338
|
"meta": { "type": "<ELEMENT_TYPE>", "title": "<title>" },
|
|
337
339
|
"node": { "data": { "title": "<title>" } }
|
|
338
|
-
}]
|
|
340
|
+
}],
|
|
341
|
+
"compact": true
|
|
339
342
|
}
|
|
340
343
|
```
|
|
341
344
|
|
|
@@ -356,7 +359,8 @@ mcp__eventmodelers__submit_node_events {
|
|
|
356
359
|
"cellName": "<CELL_NAME>",
|
|
357
360
|
"meta": { "type": "<ELEMENT_TYPE>", "title": "<title>" },
|
|
358
361
|
"node": { "data": { "title": "<title>" } }
|
|
359
|
-
}]
|
|
362
|
+
}],
|
|
363
|
+
"compact": true
|
|
360
364
|
}
|
|
361
365
|
```
|
|
362
366
|
|
|
@@ -385,7 +389,7 @@ Take the inbound edges (`target === COMMAND_NODE_ID`) and resolve their source t
|
|
|
385
389
|
- **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:
|
|
386
390
|
|
|
387
391
|
```
|
|
388
|
-
mcp__eventmodelers__set_connection { "boardId": "<BOARD_ID>", "connections": [{ "source": "<extra-issuer-node-id>", "target": "<COMMAND_NODE_ID>", "action": "remove" }] }
|
|
392
|
+
mcp__eventmodelers__set_connection { "boardId": "<BOARD_ID>", "connections": [{ "source": "<extra-issuer-node-id>", "target": "<COMMAND_NODE_ID>", "action": "remove" }], "compact": true }
|
|
389
393
|
```
|
|
390
394
|
|
|
391
395
|
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.
|
|
@@ -416,4 +420,4 @@ Timeline: <timelineId>
|
|
|
416
420
|
|
|
417
421
|
## Example — place an EVENT via curl
|
|
418
422
|
|
|
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).
|
|
423
|
+
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" }], "compact": true }` (see "Prefer MCP" above).
|
|
@@ -230,7 +230,8 @@ mcp__eventmodelers__submit_node_events {
|
|
|
230
230
|
"id": "<event-uuid>", "eventType": "node:changed", "nodeId": "<SCREEN_NODE_ID>",
|
|
231
231
|
"changedAttributes": ["meta.fields"],
|
|
232
232
|
"meta": { "type": "HTML_SCREEN", "fields": [ /* planned fields */ ] }
|
|
233
|
-
}]
|
|
233
|
+
}],
|
|
234
|
+
"compact": true
|
|
234
235
|
}
|
|
235
236
|
```
|
|
236
237
|
|
|
@@ -126,7 +126,8 @@ mcp__eventmodelers__submit_node_events {
|
|
|
126
126
|
"meta": { "type": "SCREEN", "fields": [
|
|
127
127
|
{"name": "status", "type": "String", "example": "confirmed", "mapping": "ActiveReservationView.status", "cardinality": "Single"}
|
|
128
128
|
] }
|
|
129
|
-
}]
|
|
129
|
+
}],
|
|
130
|
+
"compact": true
|
|
130
131
|
}
|
|
131
132
|
```
|
|
132
133
|
|
|
@@ -290,7 +290,8 @@ mcp__eventmodelers__submit_node_events {
|
|
|
290
290
|
"cellId": "<CELL_ID>",
|
|
291
291
|
"meta": { "type": "EVENT", "title": "<EventName>" },
|
|
292
292
|
"node": { "id": "<node-uuid>", "data": { "title": "<EventName>" } }
|
|
293
|
-
}]
|
|
293
|
+
}],
|
|
294
|
+
"compact": true
|
|
294
295
|
}
|
|
295
296
|
```
|
|
296
297
|
|
|
@@ -300,7 +301,7 @@ mcp__eventmodelers__submit_node_events {
|
|
|
300
301
|
|
|
301
302
|
**Prefer MCP:** this whole "find/create a column, compute the cell, place the node" sequence collapses into one call:
|
|
302
303
|
```
|
|
303
|
-
mcp__eventmodelers__place_element { "boardId": "<BOARD_ID>", "timelineId": "<CHAPTER_ID>", "elements": [{ "elementType": "EVENT", "title": "<EventName>", "columnIndex": <index> }] }
|
|
304
|
+
mcp__eventmodelers__place_element { "boardId": "<BOARD_ID>", "timelineId": "<CHAPTER_ID>", "elements": [{ "elementType": "EVENT", "title": "<EventName>", "columnIndex": <index> }], "compact": true }
|
|
304
305
|
```
|
|
305
306
|
Extract `nodeId` and `columnId` directly from the tool result.
|
|
306
307
|
|
|
@@ -343,7 +344,8 @@ mcp__eventmodelers__submit_node_events {
|
|
|
343
344
|
"changedAttributes": ["meta.title"],
|
|
344
345
|
"meta": { "type": "EVENT", "title": "<NewTitle>" },
|
|
345
346
|
"node": { "id": "<eventNodeId>", "data": {} }
|
|
346
|
-
}]
|
|
347
|
+
}],
|
|
348
|
+
"compact": true
|
|
347
349
|
}
|
|
348
350
|
```
|
|
349
351
|
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: walkthrough
|
|
3
|
+
description: Walk a person through the board step by step, as a player in the chat. Two modes — explain ("how does registration work?") follows a process through its screens, commands, events and read models; impact ("we need to add an email — walk me through the changes") lists, in order, every slice, element and scenario a planned change touches and what has to change there. Each step carries a description, the business rules that apply, a link that zooms the canvas to it, and its screen; the person can play it full-screen like the screen movie strip. Read-only — changes nothing on the board.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Walkthrough — step by step through the board
|
|
7
|
+
|
|
8
|
+
> **Before doing anything else**, invoke the `connect` skill — if not already connected — to resolve `TOKEN`, `BOARD_ID`, `ORG_ID`, and `BASE_URL`. Do not proceed until it has completed.
|
|
9
|
+
|
|
10
|
+
Prefer `mcp__eventmodelers__*` tools. See `learn-eventmodelers-api` for the curl fallback and §16 *Chat snippets* for the `walkthrough` shape.
|
|
11
|
+
|
|
12
|
+
The result is **one `walkthrough` snippet** in the chat. The person steps back and forth through it; selecting a step zooms the canvas to that step's element, slice or scenario, and **Play** opens all steps full-screen as a strip of their screens with the description, the changes and the rules underneath. The walkthrough is only as good as its links: every step points at a real node on this board.
|
|
13
|
+
|
|
14
|
+
**This skill never writes to the board.** In impact mode it shows what would change; making those changes is separate work the person asks for afterwards.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Step 1 — Mode and subject
|
|
19
|
+
|
|
20
|
+
From `$ARGUMENTS` / the message, and the turn's `context=` (selected nodes, `timelineId`, `focusArea` — resolved as in the kit's CLAUDE.md):
|
|
21
|
+
|
|
22
|
+
| Mode | Typical message | The steps are |
|
|
23
|
+
|---|---|---|
|
|
24
|
+
| `explain` | "How does registration work?", "walk me through checkout", "/walkthrough Registration" | the process in the order it runs, as a person experiences it |
|
|
25
|
+
| `impact` | "We need to add an email — walk me through the changes", "what does it take to support refunds?" | every place in the model the change touches, in the order it should be changed |
|
|
26
|
+
|
|
27
|
+
The **subject** is the process or the change, in the person's words. "This"/"here" means what they have selected or zoomed to.
|
|
28
|
+
|
|
29
|
+
### No subject yet — ask first
|
|
30
|
+
|
|
31
|
+
Called without one (a bare `/walkthrough`, the chat menu's entry sent as is, "walk me through" with nothing named), **ask before reading anything in detail** — the selection or the chapter in view is not enough on its own to guess which flow or which feature they mean. One cheap read for the options: `get_nodes { boardId, type: "CHAPTER", projection: "line" }` (and, for a single chapter, `list_slices`). Then reply once and **end the turn**:
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
mcp__eventmodelers__post_chat_message {
|
|
35
|
+
"boardId": "$BOARD_ID",
|
|
36
|
+
"replyTo": "<message_id>",
|
|
37
|
+
"text": "Which flow should I walk you through? Or tell me the new feature you're planning, and I'll walk you through what it changes.",
|
|
38
|
+
"snippet": {
|
|
39
|
+
"kind": "poll",
|
|
40
|
+
"question": "Walk through which flow?",
|
|
41
|
+
"options": [
|
|
42
|
+
{ "label": "Registration", "message": "/walkthrough How does Registration work?" },
|
|
43
|
+
{ "label": "Checkout", "message": "/walkthrough How does Checkout work?" }
|
|
44
|
+
]
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
- The options are the board's flows — chapters, or the main slices when the board has one chapter — at most ~8, the one in the person's view first. Each option's `message` is a complete `/walkthrough …` request, so the pick comes back as a new message that runs this skill with its subject.
|
|
50
|
+
- The text always offers the **impact** mode in words ("tell me the new feature you're planning") — a planned change can't be picked from a list; the person types it, and their reply is the subject.
|
|
51
|
+
- Fewer than two flows on the board: ask in the text only, no snippet. An empty board: say there is nothing to walk through yet.
|
|
52
|
+
|
|
53
|
+
The same goes for a subject that is still too vague with the context (several chapters equally likely): ask with a `poll` of those candidates — don't guess between them.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Step 2 — Outline first: where on the board is it?
|
|
58
|
+
|
|
59
|
+
Orient cheaply before reading anything in detail — the board can be large, and only a handful of nodes matter.
|
|
60
|
+
|
|
61
|
+
1. **Chapters**: `get_nodes { boardId, type: "CHAPTER", projection: "line" }` — pick the chapter(s) the subject belongs to by title. With a `timelineId` in context, start there.
|
|
62
|
+
2. **Context notes**: for each candidate chapter, `get_board_outline { boardId, chapterId }`, then read the MARKDOWN note in the first column's `feedback` lane (`get_node`, `meta.description`) if there is one. It says what the chapter is for and often names the decisions behind it — use it in the descriptions.
|
|
63
|
+
3. **Slices**: `list_slices { boardId, contextName }` and `get_slice_data { boardId, contextName, projection: "outline", format: "toon" }` — every slice with its elements as `{id, title, type}`.
|
|
64
|
+
4. **Find the nodes that matter.** With the outline in hand, decide which slices and elements belong to the subject:
|
|
65
|
+
- **explain**: the slices whose commands, events, read models or screens are about the subject; follow the edges in the outline (screen → command → event → read model → next screen, events → automations) from where the process starts to where it ends. Other chapters only when the flow crosses into them (an external or translated event).
|
|
66
|
+
- **impact**: start from the element the change lands on first (the screen or command where the new data enters, or the event whose meaning changes), then follow the flow **downstream** — every event that would carry it, every read model and automation fed by those events, every screen that shows those read models — and **upstream** where the data has to come from. A name search helps: `get_nodes { boardId, name: "<term>", projection: "line" }` for the field or concept ("email") finds the places that mention it already.
|
|
67
|
+
|
|
68
|
+
Stop widening when a further step adds nothing the person asked about. A walkthrough of 4–12 steps is typical; 20+ means the subject is really several — say so in the text and walk the first one.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Step 3 — Read only those
|
|
73
|
+
|
|
74
|
+
Now read the working set in detail — never the whole board:
|
|
75
|
+
|
|
76
|
+
- `get_slice_data { boardId, contextName, sliceId, projection: "fields" }` per relevant slice — fields and dependencies.
|
|
77
|
+
- `get_slice_data { boardId, contextName, sliceId, projection: "specs", format: "toon" }` — the **scenarios**: these are the business rules. A scenario's title in business words ("Email must be unique") is a rule; its Given/When/Then says when it applies.
|
|
78
|
+
- `get_nodes { boardId, type: "SCENARIO", chapterId, projection: "line" }` — the ids of the scenario nodes, so an impact step can point at a scenario directly.
|
|
79
|
+
- Full `get_nodes { boardId, nodeIds: [...] }` only for the few nodes whose `description` you need.
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Step 4 — Build the steps
|
|
84
|
+
|
|
85
|
+
One step per thing the person should look at, in order.
|
|
86
|
+
|
|
87
|
+
**explain** — follow the process as the person living it experiences it. One step per meaningful moment, usually one slice: *what they see → what they do → what is recorded → what that makes visible or triggers*. Merge a command and its event into one step when nothing happens between them; give an automation its own step.
|
|
88
|
+
|
|
89
|
+
**impact** — one step per place that has to change, ordered so each step builds on the previous one (where the data enters → the command → the event → read models → screens → automations → scenarios). Include **scenarios** as their own steps when they need a new case or an update (e.g. "add: Register with an email that is already taken → rejected"). Say what is *not* affected only if the person would reasonably expect it to be.
|
|
90
|
+
|
|
91
|
+
Per step:
|
|
92
|
+
|
|
93
|
+
| Field | What goes in |
|
|
94
|
+
|---|---|
|
|
95
|
+
| `title` | short, business words — the moment ("Customer submits registration") or the place ("Register Customer — command") |
|
|
96
|
+
| `description` | 1–3 sentences: what happens here and why it matters, in the board's language. No ids, no cell addresses. |
|
|
97
|
+
| `nodeId` | the node to zoom to: the **slice** (its `SLICE_BORDER` id from `list_slices`) when the step is about the slice as a whole, the **element** when it is about one element, the **scenario** node when the step is a scenario |
|
|
98
|
+
| `screenId` | the SCREEN / HTML_SCREEN shown in this step, if there is one — that is what the player shows. Leave it out otherwise; don't point at an unrelated screen to fill the frame |
|
|
99
|
+
| `rules` | the business rules that apply here, taken from the scenarios (and the context note); one line each, thresholds verbatim. Empty when there are none — never invent one |
|
|
100
|
+
| `changes` | **impact mode only**: what has to change here, one line each — "add field `email` (String)", "new scenario: duplicate email is rejected", "show email in the confirmation screen" |
|
|
101
|
+
|
|
102
|
+
**Faithfulness.** Everything comes from the board. A rule nobody modelled is not a rule — if the walkthrough reveals a gap ("nothing says what happens when confirmation never arrives"), mention it in the step's `description` as an open question, not as a rule.
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## Step 5 — Post it
|
|
107
|
+
|
|
108
|
+
**One** `post_chat_message`: in a `CHAT` turn `replyTo` = this turn's `message_id`; in a prompt turn that came from a chat, `sessionId` = `CHAT_SESSION_ID` and no `replyTo`.
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
mcp__eventmodelers__post_chat_message {
|
|
112
|
+
"boardId": "$BOARD_ID",
|
|
113
|
+
"replyTo": "<message_id>",
|
|
114
|
+
"text": "Registration in 5 steps — step through it here, or press Play.",
|
|
115
|
+
"snippet": {
|
|
116
|
+
"kind": "walkthrough",
|
|
117
|
+
"title": "How registration works",
|
|
118
|
+
"intro": "From the sign-up form to a confirmed account.",
|
|
119
|
+
"steps": [
|
|
120
|
+
{ "title": "Customer fills in the sign-up form", "nodeId": "<slice id>", "screenId": "<screen id>",
|
|
121
|
+
"description": "Name, email and password are entered on the registration screen.",
|
|
122
|
+
"rules": ["Email must be unique", "Password at least 12 characters"] },
|
|
123
|
+
{ "title": "Customer registered", "nodeId": "<event id>",
|
|
124
|
+
"description": "The registration is recorded; the account is not active yet." }
|
|
125
|
+
]
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Impact mode, same shape with `changes` per step:
|
|
131
|
+
|
|
132
|
+
```
|
|
133
|
+
{ "title": "Register Customer — command", "nodeId": "<command id>",
|
|
134
|
+
"description": "The email enters here and has to be validated before anything is recorded.",
|
|
135
|
+
"changes": ["Add field email (String)", "Reject the command when the email is already registered"],
|
|
136
|
+
"rules": ["Customer name is required"] },
|
|
137
|
+
{ "title": "Scenario: duplicate email", "nodeId": "<scenario id>",
|
|
138
|
+
"changes": ["New case: Given Customer registered with x@y.z, When Register Customer with x@y.z, Then rejected"] }
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
- `text` is one line: the subject and the number of steps. It is the fallback, so it must make sense alone.
|
|
142
|
+
- Every `nodeId` / `screenId` is an id you read in Steps 2–3 — never a guessed or remembered one.
|
|
143
|
+
- The snippet is at most 64 KB; keep descriptions short rather than dropping steps.
|
|
144
|
+
- **Impact mode** ends there: the walkthrough is the proposal. If the person then asks for the changes, that is ordinary work (prompts per the kit's CLAUDE.md) — and a slice that is not `Created` still needs their confirmation first.
|
|
145
|
+
|
|
146
|
+
**No chat** (run from a terminal): print the steps as a numbered list with the same fields instead of posting.
|
|
@@ -202,6 +202,12 @@ for it. Instead:
|
|
|
202
202
|
(`timelineId` for the chapter, what they have selected). It sends its findings back as a snippet to tick
|
|
203
203
|
and posts nothing to the board until they answer (`/wdyt` Step 4.0). Your reply here is one line —
|
|
204
204
|
*"On it — looking at Registration."*
|
|
205
|
+
- **walkthrough** — "how does X work?", "walk me through …", "what does it take to add …?", or `/walkthrough …`:
|
|
206
|
+
run the `/walkthrough` skill **in this turn** — it only reads the board, so no prompt is needed. It finds the
|
|
207
|
+
slices, elements and scenarios involved and its `walkthrough` snippet is your one reply (step 4). Without a
|
|
208
|
+
subject (a bare `/walkthrough`) it asks first — which flow, or which new feature — and that question is the reply. A planned change
|
|
209
|
+
("we need to add an email") is its impact mode: the walkthrough is the proposal, and the changes become work only
|
|
210
|
+
when the person asks for them afterwards.
|
|
205
211
|
- **a skill by name** — the message starts with `/<name>` of one of your skills (the chat panel's menu
|
|
206
212
|
writes these: `/analyze-existing-model`, `/analyze-code-base`, `/detect-model-drift`, `/add-next-slice`, `/examples`, `/timeline …`,
|
|
207
213
|
`/html-screen …`, `/storyboard …`): the person chose that skill, so it **is** the work — create one prompt,
|
|
@@ -358,6 +364,7 @@ nothing to sanitize either, since a board change is not user text.
|
|
|
358
364
|
| Analyse the existing model structure, slice coverage, element counts | `/analyze-existing-model` |
|
|
359
365
|
| Reverse-engineer the business process of an existing code base into the model, as an interview — all chapters first, then one chapter at a time | `/analyze-code-base` |
|
|
360
366
|
| Find where the model and the code have drifted apart (fields, specs, screens, edges, missing/extra slices) and propose fixes | `/detect-model-drift` |
|
|
367
|
+
| Walk someone through a process step by step, or through every slice, element and scenario a planned change touches, as a player in the chat | `/walkthrough` |
|
|
361
368
|
| Turn a document or image (e.g. a tender/RFP) into a chaptered event model with screens, scenarios and a written blueprint summary | `/summarize` |
|
|
362
369
|
| Look up any API endpoint or element type not already covered by the skill you're executing | `/learn-eventmodelers-api` |
|
|
363
370
|
| Add or rename an attribute across a chain of elements | `/attributes` |
|