@eventmodelers/cli 2.0.54 → 2.0.55

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.
Files changed (2) hide show
  1. package/cli.js +24 -7
  2. package/package.json +1 -1
package/cli.js CHANGED
@@ -4525,7 +4525,7 @@ credentialFlags(program
4525
4525
  // path with no stream-json parsing to gate. RALPH_LOCAL is read by ralph.js's startRalph to force
4526
4526
  // the local-only branch even when .eventmodelers/config.json has valid credentials.
4527
4527
  // RALPH_AGENT_ID/RALPH_AGENT_NAME (--id/--name) are read there too.
4528
- execSync(cmd, { cwd: kitDir, stdio: 'inherit', env: { ...process.env, RALPH_VERBOSE: opts.verbose ? '1' : '', RALPH_SYNC: opts.sync ? '1' : '', RALPH_LOCAL: opts.local ? '1' : '', RALPH_HANDOVER: opts.handover ? '1' : '', RALPH_STATUS_TRIGGER: opts.statusTrigger ? String(opts.statusTrigger).trim() : '', RALPH_FEATURE: opts.feature ? String(opts.feature).trim() : '', RALPH_AGENT_ID: identity.agentId ?? '', RALPH_AGENT_NAME: identity.agentName ?? '', ...(typeof localAiTarget === 'string' ? { LOCAL_AI_TARGET: localAiTarget } : {}), ...(typeof opts.exec === 'string' ? { RALPH_EXEC_CMD: opts.exec } : {}), ...(acpAgent ? { RALPH_ACP_AGENT: opts.acpAgent ?? '', RALPH_ACP_CMD: opts.acpCmd ?? '' } : {}) } });
4528
+ execSync(cmd, { cwd: kitDir, stdio: 'inherit', env: { ...process.env, RALPH_VERBOSE: opts.verbose ? '1' : '', RALPH_SYNC: opts.sync ? '1' : '', RALPH_LOCAL: opts.local ? '1' : '', RALPH_HANDOVER: opts.handover ? '1' : '', RALPH_STATUS_TRIGGER: opts.statusTrigger ? String(opts.statusTrigger).trim() : '', RALPH_FEATURE: opts.feature ? String(opts.feature).trim() : '', EVENTMODELERS_KIT_DIR: kitDir, RALPH_AGENT_ID: identity.agentId ?? '', RALPH_AGENT_NAME: identity.agentName ?? '', ...(typeof localAiTarget === 'string' ? { LOCAL_AI_TARGET: localAiTarget } : {}), ...(typeof opts.exec === 'string' ? { RALPH_EXEC_CMD: opts.exec } : {}), ...(acpAgent ? { RALPH_ACP_AGENT: opts.acpAgent ?? '', RALPH_ACP_CMD: opts.acpCmd ?? '' } : {}) } });
4529
4529
  } catch (err) {
4530
4530
  process.exit(err.status || 1);
4531
4531
  }
@@ -5296,10 +5296,27 @@ program
5296
5296
  console.log(`✅ Pushed status change to the board (node ${slice.id}).`);
5297
5297
  });
5298
5298
 
5299
+ // The kit directory the run loop pinned for its agent (EVENTMODELERS_KIT_DIR, set by `eventmodelers run`), or null.
5300
+ // An agent's shell cwd drifts; the loop's does not. A stale value (directory gone) is ignored rather than trusted.
5301
+ function pinnedKitDir() {
5302
+ const dir = process.env.EVENTMODELERS_KIT_DIR;
5303
+ return dir && existsSync(dir) ? resolve(dir) : null;
5304
+ }
5305
+
5306
+ // Where an agent-side command resolves the project from: the pinned kit's project, else the shell's cwd.
5307
+ function agentCwd() {
5308
+ const pinned = pinnedKitDir();
5309
+ return pinned ? dirname(pinned) : process.cwd();
5310
+ }
5311
+
5299
5312
  // The kit a command that records events works against: a build kit if one is installed, else the modeling
5300
5313
  // kit. The build kit wins when both are installed — the modeling agent never runs these commands itself
5301
5314
  // (its Bash is an allowlist); it states its learnings in its reply and `runModeling` records them.
5302
5315
  function requireBuildKitDir(cwd) {
5316
+ // The run loop exports the kit it runs in. Trust it over the shell's cwd: the build agent may `cd` elsewhere in the
5317
+ // project (an app with a root kit and a web/ kit) and its commands must still reach the kit that holds the claim.
5318
+ const pinned = pinnedKitDir();
5319
+ if (pinned) return pinned;
5303
5320
  const installed = findAllInstalledKitDirs(cwd);
5304
5321
  const kitDir = installed.find((d) => !d.endsWith(MODELING_KIT.kitDirName)) ?? installed.find((d) => d.endsWith(MODELING_KIT.kitDirName));
5305
5322
  if (!kitDir) {
@@ -5325,7 +5342,7 @@ program
5325
5342
  .description("For a build agent: record the outcome of the slice the run loop is building (Done, Waiting, Blocked, ...). The loop owns the slice's status on the board and pushes it when the build ends — never edit index.json or call update-slice-status for a loop build.")
5326
5343
  .option('--slice <idOrTitle>', 'The slice, when the loop has claimed more than one (default: the one it is building)')
5327
5344
  .action((status, opts, command) => {
5328
- const cwd = process.cwd();
5345
+ const cwd = agentCwd();
5329
5346
  // `Handover` is the old name of `Waiting`; older skills and prompts still say it
5330
5347
  const wanted = status.toLowerCase() === 'handover' ? 'waiting' : status.toLowerCase();
5331
5348
  const canonical = SLICE_STATUSES.find((s) => s.value.toLowerCase() === wanted)?.value;
@@ -5359,7 +5376,7 @@ program
5359
5376
  console.error('❌ Action must be `check` or `record`.');
5360
5377
  process.exit(1);
5361
5378
  }
5362
- const cwd = process.cwd();
5379
+ const cwd = agentCwd();
5363
5380
  const kitDir = requireBuildKitDir(cwd);
5364
5381
  let wanted = opts.slice;
5365
5382
  if (!wanted) {
@@ -5367,7 +5384,7 @@ program
5367
5384
  if (claimed.length !== 1) {
5368
5385
  if (!claimed.length) {
5369
5386
  // Where it looked: an agent running from another kit's directory finds no claim in that kit's log.
5370
- try { appendEvent(kitDir, { type: 'claim-not-found', command: 'build-baseline', claimed: 0, ...locationOf(kitDir, cwd) }, agentEventMeta(cwd, kitDir, command)); } catch { /* best effort */ }
5387
+ try { appendEvent(kitDir, { type: 'claim-not-found', command: 'build-baseline', claimed: 0, ...locationOf(kitDir, process.cwd()) }, agentEventMeta(cwd, kitDir, command)); } catch { /* best effort */ }
5371
5388
  }
5372
5389
  console.error(`❌ ${claimed.length ? `${claimed.length} slices are claimed` : 'No slice is claimed by the run loop'} — name the slice with --slice.`);
5373
5390
  process.exit(1);
@@ -5432,7 +5449,7 @@ program
5432
5449
  .option('--merge <ids>', 'Replace these learnings (comma-separated ids) by one with the given text — the curator\'s tool')
5433
5450
  .option('--reason <reason>', 'Why — recorded with a retraction or a merge')
5434
5451
  .action((text, opts, command) => {
5435
- const cwd = process.cwd();
5452
+ const cwd = agentCwd();
5436
5453
  const kitDir = requireBuildKitDir(cwd);
5437
5454
  const meta = agentEventMeta(cwd, kitDir, command);
5438
5455
  try {
@@ -5465,7 +5482,7 @@ program
5465
5482
  .option('--slice <idOrTitle>', 'The slice it is about (default: the one the run loop has claimed)')
5466
5483
  .option('--tag <tag>', 'Label the info (repeatable)', (tag, tags) => [...tags, tag], [])
5467
5484
  .action(async (text, opts, command) => {
5468
- const cwd = process.cwd();
5485
+ const cwd = agentCwd();
5469
5486
  const kitDir = requireBuildKitDir(cwd);
5470
5487
  const meta = agentEventMeta(cwd, kitDir, command);
5471
5488
  try {
@@ -5647,7 +5664,7 @@ program
5647
5664
  .description('Print the recorded learnings — what .build-kit/AGENTS.md says. With --ids, one line each with the id to retract it by.')
5648
5665
  .option('--ids', 'One line per learning: id, topic, text')
5649
5666
  .action((opts, command) => {
5650
- const cwd = process.cwd();
5667
+ const cwd = agentCwd();
5651
5668
  const kitDir = requireBuildKitDir(cwd);
5652
5669
  syncLearnings({ kitDir, meta: agentEventMeta(cwd, kitDir, command) });
5653
5670
  const all = listLearnings(kitDir);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eventmodelers/cli",
3
- "version": "2.0.54",
3
+ "version": "2.0.55",
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": {