ai-agent 0.13.4

Idiomatic agent sdk inspired by the claude code source leak
Documentation
#![allow(dead_code)]

#[derive(Debug, Clone)]
pub struct ParsedSlashCommand {
    pub command_name: String,
    pub args: String,
    pub is_mcp: bool,
}

pub fn parse_slash_command(input: &str) -> Option<ParsedSlashCommand> {
    let trimmed = input.trim();

    if !trimmed.starts_with('/') {
        return None;
    }

    let without_slash = &trimmed[1..];
    let words: Vec<&str> = without_slash.split(' ').collect();

    if words.is_empty() || words[0].is_empty() {
        return None;
    }

    let mut command_name = words[0].to_string();
    let mut is_mcp = false;
    let mut args_start_index = 1;

    // Check for MCP commands (second word is '(MCP)')
    if words.len() > 1 && words[1] == "(MCP)" {
        command_name = format!("{} (MCP)", command_name);
        is_mcp = true;
        args_start_index = 2;
    }

    let args = if args_start_index < words.len() {
        words[args_start_index..].join(" ")
    } else {
        String::new()
    };

    Some(ParsedSlashCommand {
        command_name,
        args,
        is_mcp,
    })
}

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

    #[test]
    fn test_parse_slash_command() {
        let result = parse_slash_command("/search foo bar");
        assert!(result.is_some());
        let r = result.unwrap();
        assert_eq!(r.command_name, "search");
        assert_eq!(r.args, "foo bar");
        assert!(!r.is_mcp);
    }

    #[test]
    fn test_parse_slash_command_mcp() {
        let result = parse_slash_command("/mcp:tool (MCP) arg1 arg2");
        assert!(result.is_some());
        let r = result.unwrap();
        assert_eq!(r.command_name, "mcp:tool (MCP)");
        assert_eq!(r.args, "arg1 arg2");
        assert!(r.is_mcp);
    }

    #[test]
    fn test_parse_slash_command_invalid() {
        assert!(parse_slash_command("search").is_none());
        assert!(parse_slash_command("").is_none());
    }
}