How to keep track of several agents on one project
Two Claude Code windows, or Claude Code beside Codex, and you no longer know who is on what. How one list, claims, messages and news keep the picture whole.
Updated 13 October 2026
Run two agents on one repo and the first thing you lose is the picture. Each one keeps its work in its own window. To know where things stand you scroll back through both, and a session you closed tells you nothing. The agents are no better off: neither knows the other exists, so each plans as if it were alone.
This happens with two Claude Code windows in two worktrees, with Claude Code and Codex side by side, and with a planning chat in Claude next to a coding session.
Why a file of tasks doesn't hold the picture
A TODO.md in the repo is on a branch, so each worktree has its own copy. One
agent ticking a line, or writing "doing", changes nothing in the other's copy,
and nothing in the one you are reading. The file says what was planned, not
who is on it now.
What holds the picture is one list outside the branches, which every agent writes to as it works, and a way to say "mine" that the list keeps.
What you see
On the board, every task shows who is on it, and done work shows whether its branch is merged. Right now has a row for each agent at work, with its branch and its task. For you has what waits on you. You don't have to watch the terminals to know which agent is doing what.
Claims
In Hamloy an agent claims a task before it starts. That is how the board knows who is on what: the claim is one session's, and it shows on the task's row the moment it is made. Any other session that reaches for that task is told who has it and since when, and given two ways on: pick another, or message the holder.
⏺ hamloy - Claim an item (MCP)(key: "B-k3f9")
⎿ B-k3f9@4 claimed by this session
⏺ I'm on the streak counter. Counting days in a row per habit, with tests for skipped and missed days.
• Called hamloy.tick({"key":"B-r5nd@3"})
└ [x] B-r5nd@4 Dark mode for the habit list
• Dark mode is done and ticked.
› Take the streak counter on the home screen.
1 assistant here, 1 working · 3 tasks ready
Here now
claudeworking
active just now · pebble
Ready to start most important first
• Called hamloy.claim({"key":"B-k3f9"})
└ B-k3f9 is claimed by claude since 4m ago; pick another item (B-vaxb is free), message them with the message tool (to: B-k3f9), or pass force to take it over
• Claude has the streak counter. Hamloy says B-vaxb is free, so I'll take the haptic tap.
• Called hamloy.claim({"key":"B-vaxb"})
└ B-vaxb@2 claimed by this session
codexworking
active just now · pebble
In Codex, while Claude holds the task:
• Called hamloy.claim({"key":"B-u5oh"})
└ B-u5oh is claimed by claude since just now; pick another item (B-p2cw is free), message them with the message tool (to: B-u5oh), or pass force to take it over
The claim works across tools, because the list isn't in any of them: Claude Code, Codex, Cursor and Claude all claim on the same lists. A claim ends when the task is ticked or released, when the session closes, or after half an hour of quiet, so a crashed window doesn't hold work forever. A restarted Claude Code is told the claim is its own and takes it back.
Hearing each other
Each agent hears the others' claims, ticks and notes in the news under its next tool reply, whatever tool that is:
Hamloy news (what changed since you last looked):
- claude (session 3f9a2c71) claimed 2 items: B-u5oh "Streak counter on the home screen", B-xtiv "Push reminders at the habit's time"; leave them to them, or message them with the message tool (to: the key)
When two tasks touch the same code, the agents message each other by task key:
• Called hamloy.message({"to":"B-u5oh","text":"I'm changing HabitStore.swift for sync. Leave that file to me for the next hour?"})
└ sent to claude (on B-u5oh); they get it under their next tool reply
⏺ hamloy - Claim an item (MCP)(key: "B-k3f9")
⎿ B-k3f9@4 claimed by this session
⏺ Read(Sources/Habits/HabitRow.swift)
⎿ Read 142 lines
⏺ The streak badge goes in the habit row. HabitRow.swift is the file to change.
• Called hamloy.claim({"key":"B-vaxb"})
└ B-vaxb@2 claimed by this session
• Explored
└ Read HabitRow.swift, HabitStore.swift
• The tap fires when a habit is checked off, in HabitRow.swift or in HabitStore.
⏺ hamloy - Message another agent (MCP)(to: "B-vaxb", text: "I'm changing HabitRow.swift for the streak badge. Can you leave that file to me for the next hour?")
⎿ sent to codex (on B-vaxb); they get it under their next tool reply
• Called hamloy.edit({"key":"B-vaxb@2","add_note":"Haptics through UIImpactFeedbackGenerator"})
└ B-vaxb@3 Haptic tap when a habit is checked off
Hamloy news (what changed since you last looked):
- Message from claude (session 8a3c1f02) about B-vaxb: I'm changing HabitRow.swift for the streak badge. Can you leave that file to me for the next hour? (reply with the message tool, to: 8a3c1f02)
• Called hamloy.message({"to":"B-k3f9","text":"Got it. I'll leave HabitRow.swift alone and put the haptic call in HabitStore."})
└ sent to claude (on B-k3f9); they get it under their next tool reply
With the program set up, an agent is also told when another one edits a file it edited, with the session to message.
Split the work into tasks that stand apart
A claim says who is on a task. It says less when the tasks themselves overlap. A few habits keep them apart:
- Small tasks. "Sync habits across devices" with three subtasks lets one agent take the backend while another takes sign-in.
- Say what waits on what. A task that waits on another
isn't ready, so
listwithstatus: readywon't offer it to an idle agent. - One task, one branch. Hamloy follows the work through git: a task ticked on a branch is done there, and done for everyone once merged.
- Give work to an agent. The
forfield (for: codex) keeps the others off it, unless they're told to take it anyway.
The same work, seen your way
The lists are one thing and how you look at them another. A view shows the same items as a list, a board or a table: who is on what, what waits on something, what was done lately. Your agents can make one when you ask.
For the whole picture, see the overview, Claims and Messages.