diff --git a/crates/goose/src/agents/execute_commands.rs b/crates/goose/src/agents/execute_commands.rs index 3a488c70a1..66d5d34bed 100644 --- a/crates/goose/src/agents/execute_commands.rs +++ b/crates/goose/src/agents/execute_commands.rs @@ -161,6 +161,7 @@ impl Agent { output.push_str("No skills installed.\n\n"); output.push_str("Skills are loaded from SKILL.md files in:\n"); output.push_str(" - ~/.agents/skills/ (global)\n"); + output.push_str(" - ~/.agents/plugins/*/skills/ (installed plugins)\n"); output.push_str(" - .agents/skills/ (in current project)\n"); } else { output.push_str(&format!("**Installed skills ({}):**\n\n", skills.len())); diff --git a/crates/goose/src/config/paths.rs b/crates/goose/src/config/paths.rs index 0fadf90ab3..41441ece2f 100644 --- a/crates/goose/src/config/paths.rs +++ b/crates/goose/src/config/paths.rs @@ -11,6 +11,7 @@ impl Paths { DirType::Config => base.join("config"), DirType::Data => base.join("data"), DirType::State => base.join("state"), + DirType::Plugins => base.join(".agents").join("plugins"), } } else { // NOTE: "Block" is kept here for backwards compatibility with existing @@ -27,6 +28,7 @@ impl Paths { DirType::Config => strategy.config_dir(), DirType::Data => strategy.data_dir(), DirType::State => strategy.state_dir().unwrap_or(strategy.data_dir()), + DirType::Plugins => strategy.home_dir().join(".agents").join("plugins"), } } } @@ -43,6 +45,10 @@ impl Paths { Self::get_dir(DirType::State) } + pub fn plugins_dir() -> PathBuf { + Self::get_dir(DirType::Plugins) + } + pub fn in_state_dir(subpath: &str) -> PathBuf { Self::state_dir().join(subpath) } @@ -60,4 +66,5 @@ enum DirType { Config, Data, State, + Plugins, } diff --git a/crates/goose/src/plugins/mod.rs b/crates/goose/src/plugins/mod.rs index 09bf0fd2fe..cbec1831bd 100644 --- a/crates/goose/src/plugins/mod.rs +++ b/crates/goose/src/plugins/mod.rs @@ -69,12 +69,8 @@ struct InstallMetadata { last_update_check: Option>, } -pub fn plugin_install_dir() -> PathBuf { - Paths::data_dir().join("plugins") -} - pub fn installed_plugin_skill_dirs() -> Vec { - let plugins_dir = plugin_install_dir(); + let plugins_dir = Paths::plugins_dir(); for update in auto_update_plugins_at_root(Utc::now(), &plugins_dir) { if let Err(err) = update.result { warn!( @@ -104,7 +100,7 @@ pub fn install_plugin_with_options( source: &str, options: PluginInstallOptions, ) -> Result { - install_plugin_with_options_at_root(source, options, &plugin_install_dir()) + install_plugin_with_options_at_root(source, options, &Paths::plugins_dir()) } fn install_plugin_with_options_at_root( @@ -130,11 +126,11 @@ fn install_plugin_with_options_at_root( } pub fn update_plugin(name: &str) -> Result { - update_plugin_at_root(Utc::now(), &plugin_install_dir(), name) + update_plugin_at_root(Utc::now(), &Paths::plugins_dir(), name) } pub fn auto_update_plugins() -> Vec { - auto_update_plugins_at_root(Utc::now(), &plugin_install_dir()) + auto_update_plugins_at_root(Utc::now(), &Paths::plugins_dir()) } fn auto_update_plugins_at_root( diff --git a/crates/goose/src/skills/mod.rs b/crates/goose/src/skills/mod.rs index aab8edfb7b..0c84d9a3e5 100644 --- a/crates/goose/src/skills/mod.rs +++ b/crates/goose/src/skills/mod.rs @@ -112,6 +112,7 @@ fn inferred_discoverable_skill_root(path: &Path) -> Option { global_roots.push(home.join(".claude").join("skills")); global_roots.push(home.join(".config").join("agents").join("skills")); } + global_roots.extend(installed_plugin_skill_dirs()); for root in global_roots { let canonical_root = canonicalize_or_original(&root);