A terminal-native multi-agent command center
Project description
maestro
A terminal-native multi-agent command center. Spawns AI/CLI agents in real PTYs and shows them in switchable panes with a session timeline — all inside one TUI.
Install
Maestro is a Python CLI (needs Python 3.11+ and a claude on your PATH).
Install it on any device with pipx so it lands in its
own isolated venv with the maestro command on your PATH:
pipx install "git+https://github.com/jmbmunda/maestro.git"
Or run it once without installing, using uv:
uvx --from git+https://github.com/jmbmunda/maestro.git maestro
Update later with pipx upgrade maestro. Pin a release with ...@v0.1.0.
From source (development)
git clone https://github.com/jmbmunda/maestro.git && cd maestro
python3 -m venv .venv && source .venv/bin/activate
pip install -e .
Run
maestro
Keys
Each pane is a real terminal (full ANSI: colors, cursor, alt-screen), so
claude, vim, htop etc. render correctly. Maestro has two modes:
OUTSIDE (default — manage panes):
Ctrl+S— spawn aclaudeagent in a new paneCtrl+Shift+S— spawn a$SHELLagent (terminal-dependent; see note)Ctrl+W— dismiss the focused pane (confirms first if it's still running)r— rename the focused pane (blank resets to the defaultpane-N · claude)b— broadcast one prompt to multiple panes at once (pick targets, type, Enter)a— quick agents: launch a pre-seeded role, or create/edit/delete templatesCtrl+J/Ctrl+K— focus next / previous paneCtrl+L— cycle layout: split → grid → focusedCtrl+B— toggle the sessions status panelCtrl+T— toggle the timeline/— open the skills launcher (pick a skill → injects/nameinto the focused pane)Enter— step INSIDE the focused pane to interact with itq— quit (alsoCtrl+Q, where the terminal doesn't grab it — the VSCode integrated terminal does)
INSIDE (drive one agent): every keystroke goes straight to that pane's
terminal — arrows, Esc, Tab, Ctrl-C, everything. The one reserved key is
Ctrl+Esc, which steps back OUTSIDE.
Heads-up:
Ctrl+Esconly fires in terminals that transmit it distinctly (kitty keyboard protocol /modifyOtherKeys=2). If your terminal doesn't, the binding won't trigger and there's no built-in fallback exit — kill maestro from another terminal (pkill -f maestro) and report it so we can add a fallback. The footer reflects the mode — while INSIDE it shows justCtrl+] Exit pane; OUTSIDE it shows the command list.
Click a pane to focus + interact in one step — clicking auto-enters that pane,
no separate Enter needed. Clicking a different pane while INSIDE another stays
INSIDE the new one. Clicking a finished pane drops you back OUTSIDE. In focused
layout, click a row in the panes strip to switch.
(Keyboard nav Ctrl+J/Ctrl+K still moves focus without auto-entering, so you
can chain commands like spawn → navigate → spawn → … without stepping in.) The background is transparent, so maestro inherits your terminal's
wallpaper/theme.
Quick agents
Press a (OUTSIDE) for one-click specialized agents. A quick agent is a template
— a name + a starting prompt + an optional skill — that spawns a claude pane, names
it, injects the skill and prompt, and drops you inside. Ships with built-ins (Reviewer,
Tester, Security, Docs, Refactor) and is fully CRUD-able in-app: Enter launches the
highlighted one, n new, e edit, d delete. Templates live in a hand-editable
~/.config/maestro/quick-agents.toml (seeded on first run).
Broadcast
Press b (OUTSIDE) to fan one prompt out to several sessions at once: a modal
lists the running panes (all checked by default — Space toggles), you type a prompt,
and Enter sends it to every checked pane. Great for "run the same task across N
agents" or kicking off a fleet. Uncheck any pane (e.g. a $SHELL) you don't want.
Skills
Press / (OUTSIDE) to open the skills launcher — a filterable list of the skills
in ~/.claude/skills (and a project's .claude/skills). Pick one and maestro types
/name into the focused pane and steps you inside, exactly as if you'd typed it in
Claude. (Typing /name yourself while INSIDE still works too.)
Maestro also watches each pane's output for Claude's skill markers and shows the
active skill as a ⚡<skill> badge on the pane's border (best-effort — it keys off
Claude's output text).
Status board
Maestro shows, at a glance, which sessions need you. Each pane gets a best-effort status inferred from output timing:
▶working — producing output right now⏳waiting — alive but quiet → needs you (a question, an approval, or just done with its turn); the pane border glows amber○done — exited cleanly ·✗failed — exited non-zero
There's a dedicated sessions panel at the top listing every pane with its
status, the header summarises it (e.g. maestro ▶2 ⏳1 ○1), and each pane border
reflects it too. (Heuristic: maestro can't tell "waiting for approval" from "waiting
for your next message" — both show as ⏳ waiting.) The focused pane stands out with a
colored border (green while you're INSIDE it) and full-brightness text, while
non-focused panes are dimmed. The sessions panel is on by default (toggle with
Ctrl+B); the timeline event log is off by default (toggle with Ctrl+T).
Theme
Maestro defaults to the ansi-dark theme, which draws with your terminal's own
16-colour palette — so it adapts to whatever colour scheme your terminal uses. Press
Ctrl+P → "Change theme" to pick another (ansi-light for light terminals, or any
of Textual's built-ins like gruvbox / dracula). Your choice is remembered in
.maestro/state.json.
Note:
Ctrl+Shift+Srelies on the terminal forwarding shift+ctrl combos; some terminals fold it intoCtrl+S.claudeis the default spawn either way.
Ctrl+]is the only key maestro reserves while INSIDE, so apps that use it (e.g. vim's tag-jump) won't see it.
Layouts
- split — vertical stack; auto-promotes to grid once a 4th pane spawns
- grid — auto-shaped tiles (2×2, 2×3, 3×3, then a scrollable 3×N)
- focused — one large pane plus a left strip of status tiles for the rest
When an agent exits cleanly (exit=0) the pane is auto-dismissed — no
frozen-screen confusion. Failed exits (non-zero) stay sticky so you can read
what went wrong; press Ctrl+W to dismiss those.
Layout
┌─timeline──────────────────────────────────────────┐
│ 16:18:30 spawn pane-1 claude │
│ 16:18:42 spawn pane-2 /bin/zsh -l │
└────────────────────────────────────────────────────┘
┌─panes──┐ ┌─● pane-1 · claude · INSIDE — Ctrl+Esc to exit┐
│ ● 1 cla│ │ │
│ ○ 2 sh │ │ (live terminal — claude renders here) │
│ ◄ │ │ │
└────────┘ └────────────────────────────────────────────┘
(The panes strip only appears in focused layout. A pane's border turns
heavy/green while you're INSIDE it.)
Where things live
maestro/app.py— Textual app, key bindings, focus-toggle, spawn/dismiss/focusmaestro/panes.py—Panemodel +PaneManagerstate machine (Textual-agnostic)maestro/layouts.py— split / grid / focused renderers + the focus tiles stripmaestro/terminal.py— pyte-backedEmulator,TerminalView, query responder, key encodermaestro/agent.py— PTY-backed subprocess wrapper (ptyprocess); raw bytes + resizemaestro/events.py— append-only JSONL event log (.maestro/session.jsonl)
.maestro/state.json persists your layout + timeline-visibility choices across
restarts. Agent sessions themselves are not resumed.
Tests
pip install -e '.[test]'
pytest
Next steps
- Provider adapters beyond
claude/$SHELL(codex,gemini,gh copilot) - Claude Code skill passthrough (toggle
~/.claude/skillsper pane) - Prompt library + per-agent system prompts
- Inter-agent message bus for "review on modify" workflows
- Terminal niceties: mouse reporting, bracketed paste, configurable INSIDE-exit key
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file maestro_tui-0.1.0.tar.gz.
File metadata
- Download URL: maestro_tui-0.1.0.tar.gz
- Upload date:
- Size: 50.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7fb5b2d2ccbffdac84e9a8f196fff4c8eb1cd70adfb770dc382184bfa97f36ea
|
|
| MD5 |
a69f35afad298c2386fa5bdb4c971e91
|
|
| BLAKE2b-256 |
11abf447463fbdf2a03ed00d6df6cc7b4c63b949b4e9b50f21208fc79c3aa5f7
|
Provenance
The following attestation bundles were made for maestro_tui-0.1.0.tar.gz:
Publisher:
release.yml on jmbmunda/maestro
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
maestro_tui-0.1.0.tar.gz -
Subject digest:
7fb5b2d2ccbffdac84e9a8f196fff4c8eb1cd70adfb770dc382184bfa97f36ea - Sigstore transparency entry: 1809217832
- Sigstore integration time:
-
Permalink:
jmbmunda/maestro@67ae072a56af5fd99299be22f186e749d717073e -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/jmbmunda
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@67ae072a56af5fd99299be22f186e749d717073e -
Trigger Event:
push
-
Statement type:
File details
Details for the file maestro_tui-0.1.0-py3-none-any.whl.
File metadata
- Download URL: maestro_tui-0.1.0-py3-none-any.whl
- Upload date:
- Size: 30.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a9d0d81661e694b6ba3a71366fe501d01023f277bc6ebd91fffb8d391797c660
|
|
| MD5 |
b0a5658abd2a672cc6b6ae8672b1a8a6
|
|
| BLAKE2b-256 |
ca182a76063e0aada009e8166f68d5c65b7dfdf02057eeda6e2bbfac604a8e39
|
Provenance
The following attestation bundles were made for maestro_tui-0.1.0-py3-none-any.whl:
Publisher:
release.yml on jmbmunda/maestro
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
maestro_tui-0.1.0-py3-none-any.whl -
Subject digest:
a9d0d81661e694b6ba3a71366fe501d01023f277bc6ebd91fffb8d391797c660 - Sigstore transparency entry: 1809217859
- Sigstore integration time:
-
Permalink:
jmbmunda/maestro@67ae072a56af5fd99299be22f186e749d717073e -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/jmbmunda
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@67ae072a56af5fd99299be22f186e749d717073e -
Trigger Event:
push
-
Statement type: