tui: copy chat to system clipboard via reading mode + selection fixes
Two ways to copy chat content out of the TUI now work:

1. In-app selection (Ctrl+C, OSC 52): _ChatItemView.render() now builds a
   selection-aware Content from the rich renderable instead of letting Static
   wrap a Panel into a non-selection-aware RichVisual — so the magenta
   drag-select highlight actually renders and get_selection returns clean,
   chrome-free text. rich Segment styles are converted to Textual Style
   (Style.from_rich_style) so the selection_style merge doesn't crash, and
   None segment styles are guarded. get_content_height is overridden to
   compute auto-height straight from the rich renderable; without it the
   width-keyed Content churned new Visual objects per width change and spread
   the layout-settling cascade across refreshes, leaving a deferred scroll_end
   at an intermediate max_scroll_y (chat no longer stuck to bottom). Theme
   defines screen-selection-background/foreground so the highlight is visible.

2. Reading mode (Ctrl+R) for terminals without OSC 52 (e.g. GNOME Console,
   TERM_PROGRAM=kgx, which silently ignores OSC 52 so Ctrl+C never reaches the
   OS clipboard). Toggling the app's reading-mode class hides the chrome around
   the chat (right status/todo column, input prompt, status bar, chat outer
   border) and re-renders every message without its Panel borders via the
   registry's new render_plain — so Shift+drag + Ctrl+Shift+C copies just the
   conversation text to the system clipboard. ContentRenderer.render_plain
   defaults to unwrapping Panel/Padding(Panel) to its body; assistant messages
   and plan_ready override it to raw Text(content) so rich Markdown doesn't
   re-wrap fenced code blocks in their own bordered Panels. ChatPanel tracks
   reading mode and re-renders visible widgets in place (scroll preserved);
   new streamed items pick up the mode on mount.

Help (/help) now lists keys and documents both copy paths.

Tests: render_plain parametrized across all item types, message renderer
plain tests, chat panel reading-mode toggle (borders off/on, scroll kept,
new items borderless), tui_app reading-mode chrome hide, plus the existing
selection suite. Full suite green (922 passed, 1 skipped).
1 parent cc44da9 commit 3406226aee6e7928ad4e0940946803ffdf3fa7f7
@Eugene Sukhodolskiy Eugene Sukhodolskiy authored 7 hours ago
Showing 12 changed files
View
clients/terminal/tui/commands/builtin.py
View
clients/terminal/tui/renderers/base.py
View
clients/terminal/tui/renderers/message.py
View
clients/terminal/tui/renderers/planning.py
View
clients/terminal/tui/renderers/registry.py
View
clients/terminal/tui/themes.py
View
clients/terminal/tui/tui_app.py
View
clients/terminal/tui/widgets/chat_panel.py
View
tests/clients/test_chat_panel.py
View
tests/clients/test_message_renderers.py
View
tests/clients/test_render_plain.py 0 → 100644
View
tests/clients/test_tui_app.py