1use clap::Subcommand;
4use clap_complete::Shell;
5
6use crate::{JsonOutput, StandardCommand, StandardCommandMap, agent::AgentSubcommand};
7
8#[derive(Debug, Clone, PartialEq, Eq, Subcommand)]
10pub enum MetaCommand {
11 Version {
13 #[arg(long)]
15 json: bool,
16 },
17 License,
19 Completions {
21 shell: Shell,
23 },
24 Doctor {
26 #[arg(long)]
28 json: bool,
29 },
30 Agent {
32 #[command(subcommand)]
34 command: AgentSubcommand,
35 },
36}
37
38impl StandardCommandMap for MetaCommand {
39 fn to_standard_command(&self, _output: JsonOutput) -> StandardCommand {
40 match self {
41 Self::Version { json } => StandardCommand::Version {
42 output: JsonOutput::from_flag(*json),
43 },
44 Self::License => StandardCommand::License,
45 Self::Completions { shell } => StandardCommand::Completions { shell: *shell },
46 Self::Doctor { json } => StandardCommand::Doctor {
47 output: JsonOutput::from_flag(*json),
48 },
49 Self::Agent { command } => StandardCommand::Agent {
50 command: command.clone(),
51 },
52 }
53 }
54}
55
56#[cfg(test)]
57mod tests {
58 use clap::{Parser, Subcommand};
59
60 use super::*;
61 use crate::{JsonOutput, StandardCommand, map_standard_command};
62
63 #[derive(Debug, Parser)]
64 #[command(name = "tool")]
65 struct Cli {
66 #[command(subcommand)]
67 command: Command,
68 }
69
70 #[derive(Debug, Subcommand)]
71 enum Command {
72 Meta {
74 #[command(subcommand)]
75 command: MetaCommand,
76 },
77 }
78
79 fn parse_meta(argv: &[&str]) -> MetaCommand {
80 match Cli::parse_from(argv).command {
81 Command::Meta { command } => command,
82 }
83 }
84
85 #[test]
86 fn parses_meta_version_json() {
87 let command = parse_meta(&["tool", "meta", "version", "--json"]);
88 assert_eq!(command, MetaCommand::Version { json: true });
89 assert_eq!(
90 map_standard_command(&command, JsonOutput::Text),
91 StandardCommand::Version {
92 output: JsonOutput::Json
93 }
94 );
95 }
96
97 #[test]
98 fn parses_meta_license() {
99 let command = parse_meta(&["tool", "meta", "license"]);
100 assert_eq!(command, MetaCommand::License);
101 assert_eq!(
102 map_standard_command(&command, JsonOutput::Text),
103 StandardCommand::License
104 );
105 }
106
107 #[test]
108 fn parses_meta_completions() {
109 let command = parse_meta(&["tool", "meta", "completions", "bash"]);
110 assert_eq!(command, MetaCommand::Completions { shell: Shell::Bash });
111 assert_eq!(
112 map_standard_command(&command, JsonOutput::Text),
113 StandardCommand::Completions { shell: Shell::Bash }
114 );
115 }
116
117 #[test]
118 fn parses_meta_doctor_json() {
119 let command = parse_meta(&["tool", "meta", "doctor", "--json"]);
120 assert_eq!(command, MetaCommand::Doctor { json: true });
121 assert_eq!(
122 map_standard_command(&command, JsonOutput::Text),
123 StandardCommand::Doctor {
124 output: JsonOutput::Json
125 }
126 );
127 }
128
129 #[test]
130 fn rejects_meta_update() {
131 let result = Cli::try_parse_from(["tool", "meta", "update"]);
132 assert!(result.is_err(), "meta update must no longer parse");
133 }
134}