Skip to content

fix(cli): make render progress visible when stdout is piped#1892

Draft
miguel-heygen wants to merge 2 commits into
mainfrom
fix/progress-non-tty-newline-output
Draft

fix(cli): make render progress visible when stdout is piped#1892
miguel-heygen wants to merge 2 commits into
mainfrom
fix/progress-non-tty-newline-output

Conversation

@miguel-heygen

Copy link
Copy Markdown
Collaborator

Summary

renderProgress's non-TTY fallback still wrote a carriage-return line with ANSI cursor-erase codes on every single progress tick — "progress output invisible when stdout piped (buffered until exit)". A piped/redirected stdout has no cursor to move, and Node full-buffers non-TTY streams by default (unlike the line-buffered behavior of an interactive TTY), so these \r-prefixed writes accumulated silently and never became visible until the process exited.

Fix

Non-TTY stdout now gets plain, newline-terminated lines instead of carriage-return/ANSI codes, throttled to one line per integer percent so a long render doesn't spam piped/logged output with hundreds of near-identical lines. The interactive TTY behavior (the live carriage-return progress bar) is completely unchanged.

(A second complaint in the same feedback batch — "npx hyperframes in non-TTY printed no doctor output on first runs" — turned out to be unrelated: doctor.ts doesn't call renderProgress or check isTTY at all, so it's a separate, still open question, likely related to npx's own first-run package resolution rather than this code path.)

Test plan

  • bunx vitest run packages/cli/src/ui/progress.test.ts — 4 new tests pass: TTY still gets the carriage-return cursor-based line, non-TTY gets a plain newline-terminated line, non-TTY output throttles to one line per integer percent, and throttle state doesn't leak in ways that would suppress a fresh render's very first line
  • bun run build — full monorepo typecheck passes

renderProgress's non-TTY fallback still wrote a carriage-return line with
ANSI cursor-erase codes, unthrottled, on every progress tick. A piped or
redirected stdout has no cursor to move, and Node full-buffers non-TTY
streams by default, so these writes accumulated invisibly until the
process exited rather than ever appearing in piped/logged output -
reported as "progress output invisible when stdout piped (buffered until
exit)".

Non-TTY stdout now gets plain, newline-terminated lines instead, throttled
to one per integer percent so a long render doesn't spam a log file with
hundreds of near-identical lines. TTY behavior (the interactive
carriage-return progress bar) is unchanged.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant