@eventmodelers/cli 1.0.96 → 1.0.97
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 +27 -3
- package/cli.js +55 -2
- package/package.json +1 -1
- package/shared/build-kit/README.md +11 -1
package/README.md
CHANGED
|
@@ -128,7 +128,8 @@ npx @eventmodelers/cli init --stack <name> --demo # same, plus a ready-made de
|
|
|
128
128
|
npx @eventmodelers/cli re-init # refresh an already-installed kit's scripts/skills only — never touches the root scaffold
|
|
129
129
|
npx @eventmodelers/cli run # start the agent loop (ralph-claude.js) from the installed kit dir
|
|
130
130
|
npx @eventmodelers/cli run --local-ai [target] # board work only via a local/self-hosted model (ralph-local-ai.js) — does NOT build slices; build locally with --exec
|
|
131
|
-
npx @eventmodelers/cli run --
|
|
131
|
+
npx @eventmodelers/cli run --agent <name> # pick the agent: claude (default), opencode, codex, gemini — bare --agent lists them with their exact commands
|
|
132
|
+
npx @eventmodelers/cli run --exec "<command>" # manual fallback for any other harness (ralph-exec.js) — agent tracing needs its JSON flag, e.g. "codex exec --json --full-auto"
|
|
132
133
|
npx @eventmodelers/cli run --bash # bash-only loop, no realtime (ralph.sh)
|
|
133
134
|
npx @eventmodelers/cli run --local # skip platform config/credential lookup entirely — local-only, no board sync
|
|
134
135
|
npx @eventmodelers/cli run --modeling # modeling-kit: warm Claude process driven by the board's prompt queue
|
|
@@ -191,8 +192,31 @@ npx @eventmodelers/cli run --modeling # react to prompts sent to t
|
|
|
191
192
|
npx @eventmodelers/cli run --standalone # …and to board changes, on its own initiative
|
|
192
193
|
```
|
|
193
194
|
|
|
194
|
-
`--standalone` implies `--modeling`, so you never need both.
|
|
195
|
-
|
|
195
|
+
`--standalone` implies `--modeling`, so you never need both.
|
|
196
|
+
|
|
197
|
+
**Another coding agent.** `--agent` hands each prompt and chat message to another harness
|
|
198
|
+
instead of the warm Claude process — one process per turn, with the eventmodelers MCP server
|
|
199
|
+
registered for it (`opencode.json`, `.gemini/settings.json`, or `-c` flags for Codex):
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
npx @eventmodelers/cli run --standalone --agent opencode # = --exec "opencode run"
|
|
203
|
+
npx @eventmodelers/cli run --modeling --agent codex # = --exec "codex exec --full-auto"
|
|
204
|
+
npx @eventmodelers/cli run --modeling --agent gemini # = --exec "gemini --yolo -p"
|
|
205
|
+
npx @eventmodelers/cli run --modeling --agent claude # the default, spelled out
|
|
206
|
+
npx @eventmodelers/cli run --agent # list the agents and the command each runs
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
`--agent` is only a shortcut: to run a harness it does not know, or the same one with other
|
|
210
|
+
flags, pass the command yourself with `--exec "<command>"`. Keep the harness in its plain-text
|
|
211
|
+
output mode — its stdout is the turn's answer. For an unknown command the loop logs the MCP
|
|
212
|
+
server to register by hand (`<baseUrl>/mcp`, header `x-token` from `$EVENTMODELERS_TOKEN`).
|
|
213
|
+
Run `init-agents --hosts <harness>` to install the skills for a harness that does not read
|
|
214
|
+
`.claude/skills`. There are no subagents: self-directed work is done inline.
|
|
215
|
+
|
|
216
|
+
`--agent`, `--exec`, `--local-ai` and `--bash` each pick the runner, so pass at most one of them —
|
|
217
|
+
any two together are rejected. For a local or self-hosted model use `--local-ai`, not `--agent`.
|
|
218
|
+
|
|
219
|
+
To drive either one with a local model instead of Claude, see [Running the modeling agent on a local model](#running-the-modeling-agent-on-a-local-model).
|
|
196
220
|
|
|
197
221
|
**No install required.** A modeling agent never touches the directory it was started from —
|
|
198
222
|
it works against the board over MCP/REST — so it doesn't need a kit scaffolded there. When
|
package/cli.js
CHANGED
|
@@ -67,6 +67,55 @@ function resolveLocalAiTarget(opts) {
|
|
|
67
67
|
return raw;
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
+
// --- --agent: named shortcuts for --exec ---------------------------------------
|
|
71
|
+
// `run --agent opencode` is exactly `run --exec "<preset>"` — the harness command spelled out
|
|
72
|
+
// once here, so nobody has to remember its headless flags. The two loops want different output
|
|
73
|
+
// from the same harness: the modeling loop reads a turn's answer from plain-text stdout, while a
|
|
74
|
+
// build kit wants the JSON mode, the only one that reports the usage agent tracing records.
|
|
75
|
+
// claude has no command — it is the default runner, named so it can be picked explicitly.
|
|
76
|
+
// --exec stays the fallback for any harness or flag set not listed here.
|
|
77
|
+
const AGENT_PRESETS = {
|
|
78
|
+
claude: null,
|
|
79
|
+
opencode: { modeling: 'opencode run', build: 'opencode run --auto --format json' },
|
|
80
|
+
codex: { modeling: 'codex exec --full-auto', build: 'codex exec --json --full-auto' },
|
|
81
|
+
gemini: { modeling: 'gemini --yolo -p', build: 'gemini --yolo --output-format stream-json -p' },
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
function printAgentPresets() {
|
|
85
|
+
console.log('Supported agents for run --agent <name>:\n');
|
|
86
|
+
for (const [name, preset] of Object.entries(AGENT_PRESETS)) {
|
|
87
|
+
console.log(` ${name.padEnd(9)}${preset ? `modeling: ${preset.modeling}\n ${''.padEnd(9)}build: ${preset.build}` : 'the default runner (warm Claude process / ralph-claude.js)'}`);
|
|
88
|
+
}
|
|
89
|
+
console.log('\nAny other harness: run --exec "<command>".');
|
|
90
|
+
console.log(`A local or self-hosted model: run --local-ai [${LOCAL_AI_TARGETS.join('|')}].`);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Resolves --agent into the --exec command it stands for, or null for the default Claude runner.
|
|
94
|
+
// Bare --agent lists the presets and stops.
|
|
95
|
+
function resolveAgentPreset(opts, loop) {
|
|
96
|
+
if (opts.agent === undefined) return null;
|
|
97
|
+
if (opts.agent === true) {
|
|
98
|
+
printAgentPresets();
|
|
99
|
+
process.exit(0);
|
|
100
|
+
}
|
|
101
|
+
const name = String(opts.agent).toLowerCase();
|
|
102
|
+
if (!(name in AGENT_PRESETS)) {
|
|
103
|
+
console.error(`❌ Unknown --agent "${opts.agent}" — one of: ${Object.keys(AGENT_PRESETS).join(', ')}.`);
|
|
104
|
+
console.error(' Any other harness works via --exec "<command>".');
|
|
105
|
+
console.error(` A local or self-hosted model works via --local-ai [${LOCAL_AI_TARGETS.join('|')}].`);
|
|
106
|
+
process.exit(1);
|
|
107
|
+
}
|
|
108
|
+
if (opts.exec) {
|
|
109
|
+
console.error('❌ --agent and --exec are mutually exclusive — --agent is a shortcut for --exec.');
|
|
110
|
+
process.exit(1);
|
|
111
|
+
}
|
|
112
|
+
if (resolveLocalAiTarget(opts) !== null || opts.bash) {
|
|
113
|
+
console.error('❌ --agent is mutually exclusive with --local-ai/--bash — pick one runner.');
|
|
114
|
+
process.exit(1);
|
|
115
|
+
}
|
|
116
|
+
return AGENT_PRESETS[name]?.[loop] ?? null;
|
|
117
|
+
}
|
|
118
|
+
|
|
70
119
|
const STACKS = {
|
|
71
120
|
node: {
|
|
72
121
|
label: 'Node.js / TypeScript',
|
|
@@ -3513,9 +3562,10 @@ credentialFlags(program
|
|
|
3513
3562
|
.command('run')
|
|
3514
3563
|
.description('Start the agent loop from the installed kit dir — build-kit stacks: ralph-claude.js (default); modeling-kit: --modeling, or --standalone, which needs no install at all')
|
|
3515
3564
|
.option('--local-ai [target]', `Drive the loop with a local (or self-hosted) model instead of the default Claude runner: a build kit runs it via ralph-local-ai.js, and --modeling/--standalone via lib/modeling-local-ai.js (board tools over MCP, but no skills and no subagent fan-out — those are Claude Code features). Optional target preset picks the URL and wire dialect: ${LOCAL_AI_TARGETS.join(', ')} — bare --local-ai means ollama. Anything OpenAI-compatible (vLLM, LM Studio, llama.cpp, TGI) works by pointing LOCAL_AI_URL at it; see LOCAL_AI_* in the docs. Board work only: --local-ai never builds a Planned slice (no file, shell or git tools). To build code with a local model, use --exec with a coding harness pointed at it, e.g. "codex exec --oss --full-auto". Claude remains the default when this flag is absent.`)
|
|
3516
|
-
.option('--
|
|
3565
|
+
.option('--agent [name]', `Pick the agent that does the work by name: ${Object.keys(AGENT_PRESETS).join(', ')}. claude is the default runner; any other is a shortcut for --exec with that harness's headless command filled in — plain-text output for --modeling/--standalone/--worker, JSON output (for agent tracing) for a build kit. Bare --agent lists the agents and the exact command each runs, then stops. Mutually exclusive with --exec, --local-ai and --bash.`)
|
|
3566
|
+
.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.')
|
|
3517
3567
|
.option('--bash', 'Use the bash-only ralph.sh loop (build-kit stacks only, no realtime)')
|
|
3518
|
-
.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; --local-ai or --exec
|
|
3568
|
+
.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.')
|
|
3519
3569
|
.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).')
|
|
3520
3570
|
.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.')
|
|
3521
3571
|
.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')
|
|
@@ -3534,6 +3584,9 @@ credentialFlags(program
|
|
|
3534
3584
|
// should fail on the spot, not once the loop is already up — and a cap passed where
|
|
3535
3585
|
// nothing will read it is worth saying out loud rather than ignoring silently.
|
|
3536
3586
|
const maxAgents = parseMaxAgents(opts.maxAgents);
|
|
3587
|
+
// --agent is --exec with the command filled in for the loop this run picks.
|
|
3588
|
+
const agentExec = resolveAgentPreset(opts, (opts.modeling || opts.standalone || opts.worker || opts.global) ? 'modeling' : 'build');
|
|
3589
|
+
if (agentExec) opts.exec = agentExec;
|
|
3537
3590
|
if (command.getOptionValueSource('maxAgents') === 'cli' && !opts.standalone) {
|
|
3538
3591
|
console.log('ℹ️ --max-agents only applies to --standalone turns; ignoring it here.');
|
|
3539
3592
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eventmodelers/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.97",
|
|
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": {
|
|
@@ -121,7 +121,17 @@ llama.cpp `-c 32768`); an overflow there surfaces as an HTTP 400.
|
|
|
121
121
|
|
|
122
122
|
Agentic harnesses that bring their own tool loop — Codex CLI, OpenCode, Gemini CLI —
|
|
123
123
|
are not `--local-ai` targets: `--local-ai` *supplies* the agent loop, while a harness
|
|
124
|
-
already is one and only wants a prompt. They go through `ralph-exec.js` instead
|
|
124
|
+
already is one and only wants a prompt. They go through `ralph-exec.js` instead. The
|
|
125
|
+
known ones have a shortcut that fills in the command, JSON flag for agent tracing included
|
|
126
|
+
(bare `--agent` lists them):
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
npx @eventmodelers/cli run --agent opencode # = --exec "opencode run --auto --format json"
|
|
130
|
+
npx @eventmodelers/cli run --agent codex # = --exec "codex exec --json --full-auto"
|
|
131
|
+
npx @eventmodelers/cli run --agent gemini # = --exec "gemini --yolo --output-format stream-json -p"
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
`--exec` is the manual fallback: any other harness, or one of these with other flags:
|
|
125
135
|
|
|
126
136
|
```bash
|
|
127
137
|
npx @eventmodelers/cli run --exec "codex exec --full-auto"
|