mi6 0.2.8

A top-like CLI for monitoring agentic coding sessions
//! mi6 - A unified CLI for monitoring and managing agentic coding sessions.
//!
//! When run without a subcommand, launches an interactive TUI.
//! When run with a subcommand, executes the corresponding CLI command.

use anyhow::Result;
use clap::Parser;
use mi6_cli::{Cli, RunResult, TuiArgs};

fn main() -> Result<()> {
    // Check for help flag before parsing to show custom help
    let args: Vec<String> = std::env::args().collect();

    // Show custom help for top-level --help/-h
    if args.len() == 2 && (args[1] == "--help" || args[1] == "-h") {
        mi6_cli::print_help();
        return Ok(());
    }

    // Show custom help for subcommand --help/-h (e.g., mi6 enable --help)
    if args.len() == 3
        && (args[2] == "--help" || args[2] == "-h")
        && mi6_cli::print_subcommand_help(&args[1])
    {
        return Ok(());
    }

    // Show custom help for subsubcommand --help/-h (e.g., mi6 ingest transcript --help)
    if args.len() == 4
        && (args[3] == "--help" || args[3] == "-h")
        && mi6_cli::print_command_help(&[&args[1], &args[2]])
    {
        return Ok(());
    }

    let cli = Cli::parse();

    // Create storage factory that opens the database using configured path
    let storage_factory = || {
        let path = mi6_core::Config::db_path().map_err(|e| {
            mi6_core::StorageError::Io(std::io::Error::new(std::io::ErrorKind::NotFound, e))
        })?;
        mi6_storage_sqlite::SqliteStorage::open(&path)
    };

    // Run the CLI and handle the result
    match mi6_cli::run(cli, storage_factory)? {
        RunResult::Success => Ok(()),
        RunResult::ExitWithCode(code) => std::process::exit(code),
        RunResult::RunTui(args) => run_tui(args),
    }
}

/// Run the TUI with the provided arguments
fn run_tui(args: TuiArgs) -> Result<()> {
    // Parse column specification
    let columns = if let Some(cols) = args.columns {
        let spec = cols.join(" ");
        if let Some(visibility) = mi6_tui::parse_column_spec(&spec) {
            Some(visibility)
        } else {
            let valid_cols: Vec<_> = mi6_tui::SessionField::all().map(|f| f.def().name).collect();
            anyhow::bail!(
                "Invalid column name. Valid columns: {}",
                valid_cols.join(", ")
            );
        }
    } else {
        None
    };

    let config = mi6_tui::Config {
        interval_ms: args.interval,
        transcript_poll_ms: args.transcript_poll,
        show_all: args.all,
        theme: args.theme,
        columns,
        expert_mode: args.expert,
    };

    mi6_tui::run(config)
}