OdyTTY Feature Reference

September 5, 2026 · View on GitHub

Use this guide to understand OdyTTY's terminal behavior, configure the native app, and work with tabs, panes, workspaces, remote hosts, and shell integration. For installation and a shorter overview, start with the README.

Contents

Configuring OdyTTY

Most customization happens inside OdyTTY. Hand-editing a config file is optional: the settings panel, pickers, and command palette provide the primary in-app paths. For a shorter tour of what ships enabled and which opt-ins fit particular workflows, start with the settings guide.

TaskWhere to do itWhat happens
Browse and edit settingsCtrl+Shift+,Changes apply live in the terminal behind the panel
Find a settingPress / inside SettingsFilters by name, config key, description, or group
Save changesCtrl+S inside SettingsWrites only changed rows to odytty.conf
Choose a themeCtrl+Shift+H or Settings → ThemesOpens the theme picker
Choose a fontOpen a font row in Settings → FontsOpens the bundled and system font picker
Run an actionCtrl+Shift+POpens the command palette
Configure tabs and panesSettings → LayoutGroups Tabs, Workspace rail, Panel, and Panes

The settings panel is keyboard- and pointer-driven. Arrow keys move through sections and rows, Enter activates a choice, and Esc clears a search or closes the panel. Clicking a numeric row starts text entry; the first keystroke replaces the prefilled value so a new number can be typed directly.

Ctrl+Shift+, and Settings from the terminal content menu open the section list. Settings from the empty tab strip, a workspace slot, or the empty workspace rail opens Layout directly.

Edits apply live, but the config file is not changed until you press Ctrl+S. Saving uses a preservation-first writeback: comments, blank lines, key order, and unknown or future keys stay in place, while changed keys are rewritten and missing changed keys are appended. OdyTTY saves through a same-directory temporary file and rename instead of truncating the file in place.

odytty.conf and hosts.conf share a single-writer, temporary-file, sync, and atomic-rename path. On Unix, a new file is created with mode 0644; a stricter existing mode is preserved, while group/other-write and execute bits are clamped back to that 0644 ceiling. Windows preserves inherited ACLs.

Settings resolve in this order:

PrioritySourceIntended use
1Built-in defaultsA complete usable setup
2odytty.confDurable preferences
3ODYTTY_* environment variablesSession-scoped overrides

On Unix, the config path is $XDG_CONFIG_HOME/odytty/odytty.conf, falling back to ~/.config/odytty/odytty.conf. On Windows it is %APPDATA%\odytty\odytty.conf. OdyTTY polls the resolved file about once per second and applies valid external edits live; environment-pinned values remain pinned for that session.

The optional file format is dependency-free key = value text with # comments:

theme = odyssey-default
font_family = Victor Mono
font_size = 20.0
render_quality = high

See Runtime Knobs for every config key, environment variable, range, default, and reload rule. The annotated config is a starting point for readers who prefer to edit the file.

Terminal Compatibility

OdyTTY owns its parser and terminal model. The supported surface covers common shells and full-screen terminal applications:

AreaSupported behavior
Text and attributesPrinting, UTF-8 chunking, SGR attributes including legacy SGR 21 double underline, 256-color, and truecolor
Cursor and editingCursor movement including CNL/CPL line-relative redraw controls, erase, insert/delete character and line, insert/replace mode (IRM), repeat, and reverse index
Screen stateScroll regions, origin mode, tab stops, bracketed paste, focus reporting, and alternate-screen modes 47/1047/1048/1049
Character setsG0/G1 designation, SO/SI selection, and DEC Special Graphics mapping for ncurses ACS line drawing
OSC sequencesOSC 0/2 titles, OSC 7 working directories, OSC 8 hyperlinks, bounded OSC 9/777 notifications, OSC 9;4 progress, OSC 52 clipboard write plus opt-in read, OSC 133 prompt marks, and OSC 4/10/11/12 dynamic colors
Queries and controlsDECRQM/DECRPM, XTWINOPS, XTGETTCAP, DECRQSS, rectangle operations, selective erase, and synchronized output mode 2026
Pointer inputBroad mouse reporting, including X10, normal, button-event, any-event, focus events, UTF-8, SGR, urxvt, legacy encodings, and SGR-pixel mode 1016
Keyboard inputMode-aware legacy encoding, negotiated Kitty keyboard protocol, and IME composition

SGR-pixel mode reports true physical pixel coordinates from the native window. Alternate scroll mode 1007 is on by default and translates the wheel into cursor-key presses on the alternate screen. Full-screen applications that do not track the mouse therefore scroll at the configured scroll_wheel_lines rows per notch.

The Kitty keyboard protocol is a negotiated overlay. With no Kitty flags active, legacy bytes are preserved. Under the disambiguate flag, modified Enter/Tab/Backspace (for example Ctrl+Enter, Shift+Enter, Ctrl+Backspace) become distinct CSI-u sequences while the unmodified keys stay on their legacy bytes.

xterm's modifyOtherKeys (XTMODKEYS, levels 1 and 2) is supported as a compatibility layer for applications that select it by TERM — Vim's default keyprotocol and emacs both do under xterm-256color, and tmux negotiates extended keys through it. Modified keys encode as CSI 27 ; modifier ; codepoint ~, the level is per-screen with the same reset behavior as the Kitty flags, and XTQMODKEYS reports it. When an application enables both protocols (fish does), non-zero Kitty flags win.

On Windows, a console application can request ConPTY Win32 input with DEC private mode 9001. While that mode is active, OdyTTY sends complete Win32 key records, including key-up state, virtual-key and scan codes, Unicode text, modifier flags, and repeat counts. This preserves input such as Ctrl+Backspace word deletion in PowerShell and distinct Shift+Enter. The application requests the mode; there is no OdyTTY setting, and the mode is inert on Unix. When it is inactive, Kitty, modifyOtherKeys, and legacy input continue through their normal selection rules.

On Linux display stacks, editing keys are normalized before shortcut and PTY dispatch whether the compositor reports a named key or its translated control character. Backspace, Tab, Shift+Tab, Enter, Escape, and forward Delete retain their ordinary behavior; at an enhanced Bash or Zsh prompt, Ctrl+Backspace remains distinct and word-deletes. Fish continues to manage its own keyboard protocol.

Paste Safety

OdyTTY's risky-paste confirmation is a structural safeguard for text entering a child that has not enabled terminal bracketed-paste mode. It does not try to understand shell syntax or decide whether a command is safe. The child application controls bracketed-paste mode; interactive shells and editors such as Fish commonly enable it while their input editor is active. In that normal case OdyTTY preserves the existing bracketed transaction without adding a second confirmation dialog.

With warn_on_risky_paste = on (the default), the dialog opens only when all of these conditions are true:

  1. A native text paste is requested for the active pane.
  2. The destination child currently reports bracketed-paste mode as disabled.
  3. The original text contains a CR or LF line break, or a Unicode control character other than Tab.
Original text and destination stateResult
Single line with ordinary text, Unicode, or tabs; bracketed paste offPaste directly
CR, LF, CRLF, empty lines, or another control character; bracketed paste offShow the risky-paste dialog
Any text while the child has bracketed paste onPreserve the existing bracketed-paste path; no dialog
Any text with warn_on_risky_paste = offUse the historical encoder; no dialog

Classification examines the complete original transaction before any line ending normalization. The dialog escapes controls for display, caps the rendered preview at 512 UTF-8 bytes, and reports exact original line and byte counts even when the preview is truncated. Raw clipboard text stays in transient application state: it is not logged, persisted in a workspace, placed in diagnostics, or copied into notification text.

The choices have explicit behavior:

  • Paste sends the held original text through the existing encoder. It does not append Enter or split the confirmation into implicit commands.
  • Paste as One Line is offered only for multiline text without another disallowed control and when the reversible result is at most 32 MiB. It displays CR/LF as visible \\r/\\n text and doubles existing backslashes; it does not silently discard or merge source bytes.
  • Cancel writes nothing. Focus loss, a destination-pane ownership change, pane exit, window close, preview setup failure, or a stale bracketed-paste state also cancels the held paste.

Shortcut, command-palette/menu, context-menu, Linux PRIMARY, external text drop, and authorized automation paste routes use the same policy. PRIMARY has no platform surface on macOS or Windows. The setting can be changed through Settings, warn_on_risky_paste in odytty.conf, or ODYTTY_WARN_ON_RISKY_PASTE; disabling it is an advanced global opt-out.

A bracketed paste is queued as one transaction containing the opening marker, sanitized text, and closing marker, so unrelated input cannot split the frame. A bracketed paste whose complete framed payload exceeds MAX_BRACKETED_PASTE_BYTES = 32 MiB is refused whole. Plain, non-bracketed paste has no comparable whole-payload rejection and remains deliberately chunked. With child bracketed-paste mode off, original multiline or control-bearing text is held behind a bounded escaped preview before PTY writing. The dialog reports original line and byte counts and offers Paste, reversible Paste as One Line when available, or Cancel. Safe single-line and child-enabled bracketed paste retain their existing byte behavior.

IME pre-edit appears inline at the cursor and committed text is sent to the shell. This supports CJK input methods and compose-key or dead-key accents.

The terminal bell (BEL) has no audible mode:

bell valueBehavior
urgentRequests window attention when unfocused; this is the default
visualShows a brief, readability-safe screen flash
allRequests attention and shows the flash
offDisables bell feedback

Text, Emoji, And Graphics

Render Text And Symbols

Victor Mono is bundled and selected by default at 20 logical pixels with line height 1.0. JetBrains Mono is also bundled and selectable through font_family.

The font picker separates always-available Bundled Fonts from host System Fonts. Its bundled symbol fallback is a chain of Nerd Fonts v3 and v2 faces, so PUA prompt icons work without a host-installed Nerd font and remain compatible with configs from either Nerd Font era.

Bundled and discovered system families both resolve without hand-written configuration.

With wheel_zoom enabled, Ctrl+wheel changes the live font size when the running application has not claimed mouse reporting. Each effective step shows a compact centered font-size HUD, replaces the previous value during a gesture, and clears after one bounded delay without animation.

Text controlSupport
Font sourcesBundled families, system families, and direct font files
StylingFont-weight variants, synthetic styles, and subpixel antialiasing
Programming ligaturesDefault-on calt+liga for ASCII plus a curated non-ASCII operator allowlist; optional off-by-default ss01/ss02; Arabic joining forms in logical LTR cell order; grid-aligned source cells
FallbackPer-range symbol maps and bundled Nerd Font v3/v2 faces
ReadabilityLinear-light color composition, glyph coverage gamma, stem darkening, and minimum-contrast enforcement

Fresh profiles enable contextual programming ligatures from the selected text font. Shaping runs cover eligible ASCII graphics, a curated allowlist of common non-ASCII operators and arrows, and Arabic joining bases, and change only presentation: the terminal model keeps one logical character per cell, so copying, selection, search, cursor placement, and wide-cell behavior retain their ordinary semantics. Latin/operator runs enable OpenType calt and liga together; optional stylistic sets ss01 and ss02 are off by default (ss01 = on / ODYTTY_LIGATURE_SS01=on, and likewise for ss02). Arabic joining is shaped in logical left-to-right cell order - not bidi reordering; RTL visual layout remains deferred. Unsupported fonts and runs render through the normal per-cell path. Set ligatures = off in Settings or configuration, or ODYTTY_LIGATURES=off for one launch, to restore scalar rendering; the setting reloads live.

The support boundary is explicit:

SurfaceCurrent supportStanding position
Latin and programming operatorsASCII calt+liga, a curated non-ASCII operator allowlist, and opt-in ss01/ss02 overlaysMore curated operators and bounded, explicit font-feature settings are candidates within the current overlay model
ArabicContextual joining forms in logical left-to-right cell order; combining-marked cells stay on the monochrome pathMore joining-script coverage that requires no visual reordering is a candidate; this is not bidirectional layout
Full Unicode bidirectional layoutNot supportedOutside the current overlay model. Correct support first requires line-level logical-to-visual mapping shared by rendering, hit testing, cursor movement, selection, damage tracking, and copy semantics
Complex Indic/Brahmic shapingNot supportedOutside the current one-character-per-cell overlay model. Correct support requires grapheme-cluster ownership plus reordered glyph placement that remains reversible to logical cells
Emoji cluster renderingVS15/VS16 presentation, flags, keycaps, skin tones, and common ZWJ clusters are reconstructed for the color-glyph rendererRendering support does not yet make grid width cluster-aware; sequence-aware width is tractable follow-up work
SVG-in-OpenTypeNot supported; SVG-only glyphs use monochrome fallbackDeferred implementation work, not a cell-model conflict. It requires a bounded, non-networked SVG raster path and portable fixtures before enablement

A partial BiDi or complex-script approximation is not planned: visual order that disagrees with cursor, selection, search, or copy behavior would weaken terminal correctness. The detailed prerequisites, acceptance boundaries, and measurement are in the text shaping roadmap.

The independent 2026-08-16 review's ucs-detect run covered 85 languages and recorded an aggregate 81.2% check pass rate. Failures appeared in 22 language cases, all Brahmic or derived from Southeast Asian Brahmic scripts; the run reported none in its Latin, Cyrillic, Greek, CJK, Hebrew, or non-conjunct Arabic cases. This is a result for that corpus, not a percentage of languages OdyTTY claims to support.

Decomposed combining marks stay attached to their base glyph in the monochrome text path. Wrapped and rectangular selection copy the base followed by its marks in stored order. If the active font lacks a combining mark, OdyTTY omits that mark instead of drawing a tofu box over the base glyph.

Supported box-drawing, block and shade elements, Braille, Powerline separators, and Symbols for Legacy Computing sextants and octants use OdyTTY's procedural cell coverage instead of font outlines. The coverage meets its cell edges exactly, keeping TUI borders, graphs, and prompt separators crisp and seamless at every font size. geometric_boxdraw is on by default; box_thickness tunes line weight when a different visual density is preferred.

Text colors are composed in linear light, with an sRGB surface preferred for correct antialiased edges. text_gamma controls coverage weight independently, and optional subpixel antialiasing uses dual-source blending on capable GPUs.

Render Color Emoji

Color emoji uses swash, Fontations, and a dedicated premultiplied-RGBA atlas. It supports bitmap strikes through Noto Color Emoji (CBDT/CBLC) and Apple Color Emoji (sbix), static COLR/CPAL v0 layers, and COLR v1 Paint graphs including solid fills, linear/radial/sweep gradients, affine transforms, clipping, and the standard composite modes. Directory discovery recognizes stock Windows Segoe UI Emoji and other parseable COLR/CPAL faces. The shared raster and atlas logic is platform-neutral.

Variation selectors, flags, keycaps, skin tones, and common ZWJ clusters are supported by the color-glyph renderer. This is presentation support, not a claim that the terminal grid computes sequence width: grid occupancy is still assigned per codepoint, so VS15, VS16, and ZWJ sequences can occupy the wrong number of columns even when they draw as one color glyph. Text-default symbols stay on the monochrome fallback path, missing color glyphs fall back there instead of becoming tofu, and emoji pixels are not SGR-tinted. Cluster coverage is bounded by the host font: stock Windows Segoe UI Emoji ships no regional-indicator flag glyphs, so flag clusters on a stock Windows install render as the visible letter fallback - the same behavior as native Windows applications - rather than a color flag.

Regional-indicator pairs currently total two columns by independent scalar arithmetic, not because the grid recognizes a flag cluster. The separate unicode-width versus Python wcwidth disagreement for a standalone regional indicator is an ecosystem compatibility decision, not an OdyTTY defect.

Source preference is bitmap strike, then COLR v0, then COLR v1. The first two paths retain their established byte output; v1 is attempted only when they do not cover the glyph. The Windows CI assertion records how many glyphs in the installed Segoe build expose v0, v1, and v1-only coverage instead of assuming a specific system-font revision. The synthetic v1-only fixture is the portable correctness evidence when no stock v1-only glyph is observed. SVG-in-OpenType remains deferred; an SVG-only glyph falls back to the monochrome path.

Display Inline Graphics

ProtocolSupported surface
Kitty graphicsStill-image actions t, T, p, d, and q, plus animation frame/control/composition actions f, a, and c; raw RGB, raw RGBA, and PNG data; direct and chunked-inline transports; opt-in file, temporary-file, and Unix POSIX shared-memory transports; image and placement ids; z-index; crop; cell scaling; pixel offsets; and Unicode placeholders (U=1 virtual placements resolved from U+10EEEE placeholder cells)
SixelDEC/xterm data language, RGB/HLS color introducers, repeat, raster attributes, transparency, VT340 palette, and DECSDM
iTerm2 inline imagesOSC 1337 ; File= with inline, size, width, height (cell / px / % / auto units), and preserveAspectRatio; PNG, JPEG, and WebP containers; cursor advances below the image. Payloads are bounded by the 128 KiB OSC cap (~96 KiB of encoded file bytes) and an over-cap command is rejected whole. inline=0 downloads are never honored — no escape sequence writes files.

Animation is supported: frame transmission (a=f), playback control (a=a), frame composition (a=c), and single-frame deletion (d=f/d=F, requiring an image id). Frames share the image store's byte budget, visible placements in every active split pane advance, and a session with no animated image schedules no extra work. Animated container formats (APNG, GIF) are still decoded as a single still frame - animation comes from the protocol's frame commands.

Tab And Pane Workflow

OdyTTY can run many shells in one window. Tabs hold one or more panes, while workspaces group complete sets of tabs.

Open, Close, And Switch Tabs

TaskShortcut
Open a new tabCtrl+Shift+T
Close the active tabCtrl+Shift+W
Switch to the next tabCtrl+PageDown or Ctrl+Shift+'
Switch to the previous tabCtrl+PageUp or Ctrl+Shift+;

Closing a tab closes the whole tab, including every pane it holds. Closing a single pane is a separate action, and closing the last tab in the last workspace quits OdyTTY.

The punctuation alternatives use the physical ; and ' keys for keyboards without PageUp/PageDown. They are unavailable on layouts where those positions produce letters, such as German O-umlaut/A-umlaut layouts; use the command palette in that case.

Rename a tab from its right-click menu or with Rename Tab in the command palette. The custom name overrides shell title updates until an empty name clears it, and names are session-local rather than saved across restarts.

When more than one workspace exists, a tab's right-click menu adds Move to Workspace…. The picker lists the other workspaces by name and moves the clicked tab to the selected destination.

Duplicate Tab in the tab menu, or Ctrl+Shift+D, opens a fresh shell at the active pane's working directory. It does not copy scrollback or the running program, and a pane without a tracked directory opens in the default one.

Adjust The Tab Bar

The bar appears when two or more sessions exist. A single unnamed shell keeps the full-grid view, while a renamed single tab always shows the bar so its workflow name remains visible.

Tab-bar controlBehavior
Always show tab barKeeps the bar visible with one unnamed tab; always_show_tab_bar is off by default
Drag the bottom edgeSets tab_bar_height from one to five text rows
Double-click the bottom edgeResets tab_bar_height to auto, the default one-row height

The bar and a pinned workspace rail form one continuous, pixel-snapped chrome surface with no exposed background gutter. Their shared junction has one intentional resize seam, while the rail-to-content gap remains content padding. The band stays opaque enough for labels to remain legible over images and effects. Inactive tabs are dimmed; the active tab is marked by a selection-role fill and a bright, bold label. A static dot marks unseen bell activity on a background tab and clears through the existing view/switch semantics.

Labels stay centered vertically when the bar grows. Inline image placements use the same reserved rows as text, so inline graphics remain aligned with the visible grid.

Split A Tab Into Panes

TaskDirect path
Split into columns, with the new pane on the rightCtrl+Shift+E or Split Right
Split into rows, with the new pane belowCtrl+Shift+O or Split Down
Close only the focused paneClose Pane, labeled with Ctrl+b x, in a multi-pane content menu
Resize adjacent panesDrag their divider

The direct split chords follow common Linux terminal conventions and work in both single-pane and multi-pane tabs. Close Pane is hidden for a single-pane tab, where closing the tab is the only close action.

Once a tab has multiple panes, a tmux-style prefix enters a transient pane command mode. The prefix is Ctrl+b by default and is configurable through pane_prefix.

Key after the prefixAction
%Split the focused pane into columns
"Split the focused pane into rows
/ / / Move focus to the neighboring pane
oCycle focus to the next pane
xClose the focused pane
zZoom or unzoom the focused pane while preserving its layout
Space / =Equalize split sizes
Ctrl+bSend a literal prefix to the focused pane for a nested multiplexer

The prefix is captured only in a multi-pane tab. A single-pane shell receives Ctrl+b unchanged, and pane_prefix=off frees it in multi-pane tabs as well.

Each pane owns an independent PTY, terminal model, scrollback, viewport, selection, search, and cursor. Selection and search highlights render in their own pane, while the search query bar stays on the focused pane.

window_padding applies at divider-facing edges as well as the outside window and chrome edges. After a window resize or divider drag settles, every affected pane is reconciled to the final whole-cell geometry. A pane narrowed below one drawable cell keeps a valid one-cell PTY backing model but clips terminal rendering and rejects cell input until it expands again.

During interactive window resize, a centered transient HUD reports the final debounced terminal geometry as columns × rows. The initial nonzero configure is silent, minimize events are ignored, and later updates clear 750 ms after the last applied resize. The same static treatment works in single- and multi-pane, plain-theme, effects, and reduced-motion paths without changing PTY state.

Inline image placements are also per-pane and clipped to the pane's sub-rectangle. Optional inactive-pane dimming uses inactive_pane_dim, defaults to 0.0, and is disabled by render_quality=plain; the no-dim frame remains byte-identical.

The terminal content menu includes Settings plus Keyboard Shortcuts, Connection Manager, Command Palette, Session Replay, Manage Sessions, and Detach & switch in a launcher section. Items with a bound chord show it right-aligned. A tab's own menu provides New Tab, optional New Local Tab for a host-bound workspace, Duplicate Tab, Rename Tab, Close Tab, Close Other Tabs, Connect to Host…, Replace with Host…, optional Move to Workspace…, and New Window.

Connect to Host… opens a saved host in a new tab immediately after the clicked tab without changing the clicked shell. Replace with Host… replaces the clicked tab and asks for confirmation when that tab still has a program running.

Right-clicking the empty tab strip offers New Tab, New Workspace, Open Layout, Command Palette, and Settings.

Organize Workspaces And The Rail

Every workspace keeps its own tabs and remembers which tab was active. Switching workspaces swaps the complete tab strip, while a one-workspace session adds no extra chrome.

TaskShortcut or control
Create a workspaceCtrl+Shift+Enter or the rail's + slot
Open the workspace pickerCtrl+Shift+G
Switch to the next workspaceCtrl+Shift+PageDown
Switch to the previous workspaceCtrl+Shift+PageUp
Duplicate a workspaceCtrl+Shift+Alt+D or Duplicate Workspace

The vertical workspace rail appears when a second workspace exists. Its + slot rests at a visible brightness, and a dead gap row above it prevents clicks past the last workspace from opening one accidentally. A static edge dot rolls up unseen activity from that workspace's tabs; it coexists with the independent remote-binding marker and uses no motion effect.

An always-visible chevron at the rail's bottom edge toggles auto-hide and saves the choice. The same control remains available while an auto-hidden rail is temporarily revealed, so it can be pinned again without opening Settings.

Drag the rail's inner edge to adjust its width.

workspace_rail valueRail placement
autoReveals the rail after a second workspace exists; this is the default
alwaysPins the rail even with one workspace
leftPins the rail on the left
rightPins the rail on the right

Drag a rail slot to reorder workspaces. A bright rule marks the destination; release drops the slot, while Esc cancels without changing the order.

A short press that stays below the drag threshold remains a normal workspace switch. Auto-hide keeps the rail revealed throughout a drag, and the shared pointer path behaves the same on Linux, Windows, and macOS.

The workspace menu offers Move Up and Move Down as a non-drag reorder path with no bindable chord. It also offers New, Duplicate, Rename, Close Workspace, Bind to Host…, Unbind from Host, and Settings.

Either reorder path follows the active workspace by identity, so focus does not change, and the order persists across restart. Rename edits the label in place.

Binding a workspace routes its future tabs to the chosen saved host without changing existing tabs. The terminal content menu exposes the same New, Rename, Close Workspace, and Bind or Unbind actions for the active workspace.

Duplicating a workspace starts a fresh workspace whose first shell uses the active pane's working directory. Like Duplicate Tab, it creates a new shell rather than cloning scrollback or the running program.

The working-directory path is shared by New Tab, Duplicate Tab, and Duplicate Workspace. It behaves consistently on Linux, macOS, and Windows, where ConPTY honors the selected directory.

Close Workspaces And Handle Shell Exit

Closing the last tab in a workspace closes that workspace. Closing the last workspace quits the app.

Typing exit or pressing Ctrl+D follows shell_exit_closes:

ValueBehavior
workspaceFollows the normal tab-to-workspace-to-app cascade; this is the default
appQuits OdyTTY whenever the exit would close a workspace

The app value pairs with Restore workspaces when the entire saved shape should reopen on the next launch.

For a short-lived initial local command, launch with --hold, --hold=true, or --hold=false. Hold is off by default. When enabled, the exited pane reports its numeric exit status, or an explicit unknown/ possible-signal result, and remains until the next keypress. Dismissal follows the same pane-to-tab-to-workspace-to-app cascade above. Later sessions do not inherit hold, and a dropped remote session still shows its reconnect prompt first.

Restore Workspaces And Open Layouts

Turn on restore_workspaces in Settings → Sessions or with ODYTTY_RESTORE_WORKSPACES to reopen the previous window shape. It is off by default.

Launching odytty with no arguments restores the primary instance's workspaces, tabs, pane splits, and each pane's recorded working directory. Any command-line argument suppresses restore.

On Unix, OdyTTY validates its final state-directory leaves as owner-private, non-symlink directories and uses owner-private regular files for layouts, snapshots, and diagnostics. State JSON is written through a private temporary sibling and atomic rename. Existing direct layout JSON files are the only entries migrated; unknown children are left untouched. A failed validation disables the affected disk sink instead of following or repairing an unexpected object. macOS preserves inherited ACL entries while tightening mode bits; Windows retains its inherited-ACL behavior.

A second window leaves restore ownership with the first and shows this notice:

Another OdyTTY window owns session restore — this window won't restore or autosave workspaces.

The snapshot records structure only. It never saves terminal output, scrollback, environment, or the commands that were running. A plain local pane therefore restores as a fresh shell at its captured directory; the live-host and remote reconnect paths below do not re-execute captured commands.

A restored remote pane reconnects through the same ssh path and opens a fresh remote login shell at the host's default directory. It does not re-enter the recorded remote directory or restart anything that was running.

If a remote host no longer resolves, OdyTTY opens a local shell instead. If a local directory has vanished or denies access, OdyTTY retries at the home directory; snapshots from before remote restore support also reopen those panes locally.

On Unix, a restored or instantiated pane reattaches when its detached session host is still alive. A dead host silently opens a fresh shell and OdyTTY shows a compact "N of M sessions reattached" notice.

Restore and named layouts use %LOCALAPPDATA% on Windows. Session-host reattachment is Unix-only, so Windows restores always open fresh shells.

Save And Reopen Named Layouts

A named layout can capture either the whole app or one workspace:

ScopeSave paths
Every workspace, tab, split, directory, and host bindingSave as Layout… in the content, rail-slot, or empty-rail menu; Save All Workspaces as Layout in the command palette
One clicked or active workspaceSave Workspace as Layout… in a rail-slot or content menu; Save Workspace as Layout in the command palette

Reusing a layout name prompts to replace the existing layout, choose another name, or cancel.

Open Open Layout from the command palette, or Open Layout… from the empty rail, empty tab strip, or content menu. When the current window already contains real state, choose how to apply it:

ChoiceResult
ReplaceTears down the current workspaces and installs the saved set
AddAppends the saved workspaces beside the current ones
CancelLeaves the window untouched

A fresh window with one untouched default workspace skips this prompt and replaces that placeholder. When no layouts exist, the picker explains how to create one.

Open Local Tools

ShortcutAction
Ctrl+Shift+FSearch scrollback
Ctrl+Shift+,Open Settings
Ctrl+Shift+HOpen the theme picker
Ctrl+Shift+BOpen the theme builder
Ctrl+Shift+POpen the command palette
Ctrl+Shift+SOpen the connection manager
Ctrl+Shift+ROpen session replay
Ctrl+Shift+AOpen the Session Navigator (detached sessions Unix-only)
Ctrl+Shift+C / Ctrl+Shift+VCopy or paste
Shift+PageUp / Shift+PageDownScroll the local viewport
Ctrl+Shift+LOpen keyboard quick-select hints
Ctrl+Shift+SpaceEnter keyboard copy mode
Ctrl+Shift+Up / Ctrl+Shift+DownJump to the previous or next prompt mark
Ctrl+Shift+KClear the current shell input line (sends readline Ctrl+A, Ctrl+K; no shell integration required)
Delete / BackspaceDelete selected editable prompt input when shell integration allows it

The command palette, connection manager, session replay, theme builder, and Manage Sessions each have a discoverable menu entry and a default Ctrl+Shift+<letter> shortcut. A TUI cannot receive those chords, so PTY input is unchanged.

Launcher actions appear in the content menu, while Settings → Themes includes an Open Theme Builder entry. The command palette also carries Create Theme From Current Colors, which captures the focused pane's live dynamic-color state into a theme draft and opens the builder on it; inside the builder, C does the same for the draft already being edited. See themes.md for what is captured versus derived.

Prompt navigation uses Ctrl+Shift+Up and Ctrl+Shift+Down. Rebind any local action through Settings → Input, in the Key bindings row, or keybinds:

keybinds = ctrl+alt+p=command-palette

Shell Integration

Enable Prompt-Aware Actions

OSC 133 prompt marks enable prompt jumps, deleting selected editable prompt input, command-status gutters, click-to-position support when the shell advertises it, and verified command-output actions.

Shell integration is on by default. Newly spawned local bash, zsh, and fish shells load OdyTTY's wrapper after their normal shell config; the wrapper only adds prompt-mark hooks and never edits your rc files. Set shell_integration = off in Settings or odytty.conf to disable it, in which case OdyTTY still parses marks a shell emits on its own but injects no hooks.

Existing shells do not change until restarted. Bash uses an interactive --rcfile, so login-shell-only startup files remain the shell's responsibility.

Windows shellIntegration behavior
powershell / pwshLoads an OdyTTY PowerShell profile through -NoExit -Command; PSReadLine drives the command-start mark
cmd.exeUnsupported because it has no OSC 133 hook surface

The single switch means different things per shell, so the Settings section lists what each one delivers rather than implying a uniform capability:

ShellWhat the switch delivers
bashPrompt marks, cwd, click-to-position, button emitters; optional prompt key enhancement
zshThe bash set plus per-keystroke edit-region reports; optional prompt key enhancement
fishPrompt marks, cwd, edit region, click-to-position, button emitters; fish 4+ drives the keyboard protocol itself
powershell / pwshWindows only: prompt marks, cwd, click-to-position, button emitters; key bindings use the PSReadLine/Console API, not a VT protocol
nushellConfigure natively: set $env.config.shell_integration.osc133/osc7/osc2 and use_kitty_protocol in your nushell config; OdyTTY injects nothing

Command-Output Actions

The command palette and terminal context menu expose these actions when the current selection is wholly inside a complete OSC 133 command range, or for the latest complete command when no selection exists:

ActionResult
Select Command OutputSelect visible output only
Select Command With PromptSelect the prompt, command line, and visible output
Copy Command OutputCopy visible output only
Copy Command With PromptCopy the prompt, command line, and visible output
Search Command OutputOpen search restricted to that output range
Jump To Previous/Next Failed CommandNavigate only explicit nonzero OSC 133 exit statuses
Export Command OutputChoose a native save destination and write bounded plain text

Each range-targeting action revalidates an opaque, generation-bound handle against the live grid; failed-command navigation derives only from the current verified range set. Missing, partial, malformed, evicted, reset, reflowed, or otherwise stale marks disable the action instead of deriving a range from terminal text. Alternate-screen content has no command-output actions.

Export has a 32 MiB UTF-8 cap and never exports control sequences, OSC metadata, hyperlink targets, inline-image payloads, or private cwd metadata. The native dialog uses an application-owned neutral filename; terminal output cannot choose a path. Cancellation writes nothing. The writer leaves the selected parent directory untouched, refuses final symlinks or Windows reparse points, and uses private atomic replacement. Linux uses the XDG portal on both Wayland and X11; macOS and Windows use their native dialog implementations.

Notifications And Pane Monitors

OSC 9 and OSC 777 requests produce bounded, pane-owned attention state. OSC 9;4 produces typed progress with a bounded lifetime. Terminal-authored text is never copied into trusted OdyTTY or desktop-notification chrome; generic application wording is used instead. The command palette provides one-shot command-finish, activity, silence, bell, process-finish, and command-failure monitors plus an explicit clear action. See notifications.md for exact sequences, caps, policy, and independent platform behavior.

Integration applies only to shells OdyTTY launches. Nested shells, sudo, and exec-swaps are not covered; fish survives a plain nested launch through XDG_DATA_DIRS, and SSH tabs keep the bash bootstrap.

All four injected shell snippets percent-encode OSC 7 working-directory paths, including non-ASCII names. The Bash encoder and prompt hooks are compatible with the Bash 3.2 that ships on older macOS systems.

Prompt Key Enhancement (bash/zsh)

Set shell_key_enhancement = on (with shell_integration on) to make modified keys reachable at the bash and zsh prompt. While the prompt is active the shell enables the Kitty keyboard protocol in disambiguate mode, then turns it off before each command runs so the programs the shell launches see the terminal's default keyboard mode. Modified keys such as Ctrl+Enter, Shift+Enter, and Ctrl+Backspace then arrive as distinct escape sequences you can bind:

# bash (~/.inputrc)
"\e[13;5u": "run-this-command\n"   # Ctrl+Enter

# zsh (~/.zshrc)
bindkey '^[[13;5u' accept-line     # Ctrl+Enter

When the knob is on, the integration also ships default bindings so the keys do something out of the box: Ctrl+Backspace deletes the previous word, Shift+Enter inserts a literal newline for multi-line edits, and Ctrl+Enter submits the line. Each default is skipped when you have already bound the sequence — your ~/.bashrc/~/.inputrc and ~/.zshrc are read before the integration, so a personal rebind always wins. To override afterwards, rebind the sequence with bind/bindkey (for example bind '"\e[127;5u": kill-whole-line').

fish manages the protocol itself (use bind ctrl-enter ...), and PowerShell key bindings use Set-PSReadLineKeyHandler through the Console API, so neither needs this knob.

Off by default, and the reason is a correctness boundary rather than taste. Kitty keyboard flag 0x1 is defined to re-encode every Ctrl+key as a CSI-u sequence — the protocol specification states that with disambiguation on, Ctrl+C no longer generates SIGINT and is delivered as an escape code instead. OdyTTY implements that faithfully, so for as long as the flag is set the terminal emits no 0x03, the tty line discipline never sees an INTR byte, and no interrupt is raised. Ctrl+D (0x04, EOF) and Ctrl+Z (0x1a, SIGTSTP) go the same way.

That is survivable only for a line editor that speaks CSI-u, and neither readline nor ZLE does out of the box — unbound CSI-u arrives at the prompt as literal text. Zsh can at least be taught to recover, because send-break is bindable:

bindkey '^[[99;5u' send-break     # Ctrl+C

Readline has no equivalent: it exposes no function that raises SIGINT, so Bash has no route back to a working Ctrl+C while the flag is set. Turning this on is a deliberate trade — three enhanced binds in exchange for hand-binding every Ctrl+key your prompt still needs.

Bash 4.4 and newer remove the prompt-only disambiguation flag through PS0 after readline accepts a command and before it runs. Bash 3.2 and other older versions do not expand PS0, so the wrapper uses a prompt-guarded first-real- command DEBUG boundary instead. Both paths remove the flag before child programs run and preserve existing scalar or array-valued PROMPT_COMMAND hooks.

The command-status gutter is on by default. Each visible pane derives its own thin green or red bar from completed OSC 133 command marks, its own scrollback viewport, and its pane origin. Bash status capture spans existing PROMPT_COMMAND helpers, while PowerShell preserves native exit codes and maps a failed cmdlet with no nonzero $LASTEXITCODE to failure. Turning command_status_gutter off leaves the margin untouched without disabling the underlying prompt marks.

For manual setup, SSH or login shells, or explicit rc management, print and source the integration:

eval "$(odytty shell-integration bash)"
eval "$(odytty shell-integration zsh)"
odytty shell-integration fish | source

Until prompt input marks are active, the content menu disables Cut and Delete for prompt input and shows an Enable shell integration in Settings hint. A plain Delete or Backspace with no selection still reaches the shell.

With a selection but no known prompt boundary, OdyTTY does not send blind edit bytes. It clears the stale selection and shows the same hint instead of risking a corrupted command line.

Search Actions, History, And Directories

The command palette fuzzy-filters local actions, bounded read-only shell history, and recent OSC 7 directories. A history or directory choice types its text into the active pane without pressing Enter; an action runs after the overlay closes.

Use an environment override for one session:

ODYTTY_KEYBINDS="ctrl+alt+p=command-palette" odytty

Environment values win for that session.

Replay Recent Output

Session replay is the session-replay action, bound to Ctrl+Shift+R. Recording is off by default, so enable session_replay before opening the scrub overlay:

session_replay = on
keybinds = ctrl+alt+r=session-replay

For a one-session override:

ODYTTY_SESSION_REPLAY=on ODYTTY_KEYBINDS="ctrl+alt+r=session-replay" odytty

The local-only ring never touches disk or the network. It is capped at 600 frames or 24 MiB, whichever limit is reached first.

The overlay is presentation-only while the live session continues underneath. Use or to step, PgUp or PgDn to jump ten frames, and Home or End to move to either end.

Connect To Saved Or Ad-Hoc Hosts

The connection-manager action opens a type-to-filter host list with Ctrl+Shift+S. Rebind it if desired:

keybinds = ctrl+alt+h=connection-manager

For a one-session override:

ODYTTY_KEYBINDS="ctrl+alt+h=connection-manager" odytty

Hosts come from OdyTTY's hosts.conf. When ssh_config_hosts = on, the manager also shows name-only entries from the OpenSSH config; while it is off, OdyTTY does not reference ~/.ssh.

The manager is presentation-only. Selecting a host starts the system ssh client in a new session.

Connect without saving. Type a valid [user@]host[:port] that matches no saved host. The Connect to: … row connects with Enter, while Shift+Enter or Ctrl+S connects and atomically appends a matching Host block to hosts.conf.

Existing contents are preserved. If the alias already exists, OdyTTY connects and reports "already saved"; embedded spaces, a leading -, and out-of-range ports are rejected to prevent option injection.

Add or edit a host. Press Tab for a blank form, or the right arrow to edit the selected OdyTTY-owned host. OpenSSH-imported rows are read-only.

Form areaFields and behavior
ConnectionAlias, host, user, and port
IdentityIdentityFile path, passed to ssh with -i; it is a path, never a stored secret
OverridesIntegration, Reuse, and Tmux, each set to inherit, on, or off
AppearanceTheme, font, and title

Saving appends a new block or edits the existing block in place while preserving every other block, comment, and unknown field byte-for-byte. ssh-copy-id remains the once-only path away from password prompts.

Test a host. The form runs a non-interactive background probe and reports one of four honest results: reachable with key-based authentication, reachable but requiring interactive authentication, host-key mismatch, or unreachable. OdyTTY never handles a password, and normal connection still works for an interactive-auth host.

Connection-launch and probe-start failures are shown in the pane or form rather than leaving a selection with no visible result.

Use the host-row menu. Right-click a row for Open in New Tab, Open in New Workspace, or Bind Current Workspace. A new host workspace is pre-bound so its later tabs use that host too.

OdyTTY-owned rows also offer Edit… and confirmed Remove… actions. Imported OpenSSH rows hide both actions, and dismissing the menu preserves the manager's selection.

Control Remote Sessions

Saved hosts support these connection behaviors:

SettingDefaultBehavior
remote_integrationonSends a temporary bash-only integration wrapper and opens an interactive shell against it
remote_reuseonReuses a shared ControlMaster connection for later tabs to the same effective SSH endpoint
remote_persist10 minutesKeeps the master socket alive after the last tab closes
remote_tmuxoffWraps the remote shell in a persistent tmux session named odytty

The integration wrapper writes a temporary remote rcfile and persists nothing on the host. A non-bash shell or any bootstrap failure falls back to plain ssh, and the tab title becomes user@host.

The tmux behavior is equivalent to:

tmux new-session -A -s odytty

Each saved host can override Integration, Reuse, and Tmux in hosts.conf. Connection reuse is available on Unix clients; Windows clients authenticate each connection independently through ssh.exe. Unix socket names use OpenSSH's %C hash of the effective host, port, and user, keeping different endpoints isolated while preserving a fixed-width path.

When a remote connection drops, the tab stays open with a reconnect prompt. Enter reconnects in place, while Esc or Ctrl+D closes the tab.

Paste Images Into Remote Sessions

Pasting a clipboard image into an integrated remote tab follows remote_image_paste, which defaults to ask. OdyTTY first shows this confirmation in the pane:

upload image to user@host? Enter: upload · Esc: cancel

Only Enter starts the transfer. The image streams over the authenticated ssh connection, reusing ControlMaster when available, into an unguessable 0600 file under /tmp.

Nothing executes remotely, and files above 10 MiB are refused. After a successful upload, OdyTTY shows image uploaded <path> · copied to clipboard, copies the remote path to the local clipboard, and does not type it into the shell.

Paste the copied path with Ctrl+Shift+V where it belongs as a command argument. Uploaded files are cleaned up best-effort when the tab closes, and the path works for reconnected and restored remote tabs.

Manage Detached Sessions

On Unix, detached sessions can be managed inside the window as well as from the CLI. The session-attach action, Ctrl+Shift+A, and Manage Sessions all open the Session Navigator, whose rows include the live detached-session registry alongside workspaces, tabs, and panes (see v0.14.0-session-navigator.md). Choosing an already-open session switches to its tab; another session prompts for New tab or Replace. Stale or errored registry entries show session unavailable and cannot be attached.

Press X on a detached session to kill it after confirmation. Detach & switch gives the focused pane's working directory to a fresh managed session.

Attaching reconnects the live PTY and terminal model. The session host keeps both alive through detach and attach cycles until the child exits or the idle timeout reaps it.

Snapshot format v3 preserves G0/G1 character-set designation and SO/SI selection, so an ACS box-drawing run survives reattach. Older v1 and v2 snapshots remain readable and restore the power-on ASCII character-set state.

On Windows, the Session Navigator lists live local and integrated SSH panes only; detached sessions and attach stay unavailable until a Windows detached session-host surface exists.

Open Interactive Paths

Interactive paths are off by default through interactive_paths. When enabled, Ctrl+click on Linux/Windows or Cmd+click on macOS opens a detected path: text files open in the configured editor with line:col positioning, while png, jpg, jpeg, and webp files open in an in-app lightbox.

Dismiss the lightbox with Esc or a click outside. A click hint and the path menu expose Open, Open With…, Copy Path, Copy File, and Reveal in File Manager.

Path detection currently recognizes POSIX path shapes (/, ~/, ./, ../). Windows drive-absolute (C:\, C:/), UNC (\\server\share), and backslash-relative paths are also recognized. Drive-relative forms such as C:folder are deliberately not detected because their meaning depends on per-drive process state.

Opening uses xdg-open on Linux, open on macOS, or explorer on Windows, each with a scheme allowlist. OdyTTY passes the target as a single argument and never interpolates a path into a shell command line.

Rebind Local Actions

The keybinds setting and ODYTTY_KEYBINDS override local actions:

ScopeActions
Globalsearch, settings, theme-picker, theme-builder, copy, paste, scroll-up, scroll-down, jump-prompt-prev, jump-prompt-next, select-command-output, select-command-with-prompt, copy-command-output, copy-command-with-prompt, search-command-output, jump-failed-command-prev, jump-failed-command-next, export-command-output, copy-mode, hints, clear-input, command-palette, session-replay, connection-manager, session-attach, new-tab, new-window, next-tab, prev-tab, close-tab, and duplicate-tab
Workspacenew-workspace, duplicate-workspace, close-workspace, rename-workspace, next-workspace, prev-workspace, and workspace-picker
Panesplit-columns, split-rows, focus-pane-left, focus-pane-right, focus-pane-up, focus-pane-down, focus-pane-next, close-pane, zoom-pane, and equalize-panes

For pane actions, the binding is the key pressed after the prefix:

keybinds = ctrl+f=zoom-pane

See Keybindings for every default chord, the pane prefix, copy mode, hints, overlay navigation, and rebinding.

Settings And Themes

Use Configuring OdyTTY for the in-app settings workflow. This section covers theme selection, background images, and transparency.

Cursor Presentation

Fresh profiles use a blinking Block cursor with cursor slide, trail, blink fade, and the restrained shape-aware glow enabled. Nearby eligible moves glide while the logical cursor and input remain immediate. Stable jumps beyond the six-cell glide range use the selected cursor_trail_strength presentation profile (balanced by default): one cursor-shaped follower stretches into the destination without delaying terminal state or input.

Keyboard and IME activity keep a requested blinking cursor visible; blinking resumes after a short quiet period and parks visibly on after prolonged idle. In an unfocused window, a Block cursor becomes a hollow outline while Bar and Underline keep their normal forms. Cursor motion, trail, glow, easing, and follower presentation advance only in the focused pane of a split, where they stay clipped and do not wake idle panes.

The aura follows the active Block, Bar, or Underline geometry without changing terminal state or input behavior. Its strength is adjustable through cursor_glow_intensity on a 0.0..=1.0 scale, independent of the whole-scene bloom: 0.0 removes the aura while leaving the glow toggle on, the default is a restrained peak, and higher values stay bounded so text remains readable. Each presentation control remains independently configurable in Settings or Runtime Knobs; reduced_motion = on makes slide, trail, glow, easing, and new-output fade static or instant while preserving their saved choices.

Follow The Desktop Theme

Set theme = system or ODYTTY_THEME=system to follow the desktop dark or light preference. The default mapping uses odyssey-classic for dark mode and odyssey-light for light mode.

Use follow_os_theme, os_theme_dark, and os_theme_light to choose custom mappings.

Change Or Disable The Background Image

Since v0.6.0, OdyTTY ships its OdysseyOS visual identity enabled by default. The odyssey-default theme is a deep forest-green palette and is also available through the odyssey-jungle alias.

The original "Dark Waves" image is bundled into the binary and shown behind the grid. It works without an external file in source builds, AppImages, and distro packages, and carries the repository license described in assets/backgrounds/LICENSE.

Draw only the theme background:

background_treatment = color

Alternatively, keep image treatment available without selecting an image:

background_image = none

Choose a custom image instead:

background_treatment = image
background_image = /path/to/your/wallpaper.png
background_image_scrim = 0.5

PNG, JPEG, and WebP images are supported. background_image_scrim ranges from 0 for no scrim to 1 for an opaque scrim, while auto selects a floor-safe value. Any image, bundled or custom, is resampled to the window before it reaches the GPU, so a large wallpaper costs what the window displays rather than what the file contains.

background_image = default, including the unset state, selects the bundled image again.

Make The Window Transparent

Window transparency lets the desktop show through the terminal background. Text, the cursor, menus, pickers, and the settings panel remain fully opaque, so only the background fades. The selection is fully opaque by default (selection_opacity = 1.0), tuned by its own strength control (selection_opacity, below) independent of the window opacity.

Transparency is on by default at window_opacity = 80, so the desktop shows through the background a little out of the box. Where the display server offers no alpha compositing the window simply presents opaque. Turn it off, or set a fully-opaque look, from Settings → Rendering or in odytty.conf:

window_transparency = off
# or keep it on and go fully opaque, which matches the opaque render path:
window_opacity = 100

selection_opacity tunes the text-selection highlight strength on its own axis, from 0.0 (invisible) through 1.5 (strongest), independent of window_opacity, the theme colours, and min_contrast. The default 1.0 is the authored fully opaque selection. Below 1.0 is a translucent tint that reads as a highlight rather than a solid block yet stays clearly visible over a transparent or busy backdrop, because a selected cell's surface alpha is lifted toward opaque as the knob rises so the selection never falls weaker than the surrounding content. Above 1.0 the surface stays fully opaque and the highlight colour is pushed stronger along the backdrop-to-selection vector, bounded and in gamut. Text under the selection stays legible through the minimum-contrast floor.

window_opacity is a percentage from 20 through 100 in steps of 5, with 100 fully opaque.

Two controls keep content readable as the window grows more transparent. colored_bg_opacity (default 0.9) holds a minimum background strength for cells whose colour differs from the theme default, so colored blocks — prompt powerline segments, button chips, and highlighted status runs — stay solid while the plain background still lets the desktop through; 1.0 removes the window-opacity attenuation from those cells so they keep their full configured background opacity (literally opaque only where the cell background already is), 0.0 disables the floor, and it has no effect at window_opacity = 100. text_brightness (default 1.0) lifts glyph ink toward white so text stays legible over busy backdrops, applied after the minimum-contrast floor and leaving colour emoji unchanged. Both live in Settings → Rendering.

Wayland and macOS support compositing natively, X11 requires a compositor, and Windows uses DWM. In an environment without alpha compositing, the setting has no visible effect.

An open menu, picker, or settings panel remains the same themed, opaque surface in one-pane and split-pane tabs without making the whole window opaque. The terminal behind it continues to show the desktop.

A configured background image is part of the background layer. With transparency enabled, it also becomes translucent and composes over the desktop.

Further reference:

  • Named profiles documents the complete profile editor: launch, appearance, cursor, effects, layout, switching, and platform fields, including bounded add/edit/remove list rows.

  • Runtime Knobs lists every config key, environment variable, range, default, and reload behavior.

  • Annotated Config is a complete commented example.

  • Themes documents the theme format and built-in roster.

  • Effects covers bloom, CRT, retro, background, and motion effects.

  • Keybindings is the complete keyboard and rebinding reference.

  • Accessibility covers minimum contrast, color-vision modes, dimming, and the bell.