# Overview Source: https://docs.runmaestro.ai/about/overview Learn about Maestro's spec-driven workflow for AI-assisted development with multiple agents. Maestro hones fractured attention into focused intent. It is built for developers who need to coordinate multiple AI agents, repositories, and long-running tasks without leaving a keyboard-first workflow. ## Spec-Driven Workflow Maestro enables a **specification-first approach** to AI-assisted development. Instead of ad-hoc prompting, you collaboratively build detailed specs with the AI, then execute them systematically: 1. **PLAN** - Discuss the feature with the AI agent 2. **SPECIFY** - Create markdown docs with task checklists in the Auto Run document folder 3. **EXECUTE** - Auto Run works through tasks, spawning a fresh session per task 4. **REFINE** - Review results, update specs, and repeat **Why this works:** * **Deliberate planning** - Conversation forces you to think through requirements before coding * **Documented specs** - Your markdown files become living documentation * **Clean execution** - Each task runs in isolation with no context bleed * **Iterative refinement** - Review, adjust specs, re-run - specs evolve with your understanding **Example workflow:** 1. **Plan**: In the AI Terminal, discuss your feature: *"I want to add user authentication with OAuth support"* 2. **Specify**: Ask the AI to help create a spec: *"Create a markdown checklist for implementing this feature"* 3. **Save**: Copy the spec to your Auto Run document folder (or have the AI write it directly) 4. **Execute**: Switch to Auto Run tab, select the doc, click Run - Maestro handles the rest 5. **Review**: Check the History tab for results, refine specs as needed This approach mirrors methodologies like [Spec-Kit](https://github.com/github/spec-kit), but with a graphical interface, real-time AI collaboration, and multi-agent parallelism. ## Key Concepts | Concept | Description | | ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Agent** | A Maestro workspace tied to a project directory, backed by a provider (Claude Code, Codex, or OpenCode). Each agent has a Command Terminal and AI Terminal. | | **Provider** | The underlying AI coding assistant (Claude Code, OpenAI Codex, or OpenCode) that powers an agent. | | **Session / Tab** | A conversation with the AI provider. Sessions and tabs are 1:1 - each tab represents one session. Agents can have multiple tabs for parallel conversations. | | **Group** | Organizational container for agents. Group by project, client, or workflow. | | **Group Chat** | Multi-agent conversation coordinated by a moderator. Ask questions across multiple agents and get synthesized answers. | | **Git Worktree** | An isolated working directory linked to a separate branch. Worktree sub-agents appear nested under their parent in the agent list and can create PRs. | | **AI Terminal** | The conversation interface with your AI provider. Supports `@` file mentions, slash commands, and image attachments. | | **Command Terminal** | A PTY shell for running commands directly. Tab completion for files, git branches, and command history. | | **Session Explorer** | Browse all past sessions for an agent. Star, rename, search, and resume any previous conversation. | | **Auto Run** | Automated task runner that processes markdown checklists. Spawns a fresh session per task. | | **Playbook** | A saved collection of Auto Run documents with document order, options, and settings for repeatable workflows. | | **History** | Timestamped log of all actions (user commands, AI responses, Auto Run completions) with session links. | | **Remote Control** | Web interface for mobile access. Local network or remote via Cloudflare tunnel. | | **CLI** | Headless command-line tool for scripting, automation, and CI/CD integration. | | **Provider Pass-Through** | Maestro delegates all AI work to your installed provider (Claude Code, Codex, OpenCode). Your MCP tools, custom skills, permissions, and authentication all carry over - Maestro runs them in batch mode (prompt in, response out) rather than interactive mode. | # Achievements Source: https://docs.runmaestro.ai/achievements Level up through 11 conductor-themed ranks based on your cumulative Auto Run time. Maestro features a conductor-themed achievement system that tracks your cumulative Auto Run time. The focus is simple: **longest run wins**. As you accumulate Auto Run hours, you level up through 11 ranks inspired by the hierarchy of orchestral conductors. Achievements ## Conductor Ranks | Level | Rank | Time Required | Example Conductor | | :---: | ----------------------------- | ------------- | ------------------------------ | | 1 | **Apprentice Conductor** | 15 minutes | Gustavo Dudamel (early career) | | 2 | **Assistant Conductor** | 1 hour | Marin Alsop | | 3 | **Associate Conductor** | 8 hours | Yannick Nezet-Seguin | | 4 | **Resident Conductor** | 24 hours | Jaap van Zweden | | 5 | **Principal Guest Conductor** | 1 week | Esa-Pekka Salonen | | 6 | **Chief Conductor** | 30 days | Andris Nelsons | | 7 | **Music Director** | 3 months | Sir Simon Rattle | | 8 | **Maestro Emeritus** | 6 months | Bernard Haitink | | 9 | **World Maestro** | 1 year | Kirill Petrenko | | 10 | **Grand Maestro** | 5 years | Riccardo Muti | | 11 | **Titan of the Baton** | 10 years | Leonard Bernstein | ## Reaching the Top Since Auto Runs can execute in parallel across multiple Maestro sessions, achieving **Titan of the Baton** (Level 11) is technically feasible in less than 10 calendar years. Run 10 agents simultaneously with worktrees and you could theoretically hit that milestone in about a year of real time. But let's be real - getting to Level 11 is going to take some serious hacking. You'll need a well-orchestrated fleet of agents running around the clock, carefully crafted playbooks that loop indefinitely, and the infrastructure to keep it all humming. It's the ultimate test of your Maestro skills. The achievement panel shows your current rank, progress to the next level, and total accumulated time. Each rank includes flavor text and information about a legendary conductor who exemplifies that level of mastery. ## Sharing Your Achievements Generate a shareable image of your achievements to celebrate milestones or compare progress with other Maestro users. The share image captures **unique statistics not tracked anywhere else** in the app. Achievement Share Image **To generate a share image:** 1. Open the Achievements panel 2. Click **Share** in the header 3. Choose **Copy to Clipboard** or **Save as Image** ### Stats Captured in Share Images The share image includes comprehensive usage statistics: | Stat | Description | | --------------------- | ---------------------------------------------------- | | **Sessions** | Total number of AI sessions created | | **Total Tokens** | Cumulative tokens processed across all sessions | | **Total AutoRun** | Cumulative Auto Run execution time | | **Longest AutoRun** | Your personal record for longest continuous Auto Run | | **Hands-on Time** | Time spent actively interacting with Maestro | | **Registered Agents** | Peak number of agents you've configured | | **Parallel AutoRuns** | Peak simultaneous Auto Runs achieved | | **Parallel Queries** | Peak simultaneous AI queries in flight | | **Queue Depth** | Peak message queue depth reached | These peak usage stats are tracked automatically and persist across sessions. They represent your high-water marks - evidence of your most intensive Maestro orchestrations. ## Keyboard Mastery Separate from Conductor ranks, Maestro tracks your **keyboard mastery** based on shortcut usage. As you discover and use more keyboard shortcuts, you level up through 5 mastery levels: | Level | Title | Shortcuts Used | | :---: | ---------------- | -------------- | | 0 | Beginner | 0-24% | | 1 | Student | 25-49% | | 2 | Performer | 50-74% | | 3 | Virtuoso | 75-99% | | 4 | Keyboard Maestro | 100% | Your current keyboard mastery level and progress are shown in the **Keyboard Shortcuts panel** (press `?` or `Cmd/Ctrl+/` to open). The panel displays which shortcuts you've used (marked with a checkmark) and which remain to be discovered. See [Keyboard Shortcuts](./keyboard-shortcuts) for the full shortcut reference. ## Leaderboard Opt-in to compete with fellow Maestro users on the global **Leaderboard** at [RunMaestro.ai](https://runmaestro.ai). Sign up to have your stats tracked and compete for top rankings. Leaderboard The leaderboard tracks two competitive categories: | Category | Description | | ---------------------------- | ------------------------------------------------ | | **Cumulative Auto Run Time** | Total time spent in Auto Run across all sessions | | **Longest Single Auto Run** | Personal record for longest continuous Auto Run | Each entry shows the user's conductor badge level, social links, and ranking. Your stats sync across devices when you're signed in, so your achievements follow you wherever you use Maestro. Your leaderboard avatar is sourced from GitHub. Link your GitHub profile in the registration form, and update your picture on GitHub to change how it appears on the leaderboard. # Auto Run + Playbooks Source: https://docs.runmaestro.ai/autorun-playbooks Process markdown checklists with AI agents using Auto Run documents and reusable Playbooks. Auto Run automates AI-driven work in one of two modes, chosen with the **Spec-Driven** / **Goal-Driven** toggle at the top of the Run dialog: * **Spec-Driven** runs markdown checklist documents to completion. You write the work as checkbox tasks in a folder of `.md` files, and Maestro works through them one by one, spawning a fresh AI session for each task (or each document). A reusable collection of these documents is a **Playbook**. Reach for this when you already know the steps. * **Goal-Driven** pursues a single free-text objective with no checklist. Each iteration spawns a fresh agent that makes one increment of progress, reports how far along it is, and exits, repeating until the goal is reached or the run stops. Reach for this for open-ended work where you can't list the steps up front. Most of this guide covers Spec-Driven documents and Playbooks. Jump to [Goal-Driven Mode](#goal-driven-mode) for that workflow. Auto Run ## Setting Up Auto Run 1. Navigate to the **Auto Run** tab in the right panel (`Cmd+Shift+1`) 2. Select a folder containing your markdown task documents 3. Each `.md` file becomes a selectable document ## Creating Tasks Use markdown checkboxes in your documents: ```markdown theme={"theme":"dracula"} # Feature Implementation Plan - [ ] Implement user authentication - [ ] Add unit tests for the login flow - [ ] Update API documentation ``` **Tip**: Press `Cmd+L` (Mac) or `Ctrl+L` (Windows/Linux) to quickly insert a new checkbox at your cursor position. ### Task Granularity: Two Approaches There are two viable ways to structure work across Auto Run documents. Pick the one that fits your project - they can also coexist. **1. Many tasks per document (classic approach)** One document holds a long list of checkboxes; the runner walks through them serially, each in a fresh session. * Good when tasks are small, independent, and share a common framing that's cheap to restate in the document body. * Each task gets a clean context, so the agent doesn't drift across them. * Tradeoff: the agent has to re-derive shared context for every task from whatever lives in the document. **2. One task (or a few) per document (recommended for richer work)** Each document is a focused brief - heavy on context, light on checkboxes. Often just a single `- [ ]` "execute the plan" task at the bottom. * Good when each unit of work needs substantial setup, references, constraints, or prior decisions to do well. * Modern agents have large context windows, so loading a richer document per task is cheap and usually produces better results than splintering it into many small checkboxes that each lose the shared framing. * Compose multi-step workflows by chaining several of these focused documents inside a Playbook instead of stuffing them into one file. * Tradeoff: more files to manage; the dropdown list grows. **Rule of thumb:** if you find yourself repeating the same context paragraph above several checkboxes in one document, that's a signal to split into multiple focused documents and let the Playbook handle ordering. ## Running Single Documents 1. Select a document from the dropdown 2. Click the **Run** button (or the ▶ icon) 3. Customize the agent prompt if needed, then click **Go** ## Running Multiple Auto Run Documents Auto Run supports running multiple documents in sequence: 1. Click **Run** to open the Auto Run configuration modal 2. Click **+ Add Docs** to add more documents to the queue 3. Drag to reorder documents as needed 4. Configure options per document: * **Reset on Completion** - Creates a working copy in `runs/` subfolder instead of modifying the original. The original document is never touched, and working copies (e.g., `TASK-1735192800000-loop-1.md`) serve as audit logs. * **Duplicate** - Add the same document multiple times 5. Enable **Loop Mode** to cycle back to the first document after completing the last 6. Click **Go** to start running documents ## Model Override The run configuration modal has **Model** and **Effort** pickers, both defaulting to **Use agent default**. Picking a value runs *this Auto Run only* on that model: every task spawn in the run uses it, the agent's own configured model is left alone (its interactive tabs keep using the default), and the override is forgotten when the run ends. The pickers reset to the default each time the modal opens, and are hidden for providers that expose no model or effort options. Worktree runs honor the override too, without changing the child worktree agent's own configured model. The same override is available from the CLI as `--model` / `--effort` on `auto-run`, `playbook`, `run-doc`, and `goal-run`. See [CLI](cli.md#per-run-model-override). ## Fresh Context: Task vs Document The run configuration modal has a **Fresh context per** toggle that controls how context is scoped as the runner works through a document. This is distinct from [task granularity](#task-granularity-two-approaches) above - granularity is how you *structure* a document, while this is how Maestro *executes* it. **Task** - A new agent is spawned for each unchecked task, with a clean context every time. * Maximum isolation; the agent never drifts across tasks. * Each task must be fully self-contained, since the agent sees nothing from previous tasks except what's written in the document. * The right choice for most agents. **Document** - A single agent walks every unchecked task in the document in one continuous session, carrying context forward between tasks. * Best for agents with very large context windows, and for work where later tasks build on earlier ones. * Requires enough context window to hold a whole document's worth of work in one session. **Auto-selection:** Maestro picks the mode by combining the running agent's context window with the average task count across the documents you've selected. The tasks-per-doc threshold scales with the window - **5** at 256K or less, **10** at 512K, **20** at 1M - and below the threshold Maestro recommends **Document**, at/above it **Task**. Selecting different documents recomputes the recommendation. If you toggle to the non-recommended mode, the modal surfaces a small note explaining what it would have picked and why, but respects your choice. A loaded Playbook's saved mode always takes precedence, and once you've manually toggled, future document-selection changes don't yank the mode back. > **Tip:** Author tasks to be self-contained regardless of mode. Document mode is an optimization, not a license to write tasks that depend on chat memory. ## Playbooks Save your Auto Run configurations as Playbooks for reuse: 1. Configure your documents, order, and options 2. Click **Save as Playbook** and enter a name 3. Load saved playbooks from the **Load Playbook** dropdown 4. Update or discard changes to loaded playbooks Playbooks ### Inline Wizard Generate new playbooks from within an existing session using the **Inline Wizard**: 1. Type `/wizard` in any AI tab (or click the Wizard button in the Auto Run panel) 2. Have a conversation with the AI about your project goals 3. Watch the confidence gauge build as the AI understands your requirements 4. At 80%+ confidence, the AI generates detailed Auto Run documents Inline Wizard The Inline Wizard creates documents in a unique subfolder under your Auto Run folder, keeping generated playbooks organized. When complete, your tab is renamed to reflect the project and you can immediately start running the generated tasks. ### Playbook Exchange Looking for pre-built playbooks? The [Playbook Exchange](./playbook-exchange) offers community-contributed playbooks for common workflows like security audits, code reviews, and documentation generation. Open it via Quick Actions (`Cmd+K`) or click the Exchange button in the Auto Run panel. ## Goal-Driven Mode Everything above describes **Spec-Driven** runs - documents of checkboxes worked to completion. **Goal-Driven** mode is the alternative: switch to the **Goal-Driven** tab in the Run dialog to chase a free-text objective instead of a document of checkboxes. Each iteration spawns a fresh agent that makes one increment of real progress toward the goal, reports how far along it is, and exits. The next iteration picks up where it left off, until the goal is reached or the run stops. Because there are no checklist documents, the playbook controls and the "Follow active task" option don't appear in this mode. Goal-Driven Auto Run ### Configuring a Goal Run Three inputs configure a run: * **Goal** - what you want accomplished, in plain language (e.g., "Migrate the settings store from Redux to Zustand and keep all tests green"). * **Exit Criteria** - what "done" looks like and when the agent should declare a deadlock instead of spinning. This guides the agent; it is **not** matched automatically. * **Iteration Limit** - a cap on how many iterations may run, or **Infinite** to run until the goal is reached or a deadlock is detected. Like Spec-Driven runs, a goal run can be [dispatched into an isolated git worktree](#run-in-worktree) so your main working tree stays clean. ### Progress Markers At the end of every iteration the agent reports an honest 0-100 self-assessment on its own line. The engine reads this to drive the progress bar and decide whether to run again: ```html theme={"theme":"dracula"} ``` The `| rationale` note after the number is optional but shows up in the progress UI. A response with no progress marker is treated as zero progress and counts toward a stall. ### How a Goal Run Stops A goal run ends on any of four conditions: * **Completed** - the agent reports `progress 100`, or emits the explicit marker ``. * **Deadlock** - the agent hits a true blocker it cannot work around and declares it with ``. * **Max iterations** - a finite iteration limit is reached before the goal completes. * **Stalled** - progress doesn't move upward for three iterations in a row, so the run stops instead of spinning. The stop reason and final progress are recorded in the **History** panel. ## Progress Tracking The runner will: * Process tasks serially from top to bottom * Skip documents with no unchecked tasks * Show progress: "Document X of Y" and "Task X of Y" * Mark tasks as complete (`- [x]`) when done * Log each completion to the **History** panel ## Thought Stream While a run is active, you can watch the agent's live reasoning without changing any settings. In the **Auto Run** card, click **View Thoughts** (the brain icon) to open the **Thought Stream** - a floating, searchable panel that streams the agent's thinking as it works. It works the same for **Spec-Driven** and **Goal-Driven** runs, because both flow through the same agent. The panel captures the raw reasoning stream directly, so it shows thoughts even when an AI tab's "show thinking" display is turned off. * **Newest on top** - the live thought sits at the top and grows; scroll down to read the history of the run. * **Timestamped blocks** - a continuous burst of thinking is grouped into one block with a time stamp; a pause (or a switch between parallel tabs) starts a new block. * **Formatted** - thoughts render as formatted markdown (headings, lists, bold, inline code, code fences), so structured reasoning stays readable. * **Search** - filter the captured thoughts with the search box; matches are highlighted. The button doubles as the live indicator: while capturing it pulses and reads **Capturing**. **Open, minimize, close:** * **Open** starts capturing for that agent and shows the panel. * **Minimize** collapses the panel but **keeps capturing** in the background, so you can reopen it later and review everything since you opened it. * **Close** stops capturing and clears that agent's buffer. Capture is in-memory only - it does not survive an app restart, and the buffer is bounded so a long run can't grow memory without limit (the oldest thoughts are dropped once the cap is reached, noted as "trimmed" in the panel header). Running several Auto Runs at once? Each agent captures into its own independent stream; opening the panel for one agent never mixes in another's thoughts. ## Session Isolation Each task executes in a completely fresh AI session with its own unique session ID. This provides: * **Clean context** - No conversation history bleeding between tasks * **Predictable behavior** - Tasks in looping playbooks execute identically each iteration * **Independent execution** - The agent approaches each task without memory of previous work This isolation is critical for playbooks with `Reset on Completion` documents that loop indefinitely. Each loop creates a fresh working copy from the original document, and the AI approaches it without memory of previous iterations. > **Note:** [Nudge messages](./general-usage#creating-agents) configured on an agent do not apply to Auto Run tasks. Nudge messages are only appended to interactive AI messages typed by the user. If you need persistent instructions for Auto Run tasks, include them directly in your task document or use environment variables. ## Environment Variables Maestro sets environment variables that your agent hooks can use to customize behavior: | Variable | Value | Description | | ------------------------- | ----- | ---------------------------------------------------------------- | | `MAESTRO_SESSION_RESUMED` | `1` | Set when resuming an existing session (not set for new sessions) | **Example: Conditional Hook Execution** Since Maestro spawns a new agent process for each message (batch mode), agent "session start" hooks will run on every turn. Use `MAESTRO_SESSION_RESUMED` to skip hooks on resumed sessions: ```bash theme={"theme":"dracula"} # In your agent's session start hook [ "$MAESTRO_SESSION_RESUMED" = "1" ] && exit 0 # ... rest of your hook logic for new sessions only ``` This works with any agent provider (Claude Code, Codex, OpenCode) since the environment variable is set by Maestro before spawning the agent process. ## History & Tracking Each completed task is logged to the History panel with: * **AUTO** label indicating automated execution * **Session ID** pill (clickable to jump to that AI conversation) * **Summary** of what the agent accomplished * **Full response** viewable by clicking the entry **Keyboard navigation in History**: * `Up/Down Arrow` - Navigate entries * `Enter` - View full response * `Esc` - Close detail view and return to list ## Expanded Editor View For editing complex Auto Run documents, use the **Expanded Editor** - a fullscreen modal that provides more screen real-estate. **To open the Expanded Editor:** * Click the **expand icon** (↗️) in the top-right corner of the Auto Run panel * Or press `Cmd+Shift+E` (Mac) / `Ctrl+Shift+E` (Windows/Linux) to toggle - works from anywhere in the interface, even when the Auto Run panel is closed * Or open the Command Palette (`Cmd+K`) and pick **Auto Run Expanded Preview** Expanded Auto Run Editor The Expanded Editor provides: * **Edit/Preview toggle** - Switch between editing markdown and previewing rendered output * **Document selector** - Switch between documents without closing the modal * **Run controls** - Start, stop, and monitor Auto Run progress from the expanded view * **Task progress** - See "X of Y tasks completed" and token count at the bottom * **Full toolbar** - Create new documents, refresh, and open folder Click **Collapse** or press `Esc` to return to the sidebar panel view. > **Maestro Pro Tip - a scratch pad from anywhere:** Because `Cmd+Shift+E` and the Command Palette open the Expanded Editor from anywhere (the Auto Run panel doesn't need to be open), it doubles as an always-available scratch pad. Keep a throwaway document in your Auto Run folder and, as ideas surface mid-session, pop open the editor and jot down tasks you want to kick off later. When you wrap up your interactive work, run that document to dispatch the whole batch at once. ## Saving Documents Save your changes with `Cmd+S` (Mac) or `Ctrl+S` (Windows/Linux), or click the **Save** button in the editor footer. The editor shows "Unsaved changes" and a **Revert** button when you have pending edits. Full undo/redo support with `Cmd+Z` / `Cmd+Shift+Z`. **Note**: Switching documents discards unsaved changes. Save before switching if you want to preserve your edits. ## Image Support Paste images directly into your documents. Images are saved to an `images/` subfolder with relative paths for portability. ## Stopping the Runner Click the **Stop** button at any time. The runner will: * Complete the current task before stopping * Preserve all completed work * Allow you to resume later by clicking Run again ## Auto-Resume on Limit If an agent pauses mid-run because it hit a provider limit (a rate, token, or credit limit), Maestro can pick the run back up on its own once the window reopens - so you can queue a batch of work, walk away, and come back to it finished. Enable it in **Settings → General → Auto-Resume on Limit**. Three settings drive it: * **Auto-Resume on Limit** (on by default) - the master toggle. * **Check interval** (default 2 hours) - how often Maestro re-checks each paused agent. * **Give up after** (default 7 days) - if an agent is still stuck this long after the first pause, Maestro stops retrying it, leaves it paused, and posts a one-time notice so you can resume manually. How it decides to resume: for Claude it reads your actual plan usage and only resumes when credits are genuinely available again; for every other provider (and Claude on an SSH remote) it simply retries on the interval - if the limit is still in force the agent re-pauses and the next check tries again. Probing is cheap, so it keeps trying the whole window. This survives a full app restart. If you reboot while an agent is limit-paused, Maestro restores the pause and resumes the **agent's conversation** (it continues from its own transcript) and drains any work you had queued. One caveat: the Auto Run / Goal-Driven **loop controller** does not survive a restart - the agent session and its queued messages resume, but the orchestration loop that was stepping through your document does not pick back up automatically. Manually resolving the error, or manually resuming or stopping the agent, always takes precedence and cancels auto-resume for that agent. ## Halt Marker (Agent Early Exit) Sometimes the agent itself discovers that the rest of the playbook cannot meaningfully proceed - a missing dependency, a broken precondition, an ambiguous spec it cannot resolve, or a destructive change it refuses to make. In that case the agent can abort the entire run by writing a halt marker into the current document: ```html theme={"theme":"dracula"} ``` When the engine re-reads the document after the task and finds this marker, it stops dispatch immediately: * No further tasks in the current document * No further documents in the playbook * The reason text is recorded in the History panel * A `halt` event is emitted to the JSONL stream, followed by a `complete` event with `success: false` and the same reason The bare form `` works without a reason, but agents are instructed to always include one. The agent should leave the unfinishable task **unchecked** so you can see exactly where execution stopped. This is distinct from clicking **Stop** (a manual user action) or a single task simply failing (which by default does **not** halt the playbook - Auto Run is designed to run independent tasks, so one failure doesn't invalidate the rest). A stale halt marker left in a document will block re-runs with an error - Auto Run refuses to start so previously-halted work isn't silently replayed. Remove the marker before launching the playbook again. ## Parallel Auto Runs Auto Run can execute in parallel across different agents without conflicts - each agent works in its own project directory, so there's no risk of clobbering each other's work. **Same project, parallel work:** To run multiple Auto Runs in the same repository simultaneously, create worktree sub-agents from the git branch menu (see [Git Worktrees](./git-worktrees)). Each worktree operates in an isolated directory with its own branch, enabling true parallel task execution on the same codebase. ### Run in Worktree You can dispatch an Auto Run directly into a new git worktree from the run configuration modal. This spins up an isolated branch and directory for the entire run, keeping your main working tree clean. Run in Worktree | Option | Description | | ----------------------------------- | ------------------------------------------------------------------------------------------ | | **Dispatch to a separate worktree** | Toggle to enable worktree isolation for this run | | **Worktree selection** | Create a new worktree or select an existing one | | **Base Branch** | The branch to base the new worktree on (e.g., `main`) | | **Worktree Branch Name** | Name for the new branch - also used as the worktree directory name | | **Automatically create PR** | When checked, Maestro opens a pull request from the worktree branch when the run completes | This is the recommended workflow for longer Auto Runs - your main branch stays untouched, all changes land on a dedicated branch, and you get a PR at the end ready for review. # BMAD Commands Source: https://docs.runmaestro.ai/bmad-commands Use BMAD Method workflows inside Maestro's AI Commands panel. # BMAD Commands Maestro bundles a curated set of prompts from [bmad-code-org/BMAD-METHOD](https://github.com/bmad-code-org/BMAD-METHOD) and exposes them in **Settings -> AI Commands**. You can review, edit, and reset these prompts the same way you can with Spec-Kit and OpenSpec. ## What Is Included The BMAD bundle covers the main workflow families published by BMAD: * **Core utilities** like `/bmad-help`, `/bmad-brainstorming`, `/bmad-party-mode`, `/bmad-index-docs`, and review-oriented prompts * **Analysis workflows** like `/bmad-bmm-market-research`, `/bmad-bmm-domain-research`, `/bmad-bmm-technical-research`, and `/bmad-bmm-create-product-brief` * **Planning workflows** like `/bmad-bmm-create-prd`, `/bmad-bmm-validate-prd`, `/bmad-bmm-edit-prd`, and `/bmad-bmm-create-ux-design` * **Solutioning workflows** like `/bmad-bmm-create-architecture`, `/bmad-bmm-create-epics-and-stories`, and `/bmad-bmm-check-implementation-readiness` * **Implementation workflows** like `/bmad-bmm-sprint-planning`, `/bmad-bmm-create-story`, `/bmad-bmm-dev-story`, `/bmad-bmm-code-review`, and `/bmad-bmm-qa-automate` * **Quick flow workflows** like `/bmad-bmm-quick-spec`, `/bmad-bmm-quick-dev`, and `/bmad-bmm-quick-dev-new-preview` ## Important Prerequisite Many BMAD prompts assume the target repository already contains BMAD's project artifacts such as the `_bmad/` directory, workflow configs, sprint files, and generated planning documents. If those files are missing, the prompt may still provide guidance, but BMAD works best when the repository has already been prepared with the BMAD installer or equivalent project structure. ## Bundle Version The BMAD bundle is pinned to **v6.2.0**, the last BMAD release whose workflows run as standalone slash commands. Newer releases moved to a skills-based architecture that requires a local install and a resolver script, so they are not compatible with Maestro's paste-in prompt model. For this reason the BMAD section shows a **Frozen** badge instead of a "Check for Updates" button. Spec-Kit and OpenSpec still pull updates from upstream; BMAD does not. ## Editing Prompts Each bundled BMAD command can be: * expanded to inspect the current prompt * edited and saved locally * reset back to the bundled default Local edits are stored in Maestro's application data and do not modify the upstream BMAD project. # Command Line Interface Source: https://docs.runmaestro.ai/cli Send messages to agents, list sessions, run playbooks, and manage Maestro settings from the command line. Maestro includes a CLI tool (`maestro-cli`) for sending messages to agents, browsing sessions, running playbooks, managing settings, and controlling resources from the command line, cron jobs, or CI/CD pipelines. The CLI requires Node.js (which you already have if you're using Claude Code). ## Installation The CLI is bundled with Maestro as a JavaScript file. Create a shell wrapper to run it: ```bash theme={"theme":"dracula"} # macOS (after installing Maestro.app) printf '#!/bin/bash\nnode "/Applications/Maestro.app/Contents/Resources/maestro-cli.js" "$@"\n' | sudo tee /usr/local/bin/maestro-cli && sudo chmod +x /usr/local/bin/maestro-cli # Linux (deb/rpm installs to /opt) printf '#!/bin/bash\nnode "/opt/Maestro/resources/maestro-cli.js" "$@"\n' | sudo tee /usr/local/bin/maestro-cli && sudo chmod +x /usr/local/bin/maestro-cli # Windows (PowerShell as Administrator) - create a batch file @" @echo off node "%ProgramFiles%\Maestro\resources\maestro-cli.js" %* "@ | Out-File -FilePath "$env:ProgramFiles\Maestro\maestro-cli.cmd" -Encoding ASCII ``` Alternatively, run directly with Node.js: ```bash theme={"theme":"dracula"} node "/Applications/Maestro.app/Contents/Resources/maestro-cli.js" list groups ``` ## Usage ### Global Flags and Exit Codes Two flags work on every command: | Flag | Description | | ------------- | ------------------------------------------------------------------------------ | | `-q, --quiet` | Suppress incidental success output (errors still print). Never gates `--json`. | | `--verbose` | Print extra detail where available | Commands exit with a standardized code so scripts and CI can branch on the failure class: | Code | Meaning | | ---- | ---------------------------------------------------------- | | `0` | Success | | `1` | Generic / uncategorized failure | | `2` | Invalid usage (unknown flag, bad argument, nothing to do) | | `3` | The Maestro desktop app is not running or not reachable | | `4` | The running app does not support the command (older build) | | `5` | The app was reachable but did not respond in time | ### Sending Messages to Agents Send a message to an agent and receive a structured JSON response. Supports creating new sessions or resuming existing ones for multi-turn conversations. ```bash theme={"theme":"dracula"} # Send a message to an agent (creates a new session) maestro-cli send "describe the authentication flow" # Resume an existing session for follow-up maestro-cli send "now add rate limiting" -s # Send in read-only mode (agent can read but not modify files) maestro-cli send "analyze the code structure" -r ``` The response is always JSON: ```json theme={"theme":"dracula"} { "agentId": "a1b2c3d4-...", "agentName": "My Agent", "sessionId": "abc123def456", "response": "The authentication flow works by...", "success": true, "usage": { "inputTokens": 1000, "outputTokens": 500, "cacheReadInputTokens": 200, "cacheCreationInputTokens": 100, "totalCostUsd": 0.05, "contextWindow": 200000, "contextUsagePercent": 1 } } ``` On failure, `success` is `false` and an `error` field is included: ```json theme={"theme":"dracula"} { "success": false, "error": "Agent not found: bad-id", "code": "AGENT_NOT_FOUND" } ``` | Flag | Description | | -------------------- | ------------------------------------------------------------- | | `-s, --session ` | Resume an existing session instead of creating a new one | | `-r, --read-only` | Run in read-only/plan mode (agent cannot modify files) | | `-t, --tab` | Open/focus the agent's session tab in the Maestro desktop app | For desktop-handoff workflows (route the message through a desktop tab, return an addressable tab id, etc.) use [`maestro-cli dispatch`](#dispatching-to-a-desktop-tab) instead. Error codes: `AGENT_NOT_FOUND`, `AGENT_UNSUPPORTED`, `_NOT_FOUND` (e.g. `CLAUDE_CODE_NOT_FOUND`, `CODEX_NOT_FOUND`), `MAESTRO_NOT_RUNNING`, `COMMAND_FAILED`. Supported agent types: any installed provider - `claude-code`, `codex`, `opencode`, `factory-droid`, `copilot-cli`, `hermes`, `pi`, `qwen3-coder`, `omp`. #### Messages that start with a dash Messages whose first character is a Unicode dash (U+2014 em dash or U+2013 en dash), a double hyphen (`--`), or an ASCII hyphen/minus (`-`) collide with option parsing and will be rejected as unknown flags. Use the standard `--` end-of-options separator so the message is passed verbatim: ```bash theme={"theme":"dracula"} maestro-cli send -- "- revise the spec" maestro-cli send -s -- "--re-run" maestro-cli dispatch -- "--force the rewrite" ``` Everything after `--` is treated as positional, so any flags you need must come before the separator. For `send` that's `-s`, `-r`, `-t` (`-t` is the boolean focus flag here); for `dispatch` it's `-t`/`--tab`, `--new-tab`, `-f`. ### Dispatching to a Desktop Tab `dispatch` hands a prompt to an agent in the running Maestro desktop app and returns the tab/session id, so callers can address the same tab on follow-up calls without holding a persistent channel. Use this for orchestration use cases (Cue pipelines, external bots, multi-step automations). ```bash theme={"theme":"dracula"} # Dispatch to the active tab of an agent maestro-cli dispatch "review the PR description" # Open a fresh tab and dispatch the prompt into it maestro-cli dispatch "start a new review pass" --new-tab # Continue a previous dispatch by targeting its tab maestro-cli dispatch "and now run the tests" -t # Force a write to a busy tab (requires allowConcurrentSend=true) maestro-cli dispatch "interrupt with this" -f ``` Output is always JSON. `sessionId` and `tabId` are the same value, duplicated so polling consumers can use either name: ```json theme={"theme":"dracula"} { "success": true, "agentId": "a1b2c3d4-...", "sessionId": "tab-xyz", "tabId": "tab-xyz" } ``` | Flag | Description | | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | | `--new-tab` | Create a fresh AI tab in the target agent. Mutually exclusive with `-t` and `-f` (a new tab is never busy, so `--force` has nothing to bypass) | | `-t, --tab ` | Target an existing tab by id (from a previous `dispatch`). Mutually exclusive with `--new-tab` | | `-f, --force` | Bypass the busy-state guard. Gated by `allowConcurrentSend`; errors with code `FORCE_NOT_ALLOWED`. Cannot be combined with `--new-tab` | Error codes: `INVALID_OPTIONS`, `AGENT_NOT_FOUND`, `FORCE_NOT_ALLOWED`, `MAESTRO_NOT_RUNNING`, `SESSION_NOT_FOUND`, `NEW_TAB_NO_ID`, `COMMAND_FAILED`. `NEW_TAB_NO_ID` fires when the desktop app acknowledges `--new-tab` without returning a tab id, leaving callers nothing to chain follow-up dispatches against. Requires the Maestro desktop app to be running. ### Dispatch with Callback (`--notify-on-complete`) `dispatch` is fire-and-forget: it returns a tab id and exits, and nothing tells the caller when that delegated run finished. `--notify-on-complete` closes that loop. When the dispatch finishes, Maestro starts a **real turn in the calling agent's live tab** carrying the result plus a handle to the full output, so an orchestrator can run build -> review -> fix -> verify without a human relaying "it's done, carry on". ```bash theme={"theme":"dracula"} # Delegate a review, and wake me when it is done maestro-cli dispatch "review the diff on feat/x" \ --new-tab \ --notify-on-complete ``` The response echoes the armed callback: ```json theme={"theme":"dracula"} { "success": true, "agentId": "reviewer-...", "sessionId": "tab-xyz", "tabId": "tab-xyz", "callbackId": "cb_01j...", "notifyOnComplete": "orchestrator-..." } ``` | Flag | Description | | --------------------------------- | ----------------------------------------------------------------------------------------- | | `--notify-on-complete ` | Agent to wake when this dispatch finishes. Requires `--new-tab` or `--tab` | | `--callback-tab ` | Specific caller tab to wake. Default: the caller's active AI tab | | `--callback-prompt ` | Replace the default wake-up prompt body. `{{DISPATCH_*}}` variables below are substituted | | `--callback-timeout ` | Give up and fire a `timeout` callback after this long. Default 3600, hard cap 86400 | **Semantics** * **Correlated.** The callback is bound to the `(target agent, target tab)` pair established at dispatch time, and only arms once the dispatched process actually starts. Other tabs of the same agent, and a predecessor turn a `--queue`d dispatch is waiting behind, never trigger it. This is why an explicit `--new-tab` or `--tab` is required. * **Fires exactly once**, on final completion. A second exit is a no-op. * **Auto Run aware.** If the dispatched prompt starts an Auto Run, the callback waits for the whole batch, not for task 1. A 6-task run wakes the caller once. * **Carries a handle, not just a slice.** The inlined result is capped at 5000 characters (same as Cue's `{{CUE_SOURCE_OUTPUT}}`); `{{DISPATCH_TARGET_ID}}` and `{{DISPATCH_TAB_ID}}` let the caller read the untruncated transcript with `maestro-cli session show `. * **Busy-safe delivery.** The wake-up turn goes through the same execution queue `dispatch --queue` uses, so a busy caller gets it on its next idle turn instead of having it dropped or interleaved. * **Self-cleaning.** Entries live in a main-process registry, never in `cue.yaml`. They expire on timeout and are dropped when the dispatch is rejected. They do not survive a desktop restart. * **Non-blocking.** The dispatching turn ends normally; the callback opens a new turn later. **Callback prompt variables** (usable in `--callback-prompt`): `{{DISPATCH_CALLBACK_ID}}`, `{{DISPATCH_TARGET_ID}}`, `{{DISPATCH_TARGET_NAME}}`, `{{DISPATCH_TAB_ID}}`, `{{DISPATCH_STATUS}}` (`completed` | `failed` | `timeout` | `cancelled`), `{{DISPATCH_EXIT_CODE}}`, `{{DISPATCH_DURATION}}`, `{{DISPATCH_OUTPUT}}`, `{{DISPATCH_OUTPUT_TRUNCATED}}`, `{{DISPATCH_TASKS_COMPLETED}}`, `{{DISPATCH_TASKS_TOTAL}}`, `{{DISPATCH_PROMPT}}`. > \[!NOTE] > `{{DISPATCH_OUTPUT}}` is another agent's output landing in your agent's prompt - the same trust model as Cue's `{{CUE_SOURCE_OUTPUT}}` and cross-agent consults. The default wrapper fences it and labels it as untrusted data. Keep that fencing if you supply your own `--callback-prompt`. Additional error cases: a callback agent that cannot be resolved (`AGENT_NOT_FOUND`), a callback that targets the dispatch tab itself, a tab that already has an armed callback (`CALLBACK_ALREADY_ARMED`), and callback flags passed without `--notify-on-complete` (all `INVALID_OPTIONS`). ### Listing Sessions Browse an agent's session history, sorted most recent to oldest. Supports pagination with limit/skip and keyword search. ```bash theme={"theme":"dracula"} # List the 25 most recent sessions maestro-cli list sessions # Limit to 10 results maestro-cli list sessions -l 10 # Paginate: skip the first 25, show next 25 maestro-cli list sessions -k 25 # Page 3 of 10-item pages maestro-cli list sessions -l 10 -k 20 # Search for sessions by keyword (matches session name and first message) maestro-cli list sessions -s "authentication" # Combine limit, skip, and search with JSON output maestro-cli list sessions -l 50 -k 0 -s "refactor" --json ``` | Flag | Description | Default | | ------------------------ | -------------------------------------------------- | ------- | | `-l, --limit ` | Maximum number of sessions to return | 25 | | `-k, --skip ` | Number of sessions to skip (for pagination) | 0 | | `-s, --search ` | Filter by keyword in session name or first message | - | | `--json` | Output as JSON | - | JSON output includes full session metadata: ```json theme={"theme":"dracula"} { "success": true, "agentId": "a1b2c3d4-...", "agentName": "My Agent", "totalCount": 42, "filteredCount": 3, "sessions": [ { "sessionId": "abc123", "sessionName": "Auth refactor", "modifiedAt": "2026-02-08T10:00:00.000Z", "firstMessage": "Help me refactor the auth module...", "messageCount": 12, "costUsd": 0.05, "inputTokens": 5000, "outputTokens": 2000, "durationSeconds": 300, "starred": true } ] } ``` Currently supported for `claude-code` agents. ### Session Inspection Inspect open AI tabs across the running Maestro desktop app and read their conversation history. Pair `dispatch --new-tab` (writes, returns a `tabId`) with `session show ` (reads, supports `--since` and `--tail`) to build a stateless poll loop without owning a persistent connection - used by Maestro-Discord and Cue follow-ups. Both verbs talk to the running desktop over the same WebSocket as `dispatch`. There is no on-disk fallback: if the app is not running, the CLI exits with code `MAESTRO_NOT_RUNNING`. #### List Open Tabs Flatten every open AI tab across every Maestro agent into addressable entries: ```bash theme={"theme":"dracula"} # Default: compact text (one tab per line) maestro-cli session list # JSON for scripting maestro-cli session list --json ``` Default text columns: `state` (`busy` / `idle`), star (`★` if starred), `tabId`, agent name + id, tab name, `createdAt` (relative). One tab per line so the output pipes cleanly into `grep`, `awk`, etc. JSON envelope: ```json theme={"theme":"dracula"} { "success": true, "sessions": [ { "tabId": "tab-1", "sessionId": "tab-1", "agentId": "a1b2c3d4-...", "agentName": "Backend", "toolType": "claude-code", "name": "Refactor parser", "agentSessionId": "claude-uuid-1", "state": "idle", "createdAt": 1714268000000, "starred": false } ] } ``` To extract just `tabId`s with `jq`: `maestro-cli session list --json | jq '.sessions[].tabId'`. #### Show Conversation History Print a tab's conversation log, with optional cursor (`--since`) and cap (`--tail`) filters applied desktop-side so the wire payload stays small even on long conversations. ```bash theme={"theme":"dracula"} # Default: formatted transcript (header + per-message blocks) maestro-cli session show # JSON for scripting maestro-cli session show --json # Only messages newer than an ISO-8601 timestamp maestro-cli session show --since "2026-04-28T10:00:00Z" # `--since` also accepts a bare epoch number (auto-detects ms vs sec by magnitude, # so both `Date.now()` and `Date.now() / 1000` cursors work without a unit flag) maestro-cli session show --since 1714268000 # Cap at the last N messages (applied after `--since`) maestro-cli session show --tail 20 # Combine cursor + cap for poll loops maestro-cli session show --since "$LAST_TS" --tail 50 ``` | Flag | Description | | --------------------- | ------------------------------------------------------------------------------------------ | | `--since ` | Only return messages strictly after this timestamp (ISO-8601, or epoch ms/sec auto-scaled) | | `--tail ` | Cap output to the last N messages (non-negative integer; applied after `--since`) | | `--json` | Output as JSON (default is a formatted transcript) | JSON shape: ```json theme={"theme":"dracula"} { "success": true, "tabId": "tab-1", "sessionId": "tab-1", "agentId": "a1b2c3d4-...", "agentSessionId": "claude-uuid-1", "messages": [ { "id": "log-1", "role": "user", "source": "user", "content": "Hello", "timestamp": "2026-04-28T10:00:00.000Z" }, { "id": "log-2", "role": "assistant", "source": "ai", "content": "Hi there", "timestamp": "2026-04-28T10:00:01.000Z" } ] } ``` `role` is a coarse classification (`user` | `assistant` | `system` | `tool` | `thinking` | `error` | `unknown`) so conversational consumers can branch on intent; the raw `source` is preserved alongside for callers that need to discriminate further. ISO timestamps are emitted verbatim so a `messages[-1].timestamp` from one call can be fed directly back into `--since` on the next. Error codes: `MISSING_TAB_ID`, `TAB_NOT_FOUND`, `INVALID_OPTION`, `MAESTRO_NOT_RUNNING`, `COMMAND_FAILED`. All errors are emitted as `{ "success": false, "error": "...", "code": "..." }` with exit code `1`. ### Creating, Updating, and Removing Agents Create, mutate, or delete agents directly from the command line. Requires the Maestro desktop app to be running. ```bash theme={"theme":"dracula"} # Create a Claude Code agent with a working directory maestro-cli create-agent "My Agent" -d /path/to/project # Create a Codex agent with custom model and environment variables maestro-cli create-agent "Codex Worker" -d . -t codex --model gpt-5.3-codex --env API_KEY=abc123 # Create an agent with SSH remote execution maestro-cli create-agent "Remote Agent" -d /home/user/project -t claude-code --ssh-remote # Create an agent with all options maestro-cli create-agent "Full Config" -d /workspace \ -t claude-code \ -g \ --nudge "Always write tests" \ --new-session-message "You are a senior engineer working on project X" \ --custom-path /usr/local/bin/claude \ --custom-args "--verbose" \ --env DEBUG=true --env LOG_LEVEL=info \ --model opus \ --effort high \ --context-window 200000 \ --provider-path /custom/provider \ --ssh-remote \ --ssh-cwd /remote/workdir \ --auto-run-folder ~/playbooks/full-config # Remove an agent maestro-cli remove-agent # Rename an agent maestro-cli rename-agent "New Name" # Move an agent into a group (use "none" to ungroup) maestro-cli update-agent --group maestro-cli update-agent --group none # Change an agent's working directory (refused while the agent process is running) maestro-cli update-agent --cwd /new/path/to/project # Combine both in a single call maestro-cli update-agent --group --cwd /new/path # Edit the agent's settings - the same fields as the Edit Agent modal maestro-cli update-agent --nudge "Always write tests" maestro-cli update-agent --new-session-message "You are a senior engineer" maestro-cli update-agent --model opus --effort high --context-window 200000 maestro-cli update-agent --env DEBUG=true --env LOG_LEVEL=info maestro-cli update-agent --custom-path /usr/local/bin/claude --custom-args "--verbose" # Clear a field by passing an empty string; --clear-env empties the env map maestro-cli update-agent --nudge "" maestro-cli update-agent --clear-env # Set the Claude token source (Claude Code agents only): api | tui | dynamic maestro-cli update-agent --token-source tui # Update SSH execution config (use "none" to revert to local) maestro-cli update-agent --ssh-remote --ssh-cwd /remote/workdir maestro-cli update-agent --ssh-remote none maestro-cli update-agent --sync-history-to-remote true ``` `update-agent` mutates an existing agent in place, writing the same live desktop Session the Edit Agent modal edits (not the per-agent config store that `settings agent set` writes). Read the current values back with `maestro-cli show agent --json`. The group update reuses the same write path as drag-and-drop in the Left Bar. The cwd update only moves the UI-facing working directory (`cwd`/`fullPath`) - `projectRoot` is preserved so historical provider sessions stay addressable, which keeps prior conversation history attached when you relocate an archived project folder. Stop the agent before changing its cwd or SSH config; the underlying PTY's working directory and spawn target are fixed at launch time, so the renderer refuses those updates while the process is alive and surfaces the reason on stderr. The remaining settings (nudge, messages, model, effort, env, token source, etc.) are spawn-time values and apply on the next launch, so they are accepted even while the agent is running. For text fields, passing an empty string (for example `--nudge ""`) clears the field. `--env` replaces the environment map with the provided pairs; `--clear-env` empties it. `--context-window 0` (or `none`) clears the context-window override. `--token-source` only carries meaning for Claude Code agents: `api` uses `claude --print` (per-token API credit), `tui` drives the maestro-p TUI (Max-plan quota), and `dynamic` starts on the TUI and falls back to API when a usage window hits its limit. The `tui` and `dynamic` modes need the [maestro-p helper](https://runmaestro.ai/maestro-p/) on PATH; it is bundled locally, but for SSH remotes it must be installed on the remote host. See [Provider Notes](/provider-notes#token-source-max-plan-vs-api). | Flag | Description | Default | | --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | | `-g, --group ` | Move the agent to this group; supports partial IDs. Use `none` (or `null`) to ungroup | - | | `-d, --cwd ` | New working directory (resolved to absolute). Agent must be stopped | - | | `--ssh-remote ` | SSH remote for remote execution. Use `none` to revert to local. Agent must be stopped | - | | `--ssh-cwd ` | Working directory override on the SSH remote | - | | `--sync-history-to-remote ` | Sync history entries to `.maestro/history/` on the remote host | - | | `--nudge ` | Nudge message appended to every message. Empty string clears | - | | `--new-session-message ` | Message prefixed to the first message of new sessions. Empty string clears | - | | `--custom-path ` | Override the agent binary path. Empty string clears | - | | `--custom-args ` | Custom CLI arguments. Empty string clears | - | | `--env ` | Set an environment variable (repeatable; replaces the env map) | - | | `--clear-env` | Clear all per-agent environment variables | - | | `--model ` | Model override (e.g. sonnet, opus). Empty string clears | - | | `--effort ` | Effort/reasoning level override. Empty string clears | - | | `--context-window ` | Context window size in tokens. `0` or `none` clears | - | | `--token-source ` | Claude Code token source: `api`, `tui`, or `dynamic` (Claude Code agents only) | - | | `--maestro-p-path ` | Override the maestro-p binary path. Empty string clears | - | | `--provider ` | Switch the agent's provider. Destructive: resets tabs and clears provider config. Requires `--force`. Cannot be combined with other settings edits | - | | `--force` | Confirm a destructive change (required for `--provider`) | - | | `--json` | Machine-readable JSON output | - | The flag table below covers `create-agent`: | Flag | Description | Default | | --------------------------------- | -------------------------------------------------------- | -------------------------- | | `-d, --cwd ` | Working directory for the agent (required) | - | | `-t, --type ` | Agent type (claude-code, codex, opencode, factory-droid) | `claude-code` | | `-g, --group ` | Group ID to assign the agent to | - | | `--nudge ` | Nudge message appended to every user message | - | | `--new-session-message ` | Message prefixed to first message in new sessions | - | | `--custom-path ` | Custom binary path for the agent CLI | - | | `--custom-args ` | Custom CLI arguments | - | | `--env ` | Environment variable (repeatable) | - | | `--model ` | Model override (e.g., sonnet, opus) | - | | `--effort ` | Effort/reasoning level override | - | | `--context-window ` | Context window size in tokens | - | | `--provider-path ` | Custom provider path | - | | `--ssh-remote ` | SSH remote ID for remote execution | - | | `--ssh-cwd ` | Working directory override on the SSH remote | - | | `--auto-run-folder ` | Auto Run / playbooks folder for this agent | `/.maestro/playbooks` | | `--json` | Machine-readable JSON output | - | ### Creating and Removing Groups Manage Left Bar groups from the command line. Requires the Maestro desktop app to be running. Use a group ID with `create-agent -g` or `update-agent --group` to place agents into it, and `update-agent --group none` to move an agent back out. ```bash theme={"theme":"dracula"} # Create a group maestro-cli create-group "Backend" # Create a group with an emoji icon maestro-cli create-group "Backend" -e 🔧 # Machine-readable output (returns the new group ID) maestro-cli create-group "Backend" --json # Remove an (empty) group maestro-cli remove-group # Remove a group that still has agents (ungroups them first) maestro-cli remove-group --force # Rename a group maestro-cli rename-group "Frontend" ``` Removing a group never deletes the agents inside it: the desktop ungroups any members (moves them to no group) and then removes the group. `remove-group` refuses a non-empty group unless you pass `--force`, so you don't accidentally scatter a populated group. Group IDs support partial-ID resolution. `create-group` flags: | Flag | Description | Default | | --------------------- | ---------------------------- | ------- | | `-e, --emoji ` | Emoji icon for the group | - | | `--json` | Machine-readable JSON output | - | `remove-group` flags: | Flag | Description | Default | | ------------- | --------------------------------------------------------- | ------- | | `-f, --force` | Delete even if the group still has agents (ungroups them) | - | | `--json` | Machine-readable JSON output | - | ### Creating Worktree Agents Branch a new agent off an existing parent agent into its own git worktree, without an Auto Run playbook. This mirrors the desktop "create worktree" flow: the parent agent must already exist in the running app, the desktop creates the worktree on disk and a child session linked to the parent, then hands back the new agent's ID. ```bash theme={"theme":"dracula"} # Create a worktree agent off a parent, on a new branch maestro-cli create-worktree -a -b feature/new-thing # Base the new branch on a specific ref when it does not yet exist maestro-cli create-worktree -a -b feature/new-thing --base-branch rc # Create the worktree and immediately dispatch an initial prompt to it maestro-cli create-worktree -a -b feature/new-thing -m "Start on the API layer" ``` The optional `--message` is delivered to the new agent as a plain prompt (not an Auto Run loop) on the same connection, addressed by the ID the desktop just returned. Both `--agent` and `--branch` support the usual partial-ID resolution. | Flag | Description | Default | | ---------------------- | ----------------------------------------------------------------------------- | ---------------- | | `-a, --agent ` | Parent agent ID the worktree branches from (required) | - | | `-b, --branch ` | Branch name for the worktree, created if it does not exist (required) | - | | `--base-branch ` | Ref the new branch is based on when it does not yet exist (e.g. `rc`, `main`) | parent repo HEAD | | `-m, --message ` | Optional initial prompt dispatched to the new agent after creation | - | | `--json` | Machine-readable JSON output | - | ### Driving the Workspace (Focus, Mode, Tabs) Steer the desktop UI itself: focus an agent, flip an agent between AI and terminal mode, and manage an agent's AI tabs. These mirror clicking around the app and require the desktop app to be running. ```bash theme={"theme":"dracula"} # Focus (select) an agent in the Left Bar; optionally focus a specific tab maestro-cli focus-agent maestro-cli focus-agent --tab # Switch an agent between AI chat and terminal mode maestro-cli switch-mode ai maestro-cli switch-mode terminal # Open a new tab for an agent (optionally seed an AI tab with a prompt) maestro-cli tab new -a maestro-cli tab new -a --prompt "Start reviewing the API layer" # Close, rename, star, or unstar a tab. The owning agent is resolved from the # tab ID automatically, so you only need the tab ID (exact or a unique prefix). maestro-cli tab close maestro-cli tab rename "Docs" maestro-cli tab star maestro-cli tab unstar ``` Find tab IDs with `maestro-cli session list`. `tab new` returns the new tab's ID (printed, or in the JSON payload with `--json`). An agent running inside Maestro gets its **own** tab ID in its system prompt (the `Tab ID` line under Session Information, from the `{{TAB_ID}}` variable), so you can just tell it "close this tab" or "rename this tab to Docs" and it will act on the right one. Every other entry in `session list` is a different live conversation, so agents are instructed never to guess a tab ID from that list. ### Listing Resources ```bash theme={"theme":"dracula"} # List all groups maestro-cli list groups # List all agents maestro-cli list agents maestro-cli list agents -g maestro-cli list agents --group # Show agent details (history, usage stats, cost) maestro-cli show agent # List all playbooks (or filter by agent) maestro-cli list playbooks maestro-cli list playbooks -a maestro-cli list playbooks --agent # Show playbook details maestro-cli show playbook ``` ### Running Playbooks ```bash theme={"theme":"dracula"} # Run a playbook maestro-cli playbook # Dry run (shows what would be executed) maestro-cli playbook --dry-run # Run without writing to history maestro-cli playbook --no-history # Wait for agent if busy, with verbose output maestro-cli playbook --wait --verbose # Debug mode for troubleshooting maestro-cli playbook --debug # Run this playbook on a different model than the agent's default maestro-cli playbook --model opus --effort high # Clean orphaned playbooks (for deleted sessions) maestro-cli clean playbooks maestro-cli clean playbooks --dry-run ``` ### Goal-Driven Auto Run Spec-Driven runs (the `playbook` command above) work through a checklist of documents. Goal-Driven runs instead pursue a single free-text objective: each iteration spawns a fresh agent that makes one increment of progress, reports how far along it is, and exits, repeating until the goal is reached, a deadlock is declared, the iteration limit is hit, or progress stalls. ```bash theme={"theme":"dracula"} # Run until the goal is reached or a deadlock is detected (infinite iterations) maestro-cli goal-run "Migrate the settings store from Redux to Zustand and keep all tests green" # Spell out what "done" looks like (guides the agent; not matched automatically) maestro-cli goal-run "Improve test coverage" \ --exit-criteria "Done when coverage is above 90% and all tests pass" # Cap the number of iterations maestro-cli goal-run "Refactor the auth module" --max-iterations 10 # Machine-parseable JSON lines for scripting / CI maestro-cli goal-run "Fix all lint errors" --json # Show the full prompt sent to the agent each iteration maestro-cli goal-run "Tidy the codebase" --verbose # Run without writing history entries maestro-cli goal-run "Quick experiment" --no-history # Pursue the goal on a different model than the agent's default maestro-cli goal-run "Port the parser to the new API" --model opus --effort high ``` | Option | Description | Default | | ------------------------ | ----------------------------------------------------------------------------- | ------------- | | `--exit-criteria ` | What "done" looks like and when to declare a deadlock | *(none)* | | `--max-iterations ` | Cap the number of iterations | Infinite | | `--no-history` | Do not write history entries | Writes | | `--json` | Output as JSON lines (for scripting) | Human text | | `--verbose` | Show the full prompt sent to the agent on each iteration | Off | | `--model ` | Model to use for this run only, overriding the agent's configured default | Agent default | | `--effort ` | Reasoning effort for this run only, overriding the agent's configured default | Agent default | The run writes an immediate "started" history entry (recording the goal and exit criteria), one entry per iteration, and a final summary with the stop reason and final progress. Goal-Driven runs honor the same per-agent SSH remote and model/effort/args overrides as `playbook`, and refuse to start if the agent is already busy in the desktop app or another CLI instance. **JSON event stream:** `goal_start`, `goal_iteration_start`, `goal_iteration_complete` (carries `progress`, `rationale`, `complete`, `deadlock`), and `goal_complete` (carries `success`, `exitReason`, `finalProgress`, `iterations`). ### Running Documents Without a Playbook (`run-doc`) `run-doc` runs one or more Auto Run `.md` documents directly, without saving a playbook first. Like `playbook`, it runs **headlessly** - it spawns the target agent itself and streams events, so it works whether or not the Maestro desktop window is open. This is the reliable way to execute a document an agent just wrote. ```bash theme={"theme":"dracula"} # Run a single document on an agent (by ID or name) maestro-cli run-doc plans/frontend-plan.md --agent "Frontend" # The path may be relative to the agent's Auto Run folder, relative to the # current directory, or absolute. Multiple documents run in sequence. maestro-cli run-doc plan-a.md plan-b.md --agent # Wait for the agent if it is busy, loop until all tasks are done maestro-cli run-doc plans/migrate.md --agent --wait --loop # JSON output for scripting; skip history writes maestro-cli run-doc plans/spec.md --agent --json --no-history # Run this document on a different model than the agent's default maestro-cli run-doc plans/spec.md --agent --model opus --effort high ``` `run-doc` accepts the same execution flags as `playbook` (`--dry-run`, `--no-history`, `--json`, `--debug`, `--verbose`, `--no-synopsis`, `--wait`, `--model`, `--effort`) plus `--prompt`, `--loop`, `--max-loops`, and `--reset-on-completion`. When no `--prompt` is given it uses the default Auto Run prompt. #### Per-run model override All four Auto Run entry points - `playbook`, `run-doc`, `goal-run`, and `auto-run` - accept `--model ` and `--effort `. Both are **run-scoped**: they apply to every agent spawn the run makes (including the per-task synopsis and goal-handoff spawns) and take precedence over the agent's configured model, but nothing is written back to the agent. When the run ends, the agent is exactly as it was. ```bash theme={"theme":"dracula"} maestro-cli playbook --model opus maestro-cli run-doc plans/spec.md --agent --model opus maestro-cli goal-run "Ship the migration" --model opus --effort high maestro-cli auto-run doc1.md --agent --launch --model opus ``` Notes: * Omitting the flags keeps the existing behavior exactly: the run uses the agent's configured model and effort. * Valid values are provider-specific (for example `sonnet` / `opus` for Claude Code). The CLI passes the value through rather than validating it against the provider's model list. * `--effort` only does something on providers that expose a reasoning-effort setting; it is ignored elsewhere. * The headless commands (`playbook`, `run-doc`, `goal-run`) print a `Model: (this run only)` line in human-readable (non-`--json`) output so you can confirm which model the run used. JSONL output is unchanged. `auto-run` hands the run to the desktop app, so confirm that one in the desktop UI instead. * The desktop Auto Run launch modal has the same two pickers, both defaulting to "Use agent default". See [Auto Run](autorun-playbooks.md). > **`playbook` vs `run-doc` vs `auto-run --launch`:** use `playbook ` for a saved playbook and `run-doc ` for raw documents - both run headlessly with no desktop dependency. `auto-run --launch` instead hands the run to the running desktop app (needed only when you want the run to appear and be controlled in the desktop UI). > **`--agent` accepts a name:** the `-a, --agent` flag on these commands resolves an agent by ID (full or partial) **or** by display name. This lets a group-chat participant target itself with `--agent ""`. ### Prompt Customization The CLI uses the same core system prompts as the desktop app. When you customize prompts via Settings → **Maestro Prompts**, those customizations are stored in `core-prompts-customizations.json` in the Maestro data directory and are automatically picked up by the CLI during playbook runs. The prompts most relevant to CLI playbook execution are: | Prompt ID | Controls | | ----------------------- | --------------------------------------------- | | `autorun-default` | Default Auto Run task execution behavior | | `autorun-synopsis` | Synopsis generation after task completion | | `commit-command` | `/commit` command behavior | | `maestro-system-prompt` | Maestro system context injected into sessions | | `context-grooming` | Context grooming during transfers | To customize these prompts, either use the desktop app's **Maestro Prompts** tab or edit the JSON file directly: ```text theme={"theme":"dracula"} # macOS ~/Library/Application Support/Maestro/core-prompts-customizations.json # Linux ~/.config/Maestro/core-prompts-customizations.json # Windows %APPDATA%\Maestro\core-prompts-customizations.json ``` The file format is: ```json theme={"theme":"dracula"} { "prompts": { "autorun-default": { "content": "Your customized prompt content...", "isModified": true, "modifiedAt": "2026-04-11T..." } } } ``` ### Reading Prompts (`prompts list` / `prompts get`) The CLI exposes Maestro's prompt registry directly so other agents can self-fetch reference material on demand. Parent prompts can use the `{{REF:name}}` directive (see [Prompt Customization → Include Directives](/prompt-customization#include-directives)) to expand into a one-line pointer; the agent then runs `prompts get` to retrieve the full content. ```bash theme={"theme":"dracula"} # List every available prompt id with description and category maestro-cli prompts list # JSON output for scripting maestro-cli prompts list --json # Print a specific prompt's content (honors user customizations) maestro-cli prompts get _maestro-cli maestro-cli prompts get autorun-default # Include metadata in the response maestro-cli prompts get _maestro-cue --json ``` `prompts get` returns the same content the desktop app would deliver, so customizations made via Settings → **Maestro Prompts** are reflected immediately. Bundled include fragments use a leading underscore in their id (e.g., `_maestro-cli`, `_history-format`); standalone prompts do not. ### Managing Settings View and modify any Maestro configuration setting directly from the CLI. Changes take effect immediately in the running desktop app - no restart required. ```bash theme={"theme":"dracula"} # List all settings with current values maestro-cli settings list # List with descriptions (great for understanding what each setting does) maestro-cli settings list -v # Filter by category maestro-cli settings list -c appearance maestro-cli settings list -c shell -v # Show only setting keys maestro-cli settings list --keys-only # Get a specific setting maestro-cli settings get fontSize maestro-cli settings get activeThemeId # Get nested settings with dot-notation maestro-cli settings get encoreFeatures.directorNotes # Get with full details (type, default, description) maestro-cli settings get fontSize -v # Set a setting (type is auto-detected) maestro-cli settings set fontSize 16 maestro-cli settings set audioFeedbackEnabled true maestro-cli settings set activeThemeId monokai maestro-cli settings set defaultShowThinking on # Set complex values with explicit JSON maestro-cli settings set localIgnorePatterns --raw '["node_modules",".git","dist"]' # Reset a setting to its default value maestro-cli settings reset fontSize ``` | Flag | Description | Commands | | ----------------------- | ------------------------------------------------------- | ------------- | | `-v, --verbose` | Show descriptions for each setting | `list`, `get` | | `--keys-only` | Show only setting key names | `list` | | `--defaults` | Show default values alongside current values | `list` | | `-c, --category ` | Filter by category (appearance, shell, editor, etc.) | `list` | | `--show-secrets` | Show sensitive values like API keys (masked by default) | `list` | | `--raw ` | Pass an explicit JSON value | `set` | | `--json` | Machine-readable JSON output | all | **Categories:** appearance, editor, shell, notifications, updates, logging, web, ssh, file-indexing, context, document-graph, stats, accessibility, integrations, onboarding, advanced, internal. Use `maestro-cli settings list -v` from inside an AI agent conversation to give the agent full context about every available setting and what it controls. ### Theme and Encore Features Ergonomic, validated wrappers over the underlying settings, for the customizations users most often ask for by voice. Unlike `settings set` (which writes the settings file), these route through the running desktop app, so the change applies live. The app must be running. ```bash theme={"theme":"dracula"} # Switch the active theme by ID or display name (case-insensitive) maestro-cli set-theme tokyo-night maestro-cli set-theme "Catppuccin Mocha" # See every available theme maestro-cli set-theme --list # List Encore (experimental) features and whether each is enabled maestro-cli encore list # Enable or disable an Encore feature maestro-cli encore enable symphony maestro-cli encore disable maestroCue ``` Encore feature IDs: `directorNotes`, `usageStats`, `symphony`, `maestroCue`. Friendly aliases are accepted (for example `group-chat` for `symphony`, `cue` for `maestroCue`). ### Custom Theme Palette `set-theme` only switches between built-in themes. The `theme` command group manages the user-configurable **Custom** theme palette (the same two settings the in-app Custom Theme Builder edits: `customThemeColors` and `customThemeBaseId`). Activate the result with `set-theme custom`. ```bash theme={"theme":"dracula"} # Print the current custom palette and its base theme (reads from disk; works offline) maestro-cli theme show maestro-cli theme show --json # Export the custom theme as portable JSON (stdout, or to a file) maestro-cli theme export maestro-cli theme export --file my-theme.json # Import a theme JSON file, apply it live, and activate it maestro-cli theme import my-theme.json maestro-cli theme import my-theme.json --no-activate # save the palette without switching to it # Set individual colors (key=value); optionally re-base from a built-in theme first maestro-cli theme set accent=#ff0000 bgMain=#1a1a1a maestro-cli theme set --base dracula accent=#ff79c6 --activate ``` Export files are byte-compatible with the in-app Custom Theme Builder, so a palette round-trips between the UI and CLI. `theme show` and `theme export` read the on-disk settings store directly (no running app required); `theme import` and `theme set` apply live through the running desktop app. Imports are validated the same way as the in-app importer: every required color key must be present and every value must be a valid CSS color. | Command | Flag | Description | | -------------- | ------------------- | ---------------------------------------------------------- | | `theme show` | `--json` | Machine-readable output | | `theme export` | `-f, --file ` | Write the theme JSON to this file instead of stdout | | `theme import` | `--no-activate` | Save the palette without switching to the Custom theme | | `theme set` | `-b, --base ` | Initialize from a built-in theme before applying overrides | | `theme set` | `-a, --activate` | Switch to the Custom theme after applying | ### Managing Agent Configuration Each agent (Claude Code, Codex, OpenCode, Factory Droid) can have its own configuration for custom paths, CLI arguments, environment variables, and model overrides. `settings agent set` writes the per-agent-type configuration store (defaults applied to newly created agents and headless CLI spawns). To change the settings of a specific existing agent shown in the Left Bar - its nudge message, model, env vars, Claude token source, and so on - use [`update-agent`](#creating-updating-and-removing-agents) instead, which writes that agent's live desktop Session. ```bash theme={"theme":"dracula"} # List all agent configurations maestro-cli settings agent list # List config for a specific agent maestro-cli settings agent list claude-code # Get a specific agent config value maestro-cli settings agent get codex model maestro-cli settings agent get claude-code customPath # Set agent config values maestro-cli settings agent set codex contextWindow 128000 maestro-cli settings agent set claude-code customPath /usr/local/bin/claude maestro-cli settings agent set codex customEnvVars --raw '{"DEBUG":"true"}' # Remove an agent config key maestro-cli settings agent reset codex model ``` | Flag | Description | Commands | | --------------- | ------------------------------------- | ------------- | | `-v, --verbose` | Show descriptions for each config key | `list`, `get` | | `--raw ` | Pass an explicit JSON value | `set` | | `--json` | Machine-readable JSON output | all | **Common agent config keys:** | Key | Type | Description | | ----------------- | ------ | ------------------------------------------------ | | `customPath` | string | Custom path to the agent CLI binary | | `customArgs` | string | Additional CLI arguments | | `customEnvVars` | object | Extra environment variables | | `model` | string | Model override (e.g., `gpt-5.3-codex`, `o3`) | | `contextWindow` | number | Context window size in tokens | | `reasoningEffort` | string | Reasoning effort level (`low`, `medium`, `high`) | Settings and agent config changes made via the CLI are automatically detected by the running Maestro desktop app. The app watches for file changes and reloads immediately - it's as if you toggled the setting in the Settings modal yourself. ### Managing SSH Remotes Create, list, and remove SSH remote configurations. These commands read and write directly to the Maestro settings file - no running desktop app required. ```bash theme={"theme":"dracula"} # List all configured SSH remotes maestro-cli list ssh-remotes # Create a new SSH remote maestro-cli create-ssh-remote "Dev Server" -H 192.168.1.100 -u deploy # Create with SSH config mode (uses ~/.ssh/config) maestro-cli create-ssh-remote "Prod" -H prod-host --ssh-config # Create with all options maestro-cli create-ssh-remote "Build Server" \ -H build.example.com \ -p 2222 \ -u ci \ -k ~/.ssh/build_key \ --env PATH=/usr/local/bin --env NODE_ENV=production \ --set-default # Remove an SSH remote maestro-cli remove-ssh-remote ``` | Flag | Description | Default | | ----------------------- | --------------------------------------------------------------- | ------- | | `-H, --host ` | SSH hostname or IP (required; Host pattern with `--ssh-config`) | - | | `-p, --port ` | SSH port | `22` | | `-u, --username ` | SSH username | - | | `-k, --key ` | Path to private key file | - | | `--env ` | Remote environment variable (repeatable) | - | | `--ssh-config` | Use `~/.ssh/config` for connection settings | - | | `--disabled` | Create in disabled state | - | | `--set-default` | Set as the global default SSH remote | - | | `--json` | Machine-readable JSON output | - | SSH remote changes made via the CLI are detected by the running Maestro desktop app through file watching, just like settings changes. ## Partial IDs All commands that accept an agent ID, group ID, or SSH remote ID support partial matching. You only need to type enough characters to uniquely identify the resource: ```bash theme={"theme":"dracula"} # These are equivalent if "a1b2" uniquely matches one agent maestro-cli send a1b2c3d4-e5f6-7890-abcd-ef1234567890 "hello" maestro-cli send a1b2 "hello" ``` If the partial ID is ambiguous, the CLI will show all matches. ## JSON Output By default, commands output human-readable formatted text. Use `--json` for machine-parseable output: ```bash theme={"theme":"dracula"} # Human-readable output (default) maestro-cli list groups GROUPS (2) 🎨 Frontend group-abc123 ⚙️ Backend group-def456 # JSON output for scripting maestro-cli list groups --json {"type":"group","id":"group-abc123","name":"Frontend","emoji":"🎨","collapsed":false,"timestamp":...} {"type":"group","id":"group-def456","name":"Backend","emoji":"⚙️","collapsed":false,"timestamp":...} # Note: list agents outputs a JSON array (not JSONL) maestro-cli list agents --json [{"id":"agent-abc123","name":"My Agent","toolType":"claude-code","cwd":"/path/to/project",...}] # Running a playbook with JSON streams events maestro-cli playbook --json {"type":"start","timestamp":...,"playbook":{...}} {"type":"document_start","timestamp":...,"document":"tasks.md","taskCount":5} {"type":"task_start","timestamp":...,"taskIndex":0} {"type":"task_complete","timestamp":...,"success":true,"summary":"...","elapsedMs":8000,"usageStats":{...}} {"type":"document_complete","timestamp":...,"document":"tasks.md","tasksCompleted":5} {"type":"loop_complete","timestamp":...,"iteration":1,"tasksCompleted":5,"elapsedMs":60000} {"type":"complete","timestamp":...,"success":true,"totalTasksCompleted":5,"totalElapsedMs":60000,"totalCost":0.05} ``` The `send` command always outputs JSON (no `--json` flag needed). ### Desktop Integration Commands for interacting with the running Maestro desktop app. These are especially useful for AI agents to trigger UI updates after creating or modifying files. #### Open a File Open a file as a preview tab in the Maestro desktop app. Without `--agent`, the owning agent is auto-detected by which agent's working directory the file lives in (longest-prefix match, most-recently-active wins on ties). Pass `--agent ` to target an explicit agent - the file must live inside that agent's `cwd`. Pass `--no-switch` to skip switching the Maestro UI to the resulting agent/tab. ```bash theme={"theme":"dracula"} maestro-cli open-file [-a ] [--no-switch] ``` | Flag | Description | | ------------------ | ------------------------------------------------------------------ | | `-a, --agent ` | Target agent (defaults to auto-detect by file path's owning agent) | | `--no-switch` | Don't switch the Maestro UI to the target agent/tab | #### Open a Browser Tab Open a URL as a browser tab in the Maestro desktop app. Only `http(s)` URLs are accepted; scheme-less inputs like `localhost:3000` or `example.com:8080` are auto-prefixed with `https://`. ```bash theme={"theme":"dracula"} # Open in the active agent maestro-cli open-browser https://docs.runmaestro.ai # Scheme-less - gets https:// prepended maestro-cli open-browser localhost:3000 # Target a specific agent maestro-cli open-browser https://github.com/RunMaestro/Maestro -a ``` | Flag | Description | | ------------------ | ------------------------------------------------- | | `-a, --agent ` | Target agent by ID (defaults to the active agent) | #### Open a Terminal Tab Open a fresh terminal tab in the Maestro desktop app. The working directory must resolve inside the target agent's `cwd`; paths outside it are rejected. ```bash theme={"theme":"dracula"} # Open a terminal in the active agent's cwd with the default shell maestro-cli open-terminal # Custom cwd, shell, and tab label maestro-cli open-terminal --cwd ./packages/api --shell bash --name "API tests" # Target a specific agent maestro-cli open-terminal -a --name "Build watch" ``` | Flag | Description | Default | | ------------------ | ------------------------------------------------------------------- | ----------- | | `-a, --agent ` | Target agent by ID (defaults to the active agent) | - | | `--cwd ` | Working directory for the terminal (must be inside the agent's cwd) | agent's cwd | | `--shell ` | Shell binary to use | `zsh` | | `--name