| name | agent |
| description | Use for PR/code reviews and any task that benefits from a dedicated tmux sub-agent with per-task git worktrees; default path for reviewing diffs (read diff → summarize → run checks/tests) with automated monitoring. |
Agent Control Panel (tmux + monitor)
Overview
Use your current Codex window as the operator console. From here, create a dedicated tmux session on the default tmux server (no custom socket) that hosts sub-agent panes. You stay outside tmux as the driver—only the sub-agents run inside tmux windows—and you poll their output to know when to step in. This keeps the control session visible alongside your existing tmux workflow. You are the hub; no separate “hub” window is spawned. Default for any code review request: assume “full agent review” unless the user explicitly opts out.
When to Use
- You need parallel sub-agents (e.g., multiple tasks/PRs) managed from one Codex session.
- Long-running interactive tools (debuggers, REPLs) where you want passive monitoring.
- Any scenario where Codex should only step in when a pane is stuck or asks a question.
- Code reviews / PR reviews: always choose this skill first; do not default to
webfor GitHub PRs.
Core Pattern
- Session on the default tmux server (driven from THIS Codex window):
SESSION=control tmux new -d -s "$SESSION" - Create a per-task git worktree (keeps tasks isolated):
task=feat-xyz git worktree add .worktrees/$task -b $task # or checkout existing: git worktree add .worktrees/$task origin/$task - Launch a sub-agent window (one task each; you remain outside):
After Codex starts, only send text prompts (no shell commands) into this pane. The sub-agent handles execution inside its own Codex.tmux new-window -t "$SESSION" -n task-a tmux send-keys -t "$SESSION:task-a" -- 'cd .worktrees/task-a' Enter tmux send-keys -t "$SESSION:task-a" -- 'codex --dangerously-bypass-approvals-and-sandbox' Enter tmux send-keys -t "$SESSION:task-a" -- 'You are the sub-agent. Wait for a single natural-language prompt from the operator; you will execute all actions yourself. Do not ask the operator for confirmations.' Enter - Monitor loop (flag panes needing input; run from this control panel):
monitor_once() { for tgt in $(tmux list-panes -a -F '#{session_name}:#{window_name}.#{pane_index}'); do OUT=$(tmux capture-pane -p -J -t "$tgt" -S -120) NEED=$(printf "%s\n\nIs this pane waiting for operator input? Reply YES or NO only." "$OUT" \ | codex exec --system "You are a detector. Reply YES if the pane asks a question/choice or is stalled; NO otherwise.") [ "$NEED" = "YES" ] && echo "$tgt" done } while true; do NEEDS=$(monitor_once); [ -n "$NEEDS" ] && { echo "Input needed: $NEEDS"; break; } sleep 10 done - Intervene minimally (from this Codex pane): map the flagged pane to its tmux target (e.g.,
control:task-a.0) and send exactly one concise answer withtmux send-keys -t <target> -- '...response...' Enter; then restart the monitor loop. - Tell the user how to attach/monitor right after creating sessions and again when wrapping up:
tmux attach -t control tmux capture-pane -p -J -t control:<window>.0 -S -200 - Cleanup:
tmux kill-session -t "$SESSION"(ortmux kill-serverif dedicated). Remove worktrees when done:git worktree remove .worktrees/task-a.
Default Code Review Flow (use this unless the user specifies otherwise)
- Ensure repo/PR exists locally (clone if missing to
~/github/<owner>/<repo>; create.worktrees/pr-<num>andgh pr checkout <num>). - Read the PR diff first and post a concise summary of changes/risks before running anything.
- Run the standard checks for the stack (fmt/lint/tests) after summarizing unless the user opts for a lighter pass.
- Deliver review findings ordered by severity with file/line refs; include any failed checks; suggest next steps.
- Only deviate (skip tests, partial review) if the user explicitly requests it.
Session Convention
- Use the default tmux server so the control session shows up alongside your existing tmux work (
tmux ls,tmux switch -t control). - Keep session/window names short and slug-like (
task-a,debug,ci).
Targeting & User Monitor Commands
- Pane target format
{session}:{window}.{pane}, default:0.0if omitted. - Keep a mapping of task → window name; set
TARGET="<session>:<window>.0"before sends to avoid misrouting. Always include-t "$TARGET"on everysend-keysandcapture-pane. - Immediately after starting any session/window, print both commands for the user:
- Attach:
tmux attach -t control - One-time capture:
tmux capture-pane -p -J -t control:<window>.0 -S -200
- Attach:
Sending Input Safely
- Prefer literal sends to avoid shell splitting:
tmux send-keys -t target -l -- "$cmd"thenEnter. - For inline commands use single quotes or ANSI C strings:
tmux ... send-keys -- $'python3 -m http.server 8000' Enter. - Control keys:
C-c,C-d,C-z,Escape, etc. - After sending the natural-language prompt, verify the model actually started: capture the pane; if you still see the CLI welcome plus your prompt with no model output, send a single bare
Enter(tmux send-keys -t target Enter) and re-check. Do not resend the full prompt unless the pane is empty.
Watching Output
- Capture recent output:
tmux capture-pane -p -J -t target -S -200. - For continuous monitoring, rely on the monitor loop; avoid
tmux wait-for(doesn’t watch pane text).
Synchronizing / Waiting for Prompts
- Poll for prompts before sending commands, e.g.:
./tools/wait-for-text.sh -t "$SESSION":0.0 -p '^>>>' -T 15 -l 4000 - For long-running tasks, poll for completion strings (“Program exited”, etc.) before proceeding.
Spawning Processes (defaults)
- Debugging: prefer
lldbunless user requests otherwise. - Python REPL: set
PYTHON_BASIC_REPL=1; start withpython3 -q; wait for^>>>; send code with-l; interrupt viaC-c.
Interactive Recipes
- Python REPL:
tmux ... send-keys -- 'PYTHON_BASIC_REPL=1 python3 -q' Enter; wait for prompt; send code;C-cto interrupt. - gdb:
tmux ... send-keys -- 'gdb --quiet ./a.out' Enter;set pagination off;C-cto break;bt,info locals; exitquittheny. - Other TTY apps (ipdb, psql, mysql, node, bash): start app, wait for prompt via
wait-for-text, then send literal text + Enter.
Cleanup
- Kill session:
tmux kill-session -t "$SESSION". - Kill all agent sessions (if dedicated server not used):
tmux list-sessions -F '#{session_name}' | grep '^control$' | xargs -r -n1 tmux kill-session -t. - If you did start a dedicated server manually, kill it with
tmux kill-server. - Remove worktree when done:
git worktree remove .worktrees/<task>.
Tips
- Keep socket under
${TMPDIR:-/tmp}/agent-tmux-sockets; names short (task-a,task-b). - Use git worktrees under
.worktrees/<task>so sub-agents never clash; point each Codex session at its worktree immediately. - Use literal
send-keys -l,capture-pane -J,wait-for-text.sh, and setPYTHON_BASIC_REPL=1before Python REPLs. Always print attach/capture commands for the user. - Poll with
capture-pane -Jto avoid wrap artifacts; limit history to ~200 lines for speed.
Quick Reference
- Start control session:
tmux new -d -s control - Launch agent window:
tmux new-window -t control -n foo; tmux send-keys -t control:foo -- 'codex ...' Enter - Monitor: loop over panes →
codex execclassifier YES/NO → intervene → resume - User attach:
tmux attach -t control - Cleanup:
tmux kill-session -t control - Helpers available:
tools/find-sessions.sh,tools/wait-for-text.sh(copied locally).find-sessions.shsupports-S SOCKET,-q filter, or--allto scan socket dir;wait-for-text.shsupports-t target -p regex [-F] [-T timeout] [-i interval] [-l lines].
Red Flags
- Spawning a separate socket; the intent is to share the default tmux server so navigation is easy.
- Not printing attach/capture commands for the user.
- Letting multiple tasks share one pane (one task per window).
- Spamming multiple inputs before re-running the monitor loop.
- Sending input without an explicit
-t <target>(risk of driving the wrong sub-agent).
Prompting & Brainstorming Workflow
- Always brainstorm with the user first using the
brainstormskill to agree on the prompt content and success criteria before dispatching anything to a sub-agent. - When ready, send a single, clear natural-language prompt into the sub-agent Codex pane (no shell commands). The sub-agent executes and reports back in that pane; you monitor and relay only when needed.
- Avoid running additional bash commands inside the sub-agent pane after Codex starts; keep interactions textual prompts/responses to maintain separation of concerns.