Rename FabroSettings to Settings, eliminate FabroSettingsExt

Move storage_dir() from FabroSettingsExt trait in fabro-config into an
inherent method on Settings in fabro-types. Remove the re-export from
fabro-config so callers import directly from fabro_types. Drop the
redundant Fabro prefix since the type already lives in the fabro_types
crate.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Bryan Helmkamp 2026-04-02 07:36:44 -07:00
parent 5f1f47a966
commit 28a1fc72f4
No known key found for this signature in database
74 changed files with 314 additions and 366 deletions

1
Cargo.lock generated
View file

@ -2070,6 +2070,7 @@ version = "0.176.2"
dependencies = [
"chrono",
"clap",
"dirs",
"fabro-macros",
"serde",
"serde_json",

View file

@ -25,7 +25,7 @@ No single event carries this data. The `run.started` event has a subset (`name`,
|-------|-------------|--------------|
| `run_id` | ULID string | `run.started``envelope.run_id` |
| `created_at` | RFC 3339 timestamp | — |
| `settings` | full FabroSettings object | — |
| `settings` | full Settings object | — |
| `graph` | parsed workflow graph | — |
| `workflow_slug` | workflow slug (optional) | — |
| `working_directory` | path string | — |

View file

@ -3984,7 +3984,7 @@ components:
# ── Settings Schemas ─────────────────────────────────────────────────
RunSettings:
description: Structured run settings mirroring FabroSettings.
description: Structured run settings mirroring fabro_types::Settings.
type: object
required:
- version
@ -4227,7 +4227,7 @@ components:
description: Whether hook runs in sandbox.
ServerSettings:
description: Structured server settings mirroring FabroSettings.
description: Structured server settings mirroring fabro_types::Settings.
type: object
properties:
storage_dir:

View file

@ -178,7 +178,7 @@ mod tests {
use super::*;
use chrono::{TimeZone, Utc};
use fabro_types::{FabroSettings, Graph, fixtures};
use fabro_types::{Graph, Settings, fixtures};
/// Create a temporary git repo with an initial commit.
fn init_repo(dir: &Path) {
@ -207,7 +207,7 @@ mod tests {
RunRecord {
run_id,
created_at: Utc.with_ymd_and_hms(2025, 1, 1, 0, 0, 0).single().unwrap(),
settings: FabroSettings::default(),
settings: Settings::default(),
graph: Graph::new("test"),
workflow_slug: None,
working_directory: PathBuf::from("/tmp"),

View file

@ -1,7 +1,6 @@
use std::path::{Path, PathBuf};
use anyhow::{Context, Result, bail};
use fabro_config::FabroSettingsExt;
use fabro_store::RuntimeState;
use fabro_workflow::assets::{AssetEntry, scan_assets};
use fabro_workflow::run_lookup::{resolve_run_combined, runs_base};

View file

@ -1,5 +1,4 @@
use anyhow::Result;
use fabro_config::FabroSettingsExt;
use fabro_store::RuntimeState;
use fabro_workflow::assets::scan_assets;
use fabro_workflow::run_lookup::{resolve_run_combined, runs_base};

View file

@ -4,9 +4,10 @@ use std::path::Path;
use crate::args::{GlobalArgs, SettingsArgs};
use crate::shared::print_json_pretty;
use crate::user_config;
use fabro_config::{ConfigLayer, FabroSettings};
use fabro_config::ConfigLayer;
use fabro_types::Settings;
fn merged_config(workflow: Option<&Path>, globals: &GlobalArgs) -> anyhow::Result<FabroSettings> {
fn merged_config(workflow: Option<&Path>, globals: &GlobalArgs) -> anyhow::Result<Settings> {
let cwd = std::env::current_dir()?;
let base = match workflow {
Some(path) => ConfigLayer::for_workflow(path, &cwd)?,

View file

@ -925,7 +925,7 @@ mod tests {
#[cfg(feature = "server")]
fn config_toml_roundtrips() {
let toml_str = format_config_toml("brynary");
let settings: fabro_config::FabroSettings =
let settings: fabro_types::Settings =
toml::from_str(&toml_str).expect("config should parse");
assert_eq!(
settings.web.unwrap().auth.allowed_usernames,
@ -937,7 +937,7 @@ mod tests {
#[cfg(feature = "server")]
fn config_toml_has_auth_strategies() {
let toml_str = format_config_toml("alice");
let settings: fabro_config::FabroSettings = toml::from_str(&toml_str).unwrap();
let settings: fabro_types::Settings = toml::from_str(&toml_str).unwrap();
assert_eq!(
settings.api.unwrap().authentication_strategies,
vec![
@ -952,7 +952,7 @@ mod tests {
fn config_toml_has_tls_paths() {
use std::path::PathBuf;
let toml_str = format_config_toml("bob");
let settings: fabro_config::FabroSettings = toml::from_str(&toml_str).unwrap();
let settings: fabro_types::Settings = 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"));

View file

@ -1,14 +1,14 @@
use anyhow::Result;
use fabro_config::FabroSettings;
use fabro_llm::cli::{ChatArgs, run_chat};
#[cfg(feature = "server")]
use fabro_llm::cli::{ServerConnection, run_chat_via_server};
use fabro_types::Settings;
use crate::args::GlobalArgs;
pub(super) async fn execute(
mut args: ChatArgs,
cli_settings: &FabroSettings,
cli_settings: &Settings,
globals: &GlobalArgs,
) -> Result<()> {
globals.require_no_json()?;

View file

@ -1,14 +1,14 @@
use anyhow::Result;
use fabro_config::FabroSettings;
use fabro_llm::cli::{PromptArgs, run_prompt};
#[cfg(feature = "server")]
use fabro_llm::cli::{ServerConnection, run_prompt_via_server};
use fabro_types::Settings;
use crate::args::GlobalArgs;
pub(super) async fn execute(
mut args: PromptArgs,
cli_settings: &FabroSettings,
cli_settings: &Settings,
globals: &GlobalArgs,
) -> Result<()> {
let llm_defaults = cli_settings.llm.as_ref();

View file

@ -1,7 +1,6 @@
use std::path::Path;
use anyhow::{Context, Result};
use fabro_config::FabroSettingsExt;
use fabro_workflow::run_lookup::runs_base;
use tracing::info;

View file

@ -1,7 +1,6 @@
use std::path::Path;
use anyhow::{Context, Result, bail};
use fabro_config::FabroSettingsExt;
use fabro_model::Catalog;
use fabro_sandbox::daytona::detect_repo_info;
use fabro_workflow::outcome::StageStatus;

View file

@ -1,7 +1,6 @@
use std::path::Path;
use anyhow::{Context, Result};
use fabro_config::FabroSettingsExt;
use fabro_types::PullRequestRecord;
use fabro_workflow::run_lookup::{runs_base, scan_runs_combined};
use futures::future::join_all;

View file

@ -1,7 +1,6 @@
use std::path::Path;
use anyhow::{Context, Result};
use fabro_config::FabroSettingsExt;
use tracing::info;
use fabro_workflow::run_lookup::runs_base;

View file

@ -1,7 +1,6 @@
use std::path::Path;
use anyhow::{Context, Result};
use fabro_config::FabroSettingsExt;
use tracing::info;
use fabro_workflow::run_lookup::runs_base;

View file

@ -2,13 +2,14 @@ use std::path::Path;
use std::sync::Arc;
use anyhow::bail;
use fabro_config::ConfigLayer;
use fabro_config::project::{resolve_workflow_path, resolve_working_directory};
use fabro_config::{ConfigLayer, FabroSettings};
use fabro_graphviz::graph::{Graph, is_llm_handler_type};
use fabro_llm::client::Client as LlmClient;
use fabro_model::{Catalog, Provider};
use fabro_sandbox::daytona::{DaytonaConfig, detect_repo_info};
use fabro_sandbox::{DockerSandboxOptions, Sandbox, SandboxProvider, SandboxSpec};
use fabro_types::Settings;
use fabro_util::check_report::CheckReport;
use fabro_util::terminal::Styles;
use fabro_workflow::git::{GitSyncStatus, sync_status};
@ -22,7 +23,7 @@ use crate::user_config::{load_user_settings_with_globals, user_layer_with_global
pub(crate) async fn execute(mut args: PreflightArgs, globals: &GlobalArgs) -> anyhow::Result<()> {
let styles: &'static Styles = Box::leak(Box::new(Styles::detect_stderr()));
let cli = user_layer_with_globals(globals)?;
let cli_settings: FabroSettings = load_user_settings_with_globals(globals)?;
let cli_settings: Settings = load_user_settings_with_globals(globals)?;
args.verbose = args.verbose || cli_settings.verbose_enabled();
let github_app = build_github_app_credentials(cli_settings.app_id())?;
@ -105,7 +106,7 @@ pub(crate) async fn execute(mut args: PreflightArgs, globals: &GlobalArgs) -> an
fn resolve_model_provider(
cli_model: Option<&str>,
cli_provider: Option<&str>,
settings: &FabroSettings,
settings: &Settings,
graph: &Graph,
) -> (String, Option<String>) {
let configured_model = settings.llm.as_ref().and_then(|llm| llm.model.as_deref());
@ -144,7 +145,7 @@ fn resolve_model_provider(
}
}
fn parse_sandbox_provider(settings: &FabroSettings) -> anyhow::Result<Option<SandboxProvider>> {
fn parse_sandbox_provider(settings: &Settings) -> anyhow::Result<Option<SandboxProvider>> {
settings
.sandbox_settings()
.and_then(|s| s.provider.as_deref())
@ -155,14 +156,14 @@ fn parse_sandbox_provider(settings: &FabroSettings) -> anyhow::Result<Option<San
fn resolve_sandbox_provider(
cli: Option<SandboxProvider>,
settings: &FabroSettings,
settings: &Settings,
) -> anyhow::Result<SandboxProvider> {
Ok(cli
.or(parse_sandbox_provider(settings)?)
.unwrap_or_default())
}
fn resolve_daytona_config(settings: &FabroSettings) -> Option<DaytonaConfig> {
fn resolve_daytona_config(settings: &Settings) -> Option<DaytonaConfig> {
settings
.sandbox_settings()
.and_then(|sandbox| sandbox.daytona.clone())
@ -196,7 +197,7 @@ async fn mint_github_token(
#[allow(clippy::too_many_arguments)]
async fn run_preflight(
graph: &Graph,
settings: &FabroSettings,
settings: &Settings,
cli_model: Option<&str>,
cli_provider: Option<&str>,
git_status: GitSyncStatus,

View file

@ -1,5 +1,4 @@
use anyhow::Result;
use fabro_config::FabroSettingsExt;
use fabro_util::terminal::Styles;
use crate::args::{GlobalArgs, RunArgs};

View file

@ -2,7 +2,6 @@ use std::path::{Path, PathBuf};
use anyhow::{Context, Result, bail};
use fabro_agent::sandbox::Sandbox;
use fabro_config::FabroSettingsExt;
use fabro_sandbox::reconnect::reconnect;
use fabro_workflow::run_lookup::{resolve_run_combined, runs_base};
use tokio::fs;

View file

@ -1,8 +1,8 @@
use std::path::PathBuf;
use crate::args::RunArgs;
use fabro_config::{ConfigLayer, FabroSettings, FabroSettingsExt};
use fabro_types::RunId;
use fabro_config::ConfigLayer;
use fabro_types::{RunId, Settings};
use fabro_util::terminal::Styles;
use fabro_workflow::error::FabroError;
use fabro_workflow::operations::{CreateRunInput, WorkflowInput, create};
@ -25,7 +25,7 @@ pub(crate) async fn create_run(
.ok_or_else(|| anyhow::anyhow!("--workflow is required"))?;
let cli_args_config = ConfigLayer::try_from(args)?;
let cwd = std::env::current_dir().unwrap_or_else(|_| PathBuf::from("."));
let settings: FabroSettings = cli_args_config
let settings: Settings = cli_args_config
.combine(ConfigLayer::for_workflow(workflow_path, &cwd)?)
.combine(cli_defaults)
.resolve()?;

View file

@ -2,7 +2,6 @@ use std::path::PathBuf;
use std::sync::Arc;
use anyhow::{Result, anyhow};
use fabro_config::FabroSettingsExt;
use fabro_interview::FileInterviewer;
use fabro_store::{RuntimeState, Store};
use fabro_types::RunId;

View file

@ -2,7 +2,6 @@ use std::io::{self, IsTerminal, Write};
use std::path::Path;
use anyhow::{Context, Result, bail};
use fabro_config::FabroSettingsExt;
use fabro_sandbox::reconnect::reconnect;
use fabro_workflow::run_lookup::{resolve_run_combined, runs_base};
use fabro_workflow::sandbox_git::GIT_REMOTE;

View file

@ -1,7 +1,6 @@
use anyhow::Context;
use anyhow::Result;
use fabro_checkpoint::git::Store;
use fabro_config::FabroSettingsExt;
use fabro_util::terminal::Styles;
use fabro_workflow::operations::{
ForkRunInput, RewindTarget, build_timeline_or_rebuild, find_run_id_by_prefix_or_store, fork,

View file

@ -2,7 +2,6 @@ use std::path::{Path, PathBuf};
use anyhow::{Context, Result};
use chrono::{DateTime, Utc};
use fabro_config::FabroSettingsExt;
use fabro_types::RunId;
use fabro_workflow::records::{RunRecord, RunRecordExt};
use serde::{Deserialize, Serialize};
@ -132,9 +131,8 @@ fn launcher_process_matches(_record: &LauncherRecord) -> bool {
mod tests {
use super::*;
use chrono::Utc;
use fabro_config::FabroSettings;
use fabro_graphviz::graph::Graph;
use fabro_types::fixtures;
use fabro_types::{Settings, fixtures};
use fabro_workflow::records::RunRecord;
#[test]
@ -147,7 +145,7 @@ mod tests {
RunRecord {
run_id: fixtures::RUN_1,
created_at: Utc::now(),
settings: FabroSettings {
settings: Settings {
storage_dir: Some(storage_dir.clone()),
..Default::default()
},

View file

@ -5,7 +5,6 @@ use std::time::Duration;
use anyhow::{Context, Result, bail};
use chrono::{DateTime, Utc};
use fabro_config::FabroSettingsExt;
use fabro_store::RunStore;
use fabro_util::redact::redact_jsonl_line;
use fabro_util::terminal::Styles;

View file

@ -1,5 +1,4 @@
use anyhow::Result;
use fabro_config::FabroSettingsExt;
use fabro_util::terminal::Styles;
use fabro_workflow::run_lookup::{resolve_run_combined, runs_base};

View file

@ -1,5 +1,4 @@
use anyhow::{Context, Result};
use fabro_config::FabroSettingsExt;
use fabro_sandbox::daytona::DaytonaSandbox;
use fabro_workflow::run_lookup::{resolve_run_combined, runs_base};
use tracing::info;

View file

@ -1,5 +1,4 @@
use anyhow::bail;
use fabro_config::FabroSettingsExt;
use fabro_util::terminal::Styles;
use fabro_workflow::run_lookup::{resolve_run_combined, runs_base};

View file

@ -3,7 +3,6 @@ use anyhow::Result;
use cli_table::format::{Border, Separator};
use cli_table::{Cell, CellStruct, Color, Style, Table};
use fabro_checkpoint::git::Store;
use fabro_config::FabroSettingsExt;
use fabro_util::terminal::Styles;
use fabro_workflow::git::MetadataStore;
use fabro_workflow::operations::{

View file

@ -1,5 +1,4 @@
use anyhow::{Context, Result, bail};
use fabro_config::FabroSettingsExt;
use fabro_sandbox::daytona::DaytonaSandbox;
use fabro_workflow::run_lookup::{resolve_run_combined, runs_base};
use tracing::info;

View file

@ -1,7 +1,6 @@
use std::io::Write;
use anyhow::{Result, bail};
use fabro_config::FabroSettingsExt;
use fabro_types::RunId;
use fabro_util::terminal::Styles;
use fabro_workflow::records::Conclusion;

View file

@ -1,7 +1,6 @@
use std::path::{Path, PathBuf};
use anyhow::{Result, anyhow};
use fabro_config::FabroSettingsExt;
use fabro_types::RunId;
use serde::Serialize;

View file

@ -4,7 +4,6 @@ use anyhow::Result;
use chrono::Utc;
use cli_table::format::{Border, Separator};
use cli_table::{Cell, CellStruct, Color, Style, Table};
use fabro_config::FabroSettingsExt;
use fabro_util::terminal::Styles;
use fabro_util::text::strip_goal_decoration;

View file

@ -1,7 +1,6 @@
use std::path::Path;
use anyhow::{Context, Result, bail};
use fabro_config::FabroSettingsExt;
use fabro_store::Store;
use tracing::warn;

View file

@ -2,7 +2,6 @@ use std::io::{ErrorKind, Write};
use std::path::{Component, Path, PathBuf};
use anyhow::{Context, Result, bail};
use fabro_config::FabroSettingsExt;
use fabro_store::{NodeVisitRef, RunSnapshot, RunStore};
use fabro_workflow::run_lookup::{resolve_run_combined, runs_base};
use serde::Serialize;
@ -360,9 +359,9 @@ mod tests {
use chrono::{DateTime, Utc};
use fabro_store::{EventEnvelope, EventPayload, InMemoryStore, Store as _};
use fabro_types::{
AggregateStats, AttrValue, Checkpoint, Conclusion, FabroSettings, Graph, NodeStatusRecord,
Retro, RunId, RunRecord, RunStatus, RunStatusRecord, SandboxRecord, StageStatus,
StartRecord, StatusReason, fixtures,
AggregateStats, AttrValue, Checkpoint, Conclusion, Graph, NodeStatusRecord, Retro, RunId,
RunRecord, RunStatus, RunStatusRecord, SandboxRecord, Settings, StageStatus, StartRecord,
StatusReason, fixtures,
};
fn dt(rfc3339: &str) -> DateTime<Utc> {
@ -384,7 +383,7 @@ mod tests {
RunRecord {
run_id,
created_at,
settings: FabroSettings::default(),
settings: Settings::default(),
graph,
workflow_slug: Some("night-sky".to_string()),
working_directory: PathBuf::from("/tmp/night-sky"),

View file

@ -4,7 +4,6 @@ use anyhow::Result;
use chrono::{DateTime, Utc};
use cli_table::format::{Border, Justify, Separator};
use cli_table::{Cell, CellStruct, Style, Table};
use fabro_config::FabroSettingsExt;
use serde::Serialize;
use fabro_workflow::run_lookup::{logs_base, runs_base, scan_runs_combined};

View file

@ -2,7 +2,6 @@ use std::path::Path;
use anyhow::{Context, Result, bail};
use chrono::Utc;
use fabro_config::FabroSettingsExt;
use fabro_store::Store;
use serde::Serialize;
use tracing::{debug, info};

View file

@ -5,14 +5,14 @@ use std::path::Path;
pub(crate) use fabro_config::user::*;
use fabro_config::ConfigLayer;
use fabro_config::FabroSettings;
use fabro_types::Settings;
use crate::args::GlobalArgs;
#[cfg(feature = "server")]
use tracing::debug;
pub(crate) fn load_user_settings() -> anyhow::Result<FabroSettings> {
pub(crate) fn load_user_settings() -> anyhow::Result<Settings> {
ConfigLayer::user()?.resolve()
}
@ -21,9 +21,7 @@ pub(crate) fn user_layer_with_globals(globals: &GlobalArgs) -> anyhow::Result<Co
Ok(apply_global_overrides(layer, globals))
}
pub(crate) fn load_user_settings_with_globals(
globals: &GlobalArgs,
) -> anyhow::Result<FabroSettings> {
pub(crate) fn load_user_settings_with_globals(globals: &GlobalArgs) -> anyhow::Result<Settings> {
user_layer_with_globals(globals)?.resolve()
}
@ -57,7 +55,7 @@ const DEFAULT_SERVER_URL: &str = "http://localhost:3000/api/v1";
pub(crate) fn resolve_mode(
cli_storage_dir: Option<&Path>,
cli_server_url: Option<&str>,
settings: &FabroSettings,
settings: &Settings,
) -> ResolvedMode {
let mode = if cli_server_url.is_some() {
ExecutionMode::Server
@ -127,7 +125,7 @@ mod tests {
#[test]
fn resolve_mode_defaults_to_standalone() {
let settings = FabroSettings::default();
let settings = Settings::default();
let resolved = resolve_mode(None, None, &settings);
assert_eq!(resolved.mode, ExecutionMode::Standalone);
assert_eq!(resolved.server_base_url, DEFAULT_SERVER_URL);
@ -136,9 +134,9 @@ mod tests {
#[test]
fn resolve_mode_storage_dir_forces_standalone() {
let settings = FabroSettings {
let settings = Settings {
mode: Some(ExecutionMode::Server),
..FabroSettings::default()
..Settings::default()
};
let resolved = resolve_mode(Some(Path::new("/tmp/fabro")), None, &settings);
assert_eq!(resolved.mode, ExecutionMode::Standalone);
@ -146,13 +144,13 @@ mod tests {
#[test]
fn resolve_mode_server_url_forces_server() {
let settings = FabroSettings {
let settings = Settings {
mode: Some(ExecutionMode::Standalone),
server: Some(ServerSettings {
base_url: Some("https://config.example.com".to_string()),
tls: None,
}),
..FabroSettings::default()
..Settings::default()
};
let resolved = resolve_mode(None, Some("https://cli.example.com"), &settings);
assert_eq!(resolved.mode, ExecutionMode::Server);
@ -161,13 +159,13 @@ mod tests {
#[test]
fn resolve_mode_config_overrides_default() {
let settings = FabroSettings {
let settings = Settings {
mode: Some(ExecutionMode::Server),
server: Some(ServerSettings {
base_url: Some("https://config.example.com".to_string()),
tls: None,
}),
..FabroSettings::default()
..Settings::default()
};
let resolved = resolve_mode(None, None, &settings);
assert_eq!(resolved.mode, ExecutionMode::Server);
@ -176,12 +174,12 @@ mod tests {
#[test]
fn resolve_mode_cli_url_overrides_config_url() {
let settings = FabroSettings {
let settings = Settings {
server: Some(ServerSettings {
base_url: Some("https://config.example.com".to_string()),
tls: None,
}),
..FabroSettings::default()
..Settings::default()
};
let resolved = resolve_mode(None, Some("https://cli.example.com"), &settings);
assert_eq!(resolved.server_base_url, "https://cli.example.com");
@ -194,12 +192,12 @@ mod tests {
key: PathBuf::from("key.pem"),
ca: PathBuf::from("ca.pem"),
};
let settings = FabroSettings {
let settings = Settings {
server: Some(ServerSettings {
base_url: None,
tls: Some(tls.clone()),
}),
..FabroSettings::default()
..Settings::default()
};
let resolved = resolve_mode(None, None, &settings);
assert_eq!(resolved.tls, Some(tls));

View file

@ -1,10 +1,10 @@
use std::path::PathBuf;
use fabro_config::FabroSettings;
use fabro_config::mcp::McpTransport;
#[cfg(feature = "server")]
use fabro_config::user::ExecutionMode;
use fabro_test::{fabro_snapshot, test_context};
use fabro_types::Settings;
use predicates::prelude::*;
use super::support::run_snapshot;
@ -59,8 +59,8 @@ fn old_config_show_command_is_rejected() {
// Helpers
// ---------------------------------------------------------------------------
fn parse_settings(stdout: &[u8]) -> FabroSettings {
serde_yaml::from_slice(stdout).expect("stdout should be valid YAML FabroSettings")
fn parse_settings(stdout: &[u8]) -> Settings {
serde_yaml::from_slice(stdout).expect("stdout should be valid YAML Settings")
}
/// Set up home config and project config for settings command tests.

View file

@ -12,8 +12,8 @@ use crate::run::{
};
use crate::sandbox::SandboxConfig;
use crate::server::{self, ApiConfig, FeaturesConfig, GitConfig, LogConfig, WebConfig};
use crate::settings::FabroSettings;
use crate::user::{self, ExecConfig, ExecutionMode, ServerConfig};
use fabro_types::Settings;
fn is_default_checkpoint(c: &CheckpointConfig) -> bool {
c.exclude_globs.is_empty()
@ -233,7 +233,7 @@ impl ConfigLayer {
}
/// Convert this combined config layer into final resolved settings.
pub fn resolve(self) -> anyhow::Result<FabroSettings> {
pub fn resolve(self) -> anyhow::Result<Settings> {
self.try_into()
}
}

View file

@ -15,7 +15,6 @@ pub mod user;
pub use config::ConfigLayer;
pub use fabro_types::Combine;
pub use fabro_util::path::expand_tilde;
pub use settings::{FabroSettings, FabroSettingsExt};
use std::path::Path;

View file

@ -4,9 +4,9 @@ use std::path::{Path, PathBuf};
use anyhow::{Context, bail};
use serde::{Deserialize, Serialize};
use crate::FabroSettings;
use crate::config::ConfigLayer;
use crate::run;
use fabro_types::Settings;
pub use fabro_types::settings::project::ProjectSettings;
const CONFIG_FILENAME: &str = "fabro.toml";
@ -171,7 +171,7 @@ pub fn resolve_workflow_path(
}
}
pub fn resolve_working_directory(settings: &FabroSettings, caller_cwd: &Path) -> PathBuf {
pub fn resolve_working_directory(settings: &Settings, caller_cwd: &Path) -> PathBuf {
let Some(work_dir) = settings.work_dir.as_deref() else {
return caller_cwd.to_path_buf();
};

View file

@ -4,7 +4,7 @@ use anyhow::anyhow;
use serde::{Deserialize, Serialize};
use crate::config::ConfigLayer;
use crate::settings::{FabroSettings, FabroSettingsExt};
use fabro_types::Settings;
pub use fabro_types::settings::server::{
ApiAuthStrategy, ApiSettings, AuthProvider, AuthSettings, FeaturesSettings, GitAuthorSettings,
GitProvider, GitSettings, LogSettings, TlsSettings, WebSettings, WebhookSettings,
@ -185,11 +185,11 @@ pub fn load_server_config(path: Option<&Path>) -> anyhow::Result<ConfigLayer> {
crate::load_config_file(path, "server.toml")
}
pub fn load_server_settings(path: Option<&Path>) -> anyhow::Result<FabroSettings> {
pub fn load_server_settings(path: Option<&Path>) -> anyhow::Result<Settings> {
load_server_config(path)?.try_into()
}
/// Resolve the storage directory: config value > default `~/.fabro`.
pub fn resolve_storage_dir(settings: &FabroSettings) -> PathBuf {
pub fn resolve_storage_dir(settings: &Settings) -> PathBuf {
settings.storage_dir()
}

View file

@ -1,24 +1,8 @@
use std::path::PathBuf;
pub use fabro_types::settings::FabroSettings;
use fabro_types::Settings;
use crate::config::ConfigLayer;
pub trait FabroSettingsExt {
fn storage_dir(&self) -> PathBuf;
}
impl FabroSettingsExt for FabroSettings {
fn storage_dir(&self) -> PathBuf {
self.storage_dir.clone().unwrap_or_else(|| {
dirs::home_dir()
.expect("could not determine home directory")
.join(".fabro")
})
}
}
impl TryFrom<ConfigLayer> for FabroSettings {
impl TryFrom<ConfigLayer> for Settings {
type Error = anyhow::Error;
fn try_from(value: ConfigLayer) -> Result<Self, Self::Error> {
@ -60,7 +44,7 @@ impl TryFrom<ConfigLayer> for FabroSettings {
}
}
impl TryFrom<&ConfigLayer> for FabroSettings {
impl TryFrom<&ConfigLayer> for Settings {
type Error = anyhow::Error;
fn try_from(value: &ConfigLayer) -> Result<Self, Self::Error> {

View file

@ -1283,7 +1283,7 @@ mod runs {
}
pub(super) fn settings() -> serde_json::Value {
serde_json::to_value(fabro_config::FabroSettings {
serde_json::to_value(fabro_types::Settings {
version: Some(1),
goal: Some("Add rate limiting to auth endpoints".into()),
graph: Some("implement.fabro".into()),
@ -1435,7 +1435,7 @@ mod workflows {
]
}
fn run_settings_to_api(cfg: fabro_config::FabroSettings) -> RunSettings {
fn run_settings_to_api(cfg: fabro_types::Settings) -> RunSettings {
fn strip_nulls(val: serde_json::Value) -> serde_json::Value {
match val {
serde_json::Value::Object(map) => serde_json::Value::Object(
@ -1459,7 +1459,7 @@ mod workflows {
WorkflowDetail {
name: "Fix Build".into(), slug: "fix_build".into(), filename: "fix_build.fabro".into(),
description: "Automatically diagnoses and fixes CI build failures by analyzing error logs, identifying root causes, and applying targeted code changes.".into(),
settings: run_settings_to_api(fabro_config::FabroSettings {
settings: run_settings_to_api(fabro_types::Settings {
version: Some(1),
goal: Some("Diagnose and fix CI build failures".into()),
graph: Some("fix_build.fabro".into()),
@ -1528,7 +1528,7 @@ mod workflows {
WorkflowDetail {
name: "Implement Feature".into(), slug: "implement".into(), filename: "implement.fabro".into(),
description: "Generates production-ready code from a technical blueprint, including tests, documentation, and a pull request ready for review.".into(),
settings: run_settings_to_api(fabro_config::FabroSettings {
settings: run_settings_to_api(fabro_types::Settings {
version: Some(1),
goal: Some("Implement feature from technical blueprint".into()),
graph: Some("implement.fabro".into()),
@ -1615,7 +1615,7 @@ mod workflows {
WorkflowDetail {
name: "Sync Drift".into(), slug: "sync_drift".into(), filename: "sync_drift.fabro".into(),
description: "Detects configuration and code drift between environments, then generates reconciliation patches to bring everything back in sync.".into(),
settings: run_settings_to_api(fabro_config::FabroSettings {
settings: run_settings_to_api(fabro_types::Settings {
version: Some(1),
goal: Some("Detect and reconcile configuration drift across environments".into()),
graph: Some("sync_drift.fabro".into()),
@ -1690,7 +1690,7 @@ mod workflows {
WorkflowDetail {
name: "Expand Product".into(), slug: "expand".into(), filename: "expand.fabro".into(),
description: "Evolves the product by analyzing usage patterns and specifications to propose and implement incremental improvements.".into(),
settings: run_settings_to_api(fabro_config::FabroSettings {
settings: run_settings_to_api(fabro_types::Settings {
version: Some(1),
goal: Some("Propose and implement incremental product improvements".into()),
graph: Some("expand.fabro".into()),
@ -3453,11 +3453,11 @@ mod insights {
}
mod settings {
use fabro_config::FabroSettings;
use fabro_config::server::*;
use fabro_types::Settings;
pub(super) fn server_settings() -> serde_json::Value {
serde_json::to_value(FabroSettings {
serde_json::to_value(Settings {
storage_dir: Some("/home/fabro/.fabro".into()),
max_concurrent_runs: Some(10),
web: Some(WebSettings {

View file

@ -12,8 +12,8 @@ pub mod serve;
pub mod server;
pub mod static_files;
pub mod server_config {
pub use fabro_config::FabroSettings;
pub use fabro_config::server::*;
pub use fabro_types::Settings;
}
pub mod sessions;
pub mod tls;

View file

@ -11,7 +11,7 @@ use tracing::{error, info, warn};
use clap::Args;
use fabro_config::FabroSettings;
use fabro_types::Settings;
use crate::github_webhooks::WebhookManager;
use crate::jwt_auth::{AuthMode, AuthStrategy, resolve_auth_mode};
@ -55,11 +55,7 @@ pub struct ServeArgs {
pub config: Option<PathBuf>,
}
fn apply_serve_overrides(
base: &FabroSettings,
args: &ServeArgs,
dry_run_mode: bool,
) -> FabroSettings {
fn apply_serve_overrides(base: &Settings, args: &ServeArgs, dry_run_mode: bool) -> Settings {
let mut settings = base.clone();
if dry_run_mode {
settings.dry_run = Some(true);

View file

@ -13,7 +13,6 @@ use axum::response::{IntoResponse, Response};
use axum::routing::{get, post};
use axum::{Json, Router};
use axum_extra::extract::cookie::Key;
use fabro_config::FabroSettings;
use fabro_llm::client::Client as LlmClient;
use fabro_llm::generate::{GenerateParams, generate, generate_object};
use fabro_llm::types::{
@ -21,7 +20,7 @@ use fabro_llm::types::{
Response as LlmResponse, Role, StreamEvent, ToolChoice, ToolDefinition, Usage,
};
use fabro_store::{InMemoryStore, Store};
use fabro_types::RunId;
use fabro_types::{RunId, Settings};
use fabro_util::redact::redact_jsonl_line;
use fabro_workflow::error::FabroError;
use fabro_workflow::handler::HandlerRegistry;
@ -131,7 +130,7 @@ pub struct AppState {
scheduler_notify: Notify,
pub sessions: SessionStore,
llm_client: OnceCell<LlmClient>,
pub(crate) settings: Arc<RwLock<FabroSettings>>,
pub(crate) settings: Arc<RwLock<Settings>>,
pub(crate) session_key: Option<Key>,
registry_factory_override: Option<Box<RegistryFactoryOverride>>,
}
@ -405,7 +404,7 @@ async fn get_aggregate_usage(
/// Create an `AppState` with the given LLM spec factory and database pool.
pub fn create_app_state(db: sqlx::SqlitePool) -> Arc<AppState> {
create_app_state_with_options(db, FabroSettings::default(), 5)
create_app_state_with_options(db, Settings::default(), 5)
}
#[doc(hidden)]
@ -415,7 +414,7 @@ pub fn create_app_state_with_registry_factory(
) -> Arc<AppState> {
build_app_state(
db,
Arc::new(RwLock::new(FabroSettings::default())),
Arc::new(RwLock::new(Settings::default())),
Some(Box::new(registry_factory_override)),
5,
Arc::new(InMemoryStore::default()),
@ -425,7 +424,7 @@ pub fn create_app_state_with_registry_factory(
/// Create an `AppState` with the given database pool, settings, and concurrency limit.
pub fn create_app_state_with_options(
db: sqlx::SqlitePool,
settings: FabroSettings,
settings: Settings,
max_concurrent_runs: usize,
) -> Arc<AppState> {
create_app_state_with_store(
@ -438,7 +437,7 @@ pub fn create_app_state_with_options(
pub fn create_app_state_with_store(
db: sqlx::SqlitePool,
settings: Arc<RwLock<FabroSettings>>,
settings: Arc<RwLock<Settings>>,
max_concurrent_runs: usize,
store: Arc<dyn Store>,
) -> Arc<AppState> {
@ -447,7 +446,7 @@ pub fn create_app_state_with_store(
fn build_app_state(
db: sqlx::SqlitePool,
settings: Arc<RwLock<FabroSettings>>,
settings: Arc<RwLock<Settings>>,
registry_factory_override: Option<Box<RegistryFactoryOverride>>,
max_concurrent_runs: usize,
store: Arc<dyn Store>,
@ -1636,8 +1635,8 @@ mod tests {
const POLL_INTERVAL: std::time::Duration = std::time::Duration::from_millis(10);
const POLL_ATTEMPTS: usize = 500;
fn dry_run_settings() -> FabroSettings {
FabroSettings {
fn dry_run_settings() -> Settings {
Settings {
dry_run: Some(true),
..Default::default()
}
@ -1716,7 +1715,7 @@ mod tests {
#[tokio::test]
async fn auth_login_github_redirects_to_github() {
let mut settings = FabroSettings::default();
let mut settings = Settings::default();
settings.web = Some(WebSettings {
url: "http://localhost:3000".to_string(),
auth: AuthSettings {
@ -2431,7 +2430,7 @@ mod tests {
#[tokio::test]
async fn start_run_persists_full_settings_snapshot() {
let settings = FabroSettings {
let settings = Settings {
dry_run: Some(true),
llm: Some(fabro_config::run::LlmSettings {
model: Some("claude-sonnet-4-5".to_string()),
@ -2534,7 +2533,7 @@ mod tests {
let body = body_json(response.into_body()).await;
let run_id = body["id"].as_str().unwrap().parse::<RunId>().unwrap();
*state.settings.write().unwrap() = FabroSettings::default();
*state.settings.write().unwrap() = Settings::default();
execute_run(Arc::clone(&state), run_id).await;
@ -2592,7 +2591,7 @@ mod tests {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn cancel_during_startup_persists_cancelled_reason() {
let settings = FabroSettings {
let settings = Settings {
setup: Some(fabro_config::run::SetupSettings {
commands: vec!["sleep 5".to_string()],
timeout_ms: Some(30_000),
@ -2754,7 +2753,7 @@ mod tests {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn concurrency_limit_respected() {
let state = create_app_state_with_options(test_db().await, FabroSettings::default(), 1);
let state = create_app_state_with_options(test_db().await, Settings::default(), 1);
let app = test_app_with_scheduler(state);
// Submit two runs with max_concurrent_runs=1

View file

@ -444,7 +444,7 @@ mod tests {
let db = test_db().await;
let state = create_app_state_with_options(
db,
fabro_config::FabroSettings {
fabro_types::Settings {
dry_run: Some(true),
..Default::default()
},

View file

@ -9,7 +9,7 @@ use axum::{Json, Router, routing::get, routing::post};
use base64::Engine;
use base64::engine::general_purpose::STANDARD;
use cookie::{Cookie, CookieJar, Expiration, Key, SameSite, time::Duration};
use fabro_config::FabroSettings;
use fabro_types::Settings;
use fabro_types::settings::{ApiAuthStrategy, GitProvider, GitSettings};
use serde::{Deserialize, Serialize};
use serde_json::json;
@ -155,7 +155,7 @@ fn json_response(status: StatusCode, body: serde_json::Value) -> Response {
(status, Json(body)).into_response()
}
fn features_json(settings: &FabroSettings) -> serde_json::Value {
fn features_json(settings: &Settings) -> serde_json::Value {
let features = settings.features.clone().unwrap_or_default();
json!({
"session_sandboxes": features.session_sandboxes,
@ -560,7 +560,7 @@ async fn setup_register(
Json(json!({"ok": true, "restart_required": true})).into_response()
}
fn build_server_toml(settings: &FabroSettings, git: &GitSettings) -> String {
fn build_server_toml(settings: &Settings, git: &GitSettings) -> String {
let web_url = settings.web.as_ref().map_or_else(
|| "http://localhost:3000".to_string(),
|web| web.url.clone(),

View file

@ -662,7 +662,7 @@ mod sse_events {
use axum::body::Body;
use axum::http::{Request, StatusCode};
use fabro_server::server::{build_router, create_app_state_with_options};
use fabro_types::settings::FabroSettings;
use fabro_types::Settings;
use http_body_util::BodyExt;
use tower::ServiceExt;
@ -677,8 +677,8 @@ mod sse_events {
const POLL_INTERVAL: Duration = Duration::from_millis(10);
const POLL_ATTEMPTS: usize = 500;
fn dry_run_settings() -> FabroSettings {
FabroSettings {
fn dry_run_settings() -> Settings {
Settings {
dry_run: Some(true),
..Default::default()
}
@ -858,7 +858,7 @@ mod serve_dry_run {
async fn dry_run_app() -> axum::Router {
let state = create_app_state_with_options(
test_db().await,
fabro_config::FabroSettings {
fabro_types::Settings {
dry_run: Some(true),
..Default::default()
},

View file

@ -226,10 +226,10 @@ fn compare_schema(
}
}
/// Build a FabroSettings with every Option set to Some so all keys appear
/// Build a Settings with every Option set to Some so all keys appear
/// in the serialized JSON.
fn fully_populated_server_config() -> FabroSettings {
FabroSettings {
fn fully_populated_server_config() -> Settings {
Settings {
storage_dir: Some("/data".into()),
max_concurrent_runs: Some(10),
web: Some(WebSettings {

View file

@ -743,8 +743,8 @@ mod tests {
use chrono::Duration as ChronoDuration;
use fabro_types::{
AttrValue, FabroSettings, Graph, PullRequestRecord, RunId, RunStatus, StageStatus,
StatusReason, fixtures,
AttrValue, Graph, PullRequestRecord, RunId, RunStatus, Settings, StageStatus, StatusReason,
fixtures,
};
use tokio::time::timeout;
@ -773,7 +773,7 @@ mod tests {
RunRecord {
run_id: test_run_id(run_id),
created_at,
settings: FabroSettings::default(),
settings: Settings::default(),
graph,
workflow_slug: Some("night-sky".to_string()),
working_directory: PathBuf::from("/tmp/night-sky"),

View file

@ -386,11 +386,11 @@ mod tests {
use bytes::Bytes;
use fabro_types::{
AttrValue, Checkpoint, Conclusion, FabroSettings, Graph, NodeStatusRecord, RunId,
RunRecord, RunStatus, RunStatusRecord, StageStatus, StartRecord, StatusReason, fixtures,
AttrValue, Checkpoint, Conclusion, Graph, NodeStatusRecord, RunId, RunRecord, RunStatus,
RunStatusRecord, Settings, StageStatus, StartRecord, StatusReason, fixtures,
};
use object_store::memory::InMemory;
use slatedb::config::Settings;
use slatedb::config::Settings as SlateSettings;
use slatedb::{CloseReason, ErrorKind};
use tokio::time::timeout;
@ -425,7 +425,7 @@ mod tests {
RunRecord {
run_id: test_run_id(run_id),
created_at,
settings: FabroSettings::default(),
settings: Settings::default(),
graph,
workflow_slug: Some("night-sky".to_string()),
working_directory: PathBuf::from("/tmp/night-sky"),
@ -530,9 +530,9 @@ mod tests {
include_init: bool,
) -> slatedb::Db {
let db = slatedb::Db::builder(record.db_prefix.clone(), object_store)
.with_settings(Settings {
.with_settings(SlateSettings {
flush_interval: Some(Duration::from_millis(1)),
..Settings::default()
..SlateSettings::default()
})
.build()
.await
@ -959,9 +959,9 @@ mod tests {
let created_at = dt("2026-03-27T12:00:00Z");
let db_prefix = catalog::db_prefix("runs/", created_at, &test_run_id("run-1"));
let db = slatedb::Db::builder(db_prefix.clone(), object_store)
.with_settings(Settings {
.with_settings(SlateSettings {
flush_interval: Some(Duration::from_millis(1)),
..Settings::default()
..SlateSettings::default()
})
.build()
.await

View file

@ -19,6 +19,7 @@ workspace = true
[dependencies]
chrono = { workspace = true, features = ["serde"] }
clap = { workspace = true, optional = true }
dirs.workspace = true
fabro-macros = { path = "../fabro-macros" }
serde.workspace = true
serde_json.workspace = true

View file

@ -32,7 +32,7 @@ pub use run::RunRecord;
pub use run_id::RunId;
pub use run_id::fixtures;
pub use sandbox_record::SandboxRecord;
pub use settings::FabroSettings;
pub use settings::Settings;
pub use start::StartRecord;
pub use status::{
InvalidTransition, ParseRunStatusError, RunStatus, RunStatusRecord, StatusReason,

View file

@ -6,13 +6,13 @@ use serde::{Deserialize, Serialize};
use crate::graph::Graph;
use crate::run_id::RunId;
use crate::settings::FabroSettings;
use crate::settings::Settings;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RunRecord {
pub run_id: RunId,
pub created_at: DateTime<Utc>,
pub settings: FabroSettings,
pub settings: Settings,
pub graph: Graph,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub workflow_slug: Option<String>,

View file

@ -39,7 +39,7 @@ fn is_default_checkpoint(c: &CheckpointSettings) -> bool {
}
#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
pub struct FabroSettings {
pub struct Settings {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub version: Option<u32>,
#[serde(default, skip_serializing_if = "Option::is_none")]
@ -108,7 +108,7 @@ pub struct FabroSettings {
pub fabro: Option<ProjectSettings>,
}
impl FabroSettings {
impl Settings {
pub fn app_id(&self) -> Option<&str> {
self.git.as_ref().and_then(|g| g.app_id.as_deref())
}
@ -183,4 +183,12 @@ impl FabroSettings {
pub fn no_retro_enabled(&self) -> bool {
self.no_retro.unwrap_or(false)
}
pub fn storage_dir(&self) -> PathBuf {
self.storage_dir.clone().unwrap_or_else(|| {
dirs::home_dir()
.expect("could not determine home directory")
.join(".fabro")
})
}
}

View file

@ -2,8 +2,8 @@ use std::path::Path;
use std::process::Command;
use fabro_checkpoint::git::Store;
use fabro_config::FabroSettings;
use fabro_store::{NodeVisitRef, RunStore};
use fabro_types::Settings;
use crate::error::{FabroError, Result};
use tokio::task::{JoinError, spawn_blocking};
@ -16,7 +16,7 @@ pub use fabro_checkpoint::metadata::MetadataStore;
/// Branch prefix for workflow run branches (e.g. `fabro/run/{run_id}`).
pub const RUN_BRANCH_PREFIX: &str = "fabro/run/";
pub fn git_author_from_settings(settings: &FabroSettings) -> GitAuthor {
pub fn git_author_from_settings(settings: &Settings) -> GitAuthor {
settings
.git_author()
.map(GitAuthor::from)
@ -592,7 +592,7 @@ mod tests {
run.put_run(&RunRecord {
run_id: fixtures::RUN_1,
created_at,
settings: fabro_config::FabroSettings::default(),
settings: Settings::default(),
graph: Graph::new("test"),
workflow_slug: None,
working_directory: std::path::PathBuf::from("."),

View file

@ -16,9 +16,9 @@ use crate::run_dir::visit_from_context;
use crate::run_options::RunOptions;
use async_trait::async_trait;
use chrono::Utc;
use fabro_config::FabroSettings;
use fabro_graphviz::graph::{AttrValue, Graph, Node};
use fabro_store::{InMemoryStore, Store};
use fabro_types::Settings;
use tokio::time::{sleep, timeout};
use super::{EngineServices, Handler};
@ -65,7 +65,7 @@ fn parse_child_graph(node: &Node) -> Result<Graph, FabroError> {
source: dot.to_string(),
base_dir: None,
},
settings: FabroSettings::default(),
settings: Settings::default(),
cwd: cwd.clone(),
custom_transforms: Vec::new(),
})?;
@ -81,7 +81,7 @@ fn parse_child_graph(node: &Node) -> Result<Graph, FabroError> {
{
let validated = validate(ValidateInput {
workflow: WorkflowInput::Path(PathBuf::from(path)),
settings: FabroSettings::default(),
settings: Settings::default(),
cwd,
custom_transforms: Vec::new(),
})?;
@ -161,7 +161,7 @@ impl Handler for SubWorkflowHandler {
let child_cancel = Arc::clone(&cancel_token);
let child_run_options = RunOptions {
settings: fabro_config::FabroSettings::default(),
settings: Settings::default(),
run_dir: child_logs,
cancel_token: Some(cancel_token),
// Child workflows are part of the parent run's event stream.

View file

@ -1,10 +1,9 @@
use chrono::{Local, Utc};
use fabro_config::{FabroSettings, FabroSettingsExt};
use fabro_graphviz::graph::{AttrValue, Graph};
use fabro_model::{Catalog, Provider};
use fabro_sandbox::SandboxProvider;
use fabro_store::Store;
use fabro_types::RunId;
use fabro_types::{RunId, Settings};
use std::collections::BTreeMap;
use std::collections::HashMap;
use std::path::{Path, PathBuf};
@ -26,7 +25,7 @@ const RUN_CONFIG_FILE: &str = "workflow.toml";
#[derive(Clone, Debug)]
pub struct CreateRunInput {
pub workflow: WorkflowInput,
pub settings: FabroSettings,
pub settings: Settings,
pub cwd: PathBuf,
pub workflow_slug: Option<String>,
pub run_dir: Option<PathBuf>,
@ -44,7 +43,7 @@ pub struct CreatedRun {
}
struct PersistCreateOptions {
settings: FabroSettings,
settings: Settings,
run_dir: Option<PathBuf>,
run_id: Option<RunId>,
workflow_slug: Option<String>,
@ -207,7 +206,7 @@ fn store_error(err: impl std::fmt::Display) -> FabroError {
FabroError::engine(err.to_string())
}
fn validate_sandbox_provider(settings: &FabroSettings) -> Result<(), FabroError> {
fn validate_sandbox_provider(settings: &Settings) -> Result<(), FabroError> {
if let Some(provider) = settings
.sandbox_settings()
.and_then(|sandbox| sandbox.provider.as_deref())
@ -261,7 +260,7 @@ pub(super) fn preprocess_and_validate(
dot_source: &str,
base_dir: Option<PathBuf>,
custom_transforms: Vec<Box<dyn Transform>>,
settings: Option<&FabroSettings>,
settings: Option<&Settings>,
goal_override: Option<&str>,
) -> Result<Validated, FabroError> {
let source = match settings.and_then(|resolved| resolved.vars.as_ref()) {
@ -338,7 +337,7 @@ fn persist_validated(
)
}
pub(crate) fn resolve_run_settings(mut settings: FabroSettings, graph: &Graph) -> FabroSettings {
pub(crate) fn resolve_run_settings(mut settings: Settings, graph: &Graph) -> Settings {
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());
@ -414,7 +413,7 @@ mod tests {
InMemoryStore::default()
}
fn validate_dot(dot_source: &str, settings: FabroSettings) -> Validated {
fn validate_dot(dot_source: &str, settings: Settings) -> Validated {
validate(ValidateInput {
workflow: WorkflowInput::DotSource {
source: dot_source.to_string(),
@ -436,7 +435,7 @@ mod tests {
#[test]
fn validate_minimal() {
let validated = validate_dot(MINIMAL_DOT, FabroSettings::default());
let validated = validate_dot(MINIMAL_DOT, Settings::default());
validated.raise_on_errors().unwrap();
assert_eq!(validated.graph().name, "Test");
@ -453,7 +452,7 @@ mod tests {
exit [shape=Msquare]
start -> work -> exit
}"#;
let validated = validate_dot(dot, FabroSettings::default());
let validated = validate_dot(dot, Settings::default());
validated.raise_on_errors().unwrap();
let prompt = validated.graph().nodes["work"]
@ -473,7 +472,7 @@ mod tests {
exit [shape=Msquare]
start -> work -> exit
}"#;
let validated = validate_dot(dot, FabroSettings::default());
let validated = validate_dot(dot, Settings::default());
validated.raise_on_errors().unwrap();
assert_eq!(
@ -493,7 +492,7 @@ mod tests {
}"#;
let validated = validate_dot(
dot,
FabroSettings {
Settings {
vars: Some(HashMap::from([("who".to_string(), "agent".to_string())])),
goal: Some("override".to_string()),
..Default::default()
@ -517,7 +516,7 @@ mod tests {
source: "not a graph".to_string(),
base_dir: None,
},
settings: FabroSettings::default(),
settings: Settings::default(),
cwd: PathBuf::from("."),
custom_transforms: Vec::new(),
});
@ -530,7 +529,7 @@ mod tests {
graph [goal="Test"]
work [label="Work"]
}"#;
let validated = validate_dot(dot, FabroSettings::default());
let validated = validate_dot(dot, Settings::default());
assert!(validated.has_errors());
assert!(validated.raise_on_errors().is_err());
@ -557,7 +556,7 @@ mod tests {
source: MINIMAL_DOT.to_string(),
base_dir: None,
},
settings: FabroSettings::default(),
settings: Settings::default(),
cwd: PathBuf::from("."),
custom_transforms: vec![Box::new(TagTransform)],
})
@ -590,7 +589,7 @@ mod tests {
let validated = validate(ValidateInput {
workflow: WorkflowInput::Path(dot_path),
settings: FabroSettings::default(),
settings: Settings::default(),
cwd: dir.path().to_path_buf(),
custom_transforms: Vec::new(),
})
@ -614,7 +613,7 @@ mod tests {
source: dot.to_string(),
base_dir: None,
},
settings: FabroSettings::default(),
settings: Settings::default(),
cwd: dir.path().to_path_buf(),
workflow_slug: None,
run_dir: Some(dir.path().join("run")),
@ -645,7 +644,7 @@ mod tests {
source: MINIMAL_DOT.to_string(),
base_dir: None,
},
settings: FabroSettings {
settings: Settings {
llm: Some(fabro_config::run::LlmSettings {
model: Some("sonnet".to_string()),
provider: None,
@ -734,7 +733,7 @@ mod tests {
&store,
CreateRunInput {
workflow: WorkflowInput::Path(workflow_dir.join("workflow.toml")),
settings: FabroSettings {
settings: Settings {
storage_dir: Some(dir.path().join("storage")),
dry_run: Some(true),
..Default::default()
@ -770,7 +769,7 @@ mod tests {
source: MINIMAL_DOT.to_string(),
base_dir: None,
},
settings: FabroSettings {
settings: Settings {
work_dir: Some("workspace".to_string()),
dry_run: Some(true),
..Default::default()
@ -816,7 +815,7 @@ mod tests {
source: MINIMAL_DOT.to_string(),
base_dir: None,
},
settings: FabroSettings {
settings: Settings {
storage_dir: Some(storage_dir.clone()),
dry_run: Some(true),
..Default::default()

View file

@ -333,11 +333,11 @@ mod tests {
use std::sync::Arc;
use chrono::{TimeZone, Utc};
use fabro_config::FabroSettings;
use fabro_graphviz::graph::Graph;
use fabro_store::{InMemoryStore, NodeVisitRef, Store as _};
use fabro_types::{
NodeStatusRecord, RunId, RunRecord, SandboxRecord, StageStatus, StartRecord, fixtures,
NodeStatusRecord, RunId, RunRecord, SandboxRecord, Settings, StageStatus, StartRecord,
fixtures,
};
use super::*;
@ -360,7 +360,7 @@ mod tests {
RunRecord {
run_id,
created_at: created_at(),
settings: FabroSettings::default(),
settings: Settings::default(),
graph: Graph::new("test"),
workflow_slug: None,
working_directory: PathBuf::from("/tmp/project"),

View file

@ -1,7 +1,8 @@
use std::path::{Path, PathBuf};
use anyhow::Context;
use fabro_config::{FabroSettings, project as project_config};
use fabro_config::project as project_config;
use fabro_types::Settings;
use fabro_util::path::expand_tilde;
#[derive(Clone, Debug)]
@ -16,14 +17,14 @@ pub enum WorkflowInput {
#[derive(Clone, Debug)]
pub(crate) struct ResolveWorkflowInput {
pub workflow: WorkflowInput,
pub settings: FabroSettings,
pub settings: Settings,
pub cwd: PathBuf,
}
#[derive(Clone, Debug)]
pub(crate) struct ResolvedWorkflow {
pub raw_source: String,
pub settings: FabroSettings,
pub settings: Settings,
pub workflow_slug: Option<String>,
pub workflow_toml_path: Option<PathBuf>,
pub dot_path: Option<PathBuf>,
@ -125,7 +126,7 @@ mod tests {
let resolved = resolve_workflow(ResolveWorkflowInput {
workflow: WorkflowInput::Path(run_dir.join("workflow.toml")),
settings: FabroSettings::default(),
settings: Settings::default(),
cwd: dir.path().to_path_buf(),
})
.unwrap();
@ -146,7 +147,7 @@ mod tests {
source: "digraph Test { start -> exit }".to_string(),
base_dir: None,
},
settings: FabroSettings {
settings: Settings {
work_dir: Some("workspace".to_string()),
..Default::default()
},

View file

@ -5,14 +5,13 @@ use std::sync::{Arc, Mutex};
use std::time::{Duration, Instant};
use chrono::Utc;
use fabro_config::FabroSettings;
use fabro_config::sandbox::WorktreeMode;
use fabro_config::{project as project_config, run as run_config, sandbox as sandbox_config};
use fabro_interview::{AutoApproveInterviewer, Interviewer};
use fabro_model::{Catalog, FallbackTarget, Provider};
use fabro_sandbox::{SandboxProvider, SandboxSpec};
use fabro_store::RunStore;
use fabro_types::RunId;
use fabro_types::{RunId, Settings};
use serde::Serialize;
use crate::context::Context;
@ -370,7 +369,7 @@ impl RunSession {
}
}
fn resolve_sandbox_provider(settings: &FabroSettings) -> Result<SandboxProvider, FabroError> {
fn resolve_sandbox_provider(settings: &Settings) -> Result<SandboxProvider, FabroError> {
settings
.sandbox_settings()
.and_then(|sandbox| sandbox.provider.as_deref())
@ -380,11 +379,11 @@ fn resolve_sandbox_provider(settings: &FabroSettings) -> Result<SandboxProvider,
.map_or_else(|| Ok(SandboxProvider::default()), Ok)
}
fn resolve_preserve_sandbox(settings: &FabroSettings) -> bool {
fn resolve_preserve_sandbox(settings: &Settings) -> bool {
settings.preserve_sandbox_enabled()
}
fn resolve_worktree_mode(settings: &FabroSettings) -> sandbox_config::WorktreeMode {
fn resolve_worktree_mode(settings: &Settings) -> sandbox_config::WorktreeMode {
settings
.sandbox_settings()
.and_then(|sandbox| sandbox.local.as_ref())
@ -392,7 +391,7 @@ fn resolve_worktree_mode(settings: &FabroSettings) -> sandbox_config::WorktreeMo
.unwrap_or_default()
}
fn resolve_daytona_config(settings: &FabroSettings) -> Option<DaytonaConfig> {
fn resolve_daytona_config(settings: &Settings) -> Option<DaytonaConfig> {
settings
.sandbox_settings()
.and_then(|sandbox| sandbox.daytona.clone())
@ -401,7 +400,7 @@ fn resolve_daytona_config(settings: &FabroSettings) -> Option<DaytonaConfig> {
fn resolve_fallback_chain(
provider: Provider,
model: &str,
settings: &FabroSettings,
settings: &Settings,
) -> Vec<FallbackTarget> {
let fallbacks = settings.llm.as_ref().and_then(|llm| llm.fallbacks.as_ref());
@ -837,9 +836,8 @@ mod tests {
use std::sync::atomic::{AtomicBool, Ordering};
use chrono::Utc;
use fabro_config::FabroSettings;
use fabro_store::{InMemoryStore, Store};
use fabro_types::fixtures;
use fabro_types::{Settings, fixtures};
use super::*;
use crate::context::Context;
@ -866,7 +864,7 @@ mod tests {
source: dot.to_string(),
base_dir: None,
},
settings: FabroSettings {
settings: Settings {
dry_run: Some(true),
..Default::default()
},

View file

@ -1,6 +1,6 @@
use std::path::PathBuf;
use fabro_config::FabroSettings;
use fabro_types::Settings;
use crate::error::FabroError;
use crate::pipeline::Validated;
@ -11,7 +11,7 @@ use super::source::{ResolveWorkflowInput, WorkflowInput, resolve_workflow};
pub struct ValidateInput {
pub workflow: WorkflowInput,
pub settings: FabroSettings,
pub settings: Settings,
pub cwd: PathBuf,
pub custom_transforms: Vec<Box<dyn Transform>>,
}

View file

@ -9,13 +9,12 @@ use std::time::Duration;
use async_trait::async_trait;
use chrono::Utc;
use fabro_agent::Sandbox;
use fabro_config::FabroSettings;
use fabro_graphviz::graph::{AttrValue, Edge, Graph, Node};
use fabro_hooks::HookSettings;
use fabro_interview::AutoApproveInterviewer;
use fabro_sandbox::SandboxSpec;
use fabro_store::InMemoryStore;
use fabro_types::{RunId, fixtures};
use fabro_types::{RunId, Settings, fixtures};
use super::*;
use crate::context::{self, Context};
@ -90,7 +89,7 @@ fn test_run_options(run_dir: &Path, run_id: &str) -> RunOptions {
run_dir: run_dir.to_path_buf(),
cancel_token: None,
run_id: test_run_id(run_id),
settings: FabroSettings::default(),
settings: Settings::default(),
git: None,
host_repo_path: None,
labels: HashMap::new(),
@ -133,7 +132,7 @@ fn persisted_workflow(graph: Graph, source: String, run_dir: &Path, run_id: RunI
RunRecord {
run_id,
created_at: Utc::now(),
settings: FabroSettings::default(),
settings: Settings::default(),
graph,
workflow_slug: Some("test".to_string()),
working_directory: std::env::current_dir().unwrap_or_else(|_| PathBuf::from(".")),

View file

@ -349,10 +349,9 @@ mod tests {
use std::sync::Arc;
use chrono::Utc;
use fabro_config::FabroSettings;
use fabro_graphviz::graph::Graph;
use fabro_store::{InMemoryStore, Store};
use fabro_types::{RunId, fixtures};
use fabro_types::{RunId, Settings, fixtures};
use super::*;
use crate::pipeline::types::Retroed;
@ -364,7 +363,7 @@ mod tests {
fn test_run_options(run_dir: &std::path::Path) -> RunOptions {
RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: run_dir.to_path_buf(),
cancel_token: None,
run_id: test_run_id(),

View file

@ -672,12 +672,11 @@ mod tests {
use std::sync::Arc;
use chrono::Utc;
use fabro_config::FabroSettings;
use fabro_graphviz::graph::{AttrValue, Edge, Graph, Node};
use fabro_interview::AutoApproveInterviewer;
use fabro_sandbox::SandboxSpec;
use fabro_store::InMemoryStore;
use fabro_types::{RunId, fixtures};
use fabro_types::{RunId, Settings, fixtures};
use super::*;
use crate::pipeline::types::InitOptions;
@ -714,7 +713,7 @@ mod tests {
fn test_settings(run_dir: &std::path::Path) -> RunOptions {
RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: run_dir.to_path_buf(),
cancel_token: None,
run_id: test_run_id(),
@ -737,7 +736,7 @@ mod tests {
RunRecord {
run_id: test_run_id(),
created_at: Utc::now(),
settings: FabroSettings::default(),
settings: Settings::default(),
graph,
workflow_slug: Some("test".to_string()),
working_directory: std::env::current_dir().unwrap(),

View file

@ -56,10 +56,9 @@ mod tests {
use std::path::PathBuf;
use chrono::Utc;
use fabro_config::FabroSettings;
use fabro_graphviz::graph::{AttrValue, Edge, Graph, Node};
use fabro_store::{InMemoryStore, Store};
use fabro_types::fixtures;
use fabro_types::{Settings, fixtures};
use super::*;
use crate::records::RunRecord;
@ -112,7 +111,7 @@ mod tests {
RunRecord {
run_id: fixtures::RUN_1,
created_at: Utc::now(),
settings: FabroSettings {
settings: Settings {
dry_run: Some(true),
verbose: Some(true),
..Default::default()

View file

@ -628,7 +628,6 @@ mod tests {
use super::*;
use crate::records::StageSummary;
use chrono::Utc;
use fabro_config::FabroSettings;
use fabro_graphviz::graph::Graph;
use fabro_llm::client::Client;
use fabro_llm::error::SdkError;
@ -639,8 +638,7 @@ mod tests {
AggregateStats, FrictionKind, FrictionPoint, OpenItem, OpenItemKind, StageRetro,
};
use fabro_store::{InMemoryStore, Store};
use fabro_types::RunRecord;
use fabro_types::fixtures;
use fabro_types::{RunRecord, Settings, fixtures};
use futures::stream;
struct MockProvider {
@ -1102,7 +1100,7 @@ mod tests {
.put_run(&RunRecord {
run_id: fixtures::RUN_1,
created_at,
settings: FabroSettings::default(),
settings: Settings::default(),
graph: Graph::new("test"),
workflow_slug: Some("test".to_string()),
working_directory: PathBuf::from("/tmp/project"),

View file

@ -169,10 +169,9 @@ mod tests {
use std::sync::{Arc, Mutex};
use chrono::Utc;
use fabro_config::FabroSettings;
use fabro_graphviz::graph::Graph;
use fabro_store::{InMemoryStore, Store};
use fabro_types::{RunId, fixtures};
use fabro_types::{RunId, Settings, fixtures};
use super::*;
use crate::context::Context;
@ -223,7 +222,7 @@ mod tests {
fn test_run_options(run_dir: &std::path::Path) -> RunOptions {
RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: run_dir.to_path_buf(),
cancel_token: None,
run_id: test_run_id(),

View file

@ -440,10 +440,9 @@ mod tests {
use std::path::PathBuf;
use chrono::Utc;
use fabro_config::FabroSettings;
use fabro_graphviz::graph::Graph;
use fabro_store::{InMemoryStore, Store};
use fabro_types::{RunStatus, RunStatusRecord, fixtures};
use fabro_types::{RunStatus, RunStatusRecord, Settings, fixtures};
use super::scan_runs_combined;
use crate::records::{RunRecord, RunRecordExt};
@ -452,7 +451,7 @@ mod tests {
RunRecord {
run_id: fixtures::RUN_1,
created_at: Utc::now(),
settings: FabroSettings::default(),
settings: Settings::default(),
graph: Graph::new("test"),
workflow_slug: Some("test".to_string()),
working_directory: PathBuf::from("/tmp/project"),

View file

@ -3,9 +3,8 @@ use std::path::PathBuf;
use std::sync::Arc;
use std::sync::atomic::AtomicBool;
use fabro_config::FabroSettings;
use fabro_config::run::PullRequestSettings;
use fabro_types::RunId;
use fabro_types::{RunId, Settings};
use crate::git::{GitAuthor, git_author_from_settings};
@ -20,7 +19,7 @@ pub struct GitCheckpointOptions {
/// Options for a workflow run.
#[derive(Clone)]
pub struct RunOptions {
pub settings: FabroSettings,
pub settings: Settings,
pub run_dir: PathBuf,
pub cancel_token: Option<Arc<AtomicBool>>,
/// Unique identifier for this workflow run.

View file

@ -18,13 +18,12 @@ use std::path::Path;
use std::sync::Arc;
use fabro_agent::Sandbox;
use fabro_config::FabroSettings;
use fabro_graphviz::graph::{AttrValue, Edge, Graph, Node};
use fabro_llm::provider::Provider;
use fabro_sandbox::SandboxRecordExt;
use fabro_sandbox::daytona::{DaytonaConfig, DaytonaSandbox, DaytonaSnapshotConfig};
use fabro_store::RuntimeState;
use fabro_types::RunId;
use fabro_types::{RunId, Settings};
use fabro_workflow::artifact::sync_artifacts_to_env;
use fabro_workflow::context::Context;
use fabro_workflow::error::FabroError;
@ -392,7 +391,7 @@ async fn daytona_pipeline_artifact_offload_and_sync() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), env.clone());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -581,7 +580,7 @@ async fn daytona_git_checkpoint_remote_emits_events() {
let engine = WorkflowRunner::new(registry, Arc::new(emitter), env.clone());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("git-cp-test"),
@ -762,7 +761,7 @@ async fn daytona_parallel_git_branching_e2e() {
let engine = WorkflowRunner::new(registry, Arc::new(emitter), Arc::clone(&env));
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: run_tmp.path().to_path_buf(),
cancel_token: None,
run_id,
@ -1122,7 +1121,7 @@ async fn daytona_git_checkpoint_with_shadow_branch() {
let meta_branch = MetadataStore::branch_name(&run_id.to_string());
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), env.clone());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id,
@ -1260,11 +1259,11 @@ async fn daytona_asset_collection() {
graph.edges.push(Edge::new("create_assets", "exit"));
let run_options = RunOptions {
settings: FabroSettings {
settings: Settings {
assets: Some(fabro_config::run::AssetsSettings {
include: vec!["test-results/**".to_string()],
}),
..FabroSettings::default()
..Settings::default()
},
run_dir: dir.path().to_path_buf(),
cancel_token: None,
@ -1515,7 +1514,7 @@ async fn daytona_git_push_run_branch_to_origin() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), env.clone());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id,

View file

@ -17,7 +17,6 @@ use std::path::Path;
use std::sync::Arc;
use std::time::Duration;
use fabro_config::FabroSettings;
use fabro_graphviz::graph::{AttrValue, Edge, Graph, Node};
use fabro_graphviz::parser::parse;
use fabro_interview::{
@ -26,7 +25,7 @@ use fabro_interview::{
};
use fabro_llm::provider::Provider;
use fabro_store::RuntimeState;
use fabro_types::RunId;
use fabro_types::{RunId, Settings};
use fabro_validate::{Severity, validate, validate_or_raise};
use fabro_workflow::context::Context;
use fabro_workflow::error::{FabroError, FailureSignatureExt};
@ -215,7 +214,7 @@ async fn end_to_end_linear_pipeline() {
local_env(),
);
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -355,7 +354,7 @@ async fn end_to_end_branching_pipeline() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -474,7 +473,7 @@ async fn end_to_end_human_gate_pipeline() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -569,7 +568,7 @@ async fn human_gate_aborted_input_fails_closed_without_fail_route() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -679,7 +678,7 @@ async fn human_gate_aborted_input_routes_via_outcome_fail_condition() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -791,7 +790,7 @@ async fn goal_gate_routes_to_retry_target_on_failure() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -911,7 +910,7 @@ async fn goal_gate_routes_to_retry_target_when_present() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -1222,7 +1221,7 @@ async fn retry_on_failure_then_succeed() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -1296,7 +1295,7 @@ async fn pipeline_with_many_nodes() {
local_env(),
);
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -1617,7 +1616,7 @@ async fn smoke_test_with_mock_codergen_backend() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -1717,7 +1716,7 @@ async fn end_to_end_parallel_fan_out_fan_in() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -1829,7 +1828,7 @@ async fn resume_from_checkpoint_completes_pipeline() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -1927,7 +1926,7 @@ async fn resume_from_checkpoint_preserves_goal_gate_outcomes() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -1969,7 +1968,7 @@ async fn graph_goal_in_context() {
local_env(),
);
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -2004,7 +2003,7 @@ async fn event_streaming_lifecycle() {
let events = collect_events(&emitter);
let engine = WorkflowRunner::new(make_linear_registry(), Arc::new(emitter), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -2079,7 +2078,7 @@ async fn context_flow_between_stages() {
local_env(),
);
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -2131,7 +2130,7 @@ async fn tool_handler_e2e() {
local_env(),
);
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -2202,7 +2201,7 @@ async fn auto_approve_interviewer_e2e() {
local_env(),
);
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -2238,7 +2237,7 @@ async fn codergen_without_backend_simulated() {
local_env(),
);
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -2339,7 +2338,7 @@ async fn branching_loop_back_on_failure() {
);
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -2421,7 +2420,7 @@ async fn human_gate_loops_back() {
registry.register("human", Box::new(HumanHandler::new(interviewer)));
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -2478,7 +2477,7 @@ async fn scenario_ship_a_feature() {
local_env(),
);
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -2559,7 +2558,7 @@ async fn scenario_parallel_expert_review() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -2642,7 +2641,7 @@ async fn scenario_node_retries_on_retry_status() {
);
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -2703,7 +2702,7 @@ async fn scenario_loop_restart_resets_context() {
);
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -2770,7 +2769,7 @@ async fn scenario_bug_triage_router() {
registry.register("conditional", Box::new(ConditionalHandler));
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -2828,7 +2827,7 @@ async fn scenario_crash_recovery() {
registry.register("exit", Box::new(ExitHandler));
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -2936,7 +2935,7 @@ async fn manager_loop_stop_condition_satisfied_e2e() {
registry.register("stack.manager_loop", Box::new(SubWorkflowHandler));
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -3014,7 +3013,7 @@ async fn manager_loop_max_cycles_exceeded_e2e() {
registry.register("stack.manager_loop", Box::new(SubWorkflowHandler));
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -3151,7 +3150,7 @@ async fn conditional_branching_success_fail_paths() {
registry.register("always_fail", Box::new(AlwaysFailHandler));
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -3203,7 +3202,7 @@ async fn edge_selection_condition_match_wins_over_weight() {
registry.register("exit", Box::new(ExitHandler));
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -3249,7 +3248,7 @@ async fn edge_selection_weight_breaks_ties() {
registry.register("exit", Box::new(ExitHandler));
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -3287,7 +3286,7 @@ async fn edge_selection_lexical_tiebreak() {
registry.register("exit", Box::new(ExitHandler));
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -3344,7 +3343,7 @@ async fn context_updates_visible_across_nodes() {
registry.register("context_setter", Box::new(ContextSetterHandler));
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -3387,7 +3386,7 @@ async fn stylesheet_applies_model_override() {
local_env(),
);
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -3442,7 +3441,7 @@ async fn custom_handler_registration_and_execution() {
registry.register("my_custom", Box::new(CustomHandler));
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -3512,7 +3511,7 @@ async fn integration_smoke_plan_implement_review_done() {
local_env(),
);
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -3613,7 +3612,7 @@ async fn manager_loop_runs_child_engine_e2e() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -3746,7 +3745,7 @@ async fn manager_loop_context_flows_e2e() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -3818,7 +3817,7 @@ async fn manager_loop_child_dotfile_e2e() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -3919,7 +3918,7 @@ async fn import_e2e_through_engine() {
local_env(),
);
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -4072,7 +4071,7 @@ async fn fidelity_default_is_compact() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -4128,7 +4127,7 @@ async fn fidelity_graph_default_applied() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -4180,7 +4179,7 @@ async fn fidelity_node_overrides_graph_default() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -4238,7 +4237,7 @@ async fn fidelity_edge_overrides_node_and_graph() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -4286,7 +4285,7 @@ async fn fidelity_full_produces_empty_preamble() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -4344,7 +4343,7 @@ async fn fidelity_truncate_preamble_minimal() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -4415,7 +4414,7 @@ async fn fidelity_summary_low_mode() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -4481,7 +4480,7 @@ async fn fidelity_summary_medium_mode() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -4547,7 +4546,7 @@ async fn fidelity_summary_high_mode() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -4606,7 +4605,7 @@ async fn fidelity_full_sets_thread_id_in_context() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -4676,7 +4675,7 @@ async fn fidelity_full_nodes_share_thread_id() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -4756,7 +4755,7 @@ async fn fidelity_resume_degrades_full_to_summary_high() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -4852,7 +4851,7 @@ async fn fidelity_resume_degrade_only_affects_first_hop() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -4935,7 +4934,7 @@ async fn fidelity_resume_no_degrade_when_not_full() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -4976,7 +4975,7 @@ async fn fidelity_stored_in_checkpoint_context() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -5061,7 +5060,7 @@ async fn fidelity_precedence_multi_node_pipeline() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -5128,7 +5127,7 @@ async fn fidelity_compact_preamble_includes_completed_stages_and_context() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -5203,7 +5202,7 @@ async fn fidelity_summary_low_excludes_context_values_in_pipeline() {
let engine_low =
WorkflowRunner::new(registry_low, Arc::new(EventEmitter::default()), local_env());
let run_options_low = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir_low.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -5270,7 +5269,7 @@ async fn fidelity_summary_low_excludes_context_values_in_pipeline() {
let engine_med =
WorkflowRunner::new(registry_med, Arc::new(EventEmitter::default()), local_env());
let run_options_med = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir_med.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -5340,7 +5339,7 @@ async fn fidelity_thread_id_fallback_to_previous_node_in_pipeline() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -5393,7 +5392,7 @@ async fn fidelity_thread_id_from_node_class_in_pipeline() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -5449,7 +5448,7 @@ async fn fidelity_edge_thread_id_override_in_pipeline() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -5506,7 +5505,7 @@ async fn fidelity_full_without_explicit_thread_id_uses_previous_node() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -5573,7 +5572,7 @@ async fn fidelity_from_parsed_dot_pipeline() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -5620,7 +5619,7 @@ async fn fidelity_checkpoint_roundtrip_preserves_fidelity() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -5689,7 +5688,7 @@ async fn fidelity_node_thread_id_overrides_edge_thread_id_in_pipeline() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -5775,7 +5774,7 @@ async fn fidelity_resume_preserves_context_values_across_checkpoint() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -5817,8 +5816,8 @@ mod real_llm {
use async_trait::async_trait;
use fabro_config::FabroSettings;
use fabro_graphviz::graph::Node;
use fabro_types::Settings;
use fabro_workflow::context::Context;
use fabro_workflow::error::FabroError;
use fabro_workflow::handler::agent::{AgentHandler, CodergenBackend, CodergenResult};
@ -6015,7 +6014,7 @@ mod real_llm {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -6122,7 +6121,7 @@ mod real_llm {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -6254,7 +6253,7 @@ mod real_llm {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -6354,7 +6353,7 @@ mod real_llm {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -6449,7 +6448,7 @@ async fn human_gate_freeform_only_routes_text() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -6578,7 +6577,7 @@ async fn human_gate_freeform_with_fixed_choice_match() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -6692,7 +6691,7 @@ async fn human_gate_freeform_fallback_on_unmatched_text() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -6819,7 +6818,7 @@ async fn human_gate_freeform_sets_allow_freeform_on_question() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -6926,7 +6925,7 @@ async fn human_gate_without_freeform_sets_allow_freeform_false() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -7210,7 +7209,7 @@ fn engine_with_hooks_and_events(
fn make_run_options(dir: &std::path::Path) -> RunOptions {
RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.to_path_buf(),
cancel_token: None,
run_id: test_run_id("hook-test-run"),
@ -7894,7 +7893,7 @@ event = "run_complete"
command = "echo done"
"#;
let cfg: FabroSettings = toml::from_str(toml).unwrap();
let cfg: Settings = toml::from_str(toml).unwrap();
assert_eq!(cfg.hooks.len(), 2);
assert_eq!(cfg.hooks[0].event, fabro_hooks::HookEvent::StageStart);
assert_eq!(cfg.hooks[0].matcher.as_deref(), Some("agent_loop"));
@ -8076,7 +8075,7 @@ max_tool_rounds = 10
timeout_ms = 120000
"#;
let cfg: FabroSettings = toml::from_str(toml).unwrap();
let cfg: Settings = toml::from_str(toml).unwrap();
assert_eq!(cfg.hooks.len(), 2);
// Prompt hook
@ -8215,7 +8214,7 @@ async fn run_fidelity_prompt_pipeline(fidelity: &str) -> String {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -8413,7 +8412,7 @@ async fn large_context_values_are_offloaded_to_artifact_store() {
let events = collect_events(&emitter);
let engine = WorkflowRunner::new(registry, Arc::new(emitter), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -8631,7 +8630,7 @@ async fn artifact_pointers_rewritten_for_remote_sandbox() {
remote_env.clone(),
);
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -8760,7 +8759,7 @@ async fn node_dir_uses_visit_count_on_revisit() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -9733,7 +9732,7 @@ async fn full_pipeline_with_cli_backend_node() {
let dir = tempfile::tempdir().unwrap();
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), env);
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -9863,7 +9862,7 @@ async fn stylesheet_backend_property_routes_to_cli() {
let dir = tempfile::tempdir().unwrap();
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), env);
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),
@ -10051,7 +10050,7 @@ async fn git_checkpoint_host_emits_events_and_diff_patch() {
let engine = WorkflowRunner::new(registry, Arc::new(emitter), env);
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: run_dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-docker"),
@ -10237,7 +10236,7 @@ async fn git_checkpoint_host_writes_shadow_branch() {
let meta_branch = MetadataStore::branch_name(&run_id.to_string());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: run_dir.path().to_path_buf(),
cancel_token: None,
run_id,
@ -10434,7 +10433,7 @@ async fn parallel_git_branching_host_e2e() {
let engine = WorkflowRunner::new(registry, Arc::new(emitter), env);
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: run_dir.path().to_path_buf(),
cancel_token: None,
run_id,
@ -10697,7 +10696,7 @@ async fn git_checkpoint_host_skips_empty_diff_patch() {
let engine = WorkflowRunner::new(registry, Arc::new(emitter), env);
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: run_dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("empty-diff"),
@ -11078,7 +11077,7 @@ async fn e2e_circuit_breaker_deterministic_self_loop() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("e2e-circuit-breaker"),
@ -11124,7 +11123,7 @@ async fn e2e_circuit_breaker_custom_limit() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("e2e-custom-limit"),
@ -11163,7 +11162,7 @@ async fn e2e_circuit_breaker_ignores_transient_failures() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("e2e-transient-no-breaker"),
@ -11209,7 +11208,7 @@ async fn e2e_circuit_breaker_different_reasons_separate_counters() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("e2e-varying-reasons"),
@ -11248,7 +11247,7 @@ async fn e2e_circuit_breaker_loop_restart() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("e2e-restart-breaker"),
@ -11309,7 +11308,7 @@ async fn e2e_failure_signature_persisted_in_context() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("e2e-sig-context"),
@ -11372,7 +11371,7 @@ async fn e2e_failure_signature_hint_overrides_reason_in_context() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("e2e-sig-hint"),
@ -11427,7 +11426,7 @@ async fn e2e_signature_maps_persist_in_checkpoint() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("e2e-sig-persist"),
@ -11553,7 +11552,7 @@ async fn e2e_circuit_breaker_emits_events_before_abort() {
let engine = WorkflowRunner::new(registry, Arc::new(emitter), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("e2e-events"),
@ -11617,7 +11616,7 @@ async fn e2e_circuit_breaker_does_not_fire_below_limit() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("e2e-below-limit"),
@ -11712,7 +11711,7 @@ async fn e2e_circuit_breaker_multi_stage_impl_verify_cycle() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("e2e-impl-verify-cycle"),
@ -11808,7 +11807,7 @@ async fn e2e_loop_restart_blocked_for_deterministic_failure() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("e2e-restart-blocked-det"),
@ -11847,7 +11846,7 @@ async fn e2e_loop_restart_blocked_for_structural_failure() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("e2e-restart-blocked-struct"),
@ -11886,7 +11885,7 @@ async fn e2e_loop_restart_blocked_for_budget_exhausted_failure() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("e2e-restart-blocked-budget"),
@ -11925,7 +11924,7 @@ async fn e2e_loop_restart_blocked_for_canceled_failure() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("e2e-restart-blocked-canceled"),
@ -11961,7 +11960,7 @@ async fn e2e_loop_restart_blocked_for_compilation_loop_failure() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("e2e-restart-blocked-comploop"),
@ -12001,7 +12000,7 @@ async fn e2e_loop_restart_allowed_for_transient_infra() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("e2e-restart-allowed-transient"),
@ -12107,7 +12106,7 @@ async fn e2e_stall_watchdog_triggers_from_dot_parsed_pipeline() {
let engine = WorkflowRunner::new(registry, Arc::new(emitter), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("stall-e2e"),
@ -12162,7 +12161,7 @@ async fn e2e_stall_watchdog_kept_alive_by_handler_events() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("stall-alive-e2e"),
@ -12207,7 +12206,7 @@ async fn e2e_stall_watchdog_disabled_with_zero_timeout() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("stall-disabled-e2e"),
@ -12271,7 +12270,7 @@ async fn e2e_stall_watchdog_with_explicit_timeout_override() {
let engine = WorkflowRunner::new(registry, Arc::new(EventEmitter::default()), local_env());
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("stall-override-e2e"),
@ -12401,11 +12400,11 @@ async fn asset_collection_local_sandbox_success() {
graph.edges.push(Edge::new("create_assets", "exit"));
let run_options = RunOptions {
settings: FabroSettings {
settings: Settings {
assets: Some(fabro_config::run::AssetsSettings {
include: vec!["test-results/**".to_string()],
}),
..FabroSettings::default()
..Settings::default()
},
run_dir: run_dir.path().to_path_buf(),
cancel_token: None,
@ -12528,11 +12527,11 @@ async fn asset_collection_local_sandbox_on_failure() {
graph.edges.push(Edge::new("create_assets", "exit"));
let run_options = RunOptions {
settings: FabroSettings {
settings: Settings {
assets: Some(fabro_config::run::AssetsSettings {
include: vec!["test-results/**".to_string()],
}),
..FabroSettings::default()
..Settings::default()
},
run_dir: run_dir.path().to_path_buf(),
cancel_token: None,
@ -12619,11 +12618,11 @@ async fn asset_collection_docker_sandbox() {
graph.edges.push(Edge::new("create_assets", "exit"));
let run_options = RunOptions {
settings: FabroSettings {
settings: Settings {
assets: Some(fabro_config::run::AssetsSettings {
include: vec!["test-results/**".to_string()],
}),
..FabroSettings::default()
..Settings::default()
},
run_dir: run_dir.path().to_path_buf(),
cancel_token: None,
@ -12687,7 +12686,7 @@ async fn wait_timer_e2e() {
local_env(),
);
let run_options = RunOptions {
settings: FabroSettings::default(),
settings: Settings::default(),
run_dir: dir.path().to_path_buf(),
cancel_token: None,
run_id: test_run_id("test-run"),