{"id":50248598,"url":"https://github.com/jigjoy-ai/baro","last_synced_at":"2026-06-06T15:01:29.887Z","repository":{"id":349365753,"uuid":"1188682315","full_name":"jigjoy-ai/baro","owner":"jigjoy-ai","description":"CLI that turns a goal into a pull request. Parallel AI coding agents on a Mozaik event bus.","archived":false,"fork":false,"pushed_at":"2026-06-03T12:05:35.000Z","size":3034,"stargazers_count":56,"open_issues_count":3,"forks_count":3,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-03T12:20:25.378Z","etag":null,"topics":["agentic-coding","ai-coding-agent","ai-developer-tools","claude-code","cli","coding-agent","mozaik","mozaik-native","multi-agent-system","parallel-agents","pull-request-automation","reactive-agents"],"latest_commit_sha":null,"homepage":"https://baro.rs","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jigjoy-ai.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-22T12:45:48.000Z","updated_at":"2026-06-03T05:33:02.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/jigjoy-ai/baro","commit_stats":null,"previous_names":["lotus015/baro","jigjoy-ai/baro"],"tags_count":109,"template":false,"template_full_name":null,"purl":"pkg:github/jigjoy-ai/baro","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jigjoy-ai%2Fbaro","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jigjoy-ai%2Fbaro/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jigjoy-ai%2Fbaro/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jigjoy-ai%2Fbaro/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jigjoy-ai","download_url":"https://codeload.github.com/jigjoy-ai/baro/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jigjoy-ai%2Fbaro/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33986901,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-06T02:00:07.033Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agentic-coding","ai-coding-agent","ai-developer-tools","claude-code","cli","coding-agent","mozaik","mozaik-native","multi-agent-system","parallel-agents","pull-request-automation","reactive-agents"],"created_at":"2026-05-27T00:05:12.787Z","updated_at":"2026-06-06T15:01:29.880Z","avatar_url":"https://github.com/jigjoy-ai.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# baro\n\n\u003e Type a goal in your repo. Walk away. Come back to a pull request.\n\n![npm downloads](https://img.shields.io/npm/dt/baro-ai) ![npm downloads weekly](https://img.shields.io/npm/dw/baro-ai) ![npm version](https://img.shields.io/npm/v/baro-ai)\n\n```bash\nnpm install -g baro-ai\n```\n\n![baro TUI at the end of a real run — 33 of 33 stories complete on a NestJS service, 2.2× parallel speedup, 32 files modified, PR opened](https://raw.githubusercontent.com/jigjoy-ai/baro/main/assets/screenshot.png)\n\n\u003csub\u003ebaro TUI at the end of an [actual run](https://jigjoy.ai/blog/baro-808-nestjs-jest-tests) — one prompt → 33-story DAG → 32 files modified → PR opened. The summary panel shows wall time (33:23), parallel speedup (2.2×), token usage, and the PR URL.\u003c/sub\u003e\n\n## Parallel coding agents, no central coordinator\n\nMost multi-agent setups have one orchestrator function in the middle that drives N agents. The orchestrator becomes the bottleneck the moment you push past a handful of concurrent agents — and adding a new behaviour means editing its control flow.\n\nbaro doesn't have that shape. Every part of the run is an independent **participant** on a shared event bus ([Mozaik](https://github.com/jigjoy-ai/mozaik)). N parallel story agents are N independent subprocesses, each emitting and consuming typed events. There is no central `run()` to bottleneck on, and adding a new behaviour is a new participant — not an orchestrator rewrite.\n\n```mermaid\nflowchart LR\n    subgraph A[\"Typical multi-agent orchestrator\"]\n        direction TB\n        C{{Coordinator}}\n        C --\u003e A1[Agent 1]\n        C --\u003e A2[Agent 2]\n        C --\u003e A3[Agent N]\n    end\n    subgraph B[\"baro on Mozaik\"]\n        direction TB\n        Bus[(shared event bus)]\n        P1[Conductor] -.-\u003e Bus\n        P2[Story Agent 1] -.-\u003e Bus\n        P3[Story Agent N] -.-\u003e Bus\n        P4[Critic / Surgeon / ...] -.-\u003e Bus\n    end\n```\n\nThat's the architectural lever. Everything else baro does — Architect, Planner, Critic, Surgeon, Librarian — is a participant on that bus. They don't call each other; they react to events.\n\n## What a run looks like\n\n```bash\ncd your-repo\nbaro \"Add JWT authentication with role-based access control\"\n```\n\n```\n→ Architect (45s)   — design decisions pinned for every story\n→ Planner   (38s)   — 7 stories in 3 levels\n→ Executing — 4 parallel Claude Code agents on baro/jwt-auth branch\n→ Critic    — per-turn acceptance evaluation, self-corrects on fail\n→ Finalizer — PR #142 opened ✓\n```\n\n```mermaid\nflowchart LR\n    Goal([your goal]) --\u003e A[Architect\u003cbr/\u003e\u003csub\u003e~45s — emits\u003cbr/\u003eDecisionDocument\u003c/sub\u003e]\n    A --\u003e P[Planner\u003cbr/\u003e\u003csub\u003e~60s — emits DAG\u003c/sub\u003e]\n    P --\u003e S1[Story 1]\n    P --\u003e S2[Story 2]\n    P --\u003e S3[Story 3]\n    S1 --\u003e S4[Story 4]\n    S2 --\u003e S4\n    S3 --\u003e S5[Story 5]\n    S4 --\u003e F[Finalizer\u003cbr/\u003e\u003csub\u003eopens PR\u003c/sub\u003e]\n    S5 --\u003e F\n    F --\u003e PR([Pull Request])\n```\n\nEvery story is one CLI subprocess — Claude Code, OpenAI Codex CLI, OpenCode, or a Mozaik-native OpenAI Responses session, depending on `--llm`. Auth inherits from whichever CLI you already have signed in, no API key plumbing.\n\n## Four LLM backends, one DAG\n\n```bash\nbaro --llm claude    \"Your goal\"   # default — Claude Code on Anthropic Max subscription\nbaro --llm codex     \"Your goal\"   # OpenAI Codex CLI on ChatGPT Pro/Plus subscription\nbaro --llm openai    \"Your goal\"   # Mozaik-native OpenAI Responses (per-call API billing)\nbaro --llm opencode  \"Your goal\"   # OpenCode CLI — multi-provider agent shell (any model)\nbaro --llm hybrid    \"Your goal\"   # Claude on Architect/Planner/Surgeon, Codex on Story/Critic\n```\n\nSame orchestration. Same DAG. Same prompts. The only thing that moves is which provider every agent talks to. `--llm hybrid` is the new default-recommendation for serious runs — Claude where the upstream plan matters, Codex for the parallel story+critic work that dominates the budget.\n\nEach phase has its own override flag if you want to mix it yourself:\n\n```bash\nbaro --architect-llm claude   \\\n     --planner-llm  claude   \\\n     --story-llm    opencode \\\n     --critic-llm   codex    \\\n     --surgeon-llm  claude   \\\n     \"Your goal\"\n```\n\n### Custom OpenAI-compatible endpoints\n\nAny provider that exposes an OpenAI-compatible Chat Completions API works with `--llm openai`. Set `OPENAI_BASE_URL` to point at your endpoint and pass any model name via `--story-model` (or let it use the default):\n\n```bash\n# Xiaomi MiMo\nOPENAI_API_KEY=your-key OPENAI_BASE_URL=https://api.mimo.xiaomi.com/v1 \\\n  baro --llm openai --story-model MiMo-7B-RL \"Your goal\"\n\n# OpenRouter (any model)\nOPENAI_API_KEY=your-key OPENAI_BASE_URL=https://openrouter.ai/api/v1 \\\n  baro --llm openai --story-model anthropic/claude-3.5-sonnet \"Your goal\"\n\n# Local vLLM / Ollama\nOPENAI_API_KEY=not-needed OPENAI_BASE_URL=http://localhost:11434/v1 \\\n  baro --llm openai --story-model llama3 \"Your goal\"\n```\n\nThe `--openai-base-url` flag also works (wins over the env var when both are set).\n\n### OpenCode (multi-provider agent shell)\n\n[OpenCode](https://opencode.ai) is an open-source coding agent that supports any LLM provider. With `--llm opencode`, baro delegates story execution to the `opencode` CLI. Model selection uses the `-m provider/model` format:\n\n```bash\n# OpenCode with Anthropic Claude\nbaro --llm opencode -m anthropic/claude-sonnet-4 \"Your goal\"\n\n# OpenCode with OpenAI\nbaro --llm opencode -m openai/gpt-4o \"Your goal\"\n\n# OpenCode with a local model (LM Studio, Ollama, etc.)\nbaro --llm opencode -m lmstudio/qwen3-coder \"Your goal\"\n\n# Mix: Claude plans, OpenCode executes stories.\n# Note: `-m` is a GLOBAL override applied to every phase, so it can't be\n# combined with a Claude/OpenCode split (a provider/model string would be\n# handed to the Claude phases too, which only accept opus/sonnet/haiku).\n# Let OpenCode pick its configured default for the story phase instead.\nbaro --architect-llm claude --planner-llm claude \\\n     --story-llm opencode \"Your goal\"\n```\n\nOpenCode manages its own API keys and per-provider model defaults via `opencode providers` — no additional env vars needed for baro, and no `-m` required when you're happy with the OpenCode default. `-m provider/model` sets the model for **all** phases at once, so use it only when every phase runs on a non-Claude backend (e.g. `--llm opencode`). Runs with `--dangerously-skip-permissions` for unattended execution in baro's per-story worktrees.\n\nFull breakdown at [docs.baro.rs/llm-providers](https://docs.baro.rs/llm-providers) — provider economics, per-phase routing, the side-by-side benchmark across three real tasks: [**I tested Claude Code vs OpenAI Codex in my parallel agent setup. Then I built a hybrid.**](https://jigjoy.ai/blog/claude-code-vs-codex-baro)\n\n### Per-story model tiering (mixed fleet)\n\n`--llm` / `--story-llm` pick a backend per *phase* — every story runs on the same one. With `--tier-map` you tier per *story* instead: the Planner tags each story with a blast-radius tier (`haiku` = mechanical/self-contained, `sonnet` = one contained module, `opus` = cross-cutting / schema / a DAG hub — \"what breaks if an agent gets this wrong?\"), and the tier map binds each tier to a concrete `backend:model`. One DAG, several backends, chosen by risk:\n\n```bash\n# Cheap single-concern stories on MiniMax, cross-cutting stories on Claude Opus\nbaro --openai-endpoint minimax=https://api.minimax.io/v1 \\\n     --tier-map \"haiku=openai:MiniMax-M3@minimax,sonnet=openai:MiniMax-M3@minimax,opus=claude:opus\" \\\n     \"Your goal\"\n```\n\nA story's route can name **any** backend (`claude:opus`, `openai:MiniMax-M3`, `codex:gpt-5.5`) and an OpenAI route can name its **own endpoint** with `@` — a registered name (`--openai-endpoint name=url`, repeatable) or an inline `@https://…` URL — so a single run can hit several OpenAI-compatible endpoints at once (e.g. MiniMax + real OpenAI). API keys are never put on the command line: each endpoint resolves its key from `BARO_OPENAI_KEY_\u003cNAME\u003e`, falling back to `OPENAI_API_KEY`. When the Surgeon splits a failed story, it tiers the pieces and escalates a tier up for any same-scope replacement (one attempt at that tier already burned out). Without `--tier-map`, per-story tiers resolve on the phase backend exactly as before.\n\n## Recent real run\n\n[**How baro generated 808 NestJS Jest tests autonomously in 71 minutes**](https://jigjoy.ai/blog/baro-808-nestjs-jest-tests) — one prompt, 33-story DAG, two sessions because of the Anthropic 3am usage cap, 64 test suites, 83.5% branch coverage, +13,606 lines of test code, zero phantom bug issues filed.\n\n## What each participant does\n\n| Participant | Role |\n|---|---|\n| **Architect** | One Opus call before planning — emits a `DecisionDocument` that pins every cross-cutting design decision (file paths, schemas, API shapes, library choices) so 30 parallel agents don't each invent their own |\n| **Planner** | Decomposes the goal into a story DAG, with the DecisionDocument already pinned |\n| **Conductor** | State machine that drives the run by reacting to bus events |\n| **StoryAgent** | One CLI subprocess per story (Claude Code / Codex / OpenCode / OpenAI Responses, picked by `--llm` or `--story-llm`); multi-turn loop until story completes |\n| **Critic** | Per-turn evaluator (Haiku). On fail verdict, injects corrective feedback as the agent's next turn |\n| **Sentry** | Flags overlapping Edit/Write tool calls across concurrent stories |\n| **Librarian** | Indexes one agent's Read/Grep findings so siblings don't redo the exploration |\n| **Surgeon** | On terminal failure, asks Opus for a richer replan (split / prereq / rewire) |\n| **Finalizer** | Runs build verification, opens the GitHub PR with stories table + stats |\n\nBus is open. CI deployers, Slack notifiers, ticket triggers — all new participants, no orchestrator changes. Architecture deep-dive: [I tested Claude Code's new /goal feature against my parallel agent setup](https://jigjoy.ai/blog/baro-vs-claude-code).\n\n## Semantic memory (new)\n\nbaro now includes **semantic memory** for cross-agent context sharing within a session. Instead of tag-based matching, agents use ONNX embeddings (CPU-only) to find semantically similar discoveries.\n\n**How it works:**\n- When Agent A reads a file, the content is cached and embedded\n- When Agent B asks for context, semantic search finds relevant discoveries\n- File reads are cached — if Agent B needs the same file, it's served from memory\n\n**Token savings:** ~50% fewer findings injected (only semantically relevant ones)\n\n**Disable with:** `baro --no-memory \"goal\"` (falls back to tag-based Librarian)\n\n## Try it\n\n```bash\nnpm install -g baro-ai\n\n# Full run (default — Claude on every phase via Claude Code CLI)\nbaro \"Migrate the hardcoded category data to a backend dictionary\"\n\n# Trivial goal — skip Architect + Critic + Surgeon, single story\nbaro --quick \"fix the typo on line 42 of README.md\"\n\n# Codex everywhere (ChatGPT Pro/Plus subscription, ~3-11× cheaper per run than Claude)\nbaro --llm codex \"Refactor the database layer\"\n\n# Per-phase routing — Claude upstream (tight plans), Codex downstream (cheap writes)\nbaro --llm hybrid \"Add WebSocket support across api and frontend\"\n\n# Route every phase through GPT-5.5 (Mozaik-native OpenAI API)\nOPENAI_API_KEY=sk-... baro --llm openai \"Refactor the database layer\"\n\n# Route through any OpenAI-compatible endpoint (Xiaomi MiMo, OpenRouter, vLLM, Ollama, etc.)\nOPENAI_API_KEY=your-key OPENAI_BASE_URL=https://api.mimo.xiaomi.com/v1 baro --llm openai \"Refactor the database layer\"\n\n# Or use the CLI flag (flag wins over env var)\nOPENAI_API_KEY=your-key baro --llm openai --openai-base-url https://api.mimo.xiaomi.com/v1 \"Refactor the database layer\"\n\n# Limit parallelism (plan-tier concurrency caps)\nbaro --parallel 3 \"Add unit tests for the auth module\"\n\n# Dry-run first, execute later\nbaro --dry-run \"Add WebSocket support\"\nbaro --resume\n\n# Self-diagnostic\nbaro --doctor\n```\n\nFull options + `.barorc` config + per-phase model overrides: [**docs.baro.rs**](https://docs.baro.rs).\n\n## How it compares\n\n| | Single Claude Code session | DIY `Promise.all` of subprocesses | baro |\n|---|---|---|---|\n| **Plans the work** | you | you | Planner agent |\n| **Pins design decisions** | implicit, drifts | n/a | Architect agent (`DecisionDocument`) |\n| **Parallel agents** | no — one session | yes, you coordinate | yes, on Mozaik bus |\n| **Mid-flight peer awareness** | n/a | implement yourself | Librarian broadcasts |\n| **Replan on failure** | manual | manual | Surgeon agent |\n| **Opens the PR** | manual | manual | Finalizer |\n| **Adding a new behaviour** | new prompt | refactor orchestrator | new bus participant |\n\nFor a deeper side-by-side on a real refactor, see [baro vs Claude Code `/goal`](https://jigjoy.ai/blog/baro-vs-claude-code).\n\n## Semantic Memory (cross-agent context sharing)\n\nbaro includes an optional semantic memory system that lets parallel story agents share discoveries in real time. When one agent reads a file or greps a pattern, the finding is embedded (CPU-only ONNX, no API calls) and stored in a local [Vectra](https://github.com/stevenic/vectra) vector index on disk. Other agents can query this shared memory mid-flight.\n\n```\nOrchestrator                         Story Agents (parallel)\n────────────                         ──────────────────────\nintercepts Read/Grep/Bash outputs    $ baro-memory query \"auth\"\n  → embeds via ONNX MiniLM            → reads Vectra index from disk\n  → stores in Vectra LocalIndex        → returns relevant findings\n  → caches file content              $ baro-memory cache get src/auth.ts\n                                       → returns cached content (no disk read)\n```\n\n**Usage:**\n\n```bash\nbaro \"your goal\"           # memory enabled by default\nbaro --no-memory \"goal\"    # disable (falls back to tag-based Librarian)\nBARO_DEBUG=memory baro ... # debug logging to stderr + ~/.baro/runs/memory-*.log\n```\n\n**When it helps:**\n\n- Large codebases (20+ files) where multiple agents explore overlapping areas\n- Staggered DAGs where later stories benefit from earlier stories' exploration\n- Runs with 5+ stories touching the same subsystems\n\n**When it doesn't help (and adds slight overhead):**\n\n- Small codebases (1-3 files) where each agent only needs one read\n- Fully parallel DAGs with no dependencies (all stories launch before any findings exist)\n- Quick single-story tasks (`--quick`)\n\nThe memory system adds ~1s startup overhead (ONNX model load) and negligible per-operation cost. It is session-scoped: data lives in `~/.baro/sessions/run-\u003ctimestamp\u003e/memory/` and is discarded after the run.\n\n## Requirements\n\n- At least one of:\n  - [Claude CLI](https://docs.anthropic.com/en/docs/claude-cli) authenticated (for `--llm claude`, the default)\n  - [OpenAI Codex CLI](https://github.com/openai/codex) authenticated (for `--llm codex`)\n  - [OpenCode CLI](https://opencode.ai) with a provider configured (for `--llm opencode`)\n  - `OPENAI_API_KEY` set (for `--llm openai`)\n  - `OPENAI_BASE_URL` set to a custom endpoint (optional, for `--llm openai` — routes through Xiaomi MiMo, OpenRouter, vLLM, Ollama, or any OpenAI-compatible API)\n  - Both Claude CLI **and** Codex CLI authenticated (for `--llm hybrid`)\n- Node.js 20+\n- macOS (arm64/x64), Linux (x64/arm64), Windows (x64)\n- `gh` CLI (optional, for automatic PR creation)\n\n## Status \u0026 feedback\n\nbaro is a work in progress. If a run explodes, the audit log at `~/.baro/runs/\u003crun-id\u003e.jsonl` is the fastest way to get it fixed — open an [issue](https://github.com/jigjoy-ai/baro/issues) with that file attached.\n\nIdeas, use cases, bug reports — Discord: [**discord.gg/dvxY9J2kWX**](https://discord.gg/dvxY9J2kWX) · Twitter: [**@lotus_sbc**](https://twitter.com/lotus_sbc)\n\n## License\n\nMIT — [JigJoy](https://jigjoy.ai/) team\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjigjoy-ai%2Fbaro","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjigjoy-ai%2Fbaro","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjigjoy-ai%2Fbaro/lists"}