1use runx_contracts::JsonValue;
5use runx_contracts::maturity::MaturityTier;
6use serde::{Deserialize, Serialize};
7
8#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
9pub struct RegistryLinkResolution {
10 pub link: String,
11 pub skill_id: String,
12 pub version: String,
13 pub digest: String,
14 #[serde(skip_serializing_if = "Option::is_none")]
15 pub registry_url: Option<String>,
16 pub install_command: String,
17 pub run_command: String,
18}
19
20#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
21#[serde(rename_all = "snake_case")]
22pub enum TrustTier {
23 FirstParty,
24 Verified,
25 Community,
26}
27
28#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
29#[serde(rename_all = "snake_case")]
30pub enum ProfileMode {
31 Portable,
32 Profiled,
33}
34
35#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
36pub struct RegistryPublisher {
37 pub kind: String,
38 pub id: String,
39 #[serde(skip_serializing_if = "Option::is_none")]
40 pub handle: Option<String>,
41 #[serde(skip_serializing_if = "Option::is_none")]
42 pub display_name: Option<String>,
43}
44
45#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
46pub struct RegistryManifestSigner {
47 pub id: String,
48 pub key_id: String,
49}
50
51#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
52pub struct RegistryManifestSignature {
53 pub alg: String,
54 pub value: String,
55}
56
57#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
58pub struct RegistrySignedManifest {
59 pub schema: String,
60 pub skill_id: String,
61 pub version: String,
62 pub digest: String,
63 #[serde(skip_serializing_if = "Option::is_none")]
64 pub profile_digest: Option<String>,
65 #[serde(skip_serializing_if = "Option::is_none")]
66 pub package_digest: Option<String>,
67 pub signer: RegistryManifestSigner,
68 pub signature: RegistryManifestSignature,
69}
70
71#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
72pub struct RegistryPackageFile {
73 pub path: String,
74 pub content: String,
75}
76
77#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
78pub struct RegistryAttestation {
79 pub kind: String,
80 pub id: String,
81 pub status: String,
82 pub summary: String,
83 #[serde(skip_serializing_if = "Option::is_none")]
84 pub source: Option<String>,
85 #[serde(skip_serializing_if = "Option::is_none")]
86 pub issued_at: Option<String>,
87 #[serde(skip_serializing_if = "Option::is_none")]
88 pub metadata: Option<JsonValue>,
89}
90
91#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
92pub struct RegistrySourceMetadata {
93 pub provider: String,
94 pub repo: String,
95 pub repo_url: String,
96 pub skill_path: String,
97 #[serde(skip_serializing_if = "Option::is_none")]
98 pub profile_path: Option<String>,
99 pub r#ref: String,
100 pub sha: String,
101 pub default_branch: String,
102 pub event: String,
103 pub immutable: bool,
104 pub live: bool,
105 #[serde(skip_serializing_if = "Option::is_none")]
106 pub tombstoned: Option<bool>,
107 #[serde(skip_serializing_if = "Option::is_none")]
108 pub tag: Option<String>,
109 #[serde(skip_serializing_if = "Option::is_none")]
110 pub publisher_handle: Option<String>,
111}
112
113#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
114pub struct TrustSignal {
115 pub id: String,
116 pub label: String,
117 pub status: String,
118 pub value: String,
119}
120
121#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
122pub struct RegistrySearchResult {
123 pub skill_id: String,
124 pub name: String,
125 #[serde(skip_serializing_if = "Option::is_none")]
126 pub summary: Option<String>,
127 #[serde(skip_serializing_if = "Option::is_none")]
128 pub category: Option<String>,
129 #[serde(skip_serializing_if = "Option::is_none")]
130 pub source_category: Option<String>,
131 pub owner: String,
132 #[serde(skip_serializing_if = "Option::is_none")]
133 pub version: Option<String>,
134 #[serde(skip_serializing_if = "Option::is_none")]
135 pub digest: Option<String>,
136 #[serde(skip_serializing_if = "Option::is_none")]
137 pub source: Option<String>,
138 #[serde(skip_serializing_if = "Option::is_none")]
139 pub source_label: Option<String>,
140 pub source_type: String,
141 pub profile_mode: ProfileMode,
142 pub runner_names: Vec<String>,
143 #[serde(skip_serializing_if = "Option::is_none")]
144 pub profile_digest: Option<String>,
145 #[serde(skip_serializing_if = "Option::is_none")]
146 pub profile_trust_tier: Option<TrustTier>,
147 pub required_scopes: Vec<String>,
148 pub tags: Vec<String>,
149 pub trust_tier: TrustTier,
150 #[serde(default, skip_serializing_if = "Vec::is_empty")]
151 pub trust_signals: Vec<TrustSignal>,
152 pub install_command: String,
153 pub run_command: String,
154}
155
156#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
157pub struct RegistrySkillVersion {
158 pub skill_id: String,
159 pub owner: String,
160 pub name: String,
161 #[serde(skip_serializing_if = "Option::is_none")]
162 pub description: Option<String>,
163 #[serde(skip_serializing_if = "Option::is_none")]
164 pub category: Option<String>,
165 #[serde(skip_serializing_if = "Option::is_none")]
166 pub source_category: Option<String>,
167 pub version: String,
168 pub digest: String,
169 #[serde(skip_serializing_if = "Option::is_none")]
170 pub signed_manifest: Option<RegistrySignedManifest>,
171 pub markdown: String,
172 #[serde(skip_serializing_if = "Option::is_none")]
173 pub profile_document: Option<String>,
174 #[serde(skip_serializing_if = "Option::is_none")]
175 pub profile_digest: Option<String>,
176 #[serde(default, skip_serializing_if = "Vec::is_empty")]
177 pub package_files: Vec<RegistryPackageFile>,
178 #[serde(skip_serializing_if = "Option::is_none")]
179 pub package_digest: Option<String>,
180 pub runner_names: Vec<String>,
181 pub source_type: String,
182 pub trust_tier: TrustTier,
183 #[serde(default)]
184 pub maturity: MaturityTier,
185 #[serde(skip_serializing_if = "Option::is_none")]
186 pub catalog_kind: Option<String>,
187 #[serde(skip_serializing_if = "Option::is_none")]
188 pub catalog_audience: Option<String>,
189 #[serde(skip_serializing_if = "Option::is_none")]
190 pub catalog_visibility: Option<String>,
191 #[serde(skip_serializing_if = "Option::is_none")]
192 pub source_metadata: Option<RegistrySourceMetadata>,
193 #[serde(default, skip_serializing_if = "Vec::is_empty")]
194 pub attestations: Vec<RegistryAttestation>,
195 pub required_scopes: Vec<String>,
196 #[serde(skip_serializing_if = "Option::is_none")]
197 pub runtime: Option<JsonValue>,
198 #[serde(skip_serializing_if = "Option::is_none")]
199 pub auth: Option<JsonValue>,
200 #[serde(skip_serializing_if = "Option::is_none")]
201 pub risk: Option<JsonValue>,
202 #[serde(skip_serializing_if = "Option::is_none")]
203 pub runx: Option<runx_contracts::JsonObject>,
204 pub tags: Vec<String>,
205 pub publisher: RegistryPublisher,
206 pub created_at: String,
207 pub updated_at: String,
208}
209
210#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
211pub struct RegistrySkill {
212 pub skill_id: String,
213 pub owner: String,
214 pub name: String,
215 #[serde(skip_serializing_if = "Option::is_none")]
216 pub description: Option<String>,
217 #[serde(skip_serializing_if = "Option::is_none")]
218 pub category: Option<String>,
219 #[serde(skip_serializing_if = "Option::is_none")]
220 pub source_category: Option<String>,
221 pub latest_version: String,
222 pub latest_digest: String,
223 pub versions: Vec<RegistrySkillVersion>,
224}
225
226#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
227pub struct RegistrySkillResolution {
228 pub markdown: String,
229 #[serde(skip_serializing_if = "Option::is_none")]
230 pub profile_document: Option<String>,
231 #[serde(skip_serializing_if = "Option::is_none")]
232 pub profile_digest: Option<String>,
233 #[serde(default, skip_serializing_if = "Vec::is_empty")]
234 pub package_files: Vec<RegistryPackageFile>,
235 #[serde(skip_serializing_if = "Option::is_none")]
236 pub package_digest: Option<String>,
237 pub runner_names: Vec<String>,
238 pub skill_id: String,
239 pub name: String,
240 pub version: String,
241 pub digest: String,
242 #[serde(skip_serializing_if = "Option::is_none")]
243 pub signed_manifest: Option<RegistrySignedManifest>,
244 pub source: String,
245 pub source_label: String,
246 pub source_type: String,
247 pub trust_tier: TrustTier,
248 #[serde(skip_serializing_if = "Option::is_none")]
249 pub registry_url: Option<String>,
250 pub install_command: String,
251 pub run_command: String,
252}
253
254#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
255pub struct PublishSkillMarkdownResult {
256 pub status: PublishStatus,
257 pub skill_id: String,
258 pub name: String,
259 pub version: String,
260 pub digest: String,
261 #[serde(skip_serializing_if = "Option::is_none")]
262 pub signed_manifest: Option<RegistrySignedManifest>,
263 #[serde(skip_serializing_if = "Option::is_none")]
264 pub profile_digest: Option<String>,
265 pub runner_names: Vec<String>,
266 pub source_type: String,
267 #[serde(skip_serializing_if = "Option::is_none")]
268 pub registry_url: Option<String>,
269 #[serde(default)]
270 pub harness: RegistryPublishHarnessReport,
271 pub link: RegistryLinkResolution,
272 pub record: RegistrySkillVersion,
273}
274
275#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
276pub struct RegistryPublishHarnessReport {
277 pub status: String,
278 pub case_count: usize,
279 pub assertion_error_count: usize,
280 pub assertion_errors: Vec<String>,
281 pub case_names: Vec<String>,
282 pub receipt_ids: Vec<String>,
283 pub graph_case_count: usize,
284}
285
286impl RegistryPublishHarnessReport {
287 #[must_use]
288 pub fn not_declared() -> Self {
289 Self {
290 status: "not_declared".to_owned(),
291 case_count: 0,
292 assertion_error_count: 0,
293 assertion_errors: Vec::new(),
294 case_names: Vec::new(),
295 receipt_ids: Vec::new(),
296 graph_case_count: 0,
297 }
298 }
299
300 #[must_use]
301 pub fn failed(&self) -> bool {
302 self.status == "failed"
303 }
304}
305
306impl Default for RegistryPublishHarnessReport {
307 fn default() -> Self {
308 Self::not_declared()
309 }
310}
311
312#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
313#[serde(rename_all = "snake_case")]
314pub enum PublishStatus {
315 Published,
316 Unchanged,
317}
318
319#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
320pub struct RegistrySkillDetail {
321 pub skill_id: String,
322 pub owner: String,
323 pub name: String,
324 #[serde(skip_serializing_if = "Option::is_none")]
325 pub description: Option<String>,
326 #[serde(skip_serializing_if = "Option::is_none")]
327 pub category: Option<String>,
328 #[serde(skip_serializing_if = "Option::is_none")]
329 pub source_category: Option<String>,
330 pub version: String,
331 pub digest: String,
332 #[serde(skip_serializing_if = "Option::is_none")]
333 pub signed_manifest: Option<RegistrySignedManifest>,
334 pub markdown: String,
335 #[serde(skip_serializing_if = "Option::is_none")]
336 pub profile_digest: Option<String>,
337 #[serde(default, skip_serializing_if = "Vec::is_empty")]
338 pub package_files: Vec<RegistryPackageFile>,
339 #[serde(skip_serializing_if = "Option::is_none")]
340 pub package_digest: Option<String>,
341 pub runner_names: Vec<String>,
342 pub source_type: String,
343 pub trust_tier: TrustTier,
344 pub required_scopes: Vec<String>,
345 pub tags: Vec<String>,
346 pub publisher: RegistryPublisher,
347 #[serde(skip_serializing_if = "Option::is_none")]
348 pub source_metadata: Option<RegistrySourceMetadata>,
349 pub attestations: Vec<RegistryAttestation>,
350 pub install_command: String,
351 pub run_command: String,
352}
353
354#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
355pub struct AcquiredRegistrySkill {
356 pub skill_id: String,
357 pub owner: String,
358 pub name: String,
359 pub version: String,
360 pub digest: String,
361 #[serde(skip_serializing_if = "Option::is_none")]
362 pub signed_manifest: Option<RegistrySignedManifest>,
363 pub markdown: String,
364 #[serde(skip_serializing_if = "Option::is_none")]
365 pub profile_document: Option<String>,
366 #[serde(skip_serializing_if = "Option::is_none")]
367 pub profile_digest: Option<String>,
368 #[serde(default, skip_serializing_if = "Vec::is_empty")]
369 pub package_files: Vec<RegistryPackageFile>,
370 #[serde(skip_serializing_if = "Option::is_none")]
371 pub package_digest: Option<String>,
372 pub runner_names: Vec<String>,
373 pub trust_tier: TrustTier,
374 pub publisher: RegistryPublisher,
375 #[serde(skip_serializing_if = "Option::is_none")]
376 pub source_metadata: Option<RegistrySourceMetadata>,
377 pub attestations: Vec<RegistryAttestation>,
378 pub install_count: u64,
379}
380
381#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
382pub struct ResolvedRegistryRef {
383 pub skill_id: String,
384 pub version: Option<String>,
385}