MCPcopy Create free account
hub / github.com/cli/cli / DiscoverLocalSkillsWithOptions

Function DiscoverLocalSkillsWithOptions

internal/skills/discovery/discovery.go:975–1058  ·  view source on GitHub ↗

DiscoverLocalSkillsWithOptions finds skills in a local directory using the same conventions as remote discovery, with configurable discovery behavior.

(dir string, opts DiscoverOptions)

Source from the content-addressed store, hash-verified

973// DiscoverLocalSkillsWithOptions finds skills in a local directory using the
974// same conventions as remote discovery, with configurable discovery behavior.
975func DiscoverLocalSkillsWithOptions(dir string, opts DiscoverOptions) ([]Skill, error) {
976 absDir, err := filepath.Abs(dir)
977 if err != nil {
978 return nil, fmt.Errorf("could not resolve path: %w", err)
979 }
980
981 info, err := os.Stat(absDir)
982 if err != nil {
983 return nil, fmt.Errorf("could not access %s: %w", dir, err)
984 }
985 if !info.IsDir() {
986 return nil, fmt.Errorf("%s is not a directory", dir)
987 }
988
989 if _, err := os.Stat(filepath.Join(absDir, "SKILL.md")); err == nil {
990 skill, err := localSkillFromDir(absDir)
991 if err != nil {
992 return nil, err
993 }
994 skill.Path = "."
995 return []Skill{*skill}, nil
996 }
997
998 var skills []Skill
999 seen := make(map[string]bool)
1000
1001 err = filepath.Walk(absDir, func(p string, info os.FileInfo, walkErr error) error {
1002 if walkErr != nil {
1003 return walkErr
1004 }
1005 // Skip symlinks to avoid following links outside the source tree.
1006 if info.Mode()&os.ModeSymlink != 0 {
1007 return nil
1008 }
1009 if info.IsDir() || info.Name() != "SKILL.md" {
1010 return nil
1011 }
1012
1013 relPath, relErr := filepath.Rel(absDir, p)
1014 if relErr != nil {
1015 return relErr
1016 }
1017 relPath = filepath.ToSlash(relPath)
1018
1019 entry := treeEntry{Path: relPath, Type: "blob"}
1020 m := matchSkillConventions(entry)
1021 if m == nil {
1022 m = matchHiddenDirConventions(entry)
1023 }
1024 if m == nil {
1025 return nil
1026 }
1027 if seen[m.skillDir] {
1028 return nil
1029 }
1030 seen[m.skillDir] = true
1031
1032 skill, skillErr := localSkillFromDir(filepath.Join(absDir, filepath.FromSlash(m.skillDir)))

Callers 3

runLocalInstallFunction · 0.92
DiscoverLocalSkillsFunction · 0.85

Calls 6

localSkillFromDirFunction · 0.85
matchSkillConventionsFunction · 0.85
JoinMethod · 0.80
ErrorfMethod · 0.65
NameMethod · 0.65

Tested by 1