Commands
What fabrikito needs, every fabrikito command and its options, which team file a command
uses, and the iTerm view. For what up does step by step, see How it works.
Requirements
macOS, tmux, claude (Claude Code), git 2.36 or later (for git worktree list -z), gh, and the
system ruby (it parses the YAML; it ships with macOS). Optional: a wrapper program that runs claude (see
sessions.claude.wrapper). A C compiler is needed only for test/e2e.sh.
The commands
cp teams/example.yaml teams/team.yaml then edit it: repo, project, storage, roles
./fabrikito check validate the team file, show where everything lives
./fabrikito up [role...] start the team (all roles, in file order)
./fabrikito status which seats are up, and where each works
./fabrikito view open an iTerm tab with every running seat in a pane
./fabrikito titles set each running seat's terminal title (role | title | session)
./fabrikito say <role|all> "..." type a message into a seat (seats use SendMessage)
./fabrikito flush <role> submit, with one Enter, a message fragment say itself left in a seat's
input box (deletes nothing; refuses anything else)
./fabrikito attach <role> attach your terminal (detach: ctrl-b d)
./fabrikito migrate [role...] remove clean worktrees that are not on the storage volume
(never one a running process works in)
./fabrikito down --yes [role...] kill seats (worktrees are kept)
./fabrikito run-exclusive -- <command> run a heavy command (a gate, an e2e run) one at a time on this
host, waiting for the run before it (needs no team file)
./fabrikito -c path/to/other.yaml up use a different team file
Options:
up --no-viewstarts the seats without opening the iTerm view.view --printprints the AppleScript that would build the view, for every role in the team file, running or not, and opens nothing.downwithout--yeslists the seats it would kill and kills nothing.attachwith no role attaches to the first role in the team file. Run from inside tmux, it switches your tmux client to the seat instead of attaching.--default-socket(onup,down,say,flush,attach,viewandtitles) lets a team file outsideteams/run on the default tmux server: see Throwaway teams. Onsay,flushandattachit must be the first argument.-c(or--config) comes before the command.fabrikitocan be run through a symlink to its file (relative or absolute, or a chain of links, for example one in a folder on yourPATH): it follows the links to the real file and finds itslib/beside that one (#263).run-exclusivetakes the command after--, as an argument list. See One heavy run at a time for the lock and what it covers.
Which team file
The team file is -c, else $TEAM_CONFIG, else teams/team.yaml. teams/example.yaml documents every
key. Team files other than the example, and anything under projects/, are git-ignored so each
project's specifics stay out of this repository. Keep a project's own prompts under projects/<name>/
and point the team file at them.
Throwaway teams
up takes a team file outside teams/ for a throwaway one (a test) and will not start its seats on your
default tmux server, where a real team runs: run it on a private server (see
Live tests), or pass up --default-socket if that team is meant to run there. down
(with or without --yes), say, flush, attach, view and titles apply the same rule before any tmux call,
because a copy of a real team file shares its session prefix and would reach the real seats: kill them,
type into them, show them or relabel them (#105, #124).
status only reads, and migrate keeps any worktree a running process works in, on whatever server
(#121). It reads each worktree's path whole, so a path with a newline in it is
acted on under its full path and shown escaped, never split in two (#134).
up --default-socket passes the option on to the view it opens. So a throwaway team file never goes in
teams/, neither this checkout's nor a worktree's copy of it: there every command takes it for a real
one. Put it in a temporary folder and run it on a private server.
The iTerm view
up opens a new iTerm tab showing every running seat, unless --no-view is given or display.iterm
is false; view opens it any time. The primary seat (display.primary, default the first role) is
the left half at full height, since it is the one you talk to. The others fill rows on the right, two
per row, and an odd last seat gets a full-width row. The window is sized to the usable area of the
screen it is on (display.window: full). Each pane is a tmux attach to the seat's session, so
closing the tab detaches and never stops a seat. Each pane's header reads <role> | <title> | <session>:
the launcher sets tmux's set-titles-string on every seat (at start, and again by view or titles).
The first run asks macOS for permission to control iTerm.