@eventmodelers/cli 1.0.1 → 1.0.3

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 CHANGED
@@ -932,6 +932,7 @@ async function installStack(stackKey, stackCfg, options = {}) {
932
932
  // even without a token yet — the file only ever holds the env-var
933
933
  // placeholder, never the literal secret (see connect/SKILL.md's Security notes).
934
934
  ensureMcpRegistered(targetDir, config.baseUrl || DEFAULT_BASE_URL);
935
+ ensureEnvToken(targetDir, config.token);
935
936
 
936
937
  // --- 6. Install manifest (drives precise `uninstall` later) ---
937
938
  // Only the footprint listed here is ever removed by `uninstall` — the root
@@ -1155,6 +1156,46 @@ function ensureMcpRegistered(projectDir, baseUrl) {
1155
1156
  writeFileSync(mcpConfigPath, JSON.stringify(mcpConfig, null, 2));
1156
1157
  }
1157
1158
 
1159
+ // Companion to ensureMcpRegistered: that function deliberately never writes the
1160
+ // token itself, on the assumption the caller sets EVENTMODELERS_TOKEN in whatever
1161
+ // process spawns `claude` (true for `run --modeling`'s own spawn). It is NOT true
1162
+ // for an interactive session opened directly in the project right after
1163
+ // `init`/`init-config` — that `claude` process inherits the user's shell env,
1164
+ // which never had a reason to already have this var set. Without a `.env` to
1165
+ // resolve it from, `.mcp.json`'s `${EVENTMODELERS_TOKEN}` placeholder resolves to
1166
+ // empty, the MCP server gets an empty x-token header, and the connection fails —
1167
+ // silently, until something happens to trigger the `connect` skill's own Step 3.5,
1168
+ // which writes this same file. Do it here too so a fresh interactive session works
1169
+ // without depending on that skill having run first.
1170
+ function ensureEnvToken(targetDir, token) {
1171
+ if (!token) return;
1172
+ const envPath = join(targetDir, '.env');
1173
+ const line = `EVENTMODELERS_TOKEN=${token}`;
1174
+
1175
+ if (existsSync(envPath)) {
1176
+ const content = readFileSync(envPath, 'utf-8');
1177
+ if (/^EVENTMODELERS_TOKEN=/m.test(content)) {
1178
+ const updated = content.replace(/^EVENTMODELERS_TOKEN=.*$/m, line);
1179
+ if (updated !== content) writeFileSync(envPath, updated);
1180
+ } else {
1181
+ appendFileSync(envPath, `${content === '' || content.endsWith('\n') ? '' : '\n'}${line}\n`);
1182
+ }
1183
+ } else {
1184
+ writeFileSync(envPath, `${line}\n`);
1185
+ }
1186
+
1187
+ const gitignorePath = join(targetDir, '.gitignore');
1188
+ if (existsSync(gitignorePath)) {
1189
+ const content = readFileSync(gitignorePath, 'utf-8');
1190
+ if (!content.split('\n').map((l) => l.trim()).includes('.env')) {
1191
+ appendFileSync(gitignorePath, `${content === '' || content.endsWith('\n') ? '' : '\n'}.env\n`);
1192
+ }
1193
+ } else {
1194
+ writeFileSync(gitignorePath, '.env\n');
1195
+ }
1196
+ console.log(' ✓ Wrote EVENTMODELERS_TOKEN to .env (gitignored)');
1197
+ }
1198
+
1158
1199
  // `run --modeling`: modeling-kit's one and only runtime mode — there is no
1159
1200
  // cold-spawn/tasks.json loop for this kit (that's a build-kit concept; see the
1160
1201
  // `run` command's build-kit-vs-modeling-kit gate above). It keeps ONE Claude
@@ -1650,6 +1691,7 @@ credentialFlags(program
1650
1691
  // stale MCP registration pointing at the wrong host is worse than none
1651
1692
  // (see the beta-api protected-resource-metadata incident this fixed).
1652
1693
  ensureMcpRegistered(targetDir, cfg.baseUrl || DEFAULT_BASE_URL);
1694
+ ensureEnvToken(targetDir, cfg.token);
1653
1695
  }
1654
1696
  });
1655
1697
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eventmodelers/cli",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "Eventmodelers CLI — real-time Claude agent + skills for Claude Code, for any stack (Node, Supabase, Axon, Cratis, or modeling-only)",
5
5
  "type": "module",
6
6
  "bin": {
@@ -93,6 +93,18 @@ Every question and every summary theme must be written in plain business languag
93
93
  - **Do not flag technical/infrastructure fields** (IDs, timestamps, correlation IDs, version numbers) as missing — these are implementation decisions, not business gaps.
94
94
  - **Do not assume** notifications (welcome email, verification, webhook) are missing just because they aren't modelled. They may belong to a different slice or context not yet built. Only ask if the model explicitly implies a notification is needed but nothing wires to it.
95
95
 
96
+ ### Category I: Structural shapes
97
+ This category is about the **shape of the model**, not any one flow's business logic — it needs the edge/relationship data and per-slice scenario counts gathered across *all* slices in Step 2, so run it once after all slices are loaded, not per-slice. Check the full element graph for these four known shapes. Each still gets a business-worded question, per the language rule — never say "bed", "left-chair", "right-chair", or "shelf" in a comment; those are your internal names for spotting the shape, not vocabulary for the board.
98
+
99
+ Only one of these four is an actual anti-pattern — invalid regardless of context. The other three are **candidates**: a count crossing the rough threshold means "worth checking against the business context," not "wrong." Never raise a candidate off the count alone — reason about the specific events/fields/scenarios involved first, and only post if, in this domain, the count still looks like it's doing more than one job. If the context justifies it, drop it silently.
100
+
101
+ - **The bed (real anti-pattern — always flag)** — one screen wired to more than one command. A screen is where the user has already committed to one decision, so it should trigger exactly one command; wiring several to it means the choice is being made somewhere invisible to the model. Flag this directly and confidently, not as a soft maybe — still in plain business language, but assertive: "This screen lets someone trigger more than one action from the same place — should this be split into separate steps or buttons so it's clear which one they're choosing?"
102
+ - **The left chair (candidate)** — one command resulting in more than two events. May mean the command is doing more than one job, or it may be a single business outcome that legitimately fans out. Check whether the outcomes always happen together or could happen independently before asking. Example, only if it holds up: "When this action succeeds, do all of these things always happen together, or could some happen without the others?"
103
+ - **The right chair (candidate)** — one read model built from more than three events. May mean the view is answering more than one question at once, or it may be one coherent picture that genuinely needs that many sources. Check whether the fields shown belong to a single thing the user is checking before asking. Example, only if it holds up: "Is this screen answering one question for the user, or several different ones bundled together?"
104
+ - **The shelf (candidate)** — one slice with noticeably more scenarios than the others on the same timeline (a rough outlier, not a fixed threshold — compare against the typical count for that timeline). May mean the step is quietly covering ground that belongs to a separate step, or it may just be genuinely more complex. Check what the extra scenarios actually cover before asking. Example, only if it holds up: "This step has a lot more cases than the ones around it — is that because it's really doing more, or because it's covering something that should be its own step?"
105
+
106
+ Each of these four is inherently about a relationship or cluster of elements, so whichever you do raise always gets a drawing per Step 4.2 in addition to its comment — a group loop around the elements involved, or an arrow if the concern is specifically about one edge among several.
107
+
96
108
  ---
97
109
 
98
110
  ## Step 4 — Comments carry every textual question; drawings carry every visual/structural hint