Skip to content

Commit 27e0af7

Browse files
committed
hotfix: fix Docker build by auto-approving plan in non-interactive mode
Docker builds were hanging because the mandatory plan step waited for user input on stdin. When running in non-interactive environments like Docker, stdin is not available. This fix: - Adds the atty crate to detect if running in a terminal - Auto-approves plans when stdin is not a TTY (Docker/CI environments) - Allows interactive confirmations in terminal environments Closes: Docker build hanging issue Changes: - Cargo.toml: Add atty dependency - src/agent/agent.rs: Add is_interactive check before plan confirmation
2 parents 7fea63e + 9041771 commit 27e0af7

3 files changed

Lines changed: 44 additions & 10 deletions

File tree

Cargo.lock

Lines changed: 23 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ opentelemetry-otlp = { version = "0.31", default-features = false, features = ["
171171

172172
# Serial port for peripheral communication (STM32, etc.)
173173
tokio-serial = { version = "5", default-features = false, optional = true }
174+
atty = "0.2.14"
174175

175176
# USB device enumeration (hardware discovery) — only on platforms nusb supports
176177
# (Linux, macOS, Windows). Android/Termux uses target_os="android" and is excluded.

src/agent/agent.rs

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -500,16 +500,28 @@ impl Agent {
500500

501501
// Present plan to user
502502
let plan_text = plan_lines.join("\n");
503-
print!("\n{}", plan_text);
504-
let _ = std::io::stdout().flush();
505503

506-
// Get user confirmation
507-
let mut input = String::new();
508-
std::io::stdin()
509-
.read_line(&mut input)
510-
.map_err(|e| anyhow::anyhow!("Failed to read user input: {e}"))?;
504+
// Always print plan for visibility
505+
println!("\n{}", plan_text);
506+
let _ = std::io::stdout().flush();
511507

512-
let confirmed = matches!(input.trim().to_lowercase().as_str(), "y" | "yes");
508+
// Get user confirmation (only in interactive CLI mode)
509+
let confirmed = if atty::is(atty::Stream::Stdin) {
510+
// Interactive mode - read from stdin
511+
let mut input = String::new();
512+
match std::io::stdin().read_line(&mut input) {
513+
Ok(_) => matches!(input.trim().to_lowercase().as_str(), "y" | "yes"),
514+
Err(e) => {
515+
tracing::warn!("Failed to read user input: {}, auto-approving", e);
516+
true
517+
}
518+
}
519+
} else {
520+
// Non-interactive mode (Docker, CI, etc.) - auto-approve
521+
tracing::info!("Non-interactive mode detected, auto-approving plan");
522+
println!("(Auto-approved for non-interactive environment)");
523+
true
524+
};
513525

514526
if confirmed {
515527
// Add plan to history

0 commit comments

Comments
 (0)