Add a native (pure-Rust) SSH path for daemon panes, replacing shell-out `ssh` for managed connections. A russh shell channel is bridged into the existing pane byte pipeline so it is indistinguishable from a local PTY: the reader thread, 8 MiB replay ring, OutputGate backpressure, and OSC 7/133 sniffer are reused unchanged. Only the handle-owning methods (resize→window-change, kill→channel close, foreground pgid→None) dispatch on a new PaneBackend seam. Engine (`src/daemon/ssh/`): - Per-daemon tokio runtime owning all russh connections; the rest of the daemon stays std-threads and crosses in via blocking Read/Write adapters over bounded/unbounded channels (backpressure reaches the SSH window). - Connection registry keyed by host/port/user/proxy/jump chain with reuse (new tab = new channel, no re-auth) and documented blast-radius semantics. - Transports: direct TCP, ProxyCommand (%h/%p/%r substituted), SOCKS5, HTTP CONNECT, and jump host via direct-tcpip (multi-level chains). - Auth (Tabby-ordered): none-probe, publickey (multi-identity, %h/%r, .pub-misconfig skip, encrypted-key passphrase), agent, password, keyboard-interactive (zero-prompt quirk, password auto-fill). - known_hosts: plaintext + hashed (HMAC-SHA1) + @revoked + @cert-authority skip; append preserves the file. Self-contained SHA-1/HMAC/base64. - Interactive prompt broker: AuthPrompt/AuthResponse/SshStatus over the pane's connection; blocks auth with a 120s per-prompt timeout. Protocol (`daemon::protocol`): - New kinds: SPAWN_NATIVE_SSH(14), AUTH_RESPONSE(15) client->daemon; AUTH_PROMPT(13), SSH_STATUS(14) daemon->client. New kind so a pre-WS2 daemon rejects rather than mis-spawns. - NativeSshSpec wire type (redacted Debug + without_secrets), prompt/host-key enums, RemoteKind::NativeSsh. Session restore: `SessionPane::Leaf.ssh_spec` (secret-free) so a dead native pane can be respawned by WS6; live panes reattach for free. Docs: `docs/ssh-native-architecture.md` (protocol, broker flow, the connection-registry API WS4/WS5 use, and the forwards/X11/SFTP seams). Tests: known_hosts parse/check/append, spec serde + redacted Debug, ProxyCommand %h/%p substitution, blocking adapter EOF + backpressure, connection-key identity, prompt-broker delivery/cancel. Full suite green.
tty7
A GPU-rendered terminal in pure Rust.
GPU rendering on Zed's gpui · VT core from Alacritty
Why tty7 · Install · Features · Benchmarks · Keybindings
English · 简体中文
Why tty7
- Fast — about 2× the throughput of Alacritty, Ghostty, or Kitty on the same hardware (benchmarks)
- A modern prompt — completion, syntax highlighting, and history search built in; no plugins to assemble
- Sessions that survive — close the window or quit the app, your shells keep running; no tmux
- Zero config — zsh, bash, fish, and PowerShell work out of the box
Native builds for macOS, Windows, and Linux ship with every release.
Install
Download the build for your platform from Releases:
- macOS —
tty7-<version>-macos-arm64.dmg(Apple Silicon) or…-x86_64.dmg(Intel); open it and dragtty7.appinto Applications. - Windows —
…-windows-x86_64-setup.exe(installer: Start Menu shortcut + uninstall entry), or…-windows-x86_64.zip(portable: unzip and runtty7.exe). - Linux —
…-linux-x86_64.AppImage(recommended: bundles the x11/wayland libraries, so it runs on Fedora / Arch / etc. with no extra packages —chmod +xand run), or…-linux-x86_64.tar.gz(bare binary; extract and run./tty7, needs the usual x11/wayland runtime libraries installed).
Features
At the prompt
- Ghost suggestions — your history completes the whole line as you type; → to accept
- Tab completion that explains — every flag and subcommand with its description, for ~100 common commands
- Syntax highlighting — as you type, nothing to install
- Fuzzy history search — ⌃ R shows what you ran, where, and whether it failed
- History from day one — your existing shell history just works, and carries across sessions
- Real line editing — selection, word motion, undo
In the window
- Tabs & splits — always open in the current directory
- Command palette ⌘ P · scrollback search ⌘ F
- ⌘-click links · desktop notifications
- Eight themes · CJK / IME input
Benchmarks
All four terminals measured back-to-back on the same machine, same day, same 155×40 grid — Apple M1 Pro, macOS 26.3.1, five-run averages (2026-07-04):
| tty7 | Alacritty | Ghostty | Kitty | |
|---|---|---|---|---|
Plaintext IO — 11 MB cat (lower = better) |
95 ms | 239 ms | 179 ms | 185 ms |
| DOOM-fire frame rate (higher = better) | 888 fps | 485 fps | 552 fps | 617 fps |
| Cold-launch memory | 116 MB¹ | 105 MB | 128 MB | 130 MB |
¹ GUI 105 MB + the persistent daemon 11 MB.
Where the speed comes from:
- The PTY is read at device speed and parsed in large batches, off the render path
- Hot paths are lock-free — a big
catnever waits on drawing - The daemon buffers up to 16 MiB ahead of the window before backpressure applies
Methodology (how each terminal is driven, grid fairness, known pitfalls) and
one-command reproduction live in scripts/bench/ —
run it yourself.
Keybindings
Keys are shown in macOS notation — on Windows and Linux, read ⌘ as Ctrl. Open Settings with ⌘ , to browse or remap them all. The essentials:
| ⌘ T · ⌘ W · ⌘ ⇧ T | new tab · close tab · reopen closed tab |
| ⌘ 1…⌘ 9 · ⌃ ⇥ · ⌃ ⇧ ⇥ | jump to tab 1–9 · next tab · previous tab |
| ⌘ D · ⌘ ⇧ D | split right · split down |
| ⌘ ] · ⌘ [ | next pane · previous pane |
| ⌘ ⌥ ←→↑↓ | focus the pane in that direction |
| ⌘ ⏎ · ⌘ ⇧ ⏎ | toggle fullscreen · maximize / restore the pane |
| ⌘ K | clear the screen and scrollback |
| ⌘ P | command palette |
| ⌘ F | search the scrollback |
| ⌃ R | fuzzy-search shell history |
| ⌘ + · ⌘ − · ⌘ 0 | font size up · down · reset |
Settings → Keybindings lists every shortcut. Click one, press the new keys
(Esc cancels, Backspace resets to default), and it takes
effect immediately. Pane resize and swap have no default keys — bind them here or
run them from the command palette. Prefer tmux muscle memory? Flip the tmux
preset to remap pane/tab actions onto a prefix (default ⌃ B): ⌃ B
C opens a tab, ⌃ B % splits, ⌃ B then an
arrow moves focus. A bare prefix reaches the shell after a brief pause, and
prefix + an unbound key is passed straight through to the terminal.
Built on gpui and alacritty_terminal · Apache-2.0 · Discord · Changelog