Baton – Keep long coding goals moving across AI coding agents A tool called baton keeps a single long-running coding goal alive for days by rotating it among coding agents, ending each agent's turn at USD 50 or 5 hours, whichever comes first, and dropping an agent from a goal once USD 150 has been spent in that goal. baton requires at least one of OpenAI's Codex CLI or Antigravity CLI (agy), treats Claude Code as an optional third paid by use that joins only after a Console API key is saved, and requires the Superpowers plugin for its plan, build and review rounds. A goal finishes only when its verification command exits 0 and every agent approves in consensus; an agent declaring itself done is not accepted. baton keeps one long coding goal moving for days by passing it between coding agents, stopping each one before it can spend money it should not. It works with Codex and Antigravity alone; Claude is an optional third, paid by use, that only joins the queue once you save an API key for it. Its turn ends at USD 50 or 5 hours, whichever comes first, it is left out of a goal after USD 150 spent in that goal, and the monthly ceiling stays above all of that. You give it a goal an objective, a working directory and a verification command . It runs one agent until that agent nears its limit or its turn 5 hours ends, hands the work to the next, and when every agent is out, sleeps until the earliest reset and carries on. It finishes only when the verification command exits 0; an agent saying "done" means nothing. Every agent runs through its vendor's own CLI. baton reimplements no agent. Context moves between them through the repository, its commits and a handoff file, and each vendor's own conversation is resumed when its turn comes again. Inside a goal the work follows a cycle of plan, build and review, with a strong and a working model per provider see Phases phases-plan-build-review . flowchart LR subgraph queue "The queue: one agent runs at a time" direction LR codex "codex" -- antigravity "antigravity" -- claude "claude" claude -. "turn ends: back to the first" .- codex end queue -- cycle subgraph cycle "Every cycle of a goal" direction LR plan "plan" -- build "build" -- review "review" end review -- check{"the check passes?"} check -- "no: back to plan" -- plan check -- yes -- consensus "consensus: every agent approves" consensus -- "an agent asks for changes" -- build consensus -- "all approve" -- done "done" How baton works: Codex, Antigravity and then Claude take turns; every goal runs plan, build and review, then the check, then consensus of every agent, and only then is it done. baton does not bring its own AI or its own methods. It drives tools you install, and works with two projects it did not write. Everything it depends on or works with: | Project | What it does for baton | Required? | How to install | |---|---|---|---| | uv https://docs.astral.sh/uv/ and Python 3.12 or newer | installs and runs baton; baton itself has no other dependencies | required | the installer on astral.sh/uv https://docs.astral.sh/uv/ ; uv fetches Python 3.12 when it is missing | | OpenCode https://opencode.ai | the chat window you type in; baton shows up in it as the model baton/auto | only for the chat interface: baton run works without it | the installer on opencode.ai https://opencode.ai | | Codex CLI https://github.com/openai/codex | runs GPT models, through your plan | at least one of Codex and Antigravity, signed in to a plan | npm install -g @openai/codex , then sign in | | Antigravity CLI https://antigravity.google agy | runs Gemini models, through your plan | at least one of Codex and Antigravity, signed in to a plan | the installer on antigravity.google, then sign in | | Claude Code https://claude.com/claude-code | an optional third in the queue, paid by use: a turn ends at USD 50 or 5 hours, and a goal leaves it out after USD 150 | optional; needs a Console API key, not a subscription | install Claude Code, then save the key Quick start, step 3 | | Superpowers https://github.com/obra/superpowers | the working methods planning, test-driven building, verification, code review that baton puts in every round | required , by design: no round runs without it a goal waits until it is installed , and baton doctor fails; see Superpowers is required superpowers-is-required | git clone https://github.com/obra/superpowers ~/.config/baton/superpowers ; it is also found automatically from the official Claude Code plugin install, and any other location needs superpowers dir | | ai-memory https://github.com/akitaonrails/ai-memory | long-term memory across goals in the same directory | optional | download the release binary for your platform from its releases page and put it on PATH ; do not run ai-memory setup , which wires global hooks see Long-term memory long-term-memory | | launchd | keeps baton serve running in the background on macOS | macOS only, recommended: baton install-service | built in to macOS; on Linux keep baton serve running in a terminal or tmux | baton was tested with Codex CLI 0.166.0, Claude Code 2.1.318 and ai-memory 3.4.1. The stream formats and hook options it relies on are version-specific, so other versions may not behave the same. How the pieces fit. baton owns the rotation, the phases, the limits and the guards. Each vendor CLI Codex, Antigravity, Claude Code does the actual work, one round at a time, inside a model baton chose. Superpowers gives every round its method. ai-memory gives the goals long-term memory. OpenCode is the chat window in front of it all. Superpowers https://github.com/obra/superpowers is not optional, and there is no setting to turn it off. No round runs without it: a goal that cannot find it waits, still running, and looks again every 5 minutes, so installing it is all that is needed. The reason is the design: Superpowers is the working method for every provider. Codex, Antigravity and Claude get the same planning, test-driven building, verification and review discipline, in every fresh conversation, whichever agent happens to hold the baton. Install it as the table above says; baton doctor fails until it is found. baton finds it automatically only from the official Claude Code plugin install or from ~/.config/baton/superpowers ; an install anywhere else needs superpowers dir in defaults.toml . This walks you through everything once, with no prior knowledge of baton. It takes about 15 minutes. The commands assume macOS; on Linux everything works except the background service, so use the note in step 4. Before you start. Get the tools in What you need what-you-need : at least one of codex or agy , signed in to your plan, plus OpenCode for the chat window. Superpowers is installed in step 1. git clone https://github.com/cahian/baton.git cd baton uv tool install . git clone https://github.com/obra/superpowers ~/.config/baton/superpowers The last line is required, by design: no round runs without Superpowers see Superpowers is required superpowers-is-required . mkdir -p ~/.config/baton cp examples/defaults.toml ~/.config/baton/defaults.toml Claude is optional. Open ~/.config/baton/defaults.toml in any text editor and pick one of these: - No Claude the simplest : change nothing, and skip step 3. Without a saved key, Claude never runs and baton uses Codex and Antigravity only. To switch it off for good, set enabled = false under agents.claude api . - With Claude: set monthly budget usd to the credit you actually have, and budget reset day to the day of the month it renews. baton stops 10% before that number. Then do step 3. Claude joins the queue after the other two; its turn ends at USD 50 or 5 hours, whichever comes first, and a goal leaves it out after USD 150. To keep it for last, so that it runs only while the others are out, set reserve = true under agents.claude api . Change enabled for codex or antigravity the same way if you only have one of them. Create an API key in the Claude Console https://platform.claude.com and copy it. Then run this, which saves what you copied into a file only you can read: touch ~/.config/baton/anthropic.key chmod 600 ~/.config/baton/anthropic.key pbpaste ~/.config/baton/anthropic.key Do not paste the key into a chat or into a project. Check your billing first. baton cannot see or change it. If the Console has auto-reload on, or holds credits you bought, using the key can spend that money. Turn auto-reload off. baton install-service baton doctor install-service keeps baton running in the background, even after a restart. Every line of doctor should read ok Superpowers included ; with no Claude key it says claude api: not configured optional , which is fine. FAIL tells you what to fix; warn is only a heads-up. It spends nothing, so run it as often as you like. On Linux , skip install-service and leave baton serve running in a terminal. Optional: long-term memory. Put the ai-memory binary on your PATH and baton does the rest; without it baton works exactly as before. See Long-term memory long-term-memory . baton opencode-config This prints a block of settings. Where it goes depends on whether you already use OpenCode: - No ~/.config/opencode/opencode.json yet: save it directly: mkdir -p ~/.config/opencode baton opencode-config ~/.config/opencode/opencode.json - You already have that file: do not run the command above, it would erase your settings. Open the file and copy the baton entry into your existing provider section. Then tell OpenCode to read the change. If you skip this, baton will not show up: opencode reload Use a throwaway folder for your first try. The agents have full access to the folder where you open OpenCode , so do not start in a project you care about: mkdir -p ~/baton-test cd ~/baton-test git init opencode 1. Type /models . Searching for baton shows No results found . That is expected the first time. 2. Press ctrl+a to see all integrations, and choose baton .3. It asks for an API key. baton does not need one, but the box cannot be empty. Type local and press Enter.4. Type /models again and choose Auto . If OpenCode asks for a variant, keep Default . baton ignores this setting; effort is set in your defaults.toml . You are ready when the box at the bottom says Auto baton : OpenCode remembers the connection, but check that label whenever you open a new session. Create a hello.py that prints "hi" and run it to check. The answer streams in the chat like any other model. A small request is answered in one round: the plan finds nothing to build and the cycle ends there. A line tells you each time one agent hands over to another, and one each time the phase changes. While it works: - To change direction, just send another message. It reaches the agent after its current tool call never later than five minutes after , including a message you type while a reply is streaming, which OpenCode would otherwise hold until the reply ends. - Closing OpenCode does not stop the work. It keeps running in the background. Run these in another terminal: baton jobs everything running; names look like session-