Stop Babysitting Your AI Agents: Orchestrating Claude Code with Purplemux
Stop Babysitting Your AI Agents: Orchestrating Claude Code with Purplemux
You fire up three different terminal windows. In tab one, an AI agent is tearing down a legacy authentication module. In tab two, another is generating unit tests. You step away to pour a single cup of coffee. When you return, nothing has happened. Why? Because three seconds after you stood up, all three agents paused, politely waiting for a "Y/n" confirmation to run a bash script. The asynchronous workflow dies right there at the terminal prompt.
I ran into this exact wall recently. As a solopreneur building systems from the ground up, I rely heavily on CLI agents like Claude Code to multiply my output. But the more agents I spawned, the more I felt like a glorified babysitter polling terminal tabs for status updates. Missing a prompt approval meant losing twenty minutes of idle time. Moving to the couch to think meant breaking my operational awareness completely.
The real bottleneck in AI-assisted coding is the orchestration of human approval. If you run agents in the background, you need an orchestration layer to manage them.
The Control Plane Missing from CLI Agents
I eventually mapped out a fundamentally better way to handle this workflow using a tool called Purplemux. It is an open-source tmux manager built specifically to wrangle Claude Code sessions.
Instead of managing detached tmux sessions manually or keeping a matrix of terminal windows open, Purplemux provides a web and mobile dashboard. You run it, and suddenly you have a unified view of every agent's state. Is it processing or waiting for input?
More importantly, it supports mobile push notifications. I can leave my desk, get an alert on my phone that an agent needs approval, and unblock it remotely.
Implementation: Systemizing the Bootstrap Phase
While you can launch the dashboard with a simple npx purplemux (which spins up on port 8022 by default), I prefer to systemize how I bootstrap my agent workspaces. Clicking around a UI to start processes violates my rule of infrastructure-as-code.
I wrote a TypeScript orchestration script to spin up my tmux sessions with predefined contexts before handing them over to the visual manager.
Here is how I automate the agent dispatch:
import { execSync } from "child_process";
import { writeFileSync } from "fs";
import { join } from "path";
interface AgentTask {
sessionName: string;
workingDir: string;
instruction: string;
}
// Define the parallel tasks I want my agents to tackle
const tasks: AgentTask[] = [
{
sessionName: "auth-migration",
workingDir: "./apps/api",
instruction: "Migrate the login controller from bcrypt to argon2. Ask for approval before running npm install."
},
{
sessionName: "frontend-tests",
workingDir: "./apps/web",
instruction: "Write Cypress E2E tests for the new checkout flow based on the existing components."
}
];
function bootstrapAgents(tasks: AgentTask[]) {
console.log("Initializing autonomous workspace...");
tasks.forEach((task) => {
console.log(`Bootstrapping agent session: ${task.sessionName}`);
// Create a detached tmux session running Claude Code with the specific prompt
const command = `tmux new-session -d -s ${task.sessionName} "cd ${task.workingDir} && claude -p '${task.instruction}'"`;
try {
execSync(command);
} catch (error) {
console.error(`Failed to start session ${task.sessionName}:`, error);
}
});
// Optionally generate a quick index file to track active sessions for our own tooling
const metadataPath = join(process.cwd(), ".agent-sessions.json");
writeFileSync(metadataPath, JSON.stringify({ activeTasks: tasks, timestamp: Date.now() }, null, 2));
console.log("\nAll agents dispatched. Run `npx purplemux` to monitor them via the web interface!");
}
bootstrapAgents(tasks);Once the script fires off the tmux sessions, the Purplemux web interface hooks right into those active processes. If I accidentally close my browser, the jobs keep churning. The persistent nature of tmux is the safety net, while the UI is the visibility layer.
Extending the Architecture: Custom Webhooks
Purplemux handles mobile push notifications out of the box, but as developers, we usually want our logs and alerts routed to our team's central nervous system, usually Slack or Discord.
Since tmux is just a local multiplexer, we can write a tiny Node daemon that tails the tmux pane outputs and looks for specific Claude Code strings (like "Cost:" or "[Y/n]"). This gives us custom webhook integrations without touching the core UI tool.
import { spawn } from "child_process";
import https from "https";
const SLACK_WEBHOOK_URL = process.env.SLACK_WEBHOOK_URL || "";
function sendSlackNotification(message: string) {
if (!SLACK_WEBHOOK_URL) return;
const payload = JSON.stringify({ text: message });
const req = https.request(SLACK_WEBHOOK_URL, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Content-Length": payload.length
}
});
req.write(payload);
req.end();
}
function monitorTmuxSession(sessionName: string) {
// Tail the tmux pane output in real-time
const tail = spawn("tmux", ["pipe-pane", "-t", sessionName, "-o", "cat"]);
tail.stdout.on("data", (data) => {
const output = data.toString();
// Pattern match Claude Code's prompt for human approval
if (output.includes("[y/N]") || output.includes("Do you want to run this command?")) {
console.log(`[Alert] ${sessionName} requires human input.`);
sendSlackNotification(`⚠️ Agent in session *${sessionName}* is paused and waiting for approval.`);
}
// Track completions
if (output.includes("Task complete")) {
sendSlackNotification(`✅ Agent in session *${sessionName}* finished its task.`);
}
});
tail.on("close", (code) => {
console.log(`Monitoring for ${sessionName} stopped with code ${code}`);
});
}
// Monitor the sessions we just created
monitorTmuxSession("auth-migration");
monitorTmuxSession("frontend-tests");This script runs alongside your Purplemux instance. Now you have a beautiful UI for when you are actively managing the process, and passive Slack notifications for when you are deep in thought on the couch.
Tracking the Burn Rate
One sneaky issue with parallel CLI agents is the API cost. When you have four sessions chewing through context windows, your usage bill can spike aggressively. If an agent gets stuck in a loop reading the same massive log file, you are burning money.
The dashboard includes rate limiting and session-specific token statistics. It is incredibly sobering to see exactly how many tokens a runaway refactor is consuming in real-time. By wrapping your agents in this manageable layer, you can kill the process from your phone before it drains your monthly API budget.
Conclusion
Treating AI agents as interactive terminal scripts limits their utility. They are background workers. They require asynchronous orchestration.
By decoupling the agent's execution from your active terminal using a tmux manager like Purplemux, you fix the broken feedback loop. Stop staring at blinking cursors waiting for permission prompts. Systemize your agents and go take a walk. Your code will be waiting for you.