diff --git a/crates/fastskill-cli/src/commands/list.rs b/crates/fastskill-cli/src/commands/list.rs index 50a91738..5c4ab247 100644 --- a/crates/fastskill-cli/src/commands/list.rs +++ b/crates/fastskill-cli/src/commands/list.rs @@ -178,7 +178,7 @@ pub async fn execute_list( // Installed skills from service let skill_manager = service.skill_manager(); - let installed_skills = skill_manager.list_skills(None).await.map_err(|e| { + let installed_skills = skill_manager.list_skills().await.map_err(|e| { CliError::Service(fastskill_core::ServiceError::Custom(format!( "Failed to list installed skills: {}", e diff --git a/crates/fastskill-cli/src/commands/read.rs b/crates/fastskill-cli/src/commands/read.rs index c7a6a330..8280c03c 100644 --- a/crates/fastskill-cli/src/commands/read.rs +++ b/crates/fastskill-cli/src/commands/read.rs @@ -176,7 +176,7 @@ async fn resolve_skill( // Check for partial matches let all_skills = service .skill_manager() - .list_skills(None) + .list_skills() .await .map_err(CliError::Service)?; @@ -371,7 +371,7 @@ pub async fn execute_read(service: Arc, args: ReadArgs) -> Cli // T024: If no exact match, check for multiple partial matches let all_skills = service .skill_manager() - .list_skills(None) + .list_skills() .await .map_err(CliError::Service)?; diff --git a/crates/fastskill-cli/tests/lock_determinism_test.rs b/crates/fastskill-cli/tests/lock_determinism_test.rs index e9fd4e61..e88ddd3e 100644 --- a/crates/fastskill-cli/tests/lock_determinism_test.rs +++ b/crates/fastskill-cli/tests/lock_determinism_test.rs @@ -22,7 +22,6 @@ fn make_skill(id: &str) -> SkillDefinition { description: "test".to_string(), version: "1.0.0".to_string(), author: None, - enabled: true, created_at: Utc::now(), updated_at: Utc::now(), skill_file: std::path::PathBuf::from("SKILL.md"), diff --git a/crates/fastskill-cli/tests/lock_scope_routing_test.rs b/crates/fastskill-cli/tests/lock_scope_routing_test.rs index 4fe1f4ce..88e91120 100644 --- a/crates/fastskill-cli/tests/lock_scope_routing_test.rs +++ b/crates/fastskill-cli/tests/lock_scope_routing_test.rs @@ -26,7 +26,6 @@ fn make_skill(id: &str) -> SkillDefinition { description: "test".to_string(), version: "1.0.0".to_string(), author: None, - enabled: true, created_at: Utc::now(), updated_at: Utc::now(), skill_file: std::path::PathBuf::from("SKILL.md"), diff --git a/crates/fastskill-core/src/core/lock.rs b/crates/fastskill-core/src/core/lock.rs index 6e293f2b..f3914dd8 100644 --- a/crates/fastskill-core/src/core/lock.rs +++ b/crates/fastskill-core/src/core/lock.rs @@ -439,7 +439,6 @@ mod tests { description: "test".to_string(), version: "1.0.0".to_string(), author: None, - enabled: true, created_at: Utc::now(), updated_at: Utc::now(), skill_file: std::path::PathBuf::from("SKILL.md"), diff --git a/crates/fastskill-core/src/core/metadata.rs b/crates/fastskill-core/src/core/metadata.rs index a08654e6..bab122a9 100644 --- a/crates/fastskill-core/src/core/metadata.rs +++ b/crates/fastskill-core/src/core/metadata.rs @@ -13,7 +13,6 @@ pub struct SkillMetadata { pub description: String, pub version: String, pub author: Option, - pub enabled: bool, pub token_estimate: usize, pub last_updated: chrono::DateTime, } @@ -26,8 +25,7 @@ impl From<&SkillDefinition> for SkillMetadata { description: skill.description.clone(), version: skill.version.clone(), author: skill.author.clone(), - enabled: skill.enabled, - token_estimate: skill.description.len() / 4, // Rough estimate + token_estimate: skill.description.len() / 4, last_updated: skill.updated_at, } } @@ -229,7 +227,7 @@ pub fn parse_yaml_frontmatter(content: &str) -> Result Result, ServiceError> { - let all_skills = self.skill_manager.list_skills(None).await?; + let all_skills = self.skill_manager.list_skills().await?; // Filter and score skills based on query relevance let mut scored_skills: Vec<(f32, &SkillDefinition)> = all_skills @@ -285,3 +283,24 @@ impl MetadataService for MetadataServiceImpl { self.parse_frontmatter(&content) } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_frontmatter_with_legacy_enabled_key() { + let content = + "---\nname: test-skill\ndescription: A test skill\nenabled: true\n---\n# Body"; + let result = parse_yaml_frontmatter(content); + assert!( + result.is_ok(), + "parse_yaml_frontmatter should succeed with legacy enabled key" + ); + let fm = result.unwrap(); + assert!( + fm.extra.contains_key("enabled"), + "extra map should contain the enabled key" + ); + } +} diff --git a/crates/fastskill-core/src/core/mod.rs b/crates/fastskill-core/src/core/mod.rs index ba697c89..f48f308c 100644 --- a/crates/fastskill-core/src/core/mod.rs +++ b/crates/fastskill-core/src/core/mod.rs @@ -109,7 +109,7 @@ pub use service::{ // skill_manager pub use skill_manager::{ - SkillDefinition, SkillFilters, SkillManagementService, SkillManager, SkillUpdate, SourceType, + SkillDefinition, SkillManagementService, SkillManager, SkillUpdate, SourceType, }; // sources diff --git a/crates/fastskill-core/src/core/repository/client.rs b/crates/fastskill-core/src/core/repository/client.rs index f2bd8abe..0ae3afb7 100644 --- a/crates/fastskill-core/src/core/repository/client.rs +++ b/crates/fastskill-core/src/core/repository/client.rs @@ -175,7 +175,6 @@ impl RepositoryClient for MarketplaceRepositoryClient { description: info.description, version: info.version.unwrap_or_else(|| "1.0.0".to_string()), author: None, - enabled: true, token_estimate: 0, last_updated: Utc::now(), }) @@ -439,7 +438,6 @@ impl RepositoryClient for CratesRegistryClient { description: s.description.clone(), version: s.latest_version.clone(), author: None, // Not available in SkillSummary - enabled: true, token_estimate: s.description.len() / 4, // Rough estimate last_updated: s.published_at.unwrap_or_else(chrono::Utc::now), }) @@ -488,7 +486,6 @@ impl RepositoryClient for CratesRegistryClient { .unwrap_or_else(|| "".to_string()), version: e.vers, author: e.metadata.as_ref().and_then(|m| m.author.clone()), - enabled: true, token_estimate: 0, last_updated: Utc::now(), }) diff --git a/crates/fastskill-core/src/core/skill_manager.rs b/crates/fastskill-core/src/core/skill_manager.rs index 6d5ee8ea..20db4008 100644 --- a/crates/fastskill-core/src/core/skill_manager.rs +++ b/crates/fastskill-core/src/core/skill_manager.rs @@ -27,7 +27,6 @@ pub struct SkillDefinition { pub description: String, pub version: String, pub author: Option, - pub enabled: bool, pub created_at: DateTime, pub updated_at: DateTime, @@ -63,7 +62,6 @@ impl SkillDefinition { description, version, author: None, - enabled: true, created_at: now, updated_at: now, skill_file: std::path::PathBuf::from(format!("./skills/{}/SKILL.md", id)), @@ -99,12 +97,7 @@ pub trait SkillManagementService: Send + Sync { updates: SkillUpdate, ) -> Result<(), ServiceError>; async fn unregister_skill(&self, skill_id: &SkillId) -> Result<(), ServiceError>; - async fn list_skills( - &self, - filters: Option, - ) -> Result, ServiceError>; - async fn enable_skill(&self, skill_id: &SkillId) -> Result<(), ServiceError>; - async fn disable_skill(&self, skill_id: &SkillId) -> Result<(), ServiceError>; + async fn list_skills(&self) -> Result, ServiceError>; } #[derive(Debug)] @@ -126,18 +119,12 @@ impl SkillManager { } } -#[derive(Debug, Clone)] -pub struct SkillFilters { - pub enabled: Option, -} - #[derive(Debug, Clone, Default)] pub struct SkillUpdate { pub name: Option, pub description: Option, pub version: Option, pub author: Option, - pub enabled: Option, pub source_url: Option, pub source_type: Option, pub source_branch: Option, @@ -197,9 +184,6 @@ impl SkillManagementService for SkillManager { if let Some(author) = updates.author { skill.author = Some(author); } - if let Some(enabled) = updates.enabled { - skill.enabled = enabled; - } if let Some(source_url) = updates.source_url { skill.source_url = Some(source_url); } @@ -244,42 +228,8 @@ impl SkillManagementService for SkillManager { } } - async fn list_skills( - &self, - filters: Option, - ) -> Result, ServiceError> { + async fn list_skills(&self) -> Result, ServiceError> { let skills = self.skills.read().await; - let mut filtered_skills: Vec = skills.values().cloned().collect(); - - if let Some(filters) = filters { - // Filter by enabled status - if let Some(enabled) = filters.enabled { - filtered_skills.retain(|skill| skill.enabled == enabled); - } - } - - Ok(filtered_skills) - } - - async fn enable_skill(&self, skill_id: &SkillId) -> Result<(), ServiceError> { - self.update_skill( - skill_id, - SkillUpdate { - enabled: Some(true), - ..Default::default() - }, - ) - .await - } - - async fn disable_skill(&self, skill_id: &SkillId) -> Result<(), ServiceError> { - self.update_skill( - skill_id, - SkillUpdate { - enabled: Some(false), - ..Default::default() - }, - ) - .await + Ok(skills.values().cloned().collect()) } } diff --git a/crates/fastskill-core/src/events/event_bus.rs b/crates/fastskill-core/src/events/event_bus.rs index cebe1023..ef7eb09f 100644 --- a/crates/fastskill-core/src/events/event_bus.rs +++ b/crates/fastskill-core/src/events/event_bus.rs @@ -49,12 +49,6 @@ pub enum SkillEvent { /// Hot reload disabled HotReloadDisabled, - /// Skill enabled - SkillEnabled { skill_id: String }, - - /// Skill disabled - SkillDisabled { skill_id: String }, - /// Custom event Custom { event_type: String, @@ -68,7 +62,6 @@ pub struct SkillUpdate { pub name: Option, pub description: Option, pub version: Option, - pub enabled: Option, } /// Hot reload configuration @@ -204,8 +197,6 @@ impl EventBus { SkillEvent::SkillValidationFailed { .. } => "skill:validation:failed", SkillEvent::HotReloadEnabled { .. } => "hot-reload:enabled", SkillEvent::HotReloadDisabled => "hot-reload:disabled", - SkillEvent::SkillEnabled { .. } => "skill:enabled", - SkillEvent::SkillDisabled { .. } => "skill:disabled", SkillEvent::Custom { event_type, .. } => event_type.as_str(), } .to_string(); @@ -300,12 +291,6 @@ impl EventHandler for LoggingEventHandler { SkillEvent::HotReloadDisabled => { info!("Hot reload disabled"); } - SkillEvent::SkillEnabled { skill_id } => { - info!("[OK] Skill enabled: {}", skill_id); - } - SkillEvent::SkillDisabled { skill_id } => { - info!("Skill disabled: {}", skill_id); - } SkillEvent::Custom { event_type, data } => { debug!("Custom event: {} - {:?}", event_type, data); } @@ -350,8 +335,6 @@ impl EventHandler for MetricsEventHandler { SkillEvent::SkillValidationFailed { .. } => "skill:validation:failed".to_string(), SkillEvent::HotReloadEnabled { .. } => "hot-reload:enabled".to_string(), SkillEvent::HotReloadDisabled => "hot-reload:disabled".to_string(), - SkillEvent::SkillEnabled { .. } => "skill:enabled".to_string(), - SkillEvent::SkillDisabled { .. } => "skill:disabled".to_string(), SkillEvent::Custom { event_type, .. } => event_type.clone(), }; @@ -434,16 +417,4 @@ impl EventBus { pub async fn publish_hot_reload_disabled(&self) -> Result { self.publish_event(SkillEvent::HotReloadDisabled).await } - - /// Publish skill enabled event - pub async fn publish_skill_enabled(&self, skill_id: String) -> Result { - self.publish_event(SkillEvent::SkillEnabled { skill_id }) - .await - } - - /// Publish skill disabled event - pub async fn publish_skill_disabled(&self, skill_id: String) -> Result { - self.publish_event(SkillEvent::SkillDisabled { skill_id }) - .await - } } diff --git a/crates/fastskill-core/src/http/handlers/registry.rs b/crates/fastskill-core/src/http/handlers/registry.rs index 8843d7ad..4abd7c4d 100644 --- a/crates/fastskill-core/src/http/handlers/registry.rs +++ b/crates/fastskill-core/src/http/handlers/registry.rs @@ -199,7 +199,7 @@ pub async fn list_all_skills( // Get all installed skills let installed_skills = skill_manager - .list_skills(None) + .list_skills() .await .map_err(|e| HttpError::InternalServerError(e.to_string()))?; @@ -306,7 +306,7 @@ pub async fn list_source_skills( // Get installed skills to check installation status let installed_skills = skill_manager - .list_skills(None) + .list_skills() .await .map_err(|e| HttpError::InternalServerError(e.to_string()))?; diff --git a/crates/fastskill-core/src/http/handlers/search.rs b/crates/fastskill-core/src/http/handlers/search.rs index bf5a5542..1c5a4e87 100644 --- a/crates/fastskill-core/src/http/handlers/search.rs +++ b/crates/fastskill-core/src/http/handlers/search.rs @@ -110,7 +110,7 @@ pub async fn search_skills( let skills_list = state .service .skill_manager() - .list_skills(None) + .list_skills() .await .map_err(|e| HttpError::ServiceError(format!("Failed to list skills: {}", e)))?; diff --git a/crates/fastskill-core/src/http/handlers/skills.rs b/crates/fastskill-core/src/http/handlers/skills.rs index 40522852..d9a6066d 100644 --- a/crates/fastskill-core/src/http/handlers/skills.rs +++ b/crates/fastskill-core/src/http/handlers/skills.rs @@ -26,7 +26,6 @@ fn skill_metadata_json(skill: &crate::core::skill_manager::SkillDefinition) -> s "description": skill.description, "version": skill.version, "author": skill.author, - "enabled": skill.enabled, "created_at": skill.created_at.to_rfc3339(), "updated_at": skill.updated_at.to_rfc3339(), "skill_file": skill.skill_file, @@ -42,7 +41,7 @@ fn skill_metadata_json(skill: &crate::core::skill_manager::SkillDefinition) -> s pub async fn list_skills( State(state): State, ) -> HttpResult>> { - let skills = state.service.skill_manager().list_skills(None).await?; + let skills = state.service.skill_manager().list_skills().await?; let skill_responses: Vec = skills .clone() @@ -73,7 +72,7 @@ pub async fn get_skill( ) -> HttpResult>> { // Check permissions - let skills = state.service.skill_manager().list_skills(None).await?; + let skills = state.service.skill_manager().list_skills().await?; let skill_id_parsed = crate::core::service::SkillId::new(skill_id.clone()) .map_err(|_| HttpError::BadRequest("Invalid skill ID format".to_string()))?; let skill = skills @@ -174,7 +173,7 @@ pub async fn delete_skill( let skill_id_parsed = crate::core::service::SkillId::new(skill_id.clone()) .map_err(|_| HttpError::BadRequest("Invalid skill ID format".to_string()))?; - let skills = state.service.skill_manager().list_skills(None).await?; + let skills = state.service.skill_manager().list_skills().await?; let skill = skills .into_iter() .find(|s| s.id == skill_id_parsed) diff --git a/crates/fastskill-core/src/http/handlers/status.rs b/crates/fastskill-core/src/http/handlers/status.rs index 4537e572..1ff6d673 100644 --- a/crates/fastskill-core/src/http/handlers/status.rs +++ b/crates/fastskill-core/src/http/handlers/status.rs @@ -60,8 +60,7 @@ impl AppState { /// GET / - Root endpoint with HTML dashboard pub async fn root(State(state): State) -> Html { - let skills: Vec<_> = - (state.service.skill_manager().list_skills(None).await).unwrap_or_default(); + let skills: Vec<_> = (state.service.skill_manager().list_skills().await).unwrap_or_default(); let skills_count = skills.len(); let uptime = state.uptime_seconds(); @@ -238,7 +237,7 @@ pub async fn root(State(state): State) -> Html { pub async fn status( State(state): State, ) -> HttpResult>> { - let skills = state.service.skill_manager().list_skills(None).await?; + let skills = state.service.skill_manager().list_skills().await?; let skills_count = skills.len(); let config = state.service.config(); diff --git a/crates/fastskill-core/src/lib.rs b/crates/fastskill-core/src/lib.rs index 80543e4a..030226bf 100644 --- a/crates/fastskill-core/src/lib.rs +++ b/crates/fastskill-core/src/lib.rs @@ -30,7 +30,7 @@ //! let service = FastSkillService::new(config).await?; //! //! // List available skills -//! let skills = service.skill_manager().list_skills(None).await?; +//! let skills = service.skill_manager().list_skills().await?; //! println!("Found {} skills", skills.len()); //! //! // Discover relevant skills @@ -127,6 +127,6 @@ mod tests { }; let service = FastSkillService::new(config).await.unwrap(); - assert!(service.skill_manager().list_skills(None).await.is_ok()); + assert!(service.skill_manager().list_skills().await.is_ok()); } }