Skip to main content

oxi/storage/packages/
types.rs

1//! Type definitions for the package system.
2//!
3//! All core data types used across the package subsystem live here:
4//! resource kinds, manifests, discovery records, scope/origin enums,
5//! resolution paths, progress events, and update/configured-package
6//! metadata. Splitting them out keeps the manager focused on lifecycle
7//! logic instead of getting buried in field-level structs.
8
9use serde::{Deserialize, Serialize};
10use std::collections::BTreeMap;
11use std::path::PathBuf;
12
13/// Types of resources a package can contribute
14#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
15#[serde(rename_all = "snake_case")]
16pub enum ResourceKind {
17    /// extension variant.
18    Extension,
19    /// skill variant.
20    Skill,
21    /// prompt variant.
22    Prompt,
23    /// theme variant.
24    Theme,
25}
26impl ResourceKind {
27    /// All resource kinds, iteration order is stable.
28    pub const ALL: [ResourceKind; 4] = [
29        ResourceKind::Extension,
30        ResourceKind::Skill,
31        ResourceKind::Prompt,
32        ResourceKind::Theme,
33    ];
34}
35
36impl std::fmt::Display for ResourceKind {
37    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
38        match self {
39            ResourceKind::Extension => write!(f, "extension"),
40            ResourceKind::Skill => write!(f, "skill"),
41            ResourceKind::Prompt => write!(f, "prompt"),
42            ResourceKind::Theme => write!(f, "theme"),
43        }
44    }
45}
46
47// All resource kinds for iteration
48
49/// Package manifest describing bundled resources
50#[derive(Debug, Clone, Serialize, Deserialize)]
51pub struct PackageManifest {
52    /// Package name (e.g. "@foo/oxi-tools")
53    pub name: String,
54    /// Semantic version (e.g. "1.0.0")
55    pub version: String,
56    /// Extension paths relative to the package root
57    #[serde(default)]
58    pub extensions: Vec<String>,
59    /// Skill names/paths
60    #[serde(default)]
61    pub skills: Vec<String>,
62    /// Prompt template paths
63    #[serde(default)]
64    pub prompts: Vec<String>,
65    /// Theme paths
66    #[serde(default)]
67    pub themes: Vec<String>,
68    /// Optional description
69    #[serde(default)]
70    pub description: Option<String>,
71    /// Package dependencies (name -> version constraint)
72    #[serde(default)]
73    pub dependencies: BTreeMap<String, String>,
74}
75
76/// A discovered resource within a package
77#[derive(Debug, Clone, Serialize, Deserialize)]
78pub struct DiscoveredResource {
79    /// Resource type
80    pub kind: ResourceKind,
81    /// Absolute path to the resource
82    pub path: PathBuf,
83    /// Relative path within the package
84    pub relative_path: String,
85}
86
87/// Metadata about a resolved resource path
88#[derive(Debug, Clone, Serialize, Deserialize)]
89pub struct PathMetadata {
90    /// Source specifier
91    pub source: String,
92    /// Scope (user / project)
93    pub scope: SourceScope,
94    /// Whether this is a package resource or top-level
95    pub origin: ResourceOrigin,
96    /// Base directory for resolving relative paths
97    pub base_dir: Option<PathBuf>,
98}
99
100/// Origin of a resource
101#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
102#[serde(rename_all = "snake_case")]
103pub enum ResourceOrigin {
104    /// package variant.
105    Package,
106    /// top level variant.
107    TopLevel,
108}
109
110/// Scope for package sources
111#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
112#[serde(rename_all = "snake_case")]
113pub enum SourceScope {
114    /// user variant.
115    User,
116    /// project variant.
117    Project,
118}
119
120impl std::fmt::Display for SourceScope {
121    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
122        match self {
123            SourceScope::User => write!(f, "user"),
124            SourceScope::Project => write!(f, "project"),
125        }
126    }
127}
128
129/// A resolved resource with metadata
130#[derive(Debug, Clone, Serialize, Deserialize)]
131pub struct ResolvedResource {
132    /// Absolute path to the resource
133    pub path: PathBuf,
134    /// Whether this resource is enabled
135    pub enabled: bool,
136    /// Metadata about the resource
137    pub metadata: PathMetadata,
138}
139
140/// Resolved paths for all resource types
141#[derive(Debug, Clone, Default, Serialize, Deserialize)]
142pub struct ResolvedPaths {
143    /// pub.
144    pub extensions: Vec<ResolvedResource>,
145    /// pub.
146    pub skills: Vec<ResolvedResource>,
147    /// pub.
148    pub prompts: Vec<ResolvedResource>,
149    /// pub.
150    pub themes: Vec<ResolvedResource>,
151}
152
153/// Progress events for package operations
154#[derive(Debug, Clone, Serialize, Deserialize)]
155pub struct ProgressEvent {
156    /// pub.
157    pub event_type: ProgressEventType,
158    /// pub.
159    pub action: ProgressAction,
160    /// pub.
161    pub source: String,
162    /// pub.
163    pub message: Option<String>,
164}
165
166/// Progress event type
167#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
168#[serde(rename_all = "snake_case")]
169pub enum ProgressEventType {
170    /// start variant.
171    Start,
172    /// progress variant.
173    Progress,
174    /// complete variant.
175    Complete,
176    /// error variant.
177    Error,
178}
179
180/// Action being performed
181#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
182#[serde(rename_all = "snake_case")]
183pub enum ProgressAction {
184    /// install variant.
185    Install,
186    /// remove variant.
187    Remove,
188    /// update variant.
189    Update,
190    /// clone variant.
191    Clone,
192    /// pull variant.
193    Pull,
194}
195
196impl std::fmt::Display for ProgressAction {
197    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
198        match self {
199            ProgressAction::Install => write!(f, "install"),
200            ProgressAction::Remove => write!(f, "remove"),
201            ProgressAction::Update => write!(f, "update"),
202            ProgressAction::Clone => write!(f, "clone"),
203            ProgressAction::Pull => write!(f, "pull"),
204        }
205    }
206}
207
208/// Callback for progress events
209pub type ProgressCallback = Box<dyn Fn(ProgressEvent) + Send + Sync>;
210
211/// Information about an available package update
212#[derive(Debug, Clone, Serialize, Deserialize)]
213pub struct PackageUpdateInfo {
214    /// pub.
215    pub source: String,
216    /// pub.
217    pub display_name: String,
218    /// pub.
219    pub source_type: String, // "npm" or "git"
220    /// pub.
221    pub scope: SourceScope,
222}
223
224/// A configured package
225#[derive(Debug, Clone, Serialize, Deserialize)]
226pub struct ConfiguredPackage {
227    /// pub.
228    pub source: String,
229    /// pub.
230    pub scope: SourceScope,
231    /// pub.
232    pub filtered: bool,
233    /// pub.
234    pub installed_path: Option<PathBuf>,
235}