MCPcopy Create free account
hub / github.com/NVIDIA-NeMo/Switchyard / ShellTUI

Class ShellTUI

switchyard/server/shell_tui.py:77–419  ·  view source on GitHub ↗

Run a child process in a PTY with a live footer drawn below it. The terminal is split into two regions via DECSTBM (scroll-region): * rows 1 … (total - footer_height): the child process's viewport. * rows (total - footer_height + 1) … total: redrawn by a background thread at ``re

Source from the content-addressed store, hash-verified

75
76
77class ShellTUI:
78 """Run a child process in a PTY with a live footer drawn below it.
79
80 The terminal is split into two regions via DECSTBM (scroll-region):
81
82 * rows 1 … (total - footer_height): the child process's viewport.
83 * rows (total - footer_height + 1) … total: redrawn by a background
84 thread at ``refresh_hz`` times per second.
85
86 The child inherits a PTY that reports a reduced row count so its own
87 TUI doesn't overlap the footer. SIGWINCH is forwarded to the child
88 and triggers an immediate footer repaint.
89
90 Parameters
91 ----------
92 command:
93 Argv for the child process (``[binary, *args]``).
94 footer_fn:
95 Called with the current terminal column width; returns a list of
96 ``(styled_line, visible_width)`` tuples, one per footer row.
97 footer_height:
98 Callable returning the number of rows reserved at the bottom of the
99 terminal. Called on every paint so the height can grow dynamically.
100 refresh_hz:
101 Footer repaint frequency in Hz.
102 env:
103 Optional dict of environment variable overrides merged on top of
104 ``os.environ`` before ``execvpe``. ``TERM`` is set to
105 ``xterm-256color`` if not already present.
106 """
107
108 def __init__(
109 self,
110 command: list[str],
111 footer_fn: Callable[[int], list[tuple[str, int]]],
112 footer_height: Callable[[], int] = lambda: 1,
113 refresh_hz: float = 2.0,
114 env: dict[str, str] | None = None,
115 ) -> None:
116 self.command = command
117 self.footer_fn = footer_fn
118 self._footer_height_fn: Callable[[], int] = footer_height
119 self.refresh_interval = 1.0 / refresh_hz
120 self._env = env
121 self._out_lock = threading.Lock()
122 self._stop = threading.Event()
123 self._master_fd: int | None = None
124 # Monotonic time of the most recent child-output write to stdout.
125 # Used by ``_maybe_paint_footer`` to debounce paints away from
126 # the middle of Ink's multi-write frame bursts. ``-inf`` so the
127 # very first paint (after startup, with no traffic yet) is not
128 # blocked.
129 self._last_activity_ts: float = float("-inf")
130 # Monotonic time of the most recent footer paint. Throttled by
131 # ``refresh_interval`` so we don't repaint at the polling rate.
132 self._last_paint_ts: float = float("-inf")
133 # Set by ``_on_winch`` (the SIGWINCH handler) and drained by the main
134 # loop, which calls ``_handle_winch`` to perform the deferred resize

Callers 4

_make_tuiFunction · 0.90

Calls

no outgoing calls

Tested by 1

_make_tuiFunction · 0.72