batonhq

Hand a unit of coding work from one AI agent to another β€” plan on your expensive agent, pass the baton to your cheap one.


Keywords
ai, agents, claude-code, cursor, handoff, llm, cli, developer-tools
License
Other
Install
npm install batonhq@0.2.2

Documentation

πŸͺ„ Baton

Plan on your expensive agent. Pass the baton to your cheap one.

Baton is a local coordination hub + knowledge base for running multiple AI coding agents on one repo β€” Claude Code, Cursor, Codex, Gemini, Aider, OpenCode. Isolated git worktrees, a realtime dashboard, shared evidence-anchored memory, installable skills, and one-file session handoff.

Baton documentation website

Docs Β· Features Β· How it works Β· Use cases Β· FAQ Β· About

In this repo: Quickstart Β· Documentation Β· CLI reference Β· Architecture

npm CI license node deps telemetry


Why Baton

Developers increasingly run two or three AI coding tools at once and split work to save money and quota β€” plan and reason on a powerful (often plan-included) agent, then do the bulk editing on a cheaper one. But the agents don't know about each other:

  • They clobber the same files with no warning.
  • Switching tools loses all the context β€” the plan, the diff, the remaining tasks die with the session.
  • Each one re-reads the whole repo to orient, burning tokens.

Baton coordinates them on one repo: every task runs in its own git worktree, a local daemon streams who's editing what in realtime, a queryable knowledge graph lets agents navigate instead of grepping, shared memory carries verified facts between sessions, and a single HANDOFF.md carries a curated, execution-ready brief β€” with a cost estimate β€” from one agent to the next.

One file (HANDOFF.md). No server lock-in. No database. Open source.

The core idea: pass the baton

Claude Code (plan / think)                 Cursor Β· Codex Β· Gemini (edit cheap)
──────────────────────────                 ─────────────────────────────────────
  baton pass my-task --to cursor ─────────▢  HANDOFF.md  ─────────▢  baton take my-task
  (curated brief + est_cost_usd)            (objective Β· plan Β·      (prints the execution
                                             files Β· git state Β·      prompt, marks in-progress)
                                             graph excerpt)                  …agent edits…
                                                                            baton done

Do the expensive thinking where it's powerful (or included in your plan); do the bulk editing where it's cheap. Baton emits a minimal, cheap-to-execute brief with a token/cost estimate β€” not a raw history dump.

Quick start

Prefer to have an agent do this for you? Paste this repo into Cursor or Claude Code and say "set this up for me" β€” it'll follow AGENTS.md, ask what it needs to know (which project to wire up, which agents you use, which port), run every command itself, and leave you a personalized GETTING_STARTED.md in your project when it's done.

Requires Node β‰₯ 24 and git. Run this in any repo:

npx batonhq setup

It scans the folder, then asks a handful of arrow-key questions β€” one repo or a hub over several, which agents you use, whether to turn on the knowledge graph. Each option carries a note explaining it, and Enter takes the recommendation. Then:

baton serve --write  # daemon + dashboard β†’ http://localhost:7077
Installing it permanently, and the optional knowledge graph
npm install -g batonhq     # `baton` on your PATH (setup offers this at the end)

Those two β€” npx or a global install β€” are the ways that work. Never npm i batonhq inside a project: Baton is a CLI, nothing imports it, and as a dependency it makes every npm install in that project rebuild the whole tree, native modules and all.

The knowledge graph needs one extra tool, the Python graphify CLI:

uv tool install graphifyy  # or pipx install graphifyy

Setup offers to install it for you and never blocks on it β€” without it you lose the graph, and worktrees, tasks, edit signals, memory, handoff and the dashboard all still work. See docs/installation.md.

The npm package is batonhq; the command is baton. (Unrelated packages named baton, baton-cli and create-baton belong to other projects.)

Then create an isolated session and point an agent at it:

baton new "refactor the auth middleware"   # β†’ branch baton/… + worktree under .baton/wt/
cd .baton/wt/refactor-the-auth-middleware  # start claude / cursor / codex here

Working across several repos? Run baton setup on the folder that holds them to create one hub β€” a single dashboard + merged knowledge graph over all of them. baton serve runs from the hub root (which needn't be a git repo); each task just names its sub-project, and the worktree branches off that repo:

baton new "fix the checkout crash" --project api-server   # or pick it in the dashboard

What you get

Feature What it does
🌳 Worktree isolation Every task gets its own git worktree + baton/<slug> branch. No clobbered branches, ever.
🧠 Knowledge graph baton kb indexes your repo into a queryable graph (via graphify) + a CODEBASE.md map. Agents navigate instead of grepping β€” the map is ~300Γ— cheaper than reading the files.
🀝 Session handoff baton pass packages a session into one HANDOFF.md β€” objective, plan, checklist, files, git state, cost estimate β€” and baton take turns it into an execution prompt.
πŸ“‘ Live edit signals A realtime dashboard (SSE) shows who's editing what β€” and what they're doing (each session's live intent note + freshness). Two sessions on one file β†’ an overlap warning before the conflict.
πŸ“Œ Evidence-anchored memory Shared facts pinned to commits + file content hashes. When an anchored file changes, the fact is withheld β€” agents can't hallucinate from stale knowledge. Nothing is hard-deleted: removed facts go to a journaled archive (baton memory log).
🧩 Installable skills A catalog of reusable agent playbooks β€” one click (or baton skills install <id>) installs a skill into every agent at once, each in its own format (.claude/skills/…, .cursor/rules/…). Ships a flagship bug-fix pipeline, a lean-code restraint skill (adapted from Ponytail, whose ladder measured ~54% less code and ~20% cheaper on real agent sessions), and an efficiency & traceability pack.
πŸ› Bug recurrence baton bugs "<symptom>" β€” was this fixed before, and did a later change re-break it? Composes recorded fixes (memory) with commit history to name the suspect commits. Zero new storage.
πŸ”€ Agent routing baton route picks the right agent per task from committed rules (deterministic, no LLM) β€” and handoff prefers the least-loaded available agent.
🧭 MCP tools baton mcp exposes coordination tools (check_files, who_touched, recall_memory, …) to every agent over MCP.

When you'd reach for it

Five situations Baton is built for. Each is one command.

Your good agent is rate-limited, and you still have work to do. Plan on the agent that reasons well, execute on the one that's cheap or still has quota. The brief carries the objective, plan, checklist, touched files, git state and a cost estimate β€” not a transcript dump.

baton pass fix-checkout --to cursor     # β†’ HANDOFF.md
baton take fix-checkout                 # on the other agent

Two agents just edited the same file. Every task gets its own worktree and branch, so they physically cannot collide. Before an agent touches a shared file, it asks β€” and gets told who's in there and what they're doing.

baton new "refactor auth"               # isolated worktree + branch
baton signals                           # who is editing what, right now

A session died mid-task β€” context ran out, the window closed, you went home. The next session picks up from a written brief instead of re-deriving everything.

baton resume fix-checkout

An agent is new to the repo and starts grepping. It reads a queryable graph and a CODEBASE.md map instead β€” roughly 300Γ— cheaper than reading the files it would otherwise open to orient.

baton kb init && baton orient

One product, several repos (api, web, mobile, infra). Point setup at the folder holding them: one merged graph, one dashboard, tasks that name their sub-project.

npx batonhq setup                       # detects the repos, offers the hub
baton new "fix the checkout crash" --project api

Bonus β€” "didn't we already fix this?" Composes recorded fixes with commit history to name the commits that likely re-broke it.

baton bugs "checkout 500s on empty cart"

Your code stays on your machine

Baton is a local tool. It is worth being precise about this rather than asking you to take it on faith:

  • No telemetry, no analytics, no account. There is no tracking code in the source β€” nothing to opt out of, because there is nothing to opt into.
  • Solo mode makes zero outbound requests. The daemon binds 127.0.0.1 and is unreachable from outside your machine. Your code, graph, memory and tasks live in .baton/ in your own repo.
  • No install scripts. npm i -g batonhq runs no postinstall, so nothing executes on install. It works fine under npm i --ignore-scripts.
  • Team mode is opt-in and metadata-only. Networking happens only after you run baton host set <url> to link machines. Even then, what crosses the wire is coordination metadata β€” task slug, agent name, which paths are being edited β€” never file contents. baton serve --host likewise binds a public interface only when you explicitly ask it to.
  • Two commands fetch a URL, and both are ones you typed. baton join <url> reads a workspace manifest from a host you name, and baton skills import <url> downloads a skill you point it at. Neither runs on its own, and neither uploads anything.
  • Your agents still talk to their own vendors. Claude Code, Cursor and the rest send your code to Anthropic, OpenAI and so on exactly as they always did. Baton neither adds to that nor can prevent it β€” it coordinates the agents, it does not sit between them and their APIs.

Everything above is checkable: the outbound calls are in src/host-link.ts, src/pipeline-claims.ts and src/remote-claims.ts, all gated on a host link you configured. See docs/security.md.

The dashboard

baton serve serves a realtime React dashboard at http://localhost:7077 β€” a Command Center board, live Activity, Conflicts, the Knowledge Graph, Memory, History, an Agents roster (with one-click MCP wiring), and the Skills catalog. It binds to 127.0.0.1 only and is read-only until you pass --write. See docs/dashboard.md.

Do I need the daemon running?

No β€” Baton is terminal-first. You open your own terminals, run claude / cursor / codex yourself, and coordination happens through hooks + MCP tools + a local SQLite file. Start the dashboard only when you want to look:

Works with no daemon Needs baton serve
Edit signals β€” sessions warn each other before touching a busy file (the edit hook writes them) The dashboard UI + realtime (SSE) live view
Shared memory, recall/save, orient briefs, baton bugs, reports, blame, handoff Knowledge-graph queries over MCP (the daemon hosts one shared graphify backend per project)
Graph rebuilds (git post-commit hook, incremental) Interactive agent terminals in the browser
The whole CLI: status, signals, pass/take, merge, doctor Headless agent launch from the UI

History, memory, and reports are plain files + git β€” so when you do open the dashboard later, the past is all there; only live uncommitted-edit activity from hook-less agents needs the daemon watching at the time.

Documentation

Tip

🌐 Read the docs on the web β†’ baton-landing.vercel.app/docs

Cross-linked and nicer to read than raw markdown β€” start with How it works for the handoff flow, Use cases for real setups, or the FAQ.

Home Β· Docs Β· Features Β· How it works Β· Use cases Β· FAQ Β· About

The same docs also live in this repo under docs/:

How it's built

  • Zero-dependency daemon β€” src/server.ts is raw node:http. No express, no fastify.
  • Realtime is SSE, not socket.io β€” every live event flows through one bus.
  • Git-native β€” no external database; a small local SQLite index over your real git history. All git runs shell-free through a hardened wrapper.
  • Loopback-only + write-gated β€” the daemon binds 127.0.0.1, and every mutating request requires a loopback origin and (mostly) --write. See the security model.
  • Strict TypeScript in two workspaces (root + web/).

Contributing

Baton is open source (AGPL-3.0) and contributions are welcome β€” the project is deliberately easy to hack on:

  • Orient first: STATUS.md is the living map β€” what's built, what's pending, and where every module lives. docs/architecture.md explains the shape; CLAUDE.md lists the conventions that must not break (zero-dependency daemon, SSE-only realtime, shell-free git).
  • How changes land: every feature is TDD'd (the test exists and fails before the code), and non-negotiable behaviors are guarded by invariant tests β€” if a future edit drops a safety rule from a bundled skill, the suite fails loudly.
  • Good first contributions: an agent adapter (add your CLI to src/agents/registry.ts), a bundled skill (src/skills/bundled/<id>/SKILL.md β€” the loader auto-discovers it), a language check against your stack, or a docs fix.
npm install && npm install --prefix web
npm run build && npx vitest run        # backend build + full test suite
npm run build --prefix web             # dashboard build
node dist/cli.js serve --write         # run it locally on :7077
npm run dev --prefix web               # UI dev server :5173 (demo data ON)

Open a PR against main with tests. If you're changing coordination behavior, run the suite a few times β€” flaky is treated as broken here.

License

AGPL-3.0-or-later Β© Rakshan Shetty. See LICENSE.

Use it, change it, run it commercially β€” all fine. The one condition: if you distribute Baton or run a modified version as a network service, the people using it get the source under the same terms. That second clause is the reason this is AGPL and not GPL β€” Baton is a daemon with a web dashboard, so hosting it without ever shipping a binary would otherwise be a way around the license.

Baton was MIT until 2026-08-07. Copies taken before then keep their MIT grant β€” relicensing does not reach backwards. Contributions are accepted under the terms in CONTRIBUTING.md.

Pass it on.