@eventmodelers/cli 1.0.139 → 1.0.141

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eventmodelers/cli",
3
- "version": "1.0.139",
3
+ "version": "1.0.141",
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": {
@@ -36,7 +36,7 @@ Write tools take their items as an array (`nodeIds[]`, `elements[]`, `connection
36
36
  | `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` |
37
37
  | `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` |
38
38
  | `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) |
39
- | `create_drawing` | `boardId`, `drawings[]` (each `kind`, `x`, `y`, `width`, `height`, ...) | Freehand canvas annotation (path/rect/text/sticky) — never placed in a cell. An annotation is rarely one stroke: an arrow plus its label is one call with several `drawings` entries, applied in order, not several calls. **"Hotspot"** means a red feedback note: `kind: "sticky"` with `fill: "#ef4444"` (a sticky with no `fill` renders yellow), `content` = the problem/question, placed right next to the element it concerns | — (REST `POST .../drawing/draw` accepts a single drawing or an array) |
39
+ | `create_drawing` | `boardId`, `drawings[]` (each `kind`, `x`, `y`, `width`, `height`, ...) | Freehand canvas annotation — **never** for a diagram the person asked to "draw/sketch" (that is a chat snippet) (path/rect/text/sticky) — never placed in a cell. An annotation is rarely one stroke: an arrow plus its label is one call with several `drawings` entries, applied in order, not several calls. **"Hotspot"** means a red feedback note: `kind: "sticky"` with `fill: "#ef4444"` (a sticky with no `fill` renders yellow), `content` = the problem/question, placed right next to the element it concerns | — (REST `POST .../drawing/draw` accepts a single drawing or an array) |
40
40
  | `create_chapter` | `boardId`, `x?`, `y?`, `title?`, `columns?`, `lanes?: [{type, label?, height?}]` | 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. Pass `title` to name it, `columns` for a known column count, and `lanes` to create named lanes (or several of one type, e.g. one swimlane per context) — none of the three needs a follow-up call, and the lanes are sorted into the required order automatically. The response carries every `columnId` and lane id, so the chapter needn't be read back before placing into it | §2 `POST .../chapters` |
41
41
  | `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` |
42
42
  | `add_column` | `boardId`, `timelineId`, `index?`, `beforeNodeId?`, `afterNodeId?`, `count?` | Add one or more columns in one call. `count` inserts that many contiguously starting at the insertion point (default 1). Position with at most one of `index` (0-based), `beforeNodeId`, or `afterNodeId` (resolves the index from where that already-placed node currently sits) — omit all three to append | §2 `POST .../timelines/:id/columns` |
@@ -31,7 +31,7 @@ Do not connect, do not read the board, and do not produce a report when either c
31
31
 
32
32
  Prefer `mcp__eventmodelers__*` tools when available. See `learn-eventmodelers-api` for the curl fallback.
33
33
 
34
- **This skill never changes the code**, and it changes the board only for what the person confirms — plus the one *Analysis history* row of Step 7.
34
+ **This skill never changes the code**, and it changes the board only for what the person confirms — plus the one *Analysis history* row of Step 7 that marks the drift resolved.
35
35
 
36
36
  ---
37
37
 
@@ -172,11 +172,17 @@ mcp__eventmodelers__post_chat_message {
172
172
  - `id` is `d:<model|code|decide>:<nodeId>:<kind>[:<detail>]` — the answering turn remembers nothing, so it must carry the direction and target. Put **every** finding in the one snippet (it pages itself at 5).
173
173
  - Zero findings: a one-line text reply, no snippet, then Step 7.
174
174
 
175
- The answer comes as a `CHAT` turn (`Please do these:` + ticked titles or ids). Read the snippet back with `get_chat_session`, match what was ticked, and create **one prompt** per direction: model fixes → *"Apply these model-drift fixes: `<id> | <title>` per line"*; code fixes → set each slice to `Planned`. Unticked fixes are declined — drop them. Then Step 7.
175
+ The answer comes as a `CHAT` turn (`Please do these:` + ticked titles or ids). Read the snippet back with `get_chat_session`, match what was ticked, and deal with each finding:
176
+
177
+ - **model fixes** → apply them (one prompt for all of them: *"Apply these model-drift fixes: `<id> | <title>` per line"*),
178
+ - **code fixes** → set each slice to `Planned`; that is the whole fix from here — the rebuild is the build kit's job, the drift doesn't wait for it,
179
+ - **unticked** → declined, nothing to do.
180
+
181
+ Once every finding is dealt with this way, do Step 7 — that is what marks the drift resolved. If the model fixes go to a separate prompt, that prompt carries the range and the outcome (*"…then mark the drift `<BASE>`→`<REF>` resolved per /detect-model-drift Step 7: `<n> applied, <n> to rebuild, <n> declined`"*) and does Step 7 when its fixes are done.
176
182
 
177
183
  ### Without a chat
178
184
 
179
- Print the report below, every finding as a `- [ ]` checkbox carrying its proposed fix, and ask which to apply. Wait for the answer, act on it, then Step 7.
185
+ Print the report below, every finding as a `- [ ]` checkbox carrying its proposed fix, and ask which to apply. Wait for the answer, deal with each finding (as in the chat case), then Step 7.
180
186
 
181
187
  Name each slice and element as `[<title>](ref:<nodeId>)` (the slice border's id for a slice); code that has no node stays plain text.
182
188
 
@@ -200,18 +206,21 @@ Omit empty sections. Say plainly when nothing drifted.
200
206
 
201
207
  ---
202
208
 
203
- ## Step 7 — Move the baseline forward
209
+ ## Step 7 — Mark the drift resolved
204
210
 
205
- Once the person has answered (or there was nothing to report), append **one row** to the *Analysis history* of every chapter in scope (`node:changed` on that note's `meta.description` — never edit or drop earlier rows), so the next run starts from here:
211
+ **When the drift has been dealt with** — every finding's fix applied, its slice set to `Planned`, or declined (or there was nothing to report) — mark it resolved **in the analysis only**: append **one row** to the *Analysis history* of every chapter in scope (`node:changed` on that note's `meta.description` — never edit or drop earlier rows). That row is the resolution and the next run's baseline:
206
212
 
207
213
  ```
208
- | 4 | 2026-10-07 | `9c1e2f0` | drift check since `a1b2c3d` | `Microchip.kt`, `RegisterMicrochipController.kt` | 2 findings: 1 model fix applied, 1 declined |
214
+ | 4 | 2026-10-07 | `9c1e2f0` | drift check since `a1b2c3d` — resolved | `Microchip.kt`, `RegisterMicrochipController.kt` | 2 findings resolved: 1 model fix applied, 1 declined |
209
215
  ```
210
216
 
217
+ - **Only the analysis note changes here.** Marking the drift resolved touches nothing else — no slice status, no comment, no other note, no code. A slice sent back to `Planned` is resolved for the analysis now; whether the rebuild succeeds is the build kit's business.
218
+ - Mark it resolved only once **all** its findings are dealt with. If a fix couldn't be applied, write no row, say which finding is still open — the next run reports it again.
219
+
211
220
  - **Commit** is `REF`'s short sha; add `+dirty` when uncommitted changes were part of the check. With `--branch`, write `<sha> (<branch>)`.
212
221
  - A declined finding is accepted as intended — that is why the baseline still moves past it; record it in the row so it can be found later.
213
222
  - A chapter without a chapter note: don't create one here — say in the report that `/analyze-code-base` would add it, and that the next drift check needs `--since` until then.
214
- - If the person never answers, the baseline stays where it was — the same changes come up again next time.
223
+ - If the person never answers, the drift isn't resolved and the baseline stays where it was — the same changes come up again next time.
215
224
 
216
225
  ---
217
226
 
@@ -225,5 +234,5 @@ Once the person has answered (or there was nothing to report), append **one row*
225
234
  - A build-kit commit (evidence note names its sha, else `feat: <Slice>`) is the as-built state; every later change to its files is a hand-made change.
226
235
  - No git history → no drift detection; say so in one line and stop (Step 0).
227
236
  - `--branch` reads the code via `git show <REF>:<path>` — never check it out, the working tree may hold someone's uncommitted work.
228
- - Every completed run appends one *Analysis history* row; an unanswered run doesn't move the baseline.
237
+ - A drift is resolved once every finding is dealt with (model fix applied, slice set to `Planned`, or declined) — then mark it resolved with one *Analysis history* row and nothing else. An unanswered run or a failed fix doesn't move the baseline.
229
238
  - `.build-kit/.slices` is no evidence of what the code was built from: every fetch, `/load-slice` and runner loop rewrites it.
@@ -71,8 +71,11 @@ transition but not the lifecycle.
71
71
  - `layout`: `"horizontal"` or `"vertical"` — how the beats are laid out in the storyline editor.
72
72
  - Each beat has an `instanceId` (unique per beat, even when the same `refId` repeats — this is what
73
73
  lets the *same* element, like the Todos read model above, appear multiple times across the
74
- walkthrough, once per state) and a `refId` (the board node this beat walks through — any element
75
- type, not just EVENT/COMMAND/READMODEL — e.g. a SCREEN beat to show the resulting UI).
74
+ walkthrough, once per state) and a `refId` (the board node this beat walks through).
75
+ - **Beat order rules** (the same ones the storyline editor enforces): the first beat is a
76
+ READMODEL; after a READMODEL comes an EVENT (or several); after an EVENT comes another EVENT or a
77
+ READMODEL. Beats are only READMODEL or EVENT — no COMMAND, SCREEN or other types. Every `refId`
78
+ must be on the same timeline.
76
79
  - `isError` marks a beat as an alternate/error branch off the previous beat.
77
80
  - `fields`, `expectEmptyList`, `exampleMode`, `examples` mirror the same fields GWT scenario steps
78
81
  use, letting a beat show concrete example data the same way a "then" readmodel step does.
@@ -196,6 +196,8 @@ Only post questions that are **genuinely unclear or missing** — don't post obs
196
196
 
197
197
  ### 4.2 Arrows (every relational finding, always)
198
198
 
199
+ > **Arrows are for relational findings only.** Never use `create_drawing` (stickies, arrows, shapes) to draw a diagram the person asked for ("draw/sketch a UML diagram") — that is a snippet in the chat, not a board change.
200
+
199
201
  **Prefer MCP:** `mcp__eventmodelers__create_drawing` — one call per drawing, no auth headers needed.
200
202
 
201
203
  **Fallback (no MCP):** `POST /api/org/{orgId}/boards/{boardId}/drawing/draw` (auth headers same as every other call — `x-token`, `x-user-id: wdyt`). Same fields as the tool args below.
@@ -309,6 +309,9 @@ for it. Instead:
309
309
  - a **screen idea** in the conversation ("what could that screen look like?") → `screen`, a sandboxed HTML mock-up in the chat; putting a screen on the board is `/html-screen` work;
310
310
  - **where one piece of information comes from and where it is used** → `dataJourney` (the `/data-journey` skill);
311
311
  - **who does what with which work object, per chapter** → an `svg` domain story (the `/domain-story` skill);
312
+ - **"draw" / "sketch" / "diagram" something** (a UML diagram, a flow, a class model) → a snippet in the chat (`svg`, or a
313
+ `code` block with Mermaid/PlantUML/ASCII), **never** drawn on the board with stickies, arrows or `create_drawing`.
314
+ Only an explicit request to put it on the board changes that, and then as an image (`/domain-story` § board), not rebuilt from shapes;
312
315
  - **rows and columns** — a comparison, a matrix, a short list with a few attributes per item → `table`.
313
316
  - anything the customer defined **their own snippet type** for → `custom` with its `ref`: `list_snippet_types`
314
317
  shows them with `instructions` on when to use each; prefer a fitting one over a built-in kind. A click on it arrives