From f52d1517059b8bedd2aeee5c9de9b33870572626 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 24 Jun 2026 10:10:50 +0000 Subject: [PATCH 1/3] Align fsskills nested discovery with .NET Stop recursive skill root discovery once a SKILL.md is found so nested files remain part of the parent skill instead of becoming independent skill roots. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- agent/skills/fsskills/source.go | 1 + agent/skills/fsskills/source_test.go | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/agent/skills/fsskills/source.go b/agent/skills/fsskills/source.go index 84ce917b..b989adcf 100644 --- a/agent/skills/fsskills/source.go +++ b/agent/skills/fsskills/source.go @@ -192,6 +192,7 @@ func searchForSkills(filesystem fs.FS, dir string, results *[]discoveredSkillDir if err == nil { *results = append(*results, discoveredSkillDir{fsys: sub, path: dir}) } + return } if currentDepth >= defaultSearchDepth { return diff --git a/agent/skills/fsskills/source_test.go b/agent/skills/fsskills/source_test.go index d5c576d1..1bb65399 100644 --- a/agent/skills/fsskills/source_test.go +++ b/agent/skills/fsskills/source_test.go @@ -70,6 +70,30 @@ func TestFileSource_NestedSkillDirectory_DiscoveredWithinDepthLimit(t *testing.T } } +func TestFileSource_NestedSkillFileUnderSkillRoot_NotDiscoveredAsIndependentSkill(t *testing.T) { + root := t.TempDir() + createSkillDir(t, root, "parent-skill", "Parent", "Parent body.") + childDir := filepath.Join(root, "parent-skill", "child") + if err := os.MkdirAll(childDir, 0o755); err != nil { + t.Fatal(err) + } + if err := os.WriteFile(filepath.Join(childDir, "SKILL.md"), []byte("---\nname: child\ndescription: Child\n---\nChild body."), 0o644); err != nil { + t.Fatal(err) + } + + source := fsskills.NewSource(os.DirFS(root)) + loaded, err := source.Skills(t.Context()) + if err != nil { + t.Fatal(err) + } + if len(loaded) != 1 { + t.Fatalf("expected 1 skill, got %d", len(loaded)) + } + if loaded[0].Frontmatter.Name != "parent-skill" { + t.Fatalf("expected parent-skill, got %q", loaded[0].Frontmatter.Name) + } +} + func TestFileSource_SkillBeyondMaxDepth_NotDiscovered(t *testing.T) { root := t.TempDir() createSkillDir(t, filepath.Join(root, "l1", "l2", "l3"), "deep-skill", "Too deep", "Body.") From 348d87d7858c9c5ec8a7798705c83ea815359444 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 24 Jun 2026 20:44:34 +0000 Subject: [PATCH 2/3] Fix root fsskills discovery handling Co-authored-by: michelle-clayton-work <262183035+michelle-clayton-work@users.noreply.github.com> --- agent/skills/fsskills/source.go | 7 +++++-- agent/skills/fsskills/source_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/agent/skills/fsskills/source.go b/agent/skills/fsskills/source.go index b989adcf..05ed23db 100644 --- a/agent/skills/fsskills/source.go +++ b/agent/skills/fsskills/source.go @@ -188,11 +188,14 @@ func discoverSkillDirectories(filesystems []fs.FS) []discoveredSkillDir { func searchForSkills(filesystem fs.FS, dir string, results *[]discoveredSkillDir, currentDepth int) { skillPath := path.Join(dir, skillFileName) if _, err := fs.Stat(filesystem, skillPath); err == nil { - sub, err := fs.Sub(filesystem, dir) + sub := filesystem + if dir != "." { + sub, err = fs.Sub(filesystem, dir) + } if err == nil { *results = append(*results, discoveredSkillDir{fsys: sub, path: dir}) + return } - return } if currentDepth >= defaultSearchDepth { return diff --git a/agent/skills/fsskills/source_test.go b/agent/skills/fsskills/source_test.go index 1bb65399..a74e7d46 100644 --- a/agent/skills/fsskills/source_test.go +++ b/agent/skills/fsskills/source_test.go @@ -70,6 +70,32 @@ func TestFileSource_NestedSkillDirectory_DiscoveredWithinDepthLimit(t *testing.T } } +func TestFileSource_RootSkillFileWithNestedSkillFile_DoesNotAbortDiscovery(t *testing.T) { + root := t.TempDir() + if err := os.WriteFile(filepath.Join(root, "SKILL.md"), []byte("---\nname: root-skill\ndescription: Root\n---\nRoot body."), 0o644); err != nil { + t.Fatal(err) + } + childDir := filepath.Join(root, "child") + if err := os.MkdirAll(childDir, 0o755); err != nil { + t.Fatal(err) + } + if err := os.WriteFile(filepath.Join(childDir, "SKILL.md"), []byte("---\nname: child\ndescription: Child\n---\nChild body."), 0o644); err != nil { + t.Fatal(err) + } + + source := fsskills.NewSource(os.DirFS(root)) + loaded, err := source.Skills(t.Context()) + if err != nil { + t.Fatal(err) + } + if len(loaded) != 1 { + t.Fatalf("expected 1 skill, got %d", len(loaded)) + } + if loaded[0].Frontmatter.Name != "root-skill" { + t.Fatalf("expected root-skill, got %q", loaded[0].Frontmatter.Name) + } +} + func TestFileSource_NestedSkillFileUnderSkillRoot_NotDiscoveredAsIndependentSkill(t *testing.T) { root := t.TempDir() createSkillDir(t, root, "parent-skill", "Parent", "Parent body.") From 1aa9c54bdd7d68775c65b1e766cb8f5818806589 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 24 Jun 2026 20:46:43 +0000 Subject: [PATCH 3/3] Clarify fsskills subfs error handling Co-authored-by: michelle-clayton-work <262183035+michelle-clayton-work@users.noreply.github.com> --- agent/skills/fsskills/source.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/agent/skills/fsskills/source.go b/agent/skills/fsskills/source.go index 05ed23db..29f01376 100644 --- a/agent/skills/fsskills/source.go +++ b/agent/skills/fsskills/source.go @@ -189,10 +189,11 @@ func searchForSkills(filesystem fs.FS, dir string, results *[]discoveredSkillDir skillPath := path.Join(dir, skillFileName) if _, err := fs.Stat(filesystem, skillPath); err == nil { sub := filesystem + var subErr error if dir != "." { - sub, err = fs.Sub(filesystem, dir) + sub, subErr = fs.Sub(filesystem, dir) } - if err == nil { + if subErr == nil { *results = append(*results, discoveredSkillDir{fsys: sub, path: dir}) return }