ralph_workflow/phases/commit_logging/
io.rs1#[derive(Debug)]
11pub struct CommitLogSession {
12 run_dir: PathBuf,
14 attempt_counter: usize,
16}
17
18impl CommitLogSession {
19 pub fn new(base_log_dir: &str, workspace: &dyn Workspace) -> std::io::Result<Self> {
27 let timestamp = Local::now().format("%Y%m%d_%H%M%S");
28 let run_dir = PathBuf::from(base_log_dir).join(format!("run_{timestamp}"));
29 workspace.create_dir_all(&run_dir)?;
30
31 Ok(Self {
32 run_dir,
33 attempt_counter: 0,
34 })
35 }
36
37 #[must_use]
39 pub fn noop() -> Self {
40 Self {
41 run_dir: PathBuf::from("/dev/null/ralph-noop-session"),
42 attempt_counter: 0,
43 }
44 }
45
46 #[must_use]
48 pub fn is_noop(&self) -> bool {
49 self.run_dir.starts_with("/dev/null")
50 }
51
52 #[must_use]
54 pub fn run_dir(&self) -> &Path {
55 &self.run_dir
56 }
57
58 pub fn next_attempt_number(&mut self) -> usize {
60 self.attempt_counter = self.attempt_counter.saturating_add(1);
61 self.attempt_counter
62 }
63
64 pub fn new_attempt(&mut self, agent: &str, strategy: &str) -> CommitAttemptLog {
66 let attempt_number = self.next_attempt_number();
67 CommitAttemptLog::new(attempt_number, agent, strategy)
68 }
69
70 pub fn write_summary(
78 &self,
79 total_attempts: usize,
80 final_outcome: &str,
81 workspace: &dyn Workspace,
82 ) -> std::io::Result<()> {
83 if self.is_noop() {
84 return Ok(());
85 }
86
87 let summary_path = self.run_dir.join("SUMMARY.txt");
88
89 let content = format!(
90 "COMMIT GENERATION SESSION SUMMARY\n\
91 =================================\n\
92 \n\
93 Run directory: {}\n\
94 Total attempts: {}\n\
95 Final outcome: {}\n\
96 \n\
97 Individual attempt logs are in this directory.\n",
98 self.run_dir.display(),
99 total_attempts,
100 final_outcome
101 );
102
103 workspace.write(&summary_path, &content)?;
104 Ok(())
105 }
106}