magi-code 0.102.0

Repository-aware CLI coding agent for terminal work
Documentation
use super::{AppError, AppResult, CliArgs, CliCommand, SessionsCommand};
use std::io::{self, IsTerminal};

fn usage_error(message: impl Into<String>) -> AppError {
    AppError::usage(anyhow::anyhow!(message.into()))
}

/// Validates subcommand values clap cannot express; flag conflicts are declared on `CliArgs`.
pub(super) fn validate_subcommand_launch(command: &CliCommand) -> AppResult<()> {
    if let CliCommand::Sessions {
        command:
            SessionsCommand::MeasureCompression {
                model,
                max_files,
                max_bytes,
            },
    } = command
    {
        if !crate::tool_output_measurement::is_valid_measurement_model(model) {
            return Err(usage_error(
                "measure-compression --model must name a supported openai-codex text model",
            ));
        }
        if !crate::tool_output_measurement::MeasurementLimits::is_valid_file_count(*max_files) {
            return Err(usage_error(
                "measure-compression --max-files must be between 1 and 10000",
            ));
        }
        if !crate::tool_output_measurement::MeasurementLimits::is_valid_byte_limit(*max_bytes) {
            return Err(usage_error(
                "measure-compression --max-bytes must be between 1048576 and 1073741824",
            ));
        }
    }

    Ok(())
}

pub(super) fn validate_initial_prompt_launch(args: &CliArgs) -> AppResult<()> {
    if args
        .initial_prompt
        .as_deref()
        .is_some_and(|prompt| prompt.trim().is_empty())
    {
        return Err(usage_error("--prompt requires non-whitespace text"));
    }
    Ok(())
}

pub(super) fn validate_tui_launch() -> AppResult<()> {
    let stdin_is_tty = io::stdin().is_terminal();
    let stdout_is_tty = io::stdout().is_terminal();
    if !stdin_is_tty || !stdout_is_tty {
        return Err(usage_error(
            "Mission Control requires both stdin and stdout to be TTYs",
        ));
    }
    Ok(())
}