Skip to main content

oxios_kernel/kernel_handle/
marketplace_api.rs

1//! Marketplace API — ClawHub + Skills.sh integration facade.
2//!
3//! Exposes search, install, and update for skills from multiple registries:
4//! - **ClawHub** (`clawhub.ai`) — zip-based skill distribution
5//! - **Skills.sh** (`skills.sh`) — JSON API skill distribution (Vercel Labs ecosystem)
6
7use std::sync::Arc;
8
9use crate::skill::clawhub::{
10    ClawHubClient, ClawHubInstaller, ClawHubSearchResult, ClawHubSkillDetail, InstallResult,
11    UpdateAvailable, UpdateResult,
12};
13use crate::skill::skills_sh::{
14    SkillsShClient, SkillsShInstallResult, SkillsShInstaller, SkillsShSearchResponse,
15    SkillsShSkillDetail,
16};
17
18/// Marketplace system calls — multi-registry skill management.
19#[derive(Clone)]
20pub struct MarketplaceApi {
21    // ClawHub
22    clawhub_installer: Arc<ClawHubInstaller>,
23    clawhub_client: Arc<ClawHubClient>,
24    // Skills.sh
25    skills_sh_installer: Arc<SkillsShInstaller>,
26    skills_sh_client: Arc<SkillsShClient>,
27}
28
29impl MarketplaceApi {
30    /// Create a new MarketplaceApi with both registries.
31    pub fn new(
32        clawhub_installer: Arc<ClawHubInstaller>,
33        clawhub_client: Arc<ClawHubClient>,
34        skills_sh_installer: Arc<SkillsShInstaller>,
35        skills_sh_client: Arc<SkillsShClient>,
36    ) -> Self {
37        Self {
38            clawhub_installer,
39            clawhub_client,
40            skills_sh_installer,
41            skills_sh_client,
42        }
43    }
44
45    // ─── ClawHub Operations ─────────────────────────────────────────
46
47    /// Search ClawHub for skills by query.
48    pub async fn search_clawhub(
49        &self,
50        query: &str,
51        limit: Option<usize>,
52    ) -> anyhow::Result<Vec<ClawHubSearchResult>> {
53        self.clawhub_client.search_skills(query, limit).await
54    }
55
56    /// Get full detail for a ClawHub skill by slug.
57    pub async fn get_clawhub_skill(&self, slug: &str) -> anyhow::Result<ClawHubSkillDetail> {
58        self.clawhub_client.get_skill(slug).await
59    }
60
61    /// Install a skill from ClawHub.
62    pub async fn install_clawhub(
63        &self,
64        slug: &str,
65        version: Option<&str>,
66    ) -> anyhow::Result<InstallResult> {
67        self.clawhub_installer.install(slug, version).await
68    }
69
70    /// Check which installed ClawHub skills have newer versions.
71    pub async fn check_clawhub_updates(&self) -> anyhow::Result<Vec<UpdateAvailable>> {
72        self.clawhub_installer.check_updates().await
73    }
74
75    /// Update a specific installed ClawHub skill.
76    pub async fn update_clawhub(&self, slug: &str) -> anyhow::Result<UpdateResult> {
77        self.clawhub_installer.update(slug).await
78    }
79
80    /// Update all installed ClawHub skills.
81    pub async fn update_clawhub_all(&self) -> anyhow::Result<Vec<UpdateResult>> {
82        self.clawhub_installer.update_all().await
83    }
84
85    // ─── Skills.sh Operations ───────────────────────────────────────
86
87    /// Search skills.sh for skills.
88    pub async fn search_skills_sh(
89        &self,
90        query: &str,
91        limit: Option<usize>,
92    ) -> anyhow::Result<SkillsShSearchResponse> {
93        self.skills_sh_client.search(query, limit).await
94    }
95
96    /// List skills from the skills.sh leaderboard.
97    pub async fn list_skills_sh(
98        &self,
99        view: Option<&str>,
100        page: Option<i64>,
101        per_page: Option<i64>,
102    ) -> anyhow::Result<crate::skill::skills_sh::SkillsShListResponse> {
103        self.skills_sh_client.list(view, page, per_page).await
104    }
105
106    /// Get detailed info for a skills.sh skill (including file contents).
107    pub async fn get_skills_sh_skill(&self, id: &str) -> anyhow::Result<SkillsShSkillDetail> {
108        self.skills_sh_client.get_skill(id).await
109    }
110
111    /// Install a skill from skills.sh by its full id.
112    pub async fn install_skills_sh(&self, skill_id: &str) -> anyhow::Result<SkillsShInstallResult> {
113        self.skills_sh_installer.install(skill_id).await
114    }
115
116    /// Update a skill from skills.sh.
117    pub async fn update_skills_sh(&self, skill_id: &str) -> anyhow::Result<SkillsShInstallResult> {
118        self.skills_sh_installer.update(skill_id).await
119    }
120
121    /// Get security audit results for a skills.sh skill.
122    pub async fn audit_skills_sh(
123        &self,
124        id: &str,
125    ) -> anyhow::Result<crate::skill::skills_sh::SkillsShAuditResponse> {
126        self.skills_sh_client.audit(id).await
127    }
128
129    // ─── Legacy Compatibility ───────────────────────────────────────
130    // These methods default to ClawHub for backward compatibility.
131
132    /// Search for skills (defaults to ClawHub).
133    pub async fn search(
134        &self,
135        query: &str,
136        limit: Option<usize>,
137    ) -> anyhow::Result<Vec<ClawHubSearchResult>> {
138        self.search_clawhub(query, limit).await
139    }
140
141    /// Get skill detail (defaults to ClawHub).
142    pub async fn get_skill(&self, slug: &str) -> anyhow::Result<ClawHubSkillDetail> {
143        self.get_clawhub_skill(slug).await
144    }
145
146    /// Install a skill (defaults to ClawHub).
147    pub async fn install(
148        &self,
149        slug: &str,
150        version: Option<&str>,
151    ) -> anyhow::Result<InstallResult> {
152        self.install_clawhub(slug, version).await
153    }
154
155    /// Check for updates (defaults to ClawHub).
156    pub async fn check_updates(&self) -> anyhow::Result<Vec<UpdateAvailable>> {
157        self.check_clawhub_updates().await
158    }
159
160    /// Update a skill (defaults to ClawHub).
161    pub async fn update(&self, slug: &str) -> anyhow::Result<UpdateResult> {
162        self.update_clawhub(slug).await
163    }
164
165    /// Update all skills (defaults to ClawHub).
166    pub async fn update_all(&self) -> anyhow::Result<Vec<UpdateResult>> {
167        self.update_clawhub_all().await
168    }
169}