darpan 0.1.0

Linux developer service monitoring utility with auto-detection, real-time health checks, and interactive TUI for databases, APIs, Docker containers, and more
Documentation
use anyhow::Result;
use clap::{Parser, Subcommand};
use darpan::core::engine::CoreEngine;
use darpan::ui::cli::CliInterface;
use darpan::ui::tui::TuiInterface;
use std::path::PathBuf;
use tracing_subscriber;

#[derive(Parser)]
#[command(name = "darpan")]
#[command(author, version, about, long_about = None)]
#[command(about = "A Linux developer service monitoring utility")]
struct Cli {
    #[command(subcommand)]
    command: Option<Commands>,

    /// Project path (defaults to current directory)
    #[arg(short, long)]
    path: Option<PathBuf>,

    /// Enable verbose logging
    #[arg(short, long)]
    verbose: bool,
}

#[derive(Subcommand)]
enum Commands {
    /// Show status of all services
    Status {
        /// Show all projects
        #[arg(short, long)]
        all: bool,

        /// Output format (text, json)
        #[arg(short, long, default_value = "text")]
        format: String,
    },

    /// Show why a service is down
    Why {
        /// Service name
        service: String,
    },

    /// Initialize .darpan.yml in current directory
    Init,

    /// Add a service to .darpan.yml
    Add {
        /// Service type (postgres, redis, http, etc.)
        service_type: String,

        /// Port number
        #[arg(short, long)]
        port: Option<u16>,

        /// Service name
        #[arg(short, long)]
        name: Option<String>,
    },

    /// Launch interactive TUI dashboard
    Watch,
}

#[tokio::main]
async fn main() -> Result<()> {
    let cli = Cli::parse();

    // Initialize tracing only for non-TUI commands
    let is_watch = matches!(cli.command, Some(Commands::Watch));
    
    if !is_watch {
        if cli.verbose {
            tracing_subscriber::fmt()
                .with_max_level(tracing::Level::DEBUG)
                .init();
        } else {
            tracing_subscriber::fmt()
                .with_max_level(tracing::Level::INFO)
                .init();
        }
    }

    // Determine project path
    let project_path = cli.path.unwrap_or_else(|| std::env::current_dir().unwrap());

    // Create core engine
    let mut engine = CoreEngine::new(project_path)?;

    match cli.command {
        Some(Commands::Status { all, format }) => {
            let cli_ui = CliInterface::new();
            cli_ui.show_status(&mut engine, all, &format).await?;
        }
        Some(Commands::Why { service }) => {
            let cli_ui = CliInterface::new();
            cli_ui.show_why(&mut engine, &service).await?;
        }
        Some(Commands::Init) => {
            let cli_ui = CliInterface::new();
            cli_ui.init_config().await?;
        }
        Some(Commands::Add {
            service_type,
            port,
            name,
        }) => {
            let cli_ui = CliInterface::new();
            cli_ui.add_service(&service_type, port, name).await?;
        }
        Some(Commands::Watch) => {
            // Disable logging for TUI mode to prevent interference
            let mut tui = TuiInterface::new()?;
            tui.run(&mut engine).await?;
        }
        None => {
            // Default: show status
            let cli_ui = CliInterface::new();
            cli_ui.show_status(&mut engine, false, "text").await?;
        }
    }

    Ok(())
}