1use crate::logger::Colors;
7use crate::logger::Logger;
8
9pub struct PipelineSummary {
13 pub total_time: String,
15 pub dev_runs_completed: usize,
17 pub dev_runs_total: usize,
19 pub review_runs: usize,
21 pub changes_detected: usize,
23 pub isolation_mode: bool,
25 pub verbose: bool,
27 pub review_summary: Option<ReviewSummary>,
29}
30
31pub struct ReviewSummary {
33 pub summary: String,
35 pub unresolved_count: usize,
37 pub blocking_count: usize,
39 pub detailed_breakdown: Option<String>,
41 pub samples: Vec<String>,
43}
44
45pub fn print_welcome_banner(colors: Colors, developer_agent: &str, reviewer_agent: &str) {
55 println!();
56 println!(
57 "{}{}╭────────────────────────────────────────────────────────────╮{}",
58 colors.bold(),
59 colors.cyan(),
60 colors.reset()
61 );
62 println!(
63 "{}{}│{} {}{}🤖 Ralph{} {}─ PROMPT-driven agent orchestrator{} {}{}│{}",
64 colors.bold(),
65 colors.cyan(),
66 colors.reset(),
67 colors.bold(),
68 colors.white(),
69 colors.reset(),
70 colors.dim(),
71 colors.reset(),
72 colors.bold(),
73 colors.cyan(),
74 colors.reset()
75 );
76 println!(
77 "{}{}│{} {}{} × {} pipeline for autonomous development{} {}{}│{}",
78 colors.bold(),
79 colors.cyan(),
80 colors.reset(),
81 colors.dim(),
82 developer_agent,
83 reviewer_agent,
84 colors.reset(),
85 colors.bold(),
86 colors.cyan(),
87 colors.reset()
88 );
89 println!(
90 "{}{}╰────────────────────────────────────────────────────────────╯{}",
91 colors.bold(),
92 colors.cyan(),
93 colors.reset()
94 );
95 println!();
96}
97
98pub fn print_final_summary(colors: Colors, summary: &PipelineSummary, logger: &Logger) {
109 logger.header("Pipeline Complete", crate::logger::Colors::green);
110
111 println!();
112 println!(
113 "{}{}📊 Summary{}",
114 colors.bold(),
115 colors.white(),
116 colors.reset()
117 );
118 println!(
119 "{}──────────────────────────────────{}",
120 colors.dim(),
121 colors.reset()
122 );
123 println!(
124 " {}⏱{} Total time: {}{}{}",
125 colors.cyan(),
126 colors.reset(),
127 colors.bold(),
128 summary.total_time,
129 colors.reset()
130 );
131 println!(
132 " {}🔄{} Dev runs: {}{}{}/{}",
133 colors.blue(),
134 colors.reset(),
135 colors.bold(),
136 summary.dev_runs_completed,
137 colors.reset(),
138 summary.dev_runs_total
139 );
140 println!(
141 " {}🔍{} Review runs: {}{}{}",
142 colors.magenta(),
143 colors.reset(),
144 colors.bold(),
145 summary.review_runs,
146 colors.reset()
147 );
148 println!(
149 " {}📝{} Changes detected: {}{}{}",
150 colors.green(),
151 colors.reset(),
152 colors.bold(),
153 summary.changes_detected,
154 colors.reset()
155 );
156
157 if let Some(ref review) = summary.review_summary {
159 print_review_summary(colors, summary.verbose, review);
160 }
161 println!();
162
163 print_output_files(colors, summary.isolation_mode);
164
165 logger.success("Ralph pipeline completed successfully!");
166}
167
168fn print_review_summary(colors: Colors, verbose: bool, review: &ReviewSummary) {
170 if review.unresolved_count == 0 && review.blocking_count == 0 {
172 println!(
173 " {}✓{} Review result: {}{}{}",
174 colors.green(),
175 colors.reset(),
176 colors.bold(),
177 review.summary,
178 colors.reset()
179 );
180 return;
181 }
182
183 println!(
185 " {}🔎{} Review summary: {}{}{}",
186 colors.yellow(),
187 colors.reset(),
188 colors.bold(),
189 review.summary,
190 colors.reset()
191 );
192
193 if review.unresolved_count > 0 {
195 println!(
196 " {}⚠{} Unresolved: {}{}{} issues remaining",
197 colors.red(),
198 colors.reset(),
199 colors.bold(),
200 review.unresolved_count,
201 colors.reset()
202 );
203 }
204
205 if verbose {
207 if let Some(ref breakdown) = review.detailed_breakdown {
208 println!(" {}📊{} Breakdown:", colors.dim(), colors.reset());
209 for line in breakdown.lines() {
210 println!(" {}{}{}", colors.dim(), line.trim(), colors.reset());
211 }
212 }
213 if !review.samples.is_empty() {
215 println!(
216 " {}🧾{} Unresolved samples:",
217 colors.dim(),
218 colors.reset()
219 );
220 for s in &review.samples {
221 println!(" {}- {}{}", colors.dim(), s, colors.reset());
222 }
223 }
224 }
225
226 if review.blocking_count > 0 {
228 println!(
229 " {}🚨{} BLOCKING: {}{}{} critical/high issues unresolved",
230 colors.red(),
231 colors.reset(),
232 colors.bold(),
233 review.blocking_count,
234 colors.reset()
235 );
236 }
237}
238
239fn print_output_files(colors: Colors, isolation_mode: bool) {
241 println!(
242 "{}{}📁 Output Files{}",
243 colors.bold(),
244 colors.white(),
245 colors.reset()
246 );
247 println!(
248 "{}──────────────────────────────────{}",
249 colors.dim(),
250 colors.reset()
251 );
252 println!(
253 " → {}PROMPT.md{} Goal definition",
254 colors.cyan(),
255 colors.reset()
256 );
257 println!(
258 " → {}.agent/STATUS.md{} Current status",
259 colors.cyan(),
260 colors.reset()
261 );
262 if !isolation_mode {
264 println!(
265 " → {}.agent/ISSUES.md{} Review findings",
266 colors.cyan(),
267 colors.reset()
268 );
269 println!(
270 " → {}.agent/NOTES.md{} Progress notes",
271 colors.cyan(),
272 colors.reset()
273 );
274 }
275 println!(
276 " → {}.agent/logs/{} Detailed logs",
277 colors.cyan(),
278 colors.reset()
279 );
280 println!();
281}