Maestro CLI
One binary, one socket. maestro talks to the running app over its control socket — the same verbs drive the UI, your scripts, and the agents themselves. Everything you can click, an agent can run.
Concepts
Every maestro-managed terminal runs inside a session (a tab in the app). Sessions form a tree — a session can have child sessions — and windows hold session trees. The env var $MAESTRO_SESSION_ID holds the current session's id; "this session"/"this tab" means that id.
Get the CLI
Sessions spawned by Maestro already have a maestro shim on their PATH. For a global command in your own shells, symlink the launcher out of the app bundle:
ln -sf /Applications/Maestro.app/Contents/Resources/bin/maestro /usr/local/bin/maestro
Targeting
<target> is a session-id prefix (e.g. 3f2a) or a unique title substring (case-insensitive). Run maestro list to see ids and titles; use "$MAESTRO_SESSION_ID" to target the current session.
Sessions
maestro list [--closed]
All sessions as JSON (id, title, kind, status, cwd, parentId, windowId). --closed lists recently-closed sessions (tombstones) instead, newest first.
maestro list | jq '.[] | {id, title, status}'
maestro open --kind <claude|codex|shell> [--child|--sibling] [--cwd <dir>] [--parent <id>] [--title <t>]
Open a new session.
--kindclaude, codex, or shell (default shell)--child/--siblingplace relative to the FOCUSED session (parent and cwd resolved server-side)--parent <id>nests under a specific session--cwd <dir>working directory--title <t>tab title
maestro open --kind claude --child --title "api tests"
maestro focus <target> | --back | --forward
Focus a session (bring its tab to front), or move back/forward through this window's focus history.
maestro focus "api tests"
maestro focus --back
maestro send <target> "<text>"
Type text into a session's terminal. Does not press Enter — follow with send-key enter.
maestro send "api tests" "npm test" && maestro send-key "api tests" enter
maestro send-key <target> <enter|escape|ctrl-c|tab>
Send a key press to a session.
maestro send-key "api tests" ctrl-c
maestro close <target> [--instant] [--discard] [--stash] [--force] [--cascade]
Close a session and its subtree. Archives by default (closed history; restore via unarchive), respecting the close countdown unless --instant.
--cascadecloses the whole subtree, children first--instantskips the close countdown--discarddestroys to Recently-Closed instead of archiving--stashsends it to the visible Stash shelf--forcebypasses the busy/dirty guard
maestro close "$MAESTRO_SESSION_ID" --cascade --force
Layout & windows
maestro split <target> [--down]
Split a tab into panes (tmux-style): spawns a shell pane beside <target> (below with --down).
maestro split "$MAESTRO_SESSION_ID" --down
maestro move <target> [up|down] [--before <id>] [--after <id>] [--child-of <id>] [--promote] [--to-window <id>] [--new-window] [--project <dir>]
Reorder or re-parent a session, or move it to another/new window.
--promotelifts it to root level--child-of <id>re-parents under another session--to-window <id>/--new-windowmoves it across windows--project <dir>regroups it under a project (clears the manual pin)
maestro move "$MAESTRO_SESSION_ID" --new-window
maestro move-project <dir> [up|down] [--before <dir>] [--after <dir>] [--first] [--last] [--window <id>]
Reorder a project group in the sidebar (per window, custom sort). Dirs resolve to their project root; defaults to the focused window.
maestro move-project ~/dev/api --first
maestro duplicate-window [--window <id>]
Open a new window viewing the same workspace (same sessions, independent focus). Defaults to the focused window.
maestro duplicate-window
Lifecycle
maestro rename <target> "<title>" | --clear
Set a session's custom title. --clear (or an empty title) reverts to the auto-derived one.
maestro rename "$MAESTRO_SESSION_ID" "api tests"
maestro reveal <target> <finder|terminal|editor>
Open the session's cwd in Finder, a new Terminal, or your editor.
maestro reveal "api tests" editor
maestro popup <target>
Open a compact popup window showing a live duplicate of a session's terminal — the same window that auto-appears when a session needs input.
maestro popup "refactor auth"
maestro reopen [<target>]
Reopen a closed session (see list --closed). <target> matches a closed session by id-prefix or title; omit it to reopen the most-recently-closed one.
maestro reopen
maestro stash <target> · maestro unstash <target>
stash shelves a session and its subtree — same as archive, but it stays visible in the sidebar Stashed section. unstash restores it; agents resume lazily on focus.
maestro stash "docs sweep"
maestro unstash "docs sweep"
maestro unarchive <target>
Restore an archived session (and its subtree) to the sidebar; agents resume lazily on focus.
maestro unarchive "refactor auth"
Agents & settings
maestro swap <target> --resume <agentSessionId> | [--to claude|codex] [--model <m>] [--handoff <file>] [--force]
Replace the agent running in a tab in place (same tab id/position). --resume <id> continues an existing claude/codex conversation; otherwise a fresh agent boots — --to picks the provider, --model the model, --handoff <file> seeds its first prompt. The outgoing conversation is tombstoned (reopen / ⌘Z restores it). --force bypasses the busy guard.
maestro swap "api tests" --to codex --model gpt-5
maestro settings <list [group] | get <key> | set <key> <value>>
Read or change maestro settings. list writes the full settings catalog (keys, labels, descriptions, current values) to a file and prints its path — read that file to find the right key, then get/set it.
maestro settings list
maestro settings set terminal.fontSize 14
maestro status-set <target> <status> [--reason <text>]
Manually override a session's status (e.g. working, waiting, idle). Mostly for scripting and testing.
maestro status-set "api tests" waiting --reason "needs review"
maestro help
Print the built-in help. Bare maestro with no verb launches (or focuses) the app.
Examples
# claude session nested under the focused one
maestro open --kind claude --child --title "api tests"
# shell tab next to the focused session
maestro open --kind shell --sibling
# run the tests in it
maestro send "api tests" "npm test" && maestro send-key "api tests" enter
# pop this session out into its own window
maestro move "$MAESTRO_SESSION_ID" --new-window
# swap this tab's agent for codex, keeping the tab in place
maestro swap "$MAESTRO_SESSION_ID" --to codex
# close this session and its whole subtree
maestro close "$MAESTRO_SESSION_ID" --cascade --force