Skip to content

First Run

The first launch of Roost creates its data directory, opens a single window, and gives you one project with one tab. Subsequent launches restore that state.

Window layout

Top to bottom, left to right:

Area Contents
Title bar Window title (active tab's cwd)
Sidebar (left) List of projects, with a + New Project button at the bottom
Tab strip (right) Tabs for the currently selected project, with a trailing + button
Terminal surface One libghostty-vt terminal per tab (Core Graphics on macOS, iced + wgpu on Linux)

Click a project in the sidebar to switch its tab strip into the right pane. Click a tab to swap the terminal surface to that tab's session.

With no host sessions saved, the sidebar looks exactly like this — one "PROJECTS" header, no dots. The first saved host splits it into per-host sections instead: a "LOCAL" band for the projects you see above, then one band per saved host, each with a small connection dot and a right-aligned agent count. This is opt-in. Hosting a session on this machine is Linux-only for now; a Mac can still connect to a remote Linux session over an SSH-forwarded socket, and its host sections look the same (see the guide's macOS note).

Default state

On first launch Roost creates a project named default with one tab. The tab's working directory is your home directory and the shell is whatever $SHELL is set to (falling back to /bin/sh).

Persistence

Every project, tab, working directory, and tab title is persisted to a small state.json file written atomically by the UI. When you relaunch Roost, all of those come back. Each tab spawns a fresh shell at its saved working directory — Roost never re-runs your last command on its own.

State Persisted? Notes
Project name + cwd Yes Sidebar order is preserved
Tab order, cwd Yes Tab strip order is preserved per project
Tab title (OSC 0/1/2) Yes Updated live as the shell sets it; locked once you rename via Cmd-R / Alt-R or roostctl set-title
Scrollback No Lost on shell exit; surface restart is fresh
Last command No (not auto-restarted) Use shell history (up arrow) to re-run

Where state lives

The user-editable config file lives under XDG on both platforms (~/.config/roost/config.conf); state files (state.json and the IPC socket) follow each platform's native convention:

  • macOS: ~/.config/roost/config.conf (config), ~/Library/Application Support/Roost/state.json (data), and ~/Library/Caches/Roost/roost.sock (socket)
  • Linux: ~/.config/roost/config.conf (config), ~/.local/share/roost/state.json (data), and $XDG_RUNTIME_DIR/roost/roost.sock (socket)

See Paths & Environment for the full layout.

What you should see

  • The default tab title shows the working directory if the shell hasn't set its own title yet (a one-line shell snippet makes this follow cd — see Working Directory Tracking)
  • Resizing the window reflows the terminal — vim and htop adjust correctly
  • Output renders with full 24-bit color and basic styles (bold, italic, inverse)
  • Two-finger scroll (or wheel) navigates the scrollback; pressing any input-producing key snaps the viewport back to the bottom
  • Click + drag selects cells with a translucent accent overlay; selection clears on PTY output, on resize, and on the next click. See Keybindings → Mouse for the full table including pass-through to vim / htop / tmux and the Shift-bypass convention.
  • Cmd-V (macOS) / Alt-V (Linux) / Ctrl-Shift-V (both) pastes the system clipboard. Multi-line pastes into modern shells are wrapped in bracketed-paste sequences so they don't auto-execute. Pastes are sanitized (NUL/ESC/DEL stripped) and capped at 4 MiB.

Common first-launch behaviors

  • macOS Notification Center may prompt for permission the first time roost (or osascript, the macOS notification fallback) tries to surface a notification.
  • On Linux the UI logs to $XDG_STATE_HOME/roost/roost.log (default ~/.local/state/roost/roost.log) and tees the same lines to stdout, so launching from a shell shows startup warnings (a missing font family, for instance) directly. RUST_LOG=debug turns the volume up. On macOS the Swift app logs to ~/Library/Logs/Roost/roost.log.

Next