Skip to main content

objectiveai_sdk/cli/command/plugins/get/
mod.rs

1//! `plugins get` — async handler stub.
2
3use crate::cli::command::CommandRequest;
4
5#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
6#[schemars(rename = "cli.command.plugins.get.Request")]
7pub struct Request {
8    pub path_type: Path,
9    pub owner: String,
10    pub name: String,
11    pub version: String,
12    pub jq: Option<String>,
13}
14
15#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
16#[schemars(rename = "cli.command.plugins.get.Path")]
17pub enum Path {
18    #[serde(rename = "plugins/get")]
19    PluginsGet,
20}
21
22impl CommandRequest for Request {
23    fn into_command(&self) -> Vec<String> {
24        let mut argv = vec![
25            "plugins".to_string(),
26            "get".to_string(),
27            "--owner".to_string(),
28            self.owner.clone(),
29            "--name".to_string(),
30            self.name.clone(),
31            "--version".to_string(),
32            self.version.clone(),
33        ];
34        if let Some(jq) = &self.jq {
35            argv.push("--jq".to_string());
36            argv.push(jq.clone());
37        }
38        argv
39    }
40}
41
42pub type Response = Option<ResponseManifest>;
43
44#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
45#[schemars(rename = "cli.command.plugins.get.ResponseManifest")]
46pub struct ResponseManifest {
47    pub name: String,
48    pub description: String,
49    pub version: String,
50    pub owner: String,
51    #[serde(default, skip_serializing_if = "Option::is_none")]
52    #[schemars(extend("omitempty" = true))]
53    pub author: Option<String>,
54    #[serde(default, skip_serializing_if = "Option::is_none")]
55    #[schemars(extend("omitempty" = true))]
56    pub homepage: Option<String>,
57    #[serde(default, skip_serializing_if = "Option::is_none")]
58    #[schemars(extend("omitempty" = true))]
59    pub license: Option<String>,
60    #[serde(default, skip_serializing_if = "ResponseBinaries::is_empty")]
61    pub binaries: ResponseBinaries,
62    #[serde(default, skip_serializing_if = "Option::is_none")]
63    #[schemars(extend("omitempty" = true))]
64    pub viewer_zip: Option<String>,
65    #[serde(default, skip_serializing_if = "Option::is_none")]
66    #[schemars(extend("omitempty" = true))]
67    pub viewer_url: Option<String>,
68    #[serde(default, skip_serializing_if = "Vec::is_empty")]
69    pub viewer_routes: Vec<ResponseViewerRoute>,
70    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
71    pub mobile_ready: bool,
72    #[serde(default, skip_serializing_if = "Vec::is_empty")]
73    pub mcp_servers: Vec<ResponseMcpServer>,
74    pub source: String,
75}
76
77#[derive(Debug, Clone, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
78#[schemars(rename = "cli.command.plugins.get.ResponseBinaries")]
79pub struct ResponseBinaries {
80    #[serde(default, skip_serializing_if = "Option::is_none")]
81    #[schemars(extend("omitempty" = true))]
82    pub linux_x86_64: Option<String>,
83    #[serde(default, skip_serializing_if = "Option::is_none")]
84    #[schemars(extend("omitempty" = true))]
85    pub linux_aarch64: Option<String>,
86    #[serde(default, skip_serializing_if = "Option::is_none")]
87    #[schemars(extend("omitempty" = true))]
88    pub windows_x86_64: Option<String>,
89    #[serde(default, skip_serializing_if = "Option::is_none")]
90    #[schemars(extend("omitempty" = true))]
91    pub windows_aarch64: Option<String>,
92    #[serde(default, skip_serializing_if = "Option::is_none")]
93    #[schemars(extend("omitempty" = true))]
94    pub macos_x86_64: Option<String>,
95    #[serde(default, skip_serializing_if = "Option::is_none")]
96    #[schemars(extend("omitempty" = true))]
97    pub macos_aarch64: Option<String>,
98}
99
100impl ResponseBinaries {
101    fn is_empty(&self) -> bool {
102        self.linux_x86_64.is_none()
103            && self.linux_aarch64.is_none()
104            && self.windows_x86_64.is_none()
105            && self.windows_aarch64.is_none()
106            && self.macos_x86_64.is_none()
107            && self.macos_aarch64.is_none()
108    }
109}
110
111#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
112#[schemars(rename = "cli.command.plugins.get.ResponseViewerRoute")]
113pub struct ResponseViewerRoute {
114    pub path: String,
115    pub method: ResponseHttpMethod,
116    pub r#type: String,
117}
118
119#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
120#[serde(rename_all = "UPPERCASE")]
121#[schemars(rename = "cli.command.plugins.get.ResponseHttpMethod")]
122pub enum ResponseHttpMethod {
123    Get,
124    Post,
125    Put,
126    Patch,
127    Delete,
128}
129
130#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
131#[schemars(rename = "cli.command.plugins.get.ResponseMcpServer")]
132pub struct ResponseMcpServer {
133    pub name: String,
134    pub url: String,
135    pub authorization: bool,
136}
137
138#[derive(clap::Args)]
139pub struct Args {
140    /// Plugin owner (GitHub `<owner>` segment). Required.
141    #[arg(long)]
142    pub owner: String,
143    /// Plugin name (repository segment). Required.
144    #[arg(long)]
145    pub name: String,
146    /// Plugin version. Required.
147    #[arg(long)]
148    pub version: String,
149    /// jq filter applied to the JSON output.
150    #[arg(long)]
151    pub jq: Option<String>,
152}
153
154#[derive(clap::Args)]
155#[command(args_conflicts_with_subcommands = true)]
156pub struct Command {
157    #[command(flatten)]
158    pub args: Args,
159    #[command(subcommand)]
160    pub schema: Option<Schema>,
161}
162
163#[derive(clap::Subcommand)]
164pub enum Schema {
165    /// Emit the JSON Schema for this leaf's `Request` type and exit.
166    RequestSchema(request_schema::Args),
167    /// Emit the JSON Schema for this leaf's `Response` type and exit.
168    ResponseSchema(response_schema::Args),
169}
170
171impl TryFrom<Args> for Request {
172    type Error = crate::cli::command::FromArgsError;
173    fn try_from(args: Args) -> Result<Self, Self::Error> {
174        Ok(Self {
175            path_type: Path::PluginsGet,
176            owner: args.owner,
177            name: args.name,
178            version: args.version,
179            jq: args.jq,
180        })
181    }
182}
183
184#[cfg(feature = "cli-executor")]
185pub async fn execute<E: crate::cli::command::CommandExecutor>(
186    executor: &E,
187    mut request: Request,
188
189        agent_arguments: Option<&crate::cli::command::AgentArguments>,
190    ) -> Result<Response, E::Error> {
191    request.jq = None;
192    executor.execute_one(request, agent_arguments).await
193}
194
195#[cfg(feature = "cli-executor")]
196pub async fn execute_jq<E: crate::cli::command::CommandExecutor>(
197    executor: &E,
198    mut request: Request,
199    jq: String,
200
201        agent_arguments: Option<&crate::cli::command::AgentArguments>,
202    ) -> Result<serde_json::Value, E::Error> {
203    request.jq = Some(jq);
204    executor.execute_one(request, agent_arguments).await
205}
206
207#[cfg(feature = "mcp")]
208impl crate::cli::command::CommandResponse for ResponseManifest {
209    fn into_mcp(self) -> crate::cli::command::McpResponseItem {
210        crate::cli::command::McpResponseItem::JSONL(serde_json::to_value(self).unwrap())
211    }
212}
213
214pub mod request_schema;
215
216
217pub mod response_schema;