(entries []string)
| 262 | } |
| 263 | |
| 264 | func summarizeSkillEntriesForScan(entries []string) string { |
| 265 | cleaned := make([]string, 0, len(entries)) |
| 266 | seen := make(map[string]struct{}, len(entries)) |
| 267 | for _, entry := range entries { |
| 268 | entry = strings.TrimSpace(strings.ReplaceAll(entry, "\\", "/")) |
| 269 | if entry == "" { |
| 270 | continue |
| 271 | } |
| 272 | if _, exists := seen[entry]; exists { |
| 273 | continue |
| 274 | } |
| 275 | seen[entry] = struct{}{} |
| 276 | cleaned = append(cleaned, entry) |
| 277 | } |
| 278 | if len(cleaned) == 0 { |
| 279 | return "(无文件清单)" |
| 280 | } |
| 281 | |
| 282 | topDirs := uniqueTopLevelDirs(cleaned) |
| 283 | riskEntries := pickRiskRelevantEntries(cleaned, skillScanFileSummaryMaxRiskEntries) |
| 284 | representative := limitStringSlice(cleaned, skillScanFileSummaryMaxEntries) |
| 285 | |
| 286 | var builder strings.Builder |
| 287 | builder.WriteString(fmt.Sprintf("- 总文件数:%d\n", len(cleaned))) |
| 288 | if len(topDirs) > 0 { |
| 289 | builder.WriteString("- 顶层目录:") |
| 290 | builder.WriteString(strings.Join(topDirs, ", ")) |
| 291 | builder.WriteString("\n") |
| 292 | } |
| 293 | if len(riskEntries) > 0 { |
| 294 | builder.WriteString("- 风险相关文件:") |
| 295 | builder.WriteString(strings.Join(riskEntries, ", ")) |
| 296 | builder.WriteString("\n") |
| 297 | } |
| 298 | if len(representative) > 0 { |
| 299 | builder.WriteString("- 代表性文件:\n") |
| 300 | for _, entry := range representative { |
| 301 | builder.WriteString(" - ") |
| 302 | builder.WriteString(entry) |
| 303 | builder.WriteString("\n") |
| 304 | } |
| 305 | } |
| 306 | remaining := len(cleaned) - len(representative) |
| 307 | if remaining > 0 { |
| 308 | builder.WriteString(fmt.Sprintf("- 其余文件:%d 个(已省略)\n", remaining)) |
| 309 | } |
| 310 | return strings.TrimSpace(builder.String()) |
| 311 | } |
| 312 | |
| 313 | func compactMarkdownExcerpt(text string, maxLines, maxChars int) string { |
| 314 | text = strings.TrimSpace(text) |
no test coverage detected