Multi-session Claude Code orchestrator with a Matrix-style terminal control center.
Maestro spawns and monitors multiple Claude Code sessions working on the same project simultaneously. It provides real-time visibility into what each agent is doing, how much it's spending, and coordinates their work to prevent conflicts — all from a single TUI dashboard.
+==================================================================+
| MAESTRO v0.1.0 | 3 agents | $8.45 spent | 14:32:01 |
+==================================================================+
| AGENT 1 | AGENT 2 | AGENT 3 |
| #42 Streaks | #43 Animations | #44 Bot Profile |
| ▶ RUNNING 4m32s | ▶ RUNNING 2m15s | ⏳ QUEUED |
| ctx: 45% ████░░ | ctx: 23% ██░░░░ | waiting for #43 |
| $1.23 | $0.87 | $0.00 |
| | | |
| > Reading | > Writing | (pending) |
| StreakService | GameView.swift | |
+-------------------+-------------------+--------------------------+
| ACTIVITY LOG |
| 14:32:01 [#42] Reading docs/api-contracts/streaks.json |
| 14:31:58 [#43] Wrote GameView.swift |
+-------------------------------------------------------------------+
| [q]uit [p]ause [k]ill [r]efresh [?]help |
+-------------------------------------------------------------------+
- Single-session TUI — spawn a Claude Code session and watch it work in real-time
- Live stream parsing — parses Claude CLI
stream-jsonoutput for tool usage, messages, and costs - Session lifecycle — QUEUED → SPAWNING → RUNNING → GATES_RUNNING → COMPLETED/NEEDS_REVIEW/ERRORED/PAUSED/KILLED
- Keyboard controls — pause (SIGSTOP), resume, kill sessions from the dashboard
- State persistence — session history and costs saved to
maestro-state.json - Cost tracking — per-session and total spending displayed in real-time
- Multi-session pool — run up to N concurrent Claude sessions with automatic queue promotion
- Git worktree isolation — each session works in its own worktree to prevent file conflicts
- File claim system — registry prevents two sessions from editing the same file simultaneously
- GitHub issue queue — fetch
maestro:ready-labeled issues and run them as sessions - Milestone mode —
--milestone <name>runs all open issues in a milestone - Label lifecycle — issues are automatically transitioned:
ready→in-progress→done/failed - Automated PR creation — on session completion, a PR is opened with cost report and file list
- Dependency scheduling —
blocked-by:#Nlabels and body references create an ordered work graph - Priority ordering —
priority:P0/P1/P2labels determine scheduling order within the queue - Context overflow detection — monitors context window usage per session; automatically forks into a continuation session at a configurable threshold with a structured handoff prompt
- Fork depth limiting — configurable maximum fork chain depth prevents runaway continuation loops
- Multi-provider support — works with GitHub (via
ghCLI) or Azure DevOps (viaazCLI); provider is auto-detected from the git remote or set explicitly in config - Session prompt guardrails — a language-specific pre-completion checklist (format, lint, test) is automatically detected from the project root and appended to every session's system prompt; can be overridden with a custom prompt via
guardrail_promptinmaestro.toml - Config-driven completion gates — after a session finishes, maestro runs a configurable list of shell commands (fmt, clippy, test, or any custom command) before accepting the result; required gate failures transition the session to
NEEDS_REVIEWand block PR creation; optional gates log warnings only; configured via[sessions.completion_gates]inmaestro.toml - Completion summary overlay — when all sessions finish, a centred overlay shows a per-session outcome summary (status, cost, elapsed time, PR link, and error snippet for failed sessions);
[i]opens the issue browser,[r]opens a new prompt,[l]views the activity log,[Esc]returns to the dashboard; use--onceto skip the overlay and exit immediately (suited for CI/scripting) - Continuous work mode —
--continuous/-Cflag onmaestro runauto-advances through all ready issues one at a time; on failure a pause overlay prompts the user to[s]skip,[r]retry, or[q]quit; the status bar shows current issue, completed, and skipped counts throughout the run - Interactive home screen — launching
maestroopens an idle dashboard with a quick-actions menu, contextual work suggestions, repo/branch info, and a recent activity panel; navigate withj/kor direct shortcut keys; suggestions auto-refresh when returning from a completed session and can be refreshed on demand withR; a loading indicator is shown while a refresh is in progress - Interactive issue browser — browse, filter, and launch GitHub issues directly from the TUI; supports single-launch (
Enter) and multi-select batch-launch (Space+Enter); filter by text (/) or milestone (m) - Milestone overview — inspect milestone progress with real-time completion gauges; drill into issues or run all open issues in a milestone with a single key (
r) - Automatic preflight checks —
maestro runvalidates thatclaude,gh/az, andgitare correctly installed and authenticated before spending any API credits; use--skip-doctorto bypass when needed - Rich real-time activity feedback — the activity log shows detailed, human-readable messages for every tool call: file-touching tools display the file path, Bash tool calls show the command preview (
$ cargo test), and tool results include elapsed time; when Claude uses extended thinking, the activity log shows"Thinking..."while the block runs and"Thought for Xs"when it finishes; text chunks are suppressed from the global log to prevent flooding - Self-upgrade — async version check on startup notifies you when a new release is available; press
[u]to download and install the update with automatic backup and restart confirmation
| Phase | What | Status |
|---|---|---|
| 0 | Single-session TUI, stream parser, state persistence | Done |
| 1 | Multi-session pool, split-pane TUI, file claim system, git worktrees | Done |
| 2 | GitHub integration — issue fetching, auto-PR, label lifecycle, dependency graph | Done |
| 3 | Intelligence — context overflow detection, budget enforcement, stall detection | Done |
| 4 | Plugin system, mode system, cost dashboard, session resumption | Done |
| 5 | Multi-provider support — GitHub and Azure DevOps | Done |
- Rust 1.75+ (tested on 1.94)
- Claude Code CLI (
claude) installed and on your PATH - GitHub CLI (
gh) — required when using the GitHub provider (default) - Azure CLI (
az) — required when using the Azure DevOps provider; runaz loginto authenticate - macOS, Linux, or WSL
brew tap CarlosDanielDev/tap
brew install carlosdanieldev/tap/maestro --formulaNote: The
--formulaflag is required because an unrelated cask named "maestro" exists in Homebrew core.
Download the tarball for your platform from the latest GitHub Release, extract it, and place the maestro binary on your PATH.
Supported targets:
| Platform | Archive |
|---|---|
| macOS (Apple Silicon) | maestro-<version>-aarch64-apple-darwin.tar.gz |
| macOS (Intel) | maestro-<version>-x86_64-apple-darwin.tar.gz |
| Linux (x86_64) | maestro-<version>-x86_64-unknown-linux-gnu.tar.gz |
A sha256sums.txt file is included in each release for checksum verification.
git clone https://github.com/CarlosDanielDev/maestro.git
cd maestro
cargo build --release
# Binary at target/release/maestroMaestro checks for new versions automatically on startup. When an update is available, a banner appears at the bottom of the TUI:
UPDATE New version v0.5.1 available [u]pgrade [Esc] dismiss
Press u to download and install the new version. Maestro backs up the current binary before replacing it and asks for restart confirmation:
READY v0.5.1 installed! Restart now? [y]es [n]o
If you decline, the upgrade takes effect on the next launch.
You can also update through your original install method:
# Homebrew
brew upgrade carlosdanieldev/tap/maestro --formula
# From source
git pull && cargo build --releaseMaestro supports tab-completion for bash, zsh, and fish. Completions are pre-generated in every release tarball and installed automatically by Homebrew.
maestro completions bash # print bash completion script
maestro completions zsh # print zsh completion script
maestro completions fish # print fish completion scriptmaestro completions bash > ~/.local/share/bash-completion/completions/maestroRestart your shell or run source ~/.bashrc to activate.
mkdir -p ~/.zfunc
maestro completions zsh > ~/.zfunc/_maestroAdd the following line to your ~/.zshrc before compinit is called:
fpath+=~/.zfuncThen reload:
source ~/.zshrcmaestro completions fish > ~/.config/fish/completions/maestro.fishFish picks up completions in that directory automatically — no shell restart required.
Homebrew installs the man page and shell completions automatically when you run brew install. No manual steps are needed.
Each release tarball on the GitHub Releases page includes a completions/ directory (containing maestro.bash, _maestro for zsh, and maestro.fish) and a man/maestro.1 man page. Copy the files to the appropriate paths listed above.
To read the man page from the tarball:
man ./man/maestro.1# Initialize config
maestro init
# Run a single session with a prompt
maestro run --prompt "Refactor the auth module to use async/await"
# Run a session and exit immediately when done (CI / scripting mode)
maestro run --issue 42 --once
# Run a session for a GitHub issue
maestro run --issue 42
# Run all open issues in a milestone (respects priority and dependencies)
maestro run --milestone "v1.0"
# Show all queued issues labelled maestro:ready
maestro queue
# Add a single issue to the work queue manually
maestro add 42
# Open the dashboard (empty, for monitoring)
maestro
# Check session status (no TUI)
maestro status
# View spending report
maestro cost
# Run preflight environment checks manually
maestro doctor
# Skip preflight checks (use when environment is already known-good)
maestro run --issue 42 --skip-doctorMaestro reads maestro.toml from the project root:
[project]
repo = "owner/repo"
base_branch = "main"
[sessions]
max_concurrent = 3 # Max parallel Claude sessions
stall_timeout_secs = 300 # Kill stalled sessions after 5 min
default_model = "opus" # opus, sonnet, haiku
default_mode = "orchestrator"
# guardrail_prompt = "..." # Custom pre-completion checklist injected into every session prompt
# Omit to auto-detect from project language (Rust/TS/Python/Go)
[budget]
per_session_usd = 5.0 # Max spend per session
total_usd = 50.0 # Global budget cap
alert_threshold_pct = 80 # Warn at 80% of budget
[github]
issue_filter_labels = ["maestro:ready"]
auto_pr = true
cache_ttl_secs = 300 # How long issue data is cached (default: 5 min)
[notifications]
desktop = true
slack = false
[sessions.context_overflow]
overflow_threshold_pct = 70 # Auto-fork when context reaches this % (default: 70)
auto_fork = true # Spawn a continuation session on overflow
commit_prompt_pct = 50 # Prompt an intermediate commit at this % (default: 50)
max_fork_depth = 5 # Max chained forks before overflow is ignored
# Completion gates — run after every session before PR creation
[sessions.completion_gates]
enabled = true # Set to false to skip all gates
[[sessions.completion_gates.commands]]
name = "fmt"
run = "cargo fmt --check"
required = true # true = failure blocks PR; false = warning only
[[sessions.completion_gates.commands]]
name = "clippy"
run = "cargo clippy -- -D warnings"
required = true
[[sessions.completion_gates.commands]]
name = "test"
run = "cargo test"
required = true
# Optional: explicit provider configuration (auto-detected from git remote by default)
[provider]
kind = "github" # "github" (default) or "azure_devops"
# Azure DevOps example:
# [provider]
# kind = "azure_devops"
# organization = "https://dev.azure.com/MyOrg"
# az_project = "MyProject"See directory-tree.md for the complete project structure.
maestro (Rust binary)
├── src/
│ ├── main.rs # CLI entry point (clap); Run/Queue/Add/Status/Cost/Init
│ ├── config.rs # maestro.toml parsing; ProviderConfig; guardrail_prompt in SessionsConfig
│ ├── provider/ # Multi-provider abstraction [Issue #29]
│ │ ├── mod.rs # create_provider factory; detect_provider_from_remote
│ │ ├── types.rs # ProviderKind (Github, AzureDevops); type re-exports
│ │ └── azure_devops.rs # AzDevOpsClient (shells out to `az`)
│ ├── github/ # GitHub API integration [Phase 2]
│ │ ├── types.rs # GhIssue, Priority, MaestroLabel, SessionMode
│ │ ├── client.rs # GitHubClient trait + GhCliClient (shells out to `gh`)
│ │ ├── labels.rs # Label lifecycle: ready→in-progress→done/failed
│ │ └── pr.rs # Auto PR creation with cost report
│ ├── session/
│ │ ├── types.rs # Session state machine, StreamEvent, issue_title
│ │ ├── parser.rs # Claude stream-json line parser
│ │ ├── manager.rs # Process spawn, stdin/stdout, lifecycle
│ │ ├── pool.rs # Concurrent session pool; guardrail injected into system prompt [Phase 1, #43]
│ │ └── worktree.rs # Git worktree isolation [Phase 1]
│ ├── state/
│ │ ├── types.rs # MaestroState, file claims, issue_cache
│ │ └── store.rs # JSON persistence (atomic writes)
│ ├── work/ # Work queue and scheduling [Phase 2]
│ │ ├── types.rs # WorkItem, WorkStatus
│ │ ├── dependencies.rs # DAG: topological sort, cycle detection
│ │ └── assigner.rs # Priority-ordered queue assignment
│ └── tui/
│ ├── app.rs # App state, WorkAssigner, GitHubClient integration
│ ├── ui.rs # ratatui rendering (panels, gauges, logs)
│ └── mod.rs # Terminal setup, async event loop
├── Cargo.toml
└── maestro.toml # Default config
Maestro reads and writes GitHub labels to coordinate work. All label names are defined in src/github/types.rs.
| Label | Meaning |
|---|---|
maestro:ready |
Issue is queued and ready for a session to pick up |
maestro:in-progress |
A session is currently working on this issue |
maestro:done |
Session completed successfully; PR was opened |
maestro:failed |
Session ended with an error |
| Label | Meaning |
|---|---|
priority:P0 |
Highest priority — scheduled first |
priority:P1 |
Medium priority |
priority:P2 |
Default priority |
mode:orchestrator |
Run session in Orchestrator mode |
mode:vibe |
Run session in Vibe Coding mode |
blocked-by:#N |
This issue cannot start until issue #N is done |
Dependencies can also be declared in the issue body as blocked-by: #N (case-insensitive).
| Key | Action |
|---|---|
q |
Quit maestro (kills all sessions) |
Ctrl+C |
Emergency exit |
| Key | Action |
|---|---|
p |
Pause all running sessions (SIGSTOP) |
r |
Resume all paused sessions (SIGCONT) |
k |
Kill all sessions |
| Key | Action |
|---|---|
i |
Open issue browser |
m |
Open milestone overview |
c |
Open cost dashboard |
R |
Refresh work suggestions |
j / Down |
Move selection down |
k / Up |
Move selection up |
Enter |
Execute selected action |
| Key | Action |
|---|---|
j / Down |
Move cursor down |
k / Up |
Move cursor up |
Space |
Toggle multi-select on current issue |
Enter |
Launch session(s) for selected issue(s) |
/ |
Enter label text filter mode |
m |
Enter milestone filter mode |
Esc |
Exit filter mode / go back |
| Key | Action |
|---|---|
j / Down |
Move cursor down |
k / Up |
Move cursor up |
Enter |
Browse issues in selected milestone |
r |
Run all open issues in selected milestone |
Esc |
Go back |
| Key | Action |
|---|---|
Enter |
Submit prompt and launch session |
Shift+Enter |
Insert newline |
Ctrl+V |
Paste from clipboard (text or image) |
Tab / Shift+Tab |
Move focus between fields |
a |
Add image attachment (in attachment list) |
d |
Remove selected attachment (in attachment list) |
Esc |
Cancel and return to previous screen |
- Maestro spawns
claude --print --output-format stream-json --model <model> "<prompt>" - Parses the JSON stream line-by-line to extract tool usage, messages, costs
- Renders real-time state in a ratatui TUI with agent panels and activity log
- Persists session state to
maestro-state.jsonfor recovery and reporting
Maestro wraps — not replaces — your existing .claude/ agent system. Each spawned Claude session inherits your project's CLAUDE.md, agents, skills, and commands. Maestro adds coordination context (file claims, peer awareness) via --append-system-prompt.
MIT