Suppress stderr output in detach and create modes

`prepare_workflow` unconditionally printed Workflow/Graph/Goal info to
stderr, which leaked into `--detach` and `create` output that should
only emit the run ID. Add a `quiet` flag to suppress this output.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Bryan Helmkamp 2026-03-21 10:26:20 -04:00
parent 1a323ceb64
commit 5ac60c7134
No known key found for this signature in database
3 changed files with 30 additions and 25 deletions

View file

@ -14,13 +14,14 @@ pub async fn create_run(
args: &RunArgs,
run_defaults: RunDefaults,
styles: &Styles,
quiet: bool,
) -> anyhow::Result<(String, PathBuf)> {
let workflow_path = args
.workflow
.as_ref()
.ok_or_else(|| anyhow::anyhow!("--workflow is required"))?;
let prep = prepare_workflow(args, run_defaults, styles)?;
let prep = prepare_workflow(args, run_defaults, styles, quiet)?;
let goal = prep.graph.goal();

View file

@ -463,6 +463,7 @@ pub(crate) fn prepare_workflow(
args: &RunArgs,
mut run_defaults: RunDefaults,
styles: &Styles,
quiet: bool,
) -> anyhow::Result<PreparedWorkflow> {
let workflow_path = args
.workflow
@ -528,30 +529,32 @@ pub(crate) fn prepare_workflow(
}
}
eprintln!(
"{} {} {}",
styles.bold.apply_to("Workflow:"),
graph.name,
styles.dim.apply_to(format!(
"({} nodes, {} edges)",
graph.nodes.len(),
graph.edges.len()
)),
);
eprintln!(
"{} {}",
styles.dim.apply_to("Graph:"),
styles.dim.apply_to(relative_path(&dot_path)),
);
if !quiet {
eprintln!(
"{} {} {}",
styles.bold.apply_to("Workflow:"),
graph.name,
styles.dim.apply_to(format!(
"({} nodes, {} edges)",
graph.nodes.len(),
graph.edges.len()
)),
);
eprintln!(
"{} {}",
styles.dim.apply_to("Graph:"),
styles.dim.apply_to(relative_path(&dot_path)),
);
let goal = graph.goal();
if !goal.is_empty() {
let stripped = fabro_util::text::strip_goal_decoration(goal);
eprintln!("{} {stripped}\n", styles.bold.apply_to("Goal:"));
let goal = graph.goal();
if !goal.is_empty() {
let stripped = fabro_util::text::strip_goal_decoration(goal);
eprintln!("{} {stripped}\n", styles.bold.apply_to("Goal:"));
}
print_diagnostics(&diagnostics, styles);
}
print_diagnostics(&diagnostics, styles);
if diagnostics.iter().any(|d| d.severity == Severity::Error) {
bail!("Validation failed");
}
@ -612,7 +615,7 @@ pub async fn run_command(
model,
provider,
run_defaults,
} = prepare_workflow(&args, run_defaults, styles)?;
} = prepare_workflow(&args, run_defaults, styles, false)?;
// Extract workflow slug from the workflow path argument.
// If bare name (no extension, e.g. "smoke"), use it directly.

View file

@ -653,7 +653,7 @@ async fn main_inner() -> (String, Result<()>) {
if args.detach {
// Detach mode: create + start + print run ID
let (run_id, run_dir) =
commands::create::create_run(&args, cli_config.run_defaults, styles)
commands::create::create_run(&args, cli_config.run_defaults, styles, true)
.await?;
commands::start::start_run(&run_dir)?;
println!("{run_id}");
@ -683,7 +683,8 @@ async fn main_inner() -> (String, Result<()>) {
Box::leak(Box::new(fabro_util::terminal::Styles::detect_stderr()));
let cli_config = cli_config::load_cli_config(None)?;
let (run_id, _run_dir) =
commands::create::create_run(&args, cli_config.run_defaults, styles).await?;
commands::create::create_run(&args, cli_config.run_defaults, styles, true)
.await?;
println!("{run_id}");
}
Command::Start { run } => {