Elyra
Elyra The coding agent eTerm The terminal that knows where each command ends Starf An activity monitor for Apple silicon that never invents a number etrans An SSH and SFTP client for macOS Litr A small, native web browser for macOS Notr A notebook for macOS e The native code editor Elyra Grove Native local development environment Askr The real server for Laravel & PHP Elyra Framework Rust + Svelte 5 framework for desktop apps Elyra Conductor Local project conductor Refr Local-first PDF workspace for macOS Elyra Workspace A desktop workspace for coding agents Elyra SQL Server MySQL-compatible SQL server in Rust Elyra Félagi Agents as teammates on one board Elyra SQL Client Native desktop SQL workbench Elyra SQL Anywhere Replication-ready SQL engine Elyra Sjá SEO & GEO workspace for macOS Elyra DataGrid Server-driven data grid for Laravel
Release notes
Changelog
Elyra
Architecture

Architecture

etrans is two crates in one workspace.

etrans-core

Everything that is not drawing, and has no UI dependency:

Module
ssh Connecting: TCP or a tunnel through a jump host, the host key check, and the login (agent, keys, password, keyboard-interactive). Anything that needs a person is put to an Asker, and the connection waits for the answer.
known_hosts ~/.ssh/known_hosts read as OpenSSH reads it: patterns, negation, hashed names, @revoked and @cert-authority, and host certificates checked against it.
ssh_config The parts of ~/.ssh/config etrans uses.
sftp The remote filesystem over an SFTP channel.
local The local filesystem, listed the same way, plus keys in ~/.ssh and user and group names.
transfer The transfer queue: planning, copying with partial files and resume, retries, conflicts.
forward Local, remote and SOCKS5 forwarding.
shell An interactive shell in a pseudo-terminal.
site, settings, secrets, import, accounts Saved servers, settings, Keychain, importing, owners by name.
runtime The tokio runtime the SSH work runs on.

SSH and SFTP are russh and russh-sftp. russh needs tokio, and gpui has its own executor, so the two meet in runtime: work is spawned onto a runtime that lives for the whole process, and the caller gets back a plain future any executor can wait on. Dropping that future stops the work, which is how cancelling a connection really cancels it.

etrans

The app, on GPUI:

Module
browser The main window: connecting and reconnecting, the server list, dialogs, the right-click menu, the transfer drawer, port forwarding, Get Info, About and the update strip.
pane One file pane: listing, selection, navigation, drag and drop.
terminal A shell window: alacritty's emulator fed from the SSH channel, drawn cell by cell.
preferences Settings as the app holds them, and the Settings window.
update The updater: the feed, the download, the signature check and the swap.
text_input, ui, theme, actions, keys Text fields, shared controls, colours, actions and their keys, and keystrokes to terminal bytes.

Two things worth knowing

Questions from the background. A connection that meets an unknown host key, or needs a password, does not know about windows. It calls an Asker — a function from a Question to a future answer — and waits. The window turns the question into a sheet and sends the answer back over a oneshot channel. A reconnect wraps the asker in one that answers passwords typed earlier from memory.

Partial files are named for their source. A transfer writes .<name>.<size>-<mtime>.etrans-part beside the destination and renames it into place when it is whole. Resuming is looking for that exact name: if the source changed, the name changed, and the copy starts over instead of continuing a different file.