- Introduced multiple markdown files covering agent spawn packages, inter-agent communication protocols, and multi-agent orchestration tools. - Detailed analysis of official SDKs for CLI agents (Claude Code, Codex, Gemini) and their integration potential. - Documented various competitor approaches to agent spawning and communication, highlighting strengths and weaknesses. - Provided insights into best practices for implementing multi-provider support within Electron applications. This comprehensive documentation aims to enhance understanding of the current AI agent ecosystem and serve as a resource for developers and stakeholders.
23 KiB
Competitor Agent Spawn Patterns Research
Date: 2026-03-25
Executive Summary
Все 4 конкурента построили собственные adapter-слои для spawning CLI-агентов. Ни один не использует готовую библиотеку. Паттерн единый: интерфейс/trait + per-agent реализация + config-driven overrides.
Самый зрелый и переиспользуемый паттерн у vibe-kanban (Rust trait StandardCodingAgentExecutor + enum_dispatch + ACP harness). У Emdash паттерн проще (per-service TypeScript классы + auto-discovery). Dorothy самый примитивный (node-pty напрямую). Superset закрыт ELv2 лицензией.
1. Vibe Kanban (BloopAI)
Repo: github.com/BloopAI/vibe-kanban Язык: Rust (backend) + TypeScript (frontend) Лицензия: Apache-2.0 Stars: ~23K Поддерживаемые агенты: Claude Code, Codex, Gemini CLI, Copilot, Amp, Cursor, OpenCode, Droid, QwenCode, Qoder
Архитектура
Самый архитектурно зрелый подход среди конкурентов.
Ядро — Rust trait + enum_dispatch:
#[async_trait]
#[enum_dispatch(CodingAgent)]
pub trait StandardCodingAgentExecutor {
async fn spawn(&self, current_dir: &Path, prompt: &str,
env: &ExecutionEnv) -> Result<SpawnedChild, ExecutorError>;
async fn spawn_follow_up(&self, current_dir: &Path, prompt: &str,
session_id: &str, reset_to_message_id: Option<&str>,
env: &ExecutionEnv) -> Result<SpawnedChild, ExecutorError>;
async fn spawn_review(&self, current_dir: &Path, prompt: &str,
session_id: Option<&str>, env: &ExecutionEnv)
-> Result<SpawnedChild, ExecutorError>;
}
Dispatch через enum (compile-time, zero-cost):
#[enum_dispatch]
#[derive(Clone, Serialize, Deserialize, PartialEq, TS, Display)]
pub enum CodingAgent {
ClaudeCode, Amp, Gemini, Codex, Opencode,
CursorAgent, QwenCode, Copilot, Droid, QaMock
}
Структура файлов
crates/executors/src/
executors/
mod.rs — trait + enum_dispatch + CodingAgent enum
claude.rs — ClaudeCode executor
gemini.rs — Gemini executor (через ACP harness)
codex.rs — Codex executor
amp.rs — Amp executor
copilot.rs — GitHub Copilot
cursor.rs — Cursor Agent
opencode.rs — OpenCode
droid.rs — Droid (factory.ai)
qwen.rs — QwenCode
qa_mock.rs — Mock для тестов
utils.rs — Общие утилиты
acp/ — ACP (Agent Communication Protocol) harness
mod.rs
client.rs — ACP client
harness.rs — Spawn + session lifecycle
session.rs — Session management
normalize_logs.rs — Log normalization
claude/ — Claude-specific subdirectory
codex/ — Codex-specific subdirectory
cursor/ — Cursor-specific subdirectory
droid/ — Droid-specific subdirectory
opencode/ — OpenCode-specific subdirectory
command.rs — CommandBuilder (base cmd + params + overrides)
env.rs — ExecutionEnv (env vars, repo context)
executor_discovery.rs — Auto-discovery + caching
mcp_config.rs — MCP server config per agent
model_selector.rs — Model selection logic
profile.rs — Agent profiles (DEFAULT, APPROVALS variants)
approvals.rs — Permission/approval system
stdout_dup.rs — Stdout duplication utilities
lib.rs — Crate root
Как добавить нового агента (на примере Qoder PR #1759)
crates/executors/src/executors/qoder.rs— реализация traitmod.rs— добавить вCodingAgentenummcp_config.rs— MCP Passthrough adapterdefault_profiles.json— профили (DEFAULT/APPROVALS)generate_types.rs— ts-rs type generationshared/types.ts— TypeScript enum (автогенерация)shared/schemas/qoder.json— JSON schemadocs/agents/qoder.mdx— документация
Пример: Gemini executor
Base command: "npx -y @google/gemini-cli@0.29.3"
Flags: --experimental-acp, --model <name>, --yolo (if auto mode)
Harness: AcpAgentHarness — manages spawn, follow-up, session lifecycle
Output: ACP protocol (structured agent communication)
Ключевые паттерны
- CommandBuilder (builder pattern): base cmd → params → overrides → platform-specific split → CommandParts
- ExecutionEnv: HashMap<String, String> env vars + repo context, inject into tokio::Command
- CmdOverrides: replace base cmd / append params / set env vars (per-profile)
- ACP Harness: shared session/spawn logic for ACP-compatible agents (Gemini, Qoder, etc.)
- executor_discovery: async discovery + caching по (path, command_key, agent_type)
- ts-rs: Rust types → TypeScript types автогенерация
Оценка
| Метрика | Значение |
|---|---|
| LOC adapter layer | ~2000-3000 (весь crate executors) |
| Паттерн | trait + enum_dispatch + CommandBuilder |
| Сложность добавления агента | ~150-200 LOC per agent |
| Можно переиспользовать? | Нет (Rust, другой стек) |
| Можно скопировать паттерн? | ДА — отличный reference |
| Надёжность подхода | 9/10 |
2. Emdash (General Action)
Repo: github.com/generalaction/emdash Язык: TypeScript (Electron) Лицензия: MIT Stars: ~6K YC W26 Поддерживаемые агенты: 22+ (Claude Code, Codex, Gemini, Amp, Cursor, Copilot, Goose, Droid, Kiro, Qwen, OpenCode, Cline, Continue, Codebuff, Charm, Kilocode, Kimi, Autohand, Auggie, Rovo Dev, Mistral Vibe, Pi)
Архитектура
Per-service TypeScript классы + auto-discovery. Самый близкий к нашему стеку.
Ключевые файлы:
src/main/services/
CodexService.ts — Manages Codex CLI child processes + log streaming
CodexSessionService.ts — Session management for Codex
ClaudeConfigService.ts — Claude-specific configuration
ClaudeHookService.ts — Claude hooks integration
AgentEventService.ts — Agent lifecycle events
TaskLifecycleService.ts — Task state machine
WorkspaceProviderService.ts — Provider workspace management
TerminalConfigParser.ts — CLI terminal config detection
ptyManager.ts — PTY session management (node-pty)
ptyIpc.ts — PTY IPC communication
ConnectionsService.ts — Connection management
RepositoryManager.ts — Git repository management
ProjectSettingsService.ts
DatabaseService.ts — SQLite (drizzle)
AutoUpdateService.ts
__tests__/ — Tests
fs/ — File system services
git-core/ — Git operations
mcp/ — MCP protocol
skills/ — Skills system
ssh/ — SSH remote development
Как добавить провайдера (из документации)
- Include: provider name, CLI invocation command, auth notes, setup steps
- Team wires up provider selection in UI and adds to Integrations matrix
- Providers auto-detected when CLI is in PATH
Spawn-паттерн
node:child_process.spawn()для CLI агентовnode-ptyдля terminal sessions- Per-service классы (CodexService, ClaudeConfigService)
TerminalConfigParserдля auto-detection CLI в PATHAgentEventServiceдля lifecycle events (running/waiting/completed/error)- SQLite (drizzle ORM) для персистенции
Ключевые особенности
- Auto-discovery: провайдеры детектятся автоматически по наличию CLI в PATH
- Native deps: sqlite3, node-pty, keytar (rebuilt per Electron version)
- Worktree isolation: каждый агент в своём git worktree
- SSH remote: агенты могут работать на удалённых машинах через SSH/SFTP
- Best-of-N: запуск нескольких агентов на одну задачу, выбор лучшего
Оценка
| Метрика | Значение |
|---|---|
| LOC adapter layer | ~1500-2000 (services + pty) |
| Паттерн | Per-service classes + auto-discovery |
| Сложность добавления агента | Средняя (новый service file) |
| Можно переиспользовать код? | Потенциально ДА (MIT, TypeScript, Electron) |
| Можно скопировать паттерн? | ДА — очень близко к нашему стеку |
| Надёжность подхода | 7/10 (less structured than vibe-kanban) |
3. Dorothy (Charlie85270)
Repo: github.com/Charlie85270/Dorothy Язык: TypeScript (Electron + Next.js) Лицензия: MIT Stars: ~3K Поддерживаемые агенты: Claude Code (primarily), расширяется
Архитектура
Самый простой подход — node-pty напрямую, без абстракции adapter layer.
electron/
agent-manager.ts — Agent lifecycle & parallel execution (node-pty)
pty-manager.ts — Terminal session multiplexing
window-manager.ts — Window management
services/
telegram-bot
slack-bot
kanban-automation
mcp-server-launcher
api-server
mcp-orchestrator/ — Super Agent MCP server
mcp-kanban/ — Kanban automation MCP
Spawn-паттерн
node-pty— каждый агент в изолированной PTY-сессии- Статус определяется парсингом stdout patterns (running/waiting/completed/error)
- N параллельных агентов с отдельными проектами
- Super Agent (мета-агент) контролирует другие через MCP tools
- Cron-based scheduling для повторяющихся задач
- Skills system для extensibility
Ключевые особенности
- Нет абстракции агентов: привязан к Claude Code, нет interface для разных CLI
- Kanban: задачи → колонки → automatic agent assignment по skills
- Automations: GitHub PR/issue polling → agent spawning
- Remote control: Telegram/Slack bot для управления
Оценка
| Метрика | Значение |
|---|---|
| LOC adapter layer | ~500-800 (agent-manager + pty-manager) |
| Паттерн | Direct node-pty, no abstraction |
| Сложность добавления агента | Высокая (нет interface) |
| Можно переиспользовать код? | Да (MIT), но мало что полезного |
| Можно скопировать паттерн? | НЕТ — слишком примитивный |
| Надёжность подхода | 5/10 |
4. Superset (superset-sh)
Repo: github.com/superset-sh/superset Язык: TypeScript (Electron, monorepo Turborepo + Bun) Лицензия: Elastic License 2.0 (ELv2) — НЕ open-source! Stars: ~7.8K Поддерживаемые агенты: Claude Code, Codex, Aider, Copilot, Cursor Agent, Gemini CLI, OpenCode + custom
Архитектура
Monorepo с 6 apps. Multi-process Electron с 5 entry points:
apps/desktop/src/
main/
index.ts — Main app entry
terminal-host/
index.ts — Persistent daemon for terminal sessions
pty-subprocess.ts — PTY handler (node-pty)
git-task-worker.ts — Worker thread for Git ops
host-service/
index.ts — Local HTTP server
packages/
@superset/trpc — tRPC routers
@superset/ui — Shared React components
@superset/local-db — SQLite (Drizzle)
@superset/db — PostgreSQL (Neon, cloud sync)
Spawn-паттерн
- Terminal Host daemon: persistent subprocess managing terminal sessions
- PTY subprocess: node-pty forked on-demand
- Git Worker: heavy git ops offloaded to worker_threads
- tRPC over Electron IPC: renderer ↔ main communication
- Worktree isolation: каждая задача в своём git worktree с уникальным branch
- Port allocation: SUPERSET_PORT_BASE + 20 портов на workspace
Ключевые особенности
- Multi-process: 5 entry points, daemon-based terminal management
- Dual DB: local SQLite + cloud PostgreSQL (ElectricSQL sync)
- Better Auth: OAuth deep links для десктопа
- .superset/config.json: workspace setup/teardown scripts
Оценка
| Метрика | Значение |
|---|---|
| LOC adapter layer | Неизвестно (code not browsable) |
| Паттерн | Multi-process + terminal-host daemon |
| Сложность добавления агента | Неизвестно |
| Можно переиспользовать код? | НЕТ (Elastic License 2.0) |
| Можно скопировать паттерн? | Частично (terminal-host daemon idea) |
| Надёжность подхода | 8/10 (production, enterprise users) |
CLI Agent Programmatic Spawn Reference
Claude Code
claude --input-format stream-json --output-format stream-json --verbose
- Bidirectional NDJSON protocol over stdin/stdout
- Message types:
initialize,user,control_response --verboseREQUIRED with stream-json--printmode for one-shot (no multi-turn)- Session hooks do NOT run in
--printmode - Official docs: incomplete — community reverse-engineered
- VS Code extension spawns:
claude --output-format stream-json --verbose --input-format stream-json --max-thinking-tokens 0 --model default --permission-prompt-tool stdio
Codex (OpenAI)
codex exec --json "prompt"
- JSONL output (one event per line)
- Event types:
thread.started,turn.started,turn.completed,turn.failed,item.* - Item types: agent_message, reasoning, command_exec, file_change, mcp_tool_call
--output-schemafor structured final outputcodex exec resume --jsonfor session resumption- App-server mode:
codex app-server— stateful JSON-RPC over stdio - Auth:
CODEX_API_KEYenv var for non-interactive - Schema BREAKING CHANGES between versions (item_type → type, assistant_message → agent_message)
Gemini CLI (Google)
gemini -p "prompt" --output-format json
# or streaming:
gemini -p "prompt" --output-format stream-json
-pflag for non-interactive headless mode--output-format json— full response + stats--output-format stream-json— real-time JSONL events--yolo— auto-approve all tool calls--experimental-acp— Agent Communication Protocol (used by vibe-kanban)- Known issues: response field may contain markdown-wrapped JSON instead of clean JSON
- Stdin piping supported for additional context
Amp (Sourcegraph)
amp --execute "prompt" --stream-json
--stream-json— JSONL output (REQUIRES--execute)--stream-json-input— JSONL input via stdin (REQUIRES--stream-json)--stream-json-thinking— includes thinking blocks (extends schema)- Claude Code compatible format (mostly)
- Multi-turn:
amp threads continue [thread-id]+--stream-json-input - Auth:
AMP_API_KEYenv var for CI/CD - Elixir SDK exists as reference: spawns CLI + parses stream-json
Goose (Block)
goose run -t "prompt"
# or from file:
goose run -i instructions.md
goose run— non-interactive one-shot mode--output-format json— feature request #4419, marked Done--format json— for session/recipe listing- Max 10 concurrent subagents (hard-coded)
- 5 min default timeout, 25 max turns
GOOSE_SUBAGENT_MAX_TURNSenv override
Сравнительная таблица
| Vibe Kanban | Emdash | Dorothy | Superset | |
|---|---|---|---|---|
| Язык | Rust | TypeScript | TypeScript | TypeScript |
| Лицензия | Apache-2.0 | MIT | MIT | ELv2 |
| Используют готовую библиотеку? | Нет | Нет | Нет | Нет |
| Паттерн | trait + enum_dispatch | Per-service classes | Direct node-pty | Multi-process daemon |
| Абстракция агентов | StandardCodingAgentExecutor trait |
Per-service (CodexService, etc.) | Нет | Terminal-host daemon |
| Количество агентов | 10+ | 22+ | 1 (Claude) | 8+ |
| Сложность добавления | ~150-200 LOC | ~300-500 LOC | Hard (no interface) | Unknown |
| LOC adapter layer | ~2000-3000 | ~1500-2000 | ~500-800 | Unknown |
| Auto-discovery | Да (executor_discovery) | Да (PATH detection) | Нет | Unknown |
| MCP support | Passthrough per agent | Да | MCP servers | Да |
| ACP protocol | Да (shared harness) | Нет | Нет | Нет |
| Type generation | ts-rs (Rust → TS) | N/A | N/A | N/A |
| Isolation | Git worktrees | Git worktrees | Separate projects | Git worktrees |
| Можно reuse код? | Нет (Rust) | Да (MIT, TS) | Да (MIT) | Нет (ELv2) |
Выводы и рекомендации для Claude Agent Teams UI
1. Какой паттерн взять за основу?
Рекомендация: гибрид vibe-kanban + emdash подходов
От vibe-kanban взять:
- Interface (trait) + per-agent implementation — TypeScript interface вместо Rust trait
- CommandBuilder pattern — построение команды через builder с overrides
- ExecutionEnv — управление env vars + repo context
- Profile system — DEFAULT/APPROVALS варианты per agent
- enum-dispatch idea — в TS реализуется через discriminated union + factory
От Emdash взять:
- Auto-discovery — детекция CLI в PATH
- Per-service approach — но с общим interface
- node-pty integration — для terminal sessions
2. Предлагаемый TypeScript interface
interface AgentExecutor {
readonly agentType: AgentType; // discriminated union tag
spawn(params: SpawnParams): Promise<SpawnedAgent>;
spawnFollowUp(params: FollowUpParams): Promise<SpawnedAgent>;
spawnReview?(params: ReviewParams): Promise<SpawnedAgent>;
discover(): Promise<DiscoveredOptions>;
isAvailable(): Promise<boolean>;
normalizeOutput(raw: string): string;
parseEvent(line: string): AgentEvent | null;
}
interface SpawnParams {
workDir: string;
prompt: string;
env: ExecutionEnv;
model?: string;
approvalMode: 'auto' | 'supervised';
mcpConfig?: string;
}
interface SpawnedAgent {
process: ChildProcess;
sessionId: string;
stdout: ReadableStream<AgentEvent>;
stderr: ReadableStream<string>;
kill(): Promise<void>;
sendMessage(msg: string): Promise<void>;
}
3. Что НЕ стоит делать
- Не использовать node-pty напрямую (как Dorothy) — нет абстракции, сложно масштабировать
- Не строить на Rust (как vibe-kanban) — у нас TypeScript стек, overhead не оправдан
- Не копировать multi-process daemon (как Superset) — over-engineering для нашего случая
- Не привязываться к одному протоколу — у каждого CLI свой формат (stream-json, --json, --stream-json)
4. Приоритет агентов для поддержки
| Приоритет | Агент | Протокол | Сложность |
|---|---|---|---|
| P0 | Claude Code | stream-json bidirectional | Уже есть |
| P1 | Codex | exec --json JSONL |
Средняя |
| P1 | Gemini CLI | --output-format stream-json |
Средняя |
| P2 | Amp | --execute --stream-json |
Средняя (CC-compatible) |
| P2 | Goose | run -t + --output-format json |
Средняя |
| P3 | OpenCode | TBD | Исследовать |
| P3 | Cursor Agent | TBD | Исследовать |
Источники
- Vibe Kanban (BloopAI) — Apache-2.0, 23K stars
- Vibe Kanban AGENTS.md
- Vibe Kanban executors crate
- Vibe Kanban PR #1759 — Qoder executor pattern
- Emdash (General Action) — MIT, 6K stars
- Emdash Providers Documentation
- Emdash AGENTS.md
- Dorothy (Charlie85270) — MIT, 3K stars
- Superset (superset-sh) — ELv2, 7.8K stars
- Superset DeepWiki Architecture
- Codex CLI Reference
- Codex Non-Interactive Mode
- Codex JSON output issues
- Gemini CLI Headless Mode
- Gemini CLI JSON issues
- Amp Streaming JSON
- Amp CLI Manual
- Goose CLI Commands
- Goose JSON output request #4419
- Claude Code stream-json docs gap #24594
- Claude Code Automation Skill (LobeHub)