refactor(config): stage 6.4 delete fabro-config re-export shims

fabro-config no longer carries the legacy pass-through shims that
forwarded type re-exports from `fabro_types::settings::{hook,mcp,sandbox,
server,user,run}`. Consumers now import the runtime types directly
from `fabro_types::settings::*`, which is the only definitional
location.

Deleted files:
- `fabro-config/src/hook.rs` (1 LOC glob re-export)
- `fabro-config/src/mcp.rs`   (1 LOC glob re-export)
- `fabro-config/src/sandbox.rs` (~8 LOC re-export list)
- `fabro-config/src/server.rs`  (re-exports + `resolve_storage_dir`;
  the `resolve_storage_dir` helper moved to `fabro_config`'s crate root
  and takes `&SettingsFile` directly)

Shrunk files:
- `fabro-config/src/run.rs` lost the `ArtifactsSettings` /
  `CheckpointSettings` / `GitHubSettings` / `LlmSettings` /
  `MergeStrategy` / `PullRequestSettings` / `SetupSettings` re-export
  block and the unused `resolve_env_refs` helper. What remains is just
  the workflow TOML loader helpers (`parse_run_config`, `load_run_config`,
  `resolve_graph_path`).
- `fabro-config/src/user.rs` lost the `ClientTlsSettings` /
  `ExecSettings` / `OutputFormat` / `PermissionLevel` /
  `ServerSettings` re-export block. The settings-path helpers and
  legacy-config warning logic stay. `fabro-cli/src/user_config.rs`
  now imports `ClientTlsSettings` directly from fabro_types.

Callers updated to use the canonical paths:
- `fabro-agent/src/cli.rs` imports `{OutputFormat, PermissionLevel}`
  from `fabro_types::settings::user`; added `fabro-types` dep.
- `fabro-hooks/src/{config,types}.rs` re-export from
  `fabro_types::settings::hook`.
- `fabro-mcp/src/config.rs` re-exports from `fabro_types::settings::mcp`.
- `fabro-sandbox/src/daytona/mod.rs` re-exports from
  `fabro_types::settings::sandbox`.
- `fabro-server/src/{lib,jwt_auth,tls,serve,demo}.rs` +
  `tests/it/openapi_conformance.rs` import server types from
  `fabro_types::settings::server` and call `fabro_config::resolve_storage_dir`
  from the crate root.
- `fabro-workflow/src/{operations/start,pipeline/types,pipeline/pull_request}.rs`
  import sandbox / pull_request types from `fabro_types::settings::*`.

Build, clippy, fmt, and 3756 / 3756 tests pass.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Bryan Helmkamp 2026-04-09 16:30:38 -04:00
parent 2c8b6c95aa
commit eb7f99310c
24 changed files with 49 additions and 107 deletions

1
Cargo.lock generated
View file

@ -1487,6 +1487,7 @@ dependencies = [
"fabro-model",
"fabro-sandbox",
"fabro-test",
"fabro-types",
"fabro-util",
"futures",
"glob",

View file

@ -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" }

View file

@ -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.

View file

@ -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;

View file

@ -1 +0,0 @@
pub use fabro_types::settings::hook::*;

View file

@ -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

View file

@ -1 +0,0 @@
pub use fabro_types::settings::mcp::*;

View file

@ -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<String, String>) -> 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> {
ConfigLayer::parse(contents).context("Failed to parse run config TOML")

View file

@ -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,
};

View file

@ -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()
}

View file

@ -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";

View file

@ -1 +1 @@
pub use fabro_config::hook::{HookDefinition, HookEvent, HookSettings, HookType, TlsMode};
pub use fabro_types::settings::hook::{HookDefinition, HookEvent, HookSettings, HookType, TlsMode};

View file

@ -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};

View file

@ -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,
};

View file

@ -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,
};

View file

@ -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,

View file

@ -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<F>(
where
F: Fn(&str) -> Option<String>,
{
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")

View file

@ -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;

View file

@ -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<SettingsFile> {
/// 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;

View file

@ -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;

View file

@ -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 {

View file

@ -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 {

View file

@ -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};

View file

@ -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.