Mirroring tasks to beads
Zeus can keep your team’s tasks in beads, a free issue tracker that works from the command line, instead of in GitHub issues. This page says which beads versions work, how to set beads up, what setting it up changes in your repository, how to turn off beads’ usage reporting, and how to switch from one place to the other.
Each Mac has its own work board: the tasks your agents file stay on your Mac. Mirroring means Zeus also copies each task to a second place that your teammates can see, and brings changes made there back to the task. A workspace is a named group of repositories that you choose in the picker at the top of the rail (the list down the left side of the window). The one repository of a workspace that receives the copies is the target repository. A workspace mirrors to one place, or to none: GitHub issues, beads, or off. Joining a team explains mirroring to GitHub issues.
Beads keeps its items in a small database inside the repository, in a
folder named .beads. We call that the beads database. Each teammate
has their own copy of it, and the command bd sync fetches teammates'
changes and sends yours. The program is called bd. One item in beads is a
bead, with a name like demo-c94.
What you need
A Zeus that can mirror to beads. Zeus 0.24.0 and older cannot. To see whether yours can, run
zeus mirror --help: it lists--store beadswhen it can.The
bdprogram, in a version Zeus supports (see the next section). One way to install it is Homebrew (a tool that installs programs on a Mac):brew install beadsThe target repository, checked out on your Mac. Beads keeps its database in the repository’s folder, so Zeus needs that folder. (GitHub issues do not need it.)
A git sign-in (usually GitHub) that can push to the repository. Beads shares its database through the repository’s own GitHub address, with your normal git sign-in. It cannot ask you for a password.
Which beads versions Zeus supports
bd version
prints the version of your bd, for example bd version 1.3.1 (Homebrew).
Your Mac may have more than one bd: which -a bd lists them all, and the
one bd version runs is the first in that list.
Zeus supports bd 1.3.1 and newer, and has been tested up to
bd 1.3.2. Zeus checks your bd before you can choose beads, and again
every hour:
- 1.3.1 to 1.3.2: supported. Mirroring works.
- Newer than 1.3.2: mirroring works if
bdstill has every option Zeus uses. The workspace sheet then shows, under beads,bd <version> is newer than Zeus has tested; mirroring continues. - Older than 1.3.1, or a
bdthat lacks an option Zeus uses: Zeus does not let you choose beads, and saysbd <version> is not supported by this Zeus (it supports 1.3.1–1.3.2). Update bd, or set mirroring off.
Zeus decides by what bd answers, not by its version number alone. A
dev build (a bd built by hand: bd version prints, for example,
1.3.0 (dev), and Zeus writes it 1.3.0-dev) is treated like a newer
version, whatever its number: it works if it has every option.
If your Mac has two bd programs, Zeus uses the first one that is not a
dev build, looking first in the folders of the PATH that Zeus’s
background program was started with, then in the usual install folders. That PATH is a copy of your shell’s PATH, saved
when Zeus was installed. It uses a dev build only when it finds no other.
After you choose beads, Zeus prints the version it uses (see Choose beads
for a workspace). Run the bd commands on this page with that same bd:
if which -a bd lists another one first, type its full path, such as
/opt/homebrew/bin/bd.
Agree on one beads version as a team
Every teammate works on a copy of the same beads database. Each version of
bd knows the database layout up to some number, and a newer bd can
move the shared database to a newer layout. When that happens, a teammate
with an older bd cannot read the database until they update. Beads does
this itself, and Zeus cannot stop it. Zeus finds it, pauses mirroring on
that one Mac, and says so on its Health page:
Your bd (<version>) is older than the team's beads database. Update bd.
The other Macs keep working.
So agree on one bd version as a team, and update together. With
Homebrew, you can stop brew upgrade from changing it until you agree:
brew pin beads
Zeus never uses beads’ option to ignore a database that is too new for
your bd. That option could damage the team’s data.
Turn off beads’ usage reporting
By default, bd sends anonymous usage data to a server outside your team:
the name of each bd command you run, the bd version and your Mac’s
system. This includes the bd commands Zeus runs for you. Zeus does not
change your beads settings, so turn it off yourself, once on each Mac:
bd metrics off
bd answers “Anonymous usage metrics are now OFF.” The setting is kept for
your user on this Mac, so it covers the bd commands Zeus runs too. To
check it at any time:
bd metrics
The first line says Anonymous usage metrics: OFF or ON.
Before you run bd init: what it changes in your repository
Zeus never sets up beads for you, because setting it up changes your
repository. As observed with bd 1.3.1, bd init:
- changes the repository’s git hooks. It points git’s
core.hooksPathat the.beads/hooksfolder, and copies your existing hooks there, adding beads’ own lines to each. Your hooks still run, but from that copy: later changes to your own hooks folder (for example, a hooks folder your team keeps in the repository) are no longer used in this clone. - adds files and hooks for AI coding tools: it writes or adds to
AGENTS.mdandCLAUDE.md(an existing file keeps its text), and adds settings for Claude Code, Codex and Cursor that runbd primeat the start of every session in this repository. - commits all of this to the branch you are on, on your Mac only. It does not push.
Before you run it, see whether your repository sets its own hooks folder:
git config core.hooksPath
If this prints a folder, git stops reading that folder after bd init
and reads the copy instead. Zeus does not need
beads’ git hooks: it runs bd sync itself. If you want to keep your own
hooks, or do not want the files for AI coding tools, beads has two options
for that: --skip-hooks and --skip-agents.
Set up beads in the target repository
One person does this once, for the whole team. Go to your checkout of the target repository:
cd <folder>
bd init
or, to keep your own git hooks and leave out the files for AI coding tools:
bd init --skip-hooks --skip-agents
<folder> is the folder of the target repository on your Mac. In a
terminal, bd init asks two questions, “Contributing to someone else’s
repo?” and “Enable auto-export?”: answer N to both. Adding
--non-interactive takes those answers without asking. Look at what bd init committed before you
push anything:
git show --stat HEAD
In a repository cloned from GitHub, bd init makes the repository’s own
GitHub address the place where beads shares its database. Beads calls this
place a remote. It keeps its data beside your branches, so you do not
need a second repository, but you will see a branch named
__dolt_remote_info__ on GitHub: it is beads’ own, so do not delete it.
To see the address:
bd dolt remote list
It prints a line like origin git+https://github.com/Owner/name.git.
Each teammate needs this address.
Send the database to the remote once, before anything else:
bd dolt push
Until you do, bd sync fails with “no branches found in remote ‘origin’”.
Then check that sharing works:
bd sync
It ends with Sync complete.
Then push the commit bd init made, the way your team changes the
repository (for example git push), before your teammates set up
beads. bd dolt push sends the database, not this commit. If a teammate
sets up beads before the commit reaches them, their next git pull stops
with a merge conflict in .beads/config.yaml.
Set up beads on each teammate’s Mac
Each teammate clones the target repository (or pulls, so that they have
the first person’s bd init commit), goes to its folder, and makes their
own copy of the team’s database from the remote:
cd <folder>
bd init --remote git+https://github.com/Owner/name.git
Use the address that bd dolt remote list printed on the first Mac. Use
--remote, so that the copy starts from the team’s database instead of a
new, empty one. Like the first bd init, it changes the git hooks, adds
the files for AI coding tools and makes a commit in the teammate’s own
clone: look at it with git show --stat HEAD. Beads works without
pushing that commit. Add --non-interactive to skip the two questions. Add --skip-hooks --skip-agents if you want them; read
Before you run bd init, above, first.
Each teammate also turns off usage reporting on their own Mac (see above).
Choose beads for a workspace
Each teammate sets this on their own Mac, to the same target repository. A change applies only to tasks filed after it: tasks that already exist do not become beads.
In the app: open the workspace picker at the top of the rail, hover the workspace and press edit. On the line Mirror tasks to, choose beads, then choose the target repository, and press Save. If this Mac cannot use beads, beads is greyed out with a line under it that says why. If the target repository is not ready for beads, it is greyed out in the repository menu with a line under it; when the workspace holds only one repository, there is no menu, the line appears under the repository, and Save stays off until the cause is fixed. The lines are the sentences in the next section.
From a terminal, with Zeus running:
zeus mirror <workspace> --store beads --target Owner/name
<workspace> is the workspace’s name — put it in quotes if it has a
space — and Owner/name is the target repository as GitHub names it, for
example acme/backend. You can leave out --target when the workspace
holds only one repository. Zeus answers with the bd version it checked:
<workspace> mirrors to beads in Owner/name (bd 1.3.1).
To see the setting of each workspace on this Mac:
zeus mirror
A workspace that mirrors to beads prints its name, beads and the target:
<workspace> beads remote:github.com/Owner/name
When beads cannot be chosen
Zeus refuses beads, in the app and in the terminal, with a sentence. These are the ones you are most likely to see, and what each one means:
| Zeus says | What to do |
|---|---|
bd is not installed on this Mac. Install beads, or set mirroring off. | Install bd (see What you need). |
bd <version> is not supported by this Zeus (it supports 1.3.1–1.3.2). Update bd, or set mirroring off. | Install a supported version. |
bd did not answer when Zeus checked it. Try again, or set mirroring off. | bd was found but did not answer in time. Try again in a minute. |
<repository> has no beads database yet. Run bd init in <folder> first. | Set up beads in that folder (see the two setup sections above). |
beads needs Owner/name checked out on this Mac. | Clone the repository on this Mac. |
Your bd (<version>) is older than the team's beads database. Update bd. | A teammate’s newer bd moved the shared database to a newer layout. Update bd to the team’s version. |
Your bd (<version>) is newer than the team's beads database. Use the bd version your team uses, or set mirroring off. | Install the version your team agreed on. Zeus never moves the team’s database to a newer layout for you. |
<repository> is already mirrored to GitHub by <workspace>; one repository mirrors to one store. (or … to beads by …) | Another workspace on this Mac holds the same repository and mirrors it to the other store. A repository mirrors to one place only: change the other workspace first. |
<repository> is also in the workspace <other> on this Mac, which mirrors its tasks to beads in <target>. … | Another workspace on this Mac holds the same repository and mirrors it to the same store, but to a different target repository. Choose the same target in both, or change the other workspace first. |
Zeus could not check beads on this Mac, so the mirror setting has not changed. | Zeus could not run its beads check. Try again. |
What a task looks like in beads
Each task filed while mirroring is on becomes one bead in the target
repository’s beads database. Its name starts with the prefix bd init
chose — by default, the name of the repository’s folder — for example
demo-c94. The bead carries the labels zeus, agent:<name> (the agent
the task is for) and repo:<name> (the repository the task is in).
When an agent takes a task, Zeus also makes a short-lived claim bead,
labelled zeus and zeus:claim, with no agent: label. Claim beads are
how two Macs agree which one holds a task. They are not tasks: leave them
alone, and Zeus closes each one when the claim ends.
zeus work show <task> prints the bead’s name and state, for example:
bead demo-c94 · open
In the app, the task’s row shows the bead’s name where an issue number
would be. A bead has no web page: on the task’s card, a click on the bead
shows the command that opens it from a terminal, such as
cd <folder> && bd show demo-c94.
Where Health tells you when copying is paused
Whatever goes wrong with beads, the task keeps working on your Mac.
Mirroring pauses, and the Health page (⇧⌘H in the app, or zeus health
in a terminal) says why, on its task mirroring card. When beads is the only
thing wrong, the card’s headline is Task mirroring cannot reach beads;
when GitHub mirroring has a problem too, the beads lines sit under the
GitHub headline. Things Zeus still has to send to beads wait, and are not
counted as failures.
Each line starts with the repository’s name. Most lines are the
sentences in When beads cannot be chosen, above — for example
Your bd (<version>) is older than the team's beads database. Update bd.
Three more are about sharing:
beads has a merge conflict in <folder>; resolve it with bd conflicts.Zeus never resolves a person’s conflict for you.beads sync is stuck in <folder>; run bd doctor.Only a person can clear this.beads passes took over 20 s three times in a row (last <n> s).Mirroring still works, but slowly.
When something else is wrong with beads, the card also shows
bd <version> is newer than Zeus has tested; mirroring continues. if your
bd is newer than Zeus has tested. That line alone does not put a card on
the Health page.
Zeus checks beads every hour. After you fix the cause — for example,
after you update bd — the line can stay for up to an hour, until the
next check, or until Zeus restarts.
Switching from one store to the other
We call each place a workspace can mirror to a store: GitHub issues or beads. A workspace can switch store. Old tasks are not moved: a switch turns the old store off for new work, and turns the new one on.
In the app, choose the other store on the Mirror tasks to line and press Save. When open tasks have links to the old store, Zeus asks first, for example:
Mirror <workspace>'s tasks to beads?
Now: GitHub issues in Owner/name
3 open tasks keep their GitHub issue and stop being updated. Only tasks filed after this go to beads.
Press Save to switch, or Keep as is to leave it. From a terminal,
zeus mirror <workspace> --store github --target Owner/name (or
--store beads) switches at once, without asking.
What happens on a switch:
- Old links are kept, and frozen. Each open task keeps its GitHub issue
or its bead, but Zeus no longer sends to it or reads it.
zeus work showand the task’s card add “no longer updated”, for examplebead demo-c94 · open · no longer updated. A link stays frozen even if you switch back later. - Sends still waiting for the old store are set aside at once, with the
reason
mirroring moved to <store>. They are not counted as failures, and they are not sent if you switch back. - Nothing is removed from the old store: issues, beads, labels and comments stay where they are.
- The Health page shows a line such as
<repository>: 3 tasks keep their GitHub issue from before the switch; Zeus no longer updates them.(or “… keep their bead …”). When nothing else is wrong, the card’s headline is Some tasks keep their links from before a switch.
Turning mirroring off is different: it freezes nothing. In the app, Zeus asks first here too, with a sentence such as “3 open tasks keep their GitHub issue and stop being updated. Tasks filed after this stay on this Mac.” The links are not updated while mirroring is off, and they are updated again when you turn the same store back on. From a terminal:
zeus mirror <workspace> --store off
Zeus answers <workspace>: mirroring off.