Run multiple CLI coding agents in parallel, each in an isolated git-worktree workspace.
1
stars
0
commits
TypeScript
primary language
Sep 11, 2026
updated
A cross-platform (macOS · Windows · Linux) desktop app that runs multiple CLI coding agents (Claude Code, Codex, Cursor, OpenCode, Kimi Code, Grok Build) in parallel, each in an isolated git-worktree-backed workspace with its own branch, terminal, chat, and diff. A functional clone of Conductor.
gh, or "Quick start" a fresh repo), or a plain folder worked in directly (a single in-place workspace, no branches — shadow-git checkpoints still power a diff-since view). Projects can also live on a remote machine over SSH (see below).git worktree add -b <branch> <base> after a git fetch, so every agent starts from the latest remote state. One branch per worktree, enforced by git — conflicts offer a -2 suffixed branch.claude -p --output-format stream-json, session resume, token-by-token streaming, tool-call chips, cost/duration). Codex, Cursor, OpenCode, Kimi Code, and Grok Build have adapters; a Shell fallback works with no agent CLI at all. Model and reasoning-effort are pickable per chat. Auth is passed through to whatever login each CLI already has — Maestro never stores model API keys.maestro-role helper), whose runs and cost fold back into the parent turn.⌘⇧E): a Monaco-backed file editor for quick in-app edits (⌘S to save), including Jupyter notebooks.⌘⇧B): an embedded browser pointed at the workspace's dev server that both you and the agent can drive — the agent navigates, screenshots, reads the console, and clicks/types via the maestro-preview helper, and you can annotate the page and send it back..env, deps, DBs — worktrees only carry git-tracked files) and a run script launches the app with a unique WORKSPACE_PORT per workspace so parallel dev servers don't collide. Spotlight run is the fallback that runs from the main repo checkout when a worktree can't run cleanly.⌘⇧D) diffs the worktree against the merge-base with the base branch (including untracked files), with a file tree, unified/split toggle, syntax highlighting, and inline comment threads that persist, resolve, and can be sent to the agent as a composer attachment.⌘⇧K): git ahead/behind + staged/unstaged/untracked, PR state with CI checks via gh pr checks data, PR comments, deployments, and a todo list. Merge is gated on approval + green checks + resolved comments + completed todos (with an explicit override).⌘⇧P): pushes the branch, lets Claude draft the title/body from the actual diff, gh pr create, polls checks, gh pr merge, then prompts to archive.git worktree remove..context/ in every worktree (git-ignored via .git/info/exclude) for notes, attachments, and agent-to-agent handoffs — pasted images/large text and dropped files are saved there and referenced in prompts.maestro-ask: an agent can pause and ask you a structured multiple-choice question, answered inline in the chat.⌘K), workspace switching (⌘1..9), live status dots (idle / running / needs-attention / reviewing), needs-attention banner, desktop notifications when an agent finishes in the background, and light / dark / system themes. Shortcuts use ⌘ on macOS and Ctrl on Windows/Linux.gh auth login --with-token (stored in gh's keyring, never by Maestro) and git's credential helper for github.com is pointed at gh, so git push and the whole PR pipeline work with one click. If the GitHub CLI isn't installed at all, Maestro downloads the official build to ~/maestro/tools/gh-cli and uses that everywhere (it's also added to agent/script PATH).~/.ssh/config or added by hand) and every exec, spawn, pty, and filesystem operation for its workspaces runs on that server. Auth is SSH agent or an explicit key (passphrase prompted, never stored); host keys are TOFU-pinned on first connect, and ProxyCommand/ProxyJump are honored..maestro/settings.tomlChecked into the repo so the whole team shares them (Settings → Repository):
[scripts]
setup = "npm install && cp ~/secrets/.env .env"
run = "npm run dev -- --port $WORKSPACE_PORT"
[project]
instructions = """
Durable guidance included in every agent session for this repo.
"""
Env injected into scripts, terminals and agents: WORKSPACE_PORT, MAESTRO_WORKSPACE_NAME, MAESTRO_ROOT_PATH, MAESTRO_BRANCH.
npm install # also rebuilds better-sqlite3 + node-pty for Electron
npm run build # renderer (vite) + main (esbuild) + native dictation helper (macOS)
npm start # launch the app
npm run dev # vite dev server + electron with HMR
npm run dist # unpacked app via electron-builder
npm run dist:dmg # macOS: .dmg
npm run dist:win # Windows: NSIS .exe installer (build on Windows)
npm run dist:linux # Linux: AppImage
Requirements: macOS, Windows 10/11, or Linux, and git. GitHub features need the GitHub CLI — either preinstalled or auto-downloaded by the in-app "Sign in with GitHub" flow. Each agent harness needs its own CLI installed (claude, codex, cursor-agent, opencode, kimi, or grok); the Shell fallback needs none.
Building for Windows: native modules (
better-sqlite3,node-pty) can't be cross-compiled from macOS, so the Windows installer must be built on Windows. Thebuild-desktopGitHub Actions workflow (.github/workflows/build-desktop.yml) does this on awindows-latestrunner — trigger it from the Actions tab or by pushing av*tag, then download the installer from the run's artifacts.
Service-level end-to-end suite (real repos, worktrees, ptys, and optionally a live Claude call):
npx esbuild scripts/e2e.ts --bundle --platform=node --format=cjs \
--external:electron --external:better-sqlite3 --external:node-pty --outfile=dist/e2e.cjs
ELECTRON_RUN_AS_NODE=1 npx electron dist/e2e.cjs [--with-claude]
Process-launching invariants (scripts/launch-probe.ts, same build/run pattern): builds a fake npm-installed CLI in a
temp dir — both cmd-shim shapes plus an unreadable batch file — and checks that argv survives byte-for-byte through
exec, spawnStream, and a pty, that an undefined env value unsets a var, and that killing a child reaps its tree.
Worth running on Windows after touching src/main/launch.ts or a host. scripts/llm-probe.ts makes one real (cheap)
generateText call — the Status-tab digest path — against whichever agent CLI is installed.
Live GitHub verification (scripts/gh-e2e.ts, same build/run pattern): starts a real device-flow session, exercises the
post-approval path with the machine's existing gh token, then runs the whole PR pipeline against a throwaway private
repo — create → clone → workspace → commit → push → PR → status → squash-merge — and cleans up.
Headless UI smoke (launches the real app, captures a screenshot):
npm run build && npx electron . --smoke --screenshot=/tmp/maestro.png [--smoke-actions=tab-diff]
┌────────────────────────── Renderer (React 19 + Zustand) ─────────────────────────┐
│ Sidebar · Chat/Composer · Terminal (xterm) · DiffViewer · Editor · Preview · Checks │
└──────────────▲────────────────────────────────────────────────────────────────────┘
│ typed IPC (contextBridge → invoke/on, src/shared/types.ts)
┌──────────────┴─────────────────── Main (Node) ───────────────────────────────┐
│ git service (worktrees/diff/status) pty service (node-pty pool + buffers) │
│ harness adapters (claude/codex/…) github service (gh CLI) │
│ host layer (local · ssh2) script runner (WORKSPACE_PORT) │
│ roles / preview / stt servers better-sqlite3 (projects/ws/chats/…) │
│ fs watchers (dirty state, .context) .maestro/settings.toml │
└──────────────────────────────────────────────────────────────────────────────┘
LocalHost (this machine) or an SshHost for remote projects — so the same services work locally or over SSH.~/maestro/workspaces/<project>/<name>; cloned repos in ~/maestro/repos.<userData>/maestro.db — i.e. ~/Library/Application Support/Maestro/ (macOS), %APPDATA%\Maestro\ (Windows), ~/.config/Maestro/ (Linux). Set MAESTRO_DB_PATH to override (used by tests).MAESTRO_POSTHOG_KEY at build time); forks that set no key emit nothing.Copyright (C) 2026 Maestro contributors.
Licensed under the Business Source License 1.1 (BSL) — see LICENSE.
You may read, run, self-host, modify, and redistribute Maestro; you may not offer
it to third parties on a hosted or embedded basis that competes with Maestro's
products or services. Four years after a given version is released, that version
converts to the Apache License 2.0.
TypeScript
97.1%
JavaScript
1.6%
Run multiple CLI coding agents in parallel, each in an isolated git-worktree workspace.
1
stars
0
commits
TypeScript
primary language
Sep 11, 2026
updated
A cross-platform (macOS · Windows · Linux) desktop app that runs multiple CLI coding agents (Claude Code, Codex, Cursor, OpenCode, Kimi Code, Grok Build) in parallel, each in an isolated git-worktree-backed workspace with its own branch, terminal, chat, and diff. A functional clone of Conductor.
gh, or "Quick start" a fresh repo), or a plain folder worked in directly (a single in-place workspace, no branches — shadow-git checkpoints still power a diff-since view). Projects can also live on a remote machine over SSH (see below).git worktree add -b <branch> <base> after a git fetch, so every agent starts from the latest remote state. One branch per worktree, enforced by git — conflicts offer a -2 suffixed branch.claude -p --output-format stream-json, session resume, token-by-token streaming, tool-call chips, cost/duration). Codex, Cursor, OpenCode, Kimi Code, and Grok Build have adapters; a Shell fallback works with no agent CLI at all. Model and reasoning-effort are pickable per chat. Auth is passed through to whatever login each CLI already has — Maestro never stores model API keys.maestro-role helper), whose runs and cost fold back into the parent turn.⌘⇧E): a Monaco-backed file editor for quick in-app edits (⌘S to save), including Jupyter notebooks.⌘⇧B): an embedded browser pointed at the workspace's dev server that both you and the agent can drive — the agent navigates, screenshots, reads the console, and clicks/types via the maestro-preview helper, and you can annotate the page and send it back..env, deps, DBs — worktrees only carry git-tracked files) and a run script launches the app with a unique WORKSPACE_PORT per workspace so parallel dev servers don't collide. Spotlight run is the fallback that runs from the main repo checkout when a worktree can't run cleanly.⌘⇧D) diffs the worktree against the merge-base with the base branch (including untracked files), with a file tree, unified/split toggle, syntax highlighting, and inline comment threads that persist, resolve, and can be sent to the agent as a composer attachment.⌘⇧K): git ahead/behind + staged/unstaged/untracked, PR state with CI checks via gh pr checks data, PR comments, deployments, and a todo list. Merge is gated on approval + green checks + resolved comments + completed todos (with an explicit override).⌘⇧P): pushes the branch, lets Claude draft the title/body from the actual diff, gh pr create, polls checks, gh pr merge, then prompts to archive.git worktree remove..context/ in every worktree (git-ignored via .git/info/exclude) for notes, attachments, and agent-to-agent handoffs — pasted images/large text and dropped files are saved there and referenced in prompts.maestro-ask: an agent can pause and ask you a structured multiple-choice question, answered inline in the chat.⌘K), workspace switching (⌘1..9), live status dots (idle / running / needs-attention / reviewing), needs-attention banner, desktop notifications when an agent finishes in the background, and light / dark / system themes. Shortcuts use ⌘ on macOS and Ctrl on Windows/Linux.gh auth login --with-token (stored in gh's keyring, never by Maestro) and git's credential helper for github.com is pointed at gh, so git push and the whole PR pipeline work with one click. If the GitHub CLI isn't installed at all, Maestro downloads the official build to ~/maestro/tools/gh-cli and uses that everywhere (it's also added to agent/script PATH).~/.ssh/config or added by hand) and every exec, spawn, pty, and filesystem operation for its workspaces runs on that server. Auth is SSH agent or an explicit key (passphrase prompted, never stored); host keys are TOFU-pinned on first connect, and ProxyCommand/ProxyJump are honored..maestro/settings.tomlChecked into the repo so the whole team shares them (Settings → Repository):
[scripts]
setup = "npm install && cp ~/secrets/.env .env"
run = "npm run dev -- --port $WORKSPACE_PORT"
[project]
instructions = """
Durable guidance included in every agent session for this repo.
"""
Env injected into scripts, terminals and agents: WORKSPACE_PORT, MAESTRO_WORKSPACE_NAME, MAESTRO_ROOT_PATH, MAESTRO_BRANCH.
npm install # also rebuilds better-sqlite3 + node-pty for Electron
npm run build # renderer (vite) + main (esbuild) + native dictation helper (macOS)
npm start # launch the app
npm run dev # vite dev server + electron with HMR
npm run dist # unpacked app via electron-builder
npm run dist:dmg # macOS: .dmg
npm run dist:win # Windows: NSIS .exe installer (build on Windows)
npm run dist:linux # Linux: AppImage
Requirements: macOS, Windows 10/11, or Linux, and git. GitHub features need the GitHub CLI — either preinstalled or auto-downloaded by the in-app "Sign in with GitHub" flow. Each agent harness needs its own CLI installed (claude, codex, cursor-agent, opencode, kimi, or grok); the Shell fallback needs none.
Building for Windows: native modules (
better-sqlite3,node-pty) can't be cross-compiled from macOS, so the Windows installer must be built on Windows. Thebuild-desktopGitHub Actions workflow (.github/workflows/build-desktop.yml) does this on awindows-latestrunner — trigger it from the Actions tab or by pushing av*tag, then download the installer from the run's artifacts.
Service-level end-to-end suite (real repos, worktrees, ptys, and optionally a live Claude call):
npx esbuild scripts/e2e.ts --bundle --platform=node --format=cjs \
--external:electron --external:better-sqlite3 --external:node-pty --outfile=dist/e2e.cjs
ELECTRON_RUN_AS_NODE=1 npx electron dist/e2e.cjs [--with-claude]
Process-launching invariants (scripts/launch-probe.ts, same build/run pattern): builds a fake npm-installed CLI in a
temp dir — both cmd-shim shapes plus an unreadable batch file — and checks that argv survives byte-for-byte through
exec, spawnStream, and a pty, that an undefined env value unsets a var, and that killing a child reaps its tree.
Worth running on Windows after touching src/main/launch.ts or a host. scripts/llm-probe.ts makes one real (cheap)
generateText call — the Status-tab digest path — against whichever agent CLI is installed.
Live GitHub verification (scripts/gh-e2e.ts, same build/run pattern): starts a real device-flow session, exercises the
post-approval path with the machine's existing gh token, then runs the whole PR pipeline against a throwaway private
repo — create → clone → workspace → commit → push → PR → status → squash-merge — and cleans up.
Headless UI smoke (launches the real app, captures a screenshot):
npm run build && npx electron . --smoke --screenshot=/tmp/maestro.png [--smoke-actions=tab-diff]
┌────────────────────────── Renderer (React 19 + Zustand) ─────────────────────────┐
│ Sidebar · Chat/Composer · Terminal (xterm) · DiffViewer · Editor · Preview · Checks │
└──────────────▲────────────────────────────────────────────────────────────────────┘
│ typed IPC (contextBridge → invoke/on, src/shared/types.ts)
┌──────────────┴─────────────────── Main (Node) ───────────────────────────────┐
│ git service (worktrees/diff/status) pty service (node-pty pool + buffers) │
│ harness adapters (claude/codex/…) github service (gh CLI) │
│ host layer (local · ssh2) script runner (WORKSPACE_PORT) │
│ roles / preview / stt servers better-sqlite3 (projects/ws/chats/…) │
│ fs watchers (dirty state, .context) .maestro/settings.toml │
└──────────────────────────────────────────────────────────────────────────────┘
LocalHost (this machine) or an SshHost for remote projects — so the same services work locally or over SSH.~/maestro/workspaces/<project>/<name>; cloned repos in ~/maestro/repos.<userData>/maestro.db — i.e. ~/Library/Application Support/Maestro/ (macOS), %APPDATA%\Maestro\ (Windows), ~/.config/Maestro/ (Linux). Set MAESTRO_DB_PATH to override (used by tests).MAESTRO_POSTHOG_KEY at build time); forks that set no key emit nothing.Copyright (C) 2026 Maestro contributors.
Licensed under the Business Source License 1.1 (BSL) — see LICENSE.
You may read, run, self-host, modify, and redistribute Maestro; you may not offer
it to third parties on a hosted or embedded basis that competes with Maestro's
products or services. Four years after a given version is released, that version
converts to the Apache License 2.0.
TypeScript
97.1%
JavaScript
1.6%