What is set up here for herdr beyond what it does out of the box: the keys in effect for panes, tabs and spaces (what herdr's sidebar shows; its API and docs call them workspaces), the commands that do the same from a shell, the patches on herdr itself, and the companions built around it. How they are used day to day is workflow.md.
The prefix is ctrl+s; pressing it twice sends a literal ctrl+s. A key marked config.toml is set in config.toml, which says why next to it; the rest are herdr's defaults. A key set there replaces herdr's default for that action, and a default whose key is taken there is dropped, so the old key may do nothing or something else (both listed under Defaults taken over). prefix+? shows every binding in effect, from herdr itself.
| Key | Does | From |
|---|---|---|
prefix+f |
Pick a space from a tree with fzf and switch to it (herdr-space-switch) | config.toml |
prefix+w |
herdr's own space navigator (up/down to move, h/j/k/l between panes) |
herdr |
prefix+g |
herdr's goto picker | herdr |
prefix+a |
Go to the pane of the latest notification | config.toml |
prefix+shift+n |
New space | herdr |
prefix+shift+g |
New worktree, opened as a space | herdr |
prefix+shift+w |
Rename the space | herdr |
prefix+shift+d |
Close the space (a worktree's checkout stays; herdr-worktree-ctl removes it) | herdr |
prefix+b |
Show or hide the sidebar | herdr |
| Key | Does | From |
|---|---|---|
prefix+c |
New tab | herdr |
prefix+n, prefix+ctrl+l |
Next tab | config.toml |
prefix+p, prefix+ctrl+h |
Previous tab | config.toml |
prefix+1 ... prefix+9 |
Go to that tab | herdr |
prefix+shift+t |
Rename the tab | herdr |
prefix+shift+x |
Close the tab | herdr |
| Key | Does | From |
|---|---|---|
prefix+h/j/k/l |
Go to the pane left, below, above, right | herdr |
prefix+o, ctrl+o |
Go to the other pane, or the next with three or more; while zoomed, only unzoom (patch 0008). ctrl+o needs no prefix and so never reaches the app in the pane |
config.toml |
prefix+shift+tab |
Go to the previous pane in order | herdr |
prefix+; |
Go back to the last pane | config.toml |
prefix+v, prefix+| |
Split side by side | config.toml |
prefix+- |
Split stacked | herdr |
prefix+x, prefix+q |
Close the pane | config.toml |
prefix+z |
Zoom the pane, or unzoom | herdr |
prefix+shift+h/j/k/l |
Resize one step left, down, up, right (no repeat; press the prefix again) | config.toml |
prefix+r |
Resize mode: h/j/k/l or the arrows, repeatedly, until esc or enter |
herdr |
prefix+shift+p |
Rename the pane (a leading * or ! marks a pane in use) |
herdr |
prefix+e |
Open the pane's scrollback in $EDITOR |
herdr |
prefix+[ |
Copy mode (below) | herdr |
prefix+[ enters it on the focused pane; the pane keeps running.
| Key | Does |
|---|---|
v, space / V |
Start a selection / a selection of whole lines |
o |
Go to the other end of the selection (a patch here) |
y, enter |
Copy the selection and leave |
q, esc |
Leave without copying (esc first clears a selection or a search) |
h/j/k/l, w/b/e, W/B/E |
Move by character, word, big word |
0, ^, $ |
Start of the line, first non-blank, last character |
{, }, g, G |
Previous and next paragraph, top and bottom of the history |
ctrl+u/d, ctrl+b/f |
Half a page, a page up and down |
/, ?, n, N |
Search forward, backward, and repeat |
| Key | Does | From |
|---|---|---|
prefix+t |
A scratch shell in a popup, in the focused pane's directory | config.toml |
prefix+shift+v |
Show or hide the reviewr pane | config.toml |
prefix+shift+r, prefix+shift+s |
hunk: review the changes, send the review to the agent | config.toml |
prefix+shift+c, prefix+shift+a |
hunk: review the last commit, the staged changes | config.toml |
prefix+ctrl+r |
Reload config.toml | config.toml |
prefix+s |
herdr's settings | herdr |
prefix+d |
Detach | config.toml |
prefix+? |
Every binding in effect | herdr |
herdr's defaults that config.toml gives to something else, for reading herdr's own docs:
| Key | herdr's default | Here |
|---|---|---|
prefix+o |
Latest notification | Next pane; the notification is prefix+a |
prefix+q |
Detach | Close the pane; detach is prefix+d |
prefix+shift+r |
Reload config | hunk review; reload is prefix+ctrl+r |
prefix+shift+h/j/k/l |
Swap the pane with its neighbor | Resize; swapping has no key |
prefix+tab |
Next pane | Nothing; the next pane is prefix+o |
These talk to the running herdr, from any shell inside or outside it.
Built in herdr/space-switch.nix from a gist; prefix+f runs it in a popup.
herdr-space-switch # pick from every space
herdr-space-switch dot # start with "dot" typed; one match switches at once
herdr-space-switch --git=status # add each checkout's marks: * + $ % ↑ ↓
herdr-space-switch --git=branch,status # add the branch too, columns in this order
herdr-space-switch -g # the same as --git=status,branchIn the picker, ctrl-/ shows the preview below, moves it to the right and hides it; ctrl-d/ctrl-u scroll it. The status mark is the one the API reports, which can differ from the sidebar's: the sidebar keeps what it has shown on its own.
herdr workspace list # every space as JSON: id, label, number, state, worktree
herdr workspace focus <workspace_id> # switch to a space
herdr tab list --workspace <id> # its tabs
herdr pane list --workspace <id> # its panes, with agent, state and title
herdr pane read <pane_id> --lines 50 # the end of a pane's output
herdr server reload-config # what prefix+ctrl+r doesherdr <command> --help lists the rest (tab, pane, agent, worktree).
herdr is nixpkgs' build with these patches, one per change, applied in name order. Each patch file's message says what it does and why; they are commits on the patches branch of the fork babarot/herdr, exported here with the import-fork-patches skill, never edited here. Making and carrying one is maintenance.md; the build is in herdr.nix. When a patch is added, changed or dropped, change its row here.
| Patch | What changes |
|---|---|
| 0001 | A worktree space renamed after its feature still shows its branch and ahead/behind in the sidebar (herdrdev/herdr#2952) |
| 0002 | A worktree token for the sidebar's rows: the checkout's directory name, which other sessions go by; left out when the checkout is named after the branch |
| 0003 | The new worktree dialog (prefix+shift+g) takes the space's name, leaving the generated branch and checkout alone |
| 0004 | "Mark as unread" in a space's menu brings back the Done mark of its agents already looked at (herdrdev/herdr#4622) |
| 0005 | o in copy mode goes to the other end of the selection, as in tmux and Vim |
| 0006 | ui.toast.duration_seconds sets how long an in-app toast stays, for every kind; 0 keeps it until clicked |
| 0007 | In-app toasts stack, up to 5, instead of waiting for the one shown to close |
| 0008 | Cycling panes (ctrl+o, prefix+o) while the tab is zoomed only unzooms, instead of moving the zoom to the next pane |
| 0009 | ui.toast.dismiss_on_read closes a space's in-app toasts once that space is opened, whatever their duration; a worktree's only its own |
| 0010 | A notification from a linked worktree space names it as repo/space, so spaces of different repos with the same name can be told apart |
What exists only for herdr, built in herdr.nix or the files it imports from herdr/, so deleting herdr.nix removes them too. Each file's header says what it does.
| Companion | What it is |
|---|---|
| herdr-space-switch | The space picker on prefix+f (above); the script is a gist |
| herdr-worktree-ctl (herdr.nix) | Lists herdr's worktrees and removes the ones picked, as closing a space leaves the checkout; the script is a gist |
| worktree-layout | A plugin that lays out each new or opened worktree space: Claude Code, reviewr, a shell |
| worktree-status | A launchd agent that puts marks after a worktree space's name by conditions set per Mac |
| reviewr, hunk-diff | Review plugins, on the keys under Other |
| plugins.nix | my.herdrPlugins, which registers the plugins with herdr on every switch |