Rename *config* variables/params that hold *Settings types

Local variables and function parameters named with "config" but holding
*Settings types (FabroSettings, TlsSettings, ApiSettings, LlmSettings)
are renamed to use "settings" for consistency with the type system.
Module paths (cli_config::) and struct fields are unchanged.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Bryan Helmkamp 2026-03-28 15:15:15 -04:00
parent 52d0478a47
commit 2eb39d368c
40 changed files with 160 additions and 152 deletions

View file

@ -69,14 +69,14 @@ pub fn decode_pem_env(name: &str, value: &str) -> String {
///
/// Call this once at startup before serving requests. Panics if the
/// configuration is invalid (JWT strategy but no public key, or mTLS without TLS config).
pub fn resolve_auth_mode(api_config: &ApiSettings, allowed_usernames: &[String]) -> AuthMode {
pub fn resolve_auth_mode(api_settings: &ApiSettings, allowed_usernames: &[String]) -> AuthMode {
use fabro_config::server::ApiAuthStrategy;
if api_config.authentication_strategies.is_empty() {
if api_settings.authentication_strategies.is_empty() {
warn!("No authentication strategies configured; all requests will be rejected");
}
let strategies = api_config
let strategies = api_settings
.authentication_strategies
.iter()
.map(|s| match s {
@ -98,7 +98,7 @@ pub fn resolve_auth_mode(api_config: &ApiSettings, allowed_usernames: &[String])
}
ApiAuthStrategy::Mtls => {
assert!(
api_config.tls.is_some(),
api_settings.tls.is_some(),
"mTLS authentication strategy requires [api.tls] configuration with cert, key, and ca"
);
AuthStrategy::Mtls

View file

@ -93,17 +93,17 @@ pub async fn serve_command(args: ServeArgs, styles: &'static Styles) -> anyhow::
let data_dir = resolve_storage_dir(&server_settings);
// Shared config for live reloading
let shared_config = Arc::new(RwLock::new(server_settings));
let shared_settings = Arc::new(RwLock::new(server_settings));
// CLI overrides take precedence over config file values, even after reload
let cli_model = args.model;
let cli_provider = args.provider;
// Build registry factory that reads live config
let config_for_factory = Arc::clone(&shared_config);
let settings_for_factory = Arc::clone(&shared_settings);
let factory = move || {
let (model, provider_enum) = resolve_model_provider(
&config_for_factory,
&settings_for_factory,
cli_model.as_deref(),
cli_provider.as_deref(),
);
@ -120,7 +120,7 @@ pub async fn serve_command(args: ServeArgs, styles: &'static Styles) -> anyhow::
fabro_db::initialize_db(&db).await?;
let (auth_mode, client_auth, max_concurrent_runs) = {
let cfg = shared_config.read().expect("config lock poisoned");
let cfg = shared_settings.read().expect("config lock poisoned");
let api = cfg.api.clone().unwrap_or_default();
let allowed_usernames = cfg
.web
@ -137,7 +137,7 @@ pub async fn serve_command(args: ServeArgs, styles: &'static Styles) -> anyhow::
};
let git_author = {
let cfg = shared_config.read().expect("config lock poisoned");
let cfg = shared_settings.read().expect("config lock poisoned");
let author = cfg.git_author();
GitAuthor::from_options(
author.and_then(|a| a.name.clone()),
@ -145,7 +145,7 @@ pub async fn serve_command(args: ServeArgs, styles: &'static Styles) -> anyhow::
)
};
let hooks = {
let cfg = shared_config.read().expect("config lock poisoned");
let cfg = shared_settings.read().expect("config lock poisoned");
cfg.hooks.clone()
};
let state = create_app_state_with_options(
@ -177,7 +177,7 @@ pub async fn serve_command(args: ServeArgs, styles: &'static Styles) -> anyhow::
// Optionally start webhook listener
let webhook_app_id = {
let cfg = shared_config.read().expect("config lock poisoned");
let cfg = shared_settings.read().expect("config lock poisoned");
cfg.git
.as_ref()
.and_then(|g| g.webhooks.as_ref().and(g.app_id.as_ref()))
@ -206,7 +206,7 @@ pub async fn serve_command(args: ServeArgs, styles: &'static Styles) -> anyhow::
};
// Spawn config polling task
let config_for_poll = Arc::clone(&shared_config);
let settings_for_poll = Arc::clone(&shared_settings);
let config_path_for_poll = config_path.clone();
tokio::spawn(async move {
let mut interval = interval(Duration::from_secs(5));
@ -214,14 +214,14 @@ pub async fn serve_command(args: ServeArgs, styles: &'static Styles) -> anyhow::
loop {
interval.tick().await;
match load_server_settings(config_path_for_poll.as_deref()) {
Ok(new_config) => {
Ok(new_settings) => {
let changed = {
let cfg = config_for_poll.read().expect("config lock poisoned");
*cfg != new_config
let cfg = settings_for_poll.read().expect("config lock poisoned");
*cfg != new_settings
};
if changed {
let mut cfg = config_for_poll.write().expect("config lock poisoned");
*cfg = new_config;
let mut cfg = settings_for_poll.write().expect("config lock poisoned");
*cfg = new_settings;
info!("Server config reloaded");
}
}
@ -233,16 +233,16 @@ pub async fn serve_command(args: ServeArgs, styles: &'static Styles) -> anyhow::
});
// Branch: TLS or plain HTTP
let tls_config = shared_config
let tls_settings = shared_settings
.read()
.expect("config lock poisoned")
.api
.as_ref()
.and_then(|a| a.tls.clone());
if let Some(ref tls_config) = tls_config {
if let Some(ref tls_settings) = tls_settings {
let client_auth = client_auth.unwrap();
let rustls_config = build_rustls_config(tls_config, client_auth);
let rustls_config = build_rustls_config(tls_settings, client_auth);
let tls_acceptor = tokio_rustls::TlsAcceptor::from(rustls_config);
info!("TLS enabled");
@ -262,11 +262,11 @@ pub async fn serve_command(args: ServeArgs, styles: &'static Styles) -> anyhow::
/// Resolve model and provider from shared config, with CLI overrides taking precedence.
fn resolve_model_provider(
shared_config: &RwLock<FabroSettings>,
shared_settings: &RwLock<FabroSettings>,
cli_model: Option<&str>,
cli_provider: Option<&str>,
) -> (String, Provider) {
let cfg = shared_config.read().expect("config lock poisoned");
let cfg = shared_settings.read().expect("config lock poisoned");
let config_provider = cfg.llm.as_ref().and_then(|l| l.provider.as_deref());
let config_model = cfg.llm.as_ref().and_then(|l| l.model.as_deref());

View file

@ -23,9 +23,12 @@ pub enum ClientAuth {
}
/// Build a rustls `ServerConfig` from the `[api.tls]` configuration.
pub fn build_rustls_config(tls_config: &TlsSettings, client_auth: ClientAuth) -> Arc<ServerConfig> {
let certs = load_certs(&tls_config.cert);
let key = load_private_key(&tls_config.key);
pub fn build_rustls_config(
tls_settings: &TlsSettings,
client_auth: ClientAuth,
) -> Arc<ServerConfig> {
let certs = load_certs(&tls_settings.cert);
let key = load_private_key(&tls_settings.key);
let config = match client_auth {
ClientAuth::None => ServerConfig::builder()
@ -33,7 +36,7 @@ pub fn build_rustls_config(tls_config: &TlsSettings, client_auth: ClientAuth) ->
.with_single_cert(certs, key)
.expect("invalid server certificate or key"),
ClientAuth::Required | ClientAuth::Optional => {
let ca_certs = load_certs(&tls_config.ca);
let ca_certs = load_certs(&tls_settings.ca);
let mut root_store = rustls::RootCertStore::empty();
for cert in ca_certs {
root_store

View file

@ -181,14 +181,14 @@ mod mtls_e2e {
/// Start a TLS server on a random port, returning the bound address.
async fn start_tls_server(
tls_config: &TlsSettings,
tls_settings: &TlsSettings,
client_auth: ClientAuth,
auth_mode: AuthMode,
) -> std::net::SocketAddr {
let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
let addr = listener.local_addr().unwrap();
let rustls_config = build_rustls_config(tls_config, client_auth);
let rustls_config = build_rustls_config(tls_settings, client_auth);
let tls_acceptor = tokio_rustls::TlsAcceptor::from(rustls_config);
let state = create_app_state(test_db().await, test_llm_spec);
@ -236,14 +236,14 @@ mod mtls_e2e {
let dir = tempfile::tempdir().unwrap();
let pki = generate_pki(dir.path(), "TestCA", "localhost", "testuser");
let tls_config = TlsSettings {
let tls_settings = TlsSettings {
cert: pki.server_cert.clone(),
key: pki.server_key.clone(),
ca: pki.ca_cert.clone(),
};
let auth_mode = AuthMode::Strategies(vec![AuthStrategy::Mtls]);
let addr = start_tls_server(&tls_config, ClientAuth::Required, auth_mode).await;
let addr = start_tls_server(&tls_settings, ClientAuth::Required, auth_mode).await;
let client = build_client(&pki.ca_cert, Some(&pki.client_cert), Some(&pki.client_key));
@ -262,14 +262,14 @@ mod mtls_e2e {
let dir = tempfile::tempdir().unwrap();
let pki = generate_pki(dir.path(), "TestCA", "localhost", "testuser");
let tls_config = TlsSettings {
let tls_settings = TlsSettings {
cert: pki.server_cert.clone(),
key: pki.server_key.clone(),
ca: pki.ca_cert.clone(),
};
let auth_mode = AuthMode::Strategies(vec![AuthStrategy::Mtls]);
let addr = start_tls_server(&tls_config, ClientAuth::Required, auth_mode).await;
let addr = start_tls_server(&tls_settings, ClientAuth::Required, auth_mode).await;
// Generate a DIFFERENT CA and client cert signed by it
let wrong_dir = dir.path().join("wrong_ca");
@ -303,7 +303,7 @@ mod mtls_e2e {
let dir = tempfile::tempdir().unwrap();
let pki = generate_pki(dir.path(), "TestCA", "localhost", "testuser");
let tls_config = TlsSettings {
let tls_settings = TlsSettings {
cert: pki.server_cert.clone(),
key: pki.server_key.clone(),
ca: pki.ca_cert.clone(),
@ -311,7 +311,7 @@ mod mtls_e2e {
// mTLS is the ONLY strategy → client cert is required at TLS level
let auth_mode = AuthMode::Strategies(vec![AuthStrategy::Mtls]);
let addr = start_tls_server(&tls_config, ClientAuth::Required, auth_mode).await;
let addr = start_tls_server(&tls_settings, ClientAuth::Required, auth_mode).await;
// Client trusts the server CA but presents NO client cert
let client = build_client(&pki.ca_cert, None, None);
@ -378,7 +378,7 @@ mod mtls_e2e {
let dir = tempfile::tempdir().unwrap();
let pki = generate_pki(dir.path(), "TestCA", "localhost", "testuser");
let tls_config = TlsSettings {
let tls_settings = TlsSettings {
cert: pki.server_cert.clone(),
key: pki.server_key.clone(),
ca: pki.ca_cert.clone(),
@ -395,7 +395,7 @@ mod mtls_e2e {
allowed_usernames: vec!["brynary".to_string()],
},
]);
let addr = start_tls_server(&tls_config, ClientAuth::Optional, auth_mode).await;
let addr = start_tls_server(&tls_settings, ClientAuth::Optional, auth_mode).await;
// Client trusts the server CA but presents NO client cert
let client = build_client(&pki.ca_cert, None, None);

View file

@ -28,11 +28,13 @@ const DEFAULT_SERVER_URL: &str = "http://localhost:3000";
pub fn resolve_mode(
cli_mode: Option<ExecutionMode>,
cli_server_url: Option<&str>,
config: &FabroSettings,
settings: &FabroSettings,
) -> ResolvedMode {
let mode = cli_mode.or_else(|| config.mode.clone()).unwrap_or_default();
let mode = cli_mode
.or_else(|| settings.mode.clone())
.unwrap_or_default();
let server_defaults = config.server.as_ref();
let server_defaults = settings.server.as_ref();
let server_base_url = cli_server_url
.map(String::from)
@ -90,8 +92,8 @@ mod tests {
#[test]
fn resolve_mode_defaults_to_standalone() {
let config = FabroSettings::default();
let resolved = resolve_mode(None, None, &config);
let settings = FabroSettings::default();
let resolved = resolve_mode(None, None, &settings);
assert_eq!(resolved.mode, ExecutionMode::Standalone);
assert_eq!(resolved.server_base_url, DEFAULT_SERVER_URL);
assert_eq!(resolved.tls, None);
@ -99,7 +101,7 @@ mod tests {
#[test]
fn resolve_mode_config_overrides_default() {
let config = FabroSettings {
let settings = FabroSettings {
mode: Some(ExecutionMode::Server),
server: Some(ServerSettings {
base_url: Some("https://config.example.com".to_string()),
@ -107,14 +109,14 @@ mod tests {
}),
..FabroSettings::default()
};
let resolved = resolve_mode(None, None, &config);
let resolved = resolve_mode(None, None, &settings);
assert_eq!(resolved.mode, ExecutionMode::Server);
assert_eq!(resolved.server_base_url, "https://config.example.com");
}
#[test]
fn resolve_mode_cli_overrides_config() {
let config = FabroSettings {
let settings = FabroSettings {
mode: Some(ExecutionMode::Standalone),
server: Some(ServerSettings {
base_url: Some("https://config.example.com".to_string()),
@ -125,7 +127,7 @@ mod tests {
let resolved = resolve_mode(
Some(ExecutionMode::Server),
Some("https://cli.example.com"),
&config,
&settings,
);
assert_eq!(resolved.mode, ExecutionMode::Server);
assert_eq!(resolved.server_base_url, "https://cli.example.com");
@ -133,14 +135,14 @@ mod tests {
#[test]
fn resolve_mode_cli_url_overrides_config_url() {
let config = FabroSettings {
let settings = FabroSettings {
server: Some(ServerSettings {
base_url: Some("https://config.example.com".to_string()),
tls: None,
}),
..FabroSettings::default()
};
let resolved = resolve_mode(None, Some("https://cli.example.com"), &config);
let resolved = resolve_mode(None, Some("https://cli.example.com"), &settings);
assert_eq!(resolved.server_base_url, "https://cli.example.com");
}
@ -151,14 +153,14 @@ mod tests {
key: PathBuf::from("key.pem"),
ca: PathBuf::from("ca.pem"),
};
let config = FabroSettings {
let settings = FabroSettings {
server: Some(ServerSettings {
base_url: None,
tls: Some(tls.clone()),
}),
..FabroSettings::default()
};
let resolved = resolve_mode(None, None, &config);
let resolved = resolve_mode(None, None, &settings);
assert_eq!(resolved.tls, Some(tls));
}
}

View file

@ -11,8 +11,8 @@ use crate::cli_config::load_cli_settings;
use crate::shared::split_run_path;
pub(super) fn cp_command(args: &AssetCpArgs) -> Result<()> {
let cli_config = load_cli_settings(None)?;
let base = runs_base(&cli_config.storage_dir());
let cli_settings = load_cli_settings(None)?;
let base = runs_base(&cli_settings.storage_dir());
let (run_id, asset_path) = parse_source(&args.source);
let run = resolve_run(&base, run_id)?;
let runtime_state = RuntimeState::new(&run.path);

View file

@ -9,8 +9,8 @@ use crate::cli_config::load_cli_settings;
use crate::shared::format_size;
pub(super) fn list_command(args: &AssetListArgs) -> Result<()> {
let cli_config = load_cli_settings(None)?;
let base = runs_base(&cli_config.storage_dir());
let cli_settings = load_cli_settings(None)?;
let base = runs_base(&cli_settings.storage_dir());
let run = resolve_run(&base, &args.run_id)?;
let runtime_state = RuntimeState::new(&run.path);
let entries = scan_assets(&runtime_state.assets_dir(), args.node.as_deref())?;

View file

@ -938,7 +938,7 @@ pub(crate) async fn run_doctor(verbose: bool, live: bool) -> i32 {
spinner.enable_steady_tick(std::time::Duration::from_millis(80));
// Gather state
let cli_config = load_cli_settings(None).unwrap_or_default();
let cli_settings = load_cli_settings(None).unwrap_or_default();
let config_path = dirs::home_dir().map(|h| h.join(".fabro").join("cli.toml"));
let config_exists = config_path.as_ref().is_some_and(|p| p.exists());
@ -953,11 +953,11 @@ pub(crate) async fn run_doctor(verbose: bool, live: bool) -> i32 {
let daytona_configured = std::env::var("DAYTONA_API_KEY").is_ok();
#[cfg(feature = "server")]
let server_config = fabro_config::server::load_server_settings(None).unwrap_or_default();
let server_settings = fabro_config::server::load_server_settings(None).unwrap_or_default();
#[cfg(feature = "server")]
let api_status = {
let api = server_config.api.clone().unwrap_or_default();
let api = server_settings.api.clone().unwrap_or_default();
ApiStatus {
base_url: api.base_url.clone(),
authentication_strategies: api.authentication_strategies.clone(),
@ -966,7 +966,7 @@ pub(crate) async fn run_doctor(verbose: bool, live: bool) -> i32 {
#[cfg(feature = "server")]
let web_status = {
let web = server_config.web.clone().unwrap_or_default();
let web = server_settings.web.clone().unwrap_or_default();
WebStatus {
url: web.url.clone(),
auth_provider: web.auth.provider.clone(),
@ -975,15 +975,15 @@ pub(crate) async fn run_doctor(verbose: bool, live: bool) -> i32 {
};
#[cfg(feature = "server")]
let server_git = server_config.git.clone().unwrap_or_default();
let server_git = server_settings.git.clone().unwrap_or_default();
#[cfg(feature = "server")]
let server_api = server_config.api.clone().unwrap_or_default();
let server_api = server_settings.api.clone().unwrap_or_default();
#[cfg(feature = "server")]
let server_web = server_config.web.clone().unwrap_or_default();
let server_web = server_settings.web.clone().unwrap_or_default();
let git_app_id = cli_config.app_id().map(str::to_owned);
let git_app_id = cli_settings.app_id().map(str::to_owned);
let private_key_raw = std::env::var("GITHUB_APP_PRIVATE_KEY").ok();
let sign_result = match (&git_app_id, &private_key_raw) {
(Some(app_id), Some(raw)) => {
@ -1011,7 +1011,7 @@ pub(crate) async fn run_doctor(verbose: bool, live: bool) -> i32 {
};
let github_status = GithubAppStatus {
app_id: git_app_id,
slug: cli_config.slug().map(str::to_owned),
slug: cli_settings.slug().map(str::to_owned),
private_key_set: private_key_raw.is_some(),
sign_result,
#[cfg(feature = "server")]

View file

@ -9,10 +9,10 @@ use crate::args::GlobalArgs;
use crate::cli_config;
pub(crate) async fn execute(mut args: AgentArgs, globals: &GlobalArgs) -> Result<()> {
let cli_config = cli_config::load_cli_settings(None)?;
let cli_settings = cli_config::load_cli_settings(None)?;
#[cfg(feature = "sleep_inhibitor")]
let _sleep_guard = crate::sleep_inhibitor::guard(cli_config.prevent_idle_sleep_enabled());
let exec_defaults = cli_config.exec.as_ref();
let _sleep_guard = crate::sleep_inhibitor::guard(cli_settings.prevent_idle_sleep_enabled());
let exec_defaults = cli_settings.exec.as_ref();
args.apply_cli_defaults(
exec_defaults.and_then(|a| a.provider.as_deref()),
exec_defaults.and_then(|a| a.model.as_deref()),
@ -23,9 +23,9 @@ pub(crate) async fn execute(mut args: AgentArgs, globals: &GlobalArgs) -> Result
let resolved = cli_config::resolve_mode(
globals.mode.clone(),
globals.server_url.as_deref(),
&cli_config,
&cli_settings,
);
let mcp_servers: Vec<McpServerConfig> = cli_config
let mcp_servers: Vec<McpServerConfig> = cli_settings
.mcp_servers
.into_iter()
.map(|(name, entry): (String, McpServerEntry)| entry.into_config(name))

View file

@ -920,18 +920,21 @@ mod tests {
#[cfg(feature = "server")]
fn config_toml_roundtrips() {
let toml_str = format_config_toml("brynary");
let config: fabro_config::FabroSettings =
let settings: fabro_config::FabroSettings =
toml::from_str(&toml_str).expect("config should parse");
assert_eq!(config.web.unwrap().auth.allowed_usernames, vec!["brynary"]);
assert_eq!(
settings.web.unwrap().auth.allowed_usernames,
vec!["brynary"]
);
}
#[test]
#[cfg(feature = "server")]
fn config_toml_has_auth_strategies() {
let toml_str = format_config_toml("alice");
let config: fabro_config::FabroSettings = toml::from_str(&toml_str).unwrap();
let settings: fabro_config::FabroSettings = toml::from_str(&toml_str).unwrap();
assert_eq!(
config.api.unwrap().authentication_strategies,
settings.api.unwrap().authentication_strategies,
vec![
fabro_config::server::ApiAuthStrategy::Jwt,
fabro_config::server::ApiAuthStrategy::Mtls,
@ -944,8 +947,8 @@ mod tests {
fn config_toml_has_tls_paths() {
use std::path::PathBuf;
let toml_str = format_config_toml("bob");
let config: fabro_config::FabroSettings = toml::from_str(&toml_str).unwrap();
let tls = config.api.unwrap().tls.expect("tls should be set");
let settings: fabro_config::FabroSettings = toml::from_str(&toml_str).unwrap();
let tls = settings.api.unwrap().tls.expect("tls should be set");
assert_eq!(tls.cert, PathBuf::from("~/.fabro/certs/server.crt"));
assert_eq!(tls.key, PathBuf::from("~/.fabro/certs/server.key"));
assert_eq!(tls.ca, PathBuf::from("~/.fabro/certs/ca.crt"));

View file

@ -8,10 +8,10 @@ use crate::args::GlobalArgs;
pub(super) async fn execute(
mut args: ChatArgs,
cli_config: &FabroSettings,
cli_settings: &FabroSettings,
globals: &GlobalArgs,
) -> Result<()> {
let llm_defaults = cli_config.llm.as_ref();
let llm_defaults = cli_settings.llm.as_ref();
if args.model.is_none() {
args.model = llm_defaults.and_then(|l| l.model.clone());
}
@ -21,7 +21,7 @@ pub(super) async fn execute(
let resolved = crate::cli_config::resolve_mode(
globals.mode.clone(),
globals.server_url.as_deref(),
cli_config,
cli_settings,
);
match resolved.mode {
crate::cli_config::ExecutionMode::Server => {

View file

@ -7,10 +7,10 @@ use crate::args::{GlobalArgs, LlmCommand, LlmNamespace};
use crate::cli_config::load_cli_settings;
pub(crate) async fn dispatch(ns: LlmNamespace, globals: &GlobalArgs) -> Result<()> {
let cli_config = load_cli_settings(None)?;
let cli_settings = load_cli_settings(None)?;
match ns.command {
LlmCommand::Prompt(args) => prompt::execute(args, &cli_config, globals).await,
LlmCommand::Chat(args) => chat::execute(args, &cli_config, globals).await,
LlmCommand::Prompt(args) => prompt::execute(args, &cli_settings, globals).await,
LlmCommand::Chat(args) => chat::execute(args, &cli_settings, globals).await,
}
}

View file

@ -8,10 +8,10 @@ use crate::args::GlobalArgs;
pub(super) async fn execute(
mut args: PromptArgs,
cli_config: &FabroSettings,
cli_settings: &FabroSettings,
globals: &GlobalArgs,
) -> Result<()> {
let llm_defaults = cli_config.llm.as_ref();
let llm_defaults = cli_settings.llm.as_ref();
if args.model.is_none() {
args.model = llm_defaults.and_then(|l| l.model.clone());
}
@ -21,7 +21,7 @@ pub(super) async fn execute(
let resolved = crate::cli_config::resolve_mode(
globals.mode.clone(),
globals.server_url.as_deref(),
cli_config,
cli_settings,
);
match resolved.mode {
crate::cli_config::ExecutionMode::Server => {

View file

@ -11,11 +11,11 @@ pub(crate) async fn execute(command: Option<ModelsCommand>, globals: &GlobalArgs
let server = {
#[cfg(feature = "server")]
{
let cli_config = cli_config::load_cli_settings(None)?;
let cli_settings = cli_config::load_cli_settings(None)?;
let resolved = cli_config::resolve_mode(
globals.mode.clone(),
globals.server_url.as_deref(),
&cli_config,
&cli_settings,
);
match resolved.mode {
cli_config::ExecutionMode::Server => {

View file

@ -12,8 +12,8 @@ pub(super) async fn close_command(
args: PrCloseArgs,
github_app: Option<fabro_github::GitHubAppCredentials>,
) -> Result<()> {
let cli_config = load_cli_settings(None)?;
let base = runs_base(&cli_config.storage_dir());
let cli_settings = load_cli_settings(None)?;
let base = runs_base(&cli_settings.storage_dir());
close_from(&base, args, github_app).await
}

View file

@ -19,8 +19,8 @@ pub(super) async fn create_command(
args: PrCreateArgs,
github_app: Option<fabro_github::GitHubAppCredentials>,
) -> Result<()> {
let cli_config = load_cli_settings(None)?;
let base = runs_base(&cli_config.storage_dir());
let cli_settings = load_cli_settings(None)?;
let base = runs_base(&cli_settings.storage_dir());
create_from(&base, args, github_app).await
}

View file

@ -14,8 +14,8 @@ pub(super) async fn list_command(
args: PrListArgs,
github_app: Option<fabro_github::GitHubAppCredentials>,
) -> Result<()> {
let cli_config = load_cli_settings(None)?;
let base = runs_base(&cli_config.storage_dir());
let cli_settings = load_cli_settings(None)?;
let base = runs_base(&cli_settings.storage_dir());
list_from(&base, args, github_app).await
}

View file

@ -13,8 +13,8 @@ pub(super) async fn merge_command(
args: PrMergeArgs,
github_app: Option<fabro_github::GitHubAppCredentials>,
) -> Result<()> {
let cli_config = load_cli_settings(None)?;
let base = runs_base(&cli_config.storage_dir());
let cli_settings = load_cli_settings(None)?;
let base = runs_base(&cli_settings.storage_dir());
merge_from(&base, args, github_app).await
}

View file

@ -16,8 +16,8 @@ use crate::cli_config::load_cli_settings;
use crate::shared::github::build_github_app_credentials;
pub(crate) async fn dispatch(ns: PrNamespace) -> Result<()> {
let cli_config = load_cli_settings(None)?;
let github_app = build_github_app_credentials(cli_config.app_id());
let cli_settings = load_cli_settings(None)?;
let github_app = build_github_app_credentials(cli_settings.app_id());
match ns.command {
PrCommand::Create(args) => create::create_command(args, github_app).await,

View file

@ -13,8 +13,8 @@ pub(super) async fn view_command(
args: PrViewArgs,
github_app: Option<fabro_github::GitHubAppCredentials>,
) -> Result<()> {
let cli_config = load_cli_settings(None)?;
let base = runs_base(&cli_config.storage_dir());
let cli_settings = load_cli_settings(None)?;
let base = runs_base(&cli_settings.storage_dir());
view_from(&base, args, github_app).await
}

View file

@ -24,10 +24,10 @@ use crate::shared::github::build_github_app_credentials;
pub(crate) async fn execute(mut args: PreflightArgs) -> anyhow::Result<()> {
let styles: &'static Styles = Box::leak(Box::new(Styles::detect_stderr()));
let cli_defaults = load_cli_config(None)?;
let cli_config: FabroSettings = cli_defaults.clone().try_into()?;
args.verbose = args.verbose || cli_config.verbose_enabled();
let cli_settings: FabroSettings = cli_defaults.clone().try_into()?;
args.verbose = args.verbose || cli_settings.verbose_enabled();
let github_app = build_github_app_credentials(cli_config.app_id());
let github_app = build_github_app_credentials(cli_settings.app_id());
let cli_args_config = FabroConfig::try_from(&args)?;
let cwd = std::env::current_dir()?;
let settings = resolve_settings(ResolveSettingsInput {

View file

@ -153,11 +153,11 @@ async fn check_github_app_installation() {
};
// Load CLI config to get app_id and slug
let Ok(cli_config) = load_cli_settings(None) else {
let Ok(cli_settings) = load_cli_settings(None) else {
return;
};
let app_id = if let Some(id) = cli_config.app_id() {
let app_id = if let Some(id) = cli_settings.app_id() {
id.to_string()
} else {
eprintln!(
@ -170,7 +170,7 @@ async fn check_github_app_installation() {
return;
};
let slug = cli_config.slug().map(String::from);
let slug = cli_settings.slug().map(String::from);
// Build GitHub App credentials
let Some(creds) = build_github_app_credentials(Some(&app_id)) else {

View file

@ -7,11 +7,11 @@ use crate::args::{GlobalArgs, RunArgs};
pub(crate) async fn execute(mut args: RunArgs, _globals: &GlobalArgs) -> Result<()> {
let styles: &'static Styles = Box::leak(Box::new(Styles::detect_stderr()));
let cli_defaults = load_cli_config(None)?;
let cli_config: fabro_config::FabroSettings = cli_defaults.clone().try_into()?;
args.verbose = args.verbose || cli_config.verbose_enabled();
let cli_settings: fabro_config::FabroSettings = cli_defaults.clone().try_into()?;
args.verbose = args.verbose || cli_settings.verbose_enabled();
let quiet = args.detach;
let prevent_idle_sleep = cli_config.prevent_idle_sleep_enabled();
let prevent_idle_sleep = cli_settings.prevent_idle_sleep_enabled();
let (run_id, run_dir) = super::create::create_run(&args, cli_defaults, styles, quiet)?;
#[cfg(feature = "sleep_inhibitor")]

View file

@ -28,8 +28,8 @@ enum CopyDirection {
pub(crate) async fn cp_command(args: CpArgs) -> Result<()> {
let direction = parse_direction(&args.src, &args.dst)?;
let cli_config = load_cli_settings(None)?;
let base = runs_base(&cli_config.storage_dir());
let cli_settings = load_cli_settings(None)?;
let base = runs_base(&cli_settings.storage_dir());
match direction {
CopyDirection::Download {

View file

@ -12,11 +12,11 @@ use crate::cli_config;
use crate::shared;
pub(crate) async fn execute(run_dir: PathBuf, launcher_path: PathBuf, resume: bool) -> Result<()> {
let cli_config = cli_config::load_cli_settings(None)?;
let github_app = shared::github::build_github_app_credentials(cli_config.app_id());
let cli_settings = cli_config::load_cli_settings(None)?;
let github_app = shared::github::build_github_app_credentials(cli_settings.app_id());
let git_author = GitAuthor::from_options(
cli_config.git_author().and_then(|a| a.name.clone()),
cli_config.git_author().and_then(|a| a.email.clone()),
cli_settings.git_author().and_then(|a| a.name.clone()),
cli_settings.git_author().and_then(|a| a.email.clone()),
);
let _launcher_guard = scopeguard::guard(launcher_path.clone(), |path| {

View file

@ -15,8 +15,8 @@ use crate::cli_config::load_cli_settings;
pub(crate) async fn run(args: DiffArgs) -> Result<()> {
info!(run_id = %args.run, "Showing diff");
let cli_config = load_cli_settings(None)?;
let base = runs_base(&cli_config.storage_dir());
let cli_settings = load_cli_settings(None)?;
let base = runs_base(&cli_settings.storage_dir());
let run_dir = resolve_run(&base, &args.run)?.path;
let patch = resolve_diff(&run_dir, &args).await?;

View file

@ -12,8 +12,8 @@ use crate::args::LogsArgs;
use crate::cli_config::load_cli_settings;
pub(crate) fn run(args: &LogsArgs, styles: &Styles) -> Result<()> {
let cli_config = load_cli_settings(None)?;
let base = runs_base(&cli_config.storage_dir());
let cli_settings = load_cli_settings(None)?;
let base = runs_base(&cli_settings.storage_dir());
let run = resolve_run(&base, &args.run)?;
info!(run_id = %run.run_id, "Showing logs");

View file

@ -37,8 +37,8 @@ pub(crate) async fn dispatch(cmd: RunCommands, globals: &GlobalArgs) -> Result<(
Ok(())
}
RunCommands::Start { run } => {
let cli_config = load_cli_settings(None)?;
let base = runs_base(&cli_config.storage_dir());
let cli_settings = load_cli_settings(None)?;
let base = runs_base(&cli_settings.storage_dir());
let run_info = resolve_run(&base, &run)?;
let child = start::start_run(&run_info.path, false)?;
eprintln!("Started engine process (PID {})", child.id());
@ -46,8 +46,8 @@ pub(crate) async fn dispatch(cmd: RunCommands, globals: &GlobalArgs) -> Result<(
}
RunCommands::Attach { run } => {
let styles: &'static Styles = Box::leak(Box::new(Styles::detect_stderr()));
let cli_config = load_cli_settings(None)?;
let base = runs_base(&cli_config.storage_dir());
let cli_settings = load_cli_settings(None)?;
let base = runs_base(&cli_settings.storage_dir());
let run_info = resolve_run(&base, &run)?;
let exit_code = attach::attach_run(&run_info.path, false, styles, None).await?;
if exit_code != std::process::ExitCode::SUCCESS {
@ -72,8 +72,8 @@ pub(crate) async fn dispatch(cmd: RunCommands, globals: &GlobalArgs) -> Result<(
let styles: &'static Styles = Box::leak(Box::new(Styles::detect_stderr()));
#[cfg(feature = "sleep_inhibitor")]
let _sleep_guard = {
let cli_config = load_cli_settings(None)?;
crate::sleep_inhibitor::guard(cli_config.prevent_idle_sleep_enabled())
let cli_settings = load_cli_settings(None)?;
crate::sleep_inhibitor::guard(cli_settings.prevent_idle_sleep_enabled())
};
resume::resume_command(args, styles).await
}

View file

@ -10,8 +10,8 @@ use crate::cli_config::load_cli_settings;
use crate::shared::validate_daytona_provider;
pub(crate) async fn run(args: PreviewArgs) -> Result<()> {
let cli_config = load_cli_settings(None)?;
let base = runs_base(&cli_config.storage_dir());
let cli_settings = load_cli_settings(None)?;
let base = runs_base(&cli_settings.storage_dir());
let run_dir = resolve_run(&base, &args.run)?.path;
let sandbox_json = run_dir.join("sandbox.json");
let record = fabro_sandbox::SandboxRecord::load(&sandbox_json).context(

View file

@ -16,8 +16,8 @@ pub(crate) async fn resume_command(
args: ResumeArgs,
styles: &'static Styles,
) -> anyhow::Result<()> {
let cli_config = load_cli_settings(None)?;
let base = runs_base(&cli_config.storage_dir());
let cli_settings = load_cli_settings(None)?;
let base = runs_base(&cli_settings.storage_dir());
let run_dir = find_run_by_prefix(&base, &args.run)?;
// find_run_by_prefix can match orphan directories (no run.json).

View file

@ -10,8 +10,8 @@ use crate::cli_config::load_cli_settings;
use crate::shared::validate_daytona_provider;
pub(crate) async fn run(args: SshArgs) -> Result<()> {
let cli_config = load_cli_settings(None)?;
let base = runs_base(&cli_config.storage_dir());
let cli_settings = load_cli_settings(None)?;
let base = runs_base(&cli_settings.storage_dir());
let run_dir = resolve_run(&base, &args.run)?.path;
let sandbox_json = run_dir.join("sandbox.json");
let record = fabro_sandbox::SandboxRecord::load(&sandbox_json).context(

View file

@ -13,8 +13,8 @@ use crate::cli_config::load_cli_settings;
use crate::shared::format_duration_ms;
pub(crate) fn run(args: &WaitArgs, styles: &Styles) -> Result<()> {
let cli_config = load_cli_settings(None)?;
let base = runs_base(&cli_config.storage_dir());
let cli_settings = load_cli_settings(None)?;
let base = runs_base(&cli_settings.storage_dir());
let run_info = resolve_run(&base, &args.run)?;
info!(run_id = %run_info.run_id, "Waiting for run to complete");

View file

@ -26,8 +26,8 @@ pub(crate) struct InspectOutput {
}
pub(crate) fn run(args: &InspectArgs) -> Result<()> {
let cli_config = load_cli_settings(None)?;
let base = runs_base(&cli_config.storage_dir());
let cli_settings = load_cli_settings(None)?;
let base = runs_base(&cli_settings.storage_dir());
let run = resolve_run(&base, &args.run)?;
let output = inspect_run_dir(&run.run_id, &run.path, run.status);
let json = serde_json::to_string_pretty(&[output])?;

View file

@ -18,8 +18,8 @@ use crate::shared::{color_if, format_duration_ms, tilde_path};
use super::short_run_id;
pub(crate) fn list_command(args: &RunsListArgs, styles: &Styles) -> Result<()> {
let cli_config = load_cli_settings(None)?;
let base = runs_base(&cli_config.storage_dir());
let cli_settings = load_cli_settings(None)?;
let base = runs_base(&cli_settings.storage_dir());
let runs = scan_runs(&base)?;
let label_filters = parse_label_filters(&args.filter.label);
let filtered = filter_runs(

View file

@ -15,8 +15,8 @@ use crate::cli_config::load_cli_settings;
use super::short_run_id;
pub(crate) async fn remove_command(args: &RunsRemoveArgs) -> Result<()> {
let cli_config = load_cli_settings(None)?;
let base = runs_base(&cli_config.storage_dir());
let cli_settings = load_cli_settings(None)?;
let base = runs_base(&cli_settings.storage_dir());
remove_from(args, &base).await
}

View file

@ -14,8 +14,8 @@ use crate::cli_config::load_cli_settings;
use crate::shared::format_size;
pub(super) fn df_command(args: &DfArgs) -> Result<()> {
let cli_config = load_cli_settings(None)?;
let data_dir = cli_config.storage_dir();
let cli_settings = load_cli_settings(None)?;
let data_dir = cli_settings.storage_dir();
let runs_base_dir = runs_base(&data_dir);
let logs_base_dir = logs_base(&data_dir);
df_from(args, &data_dir, &runs_base_dir, &logs_base_dir)

View file

@ -12,8 +12,8 @@ use crate::cli_config::load_cli_settings;
use crate::shared::format_size;
pub(super) fn prune_command(args: &RunsPruneArgs) -> Result<()> {
let cli_config = load_cli_settings(None)?;
let base = runs_base(&cli_config.storage_dir());
let cli_settings = load_cli_settings(None)?;
let base = runs_base(&cli_settings.storage_dir());
prune_from(args, &base)
}

View file

@ -113,9 +113,9 @@ async fn main_inner() -> (String, Result<()>) {
}
} else {
match cli_config::load_cli_settings(None) {
Ok(cli_config) => (
cli_config.log.as_ref().and_then(|l| l.level.clone()),
cli_config.upgrade_check_enabled(),
Ok(cli_settings) => (
cli_settings.log.as_ref().and_then(|l| l.level.clone()),
cli_settings.upgrade_check_enabled(),
),
Err(err) => return (command_name, Err(err)),
}
@ -124,9 +124,9 @@ async fn main_inner() -> (String, Result<()>) {
#[cfg(not(feature = "server"))]
{
match cli_config::load_cli_settings(None) {
Ok(cli_config) => (
cli_config.log.as_ref().and_then(|l| l.level.clone()),
cli_config.upgrade_check_enabled(),
Ok(cli_settings) => (
cli_settings.log.as_ref().and_then(|l| l.level.clone()),
cli_settings.upgrade_check_enabled(),
),
Err(err) => return (command_name, Err(err)),
}
@ -184,8 +184,8 @@ async fn main_inner() -> (String, Result<()>) {
fabro_api::serve::serve_command(args, styles).await?;
}
Commands::Doctor { verbose, dry_run } => {
let cli_config = cli_config::load_cli_settings(None)?;
let verbose = verbose || cli_config.verbose_enabled();
let cli_settings = cli_config::load_cli_settings(None)?;
let verbose = verbose || cli_settings.verbose_enabled();
let exit_code = commands::doctor::run_doctor(verbose, !dry_run).await;
std::process::exit(exit_code);
}

View file

@ -190,6 +190,6 @@ pub fn load_server_settings(path: Option<&Path>) -> anyhow::Result<FabroSettings
}
/// Resolve the storage directory: config value > default `~/.fabro`.
pub fn resolve_storage_dir(config: &FabroSettings) -> PathBuf {
config.storage_dir()
pub fn resolve_storage_dir(settings: &FabroSettings) -> PathBuf {
settings.storage_dir()
}

View file

@ -255,9 +255,9 @@ fn persist_validated(
}
pub(crate) fn resolve_run_settings(mut settings: FabroSettings, graph: &Graph) -> FabroSettings {
let llm_config = settings.llm.as_ref();
let configured_model = llm_config.and_then(|l| l.model.as_deref());
let configured_provider = llm_config.and_then(|l| l.provider.as_deref());
let llm_settings = settings.llm.as_ref();
let configured_model = llm_settings.and_then(|l| l.model.as_deref());
let configured_provider = llm_settings.and_then(|l| l.provider.as_deref());
let graph_provider = graph.attrs.get("default_provider").and_then(|v| v.as_str());
let graph_model = graph.attrs.get("default_model").and_then(|v| v.as_str());