From f60a4359a0f4c3ac0a96ca06e55bef2403daee3b Mon Sep 17 00:00:00 2001 From: Matt Van Horn Date: Tue, 24 Feb 2026 19:58:01 -0800 Subject: [PATCH] fix(ui): quiet HN and YouTube spinners in non-TTY mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reddit and X are the star of the show. In Claude Code (non-TTY), suppress ⏳ start messages for HN and YouTube so Reddit/X are the first visible lines. HN/YouTube still show ✓ completion messages. Also suppress [HN] debug logs in non-TTY to reduce output clutter. Co-Authored-By: Claude Opus 4.6 --- scripts/lib/hackernews.py | 7 ++++--- scripts/lib/ui.py | 9 +++++---- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/scripts/lib/hackernews.py b/scripts/lib/hackernews.py index f50bbdd..1ce3792 100644 --- a/scripts/lib/hackernews.py +++ b/scripts/lib/hackernews.py @@ -31,9 +31,10 @@ ENRICH_LIMITS = { def _log(msg: str): - """Log to stderr.""" - sys.stderr.write(f"[HN] {msg}\n") - sys.stderr.flush() + """Log to stderr (only in TTY mode to avoid cluttering Claude Code output).""" + if sys.stderr.isatty(): + sys.stderr.write(f"[HN] {msg}\n") + sys.stderr.flush() def _date_to_unix(date_str: str) -> int: diff --git a/scripts/lib/ui.py b/scripts/lib/ui.py index 07eba20..3b9a209 100644 --- a/scripts/lib/ui.py +++ b/scripts/lib/ui.py @@ -153,13 +153,14 @@ DOTS_FRAMES = [' ', '. ', '.. ', '...'] class Spinner: """Animated spinner for long-running operations.""" - def __init__(self, message: str = "Working", color: str = Colors.CYAN): + def __init__(self, message: str = "Working", color: str = Colors.CYAN, quiet: bool = False): self.message = message self.color = color self.running = False self.thread: Optional[threading.Thread] = None self.frame_idx = 0 self.shown_static = False + self.quiet = quiet # Suppress non-TTY start message (still shows ✓ completion) def _spin(self): while self.running: @@ -177,7 +178,7 @@ class Spinner: self.thread.start() else: # Not a TTY (Claude Code) - just print once - if not self.shown_static: + if not self.shown_static and not self.quiet: sys.stderr.write(f"⏳ {self.message}\n") sys.stderr.flush() self.shown_static = True @@ -257,7 +258,7 @@ class ProgressDisplay: def start_youtube(self): msg = random.choice(YOUTUBE_MESSAGES) - self.spinner = Spinner(f"{Colors.RED}YouTube{Colors.RESET} {msg}", Colors.RED) + self.spinner = Spinner(f"{Colors.RED}YouTube{Colors.RESET} {msg}", Colors.RED, quiet=True) self.spinner.start() def end_youtube(self, count: int): @@ -266,7 +267,7 @@ class ProgressDisplay: def start_hackernews(self): msg = random.choice(HN_MESSAGES) - self.spinner = Spinner(f"{Colors.YELLOW}HN{Colors.RESET} {msg}", Colors.YELLOW) + self.spinner = Spinner(f"{Colors.YELLOW}HN{Colors.RESET} {msg}", Colors.YELLOW, quiet=True) self.spinner.start() def end_hackernews(self, count: int):