ralph_workflow/cli/presets.rs
1//! Preset configurations for common agent combinations.
2//!
3//! Presets allow users to quickly configure Ralph for common use cases
4//! without specifying individual agent options.
5
6use crate::config::{Config, ReviewDepth};
7use crate::logger::Colors;
8use clap::ValueEnum;
9
10trait StdIoWriteCompat {
11 fn write_fmt(&mut self, args: std::fmt::Arguments<'_>) -> std::io::Result<()>;
12}
13
14impl<T: std::io::Write> StdIoWriteCompat for T {
15 fn write_fmt(&mut self, args: std::fmt::Arguments<'_>) -> std::io::Result<()> {
16 std::io::Write::write_fmt(self, args)
17 }
18}
19
20/// Preset configurations for common agent combinations.
21#[derive(Clone, Debug, ValueEnum)]
22pub enum Preset {
23 /// Use `agent_chain` defaults (no explicit agent override)
24 Default,
25 /// Use opencode for both developer and reviewer
26 Opencode,
27}
28
29/// Apply CLI arguments to the configuration (functional pattern - returns new Config).
30///
31/// This function uses the reducer architecture to process CLI arguments:
32/// 1. Parse Args into a sequence of `CliEvents`
33/// 2. Run events through the reducer to build `CliState`
34/// 3. Apply `CliState` to Config returning a new Config
35///
36/// This approach ensures:
37/// - All CLI arguments are handled (fixes missing -L, -S, -T flags)
38/// - Event processing is testable and maintainable
39/// - Consistent with the existing pipeline reducer pattern
40#[must_use]
41pub fn apply_args_to_config(args: &super::Args, config: Config, colors: Colors) -> Config {
42 use crate::cli::reducer::{apply_cli_state_to_config, args_to_events, reduce, CliState};
43
44 // Validate review depth before processing (for user warning)
45 if let Some(ref depth) = args.review_depth {
46 if ReviewDepth::from_str(depth).is_none() {
47 let _ = writeln!(
48 std::io::stderr(),
49 "{}{}Warning:{} Unknown review depth '{}'. Using default (standard).",
50 colors.bold(),
51 colors.yellow(),
52 colors.reset(),
53 depth
54 );
55 let _ = writeln!(
56 std::io::stderr(),
57 "Valid options: standard, comprehensive, security, incremental"
58 );
59 }
60 }
61
62 // Parse args into events
63 let events = args_to_events(args);
64
65 // Run events through reducer to build state (functional pattern with fold)
66 let state = events.into_iter().fold(CliState::initial(), reduce);
67
68 // Apply final state to config (functional pattern)
69 apply_cli_state_to_config(&state, &config)
70}