From 871e639abc5882b0c1a4631128952ec4a8e32ed7 Mon Sep 17 00:00:00 2001 From: Raphael Kikuchi Date: Mon, 15 Jun 2026 03:49:33 -0300 Subject: [PATCH] fix: stop libghostty stream logs from corrupting the boo ui viewport libghostty's VT stream parser logs unimplemented sequences at info level under the `stream` scope (e.g. "OSC 1 (change icon) received and ignored"). The session daemon redirects its stderr to BOO_LOG or /dev/null in startDaemon, so those lines never reach a terminal there. But `boo ui` renders in-process with stderr still attached to the user's terminal, so the same logs paint directly over the rendered viewport and corrupt it until a manual redraw (C-a l). Powerlevel10k makes this very visible: it emits an OSC 1 on every prompt and on preexec, so any command (e.g. `cat ~/.zshrc`) floods the pane with "received and ignored" lines. Install a std_options.logFn that drops info-and-below from the `stream` scope while leaving every other scope untouched. Verified at ReleaseSafe (the release build config) that this takes the emitted info(stream) count from 1 to 0; the change is zig fmt clean and `zig build test` passes. --- src/main.zig | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/main.zig b/src/main.zig index 462dff5..f74759a 100644 --- a/src/main.zig +++ b/src/main.zig @@ -13,6 +13,27 @@ const ui = @import("ui.zig"); pub const version = "0.5.18"; +/// Route std.log through a filter. libghostty's VT stream parser logs +/// unimplemented sequences at info level under the `stream` scope (e.g. +/// "OSC 1 (change icon) received and ignored"). In `boo ui` the parser runs +/// in-process with stderr still attached to the user's terminal (unlike the +/// daemon, which redirects stderr in startDaemon), so those lines paint over +/// the rendered viewport and corrupt it. Drop info-and-below from `stream`; +/// every other scope logs as before. +pub const std_options: std.Options = .{ + .logFn = filteredLog, +}; + +fn filteredLog( + comptime level: std.log.Level, + comptime scope: @TypeOf(.enum_literal), + comptime format: []const u8, + args: anytype, +) void { + if (scope == .stream and @intFromEnum(level) >= @intFromEnum(std.log.Level.info)) return; + std.log.defaultLog(level, scope, format, args); +} + /// Exit codes, documented in `boo help`. const exit_runtime: u8 = 1; const exit_usage: u8 = 2;