{"slug": "show-hn-parallel-coding-agents-on-mobile", "title": "Show HN: Parallel Coding Agents on Mobile", "summary": "A new cross-platform desktop app called Maestro runs multiple CLI coding agents — including Claude Code, Codex, Cursor, OpenCode, Kimi Code, and Grok Build — in parallel, each in an isolated git-worktree-backed workspace with its own branch, terminal, chat, and diff. The app, described as a functional clone of Conductor, supports macOS, Windows, and Linux, and passes authentication through to each CLI's existing login so Maestro never stores model API keys. Multiple agents can share one workspace, with an orchestrator turn able to delegate scoped tasks to sub-agents whose runs and cost fold back into the parent turn.", "body_md": "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](https://conductor.build).\n\n- **Projects** wrap a git repository (open local folder, clone from GitHub via`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).\n- **Workspaces** are isolated copies of the repo created with`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.\n- **Agents** run per-workspace through a pluggable harness layer. Claude Code is fully wired (`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.\n- **Multiple agents can share one workspace** (e.g. one implements while another reviews) — pick \"Agent 2 / New agent\" in the composer, or hit**Review** to spawn a reviewer.\n- **Roles / specialist sub-agents** : an orchestrator turn can delegate scoped tasks to sub-agents (via the bundled`maestro-role` helper), whose runs and cost fold back into the parent turn.\n- **Terminal** tab is a real login shell (node-pty + xterm) cwd'd to the worktree, with copy/paste (Ctrl/⌘+C/V) and a right-click menu.\n- **Editor** tab (`⌘⇧E` ): a Monaco-backed file editor for quick in-app edits (`⌘S` to save), including Jupyter notebooks.\n- **Preview** tab (`⌘⇧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.\n- **Scripts** : a repo-level*setup script* runs on workspace creation (restore`.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.\n- **Diff viewer** (`⌘⇧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.\n- **Checks** tab (`⌘⇧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).\n- **PR flow** (`⌘⇧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.\n- **Archive / History** : archived workspaces keep their worktree and chat; restore brings everything back. Hard delete runs`git worktree remove` .\n- **`.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.\n- **`maestro-ask`** : an agent can pause and ask you a structured multiple-choice question, answered inline in the chat.\n- **Command palette** (`⌘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.\n- **Dictation** (macOS only): an on-device speech-to-text button in the composer, backed by a bundled Swift helper (SFSpeechRecognizer). Hidden on other platforms.\n- **Auto-update** : packaged builds check for and download new releases in the background (electron-updater), with a progress toast.\n- **Conductor import** : migrate existing[Conductor](https://conductor.build) workspaces into Maestro.\n- **In-app \"Sign in with GitHub\"** (sidebar badge, onboarding banner, or Settings → Integrations): an OAuth device flow — enter a one-time code on github.com/login/device and Maestro finishes the rest. The token is handed to`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).\n- **Remote SSH hosts** : open a folder on a remote machine (hosts are auto-detected from`~/.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.\n\nChecked into the repo so the whole team shares them (Settings → Repository):\n\n```\n[scripts]\nsetup = \"npm install && cp ~/secrets/.env .env\"\nrun = \"npm run dev -- --port $WORKSPACE_PORT\"\n\n[project]\ninstructions = \"\"\"\nDurable guidance included in every agent session for this repo.\n\"\"\"\n```\n\nEnv injected into scripts, terminals and agents: `WORKSPACE_PORT`, `MAESTRO_WORKSPACE_NAME`, `MAESTRO_ROOT_PATH`, `MAESTRO_BRANCH`.\n\n```\nnpm install            # also rebuilds better-sqlite3 + node-pty for Electron\nnpm run build          # renderer (vite) + main (esbuild) + native dictation helper (macOS)\nnpm start              # launch the app\nnpm run dev            # vite dev server + electron with HMR\nnpm run dist           # unpacked app via electron-builder\nnpm run dist:dmg       # macOS: .dmg\nnpm run dist:win       # Windows: NSIS .exe installer (build on Windows)\nnpm run dist:linux     # Linux: AppImage\n```\n\nRequirements: 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.\n\n**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. The `build-desktop` GitHub Actions workflow (`.github/workflows/build-desktop.yml`) does this on a `windows-latest` runner — trigger it from the Actions tab or by pushing a `v*` tag, then download the installer from the run's artifacts.\n\nService-level end-to-end suite (real repos, worktrees, ptys, and optionally a live Claude call):\n\n```\nnpx esbuild scripts/e2e.ts --bundle --platform=node --format=cjs \\\n  --external:electron --external:better-sqlite3 --external:node-pty --outfile=dist/e2e.cjs\nELECTRON_RUN_AS_NODE=1 npx electron dist/e2e.cjs [--with-claude]\n```\n\nProcess-launching invariants (`scripts/launch-probe.ts`, same build/run pattern): builds a fake npm-installed CLI in a\ntemp dir — both `cmd-shim` shapes plus an unreadable batch file — and checks that argv survives byte-for-byte through\n`exec`, `spawnStream`, and a pty, that an `undefined` env value unsets a var, and that killing a child reaps its tree.\nWorth running on Windows after touching `src/main/launch.ts` or a host. `scripts/llm-probe.ts` makes one real (cheap)\n`generateText` call — the Status-tab digest path — against whichever agent CLI is installed.\n\nLive GitHub verification (`scripts/gh-e2e.ts`, same build/run pattern): starts a real device-flow session, exercises the\npost-approval path with the machine's existing gh token, then runs the whole PR pipeline against a throwaway private\nrepo — create → clone → workspace → commit → push → PR → status → squash-merge — and cleans up.\n\nHeadless UI smoke (launches the real app, captures a screenshot):\n\n```\nnpm run build && npx electron . --smoke --screenshot=/tmp/maestro.png [--smoke-actions=tab-diff]\n┌────────────────────────── Renderer (React 19 + Zustand) ─────────────────────────┐\n│ Sidebar · Chat/Composer · Terminal (xterm) · DiffViewer · Editor · Preview · Checks │\n└──────────────▲────────────────────────────────────────────────────────────────────┘\n               │ typed IPC (contextBridge → invoke/on, src/shared/types.ts)\n┌──────────────┴─────────────────── Main (Node) ───────────────────────────────┐\n│ git service (worktrees/diff/status)   pty service (node-pty pool + buffers)  │\n│ harness adapters (claude/codex/…)     github service (gh CLI)                │\n│ host layer (local · ssh2)             script runner (WORKSPACE_PORT)         │\n│ roles / preview / stt servers         better-sqlite3 (projects/ws/chats/…)   │\n│ fs watchers (dirty state, .context)   .maestro/settings.toml                 │\n└──────────────────────────────────────────────────────────────────────────────┘\n```\n\n- Every exec/spawn/pty/fs primitive goes through a **host** —`LocalHost` (this machine) or an`SshHost` for remote projects — so the same services work locally or over SSH.\n- Workspaces live in `~/maestro/workspaces/<project>/<name>` ; cloned repos in`~/maestro/repos` .\n- The DB is at `<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).\n- Agent turns are persisted as structured blocks (text / thinking / tool + result), so history renders identically after restore.\n\n- Isolation is development-grade, not a security boundary — agents run with your local permissions (or, for remote projects, the SSH user's).\n- Claude Code is the most exercised harness. Codex, Cursor, OpenCode, Kimi Code, and Grok Build adapters are wired but lightly exercised; the Shell fallback guarantees a working loop without any agent CLI.\n- Dictation is macOS-only (on-device Swift helper); the mic button is hidden elsewhere.\n- Linear integration needs a personal API token (Settings → Integrations) and fetches issue title/description into the first prompt.\n- **Anonymous analytics** : packaged builds send anonymous usage events (a random per-install id — no account, prompts, repo names, or other PII) to PostHog to gauge how many people run Maestro. It is off in dev/unpackaged runs and off unless a real PostHog key is configured (`MAESTRO_POSTHOG_KEY` at build time); forks that set no key emit nothing.\n\nCopyright (C) 2026 Maestro contributors.\n\nLicensed under the Business Source License 1.1 (BSL) — see [`LICENSE`](/PlathsOven/maestro/blob/main/LICENSE).\nYou may read, run, self-host, modify, and redistribute Maestro; you may not offer\nit to third parties on a hosted or embedded basis that competes with Maestro's\nproducts or services. Four years after a given version is released, that version\nconverts to the Apache License 2.0.", "url": "https://wpnews.pro/news/show-hn-parallel-coding-agents-on-mobile", "canonical_source": "https://github.com/PlathsOven/maestro", "published_at": "2026-09-12 12:02:50+00:00", "updated_at": "2026-09-12 12:11:19.478995+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "developer-tools", "ai-products"], "entities": ["Maestro", "Claude Code", "Codex", "Cursor", "OpenCode", "Kimi Code", "Grok Build", "Conductor"], "alternates": {"html": "https://wpnews.pro/news/show-hn-parallel-coding-agents-on-mobile", "markdown": "https://wpnews.pro/news/show-hn-parallel-coding-agents-on-mobile.md", "text": "https://wpnews.pro/news/show-hn-parallel-coding-agents-on-mobile.txt", "jsonld": "https://wpnews.pro/news/show-hn-parallel-coding-agents-on-mobile.jsonld"}}