Skip to content

[dotnet-port] Align fsskills nested discovery with .NET #347

Description

@github-actions

Summary

Aligns Go file-system skill discovery with upstream .NET behavior from commit dd4b7ff475e467ac4490090eb2436e80b898dd5c. When discovery finds a SKILL.md, that directory is treated as the skill root and traversal stops below it, so nested SKILL.md files remain part of the parent skill instead of being discovered as independent skill roots.

Ported .NET PRs

Breaking Changes

No.

Tests and Examples

  • Added TestFileSource_NestedSkillFileUnderSkillRoot_NotDiscoveredAsIndependentSkill.
  • Ran go test ./agent/skills/fsskills before and after the change.

Notes

Skipped broader upstream changes from the inspected range (dd4b7ff47 through 1fc57c45e) including skill content resource/script projection, A2A session store defaults, and OpenTelemetry span placement because this PR is intentionally limited to the narrow nested skill discovery parity fix. Upstream head inspected: dd4b7ff475e467ac4490090eb2436e80b898dd5c. An unrelated untracked .github/agents/port-candidate-selector.agent.md file existed in the workspace and was not included.

Generated by .NET to Go Porting Agent · 526.4 AIC · ⌖ 67.3 AIC · ⊞ 21.5K ·


Note

This was originally intended as a pull request, but GitHub Actions is not permitted to create or approve pull requests in this repository.
The changes have been pushed to branch dotnet-port-fsskills-stop-recursing-7ef700e8ce62f08d.

Click here to create the pull request

To fix the permissions issue, go to SettingsActionsGeneral and enable Allow GitHub Actions to create and approve pull requests. See also: gh-aw FAQ

Show patch preview (64 of 64 lines)
From 428470a9b17b8d46f63f8fe9742e95447d66d66f Mon Sep 17 00:00:00 2001
From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com>
Date: Wed, 24 Jun 2026 10:07:18 +0000
Subject: [PATCH] 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 84ce917bf..b989adcfa 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 d5c576d15..1bb65399e 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
... (truncated)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions