1use clap::{Parser, ValueEnum};
2
3use crate::ValidationError;
4use crate::commands::Command;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
7pub enum OutputFormat {
8 Text,
9 Json,
10}
11
12#[derive(Debug, Clone, Parser)]
13#[command(
14 version,
15 about = "Rust implementation of the plan-issue orchestration workflow.",
16 after_help = "Usage paths:\n - plan-issue: live GitHub-backed orchestration\n - plan-issue-local: local-first rehearsal and dry-run flow\n\nUnsupported in plan-issue-local:\n - Any --issue path that requires live GitHub reads/writes (for example: status-plan/ready-plan with --issue, close-plan with --issue-only, cleanup-worktrees).\n\nUse instead:\n - plan-issue <command> ... (live GitHub path)\n - --body-file + --dry-run flows (local rehearsal path where supported)\n\nBoth binaries share the same typed command contract.",
17 disable_help_subcommand = true
18)]
19pub struct Cli {
20 #[arg(long, global = true, value_name = "owner/repo")]
22 pub repo: Option<String>,
23
24 #[arg(long, global = true)]
26 pub dry_run: bool,
27
28 #[arg(short = 'f', long, global = true)]
30 pub force: bool,
31
32 #[arg(long, global = true)]
34 pub json: bool,
35
36 #[arg(long, global = true, value_enum)]
38 pub format: Option<OutputFormat>,
39
40 #[command(subcommand)]
41 pub command: Command,
42}
43
44impl Cli {
45 pub fn resolve_output_format(&self) -> Result<OutputFormat, ValidationError> {
46 if self.json && matches!(self.format, Some(OutputFormat::Text)) {
47 return Err(ValidationError::new(
48 "invalid-output-mode",
49 "--json cannot be combined with --format text",
50 ));
51 }
52
53 if self.json || matches!(self.format, Some(OutputFormat::Json)) {
54 return Ok(OutputFormat::Json);
55 }
56
57 Ok(OutputFormat::Text)
58 }
59
60 pub fn validate(&self) -> Result<(), ValidationError> {
61 self.command.validate(self.dry_run)
62 }
63}