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