Why I Built an Orchestration Tool for My Coding Agents
I run a lot of coding-agent sessions now.
One agent fixing a bug is easy. Five agents across different projects, with deploys, SEO checks, product loops, callbacks, and follow-up work, is a different problem. Once I run enough agents, I spend more time tracking sessions, queues, callbacks, and follow-ups than asking whether the agent can write code.
I built Agent Control for that layer of the work.
Agent Control is my in-house macOS app and CLI for coordinating coding-agent sessions. It does not replace Claude Code, Codex, or Droid. It sits around them and handles the parts I kept tracking by hand once coding agents became part of the daily workflow: queues, callbacks, loops, handoffs, locks, session history, and cross-project messages.
I am a bootstrapped indie developer, and I choose to work across many small projects at the same time. Part of that is because I use SEO as an inbound channel. SEO takes time. A project may need months before I know whether the idea, keywords, product, and market are worth more effort.
That pushes me toward a workflow with many small active bets, not one large project that gets all my time.
I wanted prompts to become work, not notes
I have a loose rule now: write prompts instead of TODOs that never get worked on.
A TODO in a notes file is a reminder. It may get done. It may sit there for six months. A prompt in Agent Control can become a queued session, a child worker, or the next loop run.
That matters because a lot of agent work starts as a half-formed thought:
- check whether this page is still ranking
- compare yesterday’s analytics with the last 7 days
- follow up on that deploy after GitHub Pages finishes
- review this repo when the current session exits
- run this SEO loop again tomorrow
Not all of that should run immediately. A few prompts should wait behind the active same-repo session. Others should run as fresh child sessions, resume an existing coordinator, or run later.
Before Agent Control, this became a mix of tmux windows, notes, shell history, Reminders.app links, and me remembering which agent was doing what. That worked for a while. Then I had enough loops and projects that the bookkeeping became its own job.
I prefer serialized work on one repo
I usually work on my own projects on the main branch. I do not reach for git worktrees unless I have a specific reason.
Partly taste, partly risk management. Most of my projects are small enough that serialized work is simpler. I would rather have one agent finish, review, commit, deploy, and archive before another agent starts changing the same repo.
Agent Control follows that preference. If a repo already has an active session, same-repo work queues behind it. A queued task can still be explicit about what it wants:
agent-control-cli add \
--repo ~/p/theblue/theblue.social \
--prompt "Check the onboarding funnel and suggest one low-risk improvement."
That prompt is queued.
There are exceptions. Parent loop sessions can spawn child sessions. Read-only investigations can force-start. But the default is conservative: one repo, one active lane.
The queue also depends on sessions exiting when they are done.
I have an ask-to-exit skill for that. A worker can finish the job, report back, then ask to close itself. Once Agent Control sees that session exit and archives it, the app knows the same-repo lane is clear and can start the next queued task.
Serial queueing works better when the finished agent can give Agent Control a clear “this session is done” signal.
I want the process to be agentic
I do not want an agent to only answer a prompt.
I want it to run the command, read the output, make the next decision, and report back to the right place. If a deploy takes a few minutes, I do not want to babysit the terminal. I want the deploy to run in tmux and send a callback to the exact Agent Control session that started it:
agent-control-cli message \
--session "$AGENT_CONTROL_SESSION_ID" \
--prompt "Deploy finished. Verify and report status."
That small callback changed a lot of my workflow.
Without it, a long-running command finishes somewhere. Maybe I notice. Maybe I do not. With it, the agent gets pulled back into the work at the right time. It checks the result, fixes errors if needed, and tells me what happened.
Agent Control has a CLI for the same reason. The app is useful, but the CLI lets agents, scripts, tmux panes, and loop workers coordinate without me clicking around.
Agents need to talk across projects
A lot of my work crosses repo boundaries now.
A product loop may inspect analytics for one app, update a landing page, queue a follow-up in the blog, and tell a coordinator session what happened. Deploys can finish in tmux and report back to the exact session that started them. Child workers can finish SEO checks and message the parent loop before they exit.
Plain tmux does not try to solve that. tmux keeps processes alive. Agent Control gives those processes an address.
An Agent Control session ID is not the same thing as a Claude Code, Codex, or Droid session ID. Agent Control owns its own session identity. That gives me a stable target for messages:
agent-control-cli message \
--session "197B1443-06E7-40F6-BC6E-13AA3BC20A73" \
--prompt "The child SEO check finished. Schedule the next run for tomorrow."
That can come from another agent, a shell script, a tmux callback, or a loop worker. It does not matter which backing agent is underneath.
What carried over from tmux
Most of my coding-agent workflow started in tmux.
I wrote about using tmux with Claude Code because tmux gave me the primitives I needed:
- persistent sessions
- visible logs and process output
- keyboard-first navigation
- scrollback and search
- simple commands agents can run
- multiple agents in separate windows
I kept all of that.
Agent Control is not a replacement for tmux. My long-running dev servers, deploys, and shell processes still run there. The difference is that tmux is process coordination, while Agent Control is agent-session coordination.
That includes deploys. If a command may take a few minutes, I still run it in tmux so the output stays visible and the process survives the agent session. Agent Control handles the callback when the command finishes.
tmux tells me where the process is.
Agent Control answers:
- which agent session owns this task?
- what is queued for this repo?
- which session needs attention?
- where should this callback go?
- what loop should run next?
- what did the last worker report?
This works well for me. tmux stays good at being tmux. Agent Control handles the layer above it.
What Agent Control does
Agent Control is a SwiftUI macOS app with a SQLite database behind it. The CLI writes into the same database and notifies the app.
The app manages sessions for:
- Claude Code
- Codex
- Droid
Each session has a repo path, agent type, status, transcript, archive state, queue state, and enough metadata for the app and CLI to find it again later.
The main things I use every day:
- start or queue a fresh coding-agent session
- message an existing session by ID
- queue work behind the active same-repo session
- search old sessions and messages
- create bookmarks into relevant parts of session history
- run callbacks from tmux and scripts
- create child sessions from a parent coordinator
- schedule recurring loop prompts
- let finished sessions ask to close themselves
- use locks for shared resources like deploys or browser control
The UI is mostly there so I can see what is going on. The CLI is there so agent sessions running inside the Agent Control app can do the coordination themselves.
Session history matters more than I expected. When a session finishes something worth remembering, I can have it create a bookmark URL for the relevant point in the transcript and append that URL to my task log. Later, when I see the task in wip.md, I can jump back to the exact session history instead of searching through dozens of old agent conversations.
The CLI primitives matter more than the UI
The CLI is intentionally small. I use it myself sometimes, but the main caller is usually an agent session already running inside the Agent Control macOS app.
Start a new task:
agent-control-cli add \
--repo ~/p/myog/myog.social \
--prompt "Check today's Google Search Console changes and report anything worth acting on."
Message an existing session:
agent-control-cli message \
--session "SESSION_ID" \
--prompt "The export finished. Verify the report and summarize the result."
Queue a child session under a parent:
agent-control-cli add \
--parent-session "$AGENT_CONTROL_SESSION_ID" \
--prompt "Run this loop iteration, then report back to the parent session."
Schedule the next loop run:
agent-control-cli loops schedule \
--session "SESSION_ID" \
--loop "LOOP_ID" \
--title "SEO check" \
--next-run "2026-07-05T09:00:00+08:00" \
--cadence "tomorrow" \
--prompt "$next_prompt"
The commands are plain enough for the agent to run. I can put them in AGENTS.md. A tmux deploy can call them after a long-running command finishes.
Loops need a coordinator
The loop workflow is where Agent Control became much more useful than my older Reminders.app setup.
The pattern uses two sessions:
- an outer coordinator session that owns the recurring loop
- a fresh inner worker session for one iteration
The coordinator wakes up, creates a child worker, and waits. That child does the actual work, sends a structured callback to the coordinator, then exits or archives. After the callback arrives, the coordinator schedules the next run.
For example, an SEO loop may do this:
- coordinator wakes up for MyOG.social
- child session checks GSC, Ahrefs, and analytics
- child makes a low-risk change only if the evidence supports it
- child runs the normal finish workflow: review, test, commit, deploy, verify
- child reports back with
agent-control-cli message - coordinator schedules the next run with the latest context
The long-lived loop context stays separate from the worker context. The coordinator does not need every log line from the child. It needs the result, evidence, changed files, commit, deploy status, blockers, and next action.
That one pattern cleaned up a lot of recurring work.
Where AGENTS.md and skills fit
Agent Control does not replace repo instructions or skills.
I still use AGENTS.md to tell agents how to work inside a repo: commands, deploy rules, coding conventions, browser-check rules, and project-specific traps.
I still use skills for repeatable workflows: commit, deploy, take over, loop-task, external service reports, and so on.
Agent Control decides which session gets work and how sessions report back. AGENTS.md tells the agent how to do the work once it is in the repo. Skills package up workflows the agent should follow.
Those layers should stay separate. It’s easier to maintain.
What I did not build
Agent Control is not an IDE.
I did not add editing or git functionality to it. I already have Neovim and GitUp for those jobs. Agent Control has configurable commands to open the current file in my editor or the current repo in my git client, but it does not try to become either tool.
It is not a replacement for Claude Code, Codex, Droid, tmux, git, Kamal, DevSnoop, or AGENTS.md.
It does not make agents smarter, decide whether an SEO edit is good, remove review, or make five agents safely edit the same repo at once.
It mostly gives my agent work a place to go:
- sessions have names and status
- queued prompts wait behind active work
- callbacks know where to return
- loops know which coordinator owns them
- child sessions can report to parents
- shared resources can be locked
I do not need much more than that for my current workflow.
Why I built it in-house
I built it by using it.
I did not start with a product spec. I started with places where the workflow kept breaking down:
- I lost track of which agent was doing what
- long-running deploys needed to call agents back
- loops needed a stable coordinator
- Reminders.app links were too clumsy for recurring agent work
- same-repo work needed to serialize by default
- agents needed to talk across projects
I could have kept layering scripts on top of tmux. I still use plenty of scripts. But once session state, queue state, loop state, and callbacks all needed to agree, a small app with a database made more sense.
The full setup is still simple in the way I care about. Agent Control owns the state. The CLI exposes it. Agents use the CLI. tmux keeps the long-running processes visible.