Skip to content

Repository files navigation

frit

codecov

frit is a command-line tool for developers who run coding agents: it finds every plan across many repositories, branches and machines, claims one with a single atomic git push, and hands it to an agent. The name is a glassmaking term for material prepared before the melt; the naming note explains the choice.

The problem frit solves

Work on a developer's machine is scattered: many repositories, many branches in each, worktrees for some, agents running in a few, and a plan file that may exist on one branch only. No single view shows all of that, and nothing stops two agents from starting the same plan; why frit exists records the gap.

frit is that single view. It does three things:

  • It reads every plan file on every branch of every repository under one root directory, without checking anything out.
  • It answers which plans are ready: their dependencies are done and nobody holds them.
  • It claims a plan by pushing a branch to the git remote, then hands the plan to an agent in a worktree of its own. That claim is the one mutation frit owns on the shared refs: it never edits a plan, never writes a prompt of its own, and never reads an agent's conversation. architecture.md calls this the one-mutation rule.

How frit works

mdsmith parses the markdown. herdr runs the panes and worktrees that agents work in. frit joins both with what git holds; how frit and mdsmith fit together draws the line.

flowchart LR
  subgraph origin["git origin, shared by every machine"]
    plans["plan files on every branch"]
    claims["claim refs: plan/<id>"]
  end
  subgraph host["one machine"]
    frit["frit"]
    herdr["herdr: panes, worktrees, agents"]
    mdsmith["mdsmith: markdown parser"]
  end
  plans -->|read| frit
  claims -->|read| frit
  frit -->|"the claim, one push"| claims
  herdr -->|"which lane has a live agent"| frit
  frit -->|"the worktree and the pane"| herdr
  mdsmith -->|library| frit
Loading

Everything the machines must agree on lives on the git remote. A ref push is the one operation every machine can race on safely. A fact that never reaches the remote, such as a running pane or an open pull request, stays on the machine that has it. frit reads that fact from herdr on that machine, or asks the agent. It never guesses it from the refs. CLAUDE.md states this rule and architecture.md explains it. --hosts a,b reads other machines' herdr over ssh; a host that does not answer is reported as a problem and its lanes show their last cached presence, while ? in the board's agent column means the local herdr socket did not answer. When two machines claim one plan at once, the remote accepts the first push and the second reports who won.

A plan moves through a small set of states; the status glyph lives in the plan file's front matter, the hold on the remote.

stateDiagram-v2
  direction LR
  [*] --> NotStarted: plan file lands, status 🔲
  NotStarted --> Held: frit claim pushes plan/id
  Held --> NotStarted: frit release
  Held --> InProgress: first work commit, status 🔳
  InProgress --> Done: last phase closes, status ✅
  Done --> [*]: branch merges, frit reap deletes it
Loading

How claiming works has the rules for each edge, including takeover of a stale lease and the rescue ref that parks unmerged commits.

Words frit uses

Word Meaning Defined in
fleet, root every git repository under one directory, the root claiming.md
plan a markdown file with id, title, status and, optionally, model up front plan/proto.md
hold, lease the branch plan/<id> on the remote; its tip says who holds it claiming.md
lane one worktree on one host, working one plan; an agent's pane rides it lease-protocol.md
rescue ref where unmerged commits are parked before a lane is torn down claiming.md
tier the model named in a plan's front matter, from the vocabulary plan/proto.md declares plan/proto.md

Install

frit needs Go 1.25 or newer to build from source:

go install github.com/jeduden/frit/cmd/frit@latest

Or download a binary from the releases page and check its provenance before you run it:

gh attestation verify frit-linux-amd64 -R jeduden/frit

frit version prints the tag a release was built from, and dev for a source build. Three other tools matter:

  • git must be on PATH. frit runs it as a subprocess for every read and for the claim, as CLAUDE.md requires.
  • herdr must be running for any verb that touches a lane: claim, start, open, nudge, message and yield. The survey verbs work without it: board then shows ? in the agent column, and who prints no live agents and reports the socket as a problem.
  • mdsmith lints plans and regenerates the plan index. Install it with go install github.com/jeduden/mdsmith/cmd/mdsmith@latest.

First run

export FRIT_ROOT=~/git
cd ~/git/myrepo && frit init --mdsmith .

Getting started carries the rest: writing a plan, checking it, claiming it, and watching it run.

Commands

frit --help lists every verb, and frit <verb> --help its flags. The full reference — every verb grouped as survey, discover, lease, drive, clean and setup, with the conventions that hold across them — is in docs/commands.md.

Scripting with JSON

Every verb takes --json; the table and the document come from one model, so they never disagree.

frit orphans --json | jq '.repos[] | select(.unstaffed | length > 0)'

UX principles has the rules that make the document safe to write against, and the golden files that pin them.

Configuration

.frit.yml holds per-repository settings; frit's own settings, such as --root, resolve from the command line, the environment, a config file and the user config, most specific first. docs/configuration.md has the keys and the exact order.

Working with agents

frit ships the instructions an agent needs to drive it. frit skills writes seven Claude Code skills into a repository's .claude/skills:

Skill What the agent does with it
plan-pick find the next unheld plan, claim it, start its lane
plan-phase execute one phase of a plan, test first, and close it
plan-handoff close a phase: write the handoff, flip its status
plan-new write a plan that passes the schema on the first try
plan-sync reconcile plan statuses against what drift found
plan-tidy read orphans and stale, then act with yield, release, reap
plan-drive survey the board and drive a lane up the ladder: open, nudge, message, start

The skills are embedded in the binary, and --via "go run ./cmd/frit" changes how they invoke frit. The prompt frit composes for a pane is /plan-phase <id> [phase], from internal/dispatch; start --note and --edit amend it, and message sends whatever text you give it. Development has the rest.

Releases

Every release is on the GitHub releases page, or from a terminal with gh release list -R jeduden/frit. It carries notes from the merged pull requests, five platform binaries, a checksum file and a provenance attestation. A release is made from the Actions "Run workflow" button on release.yml with a version such as v0.11.0; the workflow checks the version, runs the suite, builds the binaries, and creates the tag only once they exist. Development has the details.

Documentation map

Page Answers
CLAUDE.md the rules the code and its agents follow; the current record
PLAN.md what is planned, in progress and done
docs/getting-started.md init to first claimed lane, one command at a time
docs/configuration.md the .frit.yml keys, with defaults and comments
docs/architecture.md what frit, mdsmith and herdr each own
docs/claiming.md how a lease is made, kept, taken over, yielded and scavenged
docs/commands.md every verb, grouped, and the conventions across them
docs/reaping.md the orphan categories and what reap may delete
docs/ux-principles.md why the verbs, flags and JSON behave as they do
docs/development.md build, test, lint, the scenario matrix, skills, CI and release
docs/research dated notes on how each decision was reached

To contribute, follow CLAUDE.md: a failing test, the code that passes it, one small commit, with mdsmith check . clean.

License

MIT

About

No description, website, or topics provided.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages