Skip to main content

objectiveai_cli/command/plugins/install/
github.rs

1//! `plugins install github` — fetch the manifest, check the
2//! whitelist, and install the matching platform binary under
3//! `~/.objectiveai/plugins/<repository>/`. Port of the legacy
4//! `plugins::install` function minus the notification plumbing —
5//! the bare-naked contract surfaces the untrusted decision as the
6//! typed `Error::PluginNotWhitelisted` variant.
7//!
8//! The SDK `Request` does not expose `upgrade`; this leaf always
9//! installs fresh and surfaces `Error::AlreadyInstalled` if a
10//! manifest already exists.
11
12use objectiveai_sdk::cli::command::plugins::install::github::{Request, Response};
13
14use crate::context::Context;
15use crate::error::Error;
16
17pub async fn execute(ctx: &Context, request: Request) -> Result<Response, Error> {
18    let manifest = ctx
19        .filesystem
20        .fetch_plugin_manifest(
21            &request.owner,
22            &request.repository,
23            request.commit_sha.as_deref(),
24            None,
25        )
26        .await?;
27
28    let effective_sha = request.commit_sha.as_deref().unwrap_or("HEAD");
29    let whitelist = crate::filesystem::plugins::default_whitelist();
30    let allowed = crate::filesystem::plugins::check_plugin_whitelist(
31        &request.owner,
32        &request.repository,
33        effective_sha,
34        &manifest.version,
35        &whitelist,
36    )
37    .map_err(Error::WhitelistRegex)?;
38
39    if !allowed && !request.allow_untrusted {
40        return Err(Error::PluginNotWhitelisted {
41            owner: request.owner.clone(),
42            repository: request.repository.clone(),
43            commit_sha: effective_sha.to_string(),
44            version: manifest.version.clone(),
45        });
46    }
47
48    let source = crate::filesystem::plugins::raw_manifest_url(
49        &request.owner,
50        &request.repository,
51        request.commit_sha.as_deref(),
52    );
53    let installed = ctx
54        .filesystem
55        .install_plugin_from_manifest(
56            &request.owner,
57            &request.repository,
58            &manifest,
59            &source,
60            None,
61            false,
62        )
63        .await?;
64    Ok(Response { installed })
65}
66
67pub mod request_schema {
68    use objectiveai_sdk::cli::command::plugins::install::github as sdk;
69    use objectiveai_sdk::cli::command::plugins::install::github::request_schema::{Request, Response};
70
71    use crate::context::Context;
72    use crate::error::Error;
73
74    pub async fn execute(_ctx: &Context, _request: Request) -> Result<Response, Error> {
75        Ok(objectiveai_sdk::cli::command::ResponseSchema(schemars::schema_for!(sdk::Request)))
76    }
77}
78
79pub mod response_schema {
80    use objectiveai_sdk::cli::command::plugins::install::github as sdk;
81    use objectiveai_sdk::cli::command::plugins::install::github::response_schema::{Request, Response};
82
83    use crate::context::Context;
84    use crate::error::Error;
85
86    pub async fn execute(_ctx: &Context, _request: Request) -> Result<Response, Error> {
87        Ok(objectiveai_sdk::cli::command::ResponseSchema(schemars::schema_for!(sdk::Response)))
88    }
89}