looprs 0.1.11

Concise coding assistant REPL
Documentation
use super::ToolArgs;
use super::error::ToolError;
use serde_json::Value;
use std::process::{Command, Stdio};

pub(super) fn tool_bash(args: &Value) -> Result<String, ToolError> {
    let args = ToolArgs::new(args);
    let cmd = args.get_str("cmd")?;

    let output = Command::new("bash")
        .arg("-c")
        .arg(cmd)
        .stdout(Stdio::piped())
        .stderr(Stdio::piped())
        .output()?;

    let mut result = String::from_utf8_lossy(&output.stdout).to_string();

    if !output.stderr.is_empty() {
        result.push_str("\n--- stderr ---\n");
        result.push_str(&String::from_utf8_lossy(&output.stderr));
    }

    if !output.status.success() {
        return Err(ToolError::CommandFailed(format!(
            "Exit code: {}",
            output.status.code().unwrap_or(-1)
        )));
    }

    Ok(if result.trim().is_empty() {
        "(empty)".to_string()
    } else {
        result
    })
}

#[cfg(test)]
mod tests {
    use super::*;
    use serde_json::json;

    #[test]
    fn bash_runs_command() {
        let args = json!({"cmd": "echo ok"});
        let out = tool_bash(&args).expect("bash tool should run");
        assert!(out.contains("ok"));
    }
}