LoadSkills discovers SKILL.md and *.md files from multiple sources in priority order: 1. Builtin (embedded in binary) 2. Project-local (.codemap/skills/) 3. Global (~/.codemap/skills/) Later sources override earlier ones if they share the same name.
(root string)
| 21 | // 3. Global (~/.codemap/skills/) |
| 22 | // Later sources override earlier ones if they share the same name. |
| 23 | func LoadSkills(root string) (*SkillIndex, error) { |
| 24 | var all []Skill |
| 25 | |
| 26 | // 1. Builtin skills (embedded) |
| 27 | builtins, err := loadBuiltinSkills() |
| 28 | if err != nil { |
| 29 | return nil, err |
| 30 | } |
| 31 | all = append(all, builtins...) |
| 32 | |
| 33 | // 2. Project-local skills |
| 34 | projectDir := filepath.Join(root, ".codemap", "skills") |
| 35 | projectSkills, _ := loadSkillsFromDir(projectDir, projectSource) |
| 36 | all = append(all, projectSkills...) |
| 37 | |
| 38 | // 3. Global skills |
| 39 | home, _ := os.UserHomeDir() |
| 40 | if home != "" { |
| 41 | globalDir := filepath.Join(home, ".codemap", "skills") |
| 42 | globalSkills, _ := loadSkillsFromDir(globalDir, globalSource) |
| 43 | all = append(all, globalSkills...) |
| 44 | } |
| 45 | |
| 46 | // Deduplicate: later sources win (project overrides builtin, global overrides project) |
| 47 | seen := make(map[string]int) // name -> index in deduped |
| 48 | var deduped []Skill |
| 49 | for _, s := range all { |
| 50 | if idx, exists := seen[s.Meta.Name]; exists { |
| 51 | deduped[idx] = s // replace |
| 52 | } else { |
| 53 | seen[s.Meta.Name] = len(deduped) |
| 54 | deduped = append(deduped, s) |
| 55 | } |
| 56 | } |
| 57 | |
| 58 | return newIndex(deduped), nil |
| 59 | } |
| 60 | |
| 61 | // loadSkillsFromDir reads all .md files in a directory as skills. |
| 62 | func loadSkillsFromDir(dir, source string) ([]Skill, error) { |