@eventmodelers/cli 1.0.143 → 1.0.145

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 CHANGED
@@ -461,6 +461,7 @@ a rotated token, a different board) pass `--force`:
461
461
 
462
462
  ```bash
463
463
  npx @eventmodelers/cli run --modeling --force
464
+ npx @eventmodelers/cli run --force # build kit: same prompt, board id required
464
465
  ```
465
466
 
466
467
  It re-runs the same credentials prompt as `init --modeling`, overwrites the project's
package/cli.js CHANGED
@@ -3192,7 +3192,7 @@ program
3192
3192
  // dir: a modeling run falls back to the global install (see ensureGlobalKit) rather than
3193
3193
  // requiring one here, and the build-kit branch reports a better-targeted error of its own
3194
3194
  // than this generic gate can.
3195
- const NO_INIT_REQUIRED = new Set(['init', 'init-config', 'stacks', 'status', 'config', 'uninstall', 'fetch', 'activate-context', 'set-slice-status', 'release-notes', 'run']);
3195
+ const NO_INIT_REQUIRED = new Set(['init', 'init-config', 'stacks', 'status', 'config', 'uninstall', 'fetch', 'activate-context', 'set-slice-status', 'release-notes', 'run', 'listen']);
3196
3196
 
3197
3197
  // Commands that install or refresh the kit themselves — a "your kit is outdated" hint in
3198
3198
  // front of them would only be noise.
@@ -3684,7 +3684,7 @@ credentialFlags(program
3684
3684
  .option('--exec [command]', 'Fallback for any harness --agent does not cover, or other flags than its preset. Hand each prompt to an external agent command instead of the default Claude runner — for agentic harnesses that bring their own tool loop, e.g. "codex exec --full-auto", "gemini --yolo -p" or "opencode run". One process per prompt; the prompt is appended as a quoted argument and also written to the file named by RALPH_PROMPT_FILE. Bare --exec uses localAi.exec from .eventmodelers/config.json. Claude remains the default when this flag is absent. A build kit runs it via ralph-exec.js; there, with agent tracing on, include the harness\'s JSON output flag (codex exec --json, opencode run --format json, gemini --output-format stream-json) — without it no slice cost is recorded. With --modeling/--standalone/--worker it is how any agent takes board prompts and chats: the loop claims each prompt or chat message and runs the command once for it. Keep the harness in its plain-text output mode there — stdout is the turn\'s answer — the eventmodelers MCP server is registered for it on every run (opencode.json, .gemini/settings.json, or -c flags for codex; any other command logs what to register by hand), authenticating with $EVENTMODELERS_TOKEN from the env the command inherits, and `init-agents --hosts <harness>` installs the skills for a harness that does not read .claude/skills. No subagents: self-directed work is done inline.')
3685
3685
  .option('--bash', 'Use the bash-only ralph.sh loop (build-kit stacks only, no realtime)')
3686
3686
  .option('--modeling', 'Connect a modeling agent to the board: it takes prompts and chat messages and hands each to an AI — by default one Claude process kept warm across prompts, for low-latency voice/live use; --agent (or --local-ai, or --exec as the manual fallback) picks another. Runs from a modeling-kit install in this directory, or from the global install (~/.eventmodelers/kit) when there is none. Built into the CLI, not a per-project file.')
3687
- .option('-f, --force', 'Ask for credentials again before the modeling loop starts, even when a config already has everything required. With a modeling kit in this directory it re-runs the same prompt as `init --modeling`, overwriting the project\'s .eventmodelers/config.json; with the global install it drops the "keep the stored credentials" choice, so a board\'s credentials have to be answered afresh. Only affects the modeling loop (--modeling/--standalone/--worker/--global); cannot be combined with --non-interactive or --print.')
3687
+ .option('-f, --force', 'Ask for credentials again before the modeling loop starts, even when a config already has everything required. With a modeling kit in this directory it re-runs the same prompt as `init --modeling`, overwriting the project\'s .eventmodelers/config.json; with the global install it drops the "keep the stored credentials" choice, so a board\'s credentials have to be answered afresh. Applies to build-kit runs too, where it re-asks against the project\'s .eventmodelers/config.json. Cannot be combined with --non-interactive, --print or --local.')
3688
3688
  .option('--non-interactive', 'Never ask anything: take the board and credentials that resolve from flags, EVENTMODELERS_* env vars and the config files, and fail with the reason if they are incomplete instead of interviewing for them. A TTY was previously the only signal — right for CI or a supervisor, wrong for a loop started from a terminal, where stdin is a TTY nobody is watching and the run stops on a question. Only affects the modeling loop (--modeling/--standalone/--worker/--global).')
3689
3689
  .option('--standalone', 'Let the modeling agent act on board changes on its own initiative, without asking: it subscribes to the board\'s change channel and, whenever the board goes quiet after an edit — or has simply been idle for a while — it takes a turn nobody asked for, judges the model as a whole and fans the work out over parallel subagents, one per changed area (examples on a new node, specs for a new command or read model, a missing attribute along a chain, a screen, a question). Filling that detail in while the human keeps modeling is the point. A plain --modeling agent only proposes, and only to the people chatting with it: after their edits it says in the chat what it would do and waits for a yes; everyone else\'s edits are ignored. Implies --modeling.')
3690
3690
  .option('--max-agents <n>', 'Cap how many subagents a self-directed --standalone turn may dispatch at once, to bound what an unattended agent can spend per turn. The agent merges work that shares a slice or chain first, then takes the most valuable pieces up to this many and leaves the rest for a later turn. 1 makes it do the single most valuable piece itself, without spawning anything. Default 5. Ignored without --standalone — prompt turns are one piece of work by definition.', '5')
@@ -3731,11 +3731,8 @@ credentialFlags(program
3731
3731
  if (command.getOptionValueSource('maxAgents') === 'cli' && !opts.standalone) {
3732
3732
  console.log('ℹ️ --max-agents only applies to --standalone turns; ignoring it here.');
3733
3733
  }
3734
- // The build-kit runners claim their work from the same queue but have no addressee
3735
- // filter, so the flag would silently do nothing there rather than half of what it says.
3736
- if (opts.force && !(opts.modeling || opts.standalone || opts.worker || opts.global)) {
3737
- console.log('ℹ️ --force only applies to the modeling loop (--modeling/--standalone/--worker/--global); for a build kit use `re-init --force` or `init-config`. Ignoring it here.');
3738
- }
3734
+ // --exclusive is the one flag the build-kit runners can't honor: they claim their work from the
3735
+ // same queue but have no addressee filter, so it would silently do nothing there.
3739
3736
  if (opts.exclusive && !(opts.modeling || opts.standalone || opts.worker || opts.global)) {
3740
3737
  console.log('ℹ️ --exclusive only applies to the modeling loop (--modeling/--standalone/--worker/--global); ignoring it here.');
3741
3738
  }
@@ -3917,6 +3914,35 @@ credentialFlags(program
3917
3914
  process.exit(1);
3918
3915
  }
3919
3916
 
3917
+ // --force on a build kit: same credentials step as `init-config`, against the project-root
3918
+ // config the runner reads, so the loop below picks up the fresh answer.
3919
+ if (opts.force) {
3920
+ if (opts.nonInteractive || globalOpts.print) {
3921
+ console.error('❌ --force asks for credentials again, which --non-interactive/--print rule out — pick one.');
3922
+ process.exit(1);
3923
+ }
3924
+ if (opts.local) {
3925
+ console.error('❌ --force asks for credentials, which --local (no platform config) never uses — pick one.');
3926
+ process.exit(1);
3927
+ }
3928
+ const projectDir = dirname(kitDir);
3929
+ const configPath = globalOpts.config
3930
+ ? resolve(projectDir, globalOpts.config)
3931
+ : join(projectDir, '.eventmodelers', 'config.json');
3932
+ const cfg = await configureCredentials({
3933
+ config: loadEffectiveConfig(cwd, kitDir, globalOpts.config).config,
3934
+ configPath,
3935
+ targetDir: projectDir,
3936
+ requiredFields: ['organizationId', 'boardId', 'token'],
3937
+ overrides: credentialOverridesFromOpts(opts),
3938
+ print: false,
3939
+ force: true,
3940
+ });
3941
+ ensureMcpRegistered(projectDir, cfg.baseUrl || DEFAULT_BASE_URL);
3942
+ ensureEnvToken(projectDir, cfg.token);
3943
+ ensureMcpEnabled(projectDir);
3944
+ }
3945
+
3920
3946
  // ralph-claude.js hands every turn to a `claude` that only discovers MCP servers from
3921
3947
  // `.mcp.json` at its own startup, so it is rewritten on every run (see ensureMcpRegistered) —
3922
3948
  // a file deleted, or written for another baseUrl, since `init` would otherwise leave the agent
@@ -4005,22 +4031,24 @@ program
4005
4031
 
4006
4032
  program
4007
4033
  .command('listen')
4008
- .description('Start the code-export listener (code-export.mjs) from the installed kit dir — receives slice/screen data pushed from the eventmodelers board UI and writes it into .slices/')
4034
+ .description('Start the code-export listener (code-export.mjs) from the installed kit dir, or the bundled copy when no kit is installed — receives slice/screen data pushed from the eventmodelers board UI and writes it into .slices/')
4009
4035
  .option('--port <port>', 'Port to listen on (default 3001, or $PORT)')
4010
4036
  .action((opts) => {
4011
4037
  const cwd = process.cwd();
4012
4038
  const kitDir = findInstalledKitDir(cwd);
4013
4039
 
4014
- const serverPath = join(kitDir, 'code-export.mjs');
4040
+ // With a kit installed, run its own code-export.mjs. Without one, run the copy bundled
4041
+ // in this CLI, rooted at the current directory so .slices/ lands here, not in the npx cache.
4042
+ const serverPath = kitDir ? join(kitDir, 'code-export.mjs') : join(__dirname, 'shared', 'build-kit', 'code-export.mjs');
4015
4043
  if (!existsSync(serverPath)) {
4016
4044
  console.error(`❌ ${relative(cwd, serverPath)} not found.`);
4017
4045
  process.exit(1);
4018
4046
  }
4019
4047
 
4020
4048
  console.log(`▶ Starting ${relative(cwd, serverPath)}...\n`);
4021
- const env = opts.port ? { ...process.env, PORT: opts.port } : process.env;
4049
+ const env = { ...process.env, ...(opts.port && { PORT: opts.port }), ...(!kitDir && { SLICES_ROOT: cwd, WORKSPACE_PATH: cwd }) };
4022
4050
  try {
4023
- execSync(`node "${serverPath}"`, { cwd: kitDir, stdio: 'inherit', env });
4051
+ execSync(`node "${serverPath}"`, { cwd: kitDir ?? cwd, stdio: 'inherit', env });
4024
4052
  } catch (err) {
4025
4053
  process.exit(err.status || 1);
4026
4054
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eventmodelers/cli",
3
- "version": "1.0.143",
3
+ "version": "1.0.145",
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": {
@@ -7,7 +7,9 @@ import { fileURLToPath } from 'url';
7
7
 
8
8
  const __filename = fileURLToPath(import.meta.url);
9
9
  const __dirname = dirname(__filename);
10
- const ROOT = __dirname;
10
+ // SLICES_ROOT lets `eventmodelers listen` run this bundled copy outside an installed kit,
11
+ // writing .slices/ into the caller's directory instead of next to this file.
12
+ const ROOT = process.env.SLICES_ROOT ?? __dirname;
11
13
  const CONFIG_PATH = join(ROOT, 'config.json');
12
14
  const SLICES_DIR = join(ROOT, '.slices');
13
15
  const repoPath = process.env.WORKSPACE_PATH ?? join(__dirname, '..');