1use std::path::PathBuf;
7
8use anyhow::Result;
9use clap::{Args, Subcommand, ValueEnum};
10pub use claudex::filter::ResolvedFilter;
11use claudex::filter::{ProviderKind, parse_when};
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
15pub enum ProviderArg {
16 Claude,
17 Codex,
18 Copilot,
19 #[value(name = "copilot-vscode")]
20 CopilotVscode,
21 #[value(name = "openclaw")]
22 OpenClaw,
23 Pi,
24}
25
26impl From<ProviderArg> for ProviderKind {
27 fn from(provider: ProviderArg) -> Self {
28 match provider {
29 ProviderArg::Claude => ProviderKind::Claude,
30 ProviderArg::Codex => ProviderKind::Codex,
31 ProviderArg::Copilot => ProviderKind::Copilot,
32 ProviderArg::CopilotVscode => ProviderKind::CopilotVscode,
33 ProviderArg::OpenClaw => ProviderKind::OpenClaw,
34 ProviderArg::Pi => ProviderKind::Pi,
35 }
36 }
37}
38
39#[derive(Args, Clone, Debug, Default)]
42pub struct FilterArgs {
43 #[arg(long, value_enum, value_delimiter = ',')]
46 pub provider: Vec<ProviderArg>,
47 #[arg(long)]
49 pub model: Option<String>,
50 #[arg(long, value_parser = validate_when_arg)]
53 pub since: Option<String>,
54 #[arg(long, value_parser = validate_when_arg)]
56 pub until: Option<String>,
57 #[arg(long)]
60 pub on_disk_only: bool,
61}
62
63impl FilterArgs {
64 pub fn resolve(&self) -> Result<ResolvedFilter> {
65 let mut providers: Vec<String> = self
66 .provider
67 .iter()
68 .map(|p| ProviderKind::from(*p).id().to_string())
69 .collect();
70 providers.sort();
71 providers.dedup();
72 Ok(ResolvedFilter {
73 providers,
74 model: self.model.clone(),
75 since_ms: self
76 .since
77 .as_deref()
78 .map(|s| parse_when(s, false))
79 .transpose()?,
80 until_ms: self
81 .until
82 .as_deref()
83 .map(|s| parse_when(s, true))
84 .transpose()?,
85 on_disk_only: self.on_disk_only,
86 })
87 }
88}
89
90#[derive(Subcommand, Debug)]
94pub enum SkillCommand {
95 #[command(after_long_help = crate::cli_help::SKILLS_GENERATE_EXAMPLES)]
97 Generate(SkillArgs),
98 #[command(after_long_help = crate::cli_help::SKILLS_INSTALL_EXAMPLES)]
100 Install(SkillArgs),
101}
102
103#[derive(Args, Debug, Clone)]
105pub struct SkillArgs {
106 #[arg(long, value_enum, value_delimiter = ',', default_value = "all")]
108 pub target: Vec<SkillTarget>,
109 #[arg(long)]
111 pub dir: Option<PathBuf>,
112 #[arg(long)]
114 pub global: bool,
115 #[arg(long)]
117 pub force: bool,
118 #[arg(long)]
120 pub json: bool,
121}
122
123#[derive(ValueEnum, Debug, Clone, Copy, PartialEq, Eq)]
125pub enum SkillTarget {
126 ClaudeCode,
128 Codex,
130 Pi,
132 #[value(name = "openclaw")]
134 OpenClaw,
135 AgentsMd,
137 Plugin,
139 All,
141}
142
143pub fn validate_when_arg(value: &str) -> std::result::Result<String, String> {
144 parse_when(value, false)
145 .map(|_| value.to_string())
146 .map_err(|e| e.to_string())
147}