opencrates 3.0.1

Enterprise-grade AI-powered Rust development companion with comprehensive automation, monitoring, and deployment capabilities
//! OpenCrates - AI-powered Rust crate generator and registry
//!
//! OpenCrates is a comprehensive AI-powered tool for Rust developers that provides:
//! • Intelligent crate generation with best practices
//! • Advanced crate search and discovery
//! • Project analysis and health monitoring
//! • AI-powered code assistance and recommendations
//! • Interactive TUI dashboard for project management
//! • Comprehensive testing and optimization tools

use anyhow::{Context, Result};
use clap::Parser;
use console::style;
use dotenvy::dotenv;
use opencrates::cli::{Cli, EnhancedCli};
use opencrates::providers::OpenAIProvider;
use opencrates::utils::cache::CacheManager;
use opencrates::utils::logging;
use opencrates::utils::metrics::OpenCratesMetrics;
use opencrates::utils::openai_agents::{
    AgentManager, CrateAssistant, OpenAIClient, OpenAIClientConfig,
};
use std::process;
use std::sync::Arc;
use tracing::{info, warn, Level};

#[tokio::main]
async fn main() {
    // Initialize error handling and setup
    if let Err(e) = run().await {
        eprintln!("{} {}", style("ERROR:").red().bold(), e);

        // Print error chain if available
        let mut source = e.source();
        while let Some(err) = source {
            eprintln!("{} {}", style("  caused by:").dim(), err);
            source = err.source();
        }

        process::exit(1);
    }
}

async fn run() -> Result<()> {
    // Load environment variables from .env file if it exists
    dotenv().ok();
    
    // Parse CLI arguments first
    let cli = Cli::parse();

    // Setup tracing based on CLI flags
    let level = if cli.verbose {
        Level::DEBUG
    } else if cli.quiet {
        Level::ERROR
    } else {
        Level::INFO
    };
    logging::init(level);

    info!("Starting OpenCrates v{}", env!("CARGO_PKG_VERSION"));

    // Initialize AI agents and enhanced capabilities
    let _agents = initialize_agents().await?;
    info!("AI agents initialized successfully");

    // Create and run the enhanced CLI
    let mut enhanced_cli = EnhancedCli::new_with_config(cli.config.clone())
        .await
        .context("Failed to initialize OpenCrates CLI")?;

    enhanced_cli
        .run(cli)
        .await
        .context("CLI execution failed")?;

    info!("OpenCrates operation completed successfully");
    Ok(())
}

/// Initialize AI agents and services
async fn initialize_agents() -> Result<AgentManager> {
    // Check for OpenAI API key
    let api_key =
        std::env::var("OPENAI_API_KEY").context("OPENAI_API_KEY environment variable not set")?;

    if api_key.is_empty() {
        warn!("OpenAI API key is empty - some features may not work");
    }

    // Create metrics and cache
    let metrics = Arc::new(OpenCratesMetrics::new().await?);
    let cache = Arc::new(CacheManager::new());

    // Configure OpenAI client
    let config = OpenAIClientConfig {
        api_key,
        base_url: "https://api.openai.com/v1".to_string(),
        model: "gpt-4o".to_string(),
        max_tokens: Some(4096),
        temperature: Some(0.7),
        timeout: std::time::Duration::from_secs(60),
        max_retries: 3,
    };

    // Create OpenAI client and assistant
    let openai_client = Arc::new(OpenAIClient::new(config, metrics.clone(), cache.clone()));
    let _assistant = CrateAssistant::new(openai_client.clone()).await?;

    // Create OpenAI provider for agent manager
    let openai_provider = OpenAIProvider::new().await?;

    // Initialize agent manager with enhanced capabilities
    let agent_manager = AgentManager::new(openai_provider).await?;

    info!(
        "Agent manager initialized with {} agents",
        agent_manager.list_agents().await.len()
    );

    Ok(agent_manager)
}