MatchSkills returns skills relevant to a given intent category, file list, and languages. Results are sorted by score descending, capped at topK.
(category string, files []string, languages []string, topK int)
| 145 | // MatchSkills returns skills relevant to a given intent category, file list, and languages. |
| 146 | // Results are sorted by score descending, capped at topK. |
| 147 | func (idx *SkillIndex) MatchSkills(category string, files []string, languages []string, topK int) []MatchResult { |
| 148 | if idx == nil || len(idx.Skills) == 0 { |
| 149 | return nil |
| 150 | } |
| 151 | |
| 152 | type scored struct { |
| 153 | skill *Skill |
| 154 | score int |
| 155 | reason string |
| 156 | } |
| 157 | |
| 158 | var candidates []scored |
| 159 | |
| 160 | for i := range idx.Skills { |
| 161 | s := &idx.Skills[i] |
| 162 | score := 0 |
| 163 | var reasons []string |
| 164 | |
| 165 | // Keyword match with intent category |
| 166 | for _, kw := range s.Meta.Keywords { |
| 167 | if strings.EqualFold(kw, category) { |
| 168 | score += 3 |
| 169 | reasons = append(reasons, "category:"+category) |
| 170 | } |
| 171 | } |
| 172 | |
| 173 | // Language match |
| 174 | for _, lang := range languages { |
| 175 | for _, sl := range s.Meta.Languages { |
| 176 | if strings.EqualFold(sl, lang) { |
| 177 | score += 2 |
| 178 | reasons = append(reasons, "language:"+lang) |
| 179 | } |
| 180 | } |
| 181 | } |
| 182 | |
| 183 | // Path pattern match |
| 184 | for _, pattern := range s.Meta.PathPatterns { |
| 185 | for _, file := range files { |
| 186 | if matchPath(pattern, file) { |
| 187 | score += 1 |
| 188 | reasons = append(reasons, "path:"+file) |
| 189 | } |
| 190 | } |
| 191 | } |
| 192 | |
| 193 | // Priority boost — only applied when there's a real signal |
| 194 | if score > 0 { |
| 195 | score += s.Meta.Priority / 5 |
| 196 | } |
| 197 | |
| 198 | if score > 0 { |
| 199 | reason := strings.Join(reasons, ", ") |
| 200 | candidates = append(candidates, scored{skill: s, score: score, reason: reason}) |
| 201 | } |
| 202 | } |
| 203 | |
| 204 | // Sort by score descending, then by name for stability |