beady-eye
CLAUDE.md27 starsChanged 5 days agoApache-2.0View on GitHub
bdi joins a beads tracker to a herdr session and draws one tree of work per root, annotated with the live agent on each node. It writes in two ways. bdi bd is the command that whatever showed a person a question calls to carry their reply to the right tracker: it passes bd human respond through to carry an answer, bd defer --until to put a bead off until a date the person chose, and bd comments add to…
In this repository4 other files it gives its agents.
- docs/agents.mdAGENTS.md
- effect-model-auditSkill
- effect-native-auditSkill
- renovateSkill
The file
We split this CLAUDE.md into the rules it gives an agent
1 rule. About 0 are common, 0 are distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈0
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 162
Terminology comes from beads or herdr: Never invent a word where either project has the concept.
≈ “Common” is an estimate: at least 1 in 5 of the 26,980 CLAUDE.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
beady-eye — working notes
bdi joins a beads tracker to a herdr session and draws one tree of work per
root, annotated with the live agent on each node. It writes in two ways. bdi bd
is the command that whatever showed a person a question calls to carry their
reply to the right tracker: it passes bd human respond through to carry an
answer, bd defer --until to put a bead off until a date the person chose,
and bd comments add to put their words on a bead. Gates is a writer fed by
GitHub, the clock and other trackers: bdi gates settles a gate once GitHub says its pull request
has merged, closed, or left draft, its issue has closed, its workflow run has
succeeded or been skipped, or its repository has published a release, closes a
timer gate at its deadline, and closes a bead gate once the bead it awaits has
closed. Every other bd
command line bdi
spells is a read, and collect/ spells all of them.
docs/design.md's Reading a tracker is not leaving it alone has the
measurements.
What beady-eye owns
bdi, the terminal view that joins a beads tracker to a herdr session.- The reading side: which
bd,herdrandghcommand lines it spells, and how it parses what they print. bdi bd, which carries a person's reply to the right tracker: their answer to the bead that asked, the date they chose to defer a bead until, or their comment on a bead.- Gates, which settles a gate: it re-reads the pull request from GitHub, closes the gate on a merge, and on a close without one tells the beads the gate holds back. A gate on an issue, a release or a workflow run closes once the issue closes, a release is published, or the run succeeds or is skipped. A timer gate closes at its deadline, and a bead gate closes once the bead it awaits closes, in any tracker the config names.
- The model that joins the two sources, including the anomalies where they
disagree, and the words and colours
bdidraws. - The
bdiconfiguration format:[[badges]],join.pane_keyand the rest. - The
herdr-plugin.tomlthat installs it as a herdr plugin, and the releases published to crates.io and GitHub.
What it does not own
- Beads. The tracker, its schema and its commands belong to the beads
project.
bdireads from it, and a change to whatbdprints is asked of beads. - herdr. Panes, agent detection and agent status belong to the herdr
project.
bdidraws what herdr reports. - Every other write to a tracker.
bdinever creates a bead, and it writes only throughbdi bdand by settling gates.bdi bd'shuman respondrecords a person's answer and closes the bead that asked, itsdeferputs a bead off until a date, and itscomments addputs a person's comment on a bead. Settling a gate closes it or comments on the beads it holds back. Whoever runsbdidoes everything else withbd, creating the gate included. - How agents are organised.
bdiknows no roles, orchestration model or skill names. A convention a setup keeps in bead metadata is named in the user's config and drawn without interpretation. - A user's deployment. Their tracker, its server, their config and their
data live with whoever runs
bdi.
Building and testing
nix develop gives you the toolchain: cargo, clippy, rustfmt and
rust-analyzer. cargo build and cargo test work as usual inside the shell.
nix flake check is the whole of CI, and check-before-push is what to run
before you push: it runs the check, and refuses a dirty tree rather than check a
source nix cannot see all of.
plugin/ is the Claude Code plugin's TypeScript workspace, and the dev shell
gives bun, biome and tsc for it. nix flake check runs its typecheck,
lint and tests. After changing plugin/bun.lock, the fixed-output hash of
pluginModules in flake.nix changes too: set it to pkgs.lib.fakeHash and
copy the hash the failed build reports.
Once it is pushed, read-ci-verdict [<commit>] says whether CI passed for it,
and read-ci-verdict --help says why an empty answer from gh is not one.
Unit tests live in #[cfg(test)] modules inside the file they cover; tests/
holds the integration tests, which either link the library or run the built
binary. Each top-level file there is a binary of its own and costs a link, so
a test that never starts bdi and sets no environment variable is a module of
tests/never_start_bdi/ instead. A test that reaches a module no test has reached before needs that
module opening up in src/lib.rs, which says why. Fixtures under
tests/fixtures/ are faithful captures of what bd list, bd query and
herdr agent list put on the wire.
A pty test drives bdi through tests/terminal/driver.rs, which drains the
terminal on a thread of its own from the moment bdi starts. So never read the
master yourself, and never take a test's silence as a licence to stop draining.
Stopping is a deadlock rather than a delay. A bdi blocked in write cannot
finish exiting, and a process that cannot finish exiting is never reaped — so a
wait for it that stops reading in order to wait is each side waiting for the
other, and it does not end.
An absence assertion has to name the thing whose absence it means, and on this
screen that is rarely a bead's id. The bead window is drawn from the
selection rather than from the bead it was opened on, so a screen that
wrongly kept a window up after a collection draws it over whatever the
selection landed on and under that bead's name — and a test looking for the
opened bead's title to be gone finds it gone. It executes the line it is about,
cannot observe it, and passes. What says a window is up is window_over
answering at all, and what says which bead it is over is the id it hands
back.
PR policy
Changes reach main through a pull request, squash-merged — nothing is pushed
to main directly. The pull request is what puts CI in front of a change
before the branch everyone else works from carries it.
The subject
The pull request's title becomes the commit subject, because the merge is a
squash — so it is the only line of the branch main keeps. The branch's own
commit messages are squashed away, but they stay reachable on GitHub after the
merge, so they are read as well. Write the title as a conventional commit:
type(scope): description- type is one of
build,chore,ci,docs,feat,fix,perf,refactor,revert,style,test. A!before the colon marks a breaking change. - scope is optional and closed:
collect,app,model,view,tui— the five layers under Where things are — plusci,flake,docs,tests,deps. Leave it out rather than coin one; a new scope is a change to the check. - description is lower case, in the imperative, and has no full stop at the
end. It has to finish the sentence "If applied, this commit will …" — so
draw a bead id in its status colour, neverdraws,drewordrawing. An acronym or a name keeps its capitals:GitHub,CI,NO_COLOR. - 72 characters.
Say what changed in the subject and why in the body, in a sentence or two. A
subject carrying the reason wraps in git log --oneline, in blame and in
bisect — three places a reader meets it and none where they want the argument.
The conventional subject job refuses a title that is none of this. Run
conventional-subject '<title>' in the dev shell for the same verdict before
you open the pull request.
Where things are
src/ is five layers:
collect/runsbdandherdrand parses what they say.app/decides what each tracker is asked for and keeps what came back between asks —tracker.rsis one project's read,collection.rsthe standing set of them.model/joins the two into a snapshot: the tree, its badges, and the anomalies where the two sources disagree.view/turns a snapshot into rows and draws them —forest/is the scrollable tree,draw/the widgets,phrase.rsevery wordbdishows.tui/runs the loop and owns the terminal.
docs/design.md is the spec, and a starting point rather than gospel — we
deviate from it as we learn. docs/plans/ holds the implementation plans
written against it.
Rules this project was designed under
Terminology comes from beads or herdr. Never invent a word where either
project has the concept. Where both are silent, coin one and add it to the
terminology table in docs/design.md marked coined.
No coupling to any agent workflow. bdi knows nothing about how agents are
organised — no roles, no orchestration model, no skill names. A convention a
setup encodes in bead metadata is named in config ([[badges]],
join.pane_key) and drawn without interpretation. If a feature needs to know
what a metadata key means, it belongs in config, not in the model.
The key is (project, id). Bead prefixes are per-tracker and uncoordinated.
Degrade, never disappear. An unreachable tracker, a filtered tree, an orphaned dependency — each is reported, never silently dropped.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

