@eventmodelers/cli 1.0.110 → 1.0.111
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
|
@@ -1949,7 +1949,7 @@ async function ensureGlobalKit(baseUrl) {
|
|
|
1949
1949
|
// untargeted is handed straight back to the queue for another agent to take. It says
|
|
1950
1950
|
// nothing about the standalone lane — a self-directed turn is nobody's task, so an
|
|
1951
1951
|
// exclusive standalone agent still works the board on its own initiative.
|
|
1952
|
-
async function runModeling(kitDir, projectDir, { verbose = false, standalone = false, exclusive = false, worker = false, overrides = null, maxAgents = DEFAULT_MAX_AGENTS, identity = {}, localAi = null, exec = null, model = null } = {}) {
|
|
1952
|
+
async function runModeling(kitDir, projectDir, { codeDir = null, verbose = false, standalone = false, exclusive = false, worker = false, overrides = null, maxAgents = DEFAULT_MAX_AGENTS, identity = {}, localAi = null, exec = null, model = null } = {}) {
|
|
1953
1953
|
// --worker: only prompts — no chat, and no board-change turns (it has nowhere to propose).
|
|
1954
1954
|
const chat = !worker;
|
|
1955
1955
|
const configLibPath = join(kitDir, 'lib', 'config.js');
|
|
@@ -2104,8 +2104,13 @@ async function runModeling(kitDir, projectDir, { verbose = false, standalone = f
|
|
|
2104
2104
|
|
|
2105
2105
|
const claudeArgs = ['--dangerously-skip-permissions', '-p', '--input-format', 'stream-json', '--output-format', 'stream-json', '--verbose'];
|
|
2106
2106
|
if (cfg.model) claudeArgs.push('--model', cfg.model);
|
|
2107
|
+
// The global install runs in ~/.eventmodelers/kit, away from the code base the person started
|
|
2108
|
+
// the agent in — hand that directory over so code-reading skills (detect-architecture-drift)
|
|
2109
|
+
// can still see it.
|
|
2110
|
+
if (codeDir) claudeArgs.push('--add-dir', codeDir);
|
|
2107
2111
|
const claudeEnv = {
|
|
2108
2112
|
...process.env,
|
|
2113
|
+
...(codeDir ? { EVENTMODELERS_CODE_DIR: codeDir } : {}),
|
|
2109
2114
|
...(cfg.anthropicBaseUrl ? { ANTHROPIC_BASE_URL: cfg.anthropicBaseUrl } : {}),
|
|
2110
2115
|
EVENTMODELERS_TOKEN: cfg.token,
|
|
2111
2116
|
// What the connect skill puts in `.mcp.json`'s x-agent-id header and every curl-fallback
|
|
@@ -3762,7 +3767,9 @@ credentialFlags(program
|
|
|
3762
3767
|
}
|
|
3763
3768
|
let projectDir = kitDir ? resolve(kitDir, '..') : null;
|
|
3764
3769
|
let overrides = null;
|
|
3770
|
+
let codeDir = null;
|
|
3765
3771
|
if (!kitDir) {
|
|
3772
|
+
codeDir = cwd;
|
|
3766
3773
|
// The blob and the individual flags are both "explicit", so they share a
|
|
3767
3774
|
// precedence tier — with a single --token/--board-id winning, since overriding one
|
|
3768
3775
|
// field of a pasted blob is the only reason to pass both.
|
|
@@ -3785,7 +3792,7 @@ credentialFlags(program
|
|
|
3785
3792
|
const runnerLabel = modelingLocalAi ? 'local model' : opts.exec ? 'one agent process per turn' : 'warm Claude process';
|
|
3786
3793
|
await new Promise((res) => process.stdout.write(`▶ Starting modeling loop (${runnerLabel}) for ${shown && !shown.startsWith('..') ? shown : kitDir}...\n\n`, res));
|
|
3787
3794
|
try {
|
|
3788
|
-
await runModeling(kitDir, projectDir, { verbose: !!opts.verbose, standalone: !!opts.standalone, exclusive: !!opts.exclusive, worker: !!opts.worker, overrides, maxAgents, identity, localAi: modelingLocalAi, exec: opts.exec ?? null, model: !opts.exec && modelingLocalAi === null ? model : null });
|
|
3795
|
+
await runModeling(kitDir, projectDir, { codeDir, verbose: !!opts.verbose, standalone: !!opts.standalone, exclusive: !!opts.exclusive, worker: !!opts.worker, overrides, maxAgents, identity, localAi: modelingLocalAi, exec: opts.exec ?? null, model: !opts.exec && modelingLocalAi === null ? model : null });
|
|
3789
3796
|
} catch (err) {
|
|
3790
3797
|
console.error('[modeling] Fatal:', err);
|
|
3791
3798
|
process.exit(1);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eventmodelers/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.111",
|
|
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": {
|
|
@@ -1121,7 +1121,8 @@ Rule of thumb: if you are about to write "Shall I…?", "Want me to…?", "A or
|
|
|
1121
1121
|
{ kind: 'code', code: string, language?: string, title?: string } // monospaced, with a copy button
|
|
1122
1122
|
{ kind: 'report', chart: 'bar' | 'line' | 'pie', title?: string, unit?: string,
|
|
1123
1123
|
labels: string[], // 1–50 points: x axis, or the pie slices
|
|
1124
|
-
series: Array<{ name: string, values: number[] }
|
|
1124
|
+
series: Array<{ name: string, values: number[] }>, // one number per label; bar/line up to 6 series, pie uses only the first (no negatives)
|
|
1125
|
+
confirm?: { headline: string, yesLabel?: string, noLabel?: string } } // optional yes/no question under the diagram, like a confirm snippet
|
|
1125
1126
|
```
|
|
1126
1127
|
|
|
1127
1128
|
### How to use them
|
|
@@ -1131,7 +1132,7 @@ Rule of thumb: if you are about to write "Shall I…?", "Want me to…?", "A or
|
|
|
1131
1132
|
- **Name elements** with `nodeId` wherever you can (`tasks`, `changes`, `link`), so the person can click through to them — in a `tasks` list, put the element's name in `description` and its id in `nodeId`.
|
|
1132
1133
|
- **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.
|
|
1133
1134
|
- `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.
|
|
1134
|
-
- **`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.
|
|
1135
|
+
- **`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.
|
|
1135
1136
|
- A snippet is shown exactly as you send it — keep secrets and tokens out of `code` and `image`.
|
|
1136
1137
|
|
|
1137
1138
|
---
|
|
@@ -215,10 +215,12 @@ mcp__eventmodelers__post_chat_message {
|
|
|
215
215
|
"snippet": {
|
|
216
216
|
"kind": "report", "chart": "pie", "title": "Slices by status", "unit": "slices",
|
|
217
217
|
"labels": ["Done", "InProgress", "Planned", "Blocked"],
|
|
218
|
-
"series": [{ "name": "Slices", "values": [12, 6, 4, 2] }]
|
|
218
|
+
"series": [{ "name": "Slices", "values": [12, 6, 4, 2] }],
|
|
219
|
+
"confirm": { "headline": "Want the full list of slices without scenarios?" }
|
|
219
220
|
}
|
|
220
221
|
}
|
|
221
222
|
```
|
|
223
|
+
- `confirm` is optional: use it when you end on a follow-up question, instead of asking it in the text; the answer arrives as the person's next chat message.
|
|
222
224
|
- Only statuses with at least one slice, one number per label — the chart draws exactly what you send, so count first.
|
|
223
225
|
- One snippet per message: if the person asks for more diagrams (spec coverage, element inventory per type as a `bar`),
|
|
224
226
|
answer each in its own reply.
|
|
@@ -7,7 +7,7 @@ description: Compare the event model on the board with the code in this reposito
|
|
|
7
7
|
|
|
8
8
|
## Step 0 — Is there a code base?
|
|
9
9
|
|
|
10
|
-
Drift is the gap between the board and the code, so it can only be detected where code exists. **Before anything else — before `connect`, before reading the board — check that the current directory is a code base
|
|
10
|
+
Drift is the gap between the board and the code, so it can only be detected where code exists. **Before anything else — before `connect`, before reading the board — resolve the directory to check**: `$EVENTMODELERS_CODE_DIR` if it is set (the agent runs from the global install and was started inside that directory — treat it as the repository root for every step below, not the current directory), otherwise the current directory. Check that it is a code base: it contains source code (e.g. `src/`, `.build-kit/`, a `package.json`, `pom.xml`, `*.csproj`, `build.gradle`, or similar project files with slice/command/event/projection code).
|
|
11
11
|
|
|
12
12
|
If it is not (an empty folder, a modeling-only workspace holding just `.claude/`, `.eventmodelers/` or `.agent-modeling-kit/`), **stop and answer in one or two plain sentences**, e.g.:
|
|
13
13
|
|
|
@@ -58,7 +58,7 @@ Index the result in memory: per slice → commands, events, read models, screens
|
|
|
58
58
|
|
|
59
59
|
## Step 3 — Understand the code
|
|
60
60
|
|
|
61
|
-
|
|
61
|
+
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.
|
|
62
62
|
|
|
63
63
|
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).
|
|
64
64
|
2. If `.build-kit/.slices/<context>/<slice>/slice.json` exists, it is the snapshot the code was **last built from** — useful for telling "the code changed" apart from "the model changed since the build" (see Step 5).
|