Skip to main content

autom8/claude/
improve.rs

1//! Interactive Claude session for the improve command.
2//!
3//! This module provides functions for spawning an interactive Claude session
4//! with context from previous autom8 runs. Unlike other Claude modules that
5//! capture output, this module hands off control to an interactive session.
6
7use std::process::{Command, Stdio};
8
9use crate::error::{Autom8Error, Result};
10
11/// Result of an interactive improve session.
12#[derive(Debug)]
13pub struct ImproveSessionResult {
14    /// Whether the session completed successfully
15    pub success: bool,
16    /// Exit code if available
17    pub exit_code: Option<i32>,
18}
19
20/// Spawn an interactive Claude session with the given prompt.
21///
22/// This function hands off control to Claude for an interactive session.
23/// The prompt is passed as the first argument, and all I/O is inherited
24/// from the parent process.
25///
26/// # Arguments
27/// * `prompt` - The context prompt to inject into the Claude session
28///
29/// # Returns
30/// * `Ok(ImproveSessionResult)` - Session completed (check `success` for exit status)
31/// * `Err` - Failed to spawn Claude (e.g., not installed)
32pub fn run_improve_session(prompt: &str) -> Result<ImproveSessionResult> {
33    let status = Command::new("claude")
34        .arg(prompt)
35        .stdin(Stdio::inherit())
36        .stdout(Stdio::inherit())
37        .stderr(Stdio::inherit())
38        .status()
39        .map_err(|e| {
40            if e.kind() == std::io::ErrorKind::NotFound {
41                Autom8Error::ClaudeNotFound
42            } else {
43                Autom8Error::ClaudeSpawnError(e.to_string())
44            }
45        })?;
46
47    Ok(ImproveSessionResult {
48        success: status.success(),
49        exit_code: status.code(),
50    })
51}
52
53#[cfg(test)]
54mod tests {
55    use super::*;
56
57    #[test]
58    fn test_improve_session_result_debug() {
59        let result = ImproveSessionResult {
60            success: true,
61            exit_code: Some(0),
62        };
63        let debug = format!("{:?}", result);
64        assert!(debug.contains("ImproveSessionResult"));
65        assert!(debug.contains("success: true"));
66    }
67
68    #[test]
69    fn test_improve_session_result_success_false() {
70        let result = ImproveSessionResult {
71            success: false,
72            exit_code: Some(1),
73        };
74        assert!(!result.success);
75        assert_eq!(result.exit_code, Some(1));
76    }
77
78    #[test]
79    fn test_improve_session_result_no_exit_code() {
80        // When killed by signal, exit_code may be None
81        let result = ImproveSessionResult {
82            success: false,
83            exit_code: None,
84        };
85        assert!(!result.success);
86        assert!(result.exit_code.is_none());
87    }
88}