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()))
}
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(())
}