kolu
Docs

beside the tile

Inspect, compose, drive.

Every tile has a right panel with two tabs: an Inspector and a Code tab. The Inspector is where you read a terminal’s context and act on it without leaving the canvas.

What it shows, in order of urgency

The Inspector is ordered by how much a fact wants your attention, not by how the data is grouped internally.

The agent’s state leads. When a terminal is running an agent, the panel opens with its status: the agent’s name, what it’s working on, and a state chip in the colour that state wears everywhere else in kolu — violet when it’s your turn, rust while it’s working. A quiet line underneath carries the model, how long it has been running, task progress, and how much context it has used. You read “does this need me?” off the colour before reading a word.

What you’re working on comes next, as a row of chips: the branch in the same hue the dock paints on branch labels (worktree glyph when it is one), the repo (monogram + soft repo-colour frame), the pull request, and a single chip rolling up CI — ✓ 9 passed when everything passed. Below them the PR title and the working directory.

Detail folds away until it’s interesting. The per-check list, the repo’s root and worktree paths, and the terminal-CLI reference all sit behind expandable summaries. The CI list is the clearest case: nine passing checks stay folded behind their rollup, but a check that fails or is still running expands the list on its own, with the exceptions sorted to the top — you never open a list to find good news, and never miss bad news because it was folded away.

Whatever is left — the foreground process, the terminal’s colour theme — sits in one quiet line at the very bottom.

Compose a prompt

Above all of it is the Compose box, a single line at rest that grows into a multiline textarea with a Send button when you click into it. Write a prompt in peace, editing it before it ever reaches the terminal, then Send it (or Cmd/Ctrl + Enter) straight into the active terminal’s input line. It’s the in-app twin of kaval-tui send: it inserts, it doesn’t submit — the text lands in the agent’s input box for you to review and press Enter yourself, dodging the same paste race the CLI is careful about. Each terminal keeps its own draft in your browser, so a half-written prompt survives switching tiles or reloading.

Ports the terminal is serving

When something in a terminal starts listening on a TCP port, a Ports section appears listing it — the port number and the program holding it. This is the answer to “where is the thing the agent just ran?”, without scrolling back through output for a URL that has long since gone by. Detection is not a guess at printed text: kolu reads the host’s own socket table every few seconds (and immediately whenever the terminal produces output), and attributes each listener to the terminal whose process subtree holds it. So a port appears because something is genuinely listening, and it disappears when that stops.

A port bound to all interfaces on the machine running kolu already answers on the address you’re viewing kolu at, so its chip has an open link that opens it in a new tab.

A port bound only to loopback — or one on a remote host — can’t be reached from your browser as-is, so kolu opens a door for it. Click forward & open and kolu makes that port answer on the machine serving this page, then opens the tab. The row then carries a teal ⇄ :<port> pill naming where it answers, a copy button for the full address, and a that closes the door — one list, one row per port. A door you opened by hand, or one whose server has since died, trails the same list under “also forwarded on this host”, because a door belongs to the machine rather than to any one terminal.

Each of those rows also names the terminal serving the port, and the name is a link: click it and you land on the agent that started the thing.

A printed localhost URL is the same door

Agents constantly print http://localhost:5173/ (and 127.*, [::1], 0.0.0.0). In your browser that hostname is the wrong machine — the laptop you are reading kolu from, not the host running the server. Click a loopback URL in the terminal and a small card appears at the cursor: when the scanner already sees that port on this terminal it offers forward & open (and copy), with the printed path carried through the door; when nothing is listening yet it says so instead of inventing a forward from text. ⌘/Ctrl-click opens the raw URL with no card. Non-loopback links keep the usual open behaviour.

The card is live — leave it open while a server starts and it upgrades the moment the listener is real. Printed text never creates a port fact of its own; it only looks up what observation already established.

Port forwarding is documented in full under Add another machine — the two mechanisms, the one case that has no door at all, the ⌘KForward a port… path for a port kolu never saw, and the security note that a forwarded port is unauthenticated on every interface of the machine running kolu.

The terminal CLI, documented in place

An Attach section — folded until you open it, since reaching a terminal from a shell is something you do occasionally rather than watch — documents the whole shell-facing CLI for the terminal you’re looking at.

Every command that targets a terminal has the same shape, so the section is built that way: pick a pane (the main one, or any split — each split is its own PTY with its own id) and a verb (attach to take the session over, snapshot to dump its scrollback, send to type a prompt into it), and one ready-to-copy command line appears for that combination, already pinned to this kolu’s daemon. The pane’s id sits beside the pickers, copyable on its own.

Underneath it, a Drive one agent from another callout spells out the send → wait → snapshot loop, and a folded reference covers the rest of kaval-tui (list · create · kill), its awareness sibling padi-tui (status · watch · wait), and the --socket argument that points those id-less commands at this server.

It follows the terminal

Whether the panel is open, and which tab it’s on, is remembered per terminal, not as one global switch. Collapse it on a build-log tile and it stays collapsed there; leave it open on a branch diff and switching back restores it exactly. It rides session restore, so each terminal’s panel state survives a reload. New terminals open with the panel showing by default; the panel width and the Code-tab tree/content split stay global.

Next