From 277b61c41075fe43e9309787b9b71963b262653b Mon Sep 17 00:00:00 2001 From: Bradley Axen Date: Wed, 1 Apr 2026 09:11:43 -0700 Subject: [PATCH] docs: standardize on ~/.agents/skills/ as canonical skill path (#8239) Signed-off-by: Bradley Axen --- crates/goose/src/agents/execute_commands.rs | 7 ++----- .../src/agents/platform_extensions/summon.rs | 17 ++++++++++++--- crates/goose/src/recipe/local_recipes.rs | 8 +++++++ .../context-engineering/using-skills.md | 21 ++++++++++--------- documentation/docs/mcp/skills-mcp.md | 4 ++-- 5 files changed, 37 insertions(+), 20 deletions(-) diff --git a/crates/goose/src/agents/execute_commands.rs b/crates/goose/src/agents/execute_commands.rs index d6ff082b76..8efdeca366 100644 --- a/crates/goose/src/agents/execute_commands.rs +++ b/crates/goose/src/agents/execute_commands.rs @@ -154,11 +154,8 @@ impl Agent { if skills.is_empty() { output.push_str("No skills installed.\n\n"); output.push_str("Skills are loaded from SKILL.md files in:\n"); - output.push_str(" - ~/.claude/skills/\n"); - output.push_str(" - ~/.config/agents/skills/\n"); - output.push_str(" - .goose/skills/ (in current directory)\n"); - output.push_str(" - .claude/skills/ (in current directory)\n"); - output.push_str(" - .agents/skills/ (in current directory)\n"); + output.push_str(" - ~/.agents/skills/ (global)\n"); + output.push_str(" - .agents/skills/ (in current project)\n"); } else { output.push_str(&format!("**Installed skills ({}):**\n\n", skills.len())); for skill in &skills { diff --git a/crates/goose/src/agents/platform_extensions/summon.rs b/crates/goose/src/agents/platform_extensions/summon.rs index 0f0f018ac0..b32611b50d 100644 --- a/crates/goose/src/agents/platform_extensions/summon.rs +++ b/crates/goose/src/agents/platform_extensions/summon.rs @@ -410,6 +410,7 @@ fn discover_filesystem_sources(working_dir: &Path) -> Vec { let local_recipe_dirs: Vec = vec![ working_dir.to_path_buf(), working_dir.join(".goose/recipes"), + working_dir.join(".agents/recipes"), ]; let global_recipe_dirs: Vec = std::env::var("GOOSE_RECIPE_PATH") @@ -419,7 +420,14 @@ fn discover_filesystem_sources(working_dir: &Path) -> Vec { let sep = if cfg!(windows) { ';' } else { ':' }; p.split(sep).map(PathBuf::from).collect::>() }) - .chain([config.join("recipes")]) + .chain( + [ + Some(config.join("recipes")), + home.as_ref().map(|h| h.join(".agents/recipes")), + ] + .into_iter() + .flatten(), + ) .collect(); let local_skill_dirs: Vec = vec![ @@ -429,6 +437,7 @@ fn discover_filesystem_sources(working_dir: &Path) -> Vec { ]; let global_skill_dirs: Vec = [ + home.as_ref().map(|h| h.join(".agents/skills")), Some(config.join("skills")), home.as_ref().map(|h| h.join(".claude/skills")), home.as_ref().map(|h| h.join(".config/agents/skills")), @@ -440,9 +449,11 @@ fn discover_filesystem_sources(working_dir: &Path) -> Vec { let local_agent_dirs: Vec = vec![ working_dir.join(".goose/agents"), working_dir.join(".claude/agents"), + working_dir.join(".agents/agents"), ]; let global_agent_dirs: Vec = [ + home.as_ref().map(|h| h.join(".agents/agents")), Some(config.join("agents")), home.as_ref().map(|h| h.join(".claude/agents")), ] @@ -1108,8 +1119,8 @@ impl SummonClient { "No sources available for load/delegate.\n\n\ Sources are discovered from:\n\ • Current recipe's sub_recipes\n\ - • .goose/recipes/, .goose/skills/, .goose/agents/\n\ - • ~/.config/goose/recipes/, skills/, agents/\n\ + • .agents/skills/, .agents/recipes/, .agents/agents/ (project-level)\n\ + • ~/.agents/skills/, ~/.agents/agents/ (global)\n\ • GOOSE_RECIPE_PATH directories\n\ • Builtin skills", )]); diff --git a/crates/goose/src/recipe/local_recipes.rs b/crates/goose/src/recipe/local_recipes.rs index dc7fcdab66..e4edc33709 100644 --- a/crates/goose/src/recipe/local_recipes.rs +++ b/crates/goose/src/recipe/local_recipes.rs @@ -28,6 +28,14 @@ fn local_recipe_dirs() -> Vec { local_dirs.push(get_recipe_library_dir(true)); local_dirs.push(get_recipe_library_dir(false)); + // Also scan .agents/recipes/ for consistency with the .agents/ convention + if let Ok(cwd) = env::current_dir() { + local_dirs.push(cwd.join(".agents/recipes")); + } + if let Some(home) = dirs::home_dir() { + local_dirs.push(home.join(".agents/recipes")); + } + let mut dirs: Vec = local_dirs .into_iter() .map(|dir| dir.canonicalize().unwrap_or(dir)) diff --git a/documentation/docs/guides/context-engineering/using-skills.md b/documentation/docs/guides/context-engineering/using-skills.md index 6df7b92166..1a874d4ab8 100644 --- a/documentation/docs/guides/context-engineering/using-skills.md +++ b/documentation/docs/guides/context-engineering/using-skills.md @@ -25,16 +25,17 @@ goose skills are compatible with Claude Desktop and other [agents that support A ## Skill Locations -Skills can be stored globally and/or per-project. goose checks all of these directories in order and combines what it finds. If the same skill name exists in multiple directories, later directories take priority: +Skills can be stored globally or per-project: -1. `~/.claude/skills/` — Global, shared with Claude Desktop -2. `~/.config/agents/skills/` — Global, portable across AI coding agents -3. `~/.config/goose/skills/` — Global, goose-specific -4. `./.claude/skills/` — Project-level, shared with Claude Desktop -5. `./.goose/skills/` — Project-level, goose-specific -6. `./.agents/skills/` — Project-level, portable across AI coding agents +1. `~/.agents/skills/` — Global skills, available in all sessions +2. `.agents/skills/` — Project-level skills, scoped to the current project -Use global skills for workflows you use across projects. Use project-level skills for procedures unique to a codebase. +Place a `SKILL.md` file inside a named subdirectory. For example, a global skill called +`code-review` goes in `~/.agents/skills/code-review/SKILL.md`. + +> **Backward compatibility:** goose also discovers skills from `.goose/skills/`, +> `.claude/skills/`, `~/.claude/skills/`, and platform-specific config directories, +> but `agents/skills/` is the recommended standard. ## Creating a Skill @@ -45,7 +46,7 @@ Create a skill when you have a repeatable workflow that involves multiple steps, Each skill lives in its own directory with a `SKILL.md` file: ``` -~/.config/agents/skills/ +~/.agents/skills/ └── code-review/ └── SKILL.md ``` @@ -88,7 +89,7 @@ When reviewing code, check each of these areas: Skills can include supporting files like scripts, templates, or configuration files. Place them in the skill directory: ``` -~/.config/agents/skills/ +~/.agents/skills/ └── api-setup/ ├── SKILL.md ├── setup.sh diff --git a/documentation/docs/mcp/skills-mcp.md b/documentation/docs/mcp/skills-mcp.md index 3c4e6fb9df..9ddc51cd3b 100644 --- a/documentation/docs/mcp/skills-mcp.md +++ b/documentation/docs/mcp/skills-mcp.md @@ -14,7 +14,7 @@ This extension has been deprecated and is only available in v1.16.0 - v1.24.0. F The Skills extension loads *skills* — reusable sets of instructions that teach goose how to perform specific tasks or follow particular workflows. -goose automatically discovers skills at startup and uses them when relevant to your request. goose loads skills from `.agents/skills/` in your project directory and `~/.config/agents/skills/` globally, making skills portable across different AI coding agents. To learn about creating skills and how goose uses them, see [Using Skills](/docs/guides/context-engineering/using-skills). +goose automatically discovers skills at startup and uses them when relevant to your request. goose loads skills from `.agents/skills/` in your project directory and `~/.agents/skills/` globally, making skills portable across different AI coding agents. To learn about creating skills and how goose uses them, see [Using Skills](/docs/guides/context-engineering/using-skills). ## Configuration @@ -52,7 +52,7 @@ goose automatically discovers skills at startup and uses them when relevant to y ## Example Usage -Let's say you have a skill that goose discovers on startup in `~/.config/agents/skills/deploy/SKILL.md`: +Let's say you have a skill that goose discovers on startup in `~/.agents/skills/deploy/SKILL.md`: ```markdown ---