# ELYTerminal PRD A terminal for macOS, Windows and Linux. Rust, GPUI, Ely components. It draws a terminal as well as Ghostty does, shows every setting on screen, and makes no noise. Chapters run in build order. `TASKS.md` follows them line by line. ## 1. Product - One window. Sessions on the left, the terminal in the middle, Git or Files on the right. - Every setting has a control in the settings window. No setting lives only in a file. - Silent: no sound, no bell, no notifications, no update checks, no telemetry, no tips, no onboarding. - Clean: no subtitle, no tagline, no logging options, no status bar, no badges that do not carry state. - Built-in themes, each shown as a small preview, Catppuccin among them. A theme colors the terminal and the chrome. - The window background blurs on macOS, Windows, Wayland and X11. ## 2. Foundation - One binary crate, `elyterminal`, edition 2024, Rust 1.95. - Ely from git.zacharyzhang.com by pinned rev. gpui, gpui_platform from crates.io `gpui-pre` at the exact version Ely pins. - `alacritty_terminal` 0.26 for the grid, the parser and the pseudo-terminal, as Ely uses it. - Logs through `log` to stderr, `RUST_LOG` sets the level. No log setting in the app. - CI on Gitea Actions: macOS builds, tests and lints; Ubuntu and Windows build and test. - Private repo `ELYTerminal` on git.zacharyzhang.com. No credential in any file or commit. ## 3. Settings model and storage - One JSON file, `settings.json`, in the platform config folder (`dirs::config_dir()/ELYTerminal`). - Every field has a default. A missing file means defaults. A missing field means its default. - A file that does not parse, or a value out of range, stops the start with an error naming the file and the field. The app never overwrites a file it could not read. - Writes go to a temp file in the same folder, then rename. One writer: the app's settings entity. - Fields: see chapter 10. ## 4. Themes - Built in: Ely Dark, Ely Light, Catppuccin Mocha, Catppuccin Macchiato, Catppuccin Frappé, Catppuccin Latte, Tokyo Night, Dracula, Nord, Gruvbox Dark, Rosé Pine, Solarized Light, One Light, Kanagawa Wave. - A theme holds background, foreground, cursor, cursor text, selection background and foreground, and the 16 ANSI colors. Values come from the theme's upstream files (iTerm2-Color-Schemes' Ghostty export, or Ely's palette). - A theme maps onto Ely's `Palette` through `Theme::set_palette`, so panels, inputs and lists wear the theme. - Dark mode: one theme, or a second theme for when the system is dark. ## 5. Terminal engine Ghostty is the bar for what the terminal does. ELYTerminal owns its engine on `alacritty_terminal`; Ely's `Terminal` is a gallery widget without mouse reporting, IME, kitty keys or style settings. - PTY: alacritty's `tty` and event loop. The pty is wrapped so its reader passes bytes through an OSC 7 scanner. The scanner reports the working directory. - Shell integration for zsh, bash, fish and PowerShell, injected at launch as Ghostty does: each prompt sends OSC 7 and a title. A shell without integration reports nothing, and the panels say so. - Grid: colors (named, 256, truecolor, OSC 4/10/11/12), bold, dim, italic, underline (single, double, curly, dotted, dashed), strikethrough, inverse, hidden, wide characters, combining marks. - Box drawing (U+2500–U+257F), block elements (U+2580–U+259F) and powerline shapes (U+E0B0–U+E0B7) painted as geometry, so lines and segments join across cells. - Fonts: JetBrains Mono by default, any installed font by choice; Nerd Font icons the font lacks come from a bundled Nerd Font. - Cursor: block, bar, underline, hollow block; blinking per setting and per DECSCUSR; hollow when the window is not focused. - Keys: xterm encoding with modifiers, application cursor and keypad modes, Option as Alt on macOS, the kitty keyboard protocol as the program sets its flags. - IME: marked text drawn at the cursor; committed text sent to the program. - Mouse: select by character, word (double press) and line (triple press); Shift extends; mouse reporting (X10, normal, button, any; SGR and UTF-8); wheel scrolls back, or reports, or sends arrows on the alternate screen. - Clipboard: copy, paste (bracketed when asked), copy on select per setting, OSC 52 writes. - Links: OSC 8 and plain URLs; Cmd-press (Ctrl-press off macOS) opens them. - Focus reporting, title (OSC 0/2), scrollback limit per setting, find in scrollback (Ely's `FindWidget`). - Bell: no sound. The session row marks it until the session is shown. ## 6. Main window and layout - Ely's `ColumnShell`: sessions column, terminal column, right column. The window opens with blur when the setting is on. - The sessions column and the right column toggle and keep their state in settings. - The title shows the active session's title. Nothing else in the title bar. ## 7. Sessions panel - A list of sessions. Each row: title, then the working directory, home as `~`. - New session (+ and Cmd-T), close (row's ×, Cmd-W), select (press, Cmd-1…9, Ctrl-Tab and Ctrl-Shift-Tab). - A session whose program ends closes its row. The last row closing closes the window. - A bell in a hidden session marks its row. ## 8. Right panel: Files - A switch at the top: Git, Files. - Files shows the active session's working directory as a tree, folders first, Git status colors on names. - Double press: a folder opens, a file opens in the system's default app. - It reloads when the session reports a new directory and at each prompt. ## 9. Right panel: Git - Through the `git` command line. No libgit2. - Shows the branch, staged and unstaged changes, a commit message field and Commit, and recent commits. - Stage and unstage a file. Press a file to see its diff in Ely's `DiffViewer`. - Outside a repository it says so. A failed git command shows its error. - It reloads at each prompt and on directory change. ## 10. Settings window Cmd-, opens it. Categories on the left, rows on the right, Ely's settings components. Changes apply at once to every session and save. - General - Shell: a path; empty runs the login shell. - Start in: Home, or the active session's folder. - Appearance - Theme: a grid of previews. - Separate dark theme: a switch; when on, a second grid for dark mode. - Font family: a list of installed fonts. Font size. Line height. Ligatures. - Cursor: style (block, bar, underline, hollow), blink, with a live preview. - Background opacity: a slider. Background blur: a switch. - Padding: horizontal and vertical. - Terminal - Scrollback lines. - Option as Alt: off, left, right, both (macOS only). - Copy on select. ## 11. Background blur - macOS: gpui's `WindowBackgroundAppearance::Blurred` (NSVisualEffectView). - Windows: gpui's `Blurred` (acrylic accent). - Wayland: gpui's `Blurred` speaks `org_kde_kwin_blur`; ELYTerminal adds `ext_background_effect_v1` on the window's surface, which GNOME 51 and Plasma 6.7 support. - X11: ELYTerminal sets `_KDE_NET_WM_BLUR_BEHIND_REGION` (CARDINAL, 32) on the window, as Ghostty does; removes it when blur turns off. - A compositor with neither protocol shows transparency without blur. The app logs which path it took. ## 12. Menus and shortcuts - macOS menu bar: ELYTerminal (Settings, Quit), Shell (New Session, Close Session), Edit (Copy, Paste, Select All, Find), View (Toggle Sessions, Toggle Right Panel, Bigger, Smaller, Reset Size), Window. - The same shortcuts on Windows and Linux with Ctrl-Shift for terminal-colliding keys. ## 13. Acceptance - Each chapter's tasks ticked in `TASKS.md` with a passing review in `tasks/reviews.md`. - `scripts/check.sh` passes: fmt, clippy with `-D warnings`, tests, no file over 500 lines. - CI green on macOS, Ubuntu and Windows. ## Deferred Splits, tabs inside a session, profiles, key rebinding, kitty graphics, sixel, OSC 133 prompt marks, session restore, push and pull, discard changes, quick terminal.