diff --git a/Cargo.lock b/Cargo.lock index d538cf560..0a51eac92 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1487,6 +1487,7 @@ dependencies = [ "fabro-model", "fabro-sandbox", "fabro-test", + "fabro-types", "fabro-util", "futures", "glob", diff --git a/lib/crates/fabro-agent/Cargo.toml b/lib/crates/fabro-agent/Cargo.toml index 2657bd3f3..917cd93d8 100644 --- a/lib/crates/fabro-agent/Cargo.toml +++ b/lib/crates/fabro-agent/Cargo.toml @@ -25,6 +25,7 @@ workspace = true clap.workspace = true anyhow.workspace = true fabro-config = { path = "../fabro-config", features = ["clap"] } +fabro-types = { path = "../fabro-types" } fabro-llm = { path = "../fabro-llm" } fabro-model = { path = "../fabro-model" } fabro-mcp = { path = "../fabro-mcp" } diff --git a/lib/crates/fabro-agent/src/cli.rs b/lib/crates/fabro-agent/src/cli.rs index 6e754b173..a7aa862c6 100644 --- a/lib/crates/fabro-agent/src/cli.rs +++ b/lib/crates/fabro-agent/src/cli.rs @@ -68,7 +68,7 @@ struct Cli { args: AgentArgs, } -pub use fabro_config::user::{OutputFormat, PermissionLevel}; +pub use fabro_types::settings::user::{OutputFormat, PermissionLevel}; impl AgentArgs { /// Fill `None` fields from settings.toml values, then hardcoded defaults. diff --git a/lib/crates/fabro-cli/src/user_config.rs b/lib/crates/fabro-cli/src/user_config.rs index 98384ef4e..7a9d6d483 100644 --- a/lib/crates/fabro-cli/src/user_config.rs +++ b/lib/crates/fabro-cli/src/user_config.rs @@ -1,6 +1,7 @@ use std::path::{Path, PathBuf}; pub(crate) use fabro_config::user::*; +pub(crate) use fabro_types::settings::user::ClientTlsSettings; use anyhow::{Result, bail}; use fabro_config::ConfigLayer; diff --git a/lib/crates/fabro-config/src/hook.rs b/lib/crates/fabro-config/src/hook.rs deleted file mode 100644 index 806e3a995..000000000 --- a/lib/crates/fabro-config/src/hook.rs +++ /dev/null @@ -1 +0,0 @@ -pub use fabro_types::settings::hook::*; diff --git a/lib/crates/fabro-config/src/lib.rs b/lib/crates/fabro-config/src/lib.rs index 526545afd..14f79d8c9 100644 --- a/lib/crates/fabro-config/src/lib.rs +++ b/lib/crates/fabro-config/src/lib.rs @@ -3,14 +3,10 @@ extern crate self as fabro_config; pub mod config; pub mod effective_settings; pub mod home; -pub mod hook; pub mod legacy_env; -pub mod mcp; pub mod merge; pub mod project; pub mod run; -pub mod sandbox; -pub mod server; pub mod storage; pub mod user; @@ -19,10 +15,17 @@ pub use fabro_util::path::expand_tilde; pub use home::Home; pub use storage::{RunScratch, ServerState, Storage}; -use std::path::Path; +use std::path::{Path, PathBuf}; +use fabro_types::settings::v2::SettingsFile; use serde::de::DeserializeOwned; +/// Resolve the storage directory: v2 `server.storage.root` > home default. +#[must_use] +pub fn resolve_storage_dir(settings: &SettingsFile) -> PathBuf { + settings.storage_dir() +} + /// Load a TOML config from an explicit path or `~/.fabro/{filename}`. /// /// Returns `T::default()` when no explicit path is given and the default file diff --git a/lib/crates/fabro-config/src/mcp.rs b/lib/crates/fabro-config/src/mcp.rs deleted file mode 100644 index 26d5aa144..000000000 --- a/lib/crates/fabro-config/src/mcp.rs +++ /dev/null @@ -1 +0,0 @@ -pub use fabro_types::settings::mcp::*; diff --git a/lib/crates/fabro-config/src/run.rs b/lib/crates/fabro-config/src/run.rs index 3e5c61ee8..a5c015173 100644 --- a/lib/crates/fabro-config/src/run.rs +++ b/lib/crates/fabro-config/src/run.rs @@ -1,42 +1,16 @@ -//! Re-export shim for run-side settings types. +//! Workflow / run config loading helpers. //! -//! Stage 3 replaced the parse-time types previously defined here with the -//! v2 parse tree in `fabro_types::settings::v2`. This module stays alive as -//! a pass-through for crates that still import resolved run types via the -//! legacy `fabro_config::run` path; Stage 6 deletes it. +//! Thin wrappers around `ConfigLayer::parse` / `ConfigLayer::load` plus +//! path resolution for the `[workflow] graph` override. Runtime types +//! that used to be re-exported from here live under +//! `fabro_types::settings::run` now. -use std::collections::HashMap; use std::path::{Path, PathBuf}; use anyhow::Context; use crate::config::ConfigLayer; -pub use fabro_types::settings::run::{ - ArtifactsSettings, CheckpointSettings, GitHubSettings, LlmSettings, MergeStrategy, - PullRequestSettings, SetupSettings, -}; - -/// Expand `${env.NAME}` whole-value references inside a string map. -/// -/// Leaves entries that don't match the whole-value form untouched. Missing -/// host variables produce an error. This is the minimal resolver legacy -/// consumers still call while they are being migrated off `Settings`; the -/// full v2 interpolation pass lives in `fabro_types::settings::v2::interp`. -pub fn resolve_env_refs(env: &mut HashMap) -> anyhow::Result<()> { - for (key, value) in env.iter_mut() { - if let Some(var_name) = value - .strip_prefix("${env.") - .and_then(|s| s.strip_suffix('}')) - { - *value = std::env::var(var_name).with_context(|| { - format!("sandbox.env.{key}: host environment variable {var_name:?} is not set") - })?; - } - } - Ok(()) -} - /// Load and parse a run config from a TOML file. pub fn parse_run_config(contents: &str) -> anyhow::Result { ConfigLayer::parse(contents).context("Failed to parse run config TOML") diff --git a/lib/crates/fabro-config/src/sandbox.rs b/lib/crates/fabro-config/src/sandbox.rs deleted file mode 100644 index 2c247031a..000000000 --- a/lib/crates/fabro-config/src/sandbox.rs +++ /dev/null @@ -1,10 +0,0 @@ -//! Re-export shim for sandbox settings types. -//! -//! Stage 3 removed the parse-time `SandboxConfig`/`DaytonaConfig` types; -//! callers that still import resolved sandbox types via this module use the -//! re-exports below. Stage 6 deletes this file. - -pub use fabro_types::settings::sandbox::{ - DaytonaNetwork, DaytonaSettings, DaytonaSnapshotSettings, DockerfileSource, - LocalSandboxSettings, SandboxSettings, WorktreeMode, -}; diff --git a/lib/crates/fabro-config/src/server.rs b/lib/crates/fabro-config/src/server.rs deleted file mode 100644 index a874bfe1b..000000000 --- a/lib/crates/fabro-config/src/server.rs +++ /dev/null @@ -1,23 +0,0 @@ -//! Re-export shim for server settings types. -//! -//! Stage 3 removed the parse-time `*Config` types (`ApiConfig`, `GitConfig`, -//! etc.) in favor of the v2 parse tree in `fabro_types::settings::v2::server`. -//! This module stays alive as a pass-through for crates that still import -//! resolved server types via the legacy `fabro_config::server` path; -//! Stage 6.4 deletes it. - -use std::path::PathBuf; - -use fabro_types::settings::v2::SettingsFile; - -pub use fabro_types::settings::server::{ - ApiAuthStrategy, ApiSettings, ArtifactStorageBackend, ArtifactStorageSettings, AuthProvider, - AuthSettings, FeaturesSettings, GitAuthorSettings, GitProvider, GitSettings, LogSettings, - SlackSettings, TlsSettings, WebSettings, WebhookSettings, WebhookStrategy, -}; - -/// Resolve the storage directory: config value > default `~/.fabro`. -#[must_use] -pub fn resolve_storage_dir(settings: &SettingsFile) -> PathBuf { - settings.storage_dir() -} diff --git a/lib/crates/fabro-config/src/user.rs b/lib/crates/fabro-config/src/user.rs index f72d3e0f3..a979cf93d 100644 --- a/lib/crates/fabro-config/src/user.rs +++ b/lib/crates/fabro-config/src/user.rs @@ -1,8 +1,8 @@ //! User config loading. //! -//! Stage 3 removed the parse-time `ClientTlsConfig`/`ServerConfig`/`ExecConfig` -//! types; this module now only exposes machine-level settings loading plus -//! path helpers and a re-export of the resolved user-facing types. +//! Exposes machine-level settings loading plus path helpers for the +//! `~/.fabro/settings.toml` file. Runtime types that used to be +//! re-exported from here live in `fabro_types::settings::user` now. use std::collections::HashSet; use std::path::{Path, PathBuf}; @@ -11,10 +11,6 @@ use std::sync::{Mutex, OnceLock}; use crate::config::ConfigLayer; use crate::home::Home; -pub use fabro_types::settings::user::{ - ClientTlsSettings, ExecSettings, OutputFormat, PermissionLevel, ServerSettings, -}; - pub const SETTINGS_CONFIG_FILENAME: &str = "settings.toml"; pub const LEGACY_USER_CONFIG_FILENAME: &str = "cli.toml"; pub const LEGACY_OLD_USER_CONFIG_FILENAME: &str = "user.toml"; diff --git a/lib/crates/fabro-hooks/src/config.rs b/lib/crates/fabro-hooks/src/config.rs index 72f52ca45..8d055984f 100644 --- a/lib/crates/fabro-hooks/src/config.rs +++ b/lib/crates/fabro-hooks/src/config.rs @@ -1 +1 @@ -pub use fabro_config::hook::{HookDefinition, HookEvent, HookSettings, HookType, TlsMode}; +pub use fabro_types::settings::hook::{HookDefinition, HookEvent, HookSettings, HookType, TlsMode}; diff --git a/lib/crates/fabro-hooks/src/types.rs b/lib/crates/fabro-hooks/src/types.rs index a976bbe84..ca7eeaa30 100644 --- a/lib/crates/fabro-hooks/src/types.rs +++ b/lib/crates/fabro-hooks/src/types.rs @@ -1,4 +1,4 @@ -pub use fabro_config::hook::HookEvent; +pub use fabro_types::settings::hook::HookEvent; use fabro_types::RunId; use serde::{Deserialize, Serialize}; diff --git a/lib/crates/fabro-mcp/src/config.rs b/lib/crates/fabro-mcp/src/config.rs index 38da06fcb..feed3623f 100644 --- a/lib/crates/fabro-mcp/src/config.rs +++ b/lib/crates/fabro-mcp/src/config.rs @@ -1,4 +1,4 @@ -pub use fabro_config::mcp::{ +pub use fabro_types::settings::mcp::{ McpServerEntry, McpServerSettings, McpTransport, default_startup_timeout_secs, default_tool_timeout_secs, }; diff --git a/lib/crates/fabro-sandbox/src/daytona/mod.rs b/lib/crates/fabro-sandbox/src/daytona/mod.rs index 802fb91e4..1d58f8da3 100644 --- a/lib/crates/fabro-sandbox/src/daytona/mod.rs +++ b/lib/crates/fabro-sandbox/src/daytona/mod.rs @@ -22,7 +22,7 @@ use tokio_util::sync::CancellationToken; const WORKING_DIRECTORY: &str = "/home/daytona/workspace"; const DEFAULT_SNAPSHOT: &str = "daytona-medium"; -pub use fabro_config::sandbox::{ +pub use fabro_types::settings::sandbox::{ DaytonaNetwork, DaytonaSettings as DaytonaConfig, DaytonaSnapshotSettings as DaytonaSnapshotConfig, DockerfileSource, }; diff --git a/lib/crates/fabro-server/src/demo/mod.rs b/lib/crates/fabro-server/src/demo/mod.rs index 60ff9c54a..024a5244c 100644 --- a/lib/crates/fabro-server/src/demo/mod.rs +++ b/lib/crates/fabro-server/src/demo/mod.rs @@ -1330,16 +1330,16 @@ mod runs { goal: Some("Add rate limiting to auth endpoints".into()), graph: Some("implement.fabro".into()), work_dir: Some("/workspace/api-server".into()), - llm: Some(fabro_config::run::LlmSettings { + llm: Some(fabro_types::settings::run::LlmSettings { model: Some("claude-opus-4-6".into()), provider: Some("anthropic".into()), fallbacks: None, }), - setup: Some(fabro_config::run::SetupSettings { + setup: Some(fabro_types::settings::run::SetupSettings { commands: vec!["bun install".into(), "bun run typecheck".into()], timeout_ms: Some(120_000), }), - sandbox: Some(fabro_config::sandbox::SandboxSettings { + sandbox: Some(fabro_types::settings::sandbox::SandboxSettings { provider: Some("daytona".into()), preserve: None, devcontainer: None, @@ -1489,8 +1489,8 @@ mod insights { } mod settings { - use fabro_config::server::*; use fabro_types::Settings; + use fabro_types::settings::server::*; pub(super) fn server_settings() -> serde_json::Value { serde_json::to_value(Settings { @@ -1522,13 +1522,13 @@ mod settings { retros: false, }), log: Default::default(), - llm: Some(fabro_config::run::LlmSettings { + llm: Some(fabro_types::settings::run::LlmSettings { model: Some("claude-sonnet".into()), provider: Some("anthropic".into()), fallbacks: None, }), setup: None, - sandbox: Some(fabro_config::sandbox::SandboxSettings { + sandbox: Some(fabro_types::settings::sandbox::SandboxSettings { provider: Some("daytona".into()), preserve: None, devcontainer: None, diff --git a/lib/crates/fabro-server/src/jwt_auth.rs b/lib/crates/fabro-server/src/jwt_auth.rs index 79adaa30e..698b1a06d 100644 --- a/lib/crates/fabro-server/src/jwt_auth.rs +++ b/lib/crates/fabro-server/src/jwt_auth.rs @@ -10,8 +10,8 @@ use tracing::warn; use crate::error::ApiError; use crate::web_auth::SessionCookie; -use fabro_config::server::ApiSettings; use fabro_types::RunAuthMethod; +use fabro_types::settings::server::ApiSettings; /// JWT claims for service-to-service authentication. #[derive(Debug, Deserialize)] @@ -86,7 +86,7 @@ pub fn resolve_auth_mode_with_lookup( where F: Fn(&str) -> Option, { - use fabro_config::server::ApiAuthStrategy; + use fabro_types::settings::server::ApiAuthStrategy; if api_settings.authentication_strategies.is_empty() && std::env::var("FABRO_LOCAL_NO_AUTH").ok().as_deref() == Some("1") diff --git a/lib/crates/fabro-server/src/lib.rs b/lib/crates/fabro-server/src/lib.rs index 98cf30988..85e49717a 100644 --- a/lib/crates/fabro-server/src/lib.rs +++ b/lib/crates/fabro-server/src/lib.rs @@ -16,8 +16,8 @@ pub mod serve; pub mod server; pub mod static_files; pub mod server_config { - pub use fabro_config::server::*; pub use fabro_types::Settings; + pub use fabro_types::settings::server::*; } pub mod tls; pub mod web_auth; diff --git a/lib/crates/fabro-server/src/serve.rs b/lib/crates/fabro-server/src/serve.rs index 6d690201e..df6d75322 100644 --- a/lib/crates/fabro-server/src/serve.rs +++ b/lib/crates/fabro-server/src/serve.rs @@ -3,8 +3,9 @@ use std::sync::{Arc, RwLock}; use std::time::Duration; use fabro_config::Storage; -use fabro_config::server::{ApiSettings, resolve_storage_dir}; +use fabro_config::resolve_storage_dir; use fabro_config::user::{active_settings_path, load_settings_config}; +use fabro_types::settings::server::ApiSettings; use fabro_util::terminal::Styles; use object_store::ObjectStore; use object_store::aws::AmazonS3Builder; @@ -89,7 +90,7 @@ fn load_settings(path: Option<&Path>) -> anyhow::Result { /// v2 tree. Stage 6.6 replaces this with a v2-aware auth resolver and drops /// the legacy `ApiSettings` type entirely. fn build_legacy_api_settings(file: &SettingsFile) -> ApiSettings { - use fabro_config::server::{ApiAuthStrategy, TlsSettings}; + use fabro_types::settings::server::{ApiAuthStrategy, TlsSettings}; use fabro_types::settings::v2::interp::InterpString; use fabro_types::settings::v2::server::ServerListenLayer; diff --git a/lib/crates/fabro-server/src/tls.rs b/lib/crates/fabro-server/src/tls.rs index 05733d5d9..0009253ca 100644 --- a/lib/crates/fabro-server/src/tls.rs +++ b/lib/crates/fabro-server/src/tls.rs @@ -8,7 +8,7 @@ use rustls_pki_types::{CertificateDer, PrivateKeyDer}; use tokio::net::TcpListener; use tracing::error; -use fabro_config::server::TlsSettings; +use fabro_types::settings::server::TlsSettings; use crate::jwt_auth::PeerCertificates; diff --git a/lib/crates/fabro-server/tests/it/openapi_conformance.rs b/lib/crates/fabro-server/tests/it/openapi_conformance.rs index 33fc5e158..2c41c72d2 100644 --- a/lib/crates/fabro-server/tests/it/openapi_conformance.rs +++ b/lib/crates/fabro-server/tests/it/openapi_conformance.rs @@ -12,13 +12,13 @@ use std::collections::BTreeSet; use axum::body::Body; use axum::http::{Method, Request, StatusCode}; -use fabro_config::run::*; -use fabro_config::sandbox::SandboxSettings; use fabro_hooks::*; use fabro_sandbox::daytona::*; use fabro_server::jwt_auth::AuthMode; use fabro_server::server::build_router; use fabro_server::server_config::*; +use fabro_types::settings::run::*; +use fabro_types::settings::sandbox::SandboxSettings; use fabro_types::settings::{ ClientTlsSettings, ExecSettings, OutputFormat, PermissionLevel, ProjectSettings, ServerSettings as UserServerSettings, @@ -398,13 +398,13 @@ fn fully_populated_server_config() -> Settings { ], mcp_servers: std::collections::HashMap::from([( "test".into(), - fabro_config::mcp::McpServerEntry { - transport: fabro_config::mcp::McpTransport::Stdio { + fabro_types::settings::mcp::McpServerEntry { + transport: fabro_types::settings::mcp::McpTransport::Stdio { command: vec!["echo".into()], env: Default::default(), }, - startup_timeout_secs: fabro_config::mcp::default_startup_timeout_secs(), - tool_timeout_secs: fabro_config::mcp::default_tool_timeout_secs(), + startup_timeout_secs: fabro_types::settings::mcp::default_startup_timeout_secs(), + tool_timeout_secs: fabro_types::settings::mcp::default_tool_timeout_secs(), }, )]), github: Some(GitHubSettings { diff --git a/lib/crates/fabro-workflow/src/operations/start.rs b/lib/crates/fabro-workflow/src/operations/start.rs index 2a0d8e43f..7944fb576 100644 --- a/lib/crates/fabro-workflow/src/operations/start.rs +++ b/lib/crates/fabro-workflow/src/operations/start.rs @@ -4,12 +4,12 @@ use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, Mutex}; use std::time::{Duration, Instant}; -use fabro_config::sandbox::WorktreeMode; -use fabro_config::{project as project_config, sandbox as sandbox_config}; +use fabro_config::project as project_config; use fabro_interview::{AutoApproveInterviewer, Interviewer}; use fabro_model::{Catalog, FallbackTarget, Provider}; use fabro_sandbox::{SandboxProvider, SandboxSpec}; use fabro_types::RunId; +use fabro_types::settings::sandbox::{self as sandbox_config, WorktreeMode}; use fabro_types::settings::v2::run::ModelRefOrSplice; use fabro_types::settings::v2::to_runtime::{ bridge_hook, bridge_mcp_entry, bridge_pull_request, bridge_sandbox, bridge_worktree_mode, @@ -36,10 +36,10 @@ use crate::run_options::{GitCheckpointOptions, LifecycleOptions, RunOptions}; use crate::run_status::{RunStatus, StatusReason}; use crate::runtime_store::RunStoreHandle; use crate::workflow_bundle::{RunDefinition, WorkflowBundle}; -use fabro_config::run::PullRequestSettings; use fabro_retro::retro::Retro; use fabro_sandbox::daytona::DaytonaConfig; use fabro_sandbox::daytona::detect_repo_info; +use fabro_types::settings::run::PullRequestSettings; use tokio::runtime::Handle; struct RunSession { diff --git a/lib/crates/fabro-workflow/src/pipeline/pull_request.rs b/lib/crates/fabro-workflow/src/pipeline/pull_request.rs index e02cdf255..21eb8d84d 100644 --- a/lib/crates/fabro-workflow/src/pipeline/pull_request.rs +++ b/lib/crates/fabro-workflow/src/pipeline/pull_request.rs @@ -1,6 +1,6 @@ -use fabro_config::run::MergeStrategy; use fabro_store::RunProjection; use fabro_types::PullRequestRecord; +use fabro_types::settings::run::MergeStrategy; use tracing::{debug, info}; use fabro_github::{self as github_app, GitHubAppCredentials, ssh_url_to_https}; diff --git a/lib/crates/fabro-workflow/src/pipeline/types.rs b/lib/crates/fabro-workflow/src/pipeline/types.rs index c2ae831aa..d070fd0db 100644 --- a/lib/crates/fabro-workflow/src/pipeline/types.rs +++ b/lib/crates/fabro-workflow/src/pipeline/types.rs @@ -3,7 +3,6 @@ use std::path::{Path, PathBuf}; use std::sync::Arc; use fabro_agent::Sandbox; -use fabro_config::sandbox::WorktreeMode; use fabro_graphviz::graph::Graph; use fabro_hooks::HookRunner; use fabro_interview::Interviewer; @@ -12,6 +11,7 @@ use fabro_mcp::config::McpServerSettings; use fabro_model::FallbackTarget; use fabro_sandbox::SandboxSpec; use fabro_types::RunId; +use fabro_types::settings::sandbox::WorktreeMode; use fabro_validate::Diagnostic; use crate::artifact_upload::ArtifactSink; @@ -27,9 +27,9 @@ use crate::run_options::{GitCheckpointOptions, LifecycleOptions, RunOptions}; use crate::runtime_store::RunStoreHandle; use crate::transforms::Transform; use crate::workflow_bundle::WorkflowBundle; -use fabro_config::run::PullRequestSettings; use fabro_llm::client::Client; use fabro_retro::retro::Retro; +use fabro_types::settings::run::PullRequestSettings; use fabro_validate::Severity; /// Output of the PARSE phase.