Contrabass
🎸 A project-level orchestrator for AI coding agents — Go & Charm stack implementation of OpenAI's Symphony
Install / Use
/learn @junhoyeo/ContrabassREADME
Contrabass
<img alt="Contrabass Logo" src="https://raw.githubusercontent.com/junhoyeo/contrabass/main/.github/assets/contrabass.png" width="300px" />A project-level orchestrator for AI coding agents <br /> Go + Charm stack reimplementation of OpenAI's Symphony (openai/symphony) — manage work, not agents

Contrabass is a terminal-first orchestrator for issue-driven agent runs, with an optional local web dashboard for live visibility.
Current scope
Today Contrabass ships with:
- A Cobra CLI with TUI, headless, and optional embedded web dashboard modes
- A
WORKFLOW.mdparser with YAML front matter, Liquid prompt rendering, and$ENV_VARinterpolation - Issue tracker adapters for Linear, GitHub Issues, and a built-in Internal Board (local filesystem, no external service required)
- Agent runners for Codex app-server, OpenCode, oh-my-opencode, OMX (oh-my-codex), and OMC (oh-my-claudecode)
- Git-worktree-based workspace provisioning under
workspaces/<issue-id> - Teams: multi-agent coordination with a local task board, phased pipeline (plan → exec → verify), live TUI team table, and dual worker modes (tmux-based multi-process or goroutine-based in-process)
- An orchestrator with claim/release, timeout detection, stall detection, deterministic retry backoff, and state snapshots
- A Charm v2 terminal UI built with Bubble Tea, Bubbles, and Lip Gloss
- A React dashboard served from the Go binary, with state snapshots and live SSE updates
- Go unit/integration tests, TUI snapshot tests, and dashboard component/hook tests
- A tmux-based multi-process worker mode (default) alongside the in-process goroutine mode, with JSONL event logging, file-based heartbeats, dispatch queue, governance policies, and crash recovery
Requirements
- Go 1.25+
- Bun 1.3+ for the dashboard/landing workspace
- Git (workspace creation uses
git worktree) - tmux (required for the default tmux worker mode in team runs; not needed for goroutine mode)
- A supported agent runtime:
codex app-serveropencode serveoh-my-opencodeomx(oh-my-codex team runtime)omc(oh-my-claudecode team runtime)
- Tracker credentials for the backend you use:
- Linear:
LINEAR_API_KEY - GitHub:
GITHUB_TOKEN
- Linear:
From a fresh clone, run bun install once before using the JS/landing build and test commands.
Installation
Homebrew (macOS/Linux)
brew install junhoyeo/contrabass/contrabass
Download from GitHub Releases
Pre-built binaries for macOS and Linux (amd64/arm64) are available on the Releases page.
Build from source
git clone https://github.com/junhoyeo/contrabass.git
cd contrabass
bun install
make build
make build first builds packages/dashboard/dist/ and then embeds it into the Go binary.
Note:
go install github.com/junhoyeo/contrabass/cmd/contrabass@latestworks for the CLI and TUI, but the embedded web dashboard (--port) will be empty becausego installdoes not run the JS build step.
Quick start
Run with the demo workflow
LINEAR_API_KEY=your-linear-token \
./contrabass --config testdata/workflow.demo.md
Run with the embedded web dashboard
LINEAR_API_KEY=your-linear-token \
./contrabass --config testdata/workflow.demo.md --port 8080
Then open http://localhost:8080.
Run headless
LINEAR_API_KEY=your-linear-token \
./contrabass --config testdata/workflow.demo.md --no-tui
CLI flags
--config string path to WORKFLOW.md file (required)
--dry-run exit after first poll cycle
--log-file string log output path (default "contrabass.log")
--log-level string log level (debug/info/warn/error) (default "info")
--no-tui headless mode — skip TUI, log events to stdout
--port int web dashboard port (0 = disabled)
Team subcommand flags
contrabass team run --config workflow.md [flags]
--worker-mode string override worker mode (goroutine|tmux, default from config)
How Contrabass works
- Poll the configured tracker for candidate issues.
- Claim an eligible issue.
- Create or reuse a git worktree in
workspaces/<issue-id>. - Render the prompt body from
WORKFLOW.mdusing issue data. - Launch the configured agent runner.
- Stream agent events, track tokens/phases, and publish orchestrator events.
- Retry failed runs with exponential backoff + deterministic jitter.
- Mirror state into the TUI and, when enabled, the embedded web dashboard.
Runtime notes
WORKFLOW.mdis watched withfsnotify; on parse errors, Contrabass keeps the last known good config.- The Codex runner speaks newline-delimited JSON (
JSONL) tocodex app-serverrather thanContent-Lengthframed messages. Seedocs/codex-protocol.md. - The web dashboard currently has live metrics, running sessions, and retry queue data. The rate-limit panel exists, but there is not yet a live rate-limit feed behind it.
- The workflow parser already accepts more Symphony-shaped fields than the runtime fully consumes today. For example,
workspace,hooks, and somecodexsettings are parsed, but the current runtime mainly uses tracker selection, timeouts, retry settings, binary paths, and prompt/template fields.
Team worker modes
Teams support two worker modes, configured via team.worker_mode in the workflow file or the --worker-mode CLI flag:
| Mode | Description | Default |
|------|-------------|---------|
| tmux | Each worker runs in a separate tmux pane with process isolation, cross-process IPC via JSONL events, and file-based heartbeats | Yes |
| goroutine | Workers run as goroutines within the contrabass process — lighter weight, no tmux dependency | |
tmux mode (default) provides:
- Process isolation — each agent CLI runs in its own tmux pane
- JSONL event log for cross-process event streaming
- File-based heartbeat monitoring with stale detection
- Dispatch queue with ack tracking and timeout redelivery
- Governance policies with role routing heuristics
- Crash recovery with state diagnosis and automatic cleanup
- Advisory file locking via
flock(2)for safe concurrent access
goroutine mode runs all workers in-process using Go's errgroup and sync.Mutex. It requires no external dependencies but shares the process address space.
Team state is persisted as JSON files under .contrabass/state/team/{teamName}/.
Workflow file format
Contrabass reads a Markdown workflow file with YAML front matter followed by the prompt template body.
---
max_concurrency: 3
poll_interval_ms: 2000
max_retry_backoff_ms: 240000
model: openai/gpt-5-codex
project_url: https://linear.app/acme/project/example
agent_timeout_ms: 900000
stall_timeout_ms: 60000
tracker:
type: linear
agent:
type: codex
codex:
binary_path: codex app-server
---
# Workflow Prompt
Issue title: {{ issue.title }}
Issue description: {{ issue.description }}
Issue URL: {{ issue.url }}
Produce code and tests that satisfy the issue requirements.
Template bindings
The current prompt renderer exposes:
issue.titleissue.descriptionissue.url
Environment-variable interpolation
String values in YAML front matter can reference environment variables using $NAME syntax.
Examples:
tracker.token: $GITHUB_TOKENopencode.password: $OPENCODE_SERVER_PASSWORDomx.binary_path: $OMX_BINARYomc.binary_path: $OMC_BINARY
OMC / OMX workflow sections
For team-runtime-backed runners, set agent.type to omx or omc and configure the corresponding section.
agent:
type: omx
omx:
binary_path: omx
team_spec: 2:executor
poll_interval_ms: 1500
startup_timeout_ms: 22000
ralph: true
agent:
type: omc
omc:
binary_path: omc
team_spec: 2:claude
poll_interval_ms: 1200
startup_timeout_ms: 21000
Notes:
binary_pathcan point to the installed CLI wrapper, for exampleomxoromc.team_specis passed directly to the team runtime, such as1:executor,2:executor, or2:claude.- Contrabass writes the rendered task prompt into
.contrabass/runner/<runner>/...inside the workspace and instructs the team runtime to execute from that file. - OMC/OMX team runners generally require the underlying toolchain prerequisites those CLIs expect, especially tmux-based team support.
Team configuration
The team section configures multi-agent coordination:
team:
max_workers: 5
max_fix_loops: 3
claim_lease_seconds: 300
state_dir: .contrabass/state/team
execution_mode: team # team | single | auto
worker_mode: tmux # tmux (default) | goroutine
worker_mode: Controls how agent workers are spawned.tmux(default) uses separate tmux panes with process isolation.goroutineruns workers in-process.execution_mode: Controls coordination strategy.teamuses the full phased pipeline,singleruns one agent at a time,autoselects based on task count.
Example workflow files
testdata/workflow.demo.md— demo Linear + Codex workflowtestdata/workflow.github.md— GitHub + OpenCode workflowtestdata/workflow.ohmyopencode.md— oh-my-opencode workflowtestdata/workflow.omx.md— OMX workflowtestdata/workflow.omc.md— OMC workflowtestdata/workflow.md— realistic Linear fixture
Sup
Related Skills
node-connect
351.4kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
xurl
351.4kA CLI tool for making authenticated requests to the X (Twitter) API. Use this skill when you need to post tweets, reply, quote, search, read posts, manage followers, send DMs, upload media, or interact with any X API v2 endpoint.
frontend-design
110.7kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
351.4kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
