From 292f5cfb3ee84be42602128aacf55799432a79e1 Mon Sep 17 00:00:00 2001 From: sangwook Date: Mon, 20 Apr 2026 15:37:10 +0900 Subject: [PATCH 1/7] fix(cli): prevent TTY hang during command delegation by removing eager header evaluation (#1396) Commands like `vp run` or `vp test` running under background/reporter environments (e.g., lefthook with certain Node.js versions) would hang due to `query_terminal_colors()` blocking on `/dev/tty`. The root cause was `apply_custom_help()` eagerly evaluating the `vite_plus_header()` (and its OSC queries) to build the clap help template during argument parsing, prior to command dispatch. This commit: - Removes the eager header evaluation from clap help templates. - Prints the dynamic `vite_plus_header()` lazily only on `ErrorKind::DisplayHelp`. - Explicitly passes `dynamic_colors` flags into `print_runtime_header()`, allowing delegate commands to safely use `vite_plus_header_static()` right before execution without blocking on TTY queries. --- crates/vite_global_cli/src/cli.rs | 42 +++++++++++++++--------------- crates/vite_global_cli/src/main.rs | 4 +++ crates/vite_shared/src/header.rs | 16 +++++++++++- 3 files changed, 40 insertions(+), 22 deletions(-) diff --git a/crates/vite_global_cli/src/cli.rs b/crates/vite_global_cli/src/cli.rs index ec591d4d42..566de9f622 100644 --- a/crates/vite_global_cli/src/cli.rs +++ b/crates/vite_global_cli/src/cli.rs @@ -1646,7 +1646,7 @@ pub async fn run_command_with_options( packages, pass_through_args, } => { - print_runtime_header(render_options.show_header && !silent); + print_runtime_header(render_options.show_header && !silent, true); // If packages are provided, redirect to Add command if let Some(pkgs) = packages && !pkgs.is_empty() @@ -1972,7 +1972,7 @@ pub async fn run_command_with_options( if help::maybe_print_unified_delegate_help("dev", &args, render_options.show_header) { return Ok(ExitStatus::default()); } - print_runtime_header(render_options.show_header); + print_runtime_header(render_options.show_header, false); commands::delegate::execute(cwd, "dev", &args).await } @@ -1980,7 +1980,7 @@ pub async fn run_command_with_options( if help::maybe_print_unified_delegate_help("build", &args, render_options.show_header) { return Ok(ExitStatus::default()); } - print_runtime_header(render_options.show_header); + print_runtime_header(render_options.show_header, false); commands::delegate::execute(cwd, "build", &args).await } @@ -1988,7 +1988,7 @@ pub async fn run_command_with_options( if help::maybe_print_unified_delegate_help("test", &args, render_options.show_header) { return Ok(ExitStatus::default()); } - print_runtime_header(render_options.show_header); + print_runtime_header(render_options.show_header, false); commands::delegate::execute(cwd, "test", &args).await } @@ -1996,7 +1996,7 @@ pub async fn run_command_with_options( if help::maybe_print_unified_delegate_help("lint", &args, render_options.show_header) { return Ok(ExitStatus::default()); } - print_runtime_header(render_options.show_header); + print_runtime_header(render_options.show_header, false); if should_force_global_delegate("lint", &args) { commands::delegate::execute_global(cwd, "lint", &args).await } else { @@ -2008,7 +2008,7 @@ pub async fn run_command_with_options( if help::maybe_print_unified_delegate_help("fmt", &args, render_options.show_header) { return Ok(ExitStatus::default()); } - print_runtime_header(render_options.show_header); + print_runtime_header(render_options.show_header, false); if should_force_global_delegate("fmt", &args) { commands::delegate::execute_global(cwd, "fmt", &args).await } else { @@ -2020,7 +2020,7 @@ pub async fn run_command_with_options( if help::maybe_print_unified_delegate_help("check", &args, render_options.show_header) { return Ok(ExitStatus::default()); } - print_runtime_header(render_options.show_header); + print_runtime_header(render_options.show_header, false); commands::delegate::execute(cwd, "check", &args).await } @@ -2028,7 +2028,7 @@ pub async fn run_command_with_options( if help::maybe_print_unified_delegate_help("pack", &args, render_options.show_header) { return Ok(ExitStatus::default()); } - print_runtime_header(render_options.show_header); + print_runtime_header(render_options.show_header, false); commands::delegate::execute(cwd, "pack", &args).await } @@ -2036,7 +2036,7 @@ pub async fn run_command_with_options( if help::maybe_print_unified_delegate_help("run", &args, render_options.show_header) { return Ok(ExitStatus::default()); } - print_runtime_header(render_options.show_header); + print_runtime_header(render_options.show_header, false); commands::delegate::execute(cwd, "run", &args).await } @@ -2044,7 +2044,7 @@ pub async fn run_command_with_options( if help::maybe_print_unified_delegate_help("exec", &args, render_options.show_header) { return Ok(ExitStatus::default()); } - print_runtime_header(render_options.show_header); + print_runtime_header(render_options.show_header, false); commands::delegate::execute(cwd, "exec", &args).await } @@ -2053,7 +2053,7 @@ pub async fn run_command_with_options( { return Ok(ExitStatus::default()); } - print_runtime_header(render_options.show_header); + print_runtime_header(render_options.show_header, false); commands::delegate::execute(cwd, "preview", &args).await } @@ -2061,7 +2061,7 @@ pub async fn run_command_with_options( if help::maybe_print_unified_delegate_help("cache", &args, render_options.show_header) { return Ok(ExitStatus::default()); } - print_runtime_header(render_options.show_header); + print_runtime_header(render_options.show_header, false); commands::delegate::execute(cwd, "cache", &args).await } @@ -2098,11 +2098,16 @@ pub(crate) fn exit_status(code: i32) -> ExitStatus { } } -fn print_runtime_header(show_header: bool) { +fn print_runtime_header(show_header: bool, dynamic_colors: bool) { if !show_header { return; } - println!("{}", vite_shared::header::vite_plus_header()); + let header = if dynamic_colors { + vite_shared::header::vite_plus_header() + } else { + vite_shared::header::vite_plus_header_static() + }; + println!("{header}"); println!(); } @@ -2117,15 +2122,10 @@ pub fn command_with_help_with_options(render_options: RenderOptions) -> clap::Co } /// Apply custom help formatting to a clap Command to match the JS CLI output. -fn apply_custom_help(cmd: clap::Command, render_options: RenderOptions) -> clap::Command { +fn apply_custom_help(cmd: clap::Command, _render_options: RenderOptions) -> clap::Command { let after_help = help::render_help_doc(&help::top_level_help_doc()); let options_heading = help::render_heading("Options"); - let header = if render_options.show_header { - vite_shared::header::vite_plus_header() - } else { - String::new() - }; - let help_template = format!("{header}{{after-help}}\n{options_heading}\n{{options}}\n"); + let help_template = format!("{{after-help}}\n{options_heading}\n{{options}}\n"); cmd.after_help(after_help).help_template(help_template) } diff --git a/crates/vite_global_cli/src/main.rs b/crates/vite_global_cli/src/main.rs index 54c58b2a1f..4b66a606b4 100644 --- a/crates/vite_global_cli/src/main.rs +++ b/crates/vite_global_cli/src/main.rs @@ -338,6 +338,10 @@ async fn main() -> ExitCode { // --help and --version are clap "errors" but should exit successfully. if matches!(e.kind(), ErrorKind::DisplayHelp | ErrorKind::DisplayVersion) { + if e.kind() == ErrorKind::DisplayHelp { + println!("{}", vite_shared::header::vite_plus_header()); + println!(); + } e.print().ok(); ExitCode::SUCCESS } else if matches!(e.kind(), ErrorKind::InvalidSubcommand) { diff --git a/crates/vite_shared/src/header.rs b/crates/vite_shared/src/header.rs index c6bf7c70e6..3387058204 100644 --- a/crates/vite_shared/src/header.rs +++ b/crates/vite_shared/src/header.rs @@ -240,7 +240,6 @@ fn is_osc_query_unsupported() -> bool { if std::env::var_os("TMUX").is_some() || std::env::var_os("STY").is_some() { return true; } - false }) } @@ -536,6 +535,21 @@ pub fn vite_plus_header() -> String { render_header_variant(header_colors.blue, &header_colors.suffix_gradient, true, true) } +#[must_use] +pub fn vite_plus_header_static() -> String { + if !should_colorize() || !supports_true_color() { + return format!("VITE+{HEADER_SUFFIX}"); + } + + let suffix_gradient = gradient_eased( + HEADER_SUFFIX.chars().count(), + DEFAULT_BLUE, + DEFAULT_MAGENTA, + HEADER_SUFFIX_FADE_GAMMA, + ); + render_header_variant(DEFAULT_BLUE, &suffix_gradient, true, true) +} + #[cfg(all(test, unix))] mod tests { use std::io::{BufReader, Cursor}; From 7846dd63583ada931acf48f07f7ed0e9a046e1cc Mon Sep 17 00:00:00 2001 From: sangwook Date: Mon, 20 Apr 2026 16:16:18 +0900 Subject: [PATCH 2/7] test: update lint-vite-plus-imports snap --- packages/cli/snap-tests-global/cli-helper-message/snap.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/cli/snap-tests-global/cli-helper-message/snap.txt b/packages/cli/snap-tests-global/cli-helper-message/snap.txt index b376b8dc1f..44d711ec31 100644 --- a/packages/cli/snap-tests-global/cli-helper-message/snap.txt +++ b/packages/cli/snap-tests-global/cli-helper-message/snap.txt @@ -1,6 +1,7 @@ > vp -h # show help message VITE+ - The Unified Toolchain for the Web + Usage: vp [COMMAND] Start: From ed3de8ed56b8390e30aa84af0719ffa026a5abe2 Mon Sep 17 00:00:00 2001 From: sangwook Date: Mon, 20 Apr 2026 17:50:03 +0900 Subject: [PATCH 3/7] fix(cli): remove extra newline in help output to prevent TTY hang --- crates/vite_global_cli/src/main.rs | 1 - packages/cli/snap-tests-global/cli-helper-message/snap.txt | 1 - 2 files changed, 2 deletions(-) diff --git a/crates/vite_global_cli/src/main.rs b/crates/vite_global_cli/src/main.rs index 4b66a606b4..f8748d6756 100644 --- a/crates/vite_global_cli/src/main.rs +++ b/crates/vite_global_cli/src/main.rs @@ -340,7 +340,6 @@ async fn main() -> ExitCode { if matches!(e.kind(), ErrorKind::DisplayHelp | ErrorKind::DisplayVersion) { if e.kind() == ErrorKind::DisplayHelp { println!("{}", vite_shared::header::vite_plus_header()); - println!(); } e.print().ok(); ExitCode::SUCCESS diff --git a/packages/cli/snap-tests-global/cli-helper-message/snap.txt b/packages/cli/snap-tests-global/cli-helper-message/snap.txt index 44d711ec31..b376b8dc1f 100644 --- a/packages/cli/snap-tests-global/cli-helper-message/snap.txt +++ b/packages/cli/snap-tests-global/cli-helper-message/snap.txt @@ -1,7 +1,6 @@ > vp -h # show help message VITE+ - The Unified Toolchain for the Web - Usage: vp [COMMAND] Start: From 09210c6e86ffef9c908d836f8aab7027fb41b86b Mon Sep 17 00:00:00 2001 From: sangwook Date: Mon, 20 Apr 2026 18:21:51 +0900 Subject: [PATCH 4/7] fix(cli): restore top-level help header --- crates/vite_global_cli/src/cli.rs | 32 ++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/crates/vite_global_cli/src/cli.rs b/crates/vite_global_cli/src/cli.rs index 566de9f622..dcba88baf5 100644 --- a/crates/vite_global_cli/src/cli.rs +++ b/crates/vite_global_cli/src/cli.rs @@ -2122,10 +2122,15 @@ pub fn command_with_help_with_options(render_options: RenderOptions) -> clap::Co } /// Apply custom help formatting to a clap Command to match the JS CLI output. -fn apply_custom_help(cmd: clap::Command, _render_options: RenderOptions) -> clap::Command { +fn apply_custom_help(cmd: clap::Command, render_options: RenderOptions) -> clap::Command { let after_help = help::render_help_doc(&help::top_level_help_doc()); + let header = if render_options.show_header { + format!("{}\n\n", vite_shared::header::vite_plus_header()) + } else { + String::new() + }; let options_heading = help::render_heading("Options"); - let help_template = format!("{{after-help}}\n{options_heading}\n{{options}}\n"); + let help_template = format!("{header}{{after-help}}\n{options_heading}\n{{options}}\n"); cmd.after_help(after_help).help_template(help_template) } @@ -2151,7 +2156,10 @@ pub fn try_parse_args_from_with_options( #[cfg(test)] mod tests { - use super::{has_flag_before_terminator, should_force_global_delegate}; + use super::{ + RenderOptions, command_with_help_with_options, has_flag_before_terminator, + should_force_global_delegate, + }; #[test] fn detects_flag_before_option_terminator() { @@ -2184,4 +2192,22 @@ mod tests { assert!(!should_force_global_delegate("lint", &["src/index.ts".to_string()])); assert!(!should_force_global_delegate("fmt", &["--check".to_string()])); } + + #[test] + fn top_level_help_includes_header_when_enabled() { + let help = command_with_help_with_options(RenderOptions { show_header: true }) + .render_help() + .to_string(); + + assert!(help.starts_with("VITE+ - The Unified Toolchain for the Web\n\n")); + } + + #[test] + fn top_level_help_omits_header_when_disabled() { + let help = command_with_help_with_options(RenderOptions { show_header: false }) + .render_help() + .to_string(); + + assert!(!help.starts_with("VITE+ - The Unified Toolchain for the Web")); + } } From 95d71708dbd9ff43e88eeae50a66ae06630955f3 Mon Sep 17 00:00:00 2001 From: sangwook Date: Mon, 20 Apr 2026 18:43:57 +0900 Subject: [PATCH 5/7] fix(cli): disable header display in CLI argument parsing to prevent TTY hang --- crates/vite_global_cli/src/main.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/vite_global_cli/src/main.rs b/crates/vite_global_cli/src/main.rs index f8748d6756..d3eea5da7b 100644 --- a/crates/vite_global_cli/src/main.rs +++ b/crates/vite_global_cli/src/main.rs @@ -322,7 +322,8 @@ async fn main() -> ExitCode { } // Parse CLI arguments (using custom help formatting) - let parse_result = try_parse_args_from(normalized_args); + let parse_result = + try_parse_args_from_with_options(normalized_args, RenderOptions { show_header: false }); // Spawn background upgrade check for eligible commands let upgrade_handle = match &parse_result { From 3ee3a11b00d3c3a935901bd1607928a77819e86b Mon Sep 17 00:00:00 2001 From: sangwook Date: Mon, 20 Apr 2026 23:44:14 +0900 Subject: [PATCH 6/7] fix(header): bound tty color query wall-clock wait --- crates/vite_shared/src/header.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/crates/vite_shared/src/header.rs b/crates/vite_shared/src/header.rs index 3387058204..1793b3acee 100644 --- a/crates/vite_shared/src/header.rs +++ b/crates/vite_shared/src/header.rs @@ -253,6 +253,9 @@ fn is_osc_query_unsupported() -> bool { #[cfg(unix)] const DA1: &str = "\x1b[c"; +#[cfg(unix)] +const QUERY_TERMINAL_COLORS_WALL_CLOCK_TIMEOUT_MS: u64 = 250; + /// Reads from a `BufRead` until one of two delimiter bytes is found. /// Modelled after `terminal-colorsaurus`'s `read_until2`. #[cfg(unix)] @@ -294,6 +297,29 @@ fn read_until_either( /// ordering/completeness ambiguities of flat-buffer pattern matching. #[cfg(unix)] fn query_terminal_colors(palette_indices: &[u8]) -> (Option, Vec<(u8, Rgb)>) { + let indices = palette_indices.to_vec(); + let (tx, rx) = std::sync::mpsc::channel(); + + let Ok(_handle) = + std::thread::Builder::new().name("vp-tty-color-query".into()).spawn(move || { + let _ = tx.send(query_terminal_colors_inner(&indices)); + }) + else { + return (None, vec![]); + }; + + rx.recv_timeout(Duration::from_millis(QUERY_TERMINAL_COLORS_WALL_CLOCK_TIMEOUT_MS)) + .unwrap_or((None, vec![])) +} + +/// Queries terminal colors using the DA1 sandwich technique with +/// stream-based response parsing (modelled after `terminal-colorsaurus`). +/// +/// Responses are read sequentially using `BufReader` + `read_until`, +/// which provides exact response boundaries and eliminates the +/// ordering/completeness ambiguities of flat-buffer pattern matching. +#[cfg(unix)] +fn query_terminal_colors_inner(palette_indices: &[u8]) -> (Option, Vec<(u8, Rgb)>) { use std::{ fs::OpenOptions, io::{self, BufRead, BufReader}, From 22978f1a5f819de009884b4b2f44017cb31c1b08 Mon Sep 17 00:00:00 2001 From: sangwook Date: Mon, 20 Apr 2026 23:47:08 +0900 Subject: [PATCH 7/7] chore(cli): drop header workaround changes --- crates/vite_global_cli/src/cli.rs | 60 +++++++++--------------------- crates/vite_global_cli/src/main.rs | 6 +-- 2 files changed, 18 insertions(+), 48 deletions(-) diff --git a/crates/vite_global_cli/src/cli.rs b/crates/vite_global_cli/src/cli.rs index dcba88baf5..ec591d4d42 100644 --- a/crates/vite_global_cli/src/cli.rs +++ b/crates/vite_global_cli/src/cli.rs @@ -1646,7 +1646,7 @@ pub async fn run_command_with_options( packages, pass_through_args, } => { - print_runtime_header(render_options.show_header && !silent, true); + print_runtime_header(render_options.show_header && !silent); // If packages are provided, redirect to Add command if let Some(pkgs) = packages && !pkgs.is_empty() @@ -1972,7 +1972,7 @@ pub async fn run_command_with_options( if help::maybe_print_unified_delegate_help("dev", &args, render_options.show_header) { return Ok(ExitStatus::default()); } - print_runtime_header(render_options.show_header, false); + print_runtime_header(render_options.show_header); commands::delegate::execute(cwd, "dev", &args).await } @@ -1980,7 +1980,7 @@ pub async fn run_command_with_options( if help::maybe_print_unified_delegate_help("build", &args, render_options.show_header) { return Ok(ExitStatus::default()); } - print_runtime_header(render_options.show_header, false); + print_runtime_header(render_options.show_header); commands::delegate::execute(cwd, "build", &args).await } @@ -1988,7 +1988,7 @@ pub async fn run_command_with_options( if help::maybe_print_unified_delegate_help("test", &args, render_options.show_header) { return Ok(ExitStatus::default()); } - print_runtime_header(render_options.show_header, false); + print_runtime_header(render_options.show_header); commands::delegate::execute(cwd, "test", &args).await } @@ -1996,7 +1996,7 @@ pub async fn run_command_with_options( if help::maybe_print_unified_delegate_help("lint", &args, render_options.show_header) { return Ok(ExitStatus::default()); } - print_runtime_header(render_options.show_header, false); + print_runtime_header(render_options.show_header); if should_force_global_delegate("lint", &args) { commands::delegate::execute_global(cwd, "lint", &args).await } else { @@ -2008,7 +2008,7 @@ pub async fn run_command_with_options( if help::maybe_print_unified_delegate_help("fmt", &args, render_options.show_header) { return Ok(ExitStatus::default()); } - print_runtime_header(render_options.show_header, false); + print_runtime_header(render_options.show_header); if should_force_global_delegate("fmt", &args) { commands::delegate::execute_global(cwd, "fmt", &args).await } else { @@ -2020,7 +2020,7 @@ pub async fn run_command_with_options( if help::maybe_print_unified_delegate_help("check", &args, render_options.show_header) { return Ok(ExitStatus::default()); } - print_runtime_header(render_options.show_header, false); + print_runtime_header(render_options.show_header); commands::delegate::execute(cwd, "check", &args).await } @@ -2028,7 +2028,7 @@ pub async fn run_command_with_options( if help::maybe_print_unified_delegate_help("pack", &args, render_options.show_header) { return Ok(ExitStatus::default()); } - print_runtime_header(render_options.show_header, false); + print_runtime_header(render_options.show_header); commands::delegate::execute(cwd, "pack", &args).await } @@ -2036,7 +2036,7 @@ pub async fn run_command_with_options( if help::maybe_print_unified_delegate_help("run", &args, render_options.show_header) { return Ok(ExitStatus::default()); } - print_runtime_header(render_options.show_header, false); + print_runtime_header(render_options.show_header); commands::delegate::execute(cwd, "run", &args).await } @@ -2044,7 +2044,7 @@ pub async fn run_command_with_options( if help::maybe_print_unified_delegate_help("exec", &args, render_options.show_header) { return Ok(ExitStatus::default()); } - print_runtime_header(render_options.show_header, false); + print_runtime_header(render_options.show_header); commands::delegate::execute(cwd, "exec", &args).await } @@ -2053,7 +2053,7 @@ pub async fn run_command_with_options( { return Ok(ExitStatus::default()); } - print_runtime_header(render_options.show_header, false); + print_runtime_header(render_options.show_header); commands::delegate::execute(cwd, "preview", &args).await } @@ -2061,7 +2061,7 @@ pub async fn run_command_with_options( if help::maybe_print_unified_delegate_help("cache", &args, render_options.show_header) { return Ok(ExitStatus::default()); } - print_runtime_header(render_options.show_header, false); + print_runtime_header(render_options.show_header); commands::delegate::execute(cwd, "cache", &args).await } @@ -2098,16 +2098,11 @@ pub(crate) fn exit_status(code: i32) -> ExitStatus { } } -fn print_runtime_header(show_header: bool, dynamic_colors: bool) { +fn print_runtime_header(show_header: bool) { if !show_header { return; } - let header = if dynamic_colors { - vite_shared::header::vite_plus_header() - } else { - vite_shared::header::vite_plus_header_static() - }; - println!("{header}"); + println!("{}", vite_shared::header::vite_plus_header()); println!(); } @@ -2124,12 +2119,12 @@ pub fn command_with_help_with_options(render_options: RenderOptions) -> clap::Co /// Apply custom help formatting to a clap Command to match the JS CLI output. fn apply_custom_help(cmd: clap::Command, render_options: RenderOptions) -> clap::Command { let after_help = help::render_help_doc(&help::top_level_help_doc()); + let options_heading = help::render_heading("Options"); let header = if render_options.show_header { - format!("{}\n\n", vite_shared::header::vite_plus_header()) + vite_shared::header::vite_plus_header() } else { String::new() }; - let options_heading = help::render_heading("Options"); let help_template = format!("{header}{{after-help}}\n{options_heading}\n{{options}}\n"); cmd.after_help(after_help).help_template(help_template) @@ -2156,10 +2151,7 @@ pub fn try_parse_args_from_with_options( #[cfg(test)] mod tests { - use super::{ - RenderOptions, command_with_help_with_options, has_flag_before_terminator, - should_force_global_delegate, - }; + use super::{has_flag_before_terminator, should_force_global_delegate}; #[test] fn detects_flag_before_option_terminator() { @@ -2192,22 +2184,4 @@ mod tests { assert!(!should_force_global_delegate("lint", &["src/index.ts".to_string()])); assert!(!should_force_global_delegate("fmt", &["--check".to_string()])); } - - #[test] - fn top_level_help_includes_header_when_enabled() { - let help = command_with_help_with_options(RenderOptions { show_header: true }) - .render_help() - .to_string(); - - assert!(help.starts_with("VITE+ - The Unified Toolchain for the Web\n\n")); - } - - #[test] - fn top_level_help_omits_header_when_disabled() { - let help = command_with_help_with_options(RenderOptions { show_header: false }) - .render_help() - .to_string(); - - assert!(!help.starts_with("VITE+ - The Unified Toolchain for the Web")); - } } diff --git a/crates/vite_global_cli/src/main.rs b/crates/vite_global_cli/src/main.rs index d3eea5da7b..54c58b2a1f 100644 --- a/crates/vite_global_cli/src/main.rs +++ b/crates/vite_global_cli/src/main.rs @@ -322,8 +322,7 @@ async fn main() -> ExitCode { } // Parse CLI arguments (using custom help formatting) - let parse_result = - try_parse_args_from_with_options(normalized_args, RenderOptions { show_header: false }); + let parse_result = try_parse_args_from(normalized_args); // Spawn background upgrade check for eligible commands let upgrade_handle = match &parse_result { @@ -339,9 +338,6 @@ async fn main() -> ExitCode { // --help and --version are clap "errors" but should exit successfully. if matches!(e.kind(), ErrorKind::DisplayHelp | ErrorKind::DisplayVersion) { - if e.kind() == ErrorKind::DisplayHelp { - println!("{}", vite_shared::header::vite_plus_header()); - } e.print().ok(); ExitCode::SUCCESS } else if matches!(e.kind(), ErrorKind::InvalidSubcommand) {