Orchestrate multiple coding-agent CLIs (codex/gemini/copilot/claude) headlessly — each in its own git worktree, driven non-interactively (one-shot, not interactive REPLs; each worker runs in a tmux window by default so its output stays visible), then merged. Use when fanning real implementation or review work out to several model CLIs in parallel without driving interactive REPLs, when you need worktree isolation so agents don't collide, or when distributing token cost onto external providers. Trigger on "run codex/gemini/copilot in parallel", "headless multi-agent", "git worktree per agent", "non-interactive CLI agents", "offload work to other model CLIs", "parallel build with isolated worktrees". For interactive tmux worker teams use quintet-team-runtime instead; for one-shot opinions use quintet-fleet-dispatch.
93%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Passed
No findings from the security scan
Drive several coding-agent CLIs as one-shot, non-interactive processes (codex exec, gemini -p, copilot -p), each confined to its own git worktree, then verify and merge their commits. The orchestrator (you) decomposes, dispatches, reviews, and integrates; the worker CLIs spend their own provider's tokens doing the work.
exec avoids the single biggest flake source of REPL teams: the warmup-swallow (the first task sent to a cold interactive CLI is often eaten).quintet-team-runtime — long-lived interactive tmux workers you steer over time.quintet-fleet-dispatch — one-shot opinions/reviews, no files written.The deciding question: do agents mutate files in parallel and need isolation + clean merges? If yes, this skill.
quintet worktrees)Quintet provides an automated, first-class command that handles worktree creation, headless dispatch, tmux session isolation, and clean branch merging automatically:
QBIN="${CLAUDE_PLUGIN_ROOT:+$CLAUDE_PLUGIN_ROOT/bin/quintet}"
[ -n "$QBIN" ] && [ -x "$QBIN" ] || QBIN="$(command -v quintet 2>/dev/null || echo quintet)"
# 1. Start headless worktree dispatch
"$QBIN" worktrees 2:codex:implementer,1:claude:implementer "build auth module" \
--name auth-feat \
--tasks "implement JWT in src/auth/||add unit tests in tests/auth/"
# 2. Check worker status & modified files
"$QBIN" worktrees status auth-feat
# 3. Merge completed branches into an integration branch and clean up
"$QBIN" worktrees merge auth-feat --branch feat/auth-integrated
# Abort and clean up in case of failure
"$QBIN" worktrees abort auth-featbase commit ── wt1 (agent A) ─┐
── wt2 (agent B) ─┤ octopus-merge → integration branch → verify → push
── wt3 (agent C) ─┘One worktree per work package, partitioned by disjoint file ownership so branches never touch the same file. That single design choice is what makes parallel agents produce clean merges instead of conflict soup. Cross-cutting files that no package owns (a shared config, a site-wide token) are the orchestrator's to edit during integration — assign them to nobody and a holistic review will later flag the gap.
Non-interactive mode is the reliability win. Each CLI has an auto-approve flag; without it the process blocks forever waiting for a confirmation it can't receive.
| CLI | Headless form | Auto-approve |
|---|---|---|
| codex | codex exec -C <dir> [PROMPT or -] | -s workspace-write (sandboxed) |
| agy | agy -p "<prompt>" --dangerously-skip-permissions | --dangerously-skip-permissions |
| copilot | copilot -p "<prompt>" | --allow-all |
| claude | claude -p "<prompt>" | --permission-mode bypassPermissions |
| qwen | qwen -p "<prompt>" | --approval-mode yolo (with trust env vars) |
| opencode | opencode run --pure --auto "<prompt>" | --auto |
codex exec reads the prompt from a positional arg, from stdin via -, or piped. agy/claude/copilot take the prompt on -p and run in the current directory (so cd into the worktree, or for codex use -C <dir>).
When dispatching parallel worktree agents, launch each worker into its own window inside a dedicated detached tmux session. Set remain-on-exit on so a finished or crashed worker keeps its pane, and tee the output to a log in the worktree so it survives:
sess="quintet-worktrees-$(date +%s)"
tmux new-session -d -s "$sess" -c "$REPO" -n "leader"
tmux set-option -w -t "=$sess:=leader" remain-on-exit on
# Log visibility for the human user
echo "Worktree session active: tmux attach -t $sess"
# One window per worktree worker (exact targets: "=session")
tmux new-window -t "=$sess" -n "wt1-codex" -c "$WT1" \
"codex exec -C '$WT1' -s workspace-write 'Read ./.brief.txt and follow it exactly.' 2>&1 | tee '$WT1/.agent.log'"
tmux set-option -w -t "=$sess:=wt1-codex" remain-on-exit on
tmux new-window -t "=$sess" -n "wt2-agy" -c "$WT2" \
"agy -p 'Read ./.brief.txt and follow it exactly.' --dangerously-skip-permissions 2>&1 | tee '$WT2/.agent.log'"
tmux set-option -w -t "=$sess:=wt2-agy" remain-on-exit onAdd .agent.log and .brief.txt to the repo's .git/info/exclude. remain-on-exit is set right after the window is created, so a worker that dies within milliseconds can still lose its pane. For a hard guarantee, create the window on sleep 86400, set the option, then tmux respawn-pane -k -t "=$sess:=wt1-codex" "<command>" (this is what quintet team does).
No-tmux fallback: if tmux is missing or errors, run each worker as a background subshell with its output captured:
( cd "$WT1" && codex exec -C "$WT1" -s workspace-write 'Read ./.brief.txt and follow it exactly.' ) > "$WT1/.agent.log" 2>&1 &Then wait and read each .agent.log.
git worktree add -b <branch> <dir> <base>
ln -s "$REPO/node_modules" "<dir>/node_modules" # share deps; never reinstall
cp "$REPO/.env" "<dir>/.env" # gitignored secrets the build needsTell every agent "do not run npm install — node_modules is a symlink", or a sandboxed install will either fail or duplicate hundreds of MB per worktree.
The trap: .gitignore with node_modules/ (trailing slash) matches a directory, not a symlink named node_modules. So git add -A will stage the symlink into the commit, and merging it later creates a self-referential tracked symlink that collides with the real dir on checkout. Two defenses, use both:
git add src/foo.ts), never git add -A/..node_modules (no slash) to the repo's .git/info/exclude.After every agent finishes, verify the commit touched only owned files and amend out any leak.
Real task briefs contain quotes, backticks, <>, $ — interpolating them into a shell -p "..." arg corrupts the command or triggers command substitution. Don't pass the brief on the command line. Write it to a file inside the worktree and give a tiny literal prompt:
cp brief.txt "<dir>/.brief.txt" # exclude it from git too
codex exec -C "<dir>" -s workspace-write "Read ./.brief.txt and follow it exactly."The CLI opens the file with its own read tool. Zero shell-escaping risk, and the brief can be arbitrarily long/complex.
--dangerously-bypass-approvals-and-sandbox. A safety classifier (and good sense) will block it. Use sandboxed write instead: -s workspace-write -c sandbox_workspace_write.network_access=true — confined to the worktree, but with network for build-time fetches. A blanket "I approve everything" from the user does not override the bypass block; sandboxed mode is what actually runs.EROFS / index.lock: Read-only file system. A linked worktree's git index lives in the main repo's .git/worktrees/<name>/, which is outside the worktree sandbox. So a sandboxed codex can edit files and run the build, but cannot git commit. Plan for it: the agent's edits land uncommitted in the working tree — the orchestrator (unsandboxed) builds, scans, and commits them. gemini --yolo / copilot --allow-all are not filesystem-sandboxed this way and commit fine.The point of external CLIs is token distribution: keep the orchestrator (your own model) for coordination/verification, and push review and the resulting fixes onto the provider CLIs. A review that only reports, then makes the orchestrator implement, defeats the purpose.
workspace-write (the agent writes its report file); instruct "modify no source; write findings to ./REPORT.md."dist/. Either give each its own worktree, or pre-build once yourself and tell reviewers "a build already exists in ./dist; do not rebuild."git merge b1 b2 b3 ...); disjoint files → no conflicts.node_modules/brief/secret leak in the diff; (3) npm run build green on the integrated tree; (4) grep the build output for secret values (build-time secrets must not reach client bundles).CLI tools that load env (e.g. netlify env:import) often echo the values back to stdout — a leak into your transcript/logs. Pipe through a mask, or prefer file-based imports that don't print values, and if a secret does surface, tell the user to rotate it.
| Symptom | Cause | Fix |
|---|---|---|
| First task ignored | interactive REPL warmup-swallow | use headless exec/-p, not a REPL |
codex won't commit (EROFS) | git index outside worktree sandbox | orchestrator commits the agent's edits |
--dangerously-bypass… denied | safety classifier | -s workspace-write -c sandbox_workspace_write.network_access=true |
node_modules symlink in commit | node_modules/ ignore ≠ symlink | explicit git add; add node_modules to exclude |
| command mangled / substituted | quotes/backticks in -p arg | brief-file pattern |
dist/ corrupted | concurrent builds, same dir | pre-build once; reviewers don't rebuild |
| deployed site "code works but does nothing" | gitignored .env absent from CI build env | set env vars in the deploy platform; rebuild |
salemaziel/omc-octo-quintet
d347b26
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.