From 5be90cffec27ff1f9033005a45f56215d777c553 Mon Sep 17 00:00:00 2001
From: th-kim0823
Date: Thu, 7 May 2026 22:15:01 +0900
Subject: [PATCH] fix(progress): eliminate duplicate TTY frame per asset
set_position() and set_message() each call update_and_draw()
independently, producing two scrollback lines per file in TTY mode.
Suppress the draw target before the two updates, restore to stderr,
then call tick() to emit exactly one frame.
Co-Authored-By: Claude Sonnet 4.6
---
crates/kebab-cli/src/progress.rs | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/crates/kebab-cli/src/progress.rs b/crates/kebab-cli/src/progress.rs
index f91ed9e..c18948d 100644
--- a/crates/kebab-cli/src/progress.rs
+++ b/crates/kebab-cli/src/progress.rs
@@ -144,12 +144,19 @@ impl ProgressDisplay {
media,
} => {
if let Some(bar) = self.bar.as_ref() {
- // Advance position to N-1 (completed so far) and set the
- // current-asset message in one atomic update, so TTY mode
- // produces exactly one bar frame per file instead of two
- // (AssetStarted + AssetFinished each triggered a redraw).
- bar.set_position(u64::from(idx.saturating_sub(1)));
+ // Suppress draws during the two updates so only one frame
+ // lands in the TTY scrollback per file. set_position() and
+ // set_message() each call update_and_draw() independently —
+ // hiding the draw target collapses them into a single tick().
+ bar.set_draw_target(ProgressDrawTarget::hidden());
bar.set_message(format!("{media} {path}"));
+ bar.set_position(u64::from(idx.saturating_sub(1)));
+ bar.set_draw_target(if tty && !quiet {
+ ProgressDrawTarget::stderr()
+ } else {
+ ProgressDrawTarget::hidden()
+ });
+ bar.tick();
}
if !tty && !quiet {
let mut err = std::io::stderr().lock();
--
2.49.1