A meta-harness has a hard constraint most multi-agent frameworks never face: it must drive agents it didn’t write and can’t change. Omnigent does this with a *_native* bridge family per agent — a base descriptor in native_coding_agents.py plus a bridge / forwarder / hook / permissions / state set — and crucially it does not invent a common wire format and demand every agent speak it.
Instead each bridge attaches at the seam the target already exposes:
- Claude Code — type into its running TUI via tmux bracketed-paste, expose tools through an MCP stdio server, govern via its command hooks. No RPC.
- Codex — spawn its app-server and drive it with JSON-RPC
turn/startover a Unix socket. - OpenCode —
POST /session/{id}/prompt_asyncand read the SSE stream. - Cursor / Goose / Kimi / Pi / Kiro — send keystrokes, then tail the vendor’s own JSONL or SQLite transcript to recover structured events.
Eleven agents, zero forks. The only thing normalized is the outcome: every bridge ultimately feeds one NativeServerTransport Protocol driven by a single NativeServerHarness executor, and every governance question becomes the same EvaluationRequest.
Why this is non-obvious
The instinct is to define an adapter interface and write N implementations of the same shape. But these agents don’t share a shape — one has hooks, one has an app-server, one has only a TUI and a log file. Forcing them into one interface means either forking each agent or losing fidelity. Omnigent inverts it: the integration mechanism is per-agent and messy; only the normalized result is uniform. The mess is contained at the edge.
The pitfall
Transcript-tailing is fragile — it couples you to a file format the vendor can rename. Bridges that ride a real protocol (Codex’s app-server, OpenCode’s HTTP) are sturdier than ones that scrape a TUI. When you pick which agents to support first, weigh the seam, not the popularity.
Sources
-
omnigent/native_coding_agents.py✓ verified -
omnigent/native_server_transport.py✓ verified -
omnigent/claude_native_bridge.py✓ verified