package discovery import ( "os" "path/filepath" "testing" ) func writeTree(t *testing.T, root string, files map[string]string) { t.Helper() for rel, content := range files { p := filepath.Join(root, filepath.FromSlash(rel)) os.MkdirAll(filepath.Dir(p), 0o755) os.WriteFile(p, []byte(content), 0o644) } } func TestScanNestedSkillCategories(t *testing.T) { dir := t.TempDir() writeTree(t, dir, map[string]string{ "skills/flat-skill/SKILL.md": "---\nname: Flat\n---\n", "skills/engineering/tdd/SKILL.md": "---\nname: TDD\n---\n", "skills/productivity/grill-me/SKILL.md": "---\nname: Grill Me\n---\n", "skills/engineering/tdd/reference.md": "extra artifact", "skills/deprecated/old/README.md": "no skill here", "commands/deploy.md": "---\nname: Deploy\n---\n", }) items, err := Scan(&FsTree{Root: dir}, Config{}) if err != nil { t.Fatal(err) } got := map[string]Item{} for _, it := range items { got[it.UpstreamID] = it } for _, want := range []string{"flat-skill", "tdd", "grill-me"} { it, ok := got[want] if !ok { t.Fatalf("skill %q not discovered (items: %+v)", want, items) } if it.Type != "skills" { t.Errorf("%q type = %q", want, it.Type) } } if _, ok := got["old"]; ok { t.Error("folder without SKILL.md must not be a skill") } tdd := got["tdd"] if tdd.RelPath != "skills/engineering/tdd" { t.Errorf("tdd RelPath = %q", tdd.RelPath) } if got["deploy"].Type != "commands" { t.Error("flat command types must still be discovered") } } func TestScanOuterSkillWinsOverNested(t *testing.T) { dir := t.TempDir() writeTree(t, dir, map[string]string{ "skills/bundle/SKILL.md": "---\nname: Bundle\n---\n", "skills/bundle/inner/SKILL.md": "---\nname: Inner\n---\n", "skills/bundle/inner/deep/SKILL.md": "---\nname: Deep\n---\n", }) items, err := Scan(&FsTree{Root: dir}, Config{}) if err != nil { t.Fatal(err) } if len(items) != 1 || items[0].UpstreamID != "bundle" { t.Fatalf("outermost skill must win, got %+v", items) } }