Route structured logs to a file instead of the console - #358
Merged
Conversation
@intx/log installs a console sink as an import side effect, so a vendored logger's error could land on stdout mid-frame while the TUI held the alternate screen, corrupting the visible prompt box with a raw JSON log record. Install a file-backed sink as the first statement in mainWithRunners, before config loads or any other subsystem can log, replacing the console default entirely. The readable, human-facing error was already rendered elsewhere in the transcript; this only stops the duplicate raw log line from ever reaching the terminal.
Filtering the file sink at warning silently disabled a dozen logger.debug calls written specifically to diagnose teardown races in the TUI and exec runners. A file has no screen to corrupt, so drop the floor to debug and let those diagnostics reach it.
TheGreatAxios
force-pushed
the
cl-5593-log-sink-off-screen
branch
from
August 7, 2026 07:37
b75737f to
d1f9829
Compare
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.
Summary
interchange.inference.default-director) could reach stdout mid-frame and corrupt the TUI's alternate screen, because@intx/loginstalls a console sink as an import side effect and nothing in Corbits ever replaced it.installFileLogSink(src/logging/sink.ts) and call it as the first statement ofmainWithRunners, beforeloadConfigor anything else can log, so every logger — including ones insidevendor/— writes to~/.corbits/logs/corbits.loginstead of the terminal.debug, notwarning: a file has no screen to corrupt, and a dozen existinglogger.debugcalls insrc/tui/runner.tsandsrc/exec/runner.tsexist specifically to diagnose teardown races. A higher floor would have silently made those unreachable.Verification
bun run typecheckbun run buildbun run test(3968 pass)src/tui-opentui/log-sink.test.ts): mounts the shell, fires the vendored logger's exact call shape, and asserts the captured frame is unchanged,process.stdout.write/process.stderr.writeare never called, and the record lands in the log file.getLoggercall in the reachable import graph actually logs beforeinstallFileLogSink()runs — was verified by tracing the import graph rather than covered by an automated test; a mock-based ordering test was attempted and dropped after it deadlocked bun's module-mock cache. A subprocess test spawning the real entry point and asserting nothing reaches stdout would close this gap and is a reasonable follow-up.Known follow-ups (not fixed here)
src/logging/sink.tsappends to the log file forever with no rotation or size cap.LogRecordtype insrc/logging/sink.tsstructurally mirrors@logtape/logtape's real type (two packages away, not a declared dependency) rather than importing it. It typechecks today — the real type is strictly wider — but nothing catches drift if a future LogTape version renames or narrows a field this file reads.Closes CL-5593