Configuration
lazyshell config init writes a fully commented config file at the right place, and
lazyshell config show prints the configuration actually in effect — after every
layer has had its say — together with the sources it came from. That second command is the answer
to "why is my setting not taking".
lazyshell config edit opens that file in your editor — $VISUAL, else
$EDITOR, else the first of nano, vim, vi that
is installed — creating it from the commented template first if it does not exist yet. When the
editor exits, the saved file is re-read and anything wrong with it (an unknown key, an
out-of-range value, an unparseable keybinding) is reported straight away rather than at the next
start.
Where the file lives
lazyshell reads its YAML config file from the first match:
$LAZYSHELL_CONFIG, if set$XDG_CONFIG_HOME/lazyshell/config.yml~/.config/lazyshell/config.yml
A missing file is not an error — lazyshell just runs with its built-in defaults. A partial file only needs to mention the fields it wants to override; everything else keeps its default.
Precedence
built-in defaults < ~/.config/lazyshell/config.yml < project lazyshell.yml
< environment variables < command-line flags
Nothing in a config file can stop lazyshell from starting. A key it does not know, a value out of range, an unparseable keybinding or an unknown colour are each reported on stderr before the interface opens, and the built-in default is used instead — never a silent no-op, never a refusal to run.
Option reference
| Key | Type | Default | Effect |
|---|---|---|---|
language | fr | en | fr | UI language: bindings, popups, status bar, footers and session messages. CLI output (lazyshell config …) stays French. |
shell | string | "" | Command started behind each session's pty. Empty means $SHELL, falling back to /bin/bash. |
term | string | xterm-256color | TERM announced to sessions. Lower it to make programs degrade on purpose. |
scrollback_size | int ≥ 0 | 10000 | Lines kept per session once they scroll off-screen. |
sessions_panel_width | int ≥ 5 | 40 | Sessions list width, in columns, in landscape mode. |
sessions_panel_height | int ≥ 5 | 10 | Sessions list height, in rows, in portrait mode. |
agents_panel_height | int ≥ 3 | 6 | Agents dashboard height, in rows, under the sessions panel in landscape mode. Hidden automatically when no AI agent session is detected, and in portrait mode. |
portrait_max_width | int | 84 | Portrait mode applies at or below this terminal width… |
portrait_min_height | int | 45 | …and above this terminal height. Portrait stacks the panels instead of splitting them side by side. |
refresh_interval_ms | int, 10–1000 | 30 | Redraw period. An unchanged panel is never pushed, so idle cost stays near zero at any value. |
kill_timeout_ms | int ≥ 100 | 2000 | Wait after SIGTERM before escalating to SIGKILL, and again before giving up. |
prefix_key | key spec | Ctrl+O | Locks the panel: one press, out of pass-through. Must be a control key, and it can no longer be typed into a session. $LAZYSHELL_PREFIX overrides it. |
keybindings | map | see below | Remaps an action id to a key spec. An action left out keeps its default key. |
markers.bell | 0–1 char | ! | Gutter marker for a session that rang while hidden. "" turns it off. |
markers.alt_screen | 0–1 char | # | Gutter marker for a session running a full-screen application. |
markers.activity | 0–1 char | ● | Gutter marker for a session that produced output while hidden. |
markers.broadcast | 0–1 char | + | Gutter marker for a session marked to receive broadcast keystrokes. |
markers.agent_idle | 0–1 char | ● | Gutter marker for a detected AI agent session that is idle. |
markers.agent_working | 0–1 char | ● | Gutter marker for a detected AI agent session that is working. |
markers.agent_blocked | 0–1 char | ● | Gutter marker for a detected AI agent session waiting on you. |
markers.agent_done | 0–1 char | ● | Gutter marker for a detected AI agent session that finished its turn. |
markers.agent_idle_color | colour | green | Colour for markers.agent_idle. |
markers.agent_working_color | colour | yellow | Colour for markers.agent_working. Pulses between full and dimmed brightness (twice a second) while the agent is working — the only one of the four states that animates. |
markers.agent_blocked_color | colour | red | Colour for markers.agent_blocked. |
markers.agent_done_color | colour | blue | Colour for markers.agent_done. |
markers.command_failed | 0–1 char | ✗ | Marker (next to its exit code, in the name/status columns rather than the gutter) for a non-agent session whose last command — per shell-integration OSC 133 — exited non-zero. |
markers.restart | 0–1 char | ↻ | Marker (next to its attempt count, in the name/status columns rather than the gutter) for a session that has needed at least one automatic restart — see restart:. |
scroll.page_lines | int ≥ 0 | 0 | Lines PgUp/PgDn move by. 0 means one full panel height. |
scroll.half_page_divisor | int ≥ 1 | 2 | Ctrl+U/Ctrl+D move by the panel height divided by this. |
theme.active_border_color | colour | green | Focused panel's border. |
theme.inactive_border_color | colour | default | Every other panel's border. |
theme.selected_bg_color | colour | blue | Selected line's background in the sessions list. |
theme.locked_border_color | colour | red | Output panel's border while locked (i.e. not in pass-through). |
theme.tab_active_color | colour | green | Selected tab in the output panel's tab strip. |
clipboard.fallback_command | string | "" | Command run with the yanked text on its stdin, instead of OSC 52, for a terminal that does not support it. There is no way to detect support, so this is a manual switch: empty means OSC 52 only. |
notify.fallback_command | string | "" | Command run with the notification text on its stdin, instead of OSC 9/777, when a detected AI agent session goes blocked or done. Empty means OSC only. |
window_title.enabled | bool | true | Whether the host terminal's window/tab title tracks the focused session (its name, plus its live OSC 0/2 title when one is set) via OSC 0. |
mouse.enabled | bool | true | Click, wheel and drag support. Turning it on costs Shift+↑/Shift+↓ pass-through — gocui gives those keys and the mouse buttons the same values, so they cannot both work. |
mouse.wheel_lines | int ≥ 1 | 3 | Lines one wheel notch scrolls the output panel by. |
mouse.forward_to_app | bool | true | Whether a program inside a session may receive the mouse itself, and only once it has asked for it with a DECSET 9/1000/1002/1003 (vim with set mouse=a, htop). A shell or an AI agent CLI never asks. |
perf.refresh_interval_ms | 0, or int ≥ 100 | 5000 | How often every session's processes are sampled for the resources tab. Runs in the background whether or not the tab is open, in a single pass across all sessions. 0 turns sampling off — it is the one periodic job that spawns a process. |
env_tab.mask_secrets | bool | true | Whether the environment tab masks the value of variables whose name looks like a credential (TOKEN, SECRET, PASSWORD, AUTH, ..._KEY). |
control.enabled | bool | false | Whether the agent control API is open — the socket lazyshell ctl drives a running lazyshell over. Off by default; read the agent sessions page before turning it on, since it lets any process running as you create sessions, type into them and read their output. |
agent_stats_command | string | "" | Run for the selected AI agent session, with $LAZYSHELL_SESSION_ID in its environment; its first line of stdout is shown next to the turn duration. Empty disables it. |
restore_layout | ask | always | never | ask | What to do, at launch, with a saved session layout for the current directory (see layout persistence) when there is no lazyshell.yml: ask shows a confirmation popup, always restores it with no prompt, never never offers it. |
Key specs
Key specs use gocui.Parse syntax: a bare character (n), or
Ctrl+N, Alt+Space, Tab, Esc.
The remappable action ids are:
new_session, new_named_session, new_session_in_dir, kill_session,
delete_session, rename_session, duplicate_session,
restart_session, zoom, next_tab, prev_tab,
filter_sessions, export_session, toggle_broadcast,
jump_next_blocked, jump_prev_prompt, jump_next_prompt,
copy_last_output, arm_watch, set_group, filter_group,
broadcast_group, kill_group, restart_group,
toggle_debug,
select_next, select_prev,
cycle_focus, help, quit.
An id outside that list is reported rather than ignored.
Colours
Colours accept any of:
-
an ANSI terminal colour name —
black,red,green,yellow,blue,magenta,cyan,white, and each one prefixed withbright(brightblue, …). These follow your terminal's own palette; -
a W3C/CSS colour name (
navy,teal,chartreuse, …) or#rrggbb, for a specific colour rather than a palette slot; default, for the terminal's own default colour.
The two name sets overlap and disagree: in CSS, blue is #0000FF,
which a terminal shows as bright blue. lazyshell resolves the ANSI names first, so
blue gives you ordinary blue; write navy if you want the CSS one, or
brightblue for the bright terminal slot.
Full example
This is what lazyshell config init writes — every option at its default value, so
you can delete whatever you do not change.
# ~/.config/lazyshell/config.yml
language: fr
shell: ""
term: xterm-256color
scrollback_size: 10000
sessions_panel_width: 40
sessions_panel_height: 10
agents_panel_height: 6
portrait_max_width: 84
portrait_min_height: 45
refresh_interval_ms: 30
kill_timeout_ms: 2000
prefix_key: Ctrl+O
keybindings:
new_session: "n"
new_named_session: "N"
new_session_in_dir: "M"
kill_session: "x"
delete_session: "D"
rename_session: "r"
duplicate_session: "c"
restart_session: "R"
zoom: "z"
next_tab: "]"
prev_tab: "["
filter_sessions: "/"
export_session: "w"
toggle_broadcast: "b"
jump_next_blocked: "B"
jump_prev_prompt: "{"
jump_next_prompt: "}"
copy_last_output: "Y"
arm_watch: "v"
set_group: "g"
filter_group: "G"
broadcast_group: "A"
kill_group: "X"
restart_group: "W"
toggle_debug: F12
select_next: "j"
select_prev: "k"
cycle_focus: Tab
help: "?"
quit: "q"
markers:
bell: "!"
alt_screen: "#"
activity: "●"
broadcast: "+"
agent_idle: "●"
agent_working: "●"
agent_blocked: "●"
agent_done: "●"
agent_idle_color: "green"
agent_working_color: "yellow"
agent_blocked_color: "red"
agent_done_color: "blue"
command_failed: "✗"
restart: "↻"
scroll:
page_lines: 0
half_page_divisor: 2
theme:
active_border_color: green
inactive_border_color: default
selected_bg_color: blue
locked_border_color: red
tab_active_color: green
clipboard:
fallback_command: ""
notify:
fallback_command: ""
window_title:
enabled: true
mouse:
enabled: true
wheel_lines: 3
forward_to_app: true
perf:
refresh_interval_ms: 5000
env_tab:
mask_secrets: true
control:
enabled: false
agent_stats_command: ""
restore_layout: ask