opencrates 3.0.1

Enterprise-grade AI-powered Rust development companion with comprehensive automation, monitoring, and deployment capabilities
//! Aider CLI integration for AI pair programming

use anyhow::{Context, Result};
use std::path::Path;
use std::process::Command;
use tracing::{debug, error, info};

// TODO: document this
// TODO: document this
// TODO: document this
pub struct AiderIntegration;

impl AiderIntegration {
    /// Check if aider-chat is available in PATH
    // TODO: document this
    // TODO: document this
    // TODO: document this
    // TODO: document this
    #[must_use]
    pub fn is_available() -> bool {
        Command::new("aider")
            .arg("--version")
            .output()
            .map(|output| output.status.success())
            .unwrap_or(false)
    }

    /// Execute aider with given instructions in the project path
    // TODO: document this
    // TODO: document this
    // TODO: document this
    // TODO: document this
    pub async fn execute(project_path: &Path, instructions: &str) -> Result<String> {
        if !Self::is_available() {
            return Err(anyhow::anyhow!(
                "Aider is not available. Install with: pip install aider-chat"
            ));
        }

        info!("Running aider in directory: {:?}", project_path);
        debug!("Aider instructions: {}", instructions);

        let output = tokio::task::spawn_blocking({
            let project_path = project_path.to_owned();
            let instructions = instructions.to_owned();
            move || {
                Command::new("aider")
                    .current_dir(&project_path)
                    .arg("--message")
                    .arg(&instructions)
                    .arg("--yes") // Auto-accept changes
                    .arg("--no-pretty") // Plain output
                    .output()
            }
        })
        .await?
        .context("Failed to execute aider command")?;

        if !output.status.success() {
            let stderr = String::from_utf8_lossy(&output.stderr);
            error!("Aider execution failed: {}", stderr);
            return Err(anyhow::anyhow!("Aider failed: {}", stderr));
        }

        let stdout = String::from_utf8_lossy(&output.stdout);
        info!("Aider completed successfully");
        Ok(stdout.into_owned())
    }
}