tala-cli 1.1.0

Agent-to-agent messaging for AI coding tools
use clap::Parser;
use models::{Envelope, Failure};
mod api;
mod cli;
mod client;
mod daemon;
mod integration;
mod models;
mod store;
#[tokio::main]
async fn main() {
    #[cfg(unix)]
    unsafe {
        libc::signal(libc::SIGPIPE, libc::SIG_DFL);
    }
    let human = std::env::args()
        .take_while(|a| a != "--")
        .any(|a| a == "--human");
    let cli = match cli::Cli::try_parse() {
        Ok(c) => c,
        Err(e) => {
            if matches!(
                e.kind(),
                clap::error::ErrorKind::DisplayHelp | clap::error::ErrorKind::DisplayVersion
            ) {
                let _ = e.print();
                return;
            }
            if human {
                let _ = e.print();
            } else {
                eprintln!(
                    "{}",
                    serde_json::to_string(&Envelope::failure(Failure::new(
                        "USAGE_ERROR",
                        e.to_string(),
                        "Run tala <command> --help."
                    )))
                    .expect("error serializes")
                );
            }
            std::process::exit(2);
        }
    };
    let human = cli.human;
    let is_daemon = matches!(cli.command, Some(cli::Commands::Daemon));
    match cli::run(cli).await {
        Ok(result) => {
            if !is_daemon {
                let attention = client::take_attention();
                if human {
                    cli::render(&result.data, attention.as_ref());
                } else {
                    println!(
                        "{}",
                        serde_json::to_string(&Envelope {
                            attention,
                            ..Envelope::success(result.data)
                        })
                        .expect("output serializes")
                    );
                }
            }
            if result.code != 0 {
                std::process::exit(result.code);
            }
        }
        Err(error) => {
            let code = if error.code == "USAGE_ERROR" {
                2
            } else if error.stored.is_some() {
                4
            } else {
                1
            };
            if human {
                eprintln!("Error: {}\n{}", error.message, error.hint);
                if let Some(next) = &error.next {
                    eprintln!("Next: {next}");
                }
            } else {
                eprintln!(
                    "{}",
                    serde_json::to_string(&Envelope::failure(error)).expect("error serializes")
                );
            }
            std::process::exit(code);
        }
    }
}