Keybindings

Every chord goes through one registry. Panes declare the keys they want; the kernel resolves a press to an action and hands it back to the pane that claimed it. So this page is a description of what the shipped panes declare, not a fixed list — add a pane and it brings its own keys, remove one and its keys go with it.

F1 is authoritative. The help screen renders the registry itself, so it cannot drift from the running interface the way a written table can. If this page and F1 disagree, F1 is right.

What the kernel owns #

These are not a pane's to claim, because they have to work whatever is loaded — including when a plugin is broken.

Key Does
Ctrl+QQuit. Sessions keep running — tmux owns them, not thurbox
Ctrl+H / Ctrl+LMove focus back / forward through the ring
Ctrl+C / Ctrl+VCopy a selection / paste
F1 or Ctrl+GKeybindings help — the registry, rendered
F6 or Ctrl+,Settings. ] crosses to the Interface tab
F4 or Ctrl+YTheme picker (Ctrl+Y is DSUSP in some terminals, hence F4)
Ctrl+PCommand palette — every action the registry knows, filtered as you type; Enter runs one
F10Reload the interface from disk
F12Perf HUD (needs [features] perf_hud)

The session list #

Declared by ui/plugins/10_sessions.lua. The single-letter keys apply while the list is focused; the Ctrl forms work from anywhere, which is what lets you restart or fork a session without leaving the terminal you are typing in.

Key Does
j / k · / Next / previous session
Ctrl+J / Ctrl+KThe same, from anywhere
gFirst session
EnterOpen it — focus its agent
Shift+J / Shift+KMove it down / up. A parent drags its children; a whole group moves past a group edge
Shift+SSort by name within each repository group
Ctrl+DDelete — reversible, with an undo window
Shift+DDelete it and its worktree. Confirms first, itemising what would be lost
Ctrl+ZUndo the last delete
r or Ctrl+RRestart the agent, resuming the conversation where the agent supports it
Ctrl+FFork — a new session in the parent's worktree, carrying its conversation
Ctrl+SSync every worktree with its base branch
Ctrl+OOpen the session's directories in your editor
F9Hide the session list, for a full-width agent

The agent pane #

ui/plugins/20_agent.lua. Everything else you type here goes to the agent — that is the point of it.

Key Does
Ctrl+T or F8A shell in this session's directory, as a second tab beside the agent
PgUp / PgDnScroll the agent's history. Per session, so it does not follow you

Creating a session #

Ctrl+N opens the flow (ui/plugins/70_new_session.lua) — one float rather than a chain of modals. It walks host → repositories → base branch → name → branch name → agent, skipping the host step when no hosts are configured.

Key Does
j / k · / Next / previous choice
SpaceSelect a repository, or fold a folder. Multi-select — that is how one session spans several repositories
wGive that repository its own worktree
/Filter the list
Alt+PImport a folder of repositories
dForget a remembered repository
EnterConfirm the step
EscBack out. Nothing is created until the last step

Ctrl+/ opens a strip above the status bar (ui/plugins/65_search.lua). It matches session names, agents, branches and repositories — and the text on each agent's screen, which is the half that finds a session by the error in it. Matches highlight in the panes themselves; moving the selection previews it, and Esc puts back what you were looking at.

Key Does
typeFilter. Names match as a subsequence; screen text as a substring
/ Next / previous result, previewed as you move
EnterGo to it
EscClose, restoring what was on screen before

Why not Ctrl+P/Ctrl+N in the strip? A pane-scoped claim never outranks a global one, so declaring them would take Ctrl+N away from new-session everywhere. One registry for every chord is what buys that guarantee, and this is what it costs.

Rebinding anything #

From F1: select an action and press the chord you want. It takes effect on the next keystroke and persists to ui.json, beside the plugins you have turned off and the ones you trust — all three are your decisions, which is why they share a file.

Two rules the registry enforces. A chord already claimed by an action whose scope overlaps is reassigned, and you are told which one lost it — a silent double-binding is worse than a reported move. And a chord freed by a pane you removed stays unbound rather than being inherited by whatever loads next.

Chords the terminal takes first #

thurbox shares the Ctrl+letter namespace with readline, so while an agent has focus some chords are handed to it instead: Ctrl+A and Ctrl+E for line start/end, Ctrl+W and Ctrl+U for delete-word and kill-line, Ctrl+R for reverse-search. Navigation is deliberately never deferred — Ctrl+H/J/K/L, Ctrl+Q and Ctrl+N are how you get out of a focused agent, so they must keep working there.

On macOS, Cmd chords are bindable where the terminal supports the kitty keyboard protocol (iTerm2 3.5+, kitty, WezTerm, Ghostty — not Terminal.app). Shortcuts the emulator itself consumes (Cmd+Q/W/T/K…) never reach thurbox, so only bind what your terminal leaves free. F-keys need Fn on Mac laptops unless you have enabled standard function keys.

Chords a pane you install brings with it #

A pane declares its own keys, so installing one can add chords the shipped set leaves free: thurbox-code-review claims Ctrl+X/F7 and thurbox-info-panel claims F2 — see the interface.