Skip to content

Sidebar ​

The sidebar provides optional left and right docks beside your panes with tabs for activity, agents, panes, sessions, files, Git changes, worktrees, and projects. This page covers opening and navigating it, what each tab shows, and how to configure tabs or add your own.

The sidebar belongs to your client. It is never part of a shared session layout.

Open the sidebar ​

Press Ctrl+A, then b to show or hide the sidebar. Press Ctrl+A, then B to show it and move keyboard focus into its rows. Esc returns focus to the pane.

While the sidebar is visible, these command keys work without focusing it:

Command keyAction
PageDownNext tab
PageUpPrevious tab

Open Settings… → Bars → Left panels… or Right panels… to split a dock into one to three panels.

Show/Hide left sidebar and Show/Hide right sidebar in the command palette toggle one dock at a time. They have no default keys; bind them as toggle-left-sidebar and toggle-right-sidebar. The b command key hides whichever docks are shown and later brings back the same ones.

Both docks start hidden. Turn on Open sidebars at startup in Settings to reopen the docks that were open when you left; b brings them back either way.

Clicking a row runs its action and leaves keyboard focus in the pane.

After the B command key focuses the sidebar:

KeyAction
j/k or arrowsMove through selectable rows
PageUp, PageDownMove by a page
g, G, Home, EndFirst or last row
EnterActivate the selected row
Ctrl+EnterFiles/Git: insert the selected file or directory path into the focused pane. Worktrees: open the checkout the other way, see Worktrees
xClose the selected row; press again to confirm
Tab, Shift+TabNext or previous tab
h/l, arrows, SpaceCollapse, expand, or toggle directories and tree rows
Alt+Left/Right, Alt+h/lMove the active tab; cross into the other visible dock at the inner edge
Ctrl+Up/Down, Ctrl+k/jFocus the previous or next panel in this dock
Ctrl+Left/Right, Ctrl+h/lFocus the dock in that direction, keeping the panel level
Alt+Up/Down, Alt+k/jMove the active tab to the previous or next panel
Shift+Left/Right, Shift+h/lResize the sidebar
Shift+Up/Down, Shift+k/jResize the panel split
?Open Keybindings…
EscReturn focus to the pane

With the mouse, drag the sidebar's outer edge to resize it, within the same 16 to 80 columns that width allows. Drag the divider between panels to change the split.

Tab order, tab visibility, dock widths, and panel sizes are saved to config.toml and apply to every client.

Activity ​

Activity lists what is happening in the session besides your coding agents: statuses set with rozi status and rows published with rozi publish. Coding agents are listed in the Agents tab. To list the session's agents in Activity as well, turn on its Agents setting:

toml
[sidebar.settings.activity]
agents = true

An agent is anything the Agents tab lists: a coding agent rozi detects, or a program that reports or publishes its state as an agent; see Activities and agents. Rows are grouped by the Git project that contains each pane's working directory, with branch and workspace context. A published row can name its own directory, so a program that runs several sessions in separate worktrees shows each one under its own branch. A linked worktree is labelled with its repository's name and branch; a checkout with no branch shows its short commit.

Each agent takes two lines: what it works on, with its workspace number on the right, then its state and how long it has held, such as Working 9m22s, followed by what the agent says it is doing.

To name each repository once, with a line per checkout's branch and its agents beneath, set the tab's Worktrees setting to By repository. The default, Separate, gives each checkout a section of its own:

toml
[sidebar.settings.activity]
worktrees = "repository"
text
rozi
├ master
│ └ ⠋ Claude Code
├ fix/ssh
│ └ ▲ Codex
└ feat/sidebar
  └ ⠋ Claude Code

Selecting a row focuses its pane. For a published row, it also asks the program to show that activity.

When an agent runs more than once in one project, its runs are listed beneath one row for the agent, titled by what each works on, with its state and elapsed time beneath. The agent's row shows its most urgent run's state, and selecting it collapses or expands the runs. Collapsed, it counts its runs by state, such as ▲1 ⠋2 ✓1, leaving idle ones out.

A run that its program keeps in the background, such as a background session of Claude Code, has an italic title and ⧉ on its second line. Focusing its pane does not show it; selecting the row does.

Each row shows Blocked, Working, Done, Error, or Idle in its configured status colour. Blocked rows use ▲ in the warning colour and failed ones × in the error colour. A finished run stays marked Done until you look at the agent: focus its pane or, for one of several sessions in a pane, switch to that session. Programs can report their own progress here; see Program status.

Activity covers the session on screen. For agents in other local sessions and on connected hosts, use the Agents tab or the Agents view (Ctrl+A, then a).

rozi ships definitions for common coding-agent CLIs. To add or override one, see Agent definitions.

Agents ​

Agents lists every coding agent you have running, wherever it runs: in the session on screen, in your other running local sessions, and on every connected host. Each agent is listed under the Git checkout it works in, so you see who is working on what:

text
LOCAL
rozi                          master
├ Claude Code                  ▲1 ⠋1
│ ├ ▲ Fix SSH reconnect          dev
│ │   Blocked 3m20s  Permission req…
│ └ ⠋ Review the docs         review
│     Working 1m09s
└ ○ Codex                        dev
    Idle

WORKBOX
backend                      migrate
└ × Migrate the schema          prod
    Error   Thread failed · Codex

A heading names each machine once another machine has agents, LOCAL for this one. Beneath it, each checkout is a row named by its repository, with its branch on the right, followed by the branch's pull request number in the color of its status. A repository's primary checkout comes first, then its worktrees by branch, and agents outside any Git checkout come last, under Elsewhere.

Within a checkout, agents waiting for you come first, then failed ones, then finished runs you have not looked at, then agents still working, then idle ones. An agent with several runs in one checkout lists them beneath one row that shows its most urgent run's state.

A run is titled by the agent's task when it names one, then by its terminal title, then by the agent's name; runs that would read the same are numbered. The session it runs in is on the right. The second line gives the state, then the reason for it when the agent gave one, such as Permission required, then the agent's name when the run is titled by something else. Agents in a session this client holds also show a time beside their state: how long a working or blocked state has held, or how long a finished run took. A marker in the left margin shows the agent in the focused pane. As in Activity, a run its program keeps in the background has an italic title and ⧉.

A finished run reads Done with a filled ● until you look at the agent: focus its pane, or for one of several sessions in a pane, switch to that session. Looking at an agent anywhere counts everywhere, whichever session or host it runs in. Runs that finished before rozi attached or connected do not read Done.

Select a checkout, or an agent with several runs, to fold it. A folded row counts the agents it hides by state, such as ▲1 ⠋2 ○1, and its arrow takes the colour of the most urgent. It stays folded until you open it.

Activating a run goes to that agent: it focuses the pane in the session on screen, and switches to or attaches the session first anywhere else. To go to the next agent that needs you without looking for it, bind focus-next-agent-needing-attention (see Commands without default keys). Each press goes to the next agent that is waiting for you, failed, or finished a run you have not looked at, after the one on screen, in the Agents view's order.

The tab's Worktrees setting offers By repository too, as in Activity; the two tabs keep their own setting:

toml
[sidebar.settings.agents]
worktrees = "repository"

Unlike Activity, Agents lists only agents, never other activities such as rozi status reports or published activity rows.

Panes ​

Panes lists live panes grouped by workspace. Each workspace is a heading that shows the directory its panes share, with one row per pane beneath it. A row shows the pane title and its foreground program. A pane in another directory also shows where it is, relative to the heading's directory when it is inside it. Activating a row switches to that workspace and focuses the pane. Each group ends with + New pane, which opens a pane on that workspace.

To close a pane, hover its row and click x twice, or select the row in a focused sidebar and press x twice. This confirmation always applies, whatever your [confirm] settings.

Pane titles follow the order described in Layouts and panes.

Sessions ​

Sessions lists local sessions and known remote hosts. LOCAL and each host are headings, with their sessions and a row to start a new one beneath them. Activating a live session attaches or switches to it. Restorable sessions, and cached rows for offline hosts, stay listed when available.

Session rows show Current, Background for a connection held by this client, or Running for a live session this client is not attached to. Reconnecting and Offline describe retained connections that are unavailable. Stopped sessions with saved snapshots show Restorable; offline hosts' cached sessions show Last seen. When other clients share a session, their number follows its state, such as Current · 󰍺 1. Agent activity is shown separately.

Remote hosts add these rows:

  • An offline host has a connect row.
  • An online host has a disconnect row and a new-session row. Disconnecting detaches this client but leaves named sessions on the host running.
  • A session on a connected host that you are not attached to shows what its agents are doing, such as 4 panes · 2 blocked. See Agents on a machine you are not in.

The last row, + Connect a host…, opens the same prompt as Ctrl+N in Sessions → Remote hosts. rozi remembers a new host only after it connects successfully.

To kill a session, hover its row and click x twice, or select it in a focused sidebar and press x twice. Killing the session you are in leaves you in the session picker or the sessionless launcher.

See Sessions for session management and Remote sessions for host setup and authentication.

Files ​

Files browses the focused pane's working directory. It follows focus and cd, and directories load when you expand them. rozi remembers which directories are expanded until the client exits.

Files and Git follow the global nerd_icons setting: on, they show colored file icons and Nerd Font Git marks; off, Unicode expansion arrows and text Git marks. File-icon colors come from the active theme's file_icons palette.

Activating a file runs the tab's on_click action. By default, that types the path into the focused pane without pressing Enter.

Ctrl+click a file or directory, or press Ctrl+Enter on the selected entry, to insert its path into the focused pane without pressing Enter. This works in both Files and Git, whatever on_click is, and does not expand or collapse directories.

A symlink shows its target, as in guide-link.md → AGENTS.md. A linked directory does not expand.

Hidden entries, whose names start with a dot, appear dimmed in Files and Git. Turn off the tab's Hidden files setting to leave them out. Entries that Git ignores, such as a target/ build directory and everything in it, are dimmed too.

Type in the search bar above the Files tree to filter it. Git has a search bar too when you turn on its Search bar setting, and turning that setting off in Files hides the bar there. The tree shows the 1,000 closest matches, and when more entries match, the count beside the field reads like 1000/5321. Files and Git also have Root, which browses the focused pane's directory or the whole repository containing it, Line counts, and Entry limit. See Tab settings.

In a remote session, the listing comes from the remote host, and search covers only directories you have already expanded.

Git ​

Git shows changed files for the repository that contains the focused pane's working directory, with status markers and line-change counts when available. It always shows the whole repository, even when the pane is in a subdirectory.

When all of a directory's changes are inside one subdirectory, the two share a row, as in src/view/sidebar. Turn off the tab's Compact directories setting to always give each directory its own row.

In Files and Git, line-change counts appear before the status markers, as in +42 -11 M.

The tab says when the repository is clean, when the directory is not in a repository, when it is loading, or when changes are unavailable. In a remote session, git must be on the remote host's PATH.

Files and Git update as files change. Git status follows every tracked directory, open or not, so a file an agent edits under a collapsed directory still shows up as changed. On a filesystem that does not report changes, such as some network mounts, or in a repository with more than 4,096 tracked directories, the tree rereads every five seconds instead. In a remote session, both refresh when a command finishes and every few seconds. Neither refreshes while hidden.

Worktrees ​

Worktrees lists the Git worktrees of the focused pane's repository, on the host running that pane's session. A heading names the repository and host, with the checkouts beneath it. Each checkout is listed by branch, with PR/CI status underneath, such as #114 · Passed or #112 · Merged. Paths stay hidden; open the Worktrees picker to search by path or copy one with Ctrl+C. A bar in the left margin marks the checkout the focused pane is in. See Read work status for GitHub setup and status meanings.

The marker on the right shows whether a session was started from that checkout, using the same markers as the Sessions picker:

MarkerSession
●The one you are in
◐Held by this client in the background
↻Held by this client and reconnecting
×Held by this client, with its connection lost; activating reconnects
○Running on the host; activating attaches to it
◌Saved; activating restores it

A number after the marker counts the sessions using the checkout. Primary, Locked, Stale lock, or Prunable appears to its left when it applies; see Unlock a worktree. When you hover a row, or select it in a focused sidebar, the right edge changes to what activating it does: open, switch, connect, attach, restore, choose, new session, or new pane. A checkout you can remove also shows its ✕.

Activating a checkout opens its session. If several sessions use it, you choose one. If none do, rozi creates a session whose first shell starts in the checkout.

Ctrl+click, or Ctrl+Enter on the selected row, opens a shell in the checkout as a new pane of the current session instead; it needs a client that may change the layout. Set [worktrees] sidebar_open = "pane" to make a plain click open the pane, and Ctrl+click or Ctrl+Enter the session. Hold Ctrl while hovering or selecting a row and the word on its right edge changes to what Ctrl+click opens; this needs a terminal that reports modifier presses through the Kitty keyboard protocol.

+ New worktree opens the new-worktree form. The checkout appears as Creating…, and its session opens when Git finishes.

To remove a linked checkout, hover it and click x twice, or select it in a focused sidebar and press x twice. The branch is kept unless [worktrees] delete_branch says otherwise (see Delete the branch too). If Git refuses because the checkout has uncommitted changes, the row asks once more before forcing the removal. A checkout with a stale lock has an x too; confirming it unlocks the checkout and removes it. The primary checkout, checkouts with any other lock, and checkouts a session uses have no x.

See Worktrees for the picker, the CLI, and settings.

Projects ​

Projects lists every Git checkout any of your sessions works in — on this machine and on every connected host — arranged by repository:

text
 ▼ ▲ rozi
 ├▼ master
 │└─ api                1 pane
 └▼ ▲ fix/ssh
▍ └─ ▲ fix                  ▲1

Each repository lists its checkouts by branch, the primary checkout first, and each checkout lists the sessions working in it. A session is listed under every checkout one of its panes or agents works in. A row's status glyph shows the most urgent agent below it: blocked, then failed, then a finished run you have not looked at, then working. Session rows show compact colored status counts, as collapsed Activity clusters do, leaving idle agents out; a session without agents shows a pane count. Collapsed checkout and repository rows show their agents' combined counts. When more than one machine has work, each machine gets a heading, LOCAL for this one.

Sessions held by this client show connection states such as Background or Reconnecting. The current session is marked by its row highlight. An accent bar marks the session row for the focused pane's checkout.

Activating a session row keeps the focused pane when it already belongs to that checkout and session. Otherwise it goes to the most urgent agent working there, or to a pane there when none is, switching to or attaching the session first if needed. Activating a repository or checkout row shows or hides what is under it.

Projects lists where sessions work, not every checkout on disk; the Worktrees tab lists a repository's checkouts whether or not a session uses them. Panes outside a Git repository are not listed; with none to show, the tab reads No sessions in Git. If a remote host becomes unreachable, its heading shows its connection state and its work is hidden, except sessions this client is still connected to.

Expand and collapse ​

Projects, JSON command tabs, and stream tabs are trees. Click the chevron beside a row to show or hide what is under it. In a focused sidebar:

KeyAction
Right, lExpand the row, or move to its first child when it is already expanded
Left, hCollapse the row, or move to its parent
SpaceExpand or collapse the row

rozi remembers which rows you expanded or collapsed until the client exits.

Configure tabs and panels ​

Open Settings… → Bars → Sidebar tabs… to choose which tabs appear. Search by name and press Enter to turn a tab on or off. A tab with settings counts them beside its status, as in Enabled · 5 settings, and Ctrl+E opens them. A tab from an extension that is not loaded stays listed with a dash and keeps its place.

Arrange tabs by dragging them, or with the focused-sidebar keys above. Drop a tab on another panel's body to add it at the end, or on its tab bar to choose its position. A tab you turn off and on again returns to where it was.

When extensions provide presets, Settings… → Bars → Sidebar layout preset… offers them alongside the default layout.

toml
[sidebar]
startup = false
tabs = ["activity", "agents", "panes", "sessions", "files", "git", "worktrees", "projects"]
layout = { left = { width = 32, panel_count = 2, panels = [
  { weight = 0.4, tabs = ["activity", "agents", "panes", "sessions"] },
  { weight = 0.6, tabs = ["files", "git", "worktrees", "projects"] },
] }, right = { width = 32, panel_count = 1, panels = [{ weight = 1.0, tabs = [] }] }, hidden = [] }
background_follows_canvas = false
gap = true
background = true
tab_style = "padded"

The layout value can also be written as nested TOML tables. Reducing a dock's panel count moves the extra tabs into its last panel, and raising it again restores them.

background_follows_canvas, gap, background, and tab_style set the look of both docks.

See Configuration for defaults, size limits, file tree options, and custom tab syntax. A complete example is in examples/sidebar.toml.

Tab settings ​

Activity, Agents, Files, Git, Worktrees, and extension tabs that offer them have settings of their own. In Sidebar tabs…, highlight the tab and press Ctrl+E to open its settings. Ctrl+R puts the highlighted setting back to its default. Each change is saved to config.toml and takes effect at once.

A built-in tab's settings are saved in [sidebar.settings.<tab>]; see Built-in tab settings for the keys. Worktrees has one, Delete branch on remove, which is [worktrees] delete_branch, shared with the removal picker and the CLI. An extension tab's settings are the extension's own, saved in [extensions.<id>]; changing one restarts the extension's services.

Custom tabs ​

You can add three kinds of tab of your own:

  • A launcher tab lists configured entries. Each entry runs a run, send, or popup action, the same actions custom key commands use.
  • A command tab runs a command and shows its output as rows: one row per line, or a tree of rows when the command prints JSON.
  • A stream tab shows rows that running programs publish to it, and tells them when you click, expand, or act on a row.

Extensions can add tabs of every kind; see Extension sidebar tabs.

Launcher tabs ​

An entry's group puts it beneath a heading like the ones in Activity, Panes, and Sessions. Groups appear in the order they first occur, and entries without a group come first, without a heading. For example, a tab that starts an agent in a project, grouped by agent:

toml
{ name = "launch", label = "Launch", entries = [
  { label = "rozi", group = "claude", run = "cd ~/Projects/rozi && claude" },
  { label = "rozi", group = "codex", run = "cd ~/Projects/rozi && codex" },
] }

Command tabs ​

A command tab runs its command when the tab becomes visible, then again at its configured interval. The interval is at least five seconds. Each run has a five-second timeout and is limited to 64 KiB of output and 500 rows; a row keeps 4096 characters and shows 160. rozi strips terminal control sequences. A command that fails to start, times out, writes to standard error, or exits non-zero shows non-clickable error rows.

To group the output, set group_prefix. Each output line that starts with the prefix becomes a heading showing the rest of the line, with the lines after it beneath it. Headings cannot be selected. Launcher tabs use group instead.

A command tab runs in the focused pane's working directory and runs again when you cd. With --remote, the pane's directory is on the server, so the tab runs in the client's own directory.

JSON command tabs ​

With format = "json", a command tab's command prints one JSON object describing its rows instead of one row per line. Rows can nest, carry a state, and say more than a line of text can:

toml
{ name = "deps", label = "Deps", command = "deps-report --json", format = "json", on_click = { run = "deps-open \"$ROZI_ROW_ID\"" } }
json
{"rows":[
  {"id":"serde","label":"serde","description":"1.0.219","tone":"warning","detail":"1.0.228 available"},
  {"id":"serde/derive","parent":"serde","label":"serde_derive","description":"1.0.219"}
]}
FieldMeaning
idRequired. The row's identity, unique in the output. Expansion and clicks follow it.
labelRequired. The row's text.
parentThe id of the row it sits under. A missing parent makes it a top-level row.
descriptionRight-aligned text on the label's line.
metaA short value beside the label, such as how long something has run, in the row's state colour.
detailA second line under the label.
toneThe row's state, which picks its marker and colour: normal, muted, info, working, success, warning, blocked, or error.
activeMarks the current one of its kind.
disabledShows the row dimmed with this reason as its second line, and makes it inert.
expandedWhether the row starts expanded. Your own choice wins once you make one.
headingShows a top-level row as a section heading, with its rows always open beneath it. A heading cannot be activated, and its description sits at the right edge.

A row with children starts expanded unless it says otherwise. Activating a row runs the tab's on_click with the row's id in ROZI_ROW_ID and its label as the row text, so send may use {line} for the label. Without on_click, activating a row with children shows or hides them.

The same limits and error rows apply as for line output, and unknown fields are ignored. A command tab cannot use group_prefix with format = "json"; nest rows with parent instead.

Stream tabs ​

A stream tab has no command of its own. Programs publish its rows with rozi sidebar publish while they run, and rozi tells them what you do with those rows. Use one for something a program already watches: deployments, build jobs, a test watcher, the machines a service is connected to.

toml
{ name = "deploys", label = "Deploys", stream = true }
sh
deploy-watch | rozi sidebar publish --tab deploys

Each line a program writes is a complete snapshot of its rows, in the same row format as a JSON command tab. When you activate a row, expand a row marked expandable, or press one of the program's action keys on a row, rozi writes a line back. Several programs can publish to one tab at once; each owns only its own rows, and each gets a heading when there is more than one, such as LOCAL · prod or WORKBOX. A program that exits takes its rows with it.

A program can offer actions on its rows, each bound to a key that works while the sidebar is focused. One action can be the row's ✕, which, like every ✕ in the sidebar, asks for a second click or x. The sidebar's own keys are never available to a program. See the protocol for the full format.

Only processes you run and the extension that owns a tab can publish to it: an extension's processes publish only to that extension's own stream tabs, and other programs only to stream tabs in your config.toml.

Pass the selected row or path ​

ActionTabHow the selection is passed
sendCommand{line} in the text is replaced with the row
run, popup, execCommandROZI_ROW environment variable
anyJSON commandthe row's id in ROZI_ROW_ID, its label as above
sendFile tree{path} in the text is replaced with the path
run, popupFile treeROZI_FILE environment variable

{line} is sent literally — rozi does not quote or evaluate it — and is rejected in run and popup. When passing ROZI_ROW or ROZI_FILE to another program, quote it as "$ROZI_ROW" or "$ROZI_FILE". A row is command output and must never be used to build a command line.

Extension sidebar tabs ​

Extensions add tabs with [[sidebar_tabs]] in their manifest, using the same launcher, command, and stream forms. Their ids are <extension>.<name>. They may suggest an initial dock and panel; your saved placement takes precedence. An extension tab can offer some of the extension's settings in Tab settings. See Extensions.

Security ​

Custom commands run as your user through the configured command_shell. Treat sidebar configuration as executable code, and treat command output and filenames as untrusted input.

Shared sessions ​

In a shared session, the controller's sidebar narrows the shared terminal width. A follower's sidebar does not resize shared panes. See Shared sessions.

MPL-2.0