from __future__ import annotations from textual.widgets import Static from run_utils import ( CHAR_PATH, TODAY, REFRESH_SECS, clear_llm_log, ensure_log, read_todo, read_log_tail, status_summary, log_count, ) from run_ambience import HAS_AUDIO # module-level ref filled by ChaosTUI app_ambience_player: object | None = None class AutoStatic(Static): def load(self): raise NotImplementedError def on_mount(self): clear_llm_log() ensure_log() self.load() self.set_interval(REFRESH_SECS, self.load) class TodoPane(AutoStatic): def load(self): items = read_todo() self.update("\n".join(f" ☐ {i}" for i in items)) class TranscriptPane(AutoStatic): def load(self): lines = read_log_tail() display = "\n".join(lines[-80:]) if lines: display += "\n\n>>--- NOW --->" self.update(display) self.call_after_refresh(self._scroll_bottom) def _scroll_bottom(self): if self.parent and hasattr(self.parent, 'scroll_end'): self.parent.scroll_end(animate=False) class CharPane(AutoStatic): def load(self): if not CHAR_PATH.exists(): self.update("*No character sheet*") return self.update(RichMarkdown(CHAR_PATH.read_text().strip())) class StatusBar(AutoStatic): def load(self): char = status_summary() count = log_count() todo = len(read_todo()) music = "" if not HAS_AUDIO: music = " │ ♫ (install miniaudio)" elif app_ambience_player: name = app_ambience_player.ambience_name music = f" │ ♫ {name}" self.update(f"{char} │ {count} entries │ {todo} todo │ {TODAY}{music}")