diff --git a/crates/maestro-tui/src/cli.rs b/crates/maestro-tui/src/cli.rs index 6737f47..b0731d6 100644 --- a/crates/maestro-tui/src/cli.rs +++ b/crates/maestro-tui/src/cli.rs @@ -2,7 +2,9 @@ #[derive(Debug, clap::Args)] pub struct TuiArgs { - /// Override the local daemon's HTTP base URL (default `http://127.0.0.1:7070`). + /// Override the local daemon's HTTP base URL. Defaults to + /// `[cli].daemon_url`, then the local `[daemon].bind_addr`, then + /// `http://127.0.0.1:7070`. #[arg(long, env = "MAESTRO_DAEMON_URL")] pub daemon_url: Option, } diff --git a/crates/maestro-tui/src/lib.rs b/crates/maestro-tui/src/lib.rs index 66236b0..5e21af7 100644 --- a/crates/maestro-tui/src/lib.rs +++ b/crates/maestro-tui/src/lib.rs @@ -40,9 +40,11 @@ use crate::daemon_link::DaemonLink; /// `TuiArgs` plus any global flags. #[derive(Debug, Clone)] pub struct RunConfig { - /// HTTP base URL of the local daemon, e.g. `http://127.0.0.1:7070`. - /// No trailing slash. - pub daemon_url: String, + /// Explicit `--daemon-url` / `$MAESTRO_DAEMON_URL` override. When `None` + /// the URL is resolved from the config file the same way the CLI resolves + /// it: `[cli].daemon_url`, then the local `[daemon].bind_addr`, then + /// `maestro_config::DEFAULT_DAEMON_URL`. + pub daemon_url: Option, /// Explicit `--config ` override from the umbrella binary's global /// flag. When `None`, [`maestro_config::default_config_path`] picks the /// default (`$MAESTRO_CONFIG` or `~/.config/maestro/config.toml`). @@ -66,7 +68,25 @@ pub enum TuiError { pub async fn run(cfg: RunConfig) -> Result<(), TuiError> { terminal::install_panic_hook(); - let base_url = cfg.daemon_url.trim_end_matches('/').to_string(); + // Load runtime config first: it carries the daemon URL as well as the UI + // settings. Explicit `--config ` wins, then `$MAESTRO_CONFIG`, then + // the platform default. Missing file is fine — we fall back to shipped + // defaults. + let cfg_path = cfg.config_path.clone().map(Ok).unwrap_or_else(|| { + maestro_config::default_config_path().map_err(|e| TuiError::Config(e.to_string())) + }); + let cfg_file = match cfg_path { + Ok(path) => maestro_config::MaestroConfigFile::load(&path) + .map_err(|e| TuiError::Config(e.to_string()))?, + Err(_) => maestro_config::MaestroConfigFile::default(), + }; + + // Same resolution order the CLI uses, so a host that moved `bind_addr` off + // the default port stays reachable from the TUI without a second setting. + let base_url = cfg_file + .resolve_daemon_url(cfg.daemon_url.clone()) + .trim_end_matches('/') + .to_string(); // Health check — fail fast if no daemon is reachable. health_check(&DaemonClient::with_timeouts( @@ -77,18 +97,6 @@ pub async fn run(cfg: RunConfig) -> Result<(), TuiError> { .await?; let daemon = DaemonClient::with_timeouts(&base_url, REQUEST_TIMEOUT, REQUEST_TIMEOUT); - - // Load runtime config: explicit `--config ` wins, then - // `$MAESTRO_CONFIG`, then the platform default. Missing file is fine — - // we fall back to shipped defaults. - let cfg_path = cfg.config_path.clone().map(Ok).unwrap_or_else(|| { - maestro_config::default_config_path().map_err(|e| TuiError::Config(e.to_string())) - }); - let cfg_file = match cfg_path { - Ok(path) => maestro_config::MaestroConfigFile::load(&path) - .map_err(|e| TuiError::Config(e.to_string()))?, - Err(_) => maestro_config::MaestroConfigFile::default(), - }; let tui_cfg = TuiConfig::load(&cfg_file.tui).map_err(|e| TuiError::Config(e.to_string()))?; palette::set_active(tui_cfg.palette); diff --git a/crates/maestro/src/main.rs b/crates/maestro/src/main.rs index 9dfc11b..870c05f 100644 --- a/crates/maestro/src/main.rs +++ b/crates/maestro/src/main.rs @@ -169,12 +169,8 @@ async fn dispatch(cli: Cli) -> Result<(), Box> { Command::Daemon { cmd } => maestro_daemon::cli::dispatch(cli.config, cmd).await?, #[cfg(feature = "tui")] Command::Tui(args) => { - let daemon_url = args - .daemon_url - .or(cli.daemon_url) - .unwrap_or_else(|| "http://127.0.0.1:7070".to_string()); maestro_tui::run(maestro_tui::RunConfig { - daemon_url, + daemon_url: args.daemon_url.or(cli.daemon_url), config_path: cli.config, }) .await?