ExRatatui.Distributed (ExRatatui v0.10.0)

Copy Markdown View Source

Distribution-attach transport for ExRatatui.App.

Lets any connected BEAM node attach to a TUI running on a remote node. The remote node runs the app's mount/render/ handle_event callbacks and sends widget lists as BEAM terms over Erlang distribution. The local node renders those widgets on its own terminal and forwards input events back.

Quick start

On the app node (e.g. a Nerves device), add the Listener to your supervision tree:

children = [
  {MyApp.TUI, transport: :distributed}
]

On your local, connect and attach:

iex --sname mynode --cookie mycookie -S mix
iex> ExRatatui.Distributed.attach(:"app@nerves.local", MyApp.TUI)

The TUI takes over your terminal. Press the app's quit key (or Ctrl-C twice) to disconnect and restore the terminal.

How it works

  1. attach/2 connects to the remote node if not already connected.
  2. A local Client process initializes the terminal.
  3. An RPC call spawns a Server in :distributed_server mode on the remote node, pointing at the Client's pid — this process runs the app module and sends {:ex_ratatui_draw, widgets} messages directly to the Client over distribution.
  4. The Client starts monitoring the remote Server and polling input events, forwarding them as {:ex_ratatui_event, event} / {:ex_ratatui_resize, w, h}.
  5. When either side disconnects, monitors fire, both processes clean up, and the terminal is restored.

Authentication

Delegated entirely to the Erlang distribution cookie. If you can Node.connect/1, you can attach — same trust model as iex --remsh.

Summary

Functions

Attaches to a TUI app running on a remote node.

Functions

attach(node, mod, opts \\ [])

@spec attach(node(), module(), keyword()) :: :ok | {:error, term()}

Attaches to a TUI app running on a remote node.

Connects to node (if not already connected), starts a remote session for mod, and takes over the local terminal. Blocks until the session ends (app stops, remote node disconnects, or the local process is interrupted).

Options

  • :listener — the registered name of the Distributed.Listener on the remote node (default: ExRatatui.Distributed.Listener).
  • :poll_interval — local event polling interval in ms (default: 16).
  • :test_mode{width, height} for a headless test terminal. In this mode the local client does not poll the live terminal for input.
  • :image_protocol — terminal image protocol hint for the local terminal: one of :halfblocks (default behavior, also the safe fallback), :kitty, :sixel, :iterm2, or :auto (clears the hint). Drives how protocol: :auto images are rendered. Explicit protocol picks at ExRatatui.Image.new/2 are always honored.
  • :image_font_size{cell_width_px, cell_height_px} for the local terminal. When set alongside :image_protocol, the render path uses the supplied dimensions for Kitty / Sixel / iTerm2 scaling instead of ratatui-image's (8, 16) default. Pass values that match your terminal (typically (10, 20) for Kitty/Ghostty).

Returns :ok when the session ends normally, or {:error, reason}.