fix: route boo ui stderr to BOO_LOG or /dev/null to stop viewport log noise#82
Merged
Conversation
… noise boo ui renders an in-process libghostty VT stream. std.log writes to stderr, which is the user's terminal, so any scope's log line (not just the stream scope handled before) paints over the rendered viewport until a manual redraw. Replace the narrow std_options.logFn that only dropped info(stream) with a stderr redirect for the UI's lifetime: point fd 2 at $BOO_LOG when set, otherwise /dev/null, then restore it so the closing notice still shows. This drops every VT log scope and level from the viewport while keeping an opt-in debug log. Factor the daemon's existing BOO_LOG-or-/dev/null logic into openLogSink() so both paths share it.
redirectStderr dup'd the original stderr without CLOEXEC. boo ui spawns `boo new` (which forks the session daemon) via std.process.Child.run, so the saved dup of the controlling pty leaked into the daemon and its child shell, holding the pty open after the UI exited. That wedged PTY-based test teardown (macOS CI hung). Set FD_CLOEXEC on the saved fd so the exec in boo new drops it.
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
boo uirenders an in-process libghostty VT stream.std.logwrites to stderr, which is the user's terminal, so log lines paint over the rendered viewport until a manual redraw (C-a l).#65 only silenced the
streamscope at info level. libghostty logs under many other scopes (osc,terminal_dcs,kitty_gfx, ...) and levels, so lines likeinfo(osc): failed to parse OSC ...orinfo(terminal_dcs): unknown DCS hook: ...still corrupt the UI on v0.5.22+.Fix
Drop the narrow
std_options.logFnfilter and instead redirect the UI process's stderr for the lifetime ofboo ui:$BOO_LOG(appended) when set, otherwise/dev/null.[boo ui closed]notice still shows.This suppresses every scope and level from the viewport while keeping an opt-in debug log. The daemon already did this for its own stderr; that logic is factored into
openLogSink()and shared.Behavior notes
BOO_LOGnow also capturesboo uilogs (help text updated).BOO_LOGpath which fails to open now falls back to/dev/nullinstead of the inherited stderr. It is a detached daemon, so this is strictly safer.logFnis safe: onlyboo ui(andBOO_FOREGROUND=1, a debug mode) runs an in-process VT stream on a terminal; the attach client passes bytes through without parsing.Testing
zig buildclean;zig fmt --checkclean.zig build test test-integration-> 206/206 tests pass (130 unit + 76 PTY integration, including allui:tests).BOO_LOGset, confirmed the daemon logged to the file (info(daemon): renamed to ...) and thatls/rename/killwork.Implementation notes / decision log
ls, errors viastd.debug.print/std.log.err) should still reach the terminal. Onlyboo uiowns the screen, so the redirect is scoped to it and restored before the closing notice.protocol.writeAll(1, ...)); only fd 2 is moved, so drawing is unaffected.redirectStderr()returns-1(no-op restore) if the sink cannot be opened ordupfails, leaving stderr untouched.🤖 Generated by Coder Agents on behalf of @kylecarbs.