From c871ecb27442e6047de40fa56cf5a77af6064017 Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Fri, 27 Mar 2026 10:26:59 -0400 Subject: [PATCH] Refactor fabro-cli run command layout --- lib/crates/fabro-cli/src/args.rs | 126 +++++++++++------- lib/crates/fabro-cli/src/commands/mod.rs | 15 --- .../src/commands/{ => run}/attach.rs | 0 .../src/commands/{ => run}/create.rs | 2 +- .../{run_engine.rs => run/detached.rs} | 4 +- .../commands/{ => run}/detached_support.rs | 0 .../fabro-cli/src/commands/{ => run}/diff.rs | 0 .../src/commands/{run.rs => run/execute.rs} | 2 +- .../fabro-cli/src/commands/{ => run}/fork.rs | 0 .../fabro-cli/src/commands/{ => run}/logs.rs | 0 lib/crates/fabro-cli/src/commands/run/mod.rs | 81 +++++++++++ .../src/commands/{ => run}/preview.rs | 0 .../src/commands/{ => run}/resume.rs | 2 +- .../src/commands/{ => run}/rewind.rs | 0 .../src/commands/{ => run}/run_progress.rs | 0 .../fabro-cli/src/commands/{ => run}/ssh.rs | 0 .../fabro-cli/src/commands/{ => run}/start.rs | 2 +- .../fabro-cli/src/commands/{ => run}/wait.rs | 0 .../src/commands/{ => runs}/inspect.rs | 0 .../src/commands/{runs.rs => runs/mod.rs} | 15 ++- lib/crates/fabro-cli/src/main.rs | 97 ++------------ lib/crates/fabro-cli/tests/cli.rs | 12 +- 22 files changed, 196 insertions(+), 162 deletions(-) rename lib/crates/fabro-cli/src/commands/{ => run}/attach.rs (100%) rename lib/crates/fabro-cli/src/commands/{ => run}/create.rs (99%) rename lib/crates/fabro-cli/src/commands/{run_engine.rs => run/detached.rs} (96%) rename lib/crates/fabro-cli/src/commands/{ => run}/detached_support.rs (100%) rename lib/crates/fabro-cli/src/commands/{ => run}/diff.rs (100%) rename lib/crates/fabro-cli/src/commands/{run.rs => run/execute.rs} (99%) rename lib/crates/fabro-cli/src/commands/{ => run}/fork.rs (100%) rename lib/crates/fabro-cli/src/commands/{ => run}/logs.rs (100%) create mode 100644 lib/crates/fabro-cli/src/commands/run/mod.rs rename lib/crates/fabro-cli/src/commands/{ => run}/preview.rs (100%) rename lib/crates/fabro-cli/src/commands/{ => run}/resume.rs (98%) rename lib/crates/fabro-cli/src/commands/{ => run}/rewind.rs (100%) rename lib/crates/fabro-cli/src/commands/{ => run}/run_progress.rs (100%) rename lib/crates/fabro-cli/src/commands/{ => run}/ssh.rs (100%) rename lib/crates/fabro-cli/src/commands/{ => run}/start.rs (98%) rename lib/crates/fabro-cli/src/commands/{ => run}/wait.rs (100%) rename lib/crates/fabro-cli/src/commands/{ => runs}/inspect.rs (100%) rename lib/crates/fabro-cli/src/commands/{runs.rs => runs/mod.rs} (95%) diff --git a/lib/crates/fabro-cli/src/args.rs b/lib/crates/fabro-cli/src/args.rs index fcb324783..6ebdc3543 100644 --- a/lib/crates/fabro-cli/src/args.rs +++ b/lib/crates/fabro-cli/src/args.rs @@ -596,13 +596,7 @@ pub(crate) struct UpgradeArgs { } #[derive(Subcommand)] -pub(crate) enum Commands { - /// LLM prompt operations - #[command(hide = true)] - Llm(LlmNamespace), - /// Run an agentic coding session - #[command(hide = true)] - Exec(fabro_agent::cli::AgentArgs), +pub(crate) enum RunCommands { /// Launch a workflow run Run(RunArgs), /// Create a workflow run (allocate run dir, persist spec) @@ -618,8 +612,8 @@ pub(crate) enum Commands { run: String, }, /// Internal: run the engine process (reads run.json from run dir) - #[command(name = "_run_engine", hide = true)] - RunEngine { + #[command(name = "__detached", hide = true)] + Detached { /// Path to the run directory #[arg(long)] run_dir: PathBuf, @@ -627,6 +621,76 @@ pub(crate) enum Commands { #[arg(long)] resume: bool, }, + /// Get a preview URL for a port on a run's sandbox + Preview(PreviewArgs), + /// SSH into a run's Daytona sandbox + Ssh(SshArgs), + /// Show the diff of changes from a workflow run + #[command(hide = true)] + Diff(DiffArgs), + /// View the event log of a workflow run + Logs(LogsArgs), + /// Resume an interrupted workflow run + Resume(ResumeArgs), + /// Rewind a workflow run to an earlier checkpoint + Rewind(RewindArgs), + /// Fork a workflow run from an earlier checkpoint into a new run + Fork(ForkArgs), + /// Block until a workflow run completes + Wait(WaitArgs), +} + +impl RunCommands { + pub(crate) fn name(&self) -> &'static str { + match self { + Self::Run(_) => "run", + Self::Create(_) => "create", + Self::Start { .. } => "start", + Self::Attach { .. } => "attach", + Self::Detached { .. } => "__detached", + Self::Preview(_) => "preview", + Self::Ssh(_) => "ssh", + Self::Diff(_) => "diff", + Self::Logs(_) => "logs", + Self::Resume(_) => "resume", + Self::Rewind(_) => "rewind", + Self::Fork(_) => "fork", + Self::Wait(_) => "wait", + } + } +} + +#[derive(Subcommand)] +pub(crate) enum RunsCommands { + /// List workflow runs + #[command(hide = true)] + Ps(RunsListArgs), + /// Remove one or more workflow runs + Rm(RunsRemoveArgs), + /// Show detailed information about a workflow run + Inspect(InspectArgs), +} + +impl RunsCommands { + pub(crate) fn name(&self) -> &'static str { + match self { + Self::Ps(_) => "ps", + Self::Rm(_) => "rm", + Self::Inspect(_) => "inspect", + } + } +} + +#[derive(Subcommand)] +pub(crate) enum Commands { + /// LLM prompt operations + #[command(hide = true)] + Llm(LlmNamespace), + /// Run an agentic coding session + #[command(hide = true)] + Exec(fabro_agent::cli::AgentArgs), + #[command(flatten)] + RunCmd(RunCommands), /// Validate a workflow Validate(ValidateArgs), /// Render a workflow graph as SVG or PNG @@ -638,17 +702,8 @@ pub(crate) enum Commands { Asset(AssetNamespace), /// Copy files to/from a run's sandbox Cp(CpArgs), - /// Get a preview URL for a port on a run's sandbox - Preview(PreviewArgs), - /// SSH into a run's Daytona sandbox - Ssh(SshArgs), - /// Show the diff of changes from a workflow run - #[command(hide = true)] - Diff(DiffArgs), - /// View the event log of a workflow run - Logs(LogsArgs), - /// Show detailed information about a workflow run - Inspect(InspectArgs), + #[command(flatten)] + RunsCmd(RunsCommands), /// List and test LLM models Model { #[command(subcommand)] @@ -676,11 +731,6 @@ pub(crate) enum Commands { #[arg(long, default_value = "http://localhost:5173")] web_url: String, }, - /// List workflow runs - #[command(hide = true)] - Ps(RunsListArgs), - /// Remove one or more workflow runs - Rm(RunsRemoveArgs), /// Pull request operations Pr(PrNamespace), /// Skill management @@ -688,14 +738,6 @@ pub(crate) enum Commands { Skill(SkillNamespace), /// Manage secrets in ~/.fabro/.env Secret(SecretNamespace), - /// Resume an interrupted workflow run - Resume(ResumeArgs), - /// Rewind a workflow run to an earlier checkpoint - Rewind(RewindArgs), - /// Fork a workflow run from an earlier checkpoint into a new run - Fork(ForkArgs), - /// Block until a workflow run completes - Wait(WaitArgs), /// Workflow operations Workflow(WorkflowNamespace), /// Open the Discord community in the browser @@ -736,20 +778,12 @@ impl Commands { AssetCommand::Cp(_) => "asset cp", }, Self::Exec(_) => "exec", - Self::Run(_) => "run", - Self::Create(_) => "create", - Self::Start { .. } => "start", - Self::Attach { .. } => "attach", - Self::RunEngine { .. } => "_run_engine", + Self::RunCmd(cmd) => cmd.name(), Self::Validate(_) => "validate", Self::Graph(_) => "graph", Self::Parse(_) => "parse", Self::Cp(_) => "cp", - Self::Preview(_) => "preview", - Self::Ssh(_) => "ssh", - Self::Diff(_) => "diff", - Self::Logs(_) => "logs", - Self::Inspect(_) => "inspect", + Self::RunsCmd(cmd) => cmd.name(), Self::Model { command } => match command { Some(fabro_llm::cli::ModelsCommand::List { .. }) => "model list", Some(fabro_llm::cli::ModelsCommand::Test { .. }) => "model test", @@ -764,8 +798,6 @@ impl Commands { }, Self::Init => "init", Self::Install { .. } => "install", - Self::Ps(_) => "ps", - Self::Rm(_) => "rm", Self::Pr(ns) => match &ns.command { PrCommand::Create(_) => "pr create", PrCommand::List(_) => "pr list", @@ -779,10 +811,6 @@ impl Commands { SecretCommand::Rm(_) => "secret rm", SecretCommand::Set(_) => "secret set", }, - Self::Resume(_) => "resume", - Self::Rewind(_) => "rewind", - Self::Fork(_) => "fork", - Self::Wait(_) => "wait", Self::Workflow(ns) => match &ns.command { WorkflowCommand::List(_) => "workflow list", WorkflowCommand::Create(_) => "workflow create", diff --git a/lib/crates/fabro-cli/src/commands/mod.rs b/lib/crates/fabro-cli/src/commands/mod.rs index 2cb5edea7..f3c6c16c1 100644 --- a/lib/crates/fabro-cli/src/commands/mod.rs +++ b/lib/crates/fabro-cli/src/commands/mod.rs @@ -1,35 +1,20 @@ pub mod asset; -pub mod attach; pub mod cp; -pub mod create; -pub(crate) mod detached_support; -pub mod diff; pub mod doctor; pub mod exec; -pub mod fork; pub mod graph; -pub mod inspect; pub mod install; pub mod llm; -pub mod logs; pub mod model; pub mod parse; pub mod pr; -pub mod preview; pub mod provider; pub mod repo; -pub mod resume; -pub mod rewind; pub mod run; -pub mod run_engine; -pub(crate) mod run_progress; pub mod runs; pub mod secret; pub mod skill; -pub mod ssh; -pub mod start; pub mod system; pub mod upgrade; pub mod validate; -pub mod wait; pub mod workflow; diff --git a/lib/crates/fabro-cli/src/commands/attach.rs b/lib/crates/fabro-cli/src/commands/run/attach.rs similarity index 100% rename from lib/crates/fabro-cli/src/commands/attach.rs rename to lib/crates/fabro-cli/src/commands/run/attach.rs diff --git a/lib/crates/fabro-cli/src/commands/create.rs b/lib/crates/fabro-cli/src/commands/run/create.rs similarity index 99% rename from lib/crates/fabro-cli/src/commands/create.rs rename to lib/crates/fabro-cli/src/commands/run/create.rs index 6c3e1bea5..f8e9de490 100644 --- a/lib/crates/fabro-cli/src/commands/create.rs +++ b/lib/crates/fabro-cli/src/commands/run/create.rs @@ -5,7 +5,7 @@ use fabro_sandbox::SandboxProvider; use crate::args::RunArgs; -use super::run::{ +use super::execute::{ apply_execution_overrides, cached_graph_path, default_run_dir, load_workflow_source_input, parse_labels, print_diagnostics_from_error, print_workflow_report_from_persisted, resolve_sandbox_provider, write_run_config_snapshot, ExecutionOverrides, diff --git a/lib/crates/fabro-cli/src/commands/run_engine.rs b/lib/crates/fabro-cli/src/commands/run/detached.rs similarity index 96% rename from lib/crates/fabro-cli/src/commands/run_engine.rs rename to lib/crates/fabro-cli/src/commands/run/detached.rs index 111beed09..36605009e 100644 --- a/lib/crates/fabro-cli/src/commands/run_engine.rs +++ b/lib/crates/fabro-cli/src/commands/run/detached.rs @@ -47,7 +47,7 @@ pub async fn execute(run_dir: PathBuf, resume: bool) -> Result<()> { } let result = if resume { - super::run::resume_from_record( + super::execute::resume_from_record( persisted, run_dir.clone(), cli_config, @@ -57,7 +57,7 @@ pub async fn execute(run_dir: PathBuf, resume: bool) -> Result<()> { ) .await } else { - super::run::run_from_record( + super::execute::run_from_record( persisted, run_dir.clone(), cli_config, diff --git a/lib/crates/fabro-cli/src/commands/detached_support.rs b/lib/crates/fabro-cli/src/commands/run/detached_support.rs similarity index 100% rename from lib/crates/fabro-cli/src/commands/detached_support.rs rename to lib/crates/fabro-cli/src/commands/run/detached_support.rs diff --git a/lib/crates/fabro-cli/src/commands/diff.rs b/lib/crates/fabro-cli/src/commands/run/diff.rs similarity index 100% rename from lib/crates/fabro-cli/src/commands/diff.rs rename to lib/crates/fabro-cli/src/commands/run/diff.rs diff --git a/lib/crates/fabro-cli/src/commands/run.rs b/lib/crates/fabro-cli/src/commands/run/execute.rs similarity index 99% rename from lib/crates/fabro-cli/src/commands/run.rs rename to lib/crates/fabro-cli/src/commands/run/execute.rs index 98f0b7c0f..0a3f3d521 100644 --- a/lib/crates/fabro-cli/src/commands/run.rs +++ b/lib/crates/fabro-cli/src/commands/run/execute.rs @@ -1281,7 +1281,7 @@ pub fn print_run_summary(run_dir: &Path, run_id: &str, styles: &Styles) { return; }; - // PR info from pull_request.json (saved by _run_engine) + // PR info from pull_request.json (saved by __detached) let pr_url = std::fs::read_to_string(run_dir.join("pull_request.json")) .ok() .and_then(|content| { diff --git a/lib/crates/fabro-cli/src/commands/fork.rs b/lib/crates/fabro-cli/src/commands/run/fork.rs similarity index 100% rename from lib/crates/fabro-cli/src/commands/fork.rs rename to lib/crates/fabro-cli/src/commands/run/fork.rs diff --git a/lib/crates/fabro-cli/src/commands/logs.rs b/lib/crates/fabro-cli/src/commands/run/logs.rs similarity index 100% rename from lib/crates/fabro-cli/src/commands/logs.rs rename to lib/crates/fabro-cli/src/commands/run/logs.rs diff --git a/lib/crates/fabro-cli/src/commands/run/mod.rs b/lib/crates/fabro-cli/src/commands/run/mod.rs new file mode 100644 index 000000000..98e9b8b34 --- /dev/null +++ b/lib/crates/fabro-cli/src/commands/run/mod.rs @@ -0,0 +1,81 @@ +use anyhow::Result; + +use crate::args::{GlobalArgs, RunCommands}; + +pub(crate) mod attach; +pub(crate) mod create; +pub(crate) mod detached; +pub(crate) mod detached_support; +pub(crate) mod diff; +pub(crate) mod execute; +pub(crate) mod fork; +pub(crate) mod logs; +pub(crate) mod preview; +pub(crate) mod resume; +pub(crate) mod rewind; +pub(crate) mod run_progress; +pub(crate) mod ssh; +pub(crate) mod start; +pub(crate) mod wait; + +pub async fn dispatch(cmd: RunCommands, globals: &GlobalArgs) -> Result<()> { + match cmd { + RunCommands::Run(args) => execute::execute(args, globals).await, + RunCommands::Create(args) => { + let styles: &'static fabro_util::terminal::Styles = + Box::leak(Box::new(fabro_util::terminal::Styles::detect_stderr())); + let cli_config = crate::cli_config::load_cli_config(None)?; + let (run_id, _run_dir) = create::create_run(&args, cli_config, styles, true).await?; + println!("{run_id}"); + Ok(()) + } + RunCommands::Start { run } => { + let base = fabro_workflows::run_lookup::default_runs_base(); + let run_info = fabro_workflows::run_lookup::resolve_run(&base, &run)?; + let child = start::start_run(&run_info.path, false)?; + eprintln!("Started engine process (PID {})", child.id()); + Ok(()) + } + RunCommands::Attach { run } => { + let styles: &'static fabro_util::terminal::Styles = + Box::leak(Box::new(fabro_util::terminal::Styles::detect_stderr())); + let base = fabro_workflows::run_lookup::default_runs_base(); + let run_info = fabro_workflows::run_lookup::resolve_run(&base, &run)?; + let exit_code = attach::attach_run(&run_info.path, false, styles, None).await?; + if exit_code != std::process::ExitCode::SUCCESS { + std::process::exit(1); + } + Ok(()) + } + RunCommands::Detached { run_dir, resume } => detached::execute(run_dir, resume).await, + RunCommands::Preview(args) => preview::run(args).await, + RunCommands::Ssh(args) => ssh::run(args).await, + RunCommands::Diff(args) => diff::run(args).await, + RunCommands::Logs(args) => { + let styles = fabro_util::terminal::Styles::detect_stdout(); + logs::run(args, &styles) + } + RunCommands::Resume(args) => { + let styles: &'static fabro_util::terminal::Styles = + Box::leak(Box::new(fabro_util::terminal::Styles::detect_stderr())); + #[cfg(feature = "sleep_inhibitor")] + let _sleep_guard = { + let cli_config = crate::cli_config::load_cli_config(None)?; + fabro_beastie::guard(cli_config.prevent_idle_sleep_enabled()) + }; + resume::resume_command(args, styles).await + } + RunCommands::Rewind(args) => { + let styles = fabro_util::terminal::Styles::detect_stderr(); + rewind::run(&args, &styles) + } + RunCommands::Fork(args) => { + let styles = fabro_util::terminal::Styles::detect_stderr(); + fork::run(&args, &styles) + } + RunCommands::Wait(args) => { + let styles = fabro_util::terminal::Styles::detect_stderr(); + wait::run(args, &styles) + } + } +} diff --git a/lib/crates/fabro-cli/src/commands/preview.rs b/lib/crates/fabro-cli/src/commands/run/preview.rs similarity index 100% rename from lib/crates/fabro-cli/src/commands/preview.rs rename to lib/crates/fabro-cli/src/commands/run/preview.rs diff --git a/lib/crates/fabro-cli/src/commands/resume.rs b/lib/crates/fabro-cli/src/commands/run/resume.rs similarity index 98% rename from lib/crates/fabro-cli/src/commands/resume.rs rename to lib/crates/fabro-cli/src/commands/run/resume.rs index 31d3c8e8b..29e275bfe 100644 --- a/lib/crates/fabro-cli/src/commands/resume.rs +++ b/lib/crates/fabro-cli/src/commands/run/resume.rs @@ -73,7 +73,7 @@ pub async fn resume_command(args: ResumeArgs, styles: &'static Styles) -> anyhow println!("{run_id}"); } else { let exit_code = super::attach::attach_run(&run_dir, true, styles, Some(child)).await?; - super::run::print_run_summary(&run_dir, &run_id, styles); + super::execute::print_run_summary(&run_dir, &run_id, styles); if exit_code != std::process::ExitCode::SUCCESS { std::process::exit(1); } diff --git a/lib/crates/fabro-cli/src/commands/rewind.rs b/lib/crates/fabro-cli/src/commands/run/rewind.rs similarity index 100% rename from lib/crates/fabro-cli/src/commands/rewind.rs rename to lib/crates/fabro-cli/src/commands/run/rewind.rs diff --git a/lib/crates/fabro-cli/src/commands/run_progress.rs b/lib/crates/fabro-cli/src/commands/run/run_progress.rs similarity index 100% rename from lib/crates/fabro-cli/src/commands/run_progress.rs rename to lib/crates/fabro-cli/src/commands/run/run_progress.rs diff --git a/lib/crates/fabro-cli/src/commands/ssh.rs b/lib/crates/fabro-cli/src/commands/run/ssh.rs similarity index 100% rename from lib/crates/fabro-cli/src/commands/ssh.rs rename to lib/crates/fabro-cli/src/commands/run/ssh.rs diff --git a/lib/crates/fabro-cli/src/commands/start.rs b/lib/crates/fabro-cli/src/commands/run/start.rs similarity index 98% rename from lib/crates/fabro-cli/src/commands/start.rs rename to lib/crates/fabro-cli/src/commands/run/start.rs index 971aac1bc..513f557cb 100644 --- a/lib/crates/fabro-cli/src/commands/start.rs +++ b/lib/crates/fabro-cli/src/commands/run/start.rs @@ -56,7 +56,7 @@ pub fn start_run(run_dir: &Path, resume: bool) -> Result { return Err(err); } }; - cmd.args(["_run_engine", "--run-dir"]).arg(run_dir); + cmd.args(["__detached", "--run-dir"]).arg(run_dir); if resume { cmd.arg("--resume"); } diff --git a/lib/crates/fabro-cli/src/commands/wait.rs b/lib/crates/fabro-cli/src/commands/run/wait.rs similarity index 100% rename from lib/crates/fabro-cli/src/commands/wait.rs rename to lib/crates/fabro-cli/src/commands/run/wait.rs diff --git a/lib/crates/fabro-cli/src/commands/inspect.rs b/lib/crates/fabro-cli/src/commands/runs/inspect.rs similarity index 100% rename from lib/crates/fabro-cli/src/commands/inspect.rs rename to lib/crates/fabro-cli/src/commands/runs/inspect.rs diff --git a/lib/crates/fabro-cli/src/commands/runs.rs b/lib/crates/fabro-cli/src/commands/runs/mod.rs similarity index 95% rename from lib/crates/fabro-cli/src/commands/runs.rs rename to lib/crates/fabro-cli/src/commands/runs/mod.rs index 877c5dc87..ff80e4b63 100644 --- a/lib/crates/fabro-cli/src/commands/runs.rs +++ b/lib/crates/fabro-cli/src/commands/runs/mod.rs @@ -7,9 +7,22 @@ use cli_table::{print_stdout, Cell, CellStruct, Color, Style, Table}; use fabro_util::terminal::Styles; use tracing::warn; -use crate::args::{RunsListArgs, RunsRemoveArgs}; +use crate::args::{RunsCommands, RunsListArgs, RunsRemoveArgs}; use crate::shared::{color_if, format_duration_ms, tilde_path}; +pub(crate) mod inspect; + +pub async fn dispatch(cmd: RunsCommands) -> Result<()> { + match cmd { + RunsCommands::Ps(args) => { + let styles = fabro_util::terminal::Styles::detect_stdout(); + list_command(&args, &styles) + } + RunsCommands::Rm(args) => remove_command(&args).await, + RunsCommands::Inspect(args) => inspect::run(&args), + } +} + pub fn list_command(args: &RunsListArgs, styles: &Styles) -> Result<()> { let base = fabro_workflows::run_lookup::default_runs_base(); let runs = fabro_workflows::run_lookup::scan_runs(&base)?; diff --git a/lib/crates/fabro-cli/src/main.rs b/lib/crates/fabro-cli/src/main.rs index f59709695..9cb8b0d4e 100644 --- a/lib/crates/fabro-cli/src/main.rs +++ b/lib/crates/fabro-cli/src/main.rs @@ -140,8 +140,7 @@ async fn main_inner() -> (String, Result<()>) { let upgrade_handle = if matches!( command.as_ref(), - Commands::Run(_) - | Commands::Create(_) + Commands::RunCmd(RunCommands::Run(_) | RunCommands::Create(_)) | Commands::Exec(_) | Commands::Repo(_) | Commands::Init @@ -156,35 +155,7 @@ async fn main_inner() -> (String, Result<()>) { match *command { Commands::Llm(ns) => commands::llm::dispatch(ns, &globals).await?, Commands::Exec(args) => commands::exec::execute(args, &globals).await?, - Commands::Run(args) => commands::run::execute(args, &globals).await?, - Commands::Create(args) => { - let styles: &'static fabro_util::terminal::Styles = - 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, styles, true).await?; - println!("{run_id}"); - } - Commands::Start { run } => { - let base = fabro_workflows::run_lookup::default_runs_base(); - let run_info = fabro_workflows::run_lookup::resolve_run(&base, &run)?; - let child = commands::start::start_run(&run_info.path, false)?; - eprintln!("Started engine process (PID {})", child.id()); - } - Commands::Attach { run } => { - let styles: &'static fabro_util::terminal::Styles = - Box::leak(Box::new(fabro_util::terminal::Styles::detect_stderr())); - let base = fabro_workflows::run_lookup::default_runs_base(); - let run_info = fabro_workflows::run_lookup::resolve_run(&base, &run)?; - let exit_code = - commands::attach::attach_run(&run_info.path, false, styles, None).await?; - if exit_code != std::process::ExitCode::SUCCESS { - std::process::exit(1); - } - } - Commands::RunEngine { run_dir, resume } => { - commands::run_engine::execute(run_dir, resume).await?; - } + Commands::RunCmd(cmd) => commands::run::dispatch(cmd, &globals).await?, Commands::Validate(args) => { let styles = fabro_util::terminal::Styles::detect_stderr(); commands::validate::run(&args, &styles)?; @@ -200,22 +171,7 @@ async fn main_inner() -> (String, Result<()>) { Commands::Cp(args) => { commands::cp::cp_command(args).await?; } - Commands::Preview(args) => { - commands::preview::run(args).await?; - } - Commands::Ssh(args) => { - commands::ssh::run(args).await?; - } - Commands::Diff(args) => { - commands::diff::run(args).await?; - } - Commands::Logs(args) => { - let styles = fabro_util::terminal::Styles::detect_stdout(); - commands::logs::run(args, &styles)?; - } - Commands::Inspect(args) => { - commands::inspect::run(&args)?; - } + Commands::RunsCmd(cmd) => commands::runs::dispatch(cmd).await?, Commands::Model { command } => commands::model::execute(command, &globals).await?, #[cfg(feature = "server")] Commands::Serve(args) => { @@ -246,37 +202,8 @@ async fn main_inner() -> (String, Result<()>) { Commands::Install { web_url } => { commands::install::run_install(&web_url).await?; } - Commands::Ps(args) => { - let styles = fabro_util::terminal::Styles::detect_stdout(); - commands::runs::list_command(&args, &styles)?; - } - Commands::Rm(args) => { - commands::runs::remove_command(&args).await?; - } Commands::Pr(ns) => commands::pr::dispatch(ns).await?, Commands::Secret(ns) => commands::secret::dispatch(ns)?, - Commands::Resume(args) => { - let styles: &'static fabro_util::terminal::Styles = - Box::leak(Box::new(fabro_util::terminal::Styles::detect_stderr())); - #[cfg(feature = "sleep_inhibitor")] - let _sleep_guard = { - let cli_config = cli_config::load_cli_config(None)?; - fabro_beastie::guard(cli_config.prevent_idle_sleep_enabled()) - }; - commands::resume::resume_command(args, styles).await?; - } - Commands::Rewind(args) => { - let styles = fabro_util::terminal::Styles::detect_stderr(); - commands::rewind::run(&args, &styles)?; - } - Commands::Fork(args) => { - let styles = fabro_util::terminal::Styles::detect_stderr(); - commands::fork::run(&args, &styles)?; - } - Commands::Wait(args) => { - let styles = fabro_util::terminal::Styles::detect_stderr(); - commands::wait::run(args, &styles)?; - } Commands::Workflow(ns) => commands::workflow::dispatch(ns)?, Commands::Skill(ns) => commands::skill::dispatch(ns)?, Commands::Upgrade(args) => { @@ -358,7 +285,7 @@ mod tests { let cli = Cli::try_parse_from(["fabro", "create", "my-workflow.toml", "--goal", "test"]) .expect("should parse"); match *cli.command { - Commands::Create(args) => { + Commands::RunCmd(RunCommands::Create(args)) => { assert_eq!( args.workflow.as_deref(), Some(std::path::Path::new("my-workflow.toml")) @@ -373,7 +300,7 @@ mod tests { fn parse_start_command() { let cli = Cli::try_parse_from(["fabro", "start", "ABC123"]).expect("should parse"); match *cli.command { - Commands::Start { run } => { + Commands::RunCmd(RunCommands::Start { run }) => { assert_eq!(run, "ABC123"); } _ => panic!("unexpected command variant"), @@ -384,7 +311,7 @@ mod tests { fn parse_attach_command() { let cli = Cli::try_parse_from(["fabro", "attach", "ABC123"]).expect("should parse"); match *cli.command { - Commands::Attach { run } => { + Commands::RunCmd(RunCommands::Attach { run }) => { assert_eq!(run, "ABC123"); } _ => panic!("unexpected command variant"), @@ -392,11 +319,11 @@ mod tests { } #[test] - fn parse_run_engine_command() { - let cli = Cli::try_parse_from(["fabro", "_run_engine", "--run-dir", "/tmp/runs/test"]) + fn parse_detached_command() { + let cli = Cli::try_parse_from(["fabro", "__detached", "--run-dir", "/tmp/runs/test"]) .expect("should parse"); match *cli.command { - Commands::RunEngine { run_dir, resume } => { + Commands::RunCmd(RunCommands::Detached { run_dir, resume }) => { assert_eq!(run_dir, std::path::PathBuf::from("/tmp/runs/test")); assert!(!resume); } @@ -405,17 +332,17 @@ mod tests { } #[test] - fn parse_run_engine_with_resume() { + fn parse_detached_with_resume() { let cli = Cli::try_parse_from([ "fabro", - "_run_engine", + "__detached", "--run-dir", "/tmp/runs/test", "--resume", ]) .expect("should parse"); match *cli.command { - Commands::RunEngine { run_dir, resume } => { + Commands::RunCmd(RunCommands::Detached { run_dir, resume }) => { assert_eq!(run_dir, std::path::PathBuf::from("/tmp/runs/test")); assert!(resume); } diff --git a/lib/crates/fabro-cli/tests/cli.rs b/lib/crates/fabro-cli/tests/cli.rs index 41fe27835..825250fcb 100644 --- a/lib/crates/fabro-cli/tests/cli.rs +++ b/lib/crates/fabro-cli/tests/cli.rs @@ -880,11 +880,11 @@ fn start_by_workflow_name_prefers_newly_created_submitted_run() { ); } -// Bug 2: _run_engine should use cached graph.fabro, not run.json working_directory. +// Bug 2: __detached should use cached graph.fabro, not run.json working_directory. // When the original workflow file is deleted between create and start, // the engine should read the snapshot saved at create time. #[test] -fn bug2_run_engine_uses_cached_graph_not_original_path() { +fn bug2_detached_uses_cached_graph_not_original_path() { let dir = tempfile::tempdir().unwrap(); let run_dir = dir.path().join("run"); std::fs::create_dir_all(&run_dir).unwrap(); @@ -928,9 +928,9 @@ digraph G { // The cached graph snapshot saved by `fabro create` std::fs::write(run_dir.join("graph.fabro"), dot).unwrap(); - // _run_engine should use graph.fabro and never reference the deleted file. + // __detached should use graph.fabro and never reference the deleted file. let output = arc() - .args(["_run_engine", "--run-dir", run_dir.to_str().unwrap()]) + .args(["__detached", "--run-dir", run_dir.to_str().unwrap()]) .env("NO_COLOR", "1") .timeout(std::time::Duration::from_secs(15)) .output() @@ -945,7 +945,7 @@ digraph G { } #[test] -fn bug4_run_engine_resume_rejects_completed_run_without_mutating_it() { +fn bug4_detached_resume_rejects_completed_run_without_mutating_it() { let home = tempfile::tempdir().unwrap(); let project = tempfile::tempdir().unwrap(); let workflow_path = project.path().join("workflow.fabro"); @@ -1005,7 +1005,7 @@ digraph Test { arc() .env("HOME", home.path()) - .args(["_run_engine", "--run-dir", &run_dir, "--resume"]) + .args(["__detached", "--run-dir", &run_dir, "--resume"]) .timeout(std::time::Duration::from_secs(10)) .assert() .failure()