* refactor(repo): monorepo groundwork for an easier first run Trying OMA for the first time costs more than it should: a lot to read before anything runs, and no one-command way to watch a team actually work. The plan is to fix that with a `npm create oma` scaffold (a multi-agent demo that runs on the first try) and an npm README that leads with getting started. Neither lands cleanly until core lives in its own package, so this PR does that part first. This is groundwork, not the payoff: nothing changes for anyone installing `@open-multi-agent/core` today. It turns the repo into an npm-workspaces monorepo with core in `packages/core/`, and splits the README into a GitHub landing page (root) and the npm package page (`packages/core/`). Doing it now, while the repo is small, avoids migrating twice. The published package is byte-identical: same name, same three runtime dependencies, same entry points, guarded by an isolated-install smoke test. `npm ci` + lint + test (1060) + build pass; the tarball still ships only `dist/`, `README.md`, `LICENSE`, and `package.json`. * build: restore cross-platform optional deps in package-lock.json Regenerating the lockfile on macOS pruned the non-host rollup/esbuild optional binaries (npm/cli#4828), so Linux CI could not load @rollup/rollup-linux-x64-gnu and vitest failed to start. Rebuild the lock from the pre-migration base so every platform variant is present again. Verified with npm ci + lint + build + test (1060). * fix(examples,docs): correct monorepo paths and anchors after the packages/core move with-vercel-ai-sdk example (pre-existing, surfaced by the move): - package.json: the @open-multi-agent/core file: link was file:../../, which resolves to packages/core/examples (no manifest). Corrected to file:../../.. (packages/core); predev cd updated to match. - package-lock.json regenerated: was linking ../.. and pinning a stale core 1.4.0; now links ../../.. at 1.7.0. - README: setup paths and the file: note updated. docs missed by the move: - docs/cli.md: repo-clone build output is now packages/core/dist/cli/oma.js; the quick-start anchor now lives in the package README. - CONTRIBUTING.md: the architecture anchor and src/ entry-point paths now live under packages/core/.
10 KiB
Command-line interface (oma)
The package ships a small binary oma that exposes the same primitives as the TypeScript API: runTeam, runTasks, plus a static provider reference. It is meant for shell scripts and CI (JSON on stdout, stable exit codes).
It does not provide an interactive REPL, working-directory injection into tools, human approval gates, or session persistence. Those stay in application code.
Installation and invocation
After installing the package, the binary is on PATH when using npx or a local node_modules/.bin:
npm install @open-multi-agent/core
npx oma help
From a clone of the repository you need a build first:
npm run build
node packages/core/dist/cli/oma.js help
Set the usual provider API keys in the environment (see README); the CLI does not read secrets from flags. MiniMax additionally reads MINIMAX_BASE_URL to select the global (https://api.minimax.io/v1) or China (https://api.minimaxi.com/v1) endpoint. MiMo additionally reads MIMO_BASE_URL for Token Plan cluster endpoints such as https://token-plan-cn.xiaomimimo.com/v1.
OpenRouter works through the OpenAI-compatible adapter: set provider to openai, baseURL to https://openrouter.ai/api/v1, and pass OPENROUTER_API_KEY as the agent or orchestrator apiKey.
Commands
oma run
Runs OpenMultiAgent.runTeam(team, goal): coordinator decomposition, task queue, optional synthesis.
When invoked with --dashboard, the oma CLI writes a static post-execution DAG dashboard HTML to oma-dashboards/runTeam-<timestamp>.html under the current working directory (the library does not write files itself; if you want this outside the CLI, call renderTeamRunDashboard(result) in application code — see packages/core/src/dashboard/render-team-run-dashboard.ts).
The dashboard page is self-contained: it does not load remote scripts, stylesheets, or fonts, and sensitive-looking values in the embedded run payload are redacted before rendering.
| Argument | Required | Description |
|---|---|---|
--goal |
Yes | Natural-language goal passed to the team run. |
--team |
Yes | Path to JSON (see Team file). |
--orchestrator |
No | Path to JSON merged into new OpenMultiAgent(...) after any orchestrator fragment from the team file. |
--coordinator |
No | Path to JSON passed as runTeam(..., { coordinator }) (CoordinatorConfig). |
--dashboard |
No | Write a post-execution DAG dashboard HTML to oma-dashboards/runTeam-<timestamp>.html. |
Global flags: --pretty, --include-messages.
oma task
Runs OpenMultiAgent.runTasks(team, tasks) with a fixed task list (no coordinator decomposition).
| Argument | Required | Description |
|---|---|---|
--file |
Yes | Path to tasks file. |
--team |
No | Path to JSON TeamConfig. When set, overrides the team object inside --file. |
Global flags: --pretty, --include-messages.
oma provider
Read-only helper for wiring JSON configs and env vars.
oma provideroroma provider list— Prints JSON: built-in provider ids, API key environment variable names, whetherbaseURLis supported, and short notes (e.g. OpenAI-compatible servers, Copilot in CI).oma provider template <provider>— Prints a JSON object with exampleorchestratorandagentfields plus placeholderenventries.<provider>is one of:anthropic,azure-openai,openai,gemini,grok,minimax,mimo,deepseek,doubao,qiniu,copilot,bedrock.
For OpenRouter, use the openai provider template, set baseURL to https://openrouter.ai/api/v1, and set apiKey from OPENROUTER_API_KEY in your JSON config.
Supports --pretty.
oma, oma help, oma -h, oma --help
Prints usage text to stdout and exits 0.
Configuration files
Shapes match the library types TeamConfig, OrchestratorConfig, CoordinatorConfig, and the task objects accepted by runTasks().
Team file
Used with oma run --team (and optionally oma task --team).
Option A — plain TeamConfig
{
"name": "api-team",
"agents": [
{
"name": "architect",
"model": "claude-sonnet-4-6",
"provider": "anthropic",
"systemPrompt": "You design APIs.",
"tools": ["file_read", "file_write"],
"maxTurns": 6
}
],
"sharedMemory": true
}
Option B — team plus default orchestrator settings
{
"team": {
"name": "api-team",
"agents": [{ "name": "worker", "model": "claude-sonnet-4-6", "systemPrompt": "…" }]
},
"orchestrator": {
"defaultModel": "claude-sonnet-4-6",
"defaultProvider": "anthropic",
"maxConcurrency": 3
}
}
Validation rules enforced by the CLI:
- Root (or
team) must be an object. team.nameis a non-empty string.team.agentsis a non-empty array; each agent must have non-emptynameandmodel.
Any other fields are passed through to the library as in TypeScript.
SDK-only fields: sharedMemoryStore (custom MemoryStore instance) cannot be set from JSON since it is a runtime object. Use sharedMemory: true for the default in-memory store, or wire a custom store in TypeScript via orchestrator.createTeam().
Tasks file
Used with oma task --file.
{
"orchestrator": {
"defaultModel": "claude-sonnet-4-6"
},
"team": {
"name": "pipeline",
"agents": [
{ "name": "designer", "model": "claude-sonnet-4-6", "systemPrompt": "…" },
{ "name": "builder", "model": "claude-sonnet-4-6", "systemPrompt": "…" }
],
"sharedMemory": true
},
"tasks": [
{
"title": "Design",
"description": "Produce a short spec for the feature.",
"assignee": "designer"
},
{
"title": "Implement",
"description": "Implement from the design.",
"assignee": "builder",
"dependsOn": ["Design"]
}
]
}
dependsOn— Task titles (not internal ids), same convention as the coordinator output in the library.- Optional per-task fields:
memoryScope("dependencies"|"all"),maxRetries,retryDelayMs,retryBackoff. tasksmust be a non-empty array; each item needs stringtitleanddescription.
If --team path.json is passed, the file’s top-level team property is ignored and the external file is used instead (useful when the same team definition is shared across several pipeline files).
Orchestrator and coordinator JSON
These files are arbitrary JSON objects merged into OrchestratorConfig and CoordinatorConfig. Function-valued options (onProgress, onApproval, etc.) cannot appear in JSON and are not supported by the CLI.
Set defaultCwd on the orchestrator JSON, or cwd on individual agents/coordinator JSON, to choose the sandbox root for built-in filesystem tools. Paths passed to file_read, file_write, file_edit, grep, and glob must be absolute and resolve inside that root. When defaultCwd is omitted, the sandbox defaults to <cwd>/.agent-workspace (auto-created on first write). Pass the string "<process.cwd()>"-equivalent absolute path to widen it to the full working directory, or null to disable the sandbox. The bash tool is intentionally not covered — see docs/tool-configuration.md for the rationale and recommended posture.
Output
Stdout
Every invocation prints one JSON document to stdout, followed by a newline.
Successful run / task
{
"command": "run",
"success": true,
"goal": "Build a REST API with token auth",
"tasks": [
{
"id": "task-1",
"title": "Design the database schema",
"assignee": "architect",
"status": "completed",
"dependsOn": []
}
],
"totalTokenUsage": { "input_tokens": 0, "output_tokens": 0 },
"agentResults": {
"architect": {
"success": true,
"output": "…",
"tokenUsage": { "input_tokens": 0, "output_tokens": 0 },
"toolCalls": [],
"structured": null,
"loopDetected": false,
"budgetExceeded": false
}
}
}
agentResults keys are agent names. When an agent ran multiple tasks, the library merges results; the CLI mirrors the merged AgentRunResult fields.
Errors (usage, validation, I/O, runtime)
{
"error": {
"kind": "usage",
"message": "--goal and --team are required"
}
}
kind is one of: usage, validation, io, runtime, or internal (uncaught errors in the outer handler).
Output flags
| Flag | Effect |
|---|---|
--pretty |
Pretty-print JSON with indentation. |
--include-messages |
Include each agent’s full messages array in agentResults. Very large for long runs; default is omit. |
There is no separate progress stream; for rich telemetry use the TypeScript API with onProgress / onTrace.
Exit codes
| Code | Meaning |
|---|---|
| 0 | Success: run/task finished with success === true, or help / provider completed normally. |
| 1 | Run finished but success === false (agent or task failure as reported by the library). |
| 2 | Usage, validation, readable JSON errors, or file access issues (e.g. missing file). |
| 3 | Unexpected error, including typical LLM/API failures surfaced as thrown errors. |
In scripts:
npx oma run --goal "Summarize README" --team team.json > result.json
code=$?
case $code in
0) echo "OK" ;;
1) echo "Run reported failure — inspect result.json" ;;
2) echo "Bad inputs or files" ;;
3) echo "Crash or API error" ;;
esac
Argument parsing
- Long options only:
--goal,--team,--file, etc. - Values may be attached with
=:--team=./team.json. - Boolean-style flags (
--pretty,--include-messages) take no value; if the next token does not start with--, it is treated as the value of the previous option (standardgetopt-style pairing).
Limitations (by design)
- No TTY session, history, or
stdingoal input. - No dedicated flag for the filesystem sandbox root; configure it through
defaultCwd/cwdin the orchestrator or agent JSON. - No
onApprovalfrom JSON; non-interactive batch only. - Coordinator
runTeampath still requires network and API keys like any other run.