From 62ea189d9238338d54f876319eba415fb3ee079b Mon Sep 17 00:00:00 2001 From: Drew Newberry Date: Fri, 13 Mar 2026 15:37:53 -0700 Subject: [PATCH 1/2] fix(cli): use line-based stdin read for gateway recreate prompt dialoguer::Confirm::interact() puts the terminal into raw mode, which causes the prompt to return immediately without waiting for user input in some terminal environments. Replace with std::io::stdin().read_line() which blocks reliably on a full line of input. Also fix the interactive detection to check both stdin and stderr are TTYs (matching the pattern used in gateway_select), and restore the 'volume only' status label and image info in the prompt. --- crates/openshell-cli/src/run.rs | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/crates/openshell-cli/src/run.rs b/crates/openshell-cli/src/run.rs index 002596f8c..c88a69fb9 100644 --- a/crates/openshell-cli/src/run.rs +++ b/crates/openshell-cli/src/run.rs @@ -1337,22 +1337,31 @@ pub async fn gateway_admin_deploy( openshell_bootstrap::check_existing_deployment(name, remote_opts.as_ref()).await? { if !should_recreate { - let interactive = std::io::stderr().is_terminal(); + let interactive = std::io::stdin().is_terminal() && std::io::stderr().is_terminal(); if interactive { let status = if existing.container_running { "running" - } else { + } else if existing.container_exists { "stopped" + } else { + "volume only" }; eprintln!( "{} Gateway '{name}' already exists ({status}).", "!".yellow().bold() ); - should_recreate = Confirm::new() - .with_prompt("Destroy and recreate it?") - .default(false) - .interact() - .into_diagnostic()?; + if let Some(image) = &existing.container_image { + eprintln!(" {} {}", "Image:".dimmed(), image); + } + eprint!("Destroy and recreate? [y/N] "); + std::io::stderr().flush().ok(); + let mut input = String::new(); + std::io::stdin() + .read_line(&mut input) + .into_diagnostic() + .wrap_err("failed to read user input")?; + let choice = input.trim().to_lowercase(); + should_recreate = choice == "y" || choice == "yes"; if !should_recreate { eprintln!("Keeping existing gateway."); return Ok(()); From 5fa8966f68668097aa58eee0957e9888c28fcaaf Mon Sep 17 00:00:00 2001 From: Drew Newberry Date: Fri, 13 Mar 2026 15:44:00 -0700 Subject: [PATCH 2/2] fix(cli): add spacing around gateway recreate prompt --- crates/openshell-cli/src/run.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/openshell-cli/src/run.rs b/crates/openshell-cli/src/run.rs index c88a69fb9..db033e456 100644 --- a/crates/openshell-cli/src/run.rs +++ b/crates/openshell-cli/src/run.rs @@ -1346,6 +1346,7 @@ pub async fn gateway_admin_deploy( } else { "volume only" }; + eprintln!(); eprintln!( "{} Gateway '{name}' already exists ({status}).", "!".yellow().bold() @@ -1353,6 +1354,7 @@ pub async fn gateway_admin_deploy( if let Some(image) = &existing.container_image { eprintln!(" {} {}", "Image:".dimmed(), image); } + eprintln!(); eprint!("Destroy and recreate? [y/N] "); std::io::stderr().flush().ok(); let mut input = String::new();