From 3239c5d990b6360ac653f17c0946bfe182e38c3b Mon Sep 17 00:00:00 2001 From: Alex Clarke Date: Mon, 1 Jun 2026 11:17:55 -0600 Subject: [PATCH] feat: decided to make skills persist to disk like agents and not in-memory like built-in roles --- src/config/mod.rs | 1 - src/config/paths.rs | 44 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/config/mod.rs b/src/config/mod.rs index 1bdd158..8b94b42 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -77,7 +77,6 @@ const LIGHT_THEME: &[u8] = include_bytes!("../../assets/monokai-extended-light.t const CONFIG_FILE_NAME: &str = "config.yaml"; const AGENT_GRAPH_FILE_NAME: &str = "graph.yaml"; const ROLES_DIR_NAME: &str = "roles"; -#[allow(dead_code)] const SKILLS_DIR_NAME: &str = "skills"; const MACROS_DIR_NAME: &str = "macros"; const ENV_FILE_NAME: &str = ".env"; diff --git a/src/config/paths.rs b/src/config/paths.rs index b1df31e..c98c5a8 100644 --- a/src/config/paths.rs +++ b/src/config/paths.rs @@ -3,7 +3,7 @@ use super::{ AGENT_GRAPH_FILE_NAME, AGENTS_DIR_NAME, BASH_PROMPT_UTILS_FILE_NAME, CONFIG_FILE_NAME, ENV_FILE_NAME, FUNCTIONS_BIN_DIR_NAME, FUNCTIONS_DIR_NAME, GLOBAL_TOOLS_DIR_NAME, GLOBAL_TOOLS_UTILS_DIR_NAME, MACROS_DIR_NAME, MCP_FILE_NAME, ModelsOverride, RAGS_DIR_NAME, - ROLES_DIR_NAME, + ROLES_DIR_NAME, SKILLS_DIR_NAME, }; use crate::client::ProviderModels; use crate::utils::{get_env_name, list_file_names, normalize_env_name}; @@ -65,6 +65,24 @@ pub fn role_file(name: &str) -> PathBuf { roles_dir().join(format!("{name}.md")) } +#[allow(dead_code)] +pub fn skills_dir() -> PathBuf { + match env::var(get_env_name("skills_dir")) { + Ok(value) => PathBuf::from(value), + Err(_) => local_path(SKILLS_DIR_NAME), + } +} + +#[allow(dead_code)] +pub fn skill_dir(name: &str) -> PathBuf { + skills_dir().join(name) +} + +#[allow(dead_code)] +pub fn skill_file(name: &str) -> PathBuf { + skill_dir(name).join("SKILL.md") +} + pub fn macros_dir() -> PathBuf { match env::var(get_env_name("macros_dir")) { Ok(value) => PathBuf::from(value), @@ -234,6 +252,30 @@ pub fn has_macro(name: &str) -> bool { names.contains(&name.to_string()) } +#[allow(dead_code)] +pub fn list_skills() -> Vec { + let mut names = Vec::new(); + if let Ok(rd) = read_dir(skills_dir()) { + for entry in rd.flatten() { + if let Ok(file_type) = entry.file_type() + && file_type.is_dir() + && let Some(name) = entry.file_name().to_str() + && entry.path().join("SKILL.md").is_file() + { + names.push(name.to_string()); + } + } + } + + names.sort_unstable(); + names +} + +#[allow(dead_code)] +pub fn has_skill(name: &str) -> bool { + skill_file(name).is_file() +} + pub fn local_models_override() -> Result> { let model_override_path = models_override_file(); let err = || {