@eventmodelers/cli 1.0.147 → 1.0.149

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.
@@ -48,12 +48,38 @@ export async function latestPublishedVersion({ cachePath, now = Date.now(), fetc
48
48
  }
49
49
  }
50
50
 
51
+ // A loud banner, so a stale CLI is not missed among the startup output — an old CLI can lack
52
+ // features the board expects (e.g. chat), and npx happily reuses a cached copy. Bold yellow
53
+ // when stderr is a terminal (NO_COLOR respected); plain box otherwise, so piped output stays clean.
54
+ function updateBanner(currentVersion, latestVersion) {
55
+ const paint = process.stderr.isTTY && !process.env.NO_COLOR ? (t) => `\x1b[1;33m${t}\x1b[0m` : (t) => t;
56
+ const lines = [
57
+ '!! UPDATE REQUIRED — YOUR EVENTMODELERS CLI IS OUT OF DATE !!',
58
+ '',
59
+ `Installed: ${currentVersion} Latest: ${latestVersion}`,
60
+ '',
61
+ 'Update now:',
62
+ '',
63
+ ' npx @eventmodelers/cli@latest <command>',
64
+ ' (still old? clear the npx cache: rm -rf ~/.npm/_npx)',
65
+ '',
66
+ ' npm i -g @eventmodelers/cli@latest (global install)',
67
+ '',
68
+ 'Old versions miss features the board expects —',
69
+ 'e.g. agents that do not reply in the board chat.',
70
+ ];
71
+ const width = Math.max(...lines.map((l) => l.length));
72
+ const bar = '█'.repeat(width + 6);
73
+ const body = lines.map((l) => `██ ${l.padEnd(width)} ██`);
74
+ return paint(['', bar, ...body, bar, ''].join('\n'));
75
+ }
76
+
51
77
  // Hint lines for everything that's behind: this CLI against npm, and each installed kit
52
78
  // against the CLI running now (its install manifest records the version that wrote it).
53
79
  export function updateHints({ currentVersion, latestVersion, kitDirs = [], cwd = process.cwd() }) {
54
80
  const hints = [];
55
81
  if (latestVersion && compareVersions(currentVersion, latestVersion) < 0) {
56
- hints.push(`💡 A new eventmodelers CLI is available: ${currentVersion} → ${latestVersion}. Update with: npm i -g @eventmodelers/cli@latest (or use npx @eventmodelers/cli@latest)`);
82
+ hints.push(updateBanner(currentVersion, latestVersion));
57
83
  }
58
84
  for (const kitDir of kitDirs) {
59
85
  const reinit = REINIT_COMMANDS[basename(kitDir)];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eventmodelers/cli",
3
- "version": "1.0.147",
3
+ "version": "1.0.149",
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": {
@@ -164,7 +164,7 @@ UUID // universally unique identifier
164
164
  Custom // structured/nested value — use with `subfields` or `schema`
165
165
  ```
166
166
 
167
- Other `Field` properties: `name`, `example`, `subfields[]` (nested `Field`s), `mapping`, `optional`, `technicalAttribute`, `generated`, `idAttribute`, `pii`, `schema`, `cardinality` (`"List"` | `"Single"`).
167
+ Other `Field` properties: `name`, `example`, `subfields[]` (nested `Field`s), `mapping`, `optional`, `technicalAttribute`, `generated`, `idAttribute`, `pii`, `tag` (the field's value tags the event for Dynamic Consistency Boundaries — DCB; see https://dcb.events), `schema`, `cardinality` (`"List"` | `"Single"`).
168
168
 
169
169
  Use exactly these type names (case-sensitive) — not lowercase (`string`), synonyms (`Number`, `Text`, `Integer`), or types outside this set.
170
170
 
@@ -28,8 +28,9 @@ Read `.build-kit/.slices/{context}/{slicename}/slice.json`. Extract, and use **o
28
28
  - `commands[].fields[]` → Command record fields, in order
29
29
  - `events[].fields[]` → Event record fields, in order
30
30
  - `specifications[]` (GWT scenarios) → one test method per scenario
31
- - Which command field(s) have `idAttribute: true` — these carry `@TargetEntityId` (see Step 1) and the
32
- matching event field(s) carry `@EventTag`
31
+ - Which command field(s) have `idAttribute: true` — these carry `@TargetEntityId` (see Step 1)
32
+ - The event's DCB tags — **both** the field(s) matching the command's `idAttribute` field(s) **and**
33
+ every event field with `tag: true` carry `@EventTag` (see Step 2); each gets its own `EventTags` constant
33
34
  - `storylines[]` (optional, may be absent) → narrated walkthroughs with ordered `elements[]` "beats";
34
35
  see Step 7b for how a COMMAND beat in one of these can add a supplementary test
35
36
 
@@ -52,14 +52,20 @@ Skip this step entirely when creating a brand-new node (no `nodeId` given) — g
52
52
  Write normal, full-size HTML/CSS for each page — as if designing a real webpage, not a tiny thumbnail. The canvas node renders this at a real page width and visually scales it down to fit, so there is no need to shrink font sizes or padding to fit a small box; design at a realistic scale (e.g. 16px body text, generous padding) and let the node handle the shrink.
53
53
 
54
54
  Guidelines:
55
- - **Keep it simple — this is a view-only mockup, not a working app.** No JavaScript, no interactivity beyond what a static page can show (enforced server-side, see below). Keep the CSS compact: inline styles or a handful of Bulma classes are enough — don't write a large embedded `<style>` block or reinvent what Bulma already gives you for free.
55
+ - **Keep it simple — this is a view-only mockup, not a working app.** No JavaScript, no interactivity beyond what a static page can show (enforced server-side, see below). Keep the CSS compact: inline styles or a handful of the screen's framework classes (see "CSS framework" below; Bulma by default) are enough — don't write a large embedded `<style>` block or reinvent what the framework already gives you for free.
56
56
  - Each page is one complete, standalone HTML fragment — not a `data-step` div nested inside a shared blob. A multi-step flow (e.g. cart → payment → confirmation) is three separate pages in the array, each fully self-contained.
57
- - **Each page may be at most 6000 characters** (the full markup string, including inline styles). The server rejects a longer page with `400 HTML_SCREEN_PAGE_TOO_LONG` (`context: {pageIndex, length, maxLength}`) and saves nothing — the render call fails as a whole. Check each page's length before rendering; if one is over, trim it (fewer inline styles, Bulma classes instead of custom CSS, fewer repeated sample rows) or split the content into another page. Adding a mark also counts toward the limit, since it adds attributes to the page's markup.
57
+ - **Each page may be at most 6000 characters** (the full markup string, including inline styles). The server rejects a longer page with `400 HTML_SCREEN_PAGE_TOO_LONG` (`context: {pageIndex, length, maxLength}`) and saves nothing — the render call fails as a whole. Check each page's length before rendering; if one is over, trim it (fewer inline styles, framework classes instead of custom CSS, fewer repeated sample rows) or split the content into another page. Adding a mark also counts toward the limit, since it adds attributes to the page's markup.
58
58
  - Inline styles (`style="..."`) are the simplest way to keep each page self-contained.
59
59
  - No `<script>` tags, no inline event handlers (`onclick`, `onload`, ...), no `javascript:` URIs — these are stripped server-side from every page before persisting regardless of what's sent. This is a static visual mockup, not an interactive prototype.
60
60
  - A real page background (e.g. a light gray full-bleed background behind a centered white card) reads more realistically than a bare form floating on white.
61
61
  - Don't add `<html>`/`<head>`/`<body>` tags to a page — every page is a body-only fragment. The canvas wraps each page in its own `<html><head>` (stylesheet + resize script) `<body>...</body></html>` at render time, so anything sent is placed inside that generated `<body>`.
62
- - Bulma CSS (0.9.4) is loaded by default in that `<head>` — classes like `title`, `button`, `is-primary`, `field`/`control`/`input` etc. all work out of the box, no need to write custom CSS for standard form/layout components. Note headings need a size modifier too, e.g. `class="title is-1"` — a bare `title` class alone is always 2rem regardless of the tag (`h1` vs `h2` etc.).
62
+ - **CSS framework — one per screen.** Each screen loads exactly one CSS framework (or none) into every page's `<head>`, chosen by the user in the HTML editor's header and stored on the node as `cssFrameworks` (an array holding one id: `"bulma"`, `"bootstrap"` or `"tailwind"`; `[]` = none). A screen where nothing was chosen gets **Bulma** — that is the default for new screens. Write markup for the framework the screen uses, and never mix classes from several frameworks in one screen:
63
+ - **Bulma 0.9.4** (default) — classes like `title`, `button`, `is-primary`, `field`/`control`/`input` work out of the box. Note headings need a size modifier too, e.g. `class="title is-1"` — a bare `title` class alone is always 2rem regardless of the tag (`h1` vs `h2` etc.).
64
+ - **Bootstrap 5.3.3** — CSS only (no JS, so no working dropdowns/modals/collapse): `container`, `row`/`col-*`, `card`, `btn btn-primary`, `form-control`, `table`, etc.
65
+ - **Tailwind 3.4.16** — utility classes only (`flex`, `p-6`, `bg-gray-100`, `rounded-lg`, ...), built in the page by the Tailwind Play script, so arbitrary values like `w-[320px]` work too. Don't write `@apply`, a `tailwind.config`, or any `<script>`/`<style type="text/tailwindcss">`; stick to utility classes.
66
+ - **None** — the page is unstyled apart from the browser defaults, so use inline styles for everything.
67
+
68
+ When a screen already exists (Step 2), keep using whichever framework its existing pages use — read `cssFrameworks` from the node's data if it's returned, otherwise infer it from the classes in `meta.pages`. Don't switch frameworks while editing; changing it is the user's choice in the editor. When creating a new screen from scratch, use Bulma unless the user names another framework.
63
69
 
64
70
  ### Marks — only when the user explicitly asks for one
65
71
 
@@ -33,8 +33,8 @@ Read `.build-kit/.slices/{context}/{slicename}/slice.json`. Extract, and use **o
33
33
  - `commands[].fields[]` → Command record fields, in order
34
34
  - `events[].fields[]` → Event record fields, in order
35
35
  - `specifications[]` (GWT scenarios) → one test method per scenario
36
- - Which command field(s) have `idAttribute: true` — these become the tag(s) the command's Query and
37
- the resulting event are both scoped to (see Step 1/Step 3)
36
+ - The DCB tags — **both** the command field(s) with `idAttribute: true` **and** every field with
37
+ `tag: true` become tag(s) the command's Query and the resulting event are both scoped to (see Step 1/Step 3)
38
38
  - `storylines[]` (optional, may be absent) → narrated walkthroughs with ordered `elements[]`
39
39
  "beats"; see Step 7b for how a COMMAND beat in one of these can add a supplementary test
40
40