use super::{AppError, AppResult, CliArgs};
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(args: &CliArgs) -> AppResult<()> {
if args.print {
return Err(usage_error(
"subcommands cannot be combined with --print; use one mode per invocation",
));
}
if args.tui {
return Err(usage_error(
"subcommands cannot be combined with --tui; use one mode per invocation",
));
}
if args.dump_prompt {
return Err(usage_error(
"subcommands cannot be combined with --dump-prompt; use one mode per invocation",
));
}
if args.continue_session {
return Err(usage_error(
"subcommands cannot be combined with --continue; diagnostics do not attach to sessions",
));
}
if args.resume.is_some() {
return Err(usage_error(
"subcommands cannot be combined with --resume; diagnostics do not attach to sessions",
));
}
if args.no_session {
return Err(usage_error(
"subcommands cannot be combined with --no-session; diagnostics never create sessions",
));
}
if args.provider.is_some() {
return Err(usage_error(
"subcommands cannot be combined with --provider; diagnostics do not use provider auth",
));
}
if args.model.is_some() {
return Err(usage_error(
"subcommands cannot be combined with --model; diagnostics do not use provider models",
));
}
if args.api_key.is_some() {
return Err(usage_error(
"subcommands cannot be combined with --api-key; diagnostics do not authenticate",
));
}
if !args.prompt.is_empty() {
return Err(usage_error(
"subcommands do not accept trailing PROMPT arguments",
));
}
Ok(())
}
pub(super) fn validate_session_launch(args: &CliArgs) -> AppResult<()> {
if args.no_session && (args.continue_session || args.resume.is_some()) {
return Err(usage_error(
"--no-session cannot be combined with --continue or --resume",
));
}
if args.continue_session && args.resume.is_some() {
return Err(usage_error(
"--continue cannot be combined with --resume; choose one session target",
));
}
Ok(())
}
pub(super) fn validate_dump_prompt_launch(args: &CliArgs) -> AppResult<()> {
if !args.dump_prompt {
return Ok(());
}
if args.provider.is_none() {
return Err(usage_error(
"--dump-prompt requires --provider with one of: anthropic, openai, openai-compatible, openai-codex, claude-code",
));
}
if args.print {
return Err(usage_error(
"--dump-prompt cannot be combined with --print; use one mode per invocation",
));
}
if args.tui {
return Err(usage_error(
"--dump-prompt cannot be combined with --tui; use one mode per invocation",
));
}
if args.continue_session {
return Err(usage_error(
"--dump-prompt cannot be combined with --continue; dump mode never attaches to sessions",
));
}
if args.resume.is_some() {
return Err(usage_error(
"--dump-prompt cannot be combined with --resume; dump mode never attaches to sessions",
));
}
if args.no_session {
return Err(usage_error(
"--dump-prompt cannot be combined with --no-session; dump mode never creates sessions",
));
}
if args.model.is_some() {
return Err(usage_error(
"--dump-prompt cannot be combined with --model; provider schema target is selected by --provider",
));
}
if args.api_key.is_some() {
return Err(usage_error(
"--dump-prompt cannot be combined with --api-key; dump mode does not authenticate",
));
}
if !args.prompt.is_empty() {
return Err(usage_error(
"--dump-prompt does not accept trailing PROMPT arguments",
));
}
Ok(())
}
pub(super) fn validate_tui_launch(args: &CliArgs) -> AppResult<()> {
if !args.tui {
return Ok(());
}
if args.print {
return Err(usage_error(
"--tui cannot be combined with --print; use one mode per invocation",
));
}
if !args.prompt.is_empty() {
return Err(usage_error(
"--tui does not support trailing PROMPT arguments in the Phase 4 MVP; launch --tui and type the prompt in Mission Control",
));
}
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(
"--tui requires both stdin and stdout to be TTYs; use classic mode or --print for pipes/non-interactive use",
));
}
Ok(())
}