Skip to content

v0.6.1

Choose a tag to compare

@github-actions github-actions released this 09 Apr 16:44
· 252 commits to main since this release
v0.6.1
e5b5246

Fixed

  • SSH subsystem dispatchssh host -s Elixir.MyApp.TUI (and ExRatatui.SSH.subsystem/1 under nerves_ssh) would hang forever instead of rendering. The channel handler was waiting for a {:ssh_cm, _, {:subsystem, ...}} message inside handle_ssh_msg/2, but OTP :ssh consumes that request internally when it matches a name in the daemon's :subsystems config — the handler only ever receives {:ssh_channel_up, ...}. ExRatatui.SSH now detects subsystem-mode dispatch (via a new subsystem: true flag baked into the init args by subsystem/1 and ExRatatui.SSH.Daemon) and synthesizes a default 80x24 session + starts the TUI server directly from {:ssh_channel_up, ...}. Shell-mode startup (via ssh_cli) is unchanged — it still waits for pty_req + shell_req as before
  • SSH subsystem + -t pty_req races — when a client connects with ssh -t -s Elixir.MyApp.TUI, OTP fires ssh_channel_up first (we start an 80x24 session + server) and then delivers the client's pty_req with the real dimensions. The previous pty_req handler created a brand-new Session on every call, which left the SSH channel pointing at a session the running Server no longer rendered into. The handler now splits on session: nil vs session: %Session{} and resizes the existing session in place when one is already there, mirroring the window_change path
  • SSH subsystem pty-size discovery on nerves_ssh — even with the pty_req race fixed, a subsystem TUI riding on nerves_ssh (or any :ssh.daemon that configures a default CLI handler) would stay stuck at the hardcoded 80x24 fallback instead of filling the client's real terminal. Root cause: OTP :ssh_connection.handle_cli_msg/3 hands pty_req to the daemon's default CLI handler when the channel's user pid is still undefined, and then silently orphans that CLI handler the moment the subsequent subsystem request rebinds the pid to us — so the subsystem handler never sees pty_req on those deployments, no matter how early it arrives. ExRatatui.SSH now sidesteps the whole OTP path by emitting a Cursor Position Report roundtrip (ESC[s ESC[9999;9999H ESC[6n ESC[u) on {:ssh_channel_up, ...}: the client clamps the bogus cursor position to its real pty size, responds with ESC[<row>;<col>R, the session's ANSI input parser decodes that as a %ExRatatui.Event.Resize{}, and the {:data, ...} handler resizes the session in place + notifies the running server via {:ex_ratatui_resize, w, h}. Shell-mode startup is unaffected — it still reads the dimensions straight off pty_req
  • session_input.rs CPR parsing — the VTE-driven input parser now recognizes ESC[<row>;<col>R Cursor Position Report responses and emits them as NifEvent::Resize(col, row) so the SSH transport's CPR-based pty-size discovery has something to intercept. The handler runs before the simple-CSI dispatch that would otherwise silently drop any R final byte
  • SSH subsystem startup — added a shell-vs-subsystem section to ExRatatui.SSH's moduledoc and the guides/ssh_transport.md guide explaining which message triggers server boot in each mode, plus a loud "always pass -t" caveat (OpenSSH doesn't allocate a PTY for subsystem invocations by default, which leaves the client's local terminal in cooked mode — keystrokes get line-buffered and echoed locally on top of the TUI)