The map and the spine

Two screens do most of the work. The map is every conversation you have. The spine is one of them, reduced to what happened in it.

The map

$ braids
braids: the map screen

One row per conversation. A branch is indented under its parent and tagged with the turn it left at, so ← t14 means this conversation starts from turn 14 of the row above it. The columns are the title, the fork point, how many turns, how big the transcript is, how much scratch the session wrote, how long ago it was touched, and what state it is in.

State is the column to scan. your turn means the session asked you something and stopped. unanswered means the last thing in the transcript is yours. n and N walk between them, so a morning can start by pressing n until it runs out.

KeyWhat it does
j / kdown, up
↵open the spine
/search everything
ffilter this list by title
n / Nnext, previous conversation waiting on you
rrename this conversation
a / Aarchive this one, show archived ones
dmove this conversation to the bin
w / Dbrowse its work products, or bin all of them
uopen the bin
Mopen memories
y / ocopy the resume command, or open it in a terminal
qquit
vrun the installer, when the header offers it

The spine

$ braidsthen ↵ on a conversation
braids: the spine screen

A long conversation is mostly turns you do not need to see again. The spine keeps the landmarks and collapses the rest into a run marker that counts what it swallowed. A conversation of 25,000 turns becomes a few hundred rows, and reloading it takes about 30 ms.

MarkWhat it means
●a turn: yours in the bright colour, the model's in the dim one
⋯a run of turns nothing notable happened in, with how many
◆a subagent this conversation spawned
⚠a tool call that failed
≈≈the context was compacted here
← t14a branch leaves here, at turn 14

n stops at each of those marks in turn, which is the fastest way through a conversation you have not read in a week.

KeyWhat it does
j / kdown, up
↵follow the branch or subagent on this row
bbranch a new conversation here
mmerge a branch back into this one
ppromote the subagent on this row
ffilter turns by text
n / Nnext, previous mark
y / ocopy the resume command, or open it in a terminal
escback to the map

The version row

The header names the build always, and once nobody has checked for updates in a month it grows · 3 months old · v to update. The key rides in that row rather than in the legend on purpose: a fifteenth binding would need a third column of hints, and that column costs the glyph key, which names marks that are on the screen right now.

v runs the installer, which is the only thing in braids that reaches the network, and it prints the command before running it. See Files and privacy.

It keeps up on its own

Opening the map catches it up first. Nothing touches the index while braids is closed, so without this the map showed whatever was true the last time it was open: a week away, and it stayed a week out of date until something happened to a file while you were watching it. On a history of 66,000 messages that catch-up costs about 70 ms, because a transcript whose size and modification time have not moved is never opened.

After that it watches the transcript directory, the memory directories and the index. When a session writes a turn while you are looking at it, braids reads only the bytes that were added, off the drawing thread, and the row updates in place. Reading the whole file again would take about 3.3 seconds on a 145 MB conversation. Reading the tail takes about 40 ms.

If you sit on the spine of a live conversation, new turns appear as they land. The cursor stays where you put it.

Filter is not search

f filters the list in front of you, by substring, and every screen has it. / opens search across everything you have indexed. They are different tools and both are always available. When a filter is open the header says so, because a screen quietly eating your keystrokes is worse than no filter at all.

Printing a frame, and awkward terminals

braids --print                  # one frame of the map to stdout
braids --print --lane 46360382  # that conversation's spine
braids --print --query lock     # the search screen for a query
braids --print --width 195 --height 24
braids --ascii                  # narrow glyphs, for terminals that draw the box
                                # characters double width

Print mode is how the screenshots in these docs are made, so what you see here is what the program draws. Set BRAIDS_ASCII to make the narrow glyphs the default.