Files
ELYTerminal/PRD.md
T

10 KiB
Raw Blame History

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.
  • Repo ELYTerminal on git.zacharyzhang.com, private until v0.1.1, public since. 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.
  • On Omarchy 4 (Linux), an Omarchy theme wears Omarchy's current theme and changes with each switch. It is the default where Omarchy runs; picking another theme stops following.

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.
  • Inside herdr, which keeps its panes' OSC 7, the session's folder is that of herdr's focused pane, read from herdr's socket while herdr's client runs in the foreground, on macOS and Linux.
  • 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 mode, Option as Alt on macOS, the kitty keyboard protocol as the program sets its flags. Keypad keys type their characters, as Ghostty's do with mode 1035 on by default.
  • 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, each by a button at its end of the title bar or by key, and keep their state in settings, so the window opens as it was left.
  • The title shows the active session's title, and no other text.
  • The pointer over the terminal is the arrow.
  • The title bar is transparent, as Ghostty's: the window's background, opacity and blur run under it, so it wears the terminal's color.
  • Every control in the title bar takes its own press on every platform, the window buttons Ely draws on Windows and Linux too.

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, centered below the title bar: 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.
  • Discard, which Ely's changes list draws on every unstaged and untracked row, asks first: an edit goes back to the index, a new file is deleted.
  • 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; on Windows and Linux, which have no menu bar, so does a gear in the title bar. Categories on the left, rows on the right, each side scrolling on its own, Ely's components. Changes apply at once to every session and save.

  • Appearance
    • Theme: a grid of previews; on Omarchy, the Omarchy theme first.
    • 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
    • Shell: a path; empty runs the login shell.
    • Start in: Home, or the active session's folder.
    • Scrollback lines.
    • Option as Alt: off, left, right, both (macOS only).
    • Copy on select.
    • Shortcuts: every shortcut, as this platform's keys, with a search.

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, Plasma 6.7 and Hyprland support. Hyprland honors it only while its own blur is on, which Omarchy 4.0.4 turns off.
  • 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. On Windows Ctrl-V pastes too, as in Windows Terminal.

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.

14. Icon and the macOS app

  • The icon is Ely, a girl with long pink hair, holding a terminal in front of her.
  • macOS: the icon on the rounded square macOS gives app icons. Windows and Linux: the figure alone, no ground, flat, as Papirus draws.
  • scripts/mac-app.sh builds ELYTerminal.app from a release build with its icon, signed ad hoc, or for a release with Developer ID and notarized, and a disk image holding it beside a link to Applications.

15. Release

  • A release on Gitea, tagged vVERSION, carries three builds: the macOS disk image (Apple silicon, signed with Developer ID and notarized), a Windows zip (x86_64) and a Linux tarball (x86_64).
  • The Windows executable carries the icon. The Linux tarball carries the icon and a desktop entry, and the window names itself after it, com.zacharyzhang.elyterminal, as the macOS bundle does.
  • Each build comes from its platform's script: scripts/mac-app.sh, scripts/windows-zip.ps1, scripts/linux-tar.sh. The macOS one runs on the signing runner, through the Release workflow.

Deferred

Splits, tabs inside a session, profiles, key rebinding, kitty graphics, sixel, OSC 133 prompt marks, session restore, push and pull, quick terminal.