@eventmodelers/cli 1.0.12 → 1.0.14

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
@@ -105,6 +105,7 @@ npx @eventmodelers/cli re-init # refresh an already-install
105
105
  npx @eventmodelers/cli run # start the agent loop (ralph-claude.js) from the installed kit dir
106
106
  npx @eventmodelers/cli run --ollama # same, via local Ollama (ralph-ollama.js)
107
107
  npx @eventmodelers/cli run --bash # bash-only loop, no realtime (ralph.sh)
108
+ npx @eventmodelers/cli run --local # skip platform config/credential lookup entirely — local-only, no board sync
108
109
  npx @eventmodelers/cli fetch --context <name> # pull full slice detail for one context on the board into <kit-dir>/.slices/
109
110
  npx @eventmodelers/cli fetch --context <name> --slice-id <id> # same, then print just that slice
110
111
  npx @eventmodelers/cli fetch --context <name> --slice-title <title> # same, then print just the slice matching this title
@@ -312,13 +313,16 @@ npx @eventmodelers/cli listen --port 4000 # same, on a different port
312
313
  ```bash
313
314
  npx @eventmodelers/cli re-init # refresh the installed build kit (.build-kit/) + its skills
314
315
  npx @eventmodelers/cli re-init --modeling # refresh the modeling kit (.agent-modeling-kit/) + its skills
316
+ npx @eventmodelers/cli re-init --stack supabase # override which stack to refresh from (manifest missing/stale, or switching stacks)
315
317
  ```
316
318
 
317
319
  `re-init` re-runs `init` against whichever stack `install-manifest.json` says was installed (no need to pass `--stack` again), but skips step 2 of `init` entirely — the root project scaffold (`package.json`, `src/`, `server.ts`, `docker-compose.yml`, etc.) and the root `CLAUDE.md` router are never touched. Use it after upgrading the CLI to pick up fixes to `ralph.js`/`ralph.sh`/skills without re-scaffolding a project you've since built on top of.
318
320
 
321
+ Pass `--stack <name>` to override the stack instead of relying on the manifest — useful if the manifest is missing/stale, or you want to point a `.build-kit` install at a different built-in stack's templates. It's mutually exclusive with `--modeling`.
322
+
319
323
  Credentials are left alone unless you pass `--force` — same rule `init` already follows when everything required is already configured. `--global` defaults to however skills were originally installed; pass it explicitly to move them.
320
324
 
321
- If the kit dir predates install-manifest.json tracking, or was installed via `init --git <url>` (a community/custom stack, not one of the built-in `STACKS` keys), `re-init` can't tell what to re-copy and tells you to re-run the original `init` command by hand instead.
325
+ If the kit dir predates install-manifest.json tracking, or was installed via `init --git <url>` (a community/custom stack, not one of the built-in `STACKS` keys), and you don't pass `--stack` yourself, `re-init` can't tell what to re-copy and tells you to re-run the original `init` command by hand instead.
322
326
 
323
327
  ### Uninstall
324
328
 
package/cli.js CHANGED
@@ -1635,12 +1635,23 @@ credentialFlags(program
1635
1635
  .command('re-init')
1636
1636
  .description('Refresh an already-installed kit from the current CLI version — re-copies skills and the kit dir (.build-kit or .agent-modeling-kit) so you pick up script/skill updates after upgrading. Unlike `init`, never touches the project root scaffold or the root CLAUDE.md router, and leaves existing credentials alone unless --force is passed.')
1637
1637
  .option('--modeling', 'Refresh the modeling kit (.agent-modeling-kit) instead of a build kit')
1638
+ .option('--stack <name>', `Override which stack to refresh from (${Object.keys(REINITIABLE_STACKS).join(', ')}) instead of the one recorded in install-manifest.json — use this when the manifest is missing/stale, or to switch a .build-kit install to a different stack`)
1638
1639
  .option('--global', 'Re-install skills into ~/.claude/skills/ instead of the project — defaults to however they were originally installed')
1639
1640
  .option('-f, --force', 'Re-prompt for credentials even if a config already has everything required — overwrites the existing config.json'))
1640
1641
  .action(async (opts, command) => {
1641
1642
  const globalOpts = command.optsWithGlobals();
1642
1643
  const targetDir = process.cwd();
1643
1644
 
1645
+ if (opts.modeling && opts.stack) {
1646
+ console.error('❌ --modeling and --stack are mutually exclusive — pick one.');
1647
+ process.exit(1);
1648
+ }
1649
+
1650
+ if (opts.stack && !REINITIABLE_STACKS[opts.stack]) {
1651
+ console.error(`❌ Unknown stack "${opts.stack}". Available: ${Object.keys(REINITIABLE_STACKS).join(', ')}`);
1652
+ process.exit(1);
1653
+ }
1654
+
1644
1655
  const kitDirName = opts.modeling ? MODELING_KIT.kitDirName : STACKS.node.kitDirName;
1645
1656
  const kitDir = join(targetDir, kitDirName);
1646
1657
 
@@ -1650,12 +1661,12 @@ credentialFlags(program
1650
1661
  }
1651
1662
 
1652
1663
  const manifest = readJsonSafe(join(kitDir, '.eventmodelers', 'install-manifest.json'));
1653
- const stackKey = opts.modeling ? MODELING_KIT.key : manifest.stack;
1664
+ const stackKey = opts.modeling ? MODELING_KIT.key : (opts.stack || manifest.stack);
1654
1665
  const stackCfg = stackKey ? REINITIABLE_STACKS[stackKey] : null;
1655
1666
 
1656
1667
  if (!stackCfg) {
1657
1668
  console.error(`❌ Can't tell which stack ${relative(targetDir, kitDir)} was installed from (${manifest.stack ? `"${manifest.stack}" isn't one re-init recognizes — likely a --git community stack` : 'its install manifest predates this tracking, or is missing'}).`);
1658
- console.error(' Re-run the original `init --git <url> --stack <name>` command by hand instead.');
1669
+ console.error(' Pass --stack <name> explicitly, or re-run the original `init --git <url> --stack <name>` command by hand instead.');
1659
1670
  process.exit(1);
1660
1671
  }
1661
1672
 
@@ -1761,6 +1772,7 @@ program
1761
1772
  .option('--ollama', 'Use ralph-ollama.js instead of the default Claude runner (build-kit stacks only)')
1762
1773
  .option('--bash', 'Use the bash-only ralph.sh loop (build-kit stacks only, no realtime)')
1763
1774
  .option('--modeling', 'Keep one Claude process warm across prompts instead of spawning a fresh one per task, for low-latency voice/live use. Modeling-kit installs only — there is no cold-spawn/tasks.json loop for modeling-kit. Built into the CLI, not a per-project file.')
1775
+ .option('--local', 'Skip platform config/credential lookup entirely and run the local-only loop (no board sync, no realtime agent) — even if .eventmodelers/config.json has credentials (build-kit stacks only)')
1764
1776
  .option('--verbose', 'Log every tool call\'s full input (commands, skill args, file paths) and assistant reasoning text. Default is condensed, high-level per-step logging only.')
1765
1777
  .action(async (opts) => {
1766
1778
  const cwd = process.cwd();
@@ -1788,6 +1800,10 @@ program
1788
1800
  console.error('❌ --modeling is mutually exclusive with --bash/--ollama — those select a build-kit runner, which --modeling has no use for.');
1789
1801
  process.exit(1);
1790
1802
  }
1803
+ if (opts.local) {
1804
+ console.error('❌ --modeling has no local-only mode — it is always driven by the org-wide realtime prompt queue, so --local has no use for it.');
1805
+ process.exit(1);
1806
+ }
1791
1807
  if (!modelingKitDir) {
1792
1808
  console.error(`❌ --modeling only supports a modeling-kit install (${MODELING_KIT.kitDirName}/) — it subscribes to the org-wide prompt queue, which build-kit stacks don't have. Use \`eventmodelers run\` (optionally with --ollama/--bash) for build-kit's slice-status loop instead.`);
1793
1809
  process.exit(1);
@@ -1839,9 +1855,11 @@ program
1839
1855
  console.log(`▶ Starting ${relative(cwd, runnerPath)}...\n`);
1840
1856
  const cmd = runner.endsWith('.sh') ? `"${runnerPath}"` : `node "${runnerPath}"`;
1841
1857
  try {
1842
- // Only ralph-claude.js reads this — the bash loop and the ollama executor have
1843
- // their own separate output paths with no stream-json parsing to gate.
1844
- execSync(cmd, { cwd: kitDir, stdio: 'inherit', env: { ...process.env, RALPH_VERBOSE: opts.verbose ? '1' : '' } });
1858
+ // Only ralph-claude.js reads RALPH_VERBOSE — the bash loop and the ollama executor have
1859
+ // their own separate output paths with no stream-json parsing to gate. RALPH_LOCAL is
1860
+ // read by all three runners (ralph.js's startRalph, and ralph.sh directly) to force the
1861
+ // local-only branch even when .eventmodelers/config.json has valid credentials.
1862
+ execSync(cmd, { cwd: kitDir, stdio: 'inherit', env: { ...process.env, RALPH_VERBOSE: opts.verbose ? '1' : '', RALPH_LOCAL: opts.local ? '1' : '' } });
1845
1863
  } catch (err) {
1846
1864
  process.exit(err.status || 1);
1847
1865
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eventmodelers/cli",
3
- "version": "1.0.12",
3
+ "version": "1.0.14",
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": {
@@ -397,15 +397,19 @@ async function ralphLoop(kitDir, cfg, onTask, onPlannedSlice) {
397
397
 
398
398
  export { loadLocalConfig, fetchPlatformConfig, retryOn401, startRealtimeAgent };
399
399
 
400
- export async function startRalph({ kitDir, projectDir, onTask, onPlannedSlice, agentType = 'BUILD', queueAllStatuses = false }) {
400
+ export async function startRalph({ kitDir, projectDir, onTask, onPlannedSlice, agentType = 'BUILD', queueAllStatuses = false, localOnly = false }) {
401
401
  const local = loadLocalConfig(kitDir);
402
402
  local.agentId = ensureAgentId(kitDir, agentType);
403
403
 
404
404
  console.log(`Ralph — kit: ${kitDir}`);
405
405
  console.log(` project: ${projectDir}`);
406
406
 
407
- if (!hasCredentials(local)) {
408
- console.log(` mode: local-only (no platform sync)\n`);
407
+ // localOnly (set via `eventmodelers run --local`) forces this branch even when
408
+ // credentials are present — it skips fetchPlatformConfig's network call to
409
+ // ${baseUrl}/api/config and startRealtimeAgent entirely, so the loop never
410
+ // reaches out to the platform at all.
411
+ if (localOnly || !hasCredentials(local)) {
412
+ console.log(` mode: local-only (no platform sync)${localOnly ? ' — forced by --local' : ''}\n`);
409
413
  await ralphLoop(kitDir, local, onTask, onPlannedSlice);
410
414
  return;
411
415
  }
@@ -96,6 +96,7 @@ startRalph({
96
96
  projectDir,
97
97
  onTask: runClaude,
98
98
  onPlannedSlice: runClaude,
99
+ localOnly: process.env.RALPH_LOCAL === '1',
99
100
  }).catch((err) => {
100
101
  console.error('[ralph] Fatal:', err);
101
102
  process.exit(1);
@@ -33,6 +33,7 @@ startRalph({
33
33
  projectDir,
34
34
  onTask: runOllama,
35
35
  // onPlannedSlice omitted — ollama-agent manages its own task queue
36
+ localOnly: process.env.RALPH_LOCAL === '1',
36
37
  }).catch((err) => {
37
38
  console.error('[ralph] Fatal:', err);
38
39
  process.exit(1);
@@ -21,7 +21,10 @@ BACKEND_PROMPT_FILE="$KIT_DIR/lib/backend-prompt.md"
21
21
  AGENT_SCRIPT="$KIT_DIR/lib/agent.sh"
22
22
 
23
23
  HAS_CREDENTIALS=true
24
- if [[ ! -f "$KIT_DIR/.eventmodelers/config.json" ]]; then
24
+ if [[ "${RALPH_LOCAL:-}" == "1" ]]; then
25
+ echo "[ralph] --local — platform sync disabled." >&2
26
+ HAS_CREDENTIALS=false
27
+ elif [[ ! -f "$KIT_DIR/.eventmodelers/config.json" ]]; then
25
28
  echo "[ralph] Note: no .eventmodelers/config.json found — platform sync disabled." >&2
26
29
  echo " To enable board sync, follow: https://app.eventmodelers.ai/documentation#build" >&2
27
30
  echo " Code generation from local slice definitions will still run." >&2