From cb266e0071fed3fe3290012145e498b15b86c3cd Mon Sep 17 00:00:00 2001 From: th-kim0823 Date: Thu, 7 May 2026 21:49:47 +0900 Subject: [PATCH] fix(progress): eliminate duplicate bar frame per asset in TTY mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AssetStarted now advances position (idx-1) and sets message together. AssetFinished no longer updates the bar — Completed handles final cleanup via finish_and_clear. Result: one bar frame per file instead of two, eliminating the scrollback duplicate-line artifact. --- crates/kebab-cli/src/progress.rs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/crates/kebab-cli/src/progress.rs b/crates/kebab-cli/src/progress.rs index 268f7f3..f91ed9e 100644 --- a/crates/kebab-cli/src/progress.rs +++ b/crates/kebab-cli/src/progress.rs @@ -144,6 +144,11 @@ 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))); bar.set_message(format!("{media} {path}")); } if !tty && !quiet { @@ -151,10 +156,10 @@ impl ProgressDisplay { let _ = writeln!(err, "ingest: {idx}/{total} {media} {path}"); } } - IngestEvent::AssetFinished { idx, .. } => { - if let Some(bar) = self.bar.as_ref() { - bar.set_position(u64::from(*idx)); - } + IngestEvent::AssetFinished { .. } => { + // Position is advanced in AssetStarted; bar.finish_and_clear() + // in Completed handles the final state. No per-asset bar update + // here avoids the duplicate-frame artifact in TTY scrollback. } IngestEvent::Completed { counts } => { if let Some(bar) = self.bar.take() { -- 2.49.1