From 7793f02aa27690f6b597840d826ca9d3a9397e5e Mon Sep 17 00:00:00 2001 From: shuki Date: Fri, 6 Mar 2026 01:44:37 +0200 Subject: [PATCH] Fix NoMatches crash: buffer writes until OperationLog is mounted The worker starts streaming output before the modal screen finishes composing. Buffer writes until on_mount fires, then flush. Co-Authored-By: Claude Opus 4.6 --- tui/widgets/operation_log.py | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/tui/widgets/operation_log.py b/tui/widgets/operation_log.py index d95124a..1b1176a 100644 --- a/tui/widgets/operation_log.py +++ b/tui/widgets/operation_log.py @@ -1,3 +1,5 @@ +import asyncio + from rich.text import Text from textual.app import ComposeResult from textual.screen import ModalScreen @@ -12,6 +14,8 @@ class OperationLog(ModalScreen[None]): def __init__(self, title: str = "Operation Output"): super().__init__() self._title = title + self._mounted_event = asyncio.Event() + self._buffer: list[str] = [] def compose(self) -> ComposeResult: with Vertical(id="op-log"): @@ -19,15 +23,32 @@ class OperationLog(ModalScreen[None]): yield RichLog(id="ol-log", wrap=True, highlight=True, markup=True) yield Button("Close", variant="primary", id="ol-close") + def on_mount(self) -> None: + # Flush any buffered writes + log = self.query_one("#ol-log", RichLog) + for text in self._buffer: + self._write_to_log(log, text) + self._buffer.clear() + self._mounted_event.set() + def on_button_pressed(self, event: Button.Pressed) -> None: self.dismiss(None) def action_close(self) -> None: self.dismiss(None) - def write(self, text: str) -> None: - log = self.query_one("#ol-log", RichLog) + def _write_to_log(self, log: RichLog, text: str) -> None: if "[" in text and "[/" in text: log.write(Text.from_markup(text)) else: log.write(text) + + def write(self, text: str) -> None: + if not self._mounted_event.is_set(): + self._buffer.append(text) + return + try: + log = self.query_one("#ol-log", RichLog) + self._write_to_log(log, text) + except Exception: + self._buffer.append(text)