Skip to main content

ralph_workflow/cli/init/config_generation/
local.rs

1//! Local configuration file creation.
2//!
3//! Handles `--init-local-config` flag to create a local config file at
4//! `.agent/ralph-workflow.toml` in the current directory.
5
6use crate::config::{ConfigEnvironment, RealConfigEnvironment};
7use crate::logger::Colors;
8
9/// Local config template with minimal override examples.
10const LOCAL_CONFIG_TEMPLATE: &str = r#"# Local Ralph configuration (.agent/ralph-workflow.toml)
11# Overrides ~/.config/ralph-workflow.toml for this project.
12# Only include settings you want to override.
13# Run `ralph --check-config` to validate and see effective settings.
14
15[general]
16# Project-specific iteration limits
17# developer_iters = 5
18# reviewer_reviews = 2
19
20# Project-specific context levels
21# developer_context = 1
22# reviewer_context = 0
23
24# [agent_chain]
25# Project-specific agent chains
26# developer = ["claude"]
27# reviewer = ["claude"]
28"#;
29
30/// Handle the `--init-local-config` flag with a custom path resolver.
31///
32/// Creates a local config file at `.agent/ralph-workflow.toml` in the current directory.
33///
34/// # Arguments
35///
36/// * `colors` - Terminal color configuration for output
37/// * `env` - Path resolver for determining config file location
38/// * `force` - Whether to overwrite existing config file
39///
40/// # Returns
41///
42/// Returns `Ok(true)` if the flag was handled (program should exit after),
43/// or an error if config creation failed.
44pub fn handle_init_local_config_with<R: ConfigEnvironment>(
45    colors: Colors,
46    env: &R,
47    force: bool,
48) -> anyhow::Result<bool> {
49    let local_path = env
50        .local_config_path()
51        .ok_or_else(|| anyhow::anyhow!("Cannot determine local config path"))?;
52
53    // Check if config already exists
54    if env.file_exists(&local_path) && !force {
55        println!(
56            "{}Local config already exists:{} {}",
57            colors.yellow(),
58            colors.reset(),
59            local_path.display()
60        );
61        println!("Use --force-overwrite to replace it, or edit the existing file.");
62        println!();
63        println!("Run `ralph --check-config` to see effective configuration.");
64        return Ok(true);
65    }
66
67    // Create config using the environment's file operations
68    env.write_file(&local_path, LOCAL_CONFIG_TEMPLATE)
69        .map_err(|e| {
70            anyhow::anyhow!(
71                "Failed to create local config file {}: {}",
72                local_path.display(),
73                e
74            )
75        })?;
76
77    // Try to show absolute path, fall back to the path as-is if canonicalization fails
78    let display_path = local_path
79        .canonicalize()
80        .unwrap_or_else(|_| local_path.clone());
81
82    println!(
83        "{}Created{} {}",
84        colors.green(),
85        colors.reset(),
86        display_path.display()
87    );
88    println!();
89    println!(
90        "This local config will override your global settings (~/.config/ralph-workflow.toml)."
91    );
92    println!("Edit the file to customize Ralph for this project.");
93    println!();
94    println!("Tip: Run `ralph --check-config` to validate your configuration.");
95
96    Ok(true)
97}
98
99/// Handle the `--init-local-config` flag using the default path resolver.
100///
101/// Convenience wrapper that uses [`RealConfigEnvironment`] internally.
102pub fn handle_init_local_config(colors: Colors, force: bool) -> anyhow::Result<bool> {
103    handle_init_local_config_with(colors, &RealConfigEnvironment, force)
104}