Skip to content

Add SSH backend and custom-backend row diff rendering#33

Open
laudney wants to merge 1 commit intopcharbon70:developfrom
mmonad:pr/ssh-backend-runtime
Open

Add SSH backend and custom-backend row diff rendering#33
laudney wants to merge 1 commit intopcharbon70:developfrom
mmonad:pr/ssh-backend-runtime

Conversation

@laudney
Copy link

@laudney laudney commented Feb 20, 2026

Summary

Adds a first-class SSH backend and a custom-backend rendering path in Runtime that is optimized for remote PTY sessions.

Why

Remote rendering over SSH has different failure modes than local raw TTY rendering:

  • stale row artifacts during view transitions
  • edge behavior at terminal boundaries
  • per-session isolation requirements for buffer management and runtime context

This PR introduces a dedicated backend and runtime path so SSH sessions are stable without regressing local raw/TTY behavior.

What changed

New backend

  • Added TermUI.Backend.SSH with:
    • alternate screen lifecycle
    • cursor visibility management
    • mouse mode toggles
    • resize support (update_size/3)
    • row-based draw strategy (clear touched rows, redraw left-to-right)
    • autowrap off/on lifecycle around session rendering
    • bottom-right edge guard to avoid terminal scroll artifacts

Runtime custom-backend support

  • Added custom-backend message handling (:ssh_input, :ssh_resize).
  • Added backend-specific resize handling (no Terminal singleton assumptions).
  • Added custom-backend row-diff extraction:
    • compute changed rows
    • redraw full changed rows (including spaces)
  • Added Buffer.fill/2 and optional runtime :background support for deterministic first-frame rendering.
  • Isolated custom backend cleanup behavior from local raw/TTY terminal restoration paths.
  • Ensured custom backends use unique BufferManager names to avoid cross-session collisions.

Tests

  • Added comprehensive unit tests for TermUI.Backend.SSH.
  • Added integration tests for runtime + SSH rendering behavior:
    • changed-row redraw on shrink updates
    • bottom-right edge behavior

Validation

  • mix test test/term_ui/backend/ssh_test.exs test/integration/ssh_runtime_rendering_test.exs

@pcharbon70
Copy link
Owner

I have no problem with adding an extra backend but wondering where the issue is coming from. I have tested (actually even developped) the library over SSH and tested all the examples with both OTP 28 (raw) and TTY backend with Iex. Can you give me some more context?

@laudney
Copy link
Author

laudney commented Mar 5, 2026

Thanks for the feedback! To clarify — this isn't about SSH-as-a-client not working. The existing Raw/TTY backends work fine when you SSH into a machine and run a TermUI app.

This PR targets a different scenario: hosting TermUI apps inside an OTP :ssh daemon, where the BEAM VM itself serves TUI sessions to connecting SSH clients. In that model:

  1. Session isolation — the current Runtime uses global singletons (PersistentTerms, BufferManager registered name, Logger handler) that would collide when multiple SSH clients connect simultaneously
  2. Cleanup safetyTerminal.restore(), stty sane, and :io.setopts(echo: true) target the local terminal, which doesn't exist in a daemon context
  3. Row-level diffing — full-row redraws are more robust over remote channels than cell-level diffs

If this use case isn't on the roadmap, happy to close — but the session isolation changes in the Runtime (unique BufferManager names, gating global state mutations) may be worth considering regardless.

@pcharbon70
Copy link
Owner

pcharbon70 commented Mar 9, 2026

Thanks for the explanation and this is definitely a good addition. The roadmap for v1 is not set in stone so this is a good addition now before the I start on the crazy idea for v2. I will merge this today when I have a few minutes to resolve the conflicts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants