Architecture
Bouquet is an orchestration layer for multi-agent coding that composes four concerns.
The Stack
CLI (Click) → bouquet start/stop/init
└─► WorktreeManager (worktree.py — glue layer)
├─► git.py subprocess calls for worktree CRUD
├─► tmux.py libtmux wrapper for session/window/pane lifecycle
├─► template.py safe {{ expr }} rendering for service commands
├─► bootstrap.py setup commands + env capture, env file copy, CoW clone, dep install
├─► activity.py ActivityMonitor — pane scraping for live status
├─► github.py gh CLI wrapper for PR URL lookup
├─► tasks/ pluggable task queue (LocalBackend, GitHubIssuesBackend)
└─► TUI (tui/app.py — Textual app in tmux window 0)
└─► spawns worktree windows via WorktreeManager
Conceptual Layers
graph TD
subgraph orchestration ["Orchestration Layer"]
A["TUI"] ~~~ B["Agent Coordination"] ~~~ C["Task Queue"]
end
subgraph session ["Session / Mux Layer"]
D["tmux sessions"] ~~~ E["windows"] ~~~ F["panes"]
end
subgraph isolation ["Isolation Layer"]
G["git worktrees"] ~~~ H["env isolation"]
end
subgraph environment ["Environment Layer"]
I["venv / node_modules"] ~~~ J["env vars"]
end
orchestration --> session --> isolation --> environment
Key Flow
bouquet start creates a tmux session, launches the TUI in window 0, then the TUI drives WorktreeManager.create() which chains:
- Git worktree creation — new branch + worktree directory
- Bootstrap — setup commands, env capture, CoW clone, dependency install
- Tmux window — new window with agent pane + service panes
- Agent launch —
send_keysto the agent pane
Activity Detection
The ActivityMonitor polls each agent's tmux pane every 2 seconds:
- SHA256 hash of pane content; hash change → RUNNING
- Stable 3+ polls → IDLE (or WAITING if a permission prompt is detected)
- Prompt detection scans the last 10 lines for permission menus
Task Queue
Pluggable backend system with two implementations:
| Backend | Storage | Status Mapping |
|---|---|---|
| Local | SQLite (~/.local/state/bouquet/<project>.tasks.db) |
Direct status field |
| GitHub Issues | GitHub Issues via gh CLI |
OPEN = open issue, IN_PROGRESS = in-progress label, DONE = closed |
Task Lifecycle
stateDiagram-v2
[*] --> OPEN: Create task
OPEN --> IN_PROGRESS: Pick up (x)
IN_PROGRESS --> DONE: Complete (m)
IN_PROGRESS --> OPEN: Reconcile (stale)
Pane Layouts
services-top (default)
┌────────────┬────────────┐
│ api │ frontend │ ← services (~40%)
├────────────┴────────────┤
│ agent (claude) │ ← agent (~60%)
└─────────────────────────┘