Skip to content

v0.8.1

Choose a tag to compare

@github-actions github-actions released this 27 Apr 09:17
· 141 commits to main since this release
v0.8.1
3b39f04

Added

  • Telemetry instrumentation (#56) — new ExRatatui.Telemetry module emits :telemetry events across the runtime so apps can plug in logging, metrics, or OpenTelemetry tracing without forking the server. Five span events (:start / :stop / :exception) wrap the costly stages: [:ex_ratatui, :runtime, :init] around mount/1, [:ex_ratatui, :runtime, :event] around terminal-input handle_event/2, [:ex_ratatui, :runtime, :update] around info-message handle_info/2 (subscriptions, async results, user messages), [:ex_ratatui, :render, :frame] around the build+draw cycle (adds :widget_count to stop metadata), and [:ex_ratatui, :transport, :connect] around local/SSH/distributed handshakes. Four single events fire for point-in-time facts: [:ex_ratatui, :session, :lifecycle, :open] when a session-backed runtime adopts a session (carries :width / :height), [:ex_ratatui, :session, :lifecycle, :close] when it releases the session (carries :reason; fires exactly once per session even when the transport's own teardown defensively closes the same ref afterwards), [:ex_ratatui, :render, :dropped] on draw errors (with a TODO placeholder for future frame-skip backpressure), and [:ex_ratatui, :transport, :disconnect] on server teardown. Every event carries :mod and :transport in its metadata. ExRatatui.Telemetry.span/3 is a thin helper that prefixes events with :ex_ratatui and forwards start metadata to stop; execute/3 does the same for single events and auto-adds :system_time. attach_default_logger/1 / detach_default_logger/0 ship a handler that logs every event at a configurable level. New Telemetry guide walks through the full event catalogue, a Telemetry.Metrics example, and an opentelemetry_telemetry wiring snippet. Added {:telemetry, "~> 1.0"} as an explicit dependency and to extra_applications so the handler registry is available on every node (including peers in distributed tests)
  • Transport behaviour — new ExRatatui.Transport module documents the protocol between the runtime server and the processes that carry I/O for a running ExRatatui.App. Declares the server_transport, writer_fn, and to_server typespecs, plus one optional child_spec/1 callback and a public start_server/1 entrypoint for custom transports to boot the runtime without depending on internal modules. ExRatatui.SSH, ExRatatui.SSH.Daemon, and ExRatatui.Distributed.Listener all adopt the behaviour. New ExRatatui.Transport.ByteStream helper packages the byte-pump pattern (forward_input/3, forward_resize/4) so any byte-oriented transport — SSH today, Kino/Livebook next, a custom TCP bridge — can plug in without reimplementing event dispatch or Resize absorption. ExRatatui.SSH now delegates to ByteStream instead of hand-rolling the loop. New Custom Transports guide walks through the contract and a working TCP example covering separation of acceptor and per-connection worker (so the listener survives across disconnects and serves concurrent clients), the alt-screen enter/leave sequences, runtime-server monitoring, and the raw-mode client requirement (stty raw -echo; nc …; stty sane) that plain TCP needs since it has no equivalent of SSH's PTY negotiation
  • Property-based test pass over the recently-added surface — five new files under test/ex_ratatui/property/ covering the modules introduced by the telemetry + transport-behaviour work, plus older surface that previously lacked sweeping coverage. session_input_property_test.exs proves ExRatatui.Session.feed_input/2's byte stitchability (splitting any byte stream at any boundary, including byte-by-byte, yields the same event sequence) along with shape invariants for printable bytes, bare ESC, and arrow keys. byte_stream_property_test.exs covers ExRatatui.Transport.ByteStream.forward_input/3's contract: no %Event.Resize{} ever leaks as a regular event, every parsed event is delivered in order, and forward_resize/4 always emits an :ex_ratatui_resize notification. bridge_property_test.exs covers Bridge.encode_commands!/1's list-level contract — length / order preservation, {map, map} shape, rect coordinate passthrough, and ArgumentError on malformed entries — across structurally simple widgets (Paragraph, Block, Clear, Gauge, Throbber). text_encode_property_test.exs covers Text.Encode.to_wire_text!/to_wire_line! line/span count and content preservation, alignment serialization, and per-line agreement between the two encoders. normalize_property_test.exs covers Subscription.normalize/1 and Command.normalize/1 idempotence, leaf-count preservation across nested batches, order preservation, and refusal of garbage shapes. The exhaustive per-widget validation property suite (one shape generator per widget × known-malformed shapes raising ArgumentError, ~22 widgets) is intentionally deferred — the structural invariants above are uniform across widgets, so the next pass is a per-widget effort rather than a generic one

Changed

  • Internal :ssh transport tag renamed to :session — the Server's internal transport tag always described "generic byte-stream session"; SSH just happened to be the first user. The new name makes room for other byte-stream transports (Kino, custom TCP) to share the same runtime without impersonating SSH. User-facing routing shorthand is untouched: {MyApp, transport: :ssh} still routes to SSH.Daemon. Affected surfaces: Runtime.snapshot/1 .transport now returns :session for byte-stream sessions (was :ssh); telemetry metadata %{transport: _} on [:runtime, :init], [:transport, :connect], etc. is now :session on byte-stream events; mount(opts)[:transport] is now :session for SSH apps (was :ssh). If your app branches on opts[:transport] to detect SSH specifically, switch to a different signal (you control the {MyApp, transport: :ssh} line in your own supervision tree)