bough
Getting started All documents

Getting started

bough reads the history your coding agent already keeps and draws the shape of the work you did with it. It runs on your machine, reads only, and sends nothing anywhere.

It reads Claude Code, OpenAI Codex CLI and Pi. All three are found automatically, and a project worked on with any of them shows up in the same list.

Codex and Pi support are newer and have had far less exposure than Claude Code, so treat their numbers with more suspicion and please report any that look wrong.

Install

macOS:

brew install nickelsec/tap/bough

Linux, or macOS without Homebrew:

curl -fsSL https://www.bough.run/install.sh | sh

Windows:

irm https://www.bough.run/install.ps1 | iex

Each script asks GitHub for the newest release, downloads the build for your machine along with its checksums.txt, and refuses to go further if the two disagree. What lands is a single binary, in /usr/local/bin if that is yours to write to and ~/.local/bin otherwise. BOUGH_VERSION pins an older release and BOUGH_DIR chooses somewhere else to put it.

To upgrade later, run the same line again. Homebrew is the exception, because brew install on something already installed stops and tells you so, which reads the same whether or not you are current. There it is brew upgrade nickelsec/tap/bough.

Piping a script into a shell means running code you have not read, and not everybody wants to. Every build is on the releases page with the same checksums file: unpack the one for your machine and put bough anywhere on your path.

With Go 1.25 or newer:

go install github.com/nickelsec/bough/cmd/bough@latest

Or build it from source:

git clone https://github.com/nickelsec/bough
cd bough
go build ./cmd/bough

There is no runtime to install and nothing to configure. The binary is about nine megabytes and everything it needs is inside it, including the fonts and the artwork the page uses.

Use it

Run it with no arguments and pick a project from the list:

bough

Or name one directly:

bough my-project

Either way it reads the history, works out the shape, and opens a page in your browser showing it. The page is served from 127.0.0.1 on a port nobody else can reach, and it closes when you stop the command.

Reading the diagram

A square on the spine is a day you worked. A smaller square hanging off it is one task. A circle is a single prompt.

Behind each task is a faint ring, sized by what that piece of work was charged. Bigger ring, more spent. Work from before your agent recorded token counts gets no ring at all, rather than a small one that would read as cheap.

Hover anything and the path back to its day lights up, with a note saying what it was. Click a node and the full record opens beside the drawing, scrolled to the exact prompt you clicked, in your own words and untrimmed.

Work the tool scored as hard is drawn in rust rather than green. That score is a guess and is labelled as one wherever it appears.

Narrowing it down

The rail on the right of the page holds five filters. They stack, so you can ask two things at once, and they fade rather than remove: the work that did not match stays on the page, quietly, because the point of narrowing a drawing is to see one part against the whole.

filter what it does
Search your prompts rings every prompt holding all of those words, in any order
Find a file lights the work that touched it, as you type
Narrow the dates a from and a to
Spend threshold one slider over cost, or over any of the token counts
What to show hide short sittings, or show only work that went badly

The spend threshold answers the question most people arrive with. Set it to $20 and everything cheaper fades. Switch the measure and the same slider reads output tokens, or cache reads, or the total.

Work that could not be priced never passes a spend threshold. A task whose model has no published rate has not been shown to be cheap, it has not been priced at all, and lighting it beside work that was priced would say the wrong thing about both.

What it all cost

The coins in the rail open the usage table: every day and every task, in the same columns your agent reports, with a total at the foot. Days fold away so a week of totals fits on one screen.

Each record also carries what that piece of work cost, and following the figure opens the table at that task's own row rather than at the top.

Figures are what the work would have cost at published API rates. A flat rate subscription pays none of that, and nothing in a transcript says which you were on, so read it as what the same work would have cost billed per token. Read the other way, it is what the subscription saved you.

In the terminal instead

bough my-project --text

Everything the page has, as an indented list: the days and the tasks inside them, what each was charged in tokens and in dollars, the commit hashes with their subjects, the file you kept coming back to, and which models did the work. Add -v and every prompt comes with it.

This is what a pipe or a redirect gets automatically, so bough my-project > notes.txt never tries to open a browser or sit waiting on a port.

For the underlying data:

bough my-project --json

The full graph, which is what the page draws from. Its shape is documented in the transcript format.

Every option

flag what it does
--text write to the terminal instead of opening a browser
--json write the graph as JSON
--list list the projects with history and stop
-v include every prompt in the text output
-o FILE write to a file instead of standard output
--root DIR read history from here instead of the usual place
--agent=X read one agent only: claude, codex, pi, or all
--no-repo do not read the project's git history
--version print the version and stop

If something looks wrong

The thresholds that decide where one task ends and the next begins were fitted to one person's history. If your boundaries fall in places you disagree with, tuning explains what each number does and what moving it costs.

If a project is missing from the list, bough looks under ~/.claude/projects for Claude Code, ~/.codex/sessions for Codex and ~/.pi/agent/sessions for Pi. For Pi it also follows PI_CODING_AGENT_DIR and PI_CODING_AGENT_SESSION_DIR, the same as Pi does. Point --root somewhere else if your history lives elsewhere.

To read one agent only:

bough --agent=claude
bough --agent=codex
bough --agent=pi

The default is all three.