Claudemux – Run and coordinate multiple Claude Codes reliably Claudemux, a new Node.js library from @wastedcode, enables developers to reliably run and coordinate multiple real-login Claude Code CLI sessions from a single process. The tool replaces ad-hoc workarounds like child_process.spawn and sleep timers by providing session management that accurately detects when an agent has finished a task, handles first-run dialogs, and allows users to drive a fleet of named sessions that can be monitored or taken over via tmux. Run and coordinate multiple real-login Claude Code sessions on your box, from Node. await session.wait actually returns when the agent is done. You have claude logged in on your machine and you want to drive it from code — spawn a session or a whole fleet , send a task, know when it's actually done , read the result, coordinate them. Today that's child process.spawn 'claude', … + ad-hoc ANSI regex + sleep 5 , times N sessions, plus glue to keep them from colliding: it hangs on the first-run trust dialog, silently stalls on prompts, and rots on every claude update. claudemux retires that layer once. js import { create } from "@wastedcode/claudemux"; const session = await create { name: "job", cwd: process.cwd } ; await session.send "Add a CHANGELOG entry for the next release" ; await session.wait ; // blocks until the turn ends; pass { maxMs } / { idleMs } to bound it const text = await session.capture ; create boots the agent, dismisses the first-run dialogs, and returns when the REPL is genuinely ready — not after a sleep . wait blocks until the turn reaches a terminal TurnOutcome — completed and the reply is readable , awaiting a decision, aborted , or out of your patience budget — fused from the agent's hooks + transcript, not screen-scraping. For the whole round-trip in one call there's ask send → wait → read ; to continue a conversation after a crash there's resume .That's one session. The name is the other half — drive a fleet , each session addressed by name , from one process: js import { create, ask } from "@wastedcode/claudemux"; // Boot three at once — each is its own real claude session. const fleet = await Promise.all "api", "ui", "docs" .map name = create { name, cwd: ./services/${name} } , ; // Fan a task across them; collect each as it actually finishes. const summaries = await Promise.all fleet.map s = ask s, "Summarize what changed in this service this week" , ; list enumerates the fleet; another process can adopt any session by name the daemon-spawns / workers-drive split . One reliable session is just the smallest fleet. And it's a real session, not a headless pipe: each runs in a tmux session you can tmux attach into to watch the agent work — or take the keyboard yourself one writer at a time, §4 . The programmatic handle and the live session you can sit down at are the same session. What this is for: driving the consumer-login claude CLI the one you set up with claude login on a box you control — one session, or many coordinating, the way an orchestrator might run several claude sessions that talk to each other. It inherits your box's claude config auth, permission mode, model, MCP and passes claude's own flags through; it owns no configuration of its own one exception: workspace trust, §4 . What this is not for: deployed or anonymous automation that drives claude via injected credentials or API keys — CI fleets, hosted services. Consumer-login claude can't run there ephemeral boxes can't interactively log in, and it's against Anthropic's terms ; that's what the Claude Agent SDK + API are for. claudemux makes the on-a-box, real-login case reliable. npm install @wastedcode/claudemux Requires Node ≥20 and a working claude CLI on PATH you've run claude interactively at least once so it's authenticated . MIT-licensed. The CLI and library map 1:1 — claudemux send name "..." is send name, "..." on the library side. One vocabulary. bash $ npm i @wastedcode/claudemux $ claudemux spawn my-job --cwd ./fresh-repo --trust-workspace {"agentSessionId":"f47ac10b-58cc-4372-a567-0e02b2c3d479"} persist this for resume $ claudemux ask my-job "Add a CHANGELOG entry for the next release" {"outcome":{"kind":"completed"},"messages": … ,"cursor":"…"} $ claudemux kill my-job ask is the one-shot round-trip; the primitives send → wait → messages are there when you want to drive the turn yourself. The first spawn in a never-trusted folder needs --trust-workspace above — it fails closed otherwise, and the flag writes a persistent per-folder authority grant; see Workspace trust fail-closed workspace-trust-fail-closed before pointing it at code you don't control. The full verb set: | Verb | What it does | |---|---| spawn