bouquet
Warning — Alpha Software Bouquet is under active development. APIs, config format, and CLI behavior may change without notice. Use at your own risk.
An orchestration layer for multi-agent coding — multiplexing coding agents across git worktrees with isolated services, all in one tmux session.
Key Features
| Feature | Details | |
|---|---|---|
| 🌿 | Git worktree isolation | Each feature branch gets its own worktree, venv, and node_modules — no cross-contamination |
| 🖥️ | Multi-pane services | Run API servers, workers, frontends alongside the agent with automatic port offsetting per worktree |
| 🤖 | Agent orchestration | TUI in tmux window 0 to create, switch, and manage worktree-backed agent windows |
| 📋 | Task queue | Define a backlog of tasks that get automatically delegated to worktrees — agents pick up work without manual intervention |
| 🔧 | Rich configuration | Expressive .bouquet.toml with template expressions ({{ 8000 + BOUQUET_WORKTREE_INDEX }}), per-worktree variables, agent profiles, and multi-service layouts |
| ⚡ | Fast bootstrap | CoW-clones .venv/node_modules (APFS), copies .env files, runs uv sync/pnpm install |
| 🔌 | Agent-agnostic | Named profiles let you mix Claude, Aider, Codex, or any CLI agent — even different agents per worktree |
Requirements
- Python 3.14+
- tmux (
brew install tmux) - GitHub CLI (optional,
brew install gh— enables PR links in TUI and GitHub Issues task backend) - direnv (optional,
brew install direnv) - Language package managers as needed (
uv,pnpm)
Installation
# Run without installing
uvx pybouquet --help
# Or install via pip
pip install pybouquet
# Or from source (development)
git clone https://github.com/promptromp/bouquet.git
cd bouquet
uv sync
Quick Start
1. Initialize
Creates a .bouquet.toml template. Edit it to configure your project.
2. Start a session
This will:
1. Create a tmux session (bouquet-<project-name>)
2. Launch the orchestrator TUI in window 0
3. Adopt any existing git worktrees
4. Attach you to the session
You can also pass arguments explicitly:
3. Use the TUI
| Key | Action |
|---|---|
N |
Create a new worktree (opens branch dialog with optional agent profile selector) |
S / Enter |
Switch to the selected worktree's window |
D |
Delete the selected worktree and its window |
a |
Toggle auto-accept for selected worktree (auto-sends "y" at permission prompts) |
A |
Toggle autopilot mode (auto-schedules tasks by dependency order) |
P |
Send a prompt to selected or all agent terminal(s) via tmux send-keys |
T |
Request a status summary from all agents (captures responses) |
C |
Create a new task in the task queue |
X |
Pick up the highlighted task (creates worktree and sends task to agent) |
M |
Complete the highlighted task (optionally remove the associated worktree) |
Backspace |
Delete the highlighted task from the queue |
R |
Refresh the worktree list and task queue |
Q |
Quit (with confirmation — kills the session) |
When you create a worktree, bouquet will:
- Create a git worktree with a new branch
- Bootstrap the environment (copy .env files, CoW-clone .venv/node_modules)
- Open a new tmux window with service panes (if configured)
- Launch the agent (e.g. claude) in pane 0
Switch back to the orchestrator: Ctrl-b 0.
4. Stop
Cleans up all managed worktrees, resets any in-progress tasks back to open, kills the tmux session, and removes state.
Services
Run dev servers alongside the agent in each worktree window. Define them in .bouquet.toml:
[[services]]
name = "api"
command = "uv run uvicorn app.main:app --reload --port {{ 8000 + BOUQUET_WORKTREE_INDEX }}"
[[services]]
name = "frontend"
command = "npm run dev -- --port {{ 3000 + BOUQUET_WORKTREE_INDEX }}"
[tmux]
layout = "main-vertical"
Each worktree gets a unique index (1, 2, 3, ...) so services bind to different ports automatically.
Template Variables
| Variable | Type | Example |
|---|---|---|
BOUQUET_WORKTREE_INDEX |
int | 1, 2, 3 |
BOUQUET_WORKTREE_BRANCH |
str | feature/auth |
BOUQUET_WORKTREE_PATH |
str | /path/to/.bouquet-worktrees/feature-auth |
BOUQUET_PROJECT_NAME |
str | my-project |
Arithmetic supported: {{ 8000 + BOUQUET_WORKTREE_INDEX }} → 8001.
No services defined = single pane with just the agent (backward compatible).
Agent Profiles
Named agent configurations so you can switch between Claude, Aider, Codex, etc. per worktree:
[agent]
command = "claude"
default_profile = "claude"
[[agent.profiles]]
name = "claude"
command = "claude"
[[agent.profiles]]
name = "aider"
command = "aider"
args = ["--model", "claude-sonnet-4-20250514"]
When profiles are defined, the TUI's new-worktree dialog shows a profile selector. If no profiles are defined, the top-level command/args are used (backward compatible).
Activity Detection
Bouquet polls each agent's tmux pane every 2 seconds to infer real-time status:
| Status | Meaning |
|---|---|
| ● running (green) | Agent output is actively changing |
| ◆ waiting (yellow) | Agent output stopped and a permission prompt was detected |
| ○ idle (dim) | Agent output hasn't changed for several polls |
This replaces the static "active" status with live feedback. The TUI table updates automatically.
Task Queue
Define a backlog of tasks that agents pick up automatically. Two backends are supported:
Local (SQLite) — default
Tasks are stored in ~/.local/state/bouquet/<project>.tasks.db. No external dependencies.
GitHub Issues
Uses your repo's GitHub Issues as the task source. Requires gh CLI authenticated.
[task_queue]
backend = "github"
label_filter = "bouquet" # only issues with this label appear as tasks
auto_branch_prefix = "task/"
Status mapping: OPEN = open issue, IN_PROGRESS = open issue + in-progress label, DONE = closed issue.
Task workflow
- Create (
c) — opens a dialog to create a task with an optional parent dependency - Pick up (
x) — creates a worktree from the task, marks it in-progress, and sends the task description to the agent - Complete (
m) — marks the task as done, optionally removes the associated worktree - Reconciliation — on startup, tasks stuck as in-progress (from a crash or quit) are automatically reset to open if their worktree no longer exists
Task Dependencies
Tasks can declare a parent dependency, forming a DAG. A task with an unsatisfied dependency shows as blocked in the queue and cannot be picked up until its parent is done. Cycles are rejected at creation time.
Autopilot
Press A to toggle autopilot mode. When active, bouquet automatically:
- Picks up tasks whose dependencies are satisfied (or have none)
- Runs up to
max_autopilot_concurrencytasks in parallel (default 3) - Enables auto-accept on all autopilot-created worktrees
- Auto-completes tasks when their agent goes idle (~10 seconds)
- Cascades: completing a parent unblocks its children for the next scheduling cycle
[task_queue]
max_autopilot_concurrency = 3 # max parallel worktrees
autopilot_auto_complete = true # auto-complete IDLE tasks
Pane Layout
With layout = "main-vertical" and two services:
┌──────────────────┬────────────┐
│ │ api │
│ agent (claude) ├────────────┤
│ │ frontend │
└──────────────────┴────────────┘
Architecture
The Conceptual Stack
┌─────────────────────────────────────────┐
│ Orchestration Layer │ ← TUI, agent coordination, task queue
├─────────────────────────────────────────┤
│ Session / Mux Layer │ ← tmux sessions, windows, panes
├─────────────────────────────────────────┤
│ Isolation Layer │ ← git worktrees + env isolation
├─────────────────────────────────────────┤
│ Environment Layer │ ← venv/node_modules/env vars
└─────────────────────────────────────────┘
Related Projects
Bouquet draws inspiration from and complements several tools in the multi-agent coding space:
-
claude-squad — A Go-based TUI for managing multiple Claude Code instances in parallel. Claude-squad focuses on running agents side-by-side with a clean terminal UI. Bouquet goes further with declarative multi-service layouts (API servers, frontends, workers per worktree), a rich template-based configuration language with per-worktree variable expansion, and a task queue for automatic work delegation across agents.
-
ruflo — A Rust-based agentic workflow orchestrator with a focus on DAG-based task execution and CI/CD integration. Ruflo takes a pipeline-oriented approach to agent coordination, while bouquet is designed around the developer's local workflow — git worktrees, tmux sessions, and interactive TUI management with live activity detection.
-
Claude Code Agent Teams — Anthropic's experimental built-in feature for coordinating multiple Claude Code agents. Agent Teams operates within the Claude Code runtime itself. Bouquet is agent-agnostic (works with Claude, Aider, Codex, or any CLI tool), provides full control over environment isolation, service orchestration, and configuration through
.bouquet.toml.