ralph_workflow/cli/
init.rs1use crate::agents::{AgentsConfigFile, ConfigInitResult};
8use crate::config::{unified_config_path, UnifiedConfig, UnifiedConfigInitResult};
9use crate::logger::Colors;
10use crate::templates::{get_template, list_templates};
11use std::fs;
12use std::path::Path;
13
14pub fn handle_init_global(colors: Colors) -> anyhow::Result<bool> {
28 let global_path = unified_config_path()
29 .ok_or_else(|| anyhow::anyhow!("Cannot determine config directory (no home directory)"))?;
30
31 match UnifiedConfig::ensure_config_exists() {
32 Ok(UnifiedConfigInitResult::Created) => {
33 println!(
34 "{}Created unified config: {}{}{}\n",
35 colors.green(),
36 colors.bold(),
37 global_path.display(),
38 colors.reset()
39 );
40 println!("This is the primary configuration file for Ralph.");
41 println!();
42 println!("Features:");
43 println!(" - General settings (verbosity, iterations, etc.)");
44 println!(" - CCS aliases for Claude Code Switch integration");
45 println!(" - Custom agent definitions");
46 println!(" - Agent chain configuration with fallbacks");
47 println!();
48 println!("Environment variables (RALPH_*) override these settings.");
49 Ok(true)
50 }
51 Ok(UnifiedConfigInitResult::AlreadyExists) => {
52 println!(
53 "{}Unified config already exists:{} {}",
54 colors.yellow(),
55 colors.reset(),
56 global_path.display()
57 );
58 println!("Edit the file to customize, or delete it to regenerate from defaults.");
59 Ok(true)
60 }
61 Err(e) => Err(anyhow::anyhow!(
62 "Failed to create config file {}: {}",
63 global_path.display(),
64 e
65 )),
66 }
67}
68
69pub fn handle_init_legacy(colors: Colors, agents_config_path: &Path) -> anyhow::Result<bool> {
73 match AgentsConfigFile::ensure_config_exists(agents_config_path) {
74 Ok(ConfigInitResult::Created) => {
75 println!(
76 "{}Created {}{}{}\n",
77 colors.green(),
78 colors.bold(),
79 agents_config_path.display(),
80 colors.reset()
81 );
82 println!("Edit the file to customize agent configurations, then run ralph again.");
83 println!("Or run ralph now to use the default settings.");
84 Ok(true)
85 }
86 Ok(ConfigInitResult::AlreadyExists) => {
87 println!(
88 "{}Config file already exists:{} {}",
89 colors.yellow(),
90 colors.reset(),
91 agents_config_path.display()
92 );
93 println!("Edit the file to customize, or delete it to regenerate from defaults.");
94 Ok(true)
95 }
96 Err(e) => Err(anyhow::anyhow!(
97 "Failed to create config file {}: {}",
98 agents_config_path.display(),
99 e
100 )),
101 }
102}
103
104pub fn handle_init_prompt(template_name: &str, colors: Colors) -> anyhow::Result<bool> {
120 let prompt_path = Path::new("PROMPT.md");
121
122 if prompt_path.exists() {
124 println!(
125 "{}PROMPT.md already exists:{} {}",
126 colors.yellow(),
127 colors.reset(),
128 prompt_path.display()
129 );
130 println!("Delete or backup the existing file to create a new one from a template.");
131 return Ok(true);
132 }
133
134 let Some(template) = get_template(template_name) else {
136 println!(
137 "{}Unknown template: '{}'{}",
138 colors.red(),
139 template_name,
140 colors.reset()
141 );
142 println!();
143 println!("Available templates:");
144 for (name, description) in list_templates() {
145 println!(
146 " {}{}{} {}",
147 colors.cyan(),
148 name,
149 colors.reset(),
150 description
151 );
152 }
153 println!();
154 println!("Usage: ralph --init-prompt <template>");
155 println!(" ralph --list-templates");
156 return Ok(true);
157 };
158
159 let content = template.content();
161 fs::write(prompt_path, content)?;
162
163 println!(
164 "{}Created PROMPT.md from template: {}{}{}",
165 colors.green(),
166 colors.bold(),
167 template_name,
168 colors.reset()
169 );
170 println!();
171 println!(
172 "Template: {}{}{} {}",
173 colors.cyan(),
174 template.name(),
175 colors.reset(),
176 template.description()
177 );
178 println!();
179 println!("Next steps:");
180 println!(" 1. Edit PROMPT.md with your task details");
181 println!(" 2. Run: ralph \"your commit message\"");
182 println!();
183 println!("Tip: Use --list-templates to see all available templates.");
184
185 Ok(true)
186}
187
188pub fn handle_list_templates(colors: Colors) -> bool {
200 println!("Available PROMPT.md templates:");
201 println!();
202
203 let templates = list_templates();
204 let _max_name_len = templates
205 .iter()
206 .map(|(name, _)| name.len())
207 .max()
208 .unwrap_or(0);
209
210 for (name, description) in templates {
211 println!(
212 " {}{}{} {}{}{}",
213 colors.cyan(),
214 name,
215 colors.reset(),
216 colors.dim(),
217 description,
218 colors.reset()
219 );
220 }
221
222 println!();
223 println!("Usage: ralph --init-prompt <template>");
224 println!();
225 println!("Example:");
226 println!(" ralph --init-prompt feature-spec # Create comprehensive spec template");
227 println!(" ralph --init-prompt bug-fix # Create bug fix template");
228 println!(" ralph --init-prompt quick # Create quick change template");
229
230 true
231}